From d17f0910deb9789bc52d7c5a19e297b623ac93f9 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 18 Nov 2022 14:47:31 +0200 Subject: [PATCH 01/24] direct imports --- src/compiler/binder.ts | 330 ++-- src/compiler/builder.ts | 139 +- src/compiler/builderPublic.ts | 14 +- src/compiler/builderState.ts | 48 +- src/compiler/builderStatePublic.ts | 2 +- src/compiler/checker.ts | 1338 +++++++------- src/compiler/checkerUtilities.ts | 25 + src/compiler/commandLineParser.ts | 148 +- src/compiler/core.ts | 97 +- src/compiler/emitter.ts | 443 ++--- src/compiler/factory/baseNodeFactory.ts | 4 +- .../factory/binaryExpressionStateMachine.ts | 220 +++ src/compiler/factory/emitHelpers.ts | 77 +- src/compiler/factory/emitNode.ts | 20 +- src/compiler/factory/nodeConverters.ts | 38 +- src/compiler/factory/nodeFactory.ts | 350 ++-- src/compiler/factory/nodeTests.ts | 2 +- src/compiler/factory/parenthesizerRules.ts | 66 +- src/compiler/factory/utilities.ts | 476 +---- src/compiler/factory/utilitiesPublic.ts | 61 +- src/compiler/moduleNameResolver.ts | 148 +- src/compiler/moduleSpecifiers.ts | 146 +- src/compiler/parser.ts | 233 +-- src/compiler/path.ts | 12 +- src/compiler/perfLogger.ts | 2 +- src/compiler/performance.ts | 12 +- src/compiler/performanceCore.ts | 4 +- src/compiler/program.ts | 500 +++--- src/compiler/resolutionCache.ts | 151 +- src/compiler/scanner.ts | 306 +--- src/compiler/scannerUtilities.ts | 158 ++ src/compiler/semver.ts | 42 +- src/compiler/sourcemap.ts | 38 +- src/compiler/symbolWalker.ts | 8 +- src/compiler/sys.ts | 58 +- src/compiler/tracing.ts | 16 +- src/compiler/transformer.ts | 94 +- src/compiler/transformers/classFields.ts | 238 +-- src/compiler/transformers/declarations.ts | 286 +-- .../transformers/declarations/diagnostics.ts | 50 +- src/compiler/transformers/destructuring.ts | 86 +- src/compiler/transformers/es2015.ts | 270 +-- src/compiler/transformers/es2016.ts | 18 +- src/compiler/transformers/es2017.ts | 100 +- src/compiler/transformers/es2018.ts | 128 +- src/compiler/transformers/es2019.ts | 10 +- src/compiler/transformers/es2020.ts | 50 +- src/compiler/transformers/es2021.ts | 30 +- src/compiler/transformers/es5.ts | 26 +- src/compiler/transformers/esnext.ts | 6 +- src/compiler/transformers/generators.ts | 106 +- src/compiler/transformers/jsx.ts | 90 +- src/compiler/transformers/legacyDecorators.ts | 108 +- .../transformers/module/esnextAnd2015.ts | 62 +- src/compiler/transformers/module/module.ts | 178 +- src/compiler/transformers/module/node.ts | 12 +- src/compiler/transformers/module/system.ts | 158 +- src/compiler/transformers/taggedTemplate.ts | 24 +- src/compiler/transformers/ts.ts | 246 +-- src/compiler/transformers/typeSerializer.ts | 70 +- src/compiler/transformers/utilities.ts | 84 +- src/compiler/tsbuild.ts | 6 +- src/compiler/tsbuildPublic.ts | 242 +-- src/compiler/types.ts | 70 +- src/compiler/utilities.ts | 634 ++++--- src/compiler/utilitiesPublic.ts | 210 +-- src/compiler/visitorPublic.ts | 122 +- src/compiler/watch.ts | 172 +- src/compiler/watchPublic.ts | 154 +- src/compiler/watchUtilities.ts | 90 +- .../4.0/nodeFactoryTopLevelExports.ts | 22 +- src/deprecatedCompat/4.0/renamedNodeTests.ts | 2 +- .../4.2/abstractConstructorTypes.ts | 8 +- src/deprecatedCompat/4.2/renamedNodeTests.ts | 4 +- .../4.6/importTypeAssertions.ts | 16 +- .../4.7/typeParameterModifiers.ts | 8 +- .../4.8/mergeDecoratorsAndModifiers.ts | 74 +- src/deprecatedCompat/deprecate.ts | 14 +- src/deprecatedCompat/deprecations.ts | 9 +- src/executeCommandLine/executeCommandLine.ts | 177 +- src/harness/fourslashImpl.ts | 7 +- src/jsTyping/jsTyping.ts | 44 +- src/jsTyping/shared.ts | 6 +- src/jsTyping/types.ts | 30 +- src/server/editorServices.ts | 326 ++-- src/server/moduleSpecifierCache.ts | 8 +- src/server/packageJsonCache.ts | 14 +- src/server/project.ts | 256 +-- src/server/protocol.ts | 20 +- src/server/scriptInfo.ts | 102 +- src/server/scriptVersionCache.ts | 20 +- src/server/session.ts | 256 +-- src/server/types.ts | 4 +- src/server/typingsCache.ts | 24 +- src/server/utilities.ts | 14 +- src/server/utilitiesPublic.ts | 16 +- src/services/_namespaces/ts.codefix.ts | 1 + src/services/_namespaces/ts.ts | 6 +- src/services/breakpoints.ts | 58 +- src/services/callHierarchy.ts | 139 +- src/services/classifier.ts | 98 +- src/services/classifier2020.ts | 40 +- src/services/codeFixProvider.ts | 38 +- ...dConvertToUnknownForNonOverlappingTypes.ts | 24 +- .../codefixes/addEmptyExportDeclaration.ts | 14 +- src/services/codefixes/addMissingAsync.ts | 59 +- src/services/codefixes/addMissingAwait.ts | 74 +- src/services/codefixes/addMissingConst.ts | 32 +- .../codefixes/addMissingDeclareProperty.ts | 18 +- .../addMissingInvocationForDecorator.ts | 24 +- .../codefixes/addNameToNamelessParameter.ts | 20 +- .../codefixes/addOptionalPropertyUndefined.ts | 30 +- .../codefixes/annotateWithTypeFromJSDoc.ts | 88 +- src/services/codefixes/convertConstToLet.ts | 30 +- .../codefixes/convertFunctionToEs6Class.ts | 80 +- .../convertLiteralTypeToMappedType.ts | 20 +- .../codefixes/convertToAsyncFunction.ts | 106 +- src/services/codefixes/convertToEsModule.ts | 122 +- .../codefixes/convertToMappedObjectType.ts | 34 +- .../codefixes/convertToTypeOnlyExport.ts | 46 +- .../codefixes/convertToTypeOnlyImport.ts | 22 +- ...correctQualifiedNameToIndexedAccessType.ts | 24 +- .../codefixes/disableJsDiagnostics.ts | 45 +- .../codefixes/fixAddMissingConstraint.ts | 54 +- src/services/codefixes/fixAddMissingMember.ts | 182 +- .../codefixes/fixAddMissingNewOperator.ts | 22 +- .../fixAddModuleReferTypeMissingTypeof.ts | 18 +- src/services/codefixes/fixAddVoidToPromise.ts | 32 +- .../codefixes/fixAwaitInSyncFunction.ts | 38 +- src/services/codefixes/fixCannotFindModule.ts | 28 +- ...sDoesntImplementInheritedAbstractMember.ts | 38 +- .../fixClassIncorrectlyImplementsInterface.ts | 50 +- .../fixClassSuperMustPrecedeThisAccess.ts | 34 +- .../fixConstructorForDerivedNeedSuperCall.ts | 22 +- .../fixEnableExperimentalDecorators.ts | 18 +- src/services/codefixes/fixEnableJsxFlag.ts | 18 +- src/services/codefixes/fixExpectedComma.ts | 18 +- .../fixExtendsInterfaceBecomesImplements.ts | 20 +- .../fixForgottenThisPropertyAccess.ts | 26 +- src/services/codefixes/fixImplicitThis.ts | 38 +- .../codefixes/fixImportNonExportedMember.ts | 54 +- .../codefixes/fixIncorrectNamedTupleSyntax.ts | 18 +- .../codefixes/fixInvalidImportSyntax.ts | 48 +- .../codefixes/fixInvalidJsxCharacters.ts | 18 +- src/services/codefixes/fixJSDocTypes.ts | 18 +- .../codefixes/fixMissingCallParentheses.ts | 18 +- .../codefixes/fixModuleAndTargetOptions.ts | 34 +- src/services/codefixes/fixNaNEquality.ts | 28 +- .../fixNoPropertyAccessFromIndexSignature.ts | 28 +- src/services/codefixes/fixOverrideModifier.ts | 58 +- .../codefixes/fixPropertyAssignment.ts | 22 +- .../codefixes/fixPropertyOverrideAccessor.ts | 26 +- .../codefixes/fixReturnTypeInAsyncFunction.ts | 24 +- src/services/codefixes/fixSpelling.ts | 64 +- .../codefixes/fixStrictClassInitialization.ts | 56 +- .../codefixes/fixUnmatchedParameter.ts | 40 +- src/services/codefixes/fixUnreachableCode.ts | 30 +- .../fixUnreferenceableDecoratorMetadata.ts | 44 +- src/services/codefixes/fixUnusedIdentifier.ts | 109 +- src/services/codefixes/fixUnusedLabel.ts | 26 +- src/services/codefixes/generateAccessors.ts | 98 +- src/services/codefixes/helpers.ts | 112 +- src/services/codefixes/importAdder.ts | 1546 +++++++++++++++++ src/services/codefixes/importFixes.ts | 1518 +--------------- src/services/codefixes/inferFromUsage.ts | 156 +- .../removeAccidentalCallParentheses.ts | 16 +- .../codefixes/removeUnnecessaryAwait.ts | 26 +- src/services/codefixes/requireInTs.ts | 34 +- src/services/codefixes/returnValueCorrect.ts | 78 +- src/services/codefixes/splitTypeOnlyImport.ts | 24 +- src/services/codefixes/useBigintLiteral.ts | 21 +- src/services/codefixes/useDefaultImport.ts | 28 +- src/services/codefixes/wrapJsxInFragment.ts | 22 +- src/services/completions.ts | 550 +++--- src/services/documentHighlights.ts | 911 +++++----- src/services/documentRegistry.ts | 42 +- src/services/exportInfoMap.ts | 132 +- src/services/findAllReferences.ts | 463 ++--- src/services/formatting/formatting.ts | 179 +- src/services/formatting/formattingContext.ts | 12 +- src/services/formatting/formattingScanner.ts | 24 +- src/services/formatting/rule.ts | 8 +- src/services/formatting/rules.ts | 60 +- src/services/formatting/rulesMap.ts | 28 +- src/services/formatting/smartIndenter.ts | 69 +- src/services/getEditsForFileRename.ts | 82 +- src/services/goToDefinition.ts | 155 +- src/services/importTracker.ts | 90 +- src/services/inlayHints.ts | 88 +- src/services/jsDoc.ts | 110 +- src/services/navigateTo.ts | 44 +- src/services/navigationBar.ts | 148 +- src/services/organizeImports.ts | 96 +- src/services/outliningElementsCollector.ts | 66 +- src/services/patternMatcher.ts | 14 +- src/services/preProcess.ts | 14 +- src/services/refactorProvider.ts | 8 +- .../addOrRemoveBracesToArrowFunction.ts | 58 +- ...onvertArrowFunctionOrFunctionExpression.ts | 90 +- src/services/refactors/convertExport.ts | 84 +- src/services/refactors/convertImport.ts | 84 +- .../convertOverloadListToSingleSignature.ts | 64 +- .../convertParamsToDestructuredObject.ts | 165 +- .../convertStringOrTemplateLiteral.ts | 58 +- .../convertToOptionalChainExpression.ts | 68 +- src/services/refactors/extractSymbol.ts | 201 ++- src/services/refactors/extractType.ts | 100 +- .../generateGetAccessorAndSetAccessor.ts | 31 +- src/services/refactors/helpers.ts | 12 +- .../refactors/inferFunctionReturnType.ts | 52 +- src/services/refactors/moveToNewFile.ts | 196 ++- src/services/rename.ts | 87 +- src/services/services.ts | 566 +++--- src/services/shims.ts | 120 +- src/services/signatureHelp.ts | 108 +- src/services/smartSelection.ts | 48 +- src/services/sourcemaps.ts | 56 +- src/services/stringCompletions.ts | 213 ++- src/services/suggestionDiagnostics.ts | 80 +- src/services/symbolDisplay.ts | 140 +- src/services/textChanges.ts | 267 +-- src/services/transform.ts | 14 +- src/services/transpile.ts | 48 +- src/services/types.ts | 146 +- src/services/utilities.ts | 636 ++++--- .../services/convertToAsyncFunction.ts | 17 +- .../unittests/services/extract/helpers.ts | 8 +- .../unittests/services/organizeImports.ts | 3 +- .../unittests/services/textChanges.ts | 40 +- .../unittests/tsserver/exportMapCache.ts | 17 +- .../reference/api/tsserverlibrary.d.ts | 34 +- tests/baselines/reference/api/typescript.d.ts | 22 +- 232 files changed, 13640 insertions(+), 11519 deletions(-) create mode 100644 src/compiler/checkerUtilities.ts create mode 100644 src/compiler/factory/binaryExpressionStateMachine.ts create mode 100644 src/compiler/scannerUtilities.ts create mode 100644 src/services/codefixes/importAdder.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 64fbdbce0e572..476dd49ec95dc 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1,9 +1,71 @@ +import { getNodeId } from "./checkerUtilities"; import { - __String, - AccessExpression, - addRelatedInfo, append, appendIfUnique, + cast, + concatenate, + contains, + createQueue, + every, + forEach, + getRangesWhere, + isString, + length, + Pattern, + some, + tryCast, +} from "./core"; +import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { + createBinaryExpressionTrampoline, +} from "./factory/binaryExpressionStateMachine"; +import { + isBinaryExpression, + isBlock, + isCallExpression, + isClassStaticBlockDeclaration, + isConditionalTypeNode, + isElementAccessExpression, + isEnumDeclaration, + isExportAssignment, + isExportDeclaration, + isExportSpecifier, + isFunctionDeclaration, + isIdentifier, + isJSDocEnumTag, + isJSDocTemplateTag, + isModuleBlock, + isModuleDeclaration, + isNamespaceExport, + isNonNullExpression, + isObjectLiteralExpression, + isOmittedExpression, + isParenthesizedExpression, + isPrefixUnaryExpression, + isPrivateIdentifier, + isPropertyAccessExpression, + isShorthandPropertyAssignment, + isSourceFile, + isTypeAliasDeclaration, + isTypeOfExpression, + isVariableDeclaration, + isVariableStatement, +} from "./factory/nodeTests"; +import { + forEachChild, + isExternalModule, +} from "./parser"; +import { perfLogger } from "./perfLogger"; +import * as performance from "./performance"; +import { tokenToString } from "./scanner"; +import { + tracing, + TracingNode, +} from "./tracing"; +import { + __String, + AccessExpression, ArrayBindingElement, ArrayLiteralExpression, ArrowFunction, @@ -23,29 +85,18 @@ import { CallExpression, CaseBlock, CaseClause, - cast, CatchClause, ClassLikeDeclaration, ClassStaticBlockDeclaration, CompilerOptions, - concatenate, ConditionalExpression, ConditionalTypeNode, - contains, - createBinaryExpressionTrampoline, - createDiagnosticForNodeInSourceFile, - createFileDiagnostic, - createQueue, - createSymbolTable, - Debug, Declaration, - declarationNameToString, DeleteExpression, DestructuringAssignment, DiagnosticCategory, DiagnosticMessage, DiagnosticRelatedInformation, - Diagnostics, DiagnosticWithLocation, DoStatement, DynamicNamedDeclaration, @@ -53,32 +104,97 @@ import { ElementAccessExpression, EntityNameExpression, EnumDeclaration, - escapeLeadingUnderscores, - every, ExportAssignment, - exportAssignmentIsAlias, ExportDeclaration, ExportSpecifier, Expression, ExpressionStatement, - findAncestor, FlowFlags, FlowLabel, FlowNode, FlowReduceLabel, - forEach, - forEachChild, ForInOrOfStatement, ForStatement, FunctionDeclaration, FunctionExpression, FunctionLikeDeclaration, GetAccessorDeclaration, + Identifier, + IfStatement, + ImportClause, + InternalSymbolName, + JSDocCallbackTag, + JSDocClassTag, + JSDocEnumTag, + JSDocFunctionType, + JSDocParameterTag, + JSDocPropertyLikeTag, + JSDocSignature, + JSDocTypedefTag, + JSDocTypeLiteral, + JsxAttribute, + JsxAttributes, + LabeledStatement, + LiteralLikeElementAccessExpression, + MappedTypeNode, + MethodDeclaration, + ModifierFlags, + ModuleBlock, + ModuleDeclaration, + NamespaceExportDeclaration, + Node, + NodeArray, + NodeFlags, + NonNullChain, + NonNullExpression, + NumericLiteral, + ObjectLiteralExpression, + OptionalChain, + ParameterDeclaration, + ParenthesizedExpression, + PatternAmbientModule, + PostfixUnaryExpression, + PrefixUnaryExpression, + PrivateIdentifier, + PropertyAccessChain, + PropertyAccessExpression, + PropertyDeclaration, + PropertySignature, + ReturnStatement, + ScriptTarget, + SetAccessorDeclaration, + ShorthandPropertyAssignment, + SignatureDeclaration, + SourceFile, + SpreadElement, + Statement, + StringLiteral, + SwitchStatement, + Symbol, + SymbolFlags, + SymbolTable, + SyntaxKind, + TextRange, + ThrowStatement, + TokenFlags, + TryStatement, + TypeLiteralNode, + TypeOfExpression, + TypeParameterDeclaration, + VariableDeclaration, + WhileStatement, + WithStatement, +} from "./types"; +import { + addRelatedInfo, + createDiagnosticForNodeInSourceFile, + createFileDiagnostic, + createSymbolTable, + declarationNameToString, + exportAssignmentIsAlias, getAssignedExpandoInitializer, getAssignmentDeclarationKind, getAssignmentDeclarationPropertyAccessKind, - getCombinedModifierFlags, - getCombinedNodeFlags, getContainingClass, getEffectiveContainerForJSDocTemplateTag, getElementOrPropertyAccessName, @@ -89,12 +205,8 @@ import { getExpandoInitializer, getHostSignatureFromJSDoc, getImmediatelyInvokedFunctionExpression, - getJSDocTypeTag, getLeftmostAccessExpression, - getNameOfDeclaration, getNameOrArgument, - getNodeId, - getRangesWhere, getRightMostAssignedExpression, getSourceFileOfNode, getSourceTextOfNodeFromSourceFile, @@ -105,197 +217,99 @@ import { getThisContainer, getTokenPosOfNode, hasDynamicName, - hasJSDocNodes, hasSyntacticModifier, - Identifier, - idText, - IfStatement, - ImportClause, - InternalSymbolName, isAliasableExpression, isAmbientModule, isAssignmentExpression, isAssignmentOperator, isAssignmentTarget, isAsyncFunction, - isAutoAccessorPropertyDeclaration, - isBinaryExpression, isBindableObjectDefinePropertyCall, isBindableStaticAccessExpression, isBindableStaticNameExpression, - isBindingPattern, - isBlock, isBlockOrCatchScoped, - isCallExpression, - isClassStaticBlockDeclaration, - isConditionalTypeNode, - isDeclaration, - isDeclarationStatement, isDestructuringAssignment, isDottedName, - isElementAccessExpression, isEmptyObjectLiteral, isEntityNameExpression, isEnumConst, - isEnumDeclaration, - isExportAssignment, - isExportDeclaration, isExportsIdentifier, - isExportSpecifier, - isExpression, - isExpressionOfOptionalChainRoot, - isExternalModule, isExternalOrCommonJsModule, - isForInOrOfStatement, - isFunctionDeclaration, - isFunctionLike, - isFunctionLikeDeclaration, - isFunctionLikeOrClassStaticBlockDeclaration, isFunctionSymbol, isGlobalScopeAugmentation, - isIdentifier, isIdentifierName, isInJSFile, isInTopLevelContext, isJSDocConstructSignature, - isJSDocEnumTag, - isJSDocTemplateTag, isJSDocTypeAlias, isJsonSourceFile, - isLeftHandSideExpression, isLogicalOrCoalescingAssignmentOperator, isModuleAugmentationExternal, - isModuleBlock, - isModuleDeclaration, isModuleExportsAccessExpression, - isNamedDeclaration, - isNamespaceExport, - isNonNullExpression, - isNullishCoalesce, - isObjectLiteralExpression, isObjectLiteralMethod, isObjectLiteralOrClassExpressionMethodOrAccessor, - isOmittedExpression, - isOptionalChain, - isOptionalChainRoot, - isOutermostOptionalChain, isParameterDeclaration, - isParameterPropertyDeclaration, - isParenthesizedExpression, isPartOfTypeQuery, - isPrefixUnaryExpression, - isPrivateIdentifier, isPrologueDirective, isPropertyAccessEntityNameExpression, - isPropertyAccessExpression, isPropertyNameLiteral, isPrototypeAccess, isPushOrUnshiftIdentifier, isRequireCall, - isShorthandPropertyAssignment, isSignedNumericLiteral, - isSourceFile, isSpecialPropertyDeclaration, - isStatement, - isStatementButNotDeclaration, isStatic, - isString, - isStringLiteralLike, isStringOrNumericLiteralLike, isThisInitializedDeclaration, - isTypeAliasDeclaration, - isTypeOfExpression, - isVariableDeclaration, isVariableDeclarationInitializedToBareOrAccessedRequire, - isVariableStatement, - JSDocCallbackTag, - JSDocClassTag, - JSDocEnumTag, - JSDocFunctionType, - JSDocParameterTag, - JSDocPropertyLikeTag, - JSDocSignature, - JSDocTypedefTag, - JSDocTypeLiteral, - JsxAttribute, - JsxAttributes, - LabeledStatement, - length, - LiteralLikeElementAccessExpression, - MappedTypeNode, - MethodDeclaration, - ModifierFlags, - ModuleBlock, - ModuleDeclaration, Mutable, - NamespaceExportDeclaration, - Node, - NodeArray, - NodeFlags, - nodeHasName, nodeIsMissing, nodeIsPresent, - NonNullChain, - NonNullExpression, - NumericLiteral, objectAllocator, - ObjectLiteralExpression, - OptionalChain, - ParameterDeclaration, - ParenthesizedExpression, - Pattern, - PatternAmbientModule, - perfLogger, - PostfixUnaryExpression, - PrefixUnaryExpression, - PrivateIdentifier, - PropertyAccessChain, - PropertyAccessExpression, - PropertyDeclaration, - PropertySignature, removeFileExtension, - ReturnStatement, - ScriptTarget, - SetAccessorDeclaration, setParent, setParentRecursive, setValueDeclaration, - ShorthandPropertyAssignment, shouldPreserveConstEnums, - SignatureDeclaration, skipParentheses, sliceAfter, - some, - SourceFile, - SpreadElement, - Statement, - StringLiteral, - SwitchStatement, - Symbol, - SymbolFlags, - symbolName, - SymbolTable, - SyntaxKind, - TextRange, - ThrowStatement, - TokenFlags, - tokenToString, - tracing, - TracingNode, - tryCast, tryParsePattern, - TryStatement, - TypeLiteralNode, - TypeOfExpression, - TypeParameterDeclaration, - unescapeLeadingUnderscores, unreachableCodeIsError, unusedLabelIsError, - VariableDeclaration, - WhileStatement, - WithStatement, -} from "./_namespaces/ts"; -import * as performance from "./_namespaces/ts.performance"; +} from "./utilities"; +import { + escapeLeadingUnderscores, + findAncestor, + getCombinedModifierFlags, + getCombinedNodeFlags, + getJSDocTypeTag, + getNameOfDeclaration, + hasJSDocNodes, + idText, + isAutoAccessorPropertyDeclaration, + isBindingPattern, + isDeclaration, + isDeclarationStatement, + isExpression, + isExpressionOfOptionalChainRoot, + isForInOrOfStatement, + isFunctionLike, + isFunctionLikeDeclaration, + isFunctionLikeOrClassStaticBlockDeclaration, + isLeftHandSideExpression, + isNamedDeclaration, + isNullishCoalesce, + isOptionalChain, + isOptionalChainRoot, + isOutermostOptionalChain, + isParameterPropertyDeclaration, + isStatement, + isStatementButNotDeclaration, + isStringLiteralLike, + nodeHasName, + symbolName, + unescapeLeadingUnderscores, +} from "./utilitiesPublic"; /** @internal */ export const enum ModuleInstanceState { diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 6002189104f9b..b965fca232dd4 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -1,60 +1,29 @@ -import * as ts from "./_namespaces/ts"; import { - addRange, AffectedFileResult, - arrayFrom, - arrayToMap, BuilderProgram, BuilderProgramHost, - BuilderState, - BuildInfo, - BundleBuildInfo, - CancellationToken, - CommandLineOption, + EmitAndSemanticDiagnosticsBuilderProgram, + HostForComputeHash, + SemanticDiagnosticsBuilderProgram, +} from "./builderPublic"; +import { BuilderState } from "./builderState"; +import { + convertToOptionsWithAbsolutePaths, + getOptionsNameMap, +} from "./commandLineParser"; +import { + addRange, + arrayFrom, + arrayToMap, compareStringsCaseSensitive, compareValues, - CompilerHost, - CompilerOptions, - compilerOptionsAffectDeclarationPath, - compilerOptionsAffectEmit, - compilerOptionsAffectSemanticDiagnostics, - CompilerOptionsValue, concatenate, - convertToOptionsWithAbsolutePaths, - createBuildInfo, createGetCanonicalFileName, - createProgram, - CustomTransformers, - Debug, - Diagnostic, - DiagnosticCategory, - DiagnosticMessageChain, - DiagnosticRelatedInformation, - DiagnosticWithLocation, - EmitAndSemanticDiagnosticsBuilderProgram, - EmitOnly, - EmitResult, - emitSkippedWithNoDiagnostics, emptyArray, - ensurePathIsNonModuleName, - filterSemanticDiagnostics, forEach, - forEachEntry, - forEachKey, - generateDjb2Hash, GetCanonicalFileName, - getDirectoryPath, - getEmitDeclarations, - getNormalizedAbsolutePath, - getOptionsNameMap, getOwnKeys, - getRelativePathFromDirectory, - getTsBuildInfoEmitOutputFilePath, - handleNoEmitOptions, - HostForComputeHash, isArray, - isDeclarationFileName, - isJsonSourceFile, isNumber, isString, map, @@ -62,25 +31,69 @@ import { maybeBind, noop, notImplemented, - outFile, - Path, - Program, - ProjectReference, - ReadBuildProgramHost, - ReadonlyCollection, returnFalse, returnUndefined, - SemanticDiagnosticsBuilderProgram, - skipTypeChecking, some, + tryAddToSet, +} from "./core"; +import { ReadonlyCollection } from "./corePublic"; +import { Debug } from "./debug"; +import { + createBuildInfo, + getTsBuildInfoEmitOutputFilePath, +} from "./emitter"; +import { isDeclarationFileName } from "./parser"; +import { + ensurePathIsNonModuleName, + getDirectoryPath, + getNormalizedAbsolutePath, + getRelativePathFromDirectory, + toPath, +} from "./path"; +import { + createProgram, + emitSkippedWithNoDiagnostics, + filterSemanticDiagnostics, + handleNoEmitOptions, +} from "./program"; +import { generateDjb2Hash } from "./sys"; +import { + BuildInfo, + BundleBuildInfo, + CancellationToken, + CommandLineOption, + CompilerHost, + CompilerOptions, + CompilerOptionsValue, + CustomTransformers, + Diagnostic, + DiagnosticCategory, + DiagnosticMessageChain, + DiagnosticRelatedInformation, + DiagnosticWithLocation, + EmitOnly, + EmitResult, + Path, + Program, + ProjectReference, SourceFile, - sourceFileMayBeEmitted, SourceMapEmitResult, - toPath, - tryAddToSet, WriteFileCallback, WriteFileCallbackData, -} from "./_namespaces/ts"; +} from "./types"; +import { + compilerOptionsAffectDeclarationPath, + compilerOptionsAffectEmit, + compilerOptionsAffectSemanticDiagnostics, + forEachEntry, + forEachKey, + getEmitDeclarations, + isJsonSourceFile, + outFile, + skipTypeChecking, + sourceFileMayBeEmitted, +} from "./utilities"; +import { ReadBuildProgramHost } from "./watchPublic"; /** @internal */ export interface ReusableDiagnostic extends ReusableDiagnosticRelatedInformation { @@ -452,7 +465,7 @@ function convertToDiagnostics(diagnostics: readonly ReusableDiagnostic[], newPro let buildInfoDirectory: string | undefined; let getCanonicalFileName: GetCanonicalFileName | undefined; return diagnostics.map(diagnostic => { - const result: Diagnostic = convertToDiagnosticRelatedInformation(diagnostic, newProgram, toPath); + const result: Diagnostic = convertToDiagnosticRelatedInformation(diagnostic, newProgram, toPathHelper); result.reportsUnnecessary = diagnostic.reportsUnnecessary; result.reportsDeprecated = diagnostic.reportDeprecated; result.source = diagnostic.source; @@ -460,15 +473,15 @@ function convertToDiagnostics(diagnostics: readonly ReusableDiagnostic[], newPro const { relatedInformation } = diagnostic; result.relatedInformation = relatedInformation ? relatedInformation.length ? - relatedInformation.map(r => convertToDiagnosticRelatedInformation(r, newProgram, toPath)) : + relatedInformation.map(r => convertToDiagnosticRelatedInformation(r, newProgram, toPathHelper)) : [] : undefined; return result; }); - function toPath(path: string) { + function toPathHelper(path: string) { buildInfoDirectory ??= getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(newProgram.getCompilerOptions())!, newProgram.getCurrentDirectory())); - return ts.toPath(path, buildInfoDirectory, getCanonicalFileName ??= createGetCanonicalFileName(newProgram.useCaseSensitiveFileNames())); + return toPath(path, buildInfoDirectory, getCanonicalFileName ??= createGetCanonicalFileName(newProgram.useCaseSensitiveFileNames())); } } @@ -1664,7 +1677,7 @@ export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo, const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames()); let state: ReusableBuilderProgramState; - const filePaths = program.fileNames?.map(toPath); + const filePaths = program.fileNames?.map(toPathHelper); let filePathsSetList: Set[] | undefined; const latestChangedDtsFile = program.latestChangedDtsFile ? toAbsolutePath(program.latestChangedDtsFile) : undefined; if (isProgramBundleEmitBuildInfo(program)) { @@ -1744,8 +1757,8 @@ export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo, hasChangedEmitSignature: returnFalse, }; - function toPath(path: string) { - return ts.toPath(path, buildInfoDirectory, getCanonicalFileName); + function toPathHelper(path: string) { + return toPath(path, buildInfoDirectory, getCanonicalFileName); } function toAbsolutePath(path: string) { diff --git a/src/compiler/builderPublic.ts b/src/compiler/builderPublic.ts index e664960e4d59e..54344a054c830 100644 --- a/src/compiler/builderPublic.ts +++ b/src/compiler/builderPublic.ts @@ -1,22 +1,24 @@ import { BuilderProgramKind, + createBuilderProgram, + createRedirectedBuilderProgram, + getBuilderCreationParameters, + ReusableBuilderProgramState, + SavedBuildProgramEmitState, +} from "./builder"; +import { CancellationToken, CompilerHost, CompilerOptions, - createBuilderProgram, - createRedirectedBuilderProgram, CustomTransformers, Diagnostic, DiagnosticWithLocation, EmitResult, - getBuilderCreationParameters, Program, ProjectReference, - ReusableBuilderProgramState, - SavedBuildProgramEmitState, SourceFile, WriteFileCallback, -} from "./_namespaces/ts"; +} from "./types"; export type AffectedFileResult = { result: T; affected: SourceFile | Program; } | undefined; diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts index 8ae0d6295ca8d..748fd68d95445 100644 --- a/src/compiler/builderState.ts +++ b/src/compiler/builderState.ts @@ -1,39 +1,47 @@ +import { computeSignatureWithDiagnostics } from "./builder"; +import { HostForComputeHash } from "./builderPublic"; +import { + EmitOutput, + OutputFile, +} from "./builderStatePublic"; import { arrayFrom, - CancellationToken, - computeSignatureWithDiagnostics, createGetCanonicalFileName, - CustomTransformers, - Debug, - EmitOutput, emptyArray, - ExportedModulesFromDeclarationEmit, GetCanonicalFileName, - getDirectoryPath, - getSourceFileOfNode, - HostForComputeHash, - isDeclarationFileName, - isExternalOrCommonJsModule, - isGlobalScopeAugmentation, - isJsonSourceFile, - isModuleWithStringLiteralName, - isStringLiteral, mapDefined, mapDefinedIterator, + some, +} from "./core"; +import { Debug } from "./debug"; +import { isStringLiteral } from "./factory/nodeTests"; +import { isDeclarationFileName } from "./parser"; +import { + getDirectoryPath, + toPath, +} from "./path"; +import { + CancellationToken, + CustomTransformers, + ExportedModulesFromDeclarationEmit, ModuleDeclaration, ModuleKind, - outFile, - OutputFile, Path, Program, ResolutionMode, - some, SourceFile, StringLiteralLike, Symbol, - toPath, TypeChecker, -} from "./_namespaces/ts"; +} from "./types"; +import { + getSourceFileOfNode, + isExternalOrCommonJsModule, + isGlobalScopeAugmentation, + isJsonSourceFile, + isModuleWithStringLiteralName, + outFile, +} from "./utilities"; /** @internal */ export function getFileEmitOutput(program: Program, sourceFile: SourceFile, emitOnlyDtsFiles: boolean, diff --git a/src/compiler/builderStatePublic.ts b/src/compiler/builderStatePublic.ts index 17ffc222e30d1..677b62d2b01fc 100644 --- a/src/compiler/builderStatePublic.ts +++ b/src/compiler/builderStatePublic.ts @@ -1,7 +1,7 @@ import { Diagnostic, WriteFileCallbackData, -} from "./_namespaces/ts"; +} from "./types"; export interface EmitOutput { outputFiles: OutputFile[]; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6007f615da62b..3264221149aba 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1,695 +1,429 @@ -import * as ts from "./_namespaces/ts"; import { - __String, - AccessExpression, - AccessFlags, - AccessorDeclaration, + bindSourceFile, + getModuleInstanceState, + ModuleInstanceState, +} from "./binder"; +import { + getNodeId, + getSymbolId, +} from "./checkerUtilities"; +import { addRange, - addRelatedInfo, - addSyntheticLeadingComment, - AllAccessorDeclarations, and, - AnonymousType, - AnyImportOrReExport, - AnyImportSyntax, append, appendIfUnique, - ArrayBindingPattern, arrayFrom, - arrayIsHomogeneous, - ArrayLiteralExpression, arrayOf, arraysEqual, arrayToMultiMap, - ArrayTypeNode, - ArrowFunction, - AssertionExpression, - AssignmentDeclarationKind, - AssignmentKind, - AssignmentPattern, - AwaitExpression, - BaseType, - BigIntLiteral, - BigIntLiteralType, - BinaryExpression, - BinaryOperatorToken, binarySearch, - BindableObjectDefinePropertyCall, - BindingElement, - BindingElementGrandparent, - BindingName, - BindingPattern, - bindSourceFile, - Block, - BreakOrContinueStatement, - CallChain, - CallExpression, - CallLikeExpression, - CallSignatureDeclaration, - CancellationToken, - canHaveDecorators, - canHaveExportModifier, - canHaveIllegalDecorators, - canHaveIllegalModifiers, - canHaveModifiers, cartesianProduct, - CaseBlock, - CaseClause, - CaseOrDefaultClause, cast, - chainDiagnosticMessages, - CharacterCodes, - CheckFlags, - ClassDeclaration, - ClassElement, - ClassExpression, - ClassLikeDeclaration, - ClassStaticBlockDeclaration, clear, - combinePaths, - compareDiagnostics, - comparePaths, compareValues, - Comparison, - CompilerOptions, - ComputedPropertyName, concatenate, - concatenateDiagnosticMessageChains, - ConditionalExpression, - ConditionalRoot, - ConditionalType, - ConditionalTypeNode, - ConstructorDeclaration, - ConstructorTypeNode, - ConstructSignatureDeclaration, contains, - containsParseError, - ContextFlags, - copyEntries, countWhere, - createBinaryExpressionTrampoline, - createCompilerDiagnostic, - createDiagnosticCollection, - createDiagnosticForFileFromMessageChain, - createDiagnosticForNode, - createDiagnosticForNodeArray, - createDiagnosticForNodeFromMessageChain, - createDiagnosticMessageChainFromDiagnostic, - createEmptyExports, - createFileDiagnostic, createGetCanonicalFileName, - createGetSymbolWalker, - createPrinter, - createPropertyNameNodeForIdentifierOrLiteral, - createScanner, - createSymbolTable, - createTextWriter, createUnderscoreEscapedMultiMap, - Debug, - Declaration, - DeclarationName, - declarationNameToString, - DeclarationStatement, - DeclarationWithTypeParameterChildren, - DeclarationWithTypeParameters, - Decorator, deduplicate, - DefaultClause, - defaultMaximumTruncationLength, - DeferredTypeReference, - DeleteExpression, - Diagnostic, - DiagnosticCategory, - DiagnosticMessage, - DiagnosticMessageChain, - DiagnosticRelatedInformation, - Diagnostics, - DiagnosticWithLocation, - DoStatement, - DynamicNamedDeclaration, - ElementAccessChain, - ElementAccessExpression, - ElementFlags, - EmitFlags, - EmitHint, - EmitResolver, - EmitTextWriter, emptyArray, endsWith, - EntityName, - EntityNameExpression, - EntityNameOrEntityNameExpression, - entityNameToString, - EnumDeclaration, - EnumMember, equateValues, - escapeLeadingUnderscores, - escapeString, every, - EvolvingArrayType, - ExclamationToken, - ExportAssignment, - exportAssignmentIsAlias, - ExportDeclaration, - ExportSpecifier, - Expression, - expressionResultIsUnused, - ExpressionStatement, - ExpressionWithTypeArguments, - Extension, - ExternalEmitHelpers, - externalHelpersModuleNameText, - factory, - fileExtensionIs, - fileExtensionIsOneOf, filter, find, - findAncestor, findBestPatternMatch, findIndex, findLast, findLastIndex, - findUseStrictPrologue, first, firstDefined, firstOrUndefined, flatMap, flatten, - FlowArrayMutation, - FlowAssignment, - FlowCall, - FlowCondition, - FlowFlags, - FlowLabel, - FlowNode, - FlowReduceLabel, - FlowStart, - FlowSwitchClause, - FlowType, forEach, - forEachChild, - forEachChildRecursively, - forEachEnclosingBlockScopeContainer, - forEachEntry, - forEachImportClauseDeclaration, - forEachKey, - forEachReturnStatement, - forEachYieldExpression, - ForInOrOfStatement, - ForInStatement, - formatMessage, - ForOfStatement, - ForStatement, - FreshableIntrinsicType, - FreshableType, - FreshObjectLiteralType, - FunctionDeclaration, - FunctionExpression, - FunctionFlags, - FunctionLikeDeclaration, - FunctionTypeNode, - GenericType, - GetAccessorDeclaration, - getAliasDeclarationFromName, - getAllAccessorDeclarations, - getAllowSyntheticDefaultImports, - getAncestor, - getAssignedExpandoInitializer, - getAssignmentDeclarationKind, - getAssignmentDeclarationPropertyAccessKind, - getAssignmentTargetKind, - getCheckFlags, - getClassExtendsHeritageElement, - getClassLikeDeclarationOfSymbol, - getCombinedLocalAndExportSymbolFlags, - getCombinedModifierFlags, - getCombinedNodeFlags, - getContainingClass, - getContainingFunction, - getContainingFunctionOrClassStaticBlock, - getDeclarationModifierFlagsFromSymbol, - getDeclarationOfKind, - getDeclarationsOfKind, - getDeclaredExpandoInitializer, - getDirectoryPath, - getEffectiveBaseTypeNode, - getEffectiveConstraintOfTypeParameter, - getEffectiveContainerForJSDocTemplateTag, - getEffectiveImplementsTypeNodes, - getEffectiveInitializer, - getEffectiveJSDocHost, - getEffectiveModifierFlags, - getEffectiveReturnTypeNode, - getEffectiveSetAccessorTypeAnnotationNode, - getEffectiveTypeAnnotationNode, - getEffectiveTypeParameterDeclarations, - getElementOrPropertyAccessName, - getEmitDeclarations, - getEmitModuleKind, - getEmitModuleResolutionKind, - getEmitScriptTarget, - getEnclosingBlockScopeContainer, - getEntityNameFromTypeNode, getEntries, - getErrorSpanForNode, - getEscapedTextOfIdentifierOrLiteral, - getESModuleInterop, - getExpandoInitializer, - getExportAssignmentExpression, - getExternalModuleImportEqualsDeclarationExpression, - getExternalModuleName, - getExternalModuleRequireArgument, - getFirstConstructorWithBody, - getFirstIdentifier, - getFunctionFlags, - getHostSignatureFromJSDoc, - getImmediatelyInvokedFunctionExpression, - getInitializerOfBinaryExpression, - getInterfaceBaseTypeNodes, - getInvokedExpression, - getJSDocClassTag, - getJSDocDeprecatedTag, - getJSDocEnumTag, - getJSDocHost, - getJSDocParameterTags, - getJSDocRoot, - getJSDocTags, - getJSDocThisTag, - getJSDocType, - getJSDocTypeAssertionType, - getJSDocTypeParameterDeclarations, - getJSDocTypeTag, - getJSXImplicitImportBase, - getJSXRuntimeImport, - getJSXTransformEnabled, - getLeftmostAccessExpression, - getLineAndCharacterOfPosition, - getLocalSymbolForExportDefault, - getMembersOfDeclaration, - getModeForUsageLocation, - getModifiers, - getModuleInstanceState, - getNameFromIndexInfo, - getNameOfDeclaration, - getNameOfExpando, - getNamespaceDeclarationNode, - getNewTargetContainer, - getNonAugmentationDeclaration, - getNormalizedAbsolutePath, - getObjectFlags, - getOriginalNode, getOrUpdate, getOwnKeys, - getParameterSymbolFromJSDoc, - getParseTreeNode, - getPropertyAssignmentAliasLikeExpression, - getPropertyNameForPropertyNameNode, - getResolutionDiagnostic, - getResolutionModeOverrideForClause, - getResolvedExternalModuleName, - getResolvedModule, - getRestParameterElementType, - getRootDeclaration, - getScriptTargetFeatures, - getSelectedEffectiveModifierFlags, - getSemanticJsxChildren, - getSetAccessorValueParameter, - getSingleVariableOfVariableStatement, - getSourceFileOfModule, - getSourceFileOfNode, - getSpanOfTokenAtPosition, getSpellingSuggestion, - getStrictOptionValue, - getSuperContainer, - getSymbolNameForPrivateIdentifier, - getTextOfIdentifierOrLiteral, - getTextOfJSDocComment, - getTextOfNode, - getTextOfPropertyName, - getThisContainer, - getThisParameter, - getTrailingSemicolonDeferringWriter, - getTypeParameterFromJsDoc, - getTypesPackageName, - getUseDefineForClassFields, group, - hasAbstractModifier, - hasAccessorModifier, - hasAmbientModifier, - hasContextSensitiveParameters, - hasDecorators, - HasDecorators, - hasDynamicName, - hasEffectiveModifier, - hasEffectiveModifiers, - hasEffectiveReadonlyModifier, - HasExpressionInitializer, - hasExtension, - HasIllegalDecorators, - HasIllegalModifiers, - hasInitializer, - HasInitializer, - hasJSDocNodes, - hasJSDocParameterTags, - hasJsonModuleEmitEnabled, - HasModifiers, - hasOnlyExpressionInitializer, - hasOverrideModifier, - hasPossibleExternalModuleReference, - hasQuestionToken, - hasRestParameter, - hasScopeMarker, - hasStaticModifier, - hasSyntacticModifier, - hasSyntacticModifiers, - HeritageClause, - Identifier, - IdentifierTypePredicate, - idText, - IfStatement, - ImportCall, - ImportClause, - ImportDeclaration, - ImportEqualsDeclaration, - ImportOrExportSpecifier, - ImportsNotUsedAsValues, - ImportSpecifier, - ImportTypeAssertionContainer, - ImportTypeNode, - IncompleteType, - IndexedAccessType, - IndexedAccessTypeNode, - IndexInfo, - IndexKind, - indexOfNode, - IndexSignatureDeclaration, - IndexType, indicesOf, - InferenceContext, - InferenceFlags, - InferenceInfo, - InferencePriority, - InferTypeNode, - InstantiableType, - InstantiationExpressionType, - InterfaceDeclaration, - InterfaceType, - InterfaceTypeWithDeclaredMembers, - InternalSymbolName, - IntersectionType, - IntersectionTypeNode, - IntrinsicType, - introducesArgumentsExoticObject, - isAccessExpression, - isAccessor, - isAliasableExpression, - isAmbientModule, isArray, + isLineBreak, + isString, + last, + lastOrUndefined, + length, + map, + mapDefined, + maybeBind, + memoize, + not, + or, + orderedRemoveItemAt, + pushIfUnique, + rangeEquals, + reduceLeft, + relativeComplement, + removePrefix, + replaceElement, + sameMap, + singleElementArray, + some, + startsWith, + stringContains, + sum, + tryAddToSet, + tryCast, +} from "./core"; +import { Comparison } from "./corePublic"; +import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { createPrinter } from "./emitter"; +import { + createBinaryExpressionTrampoline, +} from "./factory/binaryExpressionStateMachine"; +import { + addSyntheticLeadingComment, + setCommentRange, + setEmitFlags, + setSyntheticLeadingComments, +} from "./factory/emitNode"; +import { factory } from "./factory/nodeFactory"; +import { isArrayBindingPattern, isArrayLiteralExpression, isArrowFunction, - isAssertionExpression, - isAssignmentDeclaration, - isAssignmentExpression, - isAssignmentOperator, - isAssignmentPattern, - isAssignmentTarget, - isAsyncFunction, - isAutoAccessorPropertyDeclaration, isBinaryExpression, - isBindableObjectDefinePropertyCall, - isBindableStaticElementAccessExpression, - isBindableStaticNameExpression, isBindingElement, - isBindingPattern, isBlock, - isBlockOrCatchScoped, - isBlockScopedContainerTopLevel, - isCallChain, isCallExpression, - isCallLikeExpression, - isCallOrNewExpression, isCallSignatureDeclaration, isCatchClause, - isCatchClauseVariableDeclarationOrBindingElement, - isCheckJsEnabledForFile, - isChildOfNodeWithKind, isClassDeclaration, - isClassElement, isClassExpression, - isClassLike, isClassStaticBlockDeclaration, - isCommaSequence, - isCommonJsExportedExpression, - isCommonJsExportPropertyAssignment, - isComputedNonLiteralName, isComputedPropertyName, isConstructorDeclaration, isConstructorTypeNode, - isConstTypeReference, - isDeclaration, - isDeclarationName, - isDeclarationReadonly, isDecorator, - isDefaultedExpandoInitializer, - isDeleteTarget, - isDottedName, - isDynamicName, - isEffectiveExternalModule, isElementAccessExpression, - isEntityName, - isEntityNameExpression, - isEnumConst, isEnumDeclaration, isEnumMember, - isExclusivelyTypeOnlyImportOrExport, isExportAssignment, isExportDeclaration, - isExportsIdentifier, isExportSpecifier, - isExpression, - isExpressionNode, - isExpressionOfOptionalChainRoot, isExpressionStatement, isExpressionWithTypeArguments, - isExpressionWithTypeArgumentsInClassExtendsClause, - isExternalModule, - isExternalModuleAugmentation, - isExternalModuleImportEqualsDeclaration, - isExternalModuleIndicator, - isExternalModuleNameRelative, isExternalModuleReference, - isExternalOrCommonJsModule, - isForInOrOfStatement, isForInStatement, isForOfStatement, isForStatement, isFunctionDeclaration, isFunctionExpression, - isFunctionExpressionOrArrowFunction, - isFunctionLike, - isFunctionLikeDeclaration, - isFunctionLikeOrClassStaticBlockDeclaration, - isFunctionOrModuleBlock, isFunctionTypeNode, - isGeneratedIdentifier, - isGetAccessor, isGetAccessorDeclaration, - isGetOrSetAccessorDeclaration, - isGlobalScopeAugmentation, isHeritageClause, isIdentifier, - isIdentifierStart, - isIdentifierText, - isIdentifierTypePredicate, - isIdentifierTypeReference, isIfStatement, - isImportCall, isImportClause, isImportDeclaration, isImportEqualsDeclaration, isImportKeyword, - isImportOrExportSpecifier, isImportSpecifier, isImportTypeNode, isIndexedAccessTypeNode, - isInExpressionContext, - isInfinityOrNaNString, - isInJSDoc, - isInJSFile, - isInJsonFile, isInterfaceDeclaration, - isInternalModuleImportEqualsDeclaration, - isInTopLevelContext, - isIntrinsicJsxName, - isIterationStatement, isJSDocAllType, isJSDocAugmentsTag, isJSDocCallbackTag, - isJSDocConstructSignature, isJSDocFunctionType, - isJSDocIndexSignature, - isJSDocLinkLike, isJSDocMemberName, isJSDocNameReference, - isJSDocNode, isJSDocNonNullableType, isJSDocNullableType, isJSDocOptionalType, isJSDocParameterTag, - isJSDocPropertyLikeTag, isJSDocReturnTag, isJSDocSignature, isJSDocTemplateTag, - isJSDocTypeAlias, - isJSDocTypeAssertion, isJSDocTypedefTag, isJSDocTypeExpression, isJSDocTypeLiteral, isJSDocTypeTag, isJSDocUnknownType, isJSDocVariadicType, - isJsonSourceFile, isJsxAttribute, - isJsxAttributeLike, isJsxAttributes, isJsxElement, isJsxOpeningElement, isJsxOpeningFragment, - isJsxOpeningLikeElement, isJsxSelfClosingElement, isJsxSpreadAttribute, - isJSXTagName, - isKnownSymbol, - isLateVisibilityPaintedStatement, - isLeftHandSideExpression, - isLet, - isLineBreak, - isLiteralComputedPropertyDeclarationName, - isLiteralExpressionOfObject, - isLiteralImportTypeNode, isLiteralTypeNode, isMetaProperty, isMethodDeclaration, isMethodSignature, - isModifier, isModuleBlock, isModuleDeclaration, - isModuleExportsAccessExpression, - isModuleIdentifier, - isModuleOrEnumDeclaration, - isModuleWithStringLiteralName, - isNamedDeclaration, isNamedExports, isNamedTupleMember, isNamespaceExport, isNamespaceExportDeclaration, - isNamespaceReexportDeclaration, isNewExpression, - isNightly, - isNodeDescendantOf, - isNullishCoalesce, isNumericLiteral, - isNumericLiteralName, isObjectBindingPattern, - isObjectLiteralElementLike, isObjectLiteralExpression, - isObjectLiteralMethod, - isObjectLiteralOrClassExpressionMethodOrAccessor, isOmittedExpression, - isOptionalChain, - isOptionalChainRoot, - isOptionalJSDocPropertyLikeTag, isOptionalTypeNode, - isOutermostOptionalChain, isParameter, - isParameterDeclaration, - isParameterOrCatchClauseVariable, - isParameterPropertyDeclaration, isParenthesizedExpression, isParenthesizedTypeNode, - isPartOfTypeNode, - isPartOfTypeQuery, - isPlainJsFile, isPrefixUnaryExpression, isPrivateIdentifier, - isPrivateIdentifierClassElementDeclaration, - isPrivateIdentifierPropertyAccessExpression, - isPropertyAccessEntityNameExpression, isPropertyAccessExpression, - isPropertyAccessOrQualifiedNameOrImportTypeNode, isPropertyAssignment, isPropertyDeclaration, - isPropertyName, - isPropertyNameLiteral, isPropertySignature, - isPrototypeAccess, - isPrototypePropertyAssignment, - isPushOrUnshiftIdentifier, isQualifiedName, - isRequireCall, - isRestParameter, isRestTypeNode, - isRightSideOfQualifiedNameOrPropertyAccess, - isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName, - isSameEntityName, - isSetAccessor, - isShorthandAmbientModuleSymbol, isShorthandPropertyAssignment, - isSingleOrDoubleQuote, isSourceFile, - isSourceFileJS, isSpreadAssignment, isSpreadElement, - isStatement, - isStatementWithLocals, - isStatic, - isString, - isStringANonContextualKeyword, isStringLiteral, - isStringLiteralLike, - isStringOrNumericLiteralLike, - isSuperCall, - isSuperProperty, isTaggedTemplateExpression, isTemplateSpan, - isThisContainerOrFunctionBlock, - isThisIdentifier, - isThisInitializedDeclaration, - isThisInitializedObjectBindingExpression, - isThisInTypeQuery, - isThisProperty, - isThisTypeParameter, - isTransientSymbol, isTupleTypeNode, - isTypeAlias, isTypeAliasDeclaration, - isTypeDeclaration, isTypeLiteralNode, - isTypeNode, - isTypeNodeKind, isTypeOfExpression, - isTypeOnlyImportOrExportDeclaration, isTypeOperatorNode, isTypeParameterDeclaration, isTypePredicateNode, isTypeQueryNode, isTypeReferenceNode, - isTypeReferenceType, - isUMDExportSymbol, - isValidESSymbolDeclaration, - isValidTypeOnlyAliasUseSite, - isValueSignatureDeclaration, - isVarConst, isVariableDeclaration, - isVariableDeclarationInitializedToBareOrAccessedRequire, - isVariableDeclarationInVariableStatement, isVariableDeclarationList, - isVariableLike, - isVariableLikeOrAccessor, isVariableStatement, - isWriteAccess, - isWriteOnlyAccess, +} from "./factory/nodeTests"; +import { + canHaveIllegalModifiers, + createEmptyExports, + getJSDocTypeAssertionType, + isCommaSequence, +} from "./factory/utilities"; +import { + canHaveDecorators, + canHaveModifiers, + setOriginalNode, + setTextRange, +} from "./factory/utilitiesPublic"; +import { + getTypesPackageName, + mangleScopedPackageName, +} from "./moduleNameResolver"; +import { + countPathComponents, + getModuleSpecifiers, +} from "./moduleSpecifiers"; +import { + forEachChild, + forEachChildRecursively, + isExternalModule, + parseIsolatedEntityName, + parseNodeFactory, +} from "./parser"; +import { + combinePaths, + comparePaths, + fileExtensionIs, + fileExtensionIsOneOf, + getDirectoryPath, + getNormalizedAbsolutePath, + hasExtension, + pathIsRelative, +} from "./path"; +import * as performance from "./performance"; +import { + getModeForUsageLocation, + getResolutionDiagnostic, + getResolutionModeOverrideForClause, + isExclusivelyTypeOnlyImportOrExport, + resolveTripleslashReference, +} from "./program"; +import { + createScanner, + getLineAndCharacterOfPosition, + isIdentifierStart, + isIdentifierText, + skipTrivia, + tokenToString, +} from "./scanner"; +import { createGetSymbolWalker } from "./symbolWalker"; +import { + tracing, + TracingNode, +} from "./tracing"; +import { nullTransformationContext } from "./transformer"; +import { + __String, + AccessExpression, + AccessFlags, + AccessorDeclaration, + AllAccessorDeclarations, + AnonymousType, + AnyImportOrReExport, + AnyImportSyntax, + ArrayBindingPattern, + ArrayLiteralExpression, + ArrayTypeNode, + ArrowFunction, + AssertionExpression, + AssignmentDeclarationKind, + AssignmentPattern, + AwaitExpression, + BaseType, + BigIntLiteral, + BigIntLiteralType, + BinaryExpression, + BinaryOperatorToken, + BindableObjectDefinePropertyCall, + BindingElement, + BindingElementGrandparent, + BindingName, + BindingPattern, + Block, + BreakOrContinueStatement, + CallChain, + CallExpression, + CallLikeExpression, + CallSignatureDeclaration, + CancellationToken, + CaseBlock, + CaseClause, + CaseOrDefaultClause, + CharacterCodes, + CheckFlags, + ClassDeclaration, + ClassElement, + ClassExpression, + ClassLikeDeclaration, + ClassStaticBlockDeclaration, + CompilerOptions, + ComputedPropertyName, + ConditionalExpression, + ConditionalRoot, + ConditionalType, + ConditionalTypeNode, + ConstructorDeclaration, + ConstructorTypeNode, + ConstructSignatureDeclaration, + ContextFlags, + Declaration, + DeclarationName, + DeclarationStatement, + DeclarationWithTypeParameterChildren, + DeclarationWithTypeParameters, + Decorator, + DefaultClause, + DeferredTypeReference, + DeleteExpression, + Diagnostic, + DiagnosticCategory, + DiagnosticMessage, + DiagnosticMessageChain, + DiagnosticRelatedInformation, + DiagnosticWithLocation, + DoStatement, + DynamicNamedDeclaration, + ElementAccessChain, + ElementAccessExpression, + ElementFlags, + EmitFlags, + EmitHint, + EmitResolver, + EmitTextWriter, + EntityName, + EntityNameExpression, + EntityNameOrEntityNameExpression, + EnumDeclaration, + EnumMember, + EvolvingArrayType, + ExclamationToken, + ExportAssignment, + ExportDeclaration, + ExportSpecifier, + Expression, + ExpressionStatement, + ExpressionWithTypeArguments, + Extension, + ExternalEmitHelpers, + FlowArrayMutation, + FlowAssignment, + FlowCall, + FlowCondition, + FlowFlags, + FlowLabel, + FlowNode, + FlowReduceLabel, + FlowStart, + FlowSwitchClause, + FlowType, + ForInOrOfStatement, + ForInStatement, + ForOfStatement, + ForStatement, + FreshableIntrinsicType, + FreshableType, + FreshObjectLiteralType, + FunctionDeclaration, + FunctionExpression, + FunctionLikeDeclaration, + FunctionTypeNode, + GenericType, + GetAccessorDeclaration, + HasDecorators, + HasExpressionInitializer, + HasIllegalDecorators, + HasIllegalModifiers, + HasInitializer, + HasModifiers, + HeritageClause, + Identifier, + IdentifierTypePredicate, + IfStatement, + ImportCall, + ImportClause, + ImportDeclaration, + ImportEqualsDeclaration, + ImportOrExportSpecifier, + ImportsNotUsedAsValues, + ImportSpecifier, + ImportTypeAssertionContainer, + ImportTypeNode, + IncompleteType, + IndexedAccessType, + IndexedAccessTypeNode, + IndexInfo, + IndexKind, + IndexSignatureDeclaration, + IndexType, + InferenceContext, + InferenceFlags, + InferenceInfo, + InferencePriority, + InferTypeNode, + InstantiableType, + InstantiationExpressionType, + InterfaceDeclaration, + InterfaceType, + InterfaceTypeWithDeclaredMembers, + InternalSymbolName, + IntersectionType, + IntersectionTypeNode, + IntrinsicType, IterableOrIteratorType, IterationTypes, JSDoc, @@ -738,40 +472,28 @@ import { JsxTagNameExpression, KeywordTypeNode, LabeledStatement, - last, - lastOrUndefined, LateBoundBinaryExpressionDeclaration, LateBoundDeclaration, LateBoundName, LateVisibilityPaintedStatement, LeftHandSideExpression, - length, LiteralExpression, LiteralType, LiteralTypeNode, - mangleScopedPackageName, - map, - mapDefined, MappedSymbol, MappedType, MappedTypeNode, MatchingKeys, - maybeBind, MemberName, MemberOverrideStatus, - memoize, MetaProperty, MethodDeclaration, MethodSignature, - minAndMax, MinusToken, Modifier, ModifierFlags, - modifiersToFlags, - modifierToFlag, ModuleBlock, ModuleDeclaration, - ModuleInstanceState, ModuleKind, ModuleResolutionKind, NamedDeclaration, @@ -782,30 +504,18 @@ import { NamespaceExport, NamespaceExportDeclaration, NamespaceImport, - needsScopeMarker, NewExpression, Node, NodeArray, NodeBuilderFlags, - nodeCanBeDecorated, NodeCheckFlags, NodeFlags, - nodeHasName, - nodeIsDecorated, - nodeIsMissing, - nodeIsPresent, - nodeIsSynthesized, NodeLinks, - nodeStartsNewLexicalEnvironment, NodeWithTypeArguments, NonNullChain, NonNullExpression, - not, - noTruncationMaximumTruncationLength, - nullTransformationContext, NumberLiteralType, NumericLiteral, - objectAllocator, ObjectBindingPattern, ObjectFlags, ObjectFlagsType, @@ -814,20 +524,11 @@ import { ObjectType, OptionalChain, OptionalTypeNode, - or, - orderedRemoveItemAt, OuterExpressionKinds, - outFile, ParameterDeclaration, - parameterIsThisKeyword, - ParameterPropertyDeclaration, ParenthesizedExpression, ParenthesizedTypeNode, - parseIsolatedEntityName, - parseNodeFactory, - parsePseudoBigInt, Path, - pathIsRelative, PatternAmbientModule, PlusToken, PostfixUnaryExpression, @@ -843,70 +544,36 @@ import { PropertyName, PropertySignature, PseudoBigInt, - pseudoBigIntToString, - pushIfUnique, QualifiedName, QuestionToken, - rangeEquals, - rangeOfNode, - rangeOfTypeParameters, ReadonlyKeyword, - reduceLeft, RelationComparisonResult, - relativeComplement, - removeExtension, - removePrefix, - replaceElement, - resolutionExtensionIsTSOrJson, ResolutionMode, ResolvedModuleFull, ResolvedType, - resolveTripleslashReference, - resolvingEmptyArray, RestTypeNode, ReturnStatement, ReverseMappedSymbol, ReverseMappedType, - sameMap, SatisfiesExpression, ScriptKind, ScriptTarget, SetAccessorDeclaration, - setCommentRange, - setEmitFlags, - setNodeFlags, - setOriginalNode, - setParent, - setSyntheticLeadingComments, - setTextRange, - setTextRangePosEnd, - setValueDeclaration, ShorthandPropertyAssignment, - shouldPreserveConstEnums, Signature, SignatureDeclaration, SignatureFlags, SignatureKind, - singleElementArray, - skipOuterExpressions, - skipParentheses, - skipTrivia, - skipTypeChecking, - some, SourceFile, SpreadAssignment, SpreadElement, - startsWith, Statement, - stringContains, StringLiteral, StringLiteralLike, StringLiteralType, StringMappingType, - stripQuotes, StructuredType, SubstitutionType, - sum, SuperCall, SwitchStatement, Symbol, @@ -916,7 +583,6 @@ import { SymbolFormatFlags, SymbolId, SymbolLinks, - symbolName, SymbolTable, SymbolTracker, SymbolVisibilityResult, @@ -928,25 +594,12 @@ import { TemplateLiteralType, TemplateLiteralTypeNode, Ternary, - textRangeContainsPositionInclusive, TextSpan, - textSpanContainsPosition, - textSpanEnd, ThisExpression, ThisTypeNode, ThrowStatement, TokenFlags, - tokenToString, - tracing, - TracingNode, TransientSymbol, - tryAddToSet, - tryCast, - tryExtractTSExtension, - tryGetClassImplementingOrExtendingExpressionWithTypeArguments, - tryGetExtensionFromPath, - tryGetModuleSpecifierFromDeclaration, - tryGetPropertyAccessOrIdentifierToString, TryStatement, TupleType, TupleTypeNode, @@ -983,42 +636,428 @@ import { TypeVariable, UnaryExpression, UnderscoreEscapedMap, - unescapeLeadingUnderscores, UnionOrIntersectionType, UnionOrIntersectionTypeNode, UnionReduction, UnionType, UnionTypeNode, UniqueESSymbolType, - usingSingleLineStringWriter, VariableDeclaration, VariableDeclarationList, VariableLikeDeclaration, VariableStatement, VarianceFlags, - visitEachChild, - visitNode, - visitNodes, Visitor, VisitResult, VoidExpression, - walkUpBindingElementsAndPatterns, - walkUpParenthesizedExpressions, - walkUpParenthesizedTypes, - walkUpParenthesizedTypesAndGetParentAndChild, WhileStatement, WideningContext, WithStatement, YieldExpression, -} from "./_namespaces/ts"; -import * as performance from "./_namespaces/ts.performance"; -import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers"; +} from "./types"; +import { + addRelatedInfo, + arrayIsHomogeneous, + AssignmentKind, + canHaveExportModifier, + canHaveIllegalDecorators, + chainDiagnosticMessages, + compareDiagnostics, + concatenateDiagnosticMessageChains, + containsParseError, + copyEntries, + createCompilerDiagnostic, + createDiagnosticCollection, + createDiagnosticForFileFromMessageChain, + createDiagnosticForNode, + createDiagnosticForNodeArray, + createDiagnosticForNodeFromMessageChain, + createDiagnosticMessageChainFromDiagnostic, + createFileDiagnostic, + createPropertyNameNodeForIdentifierOrLiteral, + createSymbolTable, + createTextWriter, + declarationNameToString, + defaultMaximumTruncationLength, + entityNameToString, + escapeString, + exportAssignmentIsAlias, + expressionResultIsUnused, + externalHelpersModuleNameText, + findUseStrictPrologue, + forEachEnclosingBlockScopeContainer, + forEachEntry, + forEachImportClauseDeclaration, + forEachKey, + forEachReturnStatement, + forEachYieldExpression, + formatMessage, + FunctionFlags, + getAliasDeclarationFromName, + getAllAccessorDeclarations, + getAllowSyntheticDefaultImports, + getAncestor, + getAssignedExpandoInitializer, + getAssignmentDeclarationKind, + getAssignmentDeclarationPropertyAccessKind, + getAssignmentTargetKind, + getCheckFlags, + getClassExtendsHeritageElement, + getClassLikeDeclarationOfSymbol, + getCombinedLocalAndExportSymbolFlags, + getContainingClass, + getContainingFunction, + getContainingFunctionOrClassStaticBlock, + getDeclarationModifierFlagsFromSymbol, + getDeclarationOfKind, + getDeclarationsOfKind, + getDeclaredExpandoInitializer, + getEffectiveBaseTypeNode, + getEffectiveContainerForJSDocTemplateTag, + getEffectiveImplementsTypeNodes, + getEffectiveInitializer, + getEffectiveJSDocHost, + getEffectiveModifierFlags, + getEffectiveReturnTypeNode, + getEffectiveSetAccessorTypeAnnotationNode, + getEffectiveTypeAnnotationNode, + getElementOrPropertyAccessName, + getEmitDeclarations, + getEmitModuleKind, + getEmitModuleResolutionKind, + getEmitScriptTarget, + getEnclosingBlockScopeContainer, + getEntityNameFromTypeNode, + getErrorSpanForNode, + getEscapedTextOfIdentifierOrLiteral, + getESModuleInterop, + getExpandoInitializer, + getExportAssignmentExpression, + getExternalModuleImportEqualsDeclarationExpression, + getExternalModuleName, + getExternalModuleRequireArgument, + getFirstConstructorWithBody, + getFirstIdentifier, + getFunctionFlags, + getHostSignatureFromJSDoc, + getImmediatelyInvokedFunctionExpression, + getInitializerOfBinaryExpression, + getInterfaceBaseTypeNodes, + getInvokedExpression, + getJSDocHost, + getJSDocRoot, + getJSDocTypeParameterDeclarations, + getJSXImplicitImportBase, + getJSXRuntimeImport, + getJSXTransformEnabled, + getLeftmostAccessExpression, + getLocalSymbolForExportDefault, + getMembersOfDeclaration, + getNameFromIndexInfo, + getNameOfExpando, + getNamespaceDeclarationNode, + getNewTargetContainer, + getNonAugmentationDeclaration, + getObjectFlags, + getParameterSymbolFromJSDoc, + getPropertyAssignmentAliasLikeExpression, + getPropertyNameForPropertyNameNode, + getResolvedExternalModuleName, + getResolvedModule, + getRestParameterElementType, + getRootDeclaration, + getScriptTargetFeatures, + getSelectedEffectiveModifierFlags, + getSemanticJsxChildren, + getSetAccessorValueParameter, + getSingleVariableOfVariableStatement, + getSourceFileOfModule, + getSourceFileOfNode, + getSpanOfTokenAtPosition, + getStrictOptionValue, + getSuperContainer, + getSymbolNameForPrivateIdentifier, + getTextOfIdentifierOrLiteral, + getTextOfNode, + getTextOfPropertyName, + getThisContainer, + getThisParameter, + getTrailingSemicolonDeferringWriter, + getTypeParameterFromJsDoc, + getUseDefineForClassFields, + hasAbstractModifier, + hasAccessorModifier, + hasAmbientModifier, + hasContextSensitiveParameters, + hasDecorators, + hasDynamicName, + hasEffectiveModifier, + hasEffectiveModifiers, + hasEffectiveReadonlyModifier, + hasJsonModuleEmitEnabled, + hasOverrideModifier, + hasPossibleExternalModuleReference, + hasQuestionToken, + hasStaticModifier, + hasSyntacticModifier, + hasSyntacticModifiers, + indexOfNode, + introducesArgumentsExoticObject, + isAccessExpression, + isAliasableExpression, + isAmbientModule, + isAssignmentDeclaration, + isAssignmentExpression, + isAssignmentOperator, + isAssignmentTarget, + isAsyncFunction, + isBindableObjectDefinePropertyCall, + isBindableStaticElementAccessExpression, + isBindableStaticNameExpression, + isBlockOrCatchScoped, + isBlockScopedContainerTopLevel, + isCatchClauseVariableDeclarationOrBindingElement, + isCheckJsEnabledForFile, + isChildOfNodeWithKind, + isCommonJsExportedExpression, + isCommonJsExportPropertyAssignment, + isComputedNonLiteralName, + isDeclarationName, + isDeclarationReadonly, + isDefaultedExpandoInitializer, + isDeleteTarget, + isDottedName, + isDynamicName, + isEffectiveExternalModule, + isEntityNameExpression, + isEnumConst, + isExportsIdentifier, + isExpressionNode, + isExpressionWithTypeArgumentsInClassExtendsClause, + isExternalModuleAugmentation, + isExternalModuleImportEqualsDeclaration, + isExternalOrCommonJsModule, + isFunctionExpressionOrArrowFunction, + isGlobalScopeAugmentation, + isIdentifierTypePredicate, + isIdentifierTypeReference, + isImportCall, + isInExpressionContext, + isInfinityOrNaNString, + isInJSDoc, + isInJSFile, + isInJsonFile, + isInternalModuleImportEqualsDeclaration, + isInTopLevelContext, + isIntrinsicJsxName, + isJSDocConstructSignature, + isJSDocIndexSignature, + isJSDocTypeAlias, + isJSDocTypeAssertion, + isJsonSourceFile, + isJSXTagName, + isKnownSymbol, + isLateVisibilityPaintedStatement, + isLet, + isLiteralComputedPropertyDeclarationName, + isLiteralImportTypeNode, + isModuleExportsAccessExpression, + isModuleIdentifier, + isModuleWithStringLiteralName, + isNamespaceReexportDeclaration, + isNightly, + isNodeDescendantOf, + isNumericLiteralName, + isObjectLiteralMethod, + isObjectLiteralOrClassExpressionMethodOrAccessor, + isOptionalJSDocPropertyLikeTag, + isParameterDeclaration, + isParameterOrCatchClauseVariable, + isPartOfTypeNode, + isPartOfTypeQuery, + isPlainJsFile, + isPropertyAccessEntityNameExpression, + isPropertyNameLiteral, + isPrototypeAccess, + isPrototypePropertyAssignment, + isPushOrUnshiftIdentifier, + isRequireCall, + isRightSideOfQualifiedNameOrPropertyAccess, + isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName, + isSameEntityName, + isShorthandAmbientModuleSymbol, + isSingleOrDoubleQuote, + isSourceFileJS, + isStatementWithLocals, + isStatic, + isStringANonContextualKeyword, + isStringOrNumericLiteralLike, + isSuperCall, + isSuperProperty, + isThisContainerOrFunctionBlock, + isThisIdentifier, + isThisInitializedDeclaration, + isThisInitializedObjectBindingExpression, + isThisInTypeQuery, + isThisProperty, + isThisTypeParameter, + isTransientSymbol, + isTypeAlias, + isTypeDeclaration, + isTypeNodeKind, + isUMDExportSymbol, + isValidESSymbolDeclaration, + isValidTypeOnlyAliasUseSite, + isValueSignatureDeclaration, + isVarConst, + isVariableDeclarationInitializedToBareOrAccessedRequire, + isVariableDeclarationInVariableStatement, + isVariableLike, + isVariableLikeOrAccessor, + isWriteAccess, + isWriteOnlyAccess, + minAndMax, + modifiersToFlags, + modifierToFlag, + nodeCanBeDecorated, + nodeIsDecorated, + nodeIsMissing, + nodeIsPresent, + nodeIsSynthesized, + nodeStartsNewLexicalEnvironment, + noTruncationMaximumTruncationLength, + objectAllocator, + outFile, + parameterIsThisKeyword, + parsePseudoBigInt, + pseudoBigIntToString, + rangeOfNode, + rangeOfTypeParameters, + removeExtension, + resolutionExtensionIsTSOrJson, + resolvingEmptyArray, + setNodeFlags, + setParent, + setTextRangePosEnd, + setValueDeclaration, + shouldPreserveConstEnums, + signatureHasLiteralTypes, + signatureHasRestParameter, + skipOuterExpressions, + skipParentheses, + skipTypeChecking, + stripQuotes, + tryExtractTSExtension, + tryGetClassImplementingOrExtendingExpressionWithTypeArguments, + tryGetExtensionFromPath, + tryGetModuleSpecifierFromDeclaration, + tryGetPropertyAccessOrIdentifierToString, + usingSingleLineStringWriter, + walkUpParenthesizedExpressions, + walkUpParenthesizedTypes, + walkUpParenthesizedTypesAndGetParentAndChild, +} from "./utilities"; +import { + escapeLeadingUnderscores, + findAncestor, + getCombinedModifierFlags, + getCombinedNodeFlags, + getEffectiveConstraintOfTypeParameter, + getEffectiveTypeParameterDeclarations, + getJSDocClassTag, + getJSDocDeprecatedTag, + getJSDocEnumTag, + getJSDocParameterTags, + getJSDocTags, + getJSDocThisTag, + getJSDocType, + getJSDocTypeTag, + getModifiers, + getNameOfDeclaration, + getOriginalNode, + getParseTreeNode, + getTextOfJSDocComment, + hasInitializer, + hasJSDocNodes, + hasJSDocParameterTags, + hasOnlyExpressionInitializer, + hasRestParameter, + hasScopeMarker, + hasType, + idText, + isAccessor, + isAssertionExpression, + isAssignmentPattern, + isAutoAccessorPropertyDeclaration, + isBindingPattern, + isCallChain, + isCallLikeExpression, + isCallOrNewExpression, + isClassElement, + isClassLike, + isConstTypeReference, + isDeclaration, + isEntityName, + isExpression, + isExpressionOfOptionalChainRoot, + isExternalModuleIndicator, + isExternalModuleNameRelative, + isForInOrOfStatement, + isFunctionLike, + isFunctionLikeDeclaration, + isFunctionLikeOrClassStaticBlockDeclaration, + isFunctionOrModuleBlock, + isGeneratedIdentifier, + isGetAccessor, + isGetOrSetAccessorDeclaration, + isImportOrExportSpecifier, + isIterationStatement, + isJSDocLinkLike, + isJSDocNode, + isJSDocPropertyLikeTag, + isJsxAttributeLike, + isJsxOpeningLikeElement, + isLeftHandSideExpression, + isLiteralExpressionOfObject, + isModifier, + isModuleOrEnumDeclaration, + isNamedDeclaration, + isNullishCoalesce, + isObjectLiteralElementLike, + isOptionalChain, + isOptionalChainRoot, + isOutermostOptionalChain, + isParameterPropertyDeclaration, + isPrivateIdentifierClassElementDeclaration, + isPrivateIdentifierPropertyAccessExpression, + isPropertyAccessOrQualifiedNameOrImportTypeNode, + isPropertyName, + isRestParameter, + isSetAccessor, + isStatement, + isStringLiteralLike, + isTypeNode, + isTypeOnlyImportOrExportDeclaration, + isTypeReferenceType, + needsScopeMarker, + nodeHasName, + ParameterPropertyDeclaration, + symbolName, + textRangeContainsPositionInclusive, + textSpanContainsPosition, + textSpanEnd, + unescapeLeadingUnderscores, + walkUpBindingElementsAndPatterns, +} from "./utilitiesPublic"; +import { + visitEachChild, + visitNode, + visitNodes, +} from "./visitorPublic"; const ambientModuleSymbolRegex = /^".+"$/; const anon = "(anonymous)" as __String & string; -let nextSymbolId = 1; -let nextNodeId = 1; let nextMergeId = 1; let nextFlowId = 1; @@ -1294,25 +1333,6 @@ function NodeLinks(this: NodeLinks) { this.flags = NodeCheckFlags.None; } -/** @internal */ -export function getNodeId(node: Node): number { - if (!node.id) { - node.id = nextNodeId; - nextNodeId++; - } - return node.id; -} - -/** @internal */ -export function getSymbolId(symbol: Symbol): SymbolId { - if (!symbol.id) { - symbol.id = nextSymbolId; - nextSymbolId++; - } - - return symbol.id; -} - /** @internal */ export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) { const moduleState = getModuleInstanceState(node); @@ -7314,7 +7334,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const isBRelative = pathIsRelative(specifierB); if (pathIsRelative(specifierA) === isBRelative) { // Both relative or both non-relative, sort by number of parts - return moduleSpecifiers.countPathComponents(specifierA) - moduleSpecifiers.countPathComponents(specifierB); + return countPathComponents(specifierA) - countPathComponents(specifierB); } if (isBRelative) { // A is non-relative, B is relative: prefer A @@ -7417,7 +7437,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // specifier preference const { moduleResolverHost } = context.tracker; const specifierCompilerOptions = isBundle ? { ...compilerOptions, baseUrl: moduleResolverHost.getCommonSourceDirectory() } : compilerOptions; - specifier = first(moduleSpecifiers.getModuleSpecifiers( + specifier = first(getModuleSpecifiers( symbol, checker, specifierCompilerOptions, @@ -9803,7 +9823,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function findResolutionCycleStartIndex(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): number { for (let i = resolutionTargets.length - 1; i >= 0; i--) { - if (hasType(resolutionTargets[i], resolutionPropertyNames[i])) { + if (targetHasType(resolutionTargets[i], resolutionPropertyNames[i])) { return -1; } if (resolutionTargets[i] === target && resolutionPropertyNames[i] === propertyName) { @@ -9813,7 +9833,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return -1; } - function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): boolean { + function targetHasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): boolean { switch (propertyName) { case TypeSystemPropertyName.Type: return !!getSymbolLinks(target as Symbol).type; @@ -18903,7 +18923,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return false; } // Or functions with annotated parameter types - if (some(node.parameters, ts.hasType)) { + if (some(node.parameters, hasType)) { return false; } const sourceSig = getSingleCallSignature(source); @@ -44309,7 +44329,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function typeHasCallOrConstructSignatures(type: Type): boolean { - return ts.typeHasCallOrConstructSignatures(type, checker); + return length(getSignaturesOfType(type, SignatureKind.Call)) > 0 + || length(getSignaturesOfType(type, SignatureKind.Construct)) > 0; } function getRootSymbols(symbol: Symbol): readonly Symbol[] { @@ -47216,12 +47237,3 @@ function getIterationTypesKeyFromIterationTypeKind(typeKind: IterationTypeKind) } } -/** @internal */ -export function signatureHasRestParameter(s: Signature) { - return !!(s.flags & SignatureFlags.HasRestParameter); -} - -/** @internal */ -export function signatureHasLiteralTypes(s: Signature) { - return !!(s.flags & SignatureFlags.HasLiteralTypes); -} diff --git a/src/compiler/checkerUtilities.ts b/src/compiler/checkerUtilities.ts new file mode 100644 index 0000000000000..41bf489efa536 --- /dev/null +++ b/src/compiler/checkerUtilities.ts @@ -0,0 +1,25 @@ +import { + Node, + Symbol, + SymbolId, +} from "./types"; + +let nextSymbolId = 1; +let nextNodeId = 1; + +export function getNodeId(node: Node): number { + if (!node.id) { + node.id = nextNodeId; + nextNodeId++; + } + return node.id; +} + +export function getSymbolId(symbol: Symbol): SymbolId { + if (!symbol.id) { + symbol.id = nextSymbolId; + nextSymbolId++; + } + + return symbol.id; +} diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index b62fb3b638ff1..6e61bd244b73f 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1,41 +1,13 @@ import { - AlternateModeDiagnostics, append, arrayFrom, - ArrayLiteralExpression, arrayToMap, assign, - BuildOptions, - changeExtension, - CharacterCodes, - combinePaths, - CommandLineOption, - CommandLineOptionOfCustomType, - CommandLineOptionOfListType, - CompilerOptions, - CompilerOptionsValue, - ConfigFileSpecs, - containsPath, - convertToRelativePath, - createCompilerDiagnostic, - createDiagnosticForNodeInSourceFile, createGetCanonicalFileName, - Debug, - Diagnostic, - DiagnosticMessage, - Diagnostics, - DidYouMeanOptionsDiagnostics, - directorySeparator, emptyArray, endsWith, - ensureTrailingDirectorySeparator, every, - Expression, extend, - Extension, - FileExtensionInfo, - fileExtensionIs, - fileExtensionIsOneOf, filter, filterMutate, find, @@ -43,82 +15,120 @@ import { firstDefined, flatten, forEach, - forEachEntry, - getBaseFileName, - getDirectoryPath, getEntries, - getFileMatcherPatterns, - getLocaleSpecificMessage, - getNormalizedAbsolutePath, - getRegexFromPattern, - getRegularExpressionForWildcard, - getRegularExpressionsForWildcards, - getRelativePathFromFile, getSpellingSuggestion, - getSupportedExtensions, - getSupportedExtensionsWithJsonIfResolveJsonModule, - getTextOfPropertyName, - getTsConfigPropArray, - getTsConfigPropArrayElementValue, - hasExtension, hasProperty, - ImportsNotUsedAsValues, isArray, - isArrayLiteralExpression, - isComputedNonLiteralName, - isImplicitGlob, - isObjectLiteralExpression, - isRootedDiskPath, isString, - isStringDoubleQuoted, - isStringLiteral, - JsonSourceFile, - JsxEmit, length, map, mapDefined, mapIterator, + returnTrue, + startsWith, + toFileNameLowerCase, + trimString, +} from "./core"; +import { MapLike, + Push, +} from "./corePublic"; +import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { + isArrayLiteralExpression, + isObjectLiteralExpression, + isStringLiteral, +} from "./factory/nodeTests"; +import { nodeModuleNameResolver } from "./moduleNameResolver"; +import { parseJsonText } from "./parser"; +import { + combinePaths, + containsPath, + convertToRelativePath, + directorySeparator, + ensureTrailingDirectorySeparator, + fileExtensionIs, + fileExtensionIsOneOf, + getBaseFileName, + getDirectoryPath, + getNormalizedAbsolutePath, + getRelativePathFromFile, + hasExtension, + isRootedDiskPath, + normalizePath, + normalizeSlashes, + removeTrailingDirectorySeparator, + toPath, +} from "./path"; +import { sys } from "./sys"; +import { tracing } from "./tracing"; +import { BuildOptions } from "./tsbuildPublic"; +import { + AlternateModeDiagnostics, + ArrayLiteralExpression, + CharacterCodes, + CommandLineOption, + CommandLineOptionOfCustomType, + CommandLineOptionOfListType, + CompilerOptions, + CompilerOptionsValue, + ConfigFileSpecs, + Diagnostic, + DiagnosticMessage, + DidYouMeanOptionsDiagnostics, + Expression, + Extension, + FileExtensionInfo, + ImportsNotUsedAsValues, + JsonSourceFile, + JsxEmit, ModuleDetectionKind, ModuleKind, ModuleResolutionKind, NewLineKind, Node, NodeArray, - nodeModuleNameResolver, - normalizePath, - normalizeSlashes, NumericLiteral, ObjectLiteralExpression, ParseConfigHost, ParsedCommandLine, - parseJsonText, Path, PollingWatchKind, PrefixUnaryExpression, ProjectReference, PropertyName, - Push, - removeTrailingDirectorySeparator, - returnTrue, ScriptTarget, - startsWith, StringLiteral, SyntaxKind, - sys, - toFileNameLowerCase, - toPath, - tracing, - trimString, TsConfigOnlyOption, TsConfigSourceFile, TypeAcquisition, - unescapeLeadingUnderscores, WatchDirectoryFlags, WatchDirectoryKind, WatchFileKind, WatchOptions, -} from "./_namespaces/ts"; +} from "./types"; +import { + changeExtension, + createCompilerDiagnostic, + createDiagnosticForNodeInSourceFile, + forEachEntry, + getFileMatcherPatterns, + getLocaleSpecificMessage, + getRegexFromPattern, + getRegularExpressionForWildcard, + getRegularExpressionsForWildcards, + getSupportedExtensions, + getSupportedExtensionsWithJsonIfResolveJsonModule, + getTextOfPropertyName, + getTsConfigPropArray, + getTsConfigPropArrayElementValue, + isComputedNonLiteralName, + isImplicitGlob, + isStringDoubleQuoted, +} from "./utilities"; +import { unescapeLeadingUnderscores } from "./utilitiesPublic"; /** @internal */ export const compileOnSaveCommandLineOption: CommandLineOption = { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 3961e094cde6b..acc2b77f504ee 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1,19 +1,20 @@ import { - __String, - CharacterCodes, Comparer, Comparison, - Debug, EqualityComparer, - isWhiteSpaceLike, MapLike, Push, - Queue, SortedArray, SortedReadonlyArray, +} from "./corePublic"; +// import { Debug } from "./debug"; +import { + __String, + CharacterCodes, + Queue, TextSpan, UnderscoreEscapedMap, -} from "./_namespaces/ts"; +} from "./types"; /** @internal */ export function getIterator | ReadonlyMap | undefined>(iterable: I): Iterator< @@ -135,7 +136,7 @@ export function reduceLeftIterator(iterator: Iterator | undefined, f: ( /** @internal */ 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); + // Debug.assertEqual(arrayA.length, arrayB.length); for (let i = 0; i < arrayA.length; i++) { result.push(callback(arrayA[i], arrayB[i], i)); } @@ -144,7 +145,7 @@ export function zipWith(arrayA: readonly T[], arrayB: readonly U[], cal /** @internal */ export function zipToIterator(arrayA: readonly T[], arrayB: readonly U[]): Iterator<[T, U]> { - Debug.assertEqual(arrayA.length, arrayB.length); + // Debug.assertEqual(arrayA.length, arrayB.length); let i = 0; return { next() { @@ -159,7 +160,7 @@ export function zipToIterator(arrayA: readonly T[], arrayB: readonly U[]): /** @internal */ export function zipToMap(keys: readonly K[], values: readonly V[]): Map { - Debug.assert(keys.length === values.length); + // Debug.assert(keys.length === values.length); const map = new Map(); for (let i = 0; i < keys.length; ++i) { map.set(keys[i], values[i]); @@ -279,7 +280,8 @@ export function findMap(array: readonly T[], callback: (element: T, index: return result; } } - return Debug.fail(); + // return Debug.fail(); + throw new Error(); } /** @internal */ @@ -897,7 +899,8 @@ function deduplicateSorted(array: SortedReadonlyArray, comparer: EqualityC case Comparison.LessThan: // If `array` is sorted, `next` should **never** be less than `last`. - return Debug.fail("Array is unsorted."); + // return Debug.fail("Array is unsorted."); + throw new Error("Array is unsorted."); } deduplicated.push(last = next); @@ -1018,14 +1021,14 @@ export function relativeComplement(arrayA: T[] | undefined, arrayB: T[] | und 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); + // Debug.assertGreaterThanOrEqual(comparer(arrayB[offsetB], arrayB[offsetB - 1]), 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); + // Debug.assertGreaterThanOrEqual(comparer(arrayA[offsetA], arrayA[offsetA - 1]), Comparison.EqualTo); } switch (comparer(arrayB[offsetB], arrayA[offsetA])) { @@ -1272,7 +1275,7 @@ export function firstOrUndefined(array: readonly T[] | undefined): T | undefi /** @internal */ export function first(array: readonly T[]): T { - Debug.assert(array.length !== 0); + // Debug.assert(array.length !== 0); return array[0]; } @@ -1287,7 +1290,7 @@ export function lastOrUndefined(array: readonly T[] | undefined): T | undefin /** @internal */ export function last(array: readonly T[]): T { - Debug.assert(array.length !== 0); + // Debug.assert(array.length !== 0); return array[array.length - 1]; } @@ -1308,7 +1311,12 @@ export function singleOrUndefined(array: readonly T[] | undefined): T | undef * @internal */ export function single(array: readonly T[]): T { - return Debug.checkDefined(singleOrUndefined(array)); + // return Debug.checkDefined(singleOrUndefined(array)); + const result = singleOrUndefined(array); + if (result === undefined) { + throw new Error(); + } + return result; } /** @@ -1487,18 +1495,21 @@ export function getOwnValues(collection: MapLike | T[]): T[] { return values; } -const _entries = Object.entries || ((obj: MapLike) => { +function entries(obj: MapLike): [string, T][] { + if (Object.entries) { + return Object.entries(obj); + } const keys = getOwnKeys(obj); const result: [string, T][] = Array(keys.length); for (let i = 0; i < keys.length; i++) { result[i] = [keys[i], obj[keys[i]]]; } return result; -}); +} /** @internal */ export function getEntries(obj: MapLike): [string, T][] { - return obj ? _entries(obj) : []; + return obj ? entries(obj) : []; } /** @internal */ @@ -2001,8 +2012,8 @@ export function tryCast(value: T, test: (value: T) => boolean): T | undefined /** @internal */ 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)}'.`); + throw new Error(`Invalid cast. The supplied value ${value} did not pass the test`); + // return Debug.fail(`Invalid cast. The supplied value ${value} did not pass the test '${Debug.getFunctionName(test)}'.`); } /** @@ -2488,7 +2499,7 @@ export function getSpellingSuggestion(name: string, candidates: T[], getName: continue; } - Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined + // Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined bestDistance = distance; bestCandidate = candidate; } @@ -2702,7 +2713,7 @@ export function patternText({ prefix, suffix }: Pattern): string { * @internal */ export function matchedText(pattern: Pattern, candidate: string): string { - Debug.assert(isPatternMatch(pattern, candidate)); + // Debug.assert(isPatternMatch(pattern, candidate)); return candidate.substring(pattern.prefix.length, candidate.length - pattern.suffix.length); } @@ -2936,6 +2947,46 @@ function trimEndImpl(s: string) { return s.slice(0, end + 1); } +export function isWhiteSpaceLike(ch: number): boolean { + return isWhiteSpaceSingleLine(ch) || isLineBreak(ch); +} + +/** Does not include line breaks. For that, see isWhiteSpaceLike. */ +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; +} + +export function isLineBreak(ch: number): boolean { + // ES5 7.3: + // The ECMAScript line terminator characters are listed in Table 3. + // Table 3: Line Terminator Characters + // Code Unit Value Name Formal Name + // \u000A Line Feed + // \u000D Carriage Return + // \u2028 Line separator + // \u2029 Paragraph separator + // 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; +} + declare const process: any; /** @internal */ diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index c438fab6ced3d..5c800637ed5c4 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1,16 +1,158 @@ import * as ts from "./_namespaces/ts"; +import { + computeSignature, + ProgramBuildInfo, + ProgramBundleEmitBuildInfo, +} from "./builder"; +import { OutputFile } from "./builderStatePublic"; +import { getNodeId } from "./checkerUtilities"; +import { + arrayToMap, + cast, + clone, + contains, + createGetCanonicalFileName, + createMultiMap, + emptyArray, + every, + filter, + findIndex, + firstOrUndefined, + forEach, + GetCanonicalFileName, + isArray, + last, + lastOrUndefined, + length, + maybeBind, + memoize, + notImplemented, + returnFalse, + returnUndefined, + singleOrUndefined, + some, + stableSort, + stringContains, +} from "./core"; +import { Comparison } from "./corePublic"; +import { Debug } from "./debug"; +import { + createBinaryExpressionTrampoline, +} from "./factory/binaryExpressionStateMachine"; +import { compareEmitHelpers } from "./factory/emitHelpers"; +import { + getCommentRange, + getConstantValue, + getEmitHelpers, + getSnippetElement, + getSourceMapRange, + getStartsOnNewLine, + getSyntheticLeadingComments, + getSyntheticTrailingComments, + getTypeNode, +} from "./factory/emitNode"; +import { + createInputFilesWithFileTexts, + factory, +} from "./factory/nodeFactory"; +import { + isArrowFunction, + isBinaryExpression, + isBlock, + isBundle, + isDecorator, + isEmptyStatement, + isExportAssignment, + isExportSpecifier, + isIdentifier, + isJsxClosingElement, + isJsxOpeningElement, + isModuleDeclaration, + isNumericLiteral, + isParenthesizedExpression, + isPartiallyEmittedExpression, + isPrivateIdentifier, + isSourceFile, + isStringLiteral, + isTypeParameterDeclaration, + isUnparsedPrepend, + isUnparsedSource, + isVariableStatement, +} from "./factory/nodeTests"; +import { + formatGeneratedName, + formatGeneratedNamePart, + getExternalHelpersModuleName, + getNodeForGeneratedName, + hasRecordedExternalHelpers, +} from "./factory/utilities"; +import { + setOriginalNode, + setTextRange, +} from "./factory/utilitiesPublic"; +import { + forEachChild, + isDeclarationFileName, + isJSDocLikeText, +} from "./parser"; +import { + combinePaths, + comparePaths, + directorySeparator, + ensurePathIsNonModuleName, + ensureTrailingDirectorySeparator, + fileExtensionIs, + fileExtensionIsOneOf, + getBaseFileName, + getDirectoryPath, + getNormalizedAbsolutePath, + getRelativePathFromDirectory, + getRelativePathToDirectoryOrUrl, + getRootLength, + normalizePath, + normalizeSlashes, + resolvePath, +} from "./path"; +import * as performance from "./performance"; +import { + computeCommonSourceDirectoryOfFilenames, + createPrependNodes, +} from "./program"; +import { + computeLineStarts, + forEachLeadingCommentRange, + forEachTrailingCommentRange, + getLeadingCommentRanges, + getLineAndCharacterOfPosition, + getLineStarts, + getShebang, + getTrailingCommentRanges, + skipTrivia, + tokenToString, +} from "./scanner"; +import { + createSourceMapGenerator, + tryParseRawSourceMap, +} from "./sourcemap"; +import { sys } from "./sys"; +import { tracing } from "./tracing"; +import { + getTransformers, + noEmitNotification, + noEmitSubstitution, + transformNodes, +} from "./transformer"; +import { isInternalDeclaration } from "./transformers/declarations"; import { AccessorDeclaration, ArrayBindingPattern, ArrayLiteralExpression, - arrayToMap, ArrayTypeNode, ArrowFunction, AsExpression, AssertClause, AssertEntry, AwaitExpression, - base64encode, BigIntLiteral, BinaryExpression, BinaryOperatorToken, @@ -31,74 +173,42 @@ import { CaseBlock, CaseClause, CaseOrDefaultClause, - cast, CatchClause, - changeExtension, CharacterCodes, ClassDeclaration, ClassExpression, ClassStaticBlockDeclaration, - clone, - combinePaths, CommaListExpression, CommentRange, - compareEmitHelpers, - comparePaths, - Comparison, CompilerHost, CompilerOptions, - computeCommonSourceDirectoryOfFilenames, ComputedPropertyName, - computeLineStarts, - computeSignature, ConditionalExpression, ConditionalTypeNode, ConstructorDeclaration, ConstructorTypeNode, ConstructSignatureDeclaration, - contains, ContinueStatement, - createBinaryExpressionTrampoline, - createDiagnosticCollection, - createGetCanonicalFileName, - createInputFilesWithFileTexts, - createMultiMap, - createPrependNodes, - createSourceMapGenerator, - createTextWriter, CustomTransformers, - Debug, DebuggerStatement, DeclarationName, Decorator, DefaultClause, DeleteExpression, - directorySeparator, DoStatement, DotToken, ElementAccessExpression, - emitDetachedComments, - EmitFileNames, EmitFlags, EmitHint, EmitHost, - emitNewLineBeforeLeadingCommentOfPosition, EmitOnly, EmitResolver, EmitResult, EmitTextWriter, EmitTransformers, - emptyArray, - ensurePathIsNonModuleName, - ensureTrailingDirectorySeparator, EntityName, EnumDeclaration, EnumMember, - escapeJsxAttributeString, - escapeLeadingUnderscores, - escapeNonAsciiString, - escapeString, - every, ExportAssignment, ExportDeclaration, ExportSpecifier, @@ -107,21 +217,9 @@ import { ExpressionWithTypeArguments, Extension, ExternalModuleReference, - factory, - fileExtensionIs, - fileExtensionIsOneOf, FileReference, - filter, - findIndex, - firstOrUndefined, - forEach, - forEachChild, - forEachLeadingCommentRange, - forEachTrailingCommentRange, ForInOrOfStatement, ForInStatement, - formatGeneratedName, - formatGeneratedNamePart, ForOfStatement, ForStatement, FunctionDeclaration, @@ -132,59 +230,8 @@ import { GeneratedIdentifierFlags, GeneratedNamePart, GeneratedPrivateIdentifier, - getAreDeclarationMapsEnabled, - getBaseFileName, - GetCanonicalFileName, - getCommentRange, - getConstantValue, - getContainingNodeArray, - getDeclarationEmitExtensionForPath, - getDeclarationEmitOutputFilePath, - getDirectoryPath, - getEmitDeclarations, - getEmitFlags, - getEmitHelpers, - getEmitModuleKind, - getExternalHelpersModuleName, - getExternalModuleName, - getLeadingCommentRanges, - getLineAndCharacterOfPosition, - getLinesBetweenPositionAndNextNonWhitespaceCharacter, - getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter, - getLinesBetweenRangeEndAndRangeStart, - getLineStarts, - getLiteralText, - GetLiteralTextFlags, - getNewLineCharacter, - getNodeForGeneratedName, - getNodeId, - getNormalizedAbsolutePath, - getOriginalNode, - getOwnEmitOutputFilePath, - getParseTreeNode, - getRelativePathFromDirectory, - getRelativePathToDirectoryOrUrl, - getRootLength, - getShebang, - getSnippetElement, - getSourceFileOfNode, - getSourceFilePathInNewDir, - getSourceFilesToEmit, - getSourceMapRange, - getSourceTextOfNodeFromSourceFile, - getStartsOnNewLine, - getSyntheticLeadingComments, - getSyntheticTrailingComments, - getTextOfJSDocComment, - getTrailingCommentRanges, - getTrailingSemicolonDeferringWriter, - getTransformers, - getTypeNode, - guessIndentation, - hasRecordedExternalHelpers, HeritageClause, Identifier, - idText, IfStatement, ImportClause, ImportDeclaration, @@ -197,57 +244,6 @@ import { InferTypeNode, InterfaceDeclaration, IntersectionTypeNode, - isAccessExpression, - isArray, - isArrowFunction, - isBinaryExpression, - isBindingPattern, - isBlock, - isBundle, - isBundleFileTextLike, - isDeclaration, - isDeclarationFileName, - isDecorator, - isEmptyStatement, - isExportAssignment, - isExportSpecifier, - isExpression, - isFunctionLike, - isGeneratedIdentifier, - isGeneratedPrivateIdentifier, - isIdentifier, - isIncrementalCompilation, - isInJsonFile, - isInternalDeclaration, - isJSDocLikeText, - isJsonSourceFile, - isJsxClosingElement, - isJsxOpeningElement, - isKeyword, - isLet, - isLiteralExpression, - isMemberName, - isModifier, - isModuleDeclaration, - isNodeDescendantOf, - isNumericLiteral, - isParenthesizedExpression, - isPartiallyEmittedExpression, - isPinnedComment, - isPrivateIdentifier, - isPrologueDirective, - isRecognizedTripleSlashComment, - isSourceFile, - isSourceFileNotJson, - isStringLiteral, - isTemplateLiteralKind, - isTokenKind, - isTypeParameterDeclaration, - isUnparsedNode, - isUnparsedPrepend, - isUnparsedSource, - isVarConst, - isVariableStatement, JSDoc, JSDocAugmentsTag, JSDocCallbackTag, @@ -286,18 +282,12 @@ import { JsxTagNameExpression, JsxText, LabeledStatement, - last, - lastOrUndefined, LateBoundDeclaration, - length, ListFormat, LiteralExpression, LiteralLikeNode, LiteralTypeNode, - makeIdentifierFromModuleName, MappedTypeNode, - maybeBind, - memoize, MetaProperty, MethodDeclaration, MethodSignature, @@ -319,68 +309,37 @@ import { Node, NodeArray, NodeFlags, - nodeIsSynthesized, - noEmitNotification, - noEmitSubstitution, NonNullExpression, - normalizePath, - normalizeSlashes, - notImplemented, NumericLiteral, ObjectBindingPattern, ObjectLiteralExpression, OptionalTypeNode, - outFile, - OutputFile, ParameterDeclaration, ParenthesizedExpression, ParenthesizedTypeNode, ParsedCommandLine, PartiallyEmittedExpression, Placeholder, - positionIsSynthesized, - positionsAreOnSameLine, PostfixUnaryExpression, PrefixUnaryExpression, Printer, PrinterOptions, PrintHandlers, PrivateIdentifier, - ProgramBuildInfo, - ProgramBundleEmitBuildInfo, ProjectReference, PropertyAccessExpression, PropertyAssignment, PropertyDeclaration, PropertySignature, QualifiedName, - rangeEndIsOnSameLineAsRangeStart, - rangeEndPositionsAreOnSameLine, - rangeIsOnSingleLine, - rangeStartPositionsAreOnSameLine, - readJsonOrUndefined, - removeFileExtension, - resolvePath, RestTypeNode, - returnFalse, ReturnStatement, - returnUndefined, SatisfiesExpression, ScriptTarget, - setEachParent, - setOriginalNode, - setParent, - setTextRange, - setTextRangePosEnd, - setTextRangePosWidth, ShorthandPropertyAssignment, SignatureDeclaration, - singleOrUndefined, - skipPartiallyEmittedExpressions, - skipTrivia, SnippetElement, SnippetKind, - some, SourceFile, SourceFilePrologueDirective, SourceFilePrologueInfo, @@ -389,17 +348,13 @@ import { SourceMapSource, SpreadAssignment, SpreadElement, - stableSort, Statement, - stringContains, StringLiteral, - supportedJSExtensionsFlat, SwitchStatement, Symbol, SymbolFlags, SyntaxKind, SynthesizedComment, - sys, TabStop, TaggedTemplateExpression, TemplateExpression, @@ -408,11 +363,7 @@ import { TemplateSpan, TextRange, ThrowStatement, - tokenToString, - tracing, TransformationResult, - transformNodes, - tryParseRawSourceMap, TryStatement, TupleTypeNode, TypeAliasDeclaration, @@ -438,12 +389,94 @@ import { VoidExpression, WhileStatement, WithStatement, - writeCommentRange, - writeFile, WriteFileCallbackData, YieldExpression, -} from "./_namespaces/ts"; -import * as performance from "./_namespaces/ts.performance"; +} from "./types"; +import { + base64encode, + changeExtension, + createDiagnosticCollection, + createTextWriter, + emitDetachedComments, + EmitFileNames, + emitNewLineBeforeLeadingCommentOfPosition, + escapeJsxAttributeString, + escapeNonAsciiString, + escapeString, + getAreDeclarationMapsEnabled, + getContainingNodeArray, + getDeclarationEmitExtensionForPath, + getDeclarationEmitOutputFilePath, + getEmitDeclarations, + getEmitFlags, + getEmitModuleKind, + getExternalModuleName, + getLinesBetweenPositionAndNextNonWhitespaceCharacter, + getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter, + getLinesBetweenRangeEndAndRangeStart, + getLiteralText, + GetLiteralTextFlags, + getNewLineCharacter, + getOwnEmitOutputFilePath, + getSourceFileOfNode, + getSourceFilePathInNewDir, + getSourceFilesToEmit, + getSourceTextOfNodeFromSourceFile, + getTrailingSemicolonDeferringWriter, + isAccessExpression, + isBundleFileTextLike, + isFileLevelUniqueName, + isIncrementalCompilation, + isInJsonFile, + isJsonSourceFile, + isKeyword, + isLet, + isNodeDescendantOf, + isPinnedComment, + isPrologueDirective, + isRecognizedTripleSlashComment, + isSourceFileNotJson, + isVarConst, + makeIdentifierFromModuleName, + nodeIsSynthesized, + outFile, + positionIsSynthesized, + positionsAreOnSameLine, + rangeEndIsOnSameLineAsRangeStart, + rangeEndPositionsAreOnSameLine, + rangeIsOnSingleLine, + rangeStartPositionsAreOnSameLine, + readJsonOrUndefined, + removeFileExtension, + setEachParent, + setParent, + setTextRangePosEnd, + setTextRangePosWidth, + supportedJSExtensionsFlat, + writeCommentRange, + writeFile, +} from "./utilities"; +import { + escapeLeadingUnderscores, + getOriginalNode, + getParseTreeNode, + getTextOfJSDocComment, + guessIndentation, + idText, + isBindingPattern, + isDeclaration, + isExpression, + isFunctionLike, + isGeneratedIdentifier, + isGeneratedPrivateIdentifier, + isLiteralExpression, + isMemberName, + isModifier, + isTemplateLiteralKind, + isTokenKind, + isUnparsedNode, + skipPartiallyEmittedExpressions, +} from "./utilitiesPublic"; const brackets = createBracketsMap(); @@ -1196,10 +1229,10 @@ export function emitUsingBuildInfo( customTransformers?: CustomTransformers ): EmitUsingBuildInfoResult { tracing?.push(tracing.Phase.Emit, "emitUsingBuildInfo", {}, /*separateBeginAndEnd*/ true); - ts.performance.mark("beforeEmit"); + performance.mark("beforeEmit"); const result = emitUsingBuildInfoWorker(config, host, getCommandLine, customTransformers); - ts.performance.mark("afterEmit"); - ts.performance.measure("Emit", "beforeEmit", "afterEmit"); + performance.mark("afterEmit"); + performance.measure("Emit", "beforeEmit", "afterEmit"); tracing?.pop(); return result; } @@ -5633,7 +5666,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri * or within the NameGenerator. */ function isUniqueName(name: string): boolean { - return isFileLevelUniqueName(name) + return isFileLevelUniqueNameHelper(name) && !generatedNames.has(name) && !(reservedNames && reservedNames.has(name)); } @@ -5641,8 +5674,8 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri /** * Returns a value indicating whether a name is unique globally or within the current file. */ - function isFileLevelUniqueName(name: string) { - return currentSourceFile ? ts.isFileLevelUniqueName(currentSourceFile, name, hasGlobalName) : true; + function isFileLevelUniqueNameHelper(name: string) { + return currentSourceFile ? isFileLevelUniqueName(currentSourceFile, name, hasGlobalName) : true; } /** @@ -5781,7 +5814,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri } function makeFileLevelOptimisticUniqueName(name: string) { - return makeUniqueName(name, isFileLevelUniqueName, /*optimistic*/ true, /*scoped*/ false, /*privateName*/ false, /*prefix*/ "", /*suffix*/ ""); + return makeUniqueName(name, isFileLevelUniqueNameHelper, /*optimistic*/ true, /*scoped*/ false, /*privateName*/ false, /*prefix*/ "", /*suffix*/ ""); } /** @@ -5882,7 +5915,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri case GeneratedIdentifierFlags.Unique: return makeUniqueName( idText(name), - (name.autoGenerateFlags & GeneratedIdentifierFlags.FileLevel) ? isFileLevelUniqueName : isUniqueName, + (name.autoGenerateFlags & GeneratedIdentifierFlags.FileLevel) ? isFileLevelUniqueNameHelper : isUniqueName, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.Optimistic), !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes), isPrivateIdentifier(name), diff --git a/src/compiler/factory/baseNodeFactory.ts b/src/compiler/factory/baseNodeFactory.ts index 019d3b9e27477..1d498b79a3ab4 100644 --- a/src/compiler/factory/baseNodeFactory.ts +++ b/src/compiler/factory/baseNodeFactory.ts @@ -1,8 +1,8 @@ import { Node, - objectAllocator, SyntaxKind, -} from "../_namespaces/ts"; +} from "../types"; +import { objectAllocator } from "../utilities"; /** * A `BaseNodeFactory` is an abstraction over an `ObjectAllocator` that handles caching `Node` constructors diff --git a/src/compiler/factory/binaryExpressionStateMachine.ts b/src/compiler/factory/binaryExpressionStateMachine.ts new file mode 100644 index 0000000000000..7ae6e731d8465 --- /dev/null +++ b/src/compiler/factory/binaryExpressionStateMachine.ts @@ -0,0 +1,220 @@ +import { AssertionLevel } from "../core"; +import { Debug } from "../debug"; +import { + BinaryExpression, + BinaryOperatorToken, + Expression, +} from "../types"; + +type BinaryExpressionState = (machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], resultHolder: { value: TResult }, outerState: TOuterState) => number; + +/** + * Handles walking into a `BinaryExpression`. + * @param machine State machine handler functions + * @param frame The current frame + * @returns The new frame + */ +function enter(machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], _resultHolder: { value: TResult }, outerState: TOuterState): number { + const prevUserState = stackIndex > 0 ? userStateStack[stackIndex - 1] : undefined; + Debug.assertEqual(stateStack[stackIndex], enter); + userStateStack[stackIndex] = machine.onEnter(nodeStack[stackIndex], prevUserState, outerState); + stateStack[stackIndex] = nextState(machine, enter); + return stackIndex; +} + +/** + * Handles walking the `left` side of a `BinaryExpression`. + * @param machine State machine handler functions + * @param frame The current frame + * @returns The new frame + */ +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); + stateStack[stackIndex] = nextState(machine, left); + const nextNode = machine.onLeft(nodeStack[stackIndex].left, userStateStack[stackIndex], nodeStack[stackIndex]); + if (nextNode) { + checkCircularity(stackIndex, nodeStack, nextNode); + return pushStack(stackIndex, stateStack, nodeStack, userStateStack, nextNode); + } + return stackIndex; +} + +/** + * Handles walking the `operatorToken` of a `BinaryExpression`. + * @param machine State machine handler functions + * @param frame The current frame + * @returns The new frame + */ +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); + stateStack[stackIndex] = nextState(machine, operator); + machine.onOperator(nodeStack[stackIndex].operatorToken, userStateStack[stackIndex], nodeStack[stackIndex]); + return stackIndex; +} + +/** + * Handles walking the `right` side of a `BinaryExpression`. + * @param machine State machine handler functions + * @param frame The current frame + * @returns The new frame + */ +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); + stateStack[stackIndex] = nextState(machine, right); + const nextNode = machine.onRight(nodeStack[stackIndex].right, userStateStack[stackIndex], nodeStack[stackIndex]); + if (nextNode) { + checkCircularity(stackIndex, nodeStack, nextNode); + return pushStack(stackIndex, stateStack, nodeStack, userStateStack, nextNode); + } + return stackIndex; +} + +/** + * Handles walking out of a `BinaryExpression`. + * @param machine State machine handler functions + * @param frame The current frame + * @returns The new frame + */ +function exit(machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], resultHolder: { value: TResult }, _outerState: TOuterState): number { + Debug.assertEqual(stateStack[stackIndex], exit); + stateStack[stackIndex] = nextState(machine, exit); + const result = machine.onExit(nodeStack[stackIndex], userStateStack[stackIndex]); + if (stackIndex > 0) { + stackIndex--; + if (machine.foldState) { + const side = stateStack[stackIndex] === exit ? "right" : "left"; + userStateStack[stackIndex] = machine.foldState(userStateStack[stackIndex], result, side); + } + } + else { + resultHolder.value = result; + } + return stackIndex; +} + +/** + * Handles a frame that is already done. + * @returns The `done` state. + */ +function done(_machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], _nodeStack: BinaryExpression[], _userStateStack: TState[], _resultHolder: { value: TResult }, _outerState: TOuterState): number { + Debug.assertEqual(stateStack[stackIndex], done); + return stackIndex; +} + +function nextState(machine: BinaryExpressionStateMachine, currentState: BinaryExpressionState) { + switch (currentState) { + case enter: + if (machine.onLeft) return left; + // falls through + case left: + if (machine.onOperator) return operator; + // falls through + case operator: + if (machine.onRight) return right; + // falls through + case right: return exit; + case exit: return done; + case done: return done; + default: Debug.fail("Invalid state"); + } +} + +function pushStack(stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], node: BinaryExpression) { + stackIndex++; + stateStack[stackIndex] = enter; + nodeStack[stackIndex] = node; + userStateStack[stackIndex] = undefined!; + return stackIndex; +} + +function checkCircularity(stackIndex: number, nodeStack: BinaryExpression[], node: BinaryExpression) { + if (Debug.shouldAssert(AssertionLevel.Aggressive)) { + while (stackIndex >= 0) { + Debug.assert(nodeStack[stackIndex] !== node, "Circular traversal detected."); + stackIndex--; + } + } +} + +/** + * 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, + ) { + } +} + +/** + * 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. + * @param onLeft Callback evaluated when walking the left side of a `BinaryExpression`. Return a `BinaryExpression` to continue walking, or `void` to advance to the right side. + * @param onRight Callback evaluated when walking the right side of a `BinaryExpression`. Return a `BinaryExpression` to continue walking, or `void` to advance to the end of the node. + * @param onExit Callback evaluated when exiting a `BinaryExpression`. The result returned will either be folded into the parent's state, or returned from the walker if at the top frame. + * @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. + * + * @internal + */ + 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; +/** + * 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. + * @param onLeft Callback evaluated when walking the left side of a `BinaryExpression`. Return a `BinaryExpression` to continue walking, or `void` to advance to the right side. + * @param onRight Callback evaluated when walking the right side of a `BinaryExpression`. Return a `BinaryExpression` to continue walking, or `void` to advance to the end of the node. + * @param onExit Callback evaluated when exiting a `BinaryExpression`. The result returned will either be folded into the parent's state, or returned from the walker if at the top frame. + * @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. + * + * @internal + */ +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; + +/** @internal */ +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, +) { + const machine = new BinaryExpressionStateMachine(onEnter, onLeft, onOperator, onRight, onExit, foldState); + return trampoline; + + function trampoline(node: BinaryExpression, outerState?: TOuterState) { + const resultHolder: { value: TResult } = { value: undefined! }; + const stateStack: BinaryExpressionState[] = [enter]; + const nodeStack: BinaryExpression[] = [node]; + const userStateStack: TState[] = [undefined!]; + let stackIndex = 0; + while (stateStack[stackIndex] !== done) { + stackIndex = stateStack[stackIndex](machine, stackIndex, stateStack, nodeStack, userStateStack, resultHolder, outerState); + } + Debug.assertEqual(stackIndex, 0); + return resultHolder.value; + } +} diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts index faa93c77be83a..f8c309aaf8e3d 100644 --- a/src/compiler/factory/emitHelpers.ts +++ b/src/compiler/factory/emitHelpers.ts @@ -1,76 +1,47 @@ +import { + arrayToMap, + compareValues, + memoize, +} from "../core"; +import { Comparison } from "../corePublic"; +import { Debug } from "../debug"; import { __String, ArrayLiteralExpression, - arrayToMap, BindingOrAssignmentElement, Block, - compareValues, - Comparison, - createExpressionFromEntityName, - Debug, EmitFlags, EmitHelper, + EmitHelperFactory, EmitHelperUniqueNameCallback, EmitNode, EntityName, Expression, FunctionExpression, GeneratedIdentifierFlags, - getEmitFlags, - getEmitScriptTarget, - getPropertyNameOfBindingOrAssignmentElement, Identifier, - isCallExpression, - isComputedPropertyName, - isIdentifier, - memoize, PrivateIdentifierKind, ScriptTarget, - setEmitFlags, - setTextRange, SyntaxKind, TextRange, TransformationContext, UnscopedEmitHelper, -} from "../_namespaces/ts"; - -/** @internal */ -export interface EmitHelperFactory { - getUnscopedHelperName(name: string): 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; - // 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; - // ES2018 Destructuring Helpers - createRestHelper(value: Expression, elements: readonly BindingOrAssignmentElement[], computedTempVariables: readonly Expression[] | undefined, location: TextRange): Expression; - // ES2017 Helpers - createAwaiterHelper(hasLexicalThis: boolean, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression | undefined, body: Block): Expression; - // ES2015 Helpers - createExtendsHelper(name: Identifier): Expression; - createTemplateObjectHelper(cooked: ArrayLiteralExpression, raw: ArrayLiteralExpression): Expression; - createSpreadArrayHelper(to: Expression, from: Expression, packFrom: boolean): Expression; - // ES2015 Destructuring Helpers - createValuesHelper(expression: Expression): Expression; - createReadHelper(iteratorRecord: Expression, count: number | undefined): Expression; - // ES2015 Generator Helpers - createGeneratorHelper(body: FunctionExpression): 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; - // 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; -} +} from "../types"; +import { + getEmitFlags, + getEmitScriptTarget, +} from "../utilities"; +import { setEmitFlags } from "./emitNode"; +import { + isCallExpression, + isComputedPropertyName, + isIdentifier, +} from "./nodeTests"; +import { + createExpressionFromEntityName, + getPropertyNameOfBindingOrAssignmentElement, +} from "./utilities"; +import { setTextRange } from "./utilitiesPublic"; /** @internal */ export function createEmitHelperFactory(context: TransformationContext): EmitHelperFactory { diff --git a/src/compiler/factory/emitNode.ts b/src/compiler/factory/emitNode.ts index 1fa3027f660b4..6c97d538851e4 100644 --- a/src/compiler/factory/emitNode.ts +++ b/src/compiler/factory/emitNode.ts @@ -1,25 +1,29 @@ import { - AccessExpression, append, appendIfUnique, - Debug, + orderedRemoveItem, + some, +} from "../core"; +import { Debug } from "../debug"; +import { + AccessExpression, EmitFlags, EmitHelper, EmitNode, - getParseTreeNode, - getSourceFileOfNode, - isParseTreeNode, Node, - orderedRemoveItem, SnippetElement, - some, SourceFile, SourceMapRange, SyntaxKind, SynthesizedComment, TextRange, TypeNode, -} from "../_namespaces/ts"; +} from "../types"; +import { getSourceFileOfNode } from "../utilities"; +import { + getParseTreeNode, + isParseTreeNode, +} from "../utilitiesPublic"; /** * Associates a node with the current transformation, initializing diff --git a/src/compiler/factory/nodeConverters.ts b/src/compiler/factory/nodeConverters.ts index e506391a78b78..3575231e0c5de 100644 --- a/src/compiler/factory/nodeConverters.ts +++ b/src/compiler/factory/nodeConverters.ts @@ -1,3 +1,9 @@ +import { + cast, + map, + notImplemented, +} from "../core"; +import { Debug } from "../debug"; import { ArrayBindingOrAssignmentElement, ArrayBindingOrAssignmentPattern, @@ -5,33 +11,37 @@ import { BindingOrAssignmentElementTarget, BindingOrAssignmentPattern, Block, - cast, ConciseBody, - Debug, Expression, FunctionDeclaration, + NodeConverters, + NodeFactory, + ObjectBindingOrAssignmentElement, + ObjectBindingOrAssignmentPattern, + SyntaxKind, +} from "../types"; +import { + isBindingPattern, + isExpression, + isObjectLiteralElementLike, +} from "../utilitiesPublic"; +import { getStartsOnNewLine, + setStartsOnNewLine, +} from "./emitNode"; +import { isArrayBindingPattern, isArrayLiteralExpression, isBindingElement, - isBindingPattern, isBlock, - isExpression, isIdentifier, isObjectBindingPattern, - isObjectLiteralElementLike, isObjectLiteralExpression, - map, - NodeConverters, - NodeFactory, - notImplemented, - ObjectBindingOrAssignmentElement, - ObjectBindingOrAssignmentPattern, +} from "./nodeTests"; +import { setOriginalNode, - setStartsOnNewLine, setTextRange, - SyntaxKind, -} from "../_namespaces/ts"; +} from "./utilitiesPublic"; /** @internal */ export function createNodeConverters(factory: NodeFactory): NodeConverters { diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 4e872d7babb73..c92c90744bfc4 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -1,7 +1,36 @@ +import { getNodeId } from "../checkerUtilities"; import { addRange, append, - appendIfUnique, + cast, + emptyArray, + every, + forEach, + hasProperty, + isArray, + isString, + lastOrUndefined, + map, + memoize, + memoizeOne, + reduceLeft, + returnTrue, + sameFlatMap, + singleOrUndefined, + some, + startsWith, +} from "../core"; +import { Push } from "../corePublic"; +import { Debug } from "../debug"; +import { getBuildInfo } from "../emitter"; +import { parseNodeFactory } from "../parser"; +import { + createScanner, + getLineAndCharacterOfPosition, + Scanner, + stringToToken, +} from "../scanner"; +import { ArrayBindingElement, ArrayBindingPattern, ArrayLiteralExpression, @@ -16,7 +45,6 @@ import { AsteriskToken, AwaitExpression, AwaitKeyword, - BaseNodeFactory, BigIntLiteral, BinaryExpression, BinaryOperator, @@ -37,11 +65,9 @@ import { CallChain, CallExpression, CallSignatureDeclaration, - canHaveModifiers, CaseBlock, CaseClause, CaseOrDefaultClause, - cast, CatchClause, ClassDeclaration, ClassElement, @@ -60,11 +86,6 @@ import { ConstructorTypeNode, ConstructSignatureDeclaration, ContinueStatement, - createBaseNodeFactory, - createNodeConverters, - createParenthesizerRules, - createScanner, - Debug, DebuggerStatement, Declaration, DeclarationName, @@ -77,7 +98,6 @@ import { ElementAccessExpression, EmitFlags, EmitNode, - emptyArray, EmptyStatement, EndOfDeclarationMarker, EndOfFileToken, @@ -85,8 +105,6 @@ import { EnumDeclaration, EnumMember, EqualsGreaterThanToken, - escapeLeadingUnderscores, - every, ExclamationToken, ExportAssignment, ExportDeclaration, @@ -97,11 +115,8 @@ import { ExternalModuleReference, FalseLiteral, FileReference, - findUseStrictPrologue, - forEach, ForInitializer, ForInStatement, - formatGeneratedName, ForOfStatement, ForStatement, FunctionDeclaration, @@ -112,28 +127,9 @@ import { GeneratedIdentifierFlags, GeneratedNamePart, GetAccessorDeclaration, - getAllUnscopedEmitHelpers, - getBuildInfo, - getCommentRange, - getElementsOfBindingOrAssignmentPattern, - getEmitFlags, - getJSDocTypeAliasName, - getLineAndCharacterOfPosition, - getNameOfDeclaration, - getNodeId, - getSourceMapRange, - getSyntheticLeadingComments, - getSyntheticTrailingComments, - getTargetOfBindingOrAssignmentElement, - getTextOfIdentifierOrLiteral, - hasInvalidEscape, HasModifiers, - hasProperty, - hasStaticModifier, - hasSyntacticModifier, HeritageClause, Identifier, - idText, IfStatement, ImportClause, ImportDeclaration, @@ -147,78 +143,6 @@ import { InputFiles, InterfaceDeclaration, IntersectionTypeNode, - isArray, - isArrayLiteralExpression, - isArrowFunction, - isAssignmentPattern, - isBinaryExpression, - isCallChain, - isClassDeclaration, - isClassExpression, - isCommaListExpression, - isCommaToken, - isComputedPropertyName, - isConstructorDeclaration, - isConstructorTypeNode, - isCustomPrologue, - isElementAccessChain, - isElementAccessExpression, - isEnumDeclaration, - isExclamationToken, - isExportAssignment, - isExportDeclaration, - isExternalModuleReference, - isFunctionDeclaration, - isFunctionExpression, - isGeneratedIdentifier, - isGetAccessorDeclaration, - isHoistedFunction, - isHoistedVariableStatement, - isIdentifier, - isImportDeclaration, - isImportEqualsDeclaration, - isImportKeyword, - isIndexSignatureDeclaration, - isInterfaceDeclaration, - isLabeledStatement, - isLocalName, - isLogicalOrCoalescingAssignmentOperator, - isMemberName, - isMethodDeclaration, - isMethodSignature, - isModuleDeclaration, - isNamedDeclaration, - isNodeArray, - isNodeKind, - isNonNullChain, - isNotEmittedStatement, - isObjectLiteralExpression, - isOmittedExpression, - isOuterExpression, - isParameter, - isParenthesizedExpression, - isParseTreeNode, - isPrivateIdentifier, - isPrologueDirective, - isPropertyAccessChain, - isPropertyAccessExpression, - isPropertyDeclaration, - isPropertyName, - isPropertySignature, - isQuestionToken, - isSetAccessorDeclaration, - isSourceFile, - isStatement, - isStatementOrBlock, - isString, - isStringLiteral, - isSuperKeyword, - isSuperProperty, - isThisIdentifier, - isTypeAliasDeclaration, - isTypeParameterDeclaration, - isVariableDeclaration, - isVariableStatement, JSDoc, JSDocAllType, JSDocAugmentsTag, @@ -285,14 +209,10 @@ import { KeywordTypeSyntaxKind, LabeledStatement, LanguageVariant, - lastOrUndefined, LeftHandSideExpression, LiteralToken, LiteralTypeNode, - map, MappedTypeNode, - memoize, - memoizeOne, MergeDeclarationMarker, MetaProperty, MethodDeclaration, @@ -302,7 +222,6 @@ import { Modifier, ModifierFlags, ModifierLike, - modifiersToFlags, ModifierSyntaxKind, ModifierToken, ModuleBlock, @@ -311,7 +230,6 @@ import { ModuleKind, ModuleName, ModuleReference, - Mutable, MutableNodeArray, NamedDeclaration, NamedExportBindings, @@ -327,16 +245,12 @@ import { NodeArray, NodeFactory, NodeFlags, - nodeIsSynthesized, NonNullChain, NonNullExpression, NoSubstitutionTemplateLiteral, NotEmittedStatement, NullLiteral, - nullNodeConverters, - nullParenthesizerRules, NumericLiteral, - objectAllocator, ObjectBindingPattern, ObjectLiteralElementLike, ObjectLiteralExpression, @@ -347,7 +261,6 @@ import { ParameterDeclaration, ParenthesizedExpression, ParenthesizedTypeNode, - parseNodeFactory, PartiallyEmittedExpression, PlusToken, PostfixUnaryExpression, @@ -366,47 +279,28 @@ import { PropertyNameLiteral, PropertySignature, PseudoBigInt, - pseudoBigIntToString, PunctuationSyntaxKind, PunctuationToken, - Push, QualifiedName, QuestionDotToken, QuestionToken, ReadonlyKeyword, - reduceLeft, RegularExpressionLiteral, RestTypeNode, ReturnStatement, - returnTrue, - sameFlatMap, SatisfiesExpression, - Scanner, ScriptTarget, SemicolonClassElement, SetAccessorDeclaration, - setEachParent, - setEmitFlags, - setParent, - setTextRange, - setTextRangePosEnd, - setTextRangePosWidth, ShorthandPropertyAssignment, SignatureDeclarationBase, - singleOrUndefined, - skipOuterExpressions, - skipParentheses, - some, SourceFile, SourceMapSource, SpreadAssignment, SpreadElement, - startOnNewLine, - startsWith, Statement, StringLiteral, StringLiteralLike, - stringToToken, SuperExpression, SwitchStatement, SyntaxKind, @@ -424,7 +318,6 @@ import { TemplateMiddle, TemplateSpan, TemplateTail, - TextRange, ThisExpression, ThisTypeNode, ThrowStatement, @@ -460,13 +353,141 @@ import { VariableDeclaration, VariableDeclarationList, VariableStatement, - visitNode, VisitResult, VoidExpression, WhileStatement, WithStatement, YieldExpression, -} from "../_namespaces/ts"; +} from "../types"; +import { + findUseStrictPrologue, + getEmitFlags, + getTextOfIdentifierOrLiteral, + hasInvalidEscape, + hasStaticModifier, + hasSyntacticModifier, + isCustomPrologue, + isHoistedFunction, + isHoistedVariableStatement, + isLogicalOrCoalescingAssignmentOperator, + isOuterExpression, + isPrologueDirective, + isSuperProperty, + isThisIdentifier, + modifiersToFlags, + Mutable, + nodeIsSynthesized, + objectAllocator, + pseudoBigIntToString, + setEachParent, + setParent, + setTextRangePosEnd, + setTextRangePosWidth, + skipOuterExpressions, + skipParentheses, +} from "../utilities"; +import { + escapeLeadingUnderscores, + getNameOfDeclaration, + idText, + isAssignmentPattern, + isCallChain, + isElementAccessChain, + isGeneratedIdentifier, + isMemberName, + isNamedDeclaration, + isNodeArray, + isNodeKind, + isNonNullChain, + isParseTreeNode, + isPropertyAccessChain, + isPropertyName, + isStatement, + isStatementOrBlock, +} from "../utilitiesPublic"; +import { visitNode } from "../visitorPublic"; +import { + BaseNodeFactory, + createBaseNodeFactory, +} from "./baseNodeFactory"; +import { getAllUnscopedEmitHelpers } from "./emitHelpers"; +import { + getCommentRange, + getSourceMapRange, + getSyntheticLeadingComments, + getSyntheticTrailingComments, + setEmitFlags, +} from "./emitNode"; +import { + createNodeConverters, + nullNodeConverters, +} from "./nodeConverters"; +import { + isArrayLiteralExpression, + isArrowFunction, + isBinaryExpression, + isClassDeclaration, + isClassExpression, + isCommaListExpression, + isCommaToken, + isComputedPropertyName, + isConstructorDeclaration, + isConstructorTypeNode, + isElementAccessExpression, + isEnumDeclaration, + isExclamationToken, + isExportAssignment, + isExportDeclaration, + isExternalModuleReference, + isFunctionDeclaration, + isFunctionExpression, + isGetAccessorDeclaration, + isIdentifier, + isImportDeclaration, + isImportEqualsDeclaration, + isImportKeyword, + isIndexSignatureDeclaration, + isInterfaceDeclaration, + isLabeledStatement, + isMethodDeclaration, + isMethodSignature, + isModuleDeclaration, + isNotEmittedStatement, + isObjectLiteralExpression, + isOmittedExpression, + isParameter, + isParenthesizedExpression, + isPrivateIdentifier, + isPropertyAccessExpression, + isPropertyDeclaration, + isPropertySignature, + isQuestionToken, + isSetAccessorDeclaration, + isSourceFile, + isStringLiteral, + isSuperKeyword, + isTypeAliasDeclaration, + isTypeParameterDeclaration, + isVariableDeclaration, + isVariableStatement, +} from "./nodeTests"; +import { + createParenthesizerRules, + nullParenthesizerRules, +} from "./parenthesizerRules"; +import { + formatGeneratedName, + getElementsOfBindingOrAssignmentPattern, + getJSDocTypeAliasName, + getTargetOfBindingOrAssignmentElement, + isLocalName, + startOnNewLine, +} from "./utilities"; +import { + canHaveModifiers, + setOriginalNode, + setTextRange, +} from "./utilitiesPublic"; let nextAutoGenerateId = 0; @@ -7356,54 +7377,3 @@ let SourceMapSource: new (fileName: string, text: string, skipTrivia?: (pos: num export function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): SourceMapSource { return new (SourceMapSource || (SourceMapSource = objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia); } - -// Utilities - -export function setOriginalNode(node: T, original: Node | undefined): T { - node.original = original; - if (original) { - const emitNode = original.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, - snippetElement, - } = sourceEmitNode; - if (!destEmitNode) destEmitNode = {} as 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 (helpers) { - for (const helper of helpers) { - destEmitNode.helpers = appendIfUnique(destEmitNode.helpers, helper); - } - } - if (startsOnNewLine !== undefined) destEmitNode.startsOnNewLine = startsOnNewLine; - if (snippetElement !== undefined) destEmitNode.snippetElement = snippetElement; - return destEmitNode; -} - -function mergeTokenSourceMapRanges(sourceRanges: (TextRange | undefined)[], destRanges: (TextRange | undefined)[]) { - if (!destRanges) destRanges = []; - for (const key in sourceRanges) { - destRanges[key] = sourceRanges[key]; - } - return destRanges; -} diff --git a/src/compiler/factory/nodeTests.ts b/src/compiler/factory/nodeTests.ts index 14e296610c54f..7ccf662e3397e 100644 --- a/src/compiler/factory/nodeTests.ts +++ b/src/compiler/factory/nodeTests.ts @@ -222,7 +222,7 @@ import { WhileStatement, WithStatement, YieldExpression, -} from "../_namespaces/ts"; +} from "../types"; // Literals diff --git a/src/compiler/factory/parenthesizerRules.ts b/src/compiler/factory/parenthesizerRules.ts index 119ad2953a195..3de4783b5b619 100644 --- a/src/compiler/factory/parenthesizerRules.ts +++ b/src/compiler/factory/parenthesizerRules.ts @@ -1,54 +1,62 @@ import { - Associativity, - BinaryExpression, - BinaryOperator, cast, compareValues, - Comparison, + identity, + last, + sameMap, + some, +} from "../core"; +import { Comparison } from "../corePublic"; +import { + BinaryExpression, + BinaryOperator, ConciseBody, Expression, + LeftHandSideExpression, + NamedTupleMember, + NewExpression, + NodeArray, + NodeFactory, + OuterExpressionKinds, + ParenthesizerRules, + SyntaxKind, + TypeNode, + UnaryExpression, +} from "../types"; +import { + Associativity, getExpressionAssociativity, getExpressionPrecedence, getLeftmostExpression, getOperatorAssociativity, getOperatorPrecedence, - identity, + OperatorPrecedence, +} from "../utilities"; +import { + isFunctionOrConstructorTypeNode, + isLeftHandSideExpression, + isLiteralKind, + isNodeArray, + isOptionalChain, + isUnaryExpression, + skipPartiallyEmittedExpressions, +} from "../utilitiesPublic"; +import { isBinaryExpression, isBlock, isCallExpression, - isCommaSequence, isConditionalTypeNode, isConstructorTypeNode, - isFunctionOrConstructorTypeNode, isFunctionTypeNode, isInferTypeNode, isIntersectionTypeNode, isJSDocNullableType, - isLeftHandSideExpression, - isLiteralKind, isNamedTupleMember, - isNodeArray, - isOptionalChain, isTypeOperatorNode, - isUnaryExpression, isUnionTypeNode, - last, - LeftHandSideExpression, - NamedTupleMember, - NewExpression, - NodeArray, - NodeFactory, - OperatorPrecedence, - OuterExpressionKinds, - ParenthesizerRules, - sameMap, - setTextRange, - skipPartiallyEmittedExpressions, - some, - SyntaxKind, - TypeNode, - UnaryExpression, -} from "../_namespaces/ts"; +} from "./nodeTests"; +import { isCommaSequence } from "./utilities"; +import { setTextRange } from "./utilitiesPublic"; /** @internal */ export function createParenthesizerRules(factory: NodeFactory): ParenthesizerRules { diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index 190bd6e7cb8b0..88240521d799d 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -1,9 +1,17 @@ +import { + compareStringsCaseSensitive, + first, + map, + or, + pushIfUnique, + some, +} from "../core"; +import { Debug } from "../debug"; +import { parseNodeFactory } from "../parser"; import { AccessorDeclaration, - addEmitFlags, AdditiveOperator, AdditiveOperatorOrHigher, - AssertionLevel, AssignmentOperatorOrHigher, BinaryExpression, BinaryOperator, @@ -18,9 +26,7 @@ import { BooleanLiteral, CharacterCodes, CommaListExpression, - compareStringsCaseSensitive, CompilerOptions, - Debug, Declaration, EmitFlags, EmitHelperFactory, @@ -33,78 +39,18 @@ import { ExponentiationOperator, ExportDeclaration, Expression, - ExpressionStatement, - externalHelpersModuleNameText, - first, - firstOrUndefined, ForInitializer, GeneratedIdentifier, GeneratedIdentifierFlags, GeneratedNamePart, GeneratedPrivateIdentifier, GetAccessorDeclaration, - getAllAccessorDeclarations, - getEmitFlags, - getEmitHelpers, - getEmitModuleKind, - getESModuleInterop, - getExternalModuleName, - getExternalModuleNameFromPath, - getJSDocType, - getJSDocTypeTag, - getModifiers, - getNamespaceDeclarationNode, - getOrCreateEmitNode, - getOriginalNode, - getParseTreeNode, - getSourceTextOfNodeFromSourceFile, - HasIllegalDecorators, HasIllegalModifiers, HasIllegalType, - HasIllegalTypeParameters, Identifier, - idText, ImportCall, ImportDeclaration, ImportEqualsDeclaration, - isAssignmentExpression, - isAssignmentOperator, - isBlock, - isComputedPropertyName, - isDeclarationBindingElement, - isDefaultImport, - isEffectiveExternalModule, - isExclamationToken, - isExportNamespaceAsDefaultDeclaration, - isFileLevelUniqueName, - isGeneratedIdentifier, - isGeneratedPrivateIdentifier, - isIdentifier, - isInJSFile, - isLiteralExpression, - isMemberName, - isMinusToken, - isObjectLiteralElementLike, - isParenthesizedExpression, - isPlusToken, - isPostfixUnaryExpression, - isPrefixUnaryExpression, - isPrivateIdentifier, - isPrologueDirective, - isPropertyAssignment, - isPropertyName, - isQualifiedName, - isQuestionToken, - isReadonlyKeyword, - isShorthandPropertyAssignment, - isSourceFile, - isSpreadAssignment, - isSpreadElement, - isStringLiteral, - isThisTypeNode, - isTypeNode, - isTypeParameterDeclaration, - isVariableDeclarationList, JSDocNamespaceBody, JSDocTypeAssertion, JsxOpeningFragment, @@ -113,7 +59,6 @@ import { LiteralExpression, LogicalOperator, LogicalOperatorOrHigher, - map, MemberExpression, MethodDeclaration, MinusToken, @@ -122,7 +67,6 @@ import { ModuleName, MultiplicativeOperator, MultiplicativeOperatorOrHigher, - Mutable, NamedImportBindings, Node, NodeArray, @@ -131,11 +75,6 @@ import { NumericLiteral, ObjectLiteralElementLike, ObjectLiteralExpression, - or, - OuterExpression, - OuterExpressionKinds, - outFile, - parseNodeFactory, PlusToken, PostfixUnaryExpression, PrefixUnaryExpression, @@ -143,20 +82,14 @@ import { PropertyAssignment, PropertyDeclaration, PropertyName, - pushIfUnique, QuestionToken, ReadonlyKeyword, RelationalOperator, RelationalOperatorOrHigher, SetAccessorDeclaration, - setOriginalNode, - setParent, - setStartsOnNewLine, - setTextRange, ShiftOperator, ShiftOperatorOrHigher, ShorthandPropertyAssignment, - some, SourceFile, Statement, StringLiteral, @@ -166,7 +99,75 @@ import { Token, TypeNode, TypeParameterDeclaration, -} from "../_namespaces/ts"; +} from "../types"; +import { + externalHelpersModuleNameText, + getAllAccessorDeclarations, + getEmitFlags, + getEmitModuleKind, + getESModuleInterop, + getExternalModuleName, + getExternalModuleNameFromPath, + getNamespaceDeclarationNode, + getSourceTextOfNodeFromSourceFile, + isAssignmentExpression, + isAssignmentOperator, + isDefaultImport, + isEffectiveExternalModule, + isExportNamespaceAsDefaultDeclaration, + isFileLevelUniqueName, + Mutable, + outFile, + setParent, +} from "../utilities"; +import { + getJSDocType, + getModifiers, + getOriginalNode, + getParseTreeNode, + idText, + isDeclarationBindingElement, + isGeneratedIdentifier, + isGeneratedPrivateIdentifier, + isLiteralExpression, + isMemberName, + isObjectLiteralElementLike, + isPropertyName, + isTypeNode, +} from "../utilitiesPublic"; +import { + addEmitFlags, + getEmitHelpers, + getOrCreateEmitNode, + setStartsOnNewLine, +} from "./emitNode"; +import { + isBlock, + isComputedPropertyName, + isExclamationToken, + isIdentifier, + isMinusToken, + isPlusToken, + isPostfixUnaryExpression, + isPrefixUnaryExpression, + isPrivateIdentifier, + isPropertyAssignment, + isQualifiedName, + isQuestionToken, + isReadonlyKeyword, + isShorthandPropertyAssignment, + isSourceFile, + isSpreadAssignment, + isSpreadElement, + isStringLiteral, + isThisTypeNode, + isTypeParameterDeclaration, + isVariableDeclarationList, +} from "./nodeTests"; +import { + setOriginalNode, + setTextRange, +} from "./utilitiesPublic"; // Compound nodes @@ -571,46 +572,12 @@ export function isExportName(node: Identifier) { return (getEmitFlags(node) & EmitFlags.ExportName) !== 0; } -function isUseStrictPrologue(node: ExpressionStatement): boolean { - return isStringLiteral(node.expression) && node.expression.text === "use strict"; -} - -/** @internal */ -export function findUseStrictPrologue(statements: readonly Statement[]): Statement | undefined { - for (const statement of statements) { - if (isPrologueDirective(statement)) { - if (isUseStrictPrologue(statement)) { - return statement; - } - } - else { - break; - } - } - return undefined; -} - -/** @internal */ -export function startsWithUseStrict(statements: readonly Statement[]) { - const firstStatement = firstOrUndefined(statements); - return firstStatement !== undefined - && isPrologueDirective(firstStatement) - && isUseStrictPrologue(firstStatement); -} - /** @internal */ 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; } -/** @internal */ -export function isJSDocTypeAssertion(node: Node): node is JSDocTypeAssertion { - return isParenthesizedExpression(node) - && isInJSFile(node) - && !!getJSDocTypeTag(node); -} - /** @internal */ export function getJSDocTypeAssertionType(node: JSDocTypeAssertion) { const type = getJSDocType(node); @@ -618,47 +585,6 @@ export function getJSDocTypeAssertionType(node: JSDocTypeAssertion) { return type; } -/** @internal */ -export function isOuterExpression(node: Node, kinds = OuterExpressionKinds.All): node is OuterExpression { - switch (node.kind) { - case SyntaxKind.ParenthesizedExpression: - if (kinds & OuterExpressionKinds.ExcludeJSDocTypeAssertion && isJSDocTypeAssertion(node)) { - return false; - } - return (kinds & OuterExpressionKinds.Parentheses) !== 0; - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - case SyntaxKind.SatisfiesExpression: - return (kinds & OuterExpressionKinds.TypeAssertions) !== 0; - case SyntaxKind.NonNullExpression: - return (kinds & OuterExpressionKinds.NonNullAssertions) !== 0; - case SyntaxKind.PartiallyEmittedExpression: - return (kinds & OuterExpressionKinds.PartiallyEmittedExpressions) !== 0; - } - return false; -} - -/** @internal */ -export function skipOuterExpressions(node: Expression, kinds?: OuterExpressionKinds): Expression; -/** @internal */ -export function skipOuterExpressions(node: Node, kinds?: OuterExpressionKinds): Node; -/** @internal */ -export function skipOuterExpressions(node: Node, kinds = OuterExpressionKinds.All) { - while (isOuterExpression(node, kinds)) { - node = node.expression; - } - return node; -} - -/** @internal */ -export function skipAssertions(node: Expression): Expression; -/** @internal */ -export function skipAssertions(node: Node): Node; -/** @internal */ -export function skipAssertions(node: Node): Node { - return skipOuterExpressions(node, OuterExpressionKinds.Assertions); -} - /** @internal */ export function startOnNewLine(node: T): T { return setStartsOnNewLine(node, /*newLine*/ true); @@ -1091,36 +1017,6 @@ export function canHaveIllegalType(node: Node): node is HasIllegalType { || kind === SyntaxKind.SetAccessor; } -/** @internal */ -export function canHaveIllegalTypeParameters(node: Node): node is HasIllegalTypeParameters { - const kind = node.kind; - return kind === SyntaxKind.Constructor - || kind === SyntaxKind.GetAccessor - || kind === SyntaxKind.SetAccessor; -} - -/** @internal */ -export function canHaveIllegalDecorators(node: Node): node is HasIllegalDecorators { - const kind = node.kind; - return kind === SyntaxKind.PropertyAssignment - || kind === SyntaxKind.ShorthandPropertyAssignment - || kind === SyntaxKind.FunctionDeclaration - || kind === SyntaxKind.Constructor - || kind === SyntaxKind.IndexSignature - || kind === SyntaxKind.ClassStaticBlockDeclaration - || kind === SyntaxKind.MissingDeclaration - || kind === SyntaxKind.VariableStatement - || kind === SyntaxKind.InterfaceDeclaration - || kind === SyntaxKind.TypeAliasDeclaration - || kind === SyntaxKind.EnumDeclaration - || kind === SyntaxKind.ModuleDeclaration - || kind === SyntaxKind.ImportEqualsDeclaration - || kind === SyntaxKind.ImportDeclaration - || kind === SyntaxKind.NamespaceExportDeclaration - || kind === SyntaxKind.ExportDeclaration - || kind === SyntaxKind.ExportAssignment; -} - /** @internal */ export function canHaveIllegalModifiers(node: Node): node is HasIllegalModifiers { const kind = node.kind; @@ -1255,220 +1151,6 @@ export function isBinaryOperatorToken(node: Node): node is BinaryOperatorToken { return isBinaryOperator(node.kind); } -type BinaryExpressionState = (machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], resultHolder: { value: TResult }, outerState: TOuterState) => number; - -namespace BinaryExpressionState { - /** - * Handles walking into a `BinaryExpression`. - * @param machine State machine handler functions - * @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 { - const prevUserState = stackIndex > 0 ? userStateStack[stackIndex - 1] : undefined; - Debug.assertEqual(stateStack[stackIndex], enter); - userStateStack[stackIndex] = machine.onEnter(nodeStack[stackIndex], prevUserState, outerState); - stateStack[stackIndex] = nextState(machine, enter); - return stackIndex; - } - - /** - * Handles walking the `left` side of a `BinaryExpression`. - * @param machine State machine handler functions - * @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); - stateStack[stackIndex] = nextState(machine, left); - const nextNode = machine.onLeft(nodeStack[stackIndex].left, userStateStack[stackIndex], nodeStack[stackIndex]); - if (nextNode) { - checkCircularity(stackIndex, nodeStack, nextNode); - return pushStack(stackIndex, stateStack, nodeStack, userStateStack, nextNode); - } - return stackIndex; - } - - /** - * Handles walking the `operatorToken` of a `BinaryExpression`. - * @param machine State machine handler functions - * @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); - stateStack[stackIndex] = nextState(machine, operator); - machine.onOperator(nodeStack[stackIndex].operatorToken, userStateStack[stackIndex], nodeStack[stackIndex]); - return stackIndex; - } - - /** - * Handles walking the `right` side of a `BinaryExpression`. - * @param machine State machine handler functions - * @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); - stateStack[stackIndex] = nextState(machine, right); - const nextNode = machine.onRight(nodeStack[stackIndex].right, userStateStack[stackIndex], nodeStack[stackIndex]); - if (nextNode) { - checkCircularity(stackIndex, nodeStack, nextNode); - return pushStack(stackIndex, stateStack, nodeStack, userStateStack, nextNode); - } - return stackIndex; - } - - /** - * Handles walking out of a `BinaryExpression`. - * @param machine State machine handler functions - * @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); - stateStack[stackIndex] = nextState(machine, exit); - const result = machine.onExit(nodeStack[stackIndex], userStateStack[stackIndex]); - if (stackIndex > 0) { - stackIndex--; - if (machine.foldState) { - const side = stateStack[stackIndex] === exit ? "right" : "left"; - userStateStack[stackIndex] = machine.foldState(userStateStack[stackIndex], result, side); - } - } - else { - resultHolder.value = result; - } - return stackIndex; - } - - /** - * 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); - return stackIndex; - } - - export function nextState(machine: BinaryExpressionStateMachine, currentState: BinaryExpressionState) { - switch (currentState) { - case enter: - if (machine.onLeft) return left; - // falls through - case left: - if (machine.onOperator) return operator; - // falls through - case operator: - if (machine.onRight) return right; - // falls through - case right: return exit; - case exit: return done; - case done: return done; - default: Debug.fail("Invalid state"); - } - } - - function pushStack(stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], node: BinaryExpression) { - stackIndex++; - stateStack[stackIndex] = enter; - nodeStack[stackIndex] = node; - userStateStack[stackIndex] = undefined!; - return stackIndex; - } - - function checkCircularity(stackIndex: number, nodeStack: BinaryExpression[], node: BinaryExpression) { - if (Debug.shouldAssert(AssertionLevel.Aggressive)) { - while (stackIndex >= 0) { - Debug.assert(nodeStack[stackIndex] !== node, "Circular traversal detected."); - stackIndex--; - } - } - } -} - -/** - * 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, - ) { - } -} - -/** - * 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. - * @param onLeft Callback evaluated when walking the left side of a `BinaryExpression`. Return a `BinaryExpression` to continue walking, or `void` to advance to the right side. - * @param onRight Callback evaluated when walking the right side of a `BinaryExpression`. Return a `BinaryExpression` to continue walking, or `void` to advance to the end of the node. - * @param onExit Callback evaluated when exiting a `BinaryExpression`. The result returned will either be folded into the parent's state, or returned from the walker if at the top frame. - * @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. - * - * @internal - */ - 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; -/** - * 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. - * @param onLeft Callback evaluated when walking the left side of a `BinaryExpression`. Return a `BinaryExpression` to continue walking, or `void` to advance to the right side. - * @param onRight Callback evaluated when walking the right side of a `BinaryExpression`. Return a `BinaryExpression` to continue walking, or `void` to advance to the end of the node. - * @param onExit Callback evaluated when exiting a `BinaryExpression`. The result returned will either be folded into the parent's state, or returned from the walker if at the top frame. - * @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. - * - * @internal - */ -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; -/** @internal */ -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, -) { - const machine = new BinaryExpressionStateMachine(onEnter, onLeft, onOperator, onRight, onExit, foldState); - return trampoline; - - function trampoline(node: BinaryExpression, outerState?: TOuterState) { - const resultHolder: { value: TResult } = { value: undefined! }; - const stateStack: BinaryExpressionState[] = [BinaryExpressionState.enter]; - const nodeStack: 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); - return resultHolder.value; - } -} - /** * If `nodes` is not undefined, creates an empty `NodeArray` that preserves the `pos` and `end` of `nodes`. * @internal diff --git a/src/compiler/factory/utilitiesPublic.ts b/src/compiler/factory/utilitiesPublic.ts index 8afd72574c0fb..2acff7416a490 100644 --- a/src/compiler/factory/utilitiesPublic.ts +++ b/src/compiler/factory/utilitiesPublic.ts @@ -1,11 +1,17 @@ import { + addRange, + appendIfUnique, +} from "../core"; +import { + EmitFlags, + EmitNode, HasDecorators, HasModifiers, Node, - setTextRangePosEnd, SyntaxKind, TextRange, -} from "../_namespaces/ts"; +} from "../types"; +import { setTextRangePosEnd } from "../utilities"; export function setTextRange(range: T, location: TextRange | undefined): T { return location ? setTextRangePosEnd(range, location.pos, location.end) : range; @@ -49,4 +55,53 @@ export function canHaveDecorators(node: Node): node is HasDecorators { || kind === SyntaxKind.SetAccessor || kind === SyntaxKind.ClassExpression || kind === SyntaxKind.ClassDeclaration; -} \ No newline at end of file +} + +export function setOriginalNode(node: T, original: Node | undefined): T { + node.original = original; + if (original) { + const emitNode = original.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, + snippetElement, + } = sourceEmitNode; + if (!destEmitNode) destEmitNode = {} as 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 (helpers) { + for (const helper of helpers) { + destEmitNode.helpers = appendIfUnique(destEmitNode.helpers, helper); + } + } + if (startsOnNewLine !== undefined) destEmitNode.startsOnNewLine = startsOnNewLine; + if (snippetElement !== undefined) destEmitNode.snippetElement = snippetElement; + return destEmitNode; +} + +function mergeTokenSourceMapRanges(sourceRanges: (TextRange | undefined)[], destRanges: (TextRange | undefined)[]) { + if (!destRanges) destRanges = []; + for (const key in sourceRanges) { + destRanges[key] = sourceRanges[key]; + } + return destRanges; +} diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 5177f1d5a57ab..09c770a36e311 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -1,112 +1,124 @@ +import { DiagnosticReporter } from "./commandLineParser"; import { append, appendIfUnique, arrayFrom, + contains, + emptyArray, + endsWith, + every, + filter, + firstDefined, + forEach, + GetCanonicalFileName, + getOwnKeys, + hasProperty, + isArray, + isString, + lastOrUndefined, + length, + matchedText, + noop, + noopPush, + Pattern, + patternText, + removePrefix, + some, + sort, + startsWith, + stringContains, + toFileNameLowerCase, +} from "./core"; +import { + Comparison, + MapLike, + Push, + version, + versionMajorMinor, +} from "./corePublic"; +import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { getCommonSourceDirectory } from "./emitter"; +import { changeAnyExtension, - CharacterCodes, combinePaths, comparePaths, - Comparison, - CompilerOptions, - contains, containsPath, - createCompilerDiagnostic, - Debug, - Diagnostic, - DiagnosticMessage, - DiagnosticReporter, - Diagnostics, - directoryProbablyExists, directorySeparator, - emptyArray, - endsWith, ensureTrailingDirectorySeparator, - every, - Extension, - extensionIsTS, fileExtensionIs, fileExtensionIsOneOf, - FileReference, - filter, - firstDefined, - forEach, forEachAncestorDirectory, - formatMessage, getBaseFileName, - GetCanonicalFileName, - getCommonSourceDirectory, getDirectoryPath, - GetEffectiveTypeRootsHost, - getEmitModuleKind, - getEmitModuleResolutionKind, - getModeForUsageLocation, getNormalizedAbsolutePath, - getOwnKeys, getPathComponents, getPathFromPathComponents, - getPathsBasePath, - getPossibleOriginalInputExtensionForExtension, getRelativePathFromDirectory, getRootLength, - hasJSFileExtension, - hasProperty, hasTrailingDirectorySeparator, - hostGetCanonicalFileName, - isArray, - isExternalModuleNameRelative, isRootedDiskPath, - isString, - isStringLiteralLike, - lastOrUndefined, - length, - MapLike, - matchedText, + normalizePath, + normalizeSlashes, + pathIsRelative, + toPath, +} from "./path"; +import { perfLogger } from "./perfLogger"; +import { getModeForUsageLocation } from "./program"; +import { + Version, + VersionRange, +} from "./semver"; +import { + CharacterCodes, + CompilerOptions, + Diagnostic, + DiagnosticMessage, + Extension, + FileReference, + GetEffectiveTypeRootsHost, MatchingKeys, - matchPatternOrExact, ModuleKind, ModuleResolutionHost, ModuleResolutionKind, - noop, - noopPush, - normalizePath, - normalizeSlashes, - optionsHaveModuleResolutionChanges, PackageId, - packageIdToString, ParsedCommandLine, Path, - pathIsRelative, - Pattern, - patternText, - perfLogger, - Push, - readJson, - removeExtension, - removeFileExtension, - removePrefix, ResolutionMode, ResolvedModuleWithFailedLookupLocations, ResolvedProjectReference, ResolvedTypeReferenceDirective, ResolvedTypeReferenceDirectiveWithFailedLookupLocations, - some, - sort, SourceFile, - startsWith, - stringContains, StringLiteralLike, +} from "./types"; +import { + createCompilerDiagnostic, + directoryProbablyExists, + extensionIsTS, + formatMessage, + getEmitModuleKind, + getEmitModuleResolutionKind, + getPathsBasePath, + getPossibleOriginalInputExtensionForExtension, + hasJSFileExtension, + hostGetCanonicalFileName, + matchPatternOrExact, + optionsHaveModuleResolutionChanges, + packageIdToString, + readJson, + removeExtension, + removeFileExtension, supportedDeclarationExtensions, supportedTSImplementationExtensions, - toFileNameLowerCase, - toPath, tryExtractTSExtension, tryGetExtensionFromPath, tryParsePatterns, - version, - Version, - versionMajorMinor, - VersionRange, -} from "./_namespaces/ts"; +} from "./utilities"; +import { + isExternalModuleNameRelative, + isStringLiteralLike, +} from "./utilitiesPublic"; /** @internal */ export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void; diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 84031881431b0..c757af2ba7fe3 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -1,73 +1,79 @@ import { - __String, - allKeysStartWithDot, - AmbientModuleDeclaration, append, arrayFrom, - CharacterCodes, - combinePaths, compareBooleans, - compareNumberOfDirectorySeparators, - comparePaths, - Comparison, - CompilerOptions, - containsIgnoredPath, - containsPath, createGetCanonicalFileName, - Debug, - directorySeparator, emptyArray, endsWith, - ensurePathIsNonModuleName, - ensureTrailingDirectorySeparator, every, - ExportAssignment, - Extension, - extensionFromPath, - fileExtensionIsOneOf, - FileIncludeKind, firstDefined, flatMap, flatten, forEach, - forEachAncestorDirectory, GetCanonicalFileName, - getDirectoryPath, - getEmitModuleResolutionKind, - getImpliedNodeFormatForFile, - getModeForResolutionAtIndex, - getModuleNameStringLiteralAt, - getNodeModulePathParts, - getNormalizedAbsolutePath, getOwnKeys, + isString, + map, + mapDefined, + min, + removeSuffix, + some, + startsWith, + stringContains, +} from "./core"; +import { + Comparison, + MapLike, +} from "./corePublic"; +import { Debug } from "./debug"; +import { + isModuleBlock, + isModuleDeclaration, + isSourceFile, +} from "./factory/nodeTests"; +import { + allKeysStartWithDot, getPackageJsonTypesVersionsPaths, getPackageNameFromTypesPackageName, - getPathsBasePath, + isApplicableVersionedTypesKey, + pathContainsNodeModules, +} from "./moduleNameResolver"; +import { + combinePaths, + comparePaths, + containsPath, + directorySeparator, + ensurePathIsNonModuleName, + ensureTrailingDirectorySeparator, + fileExtensionIsOneOf, + forEachAncestorDirectory, + getDirectoryPath, + getNormalizedAbsolutePath, getRelativePathFromDirectory, getRelativePathToDirectoryOrUrl, - getSourceFileOfModule, - getSupportedExtensions, - getTextOfIdentifierOrLiteral, - hasJSFileExtension, - hasTSFileExtension, - hostGetCanonicalFileName, - Identifier, - isAmbientModule, - isApplicableVersionedTypesKey, - isExternalModuleAugmentation, - isExternalModuleNameRelative, - isModuleBlock, - isModuleDeclaration, - isNonGlobalAmbientModule, isRootedDiskPath, - isSourceFile, - isString, + normalizePath, + pathIsBareSpecifier, + pathIsRelative, + resolvePath, + startsWithDirectory, + toPath, +} from "./path"; +import { + getImpliedNodeFormatForFile, + getModeForResolutionAtIndex, + getModuleNameStringLiteralAt, +} from "./program"; +import { + __String, + AmbientModuleDeclaration, + CharacterCodes, + CompilerOptions, + ExportAssignment, + Extension, + FileIncludeKind, + Identifier, JsxEmit, - map, - mapDefined, - MapLike, - matchPatternOrExact, - min, ModuleDeclaration, ModuleKind, ModulePath, @@ -77,32 +83,40 @@ import { ModuleSpecifierOptions, ModuleSpecifierResolutionHost, NodeFlags, - NodeModulePathParts, - normalizePath, Path, - pathContainsNodeModules, - pathIsBareSpecifier, - pathIsRelative, PropertyAccessExpression, - removeFileExtension, - removeSuffix, ResolutionMode, - resolvePath, ScriptKind, - some, SourceFile, - startsWith, - startsWithDirectory, - stringContains, StringLiteral, Symbol, SymbolFlags, - toPath, - tryGetExtensionFromPath, - tryParsePatterns, TypeChecker, UserPreferences, -} from "./_namespaces/ts"; +} from "./types"; +import { + compareNumberOfDirectorySeparators, + containsIgnoredPath, + extensionFromPath, + getEmitModuleResolutionKind, + getNodeModulePathParts, + getPathsBasePath, + getSourceFileOfModule, + getSupportedExtensions, + getTextOfIdentifierOrLiteral, + hasJSFileExtension, + hasTSFileExtension, + hostGetCanonicalFileName, + isAmbientModule, + isExternalModuleAugmentation, + isNonGlobalAmbientModule, + matchPatternOrExact, + NodeModulePathParts, + removeFileExtension, + tryGetExtensionFromPath, + tryParsePatterns, +} from "./utilities"; +import { isExternalModuleNameRelative } from "./utilitiesPublic"; // Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers. diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index f1f8bd002e875..962973828c7a2 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1,10 +1,80 @@ -import * as ts from "./_namespaces/ts"; +import { convertToObjectWorker } from "./commandLineParser"; import { - AccessorDeclaration, addRange, - addRelatedInfo, - AmdDependency, append, + AssertionLevel, + concatenate, + emptyArray, + emptyMap, + findIndex, + forEach, + getSpellingSuggestion, + isArray, + lastOrUndefined, + map, + mapDefined, + noop, + some, + startsWith, + toArray, + trimString, +} from "./core"; +import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { BaseNodeFactory } from "./factory/baseNodeFactory"; +import { + createNodeFactory, + NodeFactoryFlags, +} from "./factory/nodeFactory"; +import { + isAsyncModifier, + isExportAssignment, + isExportDeclaration, + isExportModifier, + isExpressionWithTypeArguments, + isExternalModuleReference, + isFunctionTypeNode, + isIdentifier as isIdentifierNode, + isImportDeclaration, + isImportEqualsDeclaration, + isJSDocFunctionType, + isJSDocNullableType, + isJSDocReturnTag, + isJSDocTypeTag, + isJsxOpeningElement, + isJsxOpeningFragment, + isMetaProperty, + isNonNullExpression, + isPrivateIdentifier, + isSetAccessorDeclaration, + isTaggedTemplateExpression, + isTypeReferenceNode, +} from "./factory/nodeTests"; +import { + canHaveModifiers, + setTextRange, +} from "./factory/utilitiesPublic"; +import { PackageJsonInfo } from "./moduleNameResolver"; +import { + fileExtensionIsOneOf, + normalizePath, +} from "./path"; +import { perfLogger } from "./perfLogger"; +import * as performance from "./performance"; +import { + createScanner, + getLeadingCommentRanges, + isIdentifierText, + skipTrivia, + tokenIsIdentifierOrKeyword, + tokenIsIdentifierOrKeywordOrGreaterThan, + tokenToString, +} from "./scanner"; +import { textToKeywordObj } from "./scannerUtilities"; +import { tracing } from "./tracing"; +import { + AccessorDeclaration, + AmdDependency, ArrayBindingElement, ArrayBindingPattern, ArrayLiteralExpression, @@ -13,11 +83,8 @@ import { AsExpression, AssertClause, AssertEntry, - AssertionLevel, AsteriskToken, - attachFileToDiagnostics, AwaitExpression, - BaseNodeFactory, BinaryExpression, BinaryOperatorToken, BindingElement, @@ -29,7 +96,6 @@ import { BreakStatement, CallExpression, CallSignatureDeclaration, - canHaveModifiers, CaseBlock, CaseClause, CaseOrDefaultClause, @@ -46,35 +112,22 @@ import { commentPragmas, CommentRange, ComputedPropertyName, - concatenate, ConditionalExpression, ConditionalTypeNode, ConstructorDeclaration, ConstructorTypeNode, ConstructSignatureDeclaration, - containsParseError, ContinueStatement, - convertToObjectWorker, - createDetachedDiagnostic, - createNodeFactory, - createScanner, - createTextChangeRange, - createTextSpanFromBounds, - Debug, Decorator, DefaultClause, DeleteExpression, Diagnostic, DiagnosticMessage, - Diagnostics, DiagnosticWithDetachedLocation, DoStatement, DotDotDotToken, ElementAccessExpression, - emptyArray, - emptyMap, EndOfFileToken, - ensureScriptKind, EntityName, EnumDeclaration, EnumMember, @@ -86,10 +139,7 @@ import { ExpressionStatement, ExpressionWithTypeArguments, ExternalModuleReference, - fileExtensionIsOneOf, FileReference, - findIndex, - forEach, ForEachChildNodes, ForInOrOfStatement, ForInStatement, @@ -100,20 +150,10 @@ import { FunctionOrConstructorTypeNode, FunctionTypeNode, GetAccessorDeclaration, - getBinaryOperatorPrecedence, - getFullWidth, - getJSDocCommentRanges, - getLanguageVariant, - getLastChild, - getLeadingCommentRanges, - getSpellingSuggestion, - getTextOfNodeFromSourceText, HasJSDoc, - hasJSDocNodes, HasModifiers, HeritageClause, Identifier, - idText, IfStatement, ImportClause, ImportDeclaration, @@ -127,37 +167,6 @@ import { InferTypeNode, InterfaceDeclaration, IntersectionTypeNode, - isArray, - isAssignmentOperator, - isAsyncModifier, - isClassMemberModifier, - isExportAssignment, - isExportDeclaration, - isExportModifier, - isExpressionWithTypeArguments, - isExternalModuleReference, - isFunctionTypeNode, - isIdentifierText, - isImportDeclaration, - isImportEqualsDeclaration, - isJSDocFunctionType, - isJSDocNullableType, - isJSDocReturnTag, - isJSDocTypeTag, - isJsxOpeningElement, - isJsxOpeningFragment, - isKeyword, - isLeftHandSideExpression, - isLiteralKind, - isMetaProperty, - isModifierKind, - isNonNullExpression, - isPrivateIdentifier, - isSetAccessorDeclaration, - isStringOrNumericLiteralLike, - isTaggedTemplateExpression, - isTemplateLiteralKind, - isTypeReferenceNode, IterationStatement, JSDoc, JSDocAllType, @@ -226,13 +235,10 @@ import { JsxTokenSyntaxKind, LabeledStatement, LanguageVariant, - lastOrUndefined, LeftHandSideExpression, LiteralExpression, LiteralLikeNode, LiteralTypeNode, - map, - mapDefined, MappedTypeNode, MemberExpression, MetaProperty, @@ -244,11 +250,9 @@ import { ModifierFlags, ModifierLike, ModifiersArray, - modifiersToFlags, ModuleBlock, ModuleDeclaration, ModuleKind, - Mutable, NamedExportBindings, NamedExports, NamedImports, @@ -261,28 +265,20 @@ import { NewExpression, Node, NodeArray, - NodeFactoryFlags, + NodeFactory, NodeFlags, - nodeIsMissing, - nodeIsPresent, NonNullExpression, - noop, - normalizePath, NoSubstitutionTemplateLiteral, NullLiteral, NumericLiteral, - objectAllocator, ObjectBindingPattern, ObjectLiteralElementLike, ObjectLiteralExpression, - OperatorPrecedence, OptionalTypeNode, - PackageJsonInfo, ParameterDeclaration, ParenthesizedExpression, ParenthesizedTypeNode, PartiallyEmittedExpression, - perfLogger, PlusToken, PostfixUnaryExpression, PostfixUnaryOperator, @@ -314,22 +310,12 @@ import { ScriptKind, ScriptTarget, SetAccessorDeclaration, - setParent, - setParentRecursive, - setTextRange, - setTextRangePos, - setTextRangePosEnd, - setTextRangePosWidth, ShorthandPropertyAssignment, - skipTrivia, - some, SourceFile, SpreadAssignment, SpreadElement, - startsWith, Statement, StringLiteral, - supportedDeclarationExtensions, SwitchStatement, SyntaxKind, TaggedTemplateExpression, @@ -342,23 +328,13 @@ import { TemplateSpan, TemplateTail, TextChangeRange, - textChangeRangeIsUnchanged, - textChangeRangeNewSpan, TextRange, - textSpanEnd, - textToKeywordObj, ThisExpression, ThisTypeNode, ThrowStatement, - toArray, Token, TokenFlags, - tokenIsIdentifierOrKeyword, - tokenIsIdentifierOrKeywordOrGreaterThan, - tokenToString, - tracing, TransformFlags, - trimString, TryStatement, TupleTypeNode, TypeAliasDeclaration, @@ -383,8 +359,49 @@ import { WhileStatement, WithStatement, YieldExpression, -} from "./_namespaces/ts"; -import * as performance from "./_namespaces/ts.performance"; +} from "./types"; +import { + addRelatedInfo, + attachFileToDiagnostics, + containsParseError, + createDetachedDiagnostic, + ensureScriptKind, + getBinaryOperatorPrecedence, + getFullWidth, + getJSDocCommentRanges, + getLanguageVariant, + getLastChild, + getTextOfNodeFromSourceText, + isAssignmentOperator, + isKeyword, + isStringOrNumericLiteralLike, + modifiersToFlags, + Mutable, + nodeIsMissing, + nodeIsPresent, + objectAllocator, + OperatorPrecedence, + setParent, + setParentRecursive, + setTextRangePos, + setTextRangePosEnd, + setTextRangePosWidth, + supportedDeclarationExtensions, +} from "./utilities"; +import { + createTextChangeRange, + createTextSpanFromBounds, + hasJSDocNodes, + idText, + isClassMemberModifier, + isLeftHandSideExpression, + isLiteralKind, + isModifierKind, + isTemplateLiteralKind, + textChangeRangeIsUnchanged, + textChangeRangeNewSpan, + textSpanEnd, +} from "./utilitiesPublic"; const enum SignatureFlags { None = 0, @@ -421,7 +438,7 @@ export const parseBaseNodeFactory: BaseNodeFactory = { }; /** @internal */ -export const parseNodeFactory = createNodeFactory(NodeFactoryFlags.NoParenthesizerRules, parseBaseNodeFactory); +export const parseNodeFactory: NodeFactory = createNodeFactory(NodeFactoryFlags.NoParenthesizerRules, parseBaseNodeFactory); function visitNode(cbNode: (node: Node) => T, node: Node | undefined): T | undefined { return node && cbNode(node); @@ -2295,7 +2312,7 @@ namespace Parser { } // Otherwise, if this isn't a well-known keyword-like identifier, give the generic fallback message. - const expressionText = ts.isIdentifier(node) ? idText(node) : undefined; + const expressionText = isIdentifierNode(node) ? idText(node) : undefined; if (!expressionText || !isIdentifierText(expressionText, languageVersion)) { parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.SemicolonToken)); return; @@ -6928,7 +6945,7 @@ namespace Parser { let node: ExpressionStatement | LabeledStatement; const hasParen = token() === SyntaxKind.OpenParenToken; const expression = allowInAnd(parseExpression); - if (ts.isIdentifier(expression) && parseOptional(SyntaxKind.ColonToken)) { + if (isIdentifierNode(expression) && parseOptional(SyntaxKind.ColonToken)) { node = factory.createLabeledStatement(expression, parseStatement()); } else { @@ -9017,7 +9034,7 @@ namespace Parser { case SyntaxKind.ArrayType: return isObjectOrObjectArrayTypeReference((node as ArrayTypeNode).elementType); default: - return isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "Object" && !node.typeArguments; + return isTypeReferenceNode(node) && isIdentifierNode(node.typeName) && node.typeName.escapedText === "Object" && !node.typeArguments; } } @@ -9287,8 +9304,8 @@ namespace Parser { } function escapedTextsEqual(a: EntityName, b: EntityName): boolean { - while (!ts.isIdentifier(a) || !ts.isIdentifier(b)) { - if (!ts.isIdentifier(a) && !ts.isIdentifier(b) && a.right.escapedText === b.right.escapedText) { + while (!isIdentifierNode(a) || !isIdentifierNode(b)) { + if (!isIdentifierNode(a) && !isIdentifierNode(b) && a.right.escapedText === b.right.escapedText) { a = a.left; b = b.left; } @@ -9313,7 +9330,7 @@ namespace Parser { const child = tryParseChildTag(target, indent); if (child && (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) && target !== PropertyLikeParse.CallbackParameter && - name && (ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) { + name && (isIdentifierNode(child.name) || !escapedTextsEqual(name, child.name.left))) { return false; } return child; diff --git a/src/compiler/path.ts b/src/compiler/path.ts index b963c9e0cc929..6762ea7583037 100644 --- a/src/compiler/path.ts +++ b/src/compiler/path.ts @@ -1,10 +1,7 @@ import { - CharacterCodes, compareStringsCaseInsensitive, compareStringsCaseSensitive, compareValues, - Comparison, - Debug, endsWith, equateStringsCaseInsensitive, equateStringsCaseSensitive, @@ -12,11 +9,16 @@ import { getStringComparer, identity, lastOrUndefined, - Path, some, startsWith, stringContains, -} from "./_namespaces/ts"; +} from "./core"; +import { Comparison } from "./corePublic"; +import { Debug } from "./debug"; +import { + CharacterCodes, + Path, +} from "./types"; /** * Internally, we represent paths as strings with '/' as the directory separator. diff --git a/src/compiler/perfLogger.ts b/src/compiler/perfLogger.ts index fd8a559c753c3..4d2074b01b95c 100644 --- a/src/compiler/perfLogger.ts +++ b/src/compiler/perfLogger.ts @@ -1,4 +1,4 @@ -import { noop } from "./_namespaces/ts"; +import { noop } from "./core"; /** @internal */ export interface PerfLogger { diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index 166163784abee..e18ba9acd97f4 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -1,13 +1,15 @@ +import { noop } from "./core"; +import { Debug } from "./debug"; import { - Debug, - noop, Performance, PerformanceHooks, - sys, - System, timestamp, tryGetNativePerformanceHooks, -} from "./_namespaces/ts"; +} from "./performanceCore"; +import { + sys, + System, +} from "./sys"; /** Performance measurements for the compiler. */ diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index 9e20bddb69480..5747a138dcfec 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -1,8 +1,8 @@ +import { isNodeLikeSystem } from "./core"; import { - isNodeLikeSystem, Version, VersionRange, -} from "./_namespaces/ts"; +} from "./semver"; // The following definitions provide the minimum compatible support for the Web Performance User Timings API // between browsers and NodeJS: diff --git a/src/compiler/program.ts b/src/compiler/program.ts index f1f67c0e87e5f..8873a05950195 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1,320 +1,355 @@ -import * as ts from "./_namespaces/ts"; +import { BuilderProgram } from "./builderPublic"; +import { createTypeChecker } from "./checker"; +import { + DiagnosticReporter, + inverseJsxOptionMap, + libMap, + libs, + ParseConfigFileHost, + parseJsonSourceFileConfigFileContent, + sourceFileAffectingCompilerOptions, + targetOptionDeclaration, +} from "./commandLineParser"; import { - __String, - addEmitFlags, addRange, append, arrayFrom, arrayIsEqualTo, - AsExpression, - AssertClause, - BuilderProgram, - CancellationToken, - canHaveModifiers, - chainDiagnosticMessages, - changeExtension, - changesAffectingProgramStructure, - changesAffectModuleResolution, clone, - combinePaths, - CommentDirective, - CommentDirectivesMap, - compareDataObjects, - comparePaths, compareValues, - Comparison, - CompilerHost, - CompilerOptions, - computeLineAndCharacterOfPosition, concatenate, contains, - containsIgnoredPath, - containsPath, - convertToRelativePath, - createCommentDirectivesMap, - createCompilerDiagnostic, - createCompilerDiagnosticFromMessageChain, - createDiagnosticCollection, - createDiagnosticForNodeInSourceFile, - createDiagnosticForRange, - createFileDiagnostic, - createFileDiagnosticFromMessageChain, createGetCanonicalFileName, + createMultiMap, + emptyArray, + equateStringsCaseInsensitive, + equateStringsCaseSensitive, + filter, + find, + firstDefined, + firstDefinedIterator, + flatMap, + flatten, + forEach, + GetCanonicalFileName, + getSpellingSuggestion, + hasProperty, + identity, + isArray, + isString, + length, + mapDefined, + mapDefinedIterator, + maybeBind, + memoize, + noop, + padLeft, + removePrefix, + removeSuffix, + returnFalse, + returnUndefined, + some, + stableSort, + startsWith, + stringContains, + toFileNameLowerCase, + trimStringEnd, +} from "./core"; +import { + Comparison, + SortedReadonlyArray, +} from "./corePublic"; +import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { + getCommonSourceDirectory as _getCommonSourceDirectory, + emitFiles, + forEachEmittedFile, + getCommonSourceDirectoryOfConfig, + getOutputDeclarationFileName, + getOutputPathsForBundle, + getTsBuildInfoEmitOutputFilePath, + isBuildInfoFile, + notImplementedResolver, +} from "./emitter"; +import { addEmitFlags } from "./factory/emitNode"; +import { createInputFilesWithFilePaths, + factory, +} from "./factory/nodeFactory"; +import { + isArrayLiteralExpression, + isDecorator, + isExportDeclaration, + isImportDeclaration, + isImportEqualsDeclaration, + isImportSpecifier, + isImportTypeNode, + isModuleDeclaration, + isObjectLiteralExpression, + isStringLiteral, +} from "./factory/nodeTests"; +import { canHaveModifiers } from "./factory/utilitiesPublic"; +import { createModeAwareCache, createModuleResolutionCache, - createMultiMap, - CreateProgramOptions, + createTypeReferenceDirectiveResolutionCache, + getAutomaticTypeDirectiveNames, + getPackageScopeForPath, + getResolutionMode, + getResolutionName, + getTemporaryModuleResolutionState, + isTraceEnabled, + ModuleResolutionCache, + nodeModulesPathPart, + PackageJsonInfoCache, + resolveModuleName, + resolveModuleNameFromCache, + resolveTypeReferenceDirective, + trace, + TypeReferenceDirectiveResolutionCache, + zipToModeAwareCache, +} from "./moduleNameResolver"; +import { createSourceFile, CreateSourceFileOptions, - createSymlinkCache, - createTypeChecker, - createTypeReferenceDirectiveResolutionCache, + forEachChild, + forEachChildRecursively, + isDeclarationFileName, + isExternalModule, + parseIsolatedEntityName, +} from "./parser"; +import { + toPath as _toPath, + combinePaths, + comparePaths, + containsPath, + convertToRelativePath, + directorySeparator, + ensureTrailingDirectorySeparator, + fileExtensionIs, + fileExtensionIsOneOf, + forEachAncestorDirectory, + getBaseFileName, + getDirectoryPath, + getNormalizedAbsolutePath, + getNormalizedAbsolutePathWithoutRoot, + getNormalizedPathComponents, + getPathFromPathComponents, + getRootLength, + hasExtension, + isRootedDiskPath, + normalizePath, + pathIsAbsolute, + pathIsRelative, +} from "./path"; +import * as performance from "./performance"; +import { + computeLineAndCharacterOfPosition, + getLineAndCharacterOfPosition, + getLineStarts, + getPositionOfLineAndCharacter, + isIdentifierText, + skipTrivia, + tokenToString, +} from "./scanner"; +import { + sys, + System, +} from "./sys"; +import { tracing } from "./tracing"; +import { + getTransformers, + noTransformers, +} from "./transformer"; +import { + getDeclarationDiagnostics as _getDeclarationDiagnostics, +} from "./transformers/declarations"; +import { resolveConfigFileProjectName } from "./tsbuild"; +import { + __String, + AsExpression, + AssertClause, + CancellationToken, + CommentDirective, + CommentDirectivesMap, + CompilerHost, + CompilerOptions, + CreateProgramOptions, CustomTransformers, - Debug, DeclarationWithTypeParameterChildren, Diagnostic, DiagnosticCategory, diagnosticCategoryName, DiagnosticMessage, DiagnosticMessageChain, - DiagnosticReporter, - Diagnostics, DiagnosticWithLocation, - directorySeparator, - DirectoryStructureHost, - emitFiles, EmitFlags, EmitHost, EmitOnly, EmitResult, - emptyArray, - ensureTrailingDirectorySeparator, - equateStringsCaseInsensitive, - equateStringsCaseSensitive, - explainIfFileIsRedirectAndImpliedFormat, ExportAssignment, ExportDeclaration, Extension, - extensionFromPath, - externalHelpersModuleNameText, - factory, - fileExtensionIs, - fileExtensionIsOneOf, FileIncludeKind, FileIncludeReason, - fileIncludeReasonToDiagnostics, FilePreprocessingDiagnostics, FilePreprocessingDiagnosticsKind, FileReference, - filter, - find, - firstDefined, - firstDefinedIterator, - flatMap, - flatten, - forEach, - forEachAncestorDirectory, - forEachChild, - forEachChildRecursively, - forEachEmittedFile, - forEachEntry, - forEachKey, FunctionLikeDeclaration, - getAllowJSCompilerOption, - getAutomaticTypeDirectiveNames, - getBaseFileName, - GetCanonicalFileName, - getCommonSourceDirectoryOfConfig, - getDefaultLibFileName, - getDirectoryPath, - getEmitDeclarations, - getEmitModuleKind, - getEmitModuleResolutionKind, - getEmitScriptTarget, - getErrorSpanForNode, - getExternalModuleName, - getJSXImplicitImportBase, - getJSXRuntimeImport, - getLineAndCharacterOfPosition, - getLineStarts, - getMatchedFileSpec, - getMatchedIncludeSpec, - getNewLineCharacter, - getNormalizedAbsolutePath, - getNormalizedAbsolutePathWithoutRoot, - getNormalizedPathComponents, - getOutputDeclarationFileName, - getOutputPathsForBundle, - getPackageScopeForPath, - getPathFromPathComponents, - getPositionOfLineAndCharacter, - getPropertyArrayElementValue, - getPropertyAssignment, - getResolutionMode, - getResolutionName, - getResolvedModule, - getResolvedTypeReferenceDirective, - getRootLength, - getSetExternalModuleIndicator, - getSpellingSuggestion, - getStrictOptionValue, - getSupportedExtensions, - getSupportedExtensionsWithJsonIfResolveJsonModule, - getTemporaryModuleResolutionState, - getTextOfIdentifierOrLiteral, - getTransformers, - getTsBuildInfoEmitOutputFilePath, - getTsConfigObjectLiteralExpression, - getTsConfigPropArray, - getTsConfigPropArrayElementValue, HasChangedAutomaticTypeDirectiveNames, - hasChangesInResolutions, - hasExtension, HasInvalidatedResolutions, - hasJSDocNodes, - hasJSFileExtension, - hasJsonModuleEmitEnabled, - hasProperty, - hasSyntacticModifier, - hasZeroOrOneAsteriskCharacter, HeritageClause, Identifier, - identity, ImportClause, ImportDeclaration, ImportOrExportSpecifier, InputFiles, - inverseJsxOptionMap, - isAmbientModule, - isAnyImportOrReExport, - isArray, - isArrayLiteralExpression, - isBuildInfoFile, - isCheckJsEnabledForFile, - isDeclarationFileName, - isDecorator, - isExportDeclaration, - isExternalModule, - isExternalModuleNameRelative, - isIdentifierText, - isImportCall, - isImportDeclaration, - isImportEqualsDeclaration, - isImportSpecifier, - isImportTypeNode, - isIncrementalCompilation, - isInJSFile, - isLiteralImportTypeNode, - isModifier, - isModuleDeclaration, - isObjectLiteralExpression, - isPlainJsFile, - isRequireCall, - isRootedDiskPath, - isSourceFileJS, - isString, - isStringLiteral, - isStringLiteralLike, - isTraceEnabled, JsonSourceFile, JsxEmit, - length, - libMap, - libs, - mapDefined, - mapDefinedIterator, - maybeBind, - memoize, MethodDeclaration, ModifierFlags, ModifierLike, ModuleBlock, ModuleDeclaration, ModuleKind, - ModuleResolutionCache, ModuleResolutionHost, ModuleResolutionInfo, - moduleResolutionIsEqualTo, ModuleResolutionKind, - Mutable, Node, NodeArray, NodeFlags, - nodeModulesPathPart, NodeWithTypeArguments, - noop, - normalizePath, - notImplementedResolver, - noTransformers, ObjectLiteralExpression, OperationCanceledException, - optionsHaveChanges, - outFile, PackageId, - packageIdToPackageName, - packageIdToString, - PackageJsonInfoCache, - padLeft, ParameterDeclaration, - ParseConfigFileHost, ParsedCommandLine, - parseIsolatedEntityName, - parseJsonSourceFileConfigFileContent, Path, - pathIsAbsolute, - pathIsRelative, Program, - ProgramHost, ProjectReference, ProjectReferenceFile, - projectReferenceIsEqualTo, PropertyDeclaration, ReferencedFile, - removeFileExtension, - removePrefix, - removeSuffix, - resolutionExtensionIsTSOrJson, ResolutionMode, - resolveConfigFileProjectName, ResolvedConfigFileName, ResolvedModuleFull, ResolvedModuleWithFailedLookupLocations, ResolvedProjectReference, ResolvedTypeReferenceDirective, - resolveModuleName, - resolveModuleNameFromCache, - resolveTypeReferenceDirective, - returnFalse, - returnUndefined, SatisfiesExpression, ScriptKind, ScriptTarget, - setParent, - setParentRecursive, - setResolvedModule, - setResolvedTypeReferenceDirective, - skipTrivia, - skipTypeChecking, - some, - sortAndDeduplicateDiagnostics, - SortedReadonlyArray, SourceFile, - sourceFileAffectingCompilerOptions, - sourceFileMayBeEmitted, SourceOfProjectReferenceRedirect, - stableSort, - startsWith, Statement, - stringContains, StringLiteral, StringLiteralLike, StructureIsReused, - supportedJSExtensionsFlat, - SymlinkCache, SyntaxKind, - sys, - targetOptionDeclaration, - toFileNameLowerCase, - tokenToString, - trace, - tracing, - trimStringEnd, TsConfigSourceFile, TypeChecker, - typeDirectiveIsEqualTo, - TypeReferenceDirectiveResolutionCache, TypeReferenceDirectiveResolutionInfo, UnparsedSource, VariableDeclaration, VariableStatement, - walkUpParenthesizedExpressions, WriteFileCallback, WriteFileCallbackData, +} from "./types"; +import { + chainDiagnosticMessages, + changeExtension, + changesAffectingProgramStructure, + changesAffectModuleResolution, + compareDataObjects, + containsIgnoredPath, + createCommentDirectivesMap, + createCompilerDiagnostic, + createCompilerDiagnosticFromMessageChain, + createDiagnosticCollection, + createDiagnosticForNodeInSourceFile, + createDiagnosticForRange, + createFileDiagnostic, + createFileDiagnosticFromMessageChain, + createSymlinkCache, + extensionFromPath, + externalHelpersModuleNameText, + forEachEntry, + forEachKey, + getAllowJSCompilerOption, + getEmitDeclarations, + getEmitModuleKind, + getEmitModuleResolutionKind, + getEmitScriptTarget, + getErrorSpanForNode, + getExternalModuleName, + getJSXImplicitImportBase, + getJSXRuntimeImport, + getNewLineCharacter, + getPropertyArrayElementValue, + getPropertyAssignment, + getResolvedModule, + getResolvedTypeReferenceDirective, + getSetExternalModuleIndicator, + getStrictOptionValue, + getSupportedExtensions, + getSupportedExtensionsWithJsonIfResolveJsonModule, + getTextOfIdentifierOrLiteral, + getTsConfigObjectLiteralExpression, + getTsConfigPropArray, + getTsConfigPropArrayElementValue, + hasChangesInResolutions, + hasJSFileExtension, + hasJsonModuleEmitEnabled, + hasSyntacticModifier, + hasZeroOrOneAsteriskCharacter, + isAmbientModule, + isAnyImportOrReExport, + isCheckJsEnabledForFile, + isImportCall, + isIncrementalCompilation, + isInJSFile, + isLiteralImportTypeNode, + isPlainJsFile, + isRequireCall, + isSourceFileJS, + moduleResolutionIsEqualTo, + Mutable, + optionsHaveChanges, + outFile, + packageIdToPackageName, + packageIdToString, + projectReferenceIsEqualTo, + removeFileExtension, + resolutionExtensionIsTSOrJson, + setParent, + setParentRecursive, + setResolvedModule, + setResolvedTypeReferenceDirective, + skipTypeChecking, + sourceFileMayBeEmitted, + supportedJSExtensionsFlat, + SymlinkCache, + typeDirectiveIsEqualTo, + walkUpParenthesizedExpressions, writeFileEnsuringDirectories, - zipToModeAwareCache, -} from "./_namespaces/ts"; -import * as performance from "./_namespaces/ts.performance"; +} from "./utilities"; +import { + getDefaultLibFileName, + hasJSDocNodes, + isExternalModuleNameRelative, + isModifier, + isStringLiteralLike, + sortAndDeduplicateDiagnostics, +} from "./utilitiesPublic"; +import { + explainIfFileIsRedirectAndImpliedFormat, + fileIncludeReasonToDiagnostics, + getMatchedFileSpec, + getMatchedIncludeSpec, +} from "./watch"; +import { ProgramHost } from "./watchPublic"; +import { DirectoryStructureHost } from "./watchUtilities"; export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string | undefined { return forEachAncestorDirectory(searchPath, ancestor => { @@ -437,7 +472,7 @@ export function createWriteFileMeasuringIO( } /** @internal */ -export function createCompilerHostWorker(options: CompilerOptions, setParentNodes?: boolean, system = sys): CompilerHost { +export function createCompilerHostWorker(options: CompilerOptions, setParentNodes?: boolean, system: System = sys): CompilerHost { const existingDirectories = new Map(); const getCanonicalFileName = createGetCanonicalFileName(system.useCaseSensitiveFileNames); function directoryExists(directoryPath: string): boolean { @@ -848,7 +883,7 @@ export interface SourceFileImportsList { * Calculates the resulting resolution mode for some reference in some file - this is generally the explicitly * provided resolution mode in the reference, unless one is not present, in which case it is the mode of the containing file. */ -export function getModeForFileReference(ref: FileReference | string, containingFileMode: ResolutionMode) { +export function getModeForFileReference(ref: FileReference | string, containingFileMode: ResolutionMode): ResolutionMode { return (isString(ref) ? containingFileMode : ref.resolutionMode) || containingFileMode; } @@ -890,7 +925,7 @@ export function isExclusivelyTypeOnlyImportOrExport(decl: ImportDeclaration | Ex * @param usage The module reference string * @returns The final resolution mode of the import */ -export function getModeForUsageLocation(file: { impliedNodeFormat?: ResolutionMode }, usage: StringLiteralLike) { +export function getModeForUsageLocation(file: { impliedNodeFormat?: ResolutionMode }, usage: StringLiteralLike): ResolutionMode { if (file.impliedNodeFormat === undefined) return undefined; if ((isImportDeclaration(usage.parent) || isExportDeclaration(usage.parent))) { const isTypeOnly = isExclusivelyTypeOnlyImportOrExport(usage.parent); @@ -969,6 +1004,13 @@ export function loadWithModeAwareCache(names: readonly StringLiteralLike[] | export function forEachResolvedProjectReference( resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined, cb: (resolvedProjectReference: ResolvedProjectReference, parent: ResolvedProjectReference | undefined) => T | undefined +): T | undefined { + return forEachResolvedProjectReferenceWorker(resolvedProjectReferences, cb); +} + +function forEachResolvedProjectReferenceWorker( + resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined, + cb: (resolvedProjectReference: ResolvedProjectReference, parent: ResolvedProjectReference | undefined) => T | undefined ): T | undefined { return forEachProjectReference(/*projectReferences*/ undefined, resolvedProjectReferences, (resolvedRef, parent) => resolvedRef && cb(resolvedRef, parent)); } @@ -1840,13 +1882,13 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } function toPath(fileName: string): Path { - return ts.toPath(fileName, currentDirectory, getCanonicalFileName); + return _toPath(fileName, currentDirectory, getCanonicalFileName); } function getCommonSourceDirectory() { if (commonSourceDirectory === undefined) { const emittedFiles = filter(files, file => sourceFileMayBeEmitted(file, program)); - commonSourceDirectory = ts.getCommonSourceDirectory( + commonSourceDirectory = _getCommonSourceDirectory( options, () => mapDefined(emittedFiles, file => file.isDeclarationFile ? undefined : file.fileName), currentDirectory, @@ -2948,7 +2990,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg 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 _getDeclarationDiagnostics(getEmitHost(noop), resolver, sourceFile) || emptyArray; }); } @@ -3521,7 +3563,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg function forEachResolvedProjectReference( cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined ): T | undefined { - return ts.forEachResolvedProjectReference(resolvedProjectReferences, cb); + return forEachResolvedProjectReferenceWorker(resolvedProjectReferences, cb); } function getSourceOfProjectReferenceRedirect(path: Path) { diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index f63ecc8773fb7..2ae39a4ec42f3 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -1,91 +1,108 @@ -import * as ts from "./_namespaces/ts"; import { arrayToMap, - CachedDirectoryStructureHost, - CacheWithRedirects, - CharacterCodes, - clearMap, - closeFileWatcher, - closeFileWatcherOf, - CompilerOptions, contains, + createMultiMap, + emptyArray, + emptyIterator, + endsWith, + firstDefinedIterator, + GetCanonicalFileName, + isString, + length, + memoize, + removeSuffix, + returnTrue, + some, + startsWith, + stringContains, + unorderedRemoveItem, +} from "./core"; +import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { + CacheWithRedirects, createCacheWithRedirects, createModeAwareCache, createModuleResolutionCache, - createMultiMap, createTypeReferenceDirectiveResolutionCache, - Debug, - Diagnostics, + getEffectiveTypeRoots, + getResolutionName, + isTraceEnabled, + loadModuleFromGlobalCache, + ModeAwareCache, + ModuleResolutionCache, + parseNodeModuleFromPath, + pathContainsNodeModules, + PerModuleNameCache, + resolveModuleName, + resolveTypeReferenceDirective, + trace, +} from "./moduleNameResolver"; +import { directorySeparator, - DirectoryWatcherCallback, - emptyArray, - emptyIterator, - endsWith, - Extension, - extensionIsTS, fileExtensionIs, fileExtensionIsOneOf, - FileReference, - FileWatcher, - FileWatcherCallback, - firstDefinedIterator, - GetCanonicalFileName, getDirectoryPath, - getEffectiveTypeRoots, - getModeForFileReference, - getModeForResolutionAtIndex, - getModeForUsageLocation, getNormalizedAbsolutePath, - getResolutionName, getRootLength, - HasInvalidatedResolutions, - ignoredPaths, - inferredTypesContainingFile, - isEmittedFileOfProgram, - isExternalModuleNameRelative, - isExternalOrCommonJsModule, isNodeModulesDirectory, isRootedDiskPath, - isString, - isStringLiteralLike, - isTraceEnabled, - length, - loadModuleFromGlobalCache, - memoize, + normalizePath, + removeTrailingDirectorySeparator, +} from "./path"; +import { + getModeForFileReference, + getModeForResolutionAtIndex, + getModeForUsageLocation, + inferredTypesContainingFile, +} from "./program"; +import { + DirectoryWatcherCallback, + FileWatcher, + FileWatcherCallback, + ignoredPaths, +} from "./sys"; +import { + CharacterCodes, + CompilerOptions, + Extension, + FileReference, + HasInvalidatedResolutions, MinimalResolutionCacheHost, - ModeAwareCache, - ModuleResolutionCache, ModuleResolutionHost, ModuleResolutionInfo, - mutateMap, - noopFileWatcher, - normalizePath, PackageId, - packageIdToString, - parseNodeModuleFromPath, Path, - pathContainsNodeModules, - PerModuleNameCache, Program, - removeSuffix, - removeTrailingDirectorySeparator, - resolutionExtensionIsTSOrJson, ResolutionMode, ResolvedModuleFull, ResolvedModuleWithFailedLookupLocations, ResolvedProjectReference, ResolvedTypeReferenceDirective, ResolvedTypeReferenceDirectiveWithFailedLookupLocations, - returnTrue, - some, SourceFile, - startsWith, - stringContains, - trace, TypeReferenceDirectiveResolutionInfo, - unorderedRemoveItem, WatchDirectoryFlags, -} from "./_namespaces/ts"; +} from "./types"; +import { + clearMap, + closeFileWatcher, + extensionIsTS, + isExternalOrCommonJsModule, + mutateMap, + packageIdToString, + resolutionExtensionIsTSOrJson, +} from "./utilities"; +import { + isExternalModuleNameRelative, + isStringLiteralLike, +} from "./utilitiesPublic"; +import { noopFileWatcher } from "./watch"; +import { + CachedDirectoryStructureHost, + closeFileWatcherOf, + isEmittedFileOfProgram, +} from "./watchUtilities"; /** * This is the cache of module/typedirectives resolution that can be retained across program @@ -473,8 +490,8 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD hasChangedAutomaticTypeDirectiveNames = false; } - function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, _containingSourceFile?: never, mode?: ResolutionMode): CachedResolvedModuleWithFailedLookupLocations { - const primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache, redirectedReference, mode); + function resolveModuleNameHelper(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, _containingSourceFile?: never, mode?: ResolutionMode): CachedResolvedModuleWithFailedLookupLocations { + const primaryResult = 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) { return primaryResult; @@ -506,8 +523,8 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD return primaryResult; } - function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, _containingSourceFile?: SourceFile, resolutionMode?: ResolutionMode): CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations { - return ts.resolveTypeReferenceDirective(typeReferenceDirectiveName, containingFile, options, host, redirectedReference, typeReferenceDirectiveResolutionCache, resolutionMode); + function resolveTypeReferenceDirectiveHelper(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, _containingSourceFile?: SourceFile, resolutionMode?: ResolutionMode): CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations { + return resolveTypeReferenceDirective(typeReferenceDirectiveName, containingFile, options, host, redirectedReference, typeReferenceDirectiveResolutionCache, resolutionMode); } interface ResolveNamesWithLocalCacheInput { @@ -583,7 +600,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD const resolved = getResolutionWithResolvedFileName(resolution); trace( host, - loader === resolveModuleName as unknown ? + loader === resolveModuleNameHelper as unknown ? resolved?.resolvedFileName ? resolved.packageId ? Diagnostics.Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3_with_Package_ID_4 : @@ -627,7 +644,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD const resolved = getResolutionWithResolvedFileName(resolution); trace( host, - loader === resolveModuleName as unknown ? + loader === resolveModuleNameHelper as unknown ? resolved?.resolvedFileName ? resolved.packageId ? Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : @@ -651,7 +668,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD } // If resolving type reference directive we dont need containingSourceFile to determine if we can use resolutionInfo - if (resolutionInfo && (loader === resolveTypeReferenceDirective as unknown || containingSourceFile)) { + if (resolutionInfo && (loader === resolveTypeReferenceDirectiveHelper as unknown || containingSourceFile)) { resolutionInfo.reusedNames?.forEach(entry => seenNamesInFile.set( getResolutionName(entry), !isString(entry) && isStringLiteralLike(entry) ? @@ -705,7 +722,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD redirectedReference, cache: resolvedTypeReferenceDirectives, perDirectoryCacheWithRedirects: perDirectoryResolvedTypeReferenceDirectives, - loader: resolveTypeReferenceDirective, + loader: resolveTypeReferenceDirectiveHelper, getResolutionWithResolvedFileName: getResolvedTypeReferenceDirective, shouldRetryResolution: resolution => resolution.resolvedTypeReferenceDirective === undefined, containingSourceFileMode: containingFileMode, @@ -727,7 +744,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD redirectedReference, cache: resolvedModuleNames, perDirectoryCacheWithRedirects: perDirectoryResolvedModuleNames, - loader: resolveModuleName, + loader: resolveModuleNameHelper, getResolutionWithResolvedFileName: getResolvedModule, shouldRetryResolution: resolution => !resolution.resolvedModule || !resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension), reusedNames, diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index bdb2fe6ef239e..bb35ca59c214c 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -2,31 +2,40 @@ import { append, arraysEqual, binarySearch, + compareValues, + identity, + isLineBreak, + isWhiteSpaceLike, + isWhiteSpaceSingleLine, + trimStringStart, +} from "./core"; +// import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { + textToKeyword, + textToToken, +} from "./scannerUtilities"; +import { CharacterCodes, CommentDirective, CommentDirectiveType, CommentKind, CommentRange, - compareValues, - Debug, DiagnosticMessage, - Diagnostics, - getEntries, - identity, JSDocSyntaxKind, JsxTokenSyntaxKind, KeywordSyntaxKind, LanguageVariant, LineAndCharacter, - MapLike, - parsePseudoBigInt, - positionIsSynthesized, ScriptTarget, SourceFileLike, SyntaxKind, TokenFlags, - trimStringStart, -} from "./_namespaces/ts"; +} from "./types"; +import { + parsePseudoBigInt, + positionIsSynthesized, +} from "./utilities"; export type ErrorCallback = (message: DiagnosticMessage, length: number) => void; @@ -106,159 +115,6 @@ export interface Scanner { tryScan(callback: () => T): T; } -/** @internal */ -export const textToKeywordObj: MapLike = { - abstract: SyntaxKind.AbstractKeyword, - accessor: SyntaxKind.AccessorKeyword, - 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, - satisfies: SyntaxKind.SatisfiesKeyword, - 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, -}; - -const textToKeyword = new Map(getEntries(textToKeywordObj)); - -const textToToken = new Map(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, -})); - /* As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers IdentifierStart :: @@ -435,7 +291,8 @@ export function computePositionOfLineAndCharacter(lineStarts: readonly number[], 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"}`); + // Debug.fail(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`); + throw new Error(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`); } } @@ -447,10 +304,16 @@ export function computePositionOfLineAndCharacter(lineStarts: readonly number[], 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]); + if (!(res < lineStarts[line + 1])) { + throw new Error(); + } + // Debug.assert(res < lineStarts[line + 1]); } else if (debugText !== undefined) { - Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline + if (!(res <= debugText.length)) { + throw new Error(); + } + // Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline } return res; } @@ -484,7 +347,10 @@ export function computeLineOfPosition(lineStarts: readonly number[], position: n // 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"); + // Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file"); + if (!(lineNumber !== -1)) { + throw new Error("position cannot precede the beginning of the file"); + } } return lineNumber; } @@ -505,46 +371,6 @@ export function getLineAndCharacterOfPosition(sourceFile: SourceFileLike, positi return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position); } -export function isWhiteSpaceLike(ch: number): boolean { - return isWhiteSpaceSingleLine(ch) || isLineBreak(ch); -} - -/** Does not include line breaks. For that, see isWhiteSpaceLike. */ -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; -} - -export function isLineBreak(ch: number): boolean { - // ES5 7.3: - // The ECMAScript line terminator characters are listed in Table 3. - // Table 3: Line Terminator Characters - // Code Unit Value Name Formal Name - // \u000A Line Feed - // \u000D Carriage Return - // \u2028 Line separator - // \u2029 Paragraph separator - // 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; -} - function isDigit(ch: number): boolean { return ch >= CharacterCodes._0 && ch <= CharacterCodes._9; } @@ -690,7 +516,10 @@ export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boole const mergeConflictMarkerLength = "<<<<<<<".length; function isConflictMarkerTrivia(text: string, pos: number) { - Debug.assert(pos >= 0); + // Debug.assert(pos >= 0); + if (!(pos >= 0)) { + throw new Error(); + } // Conflict markers must be at the start of a line. if (pos === 0 || isLineBreak(text.charCodeAt(pos - 1))) { @@ -725,7 +554,10 @@ function scanConflictMarkerTrivia(text: string, pos: number, error?: (diag: Diag } } else { - Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals); + // Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals); + if (!(ch === CharacterCodes.bar || ch === CharacterCodes.equals)) { + throw new Error(); + } // Consume everything from the start of a ||||||| or ======= marker to the start // of the next ======= or >>>>>>> marker. while (pos < len) { @@ -746,7 +578,10 @@ const shebangTriviaRegex = /^#!.*/; /** @internal */ export function isShebangTrivia(text: string, pos: number) { // Shebangs check must only be done at the start of the file - Debug.assert(pos === 0); + // Debug.assert(pos === 0); + if (!(pos === 0)) { + throw new Error(); + } return shebangTriviaRegex.test(text); } @@ -1036,14 +871,14 @@ export function createScanner(languageVersion: ScriptTarget, scanRange, }; - if (Debug.isDebugging) { - Object.defineProperty(scanner, "__debugShowCurrentPositionInText", { - get: () => { - const text = scanner.getText(); - return text.slice(0, scanner.getStartPos()) + "â•‘" + text.slice(scanner.getStartPos()); - }, - }); - } + // if (Debug.isDebugging) { + // Object.defineProperty(scanner, "__debugShowCurrentPositionInText", { + // get: () => { + // const text = scanner.getText(); + // return text.slice(0, scanner.getStartPos()) + "â•‘" + text.slice(scanner.getStartPos()); + // }, + // }); + // } return scanner; @@ -1339,7 +1174,10 @@ export function createScanner(languageVersion: ScriptTarget, pos++; } - Debug.assert(resultingToken !== undefined); + // Debug.assert(resultingToken !== undefined); + if (!(resultingToken !== undefined)) { + throw new Error(); + } tokenValue = contents; return resultingToken; @@ -2139,7 +1977,10 @@ export function createScanner(languageVersion: ScriptTarget, } function reScanInvalidIdentifier(): SyntaxKind { - Debug.assert(token === SyntaxKind.Unknown, "'reScanInvalidIdentifier' should only be called when the current token is 'SyntaxKind.Unknown'."); + // Debug.assert(token === SyntaxKind.Unknown, "'reScanInvalidIdentifier' should only be called when the current token is 'SyntaxKind.Unknown'."); + if (!(token === SyntaxKind.Unknown)) { + throw new Error("'reScanInvalidIdentifier' should only be called when the current token is 'SyntaxKind.Unknown'."); + } pos = tokenPos = startPos; tokenFlags = 0; const ch = codePointAt(text, pos); @@ -2188,7 +2029,10 @@ export function createScanner(languageVersion: ScriptTarget, } function reScanAsteriskEqualsToken(): SyntaxKind { - Debug.assert(token === SyntaxKind.AsteriskEqualsToken, "'reScanAsteriskEqualsToken' should only be called on a '*='"); + // Debug.assert(token === SyntaxKind.AsteriskEqualsToken, "'reScanAsteriskEqualsToken' should only be called on a '*='"); + if (!(token === SyntaxKind.AsteriskEqualsToken)) { + throw new Error("'reScanAsteriskEqualsToken' should only be called on a '*='"); + } pos = tokenPos + 1; return token = SyntaxKind.EqualsToken; } @@ -2288,7 +2132,10 @@ export function createScanner(languageVersion: ScriptTarget, * 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 '}'"); + // Debug.assert(token === SyntaxKind.CloseBraceToken, "'reScanTemplateToken' should only be called on a '}'"); + if (!(token === SyntaxKind.CloseBraceToken)) { + throw new Error("'reScanTemplateToken' should only be called on a '}'"); + } pos = tokenPos; return token = scanTemplateAndSetTokenValue(isTaggedTemplate); } @@ -2320,7 +2167,10 @@ export function createScanner(languageVersion: ScriptTarget, } function reScanQuestionToken(): SyntaxKind { - Debug.assert(token === SyntaxKind.QuestionQuestionToken, "'reScanQuestionToken' should only be called on a '??'"); + // Debug.assert(token === SyntaxKind.QuestionQuestionToken, "'reScanQuestionToken' should only be called on a '??'"); + if (!(token === SyntaxKind.QuestionQuestionToken)) { + throw new Error("'reScanQuestionToken' should only be called on a '??'"); + } pos = tokenPos + 1; return token = SyntaxKind.QuestionToken; } @@ -2625,7 +2475,10 @@ export function createScanner(languageVersion: ScriptTarget, } function setTextPos(textPos: number) { - Debug.assert(textPos >= 0); + // Debug.assert(textPos >= 0); + if (!(textPos >= 0)) { + throw new Error(); + } pos = textPos; startPos = textPos; tokenPos = textPos; @@ -2670,7 +2523,10 @@ function charSize(ch: number) { // Derived from the 10.1.1 UTF16Encoding of the ES6 Spec. function utf16EncodeAsStringFallback(codePoint: number) { - Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF); + // Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF); + if (!(0x0 <= codePoint && codePoint <= 0x10FFFF)) { + throw new Error(); + } if (codePoint <= 65535) { return String.fromCharCode(codePoint); diff --git a/src/compiler/scannerUtilities.ts b/src/compiler/scannerUtilities.ts new file mode 100644 index 0000000000000..96e44238970a9 --- /dev/null +++ b/src/compiler/scannerUtilities.ts @@ -0,0 +1,158 @@ +import { getEntries } from "./core"; +import { MapLike } from "./corePublic"; +import { + KeywordSyntaxKind, + SyntaxKind, +} from "./types"; + +export const textToKeywordObj: MapLike = { + abstract: SyntaxKind.AbstractKeyword, + accessor: SyntaxKind.AccessorKeyword, + 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, + satisfies: SyntaxKind.SatisfiesKeyword, + 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 textToKeyword = new Map(getEntries(textToKeywordObj)); + +export const textToToken = new Map(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, +})); diff --git a/src/compiler/semver.ts b/src/compiler/semver.ts index b9c5864c0c042..52f0e7ca3b0c7 100644 --- a/src/compiler/semver.ts +++ b/src/compiler/semver.ts @@ -1,15 +1,15 @@ import { compareStringsCaseSensitive, compareValues, - Comparison, - Debug, emptyArray, - every, isArray, map, some, trimString, -} from "./_namespaces/ts"; +} from "./core"; +import { Comparison } from "./corePublic"; + +// import { Debug } from "./debug"; // https://semver.org/#spec-item-2 // > A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative @@ -26,14 +26,14 @@ const versionRegExp = /^(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\-([a-z // > alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers // > MUST NOT include leading zeroes. const prereleaseRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)(?:\.(?:0|[1-9]\d*|[a-z-][a-z0-9-]*))*$/i; -const prereleasePartRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)$/i; +// const prereleasePartRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)$/i; // https://semver.org/#spec-item-10 // > Build metadata MAY be denoted by appending a plus sign and a series of dot separated // > identifiers immediately following the patch or pre-release version. Identifiers MUST // > comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. const buildRegExp = /^[a-z0-9-]+(?:\.[a-z0-9-]+)*$/i; -const buildPartRegExp = /^[a-z0-9-]+$/i; +// const buildPartRegExp = /^[a-z0-9-]+$/i; // https://semver.org/#spec-item-9 // > Numeric identifiers MUST NOT include leading zeroes. @@ -57,19 +57,23 @@ export class Version { constructor(major: number, minor?: number, patch?: number, prerelease?: string | readonly string[], build?: string | readonly string[]); constructor(major: number | string, minor = 0, patch = 0, prerelease: string | readonly string[] = "", build: string | readonly string[] = "") { if (typeof major === "string") { - const result = Debug.checkDefined(tryParseComponents(major), "Invalid version"); + // const result = Debug.checkDefined(tryParseComponents(major), "Invalid version"); + const result = tryParseComponents(major); + if (result === undefined) { + throw new Error("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(major >= 0, "Invalid argument: major"); + // Debug.assert(minor >= 0, "Invalid argument: minor"); + // Debug.assert(patch >= 0, "Invalid argument: patch"); const prereleaseArray = prerelease ? isArray(prerelease) ? prerelease : prerelease.split(".") : emptyArray; const buildArray = build ? isArray(build) ? build : build.split(".") : emptyArray; - Debug.assert(every(prereleaseArray, s => prereleasePartRegExp.test(s)), "Invalid argument: prerelease"); - Debug.assert(every(buildArray, s => buildPartRegExp.test(s)), "Invalid argument: build"); + // Debug.assert(every(prereleaseArray, s => prereleasePartRegExp.test(s)), "Invalid argument: prerelease"); + // Debug.assert(every(buildArray, s => buildPartRegExp.test(s)), "Invalid argument: build"); this.major = major; this.minor = minor; @@ -112,7 +116,9 @@ export class Version { 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 Debug.assertNever(field); + default: + throw new Error(field); } } @@ -204,7 +210,11 @@ export class VersionRange { private _alternatives: readonly (readonly Comparator[])[]; constructor(spec: string) { - this._alternatives = spec ? Debug.checkDefined(parseRange(spec), "Invalid range spec.") : emptyArray; + const result = spec ? parseRange(spec) : emptyArray; + if (result === undefined) { + throw new Error("Invalid range spec."); + } + this._alternatives = result; } static tryParse(text: string) { @@ -413,7 +423,9 @@ function testComparator(version: Version, operator: Comparator["operator"], oper case ">": return cmp > 0; case ">=": return cmp >= 0; case "=": return cmp === 0; - default: return Debug.assertNever(operator); + // default: return Debug.assertNever(operator); + default: + throw new Error(operator); } } diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index baf87fdd594c6..34b55750876f5 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -1,32 +1,36 @@ import { arrayFrom, binarySearchKey, - CharacterCodes, - combinePaths, compareValues, - Debug, - DocumentPosition, - DocumentPositionMapper, - DocumentPositionMapperHost, - EmitHost, emptyArray, every, - getDirectoryPath, - getNormalizedAbsolutePath, - getPositionOfLineAndCharacter, - getRelativePathToDirectoryOrUrl, identity, isArray, isString, - LineAndCharacter, - RawSourceMap, some, sortAndDeduplicate, - SortedReadonlyArray, - SourceMapGenerator, trimStringEnd, -} from "./_namespaces/ts"; -import * as performance from "./_namespaces/ts.performance"; +} from "./core"; +import { SortedReadonlyArray } from "./corePublic"; +import { Debug } from "./debug"; +import { + combinePaths, + getDirectoryPath, + getNormalizedAbsolutePath, + getRelativePathToDirectoryOrUrl, +} from "./path"; +import * as performance from "./performance"; +import { getPositionOfLineAndCharacter } from "./scanner"; +import { + CharacterCodes, + DocumentPosition, + DocumentPositionMapper, + DocumentPositionMapperHost, + EmitHost, + LineAndCharacter, + RawSourceMap, + SourceMapGenerator, +} from "./types"; /** @internal */ export interface SourceMapGeneratorOptions { diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts index 591e19c8eb647..bf181ded2626c 100644 --- a/src/compiler/symbolWalker.ts +++ b/src/compiler/symbolWalker.ts @@ -1,9 +1,11 @@ +import { getSymbolId } from "./checkerUtilities"; import { clear, - EntityNameOrEntityNameExpression, forEach, getOwnValues, - getSymbolId, +} from "./core"; +import { + EntityNameOrEntityNameExpression, Identifier, IndexedAccessType, IndexType, @@ -24,7 +26,7 @@ import { TypeQueryNode, TypeReference, UnionOrIntersectionType, -} from "./_namespaces/ts"; +} from "./types"; /** @internal */ export function createGetSymbolWalker( diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index ba707330ffeee..421454853f15b 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -1,52 +1,60 @@ +import { matchesExclude } from "./commandLineParser"; import { AssertionLevel, - closeFileWatcher, - closeFileWatcherOf, - combinePaths, - Comparison, contains, - containsPath, createGetCanonicalFileName, createMultiMap, - Debug, - directorySeparator, emptyArray, - emptyFileSystemEntries, endsWith, enumerateInsertsAndDeletes, - FileSystemEntries, - getDirectoryPath, - getFallbackOptions, - getNormalizedAbsolutePath, - getRelativePathToDirectoryOrUrl, - getRootLength, getStringComparer, isArray, isNodeLikeSystem, isString, mapDefined, - matchesExclude, - matchFiles, memoize, noop, - normalizePath, - normalizeSlashes, orderedRemoveItem, - Path, - perfLogger, - PollingWatchKind, - RequireResult, - resolveJSModule, some, startsWith, stringContains, - timestamp, unorderedRemoveItem, +} from "./core"; +import { Comparison } from "./corePublic"; +import { Debug } from "./debug"; +import { resolveJSModule } from "./moduleNameResolver"; +import { + combinePaths, + containsPath, + directorySeparator, + getDirectoryPath, + getNormalizedAbsolutePath, + getRelativePathToDirectoryOrUrl, + getRootLength, + normalizePath, + normalizeSlashes, +} from "./path"; +import { perfLogger } from "./perfLogger"; +import { timestamp } from "./performanceCore"; +import { + Path, + PollingWatchKind, + RequireResult, WatchDirectoryKind, WatchFileKind, WatchOptions, +} from "./types"; +import { + closeFileWatcher, + emptyFileSystemEntries, + FileSystemEntries, + matchFiles, writeFileEnsuringDirectories, -} from "./_namespaces/ts"; +} from "./utilities"; +import { + closeFileWatcherOf, + getFallbackOptions, +} from "./watchUtilities"; declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any; declare function clearTimeout(handle: any): void; diff --git a/src/compiler/tracing.ts b/src/compiler/tracing.ts index 4f091195827a8..f598257c858f2 100644 --- a/src/compiler/tracing.ts +++ b/src/compiler/tracing.ts @@ -1,10 +1,11 @@ +import { Debug } from "./debug"; +import { combinePaths } from "./path"; +import * as performance from "./performance"; +import { timestamp } from "./performanceCore"; +import { getLineAndCharacterOfPosition } from "./scanner"; import { - combinePaths, ConditionalType, - Debug, EvolvingArrayType, - getLineAndCharacterOfPosition, - getSourceFileOfNode, IndexedAccessType, IndexType, IntersectionType, @@ -14,14 +15,13 @@ import { Path, ReverseMappedType, SubstitutionType, - timestamp, Type, TypeFlags, TypeReference, - unescapeLeadingUnderscores, UnionType, -} from "./_namespaces/ts"; -import * as performance from "./_namespaces/ts.performance"; +} from "./types"; +import { getSourceFileOfNode } from "./utilities"; +import { unescapeLeadingUnderscores } from "./utilitiesPublic"; /* Tracing events for the compiler. */ diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 456a23a065577..4ee78002b30b8 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -1,16 +1,54 @@ import { addRange, append, + emptyArray, + map, + memoize, + noop, + notImplemented, + returnUndefined, + some, +} from "./core"; +import { Debug } from "./debug"; +import { createEmitHelperFactory } from "./factory/emitHelpers"; +import { + disposeEmitNodes, + setEmitFlags, +} from "./factory/emitNode"; +import { factory } from "./factory/nodeFactory"; +import { + isBundle, + isSourceFile, +} from "./factory/nodeTests"; +import * as performance from "./performance"; +import { tracing } from "./tracing"; +import { transformClassFields } from "./transformers/classFields"; +import { transformDeclarations } from "./transformers/declarations"; +import { transformES2015 } from "./transformers/es2015"; +import { transformES2016 } from "./transformers/es2016"; +import { transformES2017 } from "./transformers/es2017"; +import { transformES2018 } from "./transformers/es2018"; +import { transformES2019 } from "./transformers/es2019"; +import { transformES2020 } from "./transformers/es2020"; +import { transformES2021 } from "./transformers/es2021"; +import { transformES5 } from "./transformers/es5"; +import { transformESNext } from "./transformers/esnext"; +import { transformGenerators } from "./transformers/generators"; +import { transformJsx } from "./transformers/jsx"; +import { transformLegacyDecorators } from "./transformers/legacyDecorators"; +import { transformECMAScriptModule } from "./transformers/module/esnextAnd2015"; +import { transformModule } from "./transformers/module/module"; +import { transformNodeModule } from "./transformers/module/node"; +import { transformSystemModule } from "./transformers/module/system"; +import { transformTypeScript } from "./transformers/ts"; +import { chainBundle } from "./transformers/utilities"; +import { Bundle, - chainBundle, CompilerOptions, - createEmitHelperFactory, CustomTransformer, CustomTransformerFactory, CustomTransformers, - Debug, DiagnosticWithLocation, - disposeEmitNodes, EmitFlags, EmitHelper, EmitHint, @@ -18,61 +56,31 @@ import { EmitOnly, EmitResolver, EmitTransformers, - emptyArray, - factory, FunctionDeclaration, - getEmitFlags, - getEmitModuleKind, - getEmitScriptTarget, - getJSXTransformEnabled, - getParseTreeNode, - getSourceFileOfNode, Identifier, - isBundle, - isSourceFile, LexicalEnvironmentFlags, - map, - memoize, ModuleKind, Node, NodeFactory, NodeFlags, - noop, - notImplemented, - returnUndefined, ScriptTarget, - setEmitFlags, - some, SourceFile, Statement, SyntaxKind, - tracing, TransformationContext, TransformationResult, - transformClassFields, - transformDeclarations, - transformECMAScriptModule, Transformer, TransformerFactory, - transformES2015, - transformES2016, - transformES2017, - transformES2018, - transformES2019, - transformES2020, - transformES2021, - transformES5, - transformESNext, - transformGenerators, - transformJsx, - transformLegacyDecorators, - transformModule, - transformNodeModule, - transformSystemModule, - transformTypeScript, VariableDeclaration, -} from "./_namespaces/ts"; -import * as performance from "./_namespaces/ts.performance"; +} from "./types"; +import { + getEmitFlags, + getEmitModuleKind, + getEmitScriptTarget, + getJSXTransformEnabled, + getSourceFileOfNode, +} from "./utilities"; +import { getParseTreeNode } from "./utilitiesPublic"; function getModuleTransformer(moduleKind: ModuleKind): TransformerFactory { switch (moduleKind) { diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 239a7e125453d..a668fc14b6efd 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -1,10 +1,67 @@ import { - __String, - AccessorDeclaration, - addEmitFlags, - addEmitHelpers, addRange, append, + compact, + filter, + map, + some, +} from "../core"; +import { Debug } from "../debug"; +import { + addEmitFlags, + addEmitHelpers, + getCommentRange, + getSourceMapRange, + setCommentRange, + setEmitFlags, + setSourceMapRange, + setSyntheticLeadingComments, + setSyntheticTrailingComments, +} from "../factory/emitNode"; +import { factory } from "../factory/nodeFactory"; +import { + isAccessorModifier, + isArrayLiteralExpression, + isArrowFunction, + isClassDeclaration, + isClassStaticBlockDeclaration, + isComputedPropertyName, + isConstructorDeclaration, + isElementAccessExpression, + isGetAccessorDeclaration, + isHeritageClause, + isIdentifier, + isMethodDeclaration, + isParenthesizedExpression, + isPrefixUnaryExpression, + isPrivateIdentifier, + isPropertyAccessExpression, + isPropertyAssignment, + isPropertyDeclaration, + isSetAccessorDeclaration, + isShorthandPropertyAssignment, + isSpreadAssignment, + isSpreadElement, + isStaticModifier, +} from "../factory/nodeTests"; +import { + createAccessorPropertyBackingField, + createAccessorPropertyGetRedirector, + createAccessorPropertySetRedirector, + createMemberAccessForPropertyName, + expandPreOrPostfixIncrementOrDecrementExpression, + getInitializerOfBindingOrAssignmentElement, + getNodeForGeneratedName, + getTargetOfBindingOrAssignmentElement, + startOnNewLine, +} from "../factory/utilities"; +import { + setOriginalNode, + setTextRange, +} from "../factory/utilitiesPublic"; +import { + __String, + AccessorDeclaration, AssignmentOperator, AssignmentPattern, AutoAccessorPropertyDeclaration, @@ -12,156 +69,106 @@ import { BindingOrAssignmentElement, Bundle, CallExpression, - chainBundle, ClassDeclaration, ClassElement, ClassExpression, ClassLikeDeclaration, - classOrConstructorParameterIsDecorated, ClassStaticBlockDeclaration, - compact, ComputedPropertyName, ConstructorDeclaration, - createAccessorPropertyBackingField, - createAccessorPropertyGetRedirector, - createAccessorPropertySetRedirector, - createMemberAccessForPropertyName, - Debug, ElementAccessExpression, EmitFlags, EmitHint, - expandPreOrPostfixIncrementOrDecrementExpression, Expression, ExpressionStatement, ExpressionWithTypeArguments, - factory, - filter, - findSuperStatementIndex, ForStatement, GeneratedIdentifier, GeneratedIdentifierFlags, GeneratedNamePart, GeneratedPrivateIdentifier, GetAccessorDeclaration, - getCommentRange, + Identifier, + InKeyword, + LeftHandSideExpression, + MethodDeclaration, + Modifier, + ModifierFlags, + Node, + NodeCheckFlags, + ObjectLiteralElementLike, + PostfixUnaryExpression, + PrefixUnaryExpression, + PrivateIdentifier, + PrivateIdentifierKind, + PrivateIdentifierPropertyAccessExpression, + PrivateIdentifierPropertyDeclaration, + PropertyAccessExpression, + PropertyDeclaration, + PropertyName, + ScriptTarget, + SetAccessorDeclaration, + SourceFile, + Statement, + SuperProperty, + SyntaxKind, + TaggedTemplateExpression, + ThisExpression, + TransformationContext, + TransformFlags, + UnderscoreEscapedMap, + VariableStatement, + VisitResult, +} from "../types"; +import { + classOrConstructorParameterIsDecorated, getEffectiveBaseTypeNode, getEmitFlags, getEmitScriptTarget, - getInitializerOfBindingOrAssignmentElement, - getNameOfDeclaration, - getNodeForGeneratedName, - getNonAssignmentOperatorForCompoundAssignment, - getOriginalNode, - getOriginalNodeId, - getProperties, - getSourceMapRange, - getStaticPropertiesAndClassStaticBlock, - getTargetOfBindingOrAssignmentElement, getUseDefineForClassFields, hasAbstractModifier, hasAccessorModifier, hasDecorators, hasStaticModifier, hasSyntacticModifier, - Identifier, - InKeyword, - isAccessorModifier, - isArrayLiteralExpression, - isArrowFunction, isAssignmentExpression, + isDestructuringAssignment, + isStatic, + isSuperProperty, + isThisProperty, + moveRangePastModifiers, + moveRangePos, + nodeIsSynthesized, + skipOuterExpressions, + skipParentheses, + tryGetTextOfPropertyName, +} from "../utilities"; +import { + getNameOfDeclaration, + getOriginalNode, isAutoAccessorPropertyDeclaration, isCallChain, - isClassDeclaration, isClassElement, - isClassStaticBlockDeclaration, - isCompoundAssignment, - isComputedPropertyName, - isConstructorDeclaration, - isDestructuringAssignment, - isElementAccessExpression, isExpression, isForInitializer, isGeneratedIdentifier, isGeneratedPrivateIdentifier, isGetAccessor, - isGetAccessorDeclaration, - isHeritageClause, - isIdentifier, - isInitializedProperty, - isMethodDeclaration, isModifier, isModifierLike, - isNonStaticMethodOrAccessorWithPrivateName, isObjectBindingOrAssignmentElement, isObjectLiteralElementLike, isParameterPropertyDeclaration, - isParenthesizedExpression, - isPrefixUnaryExpression, - isPrivateIdentifier, isPrivateIdentifierClassElementDeclaration, isPrivateIdentifierPropertyAccessExpression, - isPropertyAccessExpression, - isPropertyAssignment, - isPropertyDeclaration, isPropertyName, isSetAccessor, - isSetAccessorDeclaration, - isShorthandPropertyAssignment, - isSimpleCopiableExpression, - isSimpleInlineableExpression, - isSpreadAssignment, - isSpreadElement, isStatement, - isStatic, - isStaticModifier, - isSuperProperty, isTemplateLiteral, - isThisProperty, - LeftHandSideExpression, - map, - MethodDeclaration, - Modifier, - ModifierFlags, - moveRangePastModifiers, - moveRangePos, - Node, - NodeCheckFlags, - nodeIsSynthesized, - ObjectLiteralElementLike, - PostfixUnaryExpression, - PrefixUnaryExpression, - PrivateIdentifier, - PrivateIdentifierPropertyAccessExpression, - PrivateIdentifierPropertyDeclaration, - PropertyAccessExpression, - PropertyDeclaration, - PropertyName, - ScriptTarget, - SetAccessorDeclaration, - setCommentRange, - setEmitFlags, - setOriginalNode, - setSourceMapRange, - setSyntheticLeadingComments, - setSyntheticTrailingComments, - setTextRange, - skipOuterExpressions, - skipParentheses, skipPartiallyEmittedExpressions, - some, - SourceFile, - startOnNewLine, - Statement, - SuperProperty, - SyntaxKind, - TaggedTemplateExpression, - ThisExpression, - TransformationContext, - TransformFlags, - tryGetTextOfPropertyName, - UnderscoreEscapedMap, unescapeLeadingUnderscores, - VariableStatement, +} from "../utilitiesPublic"; +import { visitArray, visitEachChild, visitFunctionBody, @@ -169,8 +176,20 @@ import { visitNode, visitNodes, visitParameterList, - VisitResult, -} from "../_namespaces/ts"; +} from "../visitorPublic"; +import { + chainBundle, + findSuperStatementIndex, + getNonAssignmentOperatorForCompoundAssignment, + getOriginalNodeId, + getProperties, + getStaticPropertiesAndClassStaticBlock, + isCompoundAssignment, + isInitializedProperty, + isNonStaticMethodOrAccessorWithPrivateName, + isSimpleCopiableExpression, + isSimpleInlineableExpression, +} from "./utilities"; const enum ClassPropertySubstitutionFlags { /** @@ -185,13 +204,6 @@ const enum ClassPropertySubstitutionFlags { ClassStaticThisOrSuperReference = 1 << 1, } -/** @internal */ -export const enum PrivateIdentifierKind { - Field = "f", - Method = "m", - Accessor = "a" -} - interface PrivateIdentifierInfoBase { /** * brandCheckIdentifier can contain: diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index a150c9204659e..e2513cd010b4b 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1,89 +1,131 @@ +import { + append, + arrayFrom, + compact, + concatenate, + contains, + emptyArray, + filter, + flatMap, + flatten, + forEach, + isArray, + last, + length, + map, + mapDefined, + orderedRemoveItem, + pushIfUnique, + some, + startsWith, + stringContains, + toFileNameLowerCase, + tryCast, +} from "../core"; +import { Debug } from "../debug"; +import { Diagnostics } from "../diagnosticInformationMap.generated"; +import { getOutputPathsFor } from "../emitter"; +import { + getCommentRange, + removeAllComments, + setCommentRange, + setEmitFlags, +} from "../factory/emitNode"; +import { + createUnparsedSourceFile, + factory, +} from "../factory/nodeFactory"; +import { + isClassDeclaration, + isExportAssignment, + isExportDeclaration, + isExternalModuleReference, + isFunctionDeclaration, + isIdentifier, + isImportDeclaration, + isImportEqualsDeclaration, + isIndexSignatureDeclaration, + isInterfaceDeclaration, + isMappedTypeNode, + isMethodDeclaration, + isMethodSignature, + isModuleDeclaration, + isOmittedExpression, + isPrivateIdentifier, + isPropertyAccessExpression, + isPropertySignature, + isSemicolonClassElement, + isSetAccessorDeclaration, + isSourceFile, + isStringLiteral, + isTupleTypeNode, + isTypeAliasDeclaration, + isTypeParameterDeclaration, + isTypeQueryNode, + isUnparsedSource, +} from "../factory/nodeTests"; +import { createEmptyExports } from "../factory/utilities"; +import { + canHaveModifiers, + setOriginalNode, + setTextRange, +} from "../factory/utilitiesPublic"; +import { pathContainsNodeModules } from "../moduleNameResolver"; +import { getModuleSpecifier } from "../moduleSpecifiers"; +import { + isExternalModule, + parseNodeFactory, +} from "../parser"; +import { + getDirectoryPath, + getRelativePathToDirectoryOrUrl, + hasExtension, + normalizeSlashes, + pathIsRelative, + toPath, +} from "../path"; +import { getResolutionModeOverrideForClause } from "../program"; +import { + getLeadingCommentRanges, + getLineAndCharacterOfPosition, + getTrailingCommentRanges, + skipTrivia, +} from "../scanner"; +import { transformNodes } from "../transformer"; import { AccessorDeclaration, - addRelatedInfo, AllAccessorDeclarations, AnyImportSyntax, - append, ArrayBindingElement, - arrayFrom, AssertClause, BindingElement, BindingName, BindingPattern, Bundle, CallSignatureDeclaration, - canHaveModifiers, - canProduceDiagnostics, ClassDeclaration, CommentRange, - compact, - concatenate, ConditionalTypeNode, ConstructorDeclaration, ConstructorTypeNode, ConstructSignatureDeclaration, - contains, - createDiagnosticForNode, - createEmptyExports, - createGetSymbolAccessibilityDiagnosticForNode, - createGetSymbolAccessibilityDiagnosticForNodeName, - createSymbolTable, - createUnparsedSourceFile, - Debug, Declaration, - DeclarationDiagnosticProducing, DeclarationName, - declarationNameToString, - Diagnostics, DiagnosticWithLocation, EmitFlags, EmitHost, EmitResolver, - emptyArray, EntityNameOrEntityNameExpression, EnumDeclaration, ExportAssignment, ExportDeclaration, ExpressionWithTypeArguments, - factory, FileReference, - filter, - flatMap, - flatten, - forEach, FunctionDeclaration, FunctionTypeNode, GeneratedIdentifierFlags, GetAccessorDeclaration, - getCommentRange, - getDirectoryPath, - getEffectiveBaseTypeNode, - getEffectiveModifierFlags, - getExternalModuleImportEqualsDeclarationExpression, - getExternalModuleNameFromDeclaration, - getFirstConstructorWithBody, - getLeadingCommentRanges, - getLeadingCommentRangesOfNode, - getLineAndCharacterOfPosition, - getNameOfDeclaration, - getOriginalNodeId, - getOutputPathsFor, - getParseTreeNode, - getRelativePathToDirectoryOrUrl, - getResolutionModeOverrideForClause, - getResolvedExternalModuleName, - getSetAccessorValueParameter, - getSourceFileOfNode, - GetSymbolAccessibilityDiagnostic, - getTextOfNode, - getThisParameter, - getTrailingCommentRanges, - hasDynamicName, - hasEffectiveModifier, - hasExtension, - hasJSDocNodes, HasModifiers, - hasSyntacticModifier, HeritageClause, Identifier, ImportDeclaration, @@ -91,61 +133,8 @@ import { ImportTypeNode, IndexSignatureDeclaration, InterfaceDeclaration, - isAnyImportSyntax, - isArray, - isBindingPattern, - isClassDeclaration, - isDeclaration, - isEntityName, - isEntityNameExpression, - isExportAssignment, - isExportDeclaration, - isExternalModule, - isExternalModuleAugmentation, - isExternalModuleIndicator, - isExternalModuleReference, - isExternalOrCommonJsModule, - isFunctionDeclaration, - isFunctionLike, - isGlobalScopeAugmentation, - isIdentifier, - isImportDeclaration, - isImportEqualsDeclaration, - isIndexSignatureDeclaration, - isInterfaceDeclaration, - isJsonSourceFile, - isLateVisibilityPaintedStatement, - isLiteralImportTypeNode, - isMappedTypeNode, - isMethodDeclaration, - isMethodSignature, - isModifier, - isModuleDeclaration, - isNightly, - isOmittedExpression, - isPrivateIdentifier, - isPropertyAccessExpression, - isPropertySignature, - isSemicolonClassElement, - isSetAccessorDeclaration, - isSourceFile, - isSourceFileJS, - isSourceFileNotJson, - isStringANonContextualKeyword, - isStringLiteral, - isStringLiteralLike, - isTupleTypeNode, - isTypeAliasDeclaration, - isTypeNode, - isTypeParameterDeclaration, - isTypeQueryNode, - isUnparsedSource, - last, LateBoundDeclaration, LateVisibilityPaintedStatement, - length, - map, - mapDefined, MethodDeclaration, MethodSignature, Modifier, @@ -154,37 +143,20 @@ import { ModuleDeclaration, NamedDeclaration, NamespaceDeclaration, - needsScopeMarker, Node, NodeArray, NodeBuilderFlags, NodeFlags, NodeId, - normalizeSlashes, OmittedExpression, - orderedRemoveItem, ParameterDeclaration, - parseNodeFactory, - pathContainsNodeModules, - pathIsRelative, PropertyDeclaration, PropertySignature, - pushIfUnique, - removeAllComments, ResolutionMode, SetAccessorDeclaration, - setCommentRange, - setEmitFlags, - setOriginalNode, - setParent, - setTextRange, SignatureDeclaration, - skipTrivia, - some, SourceFile, - startsWith, Statement, - stringContains, StringLiteral, Symbol, SymbolAccessibility, @@ -192,26 +164,78 @@ import { SymbolFlags, SymbolTracker, SyntaxKind, - toFileNameLowerCase, - toPath, TransformationContext, - transformNodes, - tryCast, TypeAliasDeclaration, TypeNode, TypeParameterDeclaration, TypeReferenceNode, - unescapeLeadingUnderscores, UnparsedSource, VariableDeclaration, VariableStatement, + VisitResult, +} from "../types"; +import { + addRelatedInfo, + createDiagnosticForNode, + createSymbolTable, + declarationNameToString, + getEffectiveBaseTypeNode, + getEffectiveModifierFlags, + getExternalModuleImportEqualsDeclarationExpression, + getExternalModuleNameFromDeclaration, + getFirstConstructorWithBody, + getLeadingCommentRangesOfNode, + getResolvedExternalModuleName, + getSetAccessorValueParameter, + getSourceFileOfNode, + getTextOfNode, + getThisParameter, + hasDynamicName, + hasEffectiveModifier, + hasSyntacticModifier, + isAnyImportSyntax, + isEntityNameExpression, + isExternalModuleAugmentation, + isExternalOrCommonJsModule, + isGlobalScopeAugmentation, + isJsonSourceFile, + isLateVisibilityPaintedStatement, + isLiteralImportTypeNode, + isNightly, + isSourceFileJS, + isSourceFileNotJson, + isStringANonContextualKeyword, + setParent, +} from "../utilities"; +import { + getNameOfDeclaration, + getParseTreeNode, + hasJSDocNodes, + isBindingPattern, + isDeclaration, + isEntityName, + isExternalModuleIndicator, + isFunctionLike, + isModifier, + isStringLiteralLike, + isTypeNode, + needsScopeMarker, + unescapeLeadingUnderscores, +} from "../utilitiesPublic"; +import { visitArray, visitEachChild, visitNode, visitNodes, - VisitResult, -} from "../_namespaces/ts"; -import * as moduleSpecifiers from "../_namespaces/ts.moduleSpecifiers"; +} from "../visitorPublic"; +import { + canProduceDiagnostics, + createGetSymbolAccessibilityDiagnosticForNode, + createGetSymbolAccessibilityDiagnosticForNodeName, + DeclarationDiagnosticProducing, + GetSymbolAccessibilityDiagnostic, +} from "./declarations/diagnostics"; +import { getOriginalNodeId } from "./utilities"; /** @internal */ export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] | undefined { @@ -611,7 +635,7 @@ export function transformDeclarations(context: TransformationContext) { } if (declFileName) { - const specifier = moduleSpecifiers.getModuleSpecifier( + const specifier = getModuleSpecifier( options, currentSourceFile, toPath(outputFilePath, host.getCurrentDirectory(), host.getCanonicalFileName), diff --git a/src/compiler/transformers/declarations/diagnostics.ts b/src/compiler/transformers/declarations/diagnostics.ts index 021a372123072..2c568a363a390 100644 --- a/src/compiler/transformers/declarations/diagnostics.ts +++ b/src/compiler/transformers/declarations/diagnostics.ts @@ -1,20 +1,6 @@ +import { Debug } from "../../debug"; +import { Diagnostics } from "../../diagnosticInformationMap.generated"; import { - BindingElement, - CallSignatureDeclaration, - ConstructorDeclaration, - ConstructSignatureDeclaration, - Debug, - Declaration, - DeclarationName, - DiagnosticMessage, - Diagnostics, - ExpressionWithTypeArguments, - FunctionDeclaration, - GetAccessorDeclaration, - getNameOfDeclaration, - hasSyntacticModifier, - ImportEqualsDeclaration, - IndexSignatureDeclaration, isBindingElement, isCallSignatureDeclaration, isClassDeclaration, @@ -22,23 +8,32 @@ import { isConstructSignatureDeclaration, isExpressionWithTypeArguments, isFunctionDeclaration, - isGetAccessor, isHeritageClause, isImportEqualsDeclaration, isIndexSignatureDeclaration, - isJSDocTypeAlias, isMethodDeclaration, isMethodSignature, isParameter, - isParameterPropertyDeclaration, isPropertyAccessExpression, isPropertyDeclaration, isPropertySignature, - isSetAccessor, - isStatic, isTypeAliasDeclaration, isTypeParameterDeclaration, isVariableDeclaration, +} from "../../factory/nodeTests"; +import { + BindingElement, + CallSignatureDeclaration, + ConstructorDeclaration, + ConstructSignatureDeclaration, + Declaration, + DeclarationName, + DiagnosticMessage, + ExpressionWithTypeArguments, + FunctionDeclaration, + GetAccessorDeclaration, + ImportEqualsDeclaration, + IndexSignatureDeclaration, JSDocCallbackTag, JSDocEnumTag, JSDocTypedefTag, @@ -59,7 +54,18 @@ import { TypeAliasDeclaration, TypeParameterDeclaration, VariableDeclaration, -} from "../../_namespaces/ts"; +} from "../../types"; +import { + hasSyntacticModifier, + isJSDocTypeAlias, + isStatic, +} from "../../utilities"; +import { + getNameOfDeclaration, + isGetAccessor, + isParameterPropertyDeclaration, + isSetAccessor, +} from "../../utilitiesPublic"; /** @internal */ export type GetSymbolAccessibilityDiagnostic = (symbolAccessibilityResult: SymbolAccessibilityResult) => (SymbolAccessibilityDiagnostic | undefined); diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 2effd35cfc65f..4495c9b996c18 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -1,7 +1,32 @@ import { - __String, addRange, append, + every, + forEach, + last, + map, + some, +} from "../core"; +import { Debug } from "../debug"; +import { factory } from "../factory/nodeFactory"; +import { + isBindingElement, + isComputedPropertyName, + isIdentifier, + isOmittedExpression, + isVariableDeclaration, +} from "../factory/nodeTests"; +import { + getElementsOfBindingOrAssignmentPattern, + getInitializerOfBindingOrAssignmentElement, + getPropertyNameOfBindingOrAssignmentElement, + getRestIndicatorOfBindingOrAssignmentElement, + getTargetOfBindingOrAssignmentElement, + tryGetPropertyNameOfBindingOrAssignmentElement, +} from "../factory/utilities"; +import { setTextRange } from "../factory/utilitiesPublic"; +import { + __String, ArrayBindingElement, ArrayBindingOrAssignmentPattern, BindingElement, @@ -9,58 +34,43 @@ import { BindingOrAssignmentElement, BindingOrAssignmentElementTarget, BindingOrAssignmentPattern, - Debug, DestructuringAssignment, ElementAccessExpression, - every, Expression, - factory, - forEach, - getElementsOfBindingOrAssignmentPattern, - getInitializerOfBindingOrAssignmentElement, - getPropertyNameOfBindingOrAssignmentElement, - getRestIndicatorOfBindingOrAssignmentElement, - getTargetOfBindingOrAssignmentElement, Identifier, - idText, - isArrayBindingElement, - isArrayBindingOrAssignmentPattern, - isBindingElement, - isBindingName, - isBindingOrAssignmentPattern, - isComputedPropertyName, - isDeclarationBindingElement, - isDestructuringAssignment, - isEmptyArrayLiteral, - isEmptyObjectLiteral, - isExpression, - isIdentifier, - isLiteralExpression, - isObjectBindingOrAssignmentPattern, - isOmittedExpression, - isPropertyNameLiteral, - isSimpleInlineableExpression, - isStringOrNumericLiteralLike, - isVariableDeclaration, - last, LeftHandSideExpression, - map, Node, NodeFactory, - nodeIsSynthesized, ObjectBindingOrAssignmentPattern, ParameterDeclaration, PropertyName, - setTextRange, - some, TextRange, TransformationContext, TransformFlags, - tryGetPropertyNameOfBindingOrAssignmentElement, VariableDeclaration, - visitNode, VisitResult, -} from "../_namespaces/ts"; +} from "../types"; +import { + isDestructuringAssignment, + isEmptyArrayLiteral, + isEmptyObjectLiteral, + isPropertyNameLiteral, + isStringOrNumericLiteralLike, + nodeIsSynthesized, +} from "../utilities"; +import { + idText, + isArrayBindingElement, + isArrayBindingOrAssignmentPattern, + isBindingName, + isBindingOrAssignmentPattern, + isDeclarationBindingElement, + isExpression, + isLiteralExpression, + isObjectBindingOrAssignmentPattern, +} from "../utilitiesPublic"; +import { visitNode } from "../visitorPublic"; +import { isSimpleInlineableExpression } from "./utilities"; interface FlattenContext { context: TransformationContext; diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index ab5ea56408a4c..5c2ea6b73cd87 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -1,210 +1,232 @@ import { - __String, - AccessorDeclaration, - addEmitHelpers, addRange, - addSyntheticLeadingComment, - AllAccessorDeclarations, append, arrayIsEqualTo, - ArrayLiteralExpression, - ArrowFunction, - BinaryExpression, - BindingElement, - BindingPattern, - Block, - BreakOrContinueStatement, - Bundle, - CallExpression, - CaseBlock, - CaseClause, cast, - CatchClause, - chainBundle, - ClassDeclaration, - ClassElement, - ClassExpression, - ClassLikeDeclaration, - CommaListExpression, - ComputedPropertyName, concatenate, - ConstructorDeclaration, - createExpressionForPropertyName, - createMemberAccessForPropertyName, - createRange, - createTokenRange, - Debug, - Declaration, - DoStatement, elementAt, - EmitFlags, - EmitHint, emptyArray, - Expression, - ExpressionStatement, - ExpressionWithTypeArguments, filter, first, firstOrUndefined, flatMap, flatten, - flattenDestructuringAssignment, - flattenDestructuringBinding, - FlattenLevel, - ForInStatement, - ForOfStatement, - ForStatement, - FunctionBody, - FunctionDeclaration, - FunctionExpression, - FunctionLikeDeclaration, - GeneratedIdentifierFlags, - getAllAccessorDeclarations, - getClassExtendsHeritageElement, - getCombinedNodeFlags, + last, + lastOrUndefined, + map, + singleOrMany, + singleOrUndefined, + some, + spanMap, + takeWhile, + tryCast, +} from "../core"; +import { Debug } from "../debug"; +import { isCallToHelper } from "../factory/emitHelpers"; +import { + addEmitHelpers, + addSyntheticLeadingComment, getCommentRange, - getEmitFlags, - getEnclosingBlockScopeContainer, - getFirstConstructorWithBody, - getNameOfDeclaration, - getOriginalNode, - getParseTreeNode, getSourceMapRange, - getSuperCallFromStatement, - getUseDefineForClassFields, - hasStaticModifier, - hasSyntacticModifier, - Identifier, - idText, - IfStatement, - insertStatementAfterCustomPrologue, - insertStatementsAfterCustomPrologue, - insertStatementsAfterStandardPrologue, + moveSyntheticComments, + setCommentRange, + setEmitFlags, + setSourceMapRange, + setTokenSourceMapRange, +} from "../factory/emitNode"; +import { isArrayLiteralExpression, isArrowFunction, - isAssignmentExpression, isBinaryExpression, - isBindingPattern, isBlock, isCallExpression, - isCallToHelper, isCaseBlock, isCaseClause, isCatchClause, - isClassElement, - isClassLike, isComputedPropertyName, isDefaultClause, - isDestructuringAssignment, - isExpression, isExpressionStatement, - isForInitializer, isForStatement, isFunctionExpression, - isFunctionLike, - isHoistedFunction, - isHoistedVariableStatement, isIdentifier, - isIdentifierANonContextualKeyword, isIfStatement, - isInternalName, - isIterationStatement, isLabeledStatement, - isModifier, - isObjectLiteralElementLike, isOmittedExpression, - isPackedArrayLiteral, isPrivateIdentifier, - isPrologueDirective, isPropertyDeclaration, - isPropertyName, isReturnStatement, isSpreadElement, - isStatement, - isStatic, - isSuperProperty, isSwitchStatement, isTryStatement, isVariableDeclarationList, isVariableStatement, isWithStatement, +} from "../factory/nodeTests"; +import { + createExpressionForPropertyName, + createMemberAccessForPropertyName, + isInternalName, + startOnNewLine, +} from "../factory/utilities"; +import { + setOriginalNode, + setTextRange, +} from "../factory/utilitiesPublic"; +import { skipTrivia } from "../scanner"; +import { + __String, + AccessorDeclaration, + AllAccessorDeclarations, + ArrayLiteralExpression, + ArrowFunction, + BinaryExpression, + BindingElement, + BindingPattern, + Block, + BreakOrContinueStatement, + Bundle, + CallExpression, + CaseBlock, + CaseClause, + CatchClause, + ClassDeclaration, + ClassElement, + ClassExpression, + ClassLikeDeclaration, + CommaListExpression, + ComputedPropertyName, + ConstructorDeclaration, + Declaration, + DoStatement, + EmitFlags, + EmitHint, + Expression, + ExpressionStatement, + ExpressionWithTypeArguments, + ForInStatement, + ForOfStatement, + ForStatement, + FunctionBody, + FunctionDeclaration, + FunctionExpression, + FunctionLikeDeclaration, + GeneratedIdentifierFlags, + Identifier, + IfStatement, IterationStatement, LabeledStatement, - last, - lastOrUndefined, LeftHandSideExpression, LiteralExpression, - map, MetaProperty, MethodDeclaration, ModifierFlags, - moveRangeEnd, - moveRangePos, - moveSyntheticComments, NamedDeclaration, NewExpression, Node, NodeArray, NodeCheckFlags, NodeFlags, - nodeIsSynthesized, NumericLiteral, ObjectLiteralElementLike, ObjectLiteralExpression, ParameterDeclaration, ParenthesizedExpression, PrimaryExpression, - ProcessLevel, - processTaggedTemplateExpression, PropertyAssignment, - rangeEndIsOnSameLineAsRangeStart, ReturnStatement, SemicolonClassElement, - setCommentRange, - setEmitFlags, - setOriginalNode, - setParent, - setSourceMapRange, - setTextRange, - setTextRangeEnd, - setTextRangePos, - setTokenSourceMapRange, ShorthandPropertyAssignment, - singleOrMany, - singleOrUndefined, - skipOuterExpressions, - skipTrivia, - some, SourceFile, - spanMap, SpreadElement, - startOnNewLine, Statement, StringLiteral, SwitchStatement, SyntaxKind, TaggedTemplateExpression, - takeWhile, TemplateExpression, TextRange, TokenFlags, TransformationContext, TransformFlags, - tryCast, - unescapeLeadingUnderscores, - unwrapInnermostStatementOfLabel, VariableDeclaration, VariableDeclarationList, VariableStatement, - visitEachChild, - visitNode, - visitNodes, - visitParameterList, VisitResult, VoidExpression, WhileStatement, YieldExpression, -} from "../_namespaces/ts"; +} from "../types"; +import { + createRange, + createTokenRange, + getAllAccessorDeclarations, + getClassExtendsHeritageElement, + getEmitFlags, + getEnclosingBlockScopeContainer, + getFirstConstructorWithBody, + getUseDefineForClassFields, + hasStaticModifier, + hasSyntacticModifier, + insertStatementAfterCustomPrologue, + insertStatementsAfterCustomPrologue, + insertStatementsAfterStandardPrologue, + isAssignmentExpression, + isDestructuringAssignment, + isHoistedFunction, + isHoistedVariableStatement, + isIdentifierANonContextualKeyword, + isPackedArrayLiteral, + isPrologueDirective, + isStatic, + isSuperProperty, + moveRangeEnd, + moveRangePos, + nodeIsSynthesized, + rangeEndIsOnSameLineAsRangeStart, + setParent, + setTextRangeEnd, + setTextRangePos, + skipOuterExpressions, + unwrapInnermostStatementOfLabel, +} from "../utilities"; +import { + getCombinedNodeFlags, + getNameOfDeclaration, + getOriginalNode, + getParseTreeNode, + idText, + isBindingPattern, + isClassElement, + isClassLike, + isExpression, + isForInitializer, + isFunctionLike, + isIterationStatement, + isModifier, + isObjectLiteralElementLike, + isPropertyName, + isStatement, + unescapeLeadingUnderscores, +} from "../utilitiesPublic"; +import { + visitEachChild, + visitNode, + visitNodes, + visitParameterList, +} from "../visitorPublic"; +import { + flattenDestructuringAssignment, + flattenDestructuringBinding, + FlattenLevel, +} from "./destructuring"; +import { + ProcessLevel, + processTaggedTemplateExpression, +} from "./taggedTemplate"; +import { + chainBundle, + getSuperCallFromStatement, +} from "./utilities"; const enum ES2015SubstitutionFlags { /** Enables substitutions for captured `this` */ diff --git a/src/compiler/transformers/es2016.ts b/src/compiler/transformers/es2016.ts index 33df5b94f0d0b..c534dbef5876c 100644 --- a/src/compiler/transformers/es2016.ts +++ b/src/compiler/transformers/es2016.ts @@ -1,21 +1,25 @@ +import { + isElementAccessExpression, + isPropertyAccessExpression, +} from "../factory/nodeTests"; +import { setTextRange } from "../factory/utilitiesPublic"; import { BinaryExpression, Bundle, - chainBundle, Expression, - isElementAccessExpression, - isExpression, - isPropertyAccessExpression, Node, - setTextRange, SourceFile, SyntaxKind, TransformationContext, TransformFlags, + VisitResult, +} from "../types"; +import { isExpression } from "../utilitiesPublic"; +import { visitEachChild, visitNode, - VisitResult, -} from "../_namespaces/ts"; +} from "../visitorPublic"; +import { chainBundle } from "./utilities"; /** @internal */ export function transformES2016(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle { diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 4c7a90fa6944e..8b04faabe2c8a 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -1,29 +1,50 @@ +import { getNodeId } from "../checkerUtilities"; +import { + concatenate, + forEach, + map, + some, +} from "../core"; +import { Debug } from "../debug"; +import { + advancedAsyncSuperHelper, + asyncSuperHelper, +} from "../factory/emitHelpers"; import { - __String, - AccessorDeclaration, addEmitHelper, addEmitHelpers, - advancedAsyncSuperHelper, + setEmitFlags, + setSourceMapRange, +} from "../factory/emitNode"; +import { + isBlock, + isIdentifier, + isOmittedExpression, + isPropertyAccessExpression, + isVariableDeclarationList, +} from "../factory/nodeTests"; +import { + setOriginalNode, + setTextRange, +} from "../factory/utilitiesPublic"; +import { + __String, + AccessorDeclaration, ArrowFunction, - asyncSuperHelper, AwaitExpression, BindingElement, Block, Bundle, CallExpression, CatchClause, - chainBundle, ClassDeclaration, - concatenate, ConciseBody, ConstructorDeclaration, - Debug, ElementAccessExpression, EmitFlags, EmitHint, EmitResolver, Expression, - forEach, ForInitializer, ForInStatement, ForOfStatement, @@ -31,36 +52,10 @@ import { FunctionBody, FunctionDeclaration, FunctionExpression, - FunctionFlags, FunctionLikeDeclaration, GeneratedIdentifierFlags, GetAccessorDeclaration, - getEmitScriptTarget, - getEntityNameFromTypeNode, - getFunctionFlags, - getInitializedVariables, - getNodeId, - getOriginalNode, - insertStatementsAfterStandardPrologue, - isBlock, - isConciseBody, - isEffectiveStrictModeSourceFile, - isEntityName, - isExpression, - isForInitializer, - isFunctionLike, - isFunctionLikeDeclaration, - isIdentifier, - isModifierLike, - isNodeWithPossibleHoistedDeclaration, - isOmittedExpression, - isPropertyAccessExpression, - isStatement, - isSuperProperty, - isToken, - isVariableDeclarationList, LeftHandSideExpression, - map, MethodDeclaration, Node, NodeCheckFlags, @@ -71,11 +66,6 @@ import { PropertyAssignment, ScriptTarget, SetAccessorDeclaration, - setEmitFlags, - setOriginalNode, - setSourceMapRange, - setTextRange, - some, SourceFile, Statement, SyntaxKind, @@ -84,18 +74,44 @@ import { TransformFlags, TypeNode, TypeReferenceSerializationKind, - unescapeLeadingUnderscores, VariableDeclaration, VariableDeclarationList, VariableStatement, + VisitResult, +} from "../types"; +import { + FunctionFlags, + getEmitScriptTarget, + getEntityNameFromTypeNode, + getFunctionFlags, + getInitializedVariables, + insertStatementsAfterStandardPrologue, + isEffectiveStrictModeSourceFile, + isNodeWithPossibleHoistedDeclaration, + isSuperProperty, +} from "../utilities"; +import { + getOriginalNode, + isConciseBody, + isEntityName, + isExpression, + isForInitializer, + isFunctionLike, + isFunctionLikeDeclaration, + isModifierLike, + isStatement, + isToken, + unescapeLeadingUnderscores, +} from "../utilitiesPublic"; +import { visitEachChild, visitFunctionBody, visitIterationBody, visitNode, visitNodes, visitParameterList, - VisitResult, -} from "../_namespaces/ts"; +} from "../visitorPublic"; +import { chainBundle } from "./utilities"; type SuperContainer = ClassDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration; diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index 296cfaeae2fca..8814e08d42086 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -1,70 +1,64 @@ +import { getNodeId } from "../checkerUtilities"; +import { + addRange, + append, + concatenate, + some, +} from "../core"; +import { Debug } from "../debug"; +import { + advancedAsyncSuperHelper, + asyncSuperHelper, +} from "../factory/emitHelpers"; import { - __String, - AccessorDeclaration, addEmitFlags, addEmitHelper, addEmitHelpers, - addRange, - advancedAsyncSuperHelper, - append, + setEmitFlags, + setSourceMapRange, +} from "../factory/emitNode"; +import { + isBlock, + isIdentifier, + isParameter, + isPropertyAccessExpression, + isVariableDeclarationList, +} from "../factory/nodeTests"; +import { + createForOfBindingStatement, + startOnNewLine, +} from "../factory/utilities"; +import { + setOriginalNode, + setTextRange, +} from "../factory/utilitiesPublic"; +import { + __String, + AccessorDeclaration, ArrowFunction, - asyncSuperHelper, AwaitExpression, BinaryExpression, Bundle, CallExpression, CatchClause, - chainBundle, CommaListExpression, - concatenate, ConciseBody, ConstructorDeclaration, - createForOfBindingStatement, - createSuperAccessVariableStatement, - Debug, ElementAccessExpression, EmitFlags, EmitHint, Expression, ExpressionStatement, - flattenDestructuringAssignment, - flattenDestructuringBinding, - FlattenLevel, ForInitializer, ForOfStatement, ForStatement, FunctionBody, FunctionDeclaration, FunctionExpression, - FunctionFlags, FunctionLikeDeclaration, GeneratedIdentifierFlags, GetAccessorDeclaration, - getEmitScriptTarget, - getFunctionFlags, - getNodeId, - hasSyntacticModifier, Identifier, - insertStatementsAfterStandardPrologue, - isAssignmentPattern, - isBindingPattern, - isBlock, - isConciseBody, - isDestructuringAssignment, - isEffectiveStrictModeSourceFile, - isExpression, - isForInitializer, - isIdentifier, - isModifier, - isModifierLike, - isObjectLiteralElementLike, - isParameter, - isPropertyAccessExpression, - isPropertyName, - isStatement, - isSuperProperty, - isToken, - isVariableDeclarationList, LabeledStatement, LeftHandSideExpression, MethodDeclaration, @@ -76,21 +70,12 @@ import { ObjectLiteralExpression, ParameterDeclaration, ParenthesizedExpression, - ProcessLevel, - processTaggedTemplateExpression, PropertyAccessExpression, ReturnStatement, ScriptTarget, SetAccessorDeclaration, - setEmitFlags, - setOriginalNode, - setSourceMapRange, - setTextRange, SignatureDeclaration, - skipParentheses, - some, SourceFile, - startOnNewLine, Statement, SyntaxKind, TaggedTemplateExpression, @@ -98,19 +83,56 @@ import { Token, TransformationContext, TransformFlags, - unwrapInnermostStatementOfLabel, VariableDeclaration, VariableStatement, + VisitResult, + VoidExpression, + YieldExpression, +} from "../types"; +import { + FunctionFlags, + getEmitScriptTarget, + getFunctionFlags, + hasSyntacticModifier, + insertStatementsAfterStandardPrologue, + isDestructuringAssignment, + isEffectiveStrictModeSourceFile, + isSuperProperty, + skipParentheses, + unwrapInnermostStatementOfLabel, +} from "../utilities"; +import { + isAssignmentPattern, + isBindingPattern, + isConciseBody, + isExpression, + isForInitializer, + isModifier, + isModifierLike, + isObjectLiteralElementLike, + isPropertyName, + isStatement, + isToken, +} from "../utilitiesPublic"; +import { visitEachChild, visitIterationBody, visitLexicalEnvironment, visitNode, visitNodes, visitParameterList, - VisitResult, - VoidExpression, - YieldExpression, -} from "../_namespaces/ts"; +} from "../visitorPublic"; +import { + flattenDestructuringAssignment, + flattenDestructuringBinding, + FlattenLevel, +} from "./destructuring"; +import { createSuperAccessVariableStatement } from "./es2017"; +import { + ProcessLevel, + processTaggedTemplateExpression, +} from "./taggedTemplate"; +import { chainBundle } from "./utilities"; const enum ESNextSubstitutionFlags { /** Enables substitutions for async methods with `super` calls. */ diff --git a/src/compiler/transformers/es2019.ts b/src/compiler/transformers/es2019.ts index 0bd2be45422a4..887050281f642 100644 --- a/src/compiler/transformers/es2019.ts +++ b/src/compiler/transformers/es2019.ts @@ -1,17 +1,19 @@ +import { isBlock } from "../factory/nodeTests"; import { Bundle, CatchClause, - chainBundle, - isBlock, Node, SourceFile, SyntaxKind, TransformationContext, TransformFlags, + VisitResult, +} from "../types"; +import { visitEachChild, visitNode, - VisitResult, -} from "../_namespaces/ts"; +} from "../visitorPublic"; +import { chainBundle } from "./utilities"; /** @internal */ export function transformES2019(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle { diff --git a/src/compiler/transformers/es2020.ts b/src/compiler/transformers/es2020.ts index b030dca03ce5c..651ff91ac7f7d 100644 --- a/src/compiler/transformers/es2020.ts +++ b/src/compiler/transformers/es2020.ts @@ -1,42 +1,52 @@ +import { cast } from "../core"; +import { Debug } from "../debug"; +import { addEmitFlags } from "../factory/emitNode"; +import { + isIdentifier, + isParenthesizedExpression, + isSyntheticReference, + isTaggedTemplateExpression, +} from "../factory/nodeTests"; +import { + setOriginalNode, + setTextRange, +} from "../factory/utilitiesPublic"; import { AccessExpression, - addEmitFlags, BinaryExpression, Bundle, CallExpression, - cast, - chainBundle, - Debug, DeleteExpression, EmitFlags, Expression, - isCallChain, - isExpression, - isGeneratedIdentifier, - isIdentifier, - isNonNullChain, - isOptionalChain, - isParenthesizedExpression, - isSimpleCopiableExpression, - isSyntheticReference, - isTaggedTemplateExpression, Node, OptionalChain, OuterExpressionKinds, ParenthesizedExpression, - setOriginalNode, - setTextRange, - skipParentheses, - skipPartiallyEmittedExpressions, SourceFile, SyntaxKind, TransformationContext, TransformFlags, + VisitResult, +} from "../types"; +import { skipParentheses } from "../utilities"; +import { + isCallChain, + isExpression, + isGeneratedIdentifier, + isNonNullChain, + isOptionalChain, + skipPartiallyEmittedExpressions, +} from "../utilitiesPublic"; +import { visitEachChild, visitNode, visitNodes, - VisitResult, -} from "../_namespaces/ts"; +} from "../visitorPublic"; +import { + chainBundle, + isSimpleCopiableExpression, +} from "./utilities"; /** @internal */ export function transformES2020(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle { diff --git a/src/compiler/transformers/es2021.ts b/src/compiler/transformers/es2021.ts index c521cf00bc7f0..384d976507986 100644 --- a/src/compiler/transformers/es2021.ts +++ b/src/compiler/transformers/es2021.ts @@ -1,27 +1,35 @@ +import { isPropertyAccessExpression } from "../factory/nodeTests"; import { AssignmentExpression, BinaryExpression, Bundle, - chainBundle, - getNonAssignmentOperatorForCompoundAssignment, - isAccessExpression, - isExpression, - isLeftHandSideExpression, - isLogicalOrCoalescingAssignmentExpression, - isPropertyAccessExpression, - isSimpleCopiableExpression, LogicalOrCoalescingAssignmentOperator, Node, - skipParentheses, SourceFile, SyntaxKind, Token, TransformationContext, TransformFlags, + VisitResult, +} from "../types"; +import { + isAccessExpression, + isLogicalOrCoalescingAssignmentExpression, + skipParentheses, +} from "../utilities"; +import { + isExpression, + isLeftHandSideExpression, +} from "../utilitiesPublic"; +import { visitEachChild, visitNode, - VisitResult, -} from "../_namespaces/ts"; +} from "../visitorPublic"; +import { + chainBundle, + getNonAssignmentOperatorForCompoundAssignment, + isSimpleCopiableExpression, +} from "./utilities"; /** @internal */ export function transformES2021(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle { diff --git a/src/compiler/transformers/es5.ts b/src/compiler/transformers/es5.ts index 199cfa582327e..e658d0dc5e5a6 100644 --- a/src/compiler/transformers/es5.ts +++ b/src/compiler/transformers/es5.ts @@ -1,29 +1,33 @@ import { - Bundle, - chainBundle, - EmitHint, - Expression, - getOriginalNodeId, - Identifier, - idText, isIdentifier, isPrivateIdentifier, isPropertyAccessExpression, isPropertyAssignment, +} from "../factory/nodeTests"; +import { setTextRange } from "../factory/utilitiesPublic"; +import { stringToToken } from "../scanner"; +import { + Bundle, + EmitHint, + Expression, + Identifier, JsxClosingElement, JsxEmit, JsxOpeningElement, JsxSelfClosingElement, Node, - nodeIsSynthesized, PropertyAccessExpression, PropertyAssignment, - setTextRange, SourceFile, - stringToToken, SyntaxKind, TransformationContext, -} from "../_namespaces/ts"; +} from "../types"; +import { nodeIsSynthesized } from "../utilities"; +import { idText } from "../utilitiesPublic"; +import { + chainBundle, + getOriginalNodeId, +} from "./utilities"; /** * Transforms ES5 syntax into ES3 syntax. diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 730958dae1e00..c6e001e76d0db 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -1,13 +1,13 @@ import { Bundle, - chainBundle, Node, SourceFile, TransformationContext, TransformFlags, - visitEachChild, VisitResult, -} from "../_namespaces/ts"; +} from "../types"; +import { visitEachChild } from "../visitorPublic"; +import { chainBundle } from "./utilities"; /** @internal */ export function transformESNext(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle { diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 86abe24d056d0..38305076d0e0d 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -1,63 +1,59 @@ import { - AccessorDeclaration, + forEach, + lastOrUndefined, + map, + reduceLeft, +} from "../core"; +import { Debug } from "../debug"; +import { addEmitHelpers, addSyntheticTrailingComment, + setCommentRange, + setEmitFlags, + setSourceMapRange, +} from "../factory/emitNode"; +import { + isBinaryExpression, + isBlock, + isIdentifier, + isVariableDeclarationList, +} from "../factory/nodeTests"; +import { + createExpressionForObjectLiteralElementLike, + startOnNewLine, +} from "../factory/utilities"; +import { + setOriginalNode, + setTextRange, +} from "../factory/utilitiesPublic"; +import { + AccessorDeclaration, ArrayLiteralExpression, - Associativity, BinaryExpression, Block, BreakStatement, Bundle, CallExpression, CaseClause, - chainBundle, CommaListExpression, ConditionalExpression, ContinueStatement, - createExpressionForObjectLiteralElementLike, - Debug, DoStatement, ElementAccessExpression, EmitFlags, EmitHint, Expression, ExpressionStatement, - forEach, ForInStatement, ForStatement, FunctionDeclaration, FunctionExpression, - getEmitFlags, - getEmitScriptTarget, - getExpressionAssociativity, - getInitializedVariables, - getNonAssignmentOperatorForCompoundAssignment, - getOriginalNode, - getOriginalNodeId, Identifier, - idText, IfStatement, InitializedVariableDeclaration, - insertStatementsAfterStandardPrologue, - isBinaryExpression, - isBlock, - isCompoundAssignment, - isExpression, - isFunctionLikeDeclaration, - isGeneratedIdentifier, - isIdentifier, - isImportCall, - isLeftHandSideExpression, - isLogicalOperator, - isObjectLiteralElementLike, - isStatement, - isVariableDeclarationList, LabeledStatement, - lastOrUndefined, LeftHandSideExpression, LiteralExpression, - map, - Mutable, NewExpression, Node, NodeArray, @@ -65,16 +61,8 @@ import { ObjectLiteralElementLike, ObjectLiteralExpression, PropertyAccessExpression, - reduceLeft, ReturnStatement, - setCommentRange, - setEmitFlags, - setOriginalNode, - setParent, - setSourceMapRange, - setTextRange, SourceFile, - startOnNewLine, Statement, SwitchStatement, SyntaxKind, @@ -86,16 +74,46 @@ import { VariableDeclaration, VariableDeclarationList, VariableStatement, + VisitResult, + WhileStatement, + WithStatement, + YieldExpression, +} from "../types"; +import { + Associativity, + getEmitFlags, + getEmitScriptTarget, + getExpressionAssociativity, + getInitializedVariables, + insertStatementsAfterStandardPrologue, + isImportCall, + isLogicalOperator, + Mutable, + setParent, +} from "../utilities"; +import { + getOriginalNode, + idText, + isExpression, + isFunctionLikeDeclaration, + isGeneratedIdentifier, + isLeftHandSideExpression, + isObjectLiteralElementLike, + isStatement, +} from "../utilitiesPublic"; +import { visitEachChild, visitIterationBody, visitNode, visitNodes, visitParameterList, - VisitResult, - WhileStatement, - WithStatement, - YieldExpression, -} from "../_namespaces/ts"; +} from "../visitorPublic"; +import { + chainBundle, + getNonAssignmentOperatorForCompoundAssignment, + getOriginalNodeId, + isCompoundAssignment, +} from "./utilities"; // Transforms generator functions into a compatible ES5 representation with similar runtime // semantics. This is accomplished by first transforming the body of each generator diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 2dab57966eef6..7c148d389d075 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -1,44 +1,48 @@ import { - addEmitHelpers, arrayFrom, - Bundle, - chainBundle, - createExpressionForJsxElement, - createExpressionForJsxFragment, - createExpressionFromEntityName, - createJsxFactoryExpression, - Debug, emptyArray, - Expression, filter, find, flatten, - GeneratedIdentifierFlags, - getEmitScriptTarget, getEntries, - getJSXImplicitImportBase, - getJSXRuntimeImport, - getLineAndCharacterOfPosition, - getOriginalNode, - getSemanticJsxChildren, - Identifier, - idText, - ImportSpecifier, - insertStatementAfterCustomPrologue, - isExpression, - isExternalModule, - isExternalOrCommonJsModule, + isLineBreak, + isWhiteSpaceSingleLine, + length, + map, + mapDefined, + singleOrUndefined, + spanMap, +} from "../core"; +import { Debug } from "../debug"; +import { addEmitHelpers } from "../factory/emitNode"; +import { isIdentifier, - isIntrinsicJsxName, isJsxAttribute, isJsxElement, isJsxFragment, isJsxSelfClosingElement, isJsxSpreadAttribute, - isLineBreak, isSourceFile, - isStringDoubleQuoted, - isWhiteSpaceSingleLine, +} from "../factory/nodeTests"; +import { + createExpressionForJsxElement, + createExpressionForJsxFragment, + createExpressionFromEntityName, + createJsxFactoryExpression, + startOnNewLine, +} from "../factory/utilities"; +import { setTextRange } from "../factory/utilitiesPublic"; +import { isExternalModule } from "../parser"; +import { + getLineAndCharacterOfPosition, + utf16EncodeAsString, +} from "../scanner"; +import { + Bundle, + Expression, + GeneratedIdentifierFlags, + Identifier, + ImportSpecifier, JsxAttribute, JsxAttributeValue, JsxChild, @@ -51,32 +55,42 @@ import { JsxSelfClosingElement, JsxSpreadAttribute, JsxText, - length, - map, - mapDefined, Node, NodeFlags, PropertyAssignment, ScriptTarget, - setParentRecursive, - setTextRange, - singleOrUndefined, SourceFile, - spanMap, SpreadAssignment, - startOnNewLine, Statement, StringLiteral, SyntaxKind, TextRange, TransformationContext, TransformFlags, - utf16EncodeAsString, VariableDeclaration, + VisitResult, +} from "../types"; +import { + getEmitScriptTarget, + getJSXImplicitImportBase, + getJSXRuntimeImport, + getSemanticJsxChildren, + insertStatementAfterCustomPrologue, + isExternalOrCommonJsModule, + isIntrinsicJsxName, + isStringDoubleQuoted, + setParentRecursive, +} from "../utilities"; +import { + getOriginalNode, + idText, + isExpression, +} from "../utilitiesPublic"; +import { visitEachChild, visitNode, - VisitResult, -} from "../_namespaces/ts"; +} from "../visitorPublic"; +import { chainBundle } from "./utilities"; /** @internal */ export function transformJsx(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle { diff --git a/src/compiler/transformers/legacyDecorators.ts b/src/compiler/transformers/legacyDecorators.ts index 976e0705e730b..475c6e5017eb3 100644 --- a/src/compiler/transformers/legacyDecorators.ts +++ b/src/compiler/transformers/legacyDecorators.ts @@ -1,83 +1,99 @@ import { - addEmitHelpers, addRange, - AllDecorators, append, - Bundle, + filter, + flatMap, + map, + singleOrMany, + some, +} from "../core"; +import { + addEmitHelpers, + setCommentRange, + setEmitFlags, + setSourceMapRange, +} from "../factory/emitNode"; +import { + isBlock, + isComputedPropertyName, + isDecorator, + isHeritageClause, + isIdentifier, + isPrivateIdentifier, + isPropertyDeclaration, +} from "../factory/nodeTests"; +import { elideNodes } from "../factory/utilities"; +import { canHaveDecorators, - chainBundle, - childIsDecorated, + setOriginalNode, + setTextRange, +} from "../factory/utilitiesPublic"; +import { + AllDecorators, + Bundle, ClassDeclaration, ClassElement, ClassExpression, ClassLikeDeclaration, - classOrConstructorParameterIsDecorated, ConstructorDeclaration, Decorator, - elideNodes, EmitFlags, EmitHint, EnumMember, Expression, - filter, - flatMap, GetAccessorDeclaration, - getAllDecoratorsOfClass, - getAllDecoratorsOfClassElement, - getEmitFlags, - getEmitScriptTarget, - getOriginalNodeId, - hasAccessorModifier, - hasDecorators, - hasSyntacticModifier, Identifier, - idText, - isBindingName, - isBlock, - isClassElement, - isComputedPropertyName, - isDecorator, - isExpression, - isGeneratedIdentifier, - isHeritageClause, - isIdentifier, - isModifier, - isParameterDeclaration, - isPrivateIdentifier, - isPropertyDeclaration, - isPropertyName, - isSimpleInlineableExpression, - isStatic, - map, MethodDeclaration, ModifierFlags, - moveRangePastModifiers, Node, NodeArray, NodeCheckFlags, NodeFlags, - nodeOrChildIsDecorated, ParameterDeclaration, PropertyDeclaration, ScriptTarget, SetAccessorDeclaration, - setCommentRange, - setEmitFlags, - setOriginalNode, - setSourceMapRange, - setTextRange, - singleOrMany, - some, SourceFile, Statement, SyntaxKind, TransformationContext, TransformFlags, + VisitResult, +} from "../types"; +import { + childIsDecorated, + classOrConstructorParameterIsDecorated, + getEmitFlags, + getEmitScriptTarget, + hasAccessorModifier, + hasDecorators, + hasSyntacticModifier, + isParameterDeclaration, + isStatic, + moveRangePastModifiers, + nodeOrChildIsDecorated, +} from "../utilities"; +import { + idText, + isBindingName, + isClassElement, + isExpression, + isGeneratedIdentifier, + isModifier, + isPropertyName, +} from "../utilitiesPublic"; +import { visitEachChild, visitNode, visitNodes, - VisitResult, -} from "../_namespaces/ts"; +} from "../visitorPublic"; +import { + chainBundle, + getAllDecoratorsOfClass, + getAllDecoratorsOfClassElement, + getOriginalNodeId, + isSimpleInlineableExpression, +} from "./utilities"; /** @internal */ export function transformLegacyDecorators(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle { diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index c6d065a77b88f..3bdb66b37b6ae 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -1,53 +1,67 @@ import { addRange, append, - Bundle, - chainBundle, + singleOrMany, + some, +} from "../../core"; +import { Debug } from "../../debug"; +import { + isIdentifier, + isNamespaceExport, + isSourceFile, +} from "../../factory/nodeTests"; +import { createEmptyExports, createExternalHelpersImportDeclarationIfNeeded, - Debug, + getExternalModuleNameLiteral, +} from "../../factory/utilities"; +import { + setOriginalNode, + setTextRange, +} from "../../factory/utilitiesPublic"; +import { isExternalModule } from "../../parser"; +import { + Bundle, EmitFlags, EmitHint, ExportAssignment, ExportDeclaration, Expression, GeneratedIdentifierFlags, - getEmitFlags, - getEmitModuleKind, - getEmitScriptTarget, - getExternalModuleNameLiteral, - hasSyntacticModifier, Identifier, - idText, ImportDeclaration, ImportEqualsDeclaration, - insertStatementsAfterCustomPrologue, - isExportNamespaceAsDefaultDeclaration, - isExternalModule, - isExternalModuleImportEqualsDeclaration, - isExternalModuleIndicator, - isIdentifier, - isNamespaceExport, - isSourceFile, - isStatement, ModifierFlags, ModuleKind, Node, NodeFlags, ScriptTarget, - setOriginalNode, - setTextRange, - singleOrMany, - some, SourceFile, Statement, SyntaxKind, TransformationContext, VariableStatement, + VisitResult, +} from "../../types"; +import { + getEmitFlags, + getEmitModuleKind, + getEmitScriptTarget, + hasSyntacticModifier, + insertStatementsAfterCustomPrologue, + isExportNamespaceAsDefaultDeclaration, + isExternalModuleImportEqualsDeclaration, +} from "../../utilities"; +import { + idText, + isExternalModuleIndicator, + isStatement, +} from "../../utilitiesPublic"; +import { visitEachChild, visitNodes, - VisitResult, -} from "../../_namespaces/ts"; +} from "../../visitorPublic"; +import { chainBundle } from "../utilities"; /** @internal */ export function transformECMAScriptModule(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle { diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index adedbd1281714..b3b83a8086c88 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1,100 +1,80 @@ +import { getNodeId } from "../../checkerUtilities"; +import { + addRange, + append, + emptyArray, + firstOrUndefined, + length, + mapDefined, + reduceLeft, + singleOrMany, +} from "../../core"; +import { Debug } from "../../debug"; import { addEmitFlags, addEmitHelper, addEmitHelpers, - addRange, - append, + removeAllComments, + setEmitFlags, +} from "../../factory/emitNode"; +import { + isArrayLiteralExpression, + isArrowFunction, + isClassExpression, + isExportDeclaration, + isFunctionExpression, + isIdentifier, + isImportClause, + isImportEqualsDeclaration, + isImportSpecifier, + isNamedExports, + isObjectLiteralExpression, + isOmittedExpression, + isPrefixUnaryExpression, + isShorthandPropertyAssignment, + isSpreadElement, + isStringLiteral, +} from "../../factory/nodeTests"; +import { + getExternalHelpersModuleName, + getExternalModuleNameLiteral, + getLocalNameForExternalImport, + isExportName, + isLocalName, + startOnNewLine, + tryGetModuleNameFromFile, +} from "../../factory/utilities"; +import { + setOriginalNode, + setTextRange, +} from "../../factory/utilitiesPublic"; +import { isExternalModule } from "../../parser"; +import { ArrowFunction, BinaryExpression, BindingElement, Bundle, CallExpression, - chainBundle, ClassDeclaration, - collectExternalModuleInfo, - Debug, Declaration, DestructuringAssignment, EmitFlags, EmitHelper, EmitHint, - emptyArray, EndOfDeclarationMarker, ExportAssignment, ExportDeclaration, Expression, ExpressionStatement, - ExternalModuleInfo, - firstOrUndefined, - flattenDestructuringAssignment, - FlattenLevel, ForStatement, FunctionDeclaration, FunctionExpression, GeneratedIdentifierFlags, - getEmitFlags, - getEmitModuleKind, - getEmitScriptTarget, - getESModuleInterop, - getExportNeedsImportStarHelper, - getExternalHelpersModuleName, - getExternalModuleNameLiteral, - getImportNeedsImportDefaultHelper, - getImportNeedsImportStarHelper, - getLocalNameForExternalImport, - getNamespaceDeclarationNode, - getNodeId, - getOriginalNodeId, - getStrictOptionValue, - getTextOfIdentifierOrLiteral, - hasJsonModuleEmitEnabled, - hasSyntacticModifier, Identifier, - idText, ImportCall, ImportDeclaration, ImportEqualsDeclaration, InitializedVariableDeclaration, - insertStatementsAfterStandardPrologue, - isArrayLiteralExpression, - isArrowFunction, - isAssignmentOperator, - isBindingPattern, - isClassExpression, - isDeclarationNameOfEnumOrNamespace, - isDefaultImport, - isDestructuringAssignment, - isEffectiveExternalModule, - isExportDeclaration, - isExportName, - isExportNamespaceAsDefaultDeclaration, - isExpression, - isExternalModule, - isExternalModuleImportEqualsDeclaration, - isForInitializer, - isFunctionExpression, - isGeneratedIdentifier, - isIdentifier, - isImportCall, - isImportClause, - isImportEqualsDeclaration, - isImportSpecifier, - isJsonSourceFile, - isLocalName, - isModifier, - isModifierLike, - isNamedExports, - isObjectLiteralExpression, - isOmittedExpression, - isPrefixUnaryExpression, - isShorthandPropertyAssignment, - isSimpleCopiableExpression, - isSimpleInlineableExpression, - isSpreadElement, - isStatement, - isStringLiteral, - length, - mapDefined, MergeDeclarationMarker, Modifier, ModifierFlags, @@ -103,37 +83,77 @@ import { NodeArray, NodeFlags, ObjectLiteralElementLike, - outFile, ParameterDeclaration, ParenthesizedExpression, PartiallyEmittedExpression, PostfixUnaryExpression, PrefixUnaryExpression, - reduceLeft, - removeAllComments, ScriptTarget, - setEmitFlags, - setOriginalNode, - setTextRange, ShorthandPropertyAssignment, - singleOrMany, SourceFile, - startOnNewLine, Statement, SyntaxKind, TaggedTemplateExpression, TextRange, TransformationContext, TransformFlags, - tryGetModuleNameFromFile, VariableDeclaration, VariableStatement, + VisitResult, +} from "../../types"; +import { + getEmitFlags, + getEmitModuleKind, + getEmitScriptTarget, + getESModuleInterop, + getNamespaceDeclarationNode, + getStrictOptionValue, + getTextOfIdentifierOrLiteral, + hasJsonModuleEmitEnabled, + hasSyntacticModifier, + insertStatementsAfterStandardPrologue, + isAssignmentOperator, + isDeclarationNameOfEnumOrNamespace, + isDefaultImport, + isDestructuringAssignment, + isEffectiveExternalModule, + isExportNamespaceAsDefaultDeclaration, + isExternalModuleImportEqualsDeclaration, + isImportCall, + isJsonSourceFile, + outFile, +} from "../../utilities"; +import { + idText, + isBindingPattern, + isExpression, + isForInitializer, + isGeneratedIdentifier, + isModifier, + isModifierLike, + isStatement, +} from "../../utilitiesPublic"; +import { visitEachChild, visitIterationBody, visitNode, visitNodes, - VisitResult, -} from "../../_namespaces/ts"; +} from "../../visitorPublic"; +import { + flattenDestructuringAssignment, + FlattenLevel, +} from "../destructuring"; +import { + chainBundle, + collectExternalModuleInfo, + ExternalModuleInfo, + getExportNeedsImportStarHelper, + getImportNeedsImportDefaultHelper, + getImportNeedsImportStarHelper, + getOriginalNodeId, + isSimpleCopiableExpression, + isSimpleInlineableExpression, +} from "../utilities"; /** @internal */ export function transformModule(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle { diff --git a/src/compiler/transformers/module/node.ts b/src/compiler/transformers/module/node.ts index 576c15fe6597e..9463ad5dbe73a 100644 --- a/src/compiler/transformers/module/node.ts +++ b/src/compiler/transformers/module/node.ts @@ -1,17 +1,17 @@ +import { map } from "../../core"; +import { Debug } from "../../debug"; +import { isSourceFile } from "../../factory/nodeTests"; import { Bundle, - Debug, EmitHint, - isSourceFile, - map, ModuleKind, Node, SourceFile, SyntaxKind, TransformationContext, - transformECMAScriptModule, - transformModule, -} from "../../_namespaces/ts"; +} from "../../types"; +import { transformECMAScriptModule } from "./esnextAnd2015"; +import { transformModule } from "./module"; /** @internal */ export function transformNodeModule(context: TransformationContext) { diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index c773832382369..60ce4be2130e7 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -1,6 +1,48 @@ +import { getNodeId } from "../../checkerUtilities"; import { addRange, append, + firstOrUndefined, + forEach, + map, + singleOrMany, + some, +} from "../../core"; +import { Debug } from "../../debug"; +import { + moveEmitHelpers, + setCommentRange, + setEmitFlags, +} from "../../factory/emitNode"; +import { + isArrayLiteralExpression, + isBlock, + isCaseBlock, + isHeritageClause, + isIdentifier, + isImportClause, + isImportSpecifier, + isNamedExports, + isObjectLiteralExpression, + isOmittedExpression, + isPrefixUnaryExpression, + isPropertyAssignment, + isShorthandPropertyAssignment, + isSpreadElement, + isStringLiteral, + isVariableDeclarationList, +} from "../../factory/nodeTests"; +import { + getExternalHelpersModuleName, + getExternalModuleNameLiteral, + getLocalNameForExternalImport, + isLocalName, + startOnNewLine, + tryGetModuleNameFromFile, +} from "../../factory/utilities"; +import { setTextRange } from "../../factory/utilitiesPublic"; +import { isExternalModule } from "../../parser"; +import { BinaryExpression, BindingElement, Block, @@ -9,10 +51,7 @@ import { CaseClause, CaseOrDefaultClause, CatchClause, - chainBundle, ClassDeclaration, - collectExternalModuleInfo, - Debug, Declaration, DefaultClause, DestructuringAssignment, @@ -24,91 +63,29 @@ import { ExportDeclaration, Expression, ExpressionStatement, - ExternalModuleInfo, - firstOrUndefined, - flattenDestructuringAssignment, - FlattenLevel, - forEach, ForInitializer, ForInStatement, ForOfStatement, ForStatement, FunctionDeclaration, - getEmitFlags, - getExternalHelpersModuleName, - getExternalModuleNameLiteral, - getLocalNameForExternalImport, - getNodeId, - getOriginalNode, - getOriginalNodeId, - getStrictOptionValue, - getTextOfIdentifierOrLiteral, - hasSyntacticModifier, Identifier, - idText, ImportCall, ImportDeclaration, ImportEqualsDeclaration, - insertStatementsAfterStandardPrologue, - isArrayLiteralExpression, - isAssignmentExpression, - isAssignmentOperator, - isBindingPattern, - isBlock, - isCaseBlock, - isCaseOrDefaultClause, - isClassElement, - isDeclarationNameOfEnumOrNamespace, - isDestructuringAssignment, - isEffectiveExternalModule, - isExpression, - isExternalModule, - isExternalModuleImportEqualsDeclaration, - isForInitializer, - isGeneratedIdentifier, - isHeritageClause, - isIdentifier, - isImportCall, - isImportClause, - isImportMeta, - isImportSpecifier, - isLocalName, - isModifierLike, - isModuleOrEnumDeclaration, - isNamedExports, - isObjectLiteralExpression, - isOmittedExpression, - isParameterDeclaration, - isPrefixUnaryExpression, - isPropertyAssignment, - isShorthandPropertyAssignment, - isSpreadElement, - isStatement, - isStringLiteral, - isVariableDeclarationList, LabeledStatement, - map, MergeDeclarationMarker, MetaProperty, ModifierFlags, - moveEmitHelpers, Node, NodeFlags, ObjectLiteralElementLike, - outFile, ParenthesizedExpression, PartiallyEmittedExpression, PostfixUnaryExpression, PrefixUnaryExpression, PropertyAssignment, - setCommentRange, - setEmitFlags, - setTextRange, ShorthandPropertyAssignment, - singleOrMany, - some, SourceFile, - startOnNewLine, Statement, StringLiteral, SwitchStatement, @@ -116,19 +93,60 @@ import { TextRange, TransformationContext, TransformFlags, - tryGetModuleNameFromFile, TryStatement, VariableDeclaration, VariableDeclarationList, VariableStatement, + VisitResult, + WhileStatement, + WithStatement, +} from "../../types"; +import { + getEmitFlags, + getStrictOptionValue, + getTextOfIdentifierOrLiteral, + hasSyntacticModifier, + insertStatementsAfterStandardPrologue, + isAssignmentExpression, + isAssignmentOperator, + isDeclarationNameOfEnumOrNamespace, + isDestructuringAssignment, + isEffectiveExternalModule, + isExternalModuleImportEqualsDeclaration, + isImportCall, + isImportMeta, + isParameterDeclaration, + outFile, +} from "../../utilities"; +import { + getOriginalNode, + idText, + isBindingPattern, + isCaseOrDefaultClause, + isClassElement, + isExpression, + isForInitializer, + isGeneratedIdentifier, + isModifierLike, + isModuleOrEnumDeclaration, + isStatement, +} from "../../utilitiesPublic"; +import { visitEachChild, visitIterationBody, visitNode, visitNodes, - VisitResult, - WhileStatement, - WithStatement, -} from "../../_namespaces/ts"; +} from "../../visitorPublic"; +import { + flattenDestructuringAssignment, + FlattenLevel, +} from "../destructuring"; +import { + chainBundle, + collectExternalModuleInfo, + ExternalModuleInfo, + getOriginalNodeId, +} from "../utilities"; /** @internal */ export function transformSystemModule(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle { diff --git a/src/compiler/transformers/taggedTemplate.ts b/src/compiler/transformers/taggedTemplate.ts index 041e0adf84acb..01ad0ca9ba4f1 100644 --- a/src/compiler/transformers/taggedTemplate.ts +++ b/src/compiler/transformers/taggedTemplate.ts @@ -1,16 +1,13 @@ +import { Debug } from "../debug"; +import { factory } from "../factory/nodeFactory"; +import { isNoSubstitutionTemplateLiteral } from "../factory/nodeTests"; +import { setTextRange } from "../factory/utilitiesPublic"; +import { isExternalModule } from "../parser"; import { CallExpression, - Debug, Expression, - factory, - getSourceTextOfNodeFromSourceFile, - hasInvalidEscape, Identifier, - isExpression, - isExternalModule, - isNoSubstitutionTemplateLiteral, NoSubstitutionTemplateLiteral, - setTextRange, SourceFile, SyntaxKind, TaggedTemplateExpression, @@ -19,10 +16,17 @@ import { TemplateMiddle, TemplateTail, TransformationContext, + Visitor, +} from "../types"; +import { + getSourceTextOfNodeFromSourceFile, + hasInvalidEscape, +} from "../utilities"; +import { isExpression } from "../utilitiesPublic"; +import { visitEachChild, visitNode, - Visitor, -} from "../_namespaces/ts"; +} from "../visitorPublic"; /** @internal */ export enum ProcessLevel { diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 1b27a345ce67b..0a7db17190996 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1,36 +1,80 @@ +import { isInstantiatedModule } from "../checker"; +import { + addRange, + append, + concatenate, + filter, + firstOrUndefined, + flatMap, + isArray, + lastOrUndefined, + map, + mapDefined, + singleOrMany, + some, +} from "../core"; +import { Debug } from "../debug"; import { - __String, - AccessorDeclaration, addEmitFlags, addEmitHelpers, - addRange, addSyntheticTrailingComment, + removeAllComments, + setCommentRange, + setConstantValue, + setEmitFlags, + setSourceMapRange, + setSyntheticLeadingComments, + setSyntheticTrailingComments, + setTypeNode, +} from "../factory/emitNode"; +import { createUnparsedSourceFile } from "../factory/nodeFactory"; +import { + isComputedPropertyName, + isDecorator, + isElementAccessExpression, + isExportSpecifier, + isHeritageClause, + isIdentifier, + isImportClause, + isImportSpecifier, + isJsxAttributes, + isModuleDeclaration, + isNamespaceExport, + isPrivateIdentifier, + isPropertyAccessExpression, + isShorthandPropertyAssignment, + isSourceFile, +} from "../factory/nodeTests"; +import { + createExpressionFromEntityName, + elideNodes, + isLocalName, + startOnNewLine, +} from "../factory/utilities"; +import { + setOriginalNode, + setTextRange, +} from "../factory/utilitiesPublic"; +import { isExternalModule } from "../parser"; +import { skipTrivia } from "../scanner"; +import { + __String, + AccessorDeclaration, AllDecorators, - append, ArrowFunction, AssertionExpression, Block, Bundle, CallExpression, CaseBlock, - childIsDecorated, ClassDeclaration, ClassElement, ClassExpression, ClassLikeDeclaration, - classOrConstructorParameterIsDecorated, - concatenate, ConstructorDeclaration, - createExpressionFromEntityName, - createRange, - createRuntimeTypeSerializer, - createTokenRange, - createUnparsedSourceFile, - Debug, Declaration, Decorator, ElementAccessExpression, - elideNodes, EmitFlags, EmitHint, EntityName, @@ -41,100 +85,27 @@ import { ExportSpecifier, Expression, ExpressionWithTypeArguments, - filter, - findSuperStatementIndex, - firstOrUndefined, - flatMap, - flattenDestructuringAssignment, - FlattenLevel, FunctionDeclaration, FunctionExpression, FunctionLikeDeclaration, GetAccessorDeclaration, - getAllDecoratorsOfClass, - getAllDecoratorsOfClassElement, - getEffectiveBaseTypeNode, - getEmitFlags, - getEmitModuleKind, - getEmitScriptTarget, - getFirstConstructorWithBody, - getInitializedVariables, - getOriginalNode, - getParseTreeNode, - getProperties, - getStrictOptionValue, - getTextOfNode, - hasDecorators, - hasStaticModifier, - hasSyntacticModifier, HeritageClause, Identifier, - idText, ImportClause, ImportDeclaration, ImportEqualsDeclaration, ImportsNotUsedAsValues, ImportSpecifier, InitializedVariableDeclaration, - insertStatementsAfterStandardPrologue, - isAccessExpression, - isArray, - isAssertionExpression, - isBindingName, - isBindingPattern, - isClassElement, - isClassLike, - isComputedPropertyName, - isDecorator, - isElementAccessExpression, - isEnumConst, - isExportSpecifier, - isExpression, - isExternalModule, - isExternalModuleImportEqualsDeclaration, - isGeneratedIdentifier, - isHeritageClause, - isIdentifier, - isImportClause, - isImportSpecifier, - isInJSFile, - isInstantiatedModule, - isJsonSourceFile, - isJsxAttributes, - isJsxTagNameExpression, - isLeftHandSideExpression, - isLocalName, - isModifier, - isModifierLike, - isModuleDeclaration, - isNamedExportBindings, - isNamedImportBindings, - isNamespaceExport, - isObjectLiteralElement, - isParameterPropertyDeclaration, - isPrivateIdentifier, - isPropertyAccessExpression, - isPropertyName, - isShorthandPropertyAssignment, - isSimpleInlineableExpression, - isSourceFile, - isStatement, JsxOpeningElement, JsxSelfClosingElement, - lastOrUndefined, LeftHandSideExpression, - map, - mapDefined, MethodDeclaration, ModifierFlags, ModifierLike, - modifierToFlag, ModuleBlock, ModuleDeclaration, ModuleKind, - moveRangePastDecorators, - moveRangePastModifiers, - moveRangePos, NamedExportBindings, NamedExports, NamedImportBindings, @@ -142,44 +113,20 @@ import { NewExpression, Node, NodeFlags, - nodeIsMissing, NonNullExpression, ObjectLiteralElementLike, ObjectLiteralExpression, OuterExpressionKinds, ParameterDeclaration, - parameterIsThisKeyword, - ParameterPropertyDeclaration, ParenthesizedExpression, PropertyAccessExpression, PropertyDeclaration, PropertyName, - removeAllComments, SatisfiesExpression, ScriptTarget, SetAccessorDeclaration, - setCommentRange, - setConstantValue, - setEmitFlags, - setOriginalNode, - setParent, - setSourceMapRange, - setSyntheticLeadingComments, - setSyntheticTrailingComments, - setTextRange, - setTextRangeEnd, - setTextRangePos, - setTextRangePosEnd, - setTypeNode, ShorthandPropertyAssignment, - shouldPreserveConstEnums, - singleOrMany, - skipOuterExpressions, - skipPartiallyEmittedExpressions, - skipTrivia, - some, SourceFile, - startOnNewLine, Statement, SyntaxKind, TaggedTemplateExpression, @@ -189,6 +136,68 @@ import { UnderscoreEscapedMap, VariableDeclaration, VariableStatement, + VisitResult, +} from "../types"; +import { + childIsDecorated, + classOrConstructorParameterIsDecorated, + createRange, + createTokenRange, + getEffectiveBaseTypeNode, + getEmitFlags, + getEmitModuleKind, + getEmitScriptTarget, + getFirstConstructorWithBody, + getInitializedVariables, + getStrictOptionValue, + getTextOfNode, + hasDecorators, + hasStaticModifier, + hasSyntacticModifier, + insertStatementsAfterStandardPrologue, + isAccessExpression, + isEnumConst, + isExternalModuleImportEqualsDeclaration, + isInJSFile, + isJsonSourceFile, + modifierToFlag, + moveRangePastDecorators, + moveRangePastModifiers, + moveRangePos, + nodeIsMissing, + parameterIsThisKeyword, + setParent, + setTextRangeEnd, + setTextRangePos, + setTextRangePosEnd, + shouldPreserveConstEnums, + skipOuterExpressions, +} from "../utilities"; +import { + getOriginalNode, + getParseTreeNode, + idText, + isAssertionExpression, + isBindingName, + isBindingPattern, + isClassElement, + isClassLike, + isExpression, + isGeneratedIdentifier, + isJsxTagNameExpression, + isLeftHandSideExpression, + isModifier, + isModifierLike, + isNamedExportBindings, + isNamedImportBindings, + isObjectLiteralElement, + isParameterPropertyDeclaration, + isPropertyName, + isStatement, + ParameterPropertyDeclaration, + skipPartiallyEmittedExpressions, +} from "../utilitiesPublic"; +import { visitArray, visitEachChild, visitFunctionBody, @@ -196,8 +205,19 @@ import { visitNode, visitNodes, visitParameterList, - VisitResult, -} from "../_namespaces/ts"; +} from "../visitorPublic"; +import { + flattenDestructuringAssignment, + FlattenLevel, +} from "./destructuring"; +import { createRuntimeTypeSerializer } from "./typeSerializer"; +import { + findSuperStatementIndex, + getAllDecoratorsOfClass, + getAllDecoratorsOfClassElement, + getProperties, + isSimpleInlineableExpression, +} from "./utilities"; /** * Indicates whether to emit type metadata in the new format. diff --git a/src/compiler/transformers/typeSerializer.ts b/src/compiler/transformers/typeSerializer.ts index ca773490be011..454c04d997dda 100644 --- a/src/compiler/transformers/typeSerializer.ts +++ b/src/compiler/transformers/typeSerializer.ts @@ -1,3 +1,20 @@ +import { Debug } from "../debug"; +import { factory } from "../factory/nodeFactory"; +import { + isBinaryExpression, + isConditionalExpression, + isConditionalTypeNode, + isIdentifier, + isLiteralTypeNode, + isNumericLiteral, + isParenthesizedExpression, + isPropertyAccessExpression, + isStringLiteral, + isTypeOfExpression, + isVoidExpression, +} from "../factory/nodeTests"; +import { setTextRange } from "../factory/utilitiesPublic"; +import { parseNodeFactory } from "../parser"; import { AccessorDeclaration, ArrayLiteralExpression, @@ -8,36 +25,10 @@ import { ClassLikeDeclaration, ConditionalExpression, ConditionalTypeNode, - Debug, EntityName, Expression, - factory, - findAncestor, FunctionLikeDeclaration, - getAllAccessorDeclarations, - getEffectiveReturnTypeNode, - getEmitScriptTarget, - getFirstConstructorWithBody, - getParseTreeNode, - getRestParameterElementType, - getSetAccessorTypeAnnotationNode, - getStrictOptionValue, Identifier, - isAsyncFunction, - isBinaryExpression, - isClassLike, - isConditionalExpression, - isConditionalTypeNode, - isFunctionLike, - isGeneratedIdentifier, - isIdentifier, - isLiteralTypeNode, - isNumericLiteral, - isParenthesizedExpression, - isPropertyAccessExpression, - isStringLiteral, - isTypeOfExpression, - isVoidExpression, JSDocNonNullableType, JSDocNullableType, JSDocOptionalType, @@ -45,19 +36,14 @@ import { MethodDeclaration, ModuleBlock, Node, - nodeIsPresent, NumericLiteral, ParameterDeclaration, - parseNodeFactory, PrefixUnaryExpression, PropertyAccessEntityNameExpression, PropertyDeclaration, QualifiedName, ScriptTarget, - setParent, - setTextRange, SignatureDeclaration, - skipTypeParentheses, SourceFile, SyntaxKind, TransformationContext, @@ -68,7 +54,27 @@ import { TypeReferenceSerializationKind, UnionOrIntersectionTypeNode, VoidExpression, -} from "../_namespaces/ts"; +} from "../types"; +import { + getAllAccessorDeclarations, + getEffectiveReturnTypeNode, + getEmitScriptTarget, + getFirstConstructorWithBody, + getRestParameterElementType, + getSetAccessorTypeAnnotationNode, + getStrictOptionValue, + isAsyncFunction, + nodeIsPresent, + setParent, + skipTypeParentheses, +} from "../utilities"; +import { + findAncestor, + getParseTreeNode, + isClassLike, + isFunctionLike, + isGeneratedIdentifier, +} from "../utilitiesPublic"; /** @internal */ export type SerializedEntityName = diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 90ef9bffb7f9d..e679e0bf0d30d 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -1,11 +1,31 @@ +import { getNodeId } from "../checkerUtilities"; +import { + append, + cast, + createMultiMap, + filter, + map, + some, +} from "../core"; +import { + isClassStaticBlockDeclaration, + isExpressionStatement, + isIdentifier, + isNamedExports, + isNamedImports, + isOmittedExpression, + isPrivateIdentifier, + isPropertyDeclaration, +} from "../factory/nodeTests"; +import { + createExternalHelpersImportDeclarationIfNeeded, +} from "../factory/utilities"; import { AccessorDeclaration, AllDecorators, - append, BinaryOperator, BindingElement, Bundle, - cast, ClassDeclaration, ClassElement, ClassExpression, @@ -14,65 +34,31 @@ import { CompilerOptions, CompoundAssignmentOperator, CoreTransformationContext, - createExternalHelpersImportDeclarationIfNeeded, - createMultiMap, Decorator, EmitResolver, ExportAssignment, ExportDeclaration, ExportSpecifier, Expression, - filter, FunctionDeclaration, FunctionLikeDeclaration, - getAllAccessorDeclarations, - getDecorators, - getFirstConstructorWithBody, - getNamespaceDeclarationNode, - getNodeId, - getOriginalNode, - hasDecorators, - hasStaticModifier, - hasSyntacticModifier, Identifier, - idText, ImportDeclaration, ImportEqualsDeclaration, ImportSpecifier, InitializedPropertyDeclaration, InternalSymbolName, - isAutoAccessorPropertyDeclaration, - isBindingPattern, - isClassStaticBlockDeclaration, - isDefaultImport, - isExpressionStatement, - isGeneratedIdentifier, - isIdentifier, - isKeyword, - isMethodOrAccessor, - isNamedExports, - isNamedImports, - isOmittedExpression, - isPrivateIdentifier, - isPropertyDeclaration, - isStatic, - isStringLiteralLike, - isSuperCall, LogicalOperatorOrHigher, - map, MethodDeclaration, ModifierFlags, NamedImportBindings, NamespaceExport, Node, NodeArray, - parameterIsThisKeyword, PrivateIdentifierAccessorDeclaration, PrivateIdentifierAutoAccessorPropertyDeclaration, PrivateIdentifierMethodDeclaration, PropertyDeclaration, - skipParentheses, - some, SourceFile, Statement, SuperCall, @@ -80,7 +66,31 @@ import { TransformationContext, VariableDeclaration, VariableStatement, -} from "../_namespaces/ts"; +} from "../types"; +import { + getAllAccessorDeclarations, + getFirstConstructorWithBody, + getNamespaceDeclarationNode, + hasDecorators, + hasStaticModifier, + hasSyntacticModifier, + isDefaultImport, + isKeyword, + isStatic, + isSuperCall, + parameterIsThisKeyword, + skipParentheses, +} from "../utilities"; +import { + getDecorators, + getOriginalNode, + idText, + isAutoAccessorPropertyDeclaration, + isBindingPattern, + isGeneratedIdentifier, + isMethodOrAccessor, + isStringLiteralLike, +} from "../utilitiesPublic"; /** @internal */ export function getOriginalNodeId(node: Node) { diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index dedf7e4729945..456750902f878 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -1,9 +1,11 @@ import { combinePaths, - Extension, fileExtensionIs, +} from "./path"; +import { + Extension, ResolvedConfigFileName, -} from "./_namespaces/ts"; +} from "./types"; /** @internal */ export enum UpToDateStatusType { diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 6eb8ed8862c3c..e96d397a4f1ae 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -1,138 +1,168 @@ import * as ts from "./_namespaces/ts"; +import { + getBuildInfoFileVersionMap, + getPendingEmitKind, + ProgramBuildInfo, + ProgramBundleEmitBuildInfo, + ProgramMultiFileEmitBuildInfo, +} from "./builder"; import { AffectedFileResult, - arrayToMap, - assertType, BuilderProgram, - BuildInfo, - CancellationToken, + EmitAndSemanticDiagnosticsBuilderProgram, + SemanticDiagnosticsBuilderProgram, +} from "./builderPublic"; +import { OutputFile } from "./builderStatePublic"; +import { canJsonReportNoInputFiles, - changeCompilerHostLikeToUseCache, - clearMap, - closeFileWatcher, - closeFileWatcherOf, commonOptionsWithBuild, - CompilerHost, - CompilerOptions, - CompilerOptionsValue, - ConfigFileProgramReloadLevel, - convertToRelativePath, + DiagnosticReporter, + ExtendedConfigCacheEntry, + getFileNamesFromConfigSpecs, + getParsedCommandLineOfConfigFile, + ParseConfigFileHost, + updateErrorForNoInputFiles, +} from "./commandLineParser"; +import { + arrayToMap, + assertType, copyProperties, - createCompilerDiagnostic, - createCompilerHostFromProgramHost, - createDiagnosticCollection, - createDiagnosticReporter, createGetCanonicalFileName, - createModuleResolutionCache, - CreateProgram, - createProgramHost, - createTypeReferenceDirectiveResolutionCache, - createWatchFactory, - createWatchHost, - CustomTransformers, - Debug, - Diagnostic, - DiagnosticCollection, - DiagnosticMessage, - DiagnosticReporter, - Diagnostics, - EmitAndSemanticDiagnosticsBuilderProgram, - emitFilesAndReportErrors, - EmitResult, - emitUsingBuildInfo, emptyArray, - ExitStatus, - ExtendedConfigCacheEntry, - FileWatcher, - FileWatcherCallback, findIndex, - flattenDiagnosticMessageText, forEach, - ForegroundColorEscapeSequences, - formatColorAndReset, - getAllProjectOutputs, - getBuildInfoFileVersionMap, GetCanonicalFileName, - getConfigFileParsingDiagnostics, - getDirectoryPath, getEntries, - getErrorCountForSummary, - getFileNamesFromConfigSpecs, - getFilesInErrorForSummary, - getFirstProjectOutput, - getLocaleTimeString, - getNormalizedAbsolutePath, - getParsedCommandLineOfConfigFile, - getPendingEmitKind, - getSourceFileVersionAsHashFromText, - getTsBuildInfoEmitOutputFilePath, - getWatchErrorSummaryDiagnosticMessage, hasProperty, identity, isArray, - isIgnoredFileFromWildCardWatching, - isIncrementalCompilation, isString, - listFiles, - loadWithModeAwareCache, - loadWithTypeDirectiveCache, map, maybeBind, - missingFileModifiedTime, - ModuleResolutionCache, - mutateMap, - mutateMapSkippingNewValues, noop, - outFile, - OutputFile, - ParseConfigFileHost, + returnUndefined, + some, + unorderedRemoveItem, +} from "./core"; +import { version } from "./corePublic"; +import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { + emitUsingBuildInfo, + getAllProjectOutputs, + getFirstProjectOutput, + getTsBuildInfoEmitOutputFilePath, +} from "./emitter"; +import { + createModuleResolutionCache, + createTypeReferenceDirectiveResolutionCache, + ModuleResolutionCache, + resolveModuleName, + resolveTypeReferenceDirective, + TypeReferenceDirectiveResolutionCache, +} from "./moduleNameResolver"; +import { + toPath as _toPath, + convertToRelativePath, + getDirectoryPath, + getNormalizedAbsolutePath, + resolvePath, +} from "./path"; +import * as performance from "./performance"; +import { + changeCompilerHostLikeToUseCache, + flattenDiagnosticMessageText, + ForegroundColorEscapeSequences, + formatColorAndReset, + getConfigFileParsingDiagnostics, + loadWithModeAwareCache, + loadWithTypeDirectiveCache, parseConfigHostFromCompilerHostLike, + resolveProjectReferencePath, +} from "./program"; +import { + getModifiedTime as _getModifiedTime, + FileWatcher, + FileWatcherCallback, + missingFileModifiedTime, + PollingInterval, + sys, + System, +} from "./sys"; +import { + resolveConfigFileProjectName, + Status, + UpToDateStatus, + UpToDateStatusType, +} from "./tsbuild"; +import { + BuildInfo, + CancellationToken, + CompilerHost, + CompilerOptions, + CompilerOptionsValue, + CustomTransformers, + Diagnostic, + DiagnosticCollection, + DiagnosticMessage, + EmitResult, + ExitStatus, ParsedCommandLine, Path, - PollingInterval, Program, - ProgramBuildInfo, - ProgramBundleEmitBuildInfo, - ProgramHost, - ProgramMultiFileEmitBuildInfo, - readBuilderProgram, - ReadBuildProgramHost, ResolutionMode, - resolveConfigFileProjectName, ResolvedConfigFileName, ResolvedProjectReference, ResolvedTypeReferenceDirective, - resolveModuleName, - resolvePath, - resolveProjectReferencePath, - resolveTypeReferenceDirective, - returnUndefined, - SemanticDiagnosticsBuilderProgram, + SourceFile, + WatchOptions, + WriteFileCallback, +} from "./types"; +import { + clearMap, + closeFileWatcher, + createCompilerDiagnostic, + createDiagnosticCollection, + isIncrementalCompilation, + mutateMap, + mutateMapSkippingNewValues, + outFile, + writeFile, +} from "./utilities"; +import { + createCompilerHostFromProgramHost, + createDiagnosticReporter, + createProgramHost, + createWatchFactory, + createWatchHost, + emitFilesAndReportErrors, + getErrorCountForSummary, + getFilesInErrorForSummary, + getLocaleTimeString, + getSourceFileVersionAsHashFromText, + getWatchErrorSummaryDiagnosticMessage, + listFiles, setGetSourceFileAsHashVersioned, + WatchType, +} from "./watch"; +import { + CreateProgram, + ProgramHost, + readBuilderProgram, + ReadBuildProgramHost, + WatchHost, + WatchStatusReporter, +} from "./watchPublic"; +import { + closeFileWatcherOf, + ConfigFileProgramReloadLevel, + isIgnoredFileFromWildCardWatching, SharedExtendedConfigFileWatcher, - some, - SourceFile, - Status, - sys, - System, - TypeReferenceDirectiveResolutionCache, - unorderedRemoveItem, - updateErrorForNoInputFiles, updateSharedExtendedConfigFileWatcher, updateWatchingWildcardDirectories, - UpToDateStatus, - UpToDateStatusType, - version, WatchFactory, - WatchHost, - WatchOptions, - WatchStatusReporter, - WatchType, WildcardDirectoryWatcher, - writeFile, - WriteFileCallback, -} from "./_namespaces/ts"; -import * as performance from "./_namespaces/ts.performance"; +} from "./watchUtilities"; const minimumDate = new Date(-8640000000000000); const maximumDate = new Date(8640000000000000); @@ -520,7 +550,7 @@ function createSolutionBuilderState(watch: boolean, ho } function toPath(state: SolutionBuilderState, fileName: string) { - return ts.toPath(fileName, state.currentDirectory, state.getCanonicalFileName); + return _toPath(fileName, state.currentDirectory, state.getCanonicalFileName); } function toResolvedConfigFilePath(state: SolutionBuilderState, fileName: ResolvedConfigFileName): ResolvedConfigFilePath { @@ -1144,7 +1174,7 @@ function createBuildOrUpdateInvalidedProject( const path = toPath(state, name); emittedOutputs.set(toPath(state, name), name); if (data?.buildInfo) setBuildInfo(state, data.buildInfo, projectPath, options, resultFlags); - const modifiedTime = data?.differsOnlyInMap ? ts.getModifiedTime(state.host, name) : undefined; + const modifiedTime = data?.differsOnlyInMap ? _getModifiedTime(state.host, name) : undefined; writeFile(writeFileCallback ? { writeFile: writeFileCallback } : compilerHost, emitterDiagnostics, name, text, writeByteOrderMark); // Revert the timestamp for the d.ts that is same if (data?.differsOnlyInMap) state.host.setModifiedTime(name, modifiedTime!); @@ -1559,7 +1589,7 @@ function getModifiedTime(state: SolutionBuilderState, fileName: string): Date { // In watch mode we store the modified times in the cache // This is either Date | FileWatcherWithModifiedTime because we query modified times first and // then after complete compilation of the project, watch the files so we dont want to loose these modified times. - const result = ts.getModifiedTime(state.host, fileName); + const result = _getModifiedTime(state.host, fileName); if (state.watch) { if (existing) (existing as FileWatcherWithModifiedTime).modifiedTime = result; else state.filesWatched.set(path, result); @@ -1726,7 +1756,7 @@ function getUpToDateStatusWorker(state: SolutionBuilderState, project: ParsedCom let buildInfoVersionMap: Map | undefined; if (buildInfoPath) { const buildInfoCacheEntry = getBuildInfoCacheEntry(state, buildInfoPath, resolvedPath); - buildInfoTime = buildInfoCacheEntry?.modifiedTime || ts.getModifiedTime(host, buildInfoPath); + buildInfoTime = buildInfoCacheEntry?.modifiedTime || _getModifiedTime(host, buildInfoPath); if (buildInfoTime === missingFileModifiedTime) { if (!buildInfoCacheEntry) { state.buildInfoCache.set(resolvedPath, { @@ -1841,7 +1871,7 @@ function getUpToDateStatusWorker(state: SolutionBuilderState, project: ParsedCom // Output is missing; can stop checking let outputTime = outputTimeStampMap?.get(path); if (!outputTime) { - outputTime = ts.getModifiedTime(state.host, output); + outputTime = _getModifiedTime(state.host, output); outputTimeStampMap?.set(path, outputTime); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c9516c77df0f9..07050a41aaaf6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1,20 +1,23 @@ +import { ProgramBuildInfo } from "./builder"; +import { OptionsNameMap } from "./commandLineParser"; +import { + MultiMap, + Pattern, +} from "./core"; import { - BaseNodeFactory, - CreateSourceFileOptions, - EmitHelperFactory, MapLike, + Push, +} from "./corePublic"; +import { BaseNodeFactory } from "./factory/baseNodeFactory"; +import { NodeFactoryFlags } from "./factory/nodeFactory"; +import { ModeAwareCache, ModuleResolutionCache, - MultiMap, - NodeFactoryFlags, - OptionsNameMap, PackageJsonInfo, PackageJsonInfoCache, - Pattern, - ProgramBuildInfo, - Push, - SymlinkCache, -} from "./_namespaces/ts"; +} from "./moduleNameResolver"; +import { CreateSourceFileOptions } from "./parser"; +import { SymlinkCache } from "./utilities"; // branded string type used to store absolute, normalized and canonicalized paths // arbitrary file name can be converted to Path via toPath function @@ -9439,3 +9442,48 @@ export interface Queue { dequeue(): T; isEmpty(): boolean; } + +/** @internal */ +export interface EmitHelperFactory { + getUnscopedHelperName(name: string): 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; + // 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; + // ES2018 Destructuring Helpers + createRestHelper(value: Expression, elements: readonly BindingOrAssignmentElement[], computedTempVariables: readonly Expression[] | undefined, location: TextRange): Expression; + // ES2017 Helpers + createAwaiterHelper(hasLexicalThis: boolean, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression | undefined, body: Block): Expression; + // ES2015 Helpers + createExtendsHelper(name: Identifier): Expression; + createTemplateObjectHelper(cooked: ArrayLiteralExpression, raw: ArrayLiteralExpression): Expression; + createSpreadArrayHelper(to: Expression, from: Expression, packFrom: boolean): Expression; + // ES2015 Destructuring Helpers + createValuesHelper(expression: Expression): Expression; + createReadHelper(iteratorRecord: Expression, count: number | undefined): Expression; + // ES2015 Generator Helpers + createGeneratorHelper(body: FunctionExpression): 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; + // 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; +} + +/** @internal */ +export const enum PrivateIdentifierKind { + Field = "f", + Method = "m", + Accessor = "a" +} diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8de47c348430e..77c15ba7174db 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1,28 +1,237 @@ +import { getSymbolId } from "./checkerUtilities"; +import { + affectsDeclarationPathOptionDeclarations, + affectsEmitOptionDeclarations, + moduleResolutionOptionDeclarations, + optionsAffectingProgramStructure, + parseConfigFileTextToJson, + semanticDiagnosticsOptionDeclarations, +} from "./commandLineParser"; +import { + addRange, + arrayFrom, + assertType, + binarySearch, + compareStringsCaseSensitive, + compareValues, + concatenate, + contains, + createGetCanonicalFileName, + createMultiMap, + emptyArray, + equalOwnProperties, + equateValues, + every, + filter, + find, + findBestPatternMatch, + findIndex, + findLast, + firstDefined, + firstOrUndefined, + flatMap, + flatMapToMutable, + flatten, + forEach, + GetCanonicalFileName, + getEntries, + getOwnKeys, + getStringComparer, + hasProperty, + identity, + indexOfAnyCharCode, + insertSorted, + isArray, + isLineBreak, + isString, + isWhiteSpaceLike, + isWhiteSpaceSingleLine, + last, + lastOrUndefined, + length, + map, + mapDefined, + MultiMap, + noop, + or, + Pattern, + singleElementArray, + singleOrUndefined, + some, + sort, + startsWith, + stringContains, + trimString, + trimStringStart, + tryCast, + tryRemovePrefix, +} from "./core"; +import { + Comparison, + EqualityComparer, + MapLike, + ReadonlyCollection, + SortedArray, + version, +} from "./corePublic"; +import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { factory } from "./factory/nodeFactory"; +import { + isArrayLiteralExpression, + isArrowFunction, + isBigIntLiteral, + isBinaryExpression, + isCallExpression, + isClassDeclaration, + isClassExpression, + isClassStaticBlockDeclaration, + isCommaListExpression, + isComputedPropertyName, + isConstructorDeclaration, + isDecorator, + isElementAccessExpression, + isEnumDeclaration, + isEnumMember, + isExportAssignment, + isExportDeclaration, + isExpressionStatement, + isExpressionWithTypeArguments, + isExternalModuleReference, + isForStatement, + isFunctionDeclaration, + isFunctionExpression, + isGetAccessorDeclaration, + isHeritageClause, + isIdentifier, + isImportTypeNode, + isInterfaceDeclaration, + isJSDoc, + isJSDocFunctionType, + isJSDocMemberName, + isJSDocNameReference, + isJSDocParameterTag, + isJSDocSignature, + isJSDocTemplateTag, + isJSDocTypeExpression, + isJSDocTypeLiteral, + isJSDocTypeTag, + isJsxFragment, + isJsxText, + isLiteralTypeNode, + isMetaProperty, + isModuleDeclaration, + isNamespaceExport, + isNamespaceExportDeclaration, + isNamespaceImport, + isNoSubstitutionTemplateLiteral, + isNumericLiteral, + isObjectLiteralExpression, + isOmittedExpression, + isParameter, + isParenthesizedExpression, + isParenthesizedTypeNode, + isPrefixUnaryExpression, + isPrivateIdentifier, + isPropertyAccessExpression, + isPropertyAssignment, + isPropertyDeclaration, + isPropertySignature, + isQualifiedName, + isSetAccessorDeclaration, + isShorthandPropertyAssignment, + isSourceFile, + isStringLiteral, + isTypeAliasDeclaration, + isTypeLiteralNode, + isTypeReferenceNode, + isVariableDeclaration, + isVariableStatement, + isVoidExpression, +} from "./factory/nodeTests"; +import { + canHaveDecorators, + canHaveModifiers, +} from "./factory/utilitiesPublic"; +import { + createModeAwareCache, + getResolutionMode, + getResolutionName, + ModeAwareCache, + nodeModulesPathPart, +} from "./moduleNameResolver"; +import { + forEachChild, + forEachChildRecursively, + isExternalModule, + isFileProbablyExternalModule, +} from "./parser"; +import { + changeAnyExtension, + combinePaths, + containsPath, + directorySeparator, + ensurePathIsNonModuleName, + ensureTrailingDirectorySeparator, + fileExtensionIs, + fileExtensionIsOneOf, + forEachAncestorDirectory, + getBaseFileName, + getDirectoryPath, + getNormalizedAbsolutePath, + getNormalizedPathComponents, + getPathComponents, + getPathFromPathComponents, + getRelativePathToDirectoryOrUrl, + getRootLength, + hasExtension, + isAnyDirectorySeparator, + isRootedDiskPath, + normalizePath, + pathIsRelative, + removeTrailingDirectorySeparator, + toPath, +} from "./path"; +import { + computeLineAndCharacterOfPosition, + computeLineOfPosition, + computeLineStarts, + createScanner, + getLeadingCommentRanges, + getLineAndCharacterOfPosition, + getLinesBetweenPositions, + getLineStarts, + getTrailingCommentRanges, + isIdentifierText, + skipTrivia, + stringToToken, + tokenToString, +} from "./scanner"; +import { + FileWatcher, + ignoredPaths, + sys, +} from "./sys"; +import { tracing } from "./tracing"; import { __String, AccessExpression, AccessorDeclaration, - addRange, - affectsDeclarationPathOptionDeclarations, - affectsEmitOptionDeclarations, AllAccessorDeclarations, AmbientModuleDeclaration, AnyImportOrBareOrAccessedRequire, AnyImportOrReExport, AnyImportSyntax, AnyValidImportOrReExport, - arrayFrom, ArrayLiteralExpression, ArrayTypeNode, ArrowFunction, AsExpression, AssertionExpression, - assertType, AssignmentDeclarationKind, AssignmentExpression, AssignmentOperatorToken, BinaryExpression, - binarySearch, BindableObjectDefinePropertyCall, BindableStaticAccessExpression, BindableStaticElementAccessExpression, @@ -34,47 +243,26 @@ import { BundleFileTextLike, CallExpression, CallLikeExpression, - canHaveDecorators, - canHaveIllegalDecorators, - canHaveModifiers, CaseBlock, CaseClause, CaseOrDefaultClause, CatchClause, - changeAnyExtension, CharacterCodes, CheckFlags, ClassDeclaration, ClassElement, ClassLikeDeclaration, ClassStaticBlockDeclaration, - combinePaths, CommaListExpression, CommandLineOption, CommentDirective, CommentDirectivesMap, CommentDirectiveType, CommentRange, - compareStringsCaseSensitive, - compareValues, - Comparison, CompilerOptions, ComputedPropertyName, - computeLineAndCharacterOfPosition, - computeLineOfPosition, - computeLineStarts, - concatenate, ConditionalExpression, ConstructorDeclaration, - contains, - containsPath, - createGetCanonicalFileName, - createModeAwareCache, - createMultiMap, - createScanner, - createTextSpan, - createTextSpanFromBounds, - Debug, Declaration, DeclarationName, DeclarationWithTypeParameterChildren, @@ -87,10 +275,8 @@ import { DiagnosticMessage, DiagnosticMessageChain, DiagnosticRelatedInformation, - Diagnostics, DiagnosticWithDetachedLocation, DiagnosticWithLocation, - directorySeparator, DoStatement, DynamicNamedBinaryExpression, DynamicNamedDeclaration, @@ -99,19 +285,11 @@ import { EmitHost, EmitResolver, EmitTextWriter, - emptyArray, - ensurePathIsNonModuleName, - ensureTrailingDirectorySeparator, EntityName, EntityNameExpression, EntityNameOrEntityNameExpression, EnumDeclaration, - EqualityComparer, - equalOwnProperties, EqualsToken, - equateValues, - escapeLeadingUnderscores, - every, ExportAssignment, ExportDeclaration, ExportSpecifier, @@ -120,27 +298,8 @@ import { ExpressionWithTypeArguments, Extension, ExternalModuleReference, - factory, FileExtensionInfo, - fileExtensionIs, - fileExtensionIsOneOf, FileReference, - FileWatcher, - filter, - find, - findAncestor, - findBestPatternMatch, - findIndex, - findLast, - firstDefined, - firstOrUndefined, - flatMap, - flatMapToMutable, - flatten, - forEach, - forEachAncestorDirectory, - forEachChild, - forEachChildRecursively, ForInOrOfStatement, ForInStatement, ForOfStatement, @@ -150,63 +309,18 @@ import { FunctionExpression, FunctionLikeDeclaration, GetAccessorDeclaration, - getBaseFileName, - GetCanonicalFileName, - getCombinedModifierFlags, - getCombinedNodeFlags, - getDirectoryPath, - getEntries, - getJSDocAugmentsTag, - getJSDocDeprecatedTagNoCache, - getJSDocImplementsTags, - getJSDocOverrideTagNoCache, - getJSDocParameterTags, - getJSDocParameterTagsNoCache, - getJSDocPrivateTagNoCache, - getJSDocProtectedTagNoCache, - getJSDocPublicTagNoCache, - getJSDocReadonlyTagNoCache, - getJSDocReturnType, - getJSDocTags, - getJSDocType, - getJSDocTypeParameterTags, - getJSDocTypeParameterTagsNoCache, - getJSDocTypeTag, - getLeadingCommentRanges, - getLineAndCharacterOfPosition, - getLinesBetweenPositions, - getLineStarts, - getNameOfDeclaration, - getNormalizedAbsolutePath, - getNormalizedPathComponents, - getOwnKeys, - getParseTreeNode, - getPathComponents, - getPathFromPathComponents, - getRelativePathToDirectoryOrUrl, - getResolutionMode, - getResolutionName, - getRootLength, - getStringComparer, - getSymbolId, - getTrailingCommentRanges, HasExpressionInitializer, - hasExtension, - hasInitializer, + HasIllegalDecorators, + HasIllegalTypeParameters, HasInitializer, HasJSDoc, - hasJSDocNodes, HasModifiers, - hasProperty, HasType, HasTypeArguments, HeritageClause, Identifier, IdentifierTypePredicate, - identity, - idText, IfStatement, - ignoredPaths, ImportCall, ImportClause, ImportDeclaration, @@ -215,113 +329,8 @@ import { ImportSpecifier, ImportTypeNode, IndexInfo, - indexOfAnyCharCode, InitializedVariableDeclaration, - insertSorted, InterfaceDeclaration, - isAccessor, - isAnyDirectorySeparator, - isArray, - isArrayLiteralExpression, - isArrowFunction, - isBigIntLiteral, - isBinaryExpression, - isBindingPattern, - isCallExpression, - isClassDeclaration, - isClassElement, - isClassExpression, - isClassLike, - isClassStaticBlockDeclaration, - isCommaListExpression, - isComputedPropertyName, - isConstructorDeclaration, - isDeclaration, - isDecorator, - isElementAccessExpression, - isEnumDeclaration, - isEnumMember, - isExportAssignment, - isExportDeclaration, - isExpressionStatement, - isExpressionWithTypeArguments, - isExternalModule, - isExternalModuleReference, - isFileProbablyExternalModule, - isForStatement, - isFunctionDeclaration, - isFunctionExpression, - isFunctionLike, - isFunctionLikeDeclaration, - isFunctionLikeOrClassStaticBlockDeclaration, - isGetAccessorDeclaration, - isHeritageClause, - isIdentifier, - isIdentifierText, - isImportTypeNode, - isInterfaceDeclaration, - isJSDoc, - isJSDocFunctionType, - isJSDocLinkLike, - isJSDocMemberName, - isJSDocNameReference, - isJSDocNode, - isJSDocParameterTag, - isJSDocPropertyLikeTag, - isJSDocSignature, - isJSDocTag, - isJSDocTemplateTag, - isJSDocTypeExpression, - isJSDocTypeLiteral, - isJSDocTypeTag, - isJsxChild, - isJsxFragment, - isJsxOpeningLikeElement, - isJsxText, - isLeftHandSideExpression, - isLineBreak, - isLiteralTypeNode, - isMemberName, - isMetaProperty, - isMethodOrAccessor, - isModuleDeclaration, - isNamedDeclaration, - isNamespaceExport, - isNamespaceExportDeclaration, - isNamespaceImport, - isNoSubstitutionTemplateLiteral, - isNumericLiteral, - isObjectLiteralExpression, - isOmittedExpression, - isParameter, - isParameterPropertyDeclaration, - isParenthesizedExpression, - isParenthesizedTypeNode, - isPrefixUnaryExpression, - isPrivateIdentifier, - isPropertyAccessExpression, - isPropertyAssignment, - isPropertyDeclaration, - isPropertyName, - isPropertySignature, - isQualifiedName, - isRootedDiskPath, - isSetAccessorDeclaration, - isShorthandPropertyAssignment, - isSourceFile, - isString, - isStringLiteral, - isStringLiteralLike, - isTypeAliasDeclaration, - isTypeElement, - isTypeLiteralNode, - isTypeNode, - isTypeReferenceNode, - isVariableDeclaration, - isVariableStatement, - isVoidExpression, - isWhiteSpaceLike, - isWhiteSpaceSingleLine, JSDoc, JSDocCallbackTag, JSDocEnumTag, @@ -331,6 +340,7 @@ import { JSDocSignature, JSDocTag, JSDocTemplateTag, + JSDocTypeAssertion, JSDocTypedefTag, JsonSourceFile, JsxChild, @@ -344,20 +354,13 @@ import { KeywordSyntaxKind, LabeledStatement, LanguageVariant, - last, - lastOrUndefined, LateVisibilityPaintedStatement, - length, LiteralImportTypeNode, LiteralLikeElementAccessExpression, LiteralLikeNode, LogicalOrCoalescingAssignmentOperator, - map, - mapDefined, - MapLike, MemberName, MethodDeclaration, - ModeAwareCache, ModifierFlags, ModifierLike, ModuleBlock, @@ -365,8 +368,6 @@ import { ModuleDetectionKind, ModuleKind, ModuleResolutionKind, - moduleResolutionOptionDeclarations, - MultiMap, NamedDeclaration, NamedExports, NamedImports, @@ -378,10 +379,7 @@ import { Node, NodeArray, NodeFlags, - nodeModulesPathPart, NonNullExpression, - noop, - normalizePath, NoSubstitutionTemplateLiteral, NumericLiteral, ObjectFlags, @@ -390,18 +388,14 @@ import { ObjectLiteralExpression, ObjectLiteralExpressionBase, ObjectTypeDeclaration, - optionsAffectingProgramStructure, - or, + OuterExpression, OuterExpressionKinds, PackageId, ParameterDeclaration, ParenthesizedExpression, ParenthesizedTypeNode, - parseConfigFileTextToJson, PartiallyEmittedExpression, Path, - pathIsRelative, - Pattern, PostfixUnaryExpression, PrefixUnaryExpression, PrinterOptions, @@ -417,9 +411,7 @@ import { PropertyNameLiteral, PseudoBigInt, QualifiedName, - ReadonlyCollection, ReadonlyTextRange, - removeTrailingDirectorySeparator, RequireOrImportCall, RequireVariableStatement, ResolutionMode, @@ -429,31 +421,19 @@ import { SatisfiesExpression, ScriptKind, ScriptTarget, - semanticDiagnosticsOptionDeclarations, SetAccessorDeclaration, ShorthandPropertyAssignment, Signature, SignatureDeclaration, SignatureFlags, SignatureKind, - singleElementArray, - singleOrUndefined, - skipOuterExpressions, - skipTrivia, - some, - sort, - SortedArray, SourceFile, SourceFileLike, SourceFileMayBeEmittedHost, SourceMapSource, - startsWith, - startsWithUseStrict, Statement, - stringContains, StringLiteral, StringLiteralLike, - stringToToken, SuperCall, SuperExpression, SuperProperty, @@ -463,7 +443,6 @@ import { SymbolTable, SyntaxKind, SyntaxList, - sys, TaggedTemplateExpression, TemplateLiteral, TemplateLiteralLikeNode, @@ -474,16 +453,9 @@ import { ThisTypePredicate, Token, TokenFlags, - tokenToString, - toPath, - tracing, TransformFlags, TransientSymbol, - trimString, - trimStringStart, TriviaSyntaxKind, - tryCast, - tryRemovePrefix, TryStatement, TsConfigSourceFile, TupleTypeNode, @@ -501,7 +473,6 @@ import { TypePredicate, TypePredicateKind, TypeReferenceNode, - unescapeLeadingUnderscores, UnionOrIntersectionTypeNode, ValidImportTypeNode, VariableDeclaration, @@ -509,13 +480,65 @@ import { VariableDeclarationList, VariableLikeDeclaration, VariableStatement, - version, WhileStatement, WithStatement, WriteFileCallback, WriteFileCallbackData, YieldExpression, -} from "./_namespaces/ts"; +} from "./types"; +import { + createTextSpan, + createTextSpanFromBounds, + escapeLeadingUnderscores, + findAncestor, + getCombinedModifierFlags, + getCombinedNodeFlags, + getJSDocAugmentsTag, + getJSDocDeprecatedTagNoCache, + getJSDocImplementsTags, + getJSDocOverrideTagNoCache, + getJSDocParameterTags, + getJSDocParameterTagsNoCache, + getJSDocPrivateTagNoCache, + getJSDocProtectedTagNoCache, + getJSDocPublicTagNoCache, + getJSDocReadonlyTagNoCache, + getJSDocReturnType, + getJSDocTags, + getJSDocType, + getJSDocTypeParameterTags, + getJSDocTypeParameterTagsNoCache, + getJSDocTypeTag, + getNameOfDeclaration, + getParseTreeNode, + hasInitializer, + hasJSDocNodes, + idText, + isAccessor, + isBindingPattern, + isClassElement, + isClassLike, + isDeclaration, + isFunctionLike, + isFunctionLikeDeclaration, + isFunctionLikeOrClassStaticBlockDeclaration, + isJSDocLinkLike, + isJSDocNode, + isJSDocPropertyLikeTag, + isJSDocTag, + isJsxChild, + isJsxOpeningLikeElement, + isLeftHandSideExpression, + isMemberName, + isMethodOrAccessor, + isNamedDeclaration, + isParameterPropertyDeclaration, + isPropertyName, + isStringLiteralLike, + isTypeElement, + isTypeNode, + unescapeLeadingUnderscores, +} from "./utilitiesPublic"; /** @internal */ export const resolvingEmptyArray: never[] = []; @@ -9063,3 +9086,114 @@ export function isOptionalJSDocPropertyLikeTag(node: Node): node is JSDocPropert const { isBracketed, typeExpression } = node; return isBracketed || !!typeExpression && typeExpression.type.kind === SyntaxKind.JSDocOptionalType; } + +/** @internal */ +export function signatureHasRestParameter(s: Signature) { + return !!(s.flags & SignatureFlags.HasRestParameter); +} + +/** @internal */ +export function signatureHasLiteralTypes(s: Signature) { + return !!(s.flags & SignatureFlags.HasLiteralTypes); +} + +/** @internal */ +export function skipOuterExpressions(node: Expression, kinds?: OuterExpressionKinds): Expression; +/** @internal */ +export function skipOuterExpressions(node: Node, kinds?: OuterExpressionKinds): Node; +/** @internal */ +export function skipOuterExpressions(node: Node, kinds = OuterExpressionKinds.All) { + while (isOuterExpression(node, kinds)) { + node = node.expression; + } + return node; +} + +/** @internal */ +export function skipAssertions(node: Expression): Expression; +/** @internal */ +export function skipAssertions(node: Node): Node; +/** @internal */ +export function skipAssertions(node: Node): Node { + return skipOuterExpressions(node, OuterExpressionKinds.Assertions); +} + +/** @internal */ +export function isOuterExpression(node: Node, kinds = OuterExpressionKinds.All): node is OuterExpression { + switch (node.kind) { + case SyntaxKind.ParenthesizedExpression: + if (kinds & OuterExpressionKinds.ExcludeJSDocTypeAssertion && isJSDocTypeAssertion(node)) { + return false; + } + return (kinds & OuterExpressionKinds.Parentheses) !== 0; + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.AsExpression: + case SyntaxKind.SatisfiesExpression: + return (kinds & OuterExpressionKinds.TypeAssertions) !== 0; + case SyntaxKind.NonNullExpression: + return (kinds & OuterExpressionKinds.NonNullAssertions) !== 0; + case SyntaxKind.PartiallyEmittedExpression: + return (kinds & OuterExpressionKinds.PartiallyEmittedExpressions) !== 0; + } + return false; +} + +/** @internal */ +export function isJSDocTypeAssertion(node: Node): node is JSDocTypeAssertion { + return isParenthesizedExpression(node) && isInJSFile(node) && !!getJSDocTypeTag(node); +} + +/** @internal */ +export function startsWithUseStrict(statements: readonly Statement[]) { + const firstStatement = firstOrUndefined(statements); + return firstStatement !== undefined && isPrologueDirective(firstStatement) && isUseStrictPrologue(firstStatement); +} + +function isUseStrictPrologue(node: ExpressionStatement): boolean { + return isStringLiteral(node.expression) && node.expression.text === "use strict"; +} + +/** @internal */ +export function findUseStrictPrologue(statements: readonly Statement[]): Statement | undefined { + for (const statement of statements) { + if (isPrologueDirective(statement)) { + if (isUseStrictPrologue(statement)) { + return statement; + } + } + else { + break; + } + } + return undefined; +} + +/** @internal */ +export function canHaveIllegalDecorators(node: Node): node is HasIllegalDecorators { + const kind = node.kind; + return kind === SyntaxKind.PropertyAssignment + || kind === SyntaxKind.ShorthandPropertyAssignment + || kind === SyntaxKind.FunctionDeclaration + || kind === SyntaxKind.Constructor + || kind === SyntaxKind.IndexSignature + || kind === SyntaxKind.ClassStaticBlockDeclaration + || kind === SyntaxKind.MissingDeclaration + || kind === SyntaxKind.VariableStatement + || kind === SyntaxKind.InterfaceDeclaration + || kind === SyntaxKind.TypeAliasDeclaration + || kind === SyntaxKind.EnumDeclaration + || kind === SyntaxKind.ModuleDeclaration + || kind === SyntaxKind.ImportEqualsDeclaration + || kind === SyntaxKind.ImportDeclaration + || kind === SyntaxKind.NamespaceExportDeclaration + || kind === SyntaxKind.ExportDeclaration + || kind === SyntaxKind.ExportAssignment; +} + +/** @internal */ +export function canHaveIllegalTypeParameters(node: Node): node is HasIllegalTypeParameters { + const kind = node.kind; + return kind === SyntaxKind.Constructor + || kind === SyntaxKind.GetAccessor + || kind === SyntaxKind.SetAccessor; +} diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index e6c0c5a05602a..e32757bf324ac 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1,3 +1,85 @@ +import { + contains, + emptyArray, + every, + filter, + find, + flatMap, + hasProperty, + isWhiteSpaceLike, + lastOrUndefined, + setUILocale, + some, + sortAndDeduplicate, +} from "./core"; +import { + Push, + SortedReadonlyArray, +} from "./corePublic"; +import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { + isArrowFunction, + isBinaryExpression, + isBindingElement, + isBlock, + isCallExpression, + isCallSignatureDeclaration, + isClassExpression, + isClassStaticBlockDeclaration, + isDecorator, + isElementAccessExpression, + isExportAssignment, + isExportDeclaration, + isExportSpecifier, + isFunctionExpression, + isFunctionTypeNode, + isIdentifier, + isImportSpecifier, + isJSDoc, + isJSDocAugmentsTag, + isJSDocClassTag, + isJSDocDeprecatedTag, + isJSDocEnumTag, + isJSDocFunctionType, + isJSDocImplementsTag, + isJSDocOverrideTag, + isJSDocParameterTag, + isJSDocPrivateTag, + isJSDocProtectedTag, + isJSDocPublicTag, + isJSDocReadonlyTag, + isJSDocReturnTag, + isJSDocSignature, + isJSDocTemplateTag, + isJSDocThisTag, + isJSDocTypeLiteral, + isJSDocTypeTag, + isModuleBlock, + isNonNullExpression, + isNotEmittedStatement, + isOmittedExpression, + isParameter, + isPartiallyEmittedExpression, + isPrivateIdentifier, + isPropertyAccessExpression, + isPropertyAssignment, + isPropertyDeclaration, + isSourceFile, + isStringLiteral, + isTypeLiteralNode, + isTypeReferenceNode, + isVariableDeclaration, + isVariableDeclarationList, + isVariableStatement, +} from "./factory/nodeTests"; +import { + combinePaths, + getDirectoryPath, + isRootedDiskPath, + normalizePath, + pathIsRelative, +} from "./path"; import { __String, AccessExpression, @@ -23,42 +105,29 @@ import { CallChain, CallExpression, CallLikeExpression, - canHaveIllegalTypeParameters, CaseOrDefaultClause, CharacterCodes, ClassElement, ClassLikeDeclaration, ClassStaticBlockDeclaration, - combinePaths, - compareDiagnostics, CompilerOptions, ConciseBody, ConstructorDeclaration, ConstructorTypeNode, - contains, - createCompilerDiagnostic, - Debug, Declaration, DeclarationName, DeclarationStatement, DeclarationWithTypeParameters, Decorator, Diagnostic, - Diagnostics, ElementAccessChain, ElementAccessExpression, - emptyArray, EntityName, - entityNameToString, EnumDeclaration, - every, ExportAssignment, ExportSpecifier, Expression, FileReference, - filter, - find, - flatMap, ForInitializer, ForInOrOfStatement, FunctionBody, @@ -68,23 +137,11 @@ import { GeneratedIdentifierFlags, GeneratedPrivateIdentifier, GetAccessorDeclaration, - getAssignmentDeclarationKind, - getDirectoryPath, - getEffectiveModifierFlags, - getEffectiveModifierFlagsAlwaysIncludeJSDoc, - getElementOrPropertyAccessArgumentExpressionOrName, - getEmitScriptTarget, - getJSDocCommentsAndTags, - getJSDocTypeParameterDeclarations, - hasAccessorModifier, - hasDecorators, HasDecorators, HasExpressionInitializer, HasInitializer, HasJSDoc, HasModifiers, - hasProperty, - hasSyntacticModifier, HasType, Identifier, ImportClause, @@ -92,69 +149,6 @@ import { ImportOrExportSpecifier, ImportSpecifier, ImportTypeNode, - isAccessExpression, - isAmbientModule, - isAnyImportOrReExport, - isArrowFunction, - isBinaryExpression, - isBindableStaticElementAccessExpression, - isBindingElement, - isBlock, - isCallExpression, - isCallSignatureDeclaration, - isClassExpression, - isClassStaticBlockDeclaration, - isDecorator, - isElementAccessExpression, - isExportAssignment, - isExportDeclaration, - isExportSpecifier, - isFunctionBlock, - isFunctionExpression, - isFunctionTypeNode, - isIdentifier, - isImportSpecifier, - isInJSFile, - isJSDoc, - isJSDocAugmentsTag, - isJSDocClassTag, - isJSDocDeprecatedTag, - isJSDocEnumTag, - isJSDocFunctionType, - isJSDocImplementsTag, - isJSDocOverrideTag, - isJSDocParameterTag, - isJSDocPrivateTag, - isJSDocProtectedTag, - isJSDocPublicTag, - isJSDocReadonlyTag, - isJSDocReturnTag, - isJSDocSignature, - isJSDocTemplateTag, - isJSDocThisTag, - isJSDocTypeAlias, - isJSDocTypeLiteral, - isJSDocTypeTag, - isModuleBlock, - isNonNullExpression, - isNotEmittedStatement, - isOmittedExpression, - isParameter, - isPartiallyEmittedExpression, - isPrivateIdentifier, - isPropertyAccessExpression, - isPropertyAssignment, - isPropertyDeclaration, - isRootedDiskPath, - isSourceFile, - isStringLiteral, - isTypeLiteralNode, - isTypeNodeKind, - isTypeReferenceNode, - isVariableDeclaration, - isVariableDeclarationList, - isVariableStatement, - isWhiteSpaceLike, IterationStatement, JSDocAugmentsTag, JSDocClassTag, @@ -187,7 +181,6 @@ import { JsxOpeningLikeElement, JsxTagNameExpression, LabeledStatement, - lastOrUndefined, LeftHandSideExpression, LiteralExpression, LiteralToken, @@ -196,7 +189,6 @@ import { Modifier, ModifierFlags, ModifierLike, - modifierToFlag, ModuleBody, ModuleDeclaration, ModuleReference, @@ -210,7 +202,6 @@ import { NodeArray, NodeFlags, NonNullChain, - normalizePath, NotEmittedStatement, ObjectBindingOrAssignmentElement, ObjectBindingOrAssignmentPattern, @@ -221,7 +212,6 @@ import { OuterExpressionKinds, ParameterDeclaration, PartiallyEmittedExpression, - pathIsRelative, PostfixUnaryExpression, PrefixUnaryExpression, PrivateClassElementDeclaration, @@ -231,17 +221,10 @@ import { PropertyAccessExpression, PropertyDeclaration, PropertyName, - Push, QualifiedName, ScriptTarget, SetAccessorDeclaration, - setLocalizedDiagnosticMessages, - setUILocale, SignatureDeclaration, - skipOuterExpressions, - some, - sortAndDeduplicate, - SortedReadonlyArray, Statement, StringLiteral, StringLiteralLike, @@ -263,7 +246,34 @@ import { UnparsedNode, UnparsedTextLike, VariableDeclaration, -} from "./_namespaces/ts"; +} from "./types"; +import { + canHaveIllegalTypeParameters, + compareDiagnostics, + createCompilerDiagnostic, + entityNameToString, + getAssignmentDeclarationKind, + getEffectiveModifierFlags, + getEffectiveModifierFlagsAlwaysIncludeJSDoc, + getElementOrPropertyAccessArgumentExpressionOrName, + getEmitScriptTarget, + getJSDocCommentsAndTags, + getJSDocTypeParameterDeclarations, + hasAccessorModifier, + hasDecorators, + hasSyntacticModifier, + isAccessExpression, + isAmbientModule, + isAnyImportOrReExport, + isBindableStaticElementAccessExpression, + isFunctionBlock, + isInJSFile, + isJSDocTypeAlias, + isTypeNodeKind, + modifierToFlag, + setLocalizedDiagnosticMessages, + skipOuterExpressions, +} from "./utilities"; export function isExternalModuleNameRelative(moduleName: string): boolean { // TypeScript 1.0 spec (April 2014): 11.2.1 diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index af0fd6e4db0ae..36577cd74406c 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -1,89 +1,63 @@ import { - ConciseBody, - Debug, - EmitFlags, - Expression, - factory, - FunctionBody, - getEmitFlags, - getEmitScriptTarget, - Identifier, isArray, - isArrayBindingElement, + singleOrUndefined, + some, +} from "./core"; +import { Debug } from "./debug"; +import { setEmitFlags } from "./factory/emitNode"; +import { factory } from "./factory/nodeFactory"; +import { isAssertClause, isAssertEntry, - isAssertionKey, isAssertsKeyword, isAsteriskToken, isAwaitKeyword, - isBinaryOperatorToken, isBindingElement, - isBindingName, - isBindingPattern, isBlock, - isCallChain, isCaseBlock, - isCaseOrDefaultClause, isCatchClause, - isClassElement, isColonToken, - isConciseBody, isDotDotDotToken, - isElementAccessChain, - isEntityName, isEnumMember, isEqualsGreaterThanToken, isExclamationToken, isExportSpecifier, - isExpression, isExpressionWithTypeArguments, - isForInitializer, isHeritageClause, isIdentifier, - isIdentifierOrThisTypeNode, isImportClause, isImportSpecifier, isImportTypeAssertionContainer, - isJsxAttributeLike, isJsxAttributes, - isJsxChild, isJsxClosingElement, isJsxClosingFragment, isJsxOpeningElement, isJsxOpeningFragment, - isJsxTagNameExpression, - isMemberName, - isModifier, - isModifierLike, - isModuleBody, - isModuleName, - isModuleReference, - isNamedExportBindings, - isNamedImportBindings, - isObjectLiteralElementLike, - isOptionalChain, - isParameterDeclaration, - isPropertyAccessChain, - isPropertyName, isQuestionDotToken, - isQuestionOrExclamationToken, - isQuestionOrPlusOrMinusToken, isQuestionToken, - isReadonlyKeywordOrPlusOrMinusToken, - isStatement, - isStringLiteralOrJsxExpression, isTemplateHead, - isTemplateLiteral, isTemplateLiteralTypeSpan, - isTemplateMiddleOrTemplateTail, isTemplateSpan, - isToken, - isTypeElement, - isTypeNode, - isTypeNodeOrTypeParameterDeclaration, isTypeParameterDeclaration, isVariableDeclaration, isVariableDeclarationList, +} from "./factory/nodeTests"; +import { + isBinaryOperatorToken, + isIdentifierOrThisTypeNode, + isModuleName, + isQuestionOrExclamationToken, + isQuestionOrPlusOrMinusToken, + isReadonlyKeywordOrPlusOrMinusToken, + isTypeNodeOrTypeParameterDeclaration, +} from "./factory/utilities"; +import { setTextRange } from "./factory/utilitiesPublic"; +import { + ConciseBody, + EmitFlags, + Expression, + FunctionBody, + Identifier, LexicalEnvironmentFlags, Node, NodeArray, @@ -91,17 +65,53 @@ import { NodeVisitor, ParameterDeclaration, ScriptTarget, - setEmitFlags, - setTextRange, - setTextRangePosEnd, - singleOrUndefined, - some, Statement, SyntaxKind, TransformationContext, VisitEachChildNodes, Visitor, -} from "./_namespaces/ts"; +} from "./types"; +import { + getEmitFlags, + getEmitScriptTarget, + isParameterDeclaration, + setTextRangePosEnd, +} from "./utilities"; +import { + isArrayBindingElement, + isAssertionKey, + isBindingName, + isBindingPattern, + isCallChain, + isCaseOrDefaultClause, + isClassElement, + isConciseBody, + isElementAccessChain, + isEntityName, + isExpression, + isForInitializer, + isJsxAttributeLike, + isJsxChild, + isJsxTagNameExpression, + isMemberName, + isModifier, + isModifierLike, + isModuleBody, + isModuleReference, + isNamedExportBindings, + isNamedImportBindings, + isObjectLiteralElementLike, + isOptionalChain, + isPropertyAccessChain, + isPropertyName, + isStatement, + isStringLiteralOrJsxExpression, + isTemplateLiteral, + isTemplateMiddleOrTemplateTail, + isToken, + isTypeElement, + isTypeNode, +} from "./utilitiesPublic"; /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 16bd5f3e8dd4c..a8d8b769cb497 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -1,111 +1,135 @@ import { - addRange, BuilderProgram, - CancellationToken, - chainDiagnosticMessages, - CharacterCodes, - combinePaths, - CompilerHost, - CompilerOptions, + createEmitAndSemanticDiagnosticsBuilderProgram, + EmitAndSemanticDiagnosticsBuilderProgram, +} from "./builderPublic"; +import { + DiagnosticReporter, + ExtendedConfigCacheEntry, + getParsedCommandLineOfConfigFile, + ParseConfigFileHost, + targetOptionDeclaration, +} from "./commandLineParser"; +import { + addRange, contains, - convertToRelativePath, copyProperties, countWhere, - createCompilerDiagnostic, - createEmitAndSemanticDiagnosticsBuilderProgram, createGetCanonicalFileName, + emptyArray, + endsWith, + filter, + find, + forEach, + isLineBreak, + isString, + last, + maybeBind, + memoize, + noop, +} from "./core"; +import { SortedReadonlyArray } from "./corePublic"; +import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { + combinePaths, + convertToRelativePath, + fileExtensionIs, + getDirectoryPath, + getNormalizedAbsolutePath, + getRelativePathFromDirectory, + normalizePath, + pathIsAbsolute, +} from "./path"; +import { createGetSourceFile, - createIncrementalCompilerHost, - createIncrementalProgram, - CreateProgram, createWriteFileMeasuringIO, + flattenDiagnosticMessageText, + ForegroundColorEscapeSequences, + formatColorAndReset, + formatDiagnostic, + FormatDiagnosticsHost, + formatDiagnosticsWithColorAndContext, + getReferencedFileLocation, + isReferencedFile, + isReferenceFileLocation, +} from "./program"; +import { getLineAndCharacterOfPosition } from "./scanner"; +import { + sourceMapCommentRegExp, + sourceMapCommentRegExpDontCareLineStart, + whitespaceOrMapCommentRegExp, +} from "./sourcemap"; +import { + FileWatcher, + generateDjb2Hash, + sys, + System, +} from "./sys"; +import { + ReportEmitErrorSummary, + ReportFileInError, +} from "./tsbuildPublic"; +import { + CancellationToken, + CharacterCodes, + CompilerHost, + CompilerOptions, CustomTransformers, - Debug, Diagnostic, DiagnosticCategory, DiagnosticMessage, DiagnosticMessageChain, - DiagnosticReporter, - Diagnostics, - DirectoryStructureHost, - EmitAndSemanticDiagnosticsBuilderProgram, EmitResult, - emptyArray, - endsWith, ExitStatus, - ExtendedConfigCacheEntry, Extension, - externalHelpersModuleNameText, FileExtensionInfo, - fileExtensionIs, FileIncludeKind, FileIncludeReason, - FileWatcher, - filter, - find, - flattenDiagnosticMessageText, - forEach, + HasCurrentDirectory, + ModuleKind, + ParsedCommandLine, + Program, + ProjectReference, + SourceFile, + WatchOptions, + WriteFileCallback, +} from "./types"; +import { + chainDiagnosticMessages, + createCompilerDiagnostic, + externalHelpersModuleNameText, forEachEntry, - ForegroundColorEscapeSequences, - formatColorAndReset, - formatDiagnostic, - FormatDiagnosticsHost, - formatDiagnosticsWithColorAndContext, - generateDjb2Hash, - getDefaultLibFileName, - getDirectoryPath, getEmitScriptTarget, - getLineAndCharacterOfPosition, getNewLineCharacter, - getNormalizedAbsolutePath, - getParsedCommandLineOfConfigFile, getPatternFromSpec, - getReferencedFileLocation, getRegexFromPattern, - getRelativePathFromDirectory, - getWatchFactory, - HasCurrentDirectory, isExternalOrCommonJsModule, - isLineBreak, - isReferencedFile, - isReferenceFileLocation, - isString, - last, - maybeBind, - memoize, - ModuleKind, - noop, - normalizePath, outFile, packageIdToString, - ParseConfigFileHost, - ParsedCommandLine, - pathIsAbsolute, - Program, - ProgramHost, - ProjectReference, - ReportEmitErrorSummary, - ReportFileInError, +} from "./utilities"; +import { + getDefaultLibFileName, sortAndDeduplicateDiagnostics, - SortedReadonlyArray, - SourceFile, - sourceMapCommentRegExp, - sourceMapCommentRegExpDontCareLineStart, - sys, - System, - targetOptionDeclaration, +} from "./utilitiesPublic"; +import { + createIncrementalCompilerHost, + createIncrementalProgram, + CreateProgram, + ProgramHost, WatchCompilerHost, WatchCompilerHostOfConfigFile, WatchCompilerHostOfFilesAndCompilerOptions, + WatchHost, + WatchStatusReporter, +} from "./watchPublic"; +import { + DirectoryStructureHost, + getWatchFactory, WatchFactory, WatchFactoryHost, - WatchHost, WatchLogLevel, - WatchOptions, - WatchStatusReporter, - whitespaceOrMapCommentRegExp, - WriteFileCallback, -} from "./_namespaces/ts"; +} from "./watchUtilities"; const sysFormatDiagnosticsHost: FormatDiagnosticsHost | undefined = sys ? { getCurrentDirectory: () => sys.getCurrentDirectory(), diff --git a/src/compiler/watchPublic.ts b/src/compiler/watchPublic.ts index 6810e32608551..f57d5f58f1bda 100644 --- a/src/compiler/watchPublic.ts +++ b/src/compiler/watchPublic.ts @@ -1,96 +1,120 @@ import * as ts from "./_namespaces/ts"; +import { createBuilderProgramUsingProgramBuildInfo } from "./builder"; import { BuilderProgram, - BuildInfo, + createEmitAndSemanticDiagnosticsBuilderProgram, + EmitAndSemanticDiagnosticsBuilderProgram, +} from "./builderPublic"; +import { canJsonReportNoInputFiles, - changeCompilerHostLikeToUseCache, - changesAffectModuleResolution, - cleanExtendedConfigCache, - clearMap, - clearSharedExtendedConfigFileWatcher, - closeFileWatcher, - closeFileWatcherOf, - CompilerHost, - CompilerOptions, ConfigFileDiagnosticsReporter, - ConfigFileProgramReloadLevel, - createBuilderProgramUsingProgramBuildInfo, - createCachedDirectoryStructureHost, - createCompilerDiagnostic, - createCompilerHostFromProgramHost, - createCompilerHostWorker, - createEmitAndSemanticDiagnosticsBuilderProgram, - createGetCanonicalFileName, - createResolutionCache, - CreateSourceFileOptions, - createWatchCompilerHostOfConfigFile, - createWatchCompilerHostOfFilesAndCompilerOptions, - createWatchFactory, - Debug, - Diagnostic, - DiagnosticMessage, DiagnosticReporter, - Diagnostics, - DirectoryStructureHost, - DirectoryWatcherCallback, - EmitAndSemanticDiagnosticsBuilderProgram, ExtendedConfigCacheEntry, - FileExtensionInfo, - FileReference, - FileWatcher, - FileWatcherCallback, - FileWatcherEventKind, - getBuildInfo, - getConfigFileParsingDiagnostics, - getDirectoryPath, - getEntries, getFileNamesFromConfigSpecs, - getNewLineCharacter, - getNormalizedAbsolutePath, getParsedCommandLineOfConfigFile, - getTsBuildInfoEmitOutputFilePath, - HasInvalidatedResolutions, + updateErrorForNoInputFiles, +} from "./commandLineParser"; +import { + createGetCanonicalFileName, + getEntries, isArray, - isIgnoredFileFromWildCardWatching, - isProgramUptoDate, - MapLike, maybeBind, - ModuleResolutionCache, - ModuleResolutionInfo, noop, - noopFileWatcher, + returnFalse, + returnTrue, +} from "./core"; +import { + MapLike, + version, +} from "./corePublic"; +import { Debug } from "./debug"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { + getBuildInfo, + getTsBuildInfoEmitOutputFilePath, +} from "./emitter"; +import { ModuleResolutionCache } from "./moduleNameResolver"; +import { CreateSourceFileOptions } from "./parser"; +import { + getDirectoryPath, + getNormalizedAbsolutePath, + toPath, +} from "./path"; +import { perfLogger } from "./perfLogger"; +import { + changeCompilerHostLikeToUseCache, + createCompilerHostWorker, + getConfigFileParsingDiagnostics, + isProgramUptoDate, parseConfigHostFromCompilerHostLike, +} from "./program"; +import { + createResolutionCache, + ResolutionCacheHost, +} from "./resolutionCache"; +import { + DirectoryWatcherCallback, + FileWatcher, + FileWatcherCallback, + FileWatcherEventKind, + PollingInterval, + sys, + System, +} from "./sys"; +import { + BuildInfo, + CompilerHost, + CompilerOptions, + Diagnostic, + DiagnosticMessage, + FileExtensionInfo, + FileReference, + HasInvalidatedResolutions, + ModuleResolutionInfo, ParsedCommandLine, Path, - perfLogger, - PollingInterval, ProjectReference, - ResolutionCacheHost, ResolutionMode, ResolvedModule, ResolvedProjectReference, ResolvedTypeReferenceDirective, - returnFalse, - returnTrue, ScriptTarget, - setGetSourceFileAsHashVersioned, - SharedExtendedConfigFileWatcher, SourceFile, - sys, - System, - toPath, TypeReferenceDirectiveResolutionInfo, - updateErrorForNoInputFiles, - updateMissingFilePathsWatch, - updateSharedExtendedConfigFileWatcher, - updateWatchingWildcardDirectories, - version, WatchDirectoryFlags, WatchOptions, +} from "./types"; +import { + changesAffectModuleResolution, + clearMap, + closeFileWatcher, + createCompilerDiagnostic, + getNewLineCharacter, +} from "./utilities"; +import { + createCompilerHostFromProgramHost, + createWatchCompilerHostOfConfigFile, + createWatchCompilerHostOfFilesAndCompilerOptions, + createWatchFactory, + noopFileWatcher, + setGetSourceFileAsHashVersioned, WatchType, WatchTypeRegistry, +} from "./watch"; +import { + cleanExtendedConfigCache, + clearSharedExtendedConfigFileWatcher, + closeFileWatcherOf, + ConfigFileProgramReloadLevel, + createCachedDirectoryStructureHost, + DirectoryStructureHost, + isIgnoredFileFromWildCardWatching, + SharedExtendedConfigFileWatcher, + updateMissingFilePathsWatch, + updateSharedExtendedConfigFileWatcher, + updateWatchingWildcardDirectories, WildcardDirectoryWatcher, -} from "./_namespaces/ts"; +} from "./watchUtilities"; export interface ReadBuildProgramHost { useCaseSensitiveFileNames(): boolean; diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index 62d6ffee46091..1fa781738636e 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -1,59 +1,71 @@ -import * as ts from "./_namespaces/ts"; +import { BuilderProgram } from "./builderPublic"; +import { + ExtendedConfigCacheEntry, + isExcludedFile, + matchesExclude, +} from "./commandLineParser"; import { arrayToMap, binarySearch, - BuilderProgram, - closeFileWatcher, compareStringsCaseSensitive, - CompilerOptions, createGetCanonicalFileName, - Debug, - DirectoryWatcherCallback, emptyArray, - emptyFileSystemEntries, - ensureTrailingDirectorySeparator, - ExtendedConfigCacheEntry, - Extension, - FileExtensionInfo, - fileExtensionIsOneOf, - FileSystemEntries, - FileWatcher, - FileWatcherCallback, - FileWatcherEventKind, find, - getBaseFileName, - getDirectoryPath, - getNormalizedAbsolutePath, - hasExtension, identity, insertSorted, isArray, - isDeclarationFileName, - isExcludedFile, - isSupportedSourceFileName, map, - matchesExclude, - matchFiles, - mutateMap, noop, - normalizePath, - outFile, - Path, - PollingInterval, - Program, - removeFileExtension, - removeIgnoredPath, - returnNoopFileWatcher, returnTrue, - setSysLog, +} from "./core"; +import { SortedArray, SortedReadonlyArray, - supportedJSExtensionsFlat, - timestamp, +} from "./corePublic"; +import { Debug } from "./debug"; +import { isDeclarationFileName } from "./parser"; +import { + toPath as _toPath, + ensureTrailingDirectorySeparator, + fileExtensionIsOneOf, + getBaseFileName, + getDirectoryPath, + getNormalizedAbsolutePath, + hasExtension, + normalizePath, +} from "./path"; +import { timestamp } from "./performanceCore"; +import { removeIgnoredPath } from "./resolutionCache"; +import { + DirectoryWatcherCallback, + FileWatcher, + FileWatcherCallback, + FileWatcherEventKind, + PollingInterval, + setSysLog, +} from "./sys"; +import { + CompilerOptions, + Extension, + FileExtensionInfo, + Path, + Program, WatchDirectoryFlags, WatchFileKind, WatchOptions, -} from "./_namespaces/ts"; +} from "./types"; +import { + closeFileWatcher, + emptyFileSystemEntries, + FileSystemEntries, + isSupportedSourceFileName, + matchFiles, + mutateMap, + outFile, + removeFileExtension, + supportedJSExtensionsFlat, +} from "./utilities"; +import { returnNoopFileWatcher } from "./watch"; /** * Partial interface of the System thats needed to support the caching of directory structure @@ -133,7 +145,7 @@ export function createCachedDirectoryStructureHost(host: DirectoryStructureHost, }; function toPath(fileName: string) { - return ts.toPath(fileName, currentDirectory, getCanonicalFileName); + return _toPath(fileName, currentDirectory, getCanonicalFileName); } function getCachedFileSystemEntries(rootDirPath: Path) { diff --git a/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts b/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts index caca5fc914394..966af1552b15a 100644 --- a/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts +++ b/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts @@ -1,3 +1,7 @@ +import { Debug } from "../../compiler/debug"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { setTextRange } from "../../compiler/factory/utilitiesPublic"; +import { parseBaseNodeFactory } from "../../compiler/parser"; import { ArrowFunction, AsteriskToken, @@ -12,27 +16,22 @@ import { ConciseBody, ConditionalExpression, ConstructorTypeNode, - Debug, Decorator, - DeprecationOptions, EntityName, EqualsGreaterThanToken, ExclamationToken, ExportDeclaration, Expression, ExpressionWithTypeArguments, - factory, GeneratedIdentifierFlags, HeritageClause, Identifier, ImportClause, IndexSignatureDeclaration, - isNodeKind, JSDocParameterTag, JSDocTypeExpression, MethodSignature, Modifier, - Mutable, NamedExportBindings, NamedImportBindings, Node, @@ -40,7 +39,6 @@ import { NoSubstitutionTemplateLiteral, NumericLiteral, ParameterDeclaration, - parseBaseNodeFactory, PostfixUnaryExpression, PrefixUnaryExpression, PrimaryExpression, @@ -48,9 +46,6 @@ import { PropertySignature, PseudoBigInt, QuestionToken, - setParent, - setTextRange, - setTextRangePosEnd, StringLiteral, SyntaxKind, TaggedTemplateExpression, @@ -63,8 +58,15 @@ import { TypePredicateNode, VariableDeclaration, YieldExpression, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + Mutable, + setParent, + setTextRangePosEnd, +} from "../../compiler/utilities"; +import { isNodeKind } from "../../compiler/utilitiesPublic"; import { deprecate } from "../deprecate"; +import { DeprecationOptions } from "../deprecations"; // DEPRECATION: Node factory top-level exports // DEPRECATION PLAN: diff --git a/src/deprecatedCompat/4.0/renamedNodeTests.ts b/src/deprecatedCompat/4.0/renamedNodeTests.ts index 0b3f0125de673..889a73d3a57f3 100644 --- a/src/deprecatedCompat/4.0/renamedNodeTests.ts +++ b/src/deprecatedCompat/4.0/renamedNodeTests.ts @@ -2,7 +2,7 @@ import { Node, SyntaxKind, TypeAssertion, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { deprecate } from "../deprecate"; // DEPRECATION: Renamed node tests diff --git a/src/deprecatedCompat/4.2/abstractConstructorTypes.ts b/src/deprecatedCompat/4.2/abstractConstructorTypes.ts index 5de292fb9bce3..9e6bfb845742f 100644 --- a/src/deprecatedCompat/4.2/abstractConstructorTypes.ts +++ b/src/deprecatedCompat/4.2/abstractConstructorTypes.ts @@ -1,15 +1,17 @@ import { addNodeFactoryPatcher, - buildOverload, - ConstructorTypeNode, factory, +} from "../../compiler/factory/nodeFactory"; +import { + ConstructorTypeNode, Modifier, NodeArray, NodeFactory, ParameterDeclaration, TypeNode, TypeParameterDeclaration, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { buildOverload } from "../deprecations"; // DEPRECATION: Overloads for createConstructorTypeNode/updateConstructorTypeNode that do not accept 'modifiers' // DEPRECATION PLAN: diff --git a/src/deprecatedCompat/4.2/renamedNodeTests.ts b/src/deprecatedCompat/4.2/renamedNodeTests.ts index 78a0f155f53d1..183b5e11be687 100644 --- a/src/deprecatedCompat/4.2/renamedNodeTests.ts +++ b/src/deprecatedCompat/4.2/renamedNodeTests.ts @@ -1,8 +1,8 @@ import { - isMemberName, MemberName, Node, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { isMemberName } from "../../compiler/utilitiesPublic"; import { deprecate } from "../deprecate"; // DEPRECATION: Renamed node tests diff --git a/src/deprecatedCompat/4.6/importTypeAssertions.ts b/src/deprecatedCompat/4.6/importTypeAssertions.ts index 738eb2327d1b4..625d150acf2cd 100644 --- a/src/deprecatedCompat/4.6/importTypeAssertions.ts +++ b/src/deprecatedCompat/4.6/importTypeAssertions.ts @@ -1,16 +1,20 @@ +import { isArray } from "../../compiler/core"; import { addNodeFactoryPatcher, - buildOverload, - EntityName, factory, +} from "../../compiler/factory/nodeFactory"; +import { + isImportTypeAssertionContainer, +} from "../../compiler/factory/nodeTests"; +import { + EntityName, ImportTypeAssertionContainer, ImportTypeNode, - isArray, - isEntityName, - isImportTypeAssertionContainer, NodeFactory, TypeNode, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { isEntityName } from "../../compiler/utilitiesPublic"; +import { buildOverload } from "../deprecations"; // DEPRECATION: Overloads to createImportTypeNode/updateImportTypeNode that do not accept `assertions` // DEPRECATION PLAN: diff --git a/src/deprecatedCompat/4.7/typeParameterModifiers.ts b/src/deprecatedCompat/4.7/typeParameterModifiers.ts index 97f35beba4150..39a7d3667b8e8 100644 --- a/src/deprecatedCompat/4.7/typeParameterModifiers.ts +++ b/src/deprecatedCompat/4.7/typeParameterModifiers.ts @@ -1,14 +1,16 @@ +import { isArray } from "../../compiler/core"; import { addNodeFactoryPatcher, - buildOverload, factory, +} from "../../compiler/factory/nodeFactory"; +import { Identifier, - isArray, Modifier, NodeFactory, TypeNode, TypeParameterDeclaration, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { buildOverload } from "../deprecations"; // DEPRECATION: Overloads to createTypeParameter/updateTypeParameter that does not accept `modifiers` // DEPRECATION PLAN: diff --git a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts index d23969ccda6be..effc9a08a5b04 100644 --- a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts +++ b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts @@ -1,27 +1,48 @@ +import { + concatenate, + every, + isArray, + some, +} from "../../compiler/core"; import { addNodeFactoryPatcher, + factory, +} from "../../compiler/factory/nodeFactory"; +import { + isAssertClause, + isAsteriskToken, + isBlock, + isDecorator, + isDotDotDotToken, + isHeritageClause, + isIdentifier, + isImportClause, + isParameter, + isQuestionToken, + isTypeParameterDeclaration, +} from "../../compiler/factory/nodeTests"; +import { + isModuleName, + isQuestionOrExclamationToken, +} from "../../compiler/factory/utilities"; +import { AssertClause, AsteriskToken, BindingName, Block, - buildOverload, ClassDeclaration, ClassElement, ClassExpression, ClassStaticBlockDeclaration, - concatenate, ConstructorDeclaration, Decorator, - DeprecationOptions, DotDotDotToken, EnumDeclaration, EnumMember, - every, ExclamationToken, ExportAssignment, ExportDeclaration, Expression, - factory, FunctionDeclaration, GetAccessorDeclaration, HeritageClause, @@ -31,30 +52,6 @@ import { ImportEqualsDeclaration, IndexSignatureDeclaration, InterfaceDeclaration, - isArray, - isAssertClause, - isAsteriskToken, - isBindingName, - isBlock, - isClassElement, - isDecorator, - isDotDotDotToken, - isExpression, - isHeritageClause, - isIdentifier, - isImportClause, - isModifier, - isModuleBody, - isModuleName, - isModuleReference, - isNamedExportBindings, - isParameter, - isPropertyName, - isQuestionOrExclamationToken, - isQuestionToken, - isTypeElement, - isTypeNode, - isTypeParameterDeclaration, MethodDeclaration, Modifier, ModifierLike, @@ -70,12 +67,27 @@ import { PropertyName, QuestionToken, SetAccessorDeclaration, - some, TypeAliasDeclaration, TypeElement, TypeNode, TypeParameterDeclaration, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + isBindingName, + isClassElement, + isExpression, + isModifier, + isModuleBody, + isModuleReference, + isNamedExportBindings, + isPropertyName, + isTypeElement, + isTypeNode, +} from "../../compiler/utilitiesPublic"; +import { + buildOverload, + DeprecationOptions, +} from "../deprecations"; // DEPRECATION: Deprecate passing `decorators` separate from `modifiers` // DEPRECATION PLAN: diff --git a/src/deprecatedCompat/deprecate.ts b/src/deprecatedCompat/deprecate.ts index c56abe2df1ef2..1ab1e5f1cddb4 100644 --- a/src/deprecatedCompat/deprecate.ts +++ b/src/deprecatedCompat/deprecate.ts @@ -1,11 +1,9 @@ -import { - Debug, - DeprecationOptions, - formatStringFromArgs, - noop, - version, - Version, -} from "./_namespaces/ts"; +import { noop } from "../compiler/core"; +import { version } from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { Version } from "../compiler/semver"; +import { formatStringFromArgs } from "../compiler/utilities"; +import { DeprecationOptions } from "./deprecations"; export let enableDeprecationWarnings = true; diff --git a/src/deprecatedCompat/deprecations.ts b/src/deprecatedCompat/deprecations.ts index 8682631b07830..5a6a4ca1dff7d 100644 --- a/src/deprecatedCompat/deprecations.ts +++ b/src/deprecatedCompat/deprecations.ts @@ -1,8 +1,6 @@ -import { - hasProperty, - UnionToIntersection, - Version, -} from "./_namespaces/ts"; +import { hasProperty } from "../compiler/core"; +import { Version } from "../compiler/semver"; +import { UnionToIntersection } from "../compiler/types"; import { deprecate } from "./deprecate"; /** @internal */ @@ -16,7 +14,6 @@ export interface DeprecationOptions { name?: string; } - // The following are deprecations for the public API. Deprecated exports are removed from the compiler itself // and compatible implementations are added here, along with an appropriate deprecation warning using // the `@deprecated` JSDoc tag as well as the `deprecate` API. diff --git a/src/executeCommandLine/executeCommandLine.ts b/src/executeCommandLine/executeCommandLine.ts index 58bd58cb02150..10d50f006b3d9 100644 --- a/src/executeCommandLine/executeCommandLine.ts +++ b/src/executeCommandLine/executeCommandLine.ts @@ -1,94 +1,117 @@ -import * as ts from "./_namespaces/ts"; import { - arrayFrom, BuilderProgram, - BuildOptions, + EmitAndSemanticDiagnosticsBuilderProgram, +} from "../compiler/builderPublic"; +import { buildOpts, - changeCompilerHostLikeToUseCache, - CharacterCodes, - combinePaths, - CommandLineOption, - compareStringsCaseInsensitive, - CompilerOptions, - contains, convertToOptionsWithAbsolutePaths, convertToTSConfig, - createBuilderStatusReporter, - createCompilerDiagnostic, - createCompilerHostWorker, - createDiagnosticReporter, - createGetCanonicalFileName, - createIncrementalCompilerHost, - createProgram, - CreateProgram, - CreateProgramOptions, - createSolutionBuilder, - createSolutionBuilderHost, - createSolutionBuilderWithWatch, - createSolutionBuilderWithWatchHost, - createWatchCompilerHostOfConfigFile, - createWatchCompilerHostOfFilesAndCompilerOptions, - createWatchProgram, - Debug, - Diagnostic, - DiagnosticMessage, DiagnosticReporter, - Diagnostics, - dumpTracingLegend, - EmitAndSemanticDiagnosticsBuilderProgram, - emitFilesAndReportErrorsAndGetExitStatus, - ExitStatus, ExtendedConfigCacheEntry, - Extension, - fileExtensionIs, - fileExtensionIsOneOf, - filter, - findConfigFile, - forEach, - formatMessage, generateTSConfig, - getBuildOrderFromAnyBuildOrder, getCompilerOptionsDiffValue, - getConfigFileParsingDiagnostics, getDiagnosticText, - getEntries, - getErrorSummaryText, - getLineStarts, - getNormalizedAbsolutePath, - isIncrementalCompilation, - isWatchSet, - normalizePath, optionDeclarations, optionsForBuild, optionsForWatch, - padLeft, - padRight, parseBuildCommand, parseCommandLine, - parseConfigFileWithSystem, - ParsedCommandLine, - Program, +} from "../compiler/commandLineParser"; +import { + arrayFrom, + compareStringsCaseInsensitive, + contains, + createGetCanonicalFileName, + filter, + forEach, + getEntries, + padLeft, + padRight, reduceLeftIterator, - ReportEmitErrorSummary, - SolutionBuilder, - SolutionBuilderHostBase, sort, - SourceFile, startsWith, - startTracing, stringContains, - supportedJSExtensionsFlat, - supportedTSExtensionsFlat, +} from "../compiler/core"; +import { version } from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { Diagnostics } from "../compiler/diagnosticInformationMap.generated"; +import { + combinePaths, + fileExtensionIs, + fileExtensionIsOneOf, + getNormalizedAbsolutePath, + normalizePath, + toPath, +} from "../compiler/path"; +import * as performance from "../compiler/performance"; +import { + changeCompilerHostLikeToUseCache, + createCompilerHostWorker, + createProgram, + findConfigFile, + getConfigFileParsingDiagnostics, +} from "../compiler/program"; +import { getLineStarts } from "../compiler/scanner"; +import { sys, System, - toPath, +} from "../compiler/sys"; +import { + dumpTracingLegend, + startTracing, tracing, - validateLocaleAndSetLanguage, - version, - WatchCompilerHost, +} from "../compiler/tracing"; +import { + BuildOptions, + createBuilderStatusReporter, + createSolutionBuilder, + createSolutionBuilderHost, + createSolutionBuilderWithWatch, + createSolutionBuilderWithWatchHost, + getBuildOrderFromAnyBuildOrder, + ReportEmitErrorSummary, + SolutionBuilder, + SolutionBuilderHostBase, +} from "../compiler/tsbuildPublic"; +import { + CharacterCodes, + CommandLineOption, + CompilerOptions, + CreateProgramOptions, + Diagnostic, + DiagnosticMessage, + ExitStatus, + Extension, + ParsedCommandLine, + Program, + SourceFile, WatchOptions, -} from "./_namespaces/ts"; -import * as performance from "../compiler/_namespaces/ts.performance"; +} from "../compiler/types"; +import { + createCompilerDiagnostic, + formatMessage, + isIncrementalCompilation, + isWatchSet, + supportedJSExtensionsFlat, + supportedTSExtensionsFlat, +} from "../compiler/utilities"; +import { validateLocaleAndSetLanguage } from "../compiler/utilitiesPublic"; +import { + createDiagnosticReporter, + createWatchCompilerHostOfConfigFile, + createWatchCompilerHostOfFilesAndCompilerOptions, + createWatchStatusReporter, + emitFilesAndReportErrorsAndGetExitStatus, + getErrorSummaryText, + parseConfigFileWithSystem, + performIncrementalCompilation, +} from "../compiler/watch"; +import { + createIncrementalCompilerHost, + CreateProgram, + createWatchProgram, + WatchCompilerHost, +} from "../compiler/watchPublic"; interface Statistic { name: string; @@ -673,7 +696,7 @@ function executeCommandLineWorker( ); } else if (isIncrementalCompilation(configParseResult.options)) { - performIncrementalCompilation( + performIncrementalCompilationWorker( sys, cb, reportDiagnostic, @@ -712,7 +735,7 @@ function executeCommandLineWorker( ); } else if (isIncrementalCompilation(commandLineOptions)) { - performIncrementalCompilation( + performIncrementalCompilationWorker( sys, cb, reportDiagnostic, @@ -838,7 +861,7 @@ function performBuild( /*createProgram*/ undefined, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty(sys, buildOptions)), - createWatchStatusReporter(sys, buildOptions) + createWatchStatusReporterWorker(sys, buildOptions) ); const solutionPerformance = enableSolutionPerformance(sys, buildOptions); updateSolutionBuilderHost(sys, cb, buildHost, solutionPerformance); @@ -914,7 +937,7 @@ function performCompilation( return sys.exit(exitStatus); } -function performIncrementalCompilation( +function performIncrementalCompilationWorker( sys: System, cb: ExecuteCommandLineCallbacks, reportDiagnostic: DiagnosticReporter, @@ -923,7 +946,7 @@ function performIncrementalCompilation( const { options, fileNames, projectReferences } = config; enableStatisticsAndTracing(sys, options, /*isBuildMode*/ false); const host = createIncrementalCompilerHost(options, sys); - const exitStatus = ts.performIncrementalCompilation({ + const exitStatus = performIncrementalCompilation({ host, system: sys, rootNames: fileNames, @@ -983,8 +1006,8 @@ function updateWatchCompilationHost( }; } -function createWatchStatusReporter(sys: System, options: CompilerOptions | BuildOptions) { - return ts.createWatchStatusReporter(sys, shouldBePretty(sys, options)); +function createWatchStatusReporterWorker(sys: System, options: CompilerOptions | BuildOptions) { + return createWatchStatusReporter(sys, shouldBePretty(sys, options)); } function createWatchOfConfigFile( @@ -1002,7 +1025,7 @@ function createWatchOfConfigFile( watchOptionsToExtend, system, reportDiagnostic, - reportWatchStatus: createWatchStatusReporter(system, configParseResult.options) + reportWatchStatus: createWatchStatusReporterWorker(system, configParseResult.options) }); updateWatchCompilationHost(system, cb, watchCompilerHost); watchCompilerHost.configFileParsingResult = configParseResult; @@ -1024,7 +1047,7 @@ function createWatchOfFilesAndCompilerOptions( watchOptions, system, reportDiagnostic, - reportWatchStatus: createWatchStatusReporter(system, options) + reportWatchStatus: createWatchStatusReporterWorker(system, options) }); updateWatchCompilationHost(system, cb, watchCompilerHost); return createWatchProgram(watchCompilerHost); diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index ac7c0c40ad3b5..4f2f23ebced7b 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -5,6 +5,7 @@ import * as ts from "./_namespaces/ts"; import * as fakes from "./_namespaces/fakes"; import * as vpath from "./_namespaces/vpath"; import * as Utils from "./_namespaces/Utils"; +import { applyChanges } from "../services/textChanges"; import ArrayOrSingle = FourSlashInterface.ArrayOrSingle; @@ -2990,7 +2991,7 @@ export class TestState { assert(changes.length === 1, "Affected 0 or more than 1 file, must use 'newFileContent' instead of 'newRangeContent'"); const change = ts.first(changes); assert(change.fileName = this.activeFile.fileName); - const newText = ts.textChanges.applyChanges(this.getFileContent(this.activeFile.fileName), change.textChanges); + const newText = applyChanges(this.getFileContent(this.activeFile.fileName), change.textChanges); const newRange = updateTextRangeForTextChanges(this.getOnlyRange(), change.textChanges); const actualText = newText.slice(newRange.pos, newRange.end); this.verifyTextMatches(actualText, /*includeWhitespace*/ true, newRangeContent); @@ -3005,7 +3006,7 @@ export class TestState { } const oldText = this.tryGetFileContent(change.fileName); ts.Debug.assert(!!change.isNewFile === (oldText === undefined)); - const newContent = change.isNewFile ? ts.first(change.textChanges).newText : ts.textChanges.applyChanges(oldText!, change.textChanges); + const newContent = change.isNewFile ? ts.first(change.textChanges).newText : applyChanges(oldText!, change.textChanges); this.verifyTextMatches(newContent, /*includeWhitespace*/ true, expectedNewContent); } for (const newFileName in newFileContent) { @@ -3640,7 +3641,7 @@ export class TestState { const fileContent = this.tryGetFileContent(fileName); if (fileContent !== undefined) { - const actualNewContent = ts.textChanges.applyChanges(fileContent, textChanges); + const actualNewContent = applyChanges(fileContent, textChanges); assert.equal(actualNewContent, newContent, `new content for ${fileName}`); } else { diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index e3e67e1909dc6..9c4237bbd2a37 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -1,35 +1,43 @@ +import { readConfigFile } from "../compiler/commandLineParser"; import { - CharacterCodes, - combinePaths, compareStringsCaseSensitive, - CompilerOptions, - Debug, deduplicate, equateStringsCaseSensitive, - Extension, - fileExtensionIs, flatMap, forEach, - getBaseFileName, - getDirectoryPath, getEntries, - getNormalizedAbsolutePath, getOwnKeys, - getPathComponents, getProperty, - hasJSFileExtension, mapDefined, + removeMinAndVersionNumbers, + some, +} from "../compiler/core"; +import { MapLike, + versionMajorMinor, +} from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { + combinePaths, + fileExtensionIs, + getBaseFileName, + getDirectoryPath, + getNormalizedAbsolutePath, + getPathComponents, normalizePath, +} from "../compiler/path"; +import { Version } from "../compiler/semver"; +import { + CharacterCodes, + CompilerOptions, + Extension, Path, - readConfigFile, - removeFileExtension, - removeMinAndVersionNumbers, - some, TypeAcquisition, - Version, - versionMajorMinor, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + hasJSFileExtension, + removeFileExtension, +} from "../compiler/utilities"; /** @internal */ export interface TypingResolutionHost { diff --git a/src/jsTyping/shared.ts b/src/jsTyping/shared.ts index c6a3dfb38bda2..a85cbef5ae772 100644 --- a/src/jsTyping/shared.ts +++ b/src/jsTyping/shared.ts @@ -1,7 +1,5 @@ -import { - padLeft, - sys, -} from "./_namespaces/ts"; +import { padLeft } from "../compiler/core"; +import { sys } from "../compiler/sys"; export type ActionSet = "action::set"; export type ActionInvalidate = "action::invalidate"; diff --git a/src/jsTyping/types.ts b/src/jsTyping/types.ts index a30a215adf12a..c0a30c78cff16 100644 --- a/src/jsTyping/types.ts +++ b/src/jsTyping/types.ts @@ -1,24 +1,28 @@ import { - ActionInvalidate, - ActionPackageInstalled, - ActionSet, - EventBeginInstallTypes, - EventEndInstallTypes, - EventInitializationFailed, - EventTypesRegistry, -} from "./_namespaces/ts.server"; + MapLike, + SortedReadonlyArray, +} from "../compiler/corePublic"; import { - CompilerOptions, DirectoryWatcherCallback, FileWatcher, FileWatcherCallback, - JsTyping, - MapLike, +} from "../compiler/sys"; +import { + CompilerOptions, Path, - SortedReadonlyArray, TypeAcquisition, WatchOptions, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import * as JsTyping from "./jsTyping"; +import { + ActionInvalidate, + ActionPackageInstalled, + ActionSet, + EventBeginInstallTypes, + EventEndInstallTypes, + EventInitializationFailed, + EventTypesRegistry, +} from "./shared"; export interface TypingInstallerResponse { readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 6b27c3296bcbb..086d7a38fe471 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1,185 +1,227 @@ import { - ActionInvalidate, - ActionSet, - asNormalizedPath, - AutoImportProviderProject, - BeginEnablePluginResult, - BeginInstallTypes, - ConfiguredProject, - countEachFileTypes, - createPackageJsonCache, - emptyArray, - EndInstallTypes, - Errors, - ExternalProject, - getBaseConfigFileName, - hasNoTypeScriptSource, - InferredProject, - InvalidateCachedTypings, - isConfiguredProject, - isDynamicFileName, - isInferredProject, - isInferredProjectName, - ITypingsInstaller, - Logger, - LogLevel, - makeAutoImportProviderProjectName, - makeAuxiliaryProjectName, - makeInferredProjectName, - Msg, - NormalizedPath, - normalizedPathToPath, - nullTypingsInstaller, - PackageInstalledResponse, - PackageJsonCache, - Project, - ProjectFilesWithTSDiagnostics, - ProjectKind, - ProjectOptions, - protocol, - ScriptInfo, - ScriptInfoVersion, - ServerHost, - Session, - SetTypings, - ThrottledOperations, - toNormalizedPath, - TypingsCache, -} from "./_namespaces/ts.server"; + canJsonReportNoInputFiles, + convertCompilerOptionsForTelemetry, + convertEnableAutoDiscoveryToEnable, + convertJsonOption, + ExtendedConfigCacheEntry, + getFileNamesFromConfigSpecs, + optionDeclarations, + optionsForWatch, + parseJsonSourceFileConfigFileContent, + tryReadFile, + typeAcquisitionDeclarations, +} from "../compiler/commandLineParser"; import { - addToSeen, arrayFrom, arrayToMap, AssertionLevel, - CachedDirectoryStructureHost, - canJsonReportNoInputFiles, - canWatchDirectoryOrFile, - cleanExtendedConfigCache, - clearMap, - clearSharedExtendedConfigFileWatcher, - closeFileWatcherOf, - combinePaths, - CommandLineOption, - CompilerOptions, - CompletionInfo, - ConfigFileProgramReloadLevel, contains, - containsPath, - convertCompilerOptionsForTelemetry, - convertEnableAutoDiscoveryToEnable, - convertJsonOption, - createCachedDirectoryStructureHost, - createDocumentRegistryInternal, createGetCanonicalFileName, createMultiMap, - Debug, - Diagnostic, - directorySeparator, - DirectoryStructureHost, - DocumentPosition, - DocumentPositionMapper, - DocumentRegistry, - DocumentRegistryBucketKeyWithMode, - emptyOptions, - ensureTrailingDirectorySeparator, - ExtendedConfigCacheEntry, - FileExtensionInfo, - fileExtensionIs, - FileWatcher, - FileWatcherEventKind, find, flatMap, forEach, - forEachAncestorDirectory, - forEachEntry, - forEachKey, - forEachResolvedProjectReference, - FormatCodeSettings, - getAnyExtensionFromPath, - getBaseFileName, - getDefaultFormatCodeSettings, - getDirectoryPath, - getDocumentPositionMapper, getEntries, - getFileNamesFromConfigSpecs, - getFileWatcherEventKind, - getNormalizedAbsolutePath, - getSnapshotText, - getWatchFactory, - hasExtension, hasProperty, - hasTSFileExtension, - HostCancellationToken, identity, - IncompleteCompletionsCache, - IndentStyle, isArray, - isIgnoredFileFromWildCardWatching, - isInsideNodeModules, - isJsonEqual, - isNodeModulesDirectory, - isRootedDiskPath, isString, - LanguageServiceMode, length, map, mapDefinedEntries, mapDefinedIterator, - missingFileModifiedTime, MultiMap, noop, + removeMinAndVersionNumbers, + returnTrue, + some, + startsWith, + toFileNameLowerCase, + tryAddToSet, + unorderedRemoveItem, +} from "../compiler/core"; +import { + ReadonlyCollection, + version, +} from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { parsePackageName } from "../compiler/moduleNameResolver"; +import { parseJsonText } from "../compiler/parser"; +import { + combinePaths, + containsPath, + directorySeparator, + ensureTrailingDirectorySeparator, + fileExtensionIs, + forEachAncestorDirectory, + getAnyExtensionFromPath, + getBaseFileName, + getDirectoryPath, + getNormalizedAbsolutePath, + hasExtension, + isNodeModulesDirectory, + isRootedDiskPath, normalizePath, normalizeSlashes, - optionDeclarations, - optionsForWatch, - PackageJsonAutoImportPreference, + toPath, +} from "../compiler/path"; +import { + forEachResolvedProjectReference, + resolveProjectReferencePath, +} from "../compiler/program"; +import { + canWatchDirectoryOrFile, + removeIgnoredPath, +} from "../compiler/resolutionCache"; +import { + FileWatcher, + FileWatcherEventKind, + getFileWatcherEventKind, + missingFileModifiedTime, + PollingInterval, +} from "../compiler/sys"; +import { tracing } from "../compiler/tracing"; +import { + CommandLineOption, + CompilerOptions, + Diagnostic, + DocumentPosition, + DocumentPositionMapper, + FileExtensionInfo, ParsedCommandLine, - parseJsonSourceFileConfigFileContent, - parseJsonText, - parsePackageName, Path, - PerformanceEvent, PluginImport, - PollingInterval, - ProjectPackageJsonInfo, ProjectReference, - ReadMapFile, - ReadonlyCollection, - removeFileExtension, - removeIgnoredPath, - removeMinAndVersionNumbers, ResolvedProjectReference, - resolveProjectReferencePath, - returnNoopFileWatcher, - returnTrue, ScriptKind, - SharedExtendedConfigFileWatcher, - some, SourceFile, SourceFileLike, - startsWith, Ternary, - TextChange, - toFileNameLowerCase, - toPath, - tracing, - tryAddToSet, - tryReadFile, TsConfigSourceFile, TypeAcquisition, - typeAcquisitionDeclarations, - unorderedRemoveItem, - updateSharedExtendedConfigFileWatcher, - updateWatchingWildcardDirectories, UserPreferences, - version, WatchDirectoryFlags, - WatchFactory, - WatchLogLevel, WatchOptions, +} from "../compiler/types"; +import { + addToSeen, + clearMap, + forEachEntry, + forEachKey, + hasTSFileExtension, + isJsonEqual, + removeFileExtension, +} from "../compiler/utilities"; +import { + returnNoopFileWatcher, WatchType, +} from "../compiler/watch"; +import { + CachedDirectoryStructureHost, + cleanExtendedConfigCache, + clearSharedExtendedConfigFileWatcher, + closeFileWatcherOf, + ConfigFileProgramReloadLevel, + createCachedDirectoryStructureHost, + DirectoryStructureHost, + getWatchFactory, + isIgnoredFileFromWildCardWatching, + SharedExtendedConfigFileWatcher, + updateSharedExtendedConfigFileWatcher, + updateWatchingWildcardDirectories, + WatchFactory, + WatchLogLevel, WildcardDirectoryWatcher, -} from "./_namespaces/ts"; +} from "../compiler/watchUtilities"; +import { + ActionInvalidate, + ActionSet, +} from "../jsTyping/shared"; +import { + BeginInstallTypes, + EndInstallTypes, + InvalidateCachedTypings, + PackageInstalledResponse, + SetTypings, +} from "../jsTyping/types"; +import { + createDocumentRegistryInternal, + DocumentRegistry, + DocumentRegistryBucketKeyWithMode, +} from "../services/documentRegistry"; +import { + getDocumentPositionMapper, + ReadMapFile, +} from "../services/sourcemaps"; +import { + CompletionInfo, + emptyOptions, + FormatCodeSettings, + getDefaultFormatCodeSettings, + HostCancellationToken, + IncompleteCompletionsCache, + IndentStyle, + LanguageServiceMode, + PackageJsonAutoImportPreference, + PerformanceEvent, + ProjectPackageJsonInfo, + TextChange, +} from "../services/types"; +import { + getSnapshotText, + isInsideNodeModules, +} from "../services/utilities"; +import { + createPackageJsonCache, + PackageJsonCache, +} from "./packageJsonCache"; +import { + AutoImportProviderProject, + BeginEnablePluginResult, + ConfiguredProject, + countEachFileTypes, + ExternalProject, + hasNoTypeScriptSource, + InferredProject, + isConfiguredProject, + isInferredProject, + Project, + ProjectFilesWithTSDiagnostics, + ProjectKind, +} from "./project"; +import * as protocol from "./protocol"; +import { + isDynamicFileName, + ScriptInfo, + ScriptInfoVersion, +} from "./scriptInfo"; +import { Session } from "./session"; +import { ServerHost } from "./types"; +import { + ITypingsInstaller, + nullTypingsInstaller, + TypingsCache, +} from "./typingsCache"; +import { + getBaseConfigFileName, + ThrottledOperations, +} from "./utilities"; +import { + asNormalizedPath, + emptyArray, + Errors, + isInferredProjectName, + Logger, + LogLevel, + makeAutoImportProviderProjectName, + makeAuxiliaryProjectName, + makeInferredProjectName, + Msg, + NormalizedPath, + normalizedPathToPath, + ProjectOptions, + toNormalizedPath, +} from "./utilitiesPublic"; export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024; /** @internal */ diff --git a/src/server/moduleSpecifierCache.ts b/src/server/moduleSpecifierCache.ts index 2f2142a5bb0fe..6d0e40655a053 100644 --- a/src/server/moduleSpecifierCache.ts +++ b/src/server/moduleSpecifierCache.ts @@ -1,14 +1,14 @@ +import { Debug } from "../compiler/debug"; +import { nodeModulesPathPart } from "../compiler/moduleNameResolver"; +import { FileWatcher } from "../compiler/sys"; import { - Debug, - FileWatcher, ModulePath, ModuleSpecifierCache, ModuleSpecifierOptions, - nodeModulesPathPart, Path, ResolvedModuleSpecifierInfo, UserPreferences, -} from "./_namespaces/ts"; +} from "../compiler/types"; /** @internal */ export interface ModuleSpecifierResolutionCacheHost { diff --git a/src/server/packageJsonCache.ts b/src/server/packageJsonCache.ts index d1c12c65d9bfb..bcb8733779539 100644 --- a/src/server/packageJsonCache.ts +++ b/src/server/packageJsonCache.ts @@ -1,15 +1,19 @@ +import { Debug } from "../compiler/debug"; import { combinePaths, - createPackageJsonInfo, - Debug, forEachAncestorDirectory, getDirectoryPath, +} from "../compiler/path"; +import { Path, - ProjectPackageJsonInfo, Ternary, +} from "../compiler/types"; +import { ProjectPackageJsonInfo } from "../services/types"; +import { + createPackageJsonInfo, tryFileExists, -} from "./_namespaces/ts"; -import { ProjectService } from "./_namespaces/ts.server"; +} from "../services/utilities"; +import { ProjectService } from "./editorServices"; /** @internal */ export interface PackageJsonCache { diff --git a/src/server/project.ts b/src/server/project.ts index dcce4777002b2..917a062cb5710 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1,156 +1,184 @@ -import * as ts from "./_namespaces/ts"; -import { - asNormalizedPath, - createModuleSpecifierCache, - emptyArray, - Errors, - FileStats, - forEachResolvedProjectReferenceProject, - LogLevel, - ModuleImportResult, - Msg, - NormalizedPath, - projectContainsInfoDirectly, - ProjectOptions, - ProjectReferenceProjectLoadKind, - ProjectService, - protocol, - ScriptInfo, - ServerHost, - Session, - toNormalizedPath, - TypingsCache, - updateProjectIfDirty, -} from "./_namespaces/ts.server"; +import { BuilderState } from "../compiler/builderState"; +import { updateErrorForNoInputFiles } from "../compiler/commandLineParser"; import { addRange, append, - ApplyCodeActionCommandResult, arrayFrom, arrayToMap, - BuilderState, - CachedDirectoryStructureHost, - changesAffectModuleResolution, - clearMap, - cloneCompilerOptions, - closeFileWatcher, - closeFileWatcherOf, - combinePaths, - CompilerHost, - CompilerOptions, concatenate, - ConfigFileProgramReloadLevel, - createCacheableExportInfoMap, - createLanguageService, - createResolutionCache, - createSymlinkCache, - Debug, - Diagnostic, - DirectoryStructureHost, - DirectoryWatcherCallback, - DocumentPositionMapper, - DocumentRegistry, enumerateInsertsAndDeletes, every, - explainFiles, - ExportInfoMap, - Extension, - fileExtensionIs, - FileReference, - FileWatcher, - FileWatcherCallback, - FileWatcherEventKind, filter, firstDefined, flatMap, forEach, - forEachEntry, - forEachKey, - generateDjb2Hash, - getAllowJSCompilerOption, - getAutomaticTypeDirectiveNames, GetCanonicalFileName, - getDeclarationEmitOutputFilePathWorker, - getDefaultCompilerOptions, - getDefaultLibFileName, - getDefaultLibFilePath, - getDirectoryPath, - getEffectiveTypeRoots, - getEmitDeclarations, - getEntrypointsFromPackageJsonInfo, - getNormalizedAbsolutePath, getOrUpdate, getStringComparer, - HasInvalidatedResolutions, - HostCancellationToken, - inferredTypesContainingFile, - InstallPackageOptions, - IScriptSnapshot, - isDeclarationFileName, - isExternalModuleNameRelative, - isInsideNodeModules, - JsTyping, - LanguageService, - LanguageServiceHost, - LanguageServiceMode, map, mapDefined, maybeBind, - ModuleResolutionCache, - ModuleResolutionHost, - ModuleResolutionInfo, noop, - noopFileWatcher, - normalizePath, - normalizeSlashes, orderedRemoveItem, - outFile, - PackageJsonAutoImportPreference, + returnFalse, + returnTrue, + some, + sort, + sortAndDeduplicate, + startsWith, +} from "../compiler/core"; +import { SortedReadonlyArray } from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { + getAutomaticTypeDirectiveNames, + getEffectiveTypeRoots, + getEntrypointsFromPackageJsonInfo, + ModuleResolutionCache, PackageJsonInfo, - ParsedCommandLine, parsePackageName, + resolvePackageNameToPackageJson, +} from "../compiler/moduleNameResolver"; +import { isDeclarationFileName } from "../compiler/parser"; +import { + combinePaths, + fileExtensionIs, + getDirectoryPath, + getNormalizedAbsolutePath, + normalizePath, + normalizeSlashes, + toPath, +} from "../compiler/path"; +import { perfLogger } from "../compiler/perfLogger"; +import { timestamp } from "../compiler/performanceCore"; +import { inferredTypesContainingFile } from "../compiler/program"; +import { + createResolutionCache, + ResolutionCache, +} from "../compiler/resolutionCache"; +import { + DirectoryWatcherCallback, + FileWatcher, + FileWatcherCallback, + FileWatcherEventKind, + generateDjb2Hash, + PollingInterval, +} from "../compiler/sys"; +import { tracing } from "../compiler/tracing"; +import { + CompilerHost, + CompilerOptions, + Diagnostic, + DocumentPositionMapper, + Extension, + FileReference, + HasInvalidatedResolutions, + ModuleResolutionHost, + ModuleResolutionInfo, + ParsedCommandLine, Path, - perfLogger, - PerformanceEvent, PluginImport, - PollingInterval, Program, - ProjectPackageJsonInfo, ProjectReference, - removeFileExtension, - ResolutionCache, - resolutionExtensionIsTSOrJson, ResolutionMode, ResolvedModuleFull, ResolvedModuleWithFailedLookupLocations, ResolvedProjectReference, ResolvedTypeReferenceDirective, - resolvePackageNameToPackageJson, - returnFalse, - returnTrue, ScriptKind, - some, - sort, - sortAndDeduplicate, - SortedReadonlyArray, SourceFile, - SourceMapper, - startsWith, - stripQuotes, StructureIsReused, - SymlinkCache, - ThrottledCancellationToken, - timestamp, - toPath, - tracing, TypeAcquisition, TypeReferenceDirectiveResolutionInfo, - updateErrorForNoInputFiles, - updateMissingFilePathsWatch, WatchDirectoryFlags, WatchOptions, +} from "../compiler/types"; +import { + changesAffectModuleResolution, + clearMap, + closeFileWatcher, + createSymlinkCache, + forEachEntry, + forEachKey, + getAllowJSCompilerOption, + getDeclarationEmitOutputFilePathWorker, + getEmitDeclarations, + outFile, + removeFileExtension, + resolutionExtensionIsTSOrJson, + stripQuotes, + SymlinkCache, +} from "../compiler/utilities"; +import { + getDefaultLibFileName, + isExternalModuleNameRelative, +} from "../compiler/utilitiesPublic"; +import { + explainFiles, + noopFileWatcher, WatchType, -} from "./_namespaces/ts"; +} from "../compiler/watch"; +import { + CachedDirectoryStructureHost, + closeFileWatcherOf, + ConfigFileProgramReloadLevel, + DirectoryStructureHost, + updateMissingFilePathsWatch, +} from "../compiler/watchUtilities"; +import * as JsTyping from "../jsTyping/jsTyping"; +import { DocumentRegistry } from "../services/documentRegistry"; +import { createCacheableExportInfoMap } from "../services/exportInfoMap"; +import { + createLanguageService, + getDefaultCompilerOptions, + getDefaultLibFilePath, + ThrottledCancellationToken, +} from "../services/services"; +import { SourceMapper } from "../services/sourcemaps"; +import { + ApplyCodeActionCommandResult, + ExportInfoMap, + HostCancellationToken, + InstallPackageOptions, + IScriptSnapshot, + LanguageService, + LanguageServiceHost, + LanguageServiceMode, + PackageJsonAutoImportPreference, + PerformanceEvent, + ProjectPackageJsonInfo, +} from "../services/types"; +import { + cloneCompilerOptions, + isInsideNodeModules, +} from "../services/utilities"; +import * as ts from "./_namespaces/ts"; +import { + FileStats, + forEachResolvedProjectReferenceProject, + projectContainsInfoDirectly, + ProjectReferenceProjectLoadKind, + ProjectService, + updateProjectIfDirty, +} from "./editorServices"; +import { createModuleSpecifierCache } from "./moduleSpecifierCache"; +import * as protocol from "./protocol"; +import { ScriptInfo } from "./scriptInfo"; +import { Session } from "./session"; +import { + ModuleImportResult, + ServerHost, +} from "./types"; +import { TypingsCache } from "./typingsCache"; +import { + asNormalizedPath, + emptyArray, + Errors, + LogLevel, + Msg, + NormalizedPath, + ProjectOptions, + toNormalizedPath, +} from "./utilitiesPublic"; export enum ProjectKind { Inferred, diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 5f22bb2338693..39ce78e041e49 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -1,23 +1,25 @@ -import * as ts from "./_namespaces/ts"; +import { OutputFile } from "../compiler/builderStatePublic"; +import { MapLike } from "../compiler/corePublic"; import { CompilerOptionsValue, - EndOfLineState, FileExtensionInfo, - HighlightSpanKind, - MapLike, - OutliningSpanKind, - OutputFile, PluginImport, ProjectReference, + ScriptKind, + TypeAcquisition, +} from "../compiler/types"; +import { + EndOfLineState, + HighlightSpanKind, + OutliningSpanKind, RenameLocation, ScriptElementKind, - ScriptKind, TextChange, TextInsertion, TodoComment, TodoCommentDescriptor, - TypeAcquisition, -} from "./_namespaces/ts"; +} from "../services/types"; +import * as ts from "./_namespaces/ts"; /** * Declaration module describing the TypeScript Server protocol diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 9c1371f2d9f57..14ce880bf5be4 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -1,57 +1,77 @@ -import { - AbsolutePositionAndLineText, - ConfiguredProject, - Errors, - ExternalProject, - InferredProject, - isConfiguredProject, - isExternalProject, - isInferredProject, - maxFileSize, - NormalizedPath, - Project, - ProjectKind, - protocol, - ScriptVersionCache, - ServerHost, -} from "./_namespaces/ts.server"; import { assign, clear, - closeFileWatcherOf, - computeLineAndCharacterOfPosition, - computeLineStarts, - computePositionOfLineAndCharacter, contains, - createTextSpanFromBounds, - Debug, - directorySeparator, - DocumentPositionMapper, - DocumentRegistryBucketKeyWithMode, - emptyOptions, - FileWatcher, - FileWatcherEventKind, forEach, - FormatCodeSettings, + isString, + some, + stringContains, + unorderedRemoveItem, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { + directorySeparator, getBaseFileName, - getDefaultFormatCodeSettings, +} from "../compiler/path"; +import { + computeLineAndCharacterOfPosition, + computeLineStarts, + computePositionOfLineAndCharacter, +} from "../compiler/scanner"; +import { getLineInfo, - getScriptKindFromFileName, - getSnapshotText, - hasTSFileExtension, - IScriptSnapshot, - isString, LineInfo, +} from "../compiler/sourcemap"; +import { + FileWatcher, + FileWatcherEventKind, +} from "../compiler/sys"; +import { + DocumentPositionMapper, Path, ScriptKind, - ScriptSnapshot, - some, SourceFile, SourceFileLike, - stringContains, TextSpan, - unorderedRemoveItem, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + getScriptKindFromFileName, + hasTSFileExtension, +} from "../compiler/utilities"; +import { createTextSpanFromBounds } from "../compiler/utilitiesPublic"; +import { closeFileWatcherOf } from "../compiler/watchUtilities"; +import { + DocumentRegistryBucketKeyWithMode, +} from "../services/documentRegistry"; +import { + emptyOptions, + FormatCodeSettings, + getDefaultFormatCodeSettings, + IScriptSnapshot, + ScriptSnapshot, +} from "../services/types"; +import { getSnapshotText } from "../services/utilities"; +import { maxFileSize } from "./editorServices"; +import { + ConfiguredProject, + ExternalProject, + InferredProject, + isConfiguredProject, + isExternalProject, + isInferredProject, + Project, + ProjectKind, +} from "./project"; +import * as protocol from "./protocol"; +import { + AbsolutePositionAndLineText, + ScriptVersionCache, +} from "./scriptVersionCache"; +import { ServerHost } from "./types"; +import { + Errors, + NormalizedPath, +} from "./utilitiesPublic"; export interface ScriptInfoVersion { svc: number; diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index a4acf98f5516b..c5b17dfcd386c 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -1,18 +1,18 @@ +import { Debug } from "../compiler/debug"; +import { computeLineStarts } from "../compiler/scanner"; +import { + TextChangeRange, + TextSpan, +} from "../compiler/types"; import { collapseTextChangeRangesAcrossMultipleVersions, - computeLineStarts, createTextChangeRange, createTextSpan, - Debug, - IScriptSnapshot, - TextChangeRange, - TextSpan, unchangedTextChangeRange, -} from "./_namespaces/ts"; -import { - emptyArray, - protocol, -} from "./_namespaces/ts.server"; +} from "../compiler/utilitiesPublic"; +import { IScriptSnapshot } from "../services/types"; +import * as protocol from "./protocol"; +import { emptyArray } from "./utilitiesPublic"; const lineCollectionCapacity = 4; diff --git a/src/server/session.ts b/src/server/session.ts index ceb15519eb435..2783e47db1f75 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1,168 +1,170 @@ +import { EmitOutput } from "../compiler/builderStatePublic"; import { arrayFrom, arrayIterator, arrayReverseIterator, - CallHierarchyIncomingCall, - CallHierarchyItem, - CallHierarchyOutgoingCall, cast, - CodeAction, - CodeActionCommand, - CodeFixAction, - CombinedCodeActions, - CompilerOptions, - CompletionEntry, - CompletionEntryData, - CompletionEntryDetails, - CompletionInfo, - CompletionTriggerKind, - computeLineAndCharacterOfPosition, - computeLineStarts, concatenate, createQueue, createSet, - createTextSpan, - createTextSpanFromBounds, - Debug, - decodedTextSpanIntersectsWith, deduplicate, - DefinitionInfo, - DefinitionInfoAndBoundSpan, - Diagnostic, - diagnosticCategoryName, - DiagnosticRelatedInformation, - displayPartsToString, - DocumentHighlights, - DocumentPosition, - DocumentSpan, - documentSpansEqual, - EmitOutput, equateValues, - FileTextChanges, filter, find, - FindAllReferences, first, firstOrUndefined, flatMap, flatMapToMutable, - flattenDiagnosticMessageText, - forEachNameInAccessChainWalkingLeft, - FormatCodeSettings, - formatting, - getDeclarationFromName, - getDeclarationOfKind, - getEmitDeclarations, getEntries, + identity, + isArray, + isString, + map, + mapDefined, + mapDefinedIterator, + mapIterator, + memoize, + MultiMap, + singleIterator, + some, + startsWith, + stringContains, + toArray, + toFileNameLowerCase, +} from "../compiler/core"; +import { version } from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { isIdentifier } from "../compiler/factory/nodeTests"; +import { getEntrypointsFromPackageJsonInfo, - getLineAndCharacterOfPosition, - getMappedContextSpan, - getMappedDocumentSpan, - getMappedLocation, - getNodeModulePathParts, - getNormalizedAbsolutePath, getPackageNameFromTypesPackageName, getPackageScopeForPath, - getSnapshotText, - getSupportedCodeFixes, getTemporaryModuleResolutionState, - getTextOfIdentifierOrLiteral, - getTouchingPropertyName, - GoToDefinition, - HostCancellationToken, - identity, - ImplementationLocation, + nodeModulesPathPart, + unmangleScopedPackageName, +} from "../compiler/moduleNameResolver"; +import { isDeclarationFileName } from "../compiler/parser"; +import { + getNormalizedAbsolutePath, + normalizePath, +} from "../compiler/path"; +import { perfLogger } from "../compiler/perfLogger"; +import { flattenDiagnosticMessageText } from "../compiler/program"; +import { + computeLineAndCharacterOfPosition, + computeLineStarts, + getLineAndCharacterOfPosition, +} from "../compiler/scanner"; +import { tracing } from "../compiler/tracing"; +import { + CompilerOptions, + Diagnostic, + diagnosticCategoryName, + DiagnosticRelatedInformation, + DocumentPosition, ImportSpecifier, + LineAndCharacter, + ModuleResolutionKind, + OperationCanceledException, + Path, + Program, + ScriptKind, + SourceFile, + SyntaxKind, + TextRange, + TextSpan, + UserPreferences, +} from "../compiler/types"; +import { + forEachNameInAccessChainWalkingLeft, + getDeclarationFromName, + getDeclarationOfKind, + getEmitDeclarations, + getNodeModulePathParts, + getTextOfIdentifierOrLiteral, isAccessExpression, - isArray, - isDeclarationFileName, - isIdentifier, - isString, + outFile, + removeFileExtension, +} from "../compiler/utilities"; +import { + createTextSpan, + createTextSpanFromBounds, + decodedTextSpanIntersectsWith, isStringLiteralLike, + textSpanEnd, +} from "../compiler/utilitiesPublic"; +import { Core as FindAllReferences } from "../services/findAllReferences"; +import { getIndentationString } from "../services/formatting/formatting"; +import { createDefinitionInfo } from "../services/goToDefinition"; +import { + displayPartsToString, + getSupportedCodeFixes, +} from "../services/services"; +import { + CallHierarchyIncomingCall, + CallHierarchyItem, + CallHierarchyOutgoingCall, + CodeAction, + CodeActionCommand, + CodeFixAction, + CombinedCodeActions, + CompletionEntry, + CompletionEntryData, + CompletionEntryDetails, + CompletionInfo, + CompletionTriggerKind, + DefinitionInfo, + DefinitionInfoAndBoundSpan, + DocumentHighlights, + DocumentSpan, + FileTextChanges, + FormatCodeSettings, + HostCancellationToken, + ImplementationLocation, JSDocLinkDisplayPart, JSDocTagInfo, LanguageServiceMode, - LineAndCharacter, - map, - mapDefined, - mapDefinedIterator, - mapIterator, - mapOneOrMany, - memoize, - ModuleResolutionKind, - MultiMap, NavigateToItem, NavigationBarItem, NavigationTree, - nodeModulesPathPart, - normalizePath, - OperationCanceledException, OrganizeImportsMode, - outFile, OutliningSpan, - Path, - perfLogger, PerformanceEvent, - PossibleProgramFileInfo, - Program, QuickInfo, RefactorEditInfo, ReferencedSymbol, ReferencedSymbolDefinitionInfo, ReferencedSymbolEntry, ReferenceEntry, - removeFileExtension, RenameInfo, RenameLocation, - ScriptKind, SelectionRange, SemanticClassificationFormat, SignatureHelpItem, SignatureHelpItems, - singleIterator, - some, - SourceFile, - startsWith, - stringContains, SymbolDisplayPart, - SyntaxKind, TextChange, TextInsertion, - TextRange, - TextSpan, - textSpanEnd, - toArray, - toFileNameLowerCase, - tracing, - unmangleScopedPackageName, - UserPreferences, - version, WithMetadata, -} from "./_namespaces/ts"; +} from "../services/types"; +import { + documentSpansEqual, + getMappedContextSpan, + getMappedDocumentSpan, + getMappedLocation, + getSnapshotText, + getTouchingPropertyName, + mapOneOrMany, + PossibleProgramFileInfo, +} from "../services/utilities"; import { ConfigFileDiagEvent, - ConfiguredProject, convertFormatOptions, convertScriptKindName, convertUserPreferences, - EmitResult, - emptyArray, - Errors, - GcTimer, - indent, isConfigFile, - isConfiguredProject, - isExternalProject, - isInferredProject, - ITypingsInstaller, LargeFileReferencedEvent, - Logger, - LogLevel, - Msg, - NormalizedPath, - Project, ProjectInfoTelemetryEvent, - ProjectKind, ProjectLanguageServiceStateEvent, ProjectLoadingFinishEvent, ProjectLoadingStartEvent, @@ -171,14 +173,36 @@ import { ProjectServiceEventHandler, ProjectServiceOptions, ProjectsUpdatedInBackgroundEvent, - protocol, - ScriptInfo, ScriptInfoOrConfig, - ServerHost, + updateProjectIfDirty, +} from "./editorServices"; +import { + ConfiguredProject, + EmitResult, + isConfiguredProject, + isExternalProject, + isInferredProject, + Project, + ProjectKind, +} from "./project"; +import * as protocol from "./protocol"; +import { ScriptInfo } from "./scriptInfo"; +import { ServerHost } from "./types"; +import { ITypingsInstaller } from "./typingsCache"; +import { + GcTimer, + indent, stringifyIndented, +} from "./utilities"; +import { + emptyArray, + Errors, + Logger, + LogLevel, + Msg, + NormalizedPath, toNormalizedPath, - updateProjectIfDirty, -} from "./_namespaces/ts.server"; +} from "./utilitiesPublic"; interface StackTraceError extends Error { stack?: string; @@ -1632,14 +1656,14 @@ export class Session implements EventSender { } function searchForDeclaration(declarationName: string, fileToSearch: SourceFile, noDtsProgram: Program) { - const matches = FindAllReferences.Core.getTopMostDeclarationNamesInFile(declarationName, fileToSearch); + const matches = FindAllReferences.getTopMostDeclarationNamesInFile(declarationName, fileToSearch); return mapDefined(matches, match => { const symbol = noDtsProgram.getTypeChecker().getSymbolAtLocation(match); const decl = getDeclarationFromName(match); if (symbol && decl) { // I think the last argument to this is supposed to be the start node, but it doesn't seem important. // Callers internal to GoToDefinition already get confused about this. - return GoToDefinition.createDefinitionInfo(decl, noDtsProgram.getTypeChecker(), symbol, decl, /*unverified*/ true); + return createDefinitionInfo(decl, noDtsProgram.getTypeChecker(), symbol, decl, /*unverified*/ true); } }); } @@ -2227,7 +2251,7 @@ export class Session implements EventSender { const firstNoWhiteSpacePosition = absolutePosition + i; edits.push({ span: createTextSpanFromBounds(absolutePosition, firstNoWhiteSpacePosition), - newText: formatting.getIndentationString(preferredIndent, formatOptions) + newText: getIndentationString(preferredIndent, formatOptions) }); } } diff --git a/src/server/types.ts b/src/server/types.ts index 8e1c38f9a42a3..c18316f1f8a36 100644 --- a/src/server/types.ts +++ b/src/server/types.ts @@ -3,8 +3,8 @@ import { FileWatcher, FileWatcherCallback, System, - WatchOptions, -} from "./_namespaces/ts"; +} from "../compiler/sys"; +import { WatchOptions } from "../compiler/types"; export interface CompressedData { length: number; diff --git a/src/server/typingsCache.ts b/src/server/typingsCache.ts index 42c91be6047d1..4d4906a4756fb 100644 --- a/src/server/typingsCache.ts +++ b/src/server/typingsCache.ts @@ -1,22 +1,24 @@ import { - ApplyCodeActionCommandResult, arrayIsEqualTo, - CompilerOptions, - getAllowJSCompilerOption, - InstallPackageOptions, noop, notImplemented, - Path, returnFalse, sort, - SortedReadonlyArray, +} from "../compiler/core"; +import { SortedReadonlyArray } from "../compiler/corePublic"; +import { + CompilerOptions, + Path, TypeAcquisition, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { getAllowJSCompilerOption } from "../compiler/utilities"; import { - emptyArray, - Project, - ProjectService, -} from "./_namespaces/ts.server"; + ApplyCodeActionCommandResult, + InstallPackageOptions, +} from "../services/types"; +import { ProjectService } from "./editorServices"; +import { Project } from "./project"; +import { emptyArray } from "./utilitiesPublic"; export interface InstallPackageOptionsWithProject extends InstallPackageOptions { projectName: string; diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 9c8a45c17159c..401fbd9e89c15 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -1,17 +1,19 @@ import { binarySearch, - Comparer, - getBaseFileName, identity, - perfLogger, +} from "../compiler/core"; +import { + Comparer, SortedArray, -} from "./_namespaces/ts"; +} from "../compiler/corePublic"; +import { getBaseFileName } from "../compiler/path"; +import { perfLogger } from "../compiler/perfLogger"; +import { ServerHost } from "./types"; import { Logger, LogLevel, NormalizedPath, - ServerHost, -} from "./_namespaces/ts.server"; +} from "./utilitiesPublic"; /** @internal */ export class ThrottledOperations { diff --git a/src/server/utilitiesPublic.ts b/src/server/utilitiesPublic.ts index e071e87dfbac2..9f76bb615b5db 100644 --- a/src/server/utilitiesPublic.ts +++ b/src/server/utilitiesPublic.ts @@ -1,16 +1,18 @@ +import { + SortedArray, + SortedReadonlyArray, +} from "../compiler/corePublic"; import { getNormalizedAbsolutePath, isRootedDiskPath, normalizePath, +} from "../compiler/path"; +import { Path, - SortedArray, - SortedReadonlyArray, TypeAcquisition, -} from "./_namespaces/ts"; -import { - DiscoverTypings, - Project, -} from "./_namespaces/ts.server"; +} from "../compiler/types"; +import { DiscoverTypings } from "../jsTyping/types"; +import { Project } from "./project"; export enum LogLevel { terse, diff --git a/src/services/_namespaces/ts.codefix.ts b/src/services/_namespaces/ts.codefix.ts index 23e971449be17..4176ed43b37de 100644 --- a/src/services/_namespaces/ts.codefix.ts +++ b/src/services/_namespaces/ts.codefix.ts @@ -20,6 +20,7 @@ export * from "../codefixes/convertToTypeOnlyImport"; export * from "../codefixes/convertLiteralTypeToMappedType"; export * from "../codefixes/fixClassIncorrectlyImplementsInterface"; export * from "../codefixes/importFixes"; +export * from "../codefixes/importAdder"; export * from "../codefixes/fixAddMissingConstraint"; export * from "../codefixes/fixOverrideModifier"; export * from "../codefixes/fixNoPropertyAccessFromIndexSignature"; diff --git a/src/services/_namespaces/ts.ts b/src/services/_namespaces/ts.ts index eae114fd2e834..484c4fbc1a4d4 100644 --- a/src/services/_namespaces/ts.ts +++ b/src/services/_namespaces/ts.ts @@ -17,6 +17,8 @@ export * from "../transpile"; export * from "../services"; export * from "../transform"; export * from "../shims"; +export * from "./ts.textChanges"; +export * from "./ts.formatting"; import * as BreakpointResolver from "./ts.BreakpointResolver"; export { BreakpointResolver }; import * as CallHierarchy from "./ts.CallHierarchy"; @@ -53,7 +55,3 @@ import * as SmartSelectionRange from "./ts.SmartSelectionRange"; export { SmartSelectionRange }; import * as SymbolDisplay from "./ts.SymbolDisplay"; export { SymbolDisplay }; -import * as textChanges from "./ts.textChanges"; -export { textChanges }; -import * as formatting from "./ts.formatting"; -export { formatting }; diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index f06f85142b862..5e72d7c820e97 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -1,16 +1,29 @@ +import { + getModuleInstanceState, + ModuleInstanceState, +} from "../compiler/binder"; +import { + findLast, + forEach, + lastOrUndefined, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { + isDecorator, + isVariableDeclarationList, +} from "../compiler/factory/nodeTests"; +import { canHaveDecorators } from "../compiler/factory/utilitiesPublic"; +import { skipTrivia } from "../compiler/scanner"; import { ArrayLiteralExpression, BinaryExpression, BindingPattern, Block, BreakOrContinueStatement, - canHaveDecorators, CaseBlock, CaseOrDefaultClause, CatchClause, ClassDeclaration, - createTextSpanFromBounds, - Debug, DestructuringPattern, DoStatement, EnumDeclaration, @@ -18,35 +31,17 @@ import { ExportDeclaration, Expression, ExpressionStatement, - findLast, - findNextToken, - findPrecedingToken, - forEach, ForInStatement, ForOfStatement, ForStatement, FunctionLikeDeclaration, - getModuleInstanceState, - getTokenAtPosition, HasDecorators, - hasOnlyExpressionInitializer, - hasSyntacticModifier, IfStatement, ImportDeclaration, ImportEqualsDeclaration, - isArrayLiteralOrObjectLiteralDestructuringPattern, - isAssignmentOperator, - isBindingPattern, - isDecorator, - isExpressionNode, - isFunctionBlock, - isFunctionLike, - isVariableDeclarationList, LabeledStatement, - lastOrUndefined, ModifierFlags, ModuleDeclaration, - ModuleInstanceState, Node, NodeArray, NodeFlags, @@ -57,7 +52,6 @@ import { PropertyDeclaration, PropertySignature, ReturnStatement, - skipTrivia, SourceFile, SwitchStatement, SyntaxKind, @@ -70,7 +64,25 @@ import { VariableStatement, WhileStatement, WithStatement, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + hasSyntacticModifier, + isAssignmentOperator, + isExpressionNode, + isFunctionBlock, +} from "../compiler/utilities"; +import { + createTextSpanFromBounds, + hasOnlyExpressionInitializer, + isBindingPattern, + isFunctionLike, +} from "../compiler/utilitiesPublic"; +import { + findNextToken, + findPrecedingToken, + getTokenAtPosition, + isArrayLiteralOrObjectLiteralDestructuringPattern, +} from "./utilities"; /** * Get the breakpoint span in given sourceFile diff --git a/src/services/callHierarchy.ts b/src/services/callHierarchy.ts index fc4280802ee6d..f4f1752b68806 100644 --- a/src/services/callHierarchy.ts +++ b/src/services/callHierarchy.ts @@ -1,90 +1,63 @@ +import { getNodeId } from "../compiler/checkerUtilities"; import { - AccessExpression, append, - ArrowFunction, - AsExpression, - CallExpression, - CallHierarchyIncomingCall, - CallHierarchyItem, - CallHierarchyOutgoingCall, - CancellationToken, - canHaveModifiers, - ClassDeclaration, - ClassExpression, - ClassLikeDeclaration, - ClassStaticBlockDeclaration, compareStringsCaseSensitive, - createPrinter, - createTextRangeFromNode, - createTextSpanFromBounds, - createTextSpanFromRange, - Debug, - Decorator, - ElementAccessExpression, - EmitHint, filter, find, - FindAllReferences, - findAncestor, forEach, - forEachChild, - FunctionDeclaration, - FunctionExpression, - FunctionLikeDeclaration, - GetAccessorDeclaration, - getAssignedName, - getClassExtendsHeritageElement, - getCombinedNodeFlags, - getFirstConstructorWithBody, - getNameOfDeclaration, - getNodeId, - getNodeKind, - getNodeModifiers, group, - hasSyntacticModifier, - Identifier, - idText, indicesOf, - isAccessExpression, - isArgumentExpressionOfElementAccess, isArray, + map, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { createPrinter } from "../compiler/emitter"; +import { isArrowFunction, - isCallOrNewExpressionTarget, isClassDeclaration, isClassExpression, - isClassLike, isClassStaticBlockDeclaration, isComputedPropertyName, isConstructorDeclaration, - isDeclarationName, - isDecoratorTarget, isFunctionDeclaration, isFunctionExpression, - isFunctionLikeDeclaration, isGetAccessorDeclaration, isIdentifier, - isJsxOpeningLikeElement, - isJsxOpeningLikeElementTagName, isMethodDeclaration, isMethodSignature, isModuleBlock, isModuleDeclaration, - isNamedDeclaration, - isPartOfTypeNode, isPropertyDeclaration, - isRightSideOfPropertyAccess, isSetAccessorDeclaration, isSourceFile, - isStringOrNumericLiteralLike, isTaggedTemplateExpression, - isTaggedTemplateTag, isVariableDeclaration, +} from "../compiler/factory/nodeTests"; +import { canHaveModifiers } from "../compiler/factory/utilitiesPublic"; +import { forEachChild } from "../compiler/parser"; +import { skipTrivia } from "../compiler/scanner"; +import { + AccessExpression, + ArrowFunction, + AsExpression, + CallExpression, + CancellationToken, + ClassDeclaration, + ClassExpression, + ClassLikeDeclaration, + ClassStaticBlockDeclaration, + Decorator, + ElementAccessExpression, + EmitHint, + FunctionDeclaration, + FunctionExpression, + FunctionLikeDeclaration, + GetAccessorDeclaration, + Identifier, JsxOpeningLikeElement, - map, MethodDeclaration, ModifierFlags, ModuleDeclaration, - moveRangePastModifiers, NewExpression, Node, NodeFlags, @@ -93,7 +66,6 @@ import { PropertyAccessExpression, SatisfiesExpression, SetAccessorDeclaration, - skipTrivia, SourceFile, SymbolFlags, SyntaxKind, @@ -102,9 +74,54 @@ import { TextSpan, TypeAssertion, TypeChecker, - usingSingleLineStringWriter, VariableDeclaration, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + getClassExtendsHeritageElement, + getFirstConstructorWithBody, + hasSyntacticModifier, + isAccessExpression, + isDeclarationName, + isPartOfTypeNode, + isStringOrNumericLiteralLike, + moveRangePastModifiers, + usingSingleLineStringWriter, +} from "../compiler/utilities"; +import { + createTextSpanFromBounds, + findAncestor, + getAssignedName, + getCombinedNodeFlags, + getNameOfDeclaration, + idText, + isClassLike, + isFunctionLikeDeclaration, + isJsxOpeningLikeElement, + isNamedDeclaration, +} from "../compiler/utilitiesPublic"; +import { + findReferenceOrRenameEntries, + FindReferencesUse, +} from "./findAllReferences"; +import { + CallHierarchyIncomingCall, + CallHierarchyItem, + CallHierarchyOutgoingCall, + Entry, + EntryKind, +} from "./types"; +import { + createTextRangeFromNode, + createTextSpanFromRange, + getNodeKind, + getNodeModifiers, + isArgumentExpressionOfElementAccess, + isCallOrNewExpressionTarget, + isDecoratorTarget, + isJsxOpeningLikeElementTagName, + isRightSideOfPropertyAccess, + isTaggedTemplateTag, +} from "./utilities"; /** @internal */ export type NamedExpression = @@ -429,8 +446,8 @@ interface CallSite { range: TextRange; } -function convertEntryToCallSite(entry: FindAllReferences.Entry): CallSite | undefined { - if (entry.kind === FindAllReferences.EntryKind.Node) { +function convertEntryToCallSite(entry: Entry): CallSite | undefined { + if (entry.kind === EntryKind.Node) { const { node } = entry; if (isCallOrNewExpressionTarget(node, /*includeElementAccess*/ true, /*skipPastOuterExpressions*/ true) || isTaggedTemplateTag(node, /*includeElementAccess*/ true, /*skipPastOuterExpressions*/ true) @@ -468,7 +485,7 @@ export function getIncomingCalls(program: Program, declaration: CallHierarchyDec return []; } const location = getCallHierarchyDeclarationReferenceNode(declaration); - const calls = filter(FindAllReferences.findReferenceOrRenameEntries(program, cancellationToken, program.getSourceFiles(), location, /*position*/ 0, { use: FindAllReferences.FindReferencesUse.References }, convertEntryToCallSite), isDefined); + const calls = filter(findReferenceOrRenameEntries(program, cancellationToken, program.getSourceFiles(), location, /*position*/ 0, { use: FindReferencesUse.References }, convertEntryToCallSite), isDefined); return calls ? group(calls, getCallSiteGroupKey, entries => convertCallSiteGroupToIncomingCall(program, entries)) : []; } diff --git a/src/services/classifier.ts b/src/services/classifier.ts index 40a37c99a6297..da8bca6ad3b7e 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -1,41 +1,35 @@ import { - __String, + getModuleInstanceState, + ModuleInstanceState, +} from "../compiler/binder"; +import { arrayToNumericMap, + isLineBreak, + lastOrUndefined, + some, +} from "../compiler/core"; +import { Push } from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { + isIdentifier, + isJSDoc, + isModuleDeclaration, +} from "../compiler/factory/nodeTests"; +import { parseIsolatedJSDocComment } from "../compiler/parser"; +import { + couldStartTrivia, + createScanner, + Scanner, +} from "../compiler/scanner"; +import { + __String, CancellationToken, CharacterCodes, ClassDeclaration, - ClassificationInfo, - ClassificationResult, - Classifications, - ClassificationType, - ClassificationTypeNames, - ClassifiedSpan, - Classifier, commentPragmas, - couldStartTrivia, - createScanner, - createTextSpan, - Debug, - decodedTextSpanIntersectsWith, - EndOfLineState, EnumDeclaration, - getMeaningFromLocation, - getModuleInstanceState, - getTypeArgumentOrTypeParameterList, HasJSDoc, InterfaceDeclaration, - isAccessibilityModifier, - isConstTypeReference, - isIdentifier, - isJSDoc, - isKeyword, - isLineBreak, - isModuleDeclaration, - isPunctuation, - isTemplateLiteralKind, - isThisIdentifier, - isToken, - isTrivia, JSDoc, JSDocAugmentsTag, JSDocCallbackTag, @@ -53,29 +47,51 @@ import { JsxClosingElement, JsxOpeningElement, JsxSelfClosingElement, - lastOrUndefined, ModuleDeclaration, - ModuleInstanceState, Node, - nodeIsMissing, ParameterDeclaration, - parseIsolatedJSDocComment, - Push, - Scanner, ScriptTarget, - SemanticMeaning, - setParent, - some, SourceFile, Symbol, SymbolFlags, SyntaxKind, TextSpan, - textSpanIntersectsWith, - TokenClass, TypeChecker, TypeParameterDeclaration, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + isKeyword, + isThisIdentifier, + isTrivia, + nodeIsMissing, + setParent, +} from "../compiler/utilities"; +import { + createTextSpan, + decodedTextSpanIntersectsWith, + isConstTypeReference, + isTemplateLiteralKind, + isToken, + textSpanIntersectsWith, +} from "../compiler/utilitiesPublic"; +import { + ClassificationInfo, + ClassificationResult, + Classifications, + ClassificationType, + ClassificationTypeNames, + ClassifiedSpan, + Classifier, + EndOfLineState, + TokenClass, +} from "./types"; +import { + getMeaningFromLocation, + getTypeArgumentOrTypeParameterList, + isAccessibilityModifier, + isPunctuation, + SemanticMeaning, +} from "./utilities"; /** The classifier is used for syntactic highlighting in editors via the TSServer */ export function createClassifier(): Classifier { diff --git a/src/services/classifier2020.ts b/src/services/classifier2020.ts index 96e246a85db80..4006fa848e7cb 100644 --- a/src/services/classifier2020.ts +++ b/src/services/classifier2020.ts @@ -1,16 +1,5 @@ +import { Debug } from "../compiler/debug"; import { - BindingElement, - CancellationToken, - Classifications, - ClassifiedSpan2020, - createTextSpan, - Debug, - Declaration, - EndOfLineState, - forEachChild, - getCombinedModifierFlags, - getCombinedNodeFlags, - getMeaningFromLocation, isBindingElement, isCallExpression, isCatchClause, @@ -18,7 +7,6 @@ import { isIdentifier, isImportClause, isImportSpecifier, - isInfinityOrNaNString, isJsxElement, isJsxExpression, isJsxSelfClosingElement, @@ -27,23 +15,43 @@ import { isQualifiedName, isSourceFile, isVariableDeclaration, +} from "../compiler/factory/nodeTests"; +import { forEachChild } from "../compiler/parser"; +import { + BindingElement, + CancellationToken, + Declaration, ModifierFlags, NamedDeclaration, Node, NodeFlags, ParameterDeclaration, Program, - SemanticMeaning, SourceFile, Symbol, SymbolFlags, SyntaxKind, TextSpan, - textSpanIntersectsWith, Type, TypeChecker, VariableDeclaration, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { isInfinityOrNaNString } from "../compiler/utilities"; +import { + createTextSpan, + getCombinedModifierFlags, + getCombinedNodeFlags, + textSpanIntersectsWith, +} from "../compiler/utilitiesPublic"; +import { + Classifications, + ClassifiedSpan2020, + EndOfLineState, +} from "./types"; +import { + getMeaningFromLocation, + SemanticMeaning, +} from "./utilities"; /** @internal */ export const enum TokenEncodingConsts { diff --git a/src/services/codeFixProvider.ts b/src/services/codeFixProvider.ts index 0d6ab81face1a..93bcdf990fac9 100644 --- a/src/services/codeFixProvider.ts +++ b/src/services/codeFixProvider.ts @@ -1,6 +1,21 @@ import { arrayFrom, cast, + contains, + createMultiMap, + flatMap, + isString, + map, +} from "../compiler/core"; +import { Push } from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { + Diagnostic, + DiagnosticWithLocation, +} from "../compiler/types"; +import { computeSuggestionDiagnostics } from "./suggestionDiagnostics"; +import { ChangeTracker } from "./textChanges"; +import { CodeActionCommand, CodeFixAction, CodeFixAllContext, @@ -8,22 +23,13 @@ import { CodeFixContextBase, CodeFixRegistration, CombinedCodeActions, - computeSuggestionDiagnostics, - contains, - createMultiMap, - Debug, - Diagnostic, - DiagnosticAndArguments, - diagnosticToString, - DiagnosticWithLocation, FileTextChanges, - flatMap, - isString, - map, - Push, TextChange, - textChanges, -} from "./_namespaces/ts"; +} from "./types"; +import { + DiagnosticAndArguments, + diagnosticToString, +} from "./utilities"; const errorCodeToFixes = createMultiMap(); const fixIdToRegistration = new Map(); @@ -106,10 +112,10 @@ export function createFileTextChanges(fileName: string, textChanges: TextChange[ export function codeFixAll( context: CodeFixAllContext, errorCodes: number[], - use: (changes: textChanges.ChangeTracker, error: DiagnosticWithLocation, commands: Push) => void, + use: (changes: ChangeTracker, error: DiagnosticWithLocation, commands: Push) => void, ): CombinedCodeActions { const commands: CodeActionCommand[] = []; - const changes = textChanges.ChangeTracker.with(context, t => eachDiagnostic(context, errorCodes, diag => use(t, diag, commands))); + const changes = ChangeTracker.with(context, t => eachDiagnostic(context, errorCodes, diag => use(t, diag, commands))); return createCombinedCodeActions(changes, commands.length === 0 ? undefined : commands); } diff --git a/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts b/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts index 0360e9d117a52..325bf023450a5 100644 --- a/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts +++ b/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts @@ -1,22 +1,24 @@ +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - AsExpression, - Diagnostics, - factory, - findAncestor, - getTokenAtPosition, isAsExpression, - isInJSFile, isTypeAssertionExpression, +} from "../../compiler/factory/nodeTests"; +import { + AsExpression, SourceFile, SyntaxKind, - textChanges, TypeAssertion, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { isInJSFile } from "../../compiler/utilities"; +import { findAncestor } from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "addConvertToUnknownForNonOverlappingTypes"; const errorCodes = [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.code]; @@ -25,7 +27,7 @@ registerCodeFix({ getCodeActions: function getCodeActionsToAddConvertToUnknownForNonOverlappingTypes(context) { const assertion = getAssertion(context.sourceFile, context.span.start); if (assertion === undefined) return undefined; - const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, assertion)); + const changes = ChangeTracker.with(context, t => makeChange(t, context.sourceFile, assertion)); return [createCodeFixAction(fixId, changes, Diagnostics.Add_unknown_conversion_for_non_overlapping_types, fixId, Diagnostics.Add_unknown_to_all_conversions_of_non_overlapping_types)]; }, fixIds: [fixId], @@ -37,7 +39,7 @@ registerCodeFix({ }), }); -function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, assertion: AsExpression | TypeAssertion) { +function makeChange(changeTracker: ChangeTracker, sourceFile: SourceFile, assertion: AsExpression | TypeAssertion) { const replacement = isAsExpression(assertion) ? factory.createAsExpression(assertion.expression, factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword)) : factory.createTypeAssertion(factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword), assertion.expression); diff --git a/src/services/codefixes/addEmptyExportDeclaration.ts b/src/services/codefixes/addEmptyExportDeclaration.ts index 25727bf73a384..304396ecb6fe8 100644 --- a/src/services/codefixes/addEmptyExportDeclaration.ts +++ b/src/services/codefixes/addEmptyExportDeclaration.ts @@ -1,12 +1,10 @@ +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { createCodeFixActionWithoutFixAll, registerCodeFix, -} from "../_namespaces/ts.codefix"; -import { - Diagnostics, - factory, - textChanges, -} from "../_namespaces/ts"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; registerCodeFix({ errorCodes: [ @@ -15,7 +13,7 @@ registerCodeFix({ ], getCodeActions: function getCodeActionsToAddEmptyExportDeclaration(context) { const { sourceFile } = context; - const changes = textChanges.ChangeTracker.with(context, changes => { + const changes = ChangeTracker.with(context, changes => { const exportDeclaration = factory.createExportDeclaration( /*modifiers*/ undefined, /*isTypeOnly*/ false, @@ -26,4 +24,4 @@ registerCodeFix({ }); return [createCodeFixActionWithoutFixAll("addEmptyExportDeclaration", changes, Diagnostics.Add_export_to_make_this_file_into_a_module)]; }, -}); \ No newline at end of file +}); diff --git a/src/services/codefixes/addMissingAsync.ts b/src/services/codefixes/addMissingAsync.ts index bb0510a90d0ad..a02c001a25264 100644 --- a/src/services/codefixes/addMissingAsync.ts +++ b/src/services/codefixes/addMissingAsync.ts @@ -1,41 +1,52 @@ +import { getNodeId } from "../../compiler/checkerUtilities"; import { - ArrowFunction, - CodeFixAllContext, - CodeFixContext, - createTextSpanFromNode, - Diagnostic, - Diagnostics, - factory, - FileTextChanges, find, - findAncestor, - FunctionDeclaration, - FunctionExpression, - getNodeId, - getSyntacticModifierFlags, - getSynthesizedDeepClone, - getTokenAtPosition, + isNumber, + some, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrowFunction, isFunctionDeclaration, isFunctionExpression, isMethodDeclaration, - isNumber, +} from "../../compiler/factory/nodeTests"; +import { + ArrowFunction, + Diagnostic, + FunctionDeclaration, + FunctionExpression, MethodDeclaration, ModifierFlags, - some, SourceFile, - textChanges, TextSpan, +} from "../../compiler/types"; +import { getSyntacticModifierFlags } from "../../compiler/utilities"; +import { + findAncestor, textSpanEnd, - textSpansEqual, -} from "../_namespaces/ts"; +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + CodeFixAllContext, + CodeFixContext, + FileTextChanges, +} from "../types"; +import { + createTextSpanFromNode, + getSynthesizedDeepClone, + getTokenAtPosition, + textSpansEqual, +} from "../utilities"; + +type ContextualTrackChangesFunction = (cb: (changeTracker: ChangeTracker) => void) => FileTextChanges[]; -type ContextualTrackChangesFunction = (cb: (changeTracker: textChanges.ChangeTracker) => void) => FileTextChanges[]; const fixId = "addMissingAsync"; const errorCodes = [ Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1.code, @@ -56,7 +67,7 @@ registerCodeFix({ return; } - const trackChanges: ContextualTrackChangesFunction = cb => textChanges.ChangeTracker.with(context, cb); + const trackChanges: ContextualTrackChangesFunction = cb => ChangeTracker.with(context, cb); return [getFix(context, decl, trackChanges)]; }, getAllCodeActions: context => { @@ -80,7 +91,7 @@ function getFix(context: CodeFixContext | CodeFixAllContext, decl: FixableDeclar return createCodeFixAction(fixId, changes, Diagnostics.Add_async_modifier_to_containing_function, fixId, Diagnostics.Add_all_missing_async_modifiers); } -function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, insertionSite: FixableDeclaration, fixedDeclarations?: Set) { +function makeChange(changeTracker: ChangeTracker, sourceFile: SourceFile, insertionSite: FixableDeclaration, fixedDeclarations?: Set) { if (fixedDeclarations) { if (fixedDeclarations.has(getNodeId(insertionSite))) { return; diff --git a/src/services/codefixes/addMissingAwait.ts b/src/services/codefixes/addMissingAwait.ts index d93138a1dbea8..63f6c4c26c995 100644 --- a/src/services/codefixes/addMissingAwait.ts +++ b/src/services/codefixes/addMissingAwait.ts @@ -1,58 +1,70 @@ +import { getSymbolId } from "../../compiler/checkerUtilities"; import { - CancellationToken, - CodeFixAllContext, - CodeFixContext, compact, contains, - Diagnostic, - Diagnostics, - Expression, - factory, - FileTextChanges, find, - FindAllReferences, - findAncestor, - findPrecedingToken, forEach, - getAncestor, - getFixableErrorSpanExpression, - getSymbolId, - hasSyntacticModifier, - Identifier, + isNumber, + some, + tryAddToSet, + tryCast, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrowFunction, isBinaryExpression, isBlock, - isCallOrNewExpression, isForOfStatement, isIdentifier, - isNumber, isPropertyAccessExpression, isVariableDeclaration, +} from "../../compiler/factory/nodeTests"; +import { + CancellationToken, + Diagnostic, + Expression, + Identifier, ModifierFlags, Node, NodeFlags, - positionIsASICandidate, Program, - some, SourceFile, Symbol, SyntaxKind, - textChanges, TextSpan, - textSpansEqual, - tryAddToSet, - tryCast, TypeChecker, TypeFlags, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + getAncestor, + hasSyntacticModifier, +} from "../../compiler/utilities"; +import { + findAncestor, + isCallOrNewExpression, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, createCodeFixActionWithoutFixAll, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { Core as FindAllReferences } from "../findAllReferences"; +import { ChangeTracker } from "../textChanges"; +import { + CodeFixAllContext, + CodeFixContext, + FileTextChanges, +} from "../types"; +import { + findPrecedingToken, + getFixableErrorSpanExpression, + positionIsASICandidate, + textSpansEqual, +} from "../utilities"; -type ContextualTrackChangesFunction = (cb: (changeTracker: textChanges.ChangeTracker) => void) => FileTextChanges[]; +type ContextualTrackChangesFunction = (cb: (changeTracker: ChangeTracker) => void) => FileTextChanges[]; const fixId = "addMissingAwait"; const propertyAccessCode = Diagnostics.Property_0_does_not_exist_on_type_1.code; const callableConstructableErrorCodes = [ @@ -90,7 +102,7 @@ registerCodeFix({ } const checker = context.program.getTypeChecker(); - const trackChanges: ContextualTrackChangesFunction = cb => textChanges.ChangeTracker.with(context, cb); + const trackChanges: ContextualTrackChangesFunction = cb => ChangeTracker.with(context, cb); return compact([ getDeclarationSiteFix(context, expression, errorCode, checker, trackChanges), getUseSiteFix(context, expression, errorCode, checker, trackChanges)]); @@ -199,7 +211,7 @@ function findAwaitableInitializers( } const diagnostics = program.getSemanticDiagnostics(sourceFile, cancellationToken); - const isUsedElsewhere = FindAllReferences.Core.eachSymbolReferenceInFile(variableName, checker, sourceFile, reference => { + const isUsedElsewhere = FindAllReferences.eachSymbolReferenceInFile(variableName, checker, sourceFile, reference => { return identifier !== reference && !symbolReferenceIsAlsoMissingAwait(reference, diagnostics, sourceFile, checker); }); @@ -277,7 +289,7 @@ function isInsideAwaitableBody(node: Node) { ancestor.parent.kind === SyntaxKind.MethodDeclaration)); } -function makeChange(changeTracker: textChanges.ChangeTracker, errorCode: number, sourceFile: SourceFile, checker: TypeChecker, insertionSite: Expression, fixedDeclarations?: Set) { +function makeChange(changeTracker: ChangeTracker, errorCode: number, sourceFile: SourceFile, checker: TypeChecker, insertionSite: Expression, fixedDeclarations?: Set) { if (isForOfStatement(insertionSite.parent) && !insertionSite.parent.awaitModifier) { const exprType = checker.getTypeAtLocation(insertionSite); const asyncIter = checker.getAsyncIterableType(); @@ -334,7 +346,7 @@ function makeChange(changeTracker: textChanges.ChangeTracker, errorCode: number, } } -function insertLeadingSemicolonIfNeeded(changeTracker: textChanges.ChangeTracker, beforeNode: Node, sourceFile: SourceFile) { +function insertLeadingSemicolonIfNeeded(changeTracker: ChangeTracker, beforeNode: Node, sourceFile: SourceFile) { const precedingToken = findPrecedingToken(beforeNode.pos, sourceFile); if (precedingToken && positionIsASICandidate(precedingToken.end, precedingToken.parent, sourceFile)) { changeTracker.insertText(sourceFile, beforeNode.getStart(sourceFile), ";"); diff --git a/src/services/codefixes/addMissingConst.ts b/src/services/codefixes/addMissingConst.ts index 8a848c2616f80..a5b1e0a436d38 100644 --- a/src/services/codefixes/addMissingConst.ts +++ b/src/services/codefixes/addMissingConst.ts @@ -1,28 +1,34 @@ import { - Diagnostics, every, - Expression, - findAncestor, - getTokenAtPosition, + tryAddToSet, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { isArrayLiteralExpression, - isAssignmentExpression, isBinaryExpression, isExpressionStatement, - isForInOrOfStatement, isIdentifier, +} from "../../compiler/factory/nodeTests"; +import { + Expression, Node, Program, SourceFile, SyntaxKind, - textChanges, - tryAddToSet, TypeChecker, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { isAssignmentExpression } from "../../compiler/utilities"; +import { + findAncestor, + isForInOrOfStatement, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "addMissingConst"; const errorCodes = [ @@ -33,7 +39,7 @@ const errorCodes = [ registerCodeFix({ errorCodes, getCodeActions: function getCodeActionsToAddMissingConst(context) { - const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span.start, context.program)); + const changes = ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span.start, context.program)); if (changes.length > 0) { return [createCodeFixAction(fixId, changes, Diagnostics.Add_const_to_unresolved_variable, fixId, Diagnostics.Add_const_to_all_unresolved_variables)]; } @@ -45,7 +51,7 @@ registerCodeFix({ }, }); -function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, program: Program, fixedNodes?: Set) { +function makeChange(changeTracker: ChangeTracker, sourceFile: SourceFile, pos: number, program: Program, fixedNodes?: Set) { const token = getTokenAtPosition(sourceFile, pos); const forInitializer = findAncestor(token, node => isForInOrOfStatement(node.parent) ? node.parent.initializer === node : @@ -81,7 +87,7 @@ function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: Source } } -function applyChange(changeTracker: textChanges.ChangeTracker, initializer: Node, sourceFile: SourceFile, fixedNodes?: Set) { +function applyChange(changeTracker: ChangeTracker, initializer: Node, sourceFile: SourceFile, fixedNodes?: Set) { if (!fixedNodes || tryAddToSet(fixedNodes, initializer)) { changeTracker.insertModifierBefore(sourceFile, SyntaxKind.ConstKeyword, initializer); } diff --git a/src/services/codefixes/addMissingDeclareProperty.ts b/src/services/codefixes/addMissingDeclareProperty.ts index c46c353b37f3e..fa2e768f800f2 100644 --- a/src/services/codefixes/addMissingDeclareProperty.ts +++ b/src/services/codefixes/addMissingDeclareProperty.ts @@ -1,18 +1,18 @@ +import { tryAddToSet } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { isIdentifier } from "../../compiler/factory/nodeTests"; import { - Diagnostics, - getTokenAtPosition, - isIdentifier, Node, SourceFile, SyntaxKind, - textChanges, - tryAddToSet, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "addMissingDeclareProperty"; const errorCodes = [ @@ -22,7 +22,7 @@ const errorCodes = [ registerCodeFix({ errorCodes, getCodeActions: function getCodeActionsToAddMissingDeclareOnProperty(context) { - const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span.start)); + const changes = ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span.start)); if (changes.length > 0) { return [createCodeFixAction(fixId, changes, Diagnostics.Prefix_with_declare, fixId, Diagnostics.Prefix_all_incorrect_property_declarations_with_declare)]; } @@ -34,7 +34,7 @@ registerCodeFix({ }, }); -function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, fixedNodes?: Set) { +function makeChange(changeTracker: ChangeTracker, sourceFile: SourceFile, pos: number, fixedNodes?: Set) { const token = getTokenAtPosition(sourceFile, pos); if (!isIdentifier(token)) { return; diff --git a/src/services/codefixes/addMissingInvocationForDecorator.ts b/src/services/codefixes/addMissingInvocationForDecorator.ts index 330757c9fa76f..4055032bba736 100644 --- a/src/services/codefixes/addMissingInvocationForDecorator.ts +++ b/src/services/codefixes/addMissingInvocationForDecorator.ts @@ -1,32 +1,30 @@ -import { - Debug, - Diagnostics, - factory, - findAncestor, - getTokenAtPosition, - isDecorator, - SourceFile, - textChanges, -} from "../_namespaces/ts"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isDecorator } from "../../compiler/factory/nodeTests"; +import { SourceFile } from "../../compiler/types"; +import { findAncestor } from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "addMissingInvocationForDecorator"; const errorCodes = [Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0.code]; registerCodeFix({ errorCodes, getCodeActions: function getCodeActionsToAddMissingInvocationForDecorator(context) { - const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span.start)); + const changes = ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span.start)); return [createCodeFixAction(fixId, changes, Diagnostics.Call_decorator_expression, fixId, Diagnostics.Add_to_all_uncalled_decorators)]; }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file, diag.start)), }); -function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) { +function makeChange(changeTracker: ChangeTracker, sourceFile: SourceFile, pos: number) { const token = getTokenAtPosition(sourceFile, pos); const decorator = findAncestor(token, isDecorator)!; Debug.assert(!!decorator, "Expected position to be owned by a decorator."); diff --git a/src/services/codefixes/addNameToNamelessParameter.ts b/src/services/codefixes/addNameToNamelessParameter.ts index dc36931d79237..9f194345433e8 100644 --- a/src/services/codefixes/addNameToNamelessParameter.ts +++ b/src/services/codefixes/addNameToNamelessParameter.ts @@ -1,32 +1,32 @@ +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isParameter } from "../../compiler/factory/nodeTests"; import { - Debug, - Diagnostics, - factory, - getTokenAtPosition, Identifier, - isParameter, SourceFile, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "addNameToNamelessParameter"; const errorCodes = [Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1.code]; registerCodeFix({ errorCodes, getCodeActions: function getCodeActionsToAddNameToNamelessParameter(context) { - const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span.start)); + const changes = ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span.start)); return [createCodeFixAction(fixId, changes, Diagnostics.Add_parameter_name, fixId, Diagnostics.Add_names_to_all_parameters_without_names)]; }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file, diag.start)), }); -function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) { +function makeChange(changeTracker: ChangeTracker, sourceFile: SourceFile, pos: number) { const token = getTokenAtPosition(sourceFile, pos); const param = token.parent; if (!isParameter(param)) { diff --git a/src/services/codefixes/addOptionalPropertyUndefined.ts b/src/services/codefixes/addOptionalPropertyUndefined.ts index 7664bea35be10..c48087eb426ea 100644 --- a/src/services/codefixes/addOptionalPropertyUndefined.ts +++ b/src/services/codefixes/addOptionalPropertyUndefined.ts @@ -1,14 +1,9 @@ +import { emptyArray } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - Diagnostics, - emptyArray, - factory, - getFixableErrorSpanExpression, - getSourceFileOfNode, - Identifier, isBinaryExpression, isCallExpression, - isExpression, - isFunctionLikeKind, isIdentifier, isPropertyAccessExpression, isPropertyAssignment, @@ -16,21 +11,30 @@ import { isPropertySignature, isShorthandPropertyAssignment, isVariableDeclaration, +} from "../../compiler/factory/nodeTests"; +import { + Identifier, Node, PropertyAccessExpression, SignatureDeclaration, SourceFile, Symbol, SyntaxKind, - textChanges, TextSpan, TypeChecker, UnionTypeNode, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { getSourceFileOfNode } from "../../compiler/utilities"; +import { + isExpression, + isFunctionLikeKind, +} from "../../compiler/utilitiesPublic"; import { createCodeFixActionWithoutFixAll, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getFixableErrorSpanExpression } from "../utilities"; const addOptionalPropertyUndefined = "addOptionalPropertyUndefined"; @@ -48,7 +52,7 @@ registerCodeFix({ if (!toAdd.length) { return undefined; } - const changes = textChanges.ChangeTracker.with(context, t => addUndefinedToOptionalProperty(t, toAdd)); + const changes = ChangeTracker.with(context, t => addUndefinedToOptionalProperty(t, toAdd)); return [createCodeFixActionWithoutFixAll(addOptionalPropertyUndefined, changes, Diagnostics.Add_undefined_to_optional_property_type)]; }, fixIds: [addOptionalPropertyUndefined], @@ -113,7 +117,7 @@ function getSourceTarget(errorNode: Node | undefined, checker: TypeChecker): { s return undefined; } -function addUndefinedToOptionalProperty(changes: textChanges.ChangeTracker, toAdd: Symbol[]) { +function addUndefinedToOptionalProperty(changes: ChangeTracker, toAdd: Symbol[]) { for (const add of toAdd) { const d = add.valueDeclaration; if (d && (isPropertySignature(d) || isPropertyDeclaration(d)) && d.type) { diff --git a/src/services/codefixes/annotateWithTypeFromJSDoc.ts b/src/services/codefixes/annotateWithTypeFromJSDoc.ts index 292c609bc720c..241ef58d99dd0 100644 --- a/src/services/codefixes/annotateWithTypeFromJSDoc.ts +++ b/src/services/codefixes/annotateWithTypeFromJSDoc.ts @@ -1,52 +1,61 @@ import { - Debug, - Diagnostics, - EmitFlags, emptyArray, - factory, - findChildOfKind, first, - FunctionLikeDeclaration, - getJSDocReturnType, - getJSDocType, - getJSDocTypeParameterDeclarations, - getTokenAtPosition, + last, + map, + tryCast, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { setEmitFlags } from "../../compiler/factory/emitNode"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrowFunction, - isFunctionLikeDeclaration, isIdentifier, - isJSDocIndexSignature, - isOptionalJSDocPropertyLikeTag, isParameter, +} from "../../compiler/factory/nodeTests"; +import { nullTransformationContext } from "../../compiler/transformer"; +import { + EmitFlags, JSDocFunctionType, JSDocNonNullableType, JSDocNullableType, JSDocOptionalType, JSDocTypeLiteral, JSDocVariadicType, - last, - map, - Node, - nullTransformationContext, ParameterDeclaration, - PropertyDeclaration, - PropertySignature, - setEmitFlags, SourceFile, SyntaxKind, - textChanges, - tryCast, TypeNode, TypeReferenceNode, - VariableDeclaration, +} from "../../compiler/types"; +import { + getJSDocTypeParameterDeclarations, + isJSDocIndexSignature, + isOptionalJSDocPropertyLikeTag, +} from "../../compiler/utilities"; +import { + getJSDocReturnType, + getJSDocType, + isFunctionLikeDeclaration, +} from "../../compiler/utilitiesPublic"; +import { visitEachChild, visitNode, visitNodes, -} from "../_namespaces/ts"; +} from "../../compiler/visitorPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + DeclarationWithType, + findChildOfKind, + getTokenAtPosition, + parameterShouldGetTypeFromJSDoc, +} from "../utilities"; const fixId = "annotateWithTypeFromJSDoc"; const errorCodes = [Diagnostics.JSDoc_types_may_be_moved_to_TypeScript_types.code]; @@ -55,7 +64,7 @@ registerCodeFix({ getCodeActions(context) { const decl = getDeclaration(context.sourceFile, context.span.start); if (!decl) return; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, decl)); + const changes = ChangeTracker.with(context, t => doChange(t, context.sourceFile, decl)); return [createCodeFixAction(fixId, changes, Diagnostics.Annotate_with_type_from_JSDoc, fixId, Diagnostics.Annotate_everything_with_types_from_JSDoc)]; }, fixIds: [fixId], @@ -71,25 +80,7 @@ function getDeclaration(file: SourceFile, pos: number): DeclarationWithType | un return tryCast(isParameter(name.parent) ? name.parent.parent : name.parent, parameterShouldGetTypeFromJSDoc); } -/** @internal */ -export type DeclarationWithType = - | FunctionLikeDeclaration - | VariableDeclaration - | PropertySignature - | PropertyDeclaration; - -/** @internal */ -export function parameterShouldGetTypeFromJSDoc(node: Node): node is DeclarationWithType { - return isDeclarationWithType(node) && hasUsableJSDoc(node); -} - -function hasUsableJSDoc(decl: DeclarationWithType | ParameterDeclaration): boolean { - return isFunctionLikeDeclaration(decl) - ? decl.parameters.some(hasUsableJSDoc) || (!decl.type && !!getJSDocReturnType(decl)) - : !decl.type && !!getJSDocType(decl); -} - -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, decl: DeclarationWithType): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, decl: DeclarationWithType): void { if (isFunctionLikeDeclaration(decl) && (getJSDocReturnType(decl) || decl.parameters.some(p => !!getJSDocType(p)))) { if (!decl.typeParameters) { const typeParameters = getJSDocTypeParameterDeclarations(decl); @@ -116,13 +107,6 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, de } } -function isDeclarationWithType(node: Node): node is DeclarationWithType { - return isFunctionLikeDeclaration(node) || - node.kind === SyntaxKind.VariableDeclaration || - node.kind === SyntaxKind.PropertySignature || - node.kind === SyntaxKind.PropertyDeclaration; -} - function transformJSDocType(node: TypeNode): TypeNode { switch (node.kind) { case SyntaxKind.JSDocAllType: diff --git a/src/services/codefixes/convertConstToLet.ts b/src/services/codefixes/convertConstToLet.ts index d9817ab8250b2..88c855a96529a 100644 --- a/src/services/codefixes/convertConstToLet.ts +++ b/src/services/codefixes/convertConstToLet.ts @@ -1,25 +1,27 @@ +import { getSymbolId } from "../../compiler/checkerUtilities"; +import { tryCast } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isVariableDeclarationList } from "../../compiler/factory/nodeTests"; import { - addToSeen, - Diagnostics, - factory, - findChildOfKind, - getSymbolId, - getTokenAtPosition, - isVariableDeclarationList, Program, SourceFile, Symbol, SyntaxKind, - textChanges, Token, - tryCast, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { addToSeen } from "../../compiler/utilities"; import { createCodeFixActionMaybeFixAll, createCombinedCodeActions, eachDiagnostic, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + findChildOfKind, + getTokenAtPosition, +} from "../utilities"; const fixId = "fixConvertConstToLet"; const errorCodes = [Diagnostics.Cannot_assign_to_0_because_it_is_a_constant.code]; @@ -31,14 +33,14 @@ registerCodeFix({ const info = getInfo(sourceFile, span.start, program); if (info === undefined) return; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, info.token)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, info.token)); return [createCodeFixActionMaybeFixAll(fixId, changes, Diagnostics.Convert_const_to_let, fixId, Diagnostics.Convert_all_const_to_let)]; }, getAllCodeActions: context => { const { program } = context; const seen = new Map(); - return createCombinedCodeActions(textChanges.ChangeTracker.with(context, changes => { + return createCombinedCodeActions(ChangeTracker.with(context, changes => { eachDiagnostic(context, errorCodes, diag => { const info = getInfo(diag.file, diag.start, program); if (info) { @@ -72,6 +74,6 @@ function getInfo(sourceFile: SourceFile, pos: number, program: Program): Info | return { symbol, token: constToken }; } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Token) { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, token: Token) { changes.replaceNode(sourceFile, token, factory.createToken(SyntaxKind.LetKeyword)); } diff --git a/src/services/codefixes/convertFunctionToEs6Class.ts b/src/services/codefixes/convertFunctionToEs6Class.ts index b2af8a230febc..f2902fdd7e775 100644 --- a/src/services/codefixes/convertFunctionToEs6Class.ts +++ b/src/services/codefixes/convertFunctionToEs6Class.ts @@ -1,78 +1,88 @@ import { - __String, - AccessExpression, - ArrowFunction, - BinaryExpression, - Block, - canHaveModifiers, - ClassDeclaration, - ClassElement, - CodeFixContext, - CompilerOptions, concatenate, - copyLeadingComments, - Diagnostics, every, - Expression, - factory, filter, forEach, - FunctionDeclaration, - FunctionExpression, - getEmitScriptTarget, - getNameOfDeclaration, - getQuotePreference, - getTokenAtPosition, - idText, - isAccessExpression, + some, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrowFunction, isBinaryExpression, isFunctionDeclaration, isFunctionExpression, - isFunctionLike, - isGetOrSetAccessorDeclaration, isIdentifier, - isIdentifierText, isMethodDeclaration, isNoSubstitutionTemplateLiteral, isNumericLiteral, isObjectLiteralExpression, isPropertyAccessExpression, isPropertyAssignment, - isSourceFileJS, - isStringLiteralLike, isVariableDeclaration, isVariableDeclarationList, +} from "../../compiler/factory/nodeTests"; +import { canHaveModifiers } from "../../compiler/factory/utilitiesPublic"; +import { isIdentifierText } from "../../compiler/scanner"; +import { + __String, + AccessExpression, + ArrowFunction, + BinaryExpression, + Block, + ClassDeclaration, + ClassElement, + CompilerOptions, + Expression, + FunctionDeclaration, + FunctionExpression, Modifier, Node, ObjectLiteralElementLike, ObjectLiteralExpression, PropertyAccessExpression, PropertyName, - QuotePreference, - some, SourceFile, Symbol, SymbolFlags, - symbolName, SyntaxKind, - textChanges, TypeChecker, UserPreferences, VariableDeclaration, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + getEmitScriptTarget, + isAccessExpression, + isSourceFileJS, +} from "../../compiler/utilities"; +import { + getNameOfDeclaration, + idText, + isFunctionLike, + isGetOrSetAccessorDeclaration, + isStringLiteralLike, + symbolName, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { CodeFixContext } from "../types"; +import { + copyLeadingComments, + getQuotePreference, + getTokenAtPosition, + QuotePreference, +} from "../utilities"; const fixId = "convertFunctionToEs6Class"; const errorCodes = [Diagnostics.This_constructor_function_may_be_converted_to_a_class_declaration.code]; registerCodeFix({ errorCodes, getCodeActions(context: CodeFixContext) { - const changes = textChanges.ChangeTracker.with(context, t => + const changes = ChangeTracker.with(context, t => doChange(t, context.sourceFile, context.span.start, context.program.getTypeChecker(), context.preferences, context.program.getCompilerOptions())); return [createCodeFixAction(fixId, changes, Diagnostics.Convert_function_to_an_ES2015_class, fixId, Diagnostics.Convert_all_constructor_functions_to_classes)]; }, @@ -81,7 +91,7 @@ registerCodeFix({ doChange(changes, err.file, err.start, context.program.getTypeChecker(), context.preferences, context.program.getCompilerOptions())), }); -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker, preferences: UserPreferences, compilerOptions: CompilerOptions): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker, preferences: UserPreferences, compilerOptions: CompilerOptions): void { const ctorSymbol = checker.getSymbolAtLocation(getTokenAtPosition(sourceFile, position))!; if (!ctorSymbol || !ctorSymbol.valueDeclaration || !(ctorSymbol.flags & (SymbolFlags.Function | SymbolFlags.Variable))) { // Bad input diff --git a/src/services/codefixes/convertLiteralTypeToMappedType.ts b/src/services/codefixes/convertLiteralTypeToMappedType.ts index 1e68d28758d1c..c2c54f57c8f0a 100644 --- a/src/services/codefixes/convertLiteralTypeToMappedType.ts +++ b/src/services/codefixes/convertLiteralTypeToMappedType.ts @@ -1,21 +1,23 @@ +import { cast } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - cast, - Diagnostics, - factory, - getTokenAtPosition, isIdentifier, isPropertySignature, isTypeLiteralNode, +} from "../../compiler/factory/nodeTests"; +import { SourceFile, - textChanges, TypeLiteralNode, TypeNode, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "convertLiteralTypeToMappedType"; const errorCodes = [Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Did_you_mean_to_use_1_in_0.code]; @@ -29,7 +31,7 @@ registerCodeFix({ return undefined; } const { name, constraint } = info; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, info)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, info)); return [createCodeFixAction(fixId, changes, [Diagnostics.Convert_0_to_1_in_0, constraint, name], fixId, Diagnostics.Convert_all_type_literals_to_mapped_type)]; }, fixIds: [fixId], @@ -63,7 +65,7 @@ function getInfo(sourceFile: SourceFile, pos: number): Info | undefined { return undefined; } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { container, typeNode, constraint, name }: Info): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, { container, typeNode, constraint, name }: Info): void { changes.replaceNode(sourceFile, container, factory.createMappedTypeNode( /*readonlyToken*/ undefined, factory.createTypeParameterDeclaration(/*modifiers*/ undefined, name, factory.createTypeReferenceNode(constraint)), diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 999dab6f413e5..cb12efec59fcc 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -1,87 +1,101 @@ import { - ArrowFunction, - AwaitExpression, - BindingName, - BindingPattern, - Block, - CallExpression, - canBeConvertedToAsync, - CodeFixContext, + getNodeId, + getSymbolId, +} from "../../compiler/checkerUtilities"; +import { concatenate, createMultiMap, - Debug, - Diagnostics, elementAt, emptyArray, every, - Expression, - factory, firstOrUndefined, flatMap, forEach, - forEachChild, - forEachReturnStatement, - FunctionExpression, - FunctionLikeDeclaration, - GeneratedIdentifierFlags, - getContainingFunction, - getNodeId, - getObjectFlags, - getOriginalNode, - getSymbolId, - getSynthesizedDeepClone, - getSynthesizedDeepCloneWithReplacements, - getTokenAtPosition, - hasPropertyAccessExpressionWithName, - Identifier, - idText, + lastOrUndefined, + returnTrue, + tryCast, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isBindingElement, isBlock, isCallExpression, - isExpression, - isFixablePromiseHandler, - isFunctionLike, - isFunctionLikeDeclaration, - isGeneratedIdentifier, isIdentifier, - isInJSFile, isObjectBindingPattern, isOmittedExpression, isParameter, isPropertyAccessExpression, isReturnStatement, - isReturnStatementWithFixablePromiseHandler, isVariableDeclaration, - lastOrUndefined, - moveRangePastModifiers, +} from "../../compiler/factory/nodeTests"; +import { forEachChild } from "../../compiler/parser"; +import { skipTrivia } from "../../compiler/scanner"; +import { + ArrowFunction, + AwaitExpression, + BindingName, + BindingPattern, + Block, + CallExpression, + Expression, + FunctionExpression, + FunctionLikeDeclaration, + GeneratedIdentifierFlags, + Identifier, Node, NodeFlags, ObjectFlags, PropertyAccessExpression, - returnsPromise, ReturnStatement, - returnTrue, Signature, SignatureKind, - skipTrivia, SourceFile, Statement, Symbol, SyntaxKind, - textChanges, - tryCast, TryStatement, Type, TypeChecker, TypeNode, TypeReference, UnionReduction, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + forEachReturnStatement, + getContainingFunction, + getObjectFlags, + isInJSFile, + moveRangePastModifiers, +} from "../../compiler/utilities"; +import { + getOriginalNode, + idText, + isExpression, + isFunctionLike, + isFunctionLikeDeclaration, + isGeneratedIdentifier, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { + canBeConvertedToAsync, + isFixablePromiseHandler, + isReturnStatementWithFixablePromiseHandler, + returnsPromise, +} from "../suggestionDiagnostics"; +import { ChangeTracker } from "../textChanges"; +import { CodeFixContext } from "../types"; +import { + getSynthesizedDeepClone, + getSynthesizedDeepCloneWithReplacements, + getTokenAtPosition, + hasPropertyAccessExpressionWithName, +} from "../utilities"; const fixId = "convertToAsyncFunction"; const errorCodes = [Diagnostics.This_may_be_converted_to_an_async_function.code]; @@ -90,7 +104,7 @@ registerCodeFix({ errorCodes, getCodeActions(context: CodeFixContext) { codeActionSucceeded = true; - const changes = textChanges.ChangeTracker.with(context, (t) => convertToAsyncFunction(t, context.sourceFile, context.span.start, context.program.getTypeChecker())); + const changes = ChangeTracker.with(context, (t) => convertToAsyncFunction(t, context.sourceFile, context.span.start, context.program.getTypeChecker())); return codeActionSucceeded ? [createCodeFixAction(fixId, changes, Diagnostics.Convert_to_async_function, fixId, Diagnostics.Convert_all_to_async_functions)] : []; }, fixIds: [fixId], @@ -133,7 +147,7 @@ interface PromiseReturningCallExpression extends CallExpres }; } -function convertToAsyncFunction(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker): void { +function convertToAsyncFunction(changes: ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker): void { // get the function declaration - returns a promise const tokenAtPosition = getTokenAtPosition(sourceFile, position); let functionToConvert: FunctionLikeDeclaration | undefined; diff --git a/src/services/codefixes/convertToEsModule.ts b/src/services/codefixes/convertToEsModule.ts index 959b9ea4538ad..cc011257b596f 100644 --- a/src/services/codefixes/convertToEsModule.ts +++ b/src/services/codefixes/convertToEsModule.ts @@ -1,64 +1,51 @@ +import { isExportsOrModuleExportsOrAlias } from "../../compiler/binder"; import { - createCodeFixActionWithoutFixAll, - moduleSpecifierToValidIdentifier, - registerCodeFix, -} from "../_namespaces/ts.codefix"; + arrayFrom, + concatenate, + createMultiMap, + emptyMap, + filter, + flatMap, + forEach, + isArray, + map, + mapAllOrFail, + mapIterator, + some, +} from "../../compiler/core"; +import { ReadonlyCollection } from "../../compiler/corePublic"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { + isArrowFunction, + isBinaryExpression, + isClassExpression, + isFunctionExpression, + isIdentifier, + isObjectLiteralExpression, + isPropertyAccessExpression, + isVariableStatement, +} from "../../compiler/factory/nodeTests"; +import { getModeForUsageLocation } from "../../compiler/program"; import { __String, - arrayFrom, ArrowFunction, BinaryExpression, BindingElement, BindingName, ClassDeclaration, ClassExpression, - concatenate, - copyEntries, - createMultiMap, - createRange, - Debug, - Diagnostics, - emptyMap, ExportDeclaration, ExportSpecifier, Expression, ExpressionStatement, - factory, - filter, - findChildOfKind, - flatMap, - forEach, FunctionDeclaration, FunctionExpression, - getEmitScriptTarget, - getModeForUsageLocation, - getQuotePreference, - getResolvedModule, - getSynthesizedDeepClone, - getSynthesizedDeepClones, - getSynthesizedDeepClonesWithReplacements, - getSynthesizedDeepCloneWithReplacements, Identifier, ImportDeclaration, - importFromModuleSpecifier, ImportSpecifier, InternalSymbolName, - isArray, - isArrowFunction, - isBinaryExpression, - isClassExpression, - isExportsOrModuleExportsOrAlias, - isFunctionExpression, - isIdentifier, - isNonContextualKeyword, - isObjectLiteralExpression, - isPropertyAccessExpression, - isRequireCall, - isVariableStatement, - makeImport, - map, - mapAllOrFail, - mapIterator, MethodDeclaration, Modifier, Node, @@ -67,26 +54,47 @@ import { ObjectLiteralElementLike, ObjectLiteralExpression, PropertyAccessExpression, - QuotePreference, - rangeContainsRange, - ReadonlyCollection, ScriptTarget, - some, SourceFile, Statement, StringLiteralLike, SymbolFlags, SyntaxKind, - textChanges, TypeChecker, VariableStatement, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + copyEntries, + createRange, + getEmitScriptTarget, + getResolvedModule, + importFromModuleSpecifier, + isNonContextualKeyword, + isRequireCall, +} from "../../compiler/utilities"; +import { + createCodeFixActionWithoutFixAll, + registerCodeFix, +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + findChildOfKind, + getQuotePreference, + getSynthesizedDeepClone, + getSynthesizedDeepClones, + getSynthesizedDeepClonesWithReplacements, + getSynthesizedDeepCloneWithReplacements, + makeImport, + QuotePreference, + rangeContainsRange, +} from "../utilities"; +import { moduleSpecifierToValidIdentifier } from "./importAdder"; registerCodeFix({ errorCodes: [Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES_module.code], getCodeActions(context) { const { sourceFile, program, preferences } = context; - const changes = textChanges.ChangeTracker.with(context, changes => { + const changes = ChangeTracker.with(context, changes => { const moduleExportsChangedToDefault = convertFileToEsModule(sourceFile, program.getTypeChecker(), changes, getEmitScriptTarget(program.getCompilerOptions()), getQuotePreference(sourceFile, preferences)); if (moduleExportsChangedToDefault) { for (const importingFile of program.getSourceFiles()) { @@ -99,7 +107,7 @@ registerCodeFix({ }, }); -function fixImportOfModuleExports(importingFile: SourceFile, exportingFile: SourceFile, changes: textChanges.ChangeTracker, quotePreference: QuotePreference) { +function fixImportOfModuleExports(importingFile: SourceFile, exportingFile: SourceFile, changes: ChangeTracker, quotePreference: QuotePreference) { for (const moduleSpecifier of importingFile.imports) { const imported = getResolvedModule(importingFile, moduleSpecifier.text, getModeForUsageLocation(importingFile, moduleSpecifier)); if (!imported || imported.resolvedFileName !== exportingFile.fileName) { @@ -121,7 +129,7 @@ function fixImportOfModuleExports(importingFile: SourceFile, exportingFile: Sour } /** @returns Whether we converted a `module.exports =` to a default export. */ -function convertFileToEsModule(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, target: ScriptTarget, quotePreference: QuotePreference): ModuleExportsChanged { +function convertFileToEsModule(sourceFile: SourceFile, checker: TypeChecker, changes: ChangeTracker, target: ScriptTarget, quotePreference: QuotePreference): ModuleExportsChanged { const identifiers: Identifiers = { original: collectFreeIdentifiers(sourceFile), additional: new Set() }; const exports = collectExportRenames(sourceFile, checker, identifiers); convertExportsAccesses(sourceFile, exports, changes); @@ -171,7 +179,7 @@ function collectExportRenames(sourceFile: SourceFile, checker: TypeChecker, iden return res; } -function convertExportsAccesses(sourceFile: SourceFile, exports: ExportRenames, changes: textChanges.ChangeTracker): void { +function convertExportsAccesses(sourceFile: SourceFile, exports: ExportRenames, changes: ChangeTracker): void { forEachExportReference(sourceFile, (node, isAssignmentLhs) => { if (isAssignmentLhs) { return; @@ -198,7 +206,7 @@ function convertStatement( sourceFile: SourceFile, statement: Statement, checker: TypeChecker, - changes: textChanges.ChangeTracker, + changes: ChangeTracker, identifiers: Identifiers, target: ScriptTarget, exports: ExportRenames, @@ -234,7 +242,7 @@ function convertStatement( function convertVariableStatement( sourceFile: SourceFile, statement: VariableStatement, - changes: textChanges.ChangeTracker, + changes: ChangeTracker, checker: TypeChecker, identifiers: Identifiers, target: ScriptTarget, @@ -300,7 +308,7 @@ function convertAssignment( sourceFile: SourceFile, checker: TypeChecker, assignment: BinaryExpression, - changes: textChanges.ChangeTracker, + changes: ChangeTracker, exports: ExportRenames, useSitesToUnqualify: Map | undefined, ): ModuleExportsChanged { @@ -363,7 +371,7 @@ function tryChangeModuleExportsObject(object: ObjectLiteralExpression, useSitesT function convertNamedExport( sourceFile: SourceFile, assignment: BinaryExpression & { left: PropertyAccessExpression }, - changes: textChanges.ChangeTracker, + changes: ChangeTracker, exports: ExportRenames, ): void { // If "originalKeywordKind" was set, this is e.g. `exports. @@ -402,7 +410,7 @@ function reExportDefault(moduleSpecifier: string): ExportDeclaration { return makeExportDeclaration([factory.createExportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, "default")], moduleSpecifier); } -function convertExportsPropertyAssignment({ left, right, parent }: BinaryExpression & { left: PropertyAccessExpression }, sourceFile: SourceFile, changes: textChanges.ChangeTracker): void { +function convertExportsPropertyAssignment({ left, right, parent }: BinaryExpression & { left: PropertyAccessExpression }, sourceFile: SourceFile, changes: ChangeTracker): void { const name = left.name.text; if ((isFunctionExpression(right) || isArrowFunction(right) || isClassExpression(right)) && (!right.name || right.name.text === name)) { // `exports.f = function() {}` -> `export function f() {}` -- Replace `exports.f = ` with `export `, and insert the name after `function`. diff --git a/src/services/codefixes/convertToMappedObjectType.ts b/src/services/codefixes/convertToMappedObjectType.ts index 1a3b8498a49f5..978fcf4a67751 100644 --- a/src/services/codefixes/convertToMappedObjectType.ts +++ b/src/services/codefixes/convertToMappedObjectType.ts @@ -1,32 +1,38 @@ import { cast, - Diagnostics, emptyArray, - factory, first, - getAllSuperTypeNodes, - getTokenAtPosition, - hasEffectiveReadonlyModifier, - idText, - IndexSignatureDeclaration, - InterfaceDeclaration, + tryCast, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isIdentifier, isIndexSignatureDeclaration, isInterfaceDeclaration, isTypeAliasDeclaration, +} from "../../compiler/factory/nodeTests"; +import { + IndexSignatureDeclaration, + InterfaceDeclaration, SourceFile, SyntaxKind, - textChanges, - tryCast, TypeAliasDeclaration, TypeLiteralNode, TypeNode, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + getAllSuperTypeNodes, + hasEffectiveReadonlyModifier, +} from "../../compiler/utilities"; +import { idText } from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "fixConvertToMappedObjectType"; const errorCodes = [Diagnostics.An_index_signature_parameter_type_cannot_be_a_literal_type_or_generic_type_Consider_using_a_mapped_object_type_instead.code]; @@ -39,7 +45,7 @@ registerCodeFix({ const { sourceFile, span } = context; const info = getInfo(sourceFile, span.start); if (!info) return undefined; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, info)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, info)); const name = idText(info.container.name); return [createCodeFixAction(fixId, changes, [Diagnostics.Convert_0_to_mapped_object_type, name], fixId, [Diagnostics.Convert_0_to_mapped_object_type, name])]; }, @@ -66,7 +72,7 @@ function createTypeAliasFromInterface(declaration: FixableDeclaration, type: Typ return factory.createTypeAliasDeclaration(declaration.modifiers, declaration.name, declaration.typeParameters, type); } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { indexSignature, container }: Info): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, { indexSignature, container }: Info): void { const members = isInterfaceDeclaration(container) ? container.members : (container.type as TypeLiteralNode).members; const otherMembers = members.filter(member => !isIndexSignatureDeclaration(member)); const parameter = first(indexSignature.parameters); diff --git a/src/services/codefixes/convertToTypeOnlyExport.ts b/src/services/codefixes/convertToTypeOnlyExport.ts index f6dfc027596d2..3c34f40563ad1 100644 --- a/src/services/codefixes/convertToTypeOnlyExport.ts +++ b/src/services/codefixes/convertToTypeOnlyExport.ts @@ -1,35 +1,43 @@ +import { getNodeId } from "../../compiler/checkerUtilities"; import { - addToSeen, - CodeFixContextBase, contains, - createTextSpanFromNode, - Diagnostics, - ExportSpecifier, - factory, filter, - findDiagnosticForNode, - getDiagnosticsWithinSpan, - getNodeId, - getTokenAtPosition, - isExportSpecifier, + tryCast, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isExportSpecifier } from "../../compiler/factory/nodeTests"; +import { + ExportSpecifier, SourceFile, SyntaxKind, - textChanges, TextSpan, - tryCast, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { addToSeen } from "../../compiler/utilities"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { + ChangeTracker, + LeadingTriviaOption, + TrailingTriviaOption, +} from "../textChanges"; +import { CodeFixContextBase } from "../types"; +import { + createTextSpanFromNode, + findDiagnosticForNode, + getDiagnosticsWithinSpan, + getTokenAtPosition, +} from "../utilities"; const errorCodes = [Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type.code]; const fixId = "convertToTypeOnlyExport"; registerCodeFix({ errorCodes, getCodeActions: function getCodeActionsToConvertToTypeOnlyExport(context) { - const changes = textChanges.ChangeTracker.with(context, t => fixSingleExportDeclaration(t, getExportSpecifierForDiagnosticSpan(context.span, context.sourceFile), context)); + const changes = ChangeTracker.with(context, t => fixSingleExportDeclaration(t, getExportSpecifierForDiagnosticSpan(context.span, context.sourceFile), context)); if (changes.length) { return [createCodeFixAction(fixId, changes, Diagnostics.Convert_to_type_only_export, fixId, Diagnostics.Convert_all_re_exported_types_to_type_only_exports)]; } @@ -50,7 +58,7 @@ function getExportSpecifierForDiagnosticSpan(span: TextSpan, sourceFile: SourceF return tryCast(getTokenAtPosition(sourceFile, span.start).parent, isExportSpecifier); } -function fixSingleExportDeclaration(changes: textChanges.ChangeTracker, exportSpecifier: ExportSpecifier | undefined, context: CodeFixContextBase) { +function fixSingleExportDeclaration(changes: ChangeTracker, exportSpecifier: ExportSpecifier | undefined, context: CodeFixContextBase) { if (!exportSpecifier) { return; } @@ -79,8 +87,8 @@ function fixSingleExportDeclaration(changes: textChanges.ChangeTracker, exportSp ); changes.replaceNode(context.sourceFile, exportDeclaration, valueExportDeclaration, { - leadingTriviaOption: textChanges.LeadingTriviaOption.IncludeAll, - trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude + leadingTriviaOption: LeadingTriviaOption.IncludeAll, + trailingTriviaOption: TrailingTriviaOption.Exclude, }); changes.insertNodeAfter(context.sourceFile, exportDeclaration, typeExportDeclaration); } diff --git a/src/services/codefixes/convertToTypeOnlyImport.ts b/src/services/codefixes/convertToTypeOnlyImport.ts index b4f5bda36cafa..71c69ae09345e 100644 --- a/src/services/codefixes/convertToTypeOnlyImport.ts +++ b/src/services/codefixes/convertToTypeOnlyImport.ts @@ -1,27 +1,27 @@ +import { tryCast } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isImportDeclaration } from "../../compiler/factory/nodeTests"; import { - CodeFixContextBase, - Diagnostics, - factory, - getTokenAtPosition, ImportDeclaration, - isImportDeclaration, SourceFile, - textChanges, TextSpan, - tryCast, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { CodeFixContextBase } from "../types"; +import { getTokenAtPosition } from "../utilities"; const errorCodes = [Diagnostics.This_import_is_never_used_as_a_value_and_must_use_import_type_because_importsNotUsedAsValues_is_set_to_error.code]; const fixId = "convertToTypeOnlyImport"; registerCodeFix({ errorCodes, getCodeActions: function getCodeActionsToConvertToTypeOnlyImport(context) { - const changes = textChanges.ChangeTracker.with(context, t => { + const changes = ChangeTracker.with(context, t => { const importDeclaration = getImportDeclarationForDiagnosticSpan(context.span, context.sourceFile); fixSingleImportDeclaration(t, importDeclaration, context); }); @@ -42,7 +42,7 @@ function getImportDeclarationForDiagnosticSpan(span: TextSpan, sourceFile: Sourc return tryCast(getTokenAtPosition(sourceFile, span.start).parent, isImportDeclaration); } -function fixSingleImportDeclaration(changes: textChanges.ChangeTracker, importDeclaration: ImportDeclaration | undefined, context: CodeFixContextBase) { +function fixSingleImportDeclaration(changes: ChangeTracker, importDeclaration: ImportDeclaration | undefined, context: CodeFixContextBase) { if (!importDeclaration?.importClause) { return; } diff --git a/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts b/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts index 466a8a9bcd719..0c57d3c4bb8fa 100644 --- a/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts +++ b/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts @@ -1,21 +1,23 @@ +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - Debug, - Diagnostics, - factory, - findAncestor, - getTokenAtPosition, - Identifier, isIdentifier, isQualifiedName, +} from "../../compiler/factory/nodeTests"; +import { + Identifier, QualifiedName, SourceFile, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { findAncestor } from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "correctQualifiedNameToIndexedAccessType"; const errorCodes = [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.code]; @@ -24,7 +26,7 @@ registerCodeFix({ getCodeActions(context) { const qualifiedName = getQualifiedName(context.sourceFile, context.span.start); if (!qualifiedName) return undefined; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, qualifiedName)); + const changes = ChangeTracker.with(context, t => doChange(t, context.sourceFile, qualifiedName)); const newText = `${qualifiedName.left.text}["${qualifiedName.right.text}"]`; return [createCodeFixAction(fixId, changes, [Diagnostics.Rewrite_as_the_indexed_access_type_0, newText], fixId, Diagnostics.Rewrite_all_as_indexed_access_types)]; }, @@ -43,7 +45,7 @@ function getQualifiedName(sourceFile: SourceFile, pos: number): QualifiedName & return isIdentifier(qualifiedName.left) ? qualifiedName as QualifiedName & { left: Identifier } : undefined; } -function doChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, qualifiedName: QualifiedName): void { +function doChange(changeTracker: ChangeTracker, sourceFile: SourceFile, qualifiedName: QualifiedName): void { const rightText = qualifiedName.right.text; const replacement = factory.createIndexedAccessTypeNode( factory.createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined), diff --git a/src/services/codefixes/disableJsDiagnostics.ts b/src/services/codefixes/disableJsDiagnostics.ts index 96202931ae090..f189fb4b31480 100644 --- a/src/services/codefixes/disableJsDiagnostics.ts +++ b/src/services/codefixes/disableJsDiagnostics.ts @@ -1,26 +1,37 @@ import { - CodeFixAction, - createTextChange, - createTextSpan, - createTextSpanFromBounds, + mapDefined, + tryAddToSet, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { getLineAndCharacterOfPosition } from "../../compiler/scanner"; +import { DiagnosticCategory, - Diagnostics, - getLineAndCharacterOfPosition, - getNewLineOrDefaultFromHost, + SourceFile, +} from "../../compiler/types"; +import { isCheckJsEnabledForFile, isInJSFile, - mapDefined, - SourceFile, - textChanges, - tryAddToSet, -} from "../_namespaces/ts"; +} from "../../compiler/utilities"; +import { + createTextSpan, + createTextSpanFromBounds, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, createCodeFixActionWithoutFixAll, createFileTextChanges, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { + ChangeTracker, + isValidLocationToAddComment, +} from "../textChanges"; +import { CodeFixAction } from "../types"; +import { + createTextChange, + getNewLineOrDefaultFromHost, +} from "../utilities"; const fixName = "disableJsDiagnostics"; const fixId = "disableJsDiagnostics"; @@ -51,8 +62,8 @@ registerCodeFix({ Diagnostics.Disable_checking_for_this_file), ]; - if (textChanges.isValidLocationToAddComment(sourceFile, span.start)) { - fixes.unshift(createCodeFixAction(fixName, textChanges.ChangeTracker.with(context, t => makeChange(t, sourceFile, span.start)), Diagnostics.Ignore_this_error_message, fixId, Diagnostics.Add_ts_ignore_to_all_error_messages)); + if (isValidLocationToAddComment(sourceFile, span.start)) { + fixes.unshift(createCodeFixAction(fixName, ChangeTracker.with(context, t => makeChange(t, sourceFile, span.start)), Diagnostics.Ignore_this_error_message, fixId, Diagnostics.Add_ts_ignore_to_all_error_messages)); } return fixes; @@ -61,14 +72,14 @@ registerCodeFix({ getAllCodeActions: context => { const seenLines = new Set(); return codeFixAll(context, errorCodes, (changes, diag) => { - if (textChanges.isValidLocationToAddComment(diag.file, diag.start)) { + if (isValidLocationToAddComment(diag.file, diag.start)) { makeChange(changes, diag.file, diag.start, seenLines); } }); }, }); -function makeChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, seenLines?: Set) { +function makeChange(changes: ChangeTracker, sourceFile: SourceFile, position: number, seenLines?: Set) { const { line: lineNumber } = getLineAndCharacterOfPosition(sourceFile, position); // Only need to add `// @ts-ignore` for a line once. if (!seenLines || tryAddToSet(seenLines, lineNumber)) { diff --git a/src/services/codefixes/fixAddMissingConstraint.ts b/src/services/codefixes/fixAddMissingConstraint.ts index c5b2bd3573789..64f75f6eb9d4e 100644 --- a/src/services/codefixes/fixAddMissingConstraint.ts +++ b/src/services/codefixes/fixAddMissingConstraint.ts @@ -1,41 +1,51 @@ +import { getNodeId } from "../../compiler/checkerUtilities"; import { - addToSeen, - createTextSpan, - DiagnosticMessageChain, - Diagnostics, - factory, find, - flattenDiagnosticMessageText, - getEmitScriptTarget, - getNodeId, - getTokenAtPosition, - isExpression, + isString, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isIdentifier, isMappedTypeNode, - isString, - isTypeNode, isTypeParameterDeclaration, - LanguageServiceHost, +} from "../../compiler/factory/nodeTests"; +import { flattenDiagnosticMessageText } from "../../compiler/program"; +import { + DiagnosticMessageChain, Node, Program, SourceFile, - textChanges, TextSpan, Type, TypeChecker, TypeParameterDeclaration, UserPreferences, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + addToSeen, + getEmitScriptTarget, +} from "../../compiler/utilities"; +import { + createTextSpan, + isExpression, + isTypeNode, +} from "../../compiler/utilitiesPublic"; import { createCodeFixAction, createCombinedCodeActions, - createImportAdder, eachDiagnostic, + registerCodeFix, +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { LanguageServiceHost } from "../types"; +import { getTokenAtPosition } from "../utilities"; +import { findAncestorMatchingSpan, getNoopSymbolTrackerWithResolver, - registerCodeFix, typeToAutoImportableTypeNode, -} from "../_namespaces/ts.codefix"; +} from "./helpers"; +import { createImportAdder } from "./importAdder"; const fixId = "addMissingConstraint"; const errorCodes = [ @@ -57,7 +67,7 @@ registerCodeFix({ const info = getInfo(program, sourceFile, span); if (info === undefined) return; - const changes = textChanges.ChangeTracker.with(context, t => addMissingConstraint(t, program, preferences, host, sourceFile, info)); + const changes = ChangeTracker.with(context, t => addMissingConstraint(t, program, preferences, host, sourceFile, info)); return [createCodeFixAction(fixId, changes, Diagnostics.Add_extends_constraint, fixId, Diagnostics.Add_extends_constraint_to_all_type_parameters)]; }, fixIds: [fixId], @@ -65,7 +75,7 @@ registerCodeFix({ const { program, preferences, host } = context; const seen = new Map(); - return createCombinedCodeActions(textChanges.ChangeTracker.with(context, changes => { + return createCombinedCodeActions(ChangeTracker.with(context, changes => { eachDiagnostic(context, errorCodes, diag => { const info = getInfo(program, diag.file, createTextSpan(diag.start, diag.length)); if (info) { @@ -112,7 +122,7 @@ function getInfo(program: Program, sourceFile: SourceFile, span: TextSpan): Info return undefined; } -function addMissingConstraint(changes: textChanges.ChangeTracker, program: Program, preferences: UserPreferences, host: LanguageServiceHost, sourceFile: SourceFile, info: Info): void { +function addMissingConstraint(changes: ChangeTracker, program: Program, preferences: UserPreferences, host: LanguageServiceHost, sourceFile: SourceFile, info: Info): void { const { declaration, constraint } = info; const checker = program.getTypeChecker(); @@ -122,7 +132,7 @@ function addMissingConstraint(changes: textChanges.ChangeTracker, program: Progr else { const scriptTarget = getEmitScriptTarget(program.getCompilerOptions()); const tracker = getNoopSymbolTrackerWithResolver({ program, host }); - const importAdder = createImportAdder(sourceFile, program, preferences, host); + const importAdder = createImportAdder(sourceFile, program, preferences, host, /*useAutoImportProvider*/ false); const typeNode = typeToAutoImportableTypeNode(checker, importAdder, constraint, /*contextNode*/ undefined, scriptTarget, /*flags*/ undefined, tracker); if (typeNode) { changes.replaceNode(sourceFile, declaration, factory.updateTypeParameterDeclaration(declaration, /*modifiers*/ undefined, declaration.name, typeNode, declaration.default)); diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 490d65171be2f..ef049333de3b9 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -1,59 +1,36 @@ +import { getNodeId } from "../../compiler/checkerUtilities"; import { - __String, - addToSeen, arrayFrom, - BigIntLiteralType, - BinaryExpression, - CallExpression, - CheckFlags, - ClassLikeDeclaration, - CodeFixAction, - CodeFixContext, - CodeFixContextBase, concatenate, - createPropertyNameNodeForIdentifierOrLiteral, - Debug, - Diagnostics, emptyArray, - EnumDeclaration, - Expression, - factory, filter, find, - findAncestor, findIndex, firstDefined, firstOrUndefined, - FunctionExpression, - getCheckFlags, - getClassLikeDeclarationOfSymbol, - getEmitScriptTarget, - getFirstConstructorWithBody, - getNodeId, - getObjectFlags, getOrUpdate, - getQuotePreference, - getSourceFileOfNode, - getTokenAtPosition, - hasAbstractModifier, - hasInitializer, - Identifier, - idText, - InterfaceDeclaration, + length, + map, + or, + singleElementArray, + singleOrUndefined, + some, + tryCast, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isCallExpression, - isClassLike, isComputedPropertyName, isConstructorDeclaration, isEnumDeclaration, isFunctionTypeNode, isIdentifier, - isIdentifierText, isInterfaceDeclaration, isJsxAttribute, isJsxExpression, - isJsxOpeningLikeElement, isJsxSpreadAttribute, - isMemberName, isMethodDeclaration, isMethodSignature, isModuleDeclaration, @@ -64,14 +41,23 @@ import { isPropertyDeclaration, isReturnStatement, isSourceFile, - isSourceFileFromLibrary, - isSourceFileJS, - isTransientSymbol, isTypeLiteralNode, +} from "../../compiler/factory/nodeTests"; +import { isIdentifierText } from "../../compiler/scanner"; +import { + __String, + BigIntLiteralType, + BinaryExpression, + CallExpression, + CheckFlags, + ClassLikeDeclaration, + EnumDeclaration, + Expression, + FunctionExpression, + Identifier, + InterfaceDeclaration, JsxOpeningLikeElement, LanguageVariant, - length, - map, MethodDeclaration, ModifierFlags, ModuleDeclaration, @@ -80,28 +66,18 @@ import { NumberLiteralType, ObjectFlags, ObjectLiteralExpression, - or, PrivateIdentifier, Program, PropertyDeclaration, - QuotePreference, ReturnStatement, ScriptTarget, - setParent, Signature, SignatureKind, - singleElementArray, - singleOrUndefined, - skipConstraint, - some, SourceFile, - startsWithUnderscore, StringLiteralType, Symbol, SymbolFlags, SyntaxKind, - textChanges, - tryCast, Type, TypeChecker, TypeFlags, @@ -109,20 +85,64 @@ import { TypeNode, TypeReference, UnionType, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + addToSeen, + createPropertyNameNodeForIdentifierOrLiteral, + getCheckFlags, + getClassLikeDeclarationOfSymbol, + getEmitScriptTarget, + getFirstConstructorWithBody, + getObjectFlags, + getSourceFileOfNode, + hasAbstractModifier, + isSourceFileJS, + isTransientSymbol, + setParent, +} from "../../compiler/utilities"; +import { + findAncestor, + hasInitializer, + idText, + isClassLike, + isJsxOpeningLikeElement, + isMemberName, +} from "../../compiler/utilitiesPublic"; import { createCodeFixAction, createCodeFixActionWithoutFixAll, createCombinedCodeActions, - createImportAdder, + eachDiagnostic, + registerCodeFix, +} from "../codeFixProvider"; +import { + ChangeTracker, + LeadingTriviaOption, + TrailingTriviaOption, +} from "../textChanges"; +import { + CodeFixAction, + CodeFixContext, + CodeFixContextBase, +} from "../types"; +import { + getQuotePreference, + getTokenAtPosition, + isSourceFileFromLibrary, + QuotePreference, + skipConstraint, + startsWithUnderscore, +} from "../utilities"; +import { getAllSupers } from "./generateAccessors"; +import { createSignatureDeclarationFromCallExpression, createSignatureDeclarationFromSignature, createStubbedBody, - eachDiagnostic, - getAllSupers, +} from "./helpers"; +import { + createImportAdder, ImportAdder, - registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "./importAdder"; const fixMissingMember = "fixMissingMember"; const fixMissingProperties = "fixMissingProperties"; @@ -157,19 +177,19 @@ registerCodeFix({ return undefined; } if (info.kind === InfoKind.ObjectLiteral) { - const changes = textChanges.ChangeTracker.with(context, t => addObjectLiteralProperties(t, context, info)); + const changes = ChangeTracker.with(context, t => addObjectLiteralProperties(t, context, info)); return [createCodeFixAction(fixMissingProperties, changes, Diagnostics.Add_missing_properties, fixMissingProperties, Diagnostics.Add_all_missing_properties)]; } if (info.kind === InfoKind.JsxAttributes) { - const changes = textChanges.ChangeTracker.with(context, t => addJsxAttributes(t, context, info)); + const changes = ChangeTracker.with(context, t => addJsxAttributes(t, context, info)); return [createCodeFixAction(fixMissingAttributes, changes, Diagnostics.Add_missing_attributes, fixMissingAttributes, Diagnostics.Add_all_missing_attributes)]; } if (info.kind === InfoKind.Function || info.kind === InfoKind.Signature) { - const changes = textChanges.ChangeTracker.with(context, t => addFunctionDeclaration(t, context, info)); + const changes = ChangeTracker.with(context, t => addFunctionDeclaration(t, context, info)); return [createCodeFixAction(fixMissingFunctionDeclaration, changes, [Diagnostics.Add_missing_function_declaration_0, info.token.text], fixMissingFunctionDeclaration, Diagnostics.Add_all_missing_function_declarations)]; } if (info.kind === InfoKind.Enum) { - const changes = textChanges.ChangeTracker.with(context, t => addEnumMemberDeclaration(t, context.program.getTypeChecker(), info)); + const changes = ChangeTracker.with(context, t => addEnumMemberDeclaration(t, context.program.getTypeChecker(), info)); return [createCodeFixAction(fixMissingMember, changes, [Diagnostics.Add_missing_enum_member_0, info.token.text], fixMissingMember, Diagnostics.Add_all_missing_members)]; } return concatenate(getActionsForMissingMethodDeclaration(context, info), getActionsForMissingMemberDeclaration(context, info)); @@ -181,7 +201,7 @@ registerCodeFix({ const seen = new Map(); const typeDeclToMembers = new Map(); - return createCombinedCodeActions(textChanges.ChangeTracker.with(context, changes => { + return createCombinedCodeActions(ChangeTracker.with(context, changes => { eachDiagnostic(context, errorCodes, diag => { const info = getInfo(diag.file, diag.start, diag.code, checker, context.program); if (!info || !addToSeen(seen, getNodeId(info.parentDeclaration) + "#" + info.token.text)) { @@ -398,7 +418,7 @@ function createActionForAddMissingMemberInJavascriptFile(context: CodeFixContext return undefined; } - const changes = textChanges.ChangeTracker.with(context, t => addMissingMemberInJs(t, declSourceFile, parentDeclaration, token, !!(modifierFlags & ModifierFlags.Static))); + const changes = ChangeTracker.with(context, t => addMissingMemberInJs(t, declSourceFile, parentDeclaration, token, !!(modifierFlags & ModifierFlags.Static))); if (changes.length === 0) { return undefined; } @@ -409,7 +429,7 @@ function createActionForAddMissingMemberInJavascriptFile(context: CodeFixContext return createCodeFixAction(fixMissingMember, changes, [diagnostic, token.text], fixMissingMember, Diagnostics.Add_all_missing_members); } -function addMissingMemberInJs(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, token: Identifier | PrivateIdentifier, makeStatic: boolean): void { +function addMissingMemberInJs(changeTracker: ChangeTracker, sourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, token: Identifier | PrivateIdentifier, makeStatic: boolean): void { const tokenName = token.text; if (makeStatic) { if (classDeclaration.kind === SyntaxKind.ClassExpression) { @@ -453,7 +473,7 @@ function createActionsForAddMissingMemberInTypeScriptFile(context: CodeFixContex const memberName = token.text; const isStatic = modifierFlags & ModifierFlags.Static; const typeNode = getTypeNode(context.program.getTypeChecker(), parentDeclaration, token); - const addPropertyDeclarationChanges = (modifierFlags: ModifierFlags) => textChanges.ChangeTracker.with(context, t => addPropertyDeclaration(t, declSourceFile, parentDeclaration, memberName, typeNode, modifierFlags)); + const addPropertyDeclarationChanges = (modifierFlags: ModifierFlags) => ChangeTracker.with(context, t => addPropertyDeclaration(t, declSourceFile, parentDeclaration, memberName, typeNode, modifierFlags)); const actions = [createCodeFixAction(fixMissingMember, addPropertyDeclarationChanges(modifierFlags & ModifierFlags.Static), [isStatic ? Diagnostics.Declare_static_property_0 : Diagnostics.Declare_property_0, memberName], fixMissingMember, Diagnostics.Add_all_missing_members)]; if (isStatic || isPrivateIdentifier(token)) { @@ -483,7 +503,7 @@ function getTypeNode(checker: TypeChecker, node: ClassLikeDeclaration | Interfac return typeNode || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } -function addPropertyDeclaration(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, node: ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode, tokenName: string, typeNode: TypeNode, modifierFlags: ModifierFlags): void { +function addPropertyDeclaration(changeTracker: ChangeTracker, sourceFile: SourceFile, node: ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode, tokenName: string, typeNode: TypeNode, modifierFlags: ModifierFlags): void { const modifiers = modifierFlags ? factory.createNodeArray(factory.createModifiersFromModifierFlags(modifierFlags)) : undefined; const property = isClassLike(node) @@ -524,7 +544,7 @@ function createAddIndexSignatureAction(context: CodeFixContext, sourceFile: Sour [indexingParameter], typeNode); - const changes = textChanges.ChangeTracker.with(context, t => t.insertMemberAtStart(sourceFile, node, indexSignature)); + const changes = ChangeTracker.with(context, t => t.insertMemberAtStart(sourceFile, node, indexSignature)); // No fixId here because code-fix-all currently only works on adding individual named properties. return createCodeFixActionWithoutFixAll(fixMissingMember, changes, [Diagnostics.Add_index_signature_for_property_0, tokenName]); } @@ -541,7 +561,7 @@ function getActionsForMissingMethodDeclaration(context: CodeFixContext, info: Ty } const methodName = token.text; - const addMethodDeclarationChanges = (modifierFlags: ModifierFlags) => textChanges.ChangeTracker.with(context, t => addMethodDeclaration(context, t, call, token, modifierFlags, parentDeclaration, declSourceFile)); + const addMethodDeclarationChanges = (modifierFlags: ModifierFlags) => ChangeTracker.with(context, t => addMethodDeclaration(context, t, call, token, modifierFlags, parentDeclaration, declSourceFile)); const actions = [createCodeFixAction(fixMissingMember, addMethodDeclarationChanges(modifierFlags & ModifierFlags.Static), [modifierFlags & ModifierFlags.Static ? Diagnostics.Declare_static_method_0 : Diagnostics.Declare_method_0, methodName], fixMissingMember, Diagnostics.Add_all_missing_members)]; if (modifierFlags & ModifierFlags.Private) { actions.unshift(createCodeFixActionWithoutFixAll(fixMissingMember, addMethodDeclarationChanges(ModifierFlags.Private), [Diagnostics.Declare_private_method_0, methodName])); @@ -551,14 +571,14 @@ function getActionsForMissingMethodDeclaration(context: CodeFixContext, info: Ty function addMethodDeclaration( context: CodeFixContextBase, - changes: textChanges.ChangeTracker, + changes: ChangeTracker, callExpression: CallExpression, name: Identifier, modifierFlags: ModifierFlags, parentDeclaration: ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode, sourceFile: SourceFile, ): void { - const importAdder = createImportAdder(sourceFile, context.program, context.preferences, context.host); + const importAdder = createImportAdder(sourceFile, context.program, context.preferences, context.host, /*useAutoImportProvider*/ false); const kind = isClassLike(parentDeclaration) ? SyntaxKind.MethodDeclaration : SyntaxKind.MethodSignature; const signatureDeclaration = createSignatureDeclarationFromCallExpression(kind, context, importAdder, callExpression, name, modifierFlags, parentDeclaration) as MethodDeclaration; const containingMethodDeclaration = tryGetContainingMethodDeclaration(parentDeclaration, callExpression); @@ -571,7 +591,7 @@ function addMethodDeclaration( importAdder.writeFixes(changes); } -function addEnumMemberDeclaration(changes: textChanges.ChangeTracker, checker: TypeChecker, { token, parentDeclaration }: EnumInfo) { +function addEnumMemberDeclaration(changes: ChangeTracker, checker: TypeChecker, { token, parentDeclaration }: EnumInfo) { /** * create initializer only literal enum that has string initializer. * value of initializer is a string literal that equal to name of enum member. @@ -589,14 +609,14 @@ function addEnumMemberDeclaration(changes: textChanges.ChangeTracker, checker: T parentDeclaration.name, concatenate(parentDeclaration.members, singleElementArray(enumMember)) ), { - leadingTriviaOption: textChanges.LeadingTriviaOption.IncludeAll, - trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude + leadingTriviaOption: LeadingTriviaOption.IncludeAll, + trailingTriviaOption: TrailingTriviaOption.Exclude, }); } -function addFunctionDeclaration(changes: textChanges.ChangeTracker, context: CodeFixContextBase, info: FunctionInfo | SignatureInfo) { +function addFunctionDeclaration(changes: ChangeTracker, context: CodeFixContextBase, info: FunctionInfo | SignatureInfo) { const quotePreference = getQuotePreference(context.sourceFile, context.preferences); - const importAdder = createImportAdder(context.sourceFile, context.program, context.preferences, context.host); + const importAdder = createImportAdder(context.sourceFile, context.program, context.preferences, context.host, /*useAutoImportProvider*/ false); const functionDeclaration = info.kind === InfoKind.Function ? createSignatureDeclarationFromCallExpression(SyntaxKind.FunctionDeclaration, context, importAdder, info.call, idText(info.token), info.modifierFlags, info.parentDeclaration) : createSignatureDeclarationFromSignature(SyntaxKind.FunctionDeclaration, context, quotePreference, info.signature, createStubbedBody(Diagnostics.Function_not_implemented.message, quotePreference), info.token, /*modifiers*/ undefined, /*optional*/ undefined, /*enclosingDeclaration*/ undefined, importAdder); @@ -610,8 +630,8 @@ function addFunctionDeclaration(changes: textChanges.ChangeTracker, context: Cod importAdder.writeFixes(changes); } -function addJsxAttributes(changes: textChanges.ChangeTracker, context: CodeFixContextBase, info: JsxAttributesInfo) { - const importAdder = createImportAdder(context.sourceFile, context.program, context.preferences, context.host); +function addJsxAttributes(changes: ChangeTracker, context: CodeFixContextBase, info: JsxAttributesInfo) { + const importAdder = createImportAdder(context.sourceFile, context.program, context.preferences, context.host, /*useAutoImportProvider*/ false); const quotePreference = getQuotePreference(context.sourceFile, context.preferences); const checker = context.program.getTypeChecker(); const jsxAttributesNode = info.parentDeclaration.attributes; @@ -630,8 +650,8 @@ function addJsxAttributes(changes: textChanges.ChangeTracker, context: CodeFixCo importAdder.writeFixes(changes); } -function addObjectLiteralProperties(changes: textChanges.ChangeTracker, context: CodeFixContextBase, info: ObjectLiteralInfo) { - const importAdder = createImportAdder(context.sourceFile, context.program, context.preferences, context.host); +function addObjectLiteralProperties(changes: ChangeTracker, context: CodeFixContextBase, info: ObjectLiteralInfo) { + const importAdder = createImportAdder(context.sourceFile, context.program, context.preferences, context.host, /*useAutoImportProvider*/ false); const quotePreference = getQuotePreference(context.sourceFile, context.preferences); const target = getEmitScriptTarget(context.program.getCompilerOptions()); const checker = context.program.getTypeChecker(); @@ -640,8 +660,8 @@ function addObjectLiteralProperties(changes: textChanges.ChangeTracker, context: return factory.createPropertyAssignment(createPropertyNameFromSymbol(prop, target, quotePreference, checker), initializer); }); const options = { - leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, - trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude, + leadingTriviaOption: LeadingTriviaOption.Exclude, + trailingTriviaOption: TrailingTriviaOption.Exclude, indentation: info.indentation }; changes.replaceNode(context.sourceFile, info.parentDeclaration, factory.createObjectLiteralExpression([...info.parentDeclaration.properties, ...props], /*multiLine*/ true), options); diff --git a/src/services/codefixes/fixAddMissingNewOperator.ts b/src/services/codefixes/fixAddMissingNewOperator.ts index 32b17b39233d8..61f13488f23db 100644 --- a/src/services/codefixes/fixAddMissingNewOperator.ts +++ b/src/services/codefixes/fixAddMissingNewOperator.ts @@ -1,20 +1,20 @@ +import { cast } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isCallExpression } from "../../compiler/factory/nodeTests"; import { - cast, - Diagnostics, - factory, - getTokenAtPosition, - isCallExpression, Node, SourceFile, - textChanges, TextSpan, - textSpanEnd, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { textSpanEnd } from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "addMissingNewOperator"; const errorCodes = [Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new.code]; @@ -22,7 +22,7 @@ registerCodeFix({ errorCodes, getCodeActions(context) { const { sourceFile, span } = context; - const changes = textChanges.ChangeTracker.with(context, t => addMissingNewOperator(t, sourceFile, span)); + const changes = ChangeTracker.with(context, t => addMissingNewOperator(t, sourceFile, span)); return [createCodeFixAction(fixId, changes, Diagnostics.Add_missing_new_operator_to_call, fixId, Diagnostics.Add_missing_new_operator_to_all_calls)]; }, fixIds: [fixId], @@ -30,7 +30,7 @@ registerCodeFix({ addMissingNewOperator(changes, context.sourceFile, diag)), }); -function addMissingNewOperator(changes: textChanges.ChangeTracker, sourceFile: SourceFile, span: TextSpan): void { +function addMissingNewOperator(changes: ChangeTracker, sourceFile: SourceFile, span: TextSpan): void { const call = cast(findAncestorMatchingSpan(sourceFile, span), isCallExpression); const newExpression = factory.createNewExpression(call.expression, call.typeArguments, call.arguments); diff --git a/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts b/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts index 1fa7b06bedef0..f41d825a31cc8 100644 --- a/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts +++ b/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts @@ -1,18 +1,18 @@ +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - Debug, - Diagnostics, - factory, - getTokenAtPosition, ImportTypeNode, SourceFile, SyntaxKind, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixIdAddMissingTypeof = "fixAddModuleReferTypeMissingTypeof"; const fixId = fixIdAddMissingTypeof; @@ -23,7 +23,7 @@ registerCodeFix({ getCodeActions: function getCodeActionsToAddMissingTypeof(context) { const { sourceFile, span } = context; const importType = getImportTypeNode(sourceFile, span.start); - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, importType)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, importType)); return [createCodeFixAction(fixId, changes, Diagnostics.Add_missing_typeof, fixId, Diagnostics.Add_missing_typeof)]; }, fixIds: [fixId], @@ -38,7 +38,7 @@ function getImportTypeNode(sourceFile: SourceFile, pos: number): ImportTypeNode return token.parent as ImportTypeNode; } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, importType: ImportTypeNode) { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, importType: ImportTypeNode) { const newTypeNode = factory.updateImportTypeNode(importType, importType.argument, importType.assertions, importType.qualifier, importType.typeArguments, /* isTypeOf */ true); changes.replaceNode(sourceFile, importType, newTypeNode); } diff --git a/src/services/codefixes/fixAddVoidToPromise.ts b/src/services/codefixes/fixAddVoidToPromise.ts index 4abb3cdedda2d..424a2bfac4bd8 100644 --- a/src/services/codefixes/fixAddVoidToPromise.ts +++ b/src/services/codefixes/fixAddVoidToPromise.ts @@ -1,35 +1,39 @@ +import { some } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - CodeFixAllContext, - Diagnostics, - factory, - getJSDocTypeTag, - getTokenAtPosition, - idText, isCallExpression, isIdentifier, - isInJSFile, isNewExpression, isParameter, isParenthesizedExpression, isParenthesizedTypeNode, isTypeReferenceNode, isUnionTypeNode, +} from "../../compiler/factory/nodeTests"; +import { skipTrivia } from "../../compiler/scanner"; +import { NewExpression, ParameterDeclaration, Program, - skipTrivia, - some, SourceFile, SyntaxKind, - textChanges, TextSpan, TypeFlags, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { isInJSFile } from "../../compiler/utilities"; +import { + getJSDocTypeTag, + idText, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { CodeFixAllContext } from "../types"; +import { getTokenAtPosition } from "../utilities"; const fixName = "addVoidToPromise"; const fixId = "addVoidToPromise"; @@ -41,7 +45,7 @@ registerCodeFix({ errorCodes, fixIds: [fixId], getCodeActions(context) { - const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span, context.program)); + const changes = ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span, context.program)); if (changes.length > 0) { return [createCodeFixAction(fixName, changes, Diagnostics.Add_void_to_Promise_resolved_without_a_value, fixId, Diagnostics.Add_void_to_all_Promises_resolved_without_a_value)]; } @@ -51,7 +55,7 @@ registerCodeFix({ } }); -function makeChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, span: TextSpan, program: Program, seen?: Set) { +function makeChange(changes: ChangeTracker, sourceFile: SourceFile, span: TextSpan, program: Program, seen?: Set) { const node = getTokenAtPosition(sourceFile, span.start); if (!isIdentifier(node) || !isCallExpression(node.parent) || node.parent.expression !== node || node.parent.arguments.length !== 0) return; diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts index f12ba12e3f0fc..1176287bd550e 100644 --- a/src/services/codefixes/fixAwaitInSyncFunction.ts +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -1,30 +1,36 @@ +import { getNodeId } from "../../compiler/checkerUtilities"; +import { first } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { + isFunctionTypeNode, + isVariableDeclaration, +} from "../../compiler/factory/nodeTests"; import { - addToSeen, ArrowFunction, - Diagnostics, - factory, - findChildOfKind, - first, FunctionDeclaration, FunctionExpression, - getContainingFunction, - getEntityNameFromTypeNode, - getNodeId, - getTokenAtPosition, - isFunctionTypeNode, - isVariableDeclaration, MethodDeclaration, Node, SourceFile, SyntaxKind, - textChanges, TypeNode, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + addToSeen, + getContainingFunction, + getEntityNameFromTypeNode, +} from "../../compiler/utilities"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + findChildOfKind, + getTokenAtPosition, +} from "../utilities"; const fixId = "fixAwaitInSyncFunction"; const errorCodes = [ @@ -38,7 +44,7 @@ registerCodeFix({ const { sourceFile, span } = context; const nodes = getNodes(sourceFile, span.start); if (!nodes) return undefined; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, nodes)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, nodes)); return [createCodeFixAction(fixId, changes, Diagnostics.Add_async_modifier_to_containing_function, fixId, Diagnostics.Add_all_missing_async_modifiers)]; }, fixIds: [fixId], @@ -94,7 +100,7 @@ function getNodes(sourceFile: SourceFile, start: number): { insertBefore: Node, } function doChange( - changes: textChanges.ChangeTracker, + changes: ChangeTracker, sourceFile: SourceFile, { insertBefore, returnType }: { insertBefore: Node, returnType: TypeNode | undefined }): void { diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts index d128045f7f075..e7b7961e00c7f 100644 --- a/src/services/codefixes/fixCannotFindModule.ts +++ b/src/services/codefixes/fixCannotFindModule.ts @@ -1,22 +1,24 @@ +import { tryCast } from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { isStringLiteral } from "../../compiler/factory/nodeTests"; import { - Debug, - Diagnostics, - getTokenAtPosition, getTypesPackageName, - InstallPackageAction, - isExternalModuleNameRelative, - isStringLiteral, - JsTyping, - LanguageServiceHost, parsePackageName, - SourceFile, - tryCast, -} from "../_namespaces/ts"; +} from "../../compiler/moduleNameResolver"; +import { SourceFile } from "../../compiler/types"; +import { isExternalModuleNameRelative } from "../../compiler/utilitiesPublic"; +import { nodeCoreModules } from "../../jsTyping/jsTyping"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { + InstallPackageAction, + LanguageServiceHost, +} from "../types"; +import { getTokenAtPosition } from "../utilities"; const fixName = "fixCannotFindModule"; const fixIdInstallTypesPackage = "installTypesPackage"; @@ -71,6 +73,6 @@ function tryGetImportedPackageName(sourceFile: SourceFile, pos: number): string function getTypesPackageNameToInstall(packageName: string, host: LanguageServiceHost, diagCode: number): string | undefined { return diagCode === errorCodeCannotFindModule - ? (JsTyping.nodeCoreModules.has(packageName) ? "@types/node" : undefined) + ? (nodeCoreModules.has(packageName) ? "@types/node" : undefined) : (host.isKnownTypesPackageName?.(packageName) ? getTypesPackageName(packageName) : undefined); } diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index ac9d7af09944d..8d51f696d812a 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -1,29 +1,35 @@ +import { getNodeId } from "../../compiler/checkerUtilities"; import { - addToSeen, cast, + first, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { ClassElement, ClassLikeDeclaration, - Diagnostics, - first, - getEffectiveBaseTypeNode, - getNodeId, - getSyntacticModifierFlags, - getTokenAtPosition, - isClassLike, ModifierFlags, SourceFile, Symbol, - textChanges, UserPreferences, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + addToSeen, + getEffectiveBaseTypeNode, + getSyntacticModifierFlags, +} from "../../compiler/utilities"; +import { isClassLike } from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, - createImportAdder, - createMissingMemberNodes, registerCodeFix, +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; +import { + createMissingMemberNodes, TypeConstructionContext, -} from "../_namespaces/ts.codefix"; +} from "./helpers"; +import { createImportAdder } from "./importAdder"; const errorCodes = [ Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2.code, @@ -34,7 +40,7 @@ registerCodeFix({ errorCodes, getCodeActions: function getCodeActionsToFixClassNotImplementingInheritedMembers(context) { const { sourceFile, span } = context; - const changes = textChanges.ChangeTracker.with(context, t => + const changes = ChangeTracker.with(context, t => addMissingMembers(getClass(sourceFile, span.start), sourceFile, context, t, context.preferences)); return changes.length === 0 ? undefined : [createCodeFixAction(fixId, changes, Diagnostics.Implement_inherited_abstract_class, fixId, Diagnostics.Implement_all_inherited_abstract_classes)]; }, @@ -57,7 +63,7 @@ function getClass(sourceFile: SourceFile, pos: number): ClassLikeDeclaration { return cast(token.parent, isClassLike); } -function addMissingMembers(classDeclaration: ClassLikeDeclaration, sourceFile: SourceFile, context: TypeConstructionContext, changeTracker: textChanges.ChangeTracker, preferences: UserPreferences): void { +function addMissingMembers(classDeclaration: ClassLikeDeclaration, sourceFile: SourceFile, context: TypeConstructionContext, changeTracker: ChangeTracker, preferences: UserPreferences): void { const extendsNode = getEffectiveBaseTypeNode(classDeclaration)!; const checker = context.program.getTypeChecker(); const instantiatedExtendsType = checker.getTypeAtLocation(extendsNode); @@ -66,7 +72,7 @@ function addMissingMembers(classDeclaration: ClassLikeDeclaration, sourceFile: S // so duplicates cannot occur. const abstractAndNonPrivateExtendsSymbols = checker.getPropertiesOfType(instantiatedExtendsType).filter(symbolPointsToNonPrivateAndAbstractMember); - const importAdder = createImportAdder(sourceFile, context.program, preferences, context.host); + const importAdder = createImportAdder(sourceFile, context.program, preferences, context.host, /*useAutoImportProvider*/ false); createMissingMemberNodes(classDeclaration, abstractAndNonPrivateExtendsSymbols, sourceFile, context, preferences, importAdder, member => changeTracker.insertMemberAtStart(sourceFile, classDeclaration, member as ClassElement)); importAdder.writeFixes(changeTracker); } diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index f91c49c9bece9..609fa0598d4e2 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -1,42 +1,48 @@ +import { getNodeId } from "../../compiler/checkerUtilities"; import { - addToSeen, and, + find, + mapDefined, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { isConstructorDeclaration } from "../../compiler/factory/nodeTests"; +import { ClassElement, ClassLikeDeclaration, - CodeFixAction, - createSymbolTable, - Debug, - Diagnostics, ExpressionWithTypeArguments, - find, - getContainingClass, - getEffectiveBaseTypeNode, - getEffectiveImplementsTypeNodes, - getEffectiveModifierFlags, - getNodeId, - getTokenAtPosition, IndexKind, InterfaceDeclaration, InterfaceType, - isConstructorDeclaration, - mapDefined, ModifierFlags, SourceFile, Symbol, SymbolTable, - textChanges, TypeChecker, UserPreferences, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + addToSeen, + createSymbolTable, + getContainingClass, + getEffectiveBaseTypeNode, + getEffectiveImplementsTypeNodes, + getEffectiveModifierFlags, +} from "../../compiler/utilities"; import { codeFixAll, createCodeFixAction, - createImportAdder, + registerCodeFix, +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { CodeFixAction } from "../types"; +import { getTokenAtPosition } from "../utilities"; +import { createMissingMemberNodes, getNoopSymbolTrackerWithResolver, - registerCodeFix, TypeConstructionContext, -} from "../_namespaces/ts.codefix"; +} from "./helpers"; +import { createImportAdder } from "./importAdder"; const errorCodes = [ Diagnostics.Class_0_incorrectly_implements_interface_1.code, @@ -49,7 +55,7 @@ registerCodeFix({ const { sourceFile, span } = context; const classDeclaration = getClass(sourceFile, span.start); return mapDefined(getEffectiveImplementsTypeNodes(classDeclaration), implementedTypeNode => { - const changes = textChanges.ChangeTracker.with(context, t => addMissingDeclarations(context, implementedTypeNode, sourceFile, classDeclaration, t, context.preferences)); + const changes = ChangeTracker.with(context, t => addMissingDeclarations(context, implementedTypeNode, sourceFile, classDeclaration, t, context.preferences)); return changes.length === 0 ? undefined : createCodeFixAction(fixId, changes, [Diagnostics.Implement_interface_0, implementedTypeNode.getText(sourceFile)], fixId, Diagnostics.Implement_all_unimplemented_interfaces); }); }, @@ -80,7 +86,7 @@ function addMissingDeclarations( implementedTypeNode: ExpressionWithTypeArguments, sourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, - changeTracker: textChanges.ChangeTracker, + changeTracker: ChangeTracker, preferences: UserPreferences, ): void { const checker = context.program.getTypeChecker(); @@ -101,7 +107,7 @@ function addMissingDeclarations( createMissingIndexSignatureDeclaration(implementedType, IndexKind.String); } - const importAdder = createImportAdder(sourceFile, context.program, preferences, context.host); + const importAdder = createImportAdder(sourceFile, context.program, preferences, context.host, /*useAutoImportProvider*/ false); createMissingMemberNodes(classDeclaration, nonPrivateAndNotExistedInHeritageClauseMembers, sourceFile, context, preferences, importAdder, member => insertInterfaceMemberNode(sourceFile, classDeclaration, member as ClassElement)); importAdder.writeFixes(changeTracker); diff --git a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts index 02276f8d7a482..0f68e5064e616 100644 --- a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts +++ b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts @@ -1,27 +1,31 @@ +import { getNodeId } from "../../compiler/checkerUtilities"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { + isExpressionStatement, + isPropertyAccessExpression, +} from "../../compiler/factory/nodeTests"; +import { forEachChild } from "../../compiler/parser"; import { - addToSeen, CallExpression, ConstructorDeclaration, - Diagnostics, ExpressionStatement, - forEachChild, - getContainingFunction, - getNodeId, - getTokenAtPosition, - isExpressionStatement, - isFunctionLike, - isPropertyAccessExpression, - isSuperCall, Node, SourceFile, SyntaxKind, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + addToSeen, + getContainingFunction, + isSuperCall, +} from "../../compiler/utilities"; +import { isFunctionLike } from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "classSuperMustPrecedeThisAccess"; const errorCodes = [Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class.code]; @@ -32,7 +36,7 @@ registerCodeFix({ const nodes = getNodes(sourceFile, span.start); if (!nodes) return undefined; const { constructor, superCall } = nodes; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, constructor, superCall)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, constructor, superCall)); return [createCodeFixAction(fixId, changes, Diagnostics.Make_super_call_the_first_statement_in_the_constructor, fixId, Diagnostics.Make_all_super_calls_the_first_statement_in_their_constructor)]; }, fixIds: [fixId], @@ -50,7 +54,7 @@ registerCodeFix({ }, }); -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, constructor: ConstructorDeclaration, superCall: ExpressionStatement): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, constructor: ConstructorDeclaration, superCall: ExpressionStatement): void { changes.insertNodeAtConstructorStart(sourceFile, constructor, superCall); changes.delete(sourceFile, superCall); } diff --git a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts index feee99da0d0cf..246e7e2c717f0 100644 --- a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts +++ b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts @@ -1,19 +1,19 @@ +import { emptyArray } from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isConstructorDeclaration } from "../../compiler/factory/nodeTests"; import { ConstructorDeclaration, - Debug, - Diagnostics, - emptyArray, - factory, - getTokenAtPosition, - isConstructorDeclaration, SourceFile, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "constructorForDerivedNeedSuperCall"; const errorCodes = [Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call.code]; @@ -22,7 +22,7 @@ registerCodeFix({ getCodeActions(context) { const { sourceFile, span } = context; const ctr = getNode(sourceFile, span.start); - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, ctr)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, ctr)); return [createCodeFixAction(fixId, changes, Diagnostics.Add_missing_super_call, fixId, Diagnostics.Add_all_missing_super_calls)]; }, fixIds: [fixId], @@ -36,7 +36,7 @@ function getNode(sourceFile: SourceFile, pos: number): ConstructorDeclaration { return token.parent; } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, ctr: ConstructorDeclaration) { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, ctr: ConstructorDeclaration) { const superCall = factory.createExpressionStatement(factory.createCallExpression(factory.createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray)); changes.insertNodeAtConstructorStart(sourceFile, ctr, superCall); } diff --git a/src/services/codefixes/fixEnableExperimentalDecorators.ts b/src/services/codefixes/fixEnableExperimentalDecorators.ts index 271c9b969118c..e79aa8c09dcdd 100644 --- a/src/services/codefixes/fixEnableExperimentalDecorators.ts +++ b/src/services/codefixes/fixEnableExperimentalDecorators.ts @@ -1,15 +1,13 @@ -import { - Diagnostics, - factory, - textChanges, - TsConfigSourceFile, -} from "../_namespaces/ts"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { TsConfigSourceFile } from "../../compiler/types"; import { codeFixAll, createCodeFixActionWithoutFixAll, registerCodeFix, - setJsonCompilerOptionValue, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { setJsonCompilerOptionValue } from "./helpers"; const fixId = "enableExperimentalDecorators"; const errorCodes = [ @@ -23,7 +21,7 @@ registerCodeFix({ return undefined; } - const changes = textChanges.ChangeTracker.with(context, changeTracker => doChange(changeTracker, configFile)); + const changes = ChangeTracker.with(context, changeTracker => doChange(changeTracker, configFile)); return [createCodeFixActionWithoutFixAll(fixId, changes, Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)]; }, fixIds: [fixId], @@ -36,6 +34,6 @@ registerCodeFix({ }), }); -function doChange(changeTracker: textChanges.ChangeTracker, configFile: TsConfigSourceFile) { +function doChange(changeTracker: ChangeTracker, configFile: TsConfigSourceFile) { setJsonCompilerOptionValue(changeTracker, configFile, "experimentalDecorators", factory.createTrue()); } diff --git a/src/services/codefixes/fixEnableJsxFlag.ts b/src/services/codefixes/fixEnableJsxFlag.ts index 4870e021120f7..db6e60e48a460 100644 --- a/src/services/codefixes/fixEnableJsxFlag.ts +++ b/src/services/codefixes/fixEnableJsxFlag.ts @@ -1,15 +1,13 @@ -import { - Diagnostics, - factory, - textChanges, - TsConfigSourceFile, -} from "../_namespaces/ts"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { TsConfigSourceFile } from "../../compiler/types"; import { codeFixAll, createCodeFixActionWithoutFixAll, registerCodeFix, - setJsonCompilerOptionValue, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { setJsonCompilerOptionValue } from "./helpers"; const fixID = "fixEnableJsxFlag"; const errorCodes = [Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided.code]; @@ -21,7 +19,7 @@ registerCodeFix({ return undefined; } - const changes = textChanges.ChangeTracker.with(context, changeTracker => + const changes = ChangeTracker.with(context, changeTracker => doChange(changeTracker, configFile) ); return [ @@ -40,6 +38,6 @@ registerCodeFix({ }) }); -function doChange(changeTracker: textChanges.ChangeTracker, configFile: TsConfigSourceFile) { +function doChange(changeTracker: ChangeTracker, configFile: TsConfigSourceFile) { setJsonCompilerOptionValue(changeTracker, configFile, "jsx", factory.createStringLiteral("react")); } diff --git a/src/services/codefixes/fixExpectedComma.ts b/src/services/codefixes/fixExpectedComma.ts index ed571ab443352..eed0d497e60da 100644 --- a/src/services/codefixes/fixExpectedComma.ts +++ b/src/services/codefixes/fixExpectedComma.ts @@ -1,19 +1,21 @@ +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - Diagnostics, - factory, - getTokenAtPosition, isArrayLiteralExpression, isObjectLiteralExpression, +} from "../../compiler/factory/nodeTests"; +import { Node, SourceFile, SyntaxKind, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "fixExpectedComma"; const expectedErrorCode = Diagnostics._0_expected.code; @@ -26,7 +28,7 @@ registerCodeFix({ const info = getInfo(sourceFile, context.span.start, context.errorCode); if (!info) return undefined; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, info)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, info)); return [createCodeFixAction( fixId, @@ -54,7 +56,7 @@ function getInfo(sourceFile: SourceFile, pos: number, _: number): Info | undefin isArrayLiteralExpression(node.parent))) ? { node } : undefined; } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { node }: Info): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, { node }: Info): void { const newNode = factory.createToken(SyntaxKind.CommaToken); changes.replaceNode(sourceFile, node, newNode); } diff --git a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts index 7beffebd59986..b0b1b0f4b65ca 100644 --- a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts +++ b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts @@ -1,20 +1,20 @@ +import { isWhiteSpaceSingleLine } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - Diagnostics, - factory, - getContainingClass, - getTokenAtPosition, HeritageClause, - isWhiteSpaceSingleLine, Node, SourceFile, SyntaxKind, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { getContainingClass } from "../../compiler/utilities"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "extendsInterfaceBecomesImplements"; const errorCodes = [Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements.code]; @@ -25,7 +25,7 @@ registerCodeFix({ const nodes = getNodes(sourceFile, context.span.start); if (!nodes) return undefined; const { extendsToken, heritageClauses } = nodes; - const changes = textChanges.ChangeTracker.with(context, t => doChanges(t, sourceFile, extendsToken, heritageClauses)); + const changes = ChangeTracker.with(context, t => doChanges(t, sourceFile, extendsToken, heritageClauses)); return [createCodeFixAction(fixId, changes, Diagnostics.Change_extends_to_implements, fixId, Diagnostics.Change_all_extended_interfaces_to_implements)]; }, fixIds: [fixId], @@ -42,7 +42,7 @@ function getNodes(sourceFile: SourceFile, pos: number) { return extendsToken.kind === SyntaxKind.ExtendsKeyword ? { extendsToken, heritageClauses } : undefined; } -function doChanges(changes: textChanges.ChangeTracker, sourceFile: SourceFile, extendsToken: Node, heritageClauses: readonly HeritageClause[]): void { +function doChanges(changes: ChangeTracker, sourceFile: SourceFile, extendsToken: Node, heritageClauses: readonly HeritageClause[]): void { changes.replaceNode(sourceFile, extendsToken, factory.createToken(SyntaxKind.ImplementsKeyword)); // If there is already an implements clause, replace the implements keyword with a comma. diff --git a/src/services/codefixes/fixForgottenThisPropertyAccess.ts b/src/services/codefixes/fixForgottenThisPropertyAccess.ts index ae8d0cd294f0b..89201df7a94a1 100644 --- a/src/services/codefixes/fixForgottenThisPropertyAccess.ts +++ b/src/services/codefixes/fixForgottenThisPropertyAccess.ts @@ -1,21 +1,25 @@ +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - Diagnostics, - factory, - getContainingClass, - getTokenAtPosition, - Identifier, isIdentifier, isPrivateIdentifier, +} from "../../compiler/factory/nodeTests"; +import { + Identifier, PrivateIdentifier, SourceFile, - suppressLeadingAndTrailingTrivia, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { getContainingClass } from "../../compiler/utilities"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + getTokenAtPosition, + suppressLeadingAndTrailingTrivia, +} from "../utilities"; const fixId = "forgottenThisPropertyAccess"; const didYouMeanStaticMemberCode = Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code; @@ -32,7 +36,7 @@ registerCodeFix({ if (!info) { return undefined; } - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, info)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, info)); return [createCodeFixAction(fixId, changes, [Diagnostics.Add_0_to_unresolved_variable, info.className || "this"], fixId, Diagnostics.Add_qualifier_to_all_unresolved_variables_matching_a_member_name)]; }, fixIds: [fixId], @@ -54,7 +58,7 @@ function getInfo(sourceFile: SourceFile, pos: number, diagCode: number): Info | } } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { node, className }: Info): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, { node, className }: Info): void { // TODO (https://github.com/Microsoft/TypeScript/issues/21246): use shared helper suppressLeadingAndTrailingTrivia(node); changes.replaceNode(sourceFile, node, factory.createPropertyAccessExpression(className ? factory.createIdentifier(className) : factory.createThis(), node)); diff --git a/src/services/codefixes/fixImplicitThis.ts b/src/services/codefixes/fixImplicitThis.ts index cd288e531df8c..65219fe4df65c 100644 --- a/src/services/codefixes/fixImplicitThis.ts +++ b/src/services/codefixes/fixImplicitThis.ts @@ -1,28 +1,32 @@ +import { emptyArray } from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - ANONYMOUS, - Debug, - DiagnosticAndArguments, - Diagnostics, - emptyArray, - factory, - FindAllReferences, - findChildOfKind, - getThisContainer, - getTokenAtPosition, isFunctionDeclaration, isFunctionExpression, isSourceFile, - isThis, +} from "../../compiler/factory/nodeTests"; +import { SourceFile, SyntaxKind, - textChanges, TypeChecker, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { getThisContainer } from "../../compiler/utilities"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { Core as FindAllReferences } from "../findAllReferences"; +import { ChangeTracker } from "../textChanges"; +import { + ANONYMOUS, + DiagnosticAndArguments, + findChildOfKind, + getTokenAtPosition, + isThis, +} from "../utilities"; const fixId = "fixImplicitThis"; const errorCodes = [Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation.code]; @@ -31,7 +35,7 @@ registerCodeFix({ getCodeActions: function getCodeActionsToFixImplicitThis(context) { const { sourceFile, program, span } = context; let diagnostic: DiagnosticAndArguments | undefined; - const changes = textChanges.ChangeTracker.with(context, t => { + const changes = ChangeTracker.with(context, t => { diagnostic = doChange(t, sourceFile, span.start, program.getTypeChecker()); }); return diagnostic ? [createCodeFixAction(fixId, changes, diagnostic, fixId, Diagnostics.Fix_all_implicit_this_errors)] : emptyArray; @@ -42,7 +46,7 @@ registerCodeFix({ }), }); -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, checker: TypeChecker): DiagnosticAndArguments | undefined { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, pos: number, checker: TypeChecker): DiagnosticAndArguments | undefined { const token = getTokenAtPosition(sourceFile, pos); if (!isThis(token)) return undefined; @@ -54,7 +58,7 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, po const { name } = fn; const body = Debug.checkDefined(fn.body); // Should be defined because the function contained a 'this' expression if (isFunctionExpression(fn)) { - if (name && FindAllReferences.Core.isSymbolReferencedInFile(name, checker, sourceFile, body)) { + if (name && FindAllReferences.isSymbolReferencedInFile(name, checker, sourceFile, body)) { // Function expression references itself. To fix we would have to extract it to a const. return undefined; } diff --git a/src/services/codefixes/fixImportNonExportedMember.ts b/src/services/codefixes/fixImportNonExportedMember.ts index ba1ec81fc945f..e81b383aabaa5 100644 --- a/src/services/codefixes/fixImportNonExportedMember.ts +++ b/src/services/codefixes/fixImportNonExportedMember.ts @@ -1,41 +1,49 @@ import { - canHaveExportModifier, - Declaration, - Diagnostics, - ExportDeclaration, - factory, find, - findAncestor, findLast, firstOrUndefined, - getResolvedModule, - getTokenAtPosition, - Identifier, + length, + map, + tryCast, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isExportDeclaration, isIdentifier, isImportDeclaration, isNamedExports, - isSourceFileFromLibrary, isStringLiteral, - isTypeDeclaration, isVariableDeclaration, isVariableStatement, - length, - map, +} from "../../compiler/factory/nodeTests"; +import { + Declaration, + ExportDeclaration, + Identifier, Node, Program, SourceFile, Symbol, - textChanges, - tryCast, VariableStatement, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + canHaveExportModifier, + getResolvedModule, + isTypeDeclaration, +} from "../../compiler/utilities"; +import { findAncestor } from "../../compiler/utilitiesPublic"; import { createCodeFixAction, createCombinedCodeActions, eachDiagnostic, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + getTokenAtPosition, + isSourceFileFromLibrary, +} from "../utilities"; const fixId = "fixImportNonExportedMember"; const errorCodes = [ @@ -50,12 +58,12 @@ registerCodeFix({ const info = getInfo(sourceFile, span.start, program); if (info === undefined) return undefined; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, program, info)); + const changes = ChangeTracker.with(context, t => doChange(t, program, info)); return [createCodeFixAction(fixId, changes, [Diagnostics.Export_0_from_module_1, info.exportName.node.text, info.moduleSpecifier], fixId, Diagnostics.Export_all_referenced_locals)]; }, getAllCodeActions(context) { const { program } = context; - return createCombinedCodeActions(textChanges.ChangeTracker.with(context, changes => { + return createCombinedCodeActions(ChangeTracker.with(context, changes => { const exports = new Map(); eachDiagnostic(context, errorCodes, diag => { @@ -140,7 +148,7 @@ function getInfo(sourceFile: SourceFile, pos: number, program: Program): Info | return undefined; } -function doChange(changes: textChanges.ChangeTracker, program: Program, { exportName, node, moduleSourceFile }: Info) { +function doChange(changes: ChangeTracker, program: Program, { exportName, node, moduleSourceFile }: Info) { const exportDeclaration = tryGetExportDeclaration(moduleSourceFile, exportName.isTypeOnly); if (exportDeclaration) { updateExport(changes, program, moduleSourceFile, exportDeclaration, [exportName]); @@ -153,7 +161,7 @@ function doChange(changes: textChanges.ChangeTracker, program: Program, { export } } -function doChanges(changes: textChanges.ChangeTracker, program: Program, sourceFile: SourceFile, moduleExports: ExportName[], node: ExportDeclaration | undefined) { +function doChanges(changes: ChangeTracker, program: Program, sourceFile: SourceFile, moduleExports: ExportName[], node: ExportDeclaration | undefined) { if (length(moduleExports)) { if (node) { updateExport(changes, program, sourceFile, node, moduleExports); @@ -170,7 +178,7 @@ function tryGetExportDeclaration(sourceFile: SourceFile, isTypeOnly: boolean) { return findLast(sourceFile.statements, predicate); } -function updateExport(changes: textChanges.ChangeTracker, program: Program, sourceFile: SourceFile, node: ExportDeclaration, names: ExportName[]) { +function updateExport(changes: ChangeTracker, program: Program, sourceFile: SourceFile, node: ExportDeclaration, names: ExportName[]) { const namedExports = node.exportClause && isNamedExports(node.exportClause) ? node.exportClause.elements : factory.createNodeArray([]); const allowTypeModifier = !node.isTypeOnly && !!(program.getCompilerOptions().isolatedModules || find(namedExports, e => e.isTypeOnly)); changes.replaceNode(sourceFile, node, @@ -179,7 +187,7 @@ function updateExport(changes: textChanges.ChangeTracker, program: Program, sour factory.createNodeArray([...namedExports, ...createExportSpecifiers(names, allowTypeModifier)], /*hasTrailingComma*/ namedExports.hasTrailingComma)), node.moduleSpecifier, node.assertClause)); } -function createExport(changes: textChanges.ChangeTracker, program: Program, sourceFile: SourceFile, names: ExportName[]) { +function createExport(changes: ChangeTracker, program: Program, sourceFile: SourceFile, names: ExportName[]) { changes.insertNodeAtEndOfScope(sourceFile, sourceFile, factory.createExportDeclaration(/*modifiers*/ undefined, /*isTypeOnly*/ false, factory.createNamedExports(createExportSpecifiers(names, /*allowTypeModifier*/ !!program.getCompilerOptions().isolatedModules)), /*moduleSpecifier*/ undefined, /*assertClause*/ undefined)); diff --git a/src/services/codefixes/fixIncorrectNamedTupleSyntax.ts b/src/services/codefixes/fixIncorrectNamedTupleSyntax.ts index f7e8345b217f0..33b6eb78adee6 100644 --- a/src/services/codefixes/fixIncorrectNamedTupleSyntax.ts +++ b/src/services/codefixes/fixIncorrectNamedTupleSyntax.ts @@ -1,20 +1,20 @@ +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - Diagnostics, - factory, - findAncestor, - getTokenAtPosition, NamedTupleMember, OptionalTypeNode, ParenthesizedTypeNode, RestTypeNode, SourceFile, SyntaxKind, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { findAncestor } from "../../compiler/utilitiesPublic"; import { createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "fixIncorrectNamedTupleSyntax"; const errorCodes = [ @@ -27,7 +27,7 @@ registerCodeFix({ getCodeActions: function getCodeActionsToFixIncorrectNamedTupleSyntax(context) { const { sourceFile, span } = context; const namedTupleMember = getNamedTupleMember(sourceFile, span.start); - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, namedTupleMember)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, namedTupleMember)); return [createCodeFixAction(fixId, changes, Diagnostics.Move_labeled_tuple_element_modifiers_to_labels, fixId, Diagnostics.Move_labeled_tuple_element_modifiers_to_labels)]; }, fixIds: [fixId] @@ -37,7 +37,7 @@ function getNamedTupleMember(sourceFile: SourceFile, pos: number) { const token = getTokenAtPosition(sourceFile, pos); return findAncestor(token, t => t.kind === SyntaxKind.NamedTupleMember) as NamedTupleMember | undefined; } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, namedTupleMember?: NamedTupleMember) { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, namedTupleMember?: NamedTupleMember) { if (!namedTupleMember) { return; } diff --git a/src/services/codefixes/fixInvalidImportSyntax.ts b/src/services/codefixes/fixInvalidImportSyntax.ts index 698a7397878b1..b9527d7f1b1d8 100644 --- a/src/services/codefixes/fixInvalidImportSyntax.ts +++ b/src/services/codefixes/fixInvalidImportSyntax.ts @@ -1,34 +1,42 @@ +import { addRange } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - addRange, CallExpression, - CodeFixAction, - CodeFixContext, - Diagnostics, - factory, - findAncestor, - getEmitModuleKind, - getNamespaceDeclarationNode, - getQuotePreference, - getSourceFileOfNode, - getTokenAtPosition, ImportDeclaration, - isExpression, - isImportCall, - isNamedDeclaration, - makeImport, ModuleKind, NamespaceImport, NewExpression, Node, SourceFile, SyntaxKind, - textChanges, TransientSymbol, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + getEmitModuleKind, + getNamespaceDeclarationNode, + getSourceFileOfNode, + isImportCall, +} from "../../compiler/utilities"; +import { + findAncestor, + isExpression, + isNamedDeclaration, +} from "../../compiler/utilitiesPublic"; import { createCodeFixActionWithoutFixAll, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + CodeFixAction, + CodeFixContext, +} from "../types"; +import { + getQuotePreference, + getTokenAtPosition, + makeImport, +} from "../utilities"; const fixName = "invalidImportSyntax"; @@ -55,7 +63,7 @@ function getCodeFixesForImportDeclaration(context: CodeFixContext, node: ImportD } function createAction(context: CodeFixContext, sourceFile: SourceFile, node: Node, replacement: Node): CodeFixAction { - const changes = textChanges.ChangeTracker.with(context, t => t.replaceNode(sourceFile, node, replacement)); + const changes = ChangeTracker.with(context, t => t.replaceNode(sourceFile, node, replacement)); return createCodeFixActionWithoutFixAll(fixName, changes, [Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]); } @@ -117,7 +125,7 @@ function getImportCodeFixesForExpression(context: CodeFixContext, expr: Node): C } if (isExpression(expr) && !(isNamedDeclaration(expr.parent) && expr.parent.name === expr)) { const sourceFile = context.sourceFile; - const changes = textChanges.ChangeTracker.with(context, t => t.replaceNode(sourceFile, expr, factory.createPropertyAccessExpression(expr, "default"), {})); + const changes = ChangeTracker.with(context, t => t.replaceNode(sourceFile, expr, factory.createPropertyAccessExpression(expr, "default"), {})); fixes.push(createCodeFixActionWithoutFixAll(fixName, changes, Diagnostics.Use_synthetic_default_member)); } return fixes; diff --git a/src/services/codefixes/fixInvalidJsxCharacters.ts b/src/services/codefixes/fixInvalidJsxCharacters.ts index 3c53a5da26b5e..2e8192b5090cb 100644 --- a/src/services/codefixes/fixInvalidJsxCharacters.ts +++ b/src/services/codefixes/fixInvalidJsxCharacters.ts @@ -1,16 +1,16 @@ +import { hasProperty } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { - Diagnostics, - hasProperty, - quote, SourceFile, - textChanges, UserPreferences, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { quote } from "../utilities"; const fixIdExpression = "fixInvalidJsxCharacters_expression"; const fixIdHtmlEntity = "fixInvalidJsxCharacters_htmlEntity"; @@ -25,8 +25,8 @@ registerCodeFix({ fixIds: [fixIdExpression, fixIdHtmlEntity], getCodeActions(context) { const { sourceFile, preferences, span } = context; - const changeToExpression = textChanges.ChangeTracker.with(context, t => doChange(t, preferences, sourceFile, span.start, /* useHtmlEntity */ false)); - const changeToHtmlEntity = textChanges.ChangeTracker.with(context, t => doChange(t, preferences, sourceFile, span.start, /* useHtmlEntity */ true)); + const changeToExpression = ChangeTracker.with(context, t => doChange(t, preferences, sourceFile, span.start, /* useHtmlEntity */ false)); + const changeToHtmlEntity = ChangeTracker.with(context, t => doChange(t, preferences, sourceFile, span.start, /* useHtmlEntity */ true)); return [ createCodeFixAction(fixIdExpression, changeToExpression, Diagnostics.Wrap_invalid_character_in_an_expression_container, fixIdExpression, Diagnostics.Wrap_all_invalid_characters_in_an_expression_container), @@ -47,7 +47,7 @@ function isValidCharacter(character: string): character is keyof typeof htmlEnti return hasProperty(htmlEntity, character); } -function doChange(changes: textChanges.ChangeTracker, preferences: UserPreferences, sourceFile: SourceFile, start: number, useHtmlEntity: boolean) { +function doChange(changes: ChangeTracker, preferences: UserPreferences, sourceFile: SourceFile, start: number, useHtmlEntity: boolean) { const character = sourceFile.getText()[start]; // sanity check if (!isValidCharacter(character)) { diff --git a/src/services/codefixes/fixJSDocTypes.ts b/src/services/codefixes/fixJSDocTypes.ts index 0a5442600d8c4..e1ec7bee0fdb4 100644 --- a/src/services/codefixes/fixJSDocTypes.ts +++ b/src/services/codefixes/fixJSDocTypes.ts @@ -1,14 +1,11 @@ +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { AsExpression, CallSignatureDeclaration, - CodeFixAction, ConstructSignatureDeclaration, DiagnosticMessage, - Diagnostics, - findAncestor, FunctionDeclaration, GetAccessorDeclaration, - getTokenAtPosition, IndexSignatureDeclaration, MappedTypeNode, MethodDeclaration, @@ -20,7 +17,6 @@ import { SetAccessorDeclaration, SourceFile, SyntaxKind, - textChanges, Type, TypeAliasDeclaration, TypeAssertion, @@ -28,12 +24,16 @@ import { TypeFlags, TypeNode, VariableDeclaration, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { findAncestor } from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { CodeFixAction } from "../types"; +import { getTokenAtPosition } from "../utilities"; const fixIdPlain = "fixJSDocTypes_plain"; const fixIdNullable = "fixJSDocTypes_nullable"; @@ -56,7 +56,7 @@ registerCodeFix({ return actions; function fix(type: Type, fixId: string, fixAllDescription: DiagnosticMessage): CodeFixAction { - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, typeNode, type, checker)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, typeNode, type, checker)); return createCodeFixAction("jdocTypes", changes, [Diagnostics.Change_0_to_1, original, checker.typeToString(type)], fixId, fixAllDescription); } }, @@ -74,7 +74,7 @@ registerCodeFix({ } }); -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, oldTypeNode: TypeNode, newType: Type, checker: TypeChecker): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, oldTypeNode: TypeNode, newType: Type, checker: TypeChecker): void { changes.replaceNode(sourceFile, oldTypeNode, checker.typeToTypeNode(newType, /*enclosingDeclaration*/ oldTypeNode, /*flags*/ undefined)!); // TODO: GH#18217 } diff --git a/src/services/codefixes/fixMissingCallParentheses.ts b/src/services/codefixes/fixMissingCallParentheses.ts index 4fcc89c87fcc0..61d3bc4865204 100644 --- a/src/services/codefixes/fixMissingCallParentheses.ts +++ b/src/services/codefixes/fixMissingCallParentheses.ts @@ -1,19 +1,21 @@ +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { - Diagnostics, - getTokenAtPosition, - Identifier, isIdentifier, isPropertyAccessExpression, +} from "../../compiler/factory/nodeTests"; +import { + Identifier, PrivateIdentifier, PropertyAccessExpression, SourceFile, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "fixMissingCallParentheses"; const errorCodes = [ @@ -28,7 +30,7 @@ registerCodeFix({ const callName = getCallName(sourceFile, span.start); if (!callName) return; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, callName)); + const changes = ChangeTracker.with(context, t => doChange(t, context.sourceFile, callName)); return [createCodeFixAction(fixId, changes, Diagnostics.Add_missing_call_parentheses, fixId, Diagnostics.Add_all_missing_call_parentheses)]; }, getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { @@ -37,7 +39,7 @@ registerCodeFix({ }) }); -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, name: Identifier | PrivateIdentifier): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, name: Identifier | PrivateIdentifier): void { changes.replaceNodeWithText(sourceFile, name, `${ name.text }()`); } diff --git a/src/services/codefixes/fixModuleAndTargetOptions.ts b/src/services/codefixes/fixModuleAndTargetOptions.ts index 3769fa3619ef1..1d0e6b7d78bc2 100644 --- a/src/services/codefixes/fixModuleAndTargetOptions.ts +++ b/src/services/codefixes/fixModuleAndTargetOptions.ts @@ -1,21 +1,25 @@ +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - createCodeFixActionWithoutFixAll, - registerCodeFix, - setJsonCompilerOptionValue, - setJsonCompilerOptionValues, -} from "../_namespaces/ts.codefix"; -import { - CodeFixAction, - Diagnostics, Expression, - factory, + ModuleKind, + ScriptTarget, +} from "../../compiler/types"; +import { getEmitModuleKind, getEmitScriptTarget, getTsConfigObjectLiteralExpression, - ModuleKind, - ScriptTarget, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/utilities"; +import { + createCodeFixActionWithoutFixAll, + registerCodeFix, +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { CodeFixAction } from "../types"; +import { + setJsonCompilerOptionValue, + setJsonCompilerOptionValues, +} from "./helpers"; registerCodeFix({ errorCodes: [ @@ -33,7 +37,7 @@ registerCodeFix({ const moduleKind = getEmitModuleKind(compilerOptions); const moduleOutOfRange = moduleKind >= ModuleKind.ES2015 && moduleKind < ModuleKind.ESNext; if (moduleOutOfRange) { - const changes = textChanges.ChangeTracker.with(context, changes => { + const changes = ChangeTracker.with(context, changes => { setJsonCompilerOptionValue(changes, configFile, "module", factory.createStringLiteral("esnext")); }); codeFixes.push(createCodeFixActionWithoutFixAll("fixModuleOption", changes, [Diagnostics.Set_the_module_option_in_your_configuration_file_to_0, "esnext"])); @@ -42,7 +46,7 @@ registerCodeFix({ const target = getEmitScriptTarget(compilerOptions); const targetOutOfRange = target < ScriptTarget.ES2017 || target > ScriptTarget.ESNext; if (targetOutOfRange) { - const changes = textChanges.ChangeTracker.with(context, tracker => { + const changes = ChangeTracker.with(context, tracker => { const configObject = getTsConfigObjectLiteralExpression(configFile); if (!configObject) return; diff --git a/src/services/codefixes/fixNaNEquality.ts b/src/services/codefixes/fixNaNEquality.ts index cf86a7ef2d53d..e444e47a32752 100644 --- a/src/services/codefixes/fixNaNEquality.ts +++ b/src/services/codefixes/fixNaNEquality.ts @@ -1,26 +1,28 @@ +import { find } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isBinaryExpression } from "../../compiler/factory/nodeTests"; +import { flattenDiagnosticMessageText } from "../../compiler/program"; import { BinaryExpression, - createTextSpan, DiagnosticMessageChain, - Diagnostics, Expression, - factory, - find, - flattenDiagnosticMessageText, - isBinaryExpression, - isExpression, Program, SourceFile, SyntaxKind, - textChanges, TextSpan, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + createTextSpan, + isExpression, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, - findAncestorMatchingSpan, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { findAncestorMatchingSpan } from "./helpers"; const fixId = "fixNaNEquality"; const errorCodes = [ @@ -35,7 +37,7 @@ registerCodeFix({ if (info === undefined) return; const { suggestion, expression, arg } = info; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, arg, expression)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, arg, expression)); return [createCodeFixAction(fixId, changes, [Diagnostics.Use_0, suggestion], fixId, Diagnostics.Use_Number_isNaN_in_all_conditions)]; }, fixIds: [fixId], @@ -71,7 +73,7 @@ function getInfo(program: Program, sourceFile: SourceFile, span: TextSpan): Info return undefined; } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, arg: Expression, expression: BinaryExpression) { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, arg: Expression, expression: BinaryExpression) { const callExpression = factory.createCallExpression( factory.createPropertyAccessExpression(factory.createIdentifier("Number"), factory.createIdentifier("isNaN")), /*typeArguments*/ undefined, [arg]); const operator = expression.operatorToken.kind ; diff --git a/src/services/codefixes/fixNoPropertyAccessFromIndexSignature.ts b/src/services/codefixes/fixNoPropertyAccessFromIndexSignature.ts index 7a35126032924..a65ca2632f756 100644 --- a/src/services/codefixes/fixNoPropertyAccessFromIndexSignature.ts +++ b/src/services/codefixes/fixNoPropertyAccessFromIndexSignature.ts @@ -1,22 +1,24 @@ +import { cast } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isPropertyAccessExpression } from "../../compiler/factory/nodeTests"; import { - cast, - Diagnostics, - factory, - getQuotePreference, - getTokenAtPosition, - isPropertyAccessChain, - isPropertyAccessExpression, PropertyAccessExpression, - QuotePreference, SourceFile, - textChanges, UserPreferences, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { isPropertyAccessChain } from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + getQuotePreference, + getTokenAtPosition, + QuotePreference, +} from "../utilities"; const fixId = "fixNoPropertyAccessFromIndexSignature"; const errorCodes = [ @@ -29,14 +31,14 @@ registerCodeFix({ getCodeActions(context) { const { sourceFile, span, preferences } = context; const property = getPropertyAccessExpression(sourceFile, span.start); - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, property, preferences)); + const changes = ChangeTracker.with(context, t => doChange(t, context.sourceFile, property, preferences)); return [createCodeFixAction(fixId, changes, [Diagnostics.Use_element_access_for_0, property.name.text], fixId, Diagnostics.Use_element_access_for_all_undeclared_properties)]; }, getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => doChange(changes, diag.file, getPropertyAccessExpression(diag.file, diag.start), context.preferences)) }); -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, node: PropertyAccessExpression, preferences: UserPreferences): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, node: PropertyAccessExpression, preferences: UserPreferences): void { const quotePreference = getQuotePreference(sourceFile, preferences); const argumentsExpression = factory.createStringLiteral(node.name.text, quotePreference === QuotePreference.Single); changes.replaceNode( diff --git a/src/services/codefixes/fixOverrideModifier.ts b/src/services/codefixes/fixOverrideModifier.ts index f76a8420e0699..75fdb3840327d 100644 --- a/src/services/codefixes/fixOverrideModifier.ts +++ b/src/services/codefixes/fixOverrideModifier.ts @@ -1,42 +1,52 @@ import { - CodeFixAllContext, - CodeFixContext, - ConstructorDeclaration, - Debug, - DiagnosticMessage, - Diagnostics, emptyArray, - factory, find, - findAncestor, findLast, - GetAccessorDeclaration, - getTokenAtPosition, + not, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isAbstractModifier, - isAccessibilityModifier, - isClassLike, isDecorator, isJSDocOverrideTag, isOverrideModifier, - isParameterPropertyDeclaration, - isSourceFileJS, isStaticModifier, +} from "../../compiler/factory/nodeTests"; +import { skipTrivia } from "../../compiler/scanner"; +import { + ConstructorDeclaration, + DiagnosticMessage, + GetAccessorDeclaration, MethodDeclaration, Node, - not, - ParameterPropertyDeclaration, PropertyDeclaration, SetAccessorDeclaration, - skipTrivia, SourceFile, SyntaxKind, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { isSourceFileJS } from "../../compiler/utilities"; +import { + findAncestor, + isClassLike, + isParameterPropertyDeclaration, + ParameterPropertyDeclaration, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixActionMaybeFixAll, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + CodeFixAllContext, + CodeFixContext, +} from "../types"; +import { + getTokenAtPosition, + isAccessibilityModifier, +} from "../utilities"; const fixName = "fixOverrideModifier"; const fixAddOverrideId = "fixAddOverrideModifier"; @@ -130,7 +140,7 @@ registerCodeFix({ if (!info) return emptyArray; const { descriptions, fixId, fixAllDescriptions } = info; - const changes = textChanges.ChangeTracker.with(context, changes => dispatchChanges(changes, context, errorCode, span.start)); + const changes = ChangeTracker.with(context, changes => dispatchChanges(changes, context, errorCode, span.start)); return [ createCodeFixActionMaybeFixAll(fixName, changes, descriptions, fixId, fixAllDescriptions) @@ -150,7 +160,7 @@ registerCodeFix({ }); function dispatchChanges( - changeTracker: textChanges.ChangeTracker, + changeTracker: ChangeTracker, context: CodeFixContext | CodeFixAllContext, errorCode: number, pos: number) { @@ -171,7 +181,7 @@ function dispatchChanges( } } -function doAddOverrideModifierChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) { +function doAddOverrideModifierChange(changeTracker: ChangeTracker, sourceFile: SourceFile, pos: number) { const classElement = findContainerClassElementLike(sourceFile, pos); if (isSourceFileJS(sourceFile)) { changeTracker.addJSDocTags(sourceFile, classElement, [factory.createJSDocOverrideTag(factory.createIdentifier("override"))]); @@ -190,7 +200,7 @@ function doAddOverrideModifierChange(changeTracker: textChanges.ChangeTracker, s changeTracker.insertModifierAt(sourceFile, modifierPos, SyntaxKind.OverrideKeyword, options); } -function doRemoveOverrideModifierChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) { +function doRemoveOverrideModifierChange(changeTracker: ChangeTracker, sourceFile: SourceFile, pos: number) { const classElement = findContainerClassElementLike(sourceFile, pos); if (isSourceFileJS(sourceFile)) { changeTracker.filterJSDocTags(sourceFile, classElement, not(isJSDocOverrideTag)); diff --git a/src/services/codefixes/fixPropertyAssignment.ts b/src/services/codefixes/fixPropertyAssignment.ts index 2f1ef5a198044..f2e6721e47962 100644 --- a/src/services/codefixes/fixPropertyAssignment.ts +++ b/src/services/codefixes/fixPropertyAssignment.ts @@ -1,19 +1,21 @@ +import { cast } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - cast, - Diagnostics, - Expression, - factory, - getTokenAtPosition, isShorthandPropertyAssignment, +} from "../../compiler/factory/nodeTests"; +import { + Expression, ShorthandPropertyAssignment, SourceFile, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "fixPropertyAssignment"; const errorCodes = [ @@ -26,14 +28,14 @@ registerCodeFix({ getCodeActions(context) { const { sourceFile, span } = context; const property = getProperty(sourceFile, span.start); - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, property)); + const changes = ChangeTracker.with(context, t => doChange(t, context.sourceFile, property)); return [createCodeFixAction(fixId, changes, [Diagnostics.Change_0_to_1, "=", ":"], fixId, [Diagnostics.Switch_each_misused_0_to_1, "=", ":"])]; }, getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => doChange(changes, diag.file, getProperty(diag.file, diag.start))) }); -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, node: ShorthandPropertyAssignment): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, node: ShorthandPropertyAssignment): void { changes.replaceNode(sourceFile, node, factory.createPropertyAssignment(node.name, node.objectAssignmentInitializer as Expression)); } diff --git a/src/services/codefixes/fixPropertyOverrideAccessor.ts b/src/services/codefixes/fixPropertyOverrideAccessor.ts index 954a90ba6f34a..b699611599a35 100644 --- a/src/services/codefixes/fixPropertyOverrideAccessor.ts +++ b/src/services/codefixes/fixPropertyOverrideAccessor.ts @@ -1,24 +1,30 @@ +import { singleOrUndefined } from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { SourceFile } from "../../compiler/types"; import { - CodeFixAllContext, - CodeFixContext, - Debug, - Diagnostics, getSourceFileOfNode, getTextOfPropertyName, - getTokenAtPosition, +} from "../../compiler/utilities"; +import { isAccessor, isClassLike, - singleOrUndefined, - SourceFile, unescapeLeadingUnderscores, -} from "../_namespaces/ts"; +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, + registerCodeFix, +} from "../codeFixProvider"; +import { + CodeFixAllContext, + CodeFixContext, +} from "../types"; +import { getTokenAtPosition } from "../utilities"; +import { generateAccessorFromProperty, getAllSupers, - registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "./generateAccessors"; const errorCodes = [ Diagnostics._0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property.code, diff --git a/src/services/codefixes/fixReturnTypeInAsyncFunction.ts b/src/services/codefixes/fixReturnTypeInAsyncFunction.ts index a7071d6e143f4..87848c52faf19 100644 --- a/src/services/codefixes/fixReturnTypeInAsyncFunction.ts +++ b/src/services/codefixes/fixReturnTypeInAsyncFunction.ts @@ -1,21 +1,23 @@ +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - Diagnostics, - factory, - findAncestor, - getTokenAtPosition, - isFunctionLikeDeclaration, - isInJSFile, SourceFile, - textChanges, Type, TypeChecker, TypeNode, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { isInJSFile } from "../../compiler/utilities"; +import { + findAncestor, + isFunctionLikeDeclaration, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "fixReturnTypeInAsyncFunction"; const errorCodes = [ @@ -40,7 +42,7 @@ registerCodeFix({ return undefined; } const { returnTypeNode, returnType, promisedTypeNode, promisedType } = info; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, returnTypeNode, promisedTypeNode)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, returnTypeNode, promisedTypeNode)); return [createCodeFixAction( fixId, changes, [Diagnostics.Replace_0_with_Promise_1, @@ -75,6 +77,6 @@ function getInfo(sourceFile: SourceFile, checker: TypeChecker, pos: number): Inf } } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, returnTypeNode: TypeNode, promisedTypeNode: TypeNode): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, returnTypeNode: TypeNode, promisedTypeNode: TypeNode): void { changes.replaceNode(sourceFile, returnTypeNode, factory.createTypeReferenceNode("Promise", [promisedTypeNode])); } diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts index 8e3574aa60cde..d98a3c92a9613 100644 --- a/src/services/codefixes/fixSpelling.ts +++ b/src/services/codefixes/fixSpelling.ts @@ -1,50 +1,58 @@ +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - CodeFixContextBase, - Debug, - Diagnostics, - factory, - findAncestor, - getEffectiveBaseTypeNode, - getEmitScriptTarget, - getMeaningFromLocation, - getModeForUsageLocation, - getResolvedModule, - getTextOfNode, - getTokenAtPosition, - hasSyntacticModifier, - ImportDeclaration, isBinaryExpression, - isClassElement, - isClassLike, isIdentifier, - isIdentifierText, isImportDeclaration, isImportSpecifier, isJsxAttribute, - isJsxOpeningLikeElement, - isMemberName, - isNamedDeclaration, isPrivateIdentifier, isPropertyAccessExpression, isQualifiedName, - isStringLiteralLike, +} from "../../compiler/factory/nodeTests"; +import { getModeForUsageLocation } from "../../compiler/program"; +import { isIdentifierText } from "../../compiler/scanner"; +import { + ImportDeclaration, ModifierFlags, Node, NodeFlags, ScriptTarget, - SemanticMeaning, SourceFile, Symbol, SymbolFlags, - symbolName, SyntaxKind, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + getEffectiveBaseTypeNode, + getEmitScriptTarget, + getResolvedModule, + getTextOfNode, + hasSyntacticModifier, +} from "../../compiler/utilities"; +import { + findAncestor, + isClassElement, + isClassLike, + isJsxOpeningLikeElement, + isMemberName, + isNamedDeclaration, + isStringLiteralLike, + symbolName, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { CodeFixContextBase } from "../types"; +import { + getMeaningFromLocation, + getTokenAtPosition, + SemanticMeaning, +} from "../utilities"; const fixId = "fixSpelling"; const errorCodes = [ @@ -71,7 +79,7 @@ registerCodeFix({ if (!info) return undefined; const { node, suggestedSymbol } = info; const target = getEmitScriptTarget(context.host.getCompilationSettings()); - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, node, suggestedSymbol, target)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, node, suggestedSymbol, target)); return [createCodeFixAction("spelling", changes, [Diagnostics.Change_spelling_to_0, symbolName(suggestedSymbol)], fixId, Diagnostics.Fix_all_detected_spelling_errors)]; }, fixIds: [fixId], @@ -146,7 +154,7 @@ function getInfo(sourceFile: SourceFile, pos: number, context: CodeFixContextBas return suggestedSymbol === undefined ? undefined : { node, suggestedSymbol }; } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, node: Node, suggestedSymbol: Symbol, target: ScriptTarget) { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, node: Node, suggestedSymbol: Symbol, target: ScriptTarget) { const suggestion = symbolName(suggestedSymbol); if (!isIdentifierText(suggestion, target) && isPropertyAccessExpression(node.parent)) { const valDecl = suggestedSymbol.valueDeclaration; diff --git a/src/services/codefixes/fixStrictClassInitialization.ts b/src/services/codefixes/fixStrictClassInitialization.ts index fa78042e08217..3023cce2b7b0c 100644 --- a/src/services/codefixes/fixStrictClassInitialization.ts +++ b/src/services/codefixes/fixStrictClassInitialization.ts @@ -1,38 +1,48 @@ import { append, - BigIntLiteralType, - CodeFixAction, - CodeFixContext, - Debug, - Diagnostics, - Expression, - factory, firstDefined, - getClassLikeDeclarationOfSymbol, - getEffectiveTypeAnnotationNode, - getFirstConstructorWithBody, - getTokenAtPosition, - hasSyntacticModifier, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isIdentifier, - isInJSFile, isPropertyDeclaration, isUnionTypeNode, +} from "../../compiler/factory/nodeTests"; +import { + BigIntLiteralType, + Expression, ModifierFlags, PropertyDeclaration, SourceFile, - suppressLeadingAndTrailingTrivia, SyntaxKind, - textChanges, Type, TypeChecker, TypeFlags, TypeNode, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + getClassLikeDeclarationOfSymbol, + getEffectiveTypeAnnotationNode, + getFirstConstructorWithBody, + hasSyntacticModifier, + isInJSFile, +} from "../../compiler/utilities"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + CodeFixAction, + CodeFixContext, +} from "../types"; +import { + getTokenAtPosition, + suppressLeadingAndTrailingTrivia, +} from "../utilities"; const fixName = "strictClassInitialization"; const fixIdAddDefiniteAssignmentAssertions = "addMissingPropertyDefiniteAssignmentAssertions"; @@ -96,11 +106,11 @@ function getInfo(sourceFile: SourceFile, pos: number): Info | undefined { function getActionForAddMissingDefiniteAssignmentAssertion(context: CodeFixContext, info: Info): CodeFixAction | undefined { if (info.isJs) return undefined; - const changes = textChanges.ChangeTracker.with(context, t => addDefiniteAssignmentAssertion(t, context.sourceFile, info.prop)); + const changes = ChangeTracker.with(context, t => addDefiniteAssignmentAssertion(t, context.sourceFile, info.prop)); return createCodeFixAction(fixName, changes, [Diagnostics.Add_definite_assignment_assertion_to_property_0, info.prop.getText()], fixIdAddDefiniteAssignmentAssertions, Diagnostics.Add_definite_assignment_assertions_to_all_uninitialized_properties); } -function addDefiniteAssignmentAssertion(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration): void { +function addDefiniteAssignmentAssertion(changeTracker: ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration): void { suppressLeadingAndTrailingTrivia(propertyDeclaration); const property = factory.updatePropertyDeclaration( propertyDeclaration, @@ -114,11 +124,11 @@ function addDefiniteAssignmentAssertion(changeTracker: textChanges.ChangeTracker } function getActionForAddMissingUndefinedType(context: CodeFixContext, info: Info): CodeFixAction { - const changes = textChanges.ChangeTracker.with(context, t => addUndefinedType(t, context.sourceFile, info)); + const changes = ChangeTracker.with(context, t => addUndefinedType(t, context.sourceFile, info)); return createCodeFixAction(fixName, changes, [Diagnostics.Add_undefined_type_to_property_0, info.prop.name.getText()], fixIdAddUndefinedType, Diagnostics.Add_undefined_type_to_all_uninitialized_properties); } -function addUndefinedType(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, info: Info): void { +function addUndefinedType(changeTracker: ChangeTracker, sourceFile: SourceFile, info: Info): void { const undefinedTypeNode = factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword); const types = isUnionTypeNode(info.type) ? info.type.types.concat(undefinedTypeNode) : [info.type, undefinedTypeNode]; const unionTypeNode = factory.createUnionTypeNode(types); @@ -137,11 +147,11 @@ function getActionForAddMissingInitializer(context: CodeFixContext, info: Info): const initializer = getInitializer(checker, info.prop); if (!initializer) return undefined; - const changes = textChanges.ChangeTracker.with(context, t => addInitializer(t, context.sourceFile, info.prop, initializer)); + const changes = ChangeTracker.with(context, t => addInitializer(t, context.sourceFile, info.prop, initializer)); return createCodeFixAction(fixName, changes, [Diagnostics.Add_initializer_to_property_0, info.prop.name.getText()], fixIdAddInitializer, Diagnostics.Add_initializers_to_all_uninitialized_properties); } -function addInitializer(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration, initializer: Expression): void { +function addInitializer(changeTracker: ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration, initializer: Expression): void { suppressLeadingAndTrailingTrivia(propertyDeclaration); const property = factory.updatePropertyDeclaration( propertyDeclaration, diff --git a/src/services/codefixes/fixUnmatchedParameter.ts b/src/services/codefixes/fixUnmatchedParameter.ts index bdb4bbbb28df0..6f0d4e6128925 100644 --- a/src/services/codefixes/fixUnmatchedParameter.ts +++ b/src/services/codefixes/fixUnmatchedParameter.ts @@ -1,32 +1,38 @@ import { - __String, append, - CodeFixAction, - CodeFixContext, - Diagnostics, - factory, firstDefined, - getHostSignatureFromJSDoc, - getJSDocTags, - getTokenAtPosition, - Identifier, + length, + map, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isIdentifier, isJSDocParameterTag, +} from "../../compiler/factory/nodeTests"; +import { + __String, + Identifier, JSDocParameterTag, JSDocTag, - length, - map, SignatureDeclaration, SourceFile, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { getHostSignatureFromJSDoc } from "../../compiler/utilities"; +import { getJSDocTags } from "../../compiler/utilitiesPublic"; import { createCodeFixAction, createCodeFixActionWithoutFixAll, createCombinedCodeActions, eachDiagnostic, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + CodeFixAction, + CodeFixContext, +} from "../types"; +import { getTokenAtPosition } from "../utilities"; const deleteUnmatchedParameter = "deleteUnmatchedParameter"; const renameUnmatchedParameter = "renameUnmatchedParameter"; @@ -51,7 +57,7 @@ registerCodeFix({ }, getAllCodeActions: function getAllCodeActionsToFixUnmatchedParameter(context) { const tagsToSignature = new Map(); - return createCombinedCodeActions(textChanges.ChangeTracker.with(context, changes => { + return createCombinedCodeActions(ChangeTracker.with(context, changes => { eachDiagnostic(context, errorCodes, ({ file, start }) => { const info = getInfo(file, start); if (info) { @@ -70,7 +76,7 @@ registerCodeFix({ }); function getDeleteAction(context: CodeFixContext, { name, signature, jsDocParameterTag }: Info) { - const changes = textChanges.ChangeTracker.with(context, changeTracker => + const changes = ChangeTracker.with(context, changeTracker => changeTracker.filterJSDocTags(context.sourceFile, signature, t => t !== jsDocParameterTag)); return createCodeFixAction( deleteUnmatchedParameter, @@ -107,7 +113,7 @@ function getRenameAction(context: CodeFixContext, { name, signature, jsDocParame jsDocParameterTag.isNameFirst, jsDocParameterTag.comment ); - const changes = textChanges.ChangeTracker.with(context, changeTracker => + const changes = ChangeTracker.with(context, changeTracker => changeTracker.replaceJSDocComment(sourceFile, signature, map(tags, t => t === jsDocParameterTag ? newJSDocParameterTag : t))); return createCodeFixActionWithoutFixAll(renameUnmatchedParameter, changes, [Diagnostics.Rename_param_tag_name_0_to_1, name.getText(sourceFile), parameterName]); } diff --git a/src/services/codefixes/fixUnreachableCode.ts b/src/services/codefixes/fixUnreachableCode.ts index 17afabda71a93..8a642126fd361 100644 --- a/src/services/codefixes/fixUnreachableCode.ts +++ b/src/services/codefixes/fixUnreachableCode.ts @@ -1,24 +1,28 @@ import { - Debug, - Diagnostics, emptyArray, - factory, - findAncestor, first, - getTokenAtPosition, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isBlock } from "../../compiler/factory/nodeTests"; +import { IfStatement, - isBlock, - isStatement, - sliceAfter, SourceFile, SyntaxKind, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { sliceAfter } from "../../compiler/utilities"; +import { + findAncestor, + isStatement, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "fixUnreachableCode"; const errorCodes = [Diagnostics.Unreachable_code_detected.code]; @@ -27,14 +31,14 @@ registerCodeFix({ getCodeActions(context) { const syntacticDiagnostics = context.program.getSyntacticDiagnostics(context.sourceFile, context.cancellationToken); if (syntacticDiagnostics.length) return; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, context.span.start, context.span.length, context.errorCode)); + const changes = ChangeTracker.with(context, t => doChange(t, context.sourceFile, context.span.start, context.span.length, context.errorCode)); return [createCodeFixAction(fixId, changes, Diagnostics.Remove_unreachable_code, fixId, Diagnostics.Remove_all_unreachable_code)]; }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => doChange(changes, diag.file, diag.start, diag.length, diag.code)), }); -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, start: number, length: number, errorCode: number): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, start: number, length: number, errorCode: number): void { const token = getTokenAtPosition(sourceFile, start); const statement = findAncestor(token, isStatement)!; if (statement.getStart(sourceFile) !== token.getStart(sourceFile)) { diff --git a/src/services/codefixes/fixUnreferenceableDecoratorMetadata.ts b/src/services/codefixes/fixUnreferenceableDecoratorMetadata.ts index ec5b5e6e3ca90..cf7a23dfbc8ab 100644 --- a/src/services/codefixes/fixUnreferenceableDecoratorMetadata.ts +++ b/src/services/codefixes/fixUnreferenceableDecoratorMetadata.ts @@ -1,33 +1,39 @@ import { append, - CodeFixAction, - Diagnostics, emptyArray, find, - forEachImportClauseDeclaration, - getTokenAtPosition, - ImportClause, - ImportEqualsDeclaration, - ImportSpecifier, + or, + tryCast, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { isIdentifier, isImportClause, isImportEqualsDeclaration, isImportSpecifier, +} from "../../compiler/factory/nodeTests"; +import { + ImportClause, + ImportEqualsDeclaration, + ImportSpecifier, Node, - or, Program, - refactor, - skipAlias, SourceFile, SymbolFlags, SyntaxKind, - textChanges, - tryCast, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + forEachImportClauseDeclaration, + skipAlias, +} from "../../compiler/utilities"; import { createCodeFixActionWithoutFixAll, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { doChangeNamedToNamespaceOrDefault } from "../refactors/convertImport"; +import { ChangeTracker } from "../textChanges"; +import { CodeFixAction } from "../types"; +import { getTokenAtPosition } from "../utilities"; const fixId = "fixUnreferenceableDecoratorMetadata"; const errorCodes = [Diagnostics.A_type_referenced_in_a_decorated_signature_must_be_imported_with_import_type_or_a_namespace_import_when_isolatedModules_and_emitDecoratorMetadata_are_enabled.code]; @@ -37,8 +43,8 @@ registerCodeFix({ const importDeclaration = getImportDeclaration(context.sourceFile, context.program, context.span.start); if (!importDeclaration) return; - const namespaceChanges = textChanges.ChangeTracker.with(context, t => importDeclaration.kind === SyntaxKind.ImportSpecifier && doNamespaceImportChange(t, context.sourceFile, importDeclaration, context.program)); - const typeOnlyChanges = textChanges.ChangeTracker.with(context, t => doTypeOnlyImportChange(t, context.sourceFile, importDeclaration, context.program)); + const namespaceChanges = ChangeTracker.with(context, t => importDeclaration.kind === SyntaxKind.ImportSpecifier && doNamespaceImportChange(t, context.sourceFile, importDeclaration, context.program)); + const typeOnlyChanges = ChangeTracker.with(context, t => doTypeOnlyImportChange(t, context.sourceFile, importDeclaration, context.program)); let actions: CodeFixAction[] | undefined; if (namespaceChanges.length) { actions = append(actions, createCodeFixActionWithoutFixAll(fixId, namespaceChanges, Diagnostics.Convert_named_imports_to_namespace_import)); @@ -65,7 +71,7 @@ function getImportDeclaration(sourceFile: SourceFile, program: Program, start: n // cannot be done cleanly, we could offer to *extract* the offending import to a // new type-only import declaration, but honestly I doubt anyone will ever use this // codefix at all, so it's probably not worth the lines of code. -function doTypeOnlyImportChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, importDeclaration: ImportClause | ImportSpecifier | ImportEqualsDeclaration, program: Program) { +function doTypeOnlyImportChange(changes: ChangeTracker, sourceFile: SourceFile, importDeclaration: ImportClause | ImportSpecifier | ImportEqualsDeclaration, program: Program) { if (importDeclaration.kind === SyntaxKind.ImportEqualsDeclaration) { changes.insertModifierBefore(sourceFile, SyntaxKind.TypeKeyword, importDeclaration.name); return; @@ -93,6 +99,6 @@ function doTypeOnlyImportChange(changes: textChanges.ChangeTracker, sourceFile: changes.insertModifierBefore(sourceFile, SyntaxKind.TypeKeyword, importClause); } -function doNamespaceImportChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, importDeclaration: ImportSpecifier, program: Program) { - refactor.doChangeNamedToNamespaceOrDefault(sourceFile, program, changes, importDeclaration.parent); +function doNamespaceImportChange(changes: ChangeTracker, sourceFile: SourceFile, importDeclaration: ImportSpecifier, program: Program) { + doChangeNamedToNamespaceOrDefault(sourceFile, program, changes, importDeclaration.parent); } diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index e9b0f2fc7ed12..dd9a4d96067b9 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -1,27 +1,18 @@ import { - ArrayBindingPattern, - CancellationToken, cast, - CodeFixAction, - Debug, - DiagnosticAndArguments, - DiagnosticMessage, - Diagnostics, - factory, - FileTextChanges, - FindAllReferences, first, forEach, - FunctionLikeDeclaration, - getJSDocParameterTags, - getTokenAtPosition, - Identifier, - ImportDeclaration, + map, + tryCast, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrayBindingPattern, isBinaryExpression, isCallExpression, isComputedPropertyName, - isDeclarationWithTypeParameterChildren, isExpressionStatement, isIdentifier, isImportClause, @@ -30,7 +21,6 @@ import { isJSDocTemplateTag, isMethodDeclaration, isMethodSignature, - isModifier, isObjectBindingPattern, isParameter, isPostfixUnaryExpression, @@ -38,25 +28,48 @@ import { isPropertyAccessExpression, isSuperKeyword, isVariableDeclarationList, - map, +} from "../../compiler/factory/nodeTests"; +import { + ArrayBindingPattern, + CancellationToken, + DiagnosticMessage, + FunctionLikeDeclaration, + Identifier, + ImportDeclaration, Node, ObjectBindingPattern, ParameterDeclaration, Program, - showModuleSpecifier, SourceFile, SyntaxKind, - textChanges, - tryCast, TypeChecker, VariableDeclaration, VariableDeclarationList, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + isDeclarationWithTypeParameterChildren, + showModuleSpecifier, +} from "../../compiler/utilities"; +import { + getJSDocParameterTags, + isModifier, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { Core as FindAllReferences } from "../findAllReferences"; +import { ChangeTracker } from "../textChanges"; +import { + CodeFixAction, + EntryKind, + FileTextChanges, +} from "../types"; +import { + DiagnosticAndArguments, + getTokenAtPosition, +} from "../utilities"; const fixName = "unusedIdentifier"; const fixIdPrefix = "unusedIdentifier_prefix"; @@ -82,19 +95,19 @@ registerCodeFix({ const token = getTokenAtPosition(sourceFile, context.span.start); if (isJSDocTemplateTag(token)) { - return [createDeleteFix(textChanges.ChangeTracker.with(context, t => t.delete(sourceFile, token)), Diagnostics.Remove_template_tag)]; + return [createDeleteFix(ChangeTracker.with(context, t => t.delete(sourceFile, token)), Diagnostics.Remove_template_tag)]; } if (token.kind === SyntaxKind.LessThanToken) { - const changes = textChanges.ChangeTracker.with(context, t => deleteTypeParameters(t, sourceFile, token)); + const changes = ChangeTracker.with(context, t => deleteTypeParameters(t, sourceFile, token)); return [createDeleteFix(changes, Diagnostics.Remove_type_parameters)]; } const importDecl = tryGetFullImport(token); if (importDecl) { - const changes = textChanges.ChangeTracker.with(context, t => t.delete(sourceFile, importDecl)); + const changes = ChangeTracker.with(context, t => t.delete(sourceFile, importDecl)); return [createCodeFixAction(fixName, changes, [Diagnostics.Remove_import_from_0, showModuleSpecifier(importDecl)], fixIdDeleteImports, Diagnostics.Delete_all_unused_imports)]; } else if (isImport(token)) { - const deletion = textChanges.ChangeTracker.with(context, t => tryDeleteDeclaration(sourceFile, token, t, checker, sourceFiles, program, cancellationToken, /*isFixAll*/ false)); + const deletion = ChangeTracker.with(context, t => tryDeleteDeclaration(sourceFile, token, t, checker, sourceFiles, program, cancellationToken, /*isFixAll*/ false)); if (deletion.length) { return [createCodeFixAction(fixName, deletion, [Diagnostics.Remove_unused_declaration_for_Colon_0, token.getText(sourceFile)], fixIdDeleteImports, Diagnostics.Delete_all_unused_imports)]; } @@ -108,31 +121,31 @@ registerCodeFix({ map(elements, e => e.getText(sourceFile)).join(", ") ]; return [ - createDeleteFix(textChanges.ChangeTracker.with(context, t => + createDeleteFix(ChangeTracker.with(context, t => deleteDestructuringElements(t, sourceFile, token.parent as ObjectBindingPattern | ArrayBindingPattern)), diagnostic) ]; } return [ - createDeleteFix(textChanges.ChangeTracker.with(context, t => + createDeleteFix(ChangeTracker.with(context, t => t.delete(sourceFile, token.parent.parent)), Diagnostics.Remove_unused_destructuring_declaration) ]; } if (canDeleteEntireVariableStatement(sourceFile, token)) { return [ - createDeleteFix(textChanges.ChangeTracker.with(context, t => + createDeleteFix(ChangeTracker.with(context, t => deleteEntireVariableStatement(t, sourceFile, token.parent as VariableDeclarationList)), Diagnostics.Remove_variable_statement) ]; } const result: CodeFixAction[] = []; if (token.kind === SyntaxKind.InferKeyword) { - const changes = textChanges.ChangeTracker.with(context, t => changeInferToUnknown(t, sourceFile, token)); + const changes = ChangeTracker.with(context, t => changeInferToUnknown(t, sourceFile, token)); const name = cast(token.parent, isInferTypeNode).typeParameter.name.text; result.push(createCodeFixAction(fixName, changes, [Diagnostics.Replace_infer_0_with_unknown, name], fixIdInfer, Diagnostics.Replace_all_unused_infer_with_unknown)); } else { - const deletion = textChanges.ChangeTracker.with(context, t => + const deletion = ChangeTracker.with(context, t => tryDeleteDeclaration(sourceFile, token, t, checker, sourceFiles, program, cancellationToken, /*isFixAll*/ false)); if (deletion.length) { const name = isComputedPropertyName(token.parent) ? token.parent : token; @@ -140,7 +153,7 @@ registerCodeFix({ } } - const prefix = textChanges.ChangeTracker.with(context, t => tryPrefixDeclaration(t, errorCode, sourceFile, token)); + const prefix = ChangeTracker.with(context, t => tryPrefixDeclaration(t, errorCode, sourceFile, token)); if (prefix.length) { result.push(createCodeFixAction(fixName, prefix, [Diagnostics.Prefix_0_with_an_underscore, token.getText(sourceFile)], fixIdPrefix, Diagnostics.Prefix_all_unused_declarations_with_where_possible)); } @@ -209,7 +222,7 @@ registerCodeFix({ }, }); -function changeInferToUnknown(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node): void { +function changeInferToUnknown(changes: ChangeTracker, sourceFile: SourceFile, token: Node): void { changes.replaceNode(sourceFile, token.parent, factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword)); } @@ -217,7 +230,7 @@ function createDeleteFix(changes: FileTextChanges[], diag: DiagnosticAndArgument return createCodeFixAction(fixName, changes, diag, fixIdDelete, Diagnostics.Delete_all_unused_declarations); } -function deleteTypeParameters(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node): void { +function deleteTypeParameters(changes: ChangeTracker, sourceFile: SourceFile, token: Node): void { changes.delete(sourceFile, Debug.checkDefined(cast(token.parent, isDeclarationWithTypeParameterChildren).typeParameters, "The type parameter to delete should exist")); } @@ -235,15 +248,15 @@ function canDeleteEntireVariableStatement(sourceFile: SourceFile, token: Node): return isVariableDeclarationList(token.parent) && first(token.parent.getChildren(sourceFile)) === token; } -function deleteEntireVariableStatement(changes: textChanges.ChangeTracker, sourceFile: SourceFile, node: VariableDeclarationList) { +function deleteEntireVariableStatement(changes: ChangeTracker, sourceFile: SourceFile, node: VariableDeclarationList) { changes.delete(sourceFile, node.parent.kind === SyntaxKind.VariableStatement ? node.parent : node); } -function deleteDestructuringElements(changes: textChanges.ChangeTracker, sourceFile: SourceFile, node: ObjectBindingPattern | ArrayBindingPattern) { +function deleteDestructuringElements(changes: ChangeTracker, sourceFile: SourceFile, node: ObjectBindingPattern | ArrayBindingPattern) { forEach(node.elements, n => changes.delete(sourceFile, n)); } -function tryPrefixDeclaration(changes: textChanges.ChangeTracker, errorCode: number, sourceFile: SourceFile, token: Node): void { +function tryPrefixDeclaration(changes: ChangeTracker, errorCode: number, sourceFile: SourceFile, token: Node): void { // Don't offer to prefix a property. if (errorCode === Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code) return; if (token.kind === SyntaxKind.InferKeyword) { @@ -278,10 +291,10 @@ function canPrefix(token: Identifier): boolean { return false; } -function tryDeleteDeclaration(sourceFile: SourceFile, token: Node, changes: textChanges.ChangeTracker, checker: TypeChecker, sourceFiles: readonly SourceFile[], program: Program, cancellationToken: CancellationToken, isFixAll: boolean) { +function tryDeleteDeclaration(sourceFile: SourceFile, token: Node, changes: ChangeTracker, checker: TypeChecker, sourceFiles: readonly SourceFile[], program: Program, cancellationToken: CancellationToken, isFixAll: boolean) { tryDeleteDeclarationWorker(token, changes, sourceFile, checker, sourceFiles, program, cancellationToken, isFixAll); if (isIdentifier(token)) { - FindAllReferences.Core.eachSymbolReferenceInFile(token, checker, sourceFile, (ref: Node) => { + FindAllReferences.eachSymbolReferenceInFile(token, checker, sourceFile, (ref: Node) => { if (isPropertyAccessExpression(ref.parent) && ref.parent.name === ref) ref = ref.parent; if (!isFixAll && mayDeleteExpression(ref)) { changes.delete(sourceFile, ref.parent.parent); @@ -290,12 +303,12 @@ function tryDeleteDeclaration(sourceFile: SourceFile, token: Node, changes: text } } -function tryDeleteDeclarationWorker(token: Node, changes: textChanges.ChangeTracker, sourceFile: SourceFile, checker: TypeChecker, sourceFiles: readonly SourceFile[], program: Program, cancellationToken: CancellationToken, isFixAll: boolean): void { +function tryDeleteDeclarationWorker(token: Node, changes: ChangeTracker, sourceFile: SourceFile, checker: TypeChecker, sourceFiles: readonly SourceFile[], program: Program, cancellationToken: CancellationToken, isFixAll: boolean): void { const { parent } = token; if (isParameter(parent)) { tryDeleteParameter(changes, sourceFile, parent, checker, sourceFiles, program, cancellationToken, isFixAll); } - else if (!(isFixAll && isIdentifier(token) && FindAllReferences.Core.isSymbolReferencedInFile(token, checker, sourceFile))) { + else if (!(isFixAll && isIdentifier(token) && FindAllReferences.isSymbolReferencedInFile(token, checker, sourceFile))) { const node = isImportClause(parent) ? token : isComputedPropertyName(parent) ? parent.parent : parent; Debug.assert(node !== sourceFile, "should not delete whole source file"); changes.delete(sourceFile, node); @@ -303,7 +316,7 @@ function tryDeleteDeclarationWorker(token: Node, changes: textChanges.ChangeTrac } function tryDeleteParameter( - changes: textChanges.ChangeTracker, + changes: ChangeTracker, sourceFile: SourceFile, parameter: ParameterDeclaration, checker: TypeChecker, @@ -313,7 +326,7 @@ function tryDeleteParameter( isFixAll = false): void { if (mayDeleteParameter(checker, sourceFile, parameter, sourceFiles, program, cancellationToken, isFixAll)) { if (parameter.modifiers && parameter.modifiers.length > 0 && - (!isIdentifier(parameter.name) || FindAllReferences.Core.isSymbolReferencedInFile(parameter.name, checker, sourceFile))) { + (!isIdentifier(parameter.name) || FindAllReferences.isSymbolReferencedInFile(parameter.name, checker, sourceFile))) { for (const modifier of parameter.modifiers) { if (isModifier(modifier)) { changes.deleteModifier(sourceFile, modifier); @@ -329,7 +342,7 @@ function tryDeleteParameter( function isNotProvidedArguments(parameter: ParameterDeclaration, checker: TypeChecker, sourceFiles: readonly SourceFile[]) { const index = parameter.parent.parameters.indexOf(parameter); // Just in case the call didn't provide enough arguments. - return !FindAllReferences.Core.someSignatureUsage(parameter.parent, sourceFiles, checker, (_, call) => !call || call.arguments.length > index); + return !FindAllReferences.someSignatureUsage(parameter.parent, sourceFiles, checker, (_, call) => !call || call.arguments.length > index); } function mayDeleteParameter(checker: TypeChecker, sourceFile: SourceFile, parameter: ParameterDeclaration, sourceFiles: readonly SourceFile[], program: Program, cancellationToken: CancellationToken, isFixAll: boolean): boolean { @@ -339,11 +352,11 @@ function mayDeleteParameter(checker: TypeChecker, sourceFile: SourceFile, parame case SyntaxKind.Constructor: const index = parent.parameters.indexOf(parameter); const referent = isMethodDeclaration(parent) ? parent.name : parent; - const entries = FindAllReferences.Core.getReferencedSymbolsForNode(parent.pos, referent, program, sourceFiles, cancellationToken); + const entries = FindAllReferences.getReferencedSymbolsForNode(parent.pos, referent, program, sourceFiles, cancellationToken); if (entries) { for (const entry of entries) { for (const reference of entry.references) { - if (reference.kind === FindAllReferences.EntryKind.Node) { + if (reference.kind === EntryKind.Node) { // argument in super(...) const isSuperCall = isSuperKeyword(reference.node) && isCallExpression(reference.node.parent) @@ -388,7 +401,7 @@ function mayDeleteParameter(checker: TypeChecker, sourceFile: SourceFile, parame } function isCallbackLike(checker: TypeChecker, sourceFile: SourceFile, name: Identifier): boolean { - return !!FindAllReferences.Core.eachSymbolReferenceInFile(name, checker, sourceFile, reference => + return !!FindAllReferences.eachSymbolReferenceInFile(name, checker, sourceFile, reference => isIdentifier(reference) && isCallExpression(reference.parent) && reference.parent.arguments.indexOf(reference) >= 0); } diff --git a/src/services/codefixes/fixUnusedLabel.ts b/src/services/codefixes/fixUnusedLabel.ts index 88e6aed5d41a6..d49b68b66e0ea 100644 --- a/src/services/codefixes/fixUnusedLabel.ts +++ b/src/services/codefixes/fixUnusedLabel.ts @@ -1,34 +1,36 @@ +import { cast } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { isLabeledStatement } from "../../compiler/factory/nodeTests"; +import { skipTrivia } from "../../compiler/scanner"; import { - cast, - Diagnostics, - findChildOfKind, - getTokenAtPosition, - isLabeledStatement, - positionsAreOnSameLine, - skipTrivia, SourceFile, SyntaxKind, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { positionsAreOnSameLine } from "../../compiler/utilities"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + findChildOfKind, + getTokenAtPosition, +} from "../utilities"; const fixId = "fixUnusedLabel"; const errorCodes = [Diagnostics.Unused_label.code]; registerCodeFix({ errorCodes, getCodeActions(context) { - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, context.span.start)); + const changes = ChangeTracker.with(context, t => doChange(t, context.sourceFile, context.span.start)); return [createCodeFixAction(fixId, changes, Diagnostics.Remove_unused_label, fixId, Diagnostics.Remove_all_unused_labels)]; }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => doChange(changes, diag.file, diag.start)), }); -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, start: number): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, start: number): void { const token = getTokenAtPosition(sourceFile, start); const labeledStatement = cast(token.parent, isLabeledStatement); const pos = token.getStart(sourceFile); diff --git a/src/services/codefixes/generateAccessors.ts b/src/services/codefixes/generateAccessors.ts index 96bee0d7f458b..5e01b14f54a14 100644 --- a/src/services/codefixes/generateAccessors.ts +++ b/src/services/codefixes/generateAccessors.ts @@ -1,60 +1,74 @@ import { - AccessorDeclaration, - canHaveDecorators, cast, - ClassLikeDeclaration, concatenate, - ConstructorDeclaration, - DeclarationName, - Diagnostics, - factory, - FileTextChanges, find, - findAncestor, - getClassExtendsHeritageElement, - getDecorators, - getEffectiveModifierFlags, - getFirstConstructorWithBody, - getLocaleSpecificMessage, - getTokenAtPosition, - getTypeAnnotationNode, - getUniqueName, - hasEffectiveReadonlyModifier, - hasStaticModifier, - Identifier, - InterfaceDeclaration, - isClassLike, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isElementAccessExpression, - isFunctionLike, isIdentifier, - isParameterPropertyDeclaration, isPropertyAccessExpression, isPropertyAssignment, isPropertyDeclaration, - isSourceFileJS, isStringLiteral, isUnionTypeNode, - isWriteAccess, +} from "../../compiler/factory/nodeTests"; +import { canHaveDecorators } from "../../compiler/factory/utilitiesPublic"; +import { + AccessorDeclaration, + ClassLikeDeclaration, + ConstructorDeclaration, + DeclarationName, + Identifier, + InterfaceDeclaration, ModifierFlags, ModifierLike, Node, - nodeOverlapsWithStartEnd, ObjectLiteralExpression, - ParameterPropertyDeclaration, Program, PropertyAssignment, PropertyDeclaration, - refactor, SourceFile, - startsWithUnderscore, StringLiteral, - suppressLeadingAndTrailingTrivia, SymbolFlags, SyntaxKind, - textChanges, TypeChecker, TypeNode, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + getClassExtendsHeritageElement, + getEffectiveModifierFlags, + getFirstConstructorWithBody, + getLocaleSpecificMessage, + getTypeAnnotationNode, + hasEffectiveReadonlyModifier, + hasStaticModifier, + isSourceFileJS, + isWriteAccess, +} from "../../compiler/utilities"; +import { + findAncestor, + getDecorators, + isClassLike, + isFunctionLike, + isParameterPropertyDeclaration, + ParameterPropertyDeclaration, +} from "../../compiler/utilitiesPublic"; +import { isRefactorErrorInfo } from "../refactors/helpers"; +import { ChangeTracker } from "../textChanges"; +import { + FileTextChanges, + RefactorErrorInfo, + TextChangesContext, +} from "../types"; +import { + getTokenAtPosition, + getUniqueName, + nodeOverlapsWithStartEnd, + startsWithUnderscore, + suppressLeadingAndTrailingTrivia, +} from "../utilities"; /** @internal */ export type AcceptedDeclaration = ParameterPropertyDeclaration | PropertyDeclaration | PropertyAssignment; @@ -64,7 +78,7 @@ export type AcceptedNameType = Identifier | StringLiteral; export type ContainerDeclaration = ClassLikeDeclaration | ObjectLiteralExpression; /** @internal */ -export type AccessorOrRefactorErrorInfo = AccessorInfo | refactor.RefactorErrorInfo; +export type AccessorOrRefactorErrorInfo = AccessorInfo | RefactorErrorInfo; /** @internal */ export interface AccessorInfo { readonly container: ContainerDeclaration; @@ -79,11 +93,11 @@ export interface AccessorInfo { } /** @internal */ -export function generateAccessorFromProperty(file: SourceFile, program: Program, start: number, end: number, context: textChanges.TextChangesContext, _actionName: string): FileTextChanges[] | undefined { +export function generateAccessorFromProperty(file: SourceFile, program: Program, start: number, end: number, context: TextChangesContext, _actionName: string): FileTextChanges[] | undefined { const fieldInfo = getAccessorConvertiblePropertyAtPosition(file, program, start, end); - if (!fieldInfo || refactor.isRefactorErrorInfo(fieldInfo)) return undefined; + if (!fieldInfo || isRefactorErrorInfo(fieldInfo)) return undefined; - const changeTracker = textChanges.ChangeTracker.fromContext(context); + const changeTracker = ChangeTracker.fromContext(context); const { isStatic, isReadonly, fieldName, accessorName, originalName, type, container, declaration } = fieldInfo; suppressLeadingAndTrailingTrivia(fieldName); @@ -245,7 +259,7 @@ function generateSetAccessor(fieldName: AcceptedNameType, accessorName: Accepted ); } -function updatePropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyDeclaration, type: TypeNode | undefined, fieldName: AcceptedNameType, modifiers: readonly ModifierLike[] | undefined) { +function updatePropertyDeclaration(changeTracker: ChangeTracker, file: SourceFile, declaration: PropertyDeclaration, type: TypeNode | undefined, fieldName: AcceptedNameType, modifiers: readonly ModifierLike[] | undefined) { const property = factory.updatePropertyDeclaration( declaration, modifiers, @@ -257,12 +271,12 @@ function updatePropertyDeclaration(changeTracker: textChanges.ChangeTracker, fil changeTracker.replaceNode(file, declaration, property); } -function updatePropertyAssignmentDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyAssignment, fieldName: AcceptedNameType) { +function updatePropertyAssignmentDeclaration(changeTracker: ChangeTracker, file: SourceFile, declaration: PropertyAssignment, fieldName: AcceptedNameType) { const assignment = factory.updatePropertyAssignment(declaration, fieldName, declaration.initializer); changeTracker.replacePropertyAssignment(file, declaration, assignment); } -function updateFieldDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: AcceptedDeclaration, type: TypeNode | undefined, fieldName: AcceptedNameType, modifiers: readonly ModifierLike[] | undefined) { +function updateFieldDeclaration(changeTracker: ChangeTracker, file: SourceFile, declaration: AcceptedDeclaration, type: TypeNode | undefined, fieldName: AcceptedNameType, modifiers: readonly ModifierLike[] | undefined) { if (isPropertyDeclaration(declaration)) { updatePropertyDeclaration(changeTracker, file, declaration, type, fieldName, modifiers); } @@ -275,13 +289,13 @@ function updateFieldDeclaration(changeTracker: textChanges.ChangeTracker, file: } } -function insertAccessor(changeTracker: textChanges.ChangeTracker, file: SourceFile, accessor: AccessorDeclaration, declaration: AcceptedDeclaration, container: ContainerDeclaration) { +function insertAccessor(changeTracker: ChangeTracker, file: SourceFile, accessor: AccessorDeclaration, declaration: AcceptedDeclaration, container: ContainerDeclaration) { isParameterPropertyDeclaration(declaration, declaration.parent) ? changeTracker.insertMemberAtStart(file, container as ClassLikeDeclaration, accessor) : isPropertyAssignment(declaration) ? changeTracker.insertNodeAfterComma(file, declaration, accessor) : changeTracker.insertNodeAfter(file, declaration, accessor); } -function updateReadonlyPropertyInitializerStatementConstructor(changeTracker: textChanges.ChangeTracker, file: SourceFile, constructor: ConstructorDeclaration, fieldName: string, originalName: string) { +function updateReadonlyPropertyInitializerStatementConstructor(changeTracker: ChangeTracker, file: SourceFile, constructor: ConstructorDeclaration, fieldName: string, originalName: string) { if (!constructor.body) return; constructor.body.forEachChild(function recur(node) { if (isElementAccessExpression(node) && diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 1bc5bbb658c27..b99f0b58c15e1 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -1,48 +1,25 @@ import { - AccessorDeclaration, append, arrayFrom, - ArrowFunction, - Block, - CallExpression, - CharacterCodes, - ClassLikeDeclaration, - CodeFixContextBase, - Debug, - Diagnostics, emptyArray, - EntityName, - Expression, - factory, find, flatMap, - FunctionDeclaration, - FunctionExpression, - GetAccessorDeclaration, - getAllAccessorDeclarations, - getEffectiveModifierFlags, - getEmitScriptTarget, - getFirstIdentifier, - getModuleSpecifierResolverHost, - getNameForExportedSymbol, - getNameOfDeclaration, - getQuotePreference, - getSetAccessorValueParameter, - getSynthesizedDeepClone, - getTokenAtPosition, - getTsConfigObjectLiteralExpression, - Identifier, - idText, - IntersectionType, + length, + map, + sameMap, + some, + tryCast, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrowFunction, - isAutoAccessorPropertyDeclaration, isFunctionDeclaration, isFunctionExpression, isGetAccessorDeclaration, isIdentifier, isImportTypeNode, - isInJSFile, - isLiteralImportTypeNode, isMethodDeclaration, isObjectLiteralExpression, isPropertyAccessExpression, @@ -50,9 +27,23 @@ import { isSetAccessorDeclaration, isStringLiteral, isYieldExpression, - LanguageServiceHost, - length, - map, +} from "../../compiler/factory/nodeTests"; +import { setTextRange } from "../../compiler/factory/utilitiesPublic"; +import { nullTransformationContext } from "../../compiler/transformer"; +import { + AccessorDeclaration, + ArrowFunction, + Block, + CallExpression, + CharacterCodes, + ClassLikeDeclaration, + EntityName, + Expression, + FunctionDeclaration, + FunctionExpression, + GetAccessorDeclaration, + Identifier, + IntersectionType, MethodDeclaration, MethodSignature, Modifier, @@ -61,7 +52,6 @@ import { NodeArray, NodeBuilderFlags, NodeFlags, - nullTransformationContext, ObjectFlags, ObjectLiteralExpression, ObjectType, @@ -70,24 +60,16 @@ import { PropertyAssignment, PropertyDeclaration, PropertyName, - QuotePreference, - sameMap, ScriptTarget, SetAccessorDeclaration, - setTextRange, Signature, SignatureDeclaration, - signatureHasRestParameter, - some, SourceFile, Symbol, SymbolFlags, SymbolTracker, SyntaxKind, - textChanges, TextSpan, - textSpanEnd, - tryCast, TsConfigSourceFile, Type, TypeChecker, @@ -96,10 +78,42 @@ import { TypeParameterDeclaration, UnionType, UserPreferences, +} from "../../compiler/types"; +import { + getAllAccessorDeclarations, + getEffectiveModifierFlags, + getEmitScriptTarget, + getFirstIdentifier, + getSetAccessorValueParameter, + getTsConfigObjectLiteralExpression, + isInJSFile, + isLiteralImportTypeNode, + signatureHasRestParameter, +} from "../../compiler/utilities"; +import { + getNameOfDeclaration, + idText, + isAutoAccessorPropertyDeclaration, + textSpanEnd, +} from "../../compiler/utilitiesPublic"; +import { visitEachChild, visitNode, -} from "../_namespaces/ts"; -import { ImportAdder } from "../_namespaces/ts.codefix"; +} from "../../compiler/visitorPublic"; +import { ChangeTracker } from "../textChanges"; +import { + CodeFixContextBase, + LanguageServiceHost, +} from "../types"; +import { + getModuleSpecifierResolverHost, + getNameForExportedSymbol, + getQuotePreference, + getSynthesizedDeepClone, + getTokenAtPosition, + QuotePreference, +} from "../utilities"; +import { ImportAdder } from "./importAdder"; /** * Finds members of the resolved type that are missing in the class pointed to by class decl @@ -765,7 +779,7 @@ export function createStubbedBody(text: string, quotePreference: QuotePreference /** @internal */ export function setJsonCompilerOptionValues( - changeTracker: textChanges.ChangeTracker, + changeTracker: ChangeTracker, configFile: TsConfigSourceFile, options: [string, Expression][] ) { @@ -798,7 +812,7 @@ export function setJsonCompilerOptionValues( /** @internal */ export function setJsonCompilerOptionValue( - changeTracker: textChanges.ChangeTracker, + changeTracker: ChangeTracker, configFile: TsConfigSourceFile, optionName: string, optionValue: Expression, diff --git a/src/services/codefixes/importAdder.ts b/src/services/codefixes/importAdder.ts new file mode 100644 index 0000000000000..3a4688e20306e --- /dev/null +++ b/src/services/codefixes/importAdder.ts @@ -0,0 +1,1546 @@ +import { + getNodeId, + getSymbolId, +} from "../../compiler/checkerUtilities"; +import { + arrayFrom, + cast, + combine, + compareBooleans, + compareValues, + createMultiMap, + emptyArray, + every, + first, + firstDefined, + flatMap, + flatMapIterator, + last, + mapDefined, + memoizeOne, + MultiMap, + removeSuffix, + single, + some, + sort, + stableSort, + startsWith, + tryCast, +} from "../../compiler/core"; +import { Comparison } from "../../compiler/corePublic"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { + isExternalModuleReference, + isIdentifier, + isImportEqualsDeclaration, + isJsxClosingElement, + isJsxOpeningFragment, + isNamedImports, + isNamespaceImport, + isStringLiteral, +} from "../../compiler/factory/nodeTests"; +import { pathContainsNodeModules } from "../../compiler/moduleNameResolver"; +import { + getModuleSpecifiersWithCacheInfo, + tryGetModuleSpecifiersFromCache, +} from "../../compiler/moduleSpecifiers"; +import { isExternalModule } from "../../compiler/parser"; +import { + getBaseFileName, + getDirectoryPath, + pathIsBareSpecifier, + toPath, +} from "../../compiler/path"; +import { + isIdentifierPart, + isIdentifierStart, +} from "../../compiler/scanner"; +import { + AnyImportOrRequire, + AnyImportOrRequireStatement, + AnyImportSyntax, + CancellationToken, + CompilerOptions, + DiagnosticWithLocation, + Identifier, + ImportClause, + ImportEqualsDeclaration, + ImportsNotUsedAsValues, + InternalSymbolName, + ModuleKind, + ModuleResolutionKind, + NamedImports, + Node, + NodeFlags, + ObjectBindingPattern, + Path, + Program, + RequireVariableStatement, + ScriptTarget, + SourceFile, + StringLiteral, + Symbol, + SymbolFlags, + SymbolId, + SyntaxKind, + TypeChecker, + TypeOnlyAliasDeclaration, + UserPreferences, +} from "../../compiler/types"; +import { + compareNumberOfDirectorySeparators, + getAllowSyntheticDefaultImports, + getEmitModuleKind, + getEmitModuleResolutionKind, + getEmitScriptTarget, + getSourceFileOfNode, + hostGetCanonicalFileName, + importFromModuleSpecifier, + isInJSFile, + isIntrinsicJsxName, + isJSXTagName, + isSourceFileJS, + isStringANonContextualKeyword, + isUMDExportSymbol, + isValidTypeOnlyAliasUseSite, + isVariableDeclarationInitializedToRequire, + Mutable, + nodeIsMissing, + removeFileExtension, + skipAlias, + stripQuotes, + tryGetModuleSpecifierFromDeclaration, +} from "../../compiler/utilities"; +import { + escapeLeadingUnderscores, + isJsxOpeningLikeElement, + isStringLiteralLike, + isTypeOnlyImportOrExportDeclaration, +} from "../../compiler/utilitiesPublic"; +import { createCodeFixAction } from "../codeFixProvider"; +import { + forEachExternalModuleToImportFrom, + getDefaultLikeExportInfo, + getExportInfoMap, + ImportKind, + isImportableFile, +} from "../exportInfoMap"; +import { + compareImportOrExportSpecifiers, + getImportSpecifierInsertionIndex, + importSpecifiersAreSorted, +} from "../organizeImports"; +import { ChangeTracker } from "../textChanges"; +import { + CodeAction, + CodeFixAction, + CodeFixContextBase, + ExportKind, + FormatContext, + LanguageServiceHost, + SymbolExportInfo, + TextChangesContext, +} from "../types"; +import { + createModuleSpecifierResolutionHost, + createPackageJsonImportFilter, + DiagnosticAndArguments, + getMeaningFromDeclaration, + getMeaningFromLocation, + getNameForExportedSymbol, + getQuoteFromPreference, + getQuotePreference, + getTokenAtPosition, + getTypeKeywordOfTypeOnlyImport, + getUniqueSymbolId, + insertImports, + jsxModeNeedsExplicitImport, + makeImport, + makeStringLiteral, + moduleResolutionUsesNodeModules, + PackageJsonImportFilter, + QuotePreference, + SemanticMeaning, + shouldUseUriStyleNodeCoreModules, +} from "../utilities"; + +/** @internal */ +export const fixName = "import"; + +/** @internal */ +export const fixId = "fixMissingImport"; + +/** + * Computes multiple import additions to a file and writes them to a ChangeTracker. + * + * @internal + */ +export interface ImportAdder { + hasFixes(): boolean; + addImportFromDiagnostic: (diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) => void; + addImportFromExportedSymbol: (exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean) => void; + writeFixes: (changeTracker: ChangeTracker) => void; +} + +/** + * Computes module specifiers for multiple import additions to a file. + * + * @internal + */ +export interface ImportSpecifierResolver { + getModuleSpecifierForBestExportInfo( + exportInfo: readonly SymbolExportInfo[], + symbolName: string, + position: number, + isValidTypeOnlyUseSite: boolean, + fromCacheOnly?: boolean + ): { exportInfo?: SymbolExportInfo, moduleSpecifier: string, computedWithoutCacheCount: number } | undefined; +} + +/** @internal */ +export type ImportFix = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport | FixPromoteTypeOnlyImport; +type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport; + +interface Import { + readonly name: string; + readonly addAsTypeOnly: AddAsTypeOnly; +} + +interface ImportsCollection { + readonly defaultImport?: Import; + readonly namedImports?: Map; + readonly namespaceLikeImport?: { + readonly importKind: ImportKind.CommonJS | ImportKind.Namespace; + readonly name: string; + readonly addAsTypeOnly: AddAsTypeOnly; + }; +} + +interface AddToExistingState { + readonly importClauseOrBindingPattern: ImportClause | ObjectBindingPattern; + defaultImport: Import | undefined; + readonly namedImports: Map; +} + +/** + * Sorted with the preferred fix coming first. + * @internal + */ +export const enum ImportFixKind { UseNamespace, JsdocTypeImport, AddToExisting, AddNew, PromoteTypeOnly } + +/** + * These should not be combined as bitflags, but are given powers of 2 values to + * easily detect conflicts between `NotAllowed` and `Required` by giving them a unique sum. + * They're also ordered in terms of increasing priority for a fix-all scenario (see `reduceAddAsTypeOnlyValues`). + * @internal + */ +export const enum AddAsTypeOnly { + Allowed = 1 << 0, + Required = 1 << 1, + NotAllowed = 1 << 2, +} + +/** + * Properties are be undefined if fix is derived from an existing import + * @internal + */ +export interface ImportFixBase { + readonly isReExport?: boolean; + readonly exportInfo?: SymbolExportInfo; + readonly moduleSpecifier: string; +} + +/** @internal */ +export interface FixUseNamespaceImport extends ImportFixBase { + readonly kind: ImportFixKind.UseNamespace; + readonly namespacePrefix: string; + readonly position: number; +} + +/** @internal */ +export interface FixAddJsdocTypeImport extends ImportFixBase { + readonly kind: ImportFixKind.JsdocTypeImport; + readonly position: number; + readonly isReExport: boolean; + readonly exportInfo: SymbolExportInfo; +} + +/** @internal */ +export interface FixAddToExistingImport extends ImportFixBase { + readonly kind: ImportFixKind.AddToExisting; + readonly importClauseOrBindingPattern: ImportClause | ObjectBindingPattern; + readonly importKind: ImportKind.Default | ImportKind.Named; + readonly addAsTypeOnly: AddAsTypeOnly; +} + +/** @internal */ +export interface FixAddNewImport extends ImportFixBase { + readonly kind: ImportFixKind.AddNew; + readonly importKind: ImportKind; + readonly addAsTypeOnly: AddAsTypeOnly; + readonly useRequire: boolean; +} + +/** @internal */ +export interface FixPromoteTypeOnlyImport { + readonly kind: ImportFixKind.PromoteTypeOnly; + readonly typeOnlyAliasDeclaration: TypeOnlyAliasDeclaration; +} + +/** + * Information needed to augment an existing import declaration. + * @internal + */ +export interface FixAddToExistingImportInfo { + readonly declaration: AnyImportOrRequire; + readonly importKind: ImportKind; + readonly targetFlags: SymbolFlags; + readonly symbol: Symbol; +} + +/** @internal */ +export interface FixInfo { + readonly fix: ImportFix; + readonly symbolName: string; + readonly errorIdentifierText: string | undefined; + readonly isJsxNamespaceFix?: boolean; +} + +/** @internal */ +export function createImportAdder(sourceFile: SourceFile, program: Program, preferences: UserPreferences, host: LanguageServiceHost, useAutoImportProvider: boolean, cancellationToken?: CancellationToken): ImportAdder { + return createImportAdderWorker(sourceFile, program, useAutoImportProvider, preferences, host, cancellationToken); +} + +/** @internal */ +export function createImportSpecifierResolver(importingFile: SourceFile, program: Program, host: LanguageServiceHost, preferences: UserPreferences): ImportSpecifierResolver { + const packageJsonImportFilter = createPackageJsonImportFilter(importingFile, preferences, host); + const importMap = createExistingImportMap(program.getTypeChecker(), importingFile, program.getCompilerOptions()); + return { getModuleSpecifierForBestExportInfo }; + + function getModuleSpecifierForBestExportInfo( + exportInfo: readonly SymbolExportInfo[], + symbolName: string, + position: number, + isValidTypeOnlyUseSite: boolean, + fromCacheOnly?: boolean, + ): { exportInfo?: SymbolExportInfo, moduleSpecifier: string, computedWithoutCacheCount: number } | undefined { + const { fixes, computedWithoutCacheCount } = getImportFixes( + exportInfo, + { symbolName, position }, + isValidTypeOnlyUseSite, + /*useRequire*/ false, + program, + importingFile, + host, + preferences, + importMap, + fromCacheOnly); + const result = getBestFix(fixes, importingFile, program, packageJsonImportFilter, host); + return result && { ...result, computedWithoutCacheCount }; + } +} + +/** @internal */ +export function getImportCompletionAction( + targetSymbol: Symbol, + moduleSymbol: Symbol, + sourceFile: SourceFile, + symbolName: string, + isJsxTagName: boolean, + host: LanguageServiceHost, + program: Program, + formatContext: FormatContext, + position: number, + preferences: UserPreferences, + cancellationToken: CancellationToken, +): { readonly moduleSpecifier: string, readonly codeAction: CodeAction } { + const compilerOptions = program.getCompilerOptions(); + const exportInfos = pathIsBareSpecifier(stripQuotes(moduleSymbol.name)) + ? [getSingleExportInfoForSymbol(targetSymbol, moduleSymbol, program, host)] + : getAllExportInfoForSymbol(sourceFile, targetSymbol, symbolName, isJsxTagName, program, host, preferences, cancellationToken); + + Debug.assertIsDefined(exportInfos); + const useRequire = shouldUseRequire(sourceFile, program); + const isValidTypeOnlyUseSite = isValidTypeOnlyAliasUseSite(getTokenAtPosition(sourceFile, position)); + const fix = Debug.checkDefined(getImportFixForSymbol(sourceFile, exportInfos, moduleSymbol, program, { symbolName, position }, isValidTypeOnlyUseSite, useRequire, host, preferences)); + return { + moduleSpecifier: fix.moduleSpecifier, + codeAction: codeFixActionToCodeAction(codeActionForFix( + { host, formatContext, preferences }, + sourceFile, + symbolName, + fix, + /*includeSymbolNameInDescription*/ false, + getQuotePreference(sourceFile, preferences), compilerOptions)) + }; +} + +/** @internal */ +export function getPromoteTypeOnlyCompletionAction(sourceFile: SourceFile, symbolToken: Identifier, program: Program, host: LanguageServiceHost, formatContext: FormatContext, preferences: UserPreferences) { + const compilerOptions = program.getCompilerOptions(); + const symbolName = single(getSymbolNamesToImport(sourceFile, program.getTypeChecker(), symbolToken, compilerOptions)); + const fix = getTypeOnlyPromotionFix(sourceFile, symbolToken, symbolName, program); + const includeSymbolNameInDescription = symbolName !== symbolToken.text; + return fix && codeFixActionToCodeAction(codeActionForFix({ host, formatContext, preferences }, sourceFile, symbolName, fix, includeSymbolNameInDescription, QuotePreference.Double, compilerOptions)); +} + +/** + * @param forceImportKeyword Indicates that the user has already typed `import`, so the result must start with `import`. + * (In other words, do not allow `const x = require("...")` for JS files.) + * + * @internal + */ +export function getImportKind(importingFile: SourceFile, exportKind: ExportKind, compilerOptions: CompilerOptions, forceImportKeyword?: boolean): ImportKind { + switch (exportKind) { + case ExportKind.Named: return ImportKind.Named; + case ExportKind.Default: return ImportKind.Default; + case ExportKind.ExportEquals: return getExportEqualsImportKind(importingFile, compilerOptions, !!forceImportKeyword); + case ExportKind.UMD: return getUmdImportKind(importingFile, compilerOptions, !!forceImportKeyword); + default: return Debug.assertNever(exportKind); + } +} + +/** @internal */ +export function getFixInfos(context: CodeFixContextBase, errorCode: number, pos: number, useAutoImportProvider: boolean): readonly FixInfo[] | undefined { + const symbolToken = getTokenAtPosition(context.sourceFile, pos); + let info; + if (errorCode === Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code) { + info = getFixesInfoForUMDImport(context, symbolToken); + } + else if (!isIdentifier(symbolToken)) { + return undefined; + } + else if (errorCode === Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type.code) { + const symbolName = single(getSymbolNamesToImport(context.sourceFile, context.program.getTypeChecker(), symbolToken, context.program.getCompilerOptions())); + const fix = getTypeOnlyPromotionFix(context.sourceFile, symbolToken, symbolName, context.program); + return fix && [{ fix, symbolName, errorIdentifierText: symbolToken.text }]; + } + else { + info = getFixesInfoForNonUMDImport(context, symbolToken, useAutoImportProvider); + } + + const packageJsonImportFilter = createPackageJsonImportFilter(context.sourceFile, context.preferences, context.host); + return info && sortFixInfo(info, context.sourceFile, context.program, packageJsonImportFilter, context.host); +} + +/** @internal */ +export function codeActionForFix(context: TextChangesContext, sourceFile: SourceFile, symbolName: string, fix: ImportFix, includeSymbolNameInDescription: boolean, quotePreference: QuotePreference, compilerOptions: CompilerOptions): CodeFixAction { + let diag!: DiagnosticAndArguments; + const changes = ChangeTracker.with(context, tracker => { + diag = codeActionForFixWorker(tracker, sourceFile, symbolName, fix, includeSymbolNameInDescription, quotePreference, compilerOptions); + }); + return createCodeFixAction(fixName, changes, diag, fixId, Diagnostics.Add_all_missing_imports); +} + +/** @internal */ +export function moduleSymbolToValidIdentifier(moduleSymbol: Symbol, target: ScriptTarget | undefined, forceCapitalize: boolean): string { + return moduleSpecifierToValidIdentifier(removeFileExtension(stripQuotes(moduleSymbol.name)), target, forceCapitalize); +} + +/** @internal */ +export function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget | undefined, forceCapitalize?: boolean): string { + const baseName = getBaseFileName(removeSuffix(moduleSpecifier, "/index")); + let res = ""; + let lastCharWasValid = true; + const firstCharCode = baseName.charCodeAt(0); + if (isIdentifierStart(firstCharCode, target)) { + res += String.fromCharCode(firstCharCode); + if (forceCapitalize) { + res = res.toUpperCase(); + } + } + else { + lastCharWasValid = false; + } + for (let i = 1; i < baseName.length; i++) { + const ch = baseName.charCodeAt(i); + const isValid = isIdentifierPart(ch, target); + if (isValid) { + let char = String.fromCharCode(ch); + if (!lastCharWasValid) { + char = char.toUpperCase(); + } + res += char; + } + lastCharWasValid = isValid; + } + // Need `|| "_"` to ensure result isn't empty. + return !isStringANonContextualKeyword(res) ? res || "_" : `_${res}`; +} + +function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAutoImportProvider: boolean, preferences: UserPreferences, host: LanguageServiceHost, cancellationToken: CancellationToken | undefined): ImportAdder { + const compilerOptions = program.getCompilerOptions(); + // Namespace fixes don't conflict, so just build a list. + const addToNamespace: FixUseNamespaceImport[] = []; + const importType: FixAddJsdocTypeImport[] = []; + /** Keys are import clause node IDs. */ + const addToExisting = new Map(); + + type NewImportsKey = `${0 | 1}|${string}`; + /** Use `getNewImportEntry` for access */ + const newImports = new Map>(); + return { addImportFromDiagnostic, addImportFromExportedSymbol, writeFixes, hasFixes }; + + function addImportFromDiagnostic(diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) { + const info = getFixInfos(context, diagnostic.code, diagnostic.start, useAutoImportProvider); + if (!info || !info.length) return; + addImport(first(info)); + } + + function addImportFromExportedSymbol(exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean) { + const moduleSymbol = Debug.checkDefined(exportedSymbol.parent); + const symbolName = getNameForExportedSymbol(exportedSymbol, getEmitScriptTarget(compilerOptions)); + const checker = program.getTypeChecker(); + const symbol = checker.getMergedSymbol(skipAlias(exportedSymbol, checker)); + const exportInfo = getAllExportInfoForSymbol(sourceFile, symbol, symbolName, /*isJsxTagName*/ false, program, host, preferences, cancellationToken); + const useRequire = shouldUseRequire(sourceFile, program); + const fix = getImportFixForSymbol(sourceFile, Debug.checkDefined(exportInfo), moduleSymbol, program, /*useNamespaceInfo*/ undefined, !!isValidTypeOnlyUseSite, useRequire, host, preferences); + if (fix) { + addImport({ fix, symbolName, errorIdentifierText: undefined }); + } + } + + function addImport(info: FixInfo) { + const { fix, symbolName } = info; + switch (fix.kind) { + case ImportFixKind.UseNamespace: + addToNamespace.push(fix); + break; + case ImportFixKind.JsdocTypeImport: + importType.push(fix); + break; + case ImportFixKind.AddToExisting: { + const { importClauseOrBindingPattern, importKind, addAsTypeOnly } = fix; + const key = String(getNodeId(importClauseOrBindingPattern)); + let entry = addToExisting.get(key); + if (!entry) { + addToExisting.set(key, entry = { importClauseOrBindingPattern, defaultImport: undefined, namedImports: new Map() }); + } + if (importKind === ImportKind.Named) { + const prevValue = entry?.namedImports.get(symbolName); + entry.namedImports.set(symbolName, reduceAddAsTypeOnlyValues(prevValue, addAsTypeOnly)); + } + else { + Debug.assert(entry.defaultImport === undefined || entry.defaultImport.name === symbolName, "(Add to Existing) Default import should be missing or match symbolName"); + entry.defaultImport = { + name: symbolName, + addAsTypeOnly: reduceAddAsTypeOnlyValues(entry.defaultImport?.addAsTypeOnly, addAsTypeOnly), + }; + } + break; + } + case ImportFixKind.AddNew: { + const { moduleSpecifier, importKind, useRequire, addAsTypeOnly } = fix; + const entry = getNewImportEntry(moduleSpecifier, importKind, useRequire, addAsTypeOnly); + Debug.assert(entry.useRequire === useRequire, "(Add new) Tried to add an `import` and a `require` for the same module"); + + switch (importKind) { + case ImportKind.Default: + Debug.assert(entry.defaultImport === undefined || entry.defaultImport.name === symbolName, "(Add new) Default import should be missing or match symbolName"); + entry.defaultImport = { name: symbolName, addAsTypeOnly: reduceAddAsTypeOnlyValues(entry.defaultImport?.addAsTypeOnly, addAsTypeOnly) }; + break; + case ImportKind.Named: + const prevValue = (entry.namedImports ||= new Map()).get(symbolName); + entry.namedImports.set(symbolName, reduceAddAsTypeOnlyValues(prevValue, addAsTypeOnly)); + break; + case ImportKind.CommonJS: + case ImportKind.Namespace: + Debug.assert(entry.namespaceLikeImport === undefined || entry.namespaceLikeImport.name === symbolName, "Namespacelike import shoudl be missing or match symbolName"); + entry.namespaceLikeImport = { importKind, name: symbolName, addAsTypeOnly }; + break; + } + break; + } + case ImportFixKind.PromoteTypeOnly: + // Excluding from fix-all + break; + default: + Debug.assertNever(fix, `fix wasn't never - got kind ${(fix as ImportFix).kind}`); + } + + function reduceAddAsTypeOnlyValues(prevValue: AddAsTypeOnly | undefined, newValue: AddAsTypeOnly): AddAsTypeOnly { + // `NotAllowed` overrides `Required` because one addition of a new import might be required to be type-only + // because of `--importsNotUsedAsValues=error`, but if a second addition of the same import is `NotAllowed` + // to be type-only, the reason the first one was `Required` - the unused runtime dependency - is now moot. + // Alternatively, if one addition is `Required` because it has no value meaning under `--preserveValueImports` + // and `--isolatedModules`, it should be impossible for another addition to be `NotAllowed` since that would + // mean a type is being referenced in a value location. + return Math.max(prevValue ?? 0, newValue); + } + + function getNewImportEntry(moduleSpecifier: string, importKind: ImportKind, useRequire: boolean, addAsTypeOnly: AddAsTypeOnly): Mutable { + // A default import that requires type-only makes the whole import type-only. + // (We could add `default` as a named import, but that style seems undesirable.) + // Under `--preserveValueImports` and `--importsNotUsedAsValues=error`, if a + // module default-exports a type but named-exports some values (weird), you would + // have to use a type-only default import and non-type-only named imports. These + // require two separate import declarations, so we build this into the map key. + const typeOnlyKey = newImportsKey(moduleSpecifier, /*topLevelTypeOnly*/ true); + const nonTypeOnlyKey = newImportsKey(moduleSpecifier, /*topLevelTypeOnly*/ false); + const typeOnlyEntry = newImports.get(typeOnlyKey); + const nonTypeOnlyEntry = newImports.get(nonTypeOnlyKey); + const newEntry: ImportsCollection & { useRequire: boolean } = { + defaultImport: undefined, + namedImports: undefined, + namespaceLikeImport: undefined, + useRequire + }; + if (importKind === ImportKind.Default && addAsTypeOnly === AddAsTypeOnly.Required) { + if (typeOnlyEntry) return typeOnlyEntry; + newImports.set(typeOnlyKey, newEntry); + return newEntry; + } + if (addAsTypeOnly === AddAsTypeOnly.Allowed && (typeOnlyEntry || nonTypeOnlyEntry)) { + return (typeOnlyEntry || nonTypeOnlyEntry)!; + } + if (nonTypeOnlyEntry) { + return nonTypeOnlyEntry; + } + newImports.set(nonTypeOnlyKey, newEntry); + return newEntry; + } + + function newImportsKey(moduleSpecifier: string, topLevelTypeOnly: boolean): NewImportsKey { + return `${topLevelTypeOnly ? 1 : 0}|${moduleSpecifier}`; + } + } + + function writeFixes(changeTracker: ChangeTracker) { + const quotePreference = getQuotePreference(sourceFile, preferences); + for (const fix of addToNamespace) { + addNamespaceQualifier(changeTracker, sourceFile, fix); + } + for (const fix of importType) { + addImportType(changeTracker, sourceFile, fix, quotePreference); + } + addToExisting.forEach(({ importClauseOrBindingPattern, defaultImport, namedImports }) => { + doAddExistingFix( + changeTracker, + sourceFile, + importClauseOrBindingPattern, + defaultImport, + arrayFrom(namedImports.entries(), ([name, addAsTypeOnly]) => ({ addAsTypeOnly, name })), + compilerOptions); + }); + + let newDeclarations: AnyImportOrRequireStatement | readonly AnyImportOrRequireStatement[] | undefined; + newImports.forEach(({ useRequire, defaultImport, namedImports, namespaceLikeImport }, key) => { + const moduleSpecifier = key.slice(2); // From `${0 | 1}|${moduleSpecifier}` format + const getDeclarations = useRequire ? getNewRequires : getNewImports; + const declarations = getDeclarations( + moduleSpecifier, + quotePreference, + defaultImport, + namedImports && arrayFrom(namedImports.entries(), ([name, addAsTypeOnly]) => ({ addAsTypeOnly, name })), + namespaceLikeImport); + newDeclarations = combine(newDeclarations, declarations); + }); + if (newDeclarations) { + insertImports(changeTracker, sourceFile, newDeclarations, /*blankLineBetween*/ true); + } + } + + function hasFixes() { + return addToNamespace.length > 0 || importType.length > 0 || addToExisting.size > 0 || newImports.size > 0; + } +} + +function getImportFixForSymbol(sourceFile: SourceFile, exportInfos: readonly SymbolExportInfo[], moduleSymbol: Symbol, program: Program, useNamespaceInfo: { position: number, symbolName: string } | undefined, isValidTypeOnlyUseSite: boolean, useRequire: boolean, host: LanguageServiceHost, preferences: UserPreferences) { + Debug.assert(exportInfos.some(info => info.moduleSymbol === moduleSymbol || info.symbol.parent === moduleSymbol), "Some exportInfo should match the specified moduleSymbol"); + const packageJsonImportFilter = createPackageJsonImportFilter(sourceFile, preferences, host); + return getBestFix(getImportFixes(exportInfos, useNamespaceInfo, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences).fixes, sourceFile, program, packageJsonImportFilter, host); +} + +function codeFixActionToCodeAction({ description, changes, commands }: CodeFixAction): CodeAction { + return { description, changes, commands }; +} + +function getAllExportInfoForSymbol(importingFile: SourceFile, symbol: Symbol, symbolName: string, preferCapitalized: boolean, program: Program, host: LanguageServiceHost, preferences: UserPreferences, cancellationToken: CancellationToken | undefined): readonly SymbolExportInfo[] | undefined { + const getChecker = createGetChecker(program, host); + return getExportInfoMap(importingFile, host, program, preferences, cancellationToken) + .search(importingFile.path, preferCapitalized, name => name === symbolName, info => { + if (skipAlias(info[0].symbol, getChecker(info[0].isFromPackageJson)) === symbol) { + return info; + } + }); +} + +function getSingleExportInfoForSymbol(symbol: Symbol, moduleSymbol: Symbol, program: Program, host: LanguageServiceHost): SymbolExportInfo { + const compilerOptions = program.getCompilerOptions(); + const mainProgramInfo = getInfoWithChecker(program.getTypeChecker(), /*isFromPackageJson*/ false); + if (mainProgramInfo) { + return mainProgramInfo; + } + const autoImportProvider = host.getPackageJsonAutoImportProvider?.()?.getTypeChecker(); + return Debug.checkDefined(autoImportProvider && getInfoWithChecker(autoImportProvider, /*isFromPackageJson*/ true), `Could not find symbol in specified module for code actions`); + + function getInfoWithChecker(checker: TypeChecker, isFromPackageJson: boolean): SymbolExportInfo | undefined { + const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions); + if (defaultInfo && skipAlias(defaultInfo.symbol, checker) === symbol) { + return { symbol: defaultInfo.symbol, moduleSymbol, moduleFileName: undefined, exportKind: defaultInfo.exportKind, targetFlags: skipAlias(symbol, checker).flags, isFromPackageJson }; + } + const named = checker.tryGetMemberInModuleExportsAndProperties(symbol.name, moduleSymbol); + if (named && skipAlias(named, checker) === symbol) { + return { symbol: named, moduleSymbol, moduleFileName: undefined, exportKind: ExportKind.Named, targetFlags: skipAlias(symbol, checker).flags, isFromPackageJson }; + } + } +} + +function getImportFixes( + exportInfos: readonly SymbolExportInfo[], + useNamespaceInfo: { + symbolName: string, + position: number, + } | undefined, + /** undefined only for missing JSX namespace */ + isValidTypeOnlyUseSite: boolean, + useRequire: boolean, + program: Program, + sourceFile: SourceFile, + host: LanguageServiceHost, + preferences: UserPreferences, + importMap = createExistingImportMap(program.getTypeChecker(), sourceFile, program.getCompilerOptions()), + fromCacheOnly?: boolean, +): { computedWithoutCacheCount: number, fixes: readonly ImportFixWithModuleSpecifier[] } { + const checker = program.getTypeChecker(); + const existingImports = flatMap(exportInfos, importMap.getImportsForExportInfo); + const useNamespace = useNamespaceInfo && tryUseExistingNamespaceImport(existingImports, useNamespaceInfo.symbolName, useNamespaceInfo.position, checker); + const addToExisting = tryAddToExistingImport(existingImports, isValidTypeOnlyUseSite, checker, program.getCompilerOptions()); + if (addToExisting) { + // Don't bother providing an action to add a new import if we can add to an existing one. + return { + computedWithoutCacheCount: 0, + fixes: [...(useNamespace ? [useNamespace] : emptyArray), addToExisting], + }; + } + + const { fixes, computedWithoutCacheCount = 0 } = getFixesForAddImport( + exportInfos, + existingImports, + program, + sourceFile, + useNamespaceInfo?.position, + isValidTypeOnlyUseSite, + useRequire, + host, + preferences, + fromCacheOnly); + return { + computedWithoutCacheCount, + fixes: [...(useNamespace ? [useNamespace] : emptyArray), ...fixes], + }; +} + +function tryUseExistingNamespaceImport(existingImports: readonly FixAddToExistingImportInfo[], symbolName: string, position: number, checker: TypeChecker): FixUseNamespaceImport | undefined { + // It is possible that multiple import statements with the same specifier exist in the file. + // e.g. + // + // import * as ns from "foo"; + // import { member1, member2 } from "foo"; + // + // member3/**/ <-- cusor here + // + // in this case we should provie 2 actions: + // 1. change "member3" to "ns.member3" + // 2. add "member3" to the second import statement's import list + // and it is up to the user to decide which one fits best. + return firstDefined(existingImports, ({ declaration }): FixUseNamespaceImport | undefined => { + const namespacePrefix = getNamespaceLikeImportText(declaration); + const moduleSpecifier = tryGetModuleSpecifierFromDeclaration(declaration)?.text; + if (namespacePrefix && moduleSpecifier) { + const moduleSymbol = getTargetModuleFromNamespaceLikeImport(declaration, checker); + if (moduleSymbol && moduleSymbol.exports!.has(escapeLeadingUnderscores(symbolName))) { + return { kind: ImportFixKind.UseNamespace, namespacePrefix, position, moduleSpecifier }; + } + } + }); +} + +function getTargetModuleFromNamespaceLikeImport(declaration: AnyImportOrRequire, checker: TypeChecker) { + switch (declaration.kind) { + case SyntaxKind.VariableDeclaration: + return checker.resolveExternalModuleName(declaration.initializer.arguments[0]); + case SyntaxKind.ImportEqualsDeclaration: + return checker.getAliasedSymbol(declaration.symbol); + case SyntaxKind.ImportDeclaration: + const namespaceImport = tryCast(declaration.importClause?.namedBindings, isNamespaceImport); + return namespaceImport && checker.getAliasedSymbol(namespaceImport.symbol); + default: + return Debug.assertNever(declaration); + } +} + +function getNamespaceLikeImportText(declaration: AnyImportOrRequire) { + switch (declaration.kind) { + case SyntaxKind.VariableDeclaration: + return tryCast(declaration.name, isIdentifier)?.text; + case SyntaxKind.ImportEqualsDeclaration: + return declaration.name.text; + case SyntaxKind.ImportDeclaration: + return tryCast(declaration.importClause?.namedBindings, isNamespaceImport)?.name.text; + default: + return Debug.assertNever(declaration); + } +} + +function getAddAsTypeOnly( + isValidTypeOnlyUseSite: boolean, + isForNewImportDeclaration: boolean, + symbol: Symbol, + targetFlags: SymbolFlags, + checker: TypeChecker, + compilerOptions: CompilerOptions +) { + if (!isValidTypeOnlyUseSite) { + // Can't use a type-only import if the usage is an emitting position + return AddAsTypeOnly.NotAllowed; + } + if (isForNewImportDeclaration && compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Error) { + // Not writing a (top-level) type-only import here would create an error because the runtime dependency is unnecessary + return AddAsTypeOnly.Required; + } + if (compilerOptions.isolatedModules && compilerOptions.preserveValueImports && + (!(targetFlags & SymbolFlags.Value) || !!checker.getTypeOnlyAliasDeclaration(symbol)) + ) { + // A type-only import is required for this symbol if under these settings if the symbol will + // be erased, which will happen if the target symbol is purely a type or if it was exported/imported + // as type-only already somewhere between this import and the target. + return AddAsTypeOnly.Required; + } + return AddAsTypeOnly.Allowed; +} + +function tryAddToExistingImport(existingImports: readonly FixAddToExistingImportInfo[], isValidTypeOnlyUseSite: boolean, checker: TypeChecker, compilerOptions: CompilerOptions): FixAddToExistingImport | undefined { + return firstDefined(existingImports, ({ declaration, importKind, symbol, targetFlags }): FixAddToExistingImport | undefined => { + if (importKind === ImportKind.CommonJS || importKind === ImportKind.Namespace || declaration.kind === SyntaxKind.ImportEqualsDeclaration) { + // These kinds of imports are not combinable with anything + return undefined; + } + + if (declaration.kind === SyntaxKind.VariableDeclaration) { + return (importKind === ImportKind.Named || importKind === ImportKind.Default) && declaration.name.kind === SyntaxKind.ObjectBindingPattern + ? { kind: ImportFixKind.AddToExisting, importClauseOrBindingPattern: declaration.name, importKind, moduleSpecifier: declaration.initializer.arguments[0].text, addAsTypeOnly: AddAsTypeOnly.NotAllowed } + : undefined; + } + + const { importClause } = declaration; + if (!importClause || !isStringLiteralLike(declaration.moduleSpecifier)) return undefined; + const { name, namedBindings } = importClause; + // A type-only import may not have both a default and named imports, so the only way a name can + // be added to an existing type-only import is adding a named import to existing named bindings. + if (importClause.isTypeOnly && !(importKind === ImportKind.Named && namedBindings)) return undefined; + + // N.B. we don't have to figure out whether to use the main program checker + // or the AutoImportProvider checker because we're adding to an existing import; the existence of + // the import guarantees the symbol came from the main program. + const addAsTypeOnly = getAddAsTypeOnly(isValidTypeOnlyUseSite, /*isForNewImportDeclaration*/ false, symbol, targetFlags, checker, compilerOptions); + + if (importKind === ImportKind.Default && ( + name || // Cannot add a default import to a declaration that already has one + addAsTypeOnly === AddAsTypeOnly.Required && namedBindings // Cannot add a default import as type-only if the import already has named bindings + )) return undefined; + if ( + importKind === ImportKind.Named && + namedBindings?.kind === SyntaxKind.NamespaceImport // Cannot add a named import to a declaration that has a namespace import + ) return undefined; + + return { + kind: ImportFixKind.AddToExisting, + importClauseOrBindingPattern: importClause, + importKind, + moduleSpecifier: declaration.moduleSpecifier.text, + addAsTypeOnly, + }; + }); +} + +function createExistingImportMap(checker: TypeChecker, importingFile: SourceFile, compilerOptions: CompilerOptions) { + let importMap: MultiMap | undefined; + for (const moduleSpecifier of importingFile.imports) { + const i = importFromModuleSpecifier(moduleSpecifier); + if (isVariableDeclarationInitializedToRequire(i.parent)) { + const moduleSymbol = checker.resolveExternalModuleName(moduleSpecifier); + if (moduleSymbol) { + (importMap ||= createMultiMap()).add(getSymbolId(moduleSymbol), i.parent); + } + } + else if (i.kind === SyntaxKind.ImportDeclaration || i.kind === SyntaxKind.ImportEqualsDeclaration) { + const moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier); + if (moduleSymbol) { + (importMap ||= createMultiMap()).add(getSymbolId(moduleSymbol), i); + } + } + } + + return { + getImportsForExportInfo: ({ moduleSymbol, exportKind, targetFlags, symbol }: SymbolExportInfo): readonly FixAddToExistingImportInfo[] => { + // Can't use an es6 import for a type in JS. + if (!(targetFlags & SymbolFlags.Value) && isSourceFileJS(importingFile)) return emptyArray; + const matchingDeclarations = importMap?.get(getSymbolId(moduleSymbol)); + if (!matchingDeclarations) return emptyArray; + const importKind = getImportKind(importingFile, exportKind, compilerOptions); + return matchingDeclarations.map(declaration => ({ declaration, importKind, symbol, targetFlags })); + } + }; +} + +function shouldUseRequire(sourceFile: SourceFile, program: Program): boolean { + // 1. TypeScript files don't use require variable declarations + if (!isSourceFileJS(sourceFile)) { + return false; + } + + // 2. If the current source file is unambiguously CJS or ESM, go with that + if (sourceFile.commonJsModuleIndicator && !sourceFile.externalModuleIndicator) return true; + if (sourceFile.externalModuleIndicator && !sourceFile.commonJsModuleIndicator) return false; + + // 3. If there's a tsconfig/jsconfig, use its module setting + const compilerOptions = program.getCompilerOptions(); + if (compilerOptions.configFile) { + return getEmitModuleKind(compilerOptions) < ModuleKind.ES2015; + } + + // 4. Match the first other JS file in the program that's unambiguously CJS or ESM + for (const otherFile of program.getSourceFiles()) { + if (otherFile === sourceFile || !isSourceFileJS(otherFile) || program.isSourceFileFromExternalLibrary(otherFile)) continue; + if (otherFile.commonJsModuleIndicator && !otherFile.externalModuleIndicator) return true; + if (otherFile.externalModuleIndicator && !otherFile.commonJsModuleIndicator) return false; + } + + // 5. Literally nothing to go on + return true; +} + +function createGetChecker(program: Program, host: LanguageServiceHost) { + return memoizeOne((isFromPackageJson: boolean) => isFromPackageJson ? host.getPackageJsonAutoImportProvider!()!.getTypeChecker() : program.getTypeChecker()); +} + +function getNewImportFixes( + program: Program, + sourceFile: SourceFile, + position: number | undefined, + isValidTypeOnlyUseSite: boolean, + useRequire: boolean, + exportInfo: readonly SymbolExportInfo[], + host: LanguageServiceHost, + preferences: UserPreferences, + fromCacheOnly?: boolean, +): { computedWithoutCacheCount: number, fixes: readonly (FixAddNewImport | FixAddJsdocTypeImport)[] } { + const isJs = isSourceFileJS(sourceFile); + const compilerOptions = program.getCompilerOptions(); + const moduleSpecifierResolutionHost = createModuleSpecifierResolutionHost(program, host); + const getChecker = createGetChecker(program, host); + const rejectNodeModulesRelativePaths = moduleResolutionUsesNodeModules(getEmitModuleResolutionKind(compilerOptions)); + const getModuleSpecifiers = fromCacheOnly + ? (moduleSymbol: Symbol) => ({ moduleSpecifiers: tryGetModuleSpecifiersFromCache(moduleSymbol, sourceFile, moduleSpecifierResolutionHost, preferences), computedWithoutCache: false }) + : (moduleSymbol: Symbol, checker: TypeChecker) => getModuleSpecifiersWithCacheInfo(moduleSymbol, checker, compilerOptions, sourceFile, moduleSpecifierResolutionHost, preferences); + + let computedWithoutCacheCount = 0; + const fixes = flatMap(exportInfo, (exportInfo, i) => { + const checker = getChecker(exportInfo.isFromPackageJson); + const { computedWithoutCache, moduleSpecifiers } = getModuleSpecifiers(exportInfo.moduleSymbol, checker); + const importedSymbolHasValueMeaning = !!(exportInfo.targetFlags & SymbolFlags.Value); + const addAsTypeOnly = getAddAsTypeOnly(isValidTypeOnlyUseSite, /*isForNewImportDeclaration*/ true, exportInfo.symbol, exportInfo.targetFlags, checker, compilerOptions); + computedWithoutCacheCount += computedWithoutCache ? 1 : 0; + return mapDefined(moduleSpecifiers, (moduleSpecifier): FixAddNewImport | FixAddJsdocTypeImport | undefined => + rejectNodeModulesRelativePaths && pathContainsNodeModules(moduleSpecifier) ? undefined : + // `position` should only be undefined at a missing jsx namespace, in which case we shouldn't be looking for pure types. + !importedSymbolHasValueMeaning && isJs && position !== undefined ? { kind: ImportFixKind.JsdocTypeImport, moduleSpecifier, position, exportInfo, isReExport: i > 0 } : + { + kind: ImportFixKind.AddNew, + moduleSpecifier, + importKind: getImportKind(sourceFile, exportInfo.exportKind, compilerOptions), + useRequire, + addAsTypeOnly, + exportInfo, + isReExport: i > 0, + } + ); + }); + + return { computedWithoutCacheCount, fixes }; +} + +function getFixesForAddImport( + exportInfos: readonly SymbolExportInfo[], + existingImports: readonly FixAddToExistingImportInfo[], + program: Program, + sourceFile: SourceFile, + position: number | undefined, + isValidTypeOnlyUseSite: boolean, + useRequire: boolean, + host: LanguageServiceHost, + preferences: UserPreferences, + fromCacheOnly?: boolean, +): { computedWithoutCacheCount?: number, fixes: readonly (FixAddNewImport | FixAddJsdocTypeImport)[] } { + const existingDeclaration = firstDefined(existingImports, info => newImportInfoFromExistingSpecifier(info, isValidTypeOnlyUseSite, useRequire, program.getTypeChecker(), program.getCompilerOptions())); + return existingDeclaration ? { fixes: [existingDeclaration] } : getNewImportFixes(program, sourceFile, position, isValidTypeOnlyUseSite, useRequire, exportInfos, host, preferences, fromCacheOnly); +} + +function newImportInfoFromExistingSpecifier( + { declaration, importKind, symbol, targetFlags }: FixAddToExistingImportInfo, + isValidTypeOnlyUseSite: boolean, + useRequire: boolean, + checker: TypeChecker, + compilerOptions: CompilerOptions +): FixAddNewImport | undefined { + const moduleSpecifier = tryGetModuleSpecifierFromDeclaration(declaration)?.text; + if (moduleSpecifier) { + const addAsTypeOnly = useRequire + ? AddAsTypeOnly.NotAllowed + : getAddAsTypeOnly(isValidTypeOnlyUseSite, /*isForNewImportDeclaration*/ true, symbol, targetFlags, checker, compilerOptions); + return { kind: ImportFixKind.AddNew, moduleSpecifier, importKind, addAsTypeOnly, useRequire }; + } +} + +function sortFixInfo(fixes: readonly (FixInfo & { fix: ImportFixWithModuleSpecifier })[], sourceFile: SourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier })[] { + const _toPath = (fileName: string) => toPath(fileName, host.getCurrentDirectory(), hostGetCanonicalFileName(host)); + return sort(fixes, (a, b) => + compareBooleans(!!a.isJsxNamespaceFix, !!b.isJsxNamespaceFix) || + compareValues(a.fix.kind, b.fix.kind) || + compareModuleSpecifiers(a.fix, b.fix, sourceFile, program, packageJsonImportFilter.allowsImportingSpecifier, _toPath)); +} + +function getBestFix(fixes: readonly ImportFixWithModuleSpecifier[], sourceFile: SourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): ImportFixWithModuleSpecifier | undefined { + if (!some(fixes)) return; + // These will always be placed first if available, and are better than other kinds + if (fixes[0].kind === ImportFixKind.UseNamespace || fixes[0].kind === ImportFixKind.AddToExisting) { + return fixes[0]; + } + + return fixes.reduce((best, fix) => + // Takes true branch of conditional if `fix` is better than `best` + compareModuleSpecifiers( + fix, + best, + sourceFile, + program, + packageJsonImportFilter.allowsImportingSpecifier, + fileName => toPath(fileName, host.getCurrentDirectory(), hostGetCanonicalFileName(host)), + ) === Comparison.LessThan ? fix : best + ); +} + +/** @returns `Comparison.LessThan` if `a` is better than `b`. */ +function compareModuleSpecifiers( + a: ImportFixWithModuleSpecifier, + b: ImportFixWithModuleSpecifier, + importingFile: SourceFile, + program: Program, + allowsImportingSpecifier: (specifier: string) => boolean, + toPath: (fileName: string) => Path, +): Comparison { + if (a.kind !== ImportFixKind.UseNamespace && b.kind !== ImportFixKind.UseNamespace) { + return compareBooleans(allowsImportingSpecifier(b.moduleSpecifier), allowsImportingSpecifier(a.moduleSpecifier)) + || compareNodeCoreModuleSpecifiers(a.moduleSpecifier, b.moduleSpecifier, importingFile, program) + || compareBooleans( + isFixPossiblyReExportingImportingFile(a, importingFile, program.getCompilerOptions(), toPath), + isFixPossiblyReExportingImportingFile(b, importingFile, program.getCompilerOptions(), toPath)) + || compareNumberOfDirectorySeparators(a.moduleSpecifier, b.moduleSpecifier); + } + return Comparison.EqualTo; +} + +// This is a simple heuristic to try to avoid creating an import cycle with a barrel re-export. +// E.g., do not `import { Foo } from ".."` when you could `import { Foo } from "../Foo"`. +// This can produce false positives or negatives if re-exports cross into sibling directories +// (e.g. `export * from "../whatever"`) or are not named "index" (we don't even try to consider +// this if we're in a resolution mode where you can't drop trailing "/index" from paths). +function isFixPossiblyReExportingImportingFile(fix: ImportFixWithModuleSpecifier, importingFile: SourceFile, compilerOptions: CompilerOptions, toPath: (fileName: string) => Path): boolean { + if (fix.isReExport && + fix.exportInfo?.moduleFileName && + getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs && + isIndexFileName(fix.exportInfo.moduleFileName) + ) { + const reExportDir = toPath(getDirectoryPath(fix.exportInfo.moduleFileName)); + return startsWith((importingFile.path), reExportDir); + } + return false; +} + +function isIndexFileName(fileName: string) { + return getBaseFileName(fileName, [".js", ".jsx", ".d.ts", ".ts", ".tsx"], /*ignoreCase*/ true) === "index"; +} + +function compareNodeCoreModuleSpecifiers(a: string, b: string, importingFile: SourceFile, program: Program): Comparison { + if (startsWith(a, "node:") && !startsWith(b, "node:")) return shouldUseUriStyleNodeCoreModules(importingFile, program) ? Comparison.LessThan : Comparison.GreaterThan; + if (startsWith(b, "node:") && !startsWith(a, "node:")) return shouldUseUriStyleNodeCoreModules(importingFile, program) ? Comparison.GreaterThan : Comparison.LessThan; + return Comparison.EqualTo; +} + +function getFixesInfoForUMDImport({ sourceFile, program, host, preferences }: CodeFixContextBase, token: Node): (FixInfo & { fix: ImportFixWithModuleSpecifier })[] | undefined { + const checker = program.getTypeChecker(); + const umdSymbol = getUmdSymbol(token, checker); + if (!umdSymbol) return undefined; + const symbol = checker.getAliasedSymbol(umdSymbol); + const symbolName = umdSymbol.name; + const exportInfo: readonly SymbolExportInfo[] = [{ symbol: umdSymbol, moduleSymbol: symbol, moduleFileName: undefined, exportKind: ExportKind.UMD, targetFlags: symbol.flags, isFromPackageJson: false }]; + const useRequire = shouldUseRequire(sourceFile, program); + const position = isIdentifier(token) ? token.getStart(sourceFile) : undefined; + const fixes = getImportFixes(exportInfo, position ? { position, symbolName } : undefined, /*isValidTypeOnlyUseSite*/ false, useRequire, program, sourceFile, host, preferences).fixes; + return fixes.map(fix => ({ fix, symbolName, errorIdentifierText: tryCast(token, isIdentifier)?.text })); +} + +function getUmdSymbol(token: Node, checker: TypeChecker): Symbol | undefined { + // try the identifier to see if it is the umd symbol + const umdSymbol = isIdentifier(token) ? checker.getSymbolAtLocation(token) : undefined; + if (isUMDExportSymbol(umdSymbol)) return umdSymbol; + + // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. + const { parent } = token; + return (isJsxOpeningLikeElement(parent) && parent.tagName === token) || isJsxOpeningFragment(parent) + ? tryCast(checker.resolveName(checker.getJsxNamespace(parent), isJsxOpeningLikeElement(parent) ? token : parent, SymbolFlags.Value, /*excludeGlobals*/ false), isUMDExportSymbol) + : undefined; +} + +function getUmdImportKind(importingFile: SourceFile, compilerOptions: CompilerOptions, forceImportKeyword: boolean): ImportKind { + // Import a synthetic `default` if enabled. + if (getAllowSyntheticDefaultImports(compilerOptions)) { + return ImportKind.Default; + } + + // When a synthetic `default` is unavailable, use `import..require` if the module kind supports it. + const moduleKind = getEmitModuleKind(compilerOptions); + switch (moduleKind) { + case ModuleKind.AMD: + case ModuleKind.CommonJS: + case ModuleKind.UMD: + if (isInJSFile(importingFile)) { + return isExternalModule(importingFile) || forceImportKeyword ? ImportKind.Namespace : ImportKind.CommonJS; + } + return ImportKind.CommonJS; + case ModuleKind.System: + case ModuleKind.ES2015: + case ModuleKind.ES2020: + case ModuleKind.ES2022: + case ModuleKind.ESNext: + case ModuleKind.None: + // Fall back to the `import * as ns` style import. + return ImportKind.Namespace; + case ModuleKind.Node16: + case ModuleKind.NodeNext: + return importingFile.impliedNodeFormat === ModuleKind.ESNext ? ImportKind.Namespace : ImportKind.CommonJS; + default: + return Debug.assertNever(moduleKind, `Unexpected moduleKind ${moduleKind}`); + } +} + +function getFixesInfoForNonUMDImport({ sourceFile, program, cancellationToken, host, preferences }: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier })[] | undefined { + const checker = program.getTypeChecker(); + const compilerOptions = program.getCompilerOptions(); + return flatMap(getSymbolNamesToImport(sourceFile, checker, symbolToken, compilerOptions), symbolName => { + // "default" is a keyword and not a legal identifier for the import, but appears as an identifier. + if (symbolName === InternalSymbolName.Default) { + return undefined; + } + const isValidTypeOnlyUseSite = isValidTypeOnlyAliasUseSite(symbolToken); + const useRequire = shouldUseRequire(sourceFile, program); + const exportInfo = getExportInfos(symbolName, isJSXTagName(symbolToken), getMeaningFromLocation(symbolToken), cancellationToken, sourceFile, program, useAutoImportProvider, host, preferences); + const fixes = arrayFrom(flatMapIterator(exportInfo.entries(), ([_, exportInfos]) => + getImportFixes(exportInfos, { symbolName, position: symbolToken.getStart(sourceFile) }, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences).fixes)); + return fixes.map(fix => ({ fix, symbolName, errorIdentifierText: symbolToken.text, isJsxNamespaceFix: symbolName !== symbolToken.text })); + }); +} + +function getTypeOnlyPromotionFix(sourceFile: SourceFile, symbolToken: Identifier, symbolName: string, program: Program): FixPromoteTypeOnlyImport | undefined { + const checker = program.getTypeChecker(); + const symbol = checker.resolveName(symbolName, symbolToken, SymbolFlags.Value, /*excludeGlobals*/ true); + if (!symbol) return undefined; + + const typeOnlyAliasDeclaration = checker.getTypeOnlyAliasDeclaration(symbol); + if (!typeOnlyAliasDeclaration || getSourceFileOfNode(typeOnlyAliasDeclaration) !== sourceFile) return undefined; + + return { kind: ImportFixKind.PromoteTypeOnly, typeOnlyAliasDeclaration }; +} + +function getSymbolNamesToImport(sourceFile: SourceFile, checker: TypeChecker, symbolToken: Identifier, compilerOptions: CompilerOptions): string[] { + const parent = symbolToken.parent; + if ((isJsxOpeningLikeElement(parent) || isJsxClosingElement(parent)) && parent.tagName === symbolToken && jsxModeNeedsExplicitImport(compilerOptions.jsx)) { + const jsxNamespace = checker.getJsxNamespace(sourceFile); + if (needsJsxNamespaceFix(jsxNamespace, symbolToken, checker)) { + const needsComponentNameFix = !isIntrinsicJsxName(symbolToken.text) && !checker.resolveName(symbolToken.text, symbolToken, SymbolFlags.Value, /*excludeGlobals*/ false); + return needsComponentNameFix ? [symbolToken.text, jsxNamespace] : [jsxNamespace]; + } + } + return [symbolToken.text]; +} + +function needsJsxNamespaceFix(jsxNamespace: string, symbolToken: Identifier, checker: TypeChecker) { + if (isIntrinsicJsxName(symbolToken.text)) return true; // If we were triggered by a matching error code on an intrinsic, the error must have been about missing the JSX factory + const namespaceSymbol = checker.resolveName(jsxNamespace, symbolToken, SymbolFlags.Value, /*excludeGlobals*/ true); + return !namespaceSymbol || some(namespaceSymbol.declarations, isTypeOnlyImportOrExportDeclaration) && !(namespaceSymbol.flags & SymbolFlags.Value); +} + +// Returns a map from an exported symbol's ID to a list of every way it's (re-)exported. +function getExportInfos( + symbolName: string, + isJsxTagName: boolean, + currentTokenMeaning: SemanticMeaning, + cancellationToken: CancellationToken, + fromFile: SourceFile, + program: Program, + useAutoImportProvider: boolean, + host: LanguageServiceHost, + preferences: UserPreferences, +): ReadonlyMap { + // For each original symbol, keep all re-exports of that symbol together so we can call `getCodeActionsForImport` on the whole group at once. + // Maps symbol id to info for modules providing that symbol (original export + re-exports). + const originalSymbolToExportInfos = createMultiMap(); + const packageJsonFilter = createPackageJsonImportFilter(fromFile, preferences, host); + const moduleSpecifierCache = host.getModuleSpecifierCache?.(); + const getModuleSpecifierResolutionHost = memoizeOne((isFromPackageJson: boolean) => { + return createModuleSpecifierResolutionHost(isFromPackageJson ? host.getPackageJsonAutoImportProvider!()! : program, host); + }); + function addSymbol(moduleSymbol: Symbol, toFile: SourceFile | undefined, exportedSymbol: Symbol, exportKind: ExportKind, program: Program, isFromPackageJson: boolean): void { + const moduleSpecifierResolutionHost = getModuleSpecifierResolutionHost(isFromPackageJson); + if (toFile && isImportableFile(program, fromFile, toFile, preferences, packageJsonFilter, moduleSpecifierResolutionHost, moduleSpecifierCache) || + !toFile && packageJsonFilter.allowsImportingAmbientModule(moduleSymbol, moduleSpecifierResolutionHost) + ) { + const checker = program.getTypeChecker(); + originalSymbolToExportInfos.add(getUniqueSymbolId(exportedSymbol, checker).toString(), { symbol: exportedSymbol, moduleSymbol, moduleFileName: toFile?.fileName, exportKind, targetFlags: skipAlias(exportedSymbol, checker).flags, isFromPackageJson }); + } + } + forEachExternalModuleToImportFrom(program, host, preferences, useAutoImportProvider, (moduleSymbol, sourceFile, program, isFromPackageJson) => { + const checker = program.getTypeChecker(); + cancellationToken.throwIfCancellationRequested(); + + const compilerOptions = program.getCompilerOptions(); + const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions); + if (defaultInfo && (defaultInfo.name === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, getEmitScriptTarget(compilerOptions), isJsxTagName) === symbolName) && symbolHasMeaning(defaultInfo.symbolForMeaning, currentTokenMeaning)) { + addSymbol(moduleSymbol, sourceFile, defaultInfo.symbol, defaultInfo.exportKind, program, isFromPackageJson); + } + + // check exports with the same name + const exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol); + if (exportSymbolWithIdenticalName && symbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) { + addSymbol(moduleSymbol, sourceFile, exportSymbolWithIdenticalName, ExportKind.Named, program, isFromPackageJson); + } + }); + return originalSymbolToExportInfos; +} + +function getExportEqualsImportKind(importingFile: SourceFile, compilerOptions: CompilerOptions, forceImportKeyword: boolean): ImportKind { + const allowSyntheticDefaults = getAllowSyntheticDefaultImports(compilerOptions); + const isJS = isInJSFile(importingFile); + // 1. 'import =' will not work in es2015+ TS files, so the decision is between a default + // and a namespace import, based on allowSyntheticDefaultImports/esModuleInterop. + if (!isJS && getEmitModuleKind(compilerOptions) >= ModuleKind.ES2015) { + return allowSyntheticDefaults ? ImportKind.Default : ImportKind.Namespace; + } + // 2. 'import =' will not work in JavaScript, so the decision is between a default import, + // a namespace import, and const/require. + if (isJS) { + return isExternalModule(importingFile) || forceImportKeyword + ? allowSyntheticDefaults ? ImportKind.Default : ImportKind.Namespace + : ImportKind.CommonJS; + } + // 3. At this point the most correct choice is probably 'import =', but people + // really hate that, so look to see if the importing file has any precedent + // on how to handle it. + for (const statement of importingFile.statements) { + // `import foo` parses as an ImportEqualsDeclaration even though it could be an ImportDeclaration + if (isImportEqualsDeclaration(statement) && !nodeIsMissing(statement.moduleReference)) { + return ImportKind.CommonJS; + } + } + // 4. We have no precedent to go on, so just use a default import if + // allowSyntheticDefaultImports/esModuleInterop is enabled. + return allowSyntheticDefaults ? ImportKind.Default : ImportKind.CommonJS; +} + +function codeActionForFixWorker(changes: ChangeTracker, sourceFile: SourceFile, symbolName: string, fix: ImportFix, includeSymbolNameInDescription: boolean, quotePreference: QuotePreference, compilerOptions: CompilerOptions): DiagnosticAndArguments { + switch (fix.kind) { + case ImportFixKind.UseNamespace: + addNamespaceQualifier(changes, sourceFile, fix); + return [Diagnostics.Change_0_to_1, symbolName, `${fix.namespacePrefix}.${symbolName}`]; + case ImportFixKind.JsdocTypeImport: + addImportType(changes, sourceFile, fix, quotePreference); + return [Diagnostics.Change_0_to_1, symbolName, getImportTypePrefix(fix.moduleSpecifier, quotePreference) + symbolName]; + case ImportFixKind.AddToExisting: { + const { importClauseOrBindingPattern, importKind, addAsTypeOnly, moduleSpecifier } = fix; + doAddExistingFix( + changes, + sourceFile, + importClauseOrBindingPattern, + importKind === ImportKind.Default ? { name: symbolName, addAsTypeOnly } : undefined, + importKind === ImportKind.Named ? [{ name: symbolName, addAsTypeOnly }] : emptyArray, + compilerOptions); + const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier); + return includeSymbolNameInDescription + ? [Diagnostics.Import_0_from_1, symbolName, moduleSpecifierWithoutQuotes] + : [Diagnostics.Update_import_from_0, moduleSpecifierWithoutQuotes]; + } + case ImportFixKind.AddNew: { + const { importKind, moduleSpecifier, addAsTypeOnly, useRequire } = fix; + const getDeclarations = useRequire ? getNewRequires : getNewImports; + const defaultImport: Import | undefined = importKind === ImportKind.Default ? { name: symbolName, addAsTypeOnly } : undefined; + const namedImports: Import[] | undefined = importKind === ImportKind.Named ? [{ name: symbolName, addAsTypeOnly }] : undefined; + const namespaceLikeImport = importKind === ImportKind.Namespace || importKind === ImportKind.CommonJS ? { importKind, name: symbolName, addAsTypeOnly } : undefined; + insertImports(changes, sourceFile, getDeclarations(moduleSpecifier, quotePreference, defaultImport, namedImports, namespaceLikeImport), /*blankLineBetween*/ true); + return includeSymbolNameInDescription + ? [Diagnostics.Import_0_from_1, symbolName, moduleSpecifier] + : [Diagnostics.Add_import_from_0, moduleSpecifier]; + } + case ImportFixKind.PromoteTypeOnly: { + const { typeOnlyAliasDeclaration } = fix; + const promotedDeclaration = promoteFromTypeOnly(changes, typeOnlyAliasDeclaration, compilerOptions, sourceFile); + return promotedDeclaration.kind === SyntaxKind.ImportSpecifier + ? [Diagnostics.Remove_type_from_import_of_0_from_1, symbolName, getModuleSpecifierText(promotedDeclaration.parent.parent)] + : [Diagnostics.Remove_type_from_import_declaration_from_0, getModuleSpecifierText(promotedDeclaration)]; + } + default: + return Debug.assertNever(fix, `Unexpected fix kind ${(fix as ImportFix).kind}`); + } +} + +function getModuleSpecifierText(promotedDeclaration: ImportClause | ImportEqualsDeclaration): string { + return promotedDeclaration.kind === SyntaxKind.ImportEqualsDeclaration + ? tryCast(tryCast(promotedDeclaration.moduleReference, isExternalModuleReference)?.expression, isStringLiteralLike)?.text || promotedDeclaration.moduleReference.getText() + : cast(promotedDeclaration.parent.moduleSpecifier, isStringLiteral).text; +} + +function promoteFromTypeOnly(changes: ChangeTracker, aliasDeclaration: TypeOnlyAliasDeclaration, compilerOptions: CompilerOptions, sourceFile: SourceFile) { + // See comment in `doAddExistingFix` on constant with the same name. + const convertExistingToTypeOnly = compilerOptions.preserveValueImports && compilerOptions.isolatedModules; + switch (aliasDeclaration.kind) { + case SyntaxKind.ImportSpecifier: + if (aliasDeclaration.isTypeOnly) { + if (aliasDeclaration.parent.elements.length > 1 && importSpecifiersAreSorted(aliasDeclaration.parent.elements)) { + changes.delete(sourceFile, aliasDeclaration); + const newSpecifier = factory.updateImportSpecifier(aliasDeclaration, /*isTypeOnly*/ false, aliasDeclaration.propertyName, aliasDeclaration.name); + const insertionIndex = getImportSpecifierInsertionIndex(aliasDeclaration.parent.elements, newSpecifier); + changes.insertImportSpecifierAtIndex(sourceFile, newSpecifier, aliasDeclaration.parent, insertionIndex); + } + else { + changes.deleteRange(sourceFile, aliasDeclaration.getFirstToken()!); + } + return aliasDeclaration; + } + else { + Debug.assert(aliasDeclaration.parent.parent.isTypeOnly); + promoteImportClause(aliasDeclaration.parent.parent); + return aliasDeclaration.parent.parent; + } + case SyntaxKind.ImportClause: + promoteImportClause(aliasDeclaration); + return aliasDeclaration; + case SyntaxKind.NamespaceImport: + promoteImportClause(aliasDeclaration.parent); + return aliasDeclaration.parent; + case SyntaxKind.ImportEqualsDeclaration: + changes.deleteRange(sourceFile, aliasDeclaration.getChildAt(1)); + return aliasDeclaration; + default: + Debug.failBadSyntaxKind(aliasDeclaration); + } + + function promoteImportClause(importClause: ImportClause) { + changes.delete(sourceFile, getTypeKeywordOfTypeOnlyImport(importClause, sourceFile)); + if (convertExistingToTypeOnly) { + const namedImports = tryCast(importClause.namedBindings, isNamedImports); + if (namedImports && namedImports.elements.length > 1) { + if (importSpecifiersAreSorted(namedImports.elements) && + aliasDeclaration.kind === SyntaxKind.ImportSpecifier && + namedImports.elements.indexOf(aliasDeclaration) !== 0 + ) { + // The import specifier being promoted will be the only non-type-only, + // import in the NamedImports, so it should be moved to the front. + changes.delete(sourceFile, aliasDeclaration); + changes.insertImportSpecifierAtIndex(sourceFile, aliasDeclaration, namedImports, 0); + } + for (const element of namedImports.elements) { + if (element !== aliasDeclaration && !element.isTypeOnly) { + changes.insertModifierBefore(sourceFile, SyntaxKind.TypeKeyword, element); + } + } + } + } + } +} + +function doAddExistingFix( + changes: ChangeTracker, + sourceFile: SourceFile, + clause: ImportClause | ObjectBindingPattern, + defaultImport: Import | undefined, + namedImports: readonly Import[], + compilerOptions: CompilerOptions, +): void { + if (clause.kind === SyntaxKind.ObjectBindingPattern) { + if (defaultImport) { + addElementToBindingPattern(clause, defaultImport.name, "default"); + } + for (const specifier of namedImports) { + addElementToBindingPattern(clause, specifier.name, /*propertyName*/ undefined); + } + return; + } + + const promoteFromTypeOnly = clause.isTypeOnly && some([defaultImport, ...namedImports], i => i?.addAsTypeOnly === AddAsTypeOnly.NotAllowed); + const existingSpecifiers = clause.namedBindings && tryCast(clause.namedBindings, isNamedImports)?.elements; + // If we are promoting from a type-only import and `--isolatedModules` and `--preserveValueImports` + // are enabled, we need to make every existing import specifier type-only. It may be possible that + // some of them don't strictly need to be marked type-only (if they have a value meaning and are + // never used in an emitting position). These are allowed to be imported without being type-only, + // but the user has clearly already signified that they don't need them to be present at runtime + // by placing them in a type-only import. So, just mark each specifier as type-only. + const convertExistingToTypeOnly = promoteFromTypeOnly && compilerOptions.preserveValueImports && compilerOptions.isolatedModules; + + if (defaultImport) { + Debug.assert(!clause.name, "Cannot add a default import to an import clause that already has one"); + changes.insertNodeAt(sourceFile, clause.getStart(sourceFile), factory.createIdentifier(defaultImport.name), { suffix: ", " }); + } + + if (namedImports.length) { + const newSpecifiers = stableSort( + namedImports.map(namedImport => factory.createImportSpecifier( + (!clause.isTypeOnly || promoteFromTypeOnly) && needsTypeOnly(namedImport), + /*propertyName*/ undefined, + factory.createIdentifier(namedImport.name))), + compareImportOrExportSpecifiers); + + if (existingSpecifiers?.length && importSpecifiersAreSorted(existingSpecifiers)) { + for (const spec of newSpecifiers) { + // Organize imports puts type-only import specifiers last, so if we're + // adding a non-type-only specifier and converting all the other ones to + // type-only, there's no need to ask for the insertion index - it's 0. + const insertionIndex = convertExistingToTypeOnly && !spec.isTypeOnly + ? 0 + : getImportSpecifierInsertionIndex(existingSpecifiers, spec); + changes.insertImportSpecifierAtIndex(sourceFile, spec, clause.namedBindings as NamedImports, insertionIndex); + } + } + else if (existingSpecifiers?.length) { + for (const spec of newSpecifiers) { + changes.insertNodeInListAfter(sourceFile, last(existingSpecifiers), spec, existingSpecifiers); + } + } + else { + if (newSpecifiers.length) { + const namedImports = factory.createNamedImports(newSpecifiers); + if (clause.namedBindings) { + changes.replaceNode(sourceFile, clause.namedBindings, namedImports); + } + else { + changes.insertNodeAfter(sourceFile, Debug.checkDefined(clause.name, "Import clause must have either named imports or a default import"), namedImports); + } + } + } + } + + if (promoteFromTypeOnly) { + changes.delete(sourceFile, getTypeKeywordOfTypeOnlyImport(clause, sourceFile)); + if (convertExistingToTypeOnly && existingSpecifiers) { + for (const specifier of existingSpecifiers) { + changes.insertModifierBefore(sourceFile, SyntaxKind.TypeKeyword, specifier); + } + } + } + + function addElementToBindingPattern(bindingPattern: ObjectBindingPattern, name: string, propertyName: string | undefined) { + const element = factory.createBindingElement(/*dotDotDotToken*/ undefined, propertyName, name); + if (bindingPattern.elements.length) { + changes.insertNodeInListAfter(sourceFile, last(bindingPattern.elements), element); + } + else { + changes.replaceNode(sourceFile, bindingPattern, factory.createObjectBindingPattern([element])); + } + } +} + +function addNamespaceQualifier(changes: ChangeTracker, sourceFile: SourceFile, { namespacePrefix, position }: FixUseNamespaceImport): void { + changes.insertText(sourceFile, position, namespacePrefix + "."); +} + +function addImportType(changes: ChangeTracker, sourceFile: SourceFile, { moduleSpecifier, position }: FixAddJsdocTypeImport, quotePreference: QuotePreference): void { + changes.insertText(sourceFile, position, getImportTypePrefix(moduleSpecifier, quotePreference)); +} + +function getImportTypePrefix(moduleSpecifier: string, quotePreference: QuotePreference): string { + const quote = getQuoteFromPreference(quotePreference); + return `import(${quote}${moduleSpecifier}${quote}).`; +} + +function needsTypeOnly({ addAsTypeOnly }: { addAsTypeOnly: AddAsTypeOnly }): boolean { + return addAsTypeOnly === AddAsTypeOnly.Required; +} + +function getNewImports( + moduleSpecifier: string, + quotePreference: QuotePreference, + defaultImport: Import | undefined, + namedImports: readonly Import[] | undefined, + namespaceLikeImport: Import & { importKind: ImportKind.CommonJS | ImportKind.Namespace } | undefined +): AnyImportSyntax | readonly AnyImportSyntax[] { + const quotedModuleSpecifier = makeStringLiteral(moduleSpecifier, quotePreference); + let statements: AnyImportSyntax | readonly AnyImportSyntax[] | undefined; + if (defaultImport !== undefined || namedImports?.length) { + const topLevelTypeOnly = (!defaultImport || needsTypeOnly(defaultImport)) && every(namedImports, needsTypeOnly); + statements = combine(statements, makeImport( + defaultImport && factory.createIdentifier(defaultImport.name), + namedImports?.map(({ addAsTypeOnly, name }) => factory.createImportSpecifier( + !topLevelTypeOnly && addAsTypeOnly === AddAsTypeOnly.Required, + /*propertyName*/ undefined, + factory.createIdentifier(name))), + moduleSpecifier, + quotePreference, + topLevelTypeOnly)); + } + + if (namespaceLikeImport) { + const declaration = namespaceLikeImport.importKind === ImportKind.CommonJS + ? factory.createImportEqualsDeclaration( + /*modifiers*/ undefined, + needsTypeOnly(namespaceLikeImport), + factory.createIdentifier(namespaceLikeImport.name), + factory.createExternalModuleReference(quotedModuleSpecifier)) + : factory.createImportDeclaration( + /*modifiers*/ undefined, + factory.createImportClause( + needsTypeOnly(namespaceLikeImport), + /*name*/ undefined, + factory.createNamespaceImport(factory.createIdentifier(namespaceLikeImport.name))), + quotedModuleSpecifier, + /*assertClause*/ undefined); + statements = combine(statements, declaration); + } + return Debug.checkDefined(statements); +} + +function getNewRequires(moduleSpecifier: string, quotePreference: QuotePreference, defaultImport: Import | undefined, namedImports: readonly Import[] | undefined, namespaceLikeImport: Import | undefined): RequireVariableStatement | readonly RequireVariableStatement[] { + const quotedModuleSpecifier = makeStringLiteral(moduleSpecifier, quotePreference); + let statements: RequireVariableStatement | readonly RequireVariableStatement[] | undefined; + // const { default: foo, bar, etc } = require('./mod'); + if (defaultImport || namedImports?.length) { + const bindingElements = namedImports?.map(({ name }) => factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name)) || []; + if (defaultImport) { + bindingElements.unshift(factory.createBindingElement(/*dotDotDotToken*/ undefined, "default", defaultImport.name)); + } + const declaration = createConstEqualsRequireDeclaration(factory.createObjectBindingPattern(bindingElements), quotedModuleSpecifier); + statements = combine(statements, declaration); + } + // const foo = require('./mod'); + if (namespaceLikeImport) { + const declaration = createConstEqualsRequireDeclaration(namespaceLikeImport.name, quotedModuleSpecifier); + statements = combine(statements, declaration); + } + return Debug.checkDefined(statements); +} + +function createConstEqualsRequireDeclaration(name: string | ObjectBindingPattern, quotedModuleSpecifier: StringLiteral): RequireVariableStatement { + return factory.createVariableStatement( + /*modifiers*/ undefined, + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( + typeof name === "string" ? factory.createIdentifier(name) : name, + /*exclamationToken*/ undefined, + /*type*/ undefined, + factory.createCallExpression(factory.createIdentifier("require"), /*typeArguments*/ undefined, [quotedModuleSpecifier]))], + NodeFlags.Const)) as RequireVariableStatement; +} + +function symbolHasMeaning({ declarations }: Symbol, meaning: SemanticMeaning): boolean { + return some(declarations, decl => !!(getMeaningFromDeclaration(decl) & meaning)); +} diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 2f0c90737549a..590c697127eab 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -1,151 +1,19 @@ +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { - AnyImportOrRequire, - AnyImportOrRequireStatement, - AnyImportSyntax, - arrayFrom, - CancellationToken, - cast, - CodeAction, - CodeFixAction, - CodeFixContextBase, - combine, - compareBooleans, - compareNumberOfDirectorySeparators, - compareValues, - Comparison, - CompilerOptions, - createModuleSpecifierResolutionHost, - createMultiMap, - createPackageJsonImportFilter, - Debug, - DiagnosticAndArguments, - Diagnostics, - DiagnosticWithLocation, - emptyArray, - escapeLeadingUnderscores, - every, - ExportKind, - factory, - first, - firstDefined, - flatMap, - flatMapIterator, - forEachExternalModuleToImportFrom, - formatting, - getAllowSyntheticDefaultImports, - getBaseFileName, - getDefaultLikeExportInfo, - getDirectoryPath, - getEmitModuleKind, - getEmitModuleResolutionKind, - getEmitScriptTarget, - getExportInfoMap, - getMeaningFromDeclaration, - getMeaningFromLocation, - getNameForExportedSymbol, - getNodeId, - getQuoteFromPreference, - getQuotePreference, - getSourceFileOfNode, - getSymbolId, - getTokenAtPosition, - getTypeKeywordOfTypeOnlyImport, - getUniqueSymbolId, - hostGetCanonicalFileName, - Identifier, - ImportClause, - ImportEqualsDeclaration, - importFromModuleSpecifier, - ImportKind, - ImportsNotUsedAsValues, - insertImports, - InternalSymbolName, - isExternalModule, - isExternalModuleReference, - isIdentifier, - isIdentifierPart, - isIdentifierStart, - isImportableFile, - isImportEqualsDeclaration, - isInJSFile, - isIntrinsicJsxName, - isJsxClosingElement, - isJsxOpeningFragment, - isJsxOpeningLikeElement, - isJSXTagName, - isNamedImports, - isNamespaceImport, - isSourceFileJS, - isStringANonContextualKeyword, - isStringLiteral, - isStringLiteralLike, - isTypeOnlyImportOrExportDeclaration, - isUMDExportSymbol, - isValidTypeOnlyAliasUseSite, - isVariableDeclarationInitializedToRequire, - jsxModeNeedsExplicitImport, - LanguageServiceHost, - last, - makeImport, - makeStringLiteral, - mapDefined, - memoizeOne, - ModuleKind, - ModuleResolutionKind, - moduleResolutionUsesNodeModules, - moduleSpecifiers, - MultiMap, - Mutable, - NamedImports, - Node, - NodeFlags, - nodeIsMissing, - ObjectBindingPattern, - OrganizeImports, - PackageJsonImportFilter, - Path, - pathContainsNodeModules, - pathIsBareSpecifier, - Program, - QuotePreference, - removeFileExtension, - removeSuffix, - RequireVariableStatement, - ScriptTarget, - SemanticMeaning, - shouldUseUriStyleNodeCoreModules, - single, - skipAlias, - some, - sort, - SourceFile, - stableSort, - startsWith, - StringLiteral, - stripQuotes, - Symbol, - SymbolExportInfo, - SymbolFlags, - SymbolId, - SyntaxKind, - textChanges, - toPath, - tryCast, - tryGetModuleSpecifierFromDeclaration, - TypeChecker, - TypeOnlyAliasDeclaration, - UserPreferences, -} from "../_namespaces/ts"; -import { - createCodeFixAction, createCombinedCodeActions, eachDiagnostic, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getQuotePreference } from "../utilities"; +import { + codeActionForFix, + createImportAdder, + fixId, + fixName, + getFixInfos, +} from "./importAdder"; -/** @internal */ -export const importFixName = "import"; -const importFixId = "fixMissingImport"; const errorCodes: readonly number[] = [ Diagnostics.Cannot_find_name_0.code, Diagnostics.Cannot_find_name_0_Did_you_mean_1.code, @@ -158,6 +26,9 @@ const errorCodes: readonly number[] = [ Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type.code, ]; +/** @internal */ +export const importFixName = fixName; + registerCodeFix({ errorCodes, getCodeActions(context) { @@ -165,1365 +36,14 @@ registerCodeFix({ const info = getFixInfos(context, errorCode, span.start, /*useAutoImportProvider*/ true); if (!info) return undefined; const quotePreference = getQuotePreference(sourceFile, preferences); - return info.map(({ fix, symbolName, errorIdentifierText }) => codeActionForFix( - context, - sourceFile, - symbolName, - fix, - /*includeSymbolNameInDescription*/ symbolName !== errorIdentifierText, - quotePreference, - program.getCompilerOptions())); + return info.map(({ fix, symbolName, errorIdentifierText }) => + codeActionForFix(context, sourceFile, symbolName, fix, /*includeSymbolNameInDescription*/ symbolName !== errorIdentifierText, quotePreference, program.getCompilerOptions())); }, - fixIds: [importFixId], + fixIds: [fixId], getAllCodeActions: context => { const { sourceFile, program, preferences, host, cancellationToken } = context; - const importAdder = createImportAdderWorker(sourceFile, program, /*useAutoImportProvider*/ true, preferences, host, cancellationToken); + const importAdder = createImportAdder(sourceFile, program, preferences, host, /*useAutoImportProvider*/ true, cancellationToken); eachDiagnostic(context, errorCodes, diag => importAdder.addImportFromDiagnostic(diag, context)); - return createCombinedCodeActions(textChanges.ChangeTracker.with(context, importAdder.writeFixes)); + return createCombinedCodeActions(ChangeTracker.with(context, importAdder.writeFixes)); }, }); - -/** - * Computes multiple import additions to a file and writes them to a ChangeTracker. - * - * @internal - */ -export interface ImportAdder { - hasFixes(): boolean; - addImportFromDiagnostic: (diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) => void; - addImportFromExportedSymbol: (exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean) => void; - writeFixes: (changeTracker: textChanges.ChangeTracker) => void; -} - -/** @internal */ -export function createImportAdder(sourceFile: SourceFile, program: Program, preferences: UserPreferences, host: LanguageServiceHost, cancellationToken?: CancellationToken): ImportAdder { - return createImportAdderWorker(sourceFile, program, /*useAutoImportProvider*/ false, preferences, host, cancellationToken); -} - -interface AddToExistingState { - readonly importClauseOrBindingPattern: ImportClause | ObjectBindingPattern; - defaultImport: Import | undefined; - readonly namedImports: Map; -} - -function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAutoImportProvider: boolean, preferences: UserPreferences, host: LanguageServiceHost, cancellationToken: CancellationToken | undefined): ImportAdder { - const compilerOptions = program.getCompilerOptions(); - // Namespace fixes don't conflict, so just build a list. - const addToNamespace: FixUseNamespaceImport[] = []; - const importType: FixAddJsdocTypeImport[] = []; - /** Keys are import clause node IDs. */ - const addToExisting = new Map(); - - type NewImportsKey = `${0 | 1}|${string}`; - /** Use `getNewImportEntry` for access */ - const newImports = new Map>(); - return { addImportFromDiagnostic, addImportFromExportedSymbol, writeFixes, hasFixes }; - - function addImportFromDiagnostic(diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) { - const info = getFixInfos(context, diagnostic.code, diagnostic.start, useAutoImportProvider); - if (!info || !info.length) return; - addImport(first(info)); - } - - function addImportFromExportedSymbol(exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean) { - const moduleSymbol = Debug.checkDefined(exportedSymbol.parent); - const symbolName = getNameForExportedSymbol(exportedSymbol, getEmitScriptTarget(compilerOptions)); - const checker = program.getTypeChecker(); - const symbol = checker.getMergedSymbol(skipAlias(exportedSymbol, checker)); - const exportInfo = getAllExportInfoForSymbol(sourceFile, symbol, symbolName, /*isJsxTagName*/ false, program, host, preferences, cancellationToken); - const useRequire = shouldUseRequire(sourceFile, program); - const fix = getImportFixForSymbol(sourceFile, Debug.checkDefined(exportInfo), moduleSymbol, program, /*useNamespaceInfo*/ undefined, !!isValidTypeOnlyUseSite, useRequire, host, preferences); - if (fix) { - addImport({ fix, symbolName, errorIdentifierText: undefined }); - } - } - - function addImport(info: FixInfo) { - const { fix, symbolName } = info; - switch (fix.kind) { - case ImportFixKind.UseNamespace: - addToNamespace.push(fix); - break; - case ImportFixKind.JsdocTypeImport: - importType.push(fix); - break; - case ImportFixKind.AddToExisting: { - const { importClauseOrBindingPattern, importKind, addAsTypeOnly } = fix; - const key = String(getNodeId(importClauseOrBindingPattern)); - let entry = addToExisting.get(key); - if (!entry) { - addToExisting.set(key, entry = { importClauseOrBindingPattern, defaultImport: undefined, namedImports: new Map() }); - } - if (importKind === ImportKind.Named) { - const prevValue = entry?.namedImports.get(symbolName); - entry.namedImports.set(symbolName, reduceAddAsTypeOnlyValues(prevValue, addAsTypeOnly)); - } - else { - Debug.assert(entry.defaultImport === undefined || entry.defaultImport.name === symbolName, "(Add to Existing) Default import should be missing or match symbolName"); - entry.defaultImport = { - name: symbolName, - addAsTypeOnly: reduceAddAsTypeOnlyValues(entry.defaultImport?.addAsTypeOnly, addAsTypeOnly), - }; - } - break; - } - case ImportFixKind.AddNew: { - const { moduleSpecifier, importKind, useRequire, addAsTypeOnly } = fix; - const entry = getNewImportEntry(moduleSpecifier, importKind, useRequire, addAsTypeOnly); - Debug.assert(entry.useRequire === useRequire, "(Add new) Tried to add an `import` and a `require` for the same module"); - - switch (importKind) { - case ImportKind.Default: - Debug.assert(entry.defaultImport === undefined || entry.defaultImport.name === symbolName, "(Add new) Default import should be missing or match symbolName"); - entry.defaultImport = { name: symbolName, addAsTypeOnly: reduceAddAsTypeOnlyValues(entry.defaultImport?.addAsTypeOnly, addAsTypeOnly) }; - break; - case ImportKind.Named: - const prevValue = (entry.namedImports ||= new Map()).get(symbolName); - entry.namedImports.set(symbolName, reduceAddAsTypeOnlyValues(prevValue, addAsTypeOnly)); - break; - case ImportKind.CommonJS: - case ImportKind.Namespace: - Debug.assert(entry.namespaceLikeImport === undefined || entry.namespaceLikeImport.name === symbolName, "Namespacelike import shoudl be missing or match symbolName"); - entry.namespaceLikeImport = { importKind, name: symbolName, addAsTypeOnly }; - break; - } - break; - } - case ImportFixKind.PromoteTypeOnly: - // Excluding from fix-all - break; - default: - Debug.assertNever(fix, `fix wasn't never - got kind ${(fix as ImportFix).kind}`); - } - - function reduceAddAsTypeOnlyValues(prevValue: AddAsTypeOnly | undefined, newValue: AddAsTypeOnly): AddAsTypeOnly { - // `NotAllowed` overrides `Required` because one addition of a new import might be required to be type-only - // because of `--importsNotUsedAsValues=error`, but if a second addition of the same import is `NotAllowed` - // to be type-only, the reason the first one was `Required` - the unused runtime dependency - is now moot. - // Alternatively, if one addition is `Required` because it has no value meaning under `--preserveValueImports` - // and `--isolatedModules`, it should be impossible for another addition to be `NotAllowed` since that would - // mean a type is being referenced in a value location. - return Math.max(prevValue ?? 0, newValue); - } - - function getNewImportEntry(moduleSpecifier: string, importKind: ImportKind, useRequire: boolean, addAsTypeOnly: AddAsTypeOnly): Mutable { - // A default import that requires type-only makes the whole import type-only. - // (We could add `default` as a named import, but that style seems undesirable.) - // Under `--preserveValueImports` and `--importsNotUsedAsValues=error`, if a - // module default-exports a type but named-exports some values (weird), you would - // have to use a type-only default import and non-type-only named imports. These - // require two separate import declarations, so we build this into the map key. - const typeOnlyKey = newImportsKey(moduleSpecifier, /*topLevelTypeOnly*/ true); - const nonTypeOnlyKey = newImportsKey(moduleSpecifier, /*topLevelTypeOnly*/ false); - const typeOnlyEntry = newImports.get(typeOnlyKey); - const nonTypeOnlyEntry = newImports.get(nonTypeOnlyKey); - const newEntry: ImportsCollection & { useRequire: boolean } = { - defaultImport: undefined, - namedImports: undefined, - namespaceLikeImport: undefined, - useRequire - }; - if (importKind === ImportKind.Default && addAsTypeOnly === AddAsTypeOnly.Required) { - if (typeOnlyEntry) return typeOnlyEntry; - newImports.set(typeOnlyKey, newEntry); - return newEntry; - } - if (addAsTypeOnly === AddAsTypeOnly.Allowed && (typeOnlyEntry || nonTypeOnlyEntry)) { - return (typeOnlyEntry || nonTypeOnlyEntry)!; - } - if (nonTypeOnlyEntry) { - return nonTypeOnlyEntry; - } - newImports.set(nonTypeOnlyKey, newEntry); - return newEntry; - } - - function newImportsKey(moduleSpecifier: string, topLevelTypeOnly: boolean): NewImportsKey { - return `${topLevelTypeOnly ? 1 : 0}|${moduleSpecifier}`; - } - } - - function writeFixes(changeTracker: textChanges.ChangeTracker) { - const quotePreference = getQuotePreference(sourceFile, preferences); - for (const fix of addToNamespace) { - addNamespaceQualifier(changeTracker, sourceFile, fix); - } - for (const fix of importType) { - addImportType(changeTracker, sourceFile, fix, quotePreference); - } - addToExisting.forEach(({ importClauseOrBindingPattern, defaultImport, namedImports }) => { - doAddExistingFix( - changeTracker, - sourceFile, - importClauseOrBindingPattern, - defaultImport, - arrayFrom(namedImports.entries(), ([name, addAsTypeOnly]) => ({ addAsTypeOnly, name })), - compilerOptions); - }); - - let newDeclarations: AnyImportOrRequireStatement | readonly AnyImportOrRequireStatement[] | undefined; - newImports.forEach(({ useRequire, defaultImport, namedImports, namespaceLikeImport }, key) => { - const moduleSpecifier = key.slice(2); // From `${0 | 1}|${moduleSpecifier}` format - const getDeclarations = useRequire ? getNewRequires : getNewImports; - const declarations = getDeclarations( - moduleSpecifier, - quotePreference, - defaultImport, - namedImports && arrayFrom(namedImports.entries(), ([name, addAsTypeOnly]) => ({ addAsTypeOnly, name })), - namespaceLikeImport); - newDeclarations = combine(newDeclarations, declarations); - }); - if (newDeclarations) { - insertImports(changeTracker, sourceFile, newDeclarations, /*blankLineBetween*/ true); - } - } - - function hasFixes() { - return addToNamespace.length > 0 || importType.length > 0 || addToExisting.size > 0 || newImports.size > 0; - } -} - -/** - * Computes module specifiers for multiple import additions to a file. - * - * @internal - */ - export interface ImportSpecifierResolver { - getModuleSpecifierForBestExportInfo( - exportInfo: readonly SymbolExportInfo[], - symbolName: string, - position: number, - isValidTypeOnlyUseSite: boolean, - fromCacheOnly?: boolean - ): { exportInfo?: SymbolExportInfo, moduleSpecifier: string, computedWithoutCacheCount: number } | undefined; -} - -/** @internal */ -export function createImportSpecifierResolver(importingFile: SourceFile, program: Program, host: LanguageServiceHost, preferences: UserPreferences): ImportSpecifierResolver { - const packageJsonImportFilter = createPackageJsonImportFilter(importingFile, preferences, host); - const importMap = createExistingImportMap(program.getTypeChecker(), importingFile, program.getCompilerOptions()); - return { getModuleSpecifierForBestExportInfo }; - - function getModuleSpecifierForBestExportInfo( - exportInfo: readonly SymbolExportInfo[], - symbolName: string, - position: number, - isValidTypeOnlyUseSite: boolean, - fromCacheOnly?: boolean, - ): { exportInfo?: SymbolExportInfo, moduleSpecifier: string, computedWithoutCacheCount: number } | undefined { - const { fixes, computedWithoutCacheCount } = getImportFixes( - exportInfo, - { symbolName, position }, - isValidTypeOnlyUseSite, - /*useRequire*/ false, - program, - importingFile, - host, - preferences, - importMap, - fromCacheOnly); - const result = getBestFix(fixes, importingFile, program, packageJsonImportFilter, host); - return result && { ...result, computedWithoutCacheCount }; - } -} - -// Sorted with the preferred fix coming first. -const enum ImportFixKind { UseNamespace, JsdocTypeImport, AddToExisting, AddNew, PromoteTypeOnly } -// These should not be combined as bitflags, but are given powers of 2 values to -// easily detect conflicts between `NotAllowed` and `Required` by giving them a unique sum. -// They're also ordered in terms of increasing priority for a fix-all scenario (see -// `reduceAddAsTypeOnlyValues`). -const enum AddAsTypeOnly { - Allowed = 1 << 0, - Required = 1 << 1, - NotAllowed = 1 << 2, -} -type ImportFix = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport | FixPromoteTypeOnlyImport; -type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport; - -// Properties are be undefined if fix is derived from an existing import -interface ImportFixBase { - readonly isReExport?: boolean; - readonly exportInfo?: SymbolExportInfo; - readonly moduleSpecifier: string; -} -interface FixUseNamespaceImport extends ImportFixBase { - readonly kind: ImportFixKind.UseNamespace; - readonly namespacePrefix: string; - readonly position: number; -} -interface FixAddJsdocTypeImport extends ImportFixBase { - readonly kind: ImportFixKind.JsdocTypeImport; - readonly position: number; - readonly isReExport: boolean; - readonly exportInfo: SymbolExportInfo; -} -interface FixAddToExistingImport extends ImportFixBase { - readonly kind: ImportFixKind.AddToExisting; - readonly importClauseOrBindingPattern: ImportClause | ObjectBindingPattern; - readonly importKind: ImportKind.Default | ImportKind.Named; - readonly addAsTypeOnly: AddAsTypeOnly; -} -interface FixAddNewImport extends ImportFixBase { - readonly kind: ImportFixKind.AddNew; - readonly importKind: ImportKind; - readonly addAsTypeOnly: AddAsTypeOnly; - readonly useRequire: boolean; -} -interface FixPromoteTypeOnlyImport { - readonly kind: ImportFixKind.PromoteTypeOnly; - readonly typeOnlyAliasDeclaration: TypeOnlyAliasDeclaration; -} - - -/** Information needed to augment an existing import declaration. */ -interface FixAddToExistingImportInfo { - readonly declaration: AnyImportOrRequire; - readonly importKind: ImportKind; - readonly targetFlags: SymbolFlags; - readonly symbol: Symbol; -} - -/** @internal */ -export function getImportCompletionAction( - targetSymbol: Symbol, - moduleSymbol: Symbol, - sourceFile: SourceFile, - symbolName: string, - isJsxTagName: boolean, - host: LanguageServiceHost, - program: Program, - formatContext: formatting.FormatContext, - position: number, - preferences: UserPreferences, - cancellationToken: CancellationToken, -): { readonly moduleSpecifier: string, readonly codeAction: CodeAction } { - const compilerOptions = program.getCompilerOptions(); - - const exportInfos = pathIsBareSpecifier(stripQuotes(moduleSymbol.name)) - ? [getSingleExportInfoForSymbol(targetSymbol, moduleSymbol, program, host)] - : getAllExportInfoForSymbol(sourceFile, targetSymbol, symbolName, isJsxTagName, program, host, preferences, cancellationToken); - - Debug.assertIsDefined(exportInfos); - const useRequire = shouldUseRequire(sourceFile, program); - const isValidTypeOnlyUseSite = isValidTypeOnlyAliasUseSite(getTokenAtPosition(sourceFile, position)); - const fix = Debug.checkDefined(getImportFixForSymbol(sourceFile, exportInfos, moduleSymbol, program, { symbolName, position }, isValidTypeOnlyUseSite, useRequire, host, preferences)); - return { - moduleSpecifier: fix.moduleSpecifier, - codeAction: codeFixActionToCodeAction(codeActionForFix( - { host, formatContext, preferences }, - sourceFile, - symbolName, - fix, - /*includeSymbolNameInDescription*/ false, - getQuotePreference(sourceFile, preferences), compilerOptions)) - }; -} - -/** @internal */ -export function getPromoteTypeOnlyCompletionAction(sourceFile: SourceFile, symbolToken: Identifier, program: Program, host: LanguageServiceHost, formatContext: formatting.FormatContext, preferences: UserPreferences) { - const compilerOptions = program.getCompilerOptions(); - const symbolName = single(getSymbolNamesToImport(sourceFile, program.getTypeChecker(), symbolToken, compilerOptions)); - const fix = getTypeOnlyPromotionFix(sourceFile, symbolToken, symbolName, program); - const includeSymbolNameInDescription = symbolName !== symbolToken.text; - return fix && codeFixActionToCodeAction(codeActionForFix({ host, formatContext, preferences }, sourceFile, symbolName, fix, includeSymbolNameInDescription, QuotePreference.Double, compilerOptions)); -} - -function getImportFixForSymbol(sourceFile: SourceFile, exportInfos: readonly SymbolExportInfo[], moduleSymbol: Symbol, program: Program, useNamespaceInfo: { position: number, symbolName: string } | undefined, isValidTypeOnlyUseSite: boolean, useRequire: boolean, host: LanguageServiceHost, preferences: UserPreferences) { - Debug.assert(exportInfos.some(info => info.moduleSymbol === moduleSymbol || info.symbol.parent === moduleSymbol), "Some exportInfo should match the specified moduleSymbol"); - const packageJsonImportFilter = createPackageJsonImportFilter(sourceFile, preferences, host); - return getBestFix(getImportFixes(exportInfos, useNamespaceInfo, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences).fixes, sourceFile, program, packageJsonImportFilter, host); -} - -function codeFixActionToCodeAction({ description, changes, commands }: CodeFixAction): CodeAction { - return { description, changes, commands }; -} - -function getAllExportInfoForSymbol(importingFile: SourceFile, symbol: Symbol, symbolName: string, preferCapitalized: boolean, program: Program, host: LanguageServiceHost, preferences: UserPreferences, cancellationToken: CancellationToken | undefined): readonly SymbolExportInfo[] | undefined { - const getChecker = createGetChecker(program, host); - return getExportInfoMap(importingFile, host, program, preferences, cancellationToken) - .search(importingFile.path, preferCapitalized, name => name === symbolName, info => { - if (skipAlias(info[0].symbol, getChecker(info[0].isFromPackageJson)) === symbol) { - return info; - } - }); -} - -function getSingleExportInfoForSymbol(symbol: Symbol, moduleSymbol: Symbol, program: Program, host: LanguageServiceHost): SymbolExportInfo { - const compilerOptions = program.getCompilerOptions(); - const mainProgramInfo = getInfoWithChecker(program.getTypeChecker(), /*isFromPackageJson*/ false); - if (mainProgramInfo) { - return mainProgramInfo; - } - const autoImportProvider = host.getPackageJsonAutoImportProvider?.()?.getTypeChecker(); - return Debug.checkDefined(autoImportProvider && getInfoWithChecker(autoImportProvider, /*isFromPackageJson*/ true), `Could not find symbol in specified module for code actions`); - - function getInfoWithChecker(checker: TypeChecker, isFromPackageJson: boolean): SymbolExportInfo | undefined { - const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions); - if (defaultInfo && skipAlias(defaultInfo.symbol, checker) === symbol) { - return { symbol: defaultInfo.symbol, moduleSymbol, moduleFileName: undefined, exportKind: defaultInfo.exportKind, targetFlags: skipAlias(symbol, checker).flags, isFromPackageJson }; - } - const named = checker.tryGetMemberInModuleExportsAndProperties(symbol.name, moduleSymbol); - if (named && skipAlias(named, checker) === symbol) { - return { symbol: named, moduleSymbol, moduleFileName: undefined, exportKind: ExportKind.Named, targetFlags: skipAlias(symbol, checker).flags, isFromPackageJson }; - } - } -} - -function getImportFixes( - exportInfos: readonly SymbolExportInfo[], - useNamespaceInfo: { - symbolName: string, - position: number, - } | undefined, - /** undefined only for missing JSX namespace */ - isValidTypeOnlyUseSite: boolean, - useRequire: boolean, - program: Program, - sourceFile: SourceFile, - host: LanguageServiceHost, - preferences: UserPreferences, - importMap = createExistingImportMap(program.getTypeChecker(), sourceFile, program.getCompilerOptions()), - fromCacheOnly?: boolean, -): { computedWithoutCacheCount: number, fixes: readonly ImportFixWithModuleSpecifier[] } { - const checker = program.getTypeChecker(); - const existingImports = flatMap(exportInfos, importMap.getImportsForExportInfo); - const useNamespace = useNamespaceInfo && tryUseExistingNamespaceImport(existingImports, useNamespaceInfo.symbolName, useNamespaceInfo.position, checker); - const addToExisting = tryAddToExistingImport(existingImports, isValidTypeOnlyUseSite, checker, program.getCompilerOptions()); - if (addToExisting) { - // Don't bother providing an action to add a new import if we can add to an existing one. - return { - computedWithoutCacheCount: 0, - fixes: [...(useNamespace ? [useNamespace] : emptyArray), addToExisting], - }; - } - - const { fixes, computedWithoutCacheCount = 0 } = getFixesForAddImport( - exportInfos, - existingImports, - program, - sourceFile, - useNamespaceInfo?.position, - isValidTypeOnlyUseSite, - useRequire, - host, - preferences, - fromCacheOnly); - return { - computedWithoutCacheCount, - fixes: [...(useNamespace ? [useNamespace] : emptyArray), ...fixes], - }; -} - -function tryUseExistingNamespaceImport(existingImports: readonly FixAddToExistingImportInfo[], symbolName: string, position: number, checker: TypeChecker): FixUseNamespaceImport | undefined { - // It is possible that multiple import statements with the same specifier exist in the file. - // e.g. - // - // import * as ns from "foo"; - // import { member1, member2 } from "foo"; - // - // member3/**/ <-- cusor here - // - // in this case we should provie 2 actions: - // 1. change "member3" to "ns.member3" - // 2. add "member3" to the second import statement's import list - // and it is up to the user to decide which one fits best. - return firstDefined(existingImports, ({ declaration }): FixUseNamespaceImport | undefined => { - const namespacePrefix = getNamespaceLikeImportText(declaration); - const moduleSpecifier = tryGetModuleSpecifierFromDeclaration(declaration)?.text; - if (namespacePrefix && moduleSpecifier) { - const moduleSymbol = getTargetModuleFromNamespaceLikeImport(declaration, checker); - if (moduleSymbol && moduleSymbol.exports!.has(escapeLeadingUnderscores(symbolName))) { - return { kind: ImportFixKind.UseNamespace, namespacePrefix, position, moduleSpecifier }; - } - } - }); -} - -function getTargetModuleFromNamespaceLikeImport(declaration: AnyImportOrRequire, checker: TypeChecker) { - switch (declaration.kind) { - case SyntaxKind.VariableDeclaration: - return checker.resolveExternalModuleName(declaration.initializer.arguments[0]); - case SyntaxKind.ImportEqualsDeclaration: - return checker.getAliasedSymbol(declaration.symbol); - case SyntaxKind.ImportDeclaration: - const namespaceImport = tryCast(declaration.importClause?.namedBindings, isNamespaceImport); - return namespaceImport && checker.getAliasedSymbol(namespaceImport.symbol); - default: - return Debug.assertNever(declaration); - } -} - -function getNamespaceLikeImportText(declaration: AnyImportOrRequire) { - switch (declaration.kind) { - case SyntaxKind.VariableDeclaration: - return tryCast(declaration.name, isIdentifier)?.text; - case SyntaxKind.ImportEqualsDeclaration: - return declaration.name.text; - case SyntaxKind.ImportDeclaration: - return tryCast(declaration.importClause?.namedBindings, isNamespaceImport)?.name.text; - default: - return Debug.assertNever(declaration); - } -} - -function getAddAsTypeOnly( - isValidTypeOnlyUseSite: boolean, - isForNewImportDeclaration: boolean, - symbol: Symbol, - targetFlags: SymbolFlags, - checker: TypeChecker, - compilerOptions: CompilerOptions -) { - if (!isValidTypeOnlyUseSite) { - // Can't use a type-only import if the usage is an emitting position - return AddAsTypeOnly.NotAllowed; - } - if (isForNewImportDeclaration && compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Error) { - // Not writing a (top-level) type-only import here would create an error because the runtime dependency is unnecessary - return AddAsTypeOnly.Required; - } - if (compilerOptions.isolatedModules && compilerOptions.preserveValueImports && - (!(targetFlags & SymbolFlags.Value) || !!checker.getTypeOnlyAliasDeclaration(symbol)) - ) { - // A type-only import is required for this symbol if under these settings if the symbol will - // be erased, which will happen if the target symbol is purely a type or if it was exported/imported - // as type-only already somewhere between this import and the target. - return AddAsTypeOnly.Required; - } - return AddAsTypeOnly.Allowed; -} - -function tryAddToExistingImport(existingImports: readonly FixAddToExistingImportInfo[], isValidTypeOnlyUseSite: boolean, checker: TypeChecker, compilerOptions: CompilerOptions): FixAddToExistingImport | undefined { - return firstDefined(existingImports, ({ declaration, importKind, symbol, targetFlags }): FixAddToExistingImport | undefined => { - if (importKind === ImportKind.CommonJS || importKind === ImportKind.Namespace || declaration.kind === SyntaxKind.ImportEqualsDeclaration) { - // These kinds of imports are not combinable with anything - return undefined; - } - - if (declaration.kind === SyntaxKind.VariableDeclaration) { - return (importKind === ImportKind.Named || importKind === ImportKind.Default) && declaration.name.kind === SyntaxKind.ObjectBindingPattern - ? { kind: ImportFixKind.AddToExisting, importClauseOrBindingPattern: declaration.name, importKind, moduleSpecifier: declaration.initializer.arguments[0].text, addAsTypeOnly: AddAsTypeOnly.NotAllowed } - : undefined; - } - - const { importClause } = declaration; - if (!importClause || !isStringLiteralLike(declaration.moduleSpecifier)) return undefined; - const { name, namedBindings } = importClause; - // A type-only import may not have both a default and named imports, so the only way a name can - // be added to an existing type-only import is adding a named import to existing named bindings. - if (importClause.isTypeOnly && !(importKind === ImportKind.Named && namedBindings)) return undefined; - - // N.B. we don't have to figure out whether to use the main program checker - // or the AutoImportProvider checker because we're adding to an existing import; the existence of - // the import guarantees the symbol came from the main program. - const addAsTypeOnly = getAddAsTypeOnly(isValidTypeOnlyUseSite, /*isForNewImportDeclaration*/ false, symbol, targetFlags, checker, compilerOptions); - - if (importKind === ImportKind.Default && ( - name || // Cannot add a default import to a declaration that already has one - addAsTypeOnly === AddAsTypeOnly.Required && namedBindings // Cannot add a default import as type-only if the import already has named bindings - )) return undefined; - if ( - importKind === ImportKind.Named && - namedBindings?.kind === SyntaxKind.NamespaceImport // Cannot add a named import to a declaration that has a namespace import - ) return undefined; - - return { - kind: ImportFixKind.AddToExisting, - importClauseOrBindingPattern: importClause, - importKind, - moduleSpecifier: declaration.moduleSpecifier.text, - addAsTypeOnly, - }; - }); -} - -function createExistingImportMap(checker: TypeChecker, importingFile: SourceFile, compilerOptions: CompilerOptions) { - let importMap: MultiMap | undefined; - for (const moduleSpecifier of importingFile.imports) { - const i = importFromModuleSpecifier(moduleSpecifier); - if (isVariableDeclarationInitializedToRequire(i.parent)) { - const moduleSymbol = checker.resolveExternalModuleName(moduleSpecifier); - if (moduleSymbol) { - (importMap ||= createMultiMap()).add(getSymbolId(moduleSymbol), i.parent); - } - } - else if (i.kind === SyntaxKind.ImportDeclaration || i.kind === SyntaxKind.ImportEqualsDeclaration) { - const moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier); - if (moduleSymbol) { - (importMap ||= createMultiMap()).add(getSymbolId(moduleSymbol), i); - } - } - } - - return { - getImportsForExportInfo: ({ moduleSymbol, exportKind, targetFlags, symbol }: SymbolExportInfo): readonly FixAddToExistingImportInfo[] => { - // Can't use an es6 import for a type in JS. - if (!(targetFlags & SymbolFlags.Value) && isSourceFileJS(importingFile)) return emptyArray; - const matchingDeclarations = importMap?.get(getSymbolId(moduleSymbol)); - if (!matchingDeclarations) return emptyArray; - const importKind = getImportKind(importingFile, exportKind, compilerOptions); - return matchingDeclarations.map(declaration => ({ declaration, importKind, symbol, targetFlags })); - } - }; -} - -function shouldUseRequire(sourceFile: SourceFile, program: Program): boolean { - // 1. TypeScript files don't use require variable declarations - if (!isSourceFileJS(sourceFile)) { - return false; - } - - // 2. If the current source file is unambiguously CJS or ESM, go with that - if (sourceFile.commonJsModuleIndicator && !sourceFile.externalModuleIndicator) return true; - if (sourceFile.externalModuleIndicator && !sourceFile.commonJsModuleIndicator) return false; - - // 3. If there's a tsconfig/jsconfig, use its module setting - const compilerOptions = program.getCompilerOptions(); - if (compilerOptions.configFile) { - return getEmitModuleKind(compilerOptions) < ModuleKind.ES2015; - } - - // 4. Match the first other JS file in the program that's unambiguously CJS or ESM - for (const otherFile of program.getSourceFiles()) { - if (otherFile === sourceFile || !isSourceFileJS(otherFile) || program.isSourceFileFromExternalLibrary(otherFile)) continue; - if (otherFile.commonJsModuleIndicator && !otherFile.externalModuleIndicator) return true; - if (otherFile.externalModuleIndicator && !otherFile.commonJsModuleIndicator) return false; - } - - // 5. Literally nothing to go on - return true; -} - -function createGetChecker(program: Program, host: LanguageServiceHost) { - return memoizeOne((isFromPackageJson: boolean) => isFromPackageJson ? host.getPackageJsonAutoImportProvider!()!.getTypeChecker() : program.getTypeChecker()); -} - -function getNewImportFixes( - program: Program, - sourceFile: SourceFile, - position: number | undefined, - isValidTypeOnlyUseSite: boolean, - useRequire: boolean, - exportInfo: readonly SymbolExportInfo[], - host: LanguageServiceHost, - preferences: UserPreferences, - fromCacheOnly?: boolean, -): { computedWithoutCacheCount: number, fixes: readonly (FixAddNewImport | FixAddJsdocTypeImport)[] } { - const isJs = isSourceFileJS(sourceFile); - const compilerOptions = program.getCompilerOptions(); - const moduleSpecifierResolutionHost = createModuleSpecifierResolutionHost(program, host); - const getChecker = createGetChecker(program, host); - const rejectNodeModulesRelativePaths = moduleResolutionUsesNodeModules(getEmitModuleResolutionKind(compilerOptions)); - const getModuleSpecifiers = fromCacheOnly - ? (moduleSymbol: Symbol) => ({ moduleSpecifiers: moduleSpecifiers.tryGetModuleSpecifiersFromCache(moduleSymbol, sourceFile, moduleSpecifierResolutionHost, preferences), computedWithoutCache: false }) - : (moduleSymbol: Symbol, checker: TypeChecker) => moduleSpecifiers.getModuleSpecifiersWithCacheInfo(moduleSymbol, checker, compilerOptions, sourceFile, moduleSpecifierResolutionHost, preferences); - - let computedWithoutCacheCount = 0; - const fixes = flatMap(exportInfo, (exportInfo, i) => { - const checker = getChecker(exportInfo.isFromPackageJson); - const { computedWithoutCache, moduleSpecifiers } = getModuleSpecifiers(exportInfo.moduleSymbol, checker); - const importedSymbolHasValueMeaning = !!(exportInfo.targetFlags & SymbolFlags.Value); - const addAsTypeOnly = getAddAsTypeOnly(isValidTypeOnlyUseSite, /*isForNewImportDeclaration*/ true, exportInfo.symbol, exportInfo.targetFlags, checker, compilerOptions); - computedWithoutCacheCount += computedWithoutCache ? 1 : 0; - return mapDefined(moduleSpecifiers, (moduleSpecifier): FixAddNewImport | FixAddJsdocTypeImport | undefined => - rejectNodeModulesRelativePaths && pathContainsNodeModules(moduleSpecifier) ? undefined : - // `position` should only be undefined at a missing jsx namespace, in which case we shouldn't be looking for pure types. - !importedSymbolHasValueMeaning && isJs && position !== undefined ? { kind: ImportFixKind.JsdocTypeImport, moduleSpecifier, position, exportInfo, isReExport: i > 0 } : - { - kind: ImportFixKind.AddNew, - moduleSpecifier, - importKind: getImportKind(sourceFile, exportInfo.exportKind, compilerOptions), - useRequire, - addAsTypeOnly, - exportInfo, - isReExport: i > 0, - } - ); - }); - - return { computedWithoutCacheCount, fixes }; -} - -function getFixesForAddImport( - exportInfos: readonly SymbolExportInfo[], - existingImports: readonly FixAddToExistingImportInfo[], - program: Program, - sourceFile: SourceFile, - position: number | undefined, - isValidTypeOnlyUseSite: boolean, - useRequire: boolean, - host: LanguageServiceHost, - preferences: UserPreferences, - fromCacheOnly?: boolean, -): { computedWithoutCacheCount?: number, fixes: readonly (FixAddNewImport | FixAddJsdocTypeImport)[] } { - const existingDeclaration = firstDefined(existingImports, info => newImportInfoFromExistingSpecifier(info, isValidTypeOnlyUseSite, useRequire, program.getTypeChecker(), program.getCompilerOptions())); - return existingDeclaration ? { fixes: [existingDeclaration] } : getNewImportFixes(program, sourceFile, position, isValidTypeOnlyUseSite, useRequire, exportInfos, host, preferences, fromCacheOnly); -} - -function newImportInfoFromExistingSpecifier( - { declaration, importKind, symbol, targetFlags }: FixAddToExistingImportInfo, - isValidTypeOnlyUseSite: boolean, - useRequire: boolean, - checker: TypeChecker, - compilerOptions: CompilerOptions -): FixAddNewImport | undefined { - const moduleSpecifier = tryGetModuleSpecifierFromDeclaration(declaration)?.text; - if (moduleSpecifier) { - const addAsTypeOnly = useRequire - ? AddAsTypeOnly.NotAllowed - : getAddAsTypeOnly(isValidTypeOnlyUseSite, /*isForNewImportDeclaration*/ true, symbol, targetFlags, checker, compilerOptions); - return { kind: ImportFixKind.AddNew, moduleSpecifier, importKind, addAsTypeOnly, useRequire }; - } -} - -interface FixInfo { - readonly fix: ImportFix; - readonly symbolName: string; - readonly errorIdentifierText: string | undefined; - readonly isJsxNamespaceFix?: boolean; -} -function getFixInfos(context: CodeFixContextBase, errorCode: number, pos: number, useAutoImportProvider: boolean): readonly FixInfo[] | undefined { - const symbolToken = getTokenAtPosition(context.sourceFile, pos); - let info; - if (errorCode === Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code) { - info = getFixesInfoForUMDImport(context, symbolToken); - } - else if (!isIdentifier(symbolToken)) { - return undefined; - } - else if (errorCode === Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type.code) { - const symbolName = single(getSymbolNamesToImport(context.sourceFile, context.program.getTypeChecker(), symbolToken, context.program.getCompilerOptions())); - const fix = getTypeOnlyPromotionFix(context.sourceFile, symbolToken, symbolName, context.program); - return fix && [{ fix, symbolName, errorIdentifierText: symbolToken.text }]; - } - else { - info = getFixesInfoForNonUMDImport(context, symbolToken, useAutoImportProvider); - } - - const packageJsonImportFilter = createPackageJsonImportFilter(context.sourceFile, context.preferences, context.host); - return info && sortFixInfo(info, context.sourceFile, context.program, packageJsonImportFilter, context.host); -} - -function sortFixInfo(fixes: readonly (FixInfo & { fix: ImportFixWithModuleSpecifier })[], sourceFile: SourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier })[] { - const _toPath = (fileName: string) => toPath(fileName, host.getCurrentDirectory(), hostGetCanonicalFileName(host)); - return sort(fixes, (a, b) => - compareBooleans(!!a.isJsxNamespaceFix, !!b.isJsxNamespaceFix) || - compareValues(a.fix.kind, b.fix.kind) || - compareModuleSpecifiers(a.fix, b.fix, sourceFile, program, packageJsonImportFilter.allowsImportingSpecifier, _toPath)); -} - -function getBestFix(fixes: readonly ImportFixWithModuleSpecifier[], sourceFile: SourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): ImportFixWithModuleSpecifier | undefined { - if (!some(fixes)) return; - // These will always be placed first if available, and are better than other kinds - if (fixes[0].kind === ImportFixKind.UseNamespace || fixes[0].kind === ImportFixKind.AddToExisting) { - return fixes[0]; - } - - return fixes.reduce((best, fix) => - // Takes true branch of conditional if `fix` is better than `best` - compareModuleSpecifiers( - fix, - best, - sourceFile, - program, - packageJsonImportFilter.allowsImportingSpecifier, - fileName => toPath(fileName, host.getCurrentDirectory(), hostGetCanonicalFileName(host)), - ) === Comparison.LessThan ? fix : best - ); -} - -/** @returns `Comparison.LessThan` if `a` is better than `b`. */ -function compareModuleSpecifiers( - a: ImportFixWithModuleSpecifier, - b: ImportFixWithModuleSpecifier, - importingFile: SourceFile, - program: Program, - allowsImportingSpecifier: (specifier: string) => boolean, - toPath: (fileName: string) => Path, -): Comparison { - if (a.kind !== ImportFixKind.UseNamespace && b.kind !== ImportFixKind.UseNamespace) { - return compareBooleans(allowsImportingSpecifier(b.moduleSpecifier), allowsImportingSpecifier(a.moduleSpecifier)) - || compareNodeCoreModuleSpecifiers(a.moduleSpecifier, b.moduleSpecifier, importingFile, program) - || compareBooleans( - isFixPossiblyReExportingImportingFile(a, importingFile, program.getCompilerOptions(), toPath), - isFixPossiblyReExportingImportingFile(b, importingFile, program.getCompilerOptions(), toPath)) - || compareNumberOfDirectorySeparators(a.moduleSpecifier, b.moduleSpecifier); - } - return Comparison.EqualTo; -} - -// This is a simple heuristic to try to avoid creating an import cycle with a barrel re-export. -// E.g., do not `import { Foo } from ".."` when you could `import { Foo } from "../Foo"`. -// This can produce false positives or negatives if re-exports cross into sibling directories -// (e.g. `export * from "../whatever"`) or are not named "index" (we don't even try to consider -// this if we're in a resolution mode where you can't drop trailing "/index" from paths). -function isFixPossiblyReExportingImportingFile(fix: ImportFixWithModuleSpecifier, importingFile: SourceFile, compilerOptions: CompilerOptions, toPath: (fileName: string) => Path): boolean { - if (fix.isReExport && - fix.exportInfo?.moduleFileName && - getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs && - isIndexFileName(fix.exportInfo.moduleFileName) - ) { - const reExportDir = toPath(getDirectoryPath(fix.exportInfo.moduleFileName)); - return startsWith((importingFile.path), reExportDir); - } - return false; -} - -function isIndexFileName(fileName: string) { - return getBaseFileName(fileName, [".js", ".jsx", ".d.ts", ".ts", ".tsx"], /*ignoreCase*/ true) === "index"; -} - -function compareNodeCoreModuleSpecifiers(a: string, b: string, importingFile: SourceFile, program: Program): Comparison { - if (startsWith(a, "node:") && !startsWith(b, "node:")) return shouldUseUriStyleNodeCoreModules(importingFile, program) ? Comparison.LessThan : Comparison.GreaterThan; - if (startsWith(b, "node:") && !startsWith(a, "node:")) return shouldUseUriStyleNodeCoreModules(importingFile, program) ? Comparison.GreaterThan : Comparison.LessThan; - return Comparison.EqualTo; -} - -function getFixesInfoForUMDImport({ sourceFile, program, host, preferences }: CodeFixContextBase, token: Node): (FixInfo & { fix: ImportFixWithModuleSpecifier })[] | undefined { - const checker = program.getTypeChecker(); - const umdSymbol = getUmdSymbol(token, checker); - if (!umdSymbol) return undefined; - const symbol = checker.getAliasedSymbol(umdSymbol); - const symbolName = umdSymbol.name; - const exportInfo: readonly SymbolExportInfo[] = [{ symbol: umdSymbol, moduleSymbol: symbol, moduleFileName: undefined, exportKind: ExportKind.UMD, targetFlags: symbol.flags, isFromPackageJson: false }]; - const useRequire = shouldUseRequire(sourceFile, program); - const position = isIdentifier(token) ? token.getStart(sourceFile) : undefined; - const fixes = getImportFixes(exportInfo, position ? { position, symbolName } : undefined, /*isValidTypeOnlyUseSite*/ false, useRequire, program, sourceFile, host, preferences).fixes; - return fixes.map(fix => ({ fix, symbolName, errorIdentifierText: tryCast(token, isIdentifier)?.text })); -} -function getUmdSymbol(token: Node, checker: TypeChecker): Symbol | undefined { - // try the identifier to see if it is the umd symbol - const umdSymbol = isIdentifier(token) ? checker.getSymbolAtLocation(token) : undefined; - if (isUMDExportSymbol(umdSymbol)) return umdSymbol; - - // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. - const { parent } = token; - return (isJsxOpeningLikeElement(parent) && parent.tagName === token) || isJsxOpeningFragment(parent) - ? tryCast(checker.resolveName(checker.getJsxNamespace(parent), isJsxOpeningLikeElement(parent) ? token : parent, SymbolFlags.Value, /*excludeGlobals*/ false), isUMDExportSymbol) - : undefined; -} - -/** - * @param forceImportKeyword Indicates that the user has already typed `import`, so the result must start with `import`. - * (In other words, do not allow `const x = require("...")` for JS files.) - * - * @internal - */ -export function getImportKind(importingFile: SourceFile, exportKind: ExportKind, compilerOptions: CompilerOptions, forceImportKeyword?: boolean): ImportKind { - switch (exportKind) { - case ExportKind.Named: return ImportKind.Named; - case ExportKind.Default: return ImportKind.Default; - case ExportKind.ExportEquals: return getExportEqualsImportKind(importingFile, compilerOptions, !!forceImportKeyword); - case ExportKind.UMD: return getUmdImportKind(importingFile, compilerOptions, !!forceImportKeyword); - default: return Debug.assertNever(exportKind); - } -} - -function getUmdImportKind(importingFile: SourceFile, compilerOptions: CompilerOptions, forceImportKeyword: boolean): ImportKind { - // Import a synthetic `default` if enabled. - if (getAllowSyntheticDefaultImports(compilerOptions)) { - return ImportKind.Default; - } - - // When a synthetic `default` is unavailable, use `import..require` if the module kind supports it. - const moduleKind = getEmitModuleKind(compilerOptions); - switch (moduleKind) { - case ModuleKind.AMD: - case ModuleKind.CommonJS: - case ModuleKind.UMD: - if (isInJSFile(importingFile)) { - return isExternalModule(importingFile) || forceImportKeyword ? ImportKind.Namespace : ImportKind.CommonJS; - } - return ImportKind.CommonJS; - case ModuleKind.System: - case ModuleKind.ES2015: - case ModuleKind.ES2020: - case ModuleKind.ES2022: - case ModuleKind.ESNext: - case ModuleKind.None: - // Fall back to the `import * as ns` style import. - return ImportKind.Namespace; - case ModuleKind.Node16: - case ModuleKind.NodeNext: - return importingFile.impliedNodeFormat === ModuleKind.ESNext ? ImportKind.Namespace : ImportKind.CommonJS; - default: - return Debug.assertNever(moduleKind, `Unexpected moduleKind ${moduleKind}`); - } -} - -function getFixesInfoForNonUMDImport({ sourceFile, program, cancellationToken, host, preferences }: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier })[] | undefined { - const checker = program.getTypeChecker(); - const compilerOptions = program.getCompilerOptions(); - return flatMap(getSymbolNamesToImport(sourceFile, checker, symbolToken, compilerOptions), symbolName => { - // "default" is a keyword and not a legal identifier for the import, but appears as an identifier. - if (symbolName === InternalSymbolName.Default) { - return undefined; - } - const isValidTypeOnlyUseSite = isValidTypeOnlyAliasUseSite(symbolToken); - const useRequire = shouldUseRequire(sourceFile, program); - const exportInfo = getExportInfos(symbolName, isJSXTagName(symbolToken), getMeaningFromLocation(symbolToken), cancellationToken, sourceFile, program, useAutoImportProvider, host, preferences); - const fixes = arrayFrom(flatMapIterator(exportInfo.entries(), ([_, exportInfos]) => - getImportFixes(exportInfos, { symbolName, position: symbolToken.getStart(sourceFile) }, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences).fixes)); - return fixes.map(fix => ({ fix, symbolName, errorIdentifierText: symbolToken.text, isJsxNamespaceFix: symbolName !== symbolToken.text })); - }); -} - -function getTypeOnlyPromotionFix(sourceFile: SourceFile, symbolToken: Identifier, symbolName: string, program: Program): FixPromoteTypeOnlyImport | undefined { - const checker = program.getTypeChecker(); - const symbol = checker.resolveName(symbolName, symbolToken, SymbolFlags.Value, /*excludeGlobals*/ true); - if (!symbol) return undefined; - - const typeOnlyAliasDeclaration = checker.getTypeOnlyAliasDeclaration(symbol); - if (!typeOnlyAliasDeclaration || getSourceFileOfNode(typeOnlyAliasDeclaration) !== sourceFile) return undefined; - - return { kind: ImportFixKind.PromoteTypeOnly, typeOnlyAliasDeclaration }; -} - -function getSymbolNamesToImport(sourceFile: SourceFile, checker: TypeChecker, symbolToken: Identifier, compilerOptions: CompilerOptions): string[] { - const parent = symbolToken.parent; - if ((isJsxOpeningLikeElement(parent) || isJsxClosingElement(parent)) && parent.tagName === symbolToken && jsxModeNeedsExplicitImport(compilerOptions.jsx)) { - const jsxNamespace = checker.getJsxNamespace(sourceFile); - if (needsJsxNamespaceFix(jsxNamespace, symbolToken, checker)) { - const needsComponentNameFix = !isIntrinsicJsxName(symbolToken.text) && !checker.resolveName(symbolToken.text, symbolToken, SymbolFlags.Value, /*excludeGlobals*/ false); - return needsComponentNameFix ? [symbolToken.text, jsxNamespace] : [jsxNamespace]; - } - } - return [symbolToken.text]; -} - -function needsJsxNamespaceFix(jsxNamespace: string, symbolToken: Identifier, checker: TypeChecker) { - if (isIntrinsicJsxName(symbolToken.text)) return true; // If we were triggered by a matching error code on an intrinsic, the error must have been about missing the JSX factory - const namespaceSymbol = checker.resolveName(jsxNamespace, symbolToken, SymbolFlags.Value, /*excludeGlobals*/ true); - return !namespaceSymbol || some(namespaceSymbol.declarations, isTypeOnlyImportOrExportDeclaration) && !(namespaceSymbol.flags & SymbolFlags.Value); -} - -// Returns a map from an exported symbol's ID to a list of every way it's (re-)exported. -function getExportInfos( - symbolName: string, - isJsxTagName: boolean, - currentTokenMeaning: SemanticMeaning, - cancellationToken: CancellationToken, - fromFile: SourceFile, - program: Program, - useAutoImportProvider: boolean, - host: LanguageServiceHost, - preferences: UserPreferences, -): ReadonlyMap { - // For each original symbol, keep all re-exports of that symbol together so we can call `getCodeActionsForImport` on the whole group at once. - // Maps symbol id to info for modules providing that symbol (original export + re-exports). - const originalSymbolToExportInfos = createMultiMap(); - const packageJsonFilter = createPackageJsonImportFilter(fromFile, preferences, host); - const moduleSpecifierCache = host.getModuleSpecifierCache?.(); - const getModuleSpecifierResolutionHost = memoizeOne((isFromPackageJson: boolean) => { - return createModuleSpecifierResolutionHost(isFromPackageJson ? host.getPackageJsonAutoImportProvider!()! : program, host); - }); - function addSymbol(moduleSymbol: Symbol, toFile: SourceFile | undefined, exportedSymbol: Symbol, exportKind: ExportKind, program: Program, isFromPackageJson: boolean): void { - const moduleSpecifierResolutionHost = getModuleSpecifierResolutionHost(isFromPackageJson); - if (toFile && isImportableFile(program, fromFile, toFile, preferences, packageJsonFilter, moduleSpecifierResolutionHost, moduleSpecifierCache) || - !toFile && packageJsonFilter.allowsImportingAmbientModule(moduleSymbol, moduleSpecifierResolutionHost) - ) { - const checker = program.getTypeChecker(); - originalSymbolToExportInfos.add(getUniqueSymbolId(exportedSymbol, checker).toString(), { symbol: exportedSymbol, moduleSymbol, moduleFileName: toFile?.fileName, exportKind, targetFlags: skipAlias(exportedSymbol, checker).flags, isFromPackageJson }); - } - } - forEachExternalModuleToImportFrom(program, host, preferences, useAutoImportProvider, (moduleSymbol, sourceFile, program, isFromPackageJson) => { - const checker = program.getTypeChecker(); - cancellationToken.throwIfCancellationRequested(); - - const compilerOptions = program.getCompilerOptions(); - const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions); - if (defaultInfo && (defaultInfo.name === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, getEmitScriptTarget(compilerOptions), isJsxTagName) === symbolName) && symbolHasMeaning(defaultInfo.symbolForMeaning, currentTokenMeaning)) { - addSymbol(moduleSymbol, sourceFile, defaultInfo.symbol, defaultInfo.exportKind, program, isFromPackageJson); - } - - // check exports with the same name - const exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol); - if (exportSymbolWithIdenticalName && symbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) { - addSymbol(moduleSymbol, sourceFile, exportSymbolWithIdenticalName, ExportKind.Named, program, isFromPackageJson); - } - }); - return originalSymbolToExportInfos; -} - -function getExportEqualsImportKind(importingFile: SourceFile, compilerOptions: CompilerOptions, forceImportKeyword: boolean): ImportKind { - const allowSyntheticDefaults = getAllowSyntheticDefaultImports(compilerOptions); - const isJS = isInJSFile(importingFile); - // 1. 'import =' will not work in es2015+ TS files, so the decision is between a default - // and a namespace import, based on allowSyntheticDefaultImports/esModuleInterop. - if (!isJS && getEmitModuleKind(compilerOptions) >= ModuleKind.ES2015) { - return allowSyntheticDefaults ? ImportKind.Default : ImportKind.Namespace; - } - // 2. 'import =' will not work in JavaScript, so the decision is between a default import, - // a namespace import, and const/require. - if (isJS) { - return isExternalModule(importingFile) || forceImportKeyword - ? allowSyntheticDefaults ? ImportKind.Default : ImportKind.Namespace - : ImportKind.CommonJS; - } - // 3. At this point the most correct choice is probably 'import =', but people - // really hate that, so look to see if the importing file has any precedent - // on how to handle it. - for (const statement of importingFile.statements) { - // `import foo` parses as an ImportEqualsDeclaration even though it could be an ImportDeclaration - if (isImportEqualsDeclaration(statement) && !nodeIsMissing(statement.moduleReference)) { - return ImportKind.CommonJS; - } - } - // 4. We have no precedent to go on, so just use a default import if - // allowSyntheticDefaultImports/esModuleInterop is enabled. - return allowSyntheticDefaults ? ImportKind.Default : ImportKind.CommonJS; -} - -function codeActionForFix(context: textChanges.TextChangesContext, sourceFile: SourceFile, symbolName: string, fix: ImportFix, includeSymbolNameInDescription: boolean, quotePreference: QuotePreference, compilerOptions: CompilerOptions): CodeFixAction { - let diag!: DiagnosticAndArguments; - const changes = textChanges.ChangeTracker.with(context, tracker => { - diag = codeActionForFixWorker(tracker, sourceFile, symbolName, fix, includeSymbolNameInDescription, quotePreference, compilerOptions); - }); - return createCodeFixAction(importFixName, changes, diag, importFixId, Diagnostics.Add_all_missing_imports); -} -function codeActionForFixWorker(changes: textChanges.ChangeTracker, sourceFile: SourceFile, symbolName: string, fix: ImportFix, includeSymbolNameInDescription: boolean, quotePreference: QuotePreference, compilerOptions: CompilerOptions): DiagnosticAndArguments { - switch (fix.kind) { - case ImportFixKind.UseNamespace: - addNamespaceQualifier(changes, sourceFile, fix); - return [Diagnostics.Change_0_to_1, symbolName, `${fix.namespacePrefix}.${symbolName}`]; - case ImportFixKind.JsdocTypeImport: - addImportType(changes, sourceFile, fix, quotePreference); - return [Diagnostics.Change_0_to_1, symbolName, getImportTypePrefix(fix.moduleSpecifier, quotePreference) + symbolName]; - case ImportFixKind.AddToExisting: { - const { importClauseOrBindingPattern, importKind, addAsTypeOnly, moduleSpecifier } = fix; - doAddExistingFix( - changes, - sourceFile, - importClauseOrBindingPattern, - importKind === ImportKind.Default ? { name: symbolName, addAsTypeOnly } : undefined, - importKind === ImportKind.Named ? [{ name: symbolName, addAsTypeOnly }] : emptyArray, - compilerOptions); - const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier); - return includeSymbolNameInDescription - ? [Diagnostics.Import_0_from_1, symbolName, moduleSpecifierWithoutQuotes] - : [Diagnostics.Update_import_from_0, moduleSpecifierWithoutQuotes]; - } - case ImportFixKind.AddNew: { - const { importKind, moduleSpecifier, addAsTypeOnly, useRequire } = fix; - const getDeclarations = useRequire ? getNewRequires : getNewImports; - const defaultImport: Import | undefined = importKind === ImportKind.Default ? { name: symbolName, addAsTypeOnly } : undefined; - const namedImports: Import[] | undefined = importKind === ImportKind.Named ? [{ name: symbolName, addAsTypeOnly }] : undefined; - const namespaceLikeImport = importKind === ImportKind.Namespace || importKind === ImportKind.CommonJS ? { importKind, name: symbolName, addAsTypeOnly } : undefined; - insertImports(changes, sourceFile, getDeclarations(moduleSpecifier, quotePreference, defaultImport, namedImports, namespaceLikeImport), /*blankLineBetween*/ true); - return includeSymbolNameInDescription - ? [Diagnostics.Import_0_from_1, symbolName, moduleSpecifier] - : [Diagnostics.Add_import_from_0, moduleSpecifier]; - } - case ImportFixKind.PromoteTypeOnly: { - const { typeOnlyAliasDeclaration } = fix; - const promotedDeclaration = promoteFromTypeOnly(changes, typeOnlyAliasDeclaration, compilerOptions, sourceFile); - return promotedDeclaration.kind === SyntaxKind.ImportSpecifier - ? [Diagnostics.Remove_type_from_import_of_0_from_1, symbolName, getModuleSpecifierText(promotedDeclaration.parent.parent)] - : [Diagnostics.Remove_type_from_import_declaration_from_0, getModuleSpecifierText(promotedDeclaration)]; - } - default: - return Debug.assertNever(fix, `Unexpected fix kind ${(fix as ImportFix).kind}`); - } -} - -function getModuleSpecifierText(promotedDeclaration: ImportClause | ImportEqualsDeclaration): string { - return promotedDeclaration.kind === SyntaxKind.ImportEqualsDeclaration - ? tryCast(tryCast(promotedDeclaration.moduleReference, isExternalModuleReference)?.expression, isStringLiteralLike)?.text || promotedDeclaration.moduleReference.getText() - : cast(promotedDeclaration.parent.moduleSpecifier, isStringLiteral).text; -} - -function promoteFromTypeOnly(changes: textChanges.ChangeTracker, aliasDeclaration: TypeOnlyAliasDeclaration, compilerOptions: CompilerOptions, sourceFile: SourceFile) { - // See comment in `doAddExistingFix` on constant with the same name. - const convertExistingToTypeOnly = compilerOptions.preserveValueImports && compilerOptions.isolatedModules; - switch (aliasDeclaration.kind) { - case SyntaxKind.ImportSpecifier: - if (aliasDeclaration.isTypeOnly) { - if (aliasDeclaration.parent.elements.length > 1 && OrganizeImports.importSpecifiersAreSorted(aliasDeclaration.parent.elements)) { - changes.delete(sourceFile, aliasDeclaration); - const newSpecifier = factory.updateImportSpecifier(aliasDeclaration, /*isTypeOnly*/ false, aliasDeclaration.propertyName, aliasDeclaration.name); - const insertionIndex = OrganizeImports.getImportSpecifierInsertionIndex(aliasDeclaration.parent.elements, newSpecifier); - changes.insertImportSpecifierAtIndex(sourceFile, newSpecifier, aliasDeclaration.parent, insertionIndex); - } - else { - changes.deleteRange(sourceFile, aliasDeclaration.getFirstToken()!); - } - return aliasDeclaration; - } - else { - Debug.assert(aliasDeclaration.parent.parent.isTypeOnly); - promoteImportClause(aliasDeclaration.parent.parent); - return aliasDeclaration.parent.parent; - } - case SyntaxKind.ImportClause: - promoteImportClause(aliasDeclaration); - return aliasDeclaration; - case SyntaxKind.NamespaceImport: - promoteImportClause(aliasDeclaration.parent); - return aliasDeclaration.parent; - case SyntaxKind.ImportEqualsDeclaration: - changes.deleteRange(sourceFile, aliasDeclaration.getChildAt(1)); - return aliasDeclaration; - default: - Debug.failBadSyntaxKind(aliasDeclaration); - } - - function promoteImportClause(importClause: ImportClause) { - changes.delete(sourceFile, getTypeKeywordOfTypeOnlyImport(importClause, sourceFile)); - if (convertExistingToTypeOnly) { - const namedImports = tryCast(importClause.namedBindings, isNamedImports); - if (namedImports && namedImports.elements.length > 1) { - if (OrganizeImports.importSpecifiersAreSorted(namedImports.elements) && - aliasDeclaration.kind === SyntaxKind.ImportSpecifier && - namedImports.elements.indexOf(aliasDeclaration) !== 0 - ) { - // The import specifier being promoted will be the only non-type-only, - // import in the NamedImports, so it should be moved to the front. - changes.delete(sourceFile, aliasDeclaration); - changes.insertImportSpecifierAtIndex(sourceFile, aliasDeclaration, namedImports, 0); - } - for (const element of namedImports.elements) { - if (element !== aliasDeclaration && !element.isTypeOnly) { - changes.insertModifierBefore(sourceFile, SyntaxKind.TypeKeyword, element); - } - } - } - } - } -} - -function doAddExistingFix( - changes: textChanges.ChangeTracker, - sourceFile: SourceFile, - clause: ImportClause | ObjectBindingPattern, - defaultImport: Import | undefined, - namedImports: readonly Import[], - compilerOptions: CompilerOptions, -): void { - if (clause.kind === SyntaxKind.ObjectBindingPattern) { - if (defaultImport) { - addElementToBindingPattern(clause, defaultImport.name, "default"); - } - for (const specifier of namedImports) { - addElementToBindingPattern(clause, specifier.name, /*propertyName*/ undefined); - } - return; - } - - const promoteFromTypeOnly = clause.isTypeOnly && some([defaultImport, ...namedImports], i => i?.addAsTypeOnly === AddAsTypeOnly.NotAllowed); - const existingSpecifiers = clause.namedBindings && tryCast(clause.namedBindings, isNamedImports)?.elements; - // If we are promoting from a type-only import and `--isolatedModules` and `--preserveValueImports` - // are enabled, we need to make every existing import specifier type-only. It may be possible that - // some of them don't strictly need to be marked type-only (if they have a value meaning and are - // never used in an emitting position). These are allowed to be imported without being type-only, - // but the user has clearly already signified that they don't need them to be present at runtime - // by placing them in a type-only import. So, just mark each specifier as type-only. - const convertExistingToTypeOnly = promoteFromTypeOnly && compilerOptions.preserveValueImports && compilerOptions.isolatedModules; - - if (defaultImport) { - Debug.assert(!clause.name, "Cannot add a default import to an import clause that already has one"); - changes.insertNodeAt(sourceFile, clause.getStart(sourceFile), factory.createIdentifier(defaultImport.name), { suffix: ", " }); - } - - if (namedImports.length) { - const newSpecifiers = stableSort( - namedImports.map(namedImport => factory.createImportSpecifier( - (!clause.isTypeOnly || promoteFromTypeOnly) && needsTypeOnly(namedImport), - /*propertyName*/ undefined, - factory.createIdentifier(namedImport.name))), - OrganizeImports.compareImportOrExportSpecifiers); - - if (existingSpecifiers?.length && OrganizeImports.importSpecifiersAreSorted(existingSpecifiers)) { - for (const spec of newSpecifiers) { - // Organize imports puts type-only import specifiers last, so if we're - // adding a non-type-only specifier and converting all the other ones to - // type-only, there's no need to ask for the insertion index - it's 0. - const insertionIndex = convertExistingToTypeOnly && !spec.isTypeOnly - ? 0 - : OrganizeImports.getImportSpecifierInsertionIndex(existingSpecifiers, spec); - changes.insertImportSpecifierAtIndex(sourceFile, spec, clause.namedBindings as NamedImports, insertionIndex); - } - } - else if (existingSpecifiers?.length) { - for (const spec of newSpecifiers) { - changes.insertNodeInListAfter(sourceFile, last(existingSpecifiers), spec, existingSpecifiers); - } - } - else { - if (newSpecifiers.length) { - const namedImports = factory.createNamedImports(newSpecifiers); - if (clause.namedBindings) { - changes.replaceNode(sourceFile, clause.namedBindings, namedImports); - } - else { - changes.insertNodeAfter(sourceFile, Debug.checkDefined(clause.name, "Import clause must have either named imports or a default import"), namedImports); - } - } - } - } - - if (promoteFromTypeOnly) { - changes.delete(sourceFile, getTypeKeywordOfTypeOnlyImport(clause, sourceFile)); - if (convertExistingToTypeOnly && existingSpecifiers) { - for (const specifier of existingSpecifiers) { - changes.insertModifierBefore(sourceFile, SyntaxKind.TypeKeyword, specifier); - } - } - } - - function addElementToBindingPattern(bindingPattern: ObjectBindingPattern, name: string, propertyName: string | undefined) { - const element = factory.createBindingElement(/*dotDotDotToken*/ undefined, propertyName, name); - if (bindingPattern.elements.length) { - changes.insertNodeInListAfter(sourceFile, last(bindingPattern.elements), element); - } - else { - changes.replaceNode(sourceFile, bindingPattern, factory.createObjectBindingPattern([element])); - } - } -} - -function addNamespaceQualifier(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { namespacePrefix, position }: FixUseNamespaceImport): void { - changes.insertText(sourceFile, position, namespacePrefix + "."); -} - -function addImportType(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { moduleSpecifier, position }: FixAddJsdocTypeImport, quotePreference: QuotePreference): void { - changes.insertText(sourceFile, position, getImportTypePrefix(moduleSpecifier, quotePreference)); -} - -function getImportTypePrefix(moduleSpecifier: string, quotePreference: QuotePreference): string { - const quote = getQuoteFromPreference(quotePreference); - return `import(${quote}${moduleSpecifier}${quote}).`; -} - -interface Import { - readonly name: string; - readonly addAsTypeOnly: AddAsTypeOnly; -} - -interface ImportsCollection { - readonly defaultImport?: Import; - readonly namedImports?: Map; - readonly namespaceLikeImport?: { - readonly importKind: ImportKind.CommonJS | ImportKind.Namespace; - readonly name: string; - readonly addAsTypeOnly: AddAsTypeOnly; - }; -} - -function needsTypeOnly({ addAsTypeOnly }: { addAsTypeOnly: AddAsTypeOnly }): boolean { - return addAsTypeOnly === AddAsTypeOnly.Required; -} - -function getNewImports( - moduleSpecifier: string, - quotePreference: QuotePreference, - defaultImport: Import | undefined, - namedImports: readonly Import[] | undefined, - namespaceLikeImport: Import & { importKind: ImportKind.CommonJS | ImportKind.Namespace } | undefined -): AnyImportSyntax | readonly AnyImportSyntax[] { - const quotedModuleSpecifier = makeStringLiteral(moduleSpecifier, quotePreference); - let statements: AnyImportSyntax | readonly AnyImportSyntax[] | undefined; - if (defaultImport !== undefined || namedImports?.length) { - const topLevelTypeOnly = (!defaultImport || needsTypeOnly(defaultImport)) && every(namedImports, needsTypeOnly); - statements = combine(statements, makeImport( - defaultImport && factory.createIdentifier(defaultImport.name), - namedImports?.map(({ addAsTypeOnly, name }) => factory.createImportSpecifier( - !topLevelTypeOnly && addAsTypeOnly === AddAsTypeOnly.Required, - /*propertyName*/ undefined, - factory.createIdentifier(name))), - moduleSpecifier, - quotePreference, - topLevelTypeOnly)); - } - - if (namespaceLikeImport) { - const declaration = namespaceLikeImport.importKind === ImportKind.CommonJS - ? factory.createImportEqualsDeclaration( - /*modifiers*/ undefined, - needsTypeOnly(namespaceLikeImport), - factory.createIdentifier(namespaceLikeImport.name), - factory.createExternalModuleReference(quotedModuleSpecifier)) - : factory.createImportDeclaration( - /*modifiers*/ undefined, - factory.createImportClause( - needsTypeOnly(namespaceLikeImport), - /*name*/ undefined, - factory.createNamespaceImport(factory.createIdentifier(namespaceLikeImport.name))), - quotedModuleSpecifier, - /*assertClause*/ undefined); - statements = combine(statements, declaration); - } - return Debug.checkDefined(statements); -} - -function getNewRequires(moduleSpecifier: string, quotePreference: QuotePreference, defaultImport: Import | undefined, namedImports: readonly Import[] | undefined, namespaceLikeImport: Import | undefined): RequireVariableStatement | readonly RequireVariableStatement[] { - const quotedModuleSpecifier = makeStringLiteral(moduleSpecifier, quotePreference); - let statements: RequireVariableStatement | readonly RequireVariableStatement[] | undefined; - // const { default: foo, bar, etc } = require('./mod'); - if (defaultImport || namedImports?.length) { - const bindingElements = namedImports?.map(({ name }) => factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name)) || []; - if (defaultImport) { - bindingElements.unshift(factory.createBindingElement(/*dotDotDotToken*/ undefined, "default", defaultImport.name)); - } - const declaration = createConstEqualsRequireDeclaration(factory.createObjectBindingPattern(bindingElements), quotedModuleSpecifier); - statements = combine(statements, declaration); - } - // const foo = require('./mod'); - if (namespaceLikeImport) { - const declaration = createConstEqualsRequireDeclaration(namespaceLikeImport.name, quotedModuleSpecifier); - statements = combine(statements, declaration); - } - return Debug.checkDefined(statements); -} - -function createConstEqualsRequireDeclaration(name: string | ObjectBindingPattern, quotedModuleSpecifier: StringLiteral): RequireVariableStatement { - return factory.createVariableStatement( - /*modifiers*/ undefined, - factory.createVariableDeclarationList([ - factory.createVariableDeclaration( - typeof name === "string" ? factory.createIdentifier(name) : name, - /*exclamationToken*/ undefined, - /*type*/ undefined, - factory.createCallExpression(factory.createIdentifier("require"), /*typeArguments*/ undefined, [quotedModuleSpecifier]))], - NodeFlags.Const)) as RequireVariableStatement; -} - -function symbolHasMeaning({ declarations }: Symbol, meaning: SemanticMeaning): boolean { - return some(declarations, decl => !!(getMeaningFromDeclaration(decl) & meaning)); -} - -/** @internal */ -export function moduleSymbolToValidIdentifier(moduleSymbol: Symbol, target: ScriptTarget | undefined, forceCapitalize: boolean): string { - return moduleSpecifierToValidIdentifier(removeFileExtension(stripQuotes(moduleSymbol.name)), target, forceCapitalize); -} - -/** @internal */ -export function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget | undefined, forceCapitalize?: boolean): string { - const baseName = getBaseFileName(removeSuffix(moduleSpecifier, "/index")); - let res = ""; - let lastCharWasValid = true; - const firstCharCode = baseName.charCodeAt(0); - if (isIdentifierStart(firstCharCode, target)) { - res += String.fromCharCode(firstCharCode); - if (forceCapitalize) { - res = res.toUpperCase(); - } - } - else { - lastCharWasValid = false; - } - for (let i = 1; i < baseName.length; i++) { - const ch = baseName.charCodeAt(i); - const isValid = isIdentifierPart(ch, target); - if (isValid) { - let char = String.fromCharCode(ch); - if (!lastCharWasValid) { - char = char.toUpperCase(); - } - res += char; - } - lastCharWasValid = isValid; - } - // Need `|| "_"` to ensure result isn't empty. - return !isStringANonContextualKeyword(res) ? res || "_" : `_${res}`; -} diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 7be223f9a8332..7f4d231cda1a0 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -1,70 +1,55 @@ import { - __String, - AnonymousType, - BinaryExpression, - CallExpression, - CancellationToken, - CaseOrDefaultClause, cast, createMultiMap, - createSymbolTable, - Debug, - Declaration, - DiagnosticMessage, - Diagnostics, - ElementAccessExpression, - EmitFlags, emptyArray, - escapeLeadingUnderscores, - Expression, - factory, - FindAllReferences, - findChildOfKind, first, firstOrUndefined, flatMap, forEach, - forEachEntry, - getContainingFunction, - getEmitScriptTarget, - getJSDocType, - getNameOfDeclaration, - getObjectFlags, - getSourceFileOfNode, - getTextOfNode, - getTokenAtPosition, - getTypeNodeIfAccessible, - Identifier, - IndexKind, + last, + length, + map, + mapDefined, + mapEntries, + returnTrue, + singleOrUndefined, + tryCast, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { setEmitFlags } from "../../compiler/factory/emitNode"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrowFunction, - isAssignmentExpression, isCallExpression, - isExpressionNode, isExpressionStatement, isFunctionExpression, isGetAccessorDeclaration, isIdentifier, - isInJSFile, isParameter, - isParameterPropertyModifier, isPropertyAccessExpression, isPropertyDeclaration, isPropertySignature, - isRestParameter, - isRightSideOfQualifiedNameOrPropertyAccess, isSetAccessorDeclaration, isVariableDeclaration, isVariableStatement, - LanguageServiceHost, - last, - length, - map, - mapDefined, - mapEntries, +} from "../../compiler/factory/nodeTests"; +import { + __String, + AnonymousType, + BinaryExpression, + CallExpression, + CancellationToken, + CaseOrDefaultClause, + Declaration, + DiagnosticMessage, + ElementAccessExpression, + EmitFlags, + Expression, + Identifier, + IndexKind, NewExpression, Node, - nodeSeenTracker, - NodeSeenTracker, ObjectFlags, ParameterDeclaration, PrefixUnaryExpression, @@ -75,25 +60,20 @@ import { PropertyDeclaration, PropertyName, PropertySignature, - returnTrue, ScriptTarget, SetAccessorDeclaration, - setEmitFlags, ShorthandPropertyAssignment, Signature, SignatureDeclaration, SignatureFlags, SignatureKind, - singleOrUndefined, SourceFile, Symbol, SymbolFlags, SymbolLinks, SyntaxKind, - textChanges, Token, TransientSymbol, - tryCast, Type, TypeFlags, TypeNode, @@ -103,15 +83,55 @@ import { UnionReduction, UserPreferences, VariableDeclaration, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + createSymbolTable, + forEachEntry, + getContainingFunction, + getEmitScriptTarget, + getObjectFlags, + getSourceFileOfNode, + getTextOfNode, + isAssignmentExpression, + isExpressionNode, + isInJSFile, + isRightSideOfQualifiedNameOrPropertyAccess, +} from "../../compiler/utilities"; +import { + escapeLeadingUnderscores, + getJSDocType, + getNameOfDeclaration, + isParameterPropertyModifier, + isRestParameter, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, + registerCodeFix, +} from "../codeFixProvider"; +import { getReferenceEntriesForNode } from "../findAllReferences"; +import { + ChangeTracker, + isThisTypeAnnotatable, + ThisTypeAnnotatable, + TypeAnnotatable, +} from "../textChanges"; +import { + EntryKind, + LanguageServiceHost, +} from "../types"; +import { + findChildOfKind, + getTokenAtPosition, + getTypeNodeIfAccessible, + nodeSeenTracker, + NodeSeenTracker, +} from "../utilities"; +import { tryGetAutoImportableReferenceFromTypeNode } from "./helpers"; +import { createImportAdder, ImportAdder, - registerCodeFix, - tryGetAutoImportableReferenceFromTypeNode, -} from "../_namespaces/ts.codefix"; +} from "./importAdder"; const fixId = "inferFromUsage"; const errorCodes = [ @@ -166,7 +186,7 @@ registerCodeFix({ const token = getTokenAtPosition(sourceFile, start); let declaration: Declaration | undefined; - const changes = textChanges.ChangeTracker.with(context, changes => { + const changes = ChangeTracker.with(context, changes => { declaration = doChange(changes, sourceFile, token, errorCode, program, cancellationToken, /*markSeen*/ returnTrue, host, preferences); }); const name = declaration && getNameOfDeclaration(declaration); @@ -221,13 +241,13 @@ function mapSuggestionDiagnostic(errorCode: number) { return errorCode; } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node, errorCode: number, program: Program, cancellationToken: CancellationToken, markSeen: NodeSeenTracker, host: LanguageServiceHost, preferences: UserPreferences): Declaration | undefined { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, token: Node, errorCode: number, program: Program, cancellationToken: CancellationToken, markSeen: NodeSeenTracker, host: LanguageServiceHost, preferences: UserPreferences): Declaration | undefined { if (!isParameterPropertyModifier(token.kind) && token.kind !== SyntaxKind.Identifier && token.kind !== SyntaxKind.DotDotDotToken && token.kind !== SyntaxKind.ThisKeyword) { return undefined; } const { parent } = token; - const importAdder = createImportAdder(sourceFile, program, preferences, host); + const importAdder = createImportAdder(sourceFile, program, preferences, host, /*useAutoImportProvider*/ false); errorCode = mapSuggestionDiagnostic(errorCode); switch (errorCode) { // Variable and Property declarations @@ -304,7 +324,7 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, to // Function 'this' case Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation.code: - if (textChanges.isThisTypeAnnotatable(containingFunction) && markSeen(containingFunction)) { + if (isThisTypeAnnotatable(containingFunction) && markSeen(containingFunction)) { annotateThis(changes, sourceFile, containingFunction, program, host, cancellationToken); declaration = containingFunction; } @@ -319,7 +339,7 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, to } function annotateVariableDeclaration( - changes: textChanges.ChangeTracker, + changes: ChangeTracker, importAdder: ImportAdder, sourceFile: SourceFile, declaration: VariableDeclaration | PropertyDeclaration | PropertySignature, @@ -333,7 +353,7 @@ function annotateVariableDeclaration( } function annotateParameters( - changes: textChanges.ChangeTracker, + changes: ChangeTracker, importAdder: ImportAdder, sourceFile: SourceFile, parameterDeclaration: ParameterDeclaration, @@ -364,7 +384,7 @@ function annotateParameters( } } -function annotateThis(changes: textChanges.ChangeTracker, sourceFile: SourceFile, containingFunction: textChanges.ThisTypeAnnotatable, program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken) { +function annotateThis(changes: ChangeTracker, sourceFile: SourceFile, containingFunction: ThisTypeAnnotatable, program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken) { const references = getFunctionReferences(containingFunction, sourceFile, program, cancellationToken); if (!references || !references.length) { return; @@ -383,14 +403,14 @@ function annotateThis(changes: textChanges.ChangeTracker, sourceFile: SourceFile } } -function annotateJSDocThis(changes: textChanges.ChangeTracker, sourceFile: SourceFile, containingFunction: SignatureDeclaration, typeNode: TypeNode) { +function annotateJSDocThis(changes: ChangeTracker, sourceFile: SourceFile, containingFunction: SignatureDeclaration, typeNode: TypeNode) { changes.addJSDocTags(sourceFile, containingFunction, [ factory.createJSDocThisTag(/*tagName*/ undefined, factory.createJSDocTypeExpression(typeNode)), ]); } function annotateSetAccessor( - changes: textChanges.ChangeTracker, + changes: ChangeTracker, importAdder: ImportAdder, sourceFile: SourceFile, setAccessorDeclaration: SetAccessorDeclaration, @@ -414,7 +434,7 @@ function annotateSetAccessor( } } -function annotate(changes: textChanges.ChangeTracker, importAdder: ImportAdder, sourceFile: SourceFile, declaration: textChanges.TypeAnnotatable, type: Type, program: Program, host: LanguageServiceHost): void { +function annotate(changes: ChangeTracker, importAdder: ImportAdder, sourceFile: SourceFile, declaration: TypeAnnotatable, type: Type, program: Program, host: LanguageServiceHost): void { const typeNode = getTypeNodeIfAccessible(type, declaration, program, host); if (typeNode) { if (isInJSFile(sourceFile) && declaration.kind !== SyntaxKind.PropertySignature) { @@ -434,9 +454,9 @@ function annotate(changes: textChanges.ChangeTracker, importAdder: ImportAdder, function tryReplaceImportTypeNodeWithAutoImport( typeNode: TypeNode, - declaration: textChanges.TypeAnnotatable, + declaration: TypeAnnotatable, sourceFile: SourceFile, - changes: textChanges.ChangeTracker, + changes: ChangeTracker, importAdder: ImportAdder, scriptTarget: ScriptTarget ): boolean { @@ -448,7 +468,7 @@ function tryReplaceImportTypeNodeWithAutoImport( return false; } -function annotateJSDocParameters(changes: textChanges.ChangeTracker, sourceFile: SourceFile, parameterInferences: readonly ParameterInference[], program: Program, host: LanguageServiceHost): void { +function annotateJSDocParameters(changes: ChangeTracker, sourceFile: SourceFile, parameterInferences: readonly ParameterInference[], program: Program, host: LanguageServiceHost): void { const signature = parameterInferences.length && parameterInferences[0].declaration.parent; if (!signature) { return; @@ -497,8 +517,8 @@ function annotateJSDocParameters(changes: textChanges.ChangeTracker, sourceFile: function getReferences(token: PropertyName | Token, program: Program, cancellationToken: CancellationToken): readonly Identifier[] { // Position shouldn't matter since token is not a SourceFile. - return mapDefined(FindAllReferences.getReferenceEntriesForNode(-1, token, program, program.getSourceFiles(), cancellationToken), entry => - entry.kind !== FindAllReferences.EntryKind.Span ? tryCast(entry.node, isIdentifier) : undefined); + return mapDefined(getReferenceEntriesForNode(-1, token, program, program.getSourceFiles(), cancellationToken), entry => + entry.kind !== EntryKind.Span ? tryCast(entry.node, isIdentifier) : undefined); } function inferTypeForVariableFromUsage(token: Identifier | PrivateIdentifier, program: Program, cancellationToken: CancellationToken): Type { diff --git a/src/services/codefixes/removeAccidentalCallParentheses.ts b/src/services/codefixes/removeAccidentalCallParentheses.ts index c4ad5c9ea3721..c2b864e09d76e 100644 --- a/src/services/codefixes/removeAccidentalCallParentheses.ts +++ b/src/services/codefixes/removeAccidentalCallParentheses.ts @@ -1,14 +1,12 @@ -import { - Diagnostics, - findAncestor, - getTokenAtPosition, - isCallExpression, - textChanges, -} from "../_namespaces/ts"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { isCallExpression } from "../../compiler/factory/nodeTests"; +import { findAncestor } from "../../compiler/utilitiesPublic"; import { createCodeFixActionWithoutFixAll, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "removeAccidentalCallParentheses"; const errorCodes = [ @@ -21,7 +19,7 @@ registerCodeFix({ if (!callExpression) { return undefined; } - const changes = textChanges.ChangeTracker.with(context, t => { + const changes = ChangeTracker.with(context, t => { t.deleteRange(context.sourceFile, { pos: callExpression.expression.end, end: callExpression.end }); }); return [createCodeFixActionWithoutFixAll(fixId, changes, Diagnostics.Remove_parentheses)]; diff --git a/src/services/codefixes/removeUnnecessaryAwait.ts b/src/services/codefixes/removeUnnecessaryAwait.ts index 521c8e9dc08b2..adfd37190ad7d 100644 --- a/src/services/codefixes/removeUnnecessaryAwait.ts +++ b/src/services/codefixes/removeUnnecessaryAwait.ts @@ -1,24 +1,28 @@ +import { tryCast } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { - AwaitKeywordToken, - Diagnostics, - findPrecedingToken, - getLeftmostExpression, - getTokenAtPosition, isAwaitExpression, isIdentifier, isParenthesizedExpression, +} from "../../compiler/factory/nodeTests"; +import { + AwaitKeywordToken, Node, SourceFile, SyntaxKind, - textChanges, TextSpan, - tryCast, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { getLeftmostExpression } from "../../compiler/utilities"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + findPrecedingToken, + getTokenAtPosition, +} from "../utilities"; const fixId = "removeUnnecessaryAwait"; const errorCodes = [ @@ -28,7 +32,7 @@ const errorCodes = [ registerCodeFix({ errorCodes, getCodeActions: function getCodeActionsToRemoveUnnecessaryAwait(context) { - const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span)); + const changes = ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span)); if (changes.length > 0) { return [createCodeFixAction(fixId, changes, Diagnostics.Remove_unnecessary_await, fixId, Diagnostics.Remove_all_unnecessary_uses_of_await)]; } @@ -39,7 +43,7 @@ registerCodeFix({ }, }); -function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, span: TextSpan) { +function makeChange(changeTracker: ChangeTracker, sourceFile: SourceFile, span: TextSpan) { const awaitKeyword = tryCast(getTokenAtPosition(sourceFile, span.start), (node): node is AwaitKeywordToken => node.kind === SyntaxKind.AwaitKeyword); const awaitExpression = awaitKeyword && tryCast(awaitKeyword.parent, isAwaitExpression); if (!awaitExpression) { diff --git a/src/services/codefixes/requireInTs.ts b/src/services/codefixes/requireInTs.ts index 0667683d1ffd0..476cb407bfde4 100644 --- a/src/services/codefixes/requireInTs.ts +++ b/src/services/codefixes/requireInTs.ts @@ -1,32 +1,38 @@ import { cast, - Debug, - Diagnostics, - factory, first, - getAllowSyntheticDefaultImports, - getTokenAtPosition, - Identifier, - ImportSpecifier, + tryCast, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isIdentifier, isObjectBindingPattern, - isRequireCall, isVariableDeclaration, isVariableStatement, +} from "../../compiler/factory/nodeTests"; +import { + Identifier, + ImportSpecifier, NamedImports, ObjectBindingPattern, Program, SourceFile, StringLiteralLike, - textChanges, - tryCast, VariableStatement, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + getAllowSyntheticDefaultImports, + isRequireCall, +} from "../../compiler/utilities"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "requireInTs"; const errorCodes = [Diagnostics.require_call_may_be_converted_to_an_import.code]; @@ -37,7 +43,7 @@ registerCodeFix({ if (!info) { return undefined; } - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, info)); + const changes = ChangeTracker.with(context, t => doChange(t, context.sourceFile, info)); return [createCodeFixAction(fixId, changes, Diagnostics.Convert_require_to_import, fixId, Diagnostics.Convert_all_require_to_import)]; }, fixIds: [fixId], @@ -49,7 +55,7 @@ registerCodeFix({ }), }); -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, info: Info) { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, info: Info) { const { allowSyntheticDefaults, defaultImportName, namedImports, statement, required } = info; changes.replaceNode(sourceFile, statement, defaultImportName && !allowSyntheticDefaults ? factory.createImportEqualsDeclaration(/*modifiers*/ undefined, /*isTypeOnly*/ false, defaultImportName, factory.createExternalModuleReference(required)) diff --git a/src/services/codefixes/returnValueCorrect.ts b/src/services/codefixes/returnValueCorrect.ts index b6930f0b7efba..cb67dc245bf0e 100644 --- a/src/services/codefixes/returnValueCorrect.ts +++ b/src/services/codefixes/returnValueCorrect.ts @@ -1,50 +1,64 @@ import { append, - ArrowFunction, - CodeFixContext, - copyComments, - createSymbolTable, - Debug, - Diagnostics, - Expression, - factory, - findAncestor, first, - FunctionLikeDeclaration, - getTokenAtPosition, - hasSyntacticModifier, - Identifier, + length, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrowFunction, isBlock, isCallExpression, - isDeclarationName, isExpressionStatement, - isFunctionLikeDeclaration, isJsxAttribute, isJsxExpression, isLabeledStatement, - isVariableLike, - length, +} from "../../compiler/factory/nodeTests"; +import { + ArrowFunction, + Expression, + FunctionLikeDeclaration, + Identifier, ModifierFlags, - needsParentheses, Node, - probablyUsesSemicolons, - rangeContainsRange, SourceFile, Statement, - suppressLeadingAndTrailingTrivia, SymbolFlags, SyntaxKind, - textChanges, Type, TypeChecker, VariableLikeDeclaration, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + createSymbolTable, + hasSyntacticModifier, + isDeclarationName, + isVariableLike, +} from "../../compiler/utilities"; +import { + findAncestor, + isFunctionLikeDeclaration, +} from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { + ChangeTracker, + LeadingTriviaOption, + TrailingTriviaOption, +} from "../textChanges"; +import { CodeFixContext } from "../types"; +import { + copyComments, + getTokenAtPosition, + needsParentheses, + probablyUsesSemicolons, + rangeContainsRange, + suppressLeadingAndTrailingTrivia, +} from "../utilities"; const fixId = "returnValueCorrect"; const fixIdAddReturnStatement = "fixAddReturnStatement"; @@ -250,17 +264,17 @@ function getVariableLikeInitializer(declaration: VariableLikeDeclaration): Expre } } -function addReturnStatement(changes: textChanges.ChangeTracker, sourceFile: SourceFile, expression: Expression, statement: Statement) { +function addReturnStatement(changes: ChangeTracker, sourceFile: SourceFile, expression: Expression, statement: Statement) { suppressLeadingAndTrailingTrivia(expression); const probablyNeedSemi = probablyUsesSemicolons(sourceFile); changes.replaceNode(sourceFile, statement, factory.createReturnStatement(expression), { - leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, - trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude, + leadingTriviaOption: LeadingTriviaOption.Exclude, + trailingTriviaOption: TrailingTriviaOption.Exclude, suffix: probablyNeedSemi ? ";" : undefined }); } -function removeBlockBodyBrace(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: ArrowFunction, expression: Expression, commentSource: Node, withParen: boolean) { +function removeBlockBodyBrace(changes: ChangeTracker, sourceFile: SourceFile, declaration: ArrowFunction, expression: Expression, commentSource: Node, withParen: boolean) { const newBody = (withParen || needsParentheses(expression)) ? factory.createParenthesizedExpression(expression) : expression; suppressLeadingAndTrailingTrivia(commentSource); copyComments(commentSource, newBody); @@ -268,21 +282,21 @@ function removeBlockBodyBrace(changes: textChanges.ChangeTracker, sourceFile: So changes.replaceNode(sourceFile, declaration.body, newBody); } -function wrapBlockWithParen(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: ArrowFunction, expression: Expression) { +function wrapBlockWithParen(changes: ChangeTracker, sourceFile: SourceFile, declaration: ArrowFunction, expression: Expression) { changes.replaceNode(sourceFile, declaration.body, factory.createParenthesizedExpression(expression)); } function getActionForfixAddReturnStatement(context: CodeFixContext, expression: Expression, statement: Statement) { - const changes = textChanges.ChangeTracker.with(context, t => addReturnStatement(t, context.sourceFile, expression, statement)); + const changes = ChangeTracker.with(context, t => addReturnStatement(t, context.sourceFile, expression, statement)); return createCodeFixAction(fixId, changes, Diagnostics.Add_a_return_statement, fixIdAddReturnStatement, Diagnostics.Add_all_missing_return_statement); } function getActionForFixRemoveBracesFromArrowFunctionBody(context: CodeFixContext, declaration: ArrowFunction, expression: Expression, commentSource: Node) { - const changes = textChanges.ChangeTracker.with(context, t => removeBlockBodyBrace(t, context.sourceFile, declaration, expression, commentSource, /* withParen */ false)); + const changes = ChangeTracker.with(context, t => removeBlockBodyBrace(t, context.sourceFile, declaration, expression, commentSource, /* withParen */ false)); return createCodeFixAction(fixId, changes, Diagnostics.Remove_braces_from_arrow_function_body, fixRemoveBracesFromArrowFunctionBody, Diagnostics.Remove_braces_from_all_arrow_function_bodies_with_relevant_issues); } function getActionForfixWrapTheBlockWithParen(context: CodeFixContext, declaration: ArrowFunction, expression: Expression) { - const changes = textChanges.ChangeTracker.with(context, t => wrapBlockWithParen(t, context.sourceFile, declaration, expression)); + const changes = ChangeTracker.with(context, t => wrapBlockWithParen(t, context.sourceFile, declaration, expression)); return createCodeFixAction(fixId, changes, Diagnostics.Wrap_the_following_body_with_parentheses_which_should_be_an_object_literal, fixIdWrapTheBlockWithParen, Diagnostics.Wrap_all_object_literal_with_parentheses); } diff --git a/src/services/codefixes/splitTypeOnlyImport.ts b/src/services/codefixes/splitTypeOnlyImport.ts index 6af08a70ebff6..1aebcfa32584e 100644 --- a/src/services/codefixes/splitTypeOnlyImport.ts +++ b/src/services/codefixes/splitTypeOnlyImport.ts @@ -1,21 +1,21 @@ +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isImportDeclaration } from "../../compiler/factory/nodeTests"; import { - CodeFixContextBase, - Debug, - Diagnostics, - factory, - findAncestor, - getTokenAtPosition, ImportDeclaration, - isImportDeclaration, SourceFile, - textChanges, TextSpan, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { findAncestor } from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { CodeFixContextBase } from "../types"; +import { getTokenAtPosition } from "../utilities"; const errorCodes = [Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both.code]; const fixId = "splitTypeOnlyImport"; @@ -23,7 +23,7 @@ registerCodeFix({ errorCodes, fixIds: [fixId], getCodeActions: function getCodeActionsToSplitTypeOnlyImport(context) { - const changes = textChanges.ChangeTracker.with(context, t => { + const changes = ChangeTracker.with(context, t => { return splitTypeOnlyImport(t, getImportDeclaration(context.sourceFile, context.span), context); }); if (changes.length) { @@ -39,7 +39,7 @@ function getImportDeclaration(sourceFile: SourceFile, span: TextSpan) { return findAncestor(getTokenAtPosition(sourceFile, span.start), isImportDeclaration); } -function splitTypeOnlyImport(changes: textChanges.ChangeTracker, importDeclaration: ImportDeclaration | undefined, context: CodeFixContextBase) { +function splitTypeOnlyImport(changes: ChangeTracker, importDeclaration: ImportDeclaration | undefined, context: CodeFixContextBase) { if (!importDeclaration) { return; } diff --git a/src/services/codefixes/useBigintLiteral.ts b/src/services/codefixes/useBigintLiteral.ts index 4492e176b5c57..7cfc8482ff1a9 100644 --- a/src/services/codefixes/useBigintLiteral.ts +++ b/src/services/codefixes/useBigintLiteral.ts @@ -1,18 +1,18 @@ +import { tryCast } from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isNumericLiteral } from "../../compiler/factory/nodeTests"; import { - Diagnostics, - factory, - getTokenAtPosition, - isNumericLiteral, SourceFile, - textChanges, TextSpan, - tryCast, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixId = "useBigintLiteral"; const errorCodes = [ @@ -22,7 +22,7 @@ const errorCodes = [ registerCodeFix({ errorCodes, getCodeActions: function getCodeActionsToUseBigintLiteral(context) { - const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span)); + const changes = ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span)); if (changes.length > 0) { return [createCodeFixAction(fixId, changes, Diagnostics.Convert_to_a_bigint_numeric_literal, fixId, Diagnostics.Convert_all_to_bigint_numeric_literals)]; } @@ -33,7 +33,7 @@ registerCodeFix({ }, }); -function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, span: TextSpan) { +function makeChange(changeTracker: ChangeTracker, sourceFile: SourceFile, span: TextSpan) { const numericLiteral = tryCast(getTokenAtPosition(sourceFile, span.start), isNumericLiteral); if (!numericLiteral) { return; @@ -41,6 +41,5 @@ function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: Source // We use .getText to overcome parser inaccuracies: https://github.com/microsoft/TypeScript/issues/33298 const newText = numericLiteral.getText(sourceFile) + "n"; - changeTracker.replaceNode(sourceFile, numericLiteral, factory.createBigIntLiteral(newText)); } diff --git a/src/services/codefixes/useDefaultImport.ts b/src/services/codefixes/useDefaultImport.ts index 75f72964530b6..459d06b5a23ac 100644 --- a/src/services/codefixes/useDefaultImport.ts +++ b/src/services/codefixes/useDefaultImport.ts @@ -1,24 +1,28 @@ +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { - AnyImportSyntax, - Diagnostics, - Expression, - getQuotePreference, - getTokenAtPosition, - Identifier, isExternalModuleReference, isIdentifier, isImportEqualsDeclaration, isNamespaceImport, - makeImport, +} from "../../compiler/factory/nodeTests"; +import { + AnyImportSyntax, + Expression, + Identifier, SourceFile, - textChanges, UserPreferences, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { + getQuotePreference, + getTokenAtPosition, + makeImport, +} from "../utilities"; const fixId = "useDefaultImport"; const errorCodes = [Diagnostics.Import_may_be_converted_to_a_default_import.code]; @@ -28,7 +32,7 @@ registerCodeFix({ const { sourceFile, span: { start } } = context; const info = getInfo(sourceFile, start); if (!info) return undefined; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, info, context.preferences)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, info, context.preferences)); return [createCodeFixAction(fixId, changes, Diagnostics.Convert_to_default_import, fixId, Diagnostics.Convert_all_to_default_imports)]; }, fixIds: [fixId], @@ -56,6 +60,6 @@ function getInfo(sourceFile: SourceFile, pos: number): Info | undefined { } } -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, info: Info, preferences: UserPreferences): void { +function doChange(changes: ChangeTracker, sourceFile: SourceFile, info: Info, preferences: UserPreferences): void { changes.replaceNode(sourceFile, info.importNode, makeImport(info.name, /*namedImports*/ undefined, info.moduleSpecifier, getQuotePreference(sourceFile, preferences))); } diff --git a/src/services/codefixes/wrapJsxInFragment.ts b/src/services/codefixes/wrapJsxInFragment.ts index 78122a0840c62..55ed9d17399c2 100644 --- a/src/services/codefixes/wrapJsxInFragment.ts +++ b/src/services/codefixes/wrapJsxInFragment.ts @@ -1,22 +1,22 @@ +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isBinaryExpression } from "../../compiler/factory/nodeTests"; import { BinaryExpression, - Diagnostics, - factory, - getTokenAtPosition, - isBinaryExpression, - isJsxChild, JsxChild, Node, - nodeIsMissing, SourceFile, SyntaxKind, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { nodeIsMissing } from "../../compiler/utilities"; +import { isJsxChild } from "../../compiler/utilitiesPublic"; import { codeFixAll, createCodeFixAction, registerCodeFix, -} from "../_namespaces/ts.codefix"; +} from "../codeFixProvider"; +import { ChangeTracker } from "../textChanges"; +import { getTokenAtPosition } from "../utilities"; const fixID = "wrapJsxInFragment"; const errorCodes = [Diagnostics.JSX_expressions_must_have_one_parent_element.code]; @@ -26,7 +26,7 @@ registerCodeFix({ const { sourceFile, span } = context; const node = findNodeToFix(sourceFile, span.start); if (!node) return undefined; - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, node)); + const changes = ChangeTracker.with(context, t => doChange(t, sourceFile, node)); return [createCodeFixAction(fixID, changes, Diagnostics.Wrap_in_JSX_fragment, fixID, Diagnostics.Wrap_all_unparented_JSX_in_JSX_fragment)]; }, fixIds: [fixID], @@ -52,7 +52,7 @@ function findNodeToFix(sourceFile: SourceFile, pos: number): BinaryExpression | return binaryExpr; } -function doChange(changeTracker: textChanges.ChangeTracker, sf: SourceFile, node: Node) { +function doChange(changeTracker: ChangeTracker, sf: SourceFile, node: Node) { const jsx = flattenInvalidBinaryExpr(node); if (jsx) changeTracker.replaceNode(sf, node, factory.createJsxFragment(factory.createJsxOpeningFragment(), jsx, factory.createJsxJsxClosingFragment())); } diff --git a/src/services/completions.ts b/src/services/completions.ts index 11afb4c8c0ab9..b5154e956bed3 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1,338 +1,386 @@ +import { getSymbolId } from "../compiler/checkerUtilities"; import { - __String, - addToSeen, append, - BinaryExpression, - BreakOrContinueStatement, - CancellationToken, cast, - CharacterCodes, - ClassElement, - CodeAction, - codefix, - compareNumberOfDirectorySeparators, compareStringsCaseSensitiveUI, compareTextSpans, - Comparison, - CompilerOptions, - compilerOptionsIndicateEsModules, - CompletionEntry, - CompletionEntryData, - CompletionEntryDataAutoImport, - CompletionEntryDataResolved, - CompletionEntryDataUnresolved, - CompletionEntryDetails, - CompletionEntryLabelDetails, - CompletionInfo, - CompletionInfoFlags, - CompletionsTriggerCharacter, - CompletionTriggerKind, concatenate, - ConstructorDeclaration, - ContextFlags, - createModuleSpecifierResolutionHost, - createPackageJsonImportFilter, - createPrinter, createSortedArray, - createTextRangeFromSpan, - createTextSpanFromBounds, - createTextSpanFromNode, - createTextSpanFromRange, - Debug, - Declaration, - Diagnostics, - diagnosticToString, - displayPart, - EmitHint, - EmitTextWriter, - escapeSnippetText, every, - ExportKind, - Expression, - factory, filter, find, - findAncestor, - findChildOfKind, - findPrecedingToken, first, firstDefined, flatMap, - formatting, - FunctionLikeDeclaration, - getAllSuperTypeNodes, - getAncestor, - getCombinedLocalAndExportSymbolFlags, - getContainingClass, - getContextualTypeFromParent, - getDeclarationModifierFlagsFromSymbol, - getEffectiveBaseTypeNode, - getEffectiveModifierFlags, - getEffectiveTypeAnnotationNode, - getEmitModuleResolutionKind, - getEmitScriptTarget, - getEscapedTextOfIdentifierOrLiteral, - getExportInfoMap, - getFormatCodeSettingsForWriting, - getLanguageVariant, - getLeftmostAccessExpression, - getLineAndCharacterOfPosition, - getLineStartPositionForPosition, - getLocalSymbolForExportDefault, - getNameForExportedSymbol, - getNameOfDeclaration, - getNameTable, - getNewLineCharacter, - getNewLineKind, - getPropertyNameForPropertyNameNode, - getQuotePreference, - getReplacementSpanForContextToken, - getRootDeclaration, - getSourceFileOfModule, - getSwitchedType, - getSymbolId, - getSynthesizedDeepClone, - getTokenAtPosition, - getTouchingPropertyName, - hasDocComment, - hasEffectiveModifier, - hasInitializer, - hasType, - Identifier, - ImportDeclaration, - ImportEqualsDeclaration, - ImportKind, - ImportOrExportSpecifier, - ImportSpecifier, - ImportTypeNode, - IncompleteCompletionsCache, insertSorted, - InternalSymbolName, - isAbstractConstructorSymbol, + isString, + last, + lastOrUndefined, + length, + mapDefined, + maybeBind, + memoize, + memoizeOne, + or, + singleElementArray, + some, + stableSort, + startsWith, + tryCast, +} from "../compiler/core"; +import { + Comparison, + SortedArray, +} from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { Diagnostics } from "../compiler/diagnosticInformationMap.generated"; +import { createPrinter } from "../compiler/emitter"; +import { setSnippetElement } from "../compiler/factory/emitNode"; +import { factory } from "../compiler/factory/nodeFactory"; +import { isArrowFunction, - isAssertionExpression, isBigIntLiteral, isBinaryExpression, isBindingElement, - isBindingPattern, - isBreakOrContinueStatement, isCallExpression, isCaseClause, - isCheckJsEnabledForFile, - isClassElement, - isClassLike, - isClassMemberModifier, - isClassOrTypeElement, isClassStaticBlockDeclaration, isComputedPropertyName, isConstructorDeclaration, - isContextualKeyword, - isDeclarationName, - isDeprecatedDeclaration, - isEntityName, - isEqualityOperatorKind, isExportAssignment, isExportDeclaration, - isExpression, - isExternalModuleNameRelative, isExternalModuleReference, - isExternalModuleSymbol, - isFunctionBlock, - isFunctionLike, - isFunctionLikeDeclaration, - isFunctionLikeKind, isFunctionTypeNode, isIdentifier, - isIdentifierText, - isImportableFile, isImportDeclaration, isImportEqualsDeclaration, isImportKeyword, isImportSpecifier, - isInComment, - isInitializedProperty, - isInJSFile, - isInRightSideOfInternalImportEqualsDeclaration, - isInString, isIntersectionTypeNode, isJSDoc, isJSDocParameterTag, - isJSDocTag, isJSDocTemplateTag, isJsxAttribute, isJsxClosingElement, isJsxElement, isJsxExpression, isJsxFragment, - isJsxOpeningLikeElement, isJsxSpreadAttribute, - isKeyword, - isKnownSymbol, isLabeledStatement, - isLiteralImportTypeNode, - isMemberName, isMethodDeclaration, - isModifier, - isModifierKind, isModuleDeclaration, isNamedExports, isNamedImports, - isNamedImportsOrExports, isNamespaceImport, isObjectBindingPattern, isObjectLiteralExpression, - isObjectTypeDeclaration, isParameter, - isParameterPropertyModifier, - isPartOfTypeNode, - isPossiblyTypeArgumentPosition, isPrivateIdentifier, - isPrivateIdentifierClassElementDeclaration, isPropertyAccessExpression, isPropertyDeclaration, - isPropertyNameLiteral, isRegularExpressionLiteral, isShorthandPropertyAssignment, - isSingleOrDoubleQuote, isSourceFile, - isSourceFileJS, isSpreadAssignment, - isStatement, - isStatic, - isString, - isStringANonContextualKeyword, - isStringLiteralLike, - isStringLiteralOrTemplate, - isStringTextContainingNode, isSyntaxList, - isTypeKeyword, - isTypeKeywordTokenOrIdentifier, isTypeLiteralNode, - isTypeNode, isTypeOfExpression, - isTypeOnlyImportOrExportDeclaration, - isTypeReferenceType, - isValidTypeOnlyAliasUseSite, isVariableDeclaration, - isVariableLike, - JsDoc, +} from "../compiler/factory/nodeTests"; +import { timestamp } from "../compiler/performanceCore"; +import { + getLineAndCharacterOfPosition, + isIdentifierText, + stringToToken, + tokenToString, +} from "../compiler/scanner"; +import { isInitializedProperty } from "../compiler/transformers/utilities"; +import { + __String, + BinaryExpression, + BreakOrContinueStatement, + CancellationToken, + CharacterCodes, + ClassElement, + CompilerOptions, + ConstructorDeclaration, + ContextFlags, + Declaration, + EmitHint, + EmitTextWriter, + Expression, + FunctionLikeDeclaration, + Identifier, + ImportDeclaration, + ImportEqualsDeclaration, + ImportOrExportSpecifier, + ImportSpecifier, + ImportTypeNode, + InternalSymbolName, JSDocParameterTag, JSDocPropertyTag, JSDocReturnTag, JSDocTag, - JSDocTagInfo, JSDocTemplateTag, JSDocTypedefTag, JSDocTypeExpression, JSDocTypeTag, - JsTyping, JsxAttribute, JsxAttributes, JsxClosingElement, JsxElement, JsxOpeningLikeElement, JsxSpreadAttribute, - LanguageServiceHost, LanguageVariant, - last, - lastOrUndefined, - length, ListFormat, - mapDefined, - maybeBind, MemberOverrideStatus, - memoize, - memoizeOne, MethodDeclaration, ModifierFlags, - modifiersToFlags, ModifierSyntaxKind, - modifierToFlag, ModuleDeclaration, ModuleReference, - moduleResolutionRespectsExports, NamedImportBindings, Node, NodeArray, NodeBuilderFlags, NodeFlags, - nodeIsMissing, ObjectBindingPattern, ObjectLiteralExpression, ObjectType, ObjectTypeDeclaration, - or, - positionBelongsToNode, - positionIsASICandidate, - positionsAreOnSameLine, PrinterOptions, - probablyUsesSemicolons, Program, - programContainsModules, PropertyAccessExpression, PropertyDeclaration, PropertyName, PseudoBigInt, - pseudoBigIntToString, QualifiedName, - quote, - QuotePreference, - rangeContainsPosition, - rangeContainsPositionExclusive, - rangeIsOnSingleLine, - ScriptElementKind, - ScriptElementKindModifier, ScriptTarget, - SemanticMeaning, - setSnippetElement, - shouldUseUriStyleNodeCoreModules, - SignatureHelp, SignatureKind, - singleElementArray, - skipAlias, SnippetKind, - some, - SortedArray, SourceFile, SpreadAssignment, - stableSort, - startsWith, - stringToToken, - stripQuotes, Symbol, - SymbolDisplay, - SymbolDisplayPart, - SymbolDisplayPartKind, - SymbolExportInfo, SymbolFlags, SymbolId, SyntaxKind, - TextChange, - textChanges, - textPart, TextRange, TextSpan, - timestamp, Token, TokenSyntaxKind, - tokenToString, - tryCast, - tryGetImportFromModuleSpecifier, Type, TypeChecker, TypeElement, TypeFlags, - typeHasCallOrConstructSignatures, TypeLiteralNode, TypeOnlyAliasDeclaration, - unescapeLeadingUnderscores, UnionReduction, UnionType, UserPreferences, VariableDeclaration, +} from "../compiler/types"; +import { + addToSeen, + compareNumberOfDirectorySeparators, + escapeSnippetText, + getAllSuperTypeNodes, + getAncestor, + getCombinedLocalAndExportSymbolFlags, + getContainingClass, + getDeclarationModifierFlagsFromSymbol, + getEffectiveBaseTypeNode, + getEffectiveModifierFlags, + getEffectiveTypeAnnotationNode, + getEmitModuleResolutionKind, + getEmitScriptTarget, + getEscapedTextOfIdentifierOrLiteral, + getLanguageVariant, + getLeftmostAccessExpression, + getLocalSymbolForExportDefault, + getNewLineCharacter, + getPropertyNameForPropertyNameNode, + getRootDeclaration, + getSourceFileOfModule, + hasEffectiveModifier, + isAbstractConstructorSymbol, + isCheckJsEnabledForFile, + isContextualKeyword, + isDeclarationName, + isFunctionBlock, + isInJSFile, + isKeyword, + isKnownSymbol, + isLiteralImportTypeNode, + isNamedImportsOrExports, + isObjectTypeDeclaration, + isPartOfTypeNode, + isPropertyNameLiteral, + isSingleOrDoubleQuote, + isSourceFileJS, + isStatic, + isStringANonContextualKeyword, + isValidTypeOnlyAliasUseSite, + isVariableLike, + modifiersToFlags, + modifierToFlag, + nodeIsMissing, + positionsAreOnSameLine, + pseudoBigIntToString, + rangeIsOnSingleLine, + skipAlias, + stripQuotes, + tryGetImportFromModuleSpecifier, + typeHasCallOrConstructSignatures, walkUpParenthesizedExpressions, -} from "./_namespaces/ts"; -import { StringCompletions } from "./_namespaces/ts.Completions"; +} from "../compiler/utilities"; +import { + createTextSpanFromBounds, + findAncestor, + getNameOfDeclaration, + hasInitializer, + hasType, + isAssertionExpression, + isBindingPattern, + isBreakOrContinueStatement, + isClassElement, + isClassLike, + isClassMemberModifier, + isClassOrTypeElement, + isEntityName, + isExpression, + isExternalModuleNameRelative, + isFunctionLike, + isFunctionLikeDeclaration, + isFunctionLikeKind, + isJSDocTag, + isJsxOpeningLikeElement, + isMemberName, + isModifier, + isModifierKind, + isParameterPropertyModifier, + isPrivateIdentifierClassElementDeclaration, + isStatement, + isStringLiteralLike, + isStringTextContainingNode, + isTypeNode, + isTypeOnlyImportOrExportDeclaration, + isTypeReferenceType, + unescapeLeadingUnderscores, +} from "../compiler/utilitiesPublic"; +import * as JsTyping from "../jsTyping/jsTyping"; +import { + addNewNodeForMemberSymbol, + getNoopSymbolTrackerWithResolver, + PreserveOptionalFlags, +} from "./codefixes/helpers"; +import { + createImportAdder, + createImportSpecifierResolver, + getImportCompletionAction, + getImportKind, + getPromoteTypeOnlyCompletionAction, + ImportAdder, + ImportSpecifierResolver, +} from "./codefixes/importAdder"; +import { + getExportInfoMap, + ImportKind, + isImportableFile, +} from "./exportInfoMap"; +import { formatNodeGivenIndentation } from "./formatting/formatting"; +import { + getJSDocParameterNameCompletionDetails, + getJSDocParameterNameCompletions, + getJSDocTagCompletionDetails, + getJSDocTagCompletions, + getJSDocTagNameCompletionDetails, + getJSDocTagNameCompletions, +} from "./jsDoc"; +import { getNameTable } from "./services"; +import { getArgumentInfoForCompletions } from "./signatureHelp"; +import * as StringCompletions from "./stringCompletions"; +import { + getSymbolDisplayPartsDocumentationAndSymbolKind, + getSymbolKind, + getSymbolModifiers, +} from "./symbolDisplay"; +import { + applyChanges, + assignPositionsToNode, + ChangeTracker, + createWriter, +} from "./textChanges"; +import { + CodeAction, + CompletionEntry, + CompletionEntryData, + CompletionEntryDataAutoImport, + CompletionEntryDataResolved, + CompletionEntryDataUnresolved, + CompletionEntryDetails, + CompletionEntryLabelDetails, + CompletionInfo, + CompletionInfoFlags, + CompletionsTriggerCharacter, + CompletionTriggerKind, + ExportKind, + FormatContext, + IncompleteCompletionsCache, + JSDocTagInfo, + LanguageServiceHost, + ScriptElementKind, + ScriptElementKindModifier, + SymbolDisplayPart, + SymbolDisplayPartKind, + SymbolExportInfo, + TextChange, +} from "./types"; +import { + compilerOptionsIndicateEsModules, + createModuleSpecifierResolutionHost, + createPackageJsonImportFilter, + createTextRangeFromSpan, + createTextSpanFromNode, + createTextSpanFromRange, + diagnosticToString, + displayPart, + findChildOfKind, + findPrecedingToken, + getContextualTypeFromParent, + getFormatCodeSettingsForWriting, + getLineStartPositionForPosition, + getNameForExportedSymbol, + getNewLineKind, + getQuotePreference, + getReplacementSpanForContextToken, + getSwitchedType, + getSynthesizedDeepClone, + getTokenAtPosition, + getTouchingPropertyName, + hasDocComment, + isDeprecatedDeclaration, + isEqualityOperatorKind, + isExternalModuleSymbol, + isInComment, + isInRightSideOfInternalImportEqualsDeclaration, + isInString, + isPossiblyTypeArgumentPosition, + isStringLiteralOrTemplate, + isTypeKeyword, + isTypeKeywordTokenOrIdentifier, + moduleResolutionRespectsExports, + positionBelongsToNode, + positionIsASICandidate, + probablyUsesSemicolons, + programContainsModules, + quote, + QuotePreference, + rangeContainsPosition, + rangeContainsPositionExclusive, + SemanticMeaning, + shouldUseUriStyleNodeCoreModules, + textPart, +} from "./utilities"; // Exported only for tests /** @internal */ @@ -534,7 +582,7 @@ type ModuleSpecifierResolutionResult = "skipped" | "failed" | { function resolvingModuleSpecifiers( logPrefix: string, host: LanguageServiceHost, - resolver: codefix.ImportSpecifierResolver, + resolver: ImportSpecifierResolver, program: Program, position: number, preferences: UserPreferences, @@ -607,7 +655,7 @@ export function getCompletionsAtPosition( triggerCharacter: CompletionsTriggerCharacter | undefined, completionKind: CompletionTriggerKind | undefined, cancellationToken: CancellationToken, - formatContext?: formatting.FormatContext, + formatContext?: FormatContext, ): CompletionInfo | undefined { const { previousToken } = getRelevantTokens(position, sourceFile); if (triggerCharacter && !isInString(sourceFile, position, previousToken) && !isValidTrigger(sourceFile, triggerCharacter, previousToken, position)) { @@ -661,12 +709,12 @@ export function getCompletionsAtPosition( 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(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(getJSDocTagCompletions()); case CompletionDataKind.JsDocParameterName: - return jsdocCompletionInfo(JsDoc.getJSDocParameterNameCompletions(completionData.tag)); + return jsdocCompletionInfo(getJSDocParameterNameCompletions(completionData.tag)); case CompletionDataKind.Keywords: return specificKeywordCompletionInfo(completionData.keywordCompletions, completionData.isNewIdentifierLocation); default: @@ -721,7 +769,7 @@ function continuePreviousIncompleteResponse( const newEntries = resolvingModuleSpecifiers( "continuePreviousIncompleteResponse", host, - codefix.createImportSpecifierResolver(file, program, host, preferences), + createImportSpecifierResolver(file, program, host, preferences), program, location.getStart(), preferences, @@ -824,7 +872,7 @@ function completionInfoFromData( log: Log, completionData: CompletionData, preferences: UserPreferences, - formatContext: formatting.FormatContext | undefined, + formatContext: FormatContext | undefined, position: number ): CompletionInfo | undefined { const { @@ -1041,7 +1089,7 @@ function createCompletionEntry( options: CompilerOptions, preferences: UserPreferences, completionKind: CompletionKind, - formatContext: formatting.FormatContext | undefined, + formatContext: FormatContext | undefined, isJsxIdentifierExpected: boolean | undefined, isRightOfOpenTag: boolean | undefined, ): CompletionEntry | undefined { @@ -1180,8 +1228,8 @@ function createCompletionEntry( // entries (like JavaScript identifier entries). return { name, - kind: SymbolDisplay.getSymbolKind(typeChecker, symbol, location), - kindModifiers: SymbolDisplay.getSymbolModifiers(typeChecker, symbol), + kind: getSymbolKind(typeChecker, symbol, location), + kindModifiers: getSymbolModifiers(typeChecker, symbol), sortText, source, hasAction: hasAction ? true : undefined, @@ -1255,8 +1303,8 @@ function getEntryForMemberCompletion( symbol: Symbol, location: Node, contextToken: Node | undefined, - formatContext: formatting.FormatContext | undefined, -): { insertText: string, isSnippet?: true, importAdder?: codefix.ImportAdder, replacementSpan?: TextSpan } { + formatContext: FormatContext | undefined, +): { insertText: string, isSnippet?: true, importAdder?: ImportAdder, replacementSpan?: TextSpan } { const classLikeDeclaration = findAncestor(location, isClassLike); if (!classLikeDeclaration) { return { insertText: name }; @@ -1275,7 +1323,7 @@ function getEntryForMemberCompletion( omitTrailingSemicolon: false, newLine: getNewLineKind(getNewLineCharacter(options, maybeBind(host, host.getNewLine))), }); - const importAdder = codefix.createImportAdder(sourceFile, program, preferences, host); + const importAdder = createImportAdder(sourceFile, program, preferences, host, /*useAutoImportProvider*/ false); // Create empty body for possible method implementation. let body; @@ -1298,7 +1346,7 @@ function getEntryForMemberCompletion( const { modifiers: presentModifiers, span: modifiersSpan } = getPresentModifiers(contextToken); const isAbstract = !!(presentModifiers & ModifierFlags.Abstract); const completionNodes: Node[] = []; - codefix.addNewNodeForMemberSymbol( + addNewNodeForMemberSymbol( symbol, classLikeDeclaration, sourceFile, @@ -1333,7 +1381,7 @@ function getEntryForMemberCompletion( completionNodes.push(node); }, body, - codefix.PreserveOptionalFlags.Property, + PreserveOptionalFlags.Property, isAbstract); if (completionNodes.length) { @@ -1414,7 +1462,7 @@ function getEntryForObjectLiteralMethodCompletion( host: LanguageServiceHost, options: CompilerOptions, preferences: UserPreferences, - formatContext: formatting.FormatContext | undefined, + formatContext: FormatContext | undefined, ): { insertText: string, isSnippet?: true, labelDetails: CompletionEntryLabelDetails } | undefined { const isSnippet = preferences.includeCompletionsWithSnippetText || undefined; let insertText: string = name; @@ -1503,7 +1551,7 @@ function createObjectLiteralMethod( // We don't support overloads in object literals. return undefined; } - const typeNode = checker.typeToTypeNode(effectiveType, enclosingDeclaration, builderFlags, codefix.getNoopSymbolTrackerWithResolver({ program, host })); + const typeNode = checker.typeToTypeNode(effectiveType, enclosingDeclaration, builderFlags, getNoopSymbolTrackerWithResolver({ program, host })); if (!typeNode || !isFunctionTypeNode(typeNode)) { return undefined; } @@ -1546,7 +1594,7 @@ function createSnippetPrinter( printerOptions: PrinterOptions, ) { let escapes: TextChange[] | undefined; - const baseWriter = textChanges.createWriter(getNewLineCharacter(printerOptions)); + const baseWriter = createWriter(getNewLineCharacter(printerOptions)); const printer = createPrinter(printerOptions, baseWriter); const writer: EmitTextWriter = { ...baseWriter, @@ -1589,7 +1637,7 @@ function createSnippetPrinter( sourceFile: SourceFile | undefined, ): string { const unescaped = printUnescapedSnippetList(format, list, sourceFile); - return escapes ? textChanges.applyChanges(unescaped, escapes) : unescaped; + return escapes ? applyChanges(unescaped, escapes) : unescaped; } function printUnescapedSnippetList( @@ -1607,7 +1655,7 @@ function createSnippetPrinter( format: ListFormat, list: NodeArray, sourceFile: SourceFile, - formatContext: formatting.FormatContext, + formatContext: FormatContext, ): string { const syntheticFile = { text: printUnescapedSnippetList( @@ -1621,8 +1669,8 @@ function createSnippetPrinter( const formatOptions = getFormatCodeSettingsForWriting(formatContext, sourceFile); const changes = flatMap(list, node => { - const nodeWithPos = textChanges.assignPositionsToNode(node); - return formatting.formatNodeGivenIndentation( + const nodeWithPos = assignPositionsToNode(node); + return formatNodeGivenIndentation( nodeWithPos, syntheticFile, sourceFile.languageVariant, @@ -1634,7 +1682,7 @@ function createSnippetPrinter( const allChanges = escapes ? stableSort(concatenate(changes, escapes), (a, b) => compareTextSpans(a.span, b.span)) : changes; - return textChanges.applyChanges(syntheticFile.text, allChanges); + return applyChanges(syntheticFile.text, allChanges); } } @@ -1698,7 +1746,7 @@ function getInsertTextAndReplacementSpanForImportCompletion(name: string, import origin.exportName === InternalSymbolName.ExportEquals ? ExportKind.ExportEquals : ExportKind.Named; const tabStop = preferences.includeCompletionsWithSnippetText ? "$1" : ""; - const importKind = codefix.getImportKind(sourceFile, exportKind, options, /*forceImportKeyword*/ true); + const importKind = getImportKind(sourceFile, exportKind, options, /*forceImportKeyword*/ true); const isImportSpecifierTypeOnly = importStatementCompletion.couldBeTypeOnlyImportSpecifier; const topLevelTypeOnlyText = importStatementCompletion.isTopLevelTypeOnly ? ` ${tokenToString(SyntaxKind.TypeKeyword)} ` : " "; const importSpecifierTypeOnlyText = isImportSpecifierTypeOnly ? `${tokenToString(SyntaxKind.TypeKeyword)} ` : ""; @@ -1754,7 +1802,7 @@ export function getCompletionEntriesFromSymbols( kind: CompletionKind, preferences: UserPreferences, compilerOptions: CompilerOptions, - formatContext: formatting.FormatContext | undefined, + formatContext: FormatContext | undefined, isTypeOnlyLocation?: boolean, propertyAccessToConvert?: PropertyAccessExpression, jsxIdentifierExpected?: boolean, @@ -1991,7 +2039,7 @@ export function getCompletionEntryDetails( position: number, entryId: CompletionEntryIdentifier, host: LanguageServiceHost, - formatContext: formatting.FormatContext, + formatContext: FormatContext, preferences: UserPreferences, cancellationToken: CancellationToken, ): CompletionEntryDetails | undefined { @@ -2011,11 +2059,11 @@ export function getCompletionEntryDetails( const { request } = symbolCompletion; switch (request.kind) { case CompletionDataKind.JsDocTagName: - return JsDoc.getJSDocTagNameCompletionDetails(name); + return getJSDocTagNameCompletionDetails(name); case CompletionDataKind.JsDocTag: - return JsDoc.getJSDocTagCompletionDetails(name); + return getJSDocTagCompletionDetails(name); case CompletionDataKind.JsDocParameterName: - return JsDoc.getJSDocParameterNameCompletionDetails(name); + return getJSDocParameterNameCompletionDetails(name); case CompletionDataKind.Keywords: return some(request.keywordCompletions, c => c.name === name) ? createSimpleDetails(name, ScriptElementKind.keyword, SymbolDisplayPartKind.keyword) : undefined; default: @@ -2047,9 +2095,9 @@ function createSimpleDetails(name: string, kind: ScriptElementKind, kind2: Symbo 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) + getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, sourceFile, location, location, SemanticMeaning.All) ); - return createCompletionDetails(symbol.name, SymbolDisplay.getSymbolModifiers(checker, symbol), symbolKind, displayParts, documentation, tags, codeActions, sourceDisplay); + return createCompletionDetails(symbol.name, getSymbolModifiers(checker, symbol), symbolKind, displayParts, documentation, tags, codeActions, sourceDisplay); } /** @internal */ @@ -2073,7 +2121,7 @@ function getCompletionEntryCodeActionsAndSourceDisplay( sourceFile: SourceFile, position: number, previousToken: Node | undefined, - formatContext: formatting.FormatContext, + formatContext: FormatContext, preferences: UserPreferences, data: CompletionEntryData | undefined, source: string | undefined, @@ -2098,7 +2146,7 @@ function getCompletionEntryCodeActionsAndSourceDisplay( contextToken, formatContext); if (importAdder) { - const changes = textChanges.ChangeTracker.with( + const changes = ChangeTracker.with( { host, formatContext, preferences }, importAdder.writeFixes); return { @@ -2112,7 +2160,7 @@ function getCompletionEntryCodeActionsAndSourceDisplay( } if (originIsTypeOnlyAlias(origin)) { - const codeAction = codefix.getPromoteTypeOnlyCompletionAction( + const codeAction = getPromoteTypeOnlyCompletionAction( sourceFile, origin.declaration.name, program, @@ -2132,7 +2180,7 @@ function getCompletionEntryCodeActionsAndSourceDisplay( 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( + const { moduleSpecifier, codeAction } = getImportCompletionAction( targetSymbol, moduleSymbol, sourceFile, @@ -2245,7 +2293,7 @@ function getContextualType(previousToken: Node, position: number, sourceFile: So case SyntaxKind.OpenBraceToken: return isJsxExpression(parent) && !isJsxElement(parent.parent) && !isJsxFragment(parent.parent) ? checker.getContextualTypeForJsxAttribute(parent.parent) : undefined; default: - const argInfo = SignatureHelp.getArgumentInfoForCompletions(previousToken, position, sourceFile); + const argInfo = 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)) : @@ -2275,7 +2323,7 @@ function getCompletionData( preferences: UserPreferences, detailsEntryId: CompletionEntryIdentifier | undefined, host: LanguageServiceHost, - formatContext: formatting.FormatContext | undefined, + formatContext: FormatContext | undefined, cancellationToken?: CancellationToken, ): CompletionData | Request | undefined { const typeChecker = program.getTypeChecker(); @@ -2540,7 +2588,7 @@ function getCompletionData( let hasUnresolvedAutoImports = false; // This also gets mutated in nested-functions after the return let symbols: Symbol[] = []; - let importSpecifierResolver: codefix.ImportSpecifierResolver | undefined; + let importSpecifierResolver: ImportSpecifierResolver | undefined; const symbolToOriginInfoMap: SymbolOriginInfoMap = []; const symbolToSortTextMap: SymbolSortTextMap = []; const seenPropertySymbols = new Map(); @@ -2783,7 +2831,7 @@ function getCompletionData( } else { const fileName = isExternalModuleNameRelative(stripQuotes(moduleSymbol.name)) ? getSourceFileOfModule(moduleSymbol)?.fileName : undefined; - const { moduleSpecifier } = (importSpecifierResolver ||= codefix.createImportSpecifierResolver(sourceFile, program, host, preferences)).getModuleSpecifierForBestExportInfo([{ + const { moduleSpecifier } = (importSpecifierResolver ||= createImportSpecifierResolver(sourceFile, program, host, preferences)).getModuleSpecifierForBestExportInfo([{ exportKind: ExportKind.Named, moduleFileName: fileName, isFromPackageJson: false, @@ -3070,7 +3118,7 @@ function getCompletionData( resolvingModuleSpecifiers( "collectAutoImports", host, - importSpecifierResolver ||= codefix.createImportSpecifierResolver(sourceFile, program, host, preferences), + importSpecifierResolver ||= createImportSpecifierResolver(sourceFile, program, host, preferences), program, position, preferences, diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index c3bb005234dca..ab289e59cb8b2 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -1,602 +1,611 @@ import { - __String, arrayFrom, arrayToMultiMap, - Block, - BreakOrContinueStatement, - CancellationToken, - CaseClause, cast, concatenate, - ConstructorDeclaration, contains, createGetCanonicalFileName, - createTextSpanFromBounds, - createTextSpanFromNode, - Debug, - DefaultClause, find, - FindAllReferences, - findAncestor, - findChildOfKind, - findModifier, forEach, - forEachChild, - forEachReturnStatement, - FunctionDeclaration, - FunctionLikeDeclaration, - getContainingFunction, - getTouchingPropertyName, - HighlightSpan, - HighlightSpanKind, - IfStatement, - isAccessor, + isWhiteSpaceSingleLine, + mapDefined, + toArray, +} from "../compiler/core"; +import { Push } from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { isAwaitExpression, isBlock, - isBreakOrContinueStatement, isCaseClause, isClassDeclaration, - isClassLike, isConstructorDeclaration, - isDeclaration, isDefaultClause, - isFunctionBlock, - isFunctionLike, isIfStatement, isInterfaceDeclaration, - isIterationStatement, isJsxClosingElement, isJsxOpeningElement, isLabeledStatement, - isModifierKind, isModuleDeclaration, isReturnStatement, isSwitchStatement, isThrowStatement, isTryStatement, isTypeAliasDeclaration, - isTypeNode, isVariableStatement, - isWhiteSpaceSingleLine, isYieldExpression, +} from "../compiler/factory/nodeTests"; +import { forEachChild } from "../compiler/parser"; +import { toPath } from "../compiler/path"; +import { + __String, + Block, + BreakOrContinueStatement, + CancellationToken, + CaseClause, + ConstructorDeclaration, + DefaultClause, + FunctionDeclaration, + FunctionLikeDeclaration, + IfStatement, IterationStatement, - mapDefined, MethodDeclaration, Modifier, ModifierFlags, - modifierToFlag, ModuleBlock, Node, ObjectLiteralExpression, ObjectTypeDeclaration, Program, - Push, ReturnStatement, SourceFile, SwitchStatement, SyntaxKind, ThrowStatement, - toArray, - toPath, TryStatement, -} from "./_namespaces/ts"; - -export interface DocumentHighlights { - fileName: string; - highlightSpans: HighlightSpan[]; -} +} from "../compiler/types"; +import { + forEachReturnStatement, + getContainingFunction, + isFunctionBlock, + modifierToFlag, +} from "../compiler/utilities"; +import { + createTextSpanFromBounds, + findAncestor, + isAccessor, + isBreakOrContinueStatement, + isClassLike, + isDeclaration, + isFunctionLike, + isIterationStatement, + isModifierKind, + isTypeNode, +} from "../compiler/utilitiesPublic"; +import { + getReferenceEntriesForNode, + toHighlightSpan, +} from "./findAllReferences"; +import { + DocumentHighlights, + HighlightSpan, + HighlightSpanKind, +} from "./types"; +import { + createTextSpanFromNode, + findChildOfKind, + findModifier, + getTouchingPropertyName, +} from "./utilities"; /** @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))) { - // 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)); - return [{ fileName: sourceFile.fileName, highlightSpans }]; - } - - return getSemanticDocumentHighlights(position, node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile); - } - - function getHighlightSpanForNode(node: Node, sourceFile: SourceFile): HighlightSpan { - return { - fileName: sourceFile.fileName, - textSpan: createTextSpanFromNode(node, sourceFile), - kind: HighlightSpanKind.none - }; +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))) { + // 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)); + return [{ fileName: sourceFile.fileName, highlightSpans }]; } - 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]) => { - if (!sourceFilesSet.has(fileName)) { - if (!program.redirectTargetsMap.has(toPath(fileName, program.getCurrentDirectory(), getCanonicalFileName))) { - return undefined; - } - const redirectTarget = program.getSourceFile(fileName); - const redirect = find(sourceFilesToSearch, f => !!f.redirectInfo && f.redirectInfo.redirectTarget === redirectTarget)!; - fileName = redirect.fileName; - Debug.assert(sourceFilesSet.has(fileName)); - } - return { fileName, highlightSpans }; - }); - } + return getSemanticDocumentHighlights(position, node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile); +} - function getSyntacticDocumentHighlights(node: Node, sourceFile: SourceFile): DocumentHighlights[] | undefined { - const highlightSpans = getHighlightSpans(node, sourceFile); - return highlightSpans && [{ fileName: sourceFile.fileName, highlightSpans }]; - } +function getHighlightSpanForNode(node: Node, sourceFile: SourceFile): HighlightSpan { + return { + fileName: sourceFile.fileName, + textSpan: createTextSpanFromNode(node, sourceFile), + kind: HighlightSpanKind.none + }; +} - function getHighlightSpans(node: Node, sourceFile: SourceFile): 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); - } +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 = getReferenceEntriesForNode(position, node, program, sourceFilesToSearch, cancellationToken, /*options*/ undefined, sourceFilesSet); + if (!referenceEntries) return undefined; + const map = arrayToMultiMap(referenceEntries.map(toHighlightSpan), e => e.fileName, e => e.span); + const getCanonicalFileName = createGetCanonicalFileName(program.useCaseSensitiveFileNames()); + return mapDefined(arrayFrom(map.entries()), ([fileName, highlightSpans]) => { + if (!sourceFilesSet.has(fileName)) { + if (!program.redirectTargetsMap.has(toPath(fileName, program.getCurrentDirectory(), getCanonicalFileName))) { 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: - return highlightSpans(getAsyncAndAwaitOccurrences(node)); - case SyntaxKind.YieldKeyword: - return highlightSpans(getYieldOccurrences(node)); - case SyntaxKind.InKeyword: - return undefined; - default: - return isModifierKind(node.kind) && (isDeclaration(node.parent) || isVariableStatement(node.parent)) - ? highlightSpans(getModifierOccurrences(node.kind, node.parent)) - : undefined; + const redirectTarget = program.getSourceFile(fileName); + const redirect = find(sourceFilesToSearch, f => !!f.redirectInfo && f.redirectInfo.redirectTarget === redirectTarget)!; + fileName = redirect.fileName; + Debug.assert(sourceFilesSet.has(fileName)); } + return { fileName, highlightSpans }; + }); +} - 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 getSyntacticDocumentHighlights(node: Node, sourceFile: SourceFile): DocumentHighlights[] | undefined { + const highlightSpans = getHighlightSpans(node, sourceFile); + return highlightSpans && [{ fileName: sourceFile.fileName, highlightSpans }]; +} - function useParent(node: Node, nodeTest: (node: Node) => node is T, getNodes: (node: T, sourceFile: SourceFile) => readonly Node[] | undefined): HighlightSpan[] | undefined { - return nodeTest(node) ? highlightSpans(getNodes(node, sourceFile)) : undefined; +function getHighlightSpans(node: Node, sourceFile: SourceFile): 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); + } + 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: + return highlightSpans(getAsyncAndAwaitOccurrences(node)); + case SyntaxKind.YieldKeyword: + return highlightSpans(getYieldOccurrences(node)); + case SyntaxKind.InKeyword: + return undefined; + default: + return isModifierKind(node.kind) && (isDeclaration(node.parent) || isVariableStatement(node.parent)) + ? highlightSpans(getModifierOccurrences(node.kind, node.parent)) + : undefined; + } - function highlightSpans(nodes: readonly Node[] | undefined): HighlightSpan[] | undefined { - return nodes && nodes.map(node => getHighlightSpanForNode(node, sourceFile)); - } + 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)); } - /** - * 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)) { - return [node]; - } - else if (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)); - } - // Do not cross function boundaries. - return isFunctionLike(node) ? undefined : flatMapChildren(node, aggregateOwnedThrowStatements); + function useParent(node: Node, nodeTest: (node: Node) => node is T, getNodes: (node: T, sourceFile: SourceFile) => readonly Node[] | undefined): HighlightSpan[] | undefined { + return nodeTest(node) ? highlightSpans(getNodes(node, sourceFile)) : undefined; } - /** - * For lack of a better name, this function takes a throw statement and returns the - * 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 highlightSpans(nodes: readonly Node[] | undefined): HighlightSpan[] | undefined { + return nodes && nodes.map(node => getHighlightSpanForNode(node, sourceFile)); + } +} - while (child.parent) { - const parent = child.parent; +/** + * 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)) { + return [node]; + } + else if (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)); + } + // Do not cross function boundaries. + return isFunctionLike(node) ? undefined : flatMapChildren(node, aggregateOwnedThrowStatements); +} - if (isFunctionBlock(parent) || parent.kind === SyntaxKind.SourceFile) { - return parent; - } +/** + * For lack of a better name, this function takes a throw statement and returns the + * 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; - // 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) { - return child; - } + while (child.parent) { + const parent = child.parent; - child = parent; + if (isFunctionBlock(parent) || parent.kind === SyntaxKind.SourceFile) { + return parent; } - return undefined; - } + // 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) { + return child; + } - function aggregateAllBreakAndContinueStatements(node: Node): readonly BreakOrContinueStatement[] | undefined { - return isBreakOrContinueStatement(node) ? [node] : isFunctionLike(node) ? undefined : flatMapChildren(node, aggregateAllBreakAndContinueStatements); + child = parent; } - function flatMapChildren(node: Node, cb: (child: Node) => readonly T[] | T | undefined): readonly T[] { - const result: T[] = []; - node.forEachChild(child => { - const value = cb(child); - if (value !== undefined) { - result.push(...toArray(value)); - } - }); - return result; - } + return undefined; +} - function ownsBreakOrContinueStatement(owner: Node, statement: BreakOrContinueStatement): boolean { - const actualOwner = getBreakOrContinueOwner(statement); - return !!actualOwner && actualOwner === owner; - } +function aggregateAllBreakAndContinueStatements(node: Node): readonly BreakOrContinueStatement[] | undefined { + return isBreakOrContinueStatement(node) ? [node] : isFunctionLike(node) ? undefined : flatMapChildren(node, aggregateAllBreakAndContinueStatements); +} - function getBreakOrContinueOwner(statement: BreakOrContinueStatement): Node | undefined { - return findAncestor(statement, node => { - switch (node.kind) { - case SyntaxKind.SwitchStatement: - if (statement.kind === SyntaxKind.ContinueStatement) { - return false; - } - // falls through - - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.DoStatement: - return !statement.label || isLabeledBy(node, statement.label.escapedText); - default: - // Don't cross function boundaries. - // TODO: GH#20090 - return isFunctionLike(node) && "quit"; - } - }); - } +function flatMapChildren(node: Node, cb: (child: Node) => readonly T[] | T | undefined): readonly T[] { + const result: T[] = []; + node.forEachChild(child => { + const value = cb(child); + if (value !== undefined) { + result.push(...toArray(value)); + } + }); + return result; +} - function getModifierOccurrences(modifier: Modifier["kind"], declaration: Node): Node[] { - return mapDefined(getNodesToSearchForModifier(declaration, modifierToFlag(modifier)), node => findModifier(node, modifier)); - } +function ownsBreakOrContinueStatement(owner: Node, statement: BreakOrContinueStatement): boolean { + const actualOwner = getBreakOrContinueOwner(statement); + return !!actualOwner && actualOwner === owner; +} - function getNodesToSearchForModifier(declaration: Node, modifierFlag: ModifierFlags): readonly 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; - switch (container.kind) { - case SyntaxKind.ModuleBlock: - case SyntaxKind.SourceFile: - case SyntaxKind.Block: - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: - // Container is either a class declaration or the declaration is a classDeclaration - if (modifierFlag & ModifierFlags.Abstract && 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: - 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 (constructor) { - return [...nodes, ...constructor.parameters]; - } +function getBreakOrContinueOwner(statement: BreakOrContinueStatement): Node | undefined { + return findAncestor(statement, node => { + switch (node.kind) { + case SyntaxKind.SwitchStatement: + if (statement.kind === SyntaxKind.ContinueStatement) { + return false; } - else if (modifierFlag & ModifierFlags.Abstract) { - return [...nodes, container]; + // falls through + + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + case SyntaxKind.ForOfStatement: + case SyntaxKind.WhileStatement: + case SyntaxKind.DoStatement: + return !statement.label || isLabeledBy(node, statement.label.escapedText); + default: + // Don't cross function boundaries. + // TODO: GH#20090 + return isFunctionLike(node) && "quit"; + } + }); +} + +function getModifierOccurrences(modifier: Modifier["kind"], declaration: Node): Node[] { + return mapDefined(getNodesToSearchForModifier(declaration, modifierToFlag(modifier)), node => findModifier(node, modifier)); +} + +function getNodesToSearchForModifier(declaration: Node, modifierFlag: ModifierFlags): readonly 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; + switch (container.kind) { + case SyntaxKind.ModuleBlock: + case SyntaxKind.SourceFile: + case SyntaxKind.Block: + case SyntaxKind.CaseClause: + case SyntaxKind.DefaultClause: + // Container is either a class declaration or the declaration is a classDeclaration + if (modifierFlag & ModifierFlags.Abstract && 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: + 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 (constructor) { + return [...nodes, ...constructor.parameters]; } - return nodes; + } + else if (modifierFlag & ModifierFlags.Abstract) { + return [...nodes, container]; + } + return nodes; - // Syntactically invalid positions that the parser might produce anyway - case SyntaxKind.ObjectLiteralExpression: - return undefined; + // Syntactically invalid positions that the parser might produce anyway + case SyntaxKind.ObjectLiteralExpression: + return undefined; - default: - Debug.assertNever(container, "Invalid container kind."); - } + default: + Debug.assertNever(container, "Invalid container kind."); } +} - function pushKeywordIf(keywordList: Push, token: Node | undefined, ...expected: SyntaxKind[]): boolean { - if (token && contains(expected, token.kind)) { - keywordList.push(token); - return true; - } - - return false; +function pushKeywordIf(keywordList: Push, token: Node | undefined, ...expected: SyntaxKind[]): boolean { + if (token && contains(expected, token.kind)) { + keywordList.push(token); + return true; } - function getLoopBreakContinueOccurrences(loopNode: IterationStatement): Node[] { - const keywords: Node[] = []; + return false; +} + +function getLoopBreakContinueOccurrences(loopNode: IterationStatement): Node[] { + const keywords: Node[] = []; - if (pushKeywordIf(keywords, loopNode.getFirstToken(), SyntaxKind.ForKeyword, SyntaxKind.WhileKeyword, SyntaxKind.DoKeyword)) { - // If we succeeded and got a do-while loop, then start looking for a 'while' keyword. - if (loopNode.kind === SyntaxKind.DoStatement) { - const loopTokens = loopNode.getChildren(); + if (pushKeywordIf(keywords, loopNode.getFirstToken(), SyntaxKind.ForKeyword, SyntaxKind.WhileKeyword, SyntaxKind.DoKeyword)) { + // If we succeeded and got a do-while loop, then start looking for a 'while' keyword. + if (loopNode.kind === SyntaxKind.DoStatement) { + const loopTokens = loopNode.getChildren(); - for (let i = loopTokens.length - 1; i >= 0; i--) { - if (pushKeywordIf(keywords, loopTokens[i], SyntaxKind.WhileKeyword)) { - break; - } + for (let i = loopTokens.length - 1; i >= 0; i--) { + if (pushKeywordIf(keywords, loopTokens[i], SyntaxKind.WhileKeyword)) { + break; } } } + } - forEach(aggregateAllBreakAndContinueStatements(loopNode.statement), statement => { - if (ownsBreakOrContinueStatement(loopNode, statement)) { - pushKeywordIf(keywords, statement.getFirstToken(), SyntaxKind.BreakKeyword, SyntaxKind.ContinueKeyword); - } - }); + forEach(aggregateAllBreakAndContinueStatements(loopNode.statement), statement => { + if (ownsBreakOrContinueStatement(loopNode, statement)) { + pushKeywordIf(keywords, statement.getFirstToken(), SyntaxKind.BreakKeyword, SyntaxKind.ContinueKeyword); + } + }); - return keywords; - } + return keywords; +} - function getBreakOrContinueStatementOccurrences(breakOrContinueStatement: BreakOrContinueStatement): Node[] | undefined { - const owner = getBreakOrContinueOwner(breakOrContinueStatement); +function getBreakOrContinueStatementOccurrences(breakOrContinueStatement: BreakOrContinueStatement): 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); + 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); - } } - - return undefined; } - function getSwitchCaseDefaultOccurrences(switchStatement: SwitchStatement): Node[] { - const keywords: Node[] = []; + return undefined; +} - pushKeywordIf(keywords, switchStatement.getFirstToken(), SyntaxKind.SwitchKeyword); +function getSwitchCaseDefaultOccurrences(switchStatement: SwitchStatement): Node[] { + const keywords: Node[] = []; - // 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); + pushKeywordIf(keywords, switchStatement.getFirstToken(), SyntaxKind.SwitchKeyword); - forEach(aggregateAllBreakAndContinueStatements(clause), statement => { - if (ownsBreakOrContinueStatement(switchStatement, statement)) { - pushKeywordIf(keywords, statement.getFirstToken(), SyntaxKind.BreakKeyword); - } - }); - }); + // 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); - return keywords; - } + forEach(aggregateAllBreakAndContinueStatements(clause), statement => { + if (ownsBreakOrContinueStatement(switchStatement, statement)) { + pushKeywordIf(keywords, statement.getFirstToken(), SyntaxKind.BreakKeyword); + } + }); + }); - function getTryCatchFinallyOccurrences(tryStatement: TryStatement, sourceFile: SourceFile): Node[] { - const keywords: Node[] = []; + return keywords; +} - pushKeywordIf(keywords, tryStatement.getFirstToken(), SyntaxKind.TryKeyword); +function getTryCatchFinallyOccurrences(tryStatement: TryStatement, sourceFile: SourceFile): Node[] { + const keywords: Node[] = []; - if (tryStatement.catchClause) { - pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), SyntaxKind.CatchKeyword); - } + pushKeywordIf(keywords, tryStatement.getFirstToken(), SyntaxKind.TryKeyword); - if (tryStatement.finallyBlock) { - const finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile)!; - pushKeywordIf(keywords, finallyKeyword, SyntaxKind.FinallyKeyword); - } + if (tryStatement.catchClause) { + pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), SyntaxKind.CatchKeyword); + } - return keywords; + if (tryStatement.finallyBlock) { + const finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile)!; + pushKeywordIf(keywords, finallyKeyword, SyntaxKind.FinallyKeyword); } - function getThrowOccurrences(throwStatement: ThrowStatement, sourceFile: SourceFile): Node[] | undefined { - const owner = getThrowStatementOwner(throwStatement); + return keywords; +} - if (!owner) { - return undefined; - } +function getThrowOccurrences(throwStatement: ThrowStatement, sourceFile: SourceFile): Node[] | undefined { + const owner = getThrowStatementOwner(throwStatement); + + if (!owner) { + return undefined; + } + + const keywords: Node[] = []; - const keywords: Node[] = []; + forEach(aggregateOwnedThrowStatements(owner), throwStatement => { + keywords.push(findChildOfKind(throwStatement, SyntaxKind.ThrowKeyword, sourceFile)!); + }); - forEach(aggregateOwnedThrowStatements(owner), throwStatement => { - keywords.push(findChildOfKind(throwStatement, 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 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)!); - }); - } + return keywords; +} - return keywords; +function getReturnOccurrences(returnStatement: ReturnStatement, sourceFile: SourceFile): Node[] | undefined { + const func = getContainingFunction(returnStatement) as FunctionLikeDeclaration; + if (!func) { + return undefined; } - function getReturnOccurrences(returnStatement: ReturnStatement, sourceFile: SourceFile): Node[] | undefined { - const func = getContainingFunction(returnStatement) as FunctionLikeDeclaration; - if (!func) { - return undefined; - } + const keywords: Node[] = []; + forEachReturnStatement(cast(func.body, isBlock), returnStatement => { + keywords.push(findChildOfKind(returnStatement, SyntaxKind.ReturnKeyword, sourceFile)!); + }); - const keywords: Node[] = []; - forEachReturnStatement(cast(func.body, isBlock), returnStatement => { - keywords.push(findChildOfKind(returnStatement, 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)!); + }); - // Include 'throw' statements that do not occur within a try block. - forEach(aggregateOwnedThrowStatements(func.body!), throwStatement => { - keywords.push(findChildOfKind(throwStatement, SyntaxKind.ThrowKeyword, sourceFile)!); - }); + return keywords; +} - return keywords; +function getAsyncAndAwaitOccurrences(node: Node): Node[] | undefined { + const func = getContainingFunction(node) as FunctionLikeDeclaration; + if (!func) { + return undefined; } - function getAsyncAndAwaitOccurrences(node: Node): Node[] | undefined { - const func = getContainingFunction(node) as FunctionLikeDeclaration; - if (!func) { - return undefined; - } + const keywords: Node[] = []; - const keywords: Node[] = []; - - if (func.modifiers) { - func.modifiers.forEach(modifier => { - pushKeywordIf(keywords, modifier, SyntaxKind.AsyncKeyword); - }); - } + if (func.modifiers) { + func.modifiers.forEach(modifier => { + pushKeywordIf(keywords, modifier, SyntaxKind.AsyncKeyword); + }); + } - forEachChild(func, child => { - traverseWithoutCrossingFunction(child, node => { - if (isAwaitExpression(node)) { - pushKeywordIf(keywords, node.getFirstToken(), SyntaxKind.AwaitKeyword); - } - }); + forEachChild(func, child => { + traverseWithoutCrossingFunction(child, node => { + if (isAwaitExpression(node)) { + pushKeywordIf(keywords, node.getFirstToken(), SyntaxKind.AwaitKeyword); + } }); + }); - return keywords; - } + return keywords; +} - function getYieldOccurrences(node: Node): Node[] | undefined { - const func = getContainingFunction(node) as FunctionDeclaration; - if (!func) { - return undefined; - } +function getYieldOccurrences(node: Node): Node[] | undefined { + const func = getContainingFunction(node) as FunctionDeclaration; + if (!func) { + return undefined; + } - const keywords: Node[] = []; + const keywords: Node[] = []; - forEachChild(func, child => { - traverseWithoutCrossingFunction(child, node => { - if (isYieldExpression(node)) { - pushKeywordIf(keywords, node.getFirstToken(), SyntaxKind.YieldKeyword); - } - }); + forEachChild(func, child => { + traverseWithoutCrossingFunction(child, node => { + if (isYieldExpression(node)) { + pushKeywordIf(keywords, node.getFirstToken(), SyntaxKind.YieldKeyword); + } }); + }); - return keywords; - } + return keywords; +} - // Do not cross function/class/interface/module/type boundaries. - function traverseWithoutCrossingFunction(node: Node, cb: (node: Node) => void) { - cb(node); - if (!isFunctionLike(node) && !isClassLike(node) && !isInterfaceDeclaration(node) && !isModuleDeclaration(node) && !isTypeAliasDeclaration(node) && !isTypeNode(node)) { - forEachChild(node, child => traverseWithoutCrossingFunction(child, cb)); - } +// Do not cross function/class/interface/module/type boundaries. +function traverseWithoutCrossingFunction(node: Node, cb: (node: Node) => void) { + cb(node); + if (!isFunctionLike(node) && !isClassLike(node) && !isInterfaceDeclaration(node) && !isModuleDeclaration(node) && !isTypeAliasDeclaration(node) && !isTypeNode(node)) { + forEachChild(node, child => traverseWithoutCrossingFunction(child, cb)); } +} - function getIfElseOccurrences(ifStatement: IfStatement, sourceFile: SourceFile): HighlightSpan[] { - const keywords = getIfElseKeywords(ifStatement, sourceFile); - const result: 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) { - const elseKeyword = keywords[i]; - const ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. - - let shouldCombineElseAndIf = true; - - // Avoid recalculating getStart() by iterating backwards. - for (let j = ifKeyword.getStart(sourceFile) - 1; j >= elseKeyword.end; j--) { - if (!isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(j))) { - shouldCombineElseAndIf = false; - break; - } - } +function getIfElseOccurrences(ifStatement: IfStatement, sourceFile: SourceFile): HighlightSpan[] { + const keywords = getIfElseKeywords(ifStatement, sourceFile); + const result: 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) { + const elseKeyword = keywords[i]; + const ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. - if (shouldCombineElseAndIf) { - result.push({ - fileName: sourceFile.fileName, - textSpan: createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end), - kind: HighlightSpanKind.reference - }); - i++; // skip the next keyword - continue; + let shouldCombineElseAndIf = true; + + // Avoid recalculating getStart() by iterating backwards. + for (let j = ifKeyword.getStart(sourceFile) - 1; j >= elseKeyword.end; j--) { + if (!isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(j))) { + shouldCombineElseAndIf = false; + break; } } - // Ordinary case: just highlight the keyword. - result.push(getHighlightSpanForNode(keywords[i], sourceFile)); + if (shouldCombineElseAndIf) { + result.push({ + fileName: sourceFile.fileName, + textSpan: createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end), + kind: HighlightSpanKind.reference + }); + i++; // skip the next keyword + continue; + } } - return result; + // Ordinary case: just highlight the keyword. + result.push(getHighlightSpanForNode(keywords[i], sourceFile)); } - function getIfElseKeywords(ifStatement: IfStatement, sourceFile: SourceFile): Node[] { - const keywords: Node[] = []; + return result; +} - // Traverse upwards through all parent if-statements linked by their else-branches. - while (isIfStatement(ifStatement.parent) && ifStatement.parent.elseStatement === ifStatement) { - ifStatement = ifStatement.parent; - } +function getIfElseKeywords(ifStatement: IfStatement, sourceFile: SourceFile): Node[] { + const keywords: Node[] = []; - // 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); + // Traverse upwards through all parent if-statements linked by their else-branches. + while (isIfStatement(ifStatement.parent) && ifStatement.parent.elseStatement === ifStatement) { + ifStatement = ifStatement.parent; + } - // 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)) { - break; - } - } + // 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); - if (!ifStatement.elseStatement || !isIfStatement(ifStatement.elseStatement)) { + // 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)) { break; } + } - ifStatement = ifStatement.elseStatement; + if (!ifStatement.elseStatement || !isIfStatement(ifStatement.elseStatement)) { + break; } - return keywords; + ifStatement = ifStatement.elseStatement; } - /** - * 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); - } + return keywords; +} + +/** + * 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); } diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index 27faadad16b08..0b08d7f6d2d26 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -1,35 +1,45 @@ +import { + sourceFileAffectingCompilerOptions, +} from "../compiler/commandLineParser"; import { arrayFrom, - CompilerOptions, createGetCanonicalFileName, - createLanguageServiceSourceFile, - CreateSourceFileOptions, - Debug, - ensureScriptKind, firstDefinedIterator, - forEachEntry, - getCompilerOptionValue, - getEmitScriptTarget, - getImpliedNodeFormatForFile, getOrUpdate, - getSetExternalModuleIndicator, hasProperty, identity, isArray, - IScriptSnapshot, - isDeclarationFileName, map, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { + CreateSourceFileOptions, + isDeclarationFileName, +} from "../compiler/parser"; +import { toPath } from "../compiler/path"; +import { getImpliedNodeFormatForFile } from "../compiler/program"; +import { tracing } from "../compiler/tracing"; +import { + CompilerOptions, MinimalResolutionCacheHost, Path, ResolutionMode, ScriptKind, ScriptTarget, SourceFile, - sourceFileAffectingCompilerOptions, - toPath, - tracing, +} from "../compiler/types"; +import { + ensureScriptKind, + forEachEntry, + getCompilerOptionValue, + getEmitScriptTarget, + getSetExternalModuleIndicator, +} from "../compiler/utilities"; +import { + createLanguageServiceSourceFile, updateLanguageServiceSourceFile, -} from "./_namespaces/ts"; +} from "./services"; +import { IScriptSnapshot } from "./types"; /** * The document registry represents a store of SourceFile objects that can be shared between diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index ffd9501b5db25..5fe61b8afae3c 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -1,65 +1,84 @@ +import { getSymbolId } from "../compiler/checkerUtilities"; import { - __String, - addToSeen, arrayIsEqualTo, - CancellationToken, - CompilerOptions, - consumesNodeCoreModules, createMultiMap, - Debug, emptyArray, findIndex, firstDefined, + GetCanonicalFileName, + mapDefined, + startsWith, + stringContains, + tryCast, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { + isExportAssignment, + isExportSpecifier, + isIdentifier, +} from "../compiler/factory/nodeTests"; +import { + getPackageNameFromTypesPackageName, + nodeModulesPathPart, + unmangleScopedPackageName, +} from "../compiler/moduleNameResolver"; +import { forEachFileNameOfModule } from "../compiler/moduleSpecifiers"; +import { forEachAncestorDirectory, - forEachEntry, getBaseFileName, - GetCanonicalFileName, getDirectoryPath, +} from "../compiler/path"; +import { timestamp } from "../compiler/performanceCore"; +import { + __String, + CancellationToken, + CompilerOptions, + InternalSymbolName, + ModuleSpecifierCache, + ModuleSpecifierResolutionHost, + Path, + Program, + SourceFile, + Statement, + Symbol, + SymbolFlags, + TypeChecker, + UserPreferences, +} from "../compiler/types"; +import { + addToSeen, + forEachEntry, getLocalSymbolForExportDefault, - getNameForExportedSymbol, - getNamesForExportedSymbol, getNodeModulePathParts, - getPackageNameFromTypesPackageName, getPatternFromSpec, getRegexFromPattern, - getSymbolId, hostGetCanonicalFileName, hostUsesCaseSensitiveFileNames, - InternalSymbolName, - isExportAssignment, - isExportSpecifier, - isExternalModuleNameRelative, - isExternalModuleSymbol, isExternalOrCommonJsModule, - isIdentifier, isKnownSymbol, isNonGlobalAmbientModule, isPrivateIdentifierSymbol, - LanguageServiceHost, - mapDefined, - ModuleSpecifierCache, - ModuleSpecifierResolutionHost, - moduleSpecifiers, - nodeModulesPathPart, - PackageJsonImportFilter, - Path, - Program, skipAlias, skipOuterExpressions, - SourceFile, - startsWith, - Statement, - stringContains, stripQuotes, - Symbol, - SymbolFlags, - timestamp, - tryCast, - TypeChecker, +} from "../compiler/utilities"; +import { + isExternalModuleNameRelative, unescapeLeadingUnderscores, - unmangleScopedPackageName, - UserPreferences, -} from "./_namespaces/ts"; +} from "../compiler/utilitiesPublic"; +import { + ExportInfoMap, + ExportKind, + LanguageServiceHost, + SymbolExportInfo, +} from "./types"; +import { + consumesNodeCoreModules, + getNameForExportedSymbol, + getNamesForExportedSymbol, + isExternalModuleSymbol, + PackageJsonImportFilter, +} from "./utilities"; /** @internal */ export const enum ImportKind { @@ -69,26 +88,6 @@ export const enum ImportKind { CommonJS, } -/** @internal */ -export const enum ExportKind { - Named, - Default, - ExportEquals, - UMD, -} - -/** @internal */ -export interface SymbolExportInfo { - readonly symbol: Symbol; - readonly moduleSymbol: Symbol; - /** Set if `moduleSymbol` is an external module, not an ambient module */ - moduleFileName: string | undefined; - exportKind: ExportKind; - targetFlags: SymbolFlags; - /** True if export was only found via the package.json AutoImportProvider (for telemetry). */ - isFromPackageJson: boolean; -} - interface CachedSymbolExportInfo { // Used to rehydrate `symbol` and `moduleSymbol` when transient id: number; @@ -108,19 +107,6 @@ interface CachedSymbolExportInfo { isFromPackageJson: boolean; } -/** @internal */ -export interface ExportInfoMap { - isUsableByFile(importingFile: 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) => T | undefined): T | undefined; - releaseSymbols(): void; - isEmpty(): boolean; - /** @returns Whether the change resulted in the cache being cleared */ - onFileChanged(oldSourceFile: SourceFile, newSourceFile: SourceFile, typeAcquisitionEnabled: boolean): boolean; -} - /** @internal */ export interface CacheableExportInfoMapHost { getCurrentProgram(): Program | undefined; @@ -366,7 +352,7 @@ export function isImportableFile( const getCanonicalFileName = hostGetCanonicalFileName(moduleSpecifierResolutionHost); const globalTypingsCache = moduleSpecifierResolutionHost.getGlobalTypingsCacheLocation?.(); - const hasImportablePath = !!moduleSpecifiers.forEachFileNameOfModule( + const hasImportablePath = !!forEachFileNameOfModule( from.fileName, to.fileName, moduleSpecifierResolutionHost, diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 6e9a5570306be..d5f5906421aac 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1,194 +1,111 @@ import { - __String, - addToSeen, + getNodeId, + getSymbolId, +} from "../compiler/checkerUtilities"; +import { append, - AssignmentDeclarationKind, - BinaryExpression, - BindingElement, - Block, - CallExpression, - CancellationToken, cast, - CheckFlags, - ClassLikeDeclaration, - climbPastPropertyAccess, compareValues, - ConstructorDeclaration, contains, createQueue, - createTextSpan, - createTextSpanFromBounds, - createTextSpanFromRange, - Debug, - Declaration, - displayPart, - DocumentSpan, emptyArray, - emptyOptions, - escapeLeadingUnderscores, - ExportSpecifier, - Expression, - FileIncludeReason, - FileReference, filter, find, - findAncestor, - findChildOfKind, findIndex, first, firstDefined, firstOrUndefined, flatMap, - forEachChild, - forEachReturnStatement, - ForInOrOfStatement, - FunctionDeclaration, - FunctionExpression, - FunctionLikeDeclaration, - GetAccessorDeclaration, - getAdjustedReferenceLocation, - getAdjustedRenameLocation, - getAllSuperTypeNodes, - getAncestor, - getAssignmentDeclarationKind, - getCheckFlags, - getContainerNode, - getContainingObjectLiteralElement, - getContextualTypeFromParentOrAncestorTypeNode, - getDeclarationFromName, - getDeclarationOfKind, - getEffectiveModifierFlags, - getLocalSymbolForExportDefault, - getMeaningFromDeclaration, - getMeaningFromLocation, - getModeForUsageLocation, - getNameOfDeclaration, - getNameTable, - getNextJSDocCommentLocation, - getNodeId, - getNodeKind, - getPropertySymbolFromBindingElement, - getPropertySymbolsFromContextualType, - getReferencedFileLocation, - getSuperContainer, - getSymbolId, - getSyntacticModifierFlags, - getTargetLabel, - getTextOfNode, - getThisContainer, - getTouchingPropertyName, - GoToDefinition, - hasEffectiveModifier, - hasInitializer, - hasSyntacticModifier, - hasType, - HighlightSpan, - HighlightSpanKind, - Identifier, - ImplementationLocation, - InterfaceDeclaration, - InternalSymbolName, - isAccessExpression, - isArrayLiteralOrObjectLiteralDestructuringPattern, - isAssertionExpression, + map, + mapDefined, + MultiMap, + some, + tryAddToSet, + tryCast, +} from "../compiler/core"; +import { Push } from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { isBinaryExpression, - isBindableObjectDefinePropertyCall, isBindingElement, - isBreakOrContinueStatement, isCallExpression, - isCallExpressionTarget, isCatchClause, - isClassLike, isClassStaticBlockDeclaration, isComputedPropertyName, isConstructorDeclaration, - isDeclaration, - isDeclarationName, isExportAssignment, isExportSpecifier, - isExpressionOfExternalModuleImportEqualsDeclaration, - isExpressionStatement, isExpressionWithTypeArguments, - isExternalModule, - isExternalModuleSymbol, - isExternalOrCommonJsModule, - isForInOrOfStatement, isFunctionExpression, - isFunctionLike, - isFunctionLikeDeclaration, isIdentifier, - isIdentifierPart, - isImportMeta, - isImportOrExportSpecifier, isImportSpecifier, isImportTypeNode, - isInJSFile, - isInNonReferenceComment, - isInString, isInterfaceDeclaration, isJSDocMemberName, - isJSDocTag, isJsxClosingElement, isJsxOpeningElement, isJsxSelfClosingElement, - isJumpStatementTarget, isLabeledStatement, - isLabelOfLabeledStatement, - isLiteralComputedPropertyDeclarationName, - isLiteralNameOfPropertyDeclarationOrIndexAccess, isLiteralTypeNode, - isMethodOrAccessor, isModuleDeclaration, - isModuleExportsAccessExpression, - isModuleOrEnumDeclaration, - isModuleSpecifierLike, - isNameOfModuleDeclaration, isNamespaceExportDeclaration, - isNewExpressionTarget, isNoSubstitutionTemplateLiteral, - isObjectBindingElementWithoutPropertyName, isObjectLiteralExpression, - isObjectLiteralMethod, isParameter, - isParameterPropertyDeclaration, - isPrivateIdentifierClassElementDeclaration, isPropertyAccessExpression, isQualifiedName, - isReferencedFile, - isReferenceFileLocation, - isRightSideOfPropertyAccess, isShorthandPropertyAssignment, isSourceFile, - isStatement, - isStatic, isStaticModifier, - isStringLiteralLike, - isSuperProperty, - isThis, isTypeAliasDeclaration, - isTypeElement, - isTypeKeyword, isTypeLiteralNode, - isTypeNode, isTypeOperatorNode, isUnionTypeNode, - isVariableDeclarationInitializedToBareOrAccessedRequire, - isVariableDeclarationList, - isVariableLike, - isVariableStatement, isVoidExpression, - isWriteAccess, +} from "../compiler/factory/nodeTests"; +import { + forEachChild, + isExternalModule, +} from "../compiler/parser"; +import { + getModeForUsageLocation, + getReferencedFileLocation, + isReferencedFile, + isReferenceFileLocation, +} from "../compiler/program"; +import { + isIdentifierPart, + tokenToString, +} from "../compiler/scanner"; +import { + __String, + AssignmentDeclarationKind, + BindingElement, + Block, + CallExpression, + CancellationToken, + CheckFlags, + ClassLikeDeclaration, + ConstructorDeclaration, + Declaration, + ExportSpecifier, + Expression, + FileIncludeReason, + FileReference, + FunctionDeclaration, + FunctionExpression, + FunctionLikeDeclaration, + GetAccessorDeclaration, + Identifier, + InterfaceDeclaration, + InternalSymbolName, JSDocTag, - map, - mapDefined, MethodDeclaration, ModifierFlags, ModuleDeclaration, - MultiMap, NamedDeclaration, Node, NodeFlags, - nodeSeenTracker, NumericLiteral, ParameterDeclaration, ParenthesizedExpression, @@ -198,44 +115,85 @@ import { PropertyAccessExpression, PropertyAssignment, PropertyDeclaration, - punctuationPart, - Push, - rangeIsOnSingleLine, - ReferencedSymbol, - ReferencedSymbolDefinitionInfo, - ReferencedSymbolEntry, - ReferenceEntry, - RenameLocation, - ScriptElementKind, ScriptTarget, - SemanticMeaning, SetAccessorDeclaration, SignatureDeclaration, - skipAlias, - some, SourceFile, Statement, StringLiteral, StringLiteralLike, - stripQuotes, Symbol, - SymbolDisplay, - SymbolDisplayPart, - SymbolDisplayPartKind, SymbolFlags, SymbolId, - symbolName, SyntaxKind, - textPart, TextSpan, - tokenToString, - tryAddToSet, - tryCast, - tryGetClassExtendingExpressionWithTypeArguments, - tryGetImportFromModuleSpecifier, TypeChecker, VariableDeclaration, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + addToSeen, + forEachReturnStatement, + getAllSuperTypeNodes, + getAncestor, + getAssignmentDeclarationKind, + getCheckFlags, + getDeclarationFromName, + getDeclarationOfKind, + getEffectiveModifierFlags, + getLocalSymbolForExportDefault, + getNextJSDocCommentLocation, + getSuperContainer, + getSyntacticModifierFlags, + getTextOfNode, + getThisContainer, + hasEffectiveModifier, + hasSyntacticModifier, + isAccessExpression, + isBindableObjectDefinePropertyCall, + isDeclarationName, + isExternalOrCommonJsModule, + isImportMeta, + isInJSFile, + isLiteralComputedPropertyDeclarationName, + isModuleExportsAccessExpression, + isObjectLiteralMethod, + isStatic, + isSuperProperty, + isVariableDeclarationInitializedToBareOrAccessedRequire, + isVariableLike, + isWriteAccess, + rangeIsOnSingleLine, + skipAlias, + stripQuotes, + tryGetClassExtendingExpressionWithTypeArguments, + tryGetImportFromModuleSpecifier, +} from "../compiler/utilities"; +import { + createTextSpan, + escapeLeadingUnderscores, + findAncestor, + getNameOfDeclaration, + hasInitializer, + hasType, + isAssertionExpression, + isBreakOrContinueStatement, + isClassLike, + isDeclaration, + isFunctionLike, + isFunctionLikeDeclaration, + isImportOrExportSpecifier, + isJSDocTag, + isMethodOrAccessor, + isModuleOrEnumDeclaration, + isParameterPropertyDeclaration, + isPrivateIdentifierClassElementDeclaration, + isStatement, + isStringLiteralLike, + isTypeElement, + isTypeNode, + symbolName, +} from "../compiler/utilitiesPublic"; +import { getReferenceAtPosition } from "./goToDefinition"; import { createImportTracker, ExportInfo, @@ -247,7 +205,77 @@ import { ImportsResult, ImportTracker, ModuleReference, -} from "./_namespaces/ts.FindAllReferences"; +} from "./importTracker"; +import { + getContainingObjectLiteralElement, + getNameTable, + getPropertySymbolsFromContextualType, +} from "./services"; +import { + getSymbolDisplayPartsDocumentationAndSymbolKind, +} from "./symbolDisplay"; +import { + ContextNode, + ContextWithStartAndEndNode, + DocumentSpan, + emptyOptions, + Entry, + EntryKind, + HighlightSpan, + HighlightSpanKind, + ImplementationLocation, + NodeEntry, + NodeEntryKind, + ReferencedSymbol, + ReferencedSymbolDefinitionInfo, + ReferencedSymbolEntry, + ReferenceEntry, + RenameLocation, + ScriptElementKind, + SpanEntry, + SymbolDisplayPart, + SymbolDisplayPartKind, +} from "./types"; +import { + climbPastPropertyAccess, + createTextSpanFromRange, + displayPart, + findChildOfKind, + getAdjustedReferenceLocation, + getAdjustedRenameLocation, + getContainerNode, + getContextNode, + getContextualTypeFromParentOrAncestorTypeNode, + getMeaningFromDeclaration, + getMeaningFromLocation, + getNodeKind, + getPropertySymbolFromBindingElement, + getTargetLabel, + getTextSpan, + getTextSpanOfEntry, + getTouchingPropertyName, + isArrayLiteralOrObjectLiteralDestructuringPattern, + isCallExpressionTarget, + isExpressionOfExternalModuleImportEqualsDeclaration, + isExternalModuleSymbol, + isInNonReferenceComment, + isInString, + isJumpStatementTarget, + isLabelOfLabeledStatement, + isLiteralNameOfPropertyDeclarationOrIndexAccess, + isModuleSpecifierLike, + isNameOfModuleDeclaration, + isNewExpressionTarget, + isObjectBindingElementWithoutPropertyName, + isRightSideOfPropertyAccess, + isThis, + isTypeKeyword, + nodeSeenTracker, + punctuationPart, + SemanticMeaning, + textPart, + toContextSpan, +} from "./utilities"; /** @internal */ export interface SymbolAndEntries { @@ -266,31 +294,6 @@ export type Definition = | { readonly type: DefinitionKind.String; readonly node: StringLiteralLike } | { readonly type: DefinitionKind.TripleSlashReference; readonly reference: FileReference, readonly file: SourceFile }; -/** @internal */ -export const enum EntryKind { Span, Node, StringLiteral, SearchedLocalFoundProperty, SearchedPropertyFoundLocal } -/** @internal */ -export type NodeEntryKind = EntryKind.Node | EntryKind.StringLiteral | EntryKind.SearchedLocalFoundProperty | EntryKind.SearchedPropertyFoundLocal; -/** @internal */ -export type Entry = NodeEntry | SpanEntry; -/** @internal */ -export interface ContextWithStartAndEndNode { - start: Node; - end: Node; -} -/** @internal */ -export type ContextNode = Node | ContextWithStartAndEndNode; -/** @internal */ -export interface NodeEntry { - readonly kind: NodeEntryKind; - readonly node: Node; - readonly context?: ContextNode; -} -/** @internal */ -export interface SpanEntry { - readonly kind: EntryKind.Span; - readonly fileName: string; - readonly textSpan: TextSpan; -} /** @internal */ export function nodeEntry(node: Node, kind: NodeEntryKind = EntryKind.Node): NodeEntry { return { @@ -300,10 +303,6 @@ export function nodeEntry(node: Node, kind: NodeEntryKind = EntryKind.Node): Nod }; } -/** @internal */ -export function isContextWithStartAndEndNode(node: ContextNode): node is ContextWithStartAndEndNode { - return node && (node as Node).kind === undefined; -} function getContextNodeForNodeEntry(node: Node): ContextNode | undefined { if (isDeclaration(node)) { @@ -371,71 +370,6 @@ function getContextNodeForNodeEntry(node: Node): ContextNode | undefined { return undefined; } -/** @internal */ -export function getContextNode(node: NamedDeclaration | BinaryExpression | ForInOrOfStatement | undefined): ContextNode | undefined { - if (!node) return undefined; - switch (node.kind) { - case SyntaxKind.VariableDeclaration: - return !isVariableDeclarationList(node.parent) || node.parent.declarations.length !== 1 ? - node : - isVariableStatement(node.parent.parent) ? - node.parent.parent : - isForInOrOfStatement(node.parent.parent) ? - getContextNode(node.parent.parent) : - node.parent; - - case SyntaxKind.BindingElement: - return getContextNode(node.parent.parent as NamedDeclaration); - - case SyntaxKind.ImportSpecifier: - return node.parent.parent.parent; - - case SyntaxKind.ExportSpecifier: - case SyntaxKind.NamespaceImport: - return node.parent.parent; - - case SyntaxKind.ImportClause: - case SyntaxKind.NamespaceExport: - return node.parent; - - case SyntaxKind.BinaryExpression: - return isExpressionStatement(node.parent) ? - node.parent : - node; - - case SyntaxKind.ForOfStatement: - case SyntaxKind.ForInStatement: - return { - start: (node as ForInOrOfStatement).initializer, - end: (node as ForInOrOfStatement).expression - }; - - case SyntaxKind.PropertyAssignment: - case SyntaxKind.ShorthandPropertyAssignment: - return isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent) ? - getContextNode( - findAncestor(node.parent, node => - isBinaryExpression(node) || isForInOrOfStatement(node) - ) as BinaryExpression | ForInOrOfStatement - ) : - node; - - default: - return node; - } -} - -/** @internal */ -export function toContextSpan(textSpan: TextSpan, sourceFile: SourceFile, context?: ContextNode): { contextSpan: TextSpan } | undefined { - if (!context) return undefined; - const contextSpan = isContextWithStartAndEndNode(context) ? - getTextSpan(context.start, sourceFile, context.end) : - getTextSpan(context, sourceFile); - return contextSpan.start !== textSpan.start || contextSpan.length !== textSpan.length ? - { contextSpan } : - undefined; -} - /** @internal */ export const enum FindReferencesUse { /** @@ -608,7 +542,7 @@ function definitionToReferencedSymbolDefinitionInfo(def: Definition, checker: Ty case DefinitionKind.This: { const { node } = def; const symbol = checker.getSymbolAtLocation(node); - const displayParts = symbol && SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind( + const displayParts = symbol && getSymbolDisplayPartsDocumentationAndSymbolKind( checker, symbol, node.getSourceFile(), getContainerNode(node), node).displayParts || [textPart("this")]; return { ...getFileAndTextSpanFromNode(node), name: "this", kind: ScriptElementKind.variableElement, displayParts }; } @@ -660,7 +594,7 @@ function getDefinitionKindAndDisplayParts(symbol: Symbol, checker: TypeChecker, 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); + getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, enclosingDeclaration.getSourceFile(), enclosingDeclaration, enclosingDeclaration, meaning); return { displayParts, kind: symbolKind }; } @@ -814,23 +748,6 @@ export function toHighlightSpan(entry: Entry): { fileName: string, span: Highlig return { fileName: documentSpan.fileName, span }; } -function getTextSpan(node: Node, sourceFile: SourceFile, endNode?: Node): TextSpan { - let start = node.getStart(sourceFile); - let end = (endNode || node).getEnd(); - if (isStringLiteralLike(node) && (end - start) > 2) { - Debug.assert(endNode === undefined); - start += 1; - end -= 1; - } - return createTextSpanFromBounds(start, end); -} - -/** @internal */ -export function getTextSpanOfEntry(entry: Entry) { - return entry.kind === EntryKind.Span ? entry.textSpan : - getTextSpan(entry.node, entry.node.getSourceFile()); -} - /** 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); @@ -924,7 +841,7 @@ export namespace Core { 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 { node = getAdjustedNode(node, options); if (isSourceFile(node)) { - const resolvedRef = GoToDefinition.getReferenceAtPosition(node, position, program); + const resolvedRef = getReferenceAtPosition(node, position, program); if (!resolvedRef?.file) { return undefined; } diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index ae84a63ecfbcc..53d8f615892ee 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -1,117 +1,97 @@ +import { + find, + findIndex, + forEachRight, + isLineBreak, + isWhiteSpaceSingleLine, + last, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { isDecorator } from "../../compiler/factory/nodeTests"; +import { canHaveModifiers } from "../../compiler/factory/utilitiesPublic"; +import { forEachChild } from "../../compiler/parser"; import { Block, CallExpression, - canHaveModifiers, CatchClause, CharacterCodes, ClassDeclaration, - CommentRange, - concatenate, - createTextChangeFromStartLength, - Debug, Declaration, Diagnostic, - EditorSettings, - find, - findAncestor, - findIndex, - findPrecedingToken, - forEachChild, - forEachRight, - FormatCodeSettings, - FormattingHost, FunctionDeclaration, - getEndLinePosition, - getLeadingCommentRangesOfNode, - getLineStartPositionForPosition, - getNameOfDeclaration, - getNewLineOrDefaultFromHost, - getNonDecoratorTokenPosOfNode, - getStartPositionOfLine, - getTokenAtPosition, - getTrailingCommentRanges, - hasDecorators, InterfaceDeclaration, - isComment, - isDecorator, - isJSDoc, - isLineBreak, - isModifier, - isNodeArray, - isStringOrRegularExpressionOrTemplateLiteral, - isToken, - isWhiteSpaceSingleLine, LanguageVariant, - last, LineAndCharacter, MethodDeclaration, ModuleDeclaration, Node, NodeArray, + SourceFile, + SourceFileLike, + SyntaxKind, + TextRange, + TypeReferenceNode, +} from "../../compiler/types"; +import { + getEndLinePosition, + getNonDecoratorTokenPosOfNode, + getStartPositionOfLine, + hasDecorators, nodeIsMissing, nodeIsSynthesized, - rangeContainsPositionExclusive, +} from "../../compiler/utilities"; +import { + getNameOfDeclaration, + isModifier, + isNodeArray, + isToken, +} from "../../compiler/utilitiesPublic"; +import { + EditorSettings, + FormatCodeSettings, + FormatContext, + FormattingHost, + TextChange, + TextRangeWithKind, + TokenInfo, +} from "../types"; +import { + createTextChangeFromStartLength, + findPrecedingToken, + getLineStartPositionForPosition, + getNewLineOrDefaultFromHost, + isComment, + isStringOrRegularExpressionOrTemplateLiteral, rangeContainsRange, rangeContainsStartEnd, rangeOverlapsWithStartEnd, repeatString, - SourceFile, - SourceFileLike, startEndContainsRange, startEndOverlapsWithStartEnd, - SyntaxKind, - TextChange, - TextRange, - TriviaSyntaxKind, - TypeReferenceNode, -} from "../_namespaces/ts"; +} from "../utilities"; import { FormattingContext, FormattingRequestKind, +} from "./formattingContext"; +import { FormattingScanner, getFormattingScanner, +} from "./formattingScanner"; +import { Rule, RuleAction, RuleFlags, - RulesMap, - SmartIndenter, -} from "../_namespaces/ts.formatting"; - -/** @internal */ -export interface FormatContext { - readonly options: FormatCodeSettings; - readonly getRules: RulesMap; - readonly host: FormattingHost; -} - -/** @internal */ -export interface TextRangeWithKind extends TextRange { - kind: T; -} +} from "./rule"; +import { getRulesMap } from "./rulesMap"; +import { SmartIndenter } from "./smartIndenter"; -/** @internal */ -export type TextRangeWithTriviaKind = TextRangeWithKind; - -/** @internal */ -export interface TokenInfo { - leadingTrivia: TextRangeWithTriviaKind[] | undefined; - token: TextRangeWithKind; - trailingTrivia: TextRangeWithTriviaKind[] | undefined; +const enum Constants { + Unknown = -1 } /** @internal */ -export function createTextRangeWithKind(pos: number, end: number, kind: T): TextRangeWithKind { - const textRangeWithKind: TextRangeWithKind = { pos, end, kind }; - if (Debug.isDebugging) { - Object.defineProperty(textRangeWithKind, "__debugKind", { - get: () => Debug.formatSyntaxKind(kind), - }); - } - return textRangeWithKind; -} - -const enum Constants { - Unknown = -1 +export function getFormatContext(options: FormatCodeSettings, host: FormattingHost): FormatContext { + return { options, getRules: getRulesMap(), host }; } /* @@ -489,7 +469,6 @@ function formatSpanWorker( requestKind: FormattingRequestKind, rangeContainsError: (r: TextRange) => boolean, sourceFile: SourceFileLike): TextChange[] { - // formatting context is used by rules provider const formattingContext = new FormattingContext(sourceFile, requestKind, options); let previousRangeTriviaEnd: number; @@ -1377,48 +1356,6 @@ function formatSpanWorker( const enum LineAction { None, LineAdded, LineRemoved } -/** - * - * @internal - */ -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; - 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; - - // 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) || - // 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): - // - // // asdf ^\n - // - // But for closed multi-line comments, we don't want to be inside the comment in the following case: - // - // /* asdf */^ - // - // However, unterminated multi-line comments *do* contain their end. - // - // Internally, we represent the end of the comment at the newline and closing '/', respectively. - // - position === range.end && (range.kind === SyntaxKind.SingleLineCommentTrivia || position === sourceFile.getFullWidth())); -} - function getOpenTokenForList(node: Node, list: readonly Node[]) { switch (node.kind) { case SyntaxKind.Constructor: diff --git a/src/services/formatting/formattingContext.ts b/src/services/formatting/formattingContext.ts index 511246c7d899f..566dd3ba8ff12 100644 --- a/src/services/formatting/formattingContext.ts +++ b/src/services/formatting/formattingContext.ts @@ -1,12 +1,14 @@ -import { TextRangeWithKind } from "../_namespaces/ts.formatting"; +import { Debug } from "../../compiler/debug"; import { - Debug, - findChildOfKind, - FormatCodeSettings, Node, SourceFileLike, SyntaxKind, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + FormatCodeSettings, + TextRangeWithKind, +} from "../types"; +import { findChildOfKind } from "../utilities"; /** @internal */ export const enum FormattingRequestKind { diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index 5d29e814ce807..fccb55a8edd3a 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -1,26 +1,32 @@ import { append, - createScanner, - Debug, + last, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { isJsxAttribute, isJsxElement, isJsxText, - isKeyword, - isToken, - isTrivia, +} from "../../compiler/factory/nodeTests"; +import { createScanner } from "../../compiler/scanner"; +import { LanguageVariant, - last, Node, NodeArray, ScriptTarget, SyntaxKind, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + isKeyword, + isTrivia, +} from "../../compiler/utilities"; +import { isToken } from "../../compiler/utilitiesPublic"; import { - createTextRangeWithKind, TextRangeWithKind, TextRangeWithTriviaKind, TokenInfo, -} from "../_namespaces/ts.formatting"; +} from "../types"; +import { createTextRangeWithKind } from "../utilities"; const standardScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard); const jsxScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.JSX); diff --git a/src/services/formatting/rule.ts b/src/services/formatting/rule.ts index b474c67969f6c..6fdf99278d214 100644 --- a/src/services/formatting/rule.ts +++ b/src/services/formatting/rule.ts @@ -1,8 +1,6 @@ -import { FormattingContext } from "../_namespaces/ts.formatting"; -import { - emptyArray, - SyntaxKind, -} from "../_namespaces/ts"; +import { emptyArray } from "../../compiler/core"; +import { SyntaxKind } from "../../compiler/types"; +import { FormattingContext } from "./formattingContext"; /** @internal */ export interface Rule { diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index fc7a3a0b28a74..e8f8533d7ecf0 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -1,37 +1,51 @@ import { - anyContext, - ContextPredicate, - FormattingContext, - FormattingRequestKind, - Rule, - RuleAction, - RuleFlags, - TextRangeWithKind, - TokenRange, -} from "../_namespaces/ts.formatting"; -import { - BinaryExpression, contains, - findAncestor, - findNextToken, - FormatCodeSettings, - hasDecorators, hasProperty, isArray, - isExpression, - isFunctionLikeKind, +} from "../../compiler/core"; +import { isNumericLiteral, isPropertyAccessExpression, isPropertyDeclaration, isPropertySignature, - isTrivia, +} from "../../compiler/factory/nodeTests"; +import { + BinaryExpression, Node, - positionIsASICandidate, - SemicolonPreference, SyntaxKind, - typeKeywords, YieldExpression, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + hasDecorators, + isTrivia, +} from "../../compiler/utilities"; +import { + findAncestor, + isExpression, + isFunctionLikeKind, +} from "../../compiler/utilitiesPublic"; +import { + FormatCodeSettings, + SemicolonPreference, + TextRangeWithKind, +} from "../types"; +import { + findNextToken, + positionIsASICandidate, + typeKeywords, +} from "../utilities"; +import { + FormattingContext, + FormattingRequestKind, +} from "./formattingContext"; +import { + anyContext, + ContextPredicate, + Rule, + RuleAction, + RuleFlags, + TokenRange, +} from "./rule"; /** @internal */ export interface RuleSpec { diff --git a/src/services/formatting/rulesMap.ts b/src/services/formatting/rulesMap.ts index 8970be77c18a5..ea51325686fd3 100644 --- a/src/services/formatting/rulesMap.ts +++ b/src/services/formatting/rulesMap.ts @@ -1,28 +1,24 @@ -import { - Debug, - every, - FormatCodeSettings, - FormattingHost, - SyntaxKind, -} from "../_namespaces/ts"; +import { every } from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { SyntaxKind } from "../../compiler/types"; +import { FormattingContext } from "./formattingContext"; import { anyContext, - FormatContext, - FormattingContext, - getAllRules, Rule, RuleAction, +} from "./rule"; +import { + getAllRules, RuleSpec, -} from "../_namespaces/ts.formatting"; +} from "./rules"; /** @internal */ -export function getFormatContext(options: FormatCodeSettings, host: FormattingHost): FormatContext { - return { options, getRules: getRulesMap(), host }; -} +export type RulesMap = (context: FormattingContext) => readonly Rule[] | undefined; let rulesMapCache: RulesMap | undefined; -function getRulesMap(): RulesMap { +/** @internal */ +export function getRulesMap(): RulesMap { if (rulesMapCache === undefined) { rulesMapCache = createRulesMap(getAllRules()); } @@ -50,8 +46,6 @@ function getRuleActionExclusion(ruleAction: RuleAction): RuleAction { return mask; } -/** @internal */ -export type RulesMap = (context: FormattingContext) => readonly Rule[] | undefined; function createRulesMap(rules: readonly RuleSpec[]): RulesMap { const map = buildMap(rules); return context => { diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index b48051e8a651d..b2d6618118dbf 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -1,3 +1,18 @@ +import { + contains, + find, + isWhiteSpaceLike, + isWhiteSpaceSingleLine, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { + isCallExpression, + isConditionalExpression, +} from "../../compiler/factory/nodeTests"; +import { + getLineAndCharacterOfPosition, + skipTrivia, +} from "../../compiler/scanner"; import { ArrayBindingPattern, ArrayLiteralExpression, @@ -6,32 +21,10 @@ import { ClassDeclaration, ClassExpression, CommentRange, - contains, - Debug, - EditorSettings, - find, - findChildOfKind, - findListItemInfo, - findNextToken, - findPrecedingToken, - FormatCodeSettings, GetAccessorDeclaration, - getLineAndCharacterOfPosition, - getLineStartPositionForPosition, - getStartPositionOfLine, - getTokenAtPosition, IfStatement, ImportClause, - IndentStyle, InterfaceDeclaration, - isCallExpression, - isCallOrNewExpression, - isConditionalExpression, - isDeclaration, - isStatementButNotDeclaration, - isStringOrRegularExpressionOrTemplateLiteral, - isWhiteSpaceLike, - isWhiteSpaceSingleLine, JSDocTemplateTag, LineAndCharacter, NamedImportsOrExports, @@ -39,11 +32,7 @@ import { NodeArray, ObjectBindingPattern, ObjectLiteralExpression, - positionBelongsToNode, - rangeContainsRange, - rangeContainsStartEnd, SignatureDeclaration, - skipTrivia, SourceFile, SourceFileLike, SyntaxKind, @@ -52,15 +41,35 @@ import { TypeLiteralNode, TypeReferenceNode, VariableDeclarationList, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { getStartPositionOfLine } from "../../compiler/utilities"; import { - getRangeOfEnclosingComment, + isCallOrNewExpression, + isDeclaration, + isStatementButNotDeclaration, +} from "../../compiler/utilitiesPublic"; +import { + EditorSettings, + FormatCodeSettings, + IndentStyle, TextRangeWithKind, -} from "../_namespaces/ts.formatting"; +} from "../types"; +import { + findChildOfKind, + findListItemInfo, + findNextToken, + findPrecedingToken, + getLineStartPositionForPosition, + getRangeOfEnclosingComment, + getTokenAtPosition, + isStringOrRegularExpressionOrTemplateLiteral, + positionBelongsToNode, + rangeContainsRange, + rangeContainsStartEnd, +} from "../utilities"; /** @internal */ export namespace SmartIndenter { - const enum Value { Unknown = -1 } diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index e8c7f4c2bd140..2751c7005c804 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -1,56 +1,66 @@ +import { getOptionFromName } from "../compiler/commandLineParser"; import { - combinePaths, createGetCanonicalFileName, - createModuleSpecifierResolutionHost, - createRange, - Debug, emptyArray, endsWith, - ensurePathIsNonModuleName, - Expression, - factory, - FileTextChanges, find, forEach, - formatting, GetCanonicalFileName, - getDirectoryPath, - getFileMatcherPatterns, - getModeForUsageLocation, - getOptionFromName, - getRegexFromPattern, - getRelativePathFromDirectory, - getRelativePathFromFile, - getTsConfigObjectLiteralExpression, - hostUsesCaseSensitiveFileNames, - isAmbientModule, + last, + mapDefined, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { factory } from "../compiler/factory/nodeFactory"; +import { isArrayLiteralExpression, isObjectLiteralExpression, isPropertyAssignment, isSourceFile, isStringLiteral, - LanguageServiceHost, - last, - mapDefined, - ModuleResolutionHost, - moduleSpecifiers, +} from "../compiler/factory/nodeTests"; +import { resolveModuleName } from "../compiler/moduleNameResolver"; +import { updateModuleSpecifier } from "../compiler/moduleSpecifiers"; +import { + combinePaths, + ensurePathIsNonModuleName, + getDirectoryPath, + getRelativePathFromDirectory, + getRelativePathFromFile, normalizePath, - Path, pathIsRelative, +} from "../compiler/path"; +import { getModeForUsageLocation } from "../compiler/program"; +import { + Expression, + ModuleResolutionHost, + Path, Program, PropertyAssignment, ResolvedModuleWithFailedLookupLocations, - resolveModuleName, SourceFile, SourceFileLike, - SourceMapper, StringLiteralLike, Symbol, - textChanges, TextRange, - tryRemoveDirectoryPrefix, UserPreferences, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + createRange, + getFileMatcherPatterns, + getRegexFromPattern, + getTsConfigObjectLiteralExpression, + hostUsesCaseSensitiveFileNames, + isAmbientModule, + tryRemoveDirectoryPrefix, +} from "../compiler/utilities"; +import { SourceMapper } from "./sourcemaps"; +import { ChangeTracker } from "./textChanges"; +import { + FileTextChanges, + FormatContext, + LanguageServiceHost, +} from "./types"; +import { createModuleSpecifierResolutionHost } from "./utilities"; /** @internal */ export function getEditsForFileRename( @@ -58,7 +68,7 @@ export function getEditsForFileRename( oldFileOrDirPath: string, newFileOrDirPath: string, host: LanguageServiceHost, - formatContext: formatting.FormatContext, + formatContext: FormatContext, preferences: UserPreferences, sourceMapper: SourceMapper, ): readonly FileTextChanges[] { @@ -66,7 +76,7 @@ export function getEditsForFileRename( const getCanonicalFileName = 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 ChangeTracker.with({ host, formatContext, preferences }, changeTracker => { updateTsconfigFiles(program, changeTracker, oldToNew, oldFileOrDirPath, newFileOrDirPath, host.getCurrentDirectory(), useCaseSensitiveFileNames); updateImports(program, changeTracker, oldToNew, newToOld, host, getCanonicalFileName); }); @@ -103,7 +113,7 @@ function makeCorrespondingRelativeChange(a0: string, b0: string, a1: string, get return combinePathsSafe(getDirectoryPath(a1), rel); } -function updateTsconfigFiles(program: Program, changeTracker: textChanges.ChangeTracker, oldToNew: PathUpdater, oldFileOrDirPath: string, newFileOrDirPath: string, currentDirectory: string, useCaseSensitiveFileNames: boolean): void { +function updateTsconfigFiles(program: Program, changeTracker: ChangeTracker, oldToNew: PathUpdater, oldFileOrDirPath: string, newFileOrDirPath: string, currentDirectory: string, useCaseSensitiveFileNames: boolean): void { const { configFile } = program.getCompilerOptions(); if (!configFile) return; const configDir = getDirectoryPath(configFile.fileName); @@ -175,7 +185,7 @@ function updateTsconfigFiles(program: Program, changeTracker: textChanges.Change function updateImports( program: Program, - changeTracker: textChanges.ChangeTracker, + changeTracker: ChangeTracker, oldToNew: PathUpdater, newToOld: PathUpdater, host: LanguageServiceHost, @@ -214,7 +224,7 @@ function updateImports( // 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) + ? updateModuleSpecifier(program.getCompilerOptions(), sourceFile, getCanonicalFileName(newImportFromPath) as Path, toImport.newFileName, createModuleSpecifierResolutionHost(program, host), importLiteral.text) : undefined; }); } @@ -292,7 +302,7 @@ function getSourceFileToImportFromResolved(importLiteral: StringLiteralLike, res } } -function updateImportsWorker(sourceFile: SourceFile, changeTracker: textChanges.ChangeTracker, updateRef: (refText: string) => string | undefined, updateImport: (importLiteral: StringLiteralLike) => string | undefined) { +function updateImportsWorker(sourceFile: SourceFile, changeTracker: ChangeTracker, updateRef: (refText: string) => string | undefined, updateImport: (importLiteral: StringLiteralLike) => string | undefined) { for (const ref of sourceFile.referencedFiles || 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); diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 47be1d6781c4f..02dbbba57ef87 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -1,102 +1,119 @@ import { - AssignmentDeclarationKind, - AssignmentExpression, - AssignmentOperatorToken, - CallLikeExpression, concatenate, - createTextSpan, - createTextSpanFromBounds, - createTextSpanFromNode, - createTextSpanFromRange, - Debug, - Declaration, - DefinitionInfo, - DefinitionInfoAndBoundSpan, emptyArray, every, - FileReference, filter, find, - FindAllReferences, - findAncestor, first, flatMap, forEach, - FunctionLikeDeclaration, - getAssignmentDeclarationKind, - getContainingObjectLiteralElement, - getDirectoryPath, - getEffectiveBaseTypeNode, - getInvokedExpression, - getModeForUsageLocation, - getNameFromPropertyName, - getNameOfDeclaration, - getPropertySymbolsFromContextualType, - getTargetLabel, - getTextOfPropertyName, - getTouchingPropertyName, - getTouchingToken, - hasEffectiveModifier, - hasInitializer, - hasStaticModifier, - isAnyImportOrBareOrAccessedRequire, - isAssignmentDeclaration, - isAssignmentExpression, + last, + map, + mapDefined, + some, + tryCast, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { isBindingElement, - isCallLikeExpression, - isCallOrNewExpressionTarget, - isClassElement, isClassExpression, - isClassLike, isClassStaticBlockDeclaration, isConstructorDeclaration, - isDeclarationFileName, - isExternalModuleNameRelative, - isFunctionLike, - isFunctionLikeDeclaration, isFunctionTypeNode, isIdentifier, - isImportMeta, isJSDocOverrideTag, - isJsxOpeningLikeElement, - isJumpStatementTarget, - isModuleSpecifierLike, - isNameOfFunctionDeclaration, - isNewExpressionTarget, isObjectBindingPattern, - isPropertyName, - isRightSideOfPropertyAccess, isStaticModifier, isVariableDeclaration, - last, - map, - mapDefined, +} from "../compiler/factory/nodeTests"; +import { isDeclarationFileName } from "../compiler/parser"; +import { + getDirectoryPath, + resolvePath, +} from "../compiler/path"; +import { getModeForUsageLocation } from "../compiler/program"; +import { skipTrivia } from "../compiler/scanner"; +import { + AssignmentDeclarationKind, + AssignmentExpression, + AssignmentOperatorToken, + CallLikeExpression, + Declaration, + FileReference, + FunctionLikeDeclaration, ModifierFlags, - moveRangePastModifiers, Node, NodeFlags, Program, - resolvePath, - ScriptElementKind, SignatureDeclaration, - skipAlias, - skipParentheses, - skipTrivia, - some, SourceFile, Symbol, - SymbolDisplay, SymbolFlags, SyntaxKind, - textRangeContainsPositionInclusive, TextSpan, - tryCast, - tryGetModuleSpecifierFromDeclaration, Type, TypeChecker, TypeFlags, +} from "../compiler/types"; +import { + getAssignmentDeclarationKind, + getEffectiveBaseTypeNode, + getInvokedExpression, + getTextOfPropertyName, + hasEffectiveModifier, + hasStaticModifier, + isAnyImportOrBareOrAccessedRequire, + isAssignmentDeclaration, + isAssignmentExpression, + isImportMeta, + moveRangePastModifiers, + skipAlias, + skipParentheses, + tryGetModuleSpecifierFromDeclaration, +} from "../compiler/utilities"; +import { + createTextSpan, + createTextSpanFromBounds, + findAncestor, + getNameOfDeclaration, + hasInitializer, + isCallLikeExpression, + isClassElement, + isClassLike, + isExternalModuleNameRelative, + isFunctionLike, + isFunctionLikeDeclaration, + isJsxOpeningLikeElement, + isPropertyName, + textRangeContainsPositionInclusive, unescapeLeadingUnderscores, -} from "./_namespaces/ts"; +} from "../compiler/utilitiesPublic"; +import { + getContainingObjectLiteralElement, + getPropertySymbolsFromContextualType, +} from "./services"; +import { getSymbolKind } from "./symbolDisplay"; +import { + DefinitionInfo, + DefinitionInfoAndBoundSpan, + ScriptElementKind, +} from "./types"; +import { + createTextSpanFromNode, + createTextSpanFromRange, + getContextNode, + getNameFromPropertyName, + getTargetLabel, + getTouchingPropertyName, + getTouchingToken, + isCallOrNewExpressionTarget, + isJumpStatementTarget, + isModuleSpecifierLike, + isNameOfFunctionDeclaration, + isNewExpressionTarget, + isRightSideOfPropertyAccess, + toContextSpan, +} from "./utilities"; /** @internal */ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile, position: number, searchOtherFilesOnly?: boolean, stopAtAlias?: boolean): readonly DefinitionInfo[] | undefined { @@ -510,7 +527,7 @@ function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: */ export function createDefinitionInfo(declaration: Declaration, checker: TypeChecker, symbol: Symbol, node: Node, unverified?: boolean, failedAliasResolution?: boolean): 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 = getSymbolKind(checker, symbol, node); const containerName = symbol.parent ? checker.symbolToString(symbol.parent, node) : ""; return createDefinitionInfoFromName(checker, declaration, symbolKind, symbolName, containerName, unverified, failedAliasResolution); } @@ -529,10 +546,10 @@ function createDefinitionInfoFromName(checker: TypeChecker, declaration: Declara name: symbolName, containerKind: undefined!, // TODO: GH#18217 containerName, - ...FindAllReferences.toContextSpan( + ...toContextSpan( textSpan, sourceFile, - FindAllReferences.getContextNode(declaration) + getContextNode(declaration) ), isLocal: !isDefinitionVisible(checker, declaration), isAmbient: !!(declaration.flags & NodeFlags.Ambient), diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 0cca4a93f915b..9ac172310c909 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -1,50 +1,21 @@ +import { getSymbolId } from "../compiler/checkerUtilities"; import { - __String, - AnyImportOrReExport, - AssignmentDeclarationKind, - BinaryExpression, - BindingElement, - CallExpression, - CancellationToken, - canHaveModifiers, cast, - Debug, - ExportAssignment, - ExportDeclaration, - FileReference, - findAncestor, forEach, - getAssignmentDeclarationKind, - getFirstIdentifier, - getNameOfAccessExpression, - getSourceFileOfNode, - getSymbolId, - hasSyntacticModifier, - Identifier, - ImportCall, - ImportClause, - ImportDeclaration, - ImportEqualsDeclaration, - importFromModuleSpecifier, - ImportSpecifier, - InternalSymbolName, - isAccessExpression, + some, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { isBinaryExpression, isBindingElement, isCatchClause, - isDefaultImport, isExportAssignment, isExportDeclaration, isExportModifier, isExportSpecifier, - isExternalModuleAugmentation, - isExternalModuleSymbol, - isImportCall, isImportEqualsDeclaration, isImportTypeNode, - isInJSFile, isJSDocTypedefTag, - isModuleExportsAccessExpression, isNamedExports, isNamespaceExport, isPrivateIdentifier, @@ -53,31 +24,70 @@ import { isSourceFile, isStringLiteral, isVariableDeclaration, - isVariableDeclarationInitializedToBareOrAccessedRequire, isVariableStatement, +} from "../compiler/factory/nodeTests"; +import { canHaveModifiers } from "../compiler/factory/utilitiesPublic"; +import { + __String, + AnyImportOrReExport, + AssignmentDeclarationKind, + BinaryExpression, + BindingElement, + CallExpression, + CancellationToken, + ExportAssignment, + ExportDeclaration, + FileReference, + Identifier, + ImportCall, + ImportClause, + ImportDeclaration, + ImportEqualsDeclaration, + ImportSpecifier, + InternalSymbolName, ModifierFlags, ModuleBlock, ModuleDeclaration, NamedImportsOrExports, NamespaceImport, Node, - nodeSeenTracker, Program, - some, SourceFile, Statement, StringLiteral, StringLiteralLike, Symbol, - symbolEscapedNameNoDefault, SymbolFlags, - symbolName, SyntaxKind, TypeChecker, ValidImportTypeNode, VariableDeclaration, +} from "../compiler/types"; +import { + getAssignmentDeclarationKind, + getFirstIdentifier, + getNameOfAccessExpression, + getSourceFileOfNode, + hasSyntacticModifier, + importFromModuleSpecifier, + isAccessExpression, + isDefaultImport, + isExternalModuleAugmentation, + isImportCall, + isInJSFile, + isModuleExportsAccessExpression, + isVariableDeclarationInitializedToBareOrAccessedRequire, +} from "../compiler/utilities"; +import { + findAncestor, + symbolName, walkUpBindingElementsAndPatterns, -} from "./_namespaces/ts"; +} from "../compiler/utilitiesPublic"; +import { + isExternalModuleSymbol, + nodeSeenTracker, + symbolEscapedNameNoDefault, +} from "./utilities"; /* Code for finding imports of an exported symbol. Used only by FindAllReferences. */ diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts index 45bb04e6e1329..f1fce005c3454 100644 --- a/src/services/inlayHints.ts +++ b/src/services/inlayHints.ts @@ -1,52 +1,43 @@ import { - __String, - ArrowFunction, - CallExpression, - createPrinter, - Debug, - EmitHint, - EnumMember, equateStringsCaseInsensitive, - Expression, - findChildOfKind, - forEachChild, - FunctionDeclaration, - FunctionExpression, - FunctionLikeDeclaration, - GetAccessorDeclaration, - getEffectiveReturnTypeNode, - getEffectiveTypeAnnotationNode, - getLanguageVariant, - getLeadingCommentRanges, - hasContextSensitiveParameters, - Identifier, - InlayHint, - InlayHintKind, - InlayHintsContext, + some, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { createPrinter } from "../compiler/emitter"; +import { isArrowFunction, - isAssertionExpression, - isBindingPattern, isCallExpression, isEnumMember, isExpressionWithTypeArguments, isFunctionDeclaration, isFunctionExpression, - isFunctionLikeDeclaration, isGetAccessorDeclaration, isIdentifier, - isIdentifierText, - isInfinityOrNaNString, - isLiteralExpression, isMethodDeclaration, isNewExpression, isObjectLiteralExpression, isParameter, - isParameterDeclaration, isPropertyAccessExpression, isPropertyDeclaration, - isTypeNode, - isVarConst, isVariableDeclaration, +} from "../compiler/factory/nodeTests"; +import { forEachChild } from "../compiler/parser"; +import { + getLeadingCommentRanges, + isIdentifierText, +} from "../compiler/scanner"; +import { + __String, + ArrowFunction, + CallExpression, + EmitHint, + EnumMember, + Expression, + FunctionDeclaration, + FunctionExpression, + FunctionLikeDeclaration, + GetAccessorDeclaration, + Identifier, MethodDeclaration, NewExpression, Node, @@ -56,19 +47,40 @@ import { PrinterOptions, PropertyDeclaration, Signature, - skipParentheses, - some, Symbol, SymbolFlags, SyntaxKind, - textSpanIntersectsWith, Type, TypeFormatFlags, - unescapeLeadingUnderscores, UserPreferences, - usingSingleLineStringWriter, VariableDeclaration, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + getEffectiveReturnTypeNode, + getEffectiveTypeAnnotationNode, + getLanguageVariant, + hasContextSensitiveParameters, + isInfinityOrNaNString, + isParameterDeclaration, + isVarConst, + skipParentheses, + usingSingleLineStringWriter, +} from "../compiler/utilities"; +import { + isAssertionExpression, + isBindingPattern, + isFunctionLikeDeclaration, + isLiteralExpression, + isTypeNode, + textSpanIntersectsWith, + unescapeLeadingUnderscores, +} from "../compiler/utilitiesPublic"; +import { + InlayHint, + InlayHintKind, + InlayHintsContext, +} from "./types"; +import { findChildOfKind } from "./utilities"; const maxHintsLength = 30; diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 45e9d80f673a1..561a3e512b85b 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -1,50 +1,40 @@ import { arraysEqual, - ArrowFunction, - AssignmentDeclarationKind, - BinaryExpression, - buildLinkParts, - ClassExpression, - CompletionEntry, - CompletionEntryDetails, - Completions, - ConstructorDeclaration, contains, - Declaration, - DocCommentTemplateOptions, emptyArray, - Expression, - ExpressionStatement, find, - findAncestor, flatMap, flatten, forEach, - forEachAncestor, - forEachReturnStatement, - forEachUnique, - FunctionDeclaration, - FunctionExpression, - getAssignmentDeclarationKind, - getJSDocCommentsAndTags, - getJSDocTags, - getLineStartPositionForPosition, - getTokenAtPosition, - hasJSDocNodes, - hasJSFileExtension, intersperse, + isWhiteSpaceSingleLine, + lastOrUndefined, + length, + map, + mapDefined, + startsWith, +} from "../compiler/core"; +import { isArrowFunction, isBlock, isConstructorDeclaration, - isExpression, isFunctionExpression, - isFunctionLike, - isFunctionLikeDeclaration, isFunctionTypeNode, isIdentifier, isJSDoc, isJSDocParameterTag, - isWhiteSpaceSingleLine, +} from "../compiler/factory/nodeTests"; +import { + ArrowFunction, + AssignmentDeclarationKind, + BinaryExpression, + ClassExpression, + ConstructorDeclaration, + Declaration, + Expression, + ExpressionStatement, + FunctionDeclaration, + FunctionExpression, JSDoc, JSDocAugmentsTag, JSDocCallbackTag, @@ -54,39 +44,61 @@ import { JSDocPropertyTag, JSDocSeeTag, JSDocTag, - JSDocTagInfo, JSDocTemplateTag, JSDocTypedefTag, JSDocTypeTag, - lastOrUndefined, - length, - lineBreakPart, - map, - mapDefined, MethodDeclaration, MethodSignature, Node, ParameterDeclaration, - parameterNamePart, ParenthesizedExpression, PropertyAssignment, PropertyDeclaration, - propertyNamePart, PropertySignature, - punctuationPart, - ScriptElementKind, SourceFile, - spacePart, - startsWith, - SymbolDisplayPart, SyntaxKind, + TypeChecker, + VariableStatement, +} from "../compiler/types"; +import { + forEachAncestor, + forEachReturnStatement, + getAssignmentDeclarationKind, + getJSDocCommentsAndTags, + hasJSFileExtension, +} from "../compiler/utilities"; +import { + findAncestor, + getJSDocTags, + hasJSDocNodes, + isExpression, + isFunctionLike, + isFunctionLikeDeclaration, +} from "../compiler/utilitiesPublic"; +import { SortText } from "./completions"; +import { + CompletionEntry, + CompletionEntryDetails, + DocCommentTemplateOptions, + JSDocTagInfo, + ScriptElementKind, + SymbolDisplayPart, TextInsertion, +} from "./types"; +import { + buildLinkParts, + forEachUnique, + getLineStartPositionForPosition, + getTokenAtPosition, + lineBreakPart, + parameterNamePart, + propertyNamePart, + punctuationPart, + spacePart, textPart, typeAliasNamePart, - TypeChecker, typeParameterNamePart, - VariableStatement, -} from "./_namespaces/ts"; +} from "./utilities"; const jsDocTagNames = [ "abstract", @@ -341,7 +353,7 @@ export function getJSDocTagNameCompletions(): CompletionEntry[] { name: tagName, kind: ScriptElementKind.keyword, kindModifiers: "", - sortText: Completions.SortText.LocationPriority, + sortText: SortText.LocationPriority, }; })); } @@ -356,7 +368,7 @@ export function getJSDocTagCompletions(): CompletionEntry[] { name: `@${tagName}`, kind: ScriptElementKind.keyword, kindModifiers: "", - sortText: Completions.SortText.LocationPriority + sortText: SortText.LocationPriority }; })); } @@ -393,7 +405,7 @@ export function getJSDocParameterNameCompletions(tag: JSDocParameterTag): Comple return undefined; } - return { name, kind: ScriptElementKind.parameterElement, kindModifiers: "", sortText: Completions.SortText.LocationPriority }; + return { name, kind: ScriptElementKind.parameterElement, kindModifiers: "", sortText: SortText.LocationPriority }; }); } diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index aa57b808e9f99..e6798640dcca2 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -1,33 +1,43 @@ import { - CancellationToken, compareStringsCaseSensitiveUI, compareValues, - createPatternMatcher, - createTextSpanFromNode, - Declaration, emptyArray, +} from "../compiler/core"; +import { Push } from "../compiler/corePublic"; +import { isPropertyAccessExpression } from "../compiler/factory/nodeTests"; +import { + CancellationToken, + Declaration, Expression, - getContainerNode, - getNameOfDeclaration, - getNodeKind, - getNodeModifiers, - getTextOfIdentifierOrLiteral, Identifier, ImportClause, ImportEqualsDeclaration, ImportSpecifier, - isPropertyAccessExpression, - isPropertyNameLiteral, - NavigateToItem, Node, - PatternMatcher, - PatternMatchKind, - Push, - ScriptElementKind, SourceFile, SyntaxKind, TypeChecker, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + getTextOfIdentifierOrLiteral, + isPropertyNameLiteral, +} from "../compiler/utilities"; +import { getNameOfDeclaration } from "../compiler/utilitiesPublic"; +import { + createPatternMatcher, + PatternMatcher, + PatternMatchKind, +} from "./patternMatcher"; +import { + NavigateToItem, + ScriptElementKind, +} from "./types"; +import { + createTextSpanFromNode, + getContainerNode, + getNodeKind, + getNodeModifiers, +} from "./utilities"; interface RawNavigateToItem { readonly name: string; diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 132ff59e9909b..1b94f2a404c10 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -1,3 +1,43 @@ +import { + compareStringsCaseSensitiveUI, + compareValues, + concatenate, + contains, + filterMutate, + forEach, + lastOrUndefined, + map, + mapDefined, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { factory } from "../compiler/factory/nodeFactory"; +import { + isArrowFunction, + isBinaryExpression, + isCallExpression, + isClassDeclaration, + isElementAccessExpression, + isExportAssignment, + isFunctionDeclaration, + isFunctionExpression, + isIdentifier, + isModuleBlock, + isModuleDeclaration, + isObjectLiteralExpression, + isPrivateIdentifier, + isPropertyAccessExpression, + isPropertyAssignment, + isVariableDeclaration, +} from "../compiler/factory/nodeTests"; +import { setTextRange } from "../compiler/factory/utilitiesPublic"; +import { + forEachChild, + isExternalModule, +} from "../compiler/parser"; +import { + getBaseFileName, + normalizePath, +} from "../compiler/path"; import { ArrowFunction, AssignmentDeclarationKind, @@ -11,104 +51,80 @@ import { ClassElement, ClassExpression, ClassLikeDeclaration, - compareStringsCaseSensitiveUI, - compareValues, - concatenate, ConstructorDeclaration, - contains, - createTextSpanFromNode, - createTextSpanFromRange, - Debug, Declaration, DeclarationName, - declarationNameToString, EntityNameExpression, EnumDeclaration, EnumMember, - escapeString, ExportAssignment, Expression, - factory, - filterMutate, - forEach, - forEachChild, FunctionDeclaration, FunctionExpression, FunctionLikeDeclaration, + Identifier, + ImportClause, + InterfaceDeclaration, + InternalSymbolName, + ModifierFlags, + ModuleDeclaration, + Node, + NodeFlags, + PropertyAccessExpression, + PropertyAssignment, + PropertyDeclaration, + PropertyNameLiteral, + ShorthandPropertyAssignment, + SourceFile, + SpreadAssignment, + SyntaxKind, + TextSpan, + TypeElement, + VariableDeclaration, +} from "../compiler/types"; +import { + declarationNameToString, + escapeString, getAssignmentDeclarationKind, - getBaseFileName, getElementOrPropertyAccessName, getFullWidth, - getNameOfDeclaration, getNameOrArgument, - getNodeKind, - getNodeModifiers, getPropertyNameForPropertyNameNode, getSyntacticModifierFlags, getTextOfIdentifierOrLiteral, getTextOfNode, hasDynamicName, - hasJSDocNodes, - Identifier, - idText, - ImportClause, - InterfaceDeclaration, - InternalSymbolName, isAmbientModule, - isArrowFunction, - isBinaryExpression, isBindableStaticAccessExpression, + isJSDocTypeAlias, + isPropertyNameLiteral, + isStatic, + removeFileExtension, +} from "../compiler/utilities"; +import { + getNameOfDeclaration, + hasJSDocNodes, + idText, isBindingPattern, - isCallExpression, - isClassDeclaration, isClassLike, isDeclaration, - isElementAccessExpression, - isExportAssignment, isExpression, - isExternalModule, - isFunctionDeclaration, - isFunctionExpression, - isIdentifier, - isJSDocTypeAlias, - isModuleBlock, - isModuleDeclaration, - isObjectLiteralExpression, isParameterPropertyDeclaration, - isPrivateIdentifier, - isPropertyAccessExpression, - isPropertyAssignment, isPropertyName, - isPropertyNameLiteral, - isStatic, isStringLiteralLike, isToken, - isVariableDeclaration, - lastOrUndefined, - map, - mapDefined, - ModifierFlags, - ModuleDeclaration, + unescapeLeadingUnderscores, +} from "../compiler/utilitiesPublic"; +import { NavigationBarItem, NavigationTree, - Node, - NodeFlags, - normalizePath, - PropertyAccessExpression, - PropertyAssignment, - PropertyDeclaration, - PropertyNameLiteral, - removeFileExtension, - setTextRange, - ShorthandPropertyAssignment, - SourceFile, - SpreadAssignment, - SyntaxKind, - TextSpan, - TypeElement, - unescapeLeadingUnderscores, - VariableDeclaration, -} from "./_namespaces/ts"; +} from "./types"; +import { + createTextSpanFromNode, + createTextSpanFromRange, + getNodeKind, + getNodeModifiers, +} from "./utilities"; /** * Matches all whitespace characters in a string. Eg: diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index 77874bf6e6d35..5a10d962deb4d 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -1,60 +1,78 @@ import { - AnyImportOrRequireStatement, arrayIsSorted, binarySearch, compareBooleans, compareStringsCaseInsensitive, compareValues, - Comparison, - createScanner, emptyArray, - ExportDeclaration, - ExportSpecifier, - Expression, - factory, - FileTextChanges, - FindAllReferences, flatMap, - formatting, - getNewLineOrDefaultFromHost, group, - Identifier, identity, - ImportDeclaration, - ImportOrExportSpecifier, - ImportSpecifier, - isAmbientModule, + isString, + length, + map, + some, + stableSort, + tryCast, +} from "../compiler/core"; +import { + Comparison, + SortedReadonlyArray, +} from "../compiler/corePublic"; +import { factory } from "../compiler/factory/nodeFactory"; +import { isExportDeclaration, - isExternalModuleNameRelative, isExternalModuleReference, isImportDeclaration, isNamedExports, isNamedImports, isNamespaceImport, - isString, isStringLiteral, - isStringLiteralLike, - jsxModeNeedsExplicitImport, - LanguageServiceHost, - length, - map, +} from "../compiler/factory/nodeTests"; +import { + createScanner, + Scanner, +} from "../compiler/scanner"; +import { + AnyImportOrRequireStatement, + ExportDeclaration, + ExportSpecifier, + Expression, + Identifier, + ImportDeclaration, + ImportOrExportSpecifier, + ImportSpecifier, NamedImportBindings, NamedImports, NamespaceImport, - OrganizeImportsMode, Program, - Scanner, - some, - SortedReadonlyArray, SourceFile, - stableSort, - suppressLeadingTrivia, SyntaxKind, - textChanges, TransformFlags, - tryCast, UserPreferences, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { isAmbientModule } from "../compiler/utilities"; +import { + isExternalModuleNameRelative, + isStringLiteralLike, +} from "../compiler/utilitiesPublic"; +import { Core as FindAllReferences } from "./findAllReferences"; +import { + ChangeTracker, + LeadingTriviaOption, + TrailingTriviaOption, +} from "./textChanges"; +import { + FileTextChanges, + FormatContext, + LanguageServiceHost, + OrganizeImportsMode, +} from "./types"; +import { + getNewLineOrDefaultFromHost, + jsxModeNeedsExplicitImport, + suppressLeadingTrivia, +} from "./utilities"; /** * Organize imports by: @@ -66,13 +84,13 @@ import { */ export function organizeImports( sourceFile: SourceFile, - formatContext: formatting.FormatContext, + formatContext: FormatContext, host: LanguageServiceHost, program: Program, preferences: UserPreferences, mode: OrganizeImportsMode, ): FileTextChanges[] { - const changeTracker = textChanges.ChangeTracker.fromContext({ host, formatContext, preferences }); + const changeTracker = ChangeTracker.fromContext({ host, formatContext, preferences }); const shouldSort = mode === OrganizeImportsMode.SortAndCombine || mode === OrganizeImportsMode.All; const shouldCombine = shouldSort; // These are currently inseparable, but I draw a distinction for clarity and in case we add modes in the future. const shouldRemove = mode === OrganizeImportsMode.RemoveUnused || mode === OrganizeImportsMode.All; @@ -142,20 +160,20 @@ export function 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: 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, + leadingTriviaOption: LeadingTriviaOption.Exclude, // Leave header comment in place + trailingTriviaOption: TrailingTriviaOption.Include, suffix: 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: TrailingTriviaOption.Include, }, hasTrailingComment); } } @@ -273,7 +291,7 @@ function removeUnusedImports(oldImports: readonly ImportDeclaration[], sourceFil function isDeclarationUsed(identifier: 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); + FindAllReferences.isSymbolReferencedInFile(identifier, typeChecker, sourceFile); } } diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 47ac841287c54..4b71aec8b8f1d 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -1,37 +1,34 @@ import { - ArrowFunction, - Block, - CallExpression, - CancellationToken, - CaseClause, - createTextSpanFromBounds, - createTextSpanFromNode, - createTextSpanFromRange, - Debug, - DefaultClause, - findChildOfKind, - getLeadingCommentRanges, - isAnyImportSyntax, + startsWith, + trimString, + trimStringStart, +} from "../compiler/core"; +import { Push } from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { isArrayLiteralExpression, isBinaryExpression, isBindingElement, isBlock, isCallExpression, - isCallOrNewExpression, - isClassLike, - isDeclaration, - isFunctionLike, isIfStatement, - isInComment, isInterfaceDeclaration, isJsxText, isModuleBlock, - isNodeArrayMultiLine, isParenthesizedExpression, isPropertyAccessExpression, isReturnStatement, isTupleTypeNode, isVariableStatement, +} from "../compiler/factory/nodeTests"; +import { getLeadingCommentRanges } from "../compiler/scanner"; +import { + ArrowFunction, + Block, + CallExpression, + CancellationToken, + CaseClause, + DefaultClause, JsxAttributes, JsxElement, JsxFragment, @@ -39,21 +36,36 @@ import { Node, NodeArray, NoSubstitutionTemplateLiteral, - OutliningSpan, - OutliningSpanKind, ParenthesizedExpression, - positionsAreOnSameLine, - Push, SignatureDeclaration, SourceFile, - startsWith, SyntaxKind, TemplateExpression, TextSpan, - trimString, - trimStringStart, TryStatement, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + isAnyImportSyntax, + isNodeArrayMultiLine, + positionsAreOnSameLine, +} from "../compiler/utilities"; +import { + createTextSpanFromBounds, + isCallOrNewExpression, + isClassLike, + isDeclaration, + isFunctionLike, +} from "../compiler/utilitiesPublic"; +import { + OutliningSpan, + OutliningSpanKind, +} from "./types"; +import { + createTextSpanFromNode, + createTextSpanFromRange, + findChildOfKind, + isInComment, +} from "./utilities"; /** @internal */ export function collectElements(sourceFile: SourceFile, cancellationToken: CancellationToken): OutliningSpan[] { diff --git a/src/services/patternMatcher.ts b/src/services/patternMatcher.ts index b021f959c6a34..22717693aa4eb 100644 --- a/src/services/patternMatcher.ts +++ b/src/services/patternMatcher.ts @@ -1,16 +1,18 @@ import { - CharacterCodes, compareBooleans, compareValues, - Comparison, - createTextSpan, - isUnicodeIdentifierStart, last, min, - ScriptTarget, startsWith, +} from "../compiler/core"; +import { Comparison } from "../compiler/corePublic"; +import { isUnicodeIdentifierStart } from "../compiler/scanner"; +import { + CharacterCodes, + ScriptTarget, TextSpan, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { createTextSpan } from "../compiler/utilitiesPublic"; // Note(cyrusn): this enum is ordered from strongest match type to weakest match type. /** @internal */ diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 084a99595cc5b..6f16b28ad91d5 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -1,17 +1,21 @@ import { - FileReference, - isKeyword, lastOrUndefined, length, noop, +} from "../compiler/core"; +import { PragmaContext, - PreProcessedFileInfo, processCommentPragmas, processPragmasIntoFields, - scanner, +} from "../compiler/parser"; +import { + FileReference, ScriptTarget, SyntaxKind, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { isKeyword } from "../compiler/utilities"; +import { PreProcessedFileInfo } from "./types"; +import { scanner } from "./utilities"; export function preProcessFile(sourceText: string, readImportFiles = true, detectJavaScriptImports = false): PreProcessedFileInfo { const pragmaContext: PragmaContext = { diff --git a/src/services/refactorProvider.ts b/src/services/refactorProvider.ts index 611c846c21c99..9323c1903c2a9 100644 --- a/src/services/refactorProvider.ts +++ b/src/services/refactorProvider.ts @@ -1,12 +1,14 @@ import { - ApplicableRefactorInfo, arrayFrom, flatMapIterator, +} from "../compiler/core"; +import { refactorKindBeginsWith } from "./refactors/helpers"; +import { + ApplicableRefactorInfo, Refactor, RefactorContext, RefactorEditInfo, -} from "./_namespaces/ts"; -import { refactorKindBeginsWith } from "./_namespaces/ts.refactor"; +} from "./types"; // A map with the refactor code as key, the refactor itself as value // e.g. nonSuggestableRefactors[refactorCode] -> the refactor you want diff --git a/src/services/refactors/addOrRemoveBracesToArrowFunction.ts b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts index 25aabb5d07b84..a0d9ecfe74beb 100644 --- a/src/services/refactors/addOrRemoveBracesToArrowFunction.ts +++ b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts @@ -1,38 +1,48 @@ import { - ApplicableRefactorInfo, - ArrowFunction, - ConciseBody, - copyLeadingComments, - copyTrailingAsLeadingComments, - copyTrailingComments, - Debug, - Diagnostics, emptyArray, - Expression, - factory, first, - getContainingFunction, - getLocaleSpecificMessage, - getTokenAtPosition, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrowFunction, isBlock, - isExpression, isReturnStatement, - needsParentheses, - rangeContainsRange, - RefactorContext, - RefactorEditInfo, +} from "../../compiler/factory/nodeTests"; +import { + ArrowFunction, + ConciseBody, + Expression, ReturnStatement, SourceFile, SyntaxKind, - textChanges, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { - isRefactorErrorInfo, + getContainingFunction, + getLocaleSpecificMessage, +} from "../../compiler/utilities"; +import { isExpression } from "../../compiler/utilitiesPublic"; +import { registerRefactor } from "../refactorProvider"; +import { ChangeTracker } from "../textChanges"; +import { + ApplicableRefactorInfo, + RefactorContext, + RefactorEditInfo, RefactorErrorInfo, +} from "../types"; +import { + copyLeadingComments, + copyTrailingAsLeadingComments, + copyTrailingComments, + getTokenAtPosition, + needsParentheses, + rangeContainsRange, +} from "../utilities"; +import { + isRefactorErrorInfo, refactorKindBeginsWith, - registerRefactor, -} from "../_namespaces/ts.refactor"; +} from "./helpers"; const refactorName = "Add or remove braces in an arrow function"; const refactorDescription = Diagnostics.Add_or_remove_braces_in_an_arrow_function.message; @@ -114,7 +124,7 @@ function getRefactorEditsToRemoveFunctionBraces(context: RefactorContext, action Debug.fail("invalid action"); } - const edits = textChanges.ChangeTracker.with(context, t => { + const edits = ChangeTracker.with(context, t => { t.replaceNode(file, func.body, body); }); diff --git a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts index f631f1387e221..9bd15d8b2a4c4 100644 --- a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts +++ b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts @@ -1,61 +1,71 @@ import { - ApplicableRefactorInfo, - ArrowFunction, - Block, - ConciseBody, - copyComments, - copyTrailingAsLeadingComments, - Debug, - Diagnostics, emptyArray, - factory, - FileTextChanges, - FindAllReferences, first, - forEachChild, - FunctionExpression, - getCombinedModifierFlags, - getContainingFunction, - getEffectiveModifierFlags, - getLocaleSpecificMessage, - getTokenAtPosition, - Identifier, + length, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrowFunction, - isClassLike, - isExpression, isFunctionDeclaration, isFunctionExpression, isIdentifier, isReturnStatement, - isThis, isVariableDeclaration, - isVariableDeclarationInVariableStatement, isVariableDeclarationList, isVariableStatement, - length, +} from "../../compiler/factory/nodeTests"; +import { forEachChild } from "../../compiler/parser"; +import { + ArrowFunction, + Block, + ConciseBody, + FunctionExpression, + Identifier, ModifierFlags, Node, Program, - rangeContainsRange, - RefactorActionInfo, - RefactorContext, - RefactorEditInfo, ReturnStatement, SourceFile, Statement, - suppressLeadingAndTrailingTrivia, - suppressLeadingTrivia, SyntaxKind, - textChanges, TypeChecker, VariableDeclaration, VariableDeclarationList, VariableStatement, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + getContainingFunction, + getEffectiveModifierFlags, + getLocaleSpecificMessage, + isVariableDeclarationInVariableStatement, +} from "../../compiler/utilities"; +import { + getCombinedModifierFlags, + isClassLike, + isExpression, +} from "../../compiler/utilitiesPublic"; +import { Core as FindAllReferences } from "../findAllReferences"; +import { registerRefactor } from "../refactorProvider"; +import { ChangeTracker } from "../textChanges"; import { - refactorKindBeginsWith, - registerRefactor, -} from "../_namespaces/ts.refactor"; + ApplicableRefactorInfo, + FileTextChanges, + RefactorActionInfo, + RefactorContext, + RefactorEditInfo, +} from "../types"; +import { + copyComments, + copyTrailingAsLeadingComments, + getTokenAtPosition, + isThis, + rangeContainsRange, + suppressLeadingAndTrailingTrivia, + suppressLeadingTrivia, +} from "../utilities"; +import { refactorKindBeginsWith } from "./helpers"; const refactorName = "Convert arrow function or function expression"; const refactorDescription = getLocaleSpecificMessage(Diagnostics.Convert_arrow_function_or_function_expression); @@ -261,7 +271,7 @@ function getEditInfoForConvertToAnonymousFunction(context: RefactorContext, func 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)); + return ChangeTracker.with(context, t => t.replaceNode(file, func, newNode)); } function getEditInfoForConvertToNamedFunction(context: RefactorContext, func: FunctionExpression | ArrowFunction, variableInfo: VariableInfo): FileTextChanges[] { @@ -276,10 +286,10 @@ function getEditInfoForConvertToNamedFunction(context: RefactorContext, func: Fu const newNode = factory.createFunctionDeclaration(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 ChangeTracker.with(context, t => t.replaceNode(file, statement, newNode)); } else { - return textChanges.ChangeTracker.with(context, t => { + return ChangeTracker.with(context, t => { t.delete(file, variableDeclaration); t.insertNodeAfter(file, statement, newNode); }); @@ -302,7 +312,7 @@ function getEditInfoForConvertToArrowFunction(context: RefactorContext, func: Fu } 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)); + return ChangeTracker.with(context, t => t.replaceNode(file, func, newNode)); } function canBeConvertedToExpression(body: Block, head: Statement): head is ReturnStatement { @@ -310,5 +320,5 @@ function canBeConvertedToExpression(body: Block, head: Statement): head is Retur } function isFunctionReferencedInFile(sourceFile: SourceFile, typeChecker: TypeChecker, node: FunctionExpression): boolean { - return !!node.name && FindAllReferences.Core.isSymbolReferencedInFile(node.name, typeChecker, sourceFile); + return !!node.name && FindAllReferences.isSymbolReferencedInFile(node.name, typeChecker, sourceFile); } diff --git a/src/services/refactors/convertExport.ts b/src/services/refactors/convertExport.ts index 689460c9ee2dd..5da6db84b2183 100644 --- a/src/services/refactors/convertExport.ts +++ b/src/services/refactors/convertExport.ts @@ -1,60 +1,68 @@ import { - ApplicableRefactorInfo, + emptyArray, + first, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { + isExportAssignment, + isIdentifier, + isModuleBlock, + isSourceFile, + isStringLiteral, +} from "../../compiler/factory/nodeTests"; +import { CancellationToken, ClassDeclaration, - Debug, - Diagnostics, - emptyArray, EnumDeclaration, ExportAssignment, ExportSpecifier, - factory, - FindAllReferences, - findModifier, - first, FunctionDeclaration, - getLocaleSpecificMessage, - getParentNodeInSpan, - getRefactorContextSpan, - getSyntacticModifierFlags, - getTokenAtPosition, Identifier, ImportClause, ImportSpecifier, ImportTypeNode, InterfaceDeclaration, InternalSymbolName, - isAmbientModule, - isExportAssignment, - isExternalModuleAugmentation, - isIdentifier, - isModuleBlock, - isSourceFile, - isStringLiteral, - makeImport, ModifierFlags, NamespaceDeclaration, Node, NodeFlags, Program, PropertyAccessExpression, - QuotePreference, - quotePreferenceFromString, - RefactorContext, - RefactorEditInfo, SourceFile, Symbol, SyntaxKind, - textChanges, TypeAliasDeclaration, TypeChecker, VariableStatement, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + getLocaleSpecificMessage, + getSyntacticModifierFlags, + isAmbientModule, + isExternalModuleAugmentation, +} from "../../compiler/utilities"; +import { Core as FindAllReferences } from "../findAllReferences"; +import { registerRefactor } from "../refactorProvider"; +import { ChangeTracker } from "../textChanges"; import { - isRefactorErrorInfo, + ApplicableRefactorInfo, + RefactorContext, + RefactorEditInfo, RefactorErrorInfo, - registerRefactor, -} from "../_namespaces/ts.refactor"; +} from "../types"; +import { + findModifier, + getParentNodeInSpan, + getRefactorContextSpan, + getTokenAtPosition, + makeImport, + QuotePreference, + quotePreferenceFromString, +} from "../utilities"; +import { isRefactorErrorInfo } from "./helpers"; const refactorName = "Convert export"; @@ -98,7 +106,7 @@ registerRefactor(refactorName, { 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)); + const edits = ChangeTracker.with(context, t => doChange(context.file, context.program, info, t, context.cancellationToken)); return { edits, renameFilename: undefined, renameLocation: undefined }; }, }); @@ -170,12 +178,12 @@ function getInfo(context: RefactorContext, considerPartialSpans = true): ExportI } } -function doChange(exportingSourceFile: SourceFile, program: Program, info: ExportInfo, changes: textChanges.ChangeTracker, cancellationToken: CancellationToken | undefined): void { +function doChange(exportingSourceFile: SourceFile, program: Program, info: ExportInfo, changes: ChangeTracker, cancellationToken: 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: SourceFile, { wasDefault, exportNode, exportName }: ExportInfo, changes: ChangeTracker, checker: TypeChecker): void { if (wasDefault) { if (isExportAssignment(exportNode) && !exportNode.isExportEquals) { const exp = exportNode.expression as Identifier; @@ -197,7 +205,7 @@ function changeExport(exportingSourceFile: SourceFile, { wasDefault, exportNode, case 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) { + if (!FindAllReferences.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"))); break; @@ -216,10 +224,10 @@ function changeExport(exportingSourceFile: SourceFile, { wasDefault, exportNode, } } -function changeImports(program: Program, { wasDefault, exportName, exportingModuleSymbol }: ExportInfo, changes: textChanges.ChangeTracker, cancellationToken: CancellationToken | undefined): void { +function changeImports(program: Program, { wasDefault, exportName, exportingModuleSymbol }: ExportInfo, changes: ChangeTracker, cancellationToken: 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 => { + FindAllReferences.eachExportReference(program.getSourceFiles(), checker, cancellationToken, exportSymbol, exportingModuleSymbol, exportName.text, wasDefault, ref => { if (exportName === ref) return; const importingSourceFile = ref.getSourceFile(); if (wasDefault) { @@ -231,7 +239,7 @@ function changeImports(program: Program, { wasDefault, exportName, exportingModu }); } -function changeDefaultToNamedImport(importingSourceFile: SourceFile, ref: Identifier, changes: textChanges.ChangeTracker, exportName: string): void { +function changeDefaultToNamedImport(importingSourceFile: SourceFile, ref: Identifier, changes: ChangeTracker, exportName: string): void { const { parent } = ref; switch (parent.kind) { case SyntaxKind.PropertyAccessExpression: @@ -277,7 +285,7 @@ function changeDefaultToNamedImport(importingSourceFile: SourceFile, ref: Identi } } -function changeNamedToDefaultImport(importingSourceFile: SourceFile, ref: Identifier, changes: textChanges.ChangeTracker): void { +function changeNamedToDefaultImport(importingSourceFile: SourceFile, ref: Identifier, changes: ChangeTracker): void { const parent = ref.parent as PropertyAccessExpression | ImportSpecifier | ExportSpecifier; switch (parent.kind) { case SyntaxKind.PropertyAccessExpression: diff --git a/src/services/refactors/convertImport.ts b/src/services/refactors/convertImport.ts index a7d0d0d53123b..e83db32de1cdb 100644 --- a/src/services/refactors/convertImport.ts +++ b/src/services/refactors/convertImport.ts @@ -1,54 +1,64 @@ import { - ApplicableRefactorInfo, arrayFrom, - codefix, - Debug, - Diagnostics, emptyArray, - Expression, - factory, - FindAllReferences, - findAncestor, - findNextToken, - getAllowSyntheticDefaultImports, - getLocaleSpecificMessage, getOwnValues, - getParentNodeInSpan, - getRefactorContextSpan, - getTokenAtPosition, - getUniqueName, - Identifier, - ImportClause, - ImportDeclaration, - ImportKind, - ImportSpecifier, + some, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isExportSpecifier, isImportDeclaration, isPropertyAccessExpression, - isPropertyAccessOrQualifiedName, isShorthandPropertyAssignment, isStringLiteral, +} from "../../compiler/factory/nodeTests"; +import { + Expression, + Identifier, + ImportClause, + ImportDeclaration, + ImportSpecifier, NamedImports, NamespaceImport, Program, PropertyAccessExpression, QualifiedName, - RefactorContext, - RefactorEditInfo, ScriptTarget, - some, SourceFile, Symbol, SymbolFlags, SyntaxKind, - textChanges, TypeChecker, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + getAllowSyntheticDefaultImports, + getLocaleSpecificMessage, +} from "../../compiler/utilities"; +import { + findAncestor, + isPropertyAccessOrQualifiedName, +} from "../../compiler/utilitiesPublic"; +import { moduleSpecifierToValidIdentifier } from "../codefixes/importAdder"; +import { ImportKind } from "../exportInfoMap"; +import { Core as FindAllReferences } from "../findAllReferences"; +import { registerRefactor } from "../refactorProvider"; +import { ChangeTracker } from "../textChanges"; import { - isRefactorErrorInfo, + ApplicableRefactorInfo, + RefactorContext, + RefactorEditInfo, RefactorErrorInfo, - registerRefactor, -} from "../_namespaces/ts.refactor"; +} from "../types"; +import { + findNextToken, + getParentNodeInSpan, + getRefactorContextSpan, + getTokenAtPosition, + getUniqueName, +} from "../utilities"; +import { isRefactorErrorInfo } from "./helpers"; const refactorName = "Convert import"; @@ -95,7 +105,7 @@ registerRefactor(refactorName, { Debug.assert(some(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)); + const edits = ChangeTracker.with(context, t => doChange(context.file, context.program, t, info)); return { edits, renameFilename: undefined, renameLocation: undefined }; } }); @@ -141,7 +151,7 @@ function getShouldUseDefault(program: Program, importClause: ImportClause) { && isExportEqualsModule(importClause.parent.moduleSpecifier, program.getTypeChecker()); } -function doChange(sourceFile: SourceFile, program: Program, changes: textChanges.ChangeTracker, info: ImportConversionInfo): void { +function doChange(sourceFile: SourceFile, program: Program, changes: ChangeTracker, info: ImportConversionInfo): void { const checker = program.getTypeChecker(); if (info.convertTo === ImportKind.Named) { doChangeNamespaceToNamed(sourceFile, checker, changes, info.import, getAllowSyntheticDefaultImports(program.getCompilerOptions())); @@ -151,13 +161,13 @@ function doChange(sourceFile: SourceFile, program: Program, changes: textChanges } } -function doChangeNamespaceToNamed(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, toConvert: NamespaceImport, allowSyntheticDefaultImports: boolean): void { +function doChangeNamespaceToNamed(sourceFile: SourceFile, checker: TypeChecker, changes: ChangeTracker, toConvert: NamespaceImport, allowSyntheticDefaultImports: boolean): void { let usedAsNamespaceOrDefault = false; const nodesToReplace: (PropertyAccessExpression | QualifiedName)[] = []; const conflictingNames = new Map(); - FindAllReferences.Core.eachSymbolReferenceInFile(toConvert.name, checker, sourceFile, id => { + FindAllReferences.eachSymbolReferenceInFile(toConvert.name, checker, sourceFile, id => { if (!isPropertyAccessOrQualifiedName(id.parent)) { usedAsNamespaceOrDefault = true; } @@ -207,7 +217,7 @@ function getLeftOfPropertyAccessOrQualifiedName(propertyAccessOrQualifiedName: P } /** @internal */ -export function doChangeNamedToNamespaceOrDefault(sourceFile: SourceFile, program: Program, changes: textChanges.ChangeTracker, toConvert: NamedImports, shouldUseDefault = getShouldUseDefault(program, toConvert.parent)): void { +export function doChangeNamedToNamespaceOrDefault(sourceFile: SourceFile, program: Program, changes: ChangeTracker, toConvert: NamedImports, shouldUseDefault = getShouldUseDefault(program, toConvert.parent)): void { const checker = program.getTypeChecker(); const importDecl = toConvert.parent.parent; const { moduleSpecifier } = importDecl; @@ -219,13 +229,13 @@ export function doChangeNamedToNamespaceOrDefault(sourceFile: SourceFile, progra toConvertSymbols.add(symbol); } }); - const preferredName = moduleSpecifier && isStringLiteral(moduleSpecifier) ? codefix.moduleSpecifierToValidIdentifier(moduleSpecifier.text, ScriptTarget.ESNext) : "module"; + const preferredName = moduleSpecifier && isStringLiteral(moduleSpecifier) ? moduleSpecifierToValidIdentifier(moduleSpecifier.text, ScriptTarget.ESNext) : "module"; function hasNamespaceNameConflict(namedImport: 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 => { + return !!FindAllReferences.eachSymbolReferenceInFile(namedImport.name, checker, sourceFile, id => { const symbol = checker.resolveName(preferredName, id, 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... @@ -245,7 +255,7 @@ export function doChangeNamedToNamespaceOrDefault(sourceFile: SourceFile, progra for (const element of toConvert.elements) { const propertyName = (element.propertyName || element.name).text; - FindAllReferences.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, id => { + FindAllReferences.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)); diff --git a/src/services/refactors/convertOverloadListToSingleSignature.ts b/src/services/refactors/convertOverloadListToSingleSignature.ts index c0ad2970a6138..d917a48ea095d 100644 --- a/src/services/refactors/convertOverloadListToSingleSignature.ts +++ b/src/services/refactors/convertOverloadListToSingleSignature.ts @@ -1,25 +1,27 @@ import { - ApplicableRefactorInfo, - CallSignatureDeclaration, - ConstructorDeclaration, - ConstructSignatureDeclaration, - Debug, - Diagnostics, - displayPartsToString, - EmitFlags, emptyArray, every, - factory, - findAncestor, - FunctionDeclaration, - getSourceFileOfNode, - getSyntheticLeadingComments, - getTokenAtPosition, - isFunctionLikeDeclaration, - isIdentifier, length, map, mapDefined, + some, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { + getSyntheticLeadingComments, + setEmitFlags, + setSyntheticLeadingComments, +} from "../../compiler/factory/emitNode"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isIdentifier } from "../../compiler/factory/nodeTests"; +import { setTextRange } from "../../compiler/factory/utilitiesPublic"; +import { + CallSignatureDeclaration, + ConstructorDeclaration, + ConstructSignatureDeclaration, + EmitFlags, + FunctionDeclaration, MethodDeclaration, MethodSignature, NamedTupleMember, @@ -27,19 +29,27 @@ import { NodeArray, ParameterDeclaration, Program, - rangeContainsPosition, - RefactorContext, - RefactorEditInfo, - setEmitFlags, - setSyntheticLeadingComments, - setTextRange, - some, SourceFile, SyntaxKind, - textChanges, TupleTypeNode, -} from "../_namespaces/ts"; -import { registerRefactor } from "../_namespaces/ts.refactor"; +} from "../../compiler/types"; +import { getSourceFileOfNode } from "../../compiler/utilities"; +import { + findAncestor, + isFunctionLikeDeclaration, +} from "../../compiler/utilitiesPublic"; +import { registerRefactor } from "../refactorProvider"; +import { displayPartsToString } from "../services"; +import { ChangeTracker } from "../textChanges"; +import { + ApplicableRefactorInfo, + RefactorContext, + RefactorEditInfo, +} from "../types"; +import { + getTokenAtPosition, + rangeContainsPosition, +} from "../utilities"; const refactorName = "Convert overload list to single signature"; const refactorDescription = Diagnostics.Convert_overload_list_to_single_signature.message; @@ -150,7 +160,7 @@ function getRefactorEditsToConvertOverloadsToOneSignature(context: RefactorConte return; // No edits to apply, do nothing } - const edits = textChanges.ChangeTracker.with(context, t => { + const edits = ChangeTracker.with(context, t => { t.replaceNodeRange(file, signatureDecls[0], signatureDecls[signatureDecls.length - 1], updated); }); diff --git a/src/services/refactors/convertParamsToDestructuredObject.ts b/src/services/refactors/convertParamsToDestructuredObject.ts index a86e190d2d8cd..5049c24d1cb65 100644 --- a/src/services/refactors/convertParamsToDestructuredObject.ts +++ b/src/services/refactors/convertParamsToDestructuredObject.ts @@ -1,79 +1,57 @@ import { - addEmitFlags, - ApplicableRefactorInfo, - ArrowFunction, - BindingElement, - CallExpression, - CancellationToken, - CheckFlags, - ClassDeclaration, - ClassExpression, compareValues, - ConstructorDeclaration, contains, - copyComments, - Debug, deduplicate, - Diagnostics, - ElementAccessExpression, - EmitFlags, emptyArray, equateValues, every, - Expression, - factory, - FindAllReferences, - findAncestor, - findChildOfKind, - findModifier, first, flatMap, - FunctionBody, - FunctionDeclaration, - FunctionExpression, - FunctionLikeDeclaration, - getCheckFlags, - getContainingFunctionDeclaration, - getContainingObjectLiteralElement, - getLocaleSpecificMessage, - getMeaningFromLocation, - getSourceFileOfNode, - getSymbolTarget, - getSynthesizedDeepClone, - getTextOfIdentifierOrLiteral, - getTouchingToken, - getTypeNodeIfAccessible, - Identifier, - isCallOrNewExpression, + last, + map, + sortAndDeduplicate, + tryCast, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { addEmitFlags } from "../../compiler/factory/emitNode"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isClassDeclaration, isConstructorDeclaration, - isDeclaration, isElementAccessExpression, isExportAssignment, isExportSpecifier, - isExpressionWithTypeArgumentsInClassExtendsClause, - isFunctionLikeDeclaration, isIdentifier, isImportClause, isImportEqualsDeclaration, isImportSpecifier, isInterfaceDeclaration, - isJSDocNode, isMethodSignature, isNamespaceImport, - isNewExpressionTarget, isObjectLiteralExpression, isPropertyAccessExpression, isPropertyAssignment, - isRestParameter, - isSourceFileJS, - isThis, isTypeLiteralNode, - isVarConst, isVariableDeclaration, - LanguageServiceHost, - last, - map, +} from "../../compiler/factory/nodeTests"; +import { + ArrowFunction, + BindingElement, + CallExpression, + CancellationToken, + CheckFlags, + ClassDeclaration, + ClassExpression, + ConstructorDeclaration, + ElementAccessExpression, + EmitFlags, + Expression, + FunctionBody, + FunctionDeclaration, + FunctionExpression, + FunctionLikeDeclaration, + Identifier, MethodDeclaration, MethodSignature, Modifier, @@ -87,24 +65,65 @@ import { PropertyAccessExpression, PropertyAssignment, PropertySignature, - rangeContainsRange, - RefactorContext, - RefactorEditInfo, - SemanticMeaning, ShorthandPropertyAssignment, - sortAndDeduplicate, SourceFile, - suppressLeadingAndTrailingTrivia, Symbol, SyntaxKind, - textChanges, - tryCast, TypeChecker, TypeLiteralNode, TypeNode, VariableDeclaration, -} from "../_namespaces/ts"; -import { registerRefactor } from "../_namespaces/ts.refactor"; +} from "../../compiler/types"; +import { + getCheckFlags, + getContainingFunctionDeclaration, + getLocaleSpecificMessage, + getSourceFileOfNode, + getTextOfIdentifierOrLiteral, + isExpressionWithTypeArgumentsInClassExtendsClause, + isSourceFileJS, + isVarConst, +} from "../../compiler/utilities"; +import { + findAncestor, + isCallOrNewExpression, + isDeclaration, + isFunctionLikeDeclaration, + isJSDocNode, + isRestParameter, +} from "../../compiler/utilitiesPublic"; +import { getReferenceEntriesForNode } from "../findAllReferences"; +import { registerRefactor } from "../refactorProvider"; +import { getContainingObjectLiteralElement } from "../services"; +import { + ChangeTracker, + LeadingTriviaOption, + TrailingTriviaOption, +} from "../textChanges"; +import { + ApplicableRefactorInfo, + Entry, + EntryKind, + LanguageServiceHost, + NodeEntry, + RefactorContext, + RefactorEditInfo, +} from "../types"; +import { + copyComments, + findChildOfKind, + findModifier, + getMeaningFromLocation, + getSymbolTarget, + getSynthesizedDeepClone, + getTouchingToken, + getTypeNodeIfAccessible, + isNewExpressionTarget, + isThis, + rangeContainsRange, + SemanticMeaning, + suppressLeadingAndTrailingTrivia, +} from "../utilities"; const refactorName = "Convert parameters to destructured object"; const minimumParameterLength = 1; @@ -143,7 +162,7 @@ function getRefactorEditsToConvertParametersToDestructuredObject(context: Refact 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 = ChangeTracker.with(context, t => doChange(file, program, host, t, functionDeclaration, groupedReferences)); return { renameFilename: undefined, renameLocation: undefined, edits }; } @@ -154,7 +173,7 @@ function doChange( sourceFile: SourceFile, program: Program, host: LanguageServiceHost, - changes: textChanges.ChangeTracker, + changes: ChangeTracker, functionDeclaration: ValidFunctionDeclaration, groupedReferences: GroupedReferences): void { const signature = groupedReferences.signature; @@ -175,7 +194,7 @@ function doChange( first(call.arguments), last(call.arguments), newArgument, - { leadingTriviaOption: textChanges.LeadingTriviaOption.IncludeAll, trailingTriviaOption: textChanges.TrailingTriviaOption.Include }); + { leadingTriviaOption: LeadingTriviaOption.IncludeAll, trailingTriviaOption: TrailingTriviaOption.Include }); } } @@ -189,8 +208,8 @@ function doChange( 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: LeadingTriviaOption.IncludeAll, + trailingTriviaOption: TrailingTriviaOption.Include }); } } @@ -201,7 +220,7 @@ function getGroupedReferences(functionDeclaration: ValidFunctionDeclaration, pro const names = deduplicate([...functionNames, ...classNames], equateValues); const checker = program.getTypeChecker(); - const references = flatMap(names, /*mapfn*/ name => FindAllReferences.getReferenceEntriesForNode(-1, name, program, program.getSourceFiles(), cancellationToken)); + const references = flatMap(names, /*mapfn*/ name => getReferenceEntriesForNode(-1, name, program, program.getSourceFiles(), cancellationToken)); const groupedReferences = groupReferences(references); if (!every(groupedReferences.declarations, /*callback*/ decl => contains(names, decl))) { @@ -210,7 +229,7 @@ function getGroupedReferences(functionDeclaration: ValidFunctionDeclaration, pro return groupedReferences; - function groupReferences(referenceEntries: readonly FindAllReferences.Entry[]): GroupedReferences { + function groupReferences(referenceEntries: readonly Entry[]): GroupedReferences { const classReferences: ClassReferences = { accessExpressions: [], typeUsages: [] }; const groupedReferences: GroupedReferences = { functionCalls: [], declarations: [], classReferences, valid: true }; const functionSymbols = map(functionNames, getSymbolTargetAtLocation); @@ -219,7 +238,7 @@ function getGroupedReferences(functionDeclaration: ValidFunctionDeclaration, pro const contextualSymbols = map(functionNames, name => getSymbolForContextualType(name, checker)); for (const entry of referenceEntries) { - if (entry.kind === FindAllReferences.EntryKind.Span) { + if (entry.kind === EntryKind.Span) { groupedReferences.valid = false; continue; } @@ -334,7 +353,7 @@ function getSymbolForContextualType(node: Node, checker: TypeChecker): Symbol | } } -function entryToImportOrExport(entry: FindAllReferences.NodeEntry): Node | undefined { +function entryToImportOrExport(entry: NodeEntry): Node | undefined { const node = entry.node; if (isImportSpecifier(node.parent) @@ -350,14 +369,14 @@ function entryToImportOrExport(entry: FindAllReferences.NodeEntry): Node | undef return undefined; } -function entryToDeclaration(entry: FindAllReferences.NodeEntry): Node | undefined { +function entryToDeclaration(entry: NodeEntry): Node | undefined { if (isDeclaration(entry.node.parent)) { return entry.node; } return undefined; } -function entryToFunctionCall(entry: FindAllReferences.NodeEntry): CallExpression | NewExpression | undefined { +function entryToFunctionCall(entry: NodeEntry): CallExpression | NewExpression | undefined { if (entry.node.parent) { const functionReference = entry.node; const parent = functionReference.parent; @@ -395,7 +414,7 @@ function entryToFunctionCall(entry: FindAllReferences.NodeEntry): CallExpression return undefined; } -function entryToAccessExpression(entry: FindAllReferences.NodeEntry): ElementAccessExpression | PropertyAccessExpression | undefined { +function entryToAccessExpression(entry: NodeEntry): ElementAccessExpression | PropertyAccessExpression | undefined { if (entry.node.parent) { const reference = entry.node; const parent = reference.parent; @@ -419,7 +438,7 @@ function entryToAccessExpression(entry: FindAllReferences.NodeEntry): ElementAcc return undefined; } -function entryToType(entry: FindAllReferences.NodeEntry): Node | undefined { +function entryToType(entry: NodeEntry): Node | undefined { const reference = entry.node; if (getMeaningFromLocation(reference) === SemanticMeaning.Type || isExpressionWithTypeArgumentsInClassExtendsClause(reference.parent)) { return reference; diff --git a/src/services/refactors/convertStringOrTemplateLiteral.ts b/src/services/refactors/convertStringOrTemplateLiteral.ts index 712308df7bed2..3afbd3650597a 100644 --- a/src/services/refactors/convertStringOrTemplateLiteral.ts +++ b/src/services/refactors/convertStringOrTemplateLiteral.ts @@ -1,42 +1,54 @@ import { - ApplicableRefactorInfo, - BinaryExpression, - BinaryOperator, - copyTrailingAsLeadingComments, - copyTrailingComments, - Debug, - Diagnostics, emptyArray, - Expression, - factory, - findAncestor, - getLocaleSpecificMessage, - getTextOfNode, - getTokenAtPosition, - getTrailingCommentRanges, + map, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isBinaryExpression, isNoSubstitutionTemplateLiteral, isParenthesizedExpression, isStringLiteral, - isStringLiteralLike, isTemplateExpression, isTemplateHead, isTemplateMiddle, - map, +} from "../../compiler/factory/nodeTests"; +import { getTrailingCommentRanges } from "../../compiler/scanner"; +import { + BinaryExpression, + BinaryOperator, + Expression, Node, ParenthesizedExpression, - RefactorContext, - RefactorEditInfo, SourceFile, SyntaxKind, TemplateHead, TemplateMiddle, TemplateSpan, TemplateTail, - textChanges, Token, -} from "../_namespaces/ts"; -import { registerRefactor } from "../_namespaces/ts.refactor"; +} from "../../compiler/types"; +import { + getLocaleSpecificMessage, + getTextOfNode, +} from "../../compiler/utilities"; +import { + findAncestor, + isStringLiteralLike, +} from "../../compiler/utilitiesPublic"; +import { registerRefactor } from "../refactorProvider"; +import { ChangeTracker } from "../textChanges"; +import { + ApplicableRefactorInfo, + RefactorContext, + RefactorEditInfo, +} from "../types"; +import { + copyTrailingAsLeadingComments, + copyTrailingComments, + getTokenAtPosition, +} from "../utilities"; const refactorName = "Convert to template string"; const refactorDescription = getLocaleSpecificMessage(Diagnostics.Convert_to_template_string); @@ -111,13 +123,13 @@ function getEditsForToTemplateLiteral(context: RefactorContext, node: Node) { // 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 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 ChangeTracker.with(context, t => t.replaceNode(file, maybeBinary, templateLiteral)); } } diff --git a/src/services/refactors/convertToOptionalChainExpression.ts b/src/services/refactors/convertToOptionalChainExpression.ts index a86777e97dd63..0ae38bf75f4b9 100644 --- a/src/services/refactors/convertToOptionalChainExpression.ts +++ b/src/services/refactors/convertToOptionalChainExpression.ts @@ -1,51 +1,59 @@ +import { emptyArray } from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; import { - ApplicableRefactorInfo, - BinaryExpression, - CallExpression, - ConditionalExpression, - createTextSpanFromBounds, - Debug, - Diagnostics, - ElementAccessExpression, - emptyArray, - Expression, - ExpressionStatement, - factory, - findTokenOnLeftOfPosition, - getLocaleSpecificMessage, - getRefactorContextSpan, - getSingleVariableOfVariableStatement, - getTokenAtPosition, - Identifier, isBinaryExpression, isCallExpression, isConditionalExpression, isElementAccessExpression, isExpressionStatement, isIdentifier, - isOptionalChain, isPropertyAccessExpression, isReturnStatement, - isStringOrNumericLiteralLike, isVariableStatement, +} from "../../compiler/factory/nodeTests"; +import { + BinaryExpression, + CallExpression, + ConditionalExpression, + ElementAccessExpression, + Expression, + ExpressionStatement, + Identifier, Node, PropertyAccessExpression, - RefactorContext, - RefactorEditInfo, ReturnStatement, - skipParentheses, SourceFile, SyntaxKind, - textChanges, TextSpan, TypeChecker, VariableStatement, -} from "../_namespaces/ts"; +} from "../../compiler/types"; +import { + getLocaleSpecificMessage, + getSingleVariableOfVariableStatement, + isStringOrNumericLiteralLike, + skipParentheses, +} from "../../compiler/utilities"; import { - isRefactorErrorInfo, + createTextSpanFromBounds, + isOptionalChain, +} from "../../compiler/utilitiesPublic"; +import { registerRefactor } from "../refactorProvider"; +import { ChangeTracker } from "../textChanges"; +import { + ApplicableRefactorInfo, + RefactorContext, + RefactorEditInfo, RefactorErrorInfo, - registerRefactor, -} from "../_namespaces/ts.refactor"; +} from "../types"; +import { + findTokenOnLeftOfPosition, + getRefactorContextSpan, + getTokenAtPosition, +} from "../utilities"; +import { isRefactorErrorInfo } from "./helpers"; const refactorName = "Convert to optional chain expression"; const convertToOptionalChainExpressionMessage = getLocaleSpecificMessage(Diagnostics.Convert_to_optional_chain_expression); @@ -86,7 +94,7 @@ function getRefactorActionsToConvertToOptionalChain(context: RefactorContext): r function getRefactorEditsToConvertToOptionalChain(context: RefactorContext, actionName: string): RefactorEditInfo | undefined { const info = getInfo(context); Debug.assert(info && !isRefactorErrorInfo(info), "Expected applicable refactor info"); - const edits = textChanges.ChangeTracker.with(context, t => + const edits = ChangeTracker.with(context, t => doChange(context.file, context.program.getTypeChecker(), t, info, actionName) ); return { edits, renameFilename: undefined, renameLocation: undefined }; @@ -329,7 +337,7 @@ function convertOccurrences(checker: TypeChecker, toConvert: Expression, occurre return toConvert; } -function doChange(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, info: OptionalChainInfo, _actionName: string): void { +function doChange(sourceFile: SourceFile, checker: TypeChecker, changes: ChangeTracker, info: OptionalChainInfo, _actionName: string): void { const { finalExpression, occurrences, expression } = info; const firstOccurrence = occurrences[occurrences.length - 1]; const convertedChain = convertOccurrences(checker, finalExpression, occurrences); diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 276804acf15a2..6e020ae04d587 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1,96 +1,43 @@ import { - __String, - ANONYMOUS, - ApplicableRefactorInfo, + getNodeId, + getSymbolId, +} from "../../compiler/checkerUtilities"; +import { arrayFrom, assertType, - BindingElement, - Block, - BlockLike, - BreakStatement, - CancellationToken, - canHaveModifiers, - CharacterCodes, - ClassElement, - ClassLikeDeclaration, - codefix, compareProperties, compareStringsCaseSensitive, compareValues, contains, - ContinueStatement, - createDiagnosticForNode, - createFileDiagnostic, - Debug, - Declaration, - Diagnostic, - DiagnosticCategory, - DiagnosticMessage, - Diagnostics, - EmitFlags, emptyArray, - EntityName, - Expression, - ExpressionStatement, - factory, find, - findAncestor, - findFirstNonJsxWhitespaceToken, - findTokenOnLeftOfPosition, first, firstOrUndefined, - forEachChild, - formatStringFromArgs, - FunctionDeclaration, - FunctionLikeDeclaration, - getContainingClass, - getContainingFunction, - getEffectiveTypeParameterDeclarations, - getEmitScriptTarget, - getEnclosingBlockScopeContainer, - getLocaleSpecificMessage, - getModifiers, - getNodeId, - getParentNodeInSpan, - getRefactorContextSpan, - getRenameLocation, - getSymbolId, - getSynthesizedDeepClone, - getThisContainer, - getUniqueName, - hasEffectiveModifier, - hasSyntacticModifier, - Identifier, isArray, + last, + map, + singleOrUndefined, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { setEmitFlags } from "../../compiler/factory/emitNode"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrowFunction, - isAssignmentExpression, isBinaryExpression, isBlock, - isBlockScope, isCaseClause, - isClassLike, isConstructorDeclaration, - isDeclaration, - isDeclarationWithTypeParameters, isElementAccessExpression, - isExpression, - isExpressionNode, isExpressionStatement, - isFunctionBody, isFunctionExpression, - isFunctionLike, - isFunctionLikeDeclaration, isIdentifier, - isInJSFile, - isIterationStatement, isJsxAttribute, isJsxElement, isJsxFragment, isJsxSelfClosingElement, - isKeyword, isModuleBlock, isParenthesizedTypeNode, - isPartOfTypeNode, isPrivateIdentifier, isPropertyAccessExpression, isPropertyDeclaration, @@ -98,19 +45,39 @@ import { isReturnStatement, isShorthandPropertyAssignment, isSourceFile, - isStatement, - isStatic, isStringLiteral, isSwitchStatement, - isThis, - isUnaryExpressionWithWrite, isUnionTypeNode, isVariableDeclaration, isVariableDeclarationList, isVariableStatement, +} from "../../compiler/factory/nodeTests"; +import { canHaveModifiers } from "../../compiler/factory/utilitiesPublic"; +import { forEachChild } from "../../compiler/parser"; +import { nullTransformationContext } from "../../compiler/transformer"; +import { + __String, + BindingElement, + Block, + BlockLike, + BreakStatement, + CancellationToken, + CharacterCodes, + ClassElement, + ClassLikeDeclaration, + ContinueStatement, + Declaration, + Diagnostic, + DiagnosticCategory, + DiagnosticMessage, + EmitFlags, + EntityName, + Expression, + ExpressionStatement, + FunctionDeclaration, + FunctionLikeDeclaration, + Identifier, LabeledStatement, - last, - map, MethodDeclaration, Modifier, ModifierFlags, @@ -119,31 +86,19 @@ import { Node, NodeBuilderFlags, NodeFlags, - nullTransformationContext, ObjectLiteralElementLike, ParameterDeclaration, - positionIsSynthesized, PropertyAccessExpression, - rangeContainsStartEnd, - RefactorActionInfo, - RefactorContext, - RefactorEditInfo, - setEmitFlags, ShorthandPropertyAssignment, SignatureKind, - singleOrUndefined, - skipParentheses, SourceFile, Statement, StringLiteral, - suppressLeadingAndTrailingTrivia, Symbol, SymbolFlags, SyntaxKind, - textChanges, TextRange, TextSpan, - textSpanEnd, TryStatement, Type, TypeChecker, @@ -154,15 +109,75 @@ import { TypeParameter, TypeParameterDeclaration, VariableDeclaration, + VisitResult, +} from "../../compiler/types"; +import { + createDiagnosticForNode, + createFileDiagnostic, + formatStringFromArgs, + getContainingClass, + getContainingFunction, + getEmitScriptTarget, + getEnclosingBlockScopeContainer, + getLocaleSpecificMessage, + getThisContainer, + hasEffectiveModifier, + hasSyntacticModifier, + isAssignmentExpression, + isBlockScope, + isDeclarationWithTypeParameters, + isExpressionNode, + isInJSFile, + isKeyword, + isPartOfTypeNode, + isStatic, + positionIsSynthesized, + skipParentheses, +} from "../../compiler/utilities"; +import { + findAncestor, + getEffectiveTypeParameterDeclarations, + getModifiers, + isClassLike, + isDeclaration, + isExpression, + isFunctionBody, + isFunctionLike, + isFunctionLikeDeclaration, + isIterationStatement, + isStatement, + isUnaryExpressionWithWrite, + textSpanEnd, +} from "../../compiler/utilitiesPublic"; +import { visitEachChild, visitNode, visitNodes, - VisitResult, -} from "../_namespaces/ts"; +} from "../../compiler/visitorPublic"; +import { typeToAutoImportableTypeNode } from "../codefixes/helpers"; +import { createImportAdder } from "../codefixes/importAdder"; +import { registerRefactor } from "../refactorProvider"; +import { ChangeTracker } from "../textChanges"; +import { + ApplicableRefactorInfo, + RefactorActionInfo, + RefactorContext, + RefactorEditInfo, +} from "../types"; import { - refactorKindBeginsWith, - registerRefactor, -} from "../_namespaces/ts.refactor"; + ANONYMOUS, + findFirstNonJsxWhitespaceToken, + findTokenOnLeftOfPosition, + getParentNodeInSpan, + getRefactorContextSpan, + getRenameLocation, + getSynthesizedDeepClone, + getUniqueName, + isThis, + rangeContainsStartEnd, + suppressLeadingAndTrailingTrivia, +} from "../utilities"; +import { refactorKindBeginsWith } from "./helpers"; const refactorName = "Extract Symbol"; @@ -1034,7 +1049,7 @@ function extractFunctionInScope( const checker = context.program.getTypeChecker(); const scriptTarget = getEmitScriptTarget(context.program.getCompilerOptions()); - const importAdder = codefix.createImportAdder(context.file, context.program, context.preferences, context.host); + const importAdder = createImportAdder(context.file, context.program, context.preferences, context.host, /*useAutoImportProvider*/ false); // Make a unique name for the extracted function const file = scope.getSourceFile(); @@ -1053,7 +1068,7 @@ function extractFunctionInScope( 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 = typeToAutoImportableTypeNode(checker, importAdder, type, scope, scriptTarget, NodeBuilderFlags.NoTruncation); } const paramDecl = factory.createParameterDeclaration( @@ -1145,7 +1160,7 @@ function extractFunctionInScope( ); } - const changeTracker = textChanges.ChangeTracker.fromContext(context); + const changeTracker = ChangeTracker.fromContext(context); const minInsertionPos = (isReadonlyArray(range.range) ? last(range.range) : range.range).end; const nodeToInsertBefore = getNodeToInsertFunctionBefore(minInsertionPos, scope); if (nodeToInsertBefore) { @@ -1366,7 +1381,7 @@ function extractConstantInScope( suppressLeadingAndTrailingTrivia(initializer); - const changeTracker = textChanges.ChangeTracker.fromContext(context); + const changeTracker = ChangeTracker.fromContext(context); if (isClassLike(scope)) { Debug.assert(!isJS, "Cannot extract to a JS class"); // See CannotExtractToJSClass diff --git a/src/services/refactors/extractType.ts b/src/services/refactors/extractType.ts index 5172c5020d8e0..4cf64540f7963 100644 --- a/src/services/refactors/extractType.ts +++ b/src/services/refactors/extractType.ts @@ -1,72 +1,90 @@ import { addRange, - addToSeen, append, - ApplicableRefactorInfo, cast, concatenate, - createTextRangeFromSpan, - Debug, - Diagnostics, - EmitFlags, emptyArray, - factory, - findAncestor, forEach, - forEachChild, - getEffectiveConstraintOfTypeParameter, - getLineAndCharacterOfPosition, - getLocaleSpecificMessage, - getNameFromPropertyName, - getRefactorContextSpan, - getRenameLocation, - getTokenAtPosition, - getUniqueName, + pushIfUnique, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { ignoreSourceNewlines, + setEmitFlags, +} from "../../compiler/factory/emitNode"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isConditionalTypeNode, - isFunctionLike, isIdentifier, isInferTypeNode, isIntersectionTypeNode, isJSDocTypeExpression, isParenthesizedTypeNode, - isSourceFileJS, - isStatement, - isThisIdentifier, isThisTypeNode, isTupleTypeNode, isTypeLiteralNode, - isTypeNode, isTypeParameterDeclaration, isTypePredicateNode, isTypeQueryNode, isTypeReferenceNode, +} from "../../compiler/factory/nodeTests"; +import { setTextRange } from "../../compiler/factory/utilitiesPublic"; +import { forEachChild } from "../../compiler/parser"; +import { + getLineAndCharacterOfPosition, + skipTrivia, +} from "../../compiler/scanner"; +import { + EmitFlags, JSDocTag, JSDocTemplateTag, Node, - nodeOverlapsWithStartEnd, - pushIfUnique, - rangeContainsStartEnd, - RefactorContext, - RefactorEditInfo, - setEmitFlags, - setTextRange, - skipTrivia, SourceFile, Statement, SymbolFlags, - textChanges, TextRange, TypeChecker, TypeElement, TypeNode, TypeParameterDeclaration, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { - isRefactorErrorInfo, + addToSeen, + getLocaleSpecificMessage, + isSourceFileJS, + isThisIdentifier, +} from "../../compiler/utilities"; +import { + findAncestor, + getEffectiveConstraintOfTypeParameter, + isFunctionLike, + isStatement, + isTypeNode, +} from "../../compiler/utilitiesPublic"; +import { registerRefactor } from "../refactorProvider"; +import { + ChangeTracker, + LeadingTriviaOption, + TrailingTriviaOption, +} from "../textChanges"; +import { + ApplicableRefactorInfo, + RefactorContext, + RefactorEditInfo, RefactorErrorInfo, - registerRefactor, -} from "../_namespaces/ts.refactor"; +} from "../types"; +import { + createTextRangeFromSpan, + getNameFromPropertyName, + getRefactorContextSpan, + getRenameLocation, + getTokenAtPosition, + getUniqueName, + nodeOverlapsWithStartEnd, + rangeContainsStartEnd, +} from "../utilities"; +import { isRefactorErrorInfo } from "./helpers"; const refactorName = "Extract type"; @@ -125,7 +143,7 @@ registerRefactor(refactorName, { Debug.assert(info && !isRefactorErrorInfo(info), "Expected to find a range to extract"); const name = getUniqueName("NewType", file); - const edits = textChanges.ChangeTracker.with(context, changes => { + const edits = ChangeTracker.with(context, changes => { switch (actionName) { case extractToTypeAliasAction.name: Debug.assert(!info.isJS, "Invalid actionName/JS combo"); @@ -264,7 +282,7 @@ function collectTypeParameters(checker: TypeChecker, selection: TypeNode, statem } } -function doTypeAliasChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, info: TypeAliasInfo) { +function doTypeAliasChange(changes: ChangeTracker, file: SourceFile, name: string, info: TypeAliasInfo) { const { firstStatement, selection, typeParameters } = info; const newTypeNode = factory.createTypeAliasDeclaration( @@ -274,10 +292,10 @@ function doTypeAliasChange(changes: textChanges.ChangeTracker, file: SourceFile, 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 }); + changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))), { leadingTriviaOption: LeadingTriviaOption.Exclude, trailingTriviaOption: TrailingTriviaOption.ExcludeWhitespace }); } -function doInterfaceChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, info: InterfaceInfo) { +function doInterfaceChange(changes: ChangeTracker, file: SourceFile, name: string, info: InterfaceInfo) { const { firstStatement, selection, typeParameters, typeElements } = info; const newTypeNode = factory.createInterfaceDeclaration( @@ -289,10 +307,10 @@ function doInterfaceChange(changes: textChanges.ChangeTracker, file: SourceFile, ); 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 }); + changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))), { leadingTriviaOption: LeadingTriviaOption.Exclude, trailingTriviaOption: TrailingTriviaOption.ExcludeWhitespace }); } -function doTypedefChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, info: ExtractInfo) { +function doTypedefChange(changes: ChangeTracker, file: SourceFile, name: string, info: ExtractInfo) { const { firstStatement, selection, typeParameters } = info; setEmitFlags(selection, EmitFlags.NoComments | EmitFlags.NoNestedComments); diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index 2982cacd8af7c..0b7f330445339 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -1,18 +1,21 @@ +import { emptyArray } from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { - ApplicableRefactorInfo, - codefix, - Debug, - Diagnostics, - emptyArray, - getRenameLocation, isIdentifier, isParameter, - RefactorContext, -} from "../_namespaces/ts"; +} from "../../compiler/factory/nodeTests"; +import { + generateAccessorFromProperty, + getAccessorConvertiblePropertyAtPosition, +} from "../codefixes/generateAccessors"; +import { registerRefactor } from "../refactorProvider"; import { - isRefactorErrorInfo, - registerRefactor, -} from "../_namespaces/ts.refactor"; + ApplicableRefactorInfo, + RefactorContext, +} from "../types"; +import { getRenameLocation } from "../utilities"; +import { isRefactorErrorInfo } from "./helpers"; const actionName = "Generate 'get' and 'set' accessors"; const actionDescription = Diagnostics.Generate_get_and_set_accessors.message; @@ -26,9 +29,9 @@ 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); + const info = 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); + const edits = generateAccessorFromProperty(context.file, context.program, context.startPosition, context.endPosition, context, actionName); if (!edits) return undefined; const renameFilename = context.file.fileName; @@ -40,7 +43,7 @@ registerRefactor(actionName, { }, 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"); + const info = getAccessorConvertiblePropertyAtPosition(context.file, context.program, context.startPosition, context.endPosition, context.triggerReason === "invoked"); if (!info) return emptyArray; if (!isRefactorErrorInfo(info)) { diff --git a/src/services/refactors/helpers.ts b/src/services/refactors/helpers.ts index acafb54f1e36a..3e2e60a06ace0 100644 --- a/src/services/refactors/helpers.ts +++ b/src/services/refactors/helpers.ts @@ -1,12 +1,4 @@ - -/** - * Returned by refactor functions when some error message needs to be surfaced to users. - * - * @internal - */ -export interface RefactorErrorInfo { - error: string; -} +import { RefactorErrorInfo } from "../types"; /** * Checks if some refactor info has refactor error info. @@ -24,6 +16,6 @@ export function isRefactorErrorInfo(info: unknown): info is RefactorErrorInfo { * @internal */ 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 ccce34a8a14ac..23f99e320dc93 100644 --- a/src/services/refactors/inferFunctionReturnType.ts +++ b/src/services/refactors/inferFunctionReturnType.ts @@ -1,38 +1,48 @@ import { - ApplicableRefactorInfo, - ArrowFunction, - Diagnostics, emptyArray, - factory, - findAncestor, - findChildOfKind, first, - FunctionDeclaration, - FunctionExpression, - getLocaleSpecificMessage, - getTokenAtPosition, + mapDefined, +} from "../../compiler/core"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrowFunction, isBlock, - isInJSFile, - mapDefined, +} from "../../compiler/factory/nodeTests"; +import { + ArrowFunction, + FunctionDeclaration, + FunctionExpression, MethodDeclaration, Node, NodeBuilderFlags, - RefactorContext, - RefactorEditInfo, SourceFile, SyntaxKind, - textChanges, Type, TypeChecker, TypeNode, -} from "../_namespaces/ts"; +} from "../../compiler/types"; import { - isRefactorErrorInfo, + getLocaleSpecificMessage, + isInJSFile, +} from "../../compiler/utilities"; +import { findAncestor } from "../../compiler/utilitiesPublic"; +import { registerRefactor } from "../refactorProvider"; +import { ChangeTracker } from "../textChanges"; +import { + ApplicableRefactorInfo, + RefactorContext, + RefactorEditInfo, RefactorErrorInfo, +} from "../types"; +import { + findChildOfKind, + getTokenAtPosition, +} from "../utilities"; +import { + isRefactorErrorInfo, refactorKindBeginsWith, - registerRefactor, -} from "../_namespaces/ts.refactor"; +} from "./helpers"; const refactorName = "Infer function return type"; const refactorDescription = Diagnostics.Infer_function_return_type.message; @@ -51,7 +61,7 @@ registerRefactor(refactorName, { function getRefactorEditsToInferReturnType(context: RefactorContext): 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)); + const edits = ChangeTracker.with(context, t => doChange(context.file, t, info.declaration, info.returnTypeNode)); return { renameFilename: undefined, renameLocation: undefined, edits }; } return undefined; @@ -88,7 +98,7 @@ interface FunctionInfo { returnTypeNode: TypeNode; } -function doChange(sourceFile: SourceFile, changes: textChanges.ChangeTracker, declaration: ConvertibleDeclaration, typeNode: TypeNode) { +function doChange(sourceFile: SourceFile, changes: 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; diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index 937c31edadd7f..a63f1dbc1dddd 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -1,124 +1,96 @@ +import { getSymbolId } from "../../compiler/checkerUtilities"; import { - AnyImportOrRequireStatement, append, - ApplicableRefactorInfo, - AssignmentDeclarationKind, - BinaryExpression, - BindingElement, - BindingName, - CallExpression, - canHaveDecorators, - canHaveModifiers, cast, - ClassDeclaration, - codefix, - combinePaths, concatenate, contains, - copyEntries, - createTextRangeFromSpan, - Debug, - Declaration, - DeclarationStatement, - Diagnostics, emptyArray, - ensurePathIsNonModuleName, - EnumDeclaration, - escapeLeadingUnderscores, - Expression, - ExpressionStatement, - extensionFromPath, - ExternalModuleReference, - factory, find, - FindAllReferences, findIndex, firstDefined, flatMap, - forEachEntry, - FunctionDeclaration, - getAssignmentDeclarationKind, - getBaseFileName, GetCanonicalFileName, - getDecorators, - getDirectoryPath, - getLocaleSpecificMessage, - getModifiers, - getPropertySymbolFromBindingElement, - getQuotePreference, getRangesWhere, - getRefactorContextSpan, - getRelativePathFromFile, - getSymbolId, - getUniqueName, - hasSyntacticModifier, - hostGetCanonicalFileName, - Identifier, - ImportDeclaration, - ImportEqualsDeclaration, - insertImports, - InterfaceDeclaration, - InternalSymbolName, + last, + length, + mapDefined, + some, + takeWhile, + tryCast, +} from "../../compiler/core"; +import { Debug } from "../../compiler/debug"; +import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { factory } from "../../compiler/factory/nodeFactory"; +import { isArrayLiteralExpression, isBinaryExpression, isBindingElement, - isDeclarationName, isExpressionStatement, isExternalModuleReference, isIdentifier, isImportDeclaration, isImportEqualsDeclaration, - isNamedDeclaration, isObjectLiteralExpression, isOmittedExpression, - isPrologueDirective, isPropertyAccessExpression, isPropertyAssignment, - isRequireCall, isSourceFile, isStringLiteral, - isStringLiteralLike, isVariableDeclaration, isVariableDeclarationList, isVariableStatement, - LanguageServiceHost, - last, - length, - makeImportIfNecessary, - mapDefined, +} from "../../compiler/factory/nodeTests"; +import { + canHaveDecorators, + canHaveModifiers, +} from "../../compiler/factory/utilitiesPublic"; +import { + combinePaths, + ensurePathIsNonModuleName, + getBaseFileName, + getDirectoryPath, + getRelativePathFromFile, + normalizePath, +} from "../../compiler/path"; +import { + AnyImportOrRequireStatement, + AssignmentDeclarationKind, + BinaryExpression, + BindingElement, + BindingName, + CallExpression, + ClassDeclaration, + Declaration, + DeclarationStatement, + EnumDeclaration, + Expression, + ExpressionStatement, + ExternalModuleReference, + FunctionDeclaration, + Identifier, + ImportDeclaration, + ImportEqualsDeclaration, + InterfaceDeclaration, + InternalSymbolName, ModifierFlags, ModifierLike, ModuleDeclaration, NamedImportBindings, Node, NodeFlags, - nodeSeenTracker, - normalizePath, - ObjectBindingElementWithoutPropertyName, Program, PropertyAccessExpression, PropertyAssignment, - QuotePreference, - rangeContainsRange, - RefactorContext, - RefactorEditInfo, - removeFileExtension, RequireOrImportCall, RequireVariableStatement, ScriptTarget, - skipAlias, - some, SourceFile, Statement, StringLiteralLike, Symbol, SymbolFlags, - symbolNameNoDefault, SyntaxKind, - takeWhile, - textChanges, TransformFlags, - tryCast, TypeAliasDeclaration, TypeChecker, TypeNode, @@ -126,8 +98,52 @@ import { VariableDeclaration, VariableDeclarationList, VariableStatement, -} from "../_namespaces/ts"; -import { registerRefactor } from "../_namespaces/ts.refactor"; +} from "../../compiler/types"; +import { + copyEntries, + extensionFromPath, + forEachEntry, + getAssignmentDeclarationKind, + getLocaleSpecificMessage, + hasSyntacticModifier, + hostGetCanonicalFileName, + isDeclarationName, + isPrologueDirective, + isRequireCall, + removeFileExtension, + skipAlias, +} from "../../compiler/utilities"; +import { + escapeLeadingUnderscores, + getDecorators, + getModifiers, + isNamedDeclaration, + isStringLiteralLike, +} from "../../compiler/utilitiesPublic"; +import { moduleSpecifierToValidIdentifier } from "../codefixes/importAdder"; +import { Core as FindAllReferences } from "../findAllReferences"; +import { registerRefactor } from "../refactorProvider"; +import { ChangeTracker } from "../textChanges"; +import { + ApplicableRefactorInfo, + LanguageServiceHost, + RefactorContext, + RefactorEditInfo, +} from "../types"; +import { + createTextRangeFromSpan, + getPropertySymbolFromBindingElement, + getQuotePreference, + getRefactorContextSpan, + getUniqueName, + insertImports, + makeImportIfNecessary, + nodeSeenTracker, + ObjectBindingElementWithoutPropertyName, + QuotePreference, + rangeContainsRange, + symbolNameNoDefault, +} from "../utilities"; const refactorName = "Move to a new file"; const description = getLocaleSpecificMessage(Diagnostics.Move_to_a_new_file); @@ -154,7 +170,7 @@ registerRefactor(refactorName, { 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)); + const edits = ChangeTracker.with(context, t => doChange(context.file, context.program, statements, t, context.host, context.preferences)); return { edits, renameFilename: undefined, renameLocation: undefined }; } }); @@ -185,7 +201,7 @@ function getRangeToMove(context: RefactorContext): RangeToMove | undefined { }; } -function doChange(oldFile: SourceFile, program: Program, toMove: ToMove, changes: textChanges.ChangeTracker, host: LanguageServiceHost, preferences: UserPreferences): void { +function doChange(oldFile: SourceFile, program: Program, toMove: ToMove, changes: ChangeTracker, host: LanguageServiceHost, preferences: UserPreferences): void { const checker = program.getTypeChecker(); const usage = getUsageInfo(oldFile, toMove.all, checker); @@ -242,7 +258,7 @@ function isPureImport(node: Node): boolean { } } -function addNewFileToTsconfig(program: Program, changes: textChanges.ChangeTracker, oldFileName: string, newFileNameWithExtension: string, getCanonicalFileName: GetCanonicalFileName): void { +function addNewFileToTsconfig(program: Program, changes: ChangeTracker, oldFileName: string, newFileNameWithExtension: string, getCanonicalFileName: GetCanonicalFileName): void { const cfg = program.getCompilerOptions().configFile; if (!cfg) return; @@ -258,7 +274,7 @@ function addNewFileToTsconfig(program: Program, changes: textChanges.ChangeTrack } function getNewStatementsAndRemoveFromOldFile( - oldFile: SourceFile, usage: UsageInfo, changes: textChanges.ChangeTracker, toMove: ToMove, program: Program, newModuleName: string, preferences: UserPreferences, + oldFile: SourceFile, usage: UsageInfo, changes: ChangeTracker, toMove: ToMove, program: Program, newModuleName: string, preferences: UserPreferences, ) { const checker = program.getTypeChecker(); const prologueDirectives = takeWhile(oldFile.statements, isPrologueDirective); @@ -296,20 +312,20 @@ function getNewStatementsAndRemoveFromOldFile( ]; } -function deleteMovedStatements(sourceFile: SourceFile, moved: readonly StatementRange[], changes: textChanges.ChangeTracker) { +function deleteMovedStatements(sourceFile: SourceFile, moved: readonly StatementRange[], changes: 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: SourceFile, toMove: readonly Statement[], changes: ChangeTracker, toDelete: ReadonlySymbolSet, checker: TypeChecker) { for (const statement of oldFile.statements) { if (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: ChangeTracker, program: Program, oldFile: SourceFile, movedSymbols: ReadonlySymbolSet, newModuleName: string): void { const checker = program.getTypeChecker(); for (const sourceFile of program.getSourceFiles()) { if (sourceFile === oldFile) continue; @@ -350,7 +366,7 @@ function getNamespaceLikeImport(node: SupportedImport): Identifier | undefined { } function updateNamespaceLikeImport( - changes: textChanges.ChangeTracker, + changes: ChangeTracker, sourceFile: SourceFile, checker: TypeChecker, movedSymbols: ReadonlySymbolSet, @@ -359,10 +375,10 @@ function updateNamespaceLikeImport( oldImportId: Identifier, oldImportNode: SupportedImport, ): void { - const preferredNewNamespaceName = codefix.moduleSpecifierToValidIdentifier(newModuleName, ScriptTarget.ESNext); + const preferredNewNamespaceName = moduleSpecifierToValidIdentifier(newModuleName, ScriptTarget.ESNext); let needUniqueName = false; const toChange: Identifier[] = []; - FindAllReferences.Core.eachSymbolReferenceInFile(oldImportId, checker, sourceFile, ref => { + FindAllReferences.eachSymbolReferenceInFile(oldImportId, checker, sourceFile, ref => { if (!isPropertyAccessExpression(ref.parent)) return; needUniqueName = needUniqueName || !!checker.resolveName(preferredNewNamespaceName, ref, SymbolFlags.All, /*excludeGlobals*/ true); if (movedSymbols.has(checker.getSymbolAtLocation(ref.parent.name)!)) { @@ -480,7 +496,7 @@ function addExports(sourceFile: SourceFile, toMove: readonly Statement[], needEx }); } -function deleteUnusedImports(sourceFile: SourceFile, importDecl: SupportedImport, changes: textChanges.ChangeTracker, isUnused: (name: Identifier) => boolean): void { +function deleteUnusedImports(sourceFile: SourceFile, importDecl: SupportedImport, changes: ChangeTracker, isUnused: (name: Identifier) => boolean): void { switch (importDecl.kind) { case SyntaxKind.ImportDeclaration: deleteUnusedImportsInDeclaration(sourceFile, importDecl, changes, isUnused); @@ -497,7 +513,7 @@ function deleteUnusedImports(sourceFile: SourceFile, importDecl: SupportedImport 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 { +function deleteUnusedImportsInDeclaration(sourceFile: SourceFile, importDecl: ImportDeclaration, changes: ChangeTracker, isUnused: (name: Identifier) => boolean): void { if (!importDecl.importClause) return; const { name, namedBindings } = importDecl.importClause; const defaultUnused = !name || isUnused(name); @@ -526,7 +542,7 @@ function deleteUnusedImportsInDeclaration(sourceFile: SourceFile, importDecl: Im } } } -function deleteUnusedImportsInVariableDeclaration(sourceFile: SourceFile, varDecl: VariableDeclaration, changes: textChanges.ChangeTracker, isUnused: (name: Identifier) => boolean) { +function deleteUnusedImportsInVariableDeclaration(sourceFile: SourceFile, varDecl: VariableDeclaration, changes: ChangeTracker, isUnused: (name: Identifier) => boolean) { const { name } = varDecl; switch (name.kind) { case SyntaxKind.Identifier: @@ -562,7 +578,7 @@ function getNewFileImportsAndAddExportInOldFile( oldFile: SourceFile, importsToCopy: ReadonlySymbolSet, newFileImportsFromOldFile: ReadonlySymbolSet, - changes: textChanges.ChangeTracker, + changes: ChangeTracker, checker: TypeChecker, useEsModuleSyntax: boolean, quotePreference: QuotePreference, @@ -900,7 +916,7 @@ function getTopLevelDeclarationStatement(d: TopLevelDeclaration): TopLevelDeclar } } -function addExportToChanges(sourceFile: SourceFile, decl: TopLevelDeclarationStatement, name: Identifier, changes: textChanges.ChangeTracker, useEs6Exports: boolean): void { +function addExportToChanges(sourceFile: SourceFile, decl: TopLevelDeclarationStatement, name: Identifier, changes: ChangeTracker, useEs6Exports: boolean): void { if (isExported(sourceFile, decl, useEs6Exports, name)) return; if (useEs6Exports) { if (!isExpressionStatement(decl)) changes.insertExportModifier(sourceFile, decl); diff --git a/src/services/rename.ts b/src/services/rename.ts index 52ee0b8a3f544..f8f556c411662 100644 --- a/src/services/rename.ts +++ b/src/services/rename.ts @@ -1,57 +1,74 @@ import { compareStringsCaseSensitive, - Comparison, - createTextSpan, - DiagnosticMessage, - Diagnostics, endsWith, every, - Extension, - fileExtensionIs, find, - getAdjustedRenameLocation, - getContextualTypeFromParentOrAncestorTypeNode, - getLocaleSpecificMessage, - getPathComponents, - getTextOfIdentifierOrLiteral, - getTextOfNode, - getTouchingPropertyName, - ImportSpecifier, - isExternalModuleNameRelative, + some, + tryRemoveSuffix, +} from "../compiler/core"; +import { Comparison } from "../compiler/corePublic"; +import { Diagnostics } from "../compiler/diagnosticInformationMap.generated"; +import { isIdentifier, - isImportOrExportSpecifierName, isImportSpecifier, - isInsideNodeModules, - isLabelName, - isLiteralNameOfPropertyDeclarationOrIndexAccess, isSourceFile, - isStringLiteralLike, - isStringOrNumericLiteralLike, +} from "../compiler/factory/nodeTests"; +import { + fileExtensionIs, + getPathComponents, +} from "../compiler/path"; +import { + DiagnosticMessage, + Extension, + ImportSpecifier, Node, NumericLiteral, Path, Program, - removeFileExtension, - RenameInfo, - RenameInfoFailure, - RenameInfoSuccess, - ScriptElementKind, - ScriptElementKindModifier, - some, SourceFile, StringLiteralLike, - stripQuotes, Symbol, - SymbolDisplay, SymbolFlags, SyntaxKind, - tryGetImportFromModuleSpecifier, - tryRemoveSuffix, TypeChecker, TypeFlags, UnionType, UserPreferences, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + getLocaleSpecificMessage, + getTextOfIdentifierOrLiteral, + getTextOfNode, + isStringOrNumericLiteralLike, + removeFileExtension, + stripQuotes, + tryGetImportFromModuleSpecifier, +} from "../compiler/utilities"; +import { + createTextSpan, + isExternalModuleNameRelative, + isStringLiteralLike, +} from "../compiler/utilitiesPublic"; +import { + getSymbolKind, + getSymbolModifiers, +} from "./symbolDisplay"; +import { + RenameInfo, + RenameInfoFailure, + RenameInfoSuccess, + ScriptElementKind, + ScriptElementKindModifier, +} from "./types"; +import { + getAdjustedRenameLocation, + getContextualTypeFromParentOrAncestorTypeNode, + getTouchingPropertyName, + isImportOrExportSpecifierName, + isInsideNodeModules, + isLabelName, + isLiteralNameOfPropertyDeclarationOrIndexAccess, +} from "./utilities"; /** @internal */ export function getRenameInfo(program: Program, sourceFile: SourceFile, position: number, preferences: UserPreferences): RenameInfo { @@ -111,13 +128,13 @@ function getRenameInfoForNode( return getRenameInfoError(wouldRenameNodeModules); } - const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node); + const kind = getSymbolKind(typeChecker, symbol, node); const specifierName = (isImportOrExportSpecifierName(node) || isStringOrNumericLiteralLike(node) && node.parent.kind === SyntaxKind.ComputedPropertyName) ? stripQuotes(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, getSymbolModifiers(typeChecker,symbol), node, sourceFile); } function isDefinedInLibraryFile(program: Program, declaration: Node) { diff --git a/src/services/services.ts b/src/services/services.ts index 41b3c78172ad1..fffd74afb99e2 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1,160 +1,45 @@ -import * as ts from "./_namespaces/ts"; -import * as NavigateTo from "./_namespaces/ts.NavigateTo"; -import * as NavigationBar from "./_namespaces/ts.NavigationBar"; +import { getFileEmitOutput } from "../compiler/builderState"; +import { + ParseConfigFileHost, + parseJsonSourceFileConfigFileContent, +} from "../compiler/commandLineParser"; import { - __String, - ApplicableRefactorInfo, - ApplyCodeActionCommandResult, - AssignmentDeclarationKind, - BaseType, - BinaryExpression, - BreakpointResolver, - CallHierarchy, - CallHierarchyIncomingCall, - CallHierarchyItem, - CallHierarchyOutgoingCall, - CancellationToken, - changeCompilerHostLikeToUseCache, - CharacterCodes, - CheckJsDirective, - Classifications, - ClassifiedSpan, - ClassifiedSpan2020, - classifier, - CodeActionCommand, - codefix, - CodeFixAction, - CombinedCodeActions, - CombinedCodeFixScope, - combinePaths, compareValues, - CompilerHost, - CompilerOptions, - CompletionEntryData, - CompletionEntryDetails, - CompletionInfo, - Completions, - computePositionOfLineAndCharacter, - computeSuggestionDiagnostics, - createDocumentRegistry, createGetCanonicalFileName, createMultiMap, - createProgram, - CreateProgramOptions, - createSourceFile, - CreateSourceFileOptions, - createTextSpanFromBounds, - createTextSpanFromNode, - createTextSpanFromRange, - Debug, - Declaration, deduplicate, - DefinitionInfo, - DefinitionInfoAndBoundSpan, - Diagnostic, - DiagnosticWithLocation, - directoryProbablyExists, - DocCommentTemplateOptions, - DocumentHighlights, - DocumentRegistry, - DocumentSpan, - EditorOptions, - EditorSettings, - ElementAccessExpression, - EmitTextWriter, emptyArray, - emptyOptions, - EndOfFileToken, - EntityName, equateValues, - ExportDeclaration, - FileReference, - FileTextChanges, filter, find, - FindAllReferences, - findChildOfKind, - findPrecedingToken, first, firstDefined, - firstOrOnly, flatMap, forEach, - forEachChild, - FormatCodeOptions, - FormatCodeSettings, - formatting, - FunctionLikeDeclaration, - GeneratedIdentifierFlags, - getAdjustedRenameLocation, - getAllSuperTypeNodes, - getAssignmentDeclarationKind, - GetCompletionsAtPositionOptions, - getContainerNode, - getDefaultLibFileName, - getDirectoryPath, - getEmitDeclarations, getEntries, - getEscapedTextOfIdentifierOrLiteral, - getFileEmitOutput, - getImpliedNodeFormatForFile, - getJSDocTags, - getLineAndCharacterOfPosition, - getLineStarts, - getMappedDocumentSpan, - getNameFromPropertyName, - getNewLineCharacter, - getNewLineOrDefaultFromHost, - getNonAssignedNameOfDeclaration, - getNormalizedAbsolutePath, - getObjectFlags, - getScriptKind, - getSetExternalModuleIndicator, - getSnapshotText, - getSourceFileOfNode, - getSourceMapper, - getTokenPosOfNode, - getTouchingPropertyName, - getTouchingToken, - GoToDefinition, - HasInvalidatedResolutions, - hasJSDocNodes, hasProperty, - hasStaticModifier, - hasSyntacticModifier, - HighlightSpanKind, - HostCancellationToken, - hostGetCanonicalFileName, - hostUsesCaseSensitiveFileNames, - Identifier, identity, - idText, - ImplementationLocation, - ImportDeclaration, - IndexKind, - IndexType, - InlayHint, - InlayHints, - InlayHintsContext, insertSorted, - InterfaceType, - IntersectionType, isArray, - isBindingPattern, + lastOrUndefined, + length, + map, + mapDefined, + maybeBind, + noop, + returnFalse, + singleElementArray, + stringContains, +} from "../compiler/core"; +import { + MapLike, + Push, + SortedArray, +} from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { isComputedPropertyName, - isConstTypeReference, - IScriptSnapshot, - isDeclarationName, - isGetAccessor, isIdentifier, - isImportMeta, - isInComment, - isInsideJsxElement, - isInsideJsxElementOrAttribute, - isInString, - isInTemplateString, - isIntrinsicJsxName, - isJSDocCommentContainingNode, isJsxAttributes, isJsxClosingElement, isJsxElement, @@ -162,146 +47,122 @@ import { isJsxOpeningElement, isJsxOpeningFragment, isJsxText, - isLabelName, - isLiteralComputedPropertyDeclarationName, isNamedExports, isNamedTupleMember, - isNameOfModuleDeclaration, isNewExpression, - isNodeKind, - isObjectLiteralElement, isObjectLiteralExpression, isPrivateIdentifier, - isProgramUptoDate, isPropertyAccessExpression, - isPropertyName, - isRightSideOfPropertyAccess, - isRightSideOfQualifiedName, - isSetAccessor, - isStringOrNumericLiteralLike, - isTagName, - isTextWhiteSpaceLike, - isThisTypeParameter, - JsDoc, +} from "../compiler/factory/nodeTests"; +import { ModeAwareCache } from "../compiler/moduleNameResolver"; +import { + createSourceFile, + CreateSourceFileOptions, + forEachChild, + tagNamesAreEquivalent, + updateSourceFile, +} from "../compiler/parser"; +import { + combinePaths, + getDirectoryPath, + getNormalizedAbsolutePath, + normalizePath, + toPath, +} from "../compiler/path"; +import { timestamp } from "../compiler/performanceCore"; +import { + changeCompilerHostLikeToUseCache, + createProgram, + getImpliedNodeFormatForFile, + isProgramUptoDate, +} from "../compiler/program"; +import { + computePositionOfLineAndCharacter, + getLineAndCharacterOfPosition, + getLineStarts, +} from "../compiler/scanner"; +import { sys } from "../compiler/sys"; +import { tracing } from "../compiler/tracing"; +import { + __String, + AssignmentDeclarationKind, + BaseType, + BinaryExpression, + CancellationToken, + CharacterCodes, + CheckJsDirective, + CompilerHost, + CompilerOptions, + CreateProgramOptions, + Declaration, + Diagnostic, + DiagnosticWithLocation, + ElementAccessExpression, + EmitTextWriter, + EndOfFileToken, + EntityName, + ExportDeclaration, + FileReference, + FunctionLikeDeclaration, + GeneratedIdentifierFlags, + HasInvalidatedResolutions, + Identifier, + ImportDeclaration, + IndexKind, + IndexType, + InterfaceType, + IntersectionType, JSDoc, JSDocContainer, - JSDocTagInfo, JsonSourceFile, JsxAttributes, - JsxClosingTagInfo, JsxElement, JsxEmit, JsxFragment, - LanguageService, - LanguageServiceHost, - LanguageServiceMode, LanguageVariant, - lastOrUndefined, - length, LineAndCharacter, - lineBreakPart, LiteralType, - map, - mapDefined, - MapLike, - mapOneOrMany, - maybeBind, - maybeSetLocalizedDiagnosticMessages, - ModeAwareCache, ModifierFlags, ModuleDeclaration, - NavigateToItem, - NavigationBarItem, - NavigationTree, Node, NodeArray, NodeFlags, - noop, - normalizePath, NumberLiteralType, NumericLiteral, - ObjectAllocator, ObjectFlags, ObjectLiteralElement, ObjectLiteralExpression, OperationCanceledException, - OrganizeImports, - OrganizeImportsArgs, - OrganizeImportsMode, - OutliningElementsCollector, - OutliningSpan, - ParseConfigFileHost, ParsedCommandLine, - parseJsonSourceFileConfigFileContent, Path, - positionIsSynthesized, - PossibleProgramFileInfo, PragmaMap, PrivateIdentifier, Program, PropertyName, - Push, - QuickInfo, - refactor, - RefactorContext, - RefactorEditInfo, - RefactorTriggerReason, - ReferencedSymbol, - ReferenceEntry, - Rename, - RenameInfo, - RenameInfoOptions, - RenameLocation, ResolvedModuleFull, ResolvedProjectReference, ResolvedTypeReferenceDirective, - returnFalse, - scanner, - ScriptElementKind, - ScriptElementKindModifier, ScriptKind, ScriptTarget, - SelectionRange, - SemanticClassificationFormat, - setObjectAllocator, Signature, SignatureDeclaration, SignatureFlags, - SignatureHelp, - SignatureHelpItems, - SignatureHelpItemsOptions, SignatureKind, - singleElementArray, - SmartSelectionRange, - SortedArray, SourceFile, SourceFileLike, SourceMapSource, Statement, - stringContains, StringLiteral, StringLiteralLike, StringLiteralType, Symbol, - SymbolDisplay, - SymbolDisplayPart, SymbolFlags, - symbolName, SyntaxKind, SyntaxList, - tagNamesAreEquivalent, - TextChange, TextChangeRange, - TextInsertion, TextRange, TextSpan, - textSpanEnd, - timestamp, - TodoComment, - TodoCommentDescriptor, Token, - toPath, - tracing, TransformFlags, TransientSymbol, Type, @@ -311,14 +172,198 @@ import { TypeParameter, TypePredicate, TypeReference, - typeToDisplayParts, UnderscoreEscapedMap, UnionOrIntersectionType, UnionType, - updateSourceFile, UserPreferences, VariableDeclaration, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + directoryProbablyExists, + getAllSuperTypeNodes, + getAssignmentDeclarationKind, + getEmitDeclarations, + getEscapedTextOfIdentifierOrLiteral, + getNewLineCharacter, + getObjectFlags, + getSetExternalModuleIndicator, + getSourceFileOfNode, + getTokenPosOfNode, + hasStaticModifier, + hasSyntacticModifier, + hostGetCanonicalFileName, + hostUsesCaseSensitiveFileNames, + isDeclarationName, + isImportMeta, + isIntrinsicJsxName, + isLiteralComputedPropertyDeclarationName, + isStringOrNumericLiteralLike, + isThisTypeParameter, + maybeSetLocalizedDiagnosticMessages, + ObjectAllocator, + positionIsSynthesized, + setObjectAllocator, +} from "../compiler/utilities"; +import { + createTextSpanFromBounds, + getDefaultLibFileName, + getJSDocTags, + getNonAssignedNameOfDeclaration, + hasJSDocNodes, + idText, + isBindingPattern, + isConstTypeReference, + isGetAccessor, + isJSDocCommentContainingNode, + isNodeKind, + isObjectLiteralElement, + isPropertyName, + isSetAccessor, + symbolName, + textSpanEnd, +} from "../compiler/utilitiesPublic"; +import { spanInSourceFileAtLocation } from "./breakpoints"; +import { + createCallHierarchyItem, + getIncomingCalls, + getOutgoingCalls, + resolveCallHierarchyDeclaration, +} from "./callHierarchy"; +import * as classifier from "./classifier"; +import * as classifier2020 from "./classifier2020"; +import { + getAllFixes, + getFixes, + getSupportedErrorCodes, +} from "./codeFixProvider"; +import * as completions from "./completions"; +import * as documentHighlights from "./documentHighlights"; +import { + createDocumentRegistry, + DocumentRegistry, +} from "./documentRegistry"; +import * as FindAllReferences from "./findAllReferences"; +import * as formatting from "./formatting/formatting"; +import { getFormatContext } from "./formatting/formatting"; +import { SmartIndenter } from "./formatting/smartIndenter"; +import * as EditsForFileRename from "./getEditsForFileRename"; +import * as GoToDefinition from "./goToDefinition"; +import * as InlayHints from "./inlayHints"; +import * as JsDoc from "./jsDoc"; +import * as NavigateTo from "./navigateTo"; +import * as NavigationBar from "./navigationBar"; +import * as OrganizeImports from "./organizeImports"; +import * as OutliningElementsCollector from "./outliningElementsCollector"; +import * as refactor from "./refactorProvider"; +import * as Rename from "./rename"; +import * as SignatureHelp from "./signatureHelp"; +import * as SmartSelectionRange from "./smartSelection"; +import { getSourceMapper } from "./sourcemaps"; +import { computeSuggestionDiagnostics } from "./suggestionDiagnostics"; +import { + getSymbolDisplayPartsDocumentationAndSymbolKind, + getSymbolModifiers, +} from "./symbolDisplay"; +import { + ApplicableRefactorInfo, + ApplyCodeActionCommandResult, + CallHierarchyIncomingCall, + CallHierarchyItem, + CallHierarchyOutgoingCall, + Classifications, + ClassifiedSpan, + ClassifiedSpan2020, + CodeActionCommand, + CodeFixAction, + CombinedCodeActions, + CombinedCodeFixScope, + CompletionEntryData, + CompletionEntryDetails, + CompletionInfo, + DefinitionInfo, + DefinitionInfoAndBoundSpan, + DocCommentTemplateOptions, + DocumentHighlights, + DocumentSpan, + EditorOptions, + EditorSettings, + emptyOptions, + FileTextChanges, + FormatCodeOptions, + FormatCodeSettings, + GetCompletionsAtPositionOptions, + HighlightSpanKind, + HostCancellationToken, + ImplementationLocation, + InlayHint, + InlayHintsContext, + IScriptSnapshot, + JSDocTagInfo, + JsxClosingTagInfo, + LanguageService, + LanguageServiceHost, + LanguageServiceMode, + NavigateToItem, + NavigationBarItem, + NavigationTree, + OrganizeImportsArgs, + OrganizeImportsMode, + OutliningSpan, + QuickInfo, + RefactorContext, + RefactorEditInfo, + RefactorTriggerReason, + ReferencedSymbol, + ReferenceEntry, + RenameInfo, + RenameInfoOptions, + RenameLocation, + ScriptElementKind, + ScriptElementKindModifier, + SelectionRange, + SemanticClassificationFormat, + SignatureHelpItems, + SignatureHelpItemsOptions, + SymbolDisplayPart, + TextChange, + TextInsertion, + TodoComment, + TodoCommentDescriptor, +} from "./types"; +import { + createTextSpanFromNode, + createTextSpanFromRange, + findChildOfKind, + findPrecedingToken, + firstOrOnly, + getAdjustedRenameLocation, + getContainerNode, + getMappedDocumentSpan, + getNameFromPropertyName, + getNewLineOrDefaultFromHost, + getRangeOfEnclosingComment, + getScriptKind, + getSnapshotText, + getTouchingPropertyName, + getTouchingToken, + isInComment, + isInsideJsxElement, + isInsideJsxElementOrAttribute, + isInString, + isInTemplateString, + isLabelName, + isNameOfModuleDeclaration, + isRightSideOfPropertyAccess, + isRightSideOfQualifiedName, + isTagName, + isTextWhiteSpaceLike, + lineBreakPart, + mapOneOrMany, + PossibleProgramFileInfo, + scanner, + toContextSpan, + typeToDisplayParts, +} from "./utilities"; /** The version of the language service API */ export const servicesVersion = "0.8"; @@ -1308,7 +1353,7 @@ export function getDefaultCompilerOptions(): CompilerOptions { } export function getSupportedCodeFixes() { - return codefix.getSupportedErrorCodes(); + return getSupportedErrorCodes(); } class SyntaxTreeCache { @@ -1971,7 +2016,7 @@ export function createLanguageService( includeCompletionsWithInsertText: options.includeCompletionsWithInsertText || options.includeInsertTextCompletions, }; synchronizeHostData(); - return Completions.getCompletionsAtPosition( + return completions.getCompletionsAtPosition( host, program, log, @@ -1981,19 +2026,19 @@ export function createLanguageService( options.triggerCharacter, options.triggerKind, cancellationToken, - formattingSettings && formatting.getFormatContext(formattingSettings, host)); + formattingSettings && getFormatContext(formattingSettings, host)); } function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions: FormatCodeSettings | undefined, source: string | undefined, preferences: UserPreferences = emptyOptions, data?: CompletionEntryData): CompletionEntryDetails | undefined { synchronizeHostData(); - return Completions.getCompletionEntryDetails( + return completions.getCompletionEntryDetails( program, log, getValidSourceFile(fileName), position, { name, source, data }, host, - (formattingOptions && formatting.getFormatContext(formattingOptions, host))!, // TODO: GH#18217 + (formattingOptions && getFormatContext(formattingOptions, host))!, // TODO: GH#18217 preferences, cancellationToken, ); @@ -2001,7 +2046,7 @@ export function createLanguageService( function getCompletionEntrySymbol(fileName: string, position: number, name: string, source?: string, preferences: UserPreferences = emptyOptions): Symbol | undefined { synchronizeHostData(); - return Completions.getCompletionEntrySymbol(program, log, getValidSourceFile(fileName), position, { name, source }, host, preferences); + return completions.getCompletionEntrySymbol(program, log, getValidSourceFile(fileName), position, { name, source }, host, preferences); } function getQuickInfoAtPosition(fileName: string, position: number): QuickInfo | undefined { @@ -2031,11 +2076,11 @@ export function createLanguageService( } const { symbolKind, displayParts, documentation, tags } = typeChecker.runWithCancellationToken(cancellationToken, typeChecker => - SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, getContainerNode(nodeForQuickInfo), nodeForQuickInfo) + getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, getContainerNode(nodeForQuickInfo), nodeForQuickInfo) ); return { kind: symbolKind, - kindModifiers: SymbolDisplay.getSymbolModifiers(typeChecker, symbol), + kindModifiers: getSymbolModifiers(typeChecker, symbol), textSpan: createTextSpanFromNode(nodeForQuickInfo, sourceFile), displayParts, documentation, @@ -2119,7 +2164,7 @@ export function createLanguageService( synchronizeHostData(); const sourceFilesToSearch = mapDefined(filesToSearch, fileName => program.getSourceFile(fileName)); const sourceFile = getValidSourceFile(fileName); - return DocumentHighlights.getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch); + return documentHighlights.getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch); } function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): RenameLocation[] | undefined { @@ -2134,7 +2179,7 @@ export function createLanguageService( return { fileName: sourceFile.fileName, textSpan, - ...FindAllReferences.toContextSpan(textSpan, sourceFile, node.parent) + ...toContextSpan(textSpan, sourceFile, node.parent) }; }); } @@ -2261,8 +2306,7 @@ export function createLanguageService( function getBreakpointStatementAtPosition(fileName: string, position: number): TextSpan | undefined { // doesn't use compiler - no need to synchronize with host const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - - return BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position); + return spanInSourceFileAtLocation(sourceFile, position); } function getNavigationBarItems(fileName: string): NavigationBarItem[] { @@ -2279,10 +2323,10 @@ export function createLanguageService( const responseFormat = format || SemanticClassificationFormat.Original; if (responseFormat === SemanticClassificationFormat.TwentyTwenty) { - return classifier.v2020.getSemanticClassifications(program, cancellationToken, getValidSourceFile(fileName), span); + return classifier2020.getSemanticClassifications(program, cancellationToken, getValidSourceFile(fileName), span); } else { - return ts.getSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span); + return classifier.getSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span); } } @@ -2291,21 +2335,21 @@ export function createLanguageService( const responseFormat = format || SemanticClassificationFormat.Original; if (responseFormat === SemanticClassificationFormat.Original) { - return ts.getEncodedSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span); + return classifier.getEncodedSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span); } else { - return classifier.v2020.getEncodedSemanticClassifications(program, cancellationToken, getValidSourceFile(fileName), span); + return classifier2020.getEncodedSemanticClassifications(program, cancellationToken, getValidSourceFile(fileName), span); } } function getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] { // doesn't use compiler - no need to synchronize with host - return ts.getSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); + return classifier.getSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); } function getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications { // doesn't use compiler - no need to synchronize with host - return ts.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); + return classifier.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); } function getOutliningSpans(fileName: string): OutliningSpan[] { @@ -2339,7 +2383,7 @@ export function createLanguageService( start = timestamp(); - const result = formatting.SmartIndenter.getIndentation(position, sourceFile, settings); + const result = SmartIndenter.getIndentation(position, sourceFile, settings); log("getIndentationAtPosition: computeIndentation : " + (timestamp() - start)); return result; @@ -2347,16 +2391,16 @@ export function createLanguageService( function getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions | FormatCodeSettings): TextChange[] { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - return formatting.formatSelection(start, end, sourceFile, formatting.getFormatContext(toEditorSettings(options), host)); + return formatting.formatSelection(start, end, sourceFile, getFormatContext(toEditorSettings(options), host)); } function getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[] { - return formatting.formatDocument(syntaxTreeCache.getCurrentSourceFile(fileName), formatting.getFormatContext(toEditorSettings(options), host)); + return formatting.formatDocument(syntaxTreeCache.getCurrentSourceFile(fileName), getFormatContext(toEditorSettings(options), host)); } function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[] { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const formatContext = formatting.getFormatContext(toEditorSettings(options), host); + const formatContext = getFormatContext(toEditorSettings(options), host); if (!isInComment(sourceFile, position)) { switch (key) { @@ -2378,11 +2422,11 @@ export function createLanguageService( synchronizeHostData(); const sourceFile = getValidSourceFile(fileName); const span = createTextSpanFromBounds(start, end); - const formatContext = formatting.getFormatContext(formatOptions, host); + const formatContext = getFormatContext(formatOptions, host); return flatMap(deduplicate(errorCodes, equateValues, compareValues), errorCode => { cancellationToken.throwIfCancellationRequested(); - return codefix.getFixes({ errorCode, sourceFile, span, program, host, cancellationToken, formatContext, preferences }); + return getFixes({ errorCode, sourceFile, span, program, host, cancellationToken, formatContext, preferences }); }); } @@ -2390,23 +2434,23 @@ export function createLanguageService( synchronizeHostData(); Debug.assert(scope.type === "file"); const sourceFile = getValidSourceFile(scope.fileName); - const formatContext = formatting.getFormatContext(formatOptions, host); + const formatContext = getFormatContext(formatOptions, host); - return codefix.getAllFixes({ fixId, sourceFile, program, host, cancellationToken, formatContext, preferences }); + return getAllFixes({ fixId, sourceFile, program, host, cancellationToken, formatContext, preferences }); } function organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences = emptyOptions): readonly FileTextChanges[] { synchronizeHostData(); Debug.assert(args.type === "file"); const sourceFile = getValidSourceFile(args.fileName); - const formatContext = formatting.getFormatContext(formatOptions, host); + const formatContext = getFormatContext(formatOptions, host); const mode = args.mode ?? (args.skipDestructiveCodeActions ? OrganizeImportsMode.SortAndCombine : OrganizeImportsMode.All); return OrganizeImports.organizeImports(sourceFile, formatContext, host, program, preferences, mode); } 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); + return EditsForFileRename.getEditsForFileRename(getProgram()!, oldFilePath, newFilePath, host, getFormatContext(formatOptions, host), preferences, sourceMapper); } function applyCodeActionCommand(action: CodeActionCommand, formatSettings?: FormatCodeSettings): Promise; @@ -2729,7 +2773,7 @@ export function createLanguageService( function getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan | undefined { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const range = formatting.getRangeOfEnclosingComment(sourceFile, position); + const range = getRangeOfEnclosingComment(sourceFile, position); return range && (!onlyMultiLine || range.kind === SyntaxKind.MultiLineCommentTrivia) ? createTextSpanFromRange(range) : undefined; } @@ -2893,7 +2937,7 @@ export function createLanguageService( endPosition, program: getProgram()!, host, - formatContext: formatting.getFormatContext(formatOptions!, host), // TODO: GH#18217 + formatContext: getFormatContext(formatOptions!, host), // TODO: GH#18217 cancellationToken, preferences, triggerReason, @@ -2948,22 +2992,22 @@ export function createLanguageService( function prepareCallHierarchy(fileName: string, position: number): CallHierarchyItem | CallHierarchyItem[] | undefined { synchronizeHostData(); - const declarations = CallHierarchy.resolveCallHierarchyDeclaration(program, getTouchingPropertyName(getValidSourceFile(fileName), position)); - return declarations && mapOneOrMany(declarations, declaration => CallHierarchy.createCallHierarchyItem(program, declaration)); + const declarations = resolveCallHierarchyDeclaration(program, getTouchingPropertyName(getValidSourceFile(fileName), position)); + return declarations && mapOneOrMany(declarations, declaration => createCallHierarchyItem(program, declaration)); } function provideCallHierarchyIncomingCalls(fileName: string, position: number): 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 = firstOrOnly(resolveCallHierarchyDeclaration(program, position === 0 ? sourceFile : getTouchingPropertyName(sourceFile, position))); + return declaration ? getIncomingCalls(program, declaration, cancellationToken) : []; } function provideCallHierarchyOutgoingCalls(fileName: string, position: number): 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 = firstOrOnly(resolveCallHierarchyDeclaration(program, position === 0 ? sourceFile : getTouchingPropertyName(sourceFile, position))); + return declaration ? getOutgoingCalls(program, declaration) : []; } function provideInlayHints(fileName: string, span: TextSpan, preferences: UserPreferences = emptyOptions): InlayHint[] { @@ -3192,8 +3236,8 @@ function isArgumentOfElementAccessExpression(node: Node) { * The functionality is not supported if the ts module is consumed outside of a node module. */ export function getDefaultLibFilePath(options: CompilerOptions): string { - if (ts.sys) { - return combinePaths(getDirectoryPath(normalizePath(ts.sys.getExecutingFilePath())), getDefaultLibFileName(options)); + if (sys) { + return combinePaths(getDirectoryPath(normalizePath(sys.getExecutingFilePath())), getDefaultLibFileName(options)); } throw new Error("getDefaultLibFilePath is only supported when consumed as a node module. "); diff --git a/src/services/shims.ts b/src/services/shims.ts index 64b1fe0f624b0..8d8c967a63c88 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -1,71 +1,91 @@ +import { EmitOutput } from "../compiler/builderStatePublic"; +import { + parseJsonSourceFileConfigFileContent, +} from "../compiler/commandLineParser"; import { - Classifications, - Classifier, clear, - CompilerOptions, - CompletionEntryData, - createClassifier, - createDocumentRegistry, createGetCanonicalFileName, - createLanguageService, - createTextChangeRange, - createTextSpan, - Diagnostic, - diagnosticCategoryName, - DocCommentTemplateOptions, - DocumentRegistry, - EditorOptions, - EmitOutput, - emptyOptions, - EndOfLineState, - Extension, - extensionFromPath, - FileReference, filter, - flattenDiagnosticMessageText, - FormatCodeOptions, - FormatCodeSettings, - getAutomaticTypeDirectiveNames, - GetCompletionsAtPositionOptions, - getDefaultCompilerOptions, - getDirectoryPath, - getFileMatcherPatterns, - getNewLineOrDefaultFromHost, getProperty, - getSnapshotText, - HostCancellationToken, - IScriptSnapshot, isString, - JsTyping, - LanguageService, - LanguageServiceHost, map, - MapLike, - ModuleResolutionHost, + toFileNameLowerCase, +} from "../compiler/core"; +import { MapLike } from "../compiler/corePublic"; +import { + getAutomaticTypeDirectiveNames, + resolveModuleName, + resolveTypeReferenceDirective, +} from "../compiler/moduleNameResolver"; +import { parseJsonText } from "../compiler/parser"; +import { + getDirectoryPath, normalizeSlashes, + toPath, +} from "../compiler/path"; +import { timestamp } from "../compiler/performanceCore"; +import { flattenDiagnosticMessageText } from "../compiler/program"; +import { + CompilerOptions, + Diagnostic, + diagnosticCategoryName, + Extension, + FileReference, + ModuleResolutionHost, OperationCanceledException, ParseConfigHost, - parseJsonSourceFileConfigFileContent, - parseJsonText, - preProcessFile, ResolvedModuleFull, ResolvedTypeReferenceDirective, - resolveModuleName, - resolveTypeReferenceDirective, ScriptKind, - SemanticClassificationFormat, - servicesVersion, - SignatureHelpItemsOptions, TextChangeRange, TextRange, TextSpan, - ThrottledCancellationToken, - timestamp, - toFileNameLowerCase, - toPath, TypeAcquisition, UserPreferences, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + extensionFromPath, + getFileMatcherPatterns, +} from "../compiler/utilities"; +import { + createTextChangeRange, + createTextSpan, +} from "../compiler/utilitiesPublic"; +import * as JsTyping from "../jsTyping/jsTyping"; +import { createClassifier } from "./classifier"; +import { + createDocumentRegistry, + DocumentRegistry, +} from "./documentRegistry"; +import { preProcessFile } from "./preProcess"; +import { + createLanguageService, + getDefaultCompilerOptions, + servicesVersion, + ThrottledCancellationToken, +} from "./services"; +import { + Classifications, + Classifier, + CompletionEntryData, + DocCommentTemplateOptions, + EditorOptions, + emptyOptions, + EndOfLineState, + FormatCodeOptions, + FormatCodeSettings, + GetCompletionsAtPositionOptions, + HostCancellationToken, + IScriptSnapshot, + LanguageService, + LanguageServiceHost, + SemanticClassificationFormat, + SignatureHelpItemsOptions, +} from "./types"; +import { + getNewLineOrDefaultFromHost, + getSnapshotText, +} from "./utilities"; // // Copyright (c) Microsoft Corporation. All rights reserved. diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 1ca1b0ae6dd15..f614ae39969d7 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -1,77 +1,55 @@ import { - ArrowFunction, - BinaryExpression, - CallLikeExpression, - CancellationToken, - CheckFlags, contains, countWhere, - createPrinter, - createTextSpan, - createTextSpanFromBounds, - createTextSpanFromNode, - Debug, - EmitHint, emptyArray, - Expression, - factory, - findContainingList, findIndex, - findPrecedingToken, - findTokenOnLeftOfPosition, first, firstDefined, flatMapToMutable, - FunctionExpression, - getInvokedExpression, - getPossibleGenericSignatures, - getPossibleTypeArgumentsInfo, - Identifier, identity, - InternalSymbolName, + last, + lastOrUndefined, + map, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { createPrinter } from "../compiler/emitter"; +import { factory } from "../compiler/factory/nodeFactory"; +import { isBinaryExpression, isBlock, - isCallOrNewExpression, isFunctionTypeNode, isIdentifier, - isInComment, - isInsideTemplateLiteral, - isInString, - isJsxOpeningLikeElement, isMethodDeclaration, isNoSubstitutionTemplateLiteral, isPropertyAccessExpression, isSourceFile, - isSourceFileJS, isTaggedTemplateExpression, isTemplateHead, - isTemplateLiteralToken, isTemplateSpan, isTemplateTail, - last, - lastOrUndefined, +} from "../compiler/factory/nodeTests"; +import { skipTrivia } from "../compiler/scanner"; +import { + ArrowFunction, + BinaryExpression, + CallLikeExpression, + CancellationToken, + CheckFlags, + EmitHint, + Expression, + FunctionExpression, + Identifier, + InternalSymbolName, ListFormat, - map, - mapToDisplayParts, Node, NodeBuilderFlags, ParameterDeclaration, ParenthesizedExpression, Printer, Program, - punctuationPart, - rangeContainsRange, Signature, - SignatureHelpItem, - SignatureHelpItems, - SignatureHelpParameter, - SignatureHelpTriggerReason, - skipTrivia, SourceFile, - spacePart, Symbol, - SymbolDisplayPart, - symbolToDisplayParts, SyntaxKind, TaggedTemplateExpression, TemplateExpression, @@ -80,7 +58,41 @@ import { Type, TypeChecker, TypeParameter, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + getInvokedExpression, + isSourceFileJS, +} from "../compiler/utilities"; +import { + createTextSpan, + createTextSpanFromBounds, + isCallOrNewExpression, + isJsxOpeningLikeElement, + isTemplateLiteralToken, +} from "../compiler/utilitiesPublic"; +import { + SignatureHelpItem, + SignatureHelpItems, + SignatureHelpParameter, + SignatureHelpTriggerReason, + SymbolDisplayPart, +} from "./types"; +import { + createTextSpanFromNode, + findContainingList, + findPrecedingToken, + findTokenOnLeftOfPosition, + getPossibleGenericSignatures, + getPossibleTypeArgumentsInfo, + isInComment, + isInsideTemplateLiteral, + isInString, + mapToDisplayParts, + punctuationPart, + rangeContainsRange, + spacePart, + symbolToDisplayParts, +} from "./utilities"; const enum InvocationKind { Call, TypeArgs, Contextual } interface CallInvocation { readonly kind: InvocationKind.Call; readonly node: CallLikeExpression; } @@ -663,10 +675,12 @@ function getTypeHelpItem(symbol: Symbol, typeParameters: readonly TypeParameter[ 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 }; + return { isVariadic: false, prefixDisplayParts, suffixDisplayParts: [punctuationPart(SyntaxKind.GreaterThanToken)], separatorDisplayParts: getSeparatorDisplayParts(), parameters, documentation, tags }; } -const separatorDisplayParts: SymbolDisplayPart[] = [punctuationPart(SyntaxKind.CommaToken), spacePart()]; +function getSeparatorDisplayParts(): SymbolDisplayPart[] { + return [punctuationPart(SyntaxKind.CommaToken), spacePart()]; +} function getSignatureHelpItem(candidateSignature: Signature, callTargetDisplayParts: readonly SymbolDisplayPart[], isTypeParameterList: boolean, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItem[] { const infos = (isTypeParameterList ? itemInfoForTypeParameters : itemInfoForParameters)(candidateSignature, checker, enclosingDeclaration, sourceFile); @@ -675,7 +689,7 @@ function getSignatureHelpItem(candidateSignature: Signature, callTargetDisplayPa const suffixDisplayParts = [...suffix, ...returnTypeToDisplayParts(candidateSignature, enclosingDeclaration, checker)]; const documentation = candidateSignature.getDocumentationComment(checker); const tags = candidateSignature.getJsDocTags(); - return { isVariadic, prefixDisplayParts, suffixDisplayParts, separatorDisplayParts, parameters, documentation, tags }; + return { isVariadic, prefixDisplayParts, suffixDisplayParts, separatorDisplayParts: getSeparatorDisplayParts(), parameters, documentation, tags }; }); } diff --git a/src/services/smartSelection.ts b/src/services/smartSelection.ts index 0e67fba79a386..94b46aa4430c9 100644 --- a/src/services/smartSelection.ts +++ b/src/services/smartSelection.ts @@ -1,19 +1,16 @@ import { - CharacterCodes, compact, contains, - createTextSpanFromBounds, - Debug, findIndex, first, - getTokenPosOfNode, - getTouchingPropertyName, - getTrailingCommentRanges, - hasJSDocNodes, + last, + or, + singleOrUndefined, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { isBindingElement, isBlock, - isFunctionBody, - isFunctionLikeDeclaration, isImportDeclaration, isImportEqualsDeclaration, isJSDocSignature, @@ -26,27 +23,40 @@ import { isStringLiteral, isSyntaxList, isTemplateHead, - isTemplateLiteral, - isTemplateMiddleOrTemplateTail, isTemplateSpan, isTemplateTail, isVariableDeclaration, isVariableDeclarationList, isVariableStatement, - last, +} from "../compiler/factory/nodeTests"; +import { parseNodeFactory } from "../compiler/parser"; +import { getTrailingCommentRanges } from "../compiler/scanner"; +import { + CharacterCodes, Node, - or, - parseNodeFactory, - positionsAreOnSameLine, - SelectionRange, - setTextRangePosEnd, - singleOrUndefined, SourceFile, SyntaxKind, SyntaxList, +} from "../compiler/types"; +import { + getTokenPosOfNode, + positionsAreOnSameLine, + setTextRangePosEnd, +} from "../compiler/utilities"; +import { + createTextSpanFromBounds, + hasJSDocNodes, + isFunctionBody, + isFunctionLikeDeclaration, + isTemplateLiteral, + isTemplateMiddleOrTemplateTail, textSpanIntersectsWithPosition, +} from "../compiler/utilitiesPublic"; +import { SelectionRange } from "./types"; +import { + getTouchingPropertyName, textSpansEqual, -} from "./_namespaces/ts"; +} from "./utilities"; /** @internal */ export function getSmartSelectionRange(pos: number, sourceFile: SourceFile): SelectionRange { diff --git a/src/services/sourcemaps.ts b/src/services/sourcemaps.ts index e77fe30e4acf1..c724db7004b27 100644 --- a/src/services/sourcemaps.ts +++ b/src/services/sourcemaps.ts @@ -1,31 +1,41 @@ -import * as ts from "./_namespaces/ts"; import { - base64decode, + createGetCanonicalFileName, + isString, +} from "../compiler/core"; +import { isDeclarationFileName } from "../compiler/parser"; +import { + getDirectoryPath, + getNormalizedAbsolutePath, + toPath as toPathHelper, +} from "../compiler/path"; +import { computeLineAndCharacterOfPosition, + getLineStarts, +} from "../compiler/scanner"; +import { createDocumentPositionMapper, - createGetCanonicalFileName, + getLineInfo, + identitySourceMapConsumer, + LineInfo, + tryGetSourceMappingURL, + tryParseRawSourceMap, +} from "../compiler/sourcemap"; +import { sys } from "../compiler/sys"; +import { DocumentPosition, DocumentPositionMapper, DocumentPositionMapperHost, Extension, - getDeclarationEmitOutputFilePathWorker, - getDirectoryPath, - getLineInfo, - getLineStarts, - getNormalizedAbsolutePath, - identitySourceMapConsumer, - isDeclarationFileName, - isString, LineAndCharacter, - LineInfo, - outFile, Program, - removeFileExtension, SourceFileLike, - sys, - tryGetSourceMappingURL, - tryParseRawSourceMap, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + base64decode, + getDeclarationEmitOutputFilePathWorker, + outFile, + removeFileExtension, +} from "../compiler/utilities"; const base64UrlRegExp = /^data:(?:application\/json(?:;charset=[uU][tT][fF]-8);base64,([A-Za-z0-9+\/=]+)$)?/; @@ -58,10 +68,10 @@ export function getSourceMapper(host: SourceMapperHost): SourceMapper { return { tryGetSourcePosition, tryGetGeneratedPosition, toLineColumnOffset, clearCache }; function toPath(fileName: string) { - return ts.toPath(fileName, currentDirectory, getCanonicalFileName); + return toPathHelper(fileName, currentDirectory, getCanonicalFileName); } - function getDocumentPositionMapper(generatedFileName: string, sourceFileName?: string) { + function getDocumentPositionMapperWorker(generatedFileName: string, sourceFileName?: string) { const path = toPath(generatedFileName); const value = documentPositionMappers.get(path); if (value) return value; @@ -72,7 +82,7 @@ export function getSourceMapper(host: SourceMapperHost): SourceMapper { } else if (host.readFile) { const file = getSourceFileLike(generatedFileName); - mapper = file && ts.getDocumentPositionMapper( + mapper = file && getDocumentPositionMapper( { getSourceFileLike, getCanonicalFileName, log: s => host.log(s) }, generatedFileName, getLineInfo(file.text, getLineStarts(file)), @@ -89,7 +99,7 @@ export function getSourceMapper(host: SourceMapperHost): SourceMapper { const file = getSourceFile(info.fileName); if (!file) return undefined; - const newLoc = getDocumentPositionMapper(info.fileName).getSourcePosition(info); + const newLoc = getDocumentPositionMapperWorker(info.fileName).getSourcePosition(info); return !newLoc || newLoc === info ? undefined : tryGetSourcePosition(newLoc) || newLoc; } @@ -113,7 +123,7 @@ export function getSourceMapper(host: SourceMapperHost): SourceMapper { getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName); if (declarationPath === undefined) return undefined; - const newLoc = getDocumentPositionMapper(declarationPath, info.fileName).getGeneratedPosition(info); + const newLoc = getDocumentPositionMapperWorker(declarationPath, info.fileName).getGeneratedPosition(info); return newLoc === info ? undefined : newLoc; } diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index c319ad3b8e92a..36c000802ba35 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -1,147 +1,139 @@ import { - addToSeen, - altDirectorySeparator, arrayFrom, - CallLikeExpression, - CancellationToken, - changeExtension, - CharacterCodes, - combinePaths, - comparePaths, - comparePatternKeys, compareStringsCaseSensitive, compareValues, - Comparison, - CompilerOptions, - CompletionEntry, - CompletionEntryDetails, - CompletionInfo, contains, - containsPath, - ContextFlags, createSortedArray, - createTextSpan, - createTextSpanFromStringLiteralLikeContent, - Debug, deduplicate, - directorySeparator, - ElementAccessExpression, emptyArray, endsWith, - ensureTrailingDirectorySeparator, equateStringsCaseSensitive, - Extension, - fileExtensionIsOneOf, filter, find, - findAncestor, - findPackageJson, - findPackageJsons, firstDefined, firstOrUndefined, flatMap, flatten, - forEachAncestorDirectory, - getBaseFileName, - getContextualTypeFromParent, - getDirectoryPath, - getEffectiveTypeRoots, - getEmitModuleResolutionKind, - getLeadingCommentRanges, - getModeForUsageLocation, getOwnKeys, - getPackageJsonTypesVersionsPaths, - getPathComponents, - getReplacementSpanForContextToken, - getSupportedExtensions, - getSupportedExtensionsWithJsonIfResolveJsonModule, - getTokenAtPosition, - hasIndexSignature, hasProperty, - hasTrailingDirectorySeparator, - hostGetCanonicalFileName, - IndexedAccessTypeNode, - isApplicableVersionedTypesKey, isArray, + isPatternMatch, + isString, + length, + mapDefined, + removePrefix, + singleElementArray, + startsWith, + stringContains, + tryRemovePrefix, +} from "../compiler/core"; +import { + Comparison, + MapLike, +} from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { isCallExpression, isIdentifier, - isIdentifierText, - isImportCall, - isInReferenceComment, - isInString, isJsxAttribute, - isJsxOpeningLikeElement, isLiteralTypeNode, isObjectLiteralExpression, - isPatternMatch, - isPrivateIdentifierClassElementDeclaration, - isRootedDiskPath, - isString, isStringLiteral, - isStringLiteralLike, isTypeReferenceNode, +} from "../compiler/factory/nodeTests"; +import { + comparePatternKeys, + getEffectiveTypeRoots, + getPackageJsonTypesVersionsPaths, + isApplicableVersionedTypesKey, + unmangleScopedPackageName, +} from "../compiler/moduleNameResolver"; +import { tryGetJSExtensionForFile } from "../compiler/moduleSpecifiers"; +import { + altDirectorySeparator, + combinePaths, + comparePaths, + containsPath, + directorySeparator, + ensureTrailingDirectorySeparator, + fileExtensionIsOneOf, + forEachAncestorDirectory, + getBaseFileName, + getDirectoryPath, + getPathComponents, + hasTrailingDirectorySeparator, + isRootedDiskPath, isUrl, + normalizePath, + normalizeSlashes, + removeTrailingDirectorySeparator, + resolvePath, +} from "../compiler/path"; +import { getModeForUsageLocation } from "../compiler/program"; +import { + getLeadingCommentRanges, + isIdentifierText, +} from "../compiler/scanner"; +import { + CallLikeExpression, + CancellationToken, + CharacterCodes, + CompilerOptions, + ContextFlags, + ElementAccessExpression, + Extension, + IndexedAccessTypeNode, JsxAttribute, - LanguageServiceHost, - length, LiteralExpression, LiteralTypeNode, - mapDefined, - MapLike, ModuleKind, ModuleResolutionKind, - moduleSpecifiers, Node, - normalizePath, - normalizeSlashes, ObjectLiteralExpression, Path, Program, PropertyAssignment, - rangeContainsPosition, - readJson, - removeFileExtension, - removePrefix, - removeTrailingDirectorySeparator, ResolutionMode, - resolvePath, - ScriptElementKind, - ScriptElementKindModifier, ScriptTarget, Signature, - signatureHasRestParameter, - SignatureHelp, - singleElementArray, - skipConstraint, - skipParentheses, SourceFile, - startsWith, - stringContains, StringLiteralLike, StringLiteralType, - stripQuotes, Symbol, SyntaxKind, - textPart, TextSpan, - tryAndIgnoreErrors, - tryDirectoryExists, - tryFileExists, - tryGetDirectories, - tryGetExtensionFromPath, - tryParsePattern, - tryReadDirectory, - tryRemoveDirectoryPrefix, - tryRemovePrefix, Type, TypeChecker, TypeFlags, UnionTypeNode, - unmangleScopedPackageName, UserPreferences, +} from "../compiler/types"; +import { + addToSeen, + changeExtension, + getEmitModuleResolutionKind, + getSupportedExtensions, + getSupportedExtensionsWithJsonIfResolveJsonModule, + hostGetCanonicalFileName, + isImportCall, + readJson, + removeFileExtension, + signatureHasRestParameter, + skipParentheses, + stripQuotes, + tryGetExtensionFromPath, + tryParsePattern, + tryRemoveDirectoryPrefix, walkUpParenthesizedExpressions, walkUpParenthesizedTypes, -} from "./_namespaces/ts"; +} from "../compiler/utilities"; +import { + createTextSpan, + findAncestor, + isJsxOpeningLikeElement, + isPrivateIdentifierClassElementDeclaration, + isStringLiteralLike, +} from "../compiler/utilitiesPublic"; import { CompletionKind, createCompletionDetails, @@ -150,7 +142,38 @@ import { getPropertiesForObjectExpression, Log, SortText, -} from "./_namespaces/ts.Completions"; +} from "./completions"; +import { + ArgumentInfoForCompletions, + getArgumentInfoForCompletions, +} from "./signatureHelp"; +import { + CompletionEntry, + CompletionEntryDetails, + CompletionInfo, + LanguageServiceHost, + ScriptElementKind, + ScriptElementKindModifier, +} from "./types"; +import { + createTextSpanFromStringLiteralLikeContent, + findPackageJson, + findPackageJsons, + getContextualTypeFromParent, + getReplacementSpanForContextToken, + getTokenAtPosition, + hasIndexSignature, + isInReferenceComment, + isInString, + rangeContainsPosition, + skipConstraint, + textPart, + tryAndIgnoreErrors, + tryDirectoryExists, + tryFileExists, + tryGetDirectories, + tryReadDirectory, +} from "./utilities"; interface NameAndKindSet { add(value: NameAndKind): void; @@ -391,7 +414,7 @@ function getStringLiteralCompletionEntries(sourceFile: SourceFile, node: StringL case SyntaxKind.NewExpression: case SyntaxKind.JsxAttribute: if (!isRequireCallArgument(node) && !isImportCall(parent)) { - const argumentInfo = SignatureHelp.getArgumentInfoForCompletions(parent.kind === SyntaxKind.JsxAttribute ? parent.parent : node, position, sourceFile); + const argumentInfo = getArgumentInfoForCompletions(parent.kind === 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*/") @@ -437,7 +460,7 @@ function getAlreadyUsedTypesInStringLiteralUnion(union: UnionTypeNode, current: type !== current && isLiteralTypeNode(type) && isStringLiteral(type.literal) ? type.literal.text : undefined); } -function getStringLiteralCompletionsFromSignature(call: CallLikeExpression, arg: StringLiteralLike, argumentInfo: SignatureHelp.ArgumentInfoForCompletions, checker: TypeChecker): StringLiteralCompletionsFromTypes | undefined { +function getStringLiteralCompletionsFromSignature(call: CallLikeExpression, arg: StringLiteralLike, argumentInfo: ArgumentInfoForCompletions, checker: TypeChecker): StringLiteralCompletionsFromTypes | undefined { let isNewIdentifier = false; const uniques = new Map(); const candidates: Signature[] = []; @@ -690,7 +713,7 @@ function getCompletionEntriesForDirectoryFragment( } function getFilenameWithExtensionOption(name: string, compilerOptions: CompilerOptions, includeExtensionsOption: IncludeExtensionsOption): { name: string, extension: Extension | undefined } { - const outputExtension = moduleSpecifiers.tryGetJSExtensionForFile(name, compilerOptions); + const outputExtension = tryGetJSExtensionForFile(name, compilerOptions); if (includeExtensionsOption === IncludeExtensionsOption.Exclude && !fileExtensionIsOneOf(name, [Extension.Json, Extension.Mts, Extension.Cts, Extension.Dmts, Extension.Dcts, Extension.Mjs, Extension.Cjs])) { return { name: removeFileExtension(name), extension: tryGetExtensionFromPath(name) }; } diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 3c242e580766c..023896798ad4d 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -1,64 +1,74 @@ import { addRange, + some, +} from "../compiler/core"; +import { Push } from "../compiler/corePublic"; +import { Diagnostics } from "../compiler/diagnosticInformationMap.generated"; +import { + isBinaryExpression, + isBlock, + isCallExpression, + isExportAssignment, + isIdentifier, + isPropertyAccessExpression, + isReturnStatement, + isStringLiteral, + isVariableDeclaration, + isVariableStatement, +} from "../compiler/factory/nodeTests"; +import { fileExtensionIsOneOf } from "../compiler/path"; +import { getModeForUsageLocation } from "../compiler/program"; +import { AnyValidImportOrReExport, ArrowFunction, AssignmentDeclarationKind, Block, CallExpression, CancellationToken, - codefix, - compilerOptionsIndicateEsModules, - createDiagnosticForNode, - Diagnostics, DiagnosticWithLocation, Expression, ExpressionStatement, Extension, - fileExtensionIsOneOf, - forEachReturnStatement, FunctionDeclaration, FunctionExpression, - FunctionFlags, FunctionLikeDeclaration, - getAllowSyntheticDefaultImports, - getAssignmentDeclarationKind, - getFunctionFlags, - getModeForUsageLocation, - getResolvedModule, - hasInitializer, - hasPropertyAccessExpressionWithName, Identifier, - importFromModuleSpecifier, - isAsyncFunction, - isBinaryExpression, - isBlock, - isCallExpression, - isExportAssignment, - isFunctionLike, - isIdentifier, - isPropertyAccessExpression, - isRequireCall, - isReturnStatement, - isSourceFileJS, - isStringLiteral, - isVariableDeclaration, - isVariableStatement, MethodDeclaration, ModuleKind, Node, NodeFlags, Program, - programContainsEsModules, PropertyAccessExpression, - Push, ReturnStatement, - skipAlias, - some, SourceFile, SyntaxKind, TypeChecker, VariableStatement, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + createDiagnosticForNode, + forEachReturnStatement, + FunctionFlags, + getAllowSyntheticDefaultImports, + getAssignmentDeclarationKind, + getFunctionFlags, + getResolvedModule, + importFromModuleSpecifier, + isAsyncFunction, + isRequireCall, + isSourceFileJS, + skipAlias, +} from "../compiler/utilities"; +import { + hasInitializer, + isFunctionLike, +} from "../compiler/utilitiesPublic"; +import { + compilerOptionsIndicateEsModules, + hasPropertyAccessExpressionWithName, + parameterShouldGetTypeFromJSDoc, + programContainsEsModules, +} from "./utilities"; const visitedNestedConvertibleFunctions = new Map(); @@ -115,7 +125,7 @@ export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Pr } } - if (codefix.parameterShouldGetTypeFromJSDoc(node)) { + if (parameterShouldGetTypeFromJSDoc(node)) { diags.push(createDiagnosticForNode(node.name || node, Diagnostics.JSDoc_types_may_be_moved_to_TypeScript_types)); } } diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index fff0b69e39eb0..4cf552d8f386e 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -1,112 +1,124 @@ import { addRange, arrayFrom, - BinaryExpression, - CallExpression, - CheckFlags, contains, - createPrinter, - Debug, - displayPart, - EmitHint, emptyArray, - EnumMember, - ExportAssignment, find, first, firstDefined, forEach, - GetAccessorDeclaration, - getCombinedLocalAndExportSymbolFlags, - getDeclarationOfKind, - getExternalModuleImportEqualsDeclarationExpression, - getMeaningFromLocation, - getNameOfDeclaration, - getNodeModifiers, - getObjectFlags, - getParseTreeNode, - getSourceFileOfNode, - getTextOfConstantValue, - getTextOfIdentifierOrLiteral, - getTextOfNode, - hasSyntacticModifier, - idText, - ImportEqualsDeclaration, + length, + some, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { createPrinter } from "../compiler/emitter"; +import { isArrowFunction, isBindingElement, isCallExpression, - isCallExpressionTarget, - isCallOrNewExpression, isClassExpression, - isConstTypeReference, - isDeprecatedDeclaration, - isEnumConst, isEnumDeclaration, - isExpression, - isExternalModuleImportEqualsDeclaration, - isFirstDeclarationOfSymbolParameter, - isFunctionBlock, isFunctionExpression, - isFunctionLike, - isFunctionLikeKind, isIdentifier, - isInExpressionContext, - isJsxOpeningLikeElement, - isLet, - isModuleWithStringLiteralName, - isNameOfFunctionDeclaration, - isNewExpressionTarget, isObjectBindingPattern, isTaggedTemplateExpression, - isThisInTypeQuery, - isVarConst, - JSDocTagInfo, +} from "../compiler/factory/nodeTests"; +import { + BinaryExpression, + CallExpression, + CheckFlags, + EmitHint, + EnumMember, + ExportAssignment, + GetAccessorDeclaration, + ImportEqualsDeclaration, JsxOpeningLikeElement, - keywordPart, - length, - lineBreakPart, ListFormat, - mapToDisplayParts, ModifierFlags, ModuleDeclaration, NewExpression, Node, NodeBuilderFlags, ObjectFlags, - operatorPart, Printer, PropertyAccessExpression, PropertyDeclaration, - punctuationPart, - ScriptElementKind, - ScriptElementKindModifier, - SemanticMeaning, SetAccessorDeclaration, Signature, SignatureDeclaration, SignatureFlags, - signatureToDisplayParts, - some, SourceFile, - spacePart, Symbol, - SymbolDisplayPart, - SymbolDisplayPartKind, SymbolFlags, SymbolFormatFlags, - symbolToDisplayParts, SyntaxKind, TaggedTemplateExpression, - textOrKeywordPart, - textPart, TransientSymbol, Type, TypeChecker, TypeFormatFlags, TypeParameter, - typeToDisplayParts, VariableDeclaration, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + getCombinedLocalAndExportSymbolFlags, + getDeclarationOfKind, + getExternalModuleImportEqualsDeclarationExpression, + getObjectFlags, + getSourceFileOfNode, + getTextOfConstantValue, + getTextOfIdentifierOrLiteral, + getTextOfNode, + hasSyntacticModifier, + isEnumConst, + isExternalModuleImportEqualsDeclaration, + isFunctionBlock, + isInExpressionContext, + isLet, + isModuleWithStringLiteralName, + isThisInTypeQuery, + isVarConst, +} from "../compiler/utilities"; +import { + getNameOfDeclaration, + getParseTreeNode, + idText, + isCallOrNewExpression, + isConstTypeReference, + isExpression, + isFunctionLike, + isFunctionLikeKind, + isJsxOpeningLikeElement, +} from "../compiler/utilitiesPublic"; +import { + JSDocTagInfo, + ScriptElementKind, + ScriptElementKindModifier, + SymbolDisplayPart, + SymbolDisplayPartKind, +} from "./types"; +import { + displayPart, + getMeaningFromLocation, + getNodeModifiers, + isCallExpressionTarget, + isDeprecatedDeclaration, + isFirstDeclarationOfSymbolParameter, + isNameOfFunctionDeclaration, + isNewExpressionTarget, + keywordPart, + lineBreakPart, + mapToDisplayParts, + operatorPart, + punctuationPart, + SemanticMeaning, + signatureToDisplayParts, + spacePart, + symbolToDisplayParts, + textOrKeywordPart, + textPart, + typeToDisplayParts, +} from "./utilities"; const symbolDisplayNodeBuilderFlags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope; diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 98a35af0fe3e0..6334a04455883 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1,119 +1,91 @@ +import { getNodeId } from "../compiler/checkerUtilities"; import { - addToSeen, - ArrowFunction, - BindingElement, - CharacterCodes, - ClassElement, - ClassExpression, - ClassLikeDeclaration, - CommentRange, concatenate, - ConstructorDeclaration, contains, - createNodeFactory, - createPrinter, - createRange, - createSourceFile, - createTextChange, - createTextRangeFromSpan, - createTextSpan, - createTextSpanFromRange, - createTextWriter, - Debug, - DeclarationStatement, - EmitHint, - EmitTextWriter, endsWith, - Expression, - factory, - FileTextChanges, filter, find, - findChildOfKind, findLastIndex, - findNextToken, - findPrecedingToken, first, firstOrUndefined, flatMap, flatMapToMutable, - formatting, - FunctionDeclaration, - FunctionExpression, - getAncestor, - getFirstNonSpaceCharacterPosition, - getFormatCodeSettingsForWriting, - getJSDocCommentRanges, - getLeadingCommentRanges, - getLineAndCharacterOfPosition, - getLineOfLocalPosition, - getLineStartPositionForPosition, - getNewLineKind, - getNewLineOrDefaultFromHost, - getNodeId, - getPrecedingNonSpaceCharacterPosition, - getScriptKindFromFileName, - getShebang, - getStartPositionOfLine, - getTokenAtPosition, - getTouchingToken, - getTrailingCommentRanges, group, - HasJSDoc, - hasJSDocNodes, - ImportClause, - ImportSpecifier, - indexOfNode, - InterfaceDeclaration, intersperse, - isAnyImportSyntax, isArray, + isLineBreak, + isString, + isWhiteSpaceLike, + isWhiteSpaceSingleLine, + last, + lastOrUndefined, + length, + mapDefined, + removeSuffix, + singleOrUndefined, + stableSort, +} from "../compiler/core"; +import { Debug } from "../compiler/debug"; +import { createPrinter } from "../compiler/emitter"; +import { + createNodeFactory, + factory, + NodeFactoryFlags, +} from "../compiler/factory/nodeFactory"; +import { isArrowFunction, isCallExpression, - isClassElement, - isClassOrTypeElement, isExpressionStatement, isFunctionDeclaration, isFunctionExpression, - isFunctionLike, isIdentifier, isImportClause, isImportDeclaration, isImportSpecifier, - isInComment, - isInJSXText, - isInString, - isInTemplateString, isInterfaceDeclaration, - isJsonSourceFile, - isLineBreak, isNamedImports, isObjectLiteralExpression, isParameter, - isPinnedComment, - isPrologueDirective, isPropertyDeclaration, isPropertySignature, - isRecognizedTripleSlashComment, - isStatement, - isStatementButNotDeclaration, - isString, isStringLiteral, - isSuperCall, isVariableDeclaration, - isWhiteSpaceLike, - isWhiteSpaceSingleLine, +} from "../compiler/factory/nodeTests"; +import { createSourceFile } from "../compiler/parser"; +import { + getLeadingCommentRanges, + getLineAndCharacterOfPosition, + getShebang, + getTrailingCommentRanges, + skipTrivia, + tokenToString, +} from "../compiler/scanner"; +import { nullTransformationContext } from "../compiler/transformer"; +import { + ArrowFunction, + BindingElement, + CharacterCodes, + ClassElement, + ClassExpression, + ClassLikeDeclaration, + CommentRange, + ConstructorDeclaration, + DeclarationStatement, + EmitHint, + EmitTextWriter, + Expression, + FunctionDeclaration, + FunctionExpression, + HasJSDoc, + ImportClause, + ImportSpecifier, + InterfaceDeclaration, JSDoc, JSDocComment, JSDocParameterTag, JSDocReturnTag, JSDocTag, JSDocTypeTag, - LanguageServiceHost, - last, - lastOrUndefined, - length, - mapDefined, MethodSignature, Modifier, NamedImportBindings, @@ -121,53 +93,103 @@ import { NamespaceImport, Node, NodeArray, - NodeFactoryFlags, - nodeIsSynthesized, - nullTransformationContext, ObjectLiteralElementLike, ObjectLiteralExpression, ParameterDeclaration, - positionsAreOnSameLine, PrintHandlers, PrologueDirective, PropertyAssignment, PropertyDeclaration, PropertySignature, - rangeContainsPosition, - rangeContainsRangeExclusive, - rangeOfNode, - rangeOfTypeParameters, - rangeStartPositionsAreOnSameLine, - removeSuffix, ScriptKind, ScriptTarget, - setTextRangePosEnd, SignatureDeclaration, - singleOrUndefined, - skipTrivia, SourceFile, SourceFileLike, - stableSort, Statement, - stringContainsAt, Symbol, SyntaxKind, - TextChange, TextRange, - textSpanEnd, Token, - tokenToString, TransformationContext, TypeLiteralNode, TypeNode, TypeParameterDeclaration, - UserPreferences, VariableDeclaration, VariableStatement, + Visitor, +} from "../compiler/types"; +import { + addToSeen, + createRange, + createTextWriter, + getAncestor, + getJSDocCommentRanges, + getLineOfLocalPosition, + getScriptKindFromFileName, + getStartPositionOfLine, + indexOfNode, + isAnyImportSyntax, + isJsonSourceFile, + isPinnedComment, + isPrologueDirective, + isRecognizedTripleSlashComment, + isSuperCall, + nodeIsSynthesized, + positionsAreOnSameLine, + rangeOfNode, + rangeOfTypeParameters, + rangeStartPositionsAreOnSameLine, + setTextRangePosEnd, +} from "../compiler/utilities"; +import { + createTextSpan, + hasJSDocNodes, + isClassElement, + isClassOrTypeElement, + isFunctionLike, + isStatement, + isStatementButNotDeclaration, + textSpanEnd, +} from "../compiler/utilitiesPublic"; +import { visitEachChild, visitNodes, - Visitor, -} from "./_namespaces/ts"; +} from "../compiler/visitorPublic"; +import { + formatDocument, + formatNodeGivenIndentation, +} from "./formatting/formatting"; +import { SmartIndenter } from "./formatting/smartIndenter"; +import { + FileTextChanges, + FormatContext, + TextChange, + TextChangesContext, +} from "./types"; +import { + createTextChange, + createTextRangeFromSpan, + createTextSpanFromRange, + findChildOfKind, + findNextToken, + findPrecedingToken, + getFirstNonSpaceCharacterPosition, + getFormatCodeSettingsForWriting, + getLineStartPositionForPosition, + getNewLineKind, + getNewLineOrDefaultFromHost, + getPrecedingNonSpaceCharacterPosition, + getTokenAtPosition, + getTouchingToken, + isInComment, + isInJSXText, + isInString, + isInTemplateString, + rangeContainsPosition, + rangeContainsRangeExclusive, + stringContainsAt, +} from "./utilities"; /** * Currently for simplicity we store recovered positions on the node itself. @@ -459,13 +481,6 @@ function isSeparator(node: Node, candidate: Node | undefined): candidate is Toke return !!candidate && !!node.parent && (candidate.kind === SyntaxKind.CommaToken || (candidate.kind === SyntaxKind.SemicolonToken && node.parent.kind === SyntaxKind.ObjectLiteralExpression)); } -/** @internal */ -export interface TextChangesContext { - host: LanguageServiceHost; - formatContext: formatting.FormatContext; - preferences: UserPreferences; -} - /** @internal */ export type TypeAnnotatable = SignatureDeclaration | VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature; @@ -495,7 +510,7 @@ export class ChangeTracker { } /** Public for tests only. Other callers should use `ChangeTracker.with`. */ - constructor(private readonly newLineCharacter: string, private readonly formatContext: formatting.FormatContext) {} + constructor(private readonly newLineCharacter: string, private readonly formatContext: FormatContext) {} public pushRaw(sourceFile: SourceFile, change: FileTextChanges) { Debug.assertEqual(sourceFile.fileName, change.fileName); @@ -826,7 +841,7 @@ export class ChangeTracker { return undefined; } const memberStart = member.getStart(sourceFile); - const memberIndentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(memberStart, sourceFile), memberStart, sourceFile, this.formatContext.options); + const memberIndentation = SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(memberStart, sourceFile), memberStart, sourceFile, this.formatContext.options); if (indentation === undefined) { indentation = memberIndentation; } @@ -841,7 +856,7 @@ export class ChangeTracker { private computeIndentationForNewMember(sourceFile: SourceFile, node: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression | TypeLiteralNode) { const nodeStart = node.getStart(sourceFile); - return formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(nodeStart, sourceFile), nodeStart, sourceFile, this.formatContext.options) + return SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(nodeStart, sourceFile), nodeStart, sourceFile, this.formatContext.options) + (this.formatContext.options.indentSize ?? 4); } @@ -985,7 +1000,7 @@ export class ChangeTracker { * 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: SourceFile, after: Node, newNode: Node, containingList = SmartIndenter.getContainingList(after, sourceFile)): void { if (!containingList) { Debug.fail("node is not a list element"); return; @@ -1057,7 +1072,7 @@ export class ChangeTracker { // insert separator immediately following the 'after' node to preserve comments in trailing trivia this.replaceRange(sourceFile, createRange(end), factory.createToken(separator)); // use the same indentation as 'after' item - const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.formatContext.options); + const indentation = 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); // find position before "\n" or "\r\n" @@ -1108,7 +1123,7 @@ export class ChangeTracker { deletedNodesInLists.forEach(node => { const sourceFile = node.getSourceFile(); - const list = formatting.SmartIndenter.getContainingList(node, sourceFile)!; + const list = SmartIndenter.getContainingList(node, sourceFile)!; if (node !== last(list)) return; const lastNonDeletedIndex = findLastIndex(list, n => !deletedNodesInLists.has(n), list.length - 2); @@ -1209,12 +1224,12 @@ function getMembersOrProperties(node: ClassLikeDeclaration | InterfaceDeclaratio export type ValidateNonFormattedText = (node: Node, text: string) => void; /** @internal */ -export function getNewFileText(statements: readonly Statement[], scriptKind: ScriptKind, newLineCharacter: string, formatContext: formatting.FormatContext): string { +export function getNewFileText(statements: readonly Statement[], scriptKind: ScriptKind, newLineCharacter: string, formatContext: 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[] { + export function getTextChangesFromChanges(changes: readonly Change[], newLineCharacter: string, formatContext: FormatContext, validate: ValidateNonFormattedText | undefined): FileTextChanges[] { return mapDefined(group(changes, c => c.sourceFile.path), changesInFile => { const sourceFile = changesInFile[0].sourceFile; // order changes by start position @@ -1242,20 +1257,20 @@ namespace changesToText { }); } - export function newFileChanges(oldFile: SourceFile | undefined, fileName: string, statements: readonly (Statement | SyntaxKind.NewLineTrivia)[], newLineCharacter: string, formatContext: formatting.FormatContext): FileTextChanges { + export function newFileChanges(oldFile: SourceFile | undefined, fileName: string, statements: readonly (Statement | SyntaxKind.NewLineTrivia)[], newLineCharacter: string, formatContext: FormatContext): FileTextChanges { const text = newFileChangesWorker(oldFile, getScriptKindFromFileName(fileName), statements, newLineCharacter, formatContext); return { fileName, textChanges: [createTextChange(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: SourceFile | undefined, scriptKind: ScriptKind, statements: readonly (Statement | SyntaxKind.NewLineTrivia)[], newLineCharacter: string, formatContext: 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 changes = 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: SourceFile, newLineCharacter: string, formatContext: FormatContext, validate: ValidateNonFormattedText | undefined): string { if (change.kind === ChangeKind.Remove) { return ""; } @@ -1276,16 +1291,16 @@ namespace changesToText { } /** 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: Node, sourceFile: SourceFile, pos: number, { indentation, prefix, delta }: InsertNodeOptions, newLineCharacter: string, formatContext: 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 ? indentation - : formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, prefix === newLineCharacter || getLineStartPositionForPosition(pos, sourceFile) === pos); + : SmartIndenter.getIndentation(pos, sourceFile, formatOptions, prefix === newLineCharacter || getLineStartPositionForPosition(pos, sourceFile) === pos); if (delta === undefined) { - delta = formatting.SmartIndenter.shouldIndentChildNode(formatOptions, nodeIn) ? (formatOptions.indentSize || 0) : 0; + delta = SmartIndenter.shouldIndentChildNode(formatOptions, nodeIn) ? (formatOptions.indentSize || 0) : 0; } const file: SourceFileLike = { @@ -1294,7 +1309,7 @@ namespace changesToText { return getLineAndCharacterOfPosition(this, pos); } }; - const changes = formatting.formatNodeGivenIndentation(node, file, sourceFile.languageVariant, initialIndentation, delta, { ...formatContext, options: formatOptions }); + const changes = formatNodeGivenIndentation(node, file, sourceFile.languageVariant, initialIndentation, delta, { ...formatContext, options: formatOptions }); return applyChanges(text, changes); } @@ -1329,9 +1344,7 @@ function isTrivia(s: string) { // are more aggressive than is strictly necessary. const textChangesTransformationContext: TransformationContext = { ...nullTransformationContext, - factory: createNodeFactory( - nullTransformationContext.factory.flags | NodeFactoryFlags.NoParenthesizerRules, - nullTransformationContext.factory.baseFactory), + factory: createNodeFactory(factory.flags | NodeFactoryFlags.NoParenthesizerRules, factory.baseFactory), }; /** @internal */ @@ -1791,7 +1804,7 @@ export function deleteNode(changes: ChangeTracker, sourceFile: SourceFile, node: } function deleteNodeInList(changes: ChangeTracker, deletedNodesInLists: Set, sourceFile: SourceFile, node: Node): void { - const containingList = Debug.checkDefined(formatting.SmartIndenter.getContainingList(node, sourceFile)); + const containingList = Debug.checkDefined(SmartIndenter.getContainingList(node, sourceFile)); const index = indexOfNode(containingList, node); Debug.assert(index !== -1); if (containingList.length === 1) { diff --git a/src/services/transform.ts b/src/services/transform.ts index 9c6f96408d464..bf0516a2157e1 100644 --- a/src/services/transform.ts +++ b/src/services/transform.ts @@ -1,15 +1,17 @@ import { - CompilerOptions, concatenate, - DiagnosticWithLocation, - factory, - fixupCompilerOptions, isArray, +} from "../compiler/core"; +import { factory } from "../compiler/factory/nodeFactory"; +import { transformNodes } from "../compiler/transformer"; +import { + CompilerOptions, + DiagnosticWithLocation, Node, TransformationResult, TransformerFactory, - transformNodes, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { fixupCompilerOptions } from "./transpile"; /** * Transform one or more nodes using the supplied transformers. diff --git a/src/services/transpile.ts b/src/services/transpile.ts index 7329f788aa197..71d45de2d7c24 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -1,33 +1,43 @@ +import { + createCompilerDiagnosticForInvalidCustomType, + optionDeclarations, + parseCustomTypeOption, + transpileOptionValueCompilerOptions, +} from "../compiler/commandLineParser"; import { addRange, - cloneCompilerOptions, + filter, + getEntries, + hasProperty, + isString, +} from "../compiler/core"; +import { MapLike } from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { createSourceFile } from "../compiler/parser"; +import { + fileExtensionIs, + normalizePath, + toPath, +} from "../compiler/path"; +import { + createProgram, + getImpliedNodeFormatForFile, +} from "../compiler/program"; +import { CommandLineOptionOfCustomType, CompilerHost, CompilerOptions, - createCompilerDiagnosticForInvalidCustomType, - createProgram, - createSourceFile, CustomTransformers, - Debug, Diagnostic, - fileExtensionIs, - filter, +} from "../compiler/types"; +import { forEachEntry, - getDefaultCompilerOptions, getEmitScriptTarget, - getEntries, - getImpliedNodeFormatForFile, getNewLineCharacter, getSetExternalModuleIndicator, - hasProperty, - isString, - MapLike, - normalizePath, - optionDeclarations, - parseCustomTypeOption, - toPath, - transpileOptionValueCompilerOptions, -} from "./_namespaces/ts"; +} from "../compiler/utilities"; +import { getDefaultCompilerOptions } from "./services"; +import { cloneCompilerOptions } from "./utilities"; export interface TranspileOptions { compilerOptions?: CompilerOptions; diff --git a/src/services/types.ts b/src/services/types.ts index ee6c8a22ba4dd..6baf416f00d40 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -1,23 +1,23 @@ +import { EmitOutput } from "../compiler/builderStatePublic"; +import { ModuleResolutionCache } from "../compiler/moduleNameResolver"; import { + __String, CancellationToken, CompilerHost, CompilerOptions, CustomTransformers, Diagnostic, DiagnosticWithLocation, - DocumentHighlights, DocumentPositionMapper, - EmitOutput, - ExportInfoMap, FileReference, GetEffectiveTypeRootsHost, HasChangedAutomaticTypeDirectiveNames, HasInvalidatedResolutions, LineAndCharacter, MinimalResolutionCacheHost, - ModuleResolutionCache, ModuleResolutionInfo, ModuleSpecifierCache, + Node, ParsedCommandLine, Path, Program, @@ -30,16 +30,20 @@ import { ScriptKind, SourceFile, SourceFileLike, - SourceMapper, Symbol, - SymlinkCache, + SymbolFlags, + SyntaxKind, TextChangeRange, - textChanges, TextRange, TextSpan, + TriviaSyntaxKind, + TypeChecker, TypeReferenceDirectiveResolutionInfo, UserPreferences, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { SymlinkCache } from "../compiler/utilities"; +import { RulesMap } from "./formatting/rulesMap"; +import { SourceMapper } from "./sourcemaps"; declare module "../compiler/types" { // Module transform: converted from interface augmentation @@ -280,11 +284,6 @@ export interface ProjectPackageJsonInfo { has(dependencyName: string, inGroups?: PackageJsonDependencyGroup): boolean; } -/** @internal */ -export interface FormattingHost { - getNewLine?(): string; -} - /** @internal */ export const enum PackageJsonAutoImportPreference { Off, @@ -398,6 +397,39 @@ export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalR /** @internal */ getIncompleteCompletionsCache?(): IncompleteCompletionsCache; } +/** @internal */ +export interface ExportInfoMap { + isUsableByFile(importingFile: 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) => T | undefined): T | undefined; + releaseSymbols(): void; + isEmpty(): boolean; + /** @returns Whether the change resulted in the cache being cleared */ + onFileChanged(oldSourceFile: SourceFile, newSourceFile: SourceFile, typeAcquisitionEnabled: boolean): boolean; +} + +/** @internal */ +export const enum ExportKind { + Named, + Default, + ExportEquals, + UMD, +} + +/** @internal */ +export interface SymbolExportInfo { + readonly symbol: Symbol; + readonly moduleSymbol: Symbol; + /** Set if `moduleSymbol` is an external module, not an ambient module */ + moduleFileName: string | undefined; + exportKind: ExportKind; + targetFlags: SymbolFlags; + /** True if export was only found via the package.json AutoImportProvider (for telemetry). */ + isFromPackageJson: boolean; +} + /** @internal */ export const emptyOptions = {}; @@ -1005,6 +1037,11 @@ export interface HighlightSpan { kind: HighlightSpanKind; } +export interface DocumentHighlights { + fileName: string; + highlightSpans: HighlightSpan[]; +} + export interface NavigateToItem { name: string; kind: ScriptElementKind; @@ -1092,6 +1129,12 @@ export interface FormatCodeSettings extends EditorSettings { readonly semicolons?: SemicolonPreference; } +/** @internal */ +export interface FormattingHost { + getNewLine?(): string; +} + + export function getDefaultFormatCodeSettings(newLineCharacter?: string): FormatCodeSettings { return { indentSize: 4, @@ -1697,13 +1740,27 @@ export interface CodeFixRegistration { } /** @internal */ -export interface CodeFixContextBase extends textChanges.TextChangesContext { +export interface CodeFixContextBase extends TextChangesContext { sourceFile: SourceFile; program: Program; cancellationToken: CancellationToken; preferences: UserPreferences; } +/** @internal */ +export interface FormatContext { + readonly options: FormatCodeSettings; + readonly host: FormattingHost; + readonly getRules: RulesMap; +} + +/** @internal */ +export interface TextChangesContext { + host: LanguageServiceHost; + formatContext: FormatContext; + preferences: UserPreferences; +} + /** @internal */ export interface CodeFixAllContext extends CodeFixContextBase { fixId: {}; @@ -1729,7 +1786,7 @@ export interface Refactor { } /** @internal */ -export interface RefactorContext extends textChanges.TextChangesContext { +export interface RefactorContext extends TextChangesContext { file: SourceFile; startPosition: number; endPosition?: number; @@ -1748,3 +1805,62 @@ export interface InlayHintsContext { span: TextSpan; preferences: UserPreferences; } + +/** + * Returned by refactor functions when some error message needs to be surfaced to users. + * @internal + */ +export interface RefactorErrorInfo { + error: string; +} + +/** @internal */ +export interface ContextWithStartAndEndNode { + start: Node; + end: Node; +} + +/** @internal */ +export type ContextNode = Node | ContextWithStartAndEndNode; + +/** @internal */ +export type Entry = NodeEntry | SpanEntry; + +/** @internal */ +export interface NodeEntry { + readonly kind: NodeEntryKind; + readonly node: Node; + readonly context?: ContextNode; +} + +/** @internal */ +export interface SpanEntry { + readonly kind: EntryKind.Span; + readonly fileName: string; + readonly textSpan: TextSpan; +} + +/** @internal */ +export const enum EntryKind { Span, Node, StringLiteral, SearchedLocalFoundProperty, SearchedPropertyFoundLocal } + +/** @internal */ +export type NodeEntryKind = + | EntryKind.Node + | EntryKind.StringLiteral + | EntryKind.SearchedLocalFoundProperty + | EntryKind.SearchedPropertyFoundLocal; + +/** @internal */ +export interface TextRangeWithKind extends TextRange { + kind: T; +} + +/** @internal */ +export type TextRangeWithTriviaKind = TextRangeWithKind; + +/** @internal */ +export interface TokenInfo { + leadingTrivia: TextRangeWithTriviaKind[] | undefined; + token: TextRangeWithKind; + trailingTrivia: TextRangeWithTriviaKind[] | undefined; +} diff --git a/src/services/utilities.ts b/src/services/utilities.ts index a5e151ac7ab1a..ee470673e0d4d 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1,198 +1,102 @@ import { - __String, - addEmitFlags, - addSyntheticLeadingComment, - addSyntheticTrailingComment, - AnyImportOrRequireStatement, + getModuleInstanceState, + ModuleInstanceState, +} from "../compiler/binder"; +import { + getNodeId, + getSymbolId, +} from "../compiler/checkerUtilities"; +import { setConfigFileInOptions } from "../compiler/commandLineParser"; +import { assertType, - AssignmentDeclarationKind, - BinaryExpression, binarySearchKey, - BindingElement, - BreakOrContinueStatement, - CallExpression, - canHaveModifiers, - CaseClause, cast, - CatchClause, - CharacterCodes, - ClassDeclaration, - ClassExpression, clone, - codefix, - combinePaths, - CommentKind, - CommentRange, compareTextSpans, compareValues, - Comparison, - CompilerOptions, - ConditionalExpression, + concatenate, contains, - createPrinter, - createRange, - createScanner, - createTextSpan, - createTextSpanFromBounds, - Debug, - Declaration, - Decorator, - defaultMaximumTruncationLength, - DeleteExpression, - Diagnostic, - DiagnosticMessage, - DiagnosticWithLocation, - directoryProbablyExists, - DisplayPartsSymbolWriter, - DocumentPosition, - DocumentSpan, - DoStatement, - ElementAccessExpression, - EmitFlags, - EmitHint, emptyArray, - EndOfFileToken, - ensureScriptKind, - EqualityOperator, - escapeString, - ExportAssignment, - ExportDeclaration, - Expression, - ExpressionStatement, - factory, - FileTextChanges, filter, find, - findAncestor, - findConfigFile, first, firstDefined, firstOrUndefined, - forEachAncestorDirectory, - forEachChild, - forEachLeadingCommentRange, - forEachTrailingCommentRange, - FormatCodeSettings, - formatStringFromArgs, - formatting, - FormattingHost, - ForOfStatement, - FunctionDeclaration, - FunctionExpression, - FunctionLikeDeclaration, - getAssignmentDeclarationKind, - getCombinedNodeFlagsAlwaysIncludeJSDoc, - getDirectoryPath, - getEmitScriptTarget, - getExternalModuleImportEqualsDeclarationExpression, - getIndentString, - getJSDocEnumTag, - getLastChild, - getLineAndCharacterOfPosition, - getLineStarts, - getLocaleSpecificMessage, - getModuleInstanceState, - getNameOfDeclaration, - getNodeId, - getPackageNameFromTypesPackageName, - getPathComponents, - getRootDeclaration, - getSourceFileOfNode, - getSpanOfTokenAtPosition, - getSymbolId, - getTextOfIdentifierOrLiteral, - getTextOfNode, - getTypesPackageName, - hasSyntacticModifier, - HeritageClause, - Identifier, - identifierIsThisKeyword, identity, - idText, - IfStatement, - ImportClause, - ImportDeclaration, - ImportSpecifier, - ImportTypeNode, - indexOfNode, - IndexSignatureDeclaration, - InternalSymbolName, - isAmbientModule, - isAnyImportSyntax, isArray, + isWhiteSpaceLike, + isWhiteSpaceSingleLine, + last, + lastOrUndefined, + map, + maybeBind, + noop, + notImplemented, + or, + singleOrUndefined, + some, + stableSort, + startsWith, + stringContains, + tryCast, +} from "../compiler/core"; +import { Comparison } from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { createPrinter } from "../compiler/emitter"; +import { + addEmitFlags, + addSyntheticLeadingComment, + addSyntheticTrailingComment, +} from "../compiler/factory/emitNode"; +import { factory } from "../compiler/factory/nodeFactory"; +import { isArrayBindingPattern, isArrayTypeNode, isAsExpression, isAwaitExpression, isBinaryExpression, isBindingElement, - isBreakOrContinueStatement, isCallExpression, - isCallOrNewExpression, isClassDeclaration, isClassExpression, isClassStaticBlockDeclaration, isConditionalTypeNode, - IScriptSnapshot, - isDeclaration, - isDeclarationName, isDecorator, isDeleteExpression, isElementAccessExpression, - isEntityName, isEnumDeclaration, isExportAssignment, isExportDeclaration, isExportSpecifier, - isExpression, - isExpressionNode, - isExternalModule, - isExternalModuleImportEqualsDeclaration, + isExpressionStatement, isExternalModuleReference, - isFileLevelUniqueName, isForInStatement, isForOfStatement, - isFunctionBlock, isFunctionDeclaration, isFunctionExpression, - isFunctionLike, isGetAccessorDeclaration, - isGlobalScopeAugmentation, isHeritageClause, isIdentifier, - isImportCall, isImportClause, isImportDeclaration, isImportEqualsDeclaration, - isImportOrExportSpecifier, isImportSpecifier, isInferTypeNode, - isInJSFile, isInterfaceDeclaration, - isInternalModuleImportEqualsDeclaration, isJSDoc, - isJSDocCommentContainingNode, isJSDocLink, isJSDocLinkCode, - isJSDocLinkLike, isJSDocMemberName, isJSDocNameReference, - isJSDocTag, isJSDocTemplateTag, - isJSDocTypeAlias, isJsxElement, isJsxExpression, - isJsxOpeningLikeElement, isJsxText, - isKeyword, isLabeledStatement, - isLet, isLiteralTypeNode, isMappedTypeNode, - isModifier, isModuleBlock, isModuleDeclaration, - isNamedDeclaration, isNamedExports, isNamedImports, isNamespaceExport, @@ -201,124 +105,152 @@ import { isNumericLiteral, isObjectBindingPattern, isObjectLiteralExpression, - isOptionalChain, - isOptionalChainRoot, isParameter, - isPartOfTypeNode, isPrivateIdentifier, isPropertyAccessExpression, - isPropertyNameLiteral, isQualifiedName, - isRequireCall, - isRequireVariableStatement, - isRightSideOfQualifiedNameOrPropertyAccess, - isRootedDiskPath, isSetAccessorDeclaration, isSourceFile, - isSourceFileJS, - isStringDoubleQuoted, isStringLiteral, - isStringLiteralLike, - isStringOrNumericLiteralLike, - isStringTextContainingNode, isSyntaxList, isTaggedTemplateExpression, - isTemplateLiteralKind, - isToken, isTypeAliasDeclaration, - isTypeElement, - isTypeNode, isTypeOfExpression, isTypeOperatorNode, isTypeParameterDeclaration, isTypeReferenceNode, - isVarConst, isVariableDeclarationList, + isVariableStatement, isVoidExpression, - isWhiteSpaceLike, - isWhiteSpaceSingleLine, isYieldExpression, +} from "../compiler/factory/nodeTests"; +import { + canHaveModifiers, + setOriginalNode, + setTextRange, +} from "../compiler/factory/utilitiesPublic"; +import { + getPackageNameFromTypesPackageName, + getTypesPackageName, +} from "../compiler/moduleNameResolver"; +import { getNodeModulesPackageName } from "../compiler/moduleSpecifiers"; +import { + forEachChild, + isExternalModule, +} from "../compiler/parser"; +import { + combinePaths, + forEachAncestorDirectory, + getDirectoryPath, + getPathComponents, + isRootedDiskPath, + normalizePath, + pathIsRelative, +} from "../compiler/path"; +import { findConfigFile } from "../compiler/program"; +import { + createScanner, + forEachLeadingCommentRange, + forEachTrailingCommentRange, + getLineAndCharacterOfPosition, + getLineStarts, + getTrailingCommentRanges, + Scanner, + stringToToken, + tokenToString, +} from "../compiler/scanner"; +import { nullTransformationContext } from "../compiler/transformer"; +import { + __String, + AnyImportOrRequireStatement, + AssignmentDeclarationKind, + BinaryExpression, + BindingElement, + BreakOrContinueStatement, + CallExpression, + CaseClause, + CatchClause, + CharacterCodes, + ClassDeclaration, + ClassExpression, + CommentKind, + CommentRange, + CompilerOptions, + ConditionalExpression, + Declaration, + Decorator, + DeleteExpression, + Diagnostic, + DiagnosticMessage, + DiagnosticWithLocation, + DocumentPosition, + DoStatement, + ElementAccessExpression, + EmitFlags, + EmitHint, + EndOfFileToken, + EqualityOperator, + ExportAssignment, + ExportDeclaration, + Expression, + ExpressionStatement, + ForInOrOfStatement, + ForOfStatement, + FunctionDeclaration, + FunctionExpression, + FunctionLikeDeclaration, + HeritageClause, + Identifier, + IfStatement, + ImportClause, + ImportDeclaration, + ImportSpecifier, + ImportTypeNode, + IndexSignatureDeclaration, + InternalSymbolName, IterationStatement, JSDocLink, JSDocLinkCode, - JSDocLinkDisplayPart, JSDocLinkPlain, JSDocTypedefTag, - JsTyping, JsxEmit, JsxOpeningLikeElement, LabeledStatement, - LanguageServiceHost, - last, - lastOrUndefined, LiteralExpression, - map, - maybeBind, Modifier, ModifierFlags, ModuleDeclaration, - ModuleInstanceState, ModuleResolutionKind, ModuleSpecifierResolutionHost, - moduleSpecifiers, - Mutable, + NamedDeclaration, NewExpression, NewLineKind, Node, NodeArray, NodeBuilderFlags, NodeFlags, - nodeIsMissing, - nodeIsPresent, - nodeIsSynthesized, - noop, - normalizePath, NoSubstitutionTemplateLiteral, - notImplemented, - nullTransformationContext, NumericLiteral, - or, - OrganizeImports, - PackageJsonDependencyGroup, - pathIsRelative, + ParameterDeclaration, PrefixUnaryExpression, Program, - ProjectPackageJsonInfo, PropertyAccessExpression, PropertyAssignment, + PropertyDeclaration, PropertyName, + PropertySignature, QualifiedName, - RefactorContext, - Scanner, - ScriptElementKind, - ScriptElementKindModifier, ScriptKind, ScriptTarget, - SemicolonPreference, - setConfigFileInOptions, - setOriginalNode, - setTextRange, Signature, SignatureDeclaration, - singleOrUndefined, - skipAlias, - skipOuterExpressions, - some, SourceFile, SourceFileLike, - SourceMapper, SpreadElement, - stableSort, - startsWith, - stringContains, StringLiteral, StringLiteralLike, - stringToToken, - stripQuotes, Symbol, SymbolAccessibility, - SymbolDisplayPart, - SymbolDisplayPartKind, SymbolFlags, SymbolFormatFlags, SymbolTracker, @@ -328,30 +260,150 @@ import { TemplateExpression, TemplateLiteralToken, TemplateSpan, - TextChange, - textChanges, TextRange, TextSpan, - textSpanContainsPosition, - textSpanContainsTextSpan, - textSpanEnd, Token, - tokenToString, TransientSymbol, - tryCast, Type, TypeChecker, TypeFormatFlags, TypeNode, TypeOfExpression, TypeQueryNode, - unescapeLeadingUnderscores, UserPreferences, VariableDeclaration, - visitEachChild, VoidExpression, YieldExpression, -} from "./_namespaces/ts"; +} from "../compiler/types"; +import { + createRange, + defaultMaximumTruncationLength, + directoryProbablyExists, + ensureScriptKind, + escapeString, + formatStringFromArgs, + getAssignmentDeclarationKind, + getEmitScriptTarget, + getExternalModuleImportEqualsDeclarationExpression, + getIndentString, + getLastChild, + getLeadingCommentRangesOfNode, + getLocaleSpecificMessage, + getRootDeclaration, + getSourceFileOfNode, + getSpanOfTokenAtPosition, + getTextOfIdentifierOrLiteral, + getTextOfNode, + hasSyntacticModifier, + identifierIsThisKeyword, + indexOfNode, + isAmbientModule, + isAnyImportSyntax, + isDeclarationName, + isExpressionNode, + isExternalModuleImportEqualsDeclaration, + isFileLevelUniqueName, + isFunctionBlock, + isGlobalScopeAugmentation, + isImportCall, + isInJSFile, + isInternalModuleImportEqualsDeclaration, + isJSDocTypeAlias, + isKeyword, + isLet, + isPartOfTypeNode, + isPropertyNameLiteral, + isRequireCall, + isRequireVariableStatement, + isRightSideOfQualifiedNameOrPropertyAccess, + isSourceFileJS, + isStringDoubleQuoted, + isStringOrNumericLiteralLike, + isVarConst, + Mutable, + nodeIsMissing, + nodeIsPresent, + nodeIsSynthesized, + skipAlias, + skipOuterExpressions, + stripQuotes, +} from "../compiler/utilities"; +import { + createTextSpan, + createTextSpanFromBounds, + findAncestor, + getCombinedNodeFlagsAlwaysIncludeJSDoc, + getJSDocEnumTag, + getJSDocReturnType, + getJSDocType, + getNameOfDeclaration, + idText, + isBreakOrContinueStatement, + isCallOrNewExpression, + isDeclaration, + isEntityName, + isExpression, + isForInOrOfStatement, + isFunctionLike, + isFunctionLikeDeclaration, + isImportOrExportSpecifier, + isJSDocCommentContainingNode, + isJSDocLinkLike, + isJSDocTag, + isJsxOpeningLikeElement, + isModifier, + isNamedDeclaration, + isOptionalChain, + isOptionalChainRoot, + isStringLiteralLike, + isStringTextContainingNode, + isTemplateLiteralKind, + isToken, + isTypeElement, + isTypeNode, + textSpanContainsPosition, + textSpanContainsTextSpan, + textSpanEnd, + unescapeLeadingUnderscores, +} from "../compiler/utilitiesPublic"; +import { visitEachChild } from "../compiler/visitorPublic"; +import * as JsTyping from "../jsTyping/jsTyping"; +import { moduleSymbolToValidIdentifier } from "./codefixes/importAdder"; +import { + compareImportsOrRequireStatements, + getImportDeclarationInsertionIndex, + importsAreSorted, +} from "./organizeImports"; +import { DisplayPartsSymbolWriter } from "./services"; +import { SourceMapper } from "./sourcemaps"; +import { + ChangeTracker, + LeadingTriviaOption, +} from "./textChanges"; +import { + ContextNode, + ContextWithStartAndEndNode, + DocumentSpan, + Entry, + EntryKind, + FileTextChanges, + FormatCodeSettings, + FormatContext, + FormattingHost, + IScriptSnapshot, + JSDocLinkDisplayPart, + LanguageServiceHost, + PackageJsonDependencyGroup, + ProjectPackageJsonInfo, + RefactorContext, + ScriptElementKind, + ScriptElementKindModifier, + SemicolonPreference, + SymbolDisplayPart, + SymbolDisplayPartKind, + TextChange, + TextRangeWithKind, +} from "./types"; // These utilities are common to multiple language service features. //#region @@ -2090,7 +2142,7 @@ export function getPossibleTypeArgumentsInfo(tokenIn: Node | undefined, sourceFi * @internal */ export function isInComment(sourceFile: SourceFile, position: number, tokenAtPosition?: Node): CommentRange | undefined { - return formatting.getRangeOfEnclosingComment(sourceFile, position, /*precedingToken*/ undefined, tokenAtPosition); + return getRangeOfEnclosingComment(sourceFile, position, /*precedingToken*/ undefined, tokenAtPosition); } /** @internal */ @@ -2538,21 +2590,21 @@ export function findModifier(node: Node, kind: Modifier["kind"]): Modifier | und } /** @internal */ -export function insertImports(changes: textChanges.ChangeTracker, sourceFile: SourceFile, imports: AnyImportOrRequireStatement | readonly AnyImportOrRequireStatement[], blankLineBetween: boolean): void { +export function insertImports(changes: 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]; + const sortedNewImports = isArray(imports) ? stableSort(imports, compareImportsOrRequireStatements) : [imports]; if (!existingImportStatements.length) { changes.insertNodesAtTopOfFile(sourceFile, sortedNewImports, blankLineBetween); } - else if (existingImportStatements && OrganizeImports.importsAreSorted(existingImportStatements)) { + else if (existingImportStatements && importsAreSorted(existingImportStatements)) { for (const newImport of sortedNewImports) { - const insertionIndex = OrganizeImports.getImportDeclarationInsertionIndex(existingImportStatements, newImport); + const insertionIndex = 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: LeadingTriviaOption.Exclude } : {}; changes.insertNodeBefore(sourceFile, existingImportStatements[0], newImport, /*blankLineBetween*/ false, options); } else { @@ -3740,7 +3792,7 @@ export function createPackageJsonImportFilter(fromFile: SourceFile, preferences: if (!stringContains(importedFileName, "node_modules")) { return undefined; } - const specifier = moduleSpecifiers.getNodeModulesPackageName( + const specifier = getNodeModulesPackageName( host.getCompilationSettings(), fromFile, importedFileName, @@ -3882,8 +3934,8 @@ export function getNamesForExportedSymbol(symbol: Symbol, scriptTarget: ScriptTa 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); + const fileNameCase = moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, /*preferCapitalized*/ false); + const capitalized = moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, /*preferCapitalized*/ true); if (fileNameCase === capitalized) return fileNameCase; return [fileNameCase, capitalized]; } @@ -3895,7 +3947,7 @@ export function getNameForExportedSymbol(symbol: Symbol, scriptTarget: ScriptTar 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); + || moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, !!preferCapitalized); } return symbol.name; @@ -4007,7 +4059,7 @@ export function diagnosticToString(diag: DiagnosticAndArguments): string { * * @internal */ -export function getFormatCodeSettingsForWriting({ options }: formatting.FormatContext, sourceFile: SourceFile): FormatCodeSettings { +export function getFormatCodeSettingsForWriting({ options }: FormatContext, sourceFile: SourceFile): FormatCodeSettings { const shouldAutoDetectSemicolonPreference = !options.semicolons || options.semicolons === SemicolonPreference.Ignore; const shouldRemoveSemicolons = options.semicolons === SemicolonPreference.Remove || shouldAutoDetectSemicolonPreference && !probablyUsesSemicolons(sourceFile); return { @@ -4025,3 +4077,155 @@ export function jsxModeNeedsExplicitImport(jsx: JsxEmit | undefined) { export function isSourceFileFromLibrary(program: Program, node: SourceFile) { return program.isSourceFileFromExternalLibrary(node) || program.isSourceFileDefaultLibrary(node); } + +/** @internal */ +export type DeclarationWithType = | FunctionLikeDeclaration | VariableDeclaration | PropertySignature | PropertyDeclaration; + +/** @internal */ +export function parameterShouldGetTypeFromJSDoc(node: Node): node is DeclarationWithType { + return isDeclarationWithType(node) && hasUsableJSDoc(node); +} + +function isDeclarationWithType(node: Node): node is DeclarationWithType { + return isFunctionLikeDeclaration(node) + || node.kind === SyntaxKind.VariableDeclaration + || node.kind === SyntaxKind.PropertySignature + || node.kind === SyntaxKind.PropertyDeclaration; +} + +function hasUsableJSDoc(decl: DeclarationWithType | ParameterDeclaration): boolean { + return isFunctionLikeDeclaration(decl) ? decl.parameters.some(hasUsableJSDoc) || (!decl.type && !!getJSDocReturnType(decl)) : !decl.type && !!getJSDocType(decl); +} + +/** @internal */ +export function getContextNode(node: NamedDeclaration | BinaryExpression | ForInOrOfStatement | undefined): ContextNode | undefined { + if (!node) return undefined; + switch (node.kind) { + case SyntaxKind.VariableDeclaration: + return !isVariableDeclarationList(node.parent) || node.parent.declarations.length !== 1 ? + node : + isVariableStatement(node.parent.parent) ? + node.parent.parent : + isForInOrOfStatement(node.parent.parent) ? + getContextNode(node.parent.parent) : + node.parent; + + case SyntaxKind.BindingElement: + return getContextNode(node.parent.parent as NamedDeclaration); + + case SyntaxKind.ImportSpecifier: + return node.parent.parent.parent; + + case SyntaxKind.ExportSpecifier: + case SyntaxKind.NamespaceImport: + return node.parent.parent; + + case SyntaxKind.ImportClause: + case SyntaxKind.NamespaceExport: + return node.parent; + + case SyntaxKind.BinaryExpression: + return isExpressionStatement(node.parent) ? + node.parent : + node; + + case SyntaxKind.ForOfStatement: + case SyntaxKind.ForInStatement: + return { + start: (node as ForInOrOfStatement).initializer, + end: (node as ForInOrOfStatement).expression + }; + + case SyntaxKind.PropertyAssignment: + case SyntaxKind.ShorthandPropertyAssignment: + return isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent) ? + getContextNode( + findAncestor(node.parent, node => + isBinaryExpression(node) || isForInOrOfStatement(node) + ) as BinaryExpression | ForInOrOfStatement + ) : + node; + + default: + return node; + } +} + +/** @internal */ +export function toContextSpan(textSpan: TextSpan, sourceFile: SourceFile, context?: ContextNode): { contextSpan: TextSpan } | undefined { + if (!context) return undefined; + const contextSpan = isContextWithStartAndEndNode(context) ? getTextSpan(context.start, sourceFile, context.end) : getTextSpan(context, sourceFile); + return contextSpan.start !== textSpan.start || contextSpan.length !== textSpan.length ? { contextSpan } : undefined; +} + +/** @internal */ +export function isContextWithStartAndEndNode(node: ContextNode): node is ContextWithStartAndEndNode { + return node && (node as Node).kind === undefined; +} + +/** @internal */ +export function getTextSpan(node: Node, sourceFile: SourceFile, endNode?: Node): TextSpan { + let start = node.getStart(sourceFile); + let end = (endNode || node).getEnd(); + if (isStringLiteralLike(node) && (end - start) > 2) { + Debug.assert(endNode === undefined); + start += 1; + end -= 1; + } + return createTextSpanFromBounds(start, end); +} + +/** @internal */ +export function getTextSpanOfEntry(entry: Entry) { + return entry.kind === EntryKind.Span ? entry.textSpan : getTextSpan(entry.node, entry.node.getSourceFile()); +} + +/** @internal */ +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; + 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; + + // 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) || + // 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): + // + // // asdf ^\n + // + // But for closed multi-line comments, we don't want to be inside the comment in the following case: + // + // /* asdf */^ + // + // However, unterminated multi-line comments *do* contain their end. + // + // Internally, we represent the end of the comment at the newline and closing '/', respectively. + // + position === range.end && (range.kind === SyntaxKind.SingleLineCommentTrivia || position === sourceFile.getFullWidth())); +} + +/** @internal */ +export function createTextRangeWithKind(pos: number, end: number, kind: T): TextRangeWithKind { + const textRangeWithKind: TextRangeWithKind = { pos, end, kind }; + if (Debug.isDebugging) { + Object.defineProperty(textRangeWithKind, "__debugKind", { + get: () => Debug.formatSyntaxKind(kind), + }); + } + return textRangeWithKind; +} diff --git a/src/testRunner/unittests/services/convertToAsyncFunction.ts b/src/testRunner/unittests/services/convertToAsyncFunction.ts index d677b34885fed..8e99969fcfeac 100644 --- a/src/testRunner/unittests/services/convertToAsyncFunction.ts +++ b/src/testRunner/unittests/services/convertToAsyncFunction.ts @@ -1,15 +1,10 @@ import * as ts from "../../_namespaces/ts"; import * as Harness from "../../_namespaces/Harness"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; +import { createServerHost, File } from "../virtualFileSystemWithWatch"; import { createProjectService } from "../tsserver/helpers"; -import { - extractTest, - newLineCharacter, - notImplementedHost, -} from "./extract/helpers"; +import { extractTest, newLineCharacter, notImplementedHost } from "./extract/helpers"; +import { applyChanges } from "../../../services/textChanges"; +import { getFormatContext } from "../../../services/formatting/formatting"; const libFile: File = { path: "/a/lib/lib.d.ts", @@ -356,7 +351,7 @@ function testConvertToAsyncFunction(it: Mocha.PendingTestFunction, caption: stri cancellationToken: { throwIfCancellationRequested: ts.noop, isCancellationRequested: ts.returnFalse }, preferences: ts.emptyOptions, host: notImplementedHost, - formatContext: ts.formatting.getFormatContext(ts.testFormatSettings, notImplementedHost) + formatContext: getFormatContext(ts.testFormatSettings, notImplementedHost) }; const diagnostics = languageService.getSuggestionDiagnostics(f.path); @@ -374,7 +369,7 @@ function testConvertToAsyncFunction(it: Mocha.PendingTestFunction, caption: stri assert.lengthOf(changes, 1); data.push(`// ==ASYNC FUNCTION::${action.description}==`); - const newText = ts.textChanges.applyChanges(sourceFile.text, changes[0].textChanges); + const newText = applyChanges(sourceFile.text, changes[0].textChanges); data.push(newText); const diagProgram = makeLanguageService({ path, content: newText }, includeLib, includeModule).getProgram()!; diff --git a/src/testRunner/unittests/services/extract/helpers.ts b/src/testRunner/unittests/services/extract/helpers.ts index 170ac60d0df94..05a5e94ec5a65 100644 --- a/src/testRunner/unittests/services/extract/helpers.ts +++ b/src/testRunner/unittests/services/extract/helpers.ts @@ -5,6 +5,8 @@ import { libFile, } from "../../virtualFileSystemWithWatch"; import { createProjectService } from "../../tsserver/helpers"; +import { applyChanges } from "../../../../services/textChanges"; +import { getFormatContext } from "../../../../services/formatting/formatting"; interface Range { pos: number; @@ -111,7 +113,7 @@ export function testExtractSymbol(caption: string, text: string, baselineFolder: startPosition: selectionRange.pos, endPosition: selectionRange.end, host: notImplementedHost, - formatContext: ts.formatting.getFormatContext(ts.testFormatSettings, notImplementedHost), + formatContext: getFormatContext(ts.testFormatSettings, notImplementedHost), preferences: ts.emptyOptions, }; const rangeToExtract = ts.refactor.extractSymbol.getRangeToExtract(sourceFile, ts.createTextSpanFromRange(selectionRange)); @@ -126,7 +128,7 @@ export function testExtractSymbol(caption: string, text: string, baselineFolder: const { renameLocation, edits } = ts.refactor.extractSymbol.getRefactorEditsToExtractSymbol(context, action.name)!; assert.lengthOf(edits, 1); data.push(`// ==SCOPE::${action.description}==`); - const newText = ts.textChanges.applyChanges(sourceFile.text, edits[0].textChanges); + const newText = applyChanges(sourceFile.text, edits[0].textChanges); const newTextWithRename = newText.slice(0, renameLocation) + "/*RENAME*/" + newText.slice(renameLocation); data.push(newTextWithRename); @@ -174,7 +176,7 @@ export function testExtractSymbolFailed(caption: string, text: string, descripti startPosition: selectionRange.pos, endPosition: selectionRange.end, host: notImplementedHost, - formatContext: ts.formatting.getFormatContext(ts.testFormatSettings, notImplementedHost), + formatContext: getFormatContext(ts.testFormatSettings, notImplementedHost), preferences: ts.emptyOptions, }; const rangeToExtract = ts.refactor.extractSymbol.getRangeToExtract(sourceFile, ts.createTextSpanFromRange(selectionRange)); diff --git a/src/testRunner/unittests/services/organizeImports.ts b/src/testRunner/unittests/services/organizeImports.ts index 8188d9a2cfd22..cab0113ab56b2 100644 --- a/src/testRunner/unittests/services/organizeImports.ts +++ b/src/testRunner/unittests/services/organizeImports.ts @@ -6,6 +6,7 @@ import { } from "../virtualFileSystemWithWatch"; import { createProjectService } from "../tsserver/helpers"; import { newLineCharacter } from "./extract/helpers"; +import { applyChanges } from "../../../services/textChanges"; describe("unittests:: services:: organizeImports", () => { describe("Sort imports", () => { @@ -1025,7 +1026,7 @@ export * from "lib"; assert.equal(changes.length, 1); assert.equal(changes[0].fileName, testPath); - const newText = ts.textChanges.applyChanges(testContent, changes[0].textChanges); + const newText = applyChanges(testContent, changes[0].textChanges); Harness.Baseline.runBaseline(baselinePath, [ "// ==ORIGINAL==", testContent, diff --git a/src/testRunner/unittests/services/textChanges.ts b/src/testRunner/unittests/services/textChanges.ts index a761083145999..c9309cd2d83bc 100644 --- a/src/testRunner/unittests/services/textChanges.ts +++ b/src/testRunner/unittests/services/textChanges.ts @@ -1,6 +1,9 @@ import * as ts from "../../_namespaces/ts"; import * as Harness from "../../_namespaces/Harness"; import { notImplementedHost } from "./extract/helpers"; +import { applyChanges, ChangeTracker, deleteNode, LeadingTriviaOption, TrailingTriviaOption } from "../../../services/textChanges"; +import { FormatContext } from "../../../services/types"; +import { getFormatContext } from "../../../services/formatting/formatting"; // Some tests have trailing whitespace @@ -21,8 +24,8 @@ describe("unittests:: services:: textChanges", () => { 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, notImplementedHost); + function getRuleProvider(placeOpenBraceOnNewLineForFunctions: boolean): FormatContext { + return getFormatContext(placeOpenBraceOnNewLineForFunctions ? { ...ts.testFormatSettings, placeOpenBraceOnNewLineForFunctions: true } : ts.testFormatSettings, notImplementedHost); } // validate that positions that were recovered from the printed text actually match positions that will be created if the same text is parsed. @@ -47,16 +50,16 @@ describe("unittests:: services:: textChanges", () => { } } - function runSingleFileTest(caption: string, placeOpenBraceOnNewLineForFunctions: boolean, text: string, validateNodes: boolean, testBlock: (sourceFile: ts.SourceFile, changeTracker: ts.textChanges.ChangeTracker) => void) { + function runSingleFileTest(caption: string, placeOpenBraceOnNewLineForFunctions: boolean, text: string, validateNodes: boolean, testBlock: (sourceFile: ts.SourceFile, changeTracker: ChangeTracker) => void) { it(caption, () => { const sourceFile = ts.createSourceFile("source.ts", text, ts.ScriptTarget.ES2015, /*setParentNodes*/ true); const rulesProvider = getRuleProvider(placeOpenBraceOnNewLineForFunctions); - const changeTracker = new ts.textChanges.ChangeTracker(newLineCharacter, rulesProvider); + const changeTracker = new 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 = ts.textChanges.applyChanges(sourceFile.text, changes[0].textChanges); + const modified = applyChanges(sourceFile.text, changes[0].textChanges); Harness.Baseline.runBaseline(`textChanges/${caption}.js`, `===ORIGINAL===${newLineCharacter}${text}${newLineCharacter}===MODIFIED===${newLineCharacter}${modified}`); }); } @@ -127,7 +130,6 @@ function bar() { function findVariableDeclarationContaining(name: string, sourceFile: ts.SourceFile): ts.VariableDeclaration { return ts.cast(findChild(name, sourceFile), ts.isVariableDeclaration); } - const { deleteNode } = ts.textChanges; { const text = ` var x = 1; // some comment - 1 @@ -141,13 +143,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: ts.textChanges.LeadingTriviaOption.Exclude }); + deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { leadingTriviaOption: LeadingTriviaOption.Exclude }); }); runSingleFileTest("deleteNode3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); + deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { trailingTriviaOption: TrailingTriviaOption.Exclude }); }); runSingleFileTest("deleteNode4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); + deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { leadingTriviaOption: LeadingTriviaOption.Exclude, trailingTriviaOption: TrailingTriviaOption.Exclude }); }); runSingleFileTest("deleteNode5", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { deleteNode(changeTracker, sourceFile, findVariableStatementContaining("x", sourceFile)); @@ -168,15 +170,15 @@ var a = 4; // comment 7 }); runSingleFileTest("deleteNodeRange2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), - { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude }); + { leadingTriviaOption: LeadingTriviaOption.Exclude }); }); runSingleFileTest("deleteNodeRange3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), - { trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); + { trailingTriviaOption: TrailingTriviaOption.Exclude }); }); runSingleFileTest("deleteNodeRange4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), - { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); + { leadingTriviaOption: LeadingTriviaOption.Exclude, trailingTriviaOption: TrailingTriviaOption.Exclude }); }); } function createTestVariableDeclaration(name: string) { @@ -253,16 +255,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: ts.textChanges.LeadingTriviaOption.Exclude, suffix: newLineCharacter, prefix: newLineCharacter }); + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { leadingTriviaOption: LeadingTriviaOption.Exclude, suffix: newLineCharacter, prefix: newLineCharacter }); }); runSingleFileTest("replaceNode3", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude, suffix: newLineCharacter }); + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { trailingTriviaOption: TrailingTriviaOption.Exclude, suffix: newLineCharacter }); }); runSingleFileTest("replaceNode4", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { leadingTriviaOption: LeadingTriviaOption.Exclude, trailingTriviaOption: TrailingTriviaOption.Exclude }); }); runSingleFileTest("replaceNode5", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNode(sourceFile, findVariableStatementContaining("x", sourceFile), createTestClass(), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("x", sourceFile), createTestClass(), { leadingTriviaOption: LeadingTriviaOption.Exclude, trailingTriviaOption: TrailingTriviaOption.Exclude }); }); } { @@ -278,13 +280,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: ts.textChanges.LeadingTriviaOption.Exclude, suffix: newLineCharacter, prefix: newLineCharacter }); + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { leadingTriviaOption: 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: ts.textChanges.TrailingTriviaOption.Exclude, suffix: newLineCharacter }); + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { trailingTriviaOption: TrailingTriviaOption.Exclude, suffix: newLineCharacter }); }); runSingleFileTest("replaceNodeRange4", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { leadingTriviaOption: LeadingTriviaOption.Exclude, trailingTriviaOption: TrailingTriviaOption.Exclude }); }); } { diff --git a/src/testRunner/unittests/tsserver/exportMapCache.ts b/src/testRunner/unittests/tsserver/exportMapCache.ts index 93a5b517af8e6..326bc6e9effa6 100644 --- a/src/testRunner/unittests/tsserver/exportMapCache.ts +++ b/src/testRunner/unittests/tsserver/exportMapCache.ts @@ -1,14 +1,7 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; -import { - configuredProjectAt, - createSession, - executeSessionRequest, - openFilesForSession, -} from "./helpers"; +import { getSymbolId } from "../../../compiler/checkerUtilities"; +import { createServerHost, File } from "../virtualFileSystemWithWatch"; +import { configuredProjectAt, createSession, executeSessionRequest, openFilesForSession } from "./helpers"; const packageJson: File = { path: "/package.json", @@ -103,7 +96,7 @@ describe("unittests:: tsserver:: exportMapCache", () => { }); assert.ok(sigintPropBefore); assert.ok(sigintPropBefore![0].symbol.flags & ts.SymbolFlags.Transient); - const symbolIdBefore = ts.getSymbolId(sigintPropBefore![0].symbol); + const symbolIdBefore = getSymbolId(sigintPropBefore![0].symbol); // Update program without clearing cache session.executeCommandSeq({ @@ -128,7 +121,7 @@ describe("unittests:: tsserver:: exportMapCache", () => { if (symbolName === "SIGINT") sigintPropAfter = info; }); assert.ok(sigintPropAfter); - assert.notEqual(symbolIdBefore, ts.getSymbolId(sigintPropAfter![0].symbol)); + assert.notEqual(symbolIdBefore, getSymbolId(sigintPropAfter![0].symbol)); }); }); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index d91810e42cc4e..25a57338beb7a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3165,14 +3165,14 @@ declare namespace ts { isKnownTypesPackageName(name: string): boolean; installPackage(options: InstallPackageOptions): Promise; private get typingsCache(); - getCompilationSettings(): ts.CompilerOptions; - getCompilerOptions(): ts.CompilerOptions; + getCompilationSettings(): CompilerOptions; + getCompilerOptions(): CompilerOptions; getNewLine(): string; getProjectVersion(): string; getProjectReferences(): readonly ProjectReference[] | undefined; getScriptFileNames(): string[]; private getOrCreateScriptInfoAndAttachToProject; - getScriptKind(fileName: string): ts.ScriptKind; + getScriptKind(fileName: string): ScriptKind; getScriptVersion(filename: string): string; getScriptSnapshot(filename: string): IScriptSnapshot | undefined; getCancellationToken(): HostCancellationToken; @@ -3212,7 +3212,7 @@ declare namespace ts { getProjectName(): string; protected removeLocalTypingsFromTypeAcquisition(newTypeAcquisition: TypeAcquisition): TypeAcquisition; getExternalFiles(): SortedReadonlyArray; - getSourceFile(path: Path): ts.SourceFile | undefined; + getSourceFile(path: Path): SourceFile | undefined; close(): void; private detachScriptInfoIfNotRoot; isClosed(): boolean; @@ -3249,7 +3249,7 @@ declare namespace ts { filesToString(writeProjectFileNames: boolean): string; setCompilerOptions(compilerOptions: CompilerOptions): void; setTypeAcquisition(newTypeAcquisition: TypeAcquisition | undefined): void; - getTypeAcquisition(): ts.TypeAcquisition; + getTypeAcquisition(): TypeAcquisition; protected removeRoot(info: ScriptInfo): void; protected enableGlobalPlugins(options: CompilerOptions, pluginConfigOverrides: Map | undefined): void; protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[], pluginConfigOverrides: Map | undefined): void; @@ -3283,7 +3283,7 @@ declare namespace ts { getScriptFileNames(): string[]; getLanguageService(): never; getModuleResolutionHostForAutoImportProvider(): never; - getProjectReferences(): readonly ts.ProjectReference[] | undefined; + getProjectReferences(): readonly ProjectReference[] | undefined; getTypeAcquisition(): TypeAcquisition; } /** @@ -3982,6 +3982,10 @@ declare namespace ts { interface Push { push(...values: T[]): void; } + function isWhiteSpaceLike(ch: number): boolean; + /** Does not include line breaks. For that, see isWhiteSpaceLike. */ + function isWhiteSpaceSingleLine(ch: number): boolean; + function isLineBreak(ch: number): boolean; type Path = string & { __pathBrand: any; }; @@ -8435,10 +8439,6 @@ declare namespace ts { function tokenToString(t: SyntaxKind): string | undefined; function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number): number; function getLineAndCharacterOfPosition(sourceFile: SourceFileLike, position: number): LineAndCharacter; - function isWhiteSpaceLike(ch: number): boolean; - /** Does not include line breaks. For that, see isWhiteSpaceLike. */ - function isWhiteSpaceSingleLine(ch: number): boolean; - function isLineBreak(ch: number): boolean; function couldStartTrivia(text: string, pos: number): boolean; function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; @@ -8772,7 +8772,6 @@ declare namespace ts { * Create an external source map source file reference */ function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): SourceMapSource; - function setOriginalNode(node: T, original: Node | undefined): T; const factory: NodeFactory; /** * Clears any `EmitNode` entries from parse-tree nodes. @@ -9045,6 +9044,7 @@ declare namespace ts { function setTextRange(range: T, location: TextRange | undefined): T; function canHaveModifiers(node: Node): node is HasModifiers; function canHaveDecorators(node: Node): node is HasDecorators; + function setOriginalNode(node: T, original: Node | undefined): T; /** * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise, @@ -9330,7 +9330,7 @@ declare namespace ts { * Calculates the resulting resolution mode for some reference in some file - this is generally the explicitly * provided resolution mode in the reference, unless one is not present, in which case it is the mode of the containing file. */ - function getModeForFileReference(ref: FileReference | string, containingFileMode: ResolutionMode): ts.ResolutionMode; + function getModeForFileReference(ref: FileReference | string, containingFileMode: ResolutionMode): ResolutionMode; /** * Calculates the final resolution mode for an import at some index within a file's imports list. This is generally the explicitly * defined mode of the import if provided, or, if not, the mode of the containing file (with some exceptions: import=require is always commonjs, dynamic import is always esm). @@ -9350,7 +9350,7 @@ declare namespace ts { */ function getModeForUsageLocation(file: { impliedNodeFormat?: ResolutionMode; - }, usage: StringLiteralLike): ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined; + }, usage: StringLiteralLike): ResolutionMode; function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): readonly Diagnostic[]; /** * A function for determining if a given file is esm or cjs format, assuming modern node module resolution rules, as configured by the @@ -10336,6 +10336,10 @@ declare namespace ts { contextSpan?: TextSpan; kind: HighlightSpanKind; } + interface DocumentHighlights { + fileName: string; + highlightSpans: HighlightSpan[]; + } interface NavigateToItem { name: string; kind: ScriptElementKind; @@ -10899,10 +10903,6 @@ declare namespace ts { } /** The classifier is used for syntactic highlighting in editors via the TSServer */ function createClassifier(): Classifier; - interface DocumentHighlights { - fileName: string; - highlightSpans: HighlightSpan[]; - } function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory?: string): DocumentRegistry; /** * The document registry represents a store of SourceFile objects that can be shared between diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index f7817050f13ed..098c8361da974 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -46,6 +46,10 @@ declare namespace ts { interface Push { push(...values: T[]): void; } + function isWhiteSpaceLike(ch: number): boolean; + /** Does not include line breaks. For that, see isWhiteSpaceLike. */ + function isWhiteSpaceSingleLine(ch: number): boolean; + function isLineBreak(ch: number): boolean; type Path = string & { __pathBrand: any; }; @@ -4499,10 +4503,6 @@ declare namespace ts { function tokenToString(t: SyntaxKind): string | undefined; function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number): number; function getLineAndCharacterOfPosition(sourceFile: SourceFileLike, position: number): LineAndCharacter; - function isWhiteSpaceLike(ch: number): boolean; - /** Does not include line breaks. For that, see isWhiteSpaceLike. */ - function isWhiteSpaceSingleLine(ch: number): boolean; - function isLineBreak(ch: number): boolean; function couldStartTrivia(text: string, pos: number): boolean; function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; @@ -4836,7 +4836,6 @@ declare namespace ts { * Create an external source map source file reference */ function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): SourceMapSource; - function setOriginalNode(node: T, original: Node | undefined): T; const factory: NodeFactory; /** * Clears any `EmitNode` entries from parse-tree nodes. @@ -5109,6 +5108,7 @@ declare namespace ts { function setTextRange(range: T, location: TextRange | undefined): T; function canHaveModifiers(node: Node): node is HasModifiers; function canHaveDecorators(node: Node): node is HasDecorators; + function setOriginalNode(node: T, original: Node | undefined): T; /** * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise, @@ -5394,7 +5394,7 @@ declare namespace ts { * Calculates the resulting resolution mode for some reference in some file - this is generally the explicitly * provided resolution mode in the reference, unless one is not present, in which case it is the mode of the containing file. */ - function getModeForFileReference(ref: FileReference | string, containingFileMode: ResolutionMode): ts.ResolutionMode; + function getModeForFileReference(ref: FileReference | string, containingFileMode: ResolutionMode): ResolutionMode; /** * Calculates the final resolution mode for an import at some index within a file's imports list. This is generally the explicitly * defined mode of the import if provided, or, if not, the mode of the containing file (with some exceptions: import=require is always commonjs, dynamic import is always esm). @@ -5414,7 +5414,7 @@ declare namespace ts { */ function getModeForUsageLocation(file: { impliedNodeFormat?: ResolutionMode; - }, usage: StringLiteralLike): ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined; + }, usage: StringLiteralLike): ResolutionMode; function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): readonly Diagnostic[]; /** * A function for determining if a given file is esm or cjs format, assuming modern node module resolution rules, as configured by the @@ -6473,6 +6473,10 @@ declare namespace ts { contextSpan?: TextSpan; kind: HighlightSpanKind; } + interface DocumentHighlights { + fileName: string; + highlightSpans: HighlightSpan[]; + } interface NavigateToItem { name: string; kind: ScriptElementKind; @@ -7036,10 +7040,6 @@ declare namespace ts { } /** The classifier is used for syntactic highlighting in editors via the TSServer */ function createClassifier(): Classifier; - interface DocumentHighlights { - fileName: string; - highlightSpans: HighlightSpan[]; - } function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory?: string): DocumentRegistry; /** * The document registry represents a store of SourceFile objects that can be shared between From ee8f7774263223a7ac3b14d6de6cf8bbe8f997ab Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 15 Dec 2022 19:32:15 +0200 Subject: [PATCH 02/24] fix tests --- src/compiler/checker.ts | 108 ++++++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fc8f363e8ed50..5ff78c956f302 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -144,6 +144,7 @@ import { isJSDocNonNullableType, isJSDocNullableType, isJSDocOptionalType, + isJSDocOverloadTag, isJSDocParameterTag, isJSDocPropertyTag, isJSDocReturnTag, @@ -225,11 +226,13 @@ import { createModeAwareCacheKey, getTypesPackageName, mangleScopedPackageName, + shouldAllowImportingTsExtension, } from "./moduleNameResolver"; import { countPathComponents, getModuleSpecifiers } from "./moduleSpecifiers"; import { forEachChild, forEachChildRecursively, + isDeclarationFileName, isExternalModule, parseIsolatedEntityName, parseNodeFactory, @@ -685,6 +688,7 @@ import { createTextWriter, declarationNameToString, defaultMaximumTruncationLength, + emitModuleKindIsNonNodeESM, entityNameToString, escapeString, exportAssignmentIsAlias, @@ -771,6 +775,7 @@ import { getPropertyNameForPropertyNameNode, getResolvedExternalModuleName, getResolvedModule, + getResolveJsonModule, getRestParameterElementType, getRootDeclaration, getScriptTargetFeatures, @@ -4563,6 +4568,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if ( namespace.valueDeclaration && isInJSFile(namespace.valueDeclaration) && + getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Bundler && isVariableDeclaration(namespace.valueDeclaration) && namespace.valueDeclaration.initializer && isCommonJsRequire(namespace.valueDeclaration.initializer) @@ -4747,6 +4753,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { (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 moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions); const resolvedModule = getResolvedModule(currentSourceFile, moduleReference, mode); const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule); const sourceFile = resolvedModule @@ -4757,11 +4764,26 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (resolutionDiagnostic) { error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName); } + if (resolvedModule.resolvedUsingTsExtension && isDeclarationFileName(moduleReference)) { + const importOrExport = + findAncestor(location, isImportDeclaration)?.importClause || + findAncestor(location, or(isImportEqualsDeclaration, isExportDeclaration)); + if (importOrExport && !importOrExport.isTypeOnly || findAncestor(location, isImportCall)) { + error( + errorNode, + Diagnostics.A_declaration_file_cannot_be_imported_without_import_type_Did_you_mean_to_import_an_implementation_file_0_instead, + getSuggestedImportSource(Debug.checkDefined(tryExtractTSExtension(moduleReference)))); + } + } + else if (resolvedModule.resolvedUsingTsExtension && !shouldAllowImportingTsExtension(compilerOptions, currentSourceFile.fileName)) { + const tsExtension = Debug.checkDefined(tryExtractTSExtension(moduleReference)); + error(errorNode, Diagnostics.An_import_path_can_only_end_with_a_0_extension_when_allowImportingTsExtensions_is_enabled, tsExtension); + } if (sourceFile.symbol) { if (resolvedModule.isExternalLibraryImport && !resolutionExtensionIsTSOrJson(resolvedModule.extension)) { errorOnImplicitAnyModule(/*isError*/ false, errorNode, resolvedModule, moduleReference); } - if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) { + if (moduleResolutionKind === ModuleResolutionKind.Node16 || moduleResolutionKind === 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; @@ -4869,25 +4891,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else { const tsExtension = tryExtractTSExtension(moduleReference); const isExtensionlessRelativePathImport = pathIsRelative(moduleReference) && !hasExtension(moduleReference); - const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions); const resolutionIsNode16OrNext = moduleResolutionKind === ModuleResolutionKind.Node16 || moduleResolutionKind === 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); - 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"; - } - error(errorNode, diag, tsExtension, replacedImportSource); - } - else if (!compilerOptions.resolveJsonModule && + errorOnTSExtensionImport(tsExtension); + } + else if (!getResolveJsonModule(compilerOptions) && fileExtensionIs(moduleReference, Extension.Json) && - getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Classic && + moduleResolutionKind !== ModuleResolutionKind.Classic && hasJsonModuleEmitEnabled(compilerOptions)) { error(errorNode, Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference); } @@ -4909,6 +4920,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } return undefined; + + function errorOnTSExtensionImport(tsExtension: string) { + const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; + error(errorNode, diag, tsExtension, getSuggestedImportSource(tsExtension)); + } + + function getSuggestedImportSource(tsExtension: string) { + const importSourceWithoutExtension = removeExtension(moduleReference, tsExtension); + /** + * Direct users to import source with .js extension if outputting an ES module. + * @see https://github.com/microsoft/TypeScript/issues/42151 + */ + if (emitModuleKindIsNonNodeESM(moduleKind) || mode === ModuleKind.ESNext) { + return importSourceWithoutExtension + (tsExtension === Extension.Mts ? ".mjs" : tsExtension === Extension.Cts ? ".cjs" : ".js"); + } + return importSourceWithoutExtension; + } } function errorOnImplicitAnyModule(isError: boolean, errorNode: Node, { packageId, resolvedFileName }: ResolvedModuleFull, moduleReference: string): void { @@ -14266,6 +14294,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { continue; } } + if (isInJSFile(decl) && decl.jsDoc) { + let hasJSDocOverloads = false; + for (const node of decl.jsDoc) { + if (node.tags) { + for (const tag of node.tags) { + if (isJSDocOverloadTag(tag)) { + result.push(getSignatureFromDeclaration(tag.typeExpression)); + hasJSDocOverloads = true; + } + } + } + } + if (hasJSDocOverloads) { + continue; + } + } // If this is a function or method declaration, get the signature from the @type tag for the sake of optional parameters. // Exclude contextually-typed kinds because we already apply the @type tag to the context, plus applying it here to the initializer would supress checks that the two are compatible. result.push( @@ -17585,6 +17629,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return getTypeOfSymbol(symbol); // intentionally doesn't use resolved symbol so type is cached as expected on the alias } else { + const type = tryGetDeclaredTypeOfSymbol(resolvedSymbol); // call this first to ensure typeParameters is populated (if applicable) + const typeParameters = type && getTypeParametersForTypeAndSymbol(type, resolvedSymbol); + if (node.typeArguments && typeParameters) { + addLazyDiagnostic(() => { + checkTypeArgumentConstraints(node, typeParameters); + }); + } return getTypeReferenceType(node, resolvedSymbol); // getTypeReferenceType doesn't handle aliases - it must get the resolved symbol } } @@ -33324,7 +33375,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // In JavaScript files, calls to any identifier 'require' are treated as external module imports - if (isInJSFile(node) && isCommonJsRequire(node)) { + if (isInJSFile(node) && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Bundler && isCommonJsRequire(node)) { return resolveExternalModuleTypeByLiteral(node.arguments![0] as StringLiteral); } @@ -37245,12 +37296,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return getEffectiveTypeArguments(node, typeParameters)[index]; } - function getEffectiveTypeArguments(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: readonly TypeParameter[]): Type[] { + function getEffectiveTypeArguments(node: TypeReferenceNode | ExpressionWithTypeArguments | NodeWithTypeArguments, typeParameters: readonly TypeParameter[]): Type[] { return fillMissingTypeArguments(map(node.typeArguments!, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(node)); } - function checkTypeArgumentConstraints(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: readonly TypeParameter[]): boolean { + function checkTypeArgumentConstraints(node: TypeReferenceNode | ExpressionWithTypeArguments | NodeWithTypeArguments, typeParameters: readonly TypeParameter[]): boolean { let typeArguments: Type[] | undefined; let mapper: TypeMapper | undefined; let result = true; @@ -37271,13 +37322,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return result; } + function getTypeParametersForTypeAndSymbol(type: Type, symbol: Symbol) { + if (!isErrorType(type)) { + return symbol.flags & SymbolFlags.TypeAlias && getSymbolLinks(symbol).typeParameters || + (getObjectFlags(type) & ObjectFlags.Reference ? (type as TypeReference).target.localTypeParameters : undefined); + } + return undefined; + } + function getTypeParametersForTypeReference(node: TypeReferenceNode | 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 getTypeParametersForTypeAndSymbol(type, symbol); } } return undefined; @@ -42727,6 +42785,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // 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); } + else if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Bundler) { + grammarErrorOnNode(node, Diagnostics.Import_assignment_is_not_allowed_when_moduleResolution_is_set_to_bundler_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead); + } } } } @@ -42949,6 +43010,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // system modules does not support export assignment grammarErrorOnNode(node, Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system); } + else if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Bundler) { + grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_moduleResolution_is_set_to_bundler_Consider_using_export_default_or_another_module_format_instead); + } } } @@ -44043,7 +44107,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // 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)) || + ((isInJSFile(node) && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Bundler && 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); From d7ed7df1e880122d92473c1d0f185e2898259cad Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 5 Jan 2023 09:53:24 +0200 Subject: [PATCH 03/24] include debug in scanner/core/semver --- src/compiler/_namespaces/ts.ts | 9 + src/compiler/binder.ts | 14 +- src/compiler/builder.ts | 8 +- src/compiler/checker.ts | 138 +- src/compiler/checkerUtilities.ts | 110 ++ src/compiler/commandLineParser.ts | 12 +- src/compiler/commandLineParserUtilities.ts | 16 + src/compiler/core.ts | 54 +- src/compiler/debug.ts | 824 +--------- src/compiler/debugUtilities.ts | 870 +++++++++++ src/compiler/emitter.ts | 11 +- src/compiler/emitterUtilities.ts | 45 + src/compiler/factory/baseNodeFactory.ts | 2 +- .../factory/binaryExpressionStateMachine.ts | 3 +- src/compiler/factory/nodeFactory.ts | 7 +- src/compiler/factory/utilities.ts | 14 +- src/compiler/fileMatcher.ts | 344 ++++ src/compiler/moduleNameResolver.ts | 4 +- src/compiler/moduleSpecifiers.ts | 10 +- src/compiler/moduleSpecifiersUtilities.ts | 165 ++ src/compiler/objectAllocator.ts | 128 ++ src/compiler/parser.ts | 23 +- src/compiler/parserUtilities.ts | 209 +++ src/compiler/performance.ts | 7 +- src/compiler/performanceCore.ts | 29 - src/compiler/program.ts | 106 +- src/compiler/programUtilities.ts | 96 ++ src/compiler/resolutionCache.ts | 10 +- src/compiler/scanner.ts | 93 +- src/compiler/scannerUtilities.ts | 84 + src/compiler/semver.ts | 32 +- src/compiler/symlinkCache.ts | 128 ++ src/compiler/sys.ts | 173 +- src/compiler/sysUtilities.ts | 25 + src/compiler/tracing.ts | 2 +- src/compiler/transformers/declarations.ts | 8 +- src/compiler/transformers/es2015.ts | 2 +- src/compiler/transformers/es2017.ts | 3 +- src/compiler/transformers/es2018.ts | 3 +- src/compiler/transformers/generators.ts | 4 +- src/compiler/transformers/jsx.ts | 4 +- .../transformers/module/esnextAnd2015.ts | 2 +- src/compiler/transformers/module/module.ts | 2 +- src/compiler/transformers/module/system.ts | 2 +- src/compiler/transformers/taggedTemplate.ts | 2 +- src/compiler/transformers/ts.ts | 4 +- src/compiler/transformers/typeSerializer.ts | 2 +- src/compiler/transformers/utilities.ts | 45 + src/compiler/tsbuildPublic.ts | 6 +- src/compiler/types.ts | 175 ++- src/compiler/utilities.ts | 1389 +---------------- src/compiler/watch.ts | 12 +- src/compiler/watchPublic.ts | 14 +- src/compiler/watchUtilities.ts | 16 +- .../4.0/nodeFactoryTopLevelExports.ts | 8 +- src/executeCommandLine/executeCommandLine.ts | 10 +- src/harness/fakesHosts.ts | 8 +- src/harness/fourslashImpl.ts | 3 +- src/harness/harnessIO.ts | 5 +- src/harness/harnessUtils.ts | 5 +- src/harness/util.ts | 3 +- src/harness/vfsUtil.ts | 3 +- src/jsTyping/types.ts | 4 +- src/server/editorServices.ts | 7 +- src/server/moduleSpecifierCache.ts | 2 +- src/server/project.ts | 16 +- src/server/scriptInfo.ts | 4 +- src/server/session.ts | 2 +- src/server/types.ts | 8 +- src/services/classifier.ts | 2 +- .../codefixes/convertToAsyncFunction.ts | 2 +- src/services/codefixes/fixAddMissingMember.ts | 6 +- src/services/codefixes/importAdder.ts | 4 +- src/services/completions.ts | 2 +- src/services/documentHighlights.ts | 2 +- src/services/documentRegistry.ts | 3 +- src/services/exportInfoMap.ts | 8 +- src/services/findAllReferences.ts | 8 +- src/services/getEditsForFileRename.ts | 6 +- src/services/jsDoc.ts | 2 +- src/services/navigationBar.ts | 6 +- src/services/refactors/extractSymbol.ts | 2 +- src/services/services.ts | 12 +- src/services/shims.ts | 6 +- src/services/stringCompletions.ts | 4 +- src/services/suggestionDiagnostics.ts | 2 +- src/services/transpile.ts | 4 +- src/services/types.ts | 2 +- src/services/utilities.ts | 10 +- src/testRunner/unittests/parsePseudoBigInt.ts | 18 +- .../unittests/services/textChanges.ts | 3 +- .../unittests/tsserver/symlinkCache.ts | 5 +- .../unittests/virtualFileSystemWithWatch.ts | 2 +- src/typingsInstaller/nodeTypingsInstaller.ts | 49 +- .../reference/api/tsserverlibrary.d.ts | 10 +- tests/baselines/reference/api/typescript.d.ts | 10 +- 96 files changed, 3001 insertions(+), 2777 deletions(-) create mode 100644 src/compiler/commandLineParserUtilities.ts create mode 100644 src/compiler/debugUtilities.ts create mode 100644 src/compiler/emitterUtilities.ts create mode 100644 src/compiler/fileMatcher.ts create mode 100644 src/compiler/moduleSpecifiersUtilities.ts create mode 100644 src/compiler/objectAllocator.ts create mode 100644 src/compiler/parserUtilities.ts create mode 100644 src/compiler/programUtilities.ts create mode 100644 src/compiler/symlinkCache.ts create mode 100644 src/compiler/sysUtilities.ts diff --git a/src/compiler/_namespaces/ts.ts b/src/compiler/_namespaces/ts.ts index b31b19cae7cb5..21cbf007c824c 100644 --- a/src/compiler/_namespaces/ts.ts +++ b/src/compiler/_namespaces/ts.ts @@ -9,9 +9,11 @@ export * from "../perfLogger"; export * from "../tracing"; export * from "../types"; export * from "../sys"; +export * from "../sysUtilities"; export * from "../path"; export * from "../diagnosticInformationMap.generated"; export * from "../scanner"; +export * from "../scannerUtilities"; export * from "../utilitiesPublic"; export * from "../utilities"; export * from "../factory/baseNodeFactory"; @@ -24,11 +26,17 @@ export * from "../factory/nodeTests"; export * from "../factory/utilities"; export * from "../factory/utilitiesPublic"; export * from "../parser"; +export * from "../parserUtilities"; export * from "../commandLineParser"; +export * from "../commandLineParserUtilities"; export * from "../moduleNameResolver"; +export * from "../moduleSpecifiersUtilities"; +export * from "../objectAllocator"; export * from "../binder"; export * from "../symbolWalker"; +export * from "../symlinkCache"; export * from "../checker"; +export * from "../checkerUtilities"; export * from "../visitorPublic"; export * from "../sourcemap"; export * from "../transformers/utilities"; @@ -68,6 +76,7 @@ export * from "../watch"; export * from "../watchPublic"; export * from "../tsbuild"; export * from "../tsbuildPublic"; +export * from "../fileMatcher"; import * as moduleSpecifiers from "./ts.moduleSpecifiers"; export { moduleSpecifiers }; import * as performance from "./ts.performance"; diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b45ee256905b5..28b96f413c3f5 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -50,10 +50,12 @@ import { isVariableDeclaration, isVariableStatement, } from "./factory/nodeTests"; +import { objectAllocator } from "./objectAllocator"; +import { forEachChild } from "./parser"; import { - forEachChild, - isExternalModule, -} from "./parser"; + setParent, + setParentRecursive, +} from "./parserUtilities"; import { perfLogger } from "./perfLogger"; import * as performance from "./performance"; import { tokenToString } from "./scanner"; @@ -147,6 +149,7 @@ import { ModuleBlock, ModuleDeclaration, ModuleResolutionKind, + Mutable, NamespaceExportDeclaration, Node, NodeArray, @@ -245,6 +248,7 @@ import { isEntityNameExpression, isEnumConst, isExportsIdentifier, + isExternalModule, isExternalOrCommonJsModule, isFunctionSymbol, isGlobalScopeAugmentation, @@ -273,13 +277,9 @@ import { isStringOrNumericLiteralLike, isThisInitializedDeclaration, isVariableDeclarationInitializedToBareOrAccessedRequire, - Mutable, nodeIsMissing, nodeIsPresent, - objectAllocator, removeFileExtension, - setParent, - setParentRecursive, setValueDeclaration, shouldPreserveConstEnums, skipParentheses, diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 2094d4f6f309e..e3727adf4124a 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -55,6 +55,11 @@ import { filterSemanticDiagnostics, handleNoEmitOptions, } from "./program"; +import { + compilerOptionsAffectDeclarationPath, + compilerOptionsAffectEmit, + compilerOptionsAffectSemanticDiagnostics, +} from "./programUtilities"; import { generateDjb2Hash } from "./sys"; import { BuildInfo, @@ -81,9 +86,6 @@ import { WriteFileCallbackData, } from "./types"; import { - compilerOptionsAffectDeclarationPath, - compilerOptionsAffectEmit, - compilerOptionsAffectSemanticDiagnostics, forEachEntry, forEachKey, getEmitDeclarations, diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fcc13e121a6ff..218a50bc96217 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4,8 +4,11 @@ import { ModuleInstanceState, } from "./binder"; import { + CheckMode, getNodeId, getSymbolId, + SignatureCheckMode, + TypeFacts, } from "./checkerUtilities"; import { addRange, @@ -214,6 +217,7 @@ import { import { canHaveIllegalModifiers, createEmptyExports, + createPropertyNameNodeForIdentifierOrLiteral, getJSDocTypeAssertionType, isCommaSequence, } from "./factory/utilities"; @@ -229,15 +233,24 @@ import { mangleScopedPackageName, shouldAllowImportingTsExtension, } from "./moduleNameResolver"; -import { countPathComponents, getModuleSpecifiers } from "./moduleSpecifiers"; +import { + countPathComponents, + getModuleSpecifiers, +} from "./moduleSpecifiers"; +import { objectAllocator } from "./objectAllocator"; import { forEachChild, forEachChildRecursively, isDeclarationFileName, - isExternalModule, parseIsolatedEntityName, parseNodeFactory, } from "./parser"; +import { + containsParseError, + forEachReturnStatement, + forEachYieldExpression, + setParent, +} from "./parserUtilities"; import { combinePaths, comparePaths, @@ -262,6 +275,7 @@ import { skipTrivia, tokenToString, } from "./scanner"; +import { parsePseudoBigInt } from "./scannerUtilities"; import { createGetSymbolWalker } from "./symbolWalker"; import { tracing, @@ -674,7 +688,6 @@ import { chainDiagnosticMessages, compareDiagnostics, concatenateDiagnosticMessageChains, - containsParseError, copyEntries, createCompilerDiagnostic, createDiagnosticCollection, @@ -684,7 +697,6 @@ import { createDiagnosticForNodeFromMessageChain, createDiagnosticMessageChainFromDiagnostic, createFileDiagnostic, - createPropertyNameNodeForIdentifierOrLiteral, createSymbolTable, createTextWriter, declarationNameToString, @@ -700,8 +712,6 @@ import { forEachEntry, forEachImportClauseDeclaration, forEachKey, - forEachReturnStatement, - forEachYieldExpression, formatMessage, FunctionFlags, getAliasDeclarationFromName, @@ -846,6 +856,7 @@ import { isExportsIdentifier, isExpressionNode, isExpressionWithTypeArgumentsInClassExtendsClause, + isExternalModule, isExternalModuleAugmentation, isExternalModuleImportEqualsDeclaration, isExternalOrCommonJsModule, @@ -941,10 +952,8 @@ import { nodeIsSynthesized, nodeStartsNewLexicalEnvironment, noTruncationMaximumTruncationLength, - objectAllocator, outFile, parameterIsThisKeyword, - parsePseudoBigInt, parseValidBigInt, pseudoBigIntToString, rangeOfNode, @@ -953,7 +962,6 @@ import { resolutionExtensionIsTSOrJson, resolvingEmptyArray, setNodeFlags, - setParent, setTextRangePosEnd, setValueDeclaration, shouldPreserveConstEnums, @@ -1132,90 +1140,6 @@ const enum WideningKind { GeneratorYield, } -/** @internal */ -export 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 - IsUndefined = 1 << 24, // Contains undefined or intersection with undefined - IsNull = 1 << 25, // Contains null or intersection with null - IsUndefinedOrNull = IsUndefined | IsNull, - All = (1 << 27) - 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 - // of that kind of type. - BaseStringStrictFacts = TypeofEQString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, - BaseStringFacts = BaseStringStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - StringStrictFacts = BaseStringStrictFacts | Truthy | Falsy, - StringFacts = BaseStringFacts | Truthy, - EmptyStringStrictFacts = BaseStringStrictFacts | Falsy, - EmptyStringFacts = BaseStringFacts, - NonEmptyStringStrictFacts = BaseStringStrictFacts | Truthy, - NonEmptyStringFacts = BaseStringFacts | Truthy, - BaseNumberStrictFacts = TypeofEQNumber | TypeofNEString | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, - BaseNumberFacts = BaseNumberStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - NumberStrictFacts = BaseNumberStrictFacts | Truthy | Falsy, - NumberFacts = BaseNumberFacts | Truthy, - ZeroNumberStrictFacts = BaseNumberStrictFacts | Falsy, - ZeroNumberFacts = BaseNumberFacts, - NonZeroNumberStrictFacts = BaseNumberStrictFacts | Truthy, - NonZeroNumberFacts = BaseNumberFacts | Truthy, - BaseBigIntStrictFacts = TypeofEQBigInt | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, - BaseBigIntFacts = BaseBigIntStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - BigIntStrictFacts = BaseBigIntStrictFacts | Truthy | Falsy, - BigIntFacts = BaseBigIntFacts | Truthy, - ZeroBigIntStrictFacts = BaseBigIntStrictFacts | Falsy, - ZeroBigIntFacts = BaseBigIntFacts, - NonZeroBigIntStrictFacts = BaseBigIntStrictFacts | Truthy, - NonZeroBigIntFacts = BaseBigIntFacts | Truthy, - BaseBooleanStrictFacts = TypeofEQBoolean | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, - BaseBooleanFacts = BaseBooleanStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - BooleanStrictFacts = BaseBooleanStrictFacts | Truthy | Falsy, - BooleanFacts = BaseBooleanFacts | Truthy, - FalseStrictFacts = BaseBooleanStrictFacts | Falsy, - FalseFacts = BaseBooleanFacts, - TrueStrictFacts = BaseBooleanStrictFacts | Truthy, - TrueFacts = BaseBooleanFacts | Truthy, - SymbolStrictFacts = TypeofEQSymbol | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy, - SymbolFacts = SymbolStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - ObjectStrictFacts = TypeofEQObject | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | NEUndefined | NENull | NEUndefinedOrNull | Truthy, - ObjectFacts = ObjectStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - FunctionStrictFacts = TypeofEQFunction | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy, - FunctionFacts = FunctionStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - VoidFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy, - UndefinedFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy | IsUndefined, - NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy | IsNull, - EmptyObjectStrictFacts = All & ~(EQUndefined | EQNull | EQUndefinedOrNull | IsUndefinedOrNull), - EmptyObjectFacts = All & ~IsUndefinedOrNull, - UnknownFacts = All & ~IsUndefinedOrNull, - AllTypeofNE = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | NEUndefined, - // Masks - OrFactsMask = TypeofEQFunction | TypeofNEObject, - AndFactsMask = All & ~OrFactsMask, -} - const typeofNEFacts: ReadonlyMap = new Map(getEntries({ string: TypeFacts.TypeofNEString, number: TypeFacts.TypeofNENumber, @@ -1241,30 +1165,6 @@ const enum TypeSystemPropertyName { WriteType, } -/** @internal */ -export 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 -} - -/** @internal */ -export const enum SignatureCheckMode { - None = 0, - BivariantCallback = 1 << 0, - StrictCallback = 1 << 1, - IgnoreReturnTypes = 1 << 2, - StrictArity = 1 << 3, - Callback = BivariantCallback | StrictCallback, -} - const enum IntersectionState { None = 0, Source = 1 << 0, @@ -7789,7 +7689,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return fromNameType; } const rawName = unescapeLeadingUnderscores(symbol.escapedName); - return createPropertyNameNodeForIdentifierOrLiteral(rawName, getEmitScriptTarget(compilerOptions), singleQuote, stringNamed); + return createPropertyNameNodeForIdentifierOrLiteral(factory, rawName, getEmitScriptTarget(compilerOptions), singleQuote, stringNamed); } // See getNameForSymbolFromNameType for a stringy equivalent @@ -7804,7 +7704,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (isNumericLiteralName(name) && startsWith(name, "-")) { return factory.createComputedPropertyName(factory.createNumericLiteral(+name)); } - return createPropertyNameNodeForIdentifierOrLiteral(name, getEmitScriptTarget(compilerOptions)); + return createPropertyNameNodeForIdentifierOrLiteral(factory, name, getEmitScriptTarget(compilerOptions)); } if (nameType.flags & TypeFlags.UniqueESSymbol) { return factory.createComputedPropertyName(symbolToExpression((nameType as UniqueESSymbolType).symbol, context, SymbolFlags.Value)); diff --git a/src/compiler/checkerUtilities.ts b/src/compiler/checkerUtilities.ts index 41bf489efa536..4e8c96179e7b4 100644 --- a/src/compiler/checkerUtilities.ts +++ b/src/compiler/checkerUtilities.ts @@ -7,6 +7,7 @@ import { let nextSymbolId = 1; let nextNodeId = 1; +/** @internal */ export function getNodeId(node: Node): number { if (!node.id) { node.id = nextNodeId; @@ -15,6 +16,7 @@ export function getNodeId(node: Node): number { return node.id; } +/** @internal */ export function getSymbolId(symbol: Symbol): SymbolId { if (!symbol.id) { symbol.id = nextSymbolId; @@ -23,3 +25,111 @@ export function getSymbolId(symbol: Symbol): SymbolId { return symbol.id; } + +/** @internal */ +export 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 +} + +/** @internal */ +export const enum SignatureCheckMode { + None = 0, + BivariantCallback = 1 << 0, + StrictCallback = 1 << 1, + IgnoreReturnTypes = 1 << 2, + StrictArity = 1 << 3, + Callback = BivariantCallback | StrictCallback, +} + +/** @internal */ +export 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 + IsUndefined = 1 << 24, // Contains undefined or intersection with undefined + IsNull = 1 << 25, // Contains null or intersection with null + IsUndefinedOrNull = IsUndefined | IsNull, + All = (1 << 27) - 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 + // of that kind of type. + BaseStringStrictFacts = TypeofEQString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, + BaseStringFacts = BaseStringStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + StringStrictFacts = BaseStringStrictFacts | Truthy | Falsy, + StringFacts = BaseStringFacts | Truthy, + EmptyStringStrictFacts = BaseStringStrictFacts | Falsy, + EmptyStringFacts = BaseStringFacts, + NonEmptyStringStrictFacts = BaseStringStrictFacts | Truthy, + NonEmptyStringFacts = BaseStringFacts | Truthy, + BaseNumberStrictFacts = TypeofEQNumber | TypeofNEString | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, + BaseNumberFacts = BaseNumberStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + NumberStrictFacts = BaseNumberStrictFacts | Truthy | Falsy, + NumberFacts = BaseNumberFacts | Truthy, + ZeroNumberStrictFacts = BaseNumberStrictFacts | Falsy, + ZeroNumberFacts = BaseNumberFacts, + NonZeroNumberStrictFacts = BaseNumberStrictFacts | Truthy, + NonZeroNumberFacts = BaseNumberFacts | Truthy, + BaseBigIntStrictFacts = TypeofEQBigInt | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, + BaseBigIntFacts = BaseBigIntStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + BigIntStrictFacts = BaseBigIntStrictFacts | Truthy | Falsy, + BigIntFacts = BaseBigIntFacts | Truthy, + ZeroBigIntStrictFacts = BaseBigIntStrictFacts | Falsy, + ZeroBigIntFacts = BaseBigIntFacts, + NonZeroBigIntStrictFacts = BaseBigIntStrictFacts | Truthy, + NonZeroBigIntFacts = BaseBigIntFacts | Truthy, + BaseBooleanStrictFacts = TypeofEQBoolean | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, + BaseBooleanFacts = BaseBooleanStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + BooleanStrictFacts = BaseBooleanStrictFacts | Truthy | Falsy, + BooleanFacts = BaseBooleanFacts | Truthy, + FalseStrictFacts = BaseBooleanStrictFacts | Falsy, + FalseFacts = BaseBooleanFacts, + TrueStrictFacts = BaseBooleanStrictFacts | Truthy, + TrueFacts = BaseBooleanFacts | Truthy, + SymbolStrictFacts = TypeofEQSymbol | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy, + SymbolFacts = SymbolStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + ObjectStrictFacts = TypeofEQObject | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | NEUndefined | NENull | NEUndefinedOrNull | Truthy, + ObjectFacts = ObjectStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + FunctionStrictFacts = TypeofEQFunction | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy, + FunctionFacts = FunctionStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + VoidFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy, + UndefinedFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy | IsUndefined, + NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy | IsNull, + EmptyObjectStrictFacts = All & ~(EQUndefined | EQNull | EQUndefinedOrNull | IsUndefinedOrNull), + EmptyObjectFacts = All & ~IsUndefinedOrNull, + UnknownFacts = All & ~IsUndefinedOrNull, + AllTypeofNE = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | NEUndefined, + // Masks + OrFactsMask = TypeofEQFunction | TypeofNEObject, + AndFactsMask = All & ~OrFactsMask, +} diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 607f14a00cfff..462806bb27c18 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -41,6 +41,13 @@ import { isObjectLiteralExpression, isStringLiteral, } from "./factory/nodeTests"; +import { + getFileMatcherPatterns, + getRegexFromPattern, + getRegularExpressionForWildcard, + getRegularExpressionsForWildcards, + isImplicitGlob, +} from "./fileMatcher"; import { nodeNextJsonConfigResolver } from "./moduleNameResolver"; import { parseJsonText } from "./parser"; import { @@ -115,18 +122,13 @@ import { createCompilerDiagnostic, createDiagnosticForNodeInSourceFile, forEachEntry, - getFileMatcherPatterns, getLocaleSpecificMessage, - getRegexFromPattern, - getRegularExpressionForWildcard, - getRegularExpressionsForWildcards, getSupportedExtensions, getSupportedExtensionsWithJsonIfResolveJsonModule, getTextOfPropertyName, getTsConfigPropArray, getTsConfigPropArrayElementValue, isComputedNonLiteralName, - isImplicitGlob, isStringDoubleQuoted, } from "./utilities"; import { unescapeLeadingUnderscores } from "./utilitiesPublic"; diff --git a/src/compiler/commandLineParserUtilities.ts b/src/compiler/commandLineParserUtilities.ts new file mode 100644 index 0000000000000..cc7181c9c97df --- /dev/null +++ b/src/compiler/commandLineParserUtilities.ts @@ -0,0 +1,16 @@ +import { parseConfigFileTextToJson } from "./commandLineParser"; +import { isString } from "./core"; + +/** @internal */ +export function readJsonOrUndefined(path: string, hostOrText: { readFile(fileName: string): string | undefined } | string): object | undefined { + const jsonText = isString(hostOrText) ? hostOrText : hostOrText.readFile(path); + if (!jsonText) return undefined; + // gracefully handle if readFile fails or returns not JSON + const result = parseConfigFileTextToJson(path, jsonText); + return !result.error ? result.config : undefined; +} + +/** @internal */ +export function readJson(path: string, host: { readFile(fileName: string): string | undefined }): object { + return readJsonOrUndefined(path, host) || {}; +} diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 8a68e304929d5..f006f6892c150 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -7,7 +7,7 @@ import { SortedArray, SortedReadonlyArray, } from "./corePublic"; -// import { Debug } from "./debug"; +import { Debug } from "./debug"; import { __String, CharacterCodes, @@ -136,7 +136,7 @@ export function reduceLeftIterator(iterator: Iterator | undefined, f: ( /** @internal */ 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); + Debug.assertEqual(arrayA.length, arrayB.length); for (let i = 0; i < arrayA.length; i++) { result.push(callback(arrayA[i], arrayB[i], i)); } @@ -145,7 +145,7 @@ export function zipWith(arrayA: readonly T[], arrayB: readonly U[], cal /** @internal */ export function zipToIterator(arrayA: readonly T[], arrayB: readonly U[]): Iterator<[T, U]> { - // Debug.assertEqual(arrayA.length, arrayB.length); + Debug.assertEqual(arrayA.length, arrayB.length); let i = 0; return { next() { @@ -160,7 +160,7 @@ export function zipToIterator(arrayA: readonly T[], arrayB: readonly U[]): /** @internal */ export function zipToMap(keys: readonly K[], values: readonly V[]): Map { - // Debug.assert(keys.length === values.length); + Debug.assert(keys.length === values.length); const map = new Map(); for (let i = 0; i < keys.length; ++i) { map.set(keys[i], values[i]); @@ -280,8 +280,7 @@ export function findMap(array: readonly T[], callback: (element: T, index: return result; } } - // return Debug.fail(); - throw new Error(); + return Debug.fail(); } /** @internal */ @@ -899,8 +898,7 @@ function deduplicateSorted(array: SortedReadonlyArray, comparer: EqualityC case Comparison.LessThan: // If `array` is sorted, `next` should **never** be less than `last`. - // return Debug.fail("Array is unsorted."); - throw new Error("Array is unsorted."); + return Debug.fail("Array is unsorted."); } deduplicated.push(last = next); @@ -1058,14 +1056,14 @@ export function relativeComplement(arrayA: T[] | undefined, arrayB: T[] | und 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); + Debug.assertGreaterThanOrEqual(comparer(arrayB[offsetB], arrayB[offsetB - 1]), 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); + Debug.assertGreaterThanOrEqual(comparer(arrayA[offsetA], arrayA[offsetA - 1]), Comparison.EqualTo); } switch (comparer(arrayB[offsetB], arrayA[offsetA])) { @@ -1314,7 +1312,7 @@ export function firstOrUndefined(array: readonly T[] | undefined): T | undefi /** @internal */ export function first(array: readonly T[]): T { - // Debug.assert(array.length !== 0); + Debug.assert(array.length !== 0); return array[0]; } @@ -1329,7 +1327,7 @@ export function lastOrUndefined(array: readonly T[] | undefined): T | undefin /** @internal */ export function last(array: readonly T[]): T { - // Debug.assert(array.length !== 0); + Debug.assert(array.length !== 0); return array[array.length - 1]; } @@ -1350,12 +1348,7 @@ export function singleOrUndefined(array: readonly T[] | undefined): T | undef * @internal */ export function single(array: readonly T[]): T { - // return Debug.checkDefined(singleOrUndefined(array)); - const result = singleOrUndefined(array); - if (result === undefined) { - throw new Error(); - } - return result; + return Debug.checkDefined(singleOrUndefined(array)); } /** @@ -2051,8 +2044,7 @@ export function tryCast(value: T, test: (value: T) => boolean): T | undefined /** @internal */ export function cast(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut { if (value !== undefined && test(value)) return value; - throw new Error(`Invalid cast. The supplied value ${value} did not pass the test`); - // return Debug.fail(`Invalid cast. The supplied value ${value} did not pass the test '${Debug.getFunctionName(test)}'.`); + return Debug.fail(`Invalid cast. The supplied value ${value} did not pass the test '${Debug.getFunctionName(test)}'.`); } /** @@ -2247,24 +2239,6 @@ export function compose(a: (t: T) => T, b: (t: T) => T, c: (t: T) => T, d: (t } } -/** @internal */ -export const enum AssertionLevel { - None = 0, - Normal = 1, - Aggressive = 2, - VeryAggressive = 3, -} - -/** - * Safer version of `Function` which should not be called. - * Every function should be assignable to this, but this should not be assignable to every function. - * - * @internal - */ -export type AnyFunction = (...args: never[]) => void; -/** @internal */ -export type AnyConstructor = new (...args: unknown[]) => unknown; - /** @internal */ export function equateValues(a: T, b: T) { return a === b; @@ -2576,7 +2550,7 @@ export function getSpellingSuggestion(name: string, candidates: T[], getName: continue; } - // Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined + Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined bestDistance = distance; bestCandidate = candidate; } @@ -2790,7 +2764,7 @@ export function patternText({ prefix, suffix }: Pattern): string { * @internal */ export function matchedText(pattern: Pattern, candidate: string): string { - // Debug.assert(isPatternMatch(pattern, candidate)); + Debug.assert(isPatternMatch(pattern, candidate)); return candidate.substring(pattern.prefix.length, candidate.length - pattern.suffix.length); } diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index ffbef3ef157c4..de656915863a8 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -1,97 +1,66 @@ -import * as ts from "./_namespaces/ts"; +import { CheckMode, SignatureCheckMode, TypeFacts } from "./checkerUtilities"; +import { + arrayTypeToString, + assertNoop, + attachFlowNodeDebugInfoWorker, + attachNodeArrayDebugInfoWorker, + DebugType, + deferredTypeToString, + enableDebugInfoWorder, + formatCheckModeWorker, + formatControlFlowGraphWorker, + formatEmitFlagsWorker, + formatEnumWorker, + formatFlowFlagsWorker, + formatModifierFlagsWorker, + formatNodeFlagsWorker, + formatObjectFlagsWorker, + formatRelationComparisonResultWorker, + formatSignatureCheckModeWorker, + formatSignatureFlagsWorker, + formatSnippetKindWorker, + formatSymbolFlagsWorker, + formatSymbolWorker, + formatSyntaxKindWorker, + formatTransformFlagsWorker, + formatTypeFactsWorker, + formatTypeFlagsWorker, + hasKind, + hasName, + hasPos, +} from "./debugUtilities"; import { AnyFunction, - AssertionLevel, - BigIntLiteralType, - CheckMode, - compareValues, EmitFlags, - every, FlowFlags, - FlowLabel, FlowNode, FlowNodeBase, - FlowSwitchClause, - getEffectiveModifierFlagsNoCache, - getEmitFlags, - getOwnKeys, - getParseTreeNode, - getSourceFileOfNode, - getSourceTextOfNodeFromSourceFile, - hasProperty, - idText, - IntrinsicType, - isArrayTypeNode, - isBigIntLiteral, - isCallSignatureDeclaration, - isConditionalTypeNode, - isConstructorDeclaration, - isConstructorTypeNode, - isConstructSignatureDeclaration, - isDefaultClause, - isFunctionTypeNode, - isGeneratedIdentifier, - isGetAccessorDeclaration, - isIdentifier, - isImportTypeNode, - isIndexedAccessTypeNode, - isIndexSignatureDeclaration, - isInferTypeNode, - isIntersectionTypeNode, - isLiteralTypeNode, - isMappedTypeNode, - isNamedTupleMember, - isNumericLiteral, - isOptionalTypeNode, - isParameter, - isParenthesizedTypeNode, - isParseTreeNode, - isPrivateIdentifier, - isRestTypeNode, - isSetAccessorDeclaration, - isStringLiteral, - isThisTypeNode, - isTupleTypeNode, - isTypeLiteralNode, - isTypeOperatorNode, - isTypeParameterDeclaration, - isTypePredicateNode, - isTypeQueryNode, - isTypeReferenceNode, - isUnionTypeNode, - LiteralType, - map, MatchingKeys, ModifierFlags, Node, NodeArray, NodeFlags, - nodeIsSynthesized, - noop, - objectAllocator, ObjectFlags, - ObjectType, RelationComparisonResult, - Signature, - SignatureCheckMode, SignatureFlags, SnippetKind, - SortedReadonlyArray, - stableSort, Symbol, SymbolFlags, - symbolName, SyntaxKind, TransformFlags, - Type, - TypeFacts, TypeFlags, TypeMapKind, TypeMapper, - unescapeLeadingUnderscores, VarianceFlags, - zipWith, -} from "./_namespaces/ts"; +} from "./types"; + +/** @internal */ +export const enum AssertionLevel { + None = 0, + Normal = 1, + Aggressive = 2, + VeryAggressive = 3, +} /** @internal */ export enum LogLevel { @@ -162,7 +131,7 @@ export namespace Debug { 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 Object.keys(assertionCache) as AssertionKeys[]) { const cachedFunc = assertionCache[key]; if (cachedFunc !== undefined && Debug[key] !== cachedFunc.assertion && level >= cachedFunc.level) { (Debug as any)[key] = cachedFunc; @@ -185,7 +154,7 @@ export namespace Debug { function shouldAssertFunction(level: AssertionLevel, name: K): boolean { if (!shouldAssert(level)) { assertionCache[name] = { level, assertion: Debug[name] }; - (Debug as any)[name] = noop; + (Debug as any)[name] = assertNoop; return false; } return true; @@ -267,7 +236,7 @@ export namespace Debug { } 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); + const detail = typeof member === "object" && hasKind(member) && hasPos(member) ? "SyntaxKind: " + formatSyntaxKind((member as Node).kind) : JSON.stringify(member); return fail(`${message} ${detail}`, stackCrawlMark || assertNever); } @@ -279,7 +248,7 @@ export namespace Debug { export function assertEachNode(nodes: readonly Node[] | undefined, test: (node: Node) => boolean, message?: string, stackCrawlMark?: AnyFunction) { if (shouldAssertFunction(AssertionLevel.Normal, "assertEachNode")) { assert( - test === undefined || every(nodes, test), + test === undefined || nodes?.every(test), message || "Unexpected node.", () => `Node array did not pass test '${getFunctionName(test)}'.`, stackCrawlMark || assertEachNode); @@ -359,7 +328,7 @@ export namespace Debug { if (typeof func !== "function") { return ""; } - else if (hasProperty(func, "name")) { + else if (hasName(func)) { return (func as any).name; } else { @@ -370,214 +339,84 @@ export namespace Debug { } export function formatSymbol(symbol: Symbol): string { - return `{ name: ${unescapeLeadingUnderscores(symbol.escapedName)}; flags: ${formatSymbolFlags(symbol.flags)}; declarations: ${map(symbol.declarations, node => formatSyntaxKind(node.kind))} }`; + return formatSymbolWorker(symbol); } - /** - * Formats an enum value as a string for debugging and debug assertions. - */ export function formatEnum(value = 0, enumObject: any, isFlags?: boolean) { - const members = getEnumMembers(enumObject); - if (value === 0) { - return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0"; - } - if (isFlags) { - const result: string[] = []; - let remainingFlags = value; - for (const [enumValue, enumName] of members) { - if (enumValue > value) { - break; - } - if (enumValue !== 0 && enumValue & value) { - result.push(enumName); - remainingFlags &= ~enumValue; - } - } - if (remainingFlags === 0) { - return result.join("|"); - } - } - else { - for (const [enumValue, enumName] of members) { - if (enumValue === value) { - return enumName; - } - } - } - return value.toString(); - } - - const enumMemberCache = new Map>(); - - function getEnumMembers(enumObject: any) { - // Assuming enum objects do not change at runtime, we can cache the enum members list - // to reuse later. This saves us from reconstructing this each and every time we call - // a formatting function (which can be expensive for large enums like SyntaxKind). - const existing = enumMemberCache.get(enumObject); - if (existing) { - return existing; - } - - const result: [number, string][] = []; - for (const name in enumObject) { - const value = enumObject[name]; - if (typeof value === "number") { - result.push([value, name]); - } - } - - const sorted = stableSort<[number, string]>(result, (x, y) => compareValues(x[0], y[0])); - enumMemberCache.set(enumObject, sorted); - return sorted; + return formatEnumWorker(value, enumObject, isFlags); } export function formatSyntaxKind(kind: SyntaxKind | undefined): string { - return formatEnum(kind, (ts as any).SyntaxKind, /*isFlags*/ false); + return formatSyntaxKindWorker(kind); } export function formatSnippetKind(kind: SnippetKind | undefined): string { - return formatEnum(kind, (ts as any).SnippetKind, /*isFlags*/ false); + return formatSnippetKindWorker(kind); } export function formatNodeFlags(flags: NodeFlags | undefined): string { - return formatEnum(flags, (ts as any).NodeFlags, /*isFlags*/ true); + return formatNodeFlagsWorker(flags); } export function formatModifierFlags(flags: ModifierFlags | undefined): string { - return formatEnum(flags, (ts as any).ModifierFlags, /*isFlags*/ true); + return formatModifierFlagsWorker(flags); } export function formatTransformFlags(flags: TransformFlags | undefined): string { - return formatEnum(flags, (ts as any).TransformFlags, /*isFlags*/ true); + return formatTransformFlagsWorker(flags); } export function formatEmitFlags(flags: EmitFlags | undefined): string { - return formatEnum(flags, (ts as any).EmitFlags, /*isFlags*/ true); + return formatEmitFlagsWorker(flags); } export function formatSymbolFlags(flags: SymbolFlags | undefined): string { - return formatEnum(flags, (ts as any).SymbolFlags, /*isFlags*/ true); + return formatSymbolFlagsWorker(flags); } export function formatTypeFlags(flags: TypeFlags | undefined): string { - return formatEnum(flags, (ts as any).TypeFlags, /*isFlags*/ true); + return formatTypeFlagsWorker(flags); } export function formatSignatureFlags(flags: SignatureFlags | undefined): string { - return formatEnum(flags, (ts as any).SignatureFlags, /*isFlags*/ true); + return formatSignatureFlagsWorker(flags); } export function formatObjectFlags(flags: ObjectFlags | undefined): string { - return formatEnum(flags, (ts as any).ObjectFlags, /*isFlags*/ true); + return formatObjectFlagsWorker(flags); } export function formatFlowFlags(flags: FlowFlags | undefined): string { - return formatEnum(flags, (ts as any).FlowFlags, /*isFlags*/ true); + return formatFlowFlagsWorker(flags); } export function formatRelationComparisonResult(result: RelationComparisonResult | undefined): string { - return formatEnum(result, (ts as any).RelationComparisonResult, /*isFlags*/ true); + return formatRelationComparisonResultWorker(result); } export function formatCheckMode(mode: CheckMode | undefined): string { - return formatEnum(mode, (ts as any).CheckMode, /*isFlags*/ true); + return formatCheckModeWorker(mode); } export function formatSignatureCheckMode(mode: SignatureCheckMode | undefined): string { - return formatEnum(mode, (ts as any).SignatureCheckMode, /*isFlags*/ true); + return formatSignatureCheckModeWorker(mode); } export function formatTypeFacts(facts: TypeFacts | undefined): string { - return formatEnum(facts, (ts as any).TypeFacts, /*isFlags*/ true); + return formatTypeFactsWorker(facts); } let isDebugInfoEnabled = false; - let flowNodeProto: FlowNodeBase | undefined; - - function attachFlowNodeDebugInfoWorker(flowNode: FlowNodeBase) { - if (!("__debugFlowFlags" in flowNode)) { // eslint-disable-line local/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" : - "UnknownFlow"; - const remainingFlags = this.flags & ~(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); } } - }); - } - } - export function attachFlowNodeDebugInfo(flowNode: 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; - attachFlowNodeDebugInfoWorker(flowNodeProto); - } - Object.setPrototypeOf(flowNode, flowNodeProto); - } - else { - // not running in an es2015 environment, attach the method directly. - attachFlowNodeDebugInfoWorker(flowNode); - } - } - } - - let nodeArrayProto: NodeArray | undefined; - - function attachNodeArrayDebugInfoWorker(array: NodeArray) { - if (!("__tsDebuggerDisplay" in array)) { // eslint-disable-line local/no-in-operator - Object.defineProperties(array, { - __tsDebuggerDisplay: { - value(this: 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. - // This regex can trigger slow backtracking because of overlapping potential captures. - // We don't care, this is debug code that's only enabled with a debugger attached - - // we're just taking note of it for anyone checking regex performance in the future. - defaultValue = String(defaultValue).replace(/(?:,[\s\w\d_]+:[^,]+)+\]$/, "]"); - return `NodeArray ${defaultValue}`; - } - } - }); + attachFlowNodeDebugInfoWorker(flowNode); } } export function attachNodeArrayDebugInfo(array: 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; - attachNodeArrayDebugInfoWorker(nodeArrayProto); - } - Object.setPrototypeOf(array, nodeArrayProto); - } - else { - // not running in an es2015 environment, attach the method directly. - attachNodeArrayDebugInfoWorker(array); - } + attachNodeArrayDebugInfoWorker(array); } } @@ -587,154 +426,7 @@ export namespace Debug { export function enableDebugInfo() { if (isDebugInfoEnabled) return; - // avoid recomputing - const weakTypeTextMap = new WeakMap(); - const weakNodeTextMap = new WeakMap(); - - // Add additional properties in debug mode to assist with debugging. - Object.defineProperties(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" : - "Symbol"; - const remainingSymbolFlags = this.flags & ~SymbolFlags.Transient; - return `${symbolHeader} '${symbolName(this)}'${remainingSymbolFlags ? ` (${formatSymbolFlags(remainingSymbolFlags)})` : ""}`; - } - }, - __debugFlags: { get(this: Symbol) { return formatSymbolFlags(this.flags); } } - }); - - Object.defineProperties(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" : - "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)})` : ""}`; - } - }, - __debugFlags: { get(this: Type) { return formatTypeFlags(this.flags); } }, - __debugObjectFlags: { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((this as ObjectType).objectFlags) : ""; } }, - __debugTypeToString: { - value(this: Type) { - // avoid recomputing - let text = weakTypeTextMap.get(this); - if (text === undefined) { - text = this.checker.typeToString(this); - weakTypeTextMap.set(this, text); - } - return text; - } - }, - }); - - Object.defineProperties(objectAllocator.getSignatureConstructor().prototype, { - __debugFlags: { get(this: Signature) { return formatSignatureFlags(this.flags); } }, - __debugSignatureToString: { value(this: Signature) { return this.checker?.signatureToString(this); } } - }); - - const nodeConstructors = [ - objectAllocator.getNodeConstructor(), - objectAllocator.getIdentifierConstructor(), - objectAllocator.getTokenConstructor(), - objectAllocator.getSourceFileConstructor() - ]; - - for (const ctor of nodeConstructors) { - if (!hasProperty(ctor.prototype, "__debugKind")) { - 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" : - 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)); } }, - __debugGetText: { - value(this: Node, includeTrivia?: boolean) { - if (nodeIsSynthesized(this)) return ""; - // avoid recomputing - let text = weakNodeTextMap.get(this); - if (text === undefined) { - const parseNode = getParseTreeNode(this); - const sourceFile = parseNode && getSourceFileOfNode(parseNode); - text = sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : ""; - weakNodeTextMap.set(this, text); - } - return text; - } - } - }); - } - } + enableDebugInfoWorder(); isDebugInfoEnabled = true; } @@ -756,7 +448,6 @@ export namespace Debug { return result; } - export type DebugType = Type & { __debugTypeToString(): string }; // eslint-disable-line @typescript-eslint/naming-convention export class DebugTypeMapper { declare kind: TypeMapKind; __debugToString(): string { // eslint-disable-line @typescript-eslint/naming-convention @@ -764,14 +455,8 @@ export namespace Debug { switch (this.kind) { case TypeMapKind.Function: return this.debugInfo?.() || "(function mapper)"; case TypeMapKind.Simple: return `${(this.source as DebugType).__debugTypeToString()} -> ${(this.target as DebugType).__debugTypeToString()}`; - case TypeMapKind.Array: return zipWith( - this.sources as readonly DebugType[], - this.targets as readonly DebugType[] || map(this.sources, () => "any"), - (s, t) => `${s.__debugTypeToString()} -> ${typeof t === "string" ? t : t.__debugTypeToString()}`).join(", "); - case TypeMapKind.Deferred: return zipWith( - this.sources, - this.targets, - (s, t) => `${(s as DebugType).__debugTypeToString()} -> ${(t() as DebugType).__debugTypeToString()}`).join(", "); + case TypeMapKind.Array: return arrayTypeToString(this.sources as readonly DebugType[], this.targets as DebugType[] | undefined); + case TypeMapKind.Deferred: return deferredTypeToString(this.sources, this.targets); case TypeMapKind.Merged: case TypeMapKind.Composite: return `m1: ${(this.mapper1 as unknown as DebugTypeMapper).__debugToString().split("\n").join("\n ")} m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n").join("\n ")}`; @@ -792,379 +477,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n") } export function formatControlFlowGraph(flowNode: FlowNode) { - let nextDebugFlowId = -1; - - function getDebugFlowNodeId(f: FlowNode) { - if (!f.id) { - f.id = nextDebugFlowId; - nextDebugFlowId--; - } - return f.id; - } - - const enum BoxCharacter { - lr = "─", - ud = "│", - dr = "╭", - dl = "╮", - ul = "╯", - ur = "╰", - udr = "├", - udl = "┤", - dlr = "┬", - ulr = "┴", - udlr = "╫", - } - - const enum Connection { - None = 0, - Up = 1 << 0, - Down = 1 << 1, - Left = 1 << 2, - Right = 1 << 3, - - UpDown = Up | Down, - LeftRight = Left | Right, - UpLeft = Up | Left, - UpRight = Up | Right, - DownLeft = Down | Left, - DownRight = Down | Right, - UpDownLeft = UpDown | Left, - UpDownRight = UpDown | Right, - UpLeftRight = Up | LeftRight, - DownLeftRight = Down | LeftRight, - UpDownLeftRight = UpDown | LeftRight, - - NoChildren = 1 << 4, - } - - interface FlowGraphNode { - id: number; - flowNode: FlowNode; - edges: FlowGraphEdge[]; - text: string; - lane: number; - endLane: number; - level: number; - circular: boolean | "circularity"; - } - - interface FlowGraphEdge { - source: FlowGraphNode; - target: FlowGraphNode; - } - - const hasAntecedentFlags = - FlowFlags.Assignment | - FlowFlags.Condition | - FlowFlags.SwitchClause | - FlowFlags.ArrayMutation | - FlowFlags.Call | - FlowFlags.ReduceLabel; - - const hasNodeFlags = - FlowFlags.Start | - FlowFlags.Assignment | - FlowFlags.Call | - FlowFlags.Condition | - FlowFlags.ArrayMutation; - - const links: Record = Object.create(/*o*/ null); // eslint-disable-line no-null/no-null - const nodes: FlowGraphNode[] = []; - const edges: FlowGraphEdge[] = []; - const root = buildGraphNode(flowNode, new Set()); - for (const node of nodes) { - node.text = renderFlowNode(node.flowNode, node.circular); - computeLevel(node); - } - - const height = computeHeight(root); - const columnWidths = computeColumnWidths(height); - computeLanes(root, 0); - return renderGraph(); - - function isFlowSwitchClause(f: FlowNode): f is FlowSwitchClause { - return !!(f.flags & FlowFlags.SwitchClause); - } - - function hasAntecedents(f: FlowNode): f is FlowLabel & { antecedents: FlowNode[] } { - return !!(f.flags & FlowFlags.Label) && !!(f as FlowLabel).antecedents; - } - - function hasAntecedent(f: FlowNode): f is Extract { - return !!(f.flags & hasAntecedentFlags); - } - - function hasNode(f: FlowNode): f is Extract { - return !!(f.flags & hasNodeFlags); - } - - function getChildren(node: FlowGraphNode) { - const children: FlowGraphNode[] = []; - for (const edge of node.edges) { - if (edge.source === node) { - children.push(edge.target); - } - } - return children; - } - - function getParents(node: FlowGraphNode) { - const parents: FlowGraphNode[] = []; - for (const edge of node.edges) { - if (edge.target === node) { - parents.push(edge.source); - } - } - return parents; - } - - function buildGraphNode(flowNode: FlowNode, seen: Set): FlowGraphNode { - const id = getDebugFlowNodeId(flowNode); - let graphNode = links[id]; - if (graphNode && seen.has(flowNode)) { - graphNode.circular = true; - graphNode = { - id: -1, - flowNode, - edges: [], - text: "", - lane: -1, - endLane: -1, - level: -1, - circular: "circularity" - }; - nodes.push(graphNode); - return graphNode; - } - seen.add(flowNode); - if (!graphNode) { - links[id] = graphNode = { id, flowNode, edges: [], text: "", lane: -1, endLane: -1, level: -1, circular: false }; - nodes.push(graphNode); - if (hasAntecedents(flowNode)) { - for (const antecedent of flowNode.antecedents) { - buildGraphEdge(graphNode, antecedent, seen); - } - } - else if (hasAntecedent(flowNode)) { - buildGraphEdge(graphNode, flowNode.antecedent, seen); - } - } - seen.delete(flowNode); - return graphNode; - } - - function buildGraphEdge(source: FlowGraphNode, antecedent: FlowNode, seen: Set) { - const target = buildGraphNode(antecedent, seen); - const edge: FlowGraphEdge = { source, target }; - edges.push(edge); - source.edges.push(edge); - target.edges.push(edge); - } - - function computeLevel(node: FlowGraphNode): number { - if (node.level !== -1) { - return node.level; - } - let level = 0; - for (const parent of getParents(node)) { - level = Math.max(level, computeLevel(parent) + 1); - } - return node.level = level; - } - - function computeHeight(node: FlowGraphNode): number { - let height = 0; - for (const child of getChildren(node)) { - height = Math.max(height, computeHeight(child)); - } - return height + 1; - } - - function computeColumnWidths(height: number) { - const columns: number[] = fill(Array(height), 0); - for (const node of nodes) { - columns[node.level] = Math.max(columns[node.level], node.text.length); - } - return columns; - } - - function computeLanes(node: FlowGraphNode, lane: number) { - if (node.lane === -1) { - node.lane = lane; - node.endLane = lane; - const children = getChildren(node); - for (let i = 0; i < children.length; i++) { - if (i > 0) lane++; - const child = children[i]; - computeLanes(child, lane); - if (child.endLane > node.endLane) { - lane = child.endLane; - } - } - node.endLane = lane; - } - } - - function getHeader(flags: FlowFlags) { - if (flags & FlowFlags.Start) return "Start"; - if (flags & FlowFlags.BranchLabel) return "Branch"; - if (flags & FlowFlags.LoopLabel) return "Loop"; - if (flags & FlowFlags.Assignment) return "Assignment"; - if (flags & FlowFlags.TrueCondition) return "True"; - if (flags & FlowFlags.FalseCondition) return "False"; - if (flags & FlowFlags.SwitchClause) return "SwitchClause"; - if (flags & FlowFlags.ArrayMutation) return "ArrayMutation"; - if (flags & FlowFlags.Call) return "Call"; - if (flags & FlowFlags.ReduceLabel) return "ReduceLabel"; - if (flags & FlowFlags.Unreachable) return "Unreachable"; - throw new Error(); - } - - function getNodeText(node: Node) { - const sourceFile = getSourceFileOfNode(node); - return getSourceTextOfNodeFromSourceFile(sourceFile, node, /*includeTrivia*/ false); - } - - function renderFlowNode(flowNode: FlowNode, circular: boolean | "circularity") { - let text = getHeader(flowNode.flags); - if (circular) { - text = `${text}#${getDebugFlowNodeId(flowNode)}`; - } - if (hasNode(flowNode)) { - if (flowNode.node) { - text += ` (${getNodeText(flowNode.node)})`; - } - } - else if (isFlowSwitchClause(flowNode)) { - const clauses: string[] = []; - for (let i = flowNode.clauseStart; i < flowNode.clauseEnd; i++) { - const clause = flowNode.switchStatement.caseBlock.clauses[i]; - if (isDefaultClause(clause)) { - clauses.push("default"); - } - else { - clauses.push(getNodeText(clause.expression)); - } - } - text += ` (${clauses.join(", ")})`; - } - return circular === "circularity" ? `Circular(${text})` : text; - } - - function renderGraph() { - const columnCount = columnWidths.length; - const laneCount = nodes.reduce((x, n) => Math.max(x, n.lane), 0) + 1; - const lanes: string[] = fill(Array(laneCount), ""); - const grid: (FlowGraphNode | undefined)[][] = columnWidths.map(() => Array(laneCount)); - const connectors: Connection[][] = columnWidths.map(() => fill(Array(laneCount), 0)); - - // build connectors - for (const node of nodes) { - grid[node.level][node.lane] = node; - const children = getChildren(node); - for (let i = 0; i < children.length; i++) { - const child = children[i]; - let connector: Connection = Connection.Right; - if (child.lane === node.lane) connector |= Connection.Left; - if (i > 0) connector |= Connection.Up; - if (i < children.length - 1) connector |= Connection.Down; - connectors[node.level][child.lane] |= connector; - } - if (children.length === 0) { - connectors[node.level][node.lane] |= Connection.NoChildren; - } - const parents = getParents(node); - for (let i = 0; i < parents.length; i++) { - const parent = parents[i]; - let connector: Connection = Connection.Left; - if (i > 0) connector |= Connection.Up; - if (i < parents.length - 1) connector |= Connection.Down; - connectors[node.level - 1][parent.lane] |= connector; - } - } - - // fill in missing connectors - for (let column = 0; column < columnCount; column++) { - for (let lane = 0; lane < laneCount; lane++) { - const left = column > 0 ? connectors[column - 1][lane] : 0; - const above = lane > 0 ? connectors[column][lane - 1] : 0; - let connector = connectors[column][lane]; - if (!connector) { - if (left & Connection.Right) connector |= Connection.LeftRight; - if (above & Connection.Down) connector |= Connection.UpDown; - connectors[column][lane] = connector; - } - } - } - - for (let column = 0; column < columnCount; column++) { - for (let lane = 0; lane < lanes.length; lane++) { - const connector = connectors[column][lane]; - const fill = connector & Connection.Left ? BoxCharacter.lr : " "; - const node = grid[column][lane]; - if (!node) { - if (column < columnCount - 1) { - writeLane(lane, repeat(fill, columnWidths[column] + 1)); - } - } - else { - writeLane(lane, node.text); - if (column < columnCount - 1) { - writeLane(lane, " "); - writeLane(lane, repeat(fill, columnWidths[column] - node.text.length)); - } - } - writeLane(lane, getBoxCharacter(connector)); - writeLane(lane, connector & Connection.Right && column < columnCount - 1 && !grid[column + 1][lane] ? BoxCharacter.lr : " "); - } - } - - return `\n${lanes.join("\n")}\n`; - - function writeLane(lane: number, text: string) { - lanes[lane] += text; - } - } - - function getBoxCharacter(connector: Connection) { - switch (connector) { - case Connection.UpDown: return BoxCharacter.ud; - case Connection.LeftRight: return BoxCharacter.lr; - case Connection.UpLeft: return BoxCharacter.ul; - case Connection.UpRight: return BoxCharacter.ur; - case Connection.DownLeft: return BoxCharacter.dl; - case Connection.DownRight: return BoxCharacter.dr; - case Connection.UpDownLeft: return BoxCharacter.udl; - case Connection.UpDownRight: return BoxCharacter.udr; - case Connection.UpLeftRight: return BoxCharacter.ulr; - case Connection.DownLeftRight: return BoxCharacter.dlr; - case Connection.UpDownLeftRight: return BoxCharacter.udlr; - } - return " "; - } - - function fill(array: T[], value: T) { - if (array.fill) { - array.fill(value); - } - else { - for (let i = 0; i < array.length; i++) { - array[i] = value; - } - } - return array; - } - - function repeat(ch: string, length: number) { - if (ch.repeat) { - return length > 0 ? ch.repeat(length) : ""; - } - let s = ""; - while (s.length < length) { - s += ch; - } - return s; - } + return formatControlFlowGraphWorker(flowNode); } } diff --git a/src/compiler/debugUtilities.ts b/src/compiler/debugUtilities.ts new file mode 100644 index 0000000000000..ebdf0bfaa736e --- /dev/null +++ b/src/compiler/debugUtilities.ts @@ -0,0 +1,870 @@ +/* eslint-disable */ +import * as types from "./types"; +import * as checkerTypes from "./checkerUtilities"; +/* eslint-enable */ + +import { + compareValues, + hasProperty, + map, + stableSort, + zipWith, +} from "./core"; +import { SortedReadonlyArray } from "./corePublic"; +import { + __String, + BigIntLiteralType, + EmitFlags, + FlowFlags, + FlowLabel, + FlowNode, + FlowNodeBase, + FlowSwitchClause, + IntrinsicType, + LiteralType, + ModifierFlags, + Node, + NodeArray, + NodeFlags, + ObjectFlags, + ObjectType, + RelationComparisonResult, + Signature, + SignatureFlags, + SnippetKind, + Symbol, + SymbolFlags, + SyntaxKind, + TransformFlags, + Type, + TypeFlags, +} from "./types"; +import { + getEffectiveModifierFlagsNoCache, + getEmitFlags, + getSourceFileOfNode, + getSourceTextOfNodeFromSourceFile, + nodeIsSynthesized, +} from "./utilities"; +import { + getParseTreeNode, + idText, + isGeneratedIdentifier, + isParseTreeNode, + symbolName, + unescapeLeadingUnderscores, +} from "./utilitiesPublic"; +import { objectAllocator } from "./objectAllocator"; +import { CheckMode, SignatureCheckMode, TypeFacts } from "./checkerUtilities"; +import { + isArrayTypeNode, + isBigIntLiteral, + isCallSignatureDeclaration, + isConditionalTypeNode, + isConstructorDeclaration, + isConstructorTypeNode, + isConstructSignatureDeclaration, + isDefaultClause, + isFunctionTypeNode, + isGetAccessorDeclaration, + isIdentifier, + isImportTypeNode, + isIndexedAccessTypeNode, + isIndexSignatureDeclaration, + isInferTypeNode, + isIntersectionTypeNode, + isLiteralTypeNode, + isMappedTypeNode, + isNamedTupleMember, + isNumericLiteral, + isOptionalTypeNode, + isParameter, + isParenthesizedTypeNode, + isPrivateIdentifier, + isRestTypeNode, + isSetAccessorDeclaration, + isStringLiteral, + isThisTypeNode, + isTupleTypeNode, + isTypeLiteralNode, + isTypeOperatorNode, + isTypeParameterDeclaration, + isTypePredicateNode, + isTypeQueryNode, + isTypeReferenceNode, + isUnionTypeNode, +} from "./factory/nodeTests"; + +export type DebugType = Type & { __debugTypeToString(): string }; // eslint-disable-line @typescript-eslint/naming-convention +const enumMemberCache = new Map>(); +const weakTypeTextMap = new WeakMap(); +const weakNodeTextMap = new WeakMap(); + +let nodeArrayProto: NodeArray | undefined; +let flowNodeProto: FlowNodeBase | undefined; + +function getEnumMembers(enumObject: any) { + // Assuming enum objects do not change at runtime, we can cache the enum members list + // to reuse later. This saves us from reconstructing this each and every time we call + // a formatting function (which can be expensive for large enums like SyntaxKind). + const existing = enumMemberCache.get(enumObject); + if (existing) { + return existing; + } + + const result: [number, string][] = []; + for (const name in enumObject) { + const value = enumObject[name]; + if (typeof value === "number") { + result.push([value, name]); + } + } + + const sorted = stableSort<[number, string]>(result, (x, y) => compareValues(x[0], y[0])); + enumMemberCache.set(enumObject, sorted); + return sorted; +} + +function attachSymbolDebugInfo(symbol: Symbol) { + // Add additional properties in debug mode to assist with debugging. + Object.defineProperties(symbol, { + // for use with vscode-js-debug's new customDescriptionGenerator in launch.json + __tsDebuggerDisplay: { + value(this: Symbol) { + const symbolHeader = + this.flags & SymbolFlags.Transient ? "TransientSymbol" : + "Symbol"; + const remainingSymbolFlags = this.flags & ~SymbolFlags.Transient; + return `${symbolHeader} '${symbolName(this)}'${remainingSymbolFlags ? ` (${formatSymbolFlagsWorker(remainingSymbolFlags)})` : ""}`; + } + }, + __debugFlags: { get(this: Symbol) { return formatSymbolFlagsWorker(this.flags); } } + }); +} + +function attachTypeDebugInfo(type: Type) { + Object.defineProperties(type, { + // 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" : + "ObjectType" : + "Type"; + const remainingObjectFlags = this.flags & TypeFlags.Object ? (this as ObjectType).objectFlags & ~ObjectFlags.ObjectTypeKindMask : 0; + return `${typeHeader}${this.symbol ? ` '${symbolName(this.symbol)}'` : ""}${remainingObjectFlags ? ` (${formatObjectFlagsWorker(remainingObjectFlags)})` : ""}`; + } + }, + __debugFlags: { get(this: Type) { return formatTypeFlagsWorker(this.flags); } }, + __debugObjectFlags: { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlagsWorker((this as ObjectType).objectFlags) : ""; } }, + __debugTypeToString: { + value(this: Type) { + // avoid recomputing + let text = weakTypeTextMap.get(this); + if (text === undefined) { + text = this.checker.typeToString(this); + weakTypeTextMap.set(this, text); + } + return text; + } + }, + }); +} + +function attachSignatureDebugInfo(signature: Signature) { + Object.defineProperties(signature, { + __debugFlags: { get(this: Signature) { return formatSignatureFlagsWorker(this.flags); } }, + __debugSignatureToString: { value(this: Signature) { return this.checker?.signatureToString(this); } } + }); +} + +function attachNodeDebugInfo(node: Node) { + Object.defineProperties(node, { + // 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" : + formatSyntaxKindWorker(this.kind); + return `${nodeHeader}${this.flags ? ` (${formatNodeFlagsWorker(this.flags)})` : ""}`; + } + }, + __debugKind: { get(this: Node) { return formatSyntaxKindWorker(this.kind); } }, + __debugNodeFlags: { get(this: Node) { return formatNodeFlagsWorker(this.flags); } }, + __debugModifierFlags: { get(this: Node) { return formatModifierFlagsWorker(getEffectiveModifierFlagsNoCache(this)); } }, + __debugTransformFlags: { get(this: Node) { return formatTransformFlagsWorker(this.transformFlags); } }, + __debugIsParseTreeNode: { get(this: Node) { return isParseTreeNode(this); } }, + __debugEmitFlags: { get(this: Node) { return formatEmitFlagsWorker(getEmitFlags(this)); } }, + __debugGetText: { + value(this: Node, includeTrivia?: boolean) { + if (nodeIsSynthesized(this)) return ""; + // avoid recomputing + let text = weakNodeTextMap.get(this); + if (text === undefined) { + const parseNode = getParseTreeNode(this); + const sourceFile = parseNode && getSourceFileOfNode(parseNode); + text = sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : ""; + weakNodeTextMap.set(this, text); + } + return text; + } + } + }); +} + +function attachNodeArrayDebugInfo(array: NodeArray) { + if (!("__tsDebuggerDisplay" in array)) { // eslint-disable-line local/no-in-operator + Object.defineProperties(array, { + __tsDebuggerDisplay: { + value(this: 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. + // This regex can trigger slow backtracking because of overlapping potential captures. + // We don't care, this is debug code that's only enabled with a debugger attached - + // we're just taking note of it for anyone checking regex performance in the future. + defaultValue = String(defaultValue).replace(/(?:,[\s\w\d_]+:[^,]+)+\]$/, "]"); + return `NodeArray ${defaultValue}`; + } + } + }); + } +} + +function attachFlowNodeDebugInfo(flowNode: FlowNodeBase) { + if (!("__debugFlowFlags" in flowNode)) { // eslint-disable-line local/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" : + "UnknownFlow"; + const remainingFlags = this.flags & ~(FlowFlags.Referenced - 1); + return `${flowHeader}${remainingFlags ? ` (${formatFlowFlagsWorker(remainingFlags)})`: ""}`; + } + }, + __debugFlowFlags: { get(this: FlowNodeBase) { return formatEnumWorker(this.flags, (types as any).FlowFlags, /*isFlags*/ true); } }, + __debugToString: { value(this: FlowNodeBase) { return formatControlFlowGraphWorker(this); } } + }); + } +} + +export function getNodeText(node: Node) { + const sourceFile = getSourceFileOfNode(node); + return getSourceTextOfNodeFromSourceFile(sourceFile, node, /*includeTrivia*/ false); +} + +/** + * Formats an enum value as a string for debugging and debug assertions. + */ +export function formatEnumWorker(value = 0, enumObject: any, isFlags?: boolean) { + const members = getEnumMembers(enumObject); + if (value === 0) { + return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0"; + } + if (isFlags) { + const result: string[] = []; + let remainingFlags = value; + for (const [enumValue, enumName] of members) { + if (enumValue > value) { + break; + } + if (enumValue !== 0 && enumValue & value) { + result.push(enumName); + remainingFlags &= ~enumValue; + } + } + if (remainingFlags === 0) { + return result.join("|"); + } + } + else { + for (const [enumValue, enumName] of members) { + if (enumValue === value) { + return enumName; + } + } + } + return value.toString(); +} + +export function arrayTypeToString(sources: readonly DebugType[], targets: readonly DebugType[] | undefined) { + return zipWith(sources, targets || map(sources, () => "any"), + (s, t) => `${s.__debugTypeToString()} -> ${typeof t === "string" ? t : t.__debugTypeToString()}`).join(", "); +} + +export function deferredTypeToString(sources: readonly Type[], targets: (() => Type)[]) { + return zipWith(sources, targets, + (s, t) => `${(s as DebugType).__debugTypeToString()} -> ${(t() as DebugType).__debugTypeToString()}`).join(", "); +} + +export function hasKind(node: any) { + return hasProperty(node, "kind"); +} + +export function hasPos(node: any) { + return hasProperty(node, "pos"); +} + +export function hasName(node: any) { + return hasProperty(node, "name"); +} + +export function hasDebugKind(node: any) { + return hasProperty(node, "__debugKind"); +} + +export function assertNoop(_?: unknown) {} + +export function attachFlowNodeDebugInfoWorker(flowNode: FlowNodeBase) { + 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; + attachFlowNodeDebugInfo(flowNodeProto); + } + Object.setPrototypeOf(flowNode, flowNodeProto); + } + else { + // not running in an es2015 environment, attach the method directly. + attachFlowNodeDebugInfo(flowNode); + } +} + +export function attachNodeArrayDebugInfoWorker(array: NodeArray) { + 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; + attachNodeArrayDebugInfo(nodeArrayProto); + } + Object.setPrototypeOf(array, nodeArrayProto); + } + else { + // not running in an es2015 environment, attach the method directly. + attachNodeArrayDebugInfo(array); + } +} + +export function formatSyntaxKindWorker(kind: SyntaxKind | undefined): string { + return formatEnumWorker(kind, (types as any).SyntaxKind, /*isFlags*/ false); +} + +export function formatSnippetKindWorker(kind: SnippetKind | undefined): string { + return formatEnumWorker(kind, (types as any).SnippetKind, /*isFlags*/ false); +} + +export function formatNodeFlagsWorker(flags: NodeFlags | undefined): string { + return formatEnumWorker(flags, (types as any).NodeFlags, /*isFlags*/ true); +} + +export function formatModifierFlagsWorker(flags: ModifierFlags | undefined): string { + return formatEnumWorker(flags, (types as any).ModifierFlags, /*isFlags*/ true); +} + +export function formatTransformFlagsWorker(flags: TransformFlags | undefined): string { + return formatEnumWorker(flags, (types as any).TransformFlags, /*isFlags*/ true); +} + +export function formatEmitFlagsWorker(flags: EmitFlags | undefined): string { + return formatEnumWorker(flags, (types as any).EmitFlags, /*isFlags*/ true); +} + +export function formatSymbolFlagsWorker(flags: SymbolFlags | undefined): string { + return formatEnumWorker(flags, (types as any).SymbolFlags, /*isFlags*/ true); +} + +export function formatTypeFlagsWorker(flags: TypeFlags | undefined): string { + return formatEnumWorker(flags, (types as any).TypeFlags, /*isFlags*/ true); +} + +export function formatSignatureFlagsWorker(flags: SignatureFlags | undefined): string { + return formatEnumWorker(flags, (types as any).SignatureFlags, /*isFlags*/ true); +} + +export function formatObjectFlagsWorker(flags: ObjectFlags | undefined): string { + return formatEnumWorker(flags, (types as any).ObjectFlags, /*isFlags*/ true); +} + +export function formatFlowFlagsWorker(flags: FlowFlags | undefined): string { + return formatEnumWorker(flags, (types as any).FlowFlags, /*isFlags*/ true); +} + +export function formatRelationComparisonResultWorker(result: RelationComparisonResult | undefined): string { + return formatEnumWorker(result, (types as any).RelationComparisonResult, /*isFlags*/ true); +} + +export function formatCheckModeWorker(mode: CheckMode | undefined): string { + return formatEnumWorker(mode, (checkerTypes as any).CheckMode, /*isFlags*/ true); +} + +export function formatSignatureCheckModeWorker(mode: SignatureCheckMode | undefined): string { + return formatEnumWorker(mode, (checkerTypes as any).SignatureCheckMode, /*isFlags*/ true); +} + +export function formatTypeFactsWorker(facts: TypeFacts | undefined): string { + return formatEnumWorker(facts, (checkerTypes as any).TypeFacts, /*isFlags*/ true); +} + +export function formatControlFlowGraphWorker(flowNode: FlowNode) { + let nextDebugFlowId = -1; + + function getDebugFlowNodeId(f: FlowNode) { + if (!f.id) { + f.id = nextDebugFlowId; + nextDebugFlowId--; + } + return f.id; + } + + const enum BoxCharacter { + lr = "─", + ud = "│", + dr = "╭", + dl = "╮", + ul = "╯", + ur = "╰", + udr = "├", + udl = "┤", + dlr = "┬", + ulr = "┴", + udlr = "╫", + } + + const enum Connection { + None = 0, + Up = 1 << 0, + Down = 1 << 1, + Left = 1 << 2, + Right = 1 << 3, + + UpDown = Up | Down, + LeftRight = Left | Right, + UpLeft = Up | Left, + UpRight = Up | Right, + DownLeft = Down | Left, + DownRight = Down | Right, + UpDownLeft = UpDown | Left, + UpDownRight = UpDown | Right, + UpLeftRight = Up | LeftRight, + DownLeftRight = Down | LeftRight, + UpDownLeftRight = UpDown | LeftRight, + + NoChildren = 1 << 4, + } + + interface FlowGraphNode { + id: number; + flowNode: FlowNode; + edges: FlowGraphEdge[]; + text: string; + lane: number; + endLane: number; + level: number; + circular: boolean | "circularity"; + } + + interface FlowGraphEdge { + source: FlowGraphNode; + target: FlowGraphNode; + } + + const hasAntecedentFlags = + FlowFlags.Assignment | + FlowFlags.Condition | + FlowFlags.SwitchClause | + FlowFlags.ArrayMutation | + FlowFlags.Call | + FlowFlags.ReduceLabel; + + const hasNodeFlags = + FlowFlags.Start | + FlowFlags.Assignment | + FlowFlags.Call | + FlowFlags.Condition | + FlowFlags.ArrayMutation; + + const links: Record = Object.create(/*o*/ null); // eslint-disable-line no-null/no-null + const nodes: FlowGraphNode[] = []; + const edges: FlowGraphEdge[] = []; + const root = buildGraphNode(flowNode, new Set()); + for (const node of nodes) { + node.text = renderFlowNode(node.flowNode, node.circular); + computeLevel(node); + } + + const height = computeHeight(root); + const columnWidths = computeColumnWidths(height); + computeLanes(root, 0); + return renderGraph(); + + function isFlowSwitchClause(f: FlowNode): f is FlowSwitchClause { + return !!(f.flags & FlowFlags.SwitchClause); + } + + function hasAntecedents(f: FlowNode): f is FlowLabel & { antecedents: FlowNode[] } { + return !!(f.flags & FlowFlags.Label) && !!(f as FlowLabel).antecedents; + } + + function hasAntecedent(f: FlowNode): f is Extract { + return !!(f.flags & hasAntecedentFlags); + } + + function hasNode(f: FlowNode): f is Extract { + return !!(f.flags & hasNodeFlags); + } + + function getChildren(node: FlowGraphNode) { + const children: FlowGraphNode[] = []; + for (const edge of node.edges) { + if (edge.source === node) { + children.push(edge.target); + } + } + return children; + } + + function getParents(node: FlowGraphNode) { + const parents: FlowGraphNode[] = []; + for (const edge of node.edges) { + if (edge.target === node) { + parents.push(edge.source); + } + } + return parents; + } + + function buildGraphNode(flowNode: FlowNode, seen: Set): FlowGraphNode { + const id = getDebugFlowNodeId(flowNode); + let graphNode = links[id]; + if (graphNode && seen.has(flowNode)) { + graphNode.circular = true; + graphNode = { + id: -1, + flowNode, + edges: [], + text: "", + lane: -1, + endLane: -1, + level: -1, + circular: "circularity" + }; + nodes.push(graphNode); + return graphNode; + } + seen.add(flowNode); + if (!graphNode) { + links[id] = graphNode = { id, flowNode, edges: [], text: "", lane: -1, endLane: -1, level: -1, circular: false }; + nodes.push(graphNode); + if (hasAntecedents(flowNode)) { + for (const antecedent of flowNode.antecedents) { + buildGraphEdge(graphNode, antecedent, seen); + } + } + else if (hasAntecedent(flowNode)) { + buildGraphEdge(graphNode, flowNode.antecedent, seen); + } + } + seen.delete(flowNode); + return graphNode; + } + + function buildGraphEdge(source: FlowGraphNode, antecedent: FlowNode, seen: Set) { + const target = buildGraphNode(antecedent, seen); + const edge: FlowGraphEdge = { source, target }; + edges.push(edge); + source.edges.push(edge); + target.edges.push(edge); + } + + function computeLevel(node: FlowGraphNode): number { + if (node.level !== -1) { + return node.level; + } + let level = 0; + for (const parent of getParents(node)) { + level = Math.max(level, computeLevel(parent) + 1); + } + return node.level = level; + } + + function computeHeight(node: FlowGraphNode): number { + let height = 0; + for (const child of getChildren(node)) { + height = Math.max(height, computeHeight(child)); + } + return height + 1; + } + + function computeColumnWidths(height: number) { + const columns: number[] = fill(Array(height), 0); + for (const node of nodes) { + columns[node.level] = Math.max(columns[node.level], node.text.length); + } + return columns; + } + + function computeLanes(node: FlowGraphNode, lane: number) { + if (node.lane === -1) { + node.lane = lane; + node.endLane = lane; + const children = getChildren(node); + for (let i = 0; i < children.length; i++) { + if (i > 0) lane++; + const child = children[i]; + computeLanes(child, lane); + if (child.endLane > node.endLane) { + lane = child.endLane; + } + } + node.endLane = lane; + } + } + + function getHeader(flags: FlowFlags) { + if (flags & FlowFlags.Start) return "Start"; + if (flags & FlowFlags.BranchLabel) return "Branch"; + if (flags & FlowFlags.LoopLabel) return "Loop"; + if (flags & FlowFlags.Assignment) return "Assignment"; + if (flags & FlowFlags.TrueCondition) return "True"; + if (flags & FlowFlags.FalseCondition) return "False"; + if (flags & FlowFlags.SwitchClause) return "SwitchClause"; + if (flags & FlowFlags.ArrayMutation) return "ArrayMutation"; + if (flags & FlowFlags.Call) return "Call"; + if (flags & FlowFlags.ReduceLabel) return "ReduceLabel"; + if (flags & FlowFlags.Unreachable) return "Unreachable"; + throw new Error(); + } + + function renderFlowNode(flowNode: FlowNode, circular: boolean | "circularity") { + let text = getHeader(flowNode.flags); + if (circular) { + text = `${text}#${getDebugFlowNodeId(flowNode)}`; + } + if (hasNode(flowNode)) { + if (flowNode.node) { + text += ` (${getNodeText(flowNode.node)})`; + } + } + else if (isFlowSwitchClause(flowNode)) { + const clauses: string[] = []; + for (let i = flowNode.clauseStart; i < flowNode.clauseEnd; i++) { + const clause = flowNode.switchStatement.caseBlock.clauses[i]; + if (isDefaultClause(clause)) { + clauses.push("default"); + } + else { + clauses.push(getNodeText(clause.expression)); + } + } + text += ` (${clauses.join(", ")})`; + } + return circular === "circularity" ? `Circular(${text})` : text; + } + + function renderGraph() { + const columnCount = columnWidths.length; + const laneCount = nodes.reduce((x, n) => Math.max(x, n.lane), 0) + 1; + const lanes: string[] = fill(Array(laneCount), ""); + const grid: (FlowGraphNode | undefined)[][] = columnWidths.map(() => Array(laneCount)); + const connectors: Connection[][] = columnWidths.map(() => fill(Array(laneCount), 0)); + + // build connectors + for (const node of nodes) { + grid[node.level][node.lane] = node; + const children = getChildren(node); + for (let i = 0; i < children.length; i++) { + const child = children[i]; + let connector: Connection = Connection.Right; + if (child.lane === node.lane) connector |= Connection.Left; + if (i > 0) connector |= Connection.Up; + if (i < children.length - 1) connector |= Connection.Down; + connectors[node.level][child.lane] |= connector; + } + if (children.length === 0) { + connectors[node.level][node.lane] |= Connection.NoChildren; + } + const parents = getParents(node); + for (let i = 0; i < parents.length; i++) { + const parent = parents[i]; + let connector: Connection = Connection.Left; + if (i > 0) connector |= Connection.Up; + if (i < parents.length - 1) connector |= Connection.Down; + connectors[node.level - 1][parent.lane] |= connector; + } + } + + // fill in missing connectors + for (let column = 0; column < columnCount; column++) { + for (let lane = 0; lane < laneCount; lane++) { + const left = column > 0 ? connectors[column - 1][lane] : 0; + const above = lane > 0 ? connectors[column][lane - 1] : 0; + let connector = connectors[column][lane]; + if (!connector) { + if (left & Connection.Right) connector |= Connection.LeftRight; + if (above & Connection.Down) connector |= Connection.UpDown; + connectors[column][lane] = connector; + } + } + } + + for (let column = 0; column < columnCount; column++) { + for (let lane = 0; lane < lanes.length; lane++) { + const connector = connectors[column][lane]; + const fill = connector & Connection.Left ? BoxCharacter.lr : " "; + const node = grid[column][lane]; + if (!node) { + if (column < columnCount - 1) { + writeLane(lane, repeat(fill, columnWidths[column] + 1)); + } + } + else { + writeLane(lane, node.text); + if (column < columnCount - 1) { + writeLane(lane, " "); + writeLane(lane, repeat(fill, columnWidths[column] - node.text.length)); + } + } + writeLane(lane, getBoxCharacter(connector)); + writeLane(lane, connector & Connection.Right && column < columnCount - 1 && !grid[column + 1][lane] ? BoxCharacter.lr : " "); + } + } + + return `\n${lanes.join("\n")}\n`; + + function writeLane(lane: number, text: string) { + lanes[lane] += text; + } + } + + function getBoxCharacter(connector: Connection) { + switch (connector) { + case Connection.UpDown: return BoxCharacter.ud; + case Connection.LeftRight: return BoxCharacter.lr; + case Connection.UpLeft: return BoxCharacter.ul; + case Connection.UpRight: return BoxCharacter.ur; + case Connection.DownLeft: return BoxCharacter.dl; + case Connection.DownRight: return BoxCharacter.dr; + case Connection.UpDownLeft: return BoxCharacter.udl; + case Connection.UpDownRight: return BoxCharacter.udr; + case Connection.UpLeftRight: return BoxCharacter.ulr; + case Connection.DownLeftRight: return BoxCharacter.dlr; + case Connection.UpDownLeftRight: return BoxCharacter.udlr; + } + return " "; + } + + function fill(array: T[], value: T) { + if (array.fill) { + array.fill(value); + } + else { + for (let i = 0; i < array.length; i++) { + array[i] = value; + } + } + return array; + } + + function repeat(ch: string, length: number) { + if (ch.repeat) { + return length > 0 ? ch.repeat(length) : ""; + } + let s = ""; + while (s.length < length) { + s += ch; + } + return s; + } +} + +export function formatSymbolWorker(symbol: Symbol): string { + return `{ name: ${unescapeLeadingUnderscores(symbol.escapedName)}; flags: ${formatSymbolFlagsWorker(symbol.flags)}; declarations: ${symbol.declarations?.map(node => formatSyntaxKindWorker(node.kind))} }`; +} + +export function enableDebugInfoWorder() { + attachSymbolDebugInfo(objectAllocator.getSymbolConstructor().prototype); + attachTypeDebugInfo(objectAllocator.getTypeConstructor().prototype); + attachSignatureDebugInfo(objectAllocator.getSignatureConstructor().prototype); + + const nodeConstructors = [ + objectAllocator.getNodeConstructor(), + objectAllocator.getIdentifierConstructor(), + objectAllocator.getTokenConstructor(), + objectAllocator.getSourceFileConstructor() + ]; + + for (const ctor of nodeConstructors) { + if (!hasDebugKind(ctor.prototype)) { + attachNodeDebugInfo(ctor.prototype); + } + } +} diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6eecf0cf1935f..e8b63eba6dece 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -419,11 +419,9 @@ import { getLinesBetweenRangeEndAndRangeStart, getLiteralText, GetLiteralTextFlags, - getNewLineCharacter, getOwnEmitOutputFilePath, getSourceFileOfNode, getSourceFilePathInNewDir, - getSourceFilesToEmit, getSourceTextOfNodeFromSourceFile, getTrailingSemicolonDeferringWriter, isAccessExpression, @@ -443,16 +441,12 @@ import { makeIdentifierFromModuleName, nodeIsSynthesized, outFile, - positionIsSynthesized, positionsAreOnSameLine, rangeEndIsOnSameLineAsRangeStart, rangeEndPositionsAreOnSameLine, rangeIsOnSingleLine, rangeStartPositionsAreOnSameLine, - readJsonOrUndefined, removeFileExtension, - setEachParent, - setParent, setTextRangePosEnd, setTextRangePosWidth, supportedJSExtensionsFlat, @@ -481,6 +475,11 @@ import { isUnparsedNode, skipPartiallyEmittedExpressions, } from "./utilitiesPublic"; +import { positionIsSynthesized } from "./scannerUtilities"; +import { getNewLineCharacter } from "./sysUtilities"; +import { getSourceFilesToEmit } from "./emitterUtilities"; +import { setEachParent, setParent } from "./parserUtilities"; +import { readJsonOrUndefined } from "./commandLineParserUtilities"; const brackets = createBracketsMap(); diff --git a/src/compiler/emitterUtilities.ts b/src/compiler/emitterUtilities.ts new file mode 100644 index 0000000000000..0a79870eb8291 --- /dev/null +++ b/src/compiler/emitterUtilities.ts @@ -0,0 +1,45 @@ +import { filter } from "./core"; +import { + EmitHost, + ModuleKind, + SourceFile, +} from "./types"; +import { + getEmitModuleKind, + isExternalModule, + outFile, + sourceFileMayBeEmitted, +} from "./utilities"; + +/** + * Gets the source files that are expected to have an emit output. + * + * Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support + * transformations. + * + * @param host An EmitHost. + * @param targetSourceFile An optional target source file to emit. + * + * @internal + */ +export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile, forceDtsEmit?: boolean): readonly SourceFile[] { + const options = host.getCompilerOptions(); + if (outFile(options)) { + const moduleKind = getEmitModuleKind(options); + const moduleEmitEnabled = options.emitDeclarationOnly || moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.System; + // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified + return filter( + host.getSourceFiles(), + sourceFile => + (moduleEmitEnabled || !isExternalModule(sourceFile)) && + sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit) + ); + } + else { + const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile]; + return filter( + sourceFiles, + sourceFile => sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit) + ); + } +} diff --git a/src/compiler/factory/baseNodeFactory.ts b/src/compiler/factory/baseNodeFactory.ts index 1d498b79a3ab4..5e12b57f50c24 100644 --- a/src/compiler/factory/baseNodeFactory.ts +++ b/src/compiler/factory/baseNodeFactory.ts @@ -2,7 +2,7 @@ import { Node, SyntaxKind, } from "../types"; -import { objectAllocator } from "../utilities"; +import { objectAllocator } from "../objectAllocator"; /** * A `BaseNodeFactory` is an abstraction over an `ObjectAllocator` that handles caching `Node` constructors diff --git a/src/compiler/factory/binaryExpressionStateMachine.ts b/src/compiler/factory/binaryExpressionStateMachine.ts index 7ae6e731d8465..21b3262855e27 100644 --- a/src/compiler/factory/binaryExpressionStateMachine.ts +++ b/src/compiler/factory/binaryExpressionStateMachine.ts @@ -1,5 +1,4 @@ -import { AssertionLevel } from "../core"; -import { Debug } from "../debug"; +import { AssertionLevel, Debug } from "../debug"; import { BinaryExpression, BinaryOperatorToken, diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 3a6a1c5b118a3..f59b0b00cc7bc 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -23,7 +23,9 @@ import { import { Push } from "../corePublic"; import { Debug } from "../debug"; import { getBuildInfo } from "../emitter"; +import { objectAllocator } from "../objectAllocator"; import { parseNodeFactory } from "../parser"; +import { setEachParent, setParent } from "../parserUtilities"; import { createScanner, getLineAndCharacterOfPosition, @@ -233,6 +235,7 @@ import { ModuleKind, ModuleName, ModuleReference, + Mutable, MutableNodeArray, NamedExportBindings, NamedExports, @@ -377,12 +380,8 @@ import { isSuperProperty, isThisIdentifier, modifiersToFlags, - Mutable, nodeIsSynthesized, - objectAllocator, pseudoBigIntToString, - setEachParent, - setParent, setTextRangePosWidth, skipOuterExpressions, skipParentheses, diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index 6833d638358de..fa585ebb90587 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -8,6 +8,8 @@ import { } from "../core"; import { Debug } from "../debug"; import { parseNodeFactory } from "../parser"; +import { setParent } from "../parserUtilities"; +import { isIdentifierText } from "../scanner"; import { AccessorDeclaration, AdditiveOperator, @@ -67,6 +69,7 @@ import { ModuleName, MultiplicativeOperator, MultiplicativeOperatorOrHigher, + Mutable, NamedImportBindings, Node, NodeArray, @@ -86,6 +89,7 @@ import { ReadonlyKeyword, RelationalOperator, RelationalOperatorOrHigher, + ScriptTarget, SetAccessorDeclaration, ShiftOperator, ShiftOperatorOrHigher, @@ -116,9 +120,8 @@ import { isEffectiveExternalModule, isExportNamespaceAsDefaultDeclaration, isFileLevelUniqueName, - Mutable, + isNumericLiteralName, outFile, - setParent, } from "../utilities"; import { getJSDocType, @@ -1320,3 +1323,10 @@ export function createAccessorPropertySetRedirector(factory: NodeFactory, node: ]) ); } + +/** @internal */ +export function createPropertyNameNodeForIdentifierOrLiteral(factory: NodeFactory, name: string, target: ScriptTarget, singleQuote?: boolean, stringNamed?: boolean) { + return isIdentifierText(name, target) ? factory.createIdentifier(name) : + !stringNamed && isNumericLiteralName(name) && +name >= 0 ? factory.createNumericLiteral(+name) : + factory.createStringLiteral(name, !!singleQuote); +} diff --git a/src/compiler/fileMatcher.ts b/src/compiler/fileMatcher.ts new file mode 100644 index 0000000000000..09998d4afc3e6 --- /dev/null +++ b/src/compiler/fileMatcher.ts @@ -0,0 +1,344 @@ +import { compareStringsCaseSensitive, createGetCanonicalFileName, emptyArray, every, findIndex, flatMap, flatten, getStringComparer, indexOfAnyCharCode, last, map, sort } from "./core"; +import { combinePaths, containsPath, directorySeparator, fileExtensionIsOneOf, getDirectoryPath, getNormalizedPathComponents, hasExtension, isRootedDiskPath, normalizePath, removeTrailingDirectorySeparator } from "./path"; +import { CharacterCodes } from "./types"; + +/** @internal */ +export const commonPackageFolders: readonly string[] = ["node_modules", "bower_components", "jspm_packages"]; + +// Reserved characters, forces escaping of any non-word (or digit), non-whitespace character. +// It may be inefficient (we could just match (/[-[\]{}()*+?.,\\^$|#\s]/g), but this is future +// proof. +const reservedCharacterPattern = /[^\w\s\/]/g; +const implicitExcludePathRegexPattern = `(?!(${commonPackageFolders.join("|")})(/|$))`; +const wildcardCharCodes = [CharacterCodes.asterisk, CharacterCodes.question]; + +interface WildcardMatcher { + singleAsteriskRegexFragment: string; + doubleAsteriskRegexFragment: string; + replaceWildcardCharacter: (match: string) => string; +} + +const filesMatcher: WildcardMatcher = { + /** + * Matches any single directory segment unless it is the last segment and a .min.js file + * Breakdown: + * [^./] # matches everything up to the first . character (excluding directory separators) + * (\\.(?!min\\.js$))? # matches . characters but not if they are part of the .min.js file extension + */ + singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*", + /** + * Regex for the ** wildcard. Matches any number of subdirectories. When used for including + * files or directories, does not match subdirectories that start with a . character + */ + doubleAsteriskRegexFragment: `(/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`, + replaceWildcardCharacter: match => replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment) +}; + +const directoriesMatcher: WildcardMatcher = { + singleAsteriskRegexFragment: "[^/]*", + /** + * Regex for the ** wildcard. Matches any number of subdirectories. When used for including + * files or directories, does not match subdirectories that start with a . character + */ + doubleAsteriskRegexFragment: `(/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`, + replaceWildcardCharacter: match => replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment) +}; + +const excludeMatcher: WildcardMatcher = { + singleAsteriskRegexFragment: "[^/]*", + doubleAsteriskRegexFragment: "(/.+?)?", + replaceWildcardCharacter: match => replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment) +}; + +const wildcardMatchers = { + files: filesMatcher, + directories: directoriesMatcher, + exclude: excludeMatcher +}; + +/** @internal */ +export const emptyFileSystemEntries: FileSystemEntries = { + files: emptyArray, + directories: emptyArray +}; + +/** @internal */ +export interface FileMatcherPatterns { + /** One pattern for each "include" spec. */ + includeFilePatterns: readonly string[] | undefined; + /** One pattern matching one of any of the "include" specs. */ + includeFilePattern: string | undefined; + includeDirectoryPattern: string | undefined; + excludePattern: string | undefined; + basePaths: readonly string[]; +} + +/** @internal */ +export interface FileSystemEntries { + readonly files: readonly string[]; + readonly directories: readonly string[]; +} + +/** + * @param path directory of the tsconfig.json + * + * @internal + */ +export function getFileMatcherPatterns(path: string, excludes: readonly string[] | undefined, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns { + path = normalizePath(path); + currentDirectory = normalizePath(currentDirectory); + const absolutePath = combinePaths(currentDirectory, path); + + return { + includeFilePatterns: map(getRegularExpressionsForWildcards(includes, absolutePath, "files"), pattern => `^${pattern}$`), + includeFilePattern: getRegularExpressionForWildcard(includes, absolutePath, "files"), + includeDirectoryPattern: getRegularExpressionForWildcard(includes, absolutePath, "directories"), + excludePattern: getRegularExpressionForWildcard(excludes, absolutePath, "exclude"), + basePaths: getBasePaths(path, includes, useCaseSensitiveFileNames) + }; +} + +/** + * @param path directory of the tsconfig.json + * + * @internal + */ +export function matchFiles(path: string, extensions: readonly string[] | undefined, excludes: readonly string[] | undefined, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string, depth: number | undefined, getFileSystemEntries: (path: string) => FileSystemEntries, realpath: (path: string) => string): string[] { + path = normalizePath(path); + currentDirectory = normalizePath(currentDirectory); + + const patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory); + + const includeFileRegexes = patterns.includeFilePatterns && patterns.includeFilePatterns.map(pattern => getRegexFromPattern(pattern, useCaseSensitiveFileNames)); + const includeDirectoryRegex = patterns.includeDirectoryPattern && getRegexFromPattern(patterns.includeDirectoryPattern, useCaseSensitiveFileNames); + const excludeRegex = patterns.excludePattern && getRegexFromPattern(patterns.excludePattern, useCaseSensitiveFileNames); + + // Associate an array of results with each include regex. This keeps results in order of the "include" order. + // If there are no "includes", then just put everything in results[0]. + const results: string[][] = includeFileRegexes ? includeFileRegexes.map(() => []) : [[]]; + const visited = new Map(); + const toCanonical = createGetCanonicalFileName(useCaseSensitiveFileNames); + for (const basePath of patterns.basePaths) { + visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth); + } + + return flatten(results); + + function visitDirectory(path: string, absolutePath: string, depth: number | undefined) { + const canonicalPath = toCanonical(realpath(absolutePath)); + if (visited.has(canonicalPath)) return; + visited.set(canonicalPath, true); + const { files, directories } = getFileSystemEntries(path); + + for (const current of sort(files, compareStringsCaseSensitive)) { + const name = combinePaths(path, current); + const absoluteName = combinePaths(absolutePath, current); + if (extensions && !fileExtensionIsOneOf(name, extensions)) continue; + if (excludeRegex && excludeRegex.test(absoluteName)) continue; + if (!includeFileRegexes) { + results[0].push(name); + } + else { + const includeIndex = findIndex(includeFileRegexes, re => re.test(absoluteName)); + if (includeIndex !== -1) { + results[includeIndex].push(name); + } + } + } + + if (depth !== undefined) { + depth--; + if (depth === 0) { + return; + } + } + + for (const current of sort(directories, compareStringsCaseSensitive)) { + const name = combinePaths(path, current); + const absoluteName = combinePaths(absolutePath, current); + if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) && + (!excludeRegex || !excludeRegex.test(absoluteName))) { + visitDirectory(name, absoluteName, depth); + } + } + } +} + +/** @internal */ +export function getRegularExpressionForWildcard(specs: readonly string[] | undefined, basePath: string, usage: "files" | "directories" | "exclude"): string | undefined { + const patterns = getRegularExpressionsForWildcards(specs, basePath, usage); + if (!patterns || !patterns.length) { + return undefined; + } + + const pattern = patterns.map(pattern => `(${pattern})`).join("|"); + // If excluding, match "foo/bar/baz...", but if including, only allow "foo". + const terminator = usage === "exclude" ? "($|/)" : "$"; + return `^(${pattern})${terminator}`; +} + +/** @internal */ +export function getRegularExpressionsForWildcards(specs: readonly string[] | undefined, basePath: string, usage: "files" | "directories" | "exclude"): readonly string[] | undefined { + if (specs === undefined || specs.length === 0) { + return undefined; + } + + return flatMap(specs, spec => + spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage])); +} + +/** @internal */ +export function getRegexFromPattern(pattern: string, useCaseSensitiveFileNames: boolean): RegExp { + return new RegExp(pattern, useCaseSensitiveFileNames ? "" : "i"); +} + +/** @internal */ +export function getPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude") { + const pattern = spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]); + return pattern && `^(${pattern})${usage === "exclude" ? "($|/)" : "$"}`; +} + +/** + * An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension, + * and does not contain any glob characters itself. + * + * @internal + */ +export function isImplicitGlob(lastPathComponent: string): boolean { + return !/[.*?]/.test(lastPathComponent); +} + +function getSubPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude", { singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter }: WildcardMatcher): string | undefined { + let subpattern = ""; + let hasWrittenComponent = false; + const components = getNormalizedPathComponents(spec, basePath); + const lastComponent = last(components); + if (usage !== "exclude" && lastComponent === "**") { + return undefined; + } + + // getNormalizedPathComponents includes the separator for the root component. + // We need to remove to create our regex correctly. + components[0] = removeTrailingDirectorySeparator(components[0]); + + if (isImplicitGlob(lastComponent)) { + components.push("**", "*"); + } + + let optionalCount = 0; + for (let component of components) { + if (component === "**") { + subpattern += doubleAsteriskRegexFragment; + } + else { + if (usage === "directories") { + subpattern += "("; + optionalCount++; + } + + if (hasWrittenComponent) { + subpattern += directorySeparator; + } + + if (usage !== "exclude") { + let componentPattern = ""; + // The * and ? wildcards should not match directories or files that start with . if they + // appear first in a component. Dotted directories and files can be included explicitly + // like so: **/.*/.* + if (component.charCodeAt(0) === CharacterCodes.asterisk) { + componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?"; + component = component.substr(1); + } + else if (component.charCodeAt(0) === CharacterCodes.question) { + componentPattern += "[^./]"; + component = component.substr(1); + } + + componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); + + // Patterns should not include subfolders like node_modules unless they are + // explicitly included as part of the path. + // + // As an optimization, if the component pattern is the same as the component, + // then there definitely were no wildcard characters and we do not need to + // add the exclusion pattern. + if (componentPattern !== component) { + subpattern += implicitExcludePathRegexPattern; + } + + subpattern += componentPattern; + } + else { + subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); + } + } + + hasWrittenComponent = true; + } + + while (optionalCount > 0) { + subpattern += ")?"; + optionalCount--; + } + + return subpattern; +} + + + +/** @internal */ +export function regExpEscape(text: string) { + return text.replace(reservedCharacterPattern, escapeRegExpCharacter); +} + +function escapeRegExpCharacter(match: string) { + return "\\" + match; +} + +/** + * Computes the unique non-wildcard base paths amongst the provided include patterns. + */ +function getBasePaths(path: string, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean): string[] { + // Storage for our results in the form of literal paths (e.g. the paths as written by the user). + const basePaths: string[] = [path]; + + if (includes) { + // Storage for literal base paths amongst the include patterns. + const includeBasePaths: string[] = []; + for (const include of includes) { + // We also need to check the relative paths by converting them to absolute and normalizing + // in case they escape the base path (e.g "..\somedirectory") + const absolute: string = isRootedDiskPath(include) ? include : normalizePath(combinePaths(path, include)); + // Append the literal and canonical candidate base paths. + includeBasePaths.push(getIncludeBasePath(absolute)); + } + + // Sort the offsets array using either the literal or canonical path representations. + includeBasePaths.sort(getStringComparer(!useCaseSensitiveFileNames)); + + // Iterate over each include base path and include unique base paths that are not a + // subpath of an existing base path + for (const includeBasePath of includeBasePaths) { + if (every(basePaths, basePath => !containsPath(basePath, includeBasePath, path, !useCaseSensitiveFileNames))) { + basePaths.push(includeBasePath); + } + } + } + + return basePaths; +} + +function getIncludeBasePath(absolute: string): string { + const wildcardOffset = indexOfAnyCharCode(absolute, wildcardCharCodes); + if (wildcardOffset < 0) { + // No "*" or "?" in the path + return !hasExtension(absolute) + ? absolute + : removeTrailingDirectorySeparator(getDirectoryPath(absolute)); + } + return absolute.substring(0, absolute.lastIndexOf(directorySeparator, wildcardOffset)); +} + +function replaceWildcardCharacter(match: string, singleAsteriskRegexFragment: string) { + return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match; +} diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 3738055d51218..ea748ffaa21f4 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -1,4 +1,5 @@ import { DiagnosticReporter, moduleResolutionOptionDeclarations } from "./commandLineParser"; +import { readJson } from "./commandLineParserUtilities"; import { append, appendIfUnique, @@ -67,7 +68,6 @@ import { toPath, } from "./path"; import { perfLogger } from "./perfLogger"; -import { ResolutionNameAndModeGetter } from "./program"; import { Version, VersionRange, @@ -87,6 +87,7 @@ import { PackageId, Path, ResolutionMode, + ResolutionNameAndModeGetter, ResolvedModuleWithFailedLookupLocations, ResolvedProjectReference, ResolvedTypeReferenceDirective, @@ -108,7 +109,6 @@ import { hostGetCanonicalFileName, matchPatternOrExact, packageIdToString, - readJson, removeExtension, removeFileExtension, supportedDeclarationExtensions, diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 705ea67c8c43b..70dfa5f1ae418 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -39,6 +39,11 @@ import { pathContainsNodeModules, shouldAllowImportingTsExtension, } from "./moduleNameResolver"; +import { + getModuleSpecifierEndingPreference, + getNodeModulePathParts, + NodeModulePathParts, +} from "./moduleSpecifiersUtilities"; import { isDeclarationFileName } from "./parser"; import { combinePaths, @@ -65,6 +70,7 @@ import { getModeForResolutionAtIndex, getModuleNameStringLiteralAt, } from "./program"; +import { containsIgnoredPath } from "./sysUtilities"; import { __String, AmbientModuleDeclaration, @@ -96,11 +102,8 @@ import { } from "./types"; import { compareNumberOfDirectorySeparators, - containsIgnoredPath, extensionFromPath, getEmitModuleResolutionKind, - getModuleSpecifierEndingPreference, - getNodeModulePathParts, getPathsBasePath, getSourceFileOfModule, getSupportedExtensions, @@ -113,7 +116,6 @@ import { isNonGlobalAmbientModule, matchPatternOrExact, ModuleSpecifierEnding, - NodeModulePathParts, removeFileExtension, tryGetExtensionFromPath, tryParsePatterns, diff --git a/src/compiler/moduleSpecifiersUtilities.ts b/src/compiler/moduleSpecifiersUtilities.ts new file mode 100644 index 0000000000000..b052f0694cc55 --- /dev/null +++ b/src/compiler/moduleSpecifiersUtilities.ts @@ -0,0 +1,165 @@ +import { + append, + concatenate, + emptyArray, +} from "./core"; +import { isExpressionStatement } from "./factory/nodeTests"; +import { + nodeModulesPathPart, + shouldAllowImportingTsExtension, +} from "./moduleNameResolver"; +import { pathIsRelative } from "./path"; +import { + CompilerOptions, + ModuleKind, + RequireOrImportCall, + ResolutionMode, + SourceFile, + UserPreferences, +} from "./types"; +import { + hasJSFileExtension, + hasTSFileExtension, + isRequireCall, + isRequireVariableStatement, + isSourceFileJS, + ModuleSpecifierEnding, + usesExtensionsOnImports, +} from "./utilities"; + +/** @internal */ +export interface NodeModulePathParts { + readonly topLevelNodeModulesIndex: number; + readonly topLevelPackageNameIndex: number; + readonly packageRootIndex: number; + readonly fileNameIndex: number; +} + +/** @internal */ +export function getNodeModulePathParts(fullPath: string): NodeModulePathParts | undefined { + // If fullPath can't be valid module file within node_modules, returns undefined. + // Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js + // Returns indices: ^ ^ ^ ^ + + let topLevelNodeModulesIndex = 0; + let topLevelPackageNameIndex = 0; + let packageRootIndex = 0; + let fileNameIndex = 0; + + const enum States { + BeforeNodeModules, + NodeModules, + Scope, + PackageContent + } + + let partStart = 0; + let partEnd = 0; + let state = States.BeforeNodeModules; + + while (partEnd >= 0) { + partStart = partEnd; + partEnd = fullPath.indexOf("/", partStart + 1); + switch (state) { + case States.BeforeNodeModules: + if (fullPath.indexOf(nodeModulesPathPart, partStart) === partStart) { + topLevelNodeModulesIndex = partStart; + topLevelPackageNameIndex = partEnd; + state = States.NodeModules; + } + break; + case States.NodeModules: + case States.Scope: + if (state === States.NodeModules && fullPath.charAt(partStart + 1) === "@") { + state = States.Scope; + } + else { + packageRootIndex = partEnd; + state = States.PackageContent; + } + break; + case States.PackageContent: + if (fullPath.indexOf(nodeModulesPathPart, partStart) === partStart) { + state = States.NodeModules; + } + else { + state = States.PackageContent; + } + break; + } + } + + fileNameIndex = partStart; + + return state > States.NodeModules ? { topLevelNodeModulesIndex, topLevelPackageNameIndex, packageRootIndex, fileNameIndex } : undefined; +} + +/** @internal */ +export function getModuleSpecifierEndingPreference(preference: UserPreferences["importModuleSpecifierEnding"], resolutionMode: ResolutionMode, compilerOptions: CompilerOptions, sourceFile: SourceFile): ModuleSpecifierEnding { + if (preference === "js" || resolutionMode === ModuleKind.ESNext) { + // Extensions are explicitly requested or required. Now choose between .js and .ts. + if (!shouldAllowImportingTsExtension(compilerOptions)) { + return ModuleSpecifierEnding.JsExtension; + } + // `allowImportingTsExtensions` is a strong signal, so use .ts unless the file + // already uses .js extensions and no .ts extensions. + return inferPreference() !== ModuleSpecifierEnding.JsExtension + ? ModuleSpecifierEnding.TsExtension + : ModuleSpecifierEnding.JsExtension; + } + if (preference === "minimal") { + return ModuleSpecifierEnding.Minimal; + } + if (preference === "index") { + return ModuleSpecifierEnding.Index; + } + + // No preference was specified. + // Look at imports and/or requires to guess whether .js, .ts, or extensionless imports are preferred. + // N.B. that `Index` detection is not supported since it would require file system probing to do + // accurately, and more importantly, literally nobody wants `Index` and its existence is a mystery. + if (!shouldAllowImportingTsExtension(compilerOptions)) { + // If .ts imports are not valid, we only need to see one .js import to go with that. + return usesExtensionsOnImports(sourceFile) ? ModuleSpecifierEnding.JsExtension : ModuleSpecifierEnding.Minimal; + } + + return inferPreference(); + + function inferPreference() { + let usesJsExtensions = false; + const specifiers = sourceFile.imports.length ? sourceFile.imports.map(i => i.text) : + isSourceFileJS(sourceFile) ? getRequiresAtTopOfFile(sourceFile).map(r => r.arguments[0].text) : + emptyArray; + for (const specifier of specifiers) { + if (pathIsRelative(specifier)) { + if (hasTSFileExtension(specifier)) { + return ModuleSpecifierEnding.TsExtension; + } + if (hasJSFileExtension(specifier)) { + usesJsExtensions = true; + } + } + } + return usesJsExtensions ? ModuleSpecifierEnding.JsExtension : ModuleSpecifierEnding.Minimal; + } +} + +function getRequiresAtTopOfFile(sourceFile: SourceFile): readonly RequireOrImportCall[] { + let nonRequireStatementCount = 0; + let requires: RequireOrImportCall[] | undefined; + for (const statement of sourceFile.statements) { + if (nonRequireStatementCount > 3) { + break; + } + if (isRequireVariableStatement(statement)) { + requires = concatenate(requires, statement.declarationList.declarations.map(d => d.initializer)); + } + else if (isExpressionStatement(statement) && isRequireCall(statement.expression, /*requireStringLiteralLikeArgument*/ true)) { + requires = append(requires, statement.expression); + } + else { + nonRequireStatementCount++; + } + } + return requires || emptyArray; +} diff --git a/src/compiler/objectAllocator.ts b/src/compiler/objectAllocator.ts new file mode 100644 index 0000000000000..58a5ea2819a1f --- /dev/null +++ b/src/compiler/objectAllocator.ts @@ -0,0 +1,128 @@ +import { Debug } from "./debug"; +import { tracing } from "./tracing"; +import { + __String, + Identifier, + ModifierFlags, + Mutable, + Node, + NodeFlags, + PrivateIdentifier, + Signature, + SignatureFlags, + SourceFile, + SourceMapSource, + Symbol, + SymbolFlags, + SyntaxKind, + Token, + TransformFlags, + Type, + TypeChecker, + TypeFlags, +} from "./types"; + +/** @internal */ +export interface ObjectAllocator { + getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node; + getTokenConstructor(): new (kind: TKind, pos?: number, end?: number) => Token; + getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos?: number, end?: number) => Identifier; + getPrivateIdentifierConstructor(): new (kind: SyntaxKind.PrivateIdentifier, pos?: number, end?: number) => PrivateIdentifier; + getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile; + getSymbolConstructor(): new (flags: SymbolFlags, name: __String) => Symbol; + getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type; + getSignatureConstructor(): new (checker: TypeChecker, flags: SignatureFlags) => Signature; + getSourceMapSourceConstructor(): new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource; +} + +/** @internal */ +export const objectAllocator: ObjectAllocator = { + getNodeConstructor: () => Node as any, + getTokenConstructor: () => Token as any, + getIdentifierConstructor: () => Identifier as any, + getPrivateIdentifierConstructor: () => Node as any, + getSourceFileConstructor: () => Node as any, + getSymbolConstructor: () => Symbol as any, + getTypeConstructor: () => Type as any, + getSignatureConstructor: () => Signature as any, + getSourceMapSourceConstructor: () => SourceMapSource as any, +}; + +/** @internal */ +export function setObjectAllocator(alloc: ObjectAllocator) { + Object.assign(objectAllocator, alloc); +} + +function Symbol(this: Symbol, flags: SymbolFlags, name: __String) { + this.flags = flags; + this.escapedName = name; + this.declarations = undefined; + this.valueDeclaration = undefined; + this.id = 0; + this.mergeId = 0; + this.parent = undefined; + this.members = undefined; + this.exports = undefined; + this.exportSymbol = undefined; + this.constEnumOnlyModule = undefined; + this.isReferenced = undefined; + this.isAssigned = undefined; + (this as any).links = undefined; // used by TransientSymbol +} + +function Type(this: Type, checker: TypeChecker, flags: TypeFlags) { + this.flags = flags; + if (Debug.isDebugging || tracing) { + this.checker = checker; + } +} + +function Signature(this: Signature, checker: TypeChecker, flags: SignatureFlags) { + this.flags = flags; + if (Debug.isDebugging) { + this.checker = checker; + } +} + +function Node(this: Mutable, kind: SyntaxKind, pos: number, end: number) { + this.pos = pos; + this.end = end; + this.kind = kind; + this.id = 0; + this.flags = NodeFlags.None; + this.modifierFlagsCache = ModifierFlags.None; + this.transformFlags = TransformFlags.None; + this.parent = undefined!; + this.original = undefined; + this.emitNode = undefined; +} + +function Token(this: Mutable, kind: SyntaxKind, pos: number, end: number) { + this.pos = pos; + this.end = end; + this.kind = kind; + this.id = 0; + this.flags = NodeFlags.None; + this.transformFlags = TransformFlags.None; + this.parent = undefined!; + this.emitNode = undefined; +} + +function Identifier(this: Mutable, kind: SyntaxKind, pos: number, end: number) { + this.pos = pos; + this.end = end; + this.kind = kind; + this.id = 0; + this.flags = NodeFlags.None; + this.transformFlags = TransformFlags.None; + this.parent = undefined!; + this.original = undefined; + this.emitNode = undefined; + (this as Identifier).flowNode = undefined; +} + +function SourceMapSource(this: SourceMapSource, fileName: string, text: string, skipTrivia?: (pos: number) => number) { + this.fileName = fileName; + this.text = text; + this.skipTrivia = skipTrivia || (pos => pos); +} diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 07f59ccd5f371..69b82eeca6420 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2,7 +2,6 @@ import { convertToObjectWorker } from "./commandLineParser"; import { addRange, append, - AssertionLevel, concatenate, emptyArray, emptyMap, @@ -19,7 +18,7 @@ import { toArray, trimString, } from "./core"; -import { Debug } from "./debug"; +import { AssertionLevel, Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { BaseNodeFactory } from "./factory/baseNodeFactory"; import { @@ -55,6 +54,13 @@ import { setTextRange, } from "./factory/utilitiesPublic"; import { PackageJsonInfo } from "./moduleNameResolver"; +import { objectAllocator } from "./objectAllocator"; +import { + containsParseError, + getLastChild, + setParent, + setParentRecursive, +} from "./parserUtilities"; import { fileExtensionIsOneOf, normalizePath, @@ -251,6 +257,7 @@ import { ModuleBlock, ModuleDeclaration, ModuleKind, + Mutable, NamedExportBindings, NamedExports, NamedImports, @@ -363,26 +370,21 @@ import { addRelatedInfo, attachFileToDiagnostics, canHaveJSDoc, - containsParseError, createDetachedDiagnostic, ensureScriptKind, getBinaryOperatorPrecedence, getFullWidth, getJSDocCommentRanges, getLanguageVariant, - getLastChild, getTextOfNodeFromSourceText, isAssignmentOperator, + isExternalModule, isKeyword, isStringOrNumericLiteralLike, modifiersToFlags, - Mutable, nodeIsMissing, nodeIsPresent, - objectAllocator, OperatorPrecedence, - setParent, - setParentRecursive, setTextRangePos, setTextRangePosEnd, setTextRangePosWidth, @@ -1384,11 +1386,6 @@ export function parseJsonText(fileName: string, sourceText: string): JsonSourceF return Parser.parseJsonText(fileName, sourceText); } -// See also `isExternalOrCommonJsModule` in utilities.ts -export function isExternalModule(file: SourceFile): boolean { - return file.externalModuleIndicator !== undefined; -} - // Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter // indicates what changed between the 'text' that this SourceFile has and the 'newText'. // The SourceFile will be created with the compiler attempting to reuse as many nodes from diff --git a/src/compiler/parserUtilities.ts b/src/compiler/parserUtilities.ts new file mode 100644 index 0000000000000..8ef8f06349c76 --- /dev/null +++ b/src/compiler/parserUtilities.ts @@ -0,0 +1,209 @@ +import { + forEachChild, + forEachChildRecursively, +} from "./parser"; +import { + Block, + Mutable, + Node, + NodeFlags, + ReturnStatement, + Statement, + SyntaxKind, + YieldExpression, +} from "./types"; +import { + isPartOfTypeNode, + nodeIsPresent, +} from "./utilities"; +import { + hasJSDocNodes, + isFunctionLike, + isJSDocNode, +} from "./utilitiesPublic"; + +function aggregateChildData(node: Node): void { + if (!(node.flags & NodeFlags.HasAggregatedChildData)) { + // A node is considered to contain a parse error if: + // a) the parser explicitly marked that it had an error + // b) any of it's children reported that it had an error. + const thisNodeOrAnySubNodesHasError = ((node.flags & NodeFlags.ThisNodeHasError) !== 0) || + forEachChild(node, containsParseError); + + // If so, mark ourselves accordingly. + if (thisNodeOrAnySubNodesHasError) { + (node as Mutable).flags |= NodeFlags.ThisNodeOrAnySubNodesHasError; + } + + // Also mark that we've propagated the child information to this node. This way we can + // always consult the bit directly on this node without needing to check its children + // again. + (node as Mutable).flags |= NodeFlags.HasAggregatedChildData; + } +} + +/** @internal */ +export function containsParseError(node: Node): boolean { + aggregateChildData(node); + return (node.flags & NodeFlags.ThisNodeOrAnySubNodesHasError) !== 0; +} + +/** @internal */ +export function getLastChild(node: Node): Node | undefined { + let lastChild: Node | undefined; + forEachChild(node, + child => { + if (nodeIsPresent(child)) lastChild = child; + }, + children => { + // As an optimization, jump straight to the end of the list. + for (let i = children.length - 1; i >= 0; i--) { + if (nodeIsPresent(children[i])) { + lastChild = children[i]; + break; + } + } + }); + return lastChild; +} + +// Warning: This has the same semantics as the forEach family of functions, +// in that traversal terminates in the event that 'visitor' supplies a truthy value. +/** @internal */ +export function forEachReturnStatement(body: Block | Statement, visitor: (stmt: ReturnStatement) => T): T | undefined { + + return traverse(body); + + function traverse(node: Node): T | undefined { + switch (node.kind) { + case SyntaxKind.ReturnStatement: + return visitor(node as ReturnStatement); + case SyntaxKind.CaseBlock: + case SyntaxKind.Block: + case SyntaxKind.IfStatement: + case SyntaxKind.DoStatement: + case SyntaxKind.WhileStatement: + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + case SyntaxKind.ForOfStatement: + case SyntaxKind.WithStatement: + case SyntaxKind.SwitchStatement: + case SyntaxKind.CaseClause: + case SyntaxKind.DefaultClause: + case SyntaxKind.LabeledStatement: + case SyntaxKind.TryStatement: + case SyntaxKind.CatchClause: + return forEachChild(node, traverse); + } + } +} + +/** @internal */ +export function forEachYieldExpression(body: Block, visitor: (expr: YieldExpression) => void): void { + return traverse(body); + + function traverse(node: Node): void { + switch (node.kind) { + case SyntaxKind.YieldExpression: + visitor(node as YieldExpression); + const operand = (node as YieldExpression).expression; + if (operand) { + traverse(operand); + } + return; + case SyntaxKind.EnumDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.TypeAliasDeclaration: + // These are not allowed inside a generator now, but eventually they may be allowed + // as local types. Regardless, skip them to avoid the work. + return; + default: + if (isFunctionLike(node)) { + if (node.name && node.name.kind === SyntaxKind.ComputedPropertyName) { + // Note that we will not include methods/accessors of a class because they would require + // first descending into the class. This is by design. + traverse(node.name.expression); + return; + } + } + else if (!isPartOfTypeNode(node)) { + // This is the general case, which should include mostly expressions and statements. + // Also includes NodeArrays. + forEachChild(node, traverse); + } + } + } +} + +/** + * Bypasses immutability and directly sets the `parent` property of each `Node` recursively. + * @param rootNode The root node from which to start the recursion. + * @param incremental When `true`, only recursively descends through nodes whose `parent` pointers are incorrect. + * This allows us to quickly bail out of setting `parent` for subtrees during incremental parsing. + * + * @internal + */ +export function setParentRecursive(rootNode: T, incremental: boolean): T; +/** @internal */ +export function setParentRecursive(rootNode: T | undefined, incremental: boolean): T | undefined; +/** @internal */ +export function setParentRecursive(rootNode: T | undefined, incremental: boolean): T | undefined { + if (!rootNode) return rootNode; + forEachChildRecursively(rootNode, isJSDocNode(rootNode) ? bindParentToChildIgnoringJSDoc : bindParentToChild); + return rootNode; + + function bindParentToChildIgnoringJSDoc(child: Node, parent: Node): void | "skip" { + if (incremental && child.parent === parent) { + return "skip"; + } + setParent(child, parent); + } + + function bindJSDoc(child: Node) { + if (hasJSDocNodes(child)) { + for (const doc of child.jsDoc!) { + bindParentToChildIgnoringJSDoc(doc, child); + forEachChildRecursively(doc, bindParentToChildIgnoringJSDoc); + } + } + } + + function bindParentToChild(child: Node, parent: Node) { + return bindParentToChildIgnoringJSDoc(child, parent) || bindJSDoc(child); + } +} + +/** + * Bypasses immutability and directly sets the `parent` property of a `Node`. + * + * @internal + */ +export function setParent(child: T, parent: T["parent"] | undefined): T; +/** @internal */ +export function setParent(child: T | undefined, parent: T["parent"] | undefined): T | undefined; +/** @internal */ +export function setParent(child: T | undefined, parent: T["parent"] | undefined): T | undefined { + if (child && parent) { + (child as Mutable).parent = parent; + } + return child; +} + +/** + * Bypasses immutability and directly sets the `parent` property of each `Node` in an array of nodes, if is not already set. + * + * @internal + */ +export function setEachParent(children: T, parent: T[number]["parent"]): T; +/** @internal */ +export function setEachParent(children: T | undefined, parent: T[number]["parent"]): T | undefined; +/** @internal */ +export function setEachParent(children: T | undefined, parent: T[number]["parent"]): T | undefined { + if (children) { + for (const child of children) { + setParent(child, parent); + } + } + return children; +} diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index e18ba9acd97f4..18269ede51b7d 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -6,10 +6,7 @@ import { timestamp, tryGetNativePerformanceHooks, } from "./performanceCore"; -import { - sys, - System, -} from "./sys"; +import { System } from "./types"; /** Performance measurements for the compiler. */ @@ -172,7 +169,7 @@ export function isEnabled() { * * @internal */ -export function enable(system: System = sys) { +export function enable(system: System) { if (!enabled) { enabled = true; perfHooks ||= tryGetNativePerformanceHooks(); diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index 5747a138dcfec..081bc134ac8a3 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -1,8 +1,4 @@ import { isNodeLikeSystem } from "./core"; -import { - Version, - VersionRange, -} from "./semver"; // The following definitions provide the minimum compatible support for the Web Performance User Timings API // between browsers and NodeJS: @@ -90,31 +86,6 @@ function tryGetNodePerformanceHooks(): PerformanceHooks | undefined { const { performance: nodePerformance, PerformanceObserver } = require("perf_hooks") as typeof import("perf_hooks"); if (hasRequiredAPI(nodePerformance as unknown as Performance, PerformanceObserver)) { performance = nodePerformance as unknown as Performance; - // There is a bug in Node's performance.measure prior to 12.16.3/13.13.0 that does not - // 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"); - if (range.test(version)) { - performance = { - get timeOrigin() { return nodePerformance.timeOrigin; }, - now() { return nodePerformance.now(); }, - mark(name) { return nodePerformance.mark(name); }, - measure(name, start = "nodeStart", end?) { - if (end === undefined) { - end = "__performance.measure-fix__"; - nodePerformance.mark(end); - } - nodePerformance.measure(name, start, end); - if (end === "__performance.measure-fix__") { - nodePerformance.clearMarks("__performance.measure-fix__"); - } - }, - clearMarks(name) { return nodePerformance.clearMarks(name); }, - clearMeasures(name) { return (nodePerformance as unknown as Performance).clearMeasures(name); }, - }; - } return { // By default, only write native events when generating a cpu profile or using the v8 profiler. shouldWriteNativeEvents: false, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 8e0c852b4b33a..685e76b46fc12 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -42,6 +42,7 @@ import { maybeBind, memoize, noop, + or, padLeft, removePrefix, removeSuffix, @@ -85,6 +86,7 @@ import { isImportEqualsDeclaration, isImportSpecifier, isImportTypeNode, + isJsxFragment, isModuleDeclaration, isObjectLiteralExpression, isStringLiteral, @@ -117,10 +119,11 @@ import { forEachChild, forEachChildRecursively, isDeclarationFileName, - isExternalModule, + isFileProbablyExternalModule, parseIsolatedEntityName, parseNodeFactory, } from "./parser"; +import { setParent, setParentRecursive } from "./parserUtilities"; import { combinePaths, comparePaths, @@ -146,6 +149,13 @@ import { toPath, } from "./path"; import * as performance from "./performance"; +import { + changesAffectingProgramStructure, + changesAffectModuleResolution, + hasChangesInResolutions, + setResolvedModule, + setResolvedTypeReferenceDirective, +} from "./programUtilities"; import { computeLineAndCharacterOfPosition, getLineAndCharacterOfPosition, @@ -156,9 +166,14 @@ import { tokenToString, } from "./scanner"; import { - sys, - System, -} from "./sys"; + createSymlinkCache, + SymlinkCache, +} from "./symlinkCache"; +import { sys } from "./sys"; +import { + containsIgnoredPath, + getNewLineCharacter, +} from "./sysUtilities"; import { tracing } from "./tracing"; import { getTransformers, @@ -213,9 +228,11 @@ import { ModifierLike, ModuleBlock, ModuleDeclaration, + ModuleDetectionKind, ModuleKind, ModuleResolutionHost, ModuleResolutionKind, + Mutable, Node, NodeArray, NodeFlags, @@ -232,6 +249,7 @@ import { PropertyDeclaration, ReferencedFile, ResolutionMode, + ResolutionNameAndModeGetter, ResolvedConfigFileName, ResolvedModuleFull, ResolvedModuleWithFailedLookupLocations, @@ -247,6 +265,8 @@ import { StringLiteralLike, StructureIsReused, SyntaxKind, + System, + TransformFlags, TsConfigSourceFile, TypeChecker, UnparsedSource, @@ -258,10 +278,7 @@ import { import { chainDiagnosticMessages, changeExtension, - changesAffectingProgramStructure, - changesAffectModuleResolution, compareDataObjects, - containsIgnoredPath, createCommentDirectivesMap, createCompilerDiagnostic, createCompilerDiagnosticFromMessageChain, @@ -270,13 +287,13 @@ import { createDiagnosticForRange, createFileDiagnostic, createFileDiagnosticFromMessageChain, - createSymlinkCache, extensionFromPath, externalHelpersModuleNameText, forEachEntry, forEachKey, getAllowJSCompilerOption, getEmitDeclarations, + getEmitModuleDetectionKind, getEmitModuleKind, getEmitModuleResolutionKind, getEmitScriptTarget, @@ -284,12 +301,10 @@ import { getExternalModuleName, getJSXImplicitImportBase, getJSXRuntimeImport, - getNewLineCharacter, getPropertyArrayElementValue, getPropertyAssignment, getResolvedModule, getResolveJsonModule, - getSetExternalModuleIndicator, getStrictOptionValue, getSupportedExtensions, getSupportedExtensionsWithJsonIfResolveJsonModule, @@ -297,7 +312,6 @@ import { getTsConfigObjectLiteralExpression, getTsConfigPropArray, getTsConfigPropArrayElementValue, - hasChangesInResolutions, hasJSFileExtension, hasJsonModuleEmitEnabled, hasSyntacticModifier, @@ -305,6 +319,7 @@ import { isAmbientModule, isAnyImportOrReExport, isCheckJsEnabledForFile, + isExternalModule, isImportCall, isIncrementalCompilation, isInJSFile, @@ -314,7 +329,6 @@ import { isSourceFileJS, moduleResolutionIsEqualTo, moduleResolutionSupportsPackageJsonExportsAndImports, - Mutable, optionsHaveChanges, outFile, packageIdToPackageName, @@ -322,14 +336,9 @@ import { projectReferenceIsEqualTo, removeFileExtension, resolutionExtensionIsTSOrJson, - setParent, - setParentRecursive, - setResolvedModule, - setResolvedTypeReferenceDirective, skipTypeChecking, sourceFileMayBeEmitted, supportedJSExtensionsFlat, - SymlinkCache, typeDirectiveIsEqualTo, walkUpParenthesizedExpressions, writeFileEnsuringDirectories, @@ -338,6 +347,7 @@ import { getDefaultLibFileName, hasJSDocNodes, isExternalModuleNameRelative, + isJsxOpeningLikeElement, isModifier, isStringLiteralLike, sortAndDeduplicateDiagnostics, @@ -955,12 +965,6 @@ const emptyResolution: ResolvedModuleWithFailedLookupLocations & ResolvedTypeRef resolvedTypeReferenceDirective: undefined, }; -/** @internal */ -export interface ResolutionNameAndModeGetter { - getName(entry: Entry): string; - getMode(entry: Entry, file: SourceFile): ResolutionMode; -} - /** @internal */ export interface ResolutionLoader { @@ -5038,3 +5042,59 @@ export function getModuleNameStringLiteralAt({ imports, moduleAugmentations }: S } Debug.fail("should never ask for module name at index higher than possible module name"); } + +/** @internal */ +export function getSetExternalModuleIndicator(options: CompilerOptions): (file: SourceFile) => void { + // TODO: Should this callback be cached? + switch (getEmitModuleDetectionKind(options)) { + case ModuleDetectionKind.Force: + // All non-declaration files are modules, declaration files still do the usual isFileProbablyExternalModule + return (file: SourceFile) => { + file.externalModuleIndicator = isFileProbablyExternalModule(file) || !file.isDeclarationFile || undefined; + }; + case ModuleDetectionKind.Legacy: + // Files are modules if they have imports, exports, or import.meta + return (file: SourceFile) => { + file.externalModuleIndicator = isFileProbablyExternalModule(file); + }; + case ModuleDetectionKind.Auto: + // If module is nodenext or node16, all esm format files are modules + // If jsx is react-jsx or react-jsxdev then jsx tags force module-ness + // otherwise, the presence of import or export statments (or import.meta) implies module-ness + const checks: ((file: SourceFile) => Node | true | undefined)[] = [isFileProbablyExternalModule]; + if (options.jsx === JsxEmit.ReactJSX || options.jsx === JsxEmit.ReactJSXDev) { + checks.push(isFileModuleFromUsingJSXTag); + } + checks.push(isFileForcedToBeModuleByFormat); + const combined = or(...checks); + const callback = (file: SourceFile) => void (file.externalModuleIndicator = combined(file)); + return callback; + } +} + +/** + * This is a somewhat unavoidable full tree walk to locate a JSX tag - `import.meta` requires the same, + * but we avoid that walk (or parts of it) if at all possible using the `PossiblyContainsImportMeta` node flag. + * Unfortunately, there's no `NodeFlag` space to do the same for JSX. + */ +function walkTreeForJSXTags(node: Node): Node | undefined { + if (!(node.transformFlags & TransformFlags.ContainsJsx)) return undefined; + return isJsxOpeningLikeElement(node) || isJsxFragment(node) ? node : forEachChild(node, walkTreeForJSXTags); +} + +function isFileModuleFromUsingJSXTag(file: SourceFile): Node | undefined { + // Excludes declaration files - they still require an explicit `export {}` or the like + // for back compat purposes. (not that declaration files should contain JSX tags!) + return !file.isDeclarationFile ? walkTreeForJSXTags(file) : undefined; +} + +/** + * Note that this requires file.impliedNodeFormat be set already; meaning it must be set very early on + * in SourceFile construction. + */ +function isFileForcedToBeModuleByFormat(file: SourceFile): true | undefined { + // Excludes declaration files - they still require an explicit `export {}` or the like + // for back compat purposes. The only non-declaration files _not_ forced to be a module are `.js` files + // that aren't esm-mode (meaning not in a `type: module` scope). + return (file.impliedNodeFormat === ModuleKind.ESNext || (fileExtensionIsOneOf(file.fileName, [Extension.Cjs, Extension.Cts, Extension.Mjs, Extension.Mts]))) && !file.isDeclarationFile ? true : undefined; +} diff --git a/src/compiler/programUtilities.ts b/src/compiler/programUtilities.ts new file mode 100644 index 0000000000000..6da50817b3d98 --- /dev/null +++ b/src/compiler/programUtilities.ts @@ -0,0 +1,96 @@ +import { + affectsDeclarationPathOptionDeclarations, + affectsEmitOptionDeclarations, + moduleResolutionOptionDeclarations, + optionsAffectingProgramStructure, + semanticDiagnosticsOptionDeclarations, +} from "./commandLineParser"; +import { Debug } from "./debug"; +import { + createModeAwareCache, + ModeAwareCache, +} from "./moduleNameResolver"; +import { + CompilerOptions, + ResolutionMode, + ResolutionNameAndModeGetter, + ResolvedModuleWithFailedLookupLocations, + ResolvedTypeReferenceDirectiveWithFailedLookupLocations, + SourceFile, +} from "./types"; +import { optionsHaveChanges } from "./utilities"; + +/** @internal */ +export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModuleWithFailedLookupLocations, mode: ResolutionMode): void { + if (!sourceFile.resolvedModules) { + sourceFile.resolvedModules = createModeAwareCache(); + } + sourceFile.resolvedModules.set(moduleNameText, mode, resolvedModule); +} + +/** @internal */ +export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective: ResolvedTypeReferenceDirectiveWithFailedLookupLocations, mode: ResolutionMode): void { + if (!sourceFile.resolvedTypeReferenceDirectiveNames) { + sourceFile.resolvedTypeReferenceDirectiveNames = createModeAwareCache(); + } + sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, mode, resolvedTypeReferenceDirective); +} + +/** @internal */ +export function hasChangesInResolutions( + names: readonly K[], + newSourceFile: SourceFile, + newResolutions: readonly V[], + oldResolutions: ModeAwareCache | undefined, + comparer: (oldResolution: V, newResolution: V) => boolean, + nameAndModeGetter: ResolutionNameAndModeGetter, +): boolean { + Debug.assert(names.length === newResolutions.length); + + for (let i = 0; i < names.length; i++) { + const newResolution = newResolutions[i]; + const entry = names[i]; + const name = nameAndModeGetter.getName(entry); + const mode = nameAndModeGetter.getMode(entry, newSourceFile); + const oldResolution = oldResolutions && oldResolutions.get(name, mode); + const changed = + oldResolution + ? !newResolution || !comparer(oldResolution, newResolution) + : newResolution; + if (changed) { + return true; + } + } + return false; +} + +/** @internal */ +export function changesAffectModuleResolution(oldOptions: CompilerOptions, newOptions: CompilerOptions): boolean { + return oldOptions.configFilePath !== newOptions.configFilePath || + optionsHaveModuleResolutionChanges(oldOptions, newOptions); +} + +/** @internal */ +export function optionsHaveModuleResolutionChanges(oldOptions: CompilerOptions, newOptions: CompilerOptions) { + return optionsHaveChanges(oldOptions, newOptions, moduleResolutionOptionDeclarations); +} + +/** @internal */ +export function changesAffectingProgramStructure(oldOptions: CompilerOptions, newOptions: CompilerOptions) { + return optionsHaveChanges(oldOptions, newOptions, optionsAffectingProgramStructure); +} + +/** @internal */ +export function compilerOptionsAffectSemanticDiagnostics(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean { + return optionsHaveChanges(oldOptions, newOptions, semanticDiagnosticsOptionDeclarations); +} + +/** @internal */ +export function compilerOptionsAffectEmit(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean { + return optionsHaveChanges(oldOptions, newOptions, affectsEmitOptionDeclarations); +} + +/** @internal */ +export function compilerOptionsAffectDeclarationPath(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean { + return optionsHaveChanges(oldOptions, newOptions, affectsDeclarationPathOptionDeclarations); +} diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index 75ce3841c4a66..15f0b05a41763 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -46,17 +46,15 @@ import { createTypeReferenceResolutionLoader, inferredTypesContainingFile, moduleResolutionNameAndModeGetter, ResolutionLoader, } from "./program"; -import { - DirectoryWatcherCallback, - FileWatcher, - FileWatcherCallback, - ignoredPaths, -} from "./sys"; +import { ignoredPaths } from "./sysUtilities"; import { CharacterCodes, CompilerOptions, + DirectoryWatcherCallback, Extension, FileReference, + FileWatcher, + FileWatcherCallback, HasInvalidatedResolutions, MinimalResolutionCacheHost, PackageId, diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index bb35ca59c214c..4ed0aca73e539 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -9,9 +9,11 @@ import { isWhiteSpaceSingleLine, trimStringStart, } from "./core"; -// import { Debug } from "./debug"; +import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { + parsePseudoBigInt, + positionIsSynthesized, textToKeyword, textToToken, } from "./scannerUtilities"; @@ -32,10 +34,6 @@ import { SyntaxKind, TokenFlags, } from "./types"; -import { - parsePseudoBigInt, - positionIsSynthesized, -} from "./utilities"; export type ErrorCallback = (message: DiagnosticMessage, length: number) => void; @@ -291,8 +289,7 @@ export function computePositionOfLineAndCharacter(lineStarts: readonly number[], 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"}`); - throw new Error(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`); + Debug.fail(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`); } } @@ -304,16 +301,10 @@ export function computePositionOfLineAndCharacter(lineStarts: readonly number[], return res > lineStarts[line + 1] ? lineStarts[line + 1] : typeof debugText === "string" && res > debugText.length ? debugText.length : res; } if (line < lineStarts.length - 1) { - if (!(res < lineStarts[line + 1])) { - throw new Error(); - } - // Debug.assert(res < lineStarts[line + 1]); + Debug.assert(res < lineStarts[line + 1]); } else if (debugText !== undefined) { - if (!(res <= debugText.length)) { - throw new Error(); - } - // Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline + Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline } return res; } @@ -347,10 +338,7 @@ export function computeLineOfPosition(lineStarts: readonly number[], position: n // 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"); - if (!(lineNumber !== -1)) { - throw new Error("position cannot precede the beginning of the file"); - } + Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file"); } return lineNumber; } @@ -516,10 +504,7 @@ export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boole const mergeConflictMarkerLength = "<<<<<<<".length; function isConflictMarkerTrivia(text: string, pos: number) { - // Debug.assert(pos >= 0); - if (!(pos >= 0)) { - throw new Error(); - } + Debug.assert(pos >= 0); // Conflict markers must be at the start of a line. if (pos === 0 || isLineBreak(text.charCodeAt(pos - 1))) { @@ -554,10 +539,7 @@ function scanConflictMarkerTrivia(text: string, pos: number, error?: (diag: Diag } } else { - // Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals); - if (!(ch === CharacterCodes.bar || ch === CharacterCodes.equals)) { - throw new Error(); - } + Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals); // Consume everything from the start of a ||||||| or ======= marker to the start // of the next ======= or >>>>>>> marker. while (pos < len) { @@ -578,10 +560,7 @@ const shebangTriviaRegex = /^#!.*/; /** @internal */ export function isShebangTrivia(text: string, pos: number) { // Shebangs check must only be done at the start of the file - // Debug.assert(pos === 0); - if (!(pos === 0)) { - throw new Error(); - } + Debug.assert(pos === 0); return shebangTriviaRegex.test(text); } @@ -871,14 +850,14 @@ export function createScanner(languageVersion: ScriptTarget, scanRange, }; - // if (Debug.isDebugging) { - // Object.defineProperty(scanner, "__debugShowCurrentPositionInText", { - // get: () => { - // const text = scanner.getText(); - // return text.slice(0, scanner.getStartPos()) + "║" + text.slice(scanner.getStartPos()); - // }, - // }); - // } + if (Debug.isDebugging) { + Object.defineProperty(scanner, "__debugShowCurrentPositionInText", { + get: () => { + const text = scanner.getText(); + return text.slice(0, scanner.getStartPos()) + "║" + text.slice(scanner.getStartPos()); + }, + }); + } return scanner; @@ -1174,10 +1153,7 @@ export function createScanner(languageVersion: ScriptTarget, pos++; } - // Debug.assert(resultingToken !== undefined); - if (!(resultingToken !== undefined)) { - throw new Error(); - } + Debug.assert(resultingToken !== undefined); tokenValue = contents; return resultingToken; @@ -1977,10 +1953,7 @@ export function createScanner(languageVersion: ScriptTarget, } function reScanInvalidIdentifier(): SyntaxKind { - // Debug.assert(token === SyntaxKind.Unknown, "'reScanInvalidIdentifier' should only be called when the current token is 'SyntaxKind.Unknown'."); - if (!(token === SyntaxKind.Unknown)) { - throw new Error("'reScanInvalidIdentifier' should only be called when the current token is 'SyntaxKind.Unknown'."); - } + Debug.assert(token === SyntaxKind.Unknown, "'reScanInvalidIdentifier' should only be called when the current token is 'SyntaxKind.Unknown'."); pos = tokenPos = startPos; tokenFlags = 0; const ch = codePointAt(text, pos); @@ -2029,10 +2002,7 @@ export function createScanner(languageVersion: ScriptTarget, } function reScanAsteriskEqualsToken(): SyntaxKind { - // Debug.assert(token === SyntaxKind.AsteriskEqualsToken, "'reScanAsteriskEqualsToken' should only be called on a '*='"); - if (!(token === SyntaxKind.AsteriskEqualsToken)) { - throw new Error("'reScanAsteriskEqualsToken' should only be called on a '*='"); - } + Debug.assert(token === SyntaxKind.AsteriskEqualsToken, "'reScanAsteriskEqualsToken' should only be called on a '*='"); pos = tokenPos + 1; return token = SyntaxKind.EqualsToken; } @@ -2132,10 +2102,7 @@ export function createScanner(languageVersion: ScriptTarget, * 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 '}'"); - if (!(token === SyntaxKind.CloseBraceToken)) { - throw new Error("'reScanTemplateToken' should only be called on a '}'"); - } + Debug.assert(token === SyntaxKind.CloseBraceToken, "'reScanTemplateToken' should only be called on a '}'"); pos = tokenPos; return token = scanTemplateAndSetTokenValue(isTaggedTemplate); } @@ -2167,10 +2134,7 @@ export function createScanner(languageVersion: ScriptTarget, } function reScanQuestionToken(): SyntaxKind { - // Debug.assert(token === SyntaxKind.QuestionQuestionToken, "'reScanQuestionToken' should only be called on a '??'"); - if (!(token === SyntaxKind.QuestionQuestionToken)) { - throw new Error("'reScanQuestionToken' should only be called on a '??'"); - } + Debug.assert(token === SyntaxKind.QuestionQuestionToken, "'reScanQuestionToken' should only be called on a '??'"); pos = tokenPos + 1; return token = SyntaxKind.QuestionToken; } @@ -2475,10 +2439,7 @@ export function createScanner(languageVersion: ScriptTarget, } function setTextPos(textPos: number) { - // Debug.assert(textPos >= 0); - if (!(textPos >= 0)) { - throw new Error(); - } + Debug.assert(textPos >= 0); pos = textPos; startPos = textPos; tokenPos = textPos; @@ -2523,11 +2484,7 @@ function charSize(ch: number) { // Derived from the 10.1.1 UTF16Encoding of the ES6 Spec. function utf16EncodeAsStringFallback(codePoint: number) { - // Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF); - if (!(0x0 <= codePoint && codePoint <= 0x10FFFF)) { - throw new Error(); - } - + Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF); if (codePoint <= 65535) { return String.fromCharCode(codePoint); } diff --git a/src/compiler/scannerUtilities.ts b/src/compiler/scannerUtilities.ts index 96e44238970a9..326109134f515 100644 --- a/src/compiler/scannerUtilities.ts +++ b/src/compiler/scannerUtilities.ts @@ -1,10 +1,12 @@ import { getEntries } from "./core"; import { MapLike } from "./corePublic"; import { + CharacterCodes, KeywordSyntaxKind, SyntaxKind, } from "./types"; +/** @internal */ export const textToKeywordObj: MapLike = { abstract: SyntaxKind.AbstractKeyword, accessor: SyntaxKind.AccessorKeyword, @@ -90,8 +92,10 @@ export const textToKeywordObj: MapLike = { of: SyntaxKind.OfKeyword, }; +/** @internal */ export const textToKeyword = new Map(getEntries(textToKeywordObj)); +/** @internal */ export const textToToken = new Map(getEntries({ ...textToKeywordObj, "{": SyntaxKind.OpenBraceToken, @@ -156,3 +160,83 @@ export const textToToken = new Map(getEntries({ "#": SyntaxKind.HashToken, "`": SyntaxKind.BacktickToken, })); + +/** @internal */ +export function positionIsSynthesized(pos: number): boolean { + // This is a fast way of testing the following conditions: + // pos === undefined || pos === null || isNaN(pos) || pos < 0; + return !(pos >= 0); +} + +/** + * Converts a bigint literal string, e.g. `0x1234n`, + * to its decimal string representation, e.g. `4660`. + * + * @internal + */ +export function parsePseudoBigInt(stringValue: string): string { + let log2Base: number; + switch (stringValue.charCodeAt(1)) { // "x" in "0x123" + case CharacterCodes.b: + case CharacterCodes.B: // 0b or 0B + log2Base = 1; + break; + case CharacterCodes.o: + case CharacterCodes.O: // 0o or 0O + log2Base = 3; + break; + case CharacterCodes.x: + case CharacterCodes.X: // 0x or 0X + log2Base = 4; + break; + default: // already in decimal; omit trailing "n" + const nIndex = stringValue.length - 1; + // Skip leading 0s + let nonZeroStart = 0; + while (stringValue.charCodeAt(nonZeroStart) === CharacterCodes._0) { + nonZeroStart++; + } + return stringValue.slice(nonZeroStart, nIndex) || "0"; + } + + // Omit leading "0b", "0o", or "0x", and trailing "n" + const startIndex = 2, endIndex = stringValue.length - 1; + const bitsNeeded = (endIndex - startIndex) * log2Base; + // Stores the value specified by the string as a LE array of 16-bit integers + // using Uint16 instead of Uint32 so combining steps can use bitwise operators + const segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0)); + // Add the digits, one at a time + for (let i = endIndex - 1, bitOffset = 0; i >= startIndex; i--, bitOffset += log2Base) { + const segment = bitOffset >>> 4; + const digitChar = stringValue.charCodeAt(i); + // Find character range: 0-9 < A-F < a-f + const digit = digitChar <= CharacterCodes._9 + ? digitChar - CharacterCodes._0 + : 10 + digitChar - + (digitChar <= CharacterCodes.F ? CharacterCodes.A : CharacterCodes.a); + const shiftedDigit = digit << (bitOffset & 15); + segments[segment] |= shiftedDigit; + const residual = shiftedDigit >>> 16; + if (residual) segments[segment + 1] |= residual; // overflows segment + } + // Repeatedly divide segments by 10 and add remainder to base10Value + let base10Value = ""; + let firstNonzeroSegment = segments.length - 1; + let segmentsRemaining = true; + while (segmentsRemaining) { + let mod10 = 0; + segmentsRemaining = false; + for (let segment = firstNonzeroSegment; segment >= 0; segment--) { + const newSegment = mod10 << 16 | segments[segment]; + const segmentValue = (newSegment / 10) | 0; + segments[segment] = segmentValue; + mod10 = newSegment - segmentValue * 10; + if (segmentValue && !segmentsRemaining) { + firstNonzeroSegment = segment; + segmentsRemaining = true; + } + } + base10Value = mod10 + base10Value; + } + return base10Value; +} diff --git a/src/compiler/semver.ts b/src/compiler/semver.ts index 52f0e7ca3b0c7..a5dfc31a509be 100644 --- a/src/compiler/semver.ts +++ b/src/compiler/semver.ts @@ -2,14 +2,14 @@ import { compareStringsCaseSensitive, compareValues, emptyArray, + every, isArray, map, some, trimString, } from "./core"; import { Comparison } from "./corePublic"; - -// import { Debug } from "./debug"; +import { Debug } from "./debug"; // https://semver.org/#spec-item-2 // > A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative @@ -26,14 +26,14 @@ const versionRegExp = /^(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\-([a-z // > alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers // > MUST NOT include leading zeroes. const prereleaseRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)(?:\.(?:0|[1-9]\d*|[a-z-][a-z0-9-]*))*$/i; -// const prereleasePartRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)$/i; +const prereleasePartRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)$/i; // https://semver.org/#spec-item-10 // > Build metadata MAY be denoted by appending a plus sign and a series of dot separated // > identifiers immediately following the patch or pre-release version. Identifiers MUST // > comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. const buildRegExp = /^[a-z0-9-]+(?:\.[a-z0-9-]+)*$/i; -// const buildPartRegExp = /^[a-z0-9-]+$/i; +const buildPartRegExp = /^[a-z0-9-]+$/i; // https://semver.org/#spec-item-9 // > Numeric identifiers MUST NOT include leading zeroes. @@ -57,23 +57,19 @@ export class Version { constructor(major: number, minor?: number, patch?: number, prerelease?: string | readonly string[], build?: string | readonly string[]); constructor(major: number | string, minor = 0, patch = 0, prerelease: string | readonly string[] = "", build: string | readonly string[] = "") { if (typeof major === "string") { - // const result = Debug.checkDefined(tryParseComponents(major), "Invalid version"); - const result = tryParseComponents(major); - if (result === undefined) { - throw new Error("Invalid version"); - } + const result = 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(major >= 0, "Invalid argument: major"); + Debug.assert(minor >= 0, "Invalid argument: minor"); + Debug.assert(patch >= 0, "Invalid argument: patch"); const prereleaseArray = prerelease ? isArray(prerelease) ? prerelease : prerelease.split(".") : emptyArray; const buildArray = build ? isArray(build) ? build : build.split(".") : emptyArray; - // Debug.assert(every(prereleaseArray, s => prereleasePartRegExp.test(s)), "Invalid argument: prerelease"); - // Debug.assert(every(buildArray, s => buildPartRegExp.test(s)), "Invalid argument: build"); + Debug.assert(every(prereleaseArray, s => prereleasePartRegExp.test(s)), "Invalid argument: prerelease"); + Debug.assert(every(buildArray, s => buildPartRegExp.test(s)), "Invalid argument: build"); this.major = major; this.minor = minor; @@ -116,9 +112,7 @@ export class Version { 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: - throw new Error(field); + default: return Debug.assertNever(field); } } @@ -423,9 +417,7 @@ function testComparator(version: Version, operator: Comparator["operator"], oper case ">": return cmp > 0; case ">=": return cmp >= 0; case "=": return cmp === 0; - // default: return Debug.assertNever(operator); - default: - throw new Error(operator); + default: return Debug.assertNever(operator); } } diff --git a/src/compiler/symlinkCache.ts b/src/compiler/symlinkCache.ts new file mode 100644 index 0000000000000..188e1195da0e3 --- /dev/null +++ b/src/compiler/symlinkCache.ts @@ -0,0 +1,128 @@ +import { + createMultiMap, + emptyArray, + GetCanonicalFileName, + MultiMap, + startsWith, +} from "./core"; +import { Debug } from "./debug"; +import { ModeAwareCache } from "./moduleNameResolver"; +import { + ensureTrailingDirectorySeparator, + getNormalizedAbsolutePath, + getPathComponents, + getPathFromPathComponents, + toPath, +} from "./path"; +import { containsIgnoredPath } from "./sysUtilities"; +import { + Path, + ResolvedModuleFull, + ResolvedTypeReferenceDirective, + ResolvedTypeReferenceDirectiveWithFailedLookupLocations, + SourceFile, +} from "./types"; + +/** @internal */ +export interface SymlinkedDirectory { + /** Matches the casing returned by `realpath`. Used to compute the `realpath` of children. */ + real: string; + /** toPath(real). Stored to avoid repeated recomputation. */ + realPath: Path; +} + +/** @internal */ +export interface SymlinkCache { + /** Gets a map from symlink to realpath. Keys have trailing directory separators. */ + getSymlinkedDirectories(): ReadonlyMap | undefined; + /** Gets a map from realpath to symlinks. Keys have trailing directory separators. */ + getSymlinkedDirectoriesByRealpath(): MultiMap | undefined; + /** Gets a map from symlink to realpath */ + getSymlinkedFiles(): ReadonlyMap | undefined; + setSymlinkedDirectory(symlink: string, real: SymlinkedDirectory | false): void; + setSymlinkedFile(symlinkPath: Path, real: string): void; + /** + * @internal + * Uses resolvedTypeReferenceDirectives from program instead of from files, since files + * don't include automatic type reference directives. Must be called only when + * `hasProcessedResolutions` returns false (once per cache instance). + */ + setSymlinksFromResolutions(files: readonly SourceFile[], typeReferenceDirectives: ModeAwareCache): void; + /** + * @internal + * Whether `setSymlinksFromResolutions` has already been called. + */ + hasProcessedResolutions(): boolean; +} + +/** @internal */ +export function createSymlinkCache(cwd: string, getCanonicalFileName: GetCanonicalFileName): SymlinkCache { + let symlinkedDirectories: Map | undefined; + let symlinkedDirectoriesByRealpath: MultiMap | undefined; + let symlinkedFiles: Map | undefined; + let hasProcessedResolutions = false; + return { + getSymlinkedFiles: () => symlinkedFiles, + getSymlinkedDirectories: () => symlinkedDirectories, + getSymlinkedDirectoriesByRealpath: () => symlinkedDirectoriesByRealpath, + setSymlinkedFile: (path, real) => (symlinkedFiles || (symlinkedFiles = new Map())).set(path, real), + setSymlinkedDirectory: (symlink, real) => { + // Large, interconnected dependency graphs in pnpm will have a huge number of symlinks + // where both the realpath and the symlink path are inside node_modules/.pnpm. Since + // this path is never a candidate for a module specifier, we can ignore it entirely. + let symlinkPath = toPath(symlink, cwd, getCanonicalFileName); + if (!containsIgnoredPath(symlinkPath)) { + symlinkPath = ensureTrailingDirectorySeparator(symlinkPath); + if (real !== false && !symlinkedDirectories?.has(symlinkPath)) { + (symlinkedDirectoriesByRealpath ||= createMultiMap()).add(ensureTrailingDirectorySeparator(real.realPath), symlink); + } + (symlinkedDirectories || (symlinkedDirectories = new Map())).set(symlinkPath, real); + } + }, + setSymlinksFromResolutions(files, typeReferenceDirectives) { + Debug.assert(!hasProcessedResolutions); + hasProcessedResolutions = true; + for (const file of files) { + file.resolvedModules?.forEach(resolution => processResolution(this, resolution.resolvedModule)); + file.resolvedTypeReferenceDirectiveNames?.forEach(resolution => processResolution(this, resolution.resolvedTypeReferenceDirective)); + } + typeReferenceDirectives.forEach(resolution => processResolution(this, resolution.resolvedTypeReferenceDirective)); + }, + hasProcessedResolutions: () => hasProcessedResolutions, + }; + + function processResolution(cache: SymlinkCache, resolution: ResolvedModuleFull | ResolvedTypeReferenceDirective | undefined) { + if (!resolution || !resolution.originalPath || !resolution.resolvedFileName) return; + const { resolvedFileName, originalPath } = resolution; + cache.setSymlinkedFile(toPath(originalPath, cwd, getCanonicalFileName), resolvedFileName); + const [commonResolved, commonOriginal] = guessDirectorySymlink(resolvedFileName, originalPath, cwd, getCanonicalFileName) || emptyArray; + if (commonResolved && commonOriginal) { + cache.setSymlinkedDirectory( + commonOriginal, + { real: commonResolved, realPath: toPath(commonResolved, cwd, getCanonicalFileName) }); + } + } +} + +function guessDirectorySymlink(a: string, b: string, cwd: string, getCanonicalFileName: GetCanonicalFileName): [string, string] | undefined { + const aParts = getPathComponents(getNormalizedAbsolutePath(a, cwd)); + const bParts = getPathComponents(getNormalizedAbsolutePath(b, cwd)); + let isDirectory = false; + while ( + aParts.length >= 2 && bParts.length >= 2 && + !isNodeModulesOrScopedPackageDirectory(aParts[aParts.length - 2], getCanonicalFileName) && + !isNodeModulesOrScopedPackageDirectory(bParts[bParts.length - 2], getCanonicalFileName) && + getCanonicalFileName(aParts[aParts.length - 1]) === getCanonicalFileName(bParts[bParts.length - 1]) + ) { + aParts.pop(); + bParts.pop(); + isDirectory = true; + } + return isDirectory ? [getPathFromPathComponents(aParts), getPathFromPathComponents(bParts)] : undefined; +} + +// KLUDGE: Don't assume one 'node_modules' links to another. More likely a single directory inside the node_modules is the symlink. +// ALso, don't assume that an `@foo` directory is linked. More likely the contents of that are linked. +function isNodeModulesOrScopedPackageDirectory(s: string | undefined, getCanonicalFileName: GetCanonicalFileName): boolean { + return s !== undefined && (getCanonicalFileName(s) === "node_modules" || startsWith(s, "@")); +} diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index c093a37fd9115..dca9e89fb1855 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -1,6 +1,5 @@ import { matchesExclude } from "./commandLineParser"; import { - AssertionLevel, contains, createGetCanonicalFileName, createMultiMap, @@ -21,7 +20,12 @@ import { unorderedRemoveItem, } from "./core"; import { Comparison } from "./corePublic"; -import { Debug } from "./debug"; +import { AssertionLevel, Debug } from "./debug"; +import { + emptyFileSystemEntries, + FileSystemEntries, + matchFiles, +} from "./fileMatcher"; import { resolveJSModule } from "./moduleNameResolver"; import { combinePaths, @@ -36,19 +40,21 @@ import { } from "./path"; import { perfLogger } from "./perfLogger"; import { timestamp } from "./performanceCore"; +import { ignoredPaths } from "./sysUtilities"; import { + DirectoryWatcherCallback, + FileWatcher, + FileWatcherCallback, + FileWatcherEventKind, Path, PollingWatchKind, - RequireResult, + System, WatchDirectoryKind, WatchFileKind, WatchOptions, } from "./types"; import { closeFileWatcher, - emptyFileSystemEntries, - FileSystemEntries, - matchFiles, writeFileEnsuringDirectories, } from "./utilities"; import { @@ -86,14 +92,6 @@ export function setStackTraceLimit() { } } -export enum FileWatcherEventKind { - Created, - Changed, - Deleted -} - -export type FileWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind, modifiedTime?: Date) => void; -export type DirectoryWatcherCallback = (fileName: string) => void; interface WatchedFile { readonly fileName: string; readonly callback: FileWatcherCallback; @@ -542,9 +540,6 @@ export function getFileWatcherEventKind(oldTime: number, newTime: number) { : FileWatcherEventKind.Changed; } -/** @internal */ -export const ignoredPaths = ["/node_modules/.", "/.git", "/.#"]; - let curSysLog: (s: string) => void = noop; // eslint-disable-line prefer-const /** @internal */ @@ -1304,150 +1299,6 @@ export function patchWriteFileEnsuringDirectory(sys: System) { path => sys.directoryExists(path)); } -/** @internal */ -export type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex"; - -/** @internal */ -export interface NodeBuffer extends Uint8Array { - constructor: any; - write(str: string, encoding?: BufferEncoding): number; - 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[] }; - equals(otherBuffer: Uint8Array): boolean; - 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; - writeUIntLE(value: number, offset: number, byteLength: number): number; - writeUIntBE(value: number, offset: number, byteLength: number): number; - writeIntLE(value: number, offset: number, byteLength: number): number; - writeIntBE(value: number, offset: number, byteLength: number): number; - readUIntLE(offset: number, byteLength: number): number; - readUIntBE(offset: number, byteLength: number): number; - readIntLE(offset: number, byteLength: number): number; - readIntBE(offset: number, byteLength: number): number; - readUInt8(offset: number): number; - readUInt16LE(offset: number): number; - readUInt16BE(offset: number): number; - readUInt32LE(offset: number): number; - readUInt32BE(offset: number): number; - readInt8(offset: number): number; - readInt16LE(offset: number): number; - readInt16BE(offset: number): number; - readInt32LE(offset: number): number; - readInt32BE(offset: number): number; - readFloatLE(offset: number): number; - readFloatBE(offset: number): number; - readDoubleLE(offset: number): number; - readDoubleBE(offset: number): number; - reverse(): this; - swap16(): Buffer; - swap32(): Buffer; - swap64(): Buffer; - writeUInt8(value: number, offset: number): number; - writeUInt16LE(value: number, offset: number): number; - writeUInt16BE(value: number, offset: number): number; - writeUInt32LE(value: number, offset: number): number; - writeUInt32BE(value: number, offset: number): number; - writeInt8(value: number, offset: number): number; - writeInt16LE(value: number, offset: number): number; - writeInt16BE(value: number, offset: number): number; - writeInt32LE(value: number, offset: number): number; - writeInt32BE(value: number, offset: number): number; - writeFloatLE(value: number, offset: number): number; - writeFloatBE(value: number, offset: number): number; - writeDoubleLE(value: number, offset: number): number; - writeDoubleBE(value: number, offset: number): number; - readBigUInt64BE?(offset?: number): bigint; - readBigUInt64LE?(offset?: number): bigint; - readBigInt64BE?(offset?: number): bigint; - readBigInt64LE?(offset?: number): bigint; - writeBigInt64BE?(value: bigint, offset?: number): number; - writeBigInt64LE?(value: bigint, offset?: number): number; - writeBigUInt64BE?(value: bigint, offset?: number): number; - writeBigUInt64LE?(value: bigint, offset?: number): number; - 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]>; - includes(value: string | number | Buffer, byteOffset?: number, encoding?: BufferEncoding): boolean; - keys(): IterableIterator; - values(): IterableIterator; -} - -/** @internal */ -export interface Buffer extends NodeBuffer { } - -// TODO: GH#18217 Methods on System are often used as if they are certainly defined -export interface System { - args: string[]; - newLine: string; - useCaseSensitiveFileNames: boolean; - write(s: string): void; - writeOutputIsTTY?(): boolean; - getWidthOfTerminal?(): number; - readFile(path: string, encoding?: string): string | undefined; - getFileSize?(path: string): number; - writeFile(path: string, data: string, writeByteOrderMark?: boolean): void; - - /** - * @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; - resolvePath(path: string): string; - fileExists(path: string): boolean; - directoryExists(path: string): boolean; - createDirectory(path: string): void; - getExecutingFilePath(): string; - getCurrentDirectory(): string; - getDirectories(path: string): string[]; - readDirectory(path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number): string[]; - getModifiedTime?(path: string): Date | undefined; - setModifiedTime?(path: string, time: Date): void; - deleteFile?(path: string): void; - /** - * A good implementation is node.js' `crypto.createHash`. (https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm) - */ - createHash?(data: string): string; - /** This must be cryptographically secure. Only implement this method using `crypto.createHash("sha256")`. */ - createSHA256Hash?(data: string): string; - getMemoryUsage?(): number; - exit(exitCode?: number): void; - /** @internal */ enableCPUProfiler?(path: string, continuation: () => void): boolean; - /** @internal */ disableCPUProfiler?(continuation: () => void): boolean; - /** @internal */ cpuProfilingEnabled?(): boolean; - realpath?(path: string): string; - /** @internal */ getEnvironmentVariable(name: string): string; - /** @internal */ tryEnableSourceMapsForHost?(): void; - /** @internal */ debugMode?: boolean; - setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; - clearTimeout?(timeoutId: any): void; - clearScreen?(): void; - /** @internal */ setBlocking?(): void; - base64decode?(input: string): string; - base64encode?(input: string): string; - /** @internal */ bufferFrom?(input: string, encoding?: string): Buffer; - /** @internal */ require?(baseDir: string, moduleName: string): RequireResult; - - // For testing - /** @internal */ now?(): Date; - /** @internal */ storeFilesChangingSignatureDuringEmit?: boolean; -} - -export interface FileWatcher { - close(): void; -} - interface DirectoryWatcher extends FileWatcher { referenceCount: number; } diff --git a/src/compiler/sysUtilities.ts b/src/compiler/sysUtilities.ts new file mode 100644 index 0000000000000..e999a7622aae1 --- /dev/null +++ b/src/compiler/sysUtilities.ts @@ -0,0 +1,25 @@ +import { some, stringContains } from "./core"; +import { sys } from "./sys"; +import { CompilerOptions, NewLineKind, PrinterOptions } from "./types"; + +/** @internal */ +export const ignoredPaths = ["/node_modules/.", "/.git", "/.#"]; + +/** @internal */ +export function containsIgnoredPath(path: string) { + return some(ignoredPaths, p => stringContains(path, p)); +} + +const carriageReturnLineFeed = "\r\n"; +const lineFeed = "\n"; + +/** @internal */ +export function getNewLineCharacter(options: CompilerOptions | PrinterOptions, getNewLine?: () => string): string { + switch (options.newLine) { + case NewLineKind.CarriageReturnLineFeed: + return carriageReturnLineFeed; + case NewLineKind.LineFeed: + return lineFeed; + } + return getNewLine ? getNewLine() : sys ? sys.newLine : carriageReturnLineFeed; +} diff --git a/src/compiler/tracing.ts b/src/compiler/tracing.ts index f598257c858f2..72db5262c2cb7 100644 --- a/src/compiler/tracing.ts +++ b/src/compiler/tracing.ts @@ -1,6 +1,6 @@ +import * as performance from "./performance"; import { Debug } from "./debug"; import { combinePaths } from "./path"; -import * as performance from "./performance"; import { timestamp } from "./performanceCore"; import { getLineAndCharacterOfPosition } from "./scanner"; import { diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index e2513cd010b4b..75976d1737f63 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -72,10 +72,8 @@ import { } from "../factory/utilitiesPublic"; import { pathContainsNodeModules } from "../moduleNameResolver"; import { getModuleSpecifier } from "../moduleSpecifiers"; -import { - isExternalModule, - parseNodeFactory, -} from "../parser"; +import { parseNodeFactory } from "../parser"; +import { setParent } from "../parserUtilities"; import { getDirectoryPath, getRelativePathToDirectoryOrUrl, @@ -195,6 +193,7 @@ import { hasSyntacticModifier, isAnyImportSyntax, isEntityNameExpression, + isExternalModule, isExternalModuleAugmentation, isExternalOrCommonJsModule, isGlobalScopeAugmentation, @@ -205,7 +204,6 @@ import { isSourceFileJS, isSourceFileNotJson, isStringANonContextualKeyword, - setParent, } from "../utilities"; import { getNameOfDeclaration, diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 5c2ea6b73cd87..50ca3875e0001 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -72,6 +72,7 @@ import { setOriginalNode, setTextRange, } from "../factory/utilitiesPublic"; +import { setParent } from "../parserUtilities"; import { skipTrivia } from "../scanner"; import { __String, @@ -183,7 +184,6 @@ import { moveRangePos, nodeIsSynthesized, rangeEndIsOnSameLineAsRangeStart, - setParent, setTextRangeEnd, setTextRangePos, skipOuterExpressions, diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 8b04faabe2c8a..26a5f5fcdabdc 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -86,7 +86,6 @@ import { getFunctionFlags, getInitializedVariables, insertStatementsAfterStandardPrologue, - isEffectiveStrictModeSourceFile, isNodeWithPossibleHoistedDeclaration, isSuperProperty, } from "../utilities"; @@ -111,7 +110,7 @@ import { visitNodes, visitParameterList, } from "../visitorPublic"; -import { chainBundle } from "./utilities"; +import { chainBundle, isEffectiveStrictModeSourceFile } from "./utilities"; type SuperContainer = ClassDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration; diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index 8814e08d42086..cdfc5cef7d848 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -96,7 +96,6 @@ import { hasSyntacticModifier, insertStatementsAfterStandardPrologue, isDestructuringAssignment, - isEffectiveStrictModeSourceFile, isSuperProperty, skipParentheses, unwrapInnermostStatementOfLabel, @@ -132,7 +131,7 @@ import { ProcessLevel, processTaggedTemplateExpression, } from "./taggedTemplate"; -import { chainBundle } from "./utilities"; +import { chainBundle, isEffectiveStrictModeSourceFile } from "./utilities"; const enum ESNextSubstitutionFlags { /** Enables substitutions for async methods with `super` calls. */ diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 38305076d0e0d..ca6334f25b29d 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -26,6 +26,7 @@ import { setOriginalNode, setTextRange, } from "../factory/utilitiesPublic"; +import { setParent } from "../parserUtilities"; import { AccessorDeclaration, ArrayLiteralExpression, @@ -54,6 +55,7 @@ import { LabeledStatement, LeftHandSideExpression, LiteralExpression, + Mutable, NewExpression, Node, NodeArray, @@ -88,8 +90,6 @@ import { insertStatementsAfterStandardPrologue, isImportCall, isLogicalOperator, - Mutable, - setParent, } from "../utilities"; import { getOriginalNode, diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 7c148d389d075..c79959e42f7ec 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -32,7 +32,7 @@ import { startOnNewLine, } from "../factory/utilities"; import { setTextRange } from "../factory/utilitiesPublic"; -import { isExternalModule } from "../parser"; +import { setParentRecursive } from "../parserUtilities"; import { getLineAndCharacterOfPosition, utf16EncodeAsString, @@ -76,10 +76,10 @@ import { getJSXRuntimeImport, getSemanticJsxChildren, insertStatementAfterCustomPrologue, + isExternalModule, isExternalOrCommonJsModule, isIntrinsicJsxName, isStringDoubleQuoted, - setParentRecursive, } from "../utilities"; import { getOriginalNode, diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index 3bdb66b37b6ae..3cb020f469d4a 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -19,7 +19,6 @@ import { setOriginalNode, setTextRange, } from "../../factory/utilitiesPublic"; -import { isExternalModule } from "../../parser"; import { Bundle, EmitFlags, @@ -50,6 +49,7 @@ import { hasSyntacticModifier, insertStatementsAfterCustomPrologue, isExportNamespaceAsDefaultDeclaration, + isExternalModule, isExternalModuleImportEqualsDeclaration, } from "../../utilities"; import { diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 9d1768afd8494..e98f713a86744 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -48,7 +48,6 @@ import { setOriginalNode, setTextRange, } from "../../factory/utilitiesPublic"; -import { isExternalModule } from "../../parser"; import { ArrowFunction, BinaryExpression, @@ -118,6 +117,7 @@ import { isDestructuringAssignment, isEffectiveExternalModule, isExportNamespaceAsDefaultDeclaration, + isExternalModule, isExternalModuleImportEqualsDeclaration, isImportCall, isJsonSourceFile, diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 60ce4be2130e7..cf448899d96b0 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -41,7 +41,6 @@ import { tryGetModuleNameFromFile, } from "../../factory/utilities"; import { setTextRange } from "../../factory/utilitiesPublic"; -import { isExternalModule } from "../../parser"; import { BinaryExpression, BindingElement, @@ -112,6 +111,7 @@ import { isDeclarationNameOfEnumOrNamespace, isDestructuringAssignment, isEffectiveExternalModule, + isExternalModule, isExternalModuleImportEqualsDeclaration, isImportCall, isImportMeta, diff --git a/src/compiler/transformers/taggedTemplate.ts b/src/compiler/transformers/taggedTemplate.ts index 01ad0ca9ba4f1..0dcda258a5446 100644 --- a/src/compiler/transformers/taggedTemplate.ts +++ b/src/compiler/transformers/taggedTemplate.ts @@ -2,7 +2,6 @@ import { Debug } from "../debug"; import { factory } from "../factory/nodeFactory"; import { isNoSubstitutionTemplateLiteral } from "../factory/nodeTests"; import { setTextRange } from "../factory/utilitiesPublic"; -import { isExternalModule } from "../parser"; import { CallExpression, Expression, @@ -21,6 +20,7 @@ import { import { getSourceTextOfNodeFromSourceFile, hasInvalidEscape, + isExternalModule, } from "../utilities"; import { isExpression } from "../utilitiesPublic"; import { diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 0a7db17190996..c308766aacb60 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -55,7 +55,7 @@ import { setOriginalNode, setTextRange, } from "../factory/utilitiesPublic"; -import { isExternalModule } from "../parser"; +import { setParent } from "../parserUtilities"; import { skipTrivia } from "../scanner"; import { __String, @@ -157,6 +157,7 @@ import { insertStatementsAfterStandardPrologue, isAccessExpression, isEnumConst, + isExternalModule, isExternalModuleImportEqualsDeclaration, isInJSFile, isJsonSourceFile, @@ -166,7 +167,6 @@ import { moveRangePos, nodeIsMissing, parameterIsThisKeyword, - setParent, setTextRangeEnd, setTextRangePos, setTextRangePosEnd, diff --git a/src/compiler/transformers/typeSerializer.ts b/src/compiler/transformers/typeSerializer.ts index 454c04d997dda..69c82f6fdc020 100644 --- a/src/compiler/transformers/typeSerializer.ts +++ b/src/compiler/transformers/typeSerializer.ts @@ -15,6 +15,7 @@ import { } from "../factory/nodeTests"; import { setTextRange } from "../factory/utilitiesPublic"; import { parseNodeFactory } from "../parser"; +import { setParent } from "../parserUtilities"; import { AccessorDeclaration, ArrayLiteralExpression, @@ -65,7 +66,6 @@ import { getStrictOptionValue, isAsyncFunction, nodeIsPresent, - setParent, skipTypeParentheses, } from "../utilities"; import { diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index e679e0bf0d30d..5fea7bafea613 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -51,6 +51,7 @@ import { LogicalOperatorOrHigher, MethodDeclaration, ModifierFlags, + ModuleKind, NamedImportBindings, NamespaceExport, Node, @@ -59,6 +60,7 @@ import { PrivateIdentifierAutoAccessorPropertyDeclaration, PrivateIdentifierMethodDeclaration, PropertyDeclaration, + ScriptKind, SourceFile, Statement, SuperCall, @@ -69,17 +71,21 @@ import { } from "../types"; import { getAllAccessorDeclarations, + getEmitModuleKind, getFirstConstructorWithBody, getNamespaceDeclarationNode, + getStrictOptionValue, hasDecorators, hasStaticModifier, hasSyntacticModifier, isDefaultImport, + isExternalModule, isKeyword, isStatic, isSuperCall, parameterIsThisKeyword, skipParentheses, + startsWithUseStrict, } from "../utilities"; import { getDecorators, @@ -647,3 +653,42 @@ function getAllDecoratorsOfProperty(property: PropertyDeclaration): AllDecorator return { decorators }; } + +/** + * Returns whether the source file will be treated as if it were in strict mode at runtime. + * + * @internal + */ +export function isEffectiveStrictModeSourceFile(node: SourceFile, compilerOptions: CompilerOptions) { + // We can only verify strict mode for JS/TS files + switch (node.scriptKind) { + case ScriptKind.JS: + case ScriptKind.TS: + case ScriptKind.JSX: + case ScriptKind.TSX: + break; + default: + return false; + } + // Strict mode does not matter for declaration files. + if (node.isDeclarationFile) { + return false; + } + // If `alwaysStrict` is set, then treat the file as strict. + if (getStrictOptionValue(compilerOptions, "alwaysStrict")) { + return true; + } + // Starting with a "use strict" directive indicates the file is strict. + if (startsWithUseStrict(node.statements)) { + return true; + } + if (isExternalModule(node) || compilerOptions.isolatedModules) { + // ECMAScript Modules are always strict. + if (getEmitModuleKind(compilerOptions) >= ModuleKind.ES2015) { + return true; + } + // Other modules are strict unless otherwise specified. + return !compilerOptions.noImplicitUseStrict; + } + return false; +} diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 704e06c7ea1cb..9123b68620f80 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -78,13 +78,10 @@ import { resolveProjectReferencePath, } from "./program"; import { - FileWatcher, - FileWatcherCallback, getModifiedTime, missingFileModifiedTime, PollingInterval, sys, - System, } from "./sys"; import { resolveConfigFileProjectName, @@ -104,11 +101,14 @@ import { DiagnosticMessage, EmitResult, ExitStatus, + FileWatcher, + FileWatcherCallback, ParsedCommandLine, Path, Program, ResolvedConfigFileName, SourceFile, + System, WatchOptions, WriteFileCallback, } from "./types"; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5455ba504ae52..6c6af1d89aa51 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -19,7 +19,8 @@ import { PackageJsonInfoCache, } from "./moduleNameResolver"; import { CreateSourceFileOptions } from "./parser"; -import { SymlinkCache, ThisContainer } from "./utilities"; +import { SymlinkCache } from "./symlinkCache"; +import { ThisContainer } from "./utilities"; // branded string type used to store absolute, normalized and canonicalized paths // arbitrary file name can be converted to Path via toPath function @@ -9841,3 +9842,175 @@ export const enum DeprecationVersion { v6_0 = "6.0", /* eslint-enable @typescript-eslint/naming-convention */ } + +/** + * Safer version of `Function` which should not be called. + * Every function should be assignable to this, but this should not be assignable to every function. + * + * @internal + */ +export type AnyFunction = (...args: never[]) => void; + +/** @internal */ +export type AnyConstructor = new (...args: unknown[]) => unknown; + +/** @internal */ +export type Mutable = { -readonly [K in keyof T]: T[K] }; + +/** @internal */ +export type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex"; + +/** @internal */ +export interface NodeBuffer extends Uint8Array { + constructor: any; + write(str: string, encoding?: BufferEncoding): number; + 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[] }; + equals(otherBuffer: Uint8Array): boolean; + 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; + writeUIntLE(value: number, offset: number, byteLength: number): number; + writeUIntBE(value: number, offset: number, byteLength: number): number; + writeIntLE(value: number, offset: number, byteLength: number): number; + writeIntBE(value: number, offset: number, byteLength: number): number; + readUIntLE(offset: number, byteLength: number): number; + readUIntBE(offset: number, byteLength: number): number; + readIntLE(offset: number, byteLength: number): number; + readIntBE(offset: number, byteLength: number): number; + readUInt8(offset: number): number; + readUInt16LE(offset: number): number; + readUInt16BE(offset: number): number; + readUInt32LE(offset: number): number; + readUInt32BE(offset: number): number; + readInt8(offset: number): number; + readInt16LE(offset: number): number; + readInt16BE(offset: number): number; + readInt32LE(offset: number): number; + readInt32BE(offset: number): number; + readFloatLE(offset: number): number; + readFloatBE(offset: number): number; + readDoubleLE(offset: number): number; + readDoubleBE(offset: number): number; + reverse(): this; + swap16(): Buffer; + swap32(): Buffer; + swap64(): Buffer; + writeUInt8(value: number, offset: number): number; + writeUInt16LE(value: number, offset: number): number; + writeUInt16BE(value: number, offset: number): number; + writeUInt32LE(value: number, offset: number): number; + writeUInt32BE(value: number, offset: number): number; + writeInt8(value: number, offset: number): number; + writeInt16LE(value: number, offset: number): number; + writeInt16BE(value: number, offset: number): number; + writeInt32LE(value: number, offset: number): number; + writeInt32BE(value: number, offset: number): number; + writeFloatLE(value: number, offset: number): number; + writeFloatBE(value: number, offset: number): number; + writeDoubleLE(value: number, offset: number): number; + writeDoubleBE(value: number, offset: number): number; + readBigUInt64BE?(offset?: number): bigint; + readBigUInt64LE?(offset?: number): bigint; + readBigInt64BE?(offset?: number): bigint; + readBigInt64LE?(offset?: number): bigint; + writeBigInt64BE?(value: bigint, offset?: number): number; + writeBigInt64LE?(value: bigint, offset?: number): number; + writeBigUInt64BE?(value: bigint, offset?: number): number; + writeBigUInt64LE?(value: bigint, offset?: number): number; + 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]>; + includes(value: string | number | Buffer, byteOffset?: number, encoding?: BufferEncoding): boolean; + keys(): IterableIterator; + values(): IterableIterator; +} + +/** @internal */ +export interface Buffer extends NodeBuffer { } + +export interface FileWatcher { + close(): void; +} + +export enum FileWatcherEventKind { + Created, + Changed, + Deleted +} + +export type FileWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind, modifiedTime?: Date) => void; +export type DirectoryWatcherCallback = (fileName: string) => void; + +export interface System { + args: string[]; + newLine: string; + useCaseSensitiveFileNames: boolean; + write(s: string): void; + writeOutputIsTTY?(): boolean; + getWidthOfTerminal?(): number; + readFile(path: string, encoding?: string): string | undefined; + getFileSize?(path: string): number; + writeFile(path: string, data: string, writeByteOrderMark?: boolean): void; + + /** + * @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; + resolvePath(path: string): string; + fileExists(path: string): boolean; + directoryExists(path: string): boolean; + createDirectory(path: string): void; + getExecutingFilePath(): string; + getCurrentDirectory(): string; + getDirectories(path: string): string[]; + readDirectory(path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number): string[]; + getModifiedTime?(path: string): Date | undefined; + setModifiedTime?(path: string, time: Date): void; + deleteFile?(path: string): void; + /** + * A good implementation is node.js' `crypto.createHash`. (https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm) + */ + createHash?(data: string): string; + /** This must be cryptographically secure. Only implement this method using `crypto.createHash("sha256")`. */ + createSHA256Hash?(data: string): string; + getMemoryUsage?(): number; + exit(exitCode?: number): void; + /** @internal */ enableCPUProfiler?(path: string, continuation: () => void): boolean; + /** @internal */ disableCPUProfiler?(continuation: () => void): boolean; + /** @internal */ cpuProfilingEnabled?(): boolean; + realpath?(path: string): string; + /** @internal */ getEnvironmentVariable(name: string): string; + /** @internal */ tryEnableSourceMapsForHost?(): void; + /** @internal */ debugMode?: boolean; + setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; + clearTimeout?(timeoutId: any): void; + clearScreen?(): void; + /** @internal */ setBlocking?(): void; + base64decode?(input: string): string; + base64encode?(input: string): string; + /** @internal */ bufferFrom?(input: string, encoding?: string): Buffer; + /** @internal */ require?(baseDir: string, moduleName: string): RequireResult; + + // For testing + /** @internal */ now?(): Date; + /** @internal */ storeFilesChangingSignatureDuringEmit?: boolean; +} + +/** @internal */ +export interface ResolutionNameAndModeGetter { + getName(entry: Entry): string; + getMode(entry: Entry, file: SourceFile): ResolutionMode; +} diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 1d6e77e689f17..cb2a66d14b84c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1,15 +1,6 @@ import { getSymbolId } from "./checkerUtilities"; -import { - affectsDeclarationPathOptionDeclarations, - affectsEmitOptionDeclarations, - moduleResolutionOptionDeclarations, - optionsAffectingProgramStructure, - parseConfigFileTextToJson, - semanticDiagnosticsOptionDeclarations, -} from "./commandLineParser"; import { addRange, - append, arrayFrom, assertType, binarySearch, @@ -18,7 +9,6 @@ import { concatenate, contains, createGetCanonicalFileName, - createMultiMap, emptyArray, equalOwnProperties, equateValues, @@ -26,7 +16,6 @@ import { filter, find, findBestPatternMatch, - findIndex, findLast, firstDefined, firstOrUndefined, @@ -37,10 +26,8 @@ import { GetCanonicalFileName, getEntries, getOwnKeys, - getStringComparer, hasProperty, identity, - indexOfAnyCharCode, insertSorted, isArray, isLineBreak, @@ -50,16 +37,13 @@ import { last, lastOrUndefined, length, - map, mapDefined, - MultiMap, noop, or, Pattern, singleElementArray, singleOrUndefined, some, - sort, startsWith, stringContains, trimString, @@ -78,7 +62,6 @@ import { import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { getSnippetElement } from "./factory/emitNode"; -import { factory } from "./factory/nodeFactory"; import { isArrayLiteralExpression, isArrowFunction, @@ -120,7 +103,6 @@ import { isJSDocTypeExpression, isJSDocTypeLiteral, isJSDocTypeTag, - isJsxFragment, isJsxText, isLiteralTypeNode, isMetaProperty, @@ -157,23 +139,9 @@ import { canHaveDecorators, canHaveModifiers, } from "./factory/utilitiesPublic"; -import { - createModeAwareCache, - ModeAwareCache, - nodeModulesPathPart, - shouldAllowImportingTsExtension, -} from "./moduleNameResolver"; -import { - forEachChild, - forEachChildRecursively, - isExternalModule, - isFileProbablyExternalModule, -} from "./parser"; import { changeAnyExtension, combinePaths, - containsPath, - directorySeparator, ensurePathIsNonModuleName, ensureTrailingDirectorySeparator, fileExtensionIs, @@ -182,20 +150,13 @@ import { getBaseFileName, getDirectoryPath, getNormalizedAbsolutePath, - getNormalizedPathComponents, - getPathComponents, - getPathFromPathComponents, getRelativePathToDirectoryOrUrl, getRootLength, - hasExtension, isAnyDirectorySeparator, - isRootedDiskPath, normalizePath, pathIsRelative, - removeTrailingDirectorySeparator, toPath, } from "./path"; -import { ResolutionNameAndModeGetter } from "./program"; import { computeLineAndCharacterOfPosition, computeLineOfPosition, @@ -207,17 +168,14 @@ import { getLineStarts, getTrailingCommentRanges, isIdentifierStart, - isIdentifierText, skipTrivia, stringToToken, tokenToString, } from "./scanner"; import { - FileWatcher, - ignoredPaths, - sys, -} from "./sys"; -import { tracing } from "./tracing"; + parsePseudoBigInt, + positionIsSynthesized, +} from "./scannerUtilities"; import { __String, AccessExpression, @@ -306,6 +264,7 @@ import { Extension, ExternalModuleReference, FileExtensionInfo, + FileWatcher, ForInOrOfStatement, ForInStatement, ForOfStatement, @@ -377,6 +336,7 @@ import { ModuleDetectionKind, ModuleKind, ModuleResolutionKind, + Mutable, NamedDeclaration, NamedExports, NamedImports, @@ -384,7 +344,6 @@ import { NamespaceExport, NamespaceImport, NewExpression, - NewLineKind, Node, NodeArray, NodeFlags, @@ -407,7 +366,6 @@ import { Path, PostfixUnaryExpression, PrefixUnaryExpression, - PrinterOptions, PrintHandlers, PrivateIdentifier, ProjectReference, @@ -429,7 +387,6 @@ import { ResolvedModuleWithFailedLookupLocations, ResolvedTypeReferenceDirective, ResolvedTypeReferenceDirectiveWithFailedLookupLocations, - ReturnStatement, SatisfiesExpression, ScriptKind, ScriptTarget, @@ -443,7 +400,6 @@ import { SourceFile, SourceFileLike, SourceFileMayBeEmittedHost, - SourceMapSource, Statement, StringLiteral, StringLiteralLike, @@ -466,7 +422,6 @@ import { ThisTypePredicate, Token, TokenFlags, - TransformFlags, TransientSymbol, TriviaSyntaxKind, TryStatement, @@ -487,7 +442,6 @@ import { TypePredicateKind, TypeReferenceNode, UnionOrIntersectionTypeNode, - UserPreferences, ValidImportTypeNode, VariableDeclaration, VariableDeclarationInitializedTo, @@ -498,7 +452,6 @@ import { WithStatement, WriteFileCallback, WriteFileCallbackData, - YieldExpression, } from "./types"; import { createTextSpan, @@ -541,7 +494,6 @@ import { isJSDocPropertyLikeTag, isJSDocTag, isJsxChild, - isJsxOpeningLikeElement, isLeftHandSideExpression, isMemberName, isMethodOrAccessor, @@ -554,6 +506,10 @@ import { unescapeLeadingUnderscores, } from "./utilitiesPublic"; +function isCommonJSContainingModuleKind(kind: ModuleKind) { + return kind === ModuleKind.CommonJS || kind === ModuleKind.Node16 || kind === ModuleKind.NodeNext; +} + /** @internal */ export const resolvingEmptyArray: never[] = []; @@ -579,6 +535,11 @@ export function getDeclarationOfKind(symbol: Symbol, kind return undefined; } +// See also `isExternalOrCommonJsModule` +export function isExternalModule(file: SourceFile): boolean { + return file.externalModuleIndicator !== undefined; +} + /** @internal */ export function getDeclarationsOfKind(symbol: Symbol, kind: T["kind"]): T[] { return filter(symbol.declarations || emptyArray, d => d.kind === kind) as T[]; @@ -637,22 +598,6 @@ function createSingleLineStringWriter(): EmitTextWriter { }; } -/** @internal */ -export function changesAffectModuleResolution(oldOptions: CompilerOptions, newOptions: CompilerOptions): boolean { - return oldOptions.configFilePath !== newOptions.configFilePath || - optionsHaveModuleResolutionChanges(oldOptions, newOptions); -} - -/** @internal */ -export function optionsHaveModuleResolutionChanges(oldOptions: CompilerOptions, newOptions: CompilerOptions) { - return optionsHaveChanges(oldOptions, newOptions, moduleResolutionOptionDeclarations); -} - -/** @internal */ -export function changesAffectingProgramStructure(oldOptions: CompilerOptions, newOptions: CompilerOptions) { - return optionsHaveChanges(oldOptions, newOptions, optionsAffectingProgramStructure); -} - /** @internal */ export function optionsHaveChanges(oldOptions: CompilerOptions, newOptions: CompilerOptions, optionDeclarations: readonly CommandLineOption[]) { return oldOptions !== newOptions && optionDeclarations.some(o => @@ -738,24 +683,6 @@ export function getResolvedModule(sourceFile: SourceFile | undefined, moduleName return sourceFile?.resolvedModules?.get(moduleNameText, mode)?.resolvedModule; } -/** @internal */ -export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModuleWithFailedLookupLocations, mode: ResolutionMode): void { - if (!sourceFile.resolvedModules) { - sourceFile.resolvedModules = createModeAwareCache(); - } - - sourceFile.resolvedModules.set(moduleNameText, mode, resolvedModule); -} - -/** @internal */ -export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective: ResolvedTypeReferenceDirectiveWithFailedLookupLocations, mode: ResolutionMode): void { - if (!sourceFile.resolvedTypeReferenceDirectiveNames) { - sourceFile.resolvedTypeReferenceDirectiveNames = createModeAwareCache(); - } - - sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, mode, resolvedTypeReferenceDirective); -} - /** @internal */ export function getResolvedTypeReferenceDirective(sourceFile: SourceFile | undefined, typeReferenceDirectiveName: string, mode: ResolutionMode): ResolvedTypeReferenceDirective | undefined { return sourceFile?.resolvedTypeReferenceDirectiveNames?.get(typeReferenceDirectiveName, mode)?.resolvedTypeReferenceDirective; @@ -806,61 +733,6 @@ export function typeDirectiveIsEqualTo(oldResolution: ResolvedTypeReferenceDirec oldResolution.resolvedTypeReferenceDirective.originalPath === newResolution.resolvedTypeReferenceDirective.originalPath; } -/** @internal */ -export function hasChangesInResolutions( - names: readonly K[], - newSourceFile: SourceFile, - newResolutions: readonly V[], - oldResolutions: ModeAwareCache | undefined, - comparer: (oldResolution: V, newResolution: V) => boolean, - nameAndModeGetter: ResolutionNameAndModeGetter, -): boolean { - Debug.assert(names.length === newResolutions.length); - - for (let i = 0; i < names.length; i++) { - const newResolution = newResolutions[i]; - const entry = names[i]; - const name = nameAndModeGetter.getName(entry); - const mode = nameAndModeGetter.getMode(entry, newSourceFile); - const oldResolution = oldResolutions && oldResolutions.get(name, mode); - const changed = - oldResolution - ? !newResolution || !comparer(oldResolution, newResolution) - : newResolution; - if (changed) { - return true; - } - } - return false; -} - -// Returns true if this node contains a parse error anywhere underneath it. -/** @internal */ -export function containsParseError(node: Node): boolean { - aggregateChildData(node); - return (node.flags & NodeFlags.ThisNodeOrAnySubNodesHasError) !== 0; -} - -function aggregateChildData(node: Node): void { - if (!(node.flags & NodeFlags.HasAggregatedChildData)) { - // A node is considered to contain a parse error if: - // a) the parser explicitly marked that it had an error - // b) any of it's children reported that it had an error. - const thisNodeOrAnySubNodesHasError = ((node.flags & NodeFlags.ThisNodeHasError) !== 0) || - forEachChild(node, containsParseError); - - // If so, mark ourselves accordingly. - if (thisNodeOrAnySubNodesHasError) { - (node as Mutable).flags |= NodeFlags.ThisNodeOrAnySubNodesHasError; - } - - // Also mark that we've propagated the child information to this node. This way we can - // always consult the bit directly on this node without needing to check its children - // again. - (node as Mutable).flags |= NodeFlags.HasAggregatedChildData; - } -} - /** @internal */ export function getSourceFileOfNode(node: Node): SourceFile; /** @internal */ @@ -873,11 +745,6 @@ export function getSourceFileOfNode(node: Node): SourceFile { return node as SourceFile; } -/** @internal */ -export function getSourceFileOfModule(module: Symbol) { - return getSourceFileOfNode(module.valueDeclaration || getNonAugmentationDeclaration(module)); -} - /** @internal */ export function isPlainJsFile(file: SourceFile | undefined, checkJs: boolean | undefined): boolean { return !!file && (file.scriptKind === ScriptKind.JS || file.scriptKind === ScriptKind.JSX) && !file.checkJsDirective && checkJs === undefined; @@ -1385,11 +1252,6 @@ export function isCatchClauseVariableDeclarationOrBindingElement(declaration: De return node.kind === SyntaxKind.VariableDeclaration && node.parent.kind === SyntaxKind.CatchClause; } -/** @internal */ -export function isAmbientModule(node: Node): node is AmbientModuleDeclaration { - return isModuleDeclaration(node) && (node.name.kind === SyntaxKind.StringLiteral || isGlobalScopeAugmentation(node)); -} - /** @internal */ export function isModuleWithStringLiteralName(node: Node): node is ModuleDeclaration { return isModuleDeclaration(node) && node.name.kind === SyntaxKind.StringLiteral; @@ -1433,83 +1295,6 @@ export function isBlockScopedContainerTopLevel(node: Node): boolean { isFunctionLikeOrClassStaticBlockDeclaration(node); } -/** @internal */ -export function isGlobalScopeAugmentation(module: ModuleDeclaration): boolean { - return !!(module.flags & NodeFlags.GlobalAugmentation); -} - -/** @internal */ -export function isExternalModuleAugmentation(node: Node): node is AmbientModuleDeclaration { - return isAmbientModule(node) && isModuleAugmentationExternal(node); -} - -/** @internal */ -export function isModuleAugmentationExternal(node: AmbientModuleDeclaration) { - // external module augmentation is a ambient module declaration that is either: - // - defined in the top level scope and source file is an external module - // - defined inside ambient module declaration located in the top level scope and source file not an external module - switch (node.parent.kind) { - case SyntaxKind.SourceFile: - return isExternalModule(node.parent); - case SyntaxKind.ModuleBlock: - return isAmbientModule(node.parent.parent) && isSourceFile(node.parent.parent.parent) && !isExternalModule(node.parent.parent.parent); - } - return false; -} - -/** @internal */ -export function getNonAugmentationDeclaration(symbol: Symbol) { - return symbol.declarations?.find(d => !isExternalModuleAugmentation(d) && !(isModuleDeclaration(d) && isGlobalScopeAugmentation(d))); -} - -function isCommonJSContainingModuleKind(kind: ModuleKind) { - return kind === ModuleKind.CommonJS || kind === ModuleKind.Node16 || kind === ModuleKind.NodeNext; -} - -/** @internal */ -export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) { - return isExternalModule(node) || compilerOptions.isolatedModules || (isCommonJSContainingModuleKind(getEmitModuleKind(compilerOptions)) && !!node.commonJsModuleIndicator); -} - -/** - * Returns whether the source file will be treated as if it were in strict mode at runtime. - * - * @internal - */ -export function isEffectiveStrictModeSourceFile(node: SourceFile, compilerOptions: CompilerOptions) { - // We can only verify strict mode for JS/TS files - switch (node.scriptKind) { - case ScriptKind.JS: - case ScriptKind.TS: - case ScriptKind.JSX: - case ScriptKind.TSX: - break; - default: - return false; - } - // Strict mode does not matter for declaration files. - if (node.isDeclarationFile) { - return false; - } - // If `alwaysStrict` is set, then treat the file as strict. - if (getStrictOptionValue(compilerOptions, "alwaysStrict")) { - return true; - } - // Starting with a "use strict" directive indicates the file is strict. - if (startsWithUseStrict(node.statements)) { - return true; - } - if (isExternalModule(node) || compilerOptions.isolatedModules) { - // ECMAScript Modules are always strict. - if (getEmitModuleKind(compilerOptions) >= ModuleKind.ES2015) { - return true; - } - // Other modules are strict unless otherwise specified. - return !compilerOptions.noImplicitUseStrict; - } - return false; -} - /** @internal */ export function isAmbientPropertyDeclaration(node: PropertyDeclaration) { return !!(node.flags & NodeFlags.Ambient) || hasSyntacticModifier(node, ModifierFlags.Ambient); @@ -2111,75 +1896,6 @@ export function isChildOfNodeWithKind(node: Node, kind: SyntaxKind): boolean { return false; } -// Warning: This has the same semantics as the forEach family of functions, -// in that traversal terminates in the event that 'visitor' supplies a truthy value. -/** @internal */ -export function forEachReturnStatement(body: Block | Statement, visitor: (stmt: ReturnStatement) => T): T | undefined { - - return traverse(body); - - function traverse(node: Node): T | undefined { - switch (node.kind) { - case SyntaxKind.ReturnStatement: - return visitor(node as ReturnStatement); - case SyntaxKind.CaseBlock: - case SyntaxKind.Block: - case SyntaxKind.IfStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.WithStatement: - case SyntaxKind.SwitchStatement: - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: - case SyntaxKind.LabeledStatement: - case SyntaxKind.TryStatement: - case SyntaxKind.CatchClause: - return forEachChild(node, traverse); - } - } -} - -/** @internal */ -export function forEachYieldExpression(body: Block, visitor: (expr: YieldExpression) => void): void { - - return traverse(body); - - function traverse(node: Node): void { - switch (node.kind) { - case SyntaxKind.YieldExpression: - visitor(node as YieldExpression); - const operand = (node as YieldExpression).expression; - if (operand) { - traverse(operand); - } - return; - case SyntaxKind.EnumDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.TypeAliasDeclaration: - // These are not allowed inside a generator now, but eventually they may be allowed - // as local types. Regardless, skip them to avoid the work. - return; - default: - if (isFunctionLike(node)) { - if (node.name && node.name.kind === SyntaxKind.ComputedPropertyName) { - // Note that we will not include methods/accessors of a class because they would require - // first descending into the class. This is by design. - traverse(node.name.expression); - return; - } - } - else if (!isPartOfTypeNode(node)) { - // This is the general case, which should include mostly expressions and statements. - // Also includes NodeArrays. - forEachChild(node, traverse); - } - } - } -} /** * Gets the most likely element type for a TypeNode. This is not an exhaustive test @@ -5562,39 +5278,6 @@ export interface EmitFileNames { buildInfoPath?: string | undefined; } -/** - * Gets the source files that are expected to have an emit output. - * - * Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support - * transformations. - * - * @param host An EmitHost. - * @param targetSourceFile An optional target source file to emit. - * - * @internal - */ -export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile, forceDtsEmit?: boolean): readonly SourceFile[] { - const options = host.getCompilerOptions(); - if (outFile(options)) { - const moduleKind = getEmitModuleKind(options); - const moduleEmitEnabled = options.emitDeclarationOnly || moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.System; - // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified - return filter( - host.getSourceFiles(), - sourceFile => - (moduleEmitEnabled || !isExternalModule(sourceFile)) && - sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit) - ); - } - else { - const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile]; - return filter( - sourceFiles, - sourceFile => sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit) - ); - } -} - /** * Don't call this for `--outFile`, just for `--outDir` or plain emit. `--outFile` needs additional checks. * @@ -6616,39 +6299,12 @@ export function base64decode(host: { base64decode?(input: string): string } | un return getStringFromExpandedCharCodes(expandedCharCodes); } -/** @internal */ -export function readJsonOrUndefined(path: string, hostOrText: { readFile(fileName: string): string | undefined } | string): object | undefined { - const jsonText = isString(hostOrText) ? hostOrText : hostOrText.readFile(path); - if (!jsonText) return undefined; - // gracefully handle if readFile fails or returns not JSON - const result = parseConfigFileTextToJson(path, jsonText); - return !result.error ? result.config : undefined; -} - -/** @internal */ -export function readJson(path: string, host: { readFile(fileName: string): string | undefined }): object { - return readJsonOrUndefined(path, host) || {}; -} - /** @internal */ export function directoryProbablyExists(directoryName: string, host: { directoryExists?: (directoryName: string) => boolean }): boolean { // if host does not support 'directoryExists' assume that directory will exist return !host.directoryExists || host.directoryExists(directoryName); } -const carriageReturnLineFeed = "\r\n"; -const lineFeed = "\n"; -/** @internal */ -export function getNewLineCharacter(options: CompilerOptions | PrinterOptions, getNewLine?: () => string): string { - switch (options.newLine) { - case NewLineKind.CarriageReturnLineFeed: - return carriageReturnLineFeed; - case NewLineKind.LineFeed: - return lineFeed; - } - return getNewLine ? getNewLine() : sys ? sys.newLine : carriageReturnLineFeed; -} - /** * Creates a new TextRange from the provided pos and end. * @@ -7090,25 +6746,6 @@ export function showModuleSpecifier({ moduleSpecifier }: ImportDeclaration): str return isStringLiteral(moduleSpecifier) ? moduleSpecifier.text : getTextOfNode(moduleSpecifier); } -/** @internal */ -export function getLastChild(node: Node): Node | undefined { - let lastChild: Node | undefined; - forEachChild(node, - child => { - if (nodeIsPresent(child)) lastChild = child; - }, - children => { - // As an optimization, jump straight to the end of the list. - for (let i = children.length - 1; i >= 0; i--) { - if (nodeIsPresent(children[i])) { - lastChild = children[i]; - break; - } - } - }); - return lastChild; -} - /** * Add a value to a set, and return true if it wasn't already present. * @@ -7272,112 +6909,6 @@ export function getLeftmostExpression(node: Expression, stopAtCallExpressions: b } } -/** @internal */ -export interface ObjectAllocator { - getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node; - getTokenConstructor(): new (kind: TKind, pos?: number, end?: number) => Token; - getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos?: number, end?: number) => Identifier; - getPrivateIdentifierConstructor(): new (kind: SyntaxKind.PrivateIdentifier, pos?: number, end?: number) => PrivateIdentifier; - getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile; - getSymbolConstructor(): new (flags: SymbolFlags, name: __String) => Symbol; - getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type; - getSignatureConstructor(): new (checker: TypeChecker, flags: SignatureFlags) => Signature; - getSourceMapSourceConstructor(): new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource; -} - -function Symbol(this: Symbol, flags: SymbolFlags, name: __String) { - this.flags = flags; - this.escapedName = name; - this.declarations = undefined; - this.valueDeclaration = undefined; - this.id = 0; - this.mergeId = 0; - this.parent = undefined; - this.members = undefined; - this.exports = undefined; - this.exportSymbol = undefined; - this.constEnumOnlyModule = undefined; - this.isReferenced = undefined; - this.isAssigned = undefined; - (this as any).links = undefined; // used by TransientSymbol -} - -function Type(this: Type, checker: TypeChecker, flags: TypeFlags) { - this.flags = flags; - if (Debug.isDebugging || tracing) { - this.checker = checker; - } -} - -function Signature(this: Signature, checker: TypeChecker, flags: SignatureFlags) { - this.flags = flags; - if (Debug.isDebugging) { - this.checker = checker; - } -} - -function Node(this: Mutable, kind: SyntaxKind, pos: number, end: number) { - this.pos = pos; - this.end = end; - this.kind = kind; - this.id = 0; - this.flags = NodeFlags.None; - this.modifierFlagsCache = ModifierFlags.None; - this.transformFlags = TransformFlags.None; - this.parent = undefined!; - this.original = undefined; - this.emitNode = undefined; -} - -function Token(this: Mutable, kind: SyntaxKind, pos: number, end: number) { - this.pos = pos; - this.end = end; - this.kind = kind; - this.id = 0; - this.flags = NodeFlags.None; - this.transformFlags = TransformFlags.None; - this.parent = undefined!; - this.emitNode = undefined; -} - -function Identifier(this: Mutable, kind: SyntaxKind, pos: number, end: number) { - this.pos = pos; - this.end = end; - this.kind = kind; - this.id = 0; - this.flags = NodeFlags.None; - this.transformFlags = TransformFlags.None; - this.parent = undefined!; - this.original = undefined; - this.emitNode = undefined; - (this as Identifier).flowNode = undefined; -} - -function SourceMapSource(this: SourceMapSource, fileName: string, text: string, skipTrivia?: (pos: number) => number) { - this.fileName = fileName; - this.text = text; - this.skipTrivia = skipTrivia || (pos => pos); -} - -// eslint-disable-next-line prefer-const -/** @internal */ -export const objectAllocator: ObjectAllocator = { - getNodeConstructor: () => Node as any, - getTokenConstructor: () => Token as any, - getIdentifierConstructor: () => Identifier as any, - getPrivateIdentifierConstructor: () => Node as any, - getSourceFileConstructor: () => Node as any, - getSymbolConstructor: () => Symbol as any, - getTypeConstructor: () => Type as any, - getSignatureConstructor: () => Signature as any, - getSourceMapSourceConstructor: () => SourceMapSource as any, -}; - -/** @internal */ -export function setObjectAllocator(alloc: ObjectAllocator) { - Object.assign(objectAllocator, alloc); -} - /** @internal */ export function formatStringFromArgs(text: string, args: ArrayLike, baseIndex = 0): string { return text.replace(/{(\d+)}/g, (_match, index: string) => "" + Debug.checkDefined(args[+index + baseIndex])); @@ -7657,62 +7188,6 @@ export function getLanguageVariant(scriptKind: ScriptKind) { return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard; } -/** - * This is a somewhat unavoidable full tree walk to locate a JSX tag - `import.meta` requires the same, - * but we avoid that walk (or parts of it) if at all possible using the `PossiblyContainsImportMeta` node flag. - * Unfortunately, there's no `NodeFlag` space to do the same for JSX. - */ -function walkTreeForJSXTags(node: Node): Node | undefined { - if (!(node.transformFlags & TransformFlags.ContainsJsx)) return undefined; - return isJsxOpeningLikeElement(node) || isJsxFragment(node) ? node : forEachChild(node, walkTreeForJSXTags); -} - -function isFileModuleFromUsingJSXTag(file: SourceFile): Node | undefined { - // Excludes declaration files - they still require an explicit `export {}` or the like - // for back compat purposes. (not that declaration files should contain JSX tags!) - return !file.isDeclarationFile ? walkTreeForJSXTags(file) : undefined; -} - -/** - * Note that this requires file.impliedNodeFormat be set already; meaning it must be set very early on - * in SourceFile construction. - */ -function isFileForcedToBeModuleByFormat(file: SourceFile): true | undefined { - // Excludes declaration files - they still require an explicit `export {}` or the like - // for back compat purposes. The only non-declaration files _not_ forced to be a module are `.js` files - // that aren't esm-mode (meaning not in a `type: module` scope). - return (file.impliedNodeFormat === ModuleKind.ESNext || (fileExtensionIsOneOf(file.fileName, [Extension.Cjs, Extension.Cts, Extension.Mjs, Extension.Mts]))) && !file.isDeclarationFile ? true : undefined; -} - -/** @internal */ -export function getSetExternalModuleIndicator(options: CompilerOptions): (file: SourceFile) => void { - // TODO: Should this callback be cached? - switch (getEmitModuleDetectionKind(options)) { - case ModuleDetectionKind.Force: - // All non-declaration files are modules, declaration files still do the usual isFileProbablyExternalModule - return (file: SourceFile) => { - file.externalModuleIndicator = isFileProbablyExternalModule(file) || !file.isDeclarationFile || undefined; - }; - case ModuleDetectionKind.Legacy: - // Files are modules if they have imports, exports, or import.meta - return (file: SourceFile) => { - file.externalModuleIndicator = isFileProbablyExternalModule(file); - }; - case ModuleDetectionKind.Auto: - // If module is nodenext or node16, all esm format files are modules - // If jsx is react-jsx or react-jsxdev then jsx tags force module-ness - // otherwise, the presence of import or export statments (or import.meta) implies module-ness - const checks: ((file: SourceFile) => Node | true | undefined)[] = [isFileProbablyExternalModule]; - if (options.jsx === JsxEmit.ReactJSX || options.jsx === JsxEmit.ReactJSXDev) { - checks.push(isFileModuleFromUsingJSXTag); - } - checks.push(isFileForcedToBeModuleByFormat); - const combined = or(...checks); - const callback = (file: SourceFile) => void (file.externalModuleIndicator = combined(file)); - return callback; - } -} - /** @internal */ export function getEmitScriptTarget(compilerOptions: {module?: CompilerOptions["module"], target?: CompilerOptions["target"]}): ScriptTarget { return compilerOptions.target ?? @@ -7907,21 +7382,6 @@ export function getUseDefineForClassFields(compilerOptions: CompilerOptions): bo return compilerOptions.useDefineForClassFields === undefined ? getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2022 : compilerOptions.useDefineForClassFields; } -/** @internal */ -export function compilerOptionsAffectSemanticDiagnostics(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean { - return optionsHaveChanges(oldOptions, newOptions, semanticDiagnosticsOptionDeclarations); -} - -/** @internal */ -export function compilerOptionsAffectEmit(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean { - return optionsHaveChanges(oldOptions, newOptions, affectsEmitOptionDeclarations); -} - -/** @internal */ -export function compilerOptionsAffectDeclarationPath(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean { - return optionsHaveChanges(oldOptions, newOptions, affectsDeclarationPathOptionDeclarations); -} - /** @internal */ export function getCompilerOptionValue(options: CompilerOptions, option: CommandLineOption): unknown { return option.strictFlag ? getStrictOptionValue(options, option.name as StrictOptionName) : options[option.name]; @@ -7967,110 +7427,6 @@ export function hasZeroOrOneAsteriskCharacter(str: string): boolean { return true; } -/** @internal */ -export interface SymlinkedDirectory { - /** Matches the casing returned by `realpath`. Used to compute the `realpath` of children. */ - real: string; - /** toPath(real). Stored to avoid repeated recomputation. */ - realPath: Path; -} - -/** @internal */ -export interface SymlinkCache { - /** Gets a map from symlink to realpath. Keys have trailing directory separators. */ - getSymlinkedDirectories(): ReadonlyMap | undefined; - /** Gets a map from realpath to symlinks. Keys have trailing directory separators. */ - getSymlinkedDirectoriesByRealpath(): MultiMap | undefined; - /** Gets a map from symlink to realpath */ - getSymlinkedFiles(): ReadonlyMap | undefined; - setSymlinkedDirectory(symlink: string, real: SymlinkedDirectory | false): void; - setSymlinkedFile(symlinkPath: Path, real: string): void; - /** - * @internal - * Uses resolvedTypeReferenceDirectives from program instead of from files, since files - * don't include automatic type reference directives. Must be called only when - * `hasProcessedResolutions` returns false (once per cache instance). - */ - setSymlinksFromResolutions(files: readonly SourceFile[], typeReferenceDirectives: ModeAwareCache): void; - /** - * @internal - * Whether `setSymlinksFromResolutions` has already been called. - */ - hasProcessedResolutions(): boolean; -} - -/** @internal */ -export function createSymlinkCache(cwd: string, getCanonicalFileName: GetCanonicalFileName): SymlinkCache { - let symlinkedDirectories: Map | undefined; - let symlinkedDirectoriesByRealpath: MultiMap | undefined; - let symlinkedFiles: Map | undefined; - let hasProcessedResolutions = false; - return { - getSymlinkedFiles: () => symlinkedFiles, - getSymlinkedDirectories: () => symlinkedDirectories, - getSymlinkedDirectoriesByRealpath: () => symlinkedDirectoriesByRealpath, - setSymlinkedFile: (path, real) => (symlinkedFiles || (symlinkedFiles = new Map())).set(path, real), - setSymlinkedDirectory: (symlink, real) => { - // Large, interconnected dependency graphs in pnpm will have a huge number of symlinks - // where both the realpath and the symlink path are inside node_modules/.pnpm. Since - // this path is never a candidate for a module specifier, we can ignore it entirely. - let symlinkPath = toPath(symlink, cwd, getCanonicalFileName); - if (!containsIgnoredPath(symlinkPath)) { - symlinkPath = ensureTrailingDirectorySeparator(symlinkPath); - if (real !== false && !symlinkedDirectories?.has(symlinkPath)) { - (symlinkedDirectoriesByRealpath ||= createMultiMap()).add(ensureTrailingDirectorySeparator(real.realPath), symlink); - } - (symlinkedDirectories || (symlinkedDirectories = new Map())).set(symlinkPath, real); - } - }, - setSymlinksFromResolutions(files, typeReferenceDirectives) { - Debug.assert(!hasProcessedResolutions); - hasProcessedResolutions = true; - for (const file of files) { - file.resolvedModules?.forEach(resolution => processResolution(this, resolution.resolvedModule)); - file.resolvedTypeReferenceDirectiveNames?.forEach(resolution => processResolution(this, resolution.resolvedTypeReferenceDirective)); - } - typeReferenceDirectives.forEach(resolution => processResolution(this, resolution.resolvedTypeReferenceDirective)); - }, - hasProcessedResolutions: () => hasProcessedResolutions, - }; - - function processResolution(cache: SymlinkCache, resolution: ResolvedModuleFull | ResolvedTypeReferenceDirective | undefined) { - if (!resolution || !resolution.originalPath || !resolution.resolvedFileName) return; - const { resolvedFileName, originalPath } = resolution; - cache.setSymlinkedFile(toPath(originalPath, cwd, getCanonicalFileName), resolvedFileName); - const [commonResolved, commonOriginal] = guessDirectorySymlink(resolvedFileName, originalPath, cwd, getCanonicalFileName) || emptyArray; - if (commonResolved && commonOriginal) { - cache.setSymlinkedDirectory( - commonOriginal, - { real: commonResolved, realPath: toPath(commonResolved, cwd, getCanonicalFileName) }); - } - } -} - -function guessDirectorySymlink(a: string, b: string, cwd: string, getCanonicalFileName: GetCanonicalFileName): [string, string] | undefined { - const aParts = getPathComponents(getNormalizedAbsolutePath(a, cwd)); - const bParts = getPathComponents(getNormalizedAbsolutePath(b, cwd)); - let isDirectory = false; - while ( - aParts.length >= 2 && bParts.length >= 2 && - !isNodeModulesOrScopedPackageDirectory(aParts[aParts.length - 2], getCanonicalFileName) && - !isNodeModulesOrScopedPackageDirectory(bParts[bParts.length - 2], getCanonicalFileName) && - getCanonicalFileName(aParts[aParts.length - 1]) === getCanonicalFileName(bParts[bParts.length - 1]) - ) { - aParts.pop(); - bParts.pop(); - isDirectory = true; - } - return isDirectory ? [getPathFromPathComponents(aParts), getPathFromPathComponents(bParts)] : undefined; -} - -// KLUDGE: Don't assume one 'node_modules' links to another. More likely a single directory inside the node_modules is the symlink. -// ALso, don't assume that an `@foo` directory is linked. More likely the contents of that are linked. -function isNodeModulesOrScopedPackageDirectory(s: string | undefined, getCanonicalFileName: GetCanonicalFileName): boolean { - return s !== undefined && (getCanonicalFileName(s) === "node_modules" || startsWith(s, "@")); -} - function stripLeadingDirectorySeparator(s: string): string | undefined { return isAnyDirectorySeparator(s.charCodeAt(0)) ? s.slice(1) : undefined; } @@ -8081,350 +7437,15 @@ export function tryRemoveDirectoryPrefix(path: string, dirPath: string, getCanon return withoutPrefix === undefined ? undefined : stripLeadingDirectorySeparator(withoutPrefix); } -// Reserved characters, forces escaping of any non-word (or digit), non-whitespace character. -// It may be inefficient (we could just match (/[-[\]{}()*+?.,\\^$|#\s]/g), but this is future -// proof. -const reservedCharacterPattern = /[^\w\s\/]/g; - /** @internal */ -export function regExpEscape(text: string) { - return text.replace(reservedCharacterPattern, escapeRegExpCharacter); -} - -function escapeRegExpCharacter(match: string) { - return "\\" + match; -} - -const wildcardCharCodes = [CharacterCodes.asterisk, CharacterCodes.question]; - -/** @internal */ -export const commonPackageFolders: readonly string[] = ["node_modules", "bower_components", "jspm_packages"]; - -const implicitExcludePathRegexPattern = `(?!(${commonPackageFolders.join("|")})(/|$))`; - -interface WildcardMatcher { - singleAsteriskRegexFragment: string; - doubleAsteriskRegexFragment: string; - replaceWildcardCharacter: (match: string) => string; -} - -const filesMatcher: WildcardMatcher = { - /** - * Matches any single directory segment unless it is the last segment and a .min.js file - * Breakdown: - * [^./] # matches everything up to the first . character (excluding directory separators) - * (\\.(?!min\\.js$))? # matches . characters but not if they are part of the .min.js file extension - */ - singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*", - /** - * Regex for the ** wildcard. Matches any number of subdirectories. When used for including - * files or directories, does not match subdirectories that start with a . character - */ - doubleAsteriskRegexFragment: `(/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`, - replaceWildcardCharacter: match => replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment) -}; - -const directoriesMatcher: WildcardMatcher = { - singleAsteriskRegexFragment: "[^/]*", - /** - * Regex for the ** wildcard. Matches any number of subdirectories. When used for including - * files or directories, does not match subdirectories that start with a . character - */ - doubleAsteriskRegexFragment: `(/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`, - replaceWildcardCharacter: match => replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment) -}; - -const excludeMatcher: WildcardMatcher = { - singleAsteriskRegexFragment: "[^/]*", - doubleAsteriskRegexFragment: "(/.+?)?", - replaceWildcardCharacter: match => replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment) -}; - -const wildcardMatchers = { - files: filesMatcher, - directories: directoriesMatcher, - exclude: excludeMatcher -}; - -/** @internal */ -export function getRegularExpressionForWildcard(specs: readonly string[] | undefined, basePath: string, usage: "files" | "directories" | "exclude"): string | undefined { - const patterns = getRegularExpressionsForWildcards(specs, basePath, usage); - if (!patterns || !patterns.length) { - return undefined; - } - - const pattern = patterns.map(pattern => `(${pattern})`).join("|"); - // If excluding, match "foo/bar/baz...", but if including, only allow "foo". - const terminator = usage === "exclude" ? "($|/)" : "$"; - return `^(${pattern})${terminator}`; -} - -/** @internal */ -export function getRegularExpressionsForWildcards(specs: readonly string[] | undefined, basePath: string, usage: "files" | "directories" | "exclude"): readonly string[] | undefined { - if (specs === undefined || specs.length === 0) { - return undefined; - } - - return flatMap(specs, spec => - spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage])); -} - -/** - * An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension, - * and does not contain any glob characters itself. - * - * @internal - */ -export function isImplicitGlob(lastPathComponent: string): boolean { - return !/[.*?]/.test(lastPathComponent); -} - -/** @internal */ -export function getPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude") { - const pattern = spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]); - return pattern && `^(${pattern})${usage === "exclude" ? "($|/)" : "$"}`; -} - -function getSubPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude", { singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter }: WildcardMatcher): string | undefined { - let subpattern = ""; - let hasWrittenComponent = false; - const components = getNormalizedPathComponents(spec, basePath); - const lastComponent = last(components); - if (usage !== "exclude" && lastComponent === "**") { - return undefined; - } - - // getNormalizedPathComponents includes the separator for the root component. - // We need to remove to create our regex correctly. - components[0] = removeTrailingDirectorySeparator(components[0]); - - if (isImplicitGlob(lastComponent)) { - components.push("**", "*"); - } - - let optionalCount = 0; - for (let component of components) { - if (component === "**") { - subpattern += doubleAsteriskRegexFragment; - } - else { - if (usage === "directories") { - subpattern += "("; - optionalCount++; - } - - if (hasWrittenComponent) { - subpattern += directorySeparator; - } - - if (usage !== "exclude") { - let componentPattern = ""; - // The * and ? wildcards should not match directories or files that start with . if they - // appear first in a component. Dotted directories and files can be included explicitly - // like so: **/.*/.* - if (component.charCodeAt(0) === CharacterCodes.asterisk) { - componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?"; - component = component.substr(1); - } - else if (component.charCodeAt(0) === CharacterCodes.question) { - componentPattern += "[^./]"; - component = component.substr(1); - } - - componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); - - // Patterns should not include subfolders like node_modules unless they are - // explicitly included as part of the path. - // - // As an optimization, if the component pattern is the same as the component, - // then there definitely were no wildcard characters and we do not need to - // add the exclusion pattern. - if (componentPattern !== component) { - subpattern += implicitExcludePathRegexPattern; - } - - subpattern += componentPattern; - } - else { - subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); - } - } - - hasWrittenComponent = true; - } - - while (optionalCount > 0) { - subpattern += ")?"; - optionalCount--; - } - - return subpattern; -} - -function replaceWildcardCharacter(match: string, singleAsteriskRegexFragment: string) { - return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match; -} - -/** @internal */ -export interface FileSystemEntries { - readonly files: readonly string[]; - readonly directories: readonly string[]; -} - -/** @internal */ -export interface FileMatcherPatterns { - /** One pattern for each "include" spec. */ - includeFilePatterns: readonly string[] | undefined; - /** One pattern matching one of any of the "include" specs. */ - includeFilePattern: string | undefined; - includeDirectoryPattern: string | undefined; - excludePattern: string | undefined; - basePaths: readonly string[]; -} - -/** - * @param path directory of the tsconfig.json - * - * @internal - */ -export function getFileMatcherPatterns(path: string, excludes: readonly string[] | undefined, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns { - path = normalizePath(path); - currentDirectory = normalizePath(currentDirectory); - const absolutePath = combinePaths(currentDirectory, path); - - return { - includeFilePatterns: map(getRegularExpressionsForWildcards(includes, absolutePath, "files"), pattern => `^${pattern}$`), - includeFilePattern: getRegularExpressionForWildcard(includes, absolutePath, "files"), - includeDirectoryPattern: getRegularExpressionForWildcard(includes, absolutePath, "directories"), - excludePattern: getRegularExpressionForWildcard(excludes, absolutePath, "exclude"), - basePaths: getBasePaths(path, includes, useCaseSensitiveFileNames) - }; -} - -/** @internal */ -export function getRegexFromPattern(pattern: string, useCaseSensitiveFileNames: boolean): RegExp { - return new RegExp(pattern, useCaseSensitiveFileNames ? "" : "i"); -} - -/** - * @param path directory of the tsconfig.json - * - * @internal - */ -export function matchFiles(path: string, extensions: readonly string[] | undefined, excludes: readonly string[] | undefined, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string, depth: number | undefined, getFileSystemEntries: (path: string) => FileSystemEntries, realpath: (path: string) => string): string[] { - path = normalizePath(path); - currentDirectory = normalizePath(currentDirectory); - - const patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory); - - const includeFileRegexes = patterns.includeFilePatterns && patterns.includeFilePatterns.map(pattern => getRegexFromPattern(pattern, useCaseSensitiveFileNames)); - const includeDirectoryRegex = patterns.includeDirectoryPattern && getRegexFromPattern(patterns.includeDirectoryPattern, useCaseSensitiveFileNames); - const excludeRegex = patterns.excludePattern && getRegexFromPattern(patterns.excludePattern, useCaseSensitiveFileNames); - - // Associate an array of results with each include regex. This keeps results in order of the "include" order. - // If there are no "includes", then just put everything in results[0]. - const results: string[][] = includeFileRegexes ? includeFileRegexes.map(() => []) : [[]]; - const visited = new Map(); - const toCanonical = createGetCanonicalFileName(useCaseSensitiveFileNames); - for (const basePath of patterns.basePaths) { - visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth); - } - - return flatten(results); - - function visitDirectory(path: string, absolutePath: string, depth: number | undefined) { - const canonicalPath = toCanonical(realpath(absolutePath)); - if (visited.has(canonicalPath)) return; - visited.set(canonicalPath, true); - const { files, directories } = getFileSystemEntries(path); - - for (const current of sort(files, compareStringsCaseSensitive)) { - const name = combinePaths(path, current); - const absoluteName = combinePaths(absolutePath, current); - if (extensions && !fileExtensionIsOneOf(name, extensions)) continue; - if (excludeRegex && excludeRegex.test(absoluteName)) continue; - if (!includeFileRegexes) { - results[0].push(name); - } - else { - const includeIndex = findIndex(includeFileRegexes, re => re.test(absoluteName)); - if (includeIndex !== -1) { - results[includeIndex].push(name); - } - } - } - - if (depth !== undefined) { - depth--; - if (depth === 0) { - return; - } - } - - for (const current of sort(directories, compareStringsCaseSensitive)) { - const name = combinePaths(path, current); - const absoluteName = combinePaths(absolutePath, current); - if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) && - (!excludeRegex || !excludeRegex.test(absoluteName))) { - visitDirectory(name, absoluteName, depth); - } - } - } -} - -/** - * Computes the unique non-wildcard base paths amongst the provided include patterns. - */ -function getBasePaths(path: string, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean): string[] { - // Storage for our results in the form of literal paths (e.g. the paths as written by the user). - const basePaths: string[] = [path]; - - if (includes) { - // Storage for literal base paths amongst the include patterns. - const includeBasePaths: string[] = []; - for (const include of includes) { - // We also need to check the relative paths by converting them to absolute and normalizing - // in case they escape the base path (e.g "..\somedirectory") - const absolute: string = isRootedDiskPath(include) ? include : normalizePath(combinePaths(path, include)); - // Append the literal and canonical candidate base paths. - includeBasePaths.push(getIncludeBasePath(absolute)); - } - - // Sort the offsets array using either the literal or canonical path representations. - includeBasePaths.sort(getStringComparer(!useCaseSensitiveFileNames)); - - // Iterate over each include base path and include unique base paths that are not a - // subpath of an existing base path - for (const includeBasePath of includeBasePaths) { - if (every(basePaths, basePath => !containsPath(basePath, includeBasePath, path, !useCaseSensitiveFileNames))) { - basePaths.push(includeBasePath); - } - } - } - - return basePaths; -} - -function getIncludeBasePath(absolute: string): string { - const wildcardOffset = indexOfAnyCharCode(absolute, wildcardCharCodes); - if (wildcardOffset < 0) { - // No "*" or "?" in the path - return !hasExtension(absolute) - ? absolute - : removeTrailingDirectorySeparator(getDirectoryPath(absolute)); - } - return absolute.substring(0, absolute.lastIndexOf(directorySeparator, wildcardOffset)); -} - -/** @internal */ -export function ensureScriptKind(fileName: string, scriptKind: ScriptKind | undefined): ScriptKind { - // Using scriptKind as a condition handles both: - // - 'scriptKind' is unspecified and thus it is `undefined` - // - 'scriptKind' is set and it is `Unknown` (0) - // If the 'scriptKind' is 'undefined' or 'Unknown' then we attempt - // to get the ScriptKind from the file name. If it cannot be resolved - // from the file name then the default 'TS' script kind is returned. - return scriptKind || getScriptKindFromFileName(fileName) || ScriptKind.TS; +export function ensureScriptKind(fileName: string, scriptKind: ScriptKind | undefined): ScriptKind { + // Using scriptKind as a condition handles both: + // - 'scriptKind' is unspecified and thus it is `undefined` + // - 'scriptKind' is set and it is `Unknown` (0) + // If the 'scriptKind' is 'undefined' or 'Unknown' then we attempt + // to get the ScriptKind from the file name. If it cannot be resolved + // from the file name then the default 'TS' script kind is returned. + return scriptKind || getScriptKindFromFileName(fileName) || ScriptKind.TS; } /** @internal */ @@ -8536,76 +7557,6 @@ export function usesExtensionsOnImports({ imports }: SourceFile, hasExtension: ( return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasExtension(text) : undefined) || false; } -/** @internal */ -export function getModuleSpecifierEndingPreference(preference: UserPreferences["importModuleSpecifierEnding"], resolutionMode: ResolutionMode, compilerOptions: CompilerOptions, sourceFile: SourceFile): ModuleSpecifierEnding { - if (preference === "js" || resolutionMode === ModuleKind.ESNext) { - // Extensions are explicitly requested or required. Now choose between .js and .ts. - if (!shouldAllowImportingTsExtension(compilerOptions)) { - return ModuleSpecifierEnding.JsExtension; - } - // `allowImportingTsExtensions` is a strong signal, so use .ts unless the file - // already uses .js extensions and no .ts extensions. - return inferPreference() !== ModuleSpecifierEnding.JsExtension - ? ModuleSpecifierEnding.TsExtension - : ModuleSpecifierEnding.JsExtension; - } - if (preference === "minimal") { - return ModuleSpecifierEnding.Minimal; - } - if (preference === "index") { - return ModuleSpecifierEnding.Index; - } - - // No preference was specified. - // Look at imports and/or requires to guess whether .js, .ts, or extensionless imports are preferred. - // N.B. that `Index` detection is not supported since it would require file system probing to do - // accurately, and more importantly, literally nobody wants `Index` and its existence is a mystery. - if (!shouldAllowImportingTsExtension(compilerOptions)) { - // If .ts imports are not valid, we only need to see one .js import to go with that. - return usesExtensionsOnImports(sourceFile) ? ModuleSpecifierEnding.JsExtension : ModuleSpecifierEnding.Minimal; - } - - return inferPreference(); - - function inferPreference() { - let usesJsExtensions = false; - const specifiers = sourceFile.imports.length ? sourceFile.imports.map(i => i.text) : - isSourceFileJS(sourceFile) ? getRequiresAtTopOfFile(sourceFile).map(r => r.arguments[0].text) : - emptyArray; - for (const specifier of specifiers) { - if (pathIsRelative(specifier)) { - if (hasTSFileExtension(specifier)) { - return ModuleSpecifierEnding.TsExtension; - } - if (hasJSFileExtension(specifier)) { - usesJsExtensions = true; - } - } - } - return usesJsExtensions ? ModuleSpecifierEnding.JsExtension : ModuleSpecifierEnding.Minimal; - } -} - -function getRequiresAtTopOfFile(sourceFile: SourceFile): readonly RequireOrImportCall[] { - let nonRequireStatementCount = 0; - let requires: RequireOrImportCall[] | undefined; - for (const statement of sourceFile.statements) { - if (nonRequireStatementCount > 3) { - break; - } - if (isRequireVariableStatement(statement)) { - requires = concatenate(requires, statement.declarationList.declarations.map(d => d.initializer)); - } - else if (isExpressionStatement(statement) && isRequireCall(statement.expression, /*requireStringLiteralLikeArgument*/ true)) { - requires = append(requires, statement.expression); - } - else { - nonRequireStatementCount++; - } - } - return requires || emptyArray; -} - /** @internal */ export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]) { if (!fileName) return false; @@ -8683,13 +7634,6 @@ export function tryParsePatterns(paths: MapLike): (string | Pattern)[] return mapDefined(getOwnKeys(paths), path => tryParsePattern(path)); } -/** @internal */ -export function positionIsSynthesized(pos: number): boolean { - // This is a fast way of testing the following conditions: - // pos === undefined || pos === null || isNaN(pos) || pos < 0; - return !(pos >= 0); -} - /** * True if an extension is one of the supported TypeScript extensions. * @@ -8730,13 +7674,6 @@ export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs; } -/** @internal */ -export const emptyFileSystemEntries: FileSystemEntries = { - files: emptyArray, - directories: emptyArray -}; - - /** * patternOrStrings contains both patterns (containing "*") and regular strings. * Return an exact match if possible, or a pattern match, or undefined. @@ -8759,9 +7696,6 @@ export function matchPatternOrExact(patternOrStrings: readonly (string | Pattern return findBestPatternMatch(patterns, _ => _, candidate); } -/** @internal */ -export type Mutable = { -readonly [K in keyof T]: T[K] }; - /** @internal */ export function sliceAfter(arr: readonly T[], value: T): readonly T[] { const index = arr.indexOf(value); @@ -8832,79 +7766,6 @@ export function isJsonEqual(a: unknown, b: unknown): boolean { return a === b || typeof a === "object" && a !== null && typeof b === "object" && b !== null && equalOwnProperties(a as MapLike, b as MapLike, isJsonEqual); } -/** - * Converts a bigint literal string, e.g. `0x1234n`, - * to its decimal string representation, e.g. `4660`. - * - * @internal - */ -export function parsePseudoBigInt(stringValue: string): string { - let log2Base: number; - switch (stringValue.charCodeAt(1)) { // "x" in "0x123" - case CharacterCodes.b: - case CharacterCodes.B: // 0b or 0B - log2Base = 1; - break; - case CharacterCodes.o: - case CharacterCodes.O: // 0o or 0O - log2Base = 3; - break; - case CharacterCodes.x: - case CharacterCodes.X: // 0x or 0X - log2Base = 4; - break; - default: // already in decimal; omit trailing "n" - const nIndex = stringValue.length - 1; - // Skip leading 0s - let nonZeroStart = 0; - while (stringValue.charCodeAt(nonZeroStart) === CharacterCodes._0) { - nonZeroStart++; - } - return stringValue.slice(nonZeroStart, nIndex) || "0"; - } - - // Omit leading "0b", "0o", or "0x", and trailing "n" - const startIndex = 2, endIndex = stringValue.length - 1; - const bitsNeeded = (endIndex - startIndex) * log2Base; - // Stores the value specified by the string as a LE array of 16-bit integers - // using Uint16 instead of Uint32 so combining steps can use bitwise operators - const segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0)); - // Add the digits, one at a time - for (let i = endIndex - 1, bitOffset = 0; i >= startIndex; i--, bitOffset += log2Base) { - const segment = bitOffset >>> 4; - const digitChar = stringValue.charCodeAt(i); - // Find character range: 0-9 < A-F < a-f - const digit = digitChar <= CharacterCodes._9 - ? digitChar - CharacterCodes._0 - : 10 + digitChar - - (digitChar <= CharacterCodes.F ? CharacterCodes.A : CharacterCodes.a); - const shiftedDigit = digit << (bitOffset & 15); - segments[segment] |= shiftedDigit; - const residual = shiftedDigit >>> 16; - if (residual) segments[segment + 1] |= residual; // overflows segment - } - // Repeatedly divide segments by 10 and add remainder to base10Value - let base10Value = ""; - let firstNonzeroSegment = segments.length - 1; - let segmentsRemaining = true; - while (segmentsRemaining) { - let mod10 = 0; - segmentsRemaining = false; - for (let segment = firstNonzeroSegment; segment >= 0; segment--) { - const newSegment = mod10 << 16 | segments[segment]; - const segmentValue = (newSegment / 10) | 0; - segments[segment] = segmentValue; - mod10 = newSegment - segmentValue * 10; - if (segmentValue && !segmentsRemaining) { - firstNonzeroSegment = segment; - segmentsRemaining = true; - } - } - base10Value = mod10 + base10Value; - } - return base10Value; -} - /** @internal */ export function pseudoBigIntToString({negative, base10Value}: PseudoBigInt): string { return (negative && base10Value !== "0" ? "-" : "") + base10Value; @@ -9070,78 +7931,6 @@ export function setNodeFlags(node: T | undefined, newFlags: Node return node; } -/** - * Bypasses immutability and directly sets the `parent` property of a `Node`. - * - * @internal - */ -export function setParent(child: T, parent: T["parent"] | undefined): T; -/** @internal */ -export function setParent(child: T | undefined, parent: T["parent"] | undefined): T | undefined; -/** @internal */ -export function setParent(child: T | undefined, parent: T["parent"] | undefined): T | undefined { - if (child && parent) { - (child as Mutable).parent = parent; - } - return child; -} - -/** - * Bypasses immutability and directly sets the `parent` property of each `Node` in an array of nodes, if is not already set. - * - * @internal - */ -export function setEachParent(children: T, parent: T[number]["parent"]): T; -/** @internal */ -export function setEachParent(children: T | undefined, parent: T[number]["parent"]): T | undefined; -/** @internal */ -export function setEachParent(children: T | undefined, parent: T[number]["parent"]): T | undefined { - if (children) { - for (const child of children) { - setParent(child, parent); - } - } - return children; -} - -/** - * Bypasses immutability and directly sets the `parent` property of each `Node` recursively. - * @param rootNode The root node from which to start the recursion. - * @param incremental When `true`, only recursively descends through nodes whose `parent` pointers are incorrect. - * This allows us to quickly bail out of setting `parent` for subtrees during incremental parsing. - * - * @internal - */ -export function setParentRecursive(rootNode: T, incremental: boolean): T; -/** @internal */ -export function setParentRecursive(rootNode: T | undefined, incremental: boolean): T | undefined; -/** @internal */ -export function setParentRecursive(rootNode: T | undefined, incremental: boolean): T | undefined { - if (!rootNode) return rootNode; - forEachChildRecursively(rootNode, isJSDocNode(rootNode) ? bindParentToChildIgnoringJSDoc : bindParentToChild); - return rootNode; - - function bindParentToChildIgnoringJSDoc(child: Node, parent: Node): void | "skip" { - if (incremental && child.parent === parent) { - return "skip"; - } - setParent(child, parent); - } - - function bindJSDoc(child: Node) { - if (hasJSDocNodes(child)) { - for (const doc of child.jsDoc!) { - bindParentToChildIgnoringJSDoc(doc, child); - forEachChildRecursively(doc, bindParentToChildIgnoringJSDoc); - } - } - } - - function bindParentToChild(child: Node, parent: Node) { - return bindParentToChildIgnoringJSDoc(child, parent) || bindJSDoc(child); - } -} - function isPackedElement(node: Expression) { return !isOmittedExpression(node); } @@ -9195,11 +7984,6 @@ export function expressionResultIsUnused(node: Expression): boolean { } } -/** @internal */ -export function containsIgnoredPath(path: string) { - return some(ignoredPaths, p => stringContains(path, p)); -} - /** @internal */ export function getContainingNodeArray(node: Node): NodeArray | undefined { if (!node.parent) return undefined; @@ -9344,84 +8128,11 @@ export function isNumericLiteralName(name: string | __String) { return (+name).toString() === name; } -/** @internal */ -export function createPropertyNameNodeForIdentifierOrLiteral(name: string, target: ScriptTarget, singleQuote?: boolean, stringNamed?: boolean) { - return isIdentifierText(name, target) ? factory.createIdentifier(name) : - !stringNamed && isNumericLiteralName(name) && +name >= 0 ? factory.createNumericLiteral(+name) : - factory.createStringLiteral(name, !!singleQuote); -} - /** @internal */ export function isThisTypeParameter(type: Type): boolean { return !!(type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType); } -/** @internal */ -export interface NodeModulePathParts { - readonly topLevelNodeModulesIndex: number; - readonly topLevelPackageNameIndex: number; - readonly packageRootIndex: number; - readonly fileNameIndex: number; -} -/** @internal */ -export function getNodeModulePathParts(fullPath: string): NodeModulePathParts | undefined { - // If fullPath can't be valid module file within node_modules, returns undefined. - // Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js - // Returns indices: ^ ^ ^ ^ - - let topLevelNodeModulesIndex = 0; - let topLevelPackageNameIndex = 0; - let packageRootIndex = 0; - let fileNameIndex = 0; - - const enum States { - BeforeNodeModules, - NodeModules, - Scope, - PackageContent - } - - let partStart = 0; - let partEnd = 0; - let state = States.BeforeNodeModules; - - while (partEnd >= 0) { - partStart = partEnd; - partEnd = fullPath.indexOf("/", partStart + 1); - switch (state) { - case States.BeforeNodeModules: - if (fullPath.indexOf(nodeModulesPathPart, partStart) === partStart) { - topLevelNodeModulesIndex = partStart; - topLevelPackageNameIndex = partEnd; - state = States.NodeModules; - } - break; - case States.NodeModules: - case States.Scope: - if (state === States.NodeModules && fullPath.charAt(partStart + 1) === "@") { - state = States.Scope; - } - else { - packageRootIndex = partEnd; - state = States.PackageContent; - } - break; - case States.PackageContent: - if (fullPath.indexOf(nodeModulesPathPart, partStart) === partStart) { - state = States.NodeModules; - } - else { - state = States.PackageContent; - } - break; - } - } - - fileNameIndex = partStart; - - return state > States.NodeModules ? { topLevelNodeModulesIndex, topLevelPackageNameIndex, packageRootIndex, fileNameIndex } : undefined; -} - /** @internal */ export function getParameterTypeNode(parameter: ParameterDeclaration | JSDocParameterTag) { return parameter.kind === SyntaxKind.JSDocParameterTag ? parameter.typeExpression?.type : parameter.type; @@ -9449,12 +8160,6 @@ export function isTypeDeclaration(node: Node): node is TypeParameterDeclaration } } -/** @internal */ -export function canHaveExportModifier(node: Node): node is Extract { - return isEnumDeclaration(node) || isVariableStatement(node) || isFunctionDeclaration(node) || isClassDeclaration(node) - || isInterfaceDeclaration(node) || isTypeDeclaration(node) || (isModuleDeclaration(node) && !isExternalModuleAugmentation(node) && !isGlobalScopeAugmentation(node)); -} - /** @internal */ export function isOptionalJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag { if (!isJSDocPropertyLikeTag(node)) { @@ -9616,3 +8321,53 @@ export function canHaveIllegalTypeParameters(node: Node): node is HasIllegalType || kind === SyntaxKind.GetAccessor || kind === SyntaxKind.SetAccessor; } + +/** @internal */ +export function isModuleAugmentationExternal(node: AmbientModuleDeclaration) { + // external module augmentation is a ambient module declaration that is either: + // - defined in the top level scope and source file is an external module + // - defined inside ambient module declaration located in the top level scope and source file not an external module + switch (node.parent.kind) { + case SyntaxKind.SourceFile: + return isExternalModule(node.parent); + case SyntaxKind.ModuleBlock: + return isAmbientModule(node.parent.parent) && isSourceFile(node.parent.parent.parent) && !isExternalModule(node.parent.parent.parent); + } + return false; +} + +/** @internal */ +export function isExternalModuleAugmentation(node: Node): node is AmbientModuleDeclaration { + return isAmbientModule(node) && isModuleAugmentationExternal(node); +} + +/** @internal */ +export function isAmbientModule(node: Node): node is AmbientModuleDeclaration { + return isModuleDeclaration(node) && (node.name.kind === SyntaxKind.StringLiteral || isGlobalScopeAugmentation(node)); +} + +/** @internal */ +export function isGlobalScopeAugmentation(module: ModuleDeclaration): boolean { + return !!(module.flags & NodeFlags.GlobalAugmentation); +} + +/** @internal */ +export function getNonAugmentationDeclaration(symbol: Symbol) { + return symbol.declarations?.find(d => !isExternalModuleAugmentation(d) && !(isModuleDeclaration(d) && isGlobalScopeAugmentation(d))); +} + +/** @internal */ +export function getSourceFileOfModule(module: Symbol) { + return getSourceFileOfNode(module.valueDeclaration || getNonAugmentationDeclaration(module)); +} + +/** @internal */ +export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) { + return isExternalModule(node) || compilerOptions.isolatedModules || (isCommonJSContainingModuleKind(getEmitModuleKind(compilerOptions)) && !!node.commonJsModuleIndicator); +} + +/** @internal */ +export function canHaveExportModifier(node: Node): node is Extract { + return isEnumDeclaration(node) || isVariableStatement(node) || isFunctionDeclaration(node) || isClassDeclaration(node) + || isInterfaceDeclaration(node) || isTypeDeclaration(node) || (isModuleDeclaration(node) && !isExternalModuleAugmentation(node) && !isGlobalScopeAugmentation(node)); +} diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 1e3fcd6090878..5bc9b440e1b20 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -31,6 +31,10 @@ import { import { SortedReadonlyArray } from "./corePublic"; import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { + getPatternFromSpec, + getRegexFromPattern, +} from "./fileMatcher"; import { combinePaths, convertToRelativePath, @@ -61,11 +65,10 @@ import { whitespaceOrMapCommentRegExp, } from "./sourcemap"; import { - FileWatcher, generateDjb2Hash, sys, - System, } from "./sys"; +import { getNewLineCharacter } from "./sysUtilities"; import { ReportEmitErrorSummary, ReportFileInError, @@ -86,12 +89,14 @@ import { FileExtensionInfo, FileIncludeKind, FileIncludeReason, + FileWatcher, HasCurrentDirectory, ModuleKind, ParsedCommandLine, Program, ProjectReference, SourceFile, + System, WatchOptions, WriteFileCallback, } from "./types"; @@ -101,9 +106,6 @@ import { externalHelpersModuleNameText, forEachEntry, getEmitScriptTarget, - getNewLineCharacter, - getPatternFromSpec, - getRegexFromPattern, isExternalOrCommonJsModule, outFile, packageIdToString, diff --git a/src/compiler/watchPublic.ts b/src/compiler/watchPublic.ts index e880bc65a9641..a2ed6eac71d51 100644 --- a/src/compiler/watchPublic.ts +++ b/src/compiler/watchPublic.ts @@ -47,27 +47,28 @@ import { isProgramUptoDate, parseConfigHostFromCompilerHostLike, } from "./program"; +import { changesAffectModuleResolution } from "./programUtilities"; import { createResolutionCache, ResolutionCacheHost, } from "./resolutionCache"; import { - DirectoryWatcherCallback, - FileWatcher, - FileWatcherCallback, - FileWatcherEventKind, PollingInterval, sys, - System, } from "./sys"; +import { getNewLineCharacter } from "./sysUtilities"; import { BuildInfo, CompilerHost, CompilerOptions, Diagnostic, DiagnosticMessage, + DirectoryWatcherCallback, FileExtensionInfo, FileReference, + FileWatcher, + FileWatcherCallback, + FileWatcherEventKind, HasInvalidatedResolutions, ParsedCommandLine, Path, @@ -81,15 +82,14 @@ import { ScriptTarget, SourceFile, StringLiteralLike, + System, WatchDirectoryFlags, WatchOptions, } from "./types"; import { - changesAffectModuleResolution, clearMap, closeFileWatcher, createCompilerDiagnostic, - getNewLineCharacter, } from "./utilities"; import { createCompilerHostFromProgramHost, diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index fbe14dd6f2875..62410faec47ab 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -23,6 +23,11 @@ import { SortedReadonlyArray, } from "./corePublic"; import { Debug } from "./debug"; +import { + emptyFileSystemEntries, + FileSystemEntries, + matchFiles, +} from "./fileMatcher"; import { isDeclarationFileName } from "./parser"; import { ensureTrailingDirectorySeparator, @@ -37,17 +42,17 @@ import { import { timestamp } from "./performanceCore"; import { removeIgnoredPath } from "./resolutionCache"; import { - DirectoryWatcherCallback, - FileWatcher, - FileWatcherCallback, - FileWatcherEventKind, PollingInterval, setSysLog, } from "./sys"; import { CompilerOptions, + DirectoryWatcherCallback, Extension, FileExtensionInfo, + FileWatcher, + FileWatcherCallback, + FileWatcherEventKind, Path, Program, WatchDirectoryFlags, @@ -56,10 +61,7 @@ import { } from "./types"; import { closeFileWatcher, - emptyFileSystemEntries, - FileSystemEntries, isSupportedSourceFileName, - matchFiles, mutateMap, outFile, removeFileExtension, diff --git a/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts b/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts index 966af1552b15a..d1bc895136346 100644 --- a/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts +++ b/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts @@ -2,6 +2,7 @@ import { Debug } from "../../compiler/debug"; import { factory } from "../../compiler/factory/nodeFactory"; import { setTextRange } from "../../compiler/factory/utilitiesPublic"; import { parseBaseNodeFactory } from "../../compiler/parser"; +import { setParent } from "../../compiler/parserUtilities"; import { ArrowFunction, AsteriskToken, @@ -32,6 +33,7 @@ import { JSDocTypeExpression, MethodSignature, Modifier, + Mutable, NamedExportBindings, NamedImportBindings, Node, @@ -59,11 +61,7 @@ import { VariableDeclaration, YieldExpression, } from "../../compiler/types"; -import { - Mutable, - setParent, - setTextRangePosEnd, -} from "../../compiler/utilities"; +import { setTextRangePosEnd } from "../../compiler/utilities"; import { isNodeKind } from "../../compiler/utilitiesPublic"; import { deprecate } from "../deprecate"; import { DeprecationOptions } from "../deprecations"; diff --git a/src/executeCommandLine/executeCommandLine.ts b/src/executeCommandLine/executeCommandLine.ts index 794894b67cc6a..f47112580f01b 100644 --- a/src/executeCommandLine/executeCommandLine.ts +++ b/src/executeCommandLine/executeCommandLine.ts @@ -52,10 +52,7 @@ import { getConfigFileParsingDiagnostics, } from "../compiler/program"; import { getLineStarts } from "../compiler/scanner"; -import { - sys, - System, -} from "../compiler/sys"; +import { sys } from "../compiler/sys"; import { dumpTracingLegend, startTracing, @@ -85,6 +82,7 @@ import { ParsedCommandLine, Program, SourceFile, + System, WatchOptions, } from "../compiler/types"; import { @@ -1062,7 +1060,7 @@ interface SolutionPerformance { function enableSolutionPerformance(system: System, options: BuildOptions) { if (system === sys && options.extendedDiagnostics) { - performance.enable(); + performance.enable(sys); return createSolutionPerfomrance(); } } @@ -1120,7 +1118,7 @@ function reportSolutionBuilderTimes( if (isSolutionMarkOrMeasure(name)) statistics.push({ name: `${getNameFromSolutionBuilderMarkOrMeasure(name)} time`, value: duration, type: StatisticType.time }); }); performance.disable(); - performance.enable(); + performance.enable(sys); solutionPerformance.clear(); reportAllStatistics(sys, statistics); diff --git a/src/harness/fakesHosts.ts b/src/harness/fakesHosts.ts index 8bafb0a902934..53da820e45f70 100644 --- a/src/harness/fakesHosts.ts +++ b/src/harness/fakesHosts.ts @@ -5,6 +5,8 @@ import * as vpath from "./_namespaces/vpath"; import * as documents from "./_namespaces/documents"; import * as collections from "./_namespaces/collections"; import * as Harness from "./_namespaces/Harness"; +import { getNewLineCharacter } from "../compiler/sysUtilities"; +import { FileSystemEntries, matchFiles } from "../compiler/fileMatcher"; /** * Fake implementations of various compiler dependencies. @@ -104,10 +106,10 @@ export class System implements ts.System { } public readDirectory(path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number): string[] { - return ts.matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, path => this.getAccessibleFileSystemEntries(path), path => this.realpath(path)); + return matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, path => this.getAccessibleFileSystemEntries(path), path => this.realpath(path)); } - public getAccessibleFileSystemEntries(path: string): ts.FileSystemEntries { + public getAccessibleFileSystemEntries(path: string): FileSystemEntries { const files: string[] = []; const directories: string[] = []; try { @@ -243,7 +245,7 @@ export class CompilerHost implements ts.CompilerHost { if (sys instanceof vfs.FileSystem) sys = new System(sys); this.sys = sys; this.defaultLibLocation = sys.vfs.meta.get("defaultLibLocation") || ""; - this._newLine = ts.getNewLineCharacter(options, () => this.sys.newLine); + this._newLine = getNewLineCharacter(options, () => this.sys.newLine); this._sourceFiles = new collections.SortedMap({ comparer: sys.vfs.stringComparer, sort: "insertion" }); this._setParentNodes = setParentNodes; this._outputsMap = new collections.SortedMap(this.vfs.stringComparer); diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 10fbc691e167c..f91569d7212ac 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -6,6 +6,7 @@ import * as fakes from "./_namespaces/fakes"; import * as vpath from "./_namespaces/vpath"; import * as Utils from "./_namespaces/Utils"; import { applyChanges } from "../services/textChanges"; +import { regExpEscape } from "../compiler/fileMatcher"; import ArrayOrSingle = FourSlashInterface.ArrayOrSingle; @@ -4635,7 +4636,7 @@ function displayExpectedAndActualString(expected: string, actual: string, quoted } function templateToRegExp(template: string) { - return new RegExp(`^${ts.regExpEscape(template).replace(/\\\{\d+\\\}/g, ".*?")}$`); + return new RegExp(`^${regExpEscape(template).replace(/\\\{\d+\\\}/g, ".*?")}$`); } function rangesOfDiffBetweenTwoStrings(source: string, target: string) { diff --git a/src/harness/harnessIO.ts b/src/harness/harnessIO.ts index 12cf357770963..9b436e79fa5fb 100644 --- a/src/harness/harnessIO.ts +++ b/src/harness/harnessIO.ts @@ -10,6 +10,7 @@ import { TypeWriterResult, TypeWriterWalker, } from "./_namespaces/Harness"; +import { FileSystemEntries } from "../compiler/fileMatcher"; export interface IO { newLine(): string; @@ -33,7 +34,7 @@ export interface IO { getWorkspaceRoot(): string; exit(exitCode?: number): void; readDirectory(path: string, extension?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number): readonly string[]; - getAccessibleFileSystemEntries(dirname: string): ts.FileSystemEntries; + getAccessibleFileSystemEntries(dirname: string): FileSystemEntries; tryEnableSourceMapsForHost?(): void; getEnvironmentVariable?(name: string): string; getMemoryUsage?(): number | undefined; @@ -106,7 +107,7 @@ function createNodeIO(): IO { return filesInFolder(path); } - function getAccessibleFileSystemEntries(dirname: string): ts.FileSystemEntries { + function getAccessibleFileSystemEntries(dirname: string): FileSystemEntries { try { const entries: string[] = fs.readdirSync(dirname || ".").sort(ts.sys.useCaseSensitiveFileNames ? ts.compareStringsCaseSensitive : ts.compareStringsCaseInsensitive); const files: string[] = []; diff --git a/src/harness/harnessUtils.ts b/src/harness/harnessUtils.ts index 718d7de802937..fc3654bb987fc 100644 --- a/src/harness/harnessUtils.ts +++ b/src/harness/harnessUtils.ts @@ -1,5 +1,6 @@ import * as ts from "./_namespaces/ts"; import * as Harness from "./_namespaces/Harness"; +import { containsParseError } from "../compiler/parserUtilities"; export function encodeString(s: string): string { return ts.sys.bufferFrom!(s).toString("utf8"); @@ -185,7 +186,7 @@ export function sourceFileToJSON(file: ts.Node): string { function serializeNode(n: ts.Node): any { const o: any = { kind: getKindName(n.kind) }; - if (ts.containsParseError(n)) { + if (containsParseError(n)) { o.containsParseError = true; } @@ -288,7 +289,7 @@ export function assertStructuralEquals(node1: ts.Node, node2: ts.Node) { // call this on both nodes to ensure all propagated flags have been set (and thus can be // compared). - assert.equal(ts.containsParseError(node1), ts.containsParseError(node2)); + assert.equal(containsParseError(node1), containsParseError(node2)); assert.equal(node1.flags & ~ts.NodeFlags.ReachabilityAndEmitFlags, node2.flags & ~ts.NodeFlags.ReachabilityAndEmitFlags, "node1.flags !== node2.flags"); ts.forEachChild(node1, diff --git a/src/harness/util.ts b/src/harness/util.ts index 2dac1835f1293..8e9e5f84d32ab 100644 --- a/src/harness/util.ts +++ b/src/harness/util.ts @@ -1,3 +1,4 @@ +import { regExpEscape } from "../compiler/fileMatcher"; import * as ts from "./_namespaces/ts"; /** @@ -11,7 +12,7 @@ export function removeTestPathPrefixes(text: string, retainTrailingDirectorySepa function createDiagnosticMessageReplacer string[]>(diagnosticMessage: ts.DiagnosticMessage, replacer: R) { const messageParts = diagnosticMessage.message.split(/{\d+}/g); - const regExp = new RegExp(`^(?:${messageParts.map(ts.regExpEscape).join("(.*?)")})$`); + const regExp = new RegExp(`^(?:${messageParts.map(regExpEscape).join("(.*?)")})$`); type Args = R extends (messageArgs: string[], ...args: infer A) => string[] ? A : []; return (text: string, ...args: Args) => text.replace(regExp, (_, ...fixedArgs) => ts.formatStringFromArgs(diagnosticMessage.message, replacer(fixedArgs, ...args))); } diff --git a/src/harness/vfsUtil.ts b/src/harness/vfsUtil.ts index 4547e378cf368..701e9d78cb303 100644 --- a/src/harness/vfsUtil.ts +++ b/src/harness/vfsUtil.ts @@ -3,6 +3,7 @@ import * as ts from "./_namespaces/ts"; import * as vpath from "./_namespaces/vpath"; import * as documents from "./_namespaces/documents"; import * as Harness from "./_namespaces/Harness"; +import { FileSystemEntries } from "../compiler/fileMatcher"; /** * Posix-style path to the TypeScript compiler build outputs (including tsc.js, lib.d.ts, etc.) @@ -1212,7 +1213,7 @@ export interface FileSystemResolver { export interface FileSystemResolverHost { useCaseSensitiveFileNames(): boolean; - getAccessibleFileSystemEntries(path: string): ts.FileSystemEntries; + getAccessibleFileSystemEntries(path: string): FileSystemEntries; directoryExists(path: string): boolean; fileExists(path: string): boolean; getFileSize(path: string): number; diff --git a/src/jsTyping/types.ts b/src/jsTyping/types.ts index c0a30c78cff16..0c82289a2bae2 100644 --- a/src/jsTyping/types.ts +++ b/src/jsTyping/types.ts @@ -3,12 +3,10 @@ import { SortedReadonlyArray, } from "../compiler/corePublic"; import { + CompilerOptions, DirectoryWatcherCallback, FileWatcher, FileWatcherCallback, -} from "../compiler/sys"; -import { - CompilerOptions, Path, TypeAcquisition, WatchOptions, diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 95f4a3bf9ac18..64a84199dd4ea 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -14,7 +14,6 @@ import { import { arrayFrom, arrayToMap, - AssertionLevel, contains, createGetCanonicalFileName, createMultiMap, @@ -44,7 +43,7 @@ import { ReadonlyCollection, version, } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; +import { AssertionLevel, Debug } from "../compiler/debug"; import { parsePackageName } from "../compiler/moduleNameResolver"; import { parseJsonText } from "../compiler/parser"; import { @@ -74,8 +73,6 @@ import { removeIgnoredPath, } from "../compiler/resolutionCache"; import { - FileWatcher, - FileWatcherEventKind, getFileWatcherEventKind, missingFileModifiedTime, PollingInterval, @@ -88,6 +85,8 @@ import { DocumentPosition, DocumentPositionMapper, FileExtensionInfo, + FileWatcher, + FileWatcherEventKind, ParsedCommandLine, Path, PluginImport, diff --git a/src/server/moduleSpecifierCache.ts b/src/server/moduleSpecifierCache.ts index 6d0e40655a053..c081948391815 100644 --- a/src/server/moduleSpecifierCache.ts +++ b/src/server/moduleSpecifierCache.ts @@ -1,7 +1,7 @@ import { Debug } from "../compiler/debug"; import { nodeModulesPathPart } from "../compiler/moduleNameResolver"; -import { FileWatcher } from "../compiler/sys"; import { + FileWatcher, ModulePath, ModuleSpecifierCache, ModuleSpecifierOptions, diff --git a/src/server/project.ts b/src/server/project.ts index f97c1b400d195..3dc3630661141 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -56,10 +56,6 @@ import { ResolutionCache, } from "../compiler/resolutionCache"; import { - DirectoryWatcherCallback, - FileWatcher, - FileWatcherCallback, - FileWatcherEventKind, generateDjb2Hash, PollingInterval, } from "../compiler/sys"; @@ -68,9 +64,13 @@ import { CompilerHost, CompilerOptions, Diagnostic, + DirectoryWatcherCallback, DocumentPositionMapper, Extension, FileReference, + FileWatcher, + FileWatcherCallback, + FileWatcherEventKind, HasInvalidatedResolutions, ModuleResolutionHost, ParsedCommandLine, @@ -90,10 +90,8 @@ import { WatchOptions, } from "../compiler/types"; import { - changesAffectModuleResolution, clearMap, closeFileWatcher, - createSymlinkCache, forEachEntry, forEachKey, getAllowJSCompilerOption, @@ -103,7 +101,6 @@ import { removeFileExtension, resolutionExtensionIsTSOrJson, stripQuotes, - SymlinkCache, } from "../compiler/utilities"; import { getDefaultLibFileName, @@ -176,6 +173,11 @@ import { ProjectOptions, toNormalizedPath, } from "./utilitiesPublic"; +import { + createSymlinkCache, + SymlinkCache, +} from "../compiler/symlinkCache"; +import { changesAffectModuleResolution } from "../compiler/programUtilities"; export enum ProjectKind { Inferred, diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 14ce880bf5be4..fe197d56daff5 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -23,11 +23,9 @@ import { LineInfo, } from "../compiler/sourcemap"; import { + DocumentPositionMapper, FileWatcher, FileWatcherEventKind, -} from "../compiler/sys"; -import { - DocumentPositionMapper, Path, ScriptKind, SourceFile, diff --git a/src/server/session.ts b/src/server/session.ts index cdd80d2288ee9..60b3e1d29921d 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -43,6 +43,7 @@ import { nodeModulesPathPart, unmangleScopedPackageName, } from "../compiler/moduleNameResolver"; +import { getNodeModulePathParts } from "../compiler/moduleSpecifiersUtilities"; import { isDeclarationFileName } from "../compiler/parser"; import { getNormalizedAbsolutePath, @@ -80,7 +81,6 @@ import { getDeclarationFromName, getDeclarationOfKind, getEmitDeclarations, - getNodeModulePathParts, getTextOfIdentifierOrLiteral, isAccessExpression, outFile, diff --git a/src/server/types.ts b/src/server/types.ts index c18316f1f8a36..1eba4a2255b63 100644 --- a/src/server/types.ts +++ b/src/server/types.ts @@ -1,10 +1,4 @@ -import { - DirectoryWatcherCallback, - FileWatcher, - FileWatcherCallback, - System, -} from "../compiler/sys"; -import { WatchOptions } from "../compiler/types"; +import { DirectoryWatcherCallback, FileWatcher, FileWatcherCallback, System, WatchOptions } from "../compiler/types"; export interface CompressedData { length: number; diff --git a/src/services/classifier.ts b/src/services/classifier.ts index b87d1d090bc98..fe2879ebda913 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -16,6 +16,7 @@ import { isModuleDeclaration, } from "../compiler/factory/nodeTests"; import { parseIsolatedJSDocComment } from "../compiler/parser"; +import { setParent } from "../compiler/parserUtilities"; import { couldStartTrivia, createScanner, @@ -65,7 +66,6 @@ import { isThisIdentifier, isTrivia, nodeIsMissing, - setParent, } from "../compiler/utilities"; import { createTextSpan, diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index d41a91c0e1932..241c1af610cf8 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -31,6 +31,7 @@ import { isVariableDeclaration, } from "../../compiler/factory/nodeTests"; import { forEachChild } from "../../compiler/parser"; +import { forEachReturnStatement } from "../../compiler/parserUtilities"; import { skipTrivia } from "../../compiler/scanner"; import { ArrowFunction, @@ -63,7 +64,6 @@ import { UnionReduction, } from "../../compiler/types"; import { - forEachReturnStatement, getContainingFunction, getObjectFlags, isInJSFile, diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 227ce6e796fb8..f00faaa4bd26f 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -43,6 +43,8 @@ import { isSourceFile, isTypeLiteralNode, } from "../../compiler/factory/nodeTests"; +import { createPropertyNameNodeForIdentifierOrLiteral } from "../../compiler/factory/utilities"; +import { setParent } from "../../compiler/parserUtilities"; import { isIdentifierText } from "../../compiler/scanner"; import { __String, @@ -88,7 +90,6 @@ import { } from "../../compiler/types"; import { addToSeen, - createPropertyNameNodeForIdentifierOrLiteral, getCheckFlags, getClassLikeDeclarationOfSymbol, getEmitScriptTarget, @@ -98,7 +99,6 @@ import { hasAbstractModifier, isSourceFileJS, isTransientSymbol, - setParent, } from "../../compiler/utilities"; import { findAncestor, @@ -786,7 +786,7 @@ function createPropertyNameFromSymbol(symbol: Symbol, target: ScriptTarget, quot const prop = checker.symbolToNode(symbol, SymbolFlags.Value, /*enclosingDeclaration*/ undefined, NodeBuilderFlags.WriteComputedProps); if (prop && isComputedPropertyName(prop)) return prop; } - return createPropertyNameNodeForIdentifierOrLiteral(symbol.name, target, quotePreference === QuotePreference.Single); + return createPropertyNameNodeForIdentifierOrLiteral(factory, symbol.name, target, quotePreference === QuotePreference.Single); } function findScope(node: Node) { diff --git a/src/services/codefixes/importAdder.ts b/src/services/codefixes/importAdder.ts index b4078036786db..2fb7c192e8ebd 100644 --- a/src/services/codefixes/importAdder.ts +++ b/src/services/codefixes/importAdder.ts @@ -47,7 +47,6 @@ import { getModuleSpecifiersWithCacheInfo, tryGetModuleSpecifiersFromCache, } from "../../compiler/moduleSpecifiers"; -import { isExternalModule } from "../../compiler/parser"; import { getBaseFileName, getDirectoryPath, @@ -72,6 +71,7 @@ import { InternalSymbolName, ModuleKind, ModuleResolutionKind, + Mutable, NamedImports, Node, NodeFlags, @@ -99,6 +99,7 @@ import { getSourceFileOfNode, hostGetCanonicalFileName, importFromModuleSpecifier, + isExternalModule, isInJSFile, isIntrinsicJsxName, isJSXTagName, @@ -107,7 +108,6 @@ import { isUMDExportSymbol, isValidTypeOnlyAliasUseSite, isVariableDeclarationInitializedToRequire, - Mutable, nodeIsMissing, removeFileExtension, skipAlias, diff --git a/src/services/completions.ts b/src/services/completions.ts index 47eb20b9849b3..8bdcb952369aa 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -102,6 +102,7 @@ import { stringToToken, tokenToString, } from "../compiler/scanner"; +import { getNewLineCharacter } from "../compiler/sysUtilities"; import { isInitializedProperty } from "../compiler/transformers/utilities"; import { __String, @@ -222,7 +223,6 @@ import { getLanguageVariant, getLeftmostAccessExpression, getLocalSymbolForExportDefault, - getNewLineCharacter, getPropertyNameForPropertyNameNode, getRootDeclaration, getSourceFileOfModule, diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index bc0737588fbdf..752b5b241ab1e 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -36,6 +36,7 @@ import { isYieldExpression, } from "../compiler/factory/nodeTests"; import { forEachChild } from "../compiler/parser"; +import { forEachReturnStatement } from "../compiler/parserUtilities"; import { toPath } from "../compiler/path"; import { __String, @@ -65,7 +66,6 @@ import { TryStatement, } from "../compiler/types"; import { - forEachReturnStatement, getContainingFunction, isFunctionBlock, modifierToFlag, diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index d706d97d43bbf..19f4d08d7a07a 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -15,7 +15,7 @@ import { isDeclarationFileName, } from "../compiler/parser"; import { toPath } from "../compiler/path"; -import { getImpliedNodeFormatForFile } from "../compiler/program"; +import { getImpliedNodeFormatForFile, getSetExternalModuleIndicator } from "../compiler/program"; import { tracing } from "../compiler/tracing"; import { CompilerOptions, @@ -30,7 +30,6 @@ import { ensureScriptKind, forEachEntry, getEmitScriptTarget, - getSetExternalModuleIndicator, } from "../compiler/utilities"; import { createLanguageServiceSourceFile, diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index 5fe61b8afae3c..654e17e5e052d 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -17,12 +17,17 @@ import { isExportSpecifier, isIdentifier, } from "../compiler/factory/nodeTests"; +import { + getPatternFromSpec, + getRegexFromPattern, +} from "../compiler/fileMatcher"; import { getPackageNameFromTypesPackageName, nodeModulesPathPart, unmangleScopedPackageName, } from "../compiler/moduleNameResolver"; import { forEachFileNameOfModule } from "../compiler/moduleSpecifiers"; +import { getNodeModulePathParts } from "../compiler/moduleSpecifiersUtilities"; import { forEachAncestorDirectory, getBaseFileName, @@ -49,9 +54,6 @@ import { addToSeen, forEachEntry, getLocalSymbolForExportDefault, - getNodeModulePathParts, - getPatternFromSpec, - getRegexFromPattern, hostGetCanonicalFileName, hostUsesCaseSensitiveFileNames, isExternalOrCommonJsModule, diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 897005ff06bb1..844ff9a8cf638 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -63,10 +63,8 @@ import { isUnionTypeNode, isVoidExpression, } from "../compiler/factory/nodeTests"; -import { - forEachChild, - isExternalModule, -} from "../compiler/parser"; +import { forEachChild } from "../compiler/parser"; +import { forEachReturnStatement } from "../compiler/parserUtilities"; import { getModeForUsageLocation, getReferencedFileLocation, @@ -134,7 +132,6 @@ import { } from "../compiler/types"; import { addToSeen, - forEachReturnStatement, getAllSuperTypeNodes, getAncestor, getAssignmentDeclarationKind, @@ -153,6 +150,7 @@ import { isAccessExpression, isBindableObjectDefinePropertyCall, isDeclarationName, + isExternalModule, isExternalOrCommonJsModule, isImportMeta, isInJSFile, diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index bdd63d71a0a0e..c4ac0063f44e6 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -18,6 +18,10 @@ import { isSourceFile, isStringLiteral, } from "../compiler/factory/nodeTests"; +import { + getFileMatcherPatterns, + getRegexFromPattern, +} from "../compiler/fileMatcher"; import { resolveModuleName } from "../compiler/moduleNameResolver"; import { updateModuleSpecifier } from "../compiler/moduleSpecifiers"; import { @@ -46,8 +50,6 @@ import { } from "../compiler/types"; import { createRange, - getFileMatcherPatterns, - getRegexFromPattern, getTsConfigObjectLiteralExpression, hostUsesCaseSensitiveFileNames, isAmbientModule, diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 740f03a42264e..c6195efe084be 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -24,6 +24,7 @@ import { isJSDoc, isJSDocParameterTag, } from "../compiler/factory/nodeTests"; +import { forEachReturnStatement } from "../compiler/parserUtilities"; import { ArrowFunction, AssignmentDeclarationKind, @@ -63,7 +64,6 @@ import { } from "../compiler/types"; import { forEachAncestor, - forEachReturnStatement, getAssignmentDeclarationKind, getJSDocCommentsAndTags, hasJSFileExtension, diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 1b94f2a404c10..8d13732d1d485 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -30,10 +30,7 @@ import { isVariableDeclaration, } from "../compiler/factory/nodeTests"; import { setTextRange } from "../compiler/factory/utilitiesPublic"; -import { - forEachChild, - isExternalModule, -} from "../compiler/parser"; +import { forEachChild } from "../compiler/parser"; import { getBaseFileName, normalizePath, @@ -96,6 +93,7 @@ import { hasDynamicName, isAmbientModule, isBindableStaticAccessExpression, + isExternalModule, isJSDocTypeAlias, isPropertyNameLiteral, isStatic, diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index a0e554c46a75d..8a723901e8e33 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -54,6 +54,7 @@ import { } from "../../compiler/factory/nodeTests"; import { canHaveModifiers } from "../../compiler/factory/utilitiesPublic"; import { forEachChild } from "../../compiler/parser"; +import { positionIsSynthesized } from "../../compiler/scannerUtilities"; import { nullTransformationContext } from "../../compiler/transformer"; import { __String, @@ -131,7 +132,6 @@ import { isKeyword, isPartOfTypeNode, isStatic, - positionIsSynthesized, skipParentheses, } from "../../compiler/utilities"; import { diff --git a/src/services/services.ts b/src/services/services.ts index f220825382628..7917ed09eeb1e 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -55,6 +55,10 @@ import { isPropertyAccessExpression, } from "../compiler/factory/nodeTests"; import { ModeAwareCache } from "../compiler/moduleNameResolver"; +import { + ObjectAllocator, + setObjectAllocator, +} from "../compiler/objectAllocator"; import { createSourceFile, CreateSourceFileOptions, @@ -74,6 +78,7 @@ import { changeCompilerHostLikeToUseCache, createProgram, getImpliedNodeFormatForFile, + getSetExternalModuleIndicator, isProgramUptoDate, } from "../compiler/program"; import { @@ -81,7 +86,9 @@ import { getLineAndCharacterOfPosition, getLineStarts, } from "../compiler/scanner"; +import { positionIsSynthesized } from "../compiler/scannerUtilities"; import { sys } from "../compiler/sys"; +import { getNewLineCharacter } from "../compiler/sysUtilities"; import { tracing } from "../compiler/tracing"; import { __String, @@ -183,9 +190,7 @@ import { getAssignmentDeclarationKind, getEmitDeclarations, getEscapedTextOfIdentifierOrLiteral, - getNewLineCharacter, getObjectFlags, - getSetExternalModuleIndicator, getSourceFileOfNode, getTokenPosOfNode, hasStaticModifier, @@ -201,9 +206,6 @@ import { isThisTypeParameter, isTransientSymbol, maybeSetLocalizedDiagnosticMessages, - ObjectAllocator, - positionIsSynthesized, - setObjectAllocator, } from "../compiler/utilities"; import { createTextSpanFromBounds, diff --git a/src/services/shims.ts b/src/services/shims.ts index 0cffa98e270f8..bd2c095eed1f4 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -12,6 +12,7 @@ import { toFileNameLowerCase, } from "../compiler/core"; import { MapLike } from "../compiler/corePublic"; +import { getFileMatcherPatterns } from "../compiler/fileMatcher"; import { getAutomaticTypeDirectiveNames, resolveModuleName, @@ -43,10 +44,7 @@ import { TypeAcquisition, UserPreferences, } from "../compiler/types"; -import { - extensionFromPath, - getFileMatcherPatterns, -} from "../compiler/utilities"; +import { extensionFromPath } from "../compiler/utilities"; import { createTextChangeRange, createTextSpan, diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index eea0c5b355e96..6a10ca4825cc5 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -1,3 +1,4 @@ +import { readJson } from "../compiler/commandLineParserUtilities"; import { arrayFrom, compareStringsCaseSensitive, @@ -49,6 +50,7 @@ import { unmangleScopedPackageName, } from "../compiler/moduleNameResolver"; import { tryGetJSExtensionForFile } from "../compiler/moduleSpecifiers"; +import { getModuleSpecifierEndingPreference } from "../compiler/moduleSpecifiersUtilities"; import { altDirectorySeparator, combinePaths, @@ -111,14 +113,12 @@ import { addToSeen, changeExtension, getEmitModuleResolutionKind, - getModuleSpecifierEndingPreference, getResolvePackageJsonExports, getSupportedExtensions, getSupportedExtensionsWithJsonIfResolveJsonModule, hostGetCanonicalFileName, isImportCall, ModuleSpecifierEnding, - readJson, removeFileExtension, signatureHasRestParameter, skipParentheses, diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index e3a1c6ee35f12..5e57564732ee4 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -18,6 +18,7 @@ import { isVariableDeclaration, isVariableStatement, } from "../compiler/factory/nodeTests"; +import { forEachReturnStatement } from "../compiler/parserUtilities"; import { fileExtensionIsOneOf } from "../compiler/path"; import { getModeForUsageLocation } from "../compiler/program"; import { @@ -49,7 +50,6 @@ import { } from "../compiler/types"; import { createDiagnosticForNode, - forEachReturnStatement, FunctionFlags, getAllowSyntheticDefaultImports, getAssignmentDeclarationKind, diff --git a/src/services/transpile.ts b/src/services/transpile.ts index 71d45de2d7c24..a6b1940f863f4 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -22,7 +22,9 @@ import { import { createProgram, getImpliedNodeFormatForFile, + getSetExternalModuleIndicator, } from "../compiler/program"; +import { getNewLineCharacter } from "../compiler/sysUtilities"; import { CommandLineOptionOfCustomType, CompilerHost, @@ -33,8 +35,6 @@ import { import { forEachEntry, getEmitScriptTarget, - getNewLineCharacter, - getSetExternalModuleIndicator, } from "../compiler/utilities"; import { getDefaultCompilerOptions } from "./services"; import { cloneCompilerOptions } from "./utilities"; diff --git a/src/services/types.ts b/src/services/types.ts index 2efdcb9928a5e..5c4e59b510537 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -1,5 +1,6 @@ import { EmitOutput } from "../compiler/builderStatePublic"; import { ModuleResolutionCache } from "../compiler/moduleNameResolver"; +import { SymlinkCache } from "../compiler/symlinkCache"; import { __String, CancellationToken, @@ -41,7 +42,6 @@ import { TypeChecker, UserPreferences, } from "../compiler/types"; -import { SymlinkCache } from "../compiler/utilities"; import { RulesMap } from "./formatting/rulesMap"; import { SourceMapper } from "./sourcemaps"; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index bef721e6f349b..c548c625e6e8e 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -133,10 +133,8 @@ import { getTypesPackageName, } from "../compiler/moduleNameResolver"; import { getNodeModulesPackageName } from "../compiler/moduleSpecifiers"; -import { - forEachChild, - isExternalModule, -} from "../compiler/parser"; +import { forEachChild } from "../compiler/parser"; +import { getLastChild } from "../compiler/parserUtilities"; import { combinePaths, forEachAncestorDirectory, @@ -222,6 +220,7 @@ import { ModuleDeclaration, ModuleResolutionKind, ModuleSpecifierResolutionHost, + Mutable, NamedDeclaration, NewExpression, NewLineKind, @@ -285,7 +284,6 @@ import { getEmitScriptTarget, getExternalModuleImportEqualsDeclarationExpression, getIndentString, - getLastChild, getLeadingCommentRangesOfNode, getLocaleSpecificMessage, getRootDeclaration, @@ -300,6 +298,7 @@ import { isAnyImportSyntax, isDeclarationName, isExpressionNode, + isExternalModule, isExternalModuleImportEqualsDeclaration, isFileLevelUniqueName, isFunctionBlock, @@ -320,7 +319,6 @@ import { isStringOrNumericLiteralLike, isTransientSymbol, isVarConst, - Mutable, nodeIsMissing, nodeIsPresent, nodeIsSynthesized, diff --git a/src/testRunner/unittests/parsePseudoBigInt.ts b/src/testRunner/unittests/parsePseudoBigInt.ts index 10f5e098362f9..cadf1f566f584 100644 --- a/src/testRunner/unittests/parsePseudoBigInt.ts +++ b/src/testRunner/unittests/parsePseudoBigInt.ts @@ -1,4 +1,4 @@ -import * as ts from "../_namespaces/ts"; +import { parsePseudoBigInt } from "../../compiler/scannerUtilities"; describe("unittests:: BigInt literal base conversions", () => { describe("parsePseudoBigInt", () => { @@ -11,7 +11,7 @@ describe("unittests:: BigInt literal base conversions", () => { for (const testNumber of testNumbers) { for (let leadingZeros = 0; leadingZeros < 10; leadingZeros++) { assert.equal( - ts.parsePseudoBigInt("0".repeat(leadingZeros) + testNumber + "n"), + parsePseudoBigInt("0".repeat(leadingZeros) + testNumber + "n"), String(testNumber) ); } @@ -22,7 +22,7 @@ describe("unittests:: BigInt literal base conversions", () => { for (let leadingZeros = 0; leadingZeros < 10; leadingZeros++) { const binary = "0".repeat(leadingZeros) + testNumber.toString(2) + "n"; for (const prefix of ["0b", "0B"]) { - assert.equal(ts.parsePseudoBigInt(prefix + binary), String(testNumber)); + assert.equal(parsePseudoBigInt(prefix + binary), String(testNumber)); } } } @@ -32,7 +32,7 @@ describe("unittests:: BigInt literal base conversions", () => { for (let leadingZeros = 0; leadingZeros < 10; leadingZeros++) { const octal = "0".repeat(leadingZeros) + testNumber.toString(8) + "n"; for (const prefix of ["0o", "0O"]) { - assert.equal(ts.parsePseudoBigInt(prefix + octal), String(testNumber)); + assert.equal(parsePseudoBigInt(prefix + octal), String(testNumber)); } } } @@ -43,7 +43,7 @@ describe("unittests:: BigInt literal base conversions", () => { 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(ts.parsePseudoBigInt(prefix + hexCase), String(testNumber)); + assert.equal(parsePseudoBigInt(prefix + hexCase), String(testNumber)); } } } @@ -51,19 +51,19 @@ describe("unittests:: BigInt literal base conversions", () => { }); it("can parse large literals", () => { assert.equal( - ts.parsePseudoBigInt("123456789012345678901234567890n"), + parsePseudoBigInt("123456789012345678901234567890n"), "123456789012345678901234567890" ); assert.equal( - ts.parsePseudoBigInt("0b1100011101110100100001111111101101100001101110011111000001110111001001110001111110000101011010010n"), + parsePseudoBigInt("0b1100011101110100100001111111101101100001101110011111000001110111001001110001111110000101011010010n"), "123456789012345678901234567890" ); assert.equal( - ts.parsePseudoBigInt("0o143564417755415637016711617605322n"), + parsePseudoBigInt("0o143564417755415637016711617605322n"), "123456789012345678901234567890" ); assert.equal( - ts.parsePseudoBigInt("0x18ee90ff6c373e0ee4e3f0ad2n"), + parsePseudoBigInt("0x18ee90ff6c373e0ee4e3f0ad2n"), "123456789012345678901234567890" ); }); diff --git a/src/testRunner/unittests/services/textChanges.ts b/src/testRunner/unittests/services/textChanges.ts index c9309cd2d83bc..a319b0fe4856c 100644 --- a/src/testRunner/unittests/services/textChanges.ts +++ b/src/testRunner/unittests/services/textChanges.ts @@ -4,6 +4,7 @@ import { notImplementedHost } from "./extract/helpers"; import { applyChanges, ChangeTracker, deleteNode, LeadingTriviaOption, TrailingTriviaOption } from "../../../services/textChanges"; import { FormatContext } from "../../../services/types"; import { getFormatContext } from "../../../services/formatting/formatting"; +import { getNewLineCharacter } from "../../../compiler/sysUtilities"; // Some tests have trailing whitespace @@ -22,7 +23,7 @@ describe("unittests:: services:: textChanges", () => { } const printerOptions = { newLine: ts.NewLineKind.LineFeed }; - const newLineCharacter = ts.getNewLineCharacter(printerOptions); + const newLineCharacter = getNewLineCharacter(printerOptions); function getRuleProvider(placeOpenBraceOnNewLineForFunctions: boolean): FormatContext { return getFormatContext(placeOpenBraceOnNewLineForFunctions ? { ...ts.testFormatSettings, placeOpenBraceOnNewLineForFunctions: true } : ts.testFormatSettings, notImplementedHost); diff --git a/src/testRunner/unittests/tsserver/symlinkCache.ts b/src/testRunner/unittests/tsserver/symlinkCache.ts index e389efd319f5a..5308f2dad9dc4 100644 --- a/src/testRunner/unittests/tsserver/symlinkCache.ts +++ b/src/testRunner/unittests/tsserver/symlinkCache.ts @@ -8,6 +8,9 @@ import { createSession, openFilesForSession, } from "./helpers"; +import { + createSymlinkCache, +} from "../../../compiler/symlinkCache"; const appTsconfigJson: File = { path: "/packages/app/tsconfig.json", @@ -69,7 +72,7 @@ describe("unittests:: tsserver:: symlinkCache", () => { }); it("works for paths close to the root", () => { - const cache = ts.createSymlinkCache("/", ts.createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ false)); + const cache = createSymlinkCache("/", ts.createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ false)); // Used to crash, #44953 const map = ts.createModeAwareCache(); map.set("foo", /*mode*/ undefined, { diff --git a/src/testRunner/unittests/virtualFileSystemWithWatch.ts b/src/testRunner/unittests/virtualFileSystemWithWatch.ts index 7dfb1f195f381..6759ca45f39fe 100644 --- a/src/testRunner/unittests/virtualFileSystemWithWatch.ts +++ b/src/testRunner/unittests/virtualFileSystemWithWatch.ts @@ -29,7 +29,6 @@ import { isArray, isString, mapDefined, - matchFiles, ModuleResolutionHost, MultiMap, noop, @@ -43,6 +42,7 @@ import { toPath, } from "../_namespaces/ts"; import { timeIncrements } from "../_namespaces/vfs"; +import { matchFiles } from "../../compiler/fileMatcher"; export const libFile: File = { path: "/a/lib/lib.d.ts", diff --git a/src/typingsInstaller/nodeTypingsInstaller.ts b/src/typingsInstaller/nodeTypingsInstaller.ts index 0d8d0eb5d61aa..4d111b95698b4 100644 --- a/src/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/typingsInstaller/nodeTypingsInstaller.ts @@ -1,41 +1,46 @@ import * as fs from "fs"; import * as path from "path"; - import { - installNpmPackages, - Log, - RequestCompletedAction, - TypingsInstaller, -} from "./_namespaces/ts.server.typingsInstaller"; + createGetCanonicalFileName, + getEntries, + stringContains, +} from "../compiler/core"; +import { + MapLike, + version, +} from "../compiler/corePublic"; +import { Debug } from "../compiler/debug"; +import { + combinePaths, + forEachAncestorDirectory, + getDirectoryPath, + normalizePath, + normalizeSlashes, + toPath, +} from "../compiler/path"; +import { sys } from "../compiler/sys"; import { ActionPackageInstalled, Arguments, EventTypesRegistry, findArgument, hasArgument, + nowString, +} from "../jsTyping/shared"; +import { InitializationFailedResponse, InstallTypingHost, - nowString, PackageInstalledResponse, TypesRegistryResponse, TypingInstallerRequestUnion, TypingInstallerResponseUnion, -} from "./_namespaces/ts.server"; +} from "../jsTyping/types"; import { - combinePaths, - createGetCanonicalFileName, - Debug, - forEachAncestorDirectory, - getDirectoryPath, - getEntries, - MapLike, - normalizePath, - normalizeSlashes, - stringContains, - sys, - toPath, - version, -} from "./_namespaces/ts"; + installNpmPackages, + Log, + RequestCompletedAction, + TypingsInstaller, +} from "../typingsInstallerCore/typingsInstaller"; class FileLog implements Log { constructor(private logFile: string | undefined) { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 6866f9305063d..cf8f84eac3a09 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -8414,7 +8414,9 @@ declare namespace ts { negative: boolean; base10Value: string; } - function getNodeMajorVersion(): number | undefined; + interface FileWatcher { + close(): void; + } enum FileWatcherEventKind { Created = 0, Changed = 1, @@ -8464,9 +8466,7 @@ declare namespace ts { base64decode?(input: string): string; base64encode?(input: string): string; } - interface FileWatcher { - close(): void; - } + function getNodeMajorVersion(): number | undefined; let sys: System; function tokenToString(t: SyntaxKind): string | undefined; function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number): number; @@ -8794,6 +8794,7 @@ declare namespace ts { parent: ConstructorDeclaration; name: Identifier; }; + function isExternalModule(file: SourceFile): boolean; function emitModuleKindIsNonNodeESM(moduleKind: ModuleKind): boolean; function createUnparsedSourceFile(text: string): UnparsedSource; function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts", stripInternal?: boolean): UnparsedSource; @@ -9102,7 +9103,6 @@ declare namespace ts { * @param sourceText */ function parseJsonText(fileName: string, sourceText: string): JsonSourceFile; - function isExternalModule(file: SourceFile): boolean; function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile; interface CreateSourceFileOptions { languageVersion: ScriptTarget; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index bfa18ef926bcb..a80a2cb3b68c6 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4479,7 +4479,9 @@ declare namespace ts { negative: boolean; base10Value: string; } - function getNodeMajorVersion(): number | undefined; + interface FileWatcher { + close(): void; + } enum FileWatcherEventKind { Created = 0, Changed = 1, @@ -4529,9 +4531,7 @@ declare namespace ts { base64decode?(input: string): string; base64encode?(input: string): string; } - interface FileWatcher { - close(): void; - } + function getNodeMajorVersion(): number | undefined; let sys: System; function tokenToString(t: SyntaxKind): string | undefined; function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number): number; @@ -4859,6 +4859,7 @@ declare namespace ts { parent: ConstructorDeclaration; name: Identifier; }; + function isExternalModule(file: SourceFile): boolean; function emitModuleKindIsNonNodeESM(moduleKind: ModuleKind): boolean; function createUnparsedSourceFile(text: string): UnparsedSource; function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts", stripInternal?: boolean): UnparsedSource; @@ -5167,7 +5168,6 @@ declare namespace ts { * @param sourceText */ function parseJsonText(fileName: string, sourceText: string): JsonSourceFile; - function isExternalModule(file: SourceFile): boolean; function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile; interface CreateSourceFileOptions { languageVersion: ScriptTarget; From 1136d5ac33bb73834955ff7d5738188796f8eb2e Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 6 Jan 2023 00:44:48 +0200 Subject: [PATCH 04/24] fix imports --- src/compiler/parser.ts | 2 +- src/compiler/scanner.ts | 3 +- src/compiler/scannerKeywords.ts | 158 +++++++++++++++++++++++ src/compiler/scannerUtilities.ts | 163 +----------------------- src/services/codefixes/fixJSDocTypes.ts | 4 +- 5 files changed, 163 insertions(+), 167 deletions(-) create mode 100644 src/compiler/scannerKeywords.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index d6d881d712396..a2798f1c87341 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -76,7 +76,7 @@ import { tokenIsIdentifierOrKeywordOrGreaterThan, tokenToString, } from "./scanner"; -import { textToKeywordObj } from "./scannerUtilities"; +import { textToKeywordObj } from "./scannerKeywords"; import { tracing } from "./tracing"; import { AccessorDeclaration, diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 4ed0aca73e539..8499e329bb373 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -11,11 +11,10 @@ import { } from "./core"; import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { textToKeyword, textToToken } from "./scannerKeywords"; import { parsePseudoBigInt, positionIsSynthesized, - textToKeyword, - textToToken, } from "./scannerUtilities"; import { CharacterCodes, diff --git a/src/compiler/scannerKeywords.ts b/src/compiler/scannerKeywords.ts new file mode 100644 index 0000000000000..96e44238970a9 --- /dev/null +++ b/src/compiler/scannerKeywords.ts @@ -0,0 +1,158 @@ +import { getEntries } from "./core"; +import { MapLike } from "./corePublic"; +import { + KeywordSyntaxKind, + SyntaxKind, +} from "./types"; + +export const textToKeywordObj: MapLike = { + abstract: SyntaxKind.AbstractKeyword, + accessor: SyntaxKind.AccessorKeyword, + 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, + satisfies: SyntaxKind.SatisfiesKeyword, + 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 textToKeyword = new Map(getEntries(textToKeywordObj)); + +export const textToToken = new Map(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, +})); diff --git a/src/compiler/scannerUtilities.ts b/src/compiler/scannerUtilities.ts index 326109134f515..5ce6ffc28dfdc 100644 --- a/src/compiler/scannerUtilities.ts +++ b/src/compiler/scannerUtilities.ts @@ -1,165 +1,4 @@ -import { getEntries } from "./core"; -import { MapLike } from "./corePublic"; -import { - CharacterCodes, - KeywordSyntaxKind, - SyntaxKind, -} from "./types"; - -/** @internal */ -export const textToKeywordObj: MapLike = { - abstract: SyntaxKind.AbstractKeyword, - accessor: SyntaxKind.AccessorKeyword, - 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, - satisfies: SyntaxKind.SatisfiesKeyword, - 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, -}; - -/** @internal */ -export const textToKeyword = new Map(getEntries(textToKeywordObj)); - -/** @internal */ -export const textToToken = new Map(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, -})); +import { CharacterCodes } from "./types"; /** @internal */ export function positionIsSynthesized(pos: number): boolean { diff --git a/src/services/codefixes/fixJSDocTypes.ts b/src/services/codefixes/fixJSDocTypes.ts index 3d7f112060af9..f5d27694d86de 100644 --- a/src/services/codefixes/fixJSDocTypes.ts +++ b/src/services/codefixes/fixJSDocTypes.ts @@ -1,6 +1,6 @@ import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; +import { append } from "../../compiler/core"; import { - append, AsExpression, CallSignatureDeclaration, ConstructSignatureDeclaration, @@ -8,7 +8,6 @@ import { FunctionDeclaration, GetAccessorDeclaration, IndexSignatureDeclaration, - isJSDocNullableType, MappedTypeNode, MethodDeclaration, MethodSignature, @@ -36,6 +35,7 @@ import { import { ChangeTracker } from "../textChanges"; import { CodeFixAction } from "../types"; import { getTokenAtPosition } from "../utilities"; +import { isJSDocNullableType } from "../../compiler/factory/nodeTests"; const fixIdPlain = "fixJSDocTypes_plain"; const fixIdNullable = "fixJSDocTypes_nullable"; From c5e4f4de4d613295a5b0d443757a2cc7ace8be23 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 6 Jan 2023 22:52:26 +0200 Subject: [PATCH 05/24] disable Debug in core --- src/compiler/core.ts | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index f006f6892c150..53bb80d2ea937 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -7,7 +7,7 @@ import { SortedArray, SortedReadonlyArray, } from "./corePublic"; -import { Debug } from "./debug"; +// import { Debug } from "./debug"; import { __String, CharacterCodes, @@ -136,7 +136,7 @@ export function reduceLeftIterator(iterator: Iterator | undefined, f: ( /** @internal */ 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); + // Debug.assertEqual(arrayA.length, arrayB.length); for (let i = 0; i < arrayA.length; i++) { result.push(callback(arrayA[i], arrayB[i], i)); } @@ -145,7 +145,7 @@ export function zipWith(arrayA: readonly T[], arrayB: readonly U[], cal /** @internal */ export function zipToIterator(arrayA: readonly T[], arrayB: readonly U[]): Iterator<[T, U]> { - Debug.assertEqual(arrayA.length, arrayB.length); + // Debug.assertEqual(arrayA.length, arrayB.length); let i = 0; return { next() { @@ -160,7 +160,7 @@ export function zipToIterator(arrayA: readonly T[], arrayB: readonly U[]): /** @internal */ export function zipToMap(keys: readonly K[], values: readonly V[]): Map { - Debug.assert(keys.length === values.length); + // Debug.assert(keys.length === values.length); const map = new Map(); for (let i = 0; i < keys.length; ++i) { map.set(keys[i], values[i]); @@ -280,7 +280,8 @@ export function findMap(array: readonly T[], callback: (element: T, index: return result; } } - return Debug.fail(); + throw new Error(); + // return Debug.fail(); } /** @internal */ @@ -898,7 +899,8 @@ function deduplicateSorted(array: SortedReadonlyArray, comparer: EqualityC case Comparison.LessThan: // If `array` is sorted, `next` should **never** be less than `last`. - return Debug.fail("Array is unsorted."); + // return Debug.fail("Array is unsorted."); + throw new Error("Array is unsorted."); } deduplicated.push(last = next); @@ -1056,14 +1058,14 @@ export function relativeComplement(arrayA: T[] | undefined, arrayB: T[] | und 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); + // Debug.assertGreaterThanOrEqual(comparer(arrayB[offsetB], arrayB[offsetB - 1]), 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); + // Debug.assertGreaterThanOrEqual(comparer(arrayA[offsetA], arrayA[offsetA - 1]), Comparison.EqualTo); } switch (comparer(arrayB[offsetB], arrayA[offsetA])) { @@ -1312,7 +1314,7 @@ export function firstOrUndefined(array: readonly T[] | undefined): T | undefi /** @internal */ export function first(array: readonly T[]): T { - Debug.assert(array.length !== 0); + // Debug.assert(array.length !== 0); return array[0]; } @@ -1327,7 +1329,7 @@ export function lastOrUndefined(array: readonly T[] | undefined): T | undefin /** @internal */ export function last(array: readonly T[]): T { - Debug.assert(array.length !== 0); + // Debug.assert(array.length !== 0); return array[array.length - 1]; } @@ -1348,7 +1350,12 @@ export function singleOrUndefined(array: readonly T[] | undefined): T | undef * @internal */ export function single(array: readonly T[]): T { - return Debug.checkDefined(singleOrUndefined(array)); + // return Debug.checkDefined(singleOrUndefined(array)); + const result = singleOrUndefined(array); + if (result === undefined) { + throw new Error(); + } + return result; } /** @@ -2044,7 +2051,8 @@ export function tryCast(value: T, test: (value: T) => boolean): T | undefined /** @internal */ 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)}'.`); + // return Debug.fail(`Invalid cast. The supplied value ${value} did not pass the test '${Debug.getFunctionName(test)}'.`); + throw new Error("Invalid cast."); } /** @@ -2550,7 +2558,7 @@ export function getSpellingSuggestion(name: string, candidates: T[], getName: continue; } - Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined + // Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined bestDistance = distance; bestCandidate = candidate; } @@ -2764,7 +2772,7 @@ export function patternText({ prefix, suffix }: Pattern): string { * @internal */ export function matchedText(pattern: Pattern, candidate: string): string { - Debug.assert(isPatternMatch(pattern, candidate)); + // Debug.assert(isPatternMatch(pattern, candidate)); return candidate.substring(pattern.prefix.length, candidate.length - pattern.suffix.length); } From e189663cbf53b007379e0c5c3f9e47a5746f1117 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 18 Jan 2023 11:33:51 +0200 Subject: [PATCH 06/24] remove Debug namespace --- src/compiler/_namespaces/ts.ts | 3 +- src/compiler/binder.ts | 2 +- src/compiler/builder.ts | 2 +- src/compiler/builderState.ts | 2 +- src/compiler/checker.ts | 2 +- src/compiler/commandLineParser.ts | 2 +- src/compiler/debug.ts | 1429 +++++++++++++---- src/compiler/debugUtilities.ts | 870 ---------- src/compiler/emitter.ts | 14 +- .../factory/binaryExpressionStateMachine.ts | 4 +- src/compiler/factory/emitHelpers.ts | 2 +- src/compiler/factory/emitNode.ts | 2 +- src/compiler/factory/nodeConverters.ts | 2 +- src/compiler/factory/nodeFactory.ts | 2 +- src/compiler/factory/utilities.ts | 2 +- src/compiler/moduleNameResolver.ts | 2 +- src/compiler/moduleSpecifiers.ts | 2 +- src/compiler/objectAllocator.ts | 6 +- src/compiler/parser.ts | 6 +- src/compiler/path.ts | 2 +- src/compiler/performance.ts | 2 +- src/compiler/program.ts | 2 +- src/compiler/programUtilities.ts | 2 +- src/compiler/resolutionCache.ts | 2 +- src/compiler/scanner.ts | 2 +- src/compiler/semver.ts | 2 +- src/compiler/sourcemap.ts | 2 +- src/compiler/symlinkCache.ts | 2 +- src/compiler/sys.ts | 9 +- src/compiler/tracing.ts | 2 +- src/compiler/transformer.ts | 2 +- src/compiler/transformers/classFields.ts | 2 +- src/compiler/transformers/declarations.ts | 2 +- .../transformers/declarations/diagnostics.ts | 2 +- src/compiler/transformers/destructuring.ts | 2 +- src/compiler/transformers/es2015.ts | 2 +- src/compiler/transformers/es2017.ts | 2 +- src/compiler/transformers/es2018.ts | 2 +- src/compiler/transformers/es2020.ts | 2 +- src/compiler/transformers/generators.ts | 2 +- src/compiler/transformers/jsx.ts | 7 +- src/compiler/transformers/legacyDecorators.ts | 2 +- .../transformers/module/esnextAnd2015.ts | 2 +- src/compiler/transformers/module/module.ts | 2 +- src/compiler/transformers/module/node.ts | 2 +- src/compiler/transformers/module/system.ts | 2 +- src/compiler/transformers/taggedTemplate.ts | 2 +- src/compiler/transformers/ts.ts | 2 +- src/compiler/transformers/typeSerializer.ts | 2 +- src/compiler/tsbuildPublic.ts | 2 +- src/compiler/utilities.ts | 6 +- src/compiler/utilitiesPublic.ts | 2 +- src/compiler/visitorPublic.ts | 2 +- src/compiler/watch.ts | 2 +- src/compiler/watchPublic.ts | 2 +- src/compiler/watchUtilities.ts | 2 +- .../4.0/nodeFactoryTopLevelExports.ts | 2 +- src/deprecatedCompat/deprecate.ts | 2 +- src/executeCommandLine/executeCommandLine.ts | 2 +- src/jsTyping/jsTyping.ts | 2 +- src/server/editorServices.ts | 4 +- src/server/moduleSpecifierCache.ts | 2 +- src/server/packageJsonCache.ts | 2 +- src/server/project.ts | 2 +- src/server/scriptInfo.ts | 2 +- src/server/scriptVersionCache.ts | 2 +- src/server/session.ts | 2 +- src/services/breakpoints.ts | 2 +- src/services/callHierarchy.ts | 2 +- src/services/classifier.ts | 2 +- src/services/classifier2020.ts | 2 +- src/services/codeFixProvider.ts | 2 +- .../addMissingInvocationForDecorator.ts | 2 +- .../codefixes/addNameToNamelessParameter.ts | 2 +- .../codefixes/annotateWithTypeFromJSDoc.ts | 2 +- .../codefixes/convertToAsyncFunction.ts | 2 +- src/services/codefixes/convertToEsModule.ts | 2 +- ...correctQualifiedNameToIndexedAccessType.ts | 2 +- src/services/codefixes/fixAddMissingMember.ts | 2 +- .../fixAddModuleReferTypeMissingTypeof.ts | 2 +- src/services/codefixes/fixCannotFindModule.ts | 2 +- .../fixClassIncorrectlyImplementsInterface.ts | 2 +- .../fixConstructorForDerivedNeedSuperCall.ts | 2 +- src/services/codefixes/fixImplicitThis.ts | 2 +- src/services/codefixes/fixOverrideModifier.ts | 2 +- .../codefixes/fixPropertyOverrideAccessor.ts | 2 +- src/services/codefixes/fixSpelling.ts | 2 +- .../codefixes/fixStrictClassInitialization.ts | 2 +- src/services/codefixes/fixUnreachableCode.ts | 2 +- src/services/codefixes/fixUnusedIdentifier.ts | 2 +- src/services/codefixes/helpers.ts | 2 +- src/services/codefixes/importAdder.ts | 2 +- src/services/codefixes/inferFromUsage.ts | 2 +- src/services/codefixes/requireInTs.ts | 2 +- src/services/codefixes/returnValueCorrect.ts | 2 +- src/services/codefixes/splitTypeOnlyImport.ts | 2 +- src/services/completions.ts | 2 +- src/services/documentHighlights.ts | 2 +- src/services/documentRegistry.ts | 7 +- src/services/exportInfoMap.ts | 2 +- src/services/findAllReferences.ts | 2 +- src/services/formatting/formatting.ts | 2 +- src/services/formatting/formattingContext.ts | 2 +- src/services/formatting/formattingScanner.ts | 2 +- src/services/formatting/rulesMap.ts | 2 +- src/services/formatting/smartIndenter.ts | 2 +- src/services/getEditsForFileRename.ts | 2 +- src/services/goToDefinition.ts | 2 +- src/services/importTracker.ts | 2 +- src/services/inlayHints.ts | 2 +- src/services/navigationBar.ts | 2 +- src/services/outliningElementsCollector.ts | 2 +- .../addOrRemoveBracesToArrowFunction.ts | 2 +- ...onvertArrowFunctionOrFunctionExpression.ts | 2 +- src/services/refactors/convertExport.ts | 2 +- src/services/refactors/convertImport.ts | 2 +- .../convertOverloadListToSingleSignature.ts | 2 +- .../convertParamsToDestructuredObject.ts | 2 +- .../convertStringOrTemplateLiteral.ts | 2 +- .../convertToOptionalChainExpression.ts | 2 +- src/services/refactors/extractSymbol.ts | 2 +- src/services/refactors/extractType.ts | 2 +- .../generateGetAccessorAndSetAccessor.ts | 2 +- src/services/refactors/moveToNewFile.ts | 2 +- src/services/services.ts | 2 +- src/services/signatureHelp.ts | 2 +- src/services/smartSelection.ts | 2 +- src/services/stringCompletions.ts | 2 +- src/services/symbolDisplay.ts | 2 +- src/services/textChanges.ts | 2 +- src/services/transpile.ts | 2 +- src/services/utilities.ts | 2 +- src/testRunner/runner.ts | 4 +- src/testRunner/unittests/debugDeprecation.ts | 28 +- src/tsc/tsc.ts | 4 +- src/tsserver/nodeServer.ts | 12 +- src/typescript/typescript.ts | 18 +- src/typingsInstaller/nodeTypingsInstaller.ts | 2 +- 138 files changed, 1307 insertions(+), 1366 deletions(-) delete mode 100644 src/compiler/debugUtilities.ts diff --git a/src/compiler/_namespaces/ts.ts b/src/compiler/_namespaces/ts.ts index 21cbf007c824c..d8d2822f0ee1f 100644 --- a/src/compiler/_namespaces/ts.ts +++ b/src/compiler/_namespaces/ts.ts @@ -2,7 +2,6 @@ export * from "../corePublic"; export * from "../core"; -export * from "../debug"; export * from "../semver"; export * from "../performanceCore"; export * from "../perfLogger"; @@ -77,6 +76,8 @@ export * from "../watchPublic"; export * from "../tsbuild"; export * from "../tsbuildPublic"; export * from "../fileMatcher"; +import * as Debug from "../debug"; +export { Debug }; import * as moduleSpecifiers from "./ts.moduleSpecifiers"; export { moduleSpecifiers }; import * as performance from "./ts.performance"; diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 5ff8b8f61515f..ffb21754b7458 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { getNodeId } from "./checkerUtilities"; import { append, @@ -15,7 +16,6 @@ import { some, tryCast, } from "./core"; -import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { createBinaryExpressionTrampoline } from "./factory/binaryExpressionStateMachine"; import { diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index db9cb69dd0e21..94d5195e9dd58 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { AffectedFileResult, BuilderProgram, @@ -36,7 +37,6 @@ import { tryAddToSet, } from "./core"; import { ReadonlyCollection } from "./corePublic"; -import { Debug } from "./debug"; import { createBuildInfo, getTsBuildInfoEmitOutputFilePath, diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts index eeb94a99b6862..ecfaaee5dc90c 100644 --- a/src/compiler/builderState.ts +++ b/src/compiler/builderState.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { computeSignatureWithDiagnostics } from "./builder"; import { HostForComputeHash } from "./builderPublic"; import { @@ -12,7 +13,6 @@ import { mapDefinedIterator, some, } from "./core"; -import { Debug } from "./debug"; import { isStringLiteral } from "./factory/nodeTests"; import { isDeclarationFileName } from "./parser"; import { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f49dd8f98df1e..77642085499c7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { bindSourceFile, getModuleInstanceState, @@ -80,7 +81,6 @@ import { tryCast, } from "./core"; import { Comparison } from "./corePublic"; -import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { createPrinter } from "./emitter"; import { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 9144eb2648ceb..c6b1a5e124180 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { append, arrayFrom, @@ -34,7 +35,6 @@ import { MapLike, Push, } from "./corePublic"; -import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { isArrayLiteralExpression, diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index ce2553124d73a..db2e773189ecb 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -1,66 +1,109 @@ -import { CheckMode, SignatureCheckMode, TypeFacts } from "./checkerUtilities"; +/* eslint-disable */ +import * as types from "./types"; +import * as checkerTypes from "./checkerUtilities"; +/* eslint-enable */ + +import { + CheckMode, + SignatureCheckMode, + TypeFacts, +} from "./checkerUtilities"; +import { + compareValues, + every, + getOwnKeys, + hasProperty, + map, + noop, + stableSort, + zipWith, +} from "./core"; +import { SortedReadonlyArray } from "./corePublic"; import { - arrayTypeToString, - assertNoop, - attachFlowNodeDebugInfoWorker, - attachNodeArrayDebugInfoWorker, - DebugType, - deferredTypeToString, - enableDebugInfoWorder, - formatCheckModeWorker, - formatControlFlowGraphWorker, - formatEmitFlagsWorker, - formatEnumWorker, - formatFlowFlagsWorker, - formatModifierFlagsWorker, - formatNodeFlagsWorker, - formatObjectFlagsWorker, - formatRelationComparisonResultWorker, - formatSignatureCheckModeWorker, - formatSignatureFlagsWorker, - formatSnippetKindWorker, - formatSymbolFlagsWorker, - formatSymbolWorker, - formatSyntaxKindWorker, - formatTransformFlagsWorker, - formatTypeFactsWorker, - formatTypeFlagsWorker, - hasKind, - hasName, - hasPos, -} from "./debugUtilities"; + isArrayTypeNode, + isBigIntLiteral, + isCallSignatureDeclaration, + isConditionalTypeNode, + isConstructorDeclaration, + isConstructorTypeNode, + isConstructSignatureDeclaration, + isDefaultClause, + isFunctionTypeNode, + isGetAccessorDeclaration, + isIdentifier, + isImportTypeNode, + isIndexedAccessTypeNode, + isIndexSignatureDeclaration, + isInferTypeNode, + isIntersectionTypeNode, + isLiteralTypeNode, + isMappedTypeNode, + isNamedTupleMember, + isNumericLiteral, + isOptionalTypeNode, + isParameter, + isParenthesizedTypeNode, + isPrivateIdentifier, + isRestTypeNode, + isSetAccessorDeclaration, + isStringLiteral, + isThisTypeNode, + isTupleTypeNode, + isTypeLiteralNode, + isTypeOperatorNode, + isTypeParameterDeclaration, + isTypePredicateNode, + isTypeQueryNode, + isTypeReferenceNode, + isUnionTypeNode, +} from "./factory/nodeTests"; +import { objectAllocator } from "./objectAllocator"; import { AnyFunction, + BigIntLiteralType, EmitFlags, FlowFlags, + FlowLabel, FlowNode, FlowNodeBase, - MatchingKeys, + FlowSwitchClause, + IntrinsicType, + LiteralType, ModifierFlags, Node, NodeArray, NodeFlags, ObjectFlags, + ObjectType, RelationComparisonResult, + Signature, SignatureFlags, SnippetKind, Symbol, SymbolFlags, SyntaxKind, TransformFlags, + Type, TypeFlags, TypeMapKind, TypeMapper, VarianceFlags, } from "./types"; - -/** @internal */ -export const enum AssertionLevel { - None = 0, - Normal = 1, - Aggressive = 2, - VeryAggressive = 3, -} +import { + getEffectiveModifierFlagsNoCache, + getEmitFlags, + getSourceFileOfNode, + getSourceTextOfNodeFromSourceFile, + nodeIsSynthesized, +} from "./utilities"; +import { + getParseTreeNode, + idText, + isGeneratedIdentifier, + isParseTreeNode, + symbolName, + unescapeLeadingUnderscores, +} from "./utilitiesPublic"; /** @internal */ export enum LogLevel { @@ -77,406 +120,1168 @@ export interface LoggingHost { } /** @internal */ -export namespace Debug { - /* eslint-disable prefer-const */ - let currentAssertionLevel = AssertionLevel.None; - export let currentLogLevel = LogLevel.Warning; - export let isDebugging = false; - export let loggingHost: LoggingHost | undefined; - /* eslint-enable prefer-const */ +export const enum AssertionLevel { + None = 0, + Normal = 1, + Aggressive = 2, + VeryAggressive = 3, +} + +let currentAssertionLevel = AssertionLevel.None; + +/** @internal */ +export const currentLogLevel = LogLevel.Warning; + +/** @internal */ +export let isDebugging = false; + +/** @internal */ +export function setIsDebugging(newIsDebugging: boolean) { + isDebugging = newIsDebugging; +} + +/** @internal */ +export let loggingHost: LoggingHost | undefined; + +/** @internal */ +export function setLoggingHost(newLoggingHost: LoggingHost | undefined) { + loggingHost = newLoggingHost; +} + +/** @internal */ +export function shouldLog(level: LogLevel): boolean { + return currentLogLevel <= level; +} - type AssertionKeys = MatchingKeys; +function logMessage(level: LogLevel, s: string): void { + if (loggingHost && shouldLog(level)) { + loggingHost.log(level, s); + } +} - export function shouldLog(level: LogLevel): boolean { - return currentLogLevel <= level; +/** @internal */ +export function log(s: string): void { + logMessage(LogLevel.Info, s); +} + +/** @internal */ +export namespace log { + export function error(s: string): void { + logMessage(LogLevel.Error, s); } - function logMessage(level: LogLevel, s: string): void { - if (loggingHost && shouldLog(level)) { - loggingHost.log(level, s); - } + export function warn(s: string): void { + logMessage(LogLevel.Warning, s); } export function log(s: string): void { logMessage(LogLevel.Info, s); } - export namespace log { - export function error(s: string): void { - logMessage(LogLevel.Error, s); - } - - export function warn(s: string): void { - logMessage(LogLevel.Warning, s); - } + export function trace(s: string): void { + logMessage(LogLevel.Verbose, s); + } +} - export function log(s: string): void { - logMessage(LogLevel.Info, s); - } +/** @internal */ +export function getAssertionLevel() { + return currentAssertionLevel; +} - export function trace(s: string): void { - logMessage(LogLevel.Verbose, s); +/** @internal */ +export function setAssertionLevel(level: AssertionLevel) { + const prevAssertionLevel = currentAssertionLevel; + currentAssertionLevel = level; + + if (level > prevAssertionLevel) { + // restore assertion functions for the current assertion level (see `shouldAssertFunction`). + for (const name of getOwnKeys(assertionCache) as AssertionKeys[]) { + assertionCache[name].enable(level); } } +} + +/** @internal */ +export function shouldAssert(level: AssertionLevel): boolean { + return currentAssertionLevel >= level; +} - const assertionCache: Partial> = {}; +/** + * Tests whether an assertion function should be executed. If it shouldn't, it is cached and replaced with `ts.noop`. + * Replaced assertion functions are restored when `Debug.setAssertionLevel` is set to a high enough level. + * @param level The minimum assertion level required. + * @param name The name of the current assertion function. + */ +function shouldAssertFunction(level: AssertionLevel, name: K): boolean { + if (!shouldAssert(level)) { + assertionCache[name].disable(level); + return false; + } + return true; +} - export function getAssertionLevel() { - return currentAssertionLevel; +/** @internal */ +export function fail(message?: string, stackCrawlMark?: AnyFunction): never { + debugger; + const e = new Error(message ? `Debug Failure. ${message}` : "Debug Failure."); + if ((Error as any).captureStackTrace) { + (Error as any).captureStackTrace(e, stackCrawlMark || fail); } + throw e; +} - export function setAssertionLevel(level: AssertionLevel) { - const prevAssertionLevel = currentAssertionLevel; - currentAssertionLevel = level; +/** @internal */ +export function failBadSyntaxKind(node: Node, message?: string, stackCrawlMark?: AnyFunction): never { + return fail( + `${message || "Unexpected node."}\r\nNode ${formatSyntaxKind(node.kind)} was unexpected.`, + stackCrawlMark || failBadSyntaxKind); +} - if (level > prevAssertionLevel) { - // restore assertion functions for the current assertion level (see `shouldAssertFunction`). - for (const key of Object.keys(assertionCache) as AssertionKeys[]) { - const cachedFunc = assertionCache[key]; - if (cachedFunc !== undefined && Debug[key] !== cachedFunc.assertion && level >= cachedFunc.level) { - (Debug as any)[key] = cachedFunc; - assertionCache[key] = undefined; - } - } +/** @internal */ +export function assert(expression: unknown, message?: string, verboseDebugInfo?: string | (() => string), stackCrawlMark?: AnyFunction): asserts expression { + if (!expression) { + message = message ? `False expression: ${message}` : "False expression."; + if (verboseDebugInfo) { + message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo()); } + fail(message, stackCrawlMark || assert); } +} - export function shouldAssert(level: AssertionLevel): boolean { - return currentAssertionLevel >= level; +/** @internal */ +export function assertEqual(a: T, b: T, msg?: string, msg2?: string, stackCrawlMark?: AnyFunction): void { + if (a !== b) { + const message = msg ? msg2 ? `${msg} ${msg2}` : msg : ""; + fail(`Expected ${a} === ${b}. ${message}`, stackCrawlMark || assertEqual); } +} - /** - * Tests whether an assertion function should be executed. If it shouldn't, it is cached and replaced with `ts.noop`. - * Replaced assertion functions are restored when `Debug.setAssertionLevel` is set to a high enough level. - * @param level The minimum assertion level required. - * @param name The name of the current assertion function. - */ - function shouldAssertFunction(level: AssertionLevel, name: K): boolean { - if (!shouldAssert(level)) { - assertionCache[name] = { level, assertion: Debug[name] }; - (Debug as any)[name] = assertNoop; - return false; - } - return true; +/** @internal */ +export function assertLessThan(a: number, b: number, msg?: string, stackCrawlMark?: AnyFunction): void { + if (a >= b) { + fail(`Expected ${a} < ${b}. ${msg || ""}`, stackCrawlMark || assertLessThan); } +} - export function fail(message?: string, stackCrawlMark?: AnyFunction): never { - debugger; - const e = new Error(message ? `Debug Failure. ${message}` : "Debug Failure."); - if ((Error as any).captureStackTrace) { - (Error as any).captureStackTrace(e, stackCrawlMark || fail); - } - throw e; +/** @internal */ +export function assertLessThanOrEqual(a: number, b: number, stackCrawlMark?: AnyFunction): void { + if (a > b) { + fail(`Expected ${a} <= ${b}`, stackCrawlMark || assertLessThanOrEqual); } +} - export function failBadSyntaxKind(node: Node, message?: string, stackCrawlMark?: AnyFunction): never { - return fail( - `${message || "Unexpected node."}\r\nNode ${formatSyntaxKind(node.kind)} was unexpected.`, - stackCrawlMark || failBadSyntaxKind); +/** @internal */ +export function assertGreaterThanOrEqual(a: number, b: number, stackCrawlMark?: AnyFunction): void { + if (a < b) { + fail(`Expected ${a} >= ${b}`, stackCrawlMark || assertGreaterThanOrEqual); } +} - export function assert(expression: unknown, message?: string, verboseDebugInfo?: string | (() => string), stackCrawlMark?: AnyFunction): asserts expression { - if (!expression) { - message = message ? `False expression: ${message}` : "False expression."; - if (verboseDebugInfo) { - message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo()); - } - fail(message, stackCrawlMark || assert); - } +/** @internal */ +export function assertIsDefined(value: T, message?: string, stackCrawlMark?: AnyFunction): asserts value is NonNullable { + // eslint-disable-next-line no-null/no-null + if (value === undefined || value === null) { + fail(message, stackCrawlMark || assertIsDefined); } +} - export function assertEqual(a: T, b: T, msg?: string, msg2?: string, stackCrawlMark?: AnyFunction): void { - if (a !== b) { - const message = msg ? msg2 ? `${msg} ${msg2}` : msg : ""; - fail(`Expected ${a} === ${b}. ${message}`, stackCrawlMark || assertEqual); - } - } +/** @internal */ +export function checkDefined(value: T | null | undefined, message?: string, stackCrawlMark?: AnyFunction): T { + assertIsDefined(value, message, stackCrawlMark || checkDefined); + return value; +} - export function assertLessThan(a: number, b: number, msg?: string, stackCrawlMark?: AnyFunction): void { - if (a >= b) { - fail(`Expected ${a} < ${b}. ${msg || ""}`, stackCrawlMark || assertLessThan); - } +/** @internal */ +export function assertEachIsDefined(value: NodeArray, message?: string, stackCrawlMark?: AnyFunction): asserts value is NodeArray; +/** @internal */ +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) { + for (const v of value) { + assertIsDefined(v, message, stackCrawlMark || assertEachIsDefined); } +} - export function assertLessThanOrEqual(a: number, b: number, stackCrawlMark?: AnyFunction): void { - if (a > b) { - fail(`Expected ${a} <= ${b}`, stackCrawlMark || assertLessThanOrEqual); - } +/** @internal */ +export function checkEachDefined(value: A, message?: string, stackCrawlMark?: AnyFunction): A { + assertEachIsDefined(value, message, stackCrawlMark || checkEachDefined); + return value; +} + +/** @internal */ +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); + return fail(`${message} ${detail}`, stackCrawlMark || assertNever); +} + +/** @internal */ +export let assertEachNode: { + (nodes: NodeArray, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is NodeArray; + (nodes: readonly T[], test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is readonly U[]; + (nodes: NodeArray | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is NodeArray | undefined; + (nodes: readonly T[] | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is readonly U[] | undefined; + (nodes: readonly Node[], test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction): void; +} = (nodes: readonly Node[] | undefined, test: ((node: Node) => boolean) | undefined, 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 assertGreaterThanOrEqual(a: number, b: number, stackCrawlMark?: AnyFunction): void { - if (a < b) { - fail(`Expected ${a} >= ${b}`, stackCrawlMark || assertGreaterThanOrEqual); - } +/** @internal */ +export let assertNode: { + (node: T | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts node is U; + (node: Node | undefined, test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction): void; +} = (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 assertIsDefined(value: T, message?: string, stackCrawlMark?: AnyFunction): asserts value is NonNullable { - // eslint-disable-next-line no-null/no-null - if (value === undefined || value === null) { - fail(message, stackCrawlMark || assertIsDefined); - } +/** @internal */ +export let assertNotNode: { + (node: T | undefined, test: (node: Node) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts node is Exclude; + (node: Node | undefined, test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction): void; +} = (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 checkDefined(value: T | null | undefined, message?: string, stackCrawlMark?: AnyFunction): T { - assertIsDefined(value, message, stackCrawlMark || checkDefined); - return value; +/** @internal */ +export let assertOptionalNode: { + (node: T, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts node is U; + (node: T | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts node is U | undefined; + (node: Node | undefined, test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction): void; +} = (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 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) { - for (const v of value) { - assertIsDefined(v, message, stackCrawlMark || assertEachIsDefined); - } +/** @internal */ +export let assertOptionalToken: { + (node: T, kind: K, message?: string, stackCrawlMark?: AnyFunction): asserts node is Extract; + (node: T | undefined, kind: K, message?: string, stackCrawlMark?: AnyFunction): asserts node is Extract | undefined; + (node: Node | undefined, kind: SyntaxKind | undefined, message?: string, stackCrawlMark?: AnyFunction): void; +} = (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 checkEachDefined(value: A, message?: string, stackCrawlMark?: AnyFunction): A { - assertEachIsDefined(value, message, stackCrawlMark || checkEachDefined); - return value; +/** @internal */ +export let assertMissingNode: { + // eslint-disable-next-line @typescript-eslint/prefer-function-type + (node: Node | undefined, message?: string, stackCrawlMark?: AnyFunction): asserts node is undefined; +} = (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); } +}; + +interface AssertionCacheEntry { + readonly disable: (level: AssertionLevel) => void, + readonly enable: (level: AssertionLevel) => void; +} + +function createAssertionCacheEntry(original: T, set: (fn: T) => void): AssertionCacheEntry { + let currentLevel: AssertionLevel | undefined; + return { + disable(level) { + set(noop as AnyFunction as T); + currentLevel = level; + }, + enable(level) { + if (currentLevel !== undefined && level >= currentLevel) { + set(original); + currentLevel = undefined; + } + }, + }; +} + +const assertionCache = { + assertEachNode: createAssertionCacheEntry(assertEachNode, fn => assertEachNode = fn), + assertNode: createAssertionCacheEntry(assertNode, fn => assertNode = fn), + assertNotNode: createAssertionCacheEntry(assertNotNode, fn => assertNotNode = fn), + assertOptionalNode: createAssertionCacheEntry(assertOptionalNode, fn => assertOptionalNode = fn), + assertOptionalToken: createAssertionCacheEntry(assertOptionalToken, fn => assertOptionalToken = fn), + assertMissingNode: createAssertionCacheEntry(assertMissingNode, fn => assertMissingNode = fn), +} as const; + +type AssertionKeys = keyof typeof assertionCache; + +/** + * Asserts a value has the specified type in typespace only (does not perform a runtime assertion). + * This is useful in cases where we switch on `node.kind` and can be reasonably sure the type is accurate, and + * as a result can reduce the number of unnecessary casts. + * + * @internal + */ +export function assertType(value: unknown): asserts value is T; +export function assertType(_value: unknown) { } - export function assertNever(member: never, message = "Illegal value:", stackCrawlMark?: AnyFunction): never { - const detail = typeof member === "object" && hasKind(member) && hasPos(member) ? "SyntaxKind: " + formatSyntaxKind((member as Node).kind) : JSON.stringify(member); - return fail(`${message} ${detail}`, stackCrawlMark || assertNever); +/** @internal */ +export function getFunctionName(func: AnyFunction) { + if (typeof func !== "function") { + return ""; + } + else if (hasProperty(func, "name")) { + return (func as any).name; } + else { + const text = Function.prototype.toString.call(func); + const match = /^function\s+([\w\$]+)\s*\(/.exec(text); + return match ? match[1] : ""; + } +} + +/** @internal */ +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 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: NodeArray | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is NodeArray | undefined; - export function assertEachNode(nodes: readonly T[] | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is readonly U[] | undefined; - export function assertEachNode(nodes: readonly Node[], test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction): void; - export function assertEachNode(nodes: readonly Node[] | undefined, test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction) { - if (shouldAssertFunction(AssertionLevel.Normal, "assertEachNode")) { - assert( - test === undefined || nodes?.every(test), - message || "Unexpected node.", - () => `Node array did not pass test '${getFunctionName(test!)}'.`, - stackCrawlMark || assertEachNode); +/** + * Formats an enum value as a string for debugging and debug assertions. + * + * @internal + */ +export function formatEnum(value = 0, enumObject: any, isFlags?: boolean) { + const members = getEnumMembers(enumObject); + if (value === 0) { + return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0"; + } + if (isFlags) { + const result: string[] = []; + let remainingFlags = value; + for (const [enumValue, enumName] of members) { + if (enumValue > value) { + break; + } + if (enumValue !== 0 && enumValue & value) { + result.push(enumName); + remainingFlags &= ~enumValue; + } + } + if (remainingFlags === 0) { + return result.join("|"); } } - - 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); + else { + for (const [enumValue, enumName] of members) { + if (enumValue === value) { + return enumName; + } } } + return value.toString(); +} - 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); - } +const enumMemberCache = new Map>(); + +function getEnumMembers(enumObject: any) { + // Assuming enum objects do not change at runtime, we can cache the enum members list + // to reuse later. This saves us from reconstructing this each and every time we call + // a formatting function (which can be expensive for large enums like SyntaxKind). + const existing = enumMemberCache.get(enumObject); + if (existing) { + return existing; } - 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); + const result: [number, string][] = []; + for (const name in enumObject) { + const value = enumObject[name]; + if (typeof value === "number") { + result.push([value, name]); } } - 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); - } + const sorted = stableSort<[number, string]>(result, (x, y) => compareValues(x[0], y[0])); + enumMemberCache.set(enumObject, sorted); + return sorted; +} + +/** @internal */ +export function formatSyntaxKind(kind: SyntaxKind | undefined): string { + return formatEnum(kind, (types as any).SyntaxKind, /*isFlags*/ false); +} + +/** @internal */ +export function formatSnippetKind(kind: SnippetKind | undefined): string { + return formatEnum(kind, (types as any).SnippetKind, /*isFlags*/ false); +} + +/** @internal */ +export function formatNodeFlags(flags: NodeFlags | undefined): string { + return formatEnum(flags, (types as any).NodeFlags, /*isFlags*/ true); +} + +/** @internal */ +export function formatModifierFlags(flags: ModifierFlags | undefined): string { + return formatEnum(flags, (types as any).ModifierFlags, /*isFlags*/ true); +} + +/** @internal */ +export function formatTransformFlags(flags: TransformFlags | undefined): string { + return formatEnum(flags, (types as any).TransformFlags, /*isFlags*/ true); +} + +/** @internal */ +export function formatEmitFlags(flags: EmitFlags | undefined): string { + return formatEnum(flags, (types as any).EmitFlags, /*isFlags*/ true); +} + +/** @internal */ +export function formatSymbolFlags(flags: SymbolFlags | undefined): string { + return formatEnum(flags, (types as any).SymbolFlags, /*isFlags*/ true); +} + +/** @internal */ +export function formatTypeFlags(flags: TypeFlags | undefined): string { + return formatEnum(flags, (types as any).TypeFlags, /*isFlags*/ true); +} + +/** @internal */ +export function formatSignatureFlags(flags: SignatureFlags | undefined): string { + return formatEnum(flags, (types as any).SignatureFlags, /*isFlags*/ true); +} + +/** @internal */ +export function formatObjectFlags(flags: ObjectFlags | undefined): string { + return formatEnum(flags, (types as any).ObjectFlags, /*isFlags*/ true); +} + +/** @internal */ +export function formatFlowFlags(flags: FlowFlags | undefined): string { + return formatEnum(flags, (types as any).FlowFlags, /*isFlags*/ true); +} + +/** @internal */ +export function formatRelationComparisonResult(result: RelationComparisonResult | undefined): string { + return formatEnum(result, (types as any).RelationComparisonResult, /*isFlags*/ true); +} + +/** @internal */ +export function formatCheckMode(mode: CheckMode | undefined): string { + return formatEnum(mode, (checkerTypes as any).CheckMode, /*isFlags*/ true); +} + +/** @internal */ +export function formatSignatureCheckMode(mode: SignatureCheckMode | undefined): string { + return formatEnum(mode, (checkerTypes as any).SignatureCheckMode, /*isFlags*/ true); +} + +/** @internal */ +export function formatTypeFacts(facts: TypeFacts | undefined): string { + return formatEnum(facts, (checkerTypes as any).TypeFacts, /*isFlags*/ true); +} + +let isDebugInfoEnabled = false; + +let flowNodeProto: FlowNodeBase | undefined; + +function attachFlowNodeDebugInfoWorker(flowNode: FlowNodeBase) { + if (!("__debugFlowFlags" in flowNode)) { // eslint-disable-line local/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" : + "UnknownFlow"; + const remainingFlags = this.flags & ~(FlowFlags.Referenced - 1); + return `${flowHeader}${remainingFlags ? ` (${formatFlowFlags(remainingFlags)})`: ""}`; + } + }, + __debugFlowFlags: { get(this: FlowNodeBase) { return formatEnum(this.flags, (types as any).FlowFlags, /*isFlags*/ true); } }, + __debugToString: { value(this: FlowNodeBase) { return formatControlFlowGraph(this); } } + }); } +} - 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); +/** @internal */ +export function attachFlowNodeDebugInfo(flowNode: 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; + attachFlowNodeDebugInfoWorker(flowNodeProto); + } + Object.setPrototypeOf(flowNode, flowNodeProto); + } + else { + // not running in an es2015 environment, attach the method directly. + attachFlowNodeDebugInfoWorker(flowNode); } } +} - /** - * Asserts a value has the specified type in typespace only (does not perform a runtime assertion). - * This is useful in cases where we switch on `node.kind` and can be reasonably sure the type is accurate, and - * as a result can reduce the number of unnecessary casts. - */ - export function type(value: unknown): asserts value is T; - export function type(_value: unknown) { } +let nodeArrayProto: NodeArray | undefined; + +function attachNodeArrayDebugInfoWorker(array: NodeArray) { + if (!("__tsDebuggerDisplay" in array)) { // eslint-disable-line local/no-in-operator + Object.defineProperties(array, { + __tsDebuggerDisplay: { + value(this: 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. + // This regex can trigger slow backtracking because of overlapping potential captures. + // We don't care, this is debug code that's only enabled with a debugger attached - + // we're just taking note of it for anyone checking regex performance in the future. + defaultValue = String(defaultValue).replace(/(?:,[\s\w\d_]+:[^,]+)+\]$/, "]"); + return `NodeArray ${defaultValue}`; + } + } + }); + } +} - export function getFunctionName(func: AnyFunction) { - if (typeof func !== "function") { - return ""; - } - else if (hasName(func)) { - return (func as any).name; +/** @internal */ +export function attachNodeArrayDebugInfo(array: 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; + attachNodeArrayDebugInfoWorker(nodeArrayProto); + } + Object.setPrototypeOf(array, nodeArrayProto); } else { - const text = Function.prototype.toString.call(func); - const match = /^function\s+([\w\$]+)\s*\(/.exec(text); - return match ? match[1] : ""; + // not running in an es2015 environment, attach the method directly. + attachNodeArrayDebugInfoWorker(array); } } +} - export function formatSymbol(symbol: Symbol): string { - return formatSymbolWorker(symbol); +/** + * Injects debug information into frequently used types. + * + * @internal + */ +export function enableDebugInfo() { + if (isDebugInfoEnabled) return; + + // avoid recomputing + const weakTypeTextMap = new WeakMap(); + const weakNodeTextMap = new WeakMap(); + + // Add additional properties in debug mode to assist with debugging. + Object.defineProperties(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" : + "Symbol"; + const remainingSymbolFlags = this.flags & ~SymbolFlags.Transient; + return `${symbolHeader} '${symbolName(this)}'${remainingSymbolFlags ? ` (${formatSymbolFlags(remainingSymbolFlags)})` : ""}`; + } + }, + __debugFlags: { get(this: Symbol) { return formatSymbolFlags(this.flags); } } + }); + + Object.defineProperties(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" : + "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)})` : ""}`; + } + }, + __debugFlags: { get(this: Type) { return formatTypeFlags(this.flags); } }, + __debugObjectFlags: { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((this as ObjectType).objectFlags) : ""; } }, + __debugTypeToString: { + value(this: Type) { + // avoid recomputing + let text = weakTypeTextMap.get(this); + if (text === undefined) { + text = this.checker.typeToString(this); + weakTypeTextMap.set(this, text); + } + return text; + } + }, + }); + + Object.defineProperties(objectAllocator.getSignatureConstructor().prototype, { + __debugFlags: { get(this: Signature) { return formatSignatureFlags(this.flags); } }, + __debugSignatureToString: { value(this: Signature) { return this.checker?.signatureToString(this); } } + }); + + const nodeConstructors = [ + objectAllocator.getNodeConstructor(), + objectAllocator.getIdentifierConstructor(), + objectAllocator.getTokenConstructor(), + objectAllocator.getSourceFileConstructor() + ]; + + for (const ctor of nodeConstructors) { + if (!hasProperty(ctor.prototype, "__debugKind")) { + 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" : + 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)); } }, + __debugGetText: { + value(this: Node, includeTrivia?: boolean) { + if (nodeIsSynthesized(this)) return ""; + // avoid recomputing + let text = weakNodeTextMap.get(this); + if (text === undefined) { + const parseNode = getParseTreeNode(this); + const sourceFile = parseNode && getSourceFileOfNode(parseNode); + text = sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : ""; + weakNodeTextMap.set(this, text); + } + return text; + } + } + }); + } } - export function formatEnum(value = 0, enumObject: any, isFlags?: boolean) { - return formatEnumWorker(value, enumObject, isFlags); + isDebugInfoEnabled = true; +} + +/** @internal */ +export function formatVariance(varianceFlags: VarianceFlags) { + const variance = varianceFlags & VarianceFlags.VarianceMask; + let result = + variance === VarianceFlags.Invariant ? "in out" : + variance === VarianceFlags.Bivariant ? "[bivariant]" : + variance === VarianceFlags.Contravariant ? "in" : + variance === VarianceFlags.Covariant ? "out" : + variance === VarianceFlags.Independent ? "[independent]" : ""; + if (varianceFlags & VarianceFlags.Unmeasurable) { + result += " (unmeasurable)"; + } + else if (varianceFlags & VarianceFlags.Unreliable) { + result += " (unreliable)"; } + return result; +} - export function formatSyntaxKind(kind: SyntaxKind | undefined): string { - return formatSyntaxKindWorker(kind); +/** @internal */ +export type DebugType = Type & { __debugTypeToString(): string }; // eslint-disable-line @typescript-eslint/naming-convention +/** @internal */ +export class DebugTypeMapper { + declare kind: TypeMapKind; + __debugToString(): string { // eslint-disable-line @typescript-eslint/naming-convention + assertType(this); + switch (this.kind) { + case TypeMapKind.Function: return this.debugInfo?.() || "(function mapper)"; + case TypeMapKind.Simple: return `${(this.source as DebugType).__debugTypeToString()} -> ${(this.target as DebugType).__debugTypeToString()}`; + case TypeMapKind.Array: return zipWith( + this.sources as readonly DebugType[], + this.targets as readonly DebugType[] || map(this.sources, () => "any"), + (s, t) => `${s.__debugTypeToString()} -> ${typeof t === "string" ? t : t.__debugTypeToString()}`).join(", "); + case TypeMapKind.Deferred: return zipWith( + this.sources, + this.targets, + (s, t) => `${(s as DebugType).__debugTypeToString()} -> ${(t() as DebugType).__debugTypeToString()}`).join(", "); + case TypeMapKind.Merged: + case TypeMapKind.Composite: return `m1: ${(this.mapper1 as unknown as DebugTypeMapper).__debugToString().split("\n").join("\n ")} +m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n").join("\n ")}`; + default: return assertNever(this); + } } +} - export function formatSnippetKind(kind: SnippetKind | undefined): string { - return formatSnippetKindWorker(kind); +/** @internal */ +export function attachDebugPrototypeIfDebug(mapper: TypeMapper): TypeMapper { + if (isDebugging) { + return Object.setPrototypeOf(mapper, DebugTypeMapper.prototype); } + return mapper; +} + +/** @internal */ +export function printControlFlowGraph(flowNode: FlowNode) { + return console.log(formatControlFlowGraph(flowNode)); +} + +/** @internal */ +export function formatControlFlowGraph(flowNode: FlowNode) { + let nextDebugFlowId = -1; - export function formatNodeFlags(flags: NodeFlags | undefined): string { - return formatNodeFlagsWorker(flags); + function getDebugFlowNodeId(f: FlowNode) { + if (!f.id) { + f.id = nextDebugFlowId; + nextDebugFlowId--; + } + return f.id; } - export function formatModifierFlags(flags: ModifierFlags | undefined): string { - return formatModifierFlagsWorker(flags); + const enum BoxCharacter { + lr = "─", + ud = "│", + dr = "╭", + dl = "╮", + ul = "╯", + ur = "╰", + udr = "├", + udl = "┤", + dlr = "┬", + ulr = "┴", + udlr = "╫", } - export function formatTransformFlags(flags: TransformFlags | undefined): string { - return formatTransformFlagsWorker(flags); + const enum Connection { + None = 0, + Up = 1 << 0, + Down = 1 << 1, + Left = 1 << 2, + Right = 1 << 3, + + UpDown = Up | Down, + LeftRight = Left | Right, + UpLeft = Up | Left, + UpRight = Up | Right, + DownLeft = Down | Left, + DownRight = Down | Right, + UpDownLeft = UpDown | Left, + UpDownRight = UpDown | Right, + UpLeftRight = Up | LeftRight, + DownLeftRight = Down | LeftRight, + UpDownLeftRight = UpDown | LeftRight, + + NoChildren = 1 << 4, } - export function formatEmitFlags(flags: EmitFlags | undefined): string { - return formatEmitFlagsWorker(flags); + interface FlowGraphNode { + id: number; + flowNode: FlowNode; + edges: FlowGraphEdge[]; + text: string; + lane: number; + endLane: number; + level: number; + circular: boolean | "circularity"; } - export function formatSymbolFlags(flags: SymbolFlags | undefined): string { - return formatSymbolFlagsWorker(flags); + interface FlowGraphEdge { + source: FlowGraphNode; + target: FlowGraphNode; } - export function formatTypeFlags(flags: TypeFlags | undefined): string { - return formatTypeFlagsWorker(flags); + const hasAntecedentFlags = + FlowFlags.Assignment | + FlowFlags.Condition | + FlowFlags.SwitchClause | + FlowFlags.ArrayMutation | + FlowFlags.Call | + FlowFlags.ReduceLabel; + + const hasNodeFlags = + FlowFlags.Start | + FlowFlags.Assignment | + FlowFlags.Call | + FlowFlags.Condition | + FlowFlags.ArrayMutation; + + const links: Record = Object.create(/*o*/ null); // eslint-disable-line no-null/no-null + const nodes: FlowGraphNode[] = []; + const edges: FlowGraphEdge[] = []; + const root = buildGraphNode(flowNode, new Set()); + for (const node of nodes) { + node.text = renderFlowNode(node.flowNode, node.circular); + computeLevel(node); } - export function formatSignatureFlags(flags: SignatureFlags | undefined): string { - return formatSignatureFlagsWorker(flags); + const height = computeHeight(root); + const columnWidths = computeColumnWidths(height); + computeLanes(root, 0); + return renderGraph(); + + function isFlowSwitchClause(f: FlowNode): f is FlowSwitchClause { + return !!(f.flags & FlowFlags.SwitchClause); } - export function formatObjectFlags(flags: ObjectFlags | undefined): string { - return formatObjectFlagsWorker(flags); + function hasAntecedents(f: FlowNode): f is FlowLabel & { antecedents: FlowNode[] } { + return !!(f.flags & FlowFlags.Label) && !!(f as FlowLabel).antecedents; } - export function formatFlowFlags(flags: FlowFlags | undefined): string { - return formatFlowFlagsWorker(flags); + function hasAntecedent(f: FlowNode): f is Extract { + return !!(f.flags & hasAntecedentFlags); } - export function formatRelationComparisonResult(result: RelationComparisonResult | undefined): string { - return formatRelationComparisonResultWorker(result); + function hasNode(f: FlowNode): f is Extract { + return !!(f.flags & hasNodeFlags); } - export function formatCheckMode(mode: CheckMode | undefined): string { - return formatCheckModeWorker(mode); + function getChildren(node: FlowGraphNode) { + const children: FlowGraphNode[] = []; + for (const edge of node.edges) { + if (edge.source === node) { + children.push(edge.target); + } + } + return children; } - export function formatSignatureCheckMode(mode: SignatureCheckMode | undefined): string { - return formatSignatureCheckModeWorker(mode); + function getParents(node: FlowGraphNode) { + const parents: FlowGraphNode[] = []; + for (const edge of node.edges) { + if (edge.target === node) { + parents.push(edge.source); + } + } + return parents; } - export function formatTypeFacts(facts: TypeFacts | undefined): string { - return formatTypeFactsWorker(facts); + function buildGraphNode(flowNode: FlowNode, seen: Set): FlowGraphNode { + const id = getDebugFlowNodeId(flowNode); + let graphNode = links[id]; + if (graphNode && seen.has(flowNode)) { + graphNode.circular = true; + graphNode = { + id: -1, + flowNode, + edges: [], + text: "", + lane: -1, + endLane: -1, + level: -1, + circular: "circularity" + }; + nodes.push(graphNode); + return graphNode; + } + seen.add(flowNode); + if (!graphNode) { + links[id] = graphNode = { id, flowNode, edges: [], text: "", lane: -1, endLane: -1, level: -1, circular: false }; + nodes.push(graphNode); + if (hasAntecedents(flowNode)) { + for (const antecedent of flowNode.antecedents) { + buildGraphEdge(graphNode, antecedent, seen); + } + } + else if (hasAntecedent(flowNode)) { + buildGraphEdge(graphNode, flowNode.antecedent, seen); + } + } + seen.delete(flowNode); + return graphNode; } - let isDebugInfoEnabled = false; + function buildGraphEdge(source: FlowGraphNode, antecedent: FlowNode, seen: Set) { + const target = buildGraphNode(antecedent, seen); + const edge: FlowGraphEdge = { source, target }; + edges.push(edge); + source.edges.push(edge); + target.edges.push(edge); + } - export function attachFlowNodeDebugInfo(flowNode: FlowNodeBase) { - if (isDebugInfoEnabled) { - attachFlowNodeDebugInfoWorker(flowNode); + function computeLevel(node: FlowGraphNode): number { + if (node.level !== -1) { + return node.level; } + let level = 0; + for (const parent of getParents(node)) { + level = Math.max(level, computeLevel(parent) + 1); + } + return node.level = level; } - export function attachNodeArrayDebugInfo(array: NodeArray) { - if (isDebugInfoEnabled) { - attachNodeArrayDebugInfoWorker(array); + function computeHeight(node: FlowGraphNode): number { + let height = 0; + for (const child of getChildren(node)) { + height = Math.max(height, computeHeight(child)); } + return height + 1; } - /** - * Injects debug information into frequently used types. - */ - export function enableDebugInfo() { - if (isDebugInfoEnabled) return; + function computeColumnWidths(height: number) { + const columns: number[] = fill(Array(height), 0); + for (const node of nodes) { + columns[node.level] = Math.max(columns[node.level], node.text.length); + } + return columns; + } - enableDebugInfoWorder(); + function computeLanes(node: FlowGraphNode, lane: number) { + if (node.lane === -1) { + node.lane = lane; + node.endLane = lane; + const children = getChildren(node); + for (let i = 0; i < children.length; i++) { + if (i > 0) lane++; + const child = children[i]; + computeLanes(child, lane); + if (child.endLane > node.endLane) { + lane = child.endLane; + } + } + node.endLane = lane; + } + } - isDebugInfoEnabled = true; + function getHeader(flags: FlowFlags) { + if (flags & FlowFlags.Start) return "Start"; + if (flags & FlowFlags.BranchLabel) return "Branch"; + if (flags & FlowFlags.LoopLabel) return "Loop"; + if (flags & FlowFlags.Assignment) return "Assignment"; + if (flags & FlowFlags.TrueCondition) return "True"; + if (flags & FlowFlags.FalseCondition) return "False"; + if (flags & FlowFlags.SwitchClause) return "SwitchClause"; + if (flags & FlowFlags.ArrayMutation) return "ArrayMutation"; + if (flags & FlowFlags.Call) return "Call"; + if (flags & FlowFlags.ReduceLabel) return "ReduceLabel"; + if (flags & FlowFlags.Unreachable) return "Unreachable"; + throw new Error(); } - export function formatVariance(varianceFlags: VarianceFlags) { - const variance = varianceFlags & VarianceFlags.VarianceMask; - let result = - variance === VarianceFlags.Invariant ? "in out" : - variance === VarianceFlags.Bivariant ? "[bivariant]" : - variance === VarianceFlags.Contravariant ? "in" : - variance === VarianceFlags.Covariant ? "out" : - variance === VarianceFlags.Independent ? "[independent]" : ""; - if (varianceFlags & VarianceFlags.Unmeasurable) { - result += " (unmeasurable)"; + function getNodeText(node: Node) { + const sourceFile = getSourceFileOfNode(node); + return getSourceTextOfNodeFromSourceFile(sourceFile, node, /*includeTrivia*/ false); + } + + function renderFlowNode(flowNode: FlowNode, circular: boolean | "circularity") { + let text = getHeader(flowNode.flags); + if (circular) { + text = `${text}#${getDebugFlowNodeId(flowNode)}`; + } + if (hasNode(flowNode)) { + if (flowNode.node) { + text += ` (${getNodeText(flowNode.node)})`; + } } - else if (varianceFlags & VarianceFlags.Unreliable) { - result += " (unreliable)"; + else if (isFlowSwitchClause(flowNode)) { + const clauses: string[] = []; + for (let i = flowNode.clauseStart; i < flowNode.clauseEnd; i++) { + const clause = flowNode.switchStatement.caseBlock.clauses[i]; + if (isDefaultClause(clause)) { + clauses.push("default"); + } + else { + clauses.push(getNodeText(clause.expression)); + } + } + text += ` (${clauses.join(", ")})`; } - return result; + return circular === "circularity" ? `Circular(${text})` : text; } - export class DebugTypeMapper { - declare kind: TypeMapKind; - __debugToString(): string { // eslint-disable-line @typescript-eslint/naming-convention - type(this); - switch (this.kind) { - case TypeMapKind.Function: return this.debugInfo?.() || "(function mapper)"; - case TypeMapKind.Simple: return `${(this.source as DebugType).__debugTypeToString()} -> ${(this.target as DebugType).__debugTypeToString()}`; - case TypeMapKind.Array: return arrayTypeToString(this.sources as readonly DebugType[], this.targets as DebugType[] | undefined); - case TypeMapKind.Deferred: return deferredTypeToString(this.sources, this.targets); - case TypeMapKind.Merged: - case TypeMapKind.Composite: return `m1: ${(this.mapper1 as unknown as DebugTypeMapper).__debugToString().split("\n").join("\n ")} -m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n").join("\n ")}`; - default: return assertNever(this); + function renderGraph() { + const columnCount = columnWidths.length; + const laneCount = nodes.reduce((x, n) => Math.max(x, n.lane), 0) + 1; + const lanes: string[] = fill(Array(laneCount), ""); + const grid: (FlowGraphNode | undefined)[][] = columnWidths.map(() => Array(laneCount)); + const connectors: Connection[][] = columnWidths.map(() => fill(Array(laneCount), 0)); + + // build connectors + for (const node of nodes) { + grid[node.level][node.lane] = node; + const children = getChildren(node); + for (let i = 0; i < children.length; i++) { + const child = children[i]; + let connector: Connection = Connection.Right; + if (child.lane === node.lane) connector |= Connection.Left; + if (i > 0) connector |= Connection.Up; + if (i < children.length - 1) connector |= Connection.Down; + connectors[node.level][child.lane] |= connector; + } + if (children.length === 0) { + connectors[node.level][node.lane] |= Connection.NoChildren; + } + const parents = getParents(node); + for (let i = 0; i < parents.length; i++) { + const parent = parents[i]; + let connector: Connection = Connection.Left; + if (i > 0) connector |= Connection.Up; + if (i < parents.length - 1) connector |= Connection.Down; + connectors[node.level - 1][parent.lane] |= connector; + } + } + + // fill in missing connectors + for (let column = 0; column < columnCount; column++) { + for (let lane = 0; lane < laneCount; lane++) { + const left = column > 0 ? connectors[column - 1][lane] : 0; + const above = lane > 0 ? connectors[column][lane - 1] : 0; + let connector = connectors[column][lane]; + if (!connector) { + if (left & Connection.Right) connector |= Connection.LeftRight; + if (above & Connection.Down) connector |= Connection.UpDown; + connectors[column][lane] = connector; + } + } + } + + for (let column = 0; column < columnCount; column++) { + for (let lane = 0; lane < lanes.length; lane++) { + const connector = connectors[column][lane]; + const fill = connector & Connection.Left ? BoxCharacter.lr : " "; + const node = grid[column][lane]; + if (!node) { + if (column < columnCount - 1) { + writeLane(lane, repeat(fill, columnWidths[column] + 1)); + } + } + else { + writeLane(lane, node.text); + if (column < columnCount - 1) { + writeLane(lane, " "); + writeLane(lane, repeat(fill, columnWidths[column] - node.text.length)); + } + } + writeLane(lane, getBoxCharacter(connector)); + writeLane(lane, connector & Connection.Right && column < columnCount - 1 && !grid[column + 1][lane] ? BoxCharacter.lr : " "); } } + + return `\n${lanes.join("\n")}\n`; + + function writeLane(lane: number, text: string) { + lanes[lane] += text; + } } - export function attachDebugPrototypeIfDebug(mapper: TypeMapper): TypeMapper { - if (isDebugging) { - return Object.setPrototypeOf(mapper, DebugTypeMapper.prototype); + function getBoxCharacter(connector: Connection) { + switch (connector) { + case Connection.UpDown: return BoxCharacter.ud; + case Connection.LeftRight: return BoxCharacter.lr; + case Connection.UpLeft: return BoxCharacter.ul; + case Connection.UpRight: return BoxCharacter.ur; + case Connection.DownLeft: return BoxCharacter.dl; + case Connection.DownRight: return BoxCharacter.dr; + case Connection.UpDownLeft: return BoxCharacter.udl; + case Connection.UpDownRight: return BoxCharacter.udr; + case Connection.UpLeftRight: return BoxCharacter.ulr; + case Connection.DownLeftRight: return BoxCharacter.dlr; + case Connection.UpDownLeftRight: return BoxCharacter.udlr; } - return mapper; + return " "; } - export function printControlFlowGraph(flowNode: FlowNode) { - return console.log(formatControlFlowGraph(flowNode)); + function fill(array: T[], value: T) { + if (array.fill) { + array.fill(value); + } + else { + for (let i = 0; i < array.length; i++) { + array[i] = value; + } + } + return array; } - export function formatControlFlowGraph(flowNode: FlowNode) { - return formatControlFlowGraphWorker(flowNode); + function repeat(ch: string, length: number) { + if (ch.repeat) { + return length > 0 ? ch.repeat(length) : ""; + } + let s = ""; + while (s.length < length) { + s += ch; + } + return s; } } diff --git a/src/compiler/debugUtilities.ts b/src/compiler/debugUtilities.ts deleted file mode 100644 index ebdf0bfaa736e..0000000000000 --- a/src/compiler/debugUtilities.ts +++ /dev/null @@ -1,870 +0,0 @@ -/* eslint-disable */ -import * as types from "./types"; -import * as checkerTypes from "./checkerUtilities"; -/* eslint-enable */ - -import { - compareValues, - hasProperty, - map, - stableSort, - zipWith, -} from "./core"; -import { SortedReadonlyArray } from "./corePublic"; -import { - __String, - BigIntLiteralType, - EmitFlags, - FlowFlags, - FlowLabel, - FlowNode, - FlowNodeBase, - FlowSwitchClause, - IntrinsicType, - LiteralType, - ModifierFlags, - Node, - NodeArray, - NodeFlags, - ObjectFlags, - ObjectType, - RelationComparisonResult, - Signature, - SignatureFlags, - SnippetKind, - Symbol, - SymbolFlags, - SyntaxKind, - TransformFlags, - Type, - TypeFlags, -} from "./types"; -import { - getEffectiveModifierFlagsNoCache, - getEmitFlags, - getSourceFileOfNode, - getSourceTextOfNodeFromSourceFile, - nodeIsSynthesized, -} from "./utilities"; -import { - getParseTreeNode, - idText, - isGeneratedIdentifier, - isParseTreeNode, - symbolName, - unescapeLeadingUnderscores, -} from "./utilitiesPublic"; -import { objectAllocator } from "./objectAllocator"; -import { CheckMode, SignatureCheckMode, TypeFacts } from "./checkerUtilities"; -import { - isArrayTypeNode, - isBigIntLiteral, - isCallSignatureDeclaration, - isConditionalTypeNode, - isConstructorDeclaration, - isConstructorTypeNode, - isConstructSignatureDeclaration, - isDefaultClause, - isFunctionTypeNode, - isGetAccessorDeclaration, - isIdentifier, - isImportTypeNode, - isIndexedAccessTypeNode, - isIndexSignatureDeclaration, - isInferTypeNode, - isIntersectionTypeNode, - isLiteralTypeNode, - isMappedTypeNode, - isNamedTupleMember, - isNumericLiteral, - isOptionalTypeNode, - isParameter, - isParenthesizedTypeNode, - isPrivateIdentifier, - isRestTypeNode, - isSetAccessorDeclaration, - isStringLiteral, - isThisTypeNode, - isTupleTypeNode, - isTypeLiteralNode, - isTypeOperatorNode, - isTypeParameterDeclaration, - isTypePredicateNode, - isTypeQueryNode, - isTypeReferenceNode, - isUnionTypeNode, -} from "./factory/nodeTests"; - -export type DebugType = Type & { __debugTypeToString(): string }; // eslint-disable-line @typescript-eslint/naming-convention -const enumMemberCache = new Map>(); -const weakTypeTextMap = new WeakMap(); -const weakNodeTextMap = new WeakMap(); - -let nodeArrayProto: NodeArray | undefined; -let flowNodeProto: FlowNodeBase | undefined; - -function getEnumMembers(enumObject: any) { - // Assuming enum objects do not change at runtime, we can cache the enum members list - // to reuse later. This saves us from reconstructing this each and every time we call - // a formatting function (which can be expensive for large enums like SyntaxKind). - const existing = enumMemberCache.get(enumObject); - if (existing) { - return existing; - } - - const result: [number, string][] = []; - for (const name in enumObject) { - const value = enumObject[name]; - if (typeof value === "number") { - result.push([value, name]); - } - } - - const sorted = stableSort<[number, string]>(result, (x, y) => compareValues(x[0], y[0])); - enumMemberCache.set(enumObject, sorted); - return sorted; -} - -function attachSymbolDebugInfo(symbol: Symbol) { - // Add additional properties in debug mode to assist with debugging. - Object.defineProperties(symbol, { - // for use with vscode-js-debug's new customDescriptionGenerator in launch.json - __tsDebuggerDisplay: { - value(this: Symbol) { - const symbolHeader = - this.flags & SymbolFlags.Transient ? "TransientSymbol" : - "Symbol"; - const remainingSymbolFlags = this.flags & ~SymbolFlags.Transient; - return `${symbolHeader} '${symbolName(this)}'${remainingSymbolFlags ? ` (${formatSymbolFlagsWorker(remainingSymbolFlags)})` : ""}`; - } - }, - __debugFlags: { get(this: Symbol) { return formatSymbolFlagsWorker(this.flags); } } - }); -} - -function attachTypeDebugInfo(type: Type) { - Object.defineProperties(type, { - // 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" : - "ObjectType" : - "Type"; - const remainingObjectFlags = this.flags & TypeFlags.Object ? (this as ObjectType).objectFlags & ~ObjectFlags.ObjectTypeKindMask : 0; - return `${typeHeader}${this.symbol ? ` '${symbolName(this.symbol)}'` : ""}${remainingObjectFlags ? ` (${formatObjectFlagsWorker(remainingObjectFlags)})` : ""}`; - } - }, - __debugFlags: { get(this: Type) { return formatTypeFlagsWorker(this.flags); } }, - __debugObjectFlags: { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlagsWorker((this as ObjectType).objectFlags) : ""; } }, - __debugTypeToString: { - value(this: Type) { - // avoid recomputing - let text = weakTypeTextMap.get(this); - if (text === undefined) { - text = this.checker.typeToString(this); - weakTypeTextMap.set(this, text); - } - return text; - } - }, - }); -} - -function attachSignatureDebugInfo(signature: Signature) { - Object.defineProperties(signature, { - __debugFlags: { get(this: Signature) { return formatSignatureFlagsWorker(this.flags); } }, - __debugSignatureToString: { value(this: Signature) { return this.checker?.signatureToString(this); } } - }); -} - -function attachNodeDebugInfo(node: Node) { - Object.defineProperties(node, { - // 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" : - formatSyntaxKindWorker(this.kind); - return `${nodeHeader}${this.flags ? ` (${formatNodeFlagsWorker(this.flags)})` : ""}`; - } - }, - __debugKind: { get(this: Node) { return formatSyntaxKindWorker(this.kind); } }, - __debugNodeFlags: { get(this: Node) { return formatNodeFlagsWorker(this.flags); } }, - __debugModifierFlags: { get(this: Node) { return formatModifierFlagsWorker(getEffectiveModifierFlagsNoCache(this)); } }, - __debugTransformFlags: { get(this: Node) { return formatTransformFlagsWorker(this.transformFlags); } }, - __debugIsParseTreeNode: { get(this: Node) { return isParseTreeNode(this); } }, - __debugEmitFlags: { get(this: Node) { return formatEmitFlagsWorker(getEmitFlags(this)); } }, - __debugGetText: { - value(this: Node, includeTrivia?: boolean) { - if (nodeIsSynthesized(this)) return ""; - // avoid recomputing - let text = weakNodeTextMap.get(this); - if (text === undefined) { - const parseNode = getParseTreeNode(this); - const sourceFile = parseNode && getSourceFileOfNode(parseNode); - text = sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : ""; - weakNodeTextMap.set(this, text); - } - return text; - } - } - }); -} - -function attachNodeArrayDebugInfo(array: NodeArray) { - if (!("__tsDebuggerDisplay" in array)) { // eslint-disable-line local/no-in-operator - Object.defineProperties(array, { - __tsDebuggerDisplay: { - value(this: 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. - // This regex can trigger slow backtracking because of overlapping potential captures. - // We don't care, this is debug code that's only enabled with a debugger attached - - // we're just taking note of it for anyone checking regex performance in the future. - defaultValue = String(defaultValue).replace(/(?:,[\s\w\d_]+:[^,]+)+\]$/, "]"); - return `NodeArray ${defaultValue}`; - } - } - }); - } -} - -function attachFlowNodeDebugInfo(flowNode: FlowNodeBase) { - if (!("__debugFlowFlags" in flowNode)) { // eslint-disable-line local/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" : - "UnknownFlow"; - const remainingFlags = this.flags & ~(FlowFlags.Referenced - 1); - return `${flowHeader}${remainingFlags ? ` (${formatFlowFlagsWorker(remainingFlags)})`: ""}`; - } - }, - __debugFlowFlags: { get(this: FlowNodeBase) { return formatEnumWorker(this.flags, (types as any).FlowFlags, /*isFlags*/ true); } }, - __debugToString: { value(this: FlowNodeBase) { return formatControlFlowGraphWorker(this); } } - }); - } -} - -export function getNodeText(node: Node) { - const sourceFile = getSourceFileOfNode(node); - return getSourceTextOfNodeFromSourceFile(sourceFile, node, /*includeTrivia*/ false); -} - -/** - * Formats an enum value as a string for debugging and debug assertions. - */ -export function formatEnumWorker(value = 0, enumObject: any, isFlags?: boolean) { - const members = getEnumMembers(enumObject); - if (value === 0) { - return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0"; - } - if (isFlags) { - const result: string[] = []; - let remainingFlags = value; - for (const [enumValue, enumName] of members) { - if (enumValue > value) { - break; - } - if (enumValue !== 0 && enumValue & value) { - result.push(enumName); - remainingFlags &= ~enumValue; - } - } - if (remainingFlags === 0) { - return result.join("|"); - } - } - else { - for (const [enumValue, enumName] of members) { - if (enumValue === value) { - return enumName; - } - } - } - return value.toString(); -} - -export function arrayTypeToString(sources: readonly DebugType[], targets: readonly DebugType[] | undefined) { - return zipWith(sources, targets || map(sources, () => "any"), - (s, t) => `${s.__debugTypeToString()} -> ${typeof t === "string" ? t : t.__debugTypeToString()}`).join(", "); -} - -export function deferredTypeToString(sources: readonly Type[], targets: (() => Type)[]) { - return zipWith(sources, targets, - (s, t) => `${(s as DebugType).__debugTypeToString()} -> ${(t() as DebugType).__debugTypeToString()}`).join(", "); -} - -export function hasKind(node: any) { - return hasProperty(node, "kind"); -} - -export function hasPos(node: any) { - return hasProperty(node, "pos"); -} - -export function hasName(node: any) { - return hasProperty(node, "name"); -} - -export function hasDebugKind(node: any) { - return hasProperty(node, "__debugKind"); -} - -export function assertNoop(_?: unknown) {} - -export function attachFlowNodeDebugInfoWorker(flowNode: FlowNodeBase) { - 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; - attachFlowNodeDebugInfo(flowNodeProto); - } - Object.setPrototypeOf(flowNode, flowNodeProto); - } - else { - // not running in an es2015 environment, attach the method directly. - attachFlowNodeDebugInfo(flowNode); - } -} - -export function attachNodeArrayDebugInfoWorker(array: NodeArray) { - 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; - attachNodeArrayDebugInfo(nodeArrayProto); - } - Object.setPrototypeOf(array, nodeArrayProto); - } - else { - // not running in an es2015 environment, attach the method directly. - attachNodeArrayDebugInfo(array); - } -} - -export function formatSyntaxKindWorker(kind: SyntaxKind | undefined): string { - return formatEnumWorker(kind, (types as any).SyntaxKind, /*isFlags*/ false); -} - -export function formatSnippetKindWorker(kind: SnippetKind | undefined): string { - return formatEnumWorker(kind, (types as any).SnippetKind, /*isFlags*/ false); -} - -export function formatNodeFlagsWorker(flags: NodeFlags | undefined): string { - return formatEnumWorker(flags, (types as any).NodeFlags, /*isFlags*/ true); -} - -export function formatModifierFlagsWorker(flags: ModifierFlags | undefined): string { - return formatEnumWorker(flags, (types as any).ModifierFlags, /*isFlags*/ true); -} - -export function formatTransformFlagsWorker(flags: TransformFlags | undefined): string { - return formatEnumWorker(flags, (types as any).TransformFlags, /*isFlags*/ true); -} - -export function formatEmitFlagsWorker(flags: EmitFlags | undefined): string { - return formatEnumWorker(flags, (types as any).EmitFlags, /*isFlags*/ true); -} - -export function formatSymbolFlagsWorker(flags: SymbolFlags | undefined): string { - return formatEnumWorker(flags, (types as any).SymbolFlags, /*isFlags*/ true); -} - -export function formatTypeFlagsWorker(flags: TypeFlags | undefined): string { - return formatEnumWorker(flags, (types as any).TypeFlags, /*isFlags*/ true); -} - -export function formatSignatureFlagsWorker(flags: SignatureFlags | undefined): string { - return formatEnumWorker(flags, (types as any).SignatureFlags, /*isFlags*/ true); -} - -export function formatObjectFlagsWorker(flags: ObjectFlags | undefined): string { - return formatEnumWorker(flags, (types as any).ObjectFlags, /*isFlags*/ true); -} - -export function formatFlowFlagsWorker(flags: FlowFlags | undefined): string { - return formatEnumWorker(flags, (types as any).FlowFlags, /*isFlags*/ true); -} - -export function formatRelationComparisonResultWorker(result: RelationComparisonResult | undefined): string { - return formatEnumWorker(result, (types as any).RelationComparisonResult, /*isFlags*/ true); -} - -export function formatCheckModeWorker(mode: CheckMode | undefined): string { - return formatEnumWorker(mode, (checkerTypes as any).CheckMode, /*isFlags*/ true); -} - -export function formatSignatureCheckModeWorker(mode: SignatureCheckMode | undefined): string { - return formatEnumWorker(mode, (checkerTypes as any).SignatureCheckMode, /*isFlags*/ true); -} - -export function formatTypeFactsWorker(facts: TypeFacts | undefined): string { - return formatEnumWorker(facts, (checkerTypes as any).TypeFacts, /*isFlags*/ true); -} - -export function formatControlFlowGraphWorker(flowNode: FlowNode) { - let nextDebugFlowId = -1; - - function getDebugFlowNodeId(f: FlowNode) { - if (!f.id) { - f.id = nextDebugFlowId; - nextDebugFlowId--; - } - return f.id; - } - - const enum BoxCharacter { - lr = "─", - ud = "│", - dr = "╭", - dl = "╮", - ul = "╯", - ur = "╰", - udr = "├", - udl = "┤", - dlr = "┬", - ulr = "┴", - udlr = "╫", - } - - const enum Connection { - None = 0, - Up = 1 << 0, - Down = 1 << 1, - Left = 1 << 2, - Right = 1 << 3, - - UpDown = Up | Down, - LeftRight = Left | Right, - UpLeft = Up | Left, - UpRight = Up | Right, - DownLeft = Down | Left, - DownRight = Down | Right, - UpDownLeft = UpDown | Left, - UpDownRight = UpDown | Right, - UpLeftRight = Up | LeftRight, - DownLeftRight = Down | LeftRight, - UpDownLeftRight = UpDown | LeftRight, - - NoChildren = 1 << 4, - } - - interface FlowGraphNode { - id: number; - flowNode: FlowNode; - edges: FlowGraphEdge[]; - text: string; - lane: number; - endLane: number; - level: number; - circular: boolean | "circularity"; - } - - interface FlowGraphEdge { - source: FlowGraphNode; - target: FlowGraphNode; - } - - const hasAntecedentFlags = - FlowFlags.Assignment | - FlowFlags.Condition | - FlowFlags.SwitchClause | - FlowFlags.ArrayMutation | - FlowFlags.Call | - FlowFlags.ReduceLabel; - - const hasNodeFlags = - FlowFlags.Start | - FlowFlags.Assignment | - FlowFlags.Call | - FlowFlags.Condition | - FlowFlags.ArrayMutation; - - const links: Record = Object.create(/*o*/ null); // eslint-disable-line no-null/no-null - const nodes: FlowGraphNode[] = []; - const edges: FlowGraphEdge[] = []; - const root = buildGraphNode(flowNode, new Set()); - for (const node of nodes) { - node.text = renderFlowNode(node.flowNode, node.circular); - computeLevel(node); - } - - const height = computeHeight(root); - const columnWidths = computeColumnWidths(height); - computeLanes(root, 0); - return renderGraph(); - - function isFlowSwitchClause(f: FlowNode): f is FlowSwitchClause { - return !!(f.flags & FlowFlags.SwitchClause); - } - - function hasAntecedents(f: FlowNode): f is FlowLabel & { antecedents: FlowNode[] } { - return !!(f.flags & FlowFlags.Label) && !!(f as FlowLabel).antecedents; - } - - function hasAntecedent(f: FlowNode): f is Extract { - return !!(f.flags & hasAntecedentFlags); - } - - function hasNode(f: FlowNode): f is Extract { - return !!(f.flags & hasNodeFlags); - } - - function getChildren(node: FlowGraphNode) { - const children: FlowGraphNode[] = []; - for (const edge of node.edges) { - if (edge.source === node) { - children.push(edge.target); - } - } - return children; - } - - function getParents(node: FlowGraphNode) { - const parents: FlowGraphNode[] = []; - for (const edge of node.edges) { - if (edge.target === node) { - parents.push(edge.source); - } - } - return parents; - } - - function buildGraphNode(flowNode: FlowNode, seen: Set): FlowGraphNode { - const id = getDebugFlowNodeId(flowNode); - let graphNode = links[id]; - if (graphNode && seen.has(flowNode)) { - graphNode.circular = true; - graphNode = { - id: -1, - flowNode, - edges: [], - text: "", - lane: -1, - endLane: -1, - level: -1, - circular: "circularity" - }; - nodes.push(graphNode); - return graphNode; - } - seen.add(flowNode); - if (!graphNode) { - links[id] = graphNode = { id, flowNode, edges: [], text: "", lane: -1, endLane: -1, level: -1, circular: false }; - nodes.push(graphNode); - if (hasAntecedents(flowNode)) { - for (const antecedent of flowNode.antecedents) { - buildGraphEdge(graphNode, antecedent, seen); - } - } - else if (hasAntecedent(flowNode)) { - buildGraphEdge(graphNode, flowNode.antecedent, seen); - } - } - seen.delete(flowNode); - return graphNode; - } - - function buildGraphEdge(source: FlowGraphNode, antecedent: FlowNode, seen: Set) { - const target = buildGraphNode(antecedent, seen); - const edge: FlowGraphEdge = { source, target }; - edges.push(edge); - source.edges.push(edge); - target.edges.push(edge); - } - - function computeLevel(node: FlowGraphNode): number { - if (node.level !== -1) { - return node.level; - } - let level = 0; - for (const parent of getParents(node)) { - level = Math.max(level, computeLevel(parent) + 1); - } - return node.level = level; - } - - function computeHeight(node: FlowGraphNode): number { - let height = 0; - for (const child of getChildren(node)) { - height = Math.max(height, computeHeight(child)); - } - return height + 1; - } - - function computeColumnWidths(height: number) { - const columns: number[] = fill(Array(height), 0); - for (const node of nodes) { - columns[node.level] = Math.max(columns[node.level], node.text.length); - } - return columns; - } - - function computeLanes(node: FlowGraphNode, lane: number) { - if (node.lane === -1) { - node.lane = lane; - node.endLane = lane; - const children = getChildren(node); - for (let i = 0; i < children.length; i++) { - if (i > 0) lane++; - const child = children[i]; - computeLanes(child, lane); - if (child.endLane > node.endLane) { - lane = child.endLane; - } - } - node.endLane = lane; - } - } - - function getHeader(flags: FlowFlags) { - if (flags & FlowFlags.Start) return "Start"; - if (flags & FlowFlags.BranchLabel) return "Branch"; - if (flags & FlowFlags.LoopLabel) return "Loop"; - if (flags & FlowFlags.Assignment) return "Assignment"; - if (flags & FlowFlags.TrueCondition) return "True"; - if (flags & FlowFlags.FalseCondition) return "False"; - if (flags & FlowFlags.SwitchClause) return "SwitchClause"; - if (flags & FlowFlags.ArrayMutation) return "ArrayMutation"; - if (flags & FlowFlags.Call) return "Call"; - if (flags & FlowFlags.ReduceLabel) return "ReduceLabel"; - if (flags & FlowFlags.Unreachable) return "Unreachable"; - throw new Error(); - } - - function renderFlowNode(flowNode: FlowNode, circular: boolean | "circularity") { - let text = getHeader(flowNode.flags); - if (circular) { - text = `${text}#${getDebugFlowNodeId(flowNode)}`; - } - if (hasNode(flowNode)) { - if (flowNode.node) { - text += ` (${getNodeText(flowNode.node)})`; - } - } - else if (isFlowSwitchClause(flowNode)) { - const clauses: string[] = []; - for (let i = flowNode.clauseStart; i < flowNode.clauseEnd; i++) { - const clause = flowNode.switchStatement.caseBlock.clauses[i]; - if (isDefaultClause(clause)) { - clauses.push("default"); - } - else { - clauses.push(getNodeText(clause.expression)); - } - } - text += ` (${clauses.join(", ")})`; - } - return circular === "circularity" ? `Circular(${text})` : text; - } - - function renderGraph() { - const columnCount = columnWidths.length; - const laneCount = nodes.reduce((x, n) => Math.max(x, n.lane), 0) + 1; - const lanes: string[] = fill(Array(laneCount), ""); - const grid: (FlowGraphNode | undefined)[][] = columnWidths.map(() => Array(laneCount)); - const connectors: Connection[][] = columnWidths.map(() => fill(Array(laneCount), 0)); - - // build connectors - for (const node of nodes) { - grid[node.level][node.lane] = node; - const children = getChildren(node); - for (let i = 0; i < children.length; i++) { - const child = children[i]; - let connector: Connection = Connection.Right; - if (child.lane === node.lane) connector |= Connection.Left; - if (i > 0) connector |= Connection.Up; - if (i < children.length - 1) connector |= Connection.Down; - connectors[node.level][child.lane] |= connector; - } - if (children.length === 0) { - connectors[node.level][node.lane] |= Connection.NoChildren; - } - const parents = getParents(node); - for (let i = 0; i < parents.length; i++) { - const parent = parents[i]; - let connector: Connection = Connection.Left; - if (i > 0) connector |= Connection.Up; - if (i < parents.length - 1) connector |= Connection.Down; - connectors[node.level - 1][parent.lane] |= connector; - } - } - - // fill in missing connectors - for (let column = 0; column < columnCount; column++) { - for (let lane = 0; lane < laneCount; lane++) { - const left = column > 0 ? connectors[column - 1][lane] : 0; - const above = lane > 0 ? connectors[column][lane - 1] : 0; - let connector = connectors[column][lane]; - if (!connector) { - if (left & Connection.Right) connector |= Connection.LeftRight; - if (above & Connection.Down) connector |= Connection.UpDown; - connectors[column][lane] = connector; - } - } - } - - for (let column = 0; column < columnCount; column++) { - for (let lane = 0; lane < lanes.length; lane++) { - const connector = connectors[column][lane]; - const fill = connector & Connection.Left ? BoxCharacter.lr : " "; - const node = grid[column][lane]; - if (!node) { - if (column < columnCount - 1) { - writeLane(lane, repeat(fill, columnWidths[column] + 1)); - } - } - else { - writeLane(lane, node.text); - if (column < columnCount - 1) { - writeLane(lane, " "); - writeLane(lane, repeat(fill, columnWidths[column] - node.text.length)); - } - } - writeLane(lane, getBoxCharacter(connector)); - writeLane(lane, connector & Connection.Right && column < columnCount - 1 && !grid[column + 1][lane] ? BoxCharacter.lr : " "); - } - } - - return `\n${lanes.join("\n")}\n`; - - function writeLane(lane: number, text: string) { - lanes[lane] += text; - } - } - - function getBoxCharacter(connector: Connection) { - switch (connector) { - case Connection.UpDown: return BoxCharacter.ud; - case Connection.LeftRight: return BoxCharacter.lr; - case Connection.UpLeft: return BoxCharacter.ul; - case Connection.UpRight: return BoxCharacter.ur; - case Connection.DownLeft: return BoxCharacter.dl; - case Connection.DownRight: return BoxCharacter.dr; - case Connection.UpDownLeft: return BoxCharacter.udl; - case Connection.UpDownRight: return BoxCharacter.udr; - case Connection.UpLeftRight: return BoxCharacter.ulr; - case Connection.DownLeftRight: return BoxCharacter.dlr; - case Connection.UpDownLeftRight: return BoxCharacter.udlr; - } - return " "; - } - - function fill(array: T[], value: T) { - if (array.fill) { - array.fill(value); - } - else { - for (let i = 0; i < array.length; i++) { - array[i] = value; - } - } - return array; - } - - function repeat(ch: string, length: number) { - if (ch.repeat) { - return length > 0 ? ch.repeat(length) : ""; - } - let s = ""; - while (s.length < length) { - s += ch; - } - return s; - } -} - -export function formatSymbolWorker(symbol: Symbol): string { - return `{ name: ${unescapeLeadingUnderscores(symbol.escapedName)}; flags: ${formatSymbolFlagsWorker(symbol.flags)}; declarations: ${symbol.declarations?.map(node => formatSyntaxKindWorker(node.kind))} }`; -} - -export function enableDebugInfoWorder() { - attachSymbolDebugInfo(objectAllocator.getSymbolConstructor().prototype); - attachTypeDebugInfo(objectAllocator.getTypeConstructor().prototype); - attachSignatureDebugInfo(objectAllocator.getSignatureConstructor().prototype); - - const nodeConstructors = [ - objectAllocator.getNodeConstructor(), - objectAllocator.getIdentifierConstructor(), - objectAllocator.getTokenConstructor(), - objectAllocator.getSourceFileConstructor() - ]; - - for (const ctor of nodeConstructors) { - if (!hasDebugKind(ctor.prototype)) { - attachNodeDebugInfo(ctor.prototype); - } - } -} diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f214260bd57d9..97a9b740a9c69 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1,4 +1,8 @@ -import * as ts from "./_namespaces/ts"; +/* eslint-disable */ +import * as types from "./types"; +/* eslint-enable */ + +import * as Debug from "./debug"; import { computeSignature, ProgramBuildInfo, @@ -35,8 +39,7 @@ import { stringContains, tryCast, } from "./core"; -import { Comparison } from "./corePublic"; -import { Debug } from "./debug"; +import { Comparison, version } from "./corePublic"; import { createBinaryExpressionTrampoline, } from "./factory/binaryExpressionStateMachine"; @@ -1135,7 +1138,6 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi /** @internal */ export function createBuildInfo(program: ProgramBuildInfo | undefined, bundle: BundleBuildInfo | undefined): BuildInfo { - const version = ts.version; // Extracted into a const so the form is stable between namespace and module return { bundle, program, version }; } @@ -1145,7 +1147,7 @@ export function getBuildInfoText(buildInfo: BuildInfo) { } /** @internal */ -export function getBuildInfo(buildInfoFile: string, buildInfoText: string) { +export function getBuildInfo(buildInfoFile: string, buildInfoText: string): BuildInfo | undefined { return readJsonOrUndefined(buildInfoFile, buildInfoText) as BuildInfo | undefined; } @@ -6019,7 +6021,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri ); } - return Debug.fail(`Unsupported GeneratedIdentifierKind: ${Debug.formatEnum(autoGenerate.flags & GeneratedIdentifierFlags.KindMask, (ts as any).GeneratedIdentifierFlags, /*isFlags*/ true)}.`); + return Debug.fail(`Unsupported GeneratedIdentifierKind: ${Debug.formatEnum(autoGenerate.flags & GeneratedIdentifierFlags.KindMask, (types as any).GeneratedIdentifierFlags, /*isFlags*/ true)}.`); } // Comments diff --git a/src/compiler/factory/binaryExpressionStateMachine.ts b/src/compiler/factory/binaryExpressionStateMachine.ts index c5c9635ca1a5a..7b3614472a8b4 100644 --- a/src/compiler/factory/binaryExpressionStateMachine.ts +++ b/src/compiler/factory/binaryExpressionStateMachine.ts @@ -1,4 +1,4 @@ -import { AssertionLevel, Debug } from "../debug"; +import * as Debug from "../debug"; import { BinaryExpression, BinaryOperatorToken, @@ -130,7 +130,7 @@ function pushStack(stackIndex: number, stateStack: BinaryExpressionState } function checkCircularity(stackIndex: number, nodeStack: BinaryExpression[], node: BinaryExpression) { - if (Debug.shouldAssert(AssertionLevel.Aggressive)) { + if (Debug.shouldAssert(Debug.AssertionLevel.Aggressive)) { while (stackIndex >= 0) { Debug.assert(nodeStack[stackIndex] !== node, "Circular traversal detected."); stackIndex--; diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts index f8c309aaf8e3d..a7032b905e68d 100644 --- a/src/compiler/factory/emitHelpers.ts +++ b/src/compiler/factory/emitHelpers.ts @@ -1,10 +1,10 @@ +import * as Debug from "../debug"; import { arrayToMap, compareValues, memoize, } from "../core"; import { Comparison } from "../corePublic"; -import { Debug } from "../debug"; import { __String, ArrayLiteralExpression, diff --git a/src/compiler/factory/emitNode.ts b/src/compiler/factory/emitNode.ts index 15b218f1891ea..c36cb0cddee9f 100644 --- a/src/compiler/factory/emitNode.ts +++ b/src/compiler/factory/emitNode.ts @@ -1,10 +1,10 @@ +import * as Debug from "../debug"; import { append, appendIfUnique, orderedRemoveItem, some, } from "../core"; -import { Debug } from "../debug"; import { AccessExpression, AutoGenerateInfo, diff --git a/src/compiler/factory/nodeConverters.ts b/src/compiler/factory/nodeConverters.ts index 3575231e0c5de..ca708cde64eb0 100644 --- a/src/compiler/factory/nodeConverters.ts +++ b/src/compiler/factory/nodeConverters.ts @@ -1,9 +1,9 @@ +import * as Debug from "../debug"; import { cast, map, notImplemented, } from "../core"; -import { Debug } from "../debug"; import { ArrayBindingOrAssignmentElement, ArrayBindingOrAssignmentPattern, diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index e1c2298cc90b1..9ea515aca1363 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -1,3 +1,4 @@ +import * as Debug from "../debug"; import { getNodeId } from "../checkerUtilities"; import { addRange, @@ -21,7 +22,6 @@ import { startsWith, } from "../core"; import { Push } from "../corePublic"; -import { Debug } from "../debug"; import { getBuildInfo } from "../emitter"; import { objectAllocator } from "../objectAllocator"; import { parseNodeFactory } from "../parser"; diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index 55838ff7ab466..8d2729ef87a8e 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -1,3 +1,4 @@ +import * as Debug from "../debug"; import { compareStringsCaseSensitive, first, @@ -6,7 +7,6 @@ import { pushIfUnique, some, } from "../core"; -import { Debug } from "../debug"; import { parseNodeFactory } from "../parser"; import { setParent } from "../parserUtilities"; import { isIdentifierText } from "../scanner"; diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 08c54b9052d6c..8cc270169473a 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { DiagnosticReporter, moduleResolutionOptionDeclarations } from "./commandLineParser"; import { readJson } from "./commandLineParserUtilities"; import { @@ -39,7 +40,6 @@ import { version, versionMajorMinor, } from "./corePublic"; -import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { getCommonSourceDirectory } from "./emitter"; import { isDeclarationFileName } from "./parser"; diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 7a9bda70247b1..c0f8b32370f04 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { append, arrayFrom, @@ -25,7 +26,6 @@ import { Comparison, MapLike, } from "./corePublic"; -import { Debug } from "./debug"; import { isModuleBlock, isModuleDeclaration, diff --git a/src/compiler/objectAllocator.ts b/src/compiler/objectAllocator.ts index b6e497c3efd37..19ec7862bd876 100644 --- a/src/compiler/objectAllocator.ts +++ b/src/compiler/objectAllocator.ts @@ -1,5 +1,5 @@ import { forEach } from "./core"; -import { Debug } from "./debug"; +import { isDebugging } from "./debug"; import { tracing } from "./tracing"; import { __String, @@ -68,14 +68,14 @@ function Symbol(this: Symbol, flags: SymbolFlags, name: __String) { function Type(this: Type, checker: TypeChecker, flags: TypeFlags) { this.flags = flags; - if (Debug.isDebugging || tracing) { + if (isDebugging || tracing) { this.checker = checker; } } function Signature(this: Signature, checker: TypeChecker, flags: SignatureFlags) { this.flags = flags; - if (Debug.isDebugging) { + if (isDebugging) { this.checker = checker; } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1813c57b56806..c0da3abc204ff 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { convertToObjectWorker } from "./commandLineParser"; import { addRange, @@ -19,7 +20,6 @@ import { toArray, trimString, } from "./core"; -import { AssertionLevel, Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { BaseNodeFactory } from "./factory/baseNodeFactory"; import { @@ -9514,7 +9514,7 @@ namespace Parser { namespace IncrementalParser { export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean): SourceFile { - aggressiveChecks = aggressiveChecks || Debug.shouldAssert(AssertionLevel.Aggressive); + aggressiveChecks = aggressiveChecks || Debug.shouldAssert(Debug.AssertionLevel.Aggressive); checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks); if (textChangeRangeIsUnchanged(textChangeRange)) { @@ -10001,7 +10001,7 @@ namespace IncrementalParser { if (textChangeRange) { Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length); - if (aggressiveChecks || Debug.shouldAssert(AssertionLevel.VeryAggressive)) { + if (aggressiveChecks || Debug.shouldAssert(Debug.AssertionLevel.VeryAggressive)) { const oldTextPrefix = oldText.substr(0, textChangeRange.span.start); const newTextPrefix = newText.substr(0, textChangeRange.span.start); Debug.assert(oldTextPrefix === newTextPrefix); diff --git a/src/compiler/path.ts b/src/compiler/path.ts index c48f7bd26556e..32200834e357c 100644 --- a/src/compiler/path.ts +++ b/src/compiler/path.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { compareStringsCaseInsensitive, compareStringsCaseSensitive, @@ -14,7 +15,6 @@ import { stringContains, } from "./core"; import { Comparison } from "./corePublic"; -import { Debug } from "./debug"; import { CharacterCodes, Path, diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index 18269ede51b7d..2c7aaba18fe0a 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -1,5 +1,5 @@ +import * as Debug from "./debug"; import { noop } from "./core"; -import { Debug } from "./debug"; import { Performance, PerformanceHooks, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 9e58e15581158..b7c51900fde85 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { BuilderProgram } from "./builderPublic"; import { createTypeChecker } from "./checker"; import { @@ -60,7 +61,6 @@ import { SortedReadonlyArray, versionMajorMinor, } from "./corePublic"; -import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { emitFiles, diff --git a/src/compiler/programUtilities.ts b/src/compiler/programUtilities.ts index 6da50817b3d98..6aa4b9db4fb63 100644 --- a/src/compiler/programUtilities.ts +++ b/src/compiler/programUtilities.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { affectsDeclarationPathOptionDeclarations, affectsEmitOptionDeclarations, @@ -5,7 +6,6 @@ import { optionsAffectingProgramStructure, semanticDiagnosticsOptionDeclarations, } from "./commandLineParser"; -import { Debug } from "./debug"; import { createModeAwareCache, ModeAwareCache, diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index 2e30e1086132e..719015899c1f8 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { arrayToMap, createMultiMap, @@ -12,7 +13,6 @@ import { startsWith, stringContains, } from "./core"; -import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { createModeAwareCache, diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 0f8b482103ee2..be03510c6a961 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { append, arraysEqual, @@ -9,7 +10,6 @@ import { isWhiteSpaceSingleLine, trimStringStart, } from "./core"; -import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { textToKeyword, textToToken } from "./scannerKeywords"; import { diff --git a/src/compiler/semver.ts b/src/compiler/semver.ts index a5dfc31a509be..c75c53cedcacc 100644 --- a/src/compiler/semver.ts +++ b/src/compiler/semver.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { compareStringsCaseSensitive, compareValues, @@ -9,7 +10,6 @@ import { trimString, } from "./core"; import { Comparison } from "./corePublic"; -import { Debug } from "./debug"; // https://semver.org/#spec-item-2 // > A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index 827c947ea89bb..b63468394cda0 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { arrayFrom, binarySearchKey, @@ -12,7 +13,6 @@ import { trimStringEnd, } from "./core"; import { SortedReadonlyArray } from "./corePublic"; -import { Debug } from "./debug"; import { combinePaths, getDirectoryPath, diff --git a/src/compiler/symlinkCache.ts b/src/compiler/symlinkCache.ts index 188e1195da0e3..399764e07f1fd 100644 --- a/src/compiler/symlinkCache.ts +++ b/src/compiler/symlinkCache.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { createMultiMap, emptyArray, @@ -5,7 +6,6 @@ import { MultiMap, startsWith, } from "./core"; -import { Debug } from "./debug"; import { ModeAwareCache } from "./moduleNameResolver"; import { ensureTrailingDirectorySeparator, diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index dca9e89fb1855..bed3cc6a575d5 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { matchesExclude } from "./commandLineParser"; import { contains, @@ -20,7 +21,6 @@ import { unorderedRemoveItem, } from "./core"; import { Comparison } from "./corePublic"; -import { AssertionLevel, Debug } from "./debug"; import { emptyFileSystemEntries, FileSystemEntries, @@ -1886,10 +1886,9 @@ export function setSys(s: System) { if (sys && sys.getEnvironmentVariable) { setCustomPollingValues(sys); - Debug.setAssertionLevel(/^development$/i.test(sys.getEnvironmentVariable("NODE_ENV")) - ? AssertionLevel.Normal - : AssertionLevel.None); + Debug.setAssertionLevel(/^development$/i.test(sys.getEnvironmentVariable("NODE_ENV")) ? Debug.AssertionLevel.Normal : Debug.AssertionLevel.None); } + if (sys && sys.debugMode) { - Debug.isDebugging = true; + Debug.setIsDebugging(true); } diff --git a/src/compiler/tracing.ts b/src/compiler/tracing.ts index 72db5262c2cb7..4ba9756fdcd62 100644 --- a/src/compiler/tracing.ts +++ b/src/compiler/tracing.ts @@ -1,5 +1,5 @@ import * as performance from "./performance"; -import { Debug } from "./debug"; +import * as Debug from "./debug"; import { combinePaths } from "./path"; import { timestamp } from "./performanceCore"; import { getLineAndCharacterOfPosition } from "./scanner"; diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 4ee78002b30b8..9ea74354146e0 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { addRange, append, @@ -9,7 +10,6 @@ import { returnUndefined, some, } from "./core"; -import { Debug } from "./debug"; import { createEmitHelperFactory } from "./factory/emitHelpers"; import { disposeEmitNodes, diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index f97500e69f2d2..3aeef567950c7 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -1,3 +1,4 @@ +import * as Debug from "../debug"; import { addRange, append, @@ -6,7 +7,6 @@ import { map, some, } from "../core"; -import { Debug } from "../debug"; import { addEmitFlags, addEmitHelpers, diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index eb8e4d423a7b3..4ff356835d433 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1,3 +1,4 @@ +import * as Debug from "../debug"; import { append, arrayFrom, @@ -22,7 +23,6 @@ import { toFileNameLowerCase, tryCast, } from "../core"; -import { Debug } from "../debug"; import { Diagnostics } from "../diagnosticInformationMap.generated"; import { getOutputPathsFor } from "../emitter"; import { diff --git a/src/compiler/transformers/declarations/diagnostics.ts b/src/compiler/transformers/declarations/diagnostics.ts index 64e679b6350d1..8e7fe42d2bde8 100644 --- a/src/compiler/transformers/declarations/diagnostics.ts +++ b/src/compiler/transformers/declarations/diagnostics.ts @@ -1,4 +1,4 @@ -import { Debug } from "../../debug"; +import * as Debug from "../../debug"; import { Diagnostics } from "../../diagnosticInformationMap.generated"; import { isBindingElement, diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index db92131cf8dd1..374b16ffd87ff 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -1,3 +1,4 @@ +import * as Debug from "../debug"; import { addRange, append, @@ -7,7 +8,6 @@ import { map, some, } from "../core"; -import { Debug } from "../debug"; import { factory } from "../factory/nodeFactory"; import { isBindingElement, diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index ef06c97c6d4ee..1ebd60dd77b5d 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -1,3 +1,4 @@ +import * as Debug from "../debug"; import { addRange, append, @@ -20,7 +21,6 @@ import { takeWhile, tryCast, } from "../core"; -import { Debug } from "../debug"; import { isCallToHelper } from "../factory/emitHelpers"; import { addEmitHelpers, diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index d79c642d2a2d2..4133ae08331a5 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -1,3 +1,4 @@ +import * as Debug from "../debug"; import { getNodeId } from "../checkerUtilities"; import { concatenate, @@ -5,7 +6,6 @@ import { map, some, } from "../core"; -import { Debug } from "../debug"; import { advancedAsyncSuperHelper, asyncSuperHelper, diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index 51a6d1853ed8f..11b2c0c30096d 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -1,3 +1,4 @@ +import * as Debug from "../debug"; import { getNodeId } from "../checkerUtilities"; import { addRange, @@ -5,7 +6,6 @@ import { concatenate, some, } from "../core"; -import { Debug } from "../debug"; import { advancedAsyncSuperHelper, asyncSuperHelper, diff --git a/src/compiler/transformers/es2020.ts b/src/compiler/transformers/es2020.ts index 651ff91ac7f7d..689b5c3bd3ac0 100644 --- a/src/compiler/transformers/es2020.ts +++ b/src/compiler/transformers/es2020.ts @@ -1,5 +1,5 @@ +import * as Debug from "../debug"; import { cast } from "../core"; -import { Debug } from "../debug"; import { addEmitFlags } from "../factory/emitNode"; import { isIdentifier, diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 459146758abac..89dfb136d8f45 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -1,10 +1,10 @@ +import * as Debug from "../debug"; import { forEach, lastOrUndefined, map, reduceLeft, } from "../core"; -import { Debug } from "../debug"; import { addEmitHelpers, addSyntheticTrailingComment, diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 454ea253908a1..d5589c98388c8 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -1,3 +1,4 @@ +import * as Debug from "../debug"; import { arrayFrom, emptyArray, @@ -12,8 +13,10 @@ import { singleOrUndefined, spanMap, } from "../core"; -import { Debug } from "../debug"; -import { addEmitHelpers, setIdentifierGeneratedImportReference } from "../factory/emitNode"; +import { + addEmitHelpers, + setIdentifierGeneratedImportReference, +} from "../factory/emitNode"; import { isIdentifier, isJsxAttribute, diff --git a/src/compiler/transformers/legacyDecorators.ts b/src/compiler/transformers/legacyDecorators.ts index e119a1324548d..371d3fc393b76 100644 --- a/src/compiler/transformers/legacyDecorators.ts +++ b/src/compiler/transformers/legacyDecorators.ts @@ -1,3 +1,4 @@ +import * as Debug from "../debug"; import { addRange, append, @@ -7,7 +8,6 @@ import { singleOrMany, some, } from "../core"; -import { Debug } from "../debug"; import { addEmitHelpers, setCommentRange, diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index da1cd55eb514d..d2e902473174e 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -1,10 +1,10 @@ +import * as Debug from "../../debug"; import { addRange, append, singleOrMany, some, } from "../../core"; -import { Debug } from "../../debug"; import { isIdentifier, isNamespaceExport, diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 46901c7044595..c236ffdde3bc0 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../debug"; import { getNodeId } from "../../checkerUtilities"; import { addRange, @@ -9,7 +10,6 @@ import { reduceLeft, singleOrMany, } from "../../core"; -import { Debug } from "../../debug"; import { addEmitFlags, addEmitHelper, diff --git a/src/compiler/transformers/module/node.ts b/src/compiler/transformers/module/node.ts index 9463ad5dbe73a..0aba6abd9d60e 100644 --- a/src/compiler/transformers/module/node.ts +++ b/src/compiler/transformers/module/node.ts @@ -1,5 +1,5 @@ +import * as Debug from "../../debug"; import { map } from "../../core"; -import { Debug } from "../../debug"; import { isSourceFile } from "../../factory/nodeTests"; import { Bundle, diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 7c51f43ec4bf1..e4b5c48afd20b 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../debug"; import { getNodeId } from "../../checkerUtilities"; import { addRange, @@ -8,7 +9,6 @@ import { singleOrMany, some, } from "../../core"; -import { Debug } from "../../debug"; import { moveEmitHelpers, setCommentRange, diff --git a/src/compiler/transformers/taggedTemplate.ts b/src/compiler/transformers/taggedTemplate.ts index 0d470660b4fe6..fc46758cd6c5e 100644 --- a/src/compiler/transformers/taggedTemplate.ts +++ b/src/compiler/transformers/taggedTemplate.ts @@ -1,4 +1,4 @@ -import { Debug } from "../debug"; +import * as Debug from "../debug"; import { factory } from "../factory/nodeFactory"; import { isNoSubstitutionTemplateLiteral } from "../factory/nodeTests"; import { setTextRange } from "../factory/utilitiesPublic"; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 0847c7da9a9f0..8111f40a6ab4c 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1,3 +1,4 @@ +import * as Debug from "../debug"; import { isInstantiatedModule } from "../checker"; import { addRange, @@ -13,7 +14,6 @@ import { singleOrMany, some, } from "../core"; -import { Debug } from "../debug"; import { addEmitFlags, addEmitHelpers, diff --git a/src/compiler/transformers/typeSerializer.ts b/src/compiler/transformers/typeSerializer.ts index 69c82f6fdc020..0d96dd50f83ac 100644 --- a/src/compiler/transformers/typeSerializer.ts +++ b/src/compiler/transformers/typeSerializer.ts @@ -1,4 +1,4 @@ -import { Debug } from "../debug"; +import * as Debug from "../debug"; import { factory } from "../factory/nodeFactory"; import { isBinaryExpression, diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 7921077a3ef2c..be8c2d2461413 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { getBuildInfoFileVersionMap, getPendingEmitKind, @@ -41,7 +42,6 @@ import { unorderedRemoveItem, } from "./core"; import { version } from "./corePublic"; -import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { emitUsingBuildInfo, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 613d2112f765a..d8a76f50d7083 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { getSymbolId } from "./checkerUtilities"; import { addRange, @@ -59,7 +60,6 @@ import { SortedArray, version, } from "./corePublic"; -import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { getSnippetElement } from "./factory/emitNode"; import { @@ -1337,7 +1337,7 @@ export function isBlockScope(node: Node, parentNode: Node | undefined): boolean /** @internal */ export function isDeclarationWithTypeParameters(node: Node): node is DeclarationWithTypeParameters { - Debug.type(node); + Debug.assertType(node); switch (node.kind) { case SyntaxKind.JSDocCallbackTag: case SyntaxKind.JSDocTypedefTag: @@ -1351,7 +1351,7 @@ export function isDeclarationWithTypeParameters(node: Node): node is Declaration /** @internal */ export function isDeclarationWithTypeParameterChildren(node: Node): node is DeclarationWithTypeParameterChildren { - Debug.type(node); + Debug.assertType(node); switch (node.kind) { case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index c214d4c3cb9a3..104286a9249c6 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { contains, emptyArray, @@ -18,7 +19,6 @@ import { Push, SortedReadonlyArray, } from "./corePublic"; -import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { isArrowFunction, diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 302c1a098fbef..739897db4a851 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -1,9 +1,9 @@ +import * as Debug from "./debug"; import { isArray, singleOrUndefined, some, } from "./core"; -import { Debug } from "./debug"; import { setEmitFlags } from "./factory/emitNode"; import { factory } from "./factory/nodeFactory"; import { diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 093d860107650..07629b8bfabdb 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { BuilderProgram, createEmitAndSemanticDiagnosticsBuilderProgram, @@ -29,7 +30,6 @@ import { noop, } from "./core"; import { SortedReadonlyArray } from "./corePublic"; -import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { getPatternFromSpec, diff --git a/src/compiler/watchPublic.ts b/src/compiler/watchPublic.ts index 155047a6a0c70..c8500ed9b99f5 100644 --- a/src/compiler/watchPublic.ts +++ b/src/compiler/watchPublic.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { createBuilderProgramUsingProgramBuildInfo } from "./builder"; import { BuilderProgram, @@ -25,7 +26,6 @@ import { MapLike, version, } from "./corePublic"; -import { Debug } from "./debug"; import { Diagnostics } from "./diagnosticInformationMap.generated"; import { getBuildInfo, diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index 62410faec47ab..09a7501479dd3 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { BuilderProgram } from "./builderPublic"; import { ExtendedConfigCacheEntry, @@ -22,7 +23,6 @@ import { SortedArray, SortedReadonlyArray, } from "./corePublic"; -import { Debug } from "./debug"; import { emptyFileSystemEntries, FileSystemEntries, diff --git a/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts b/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts index 5a54c5bcc34ed..ddeb221db4bfb 100644 --- a/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts +++ b/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts @@ -1,4 +1,4 @@ -import { Debug } from "../../compiler/debug"; +import * as Debug from "../../compiler/debug"; import { factory } from "../../compiler/factory/nodeFactory"; import { setTextRange } from "../../compiler/factory/utilitiesPublic"; import { parseBaseNodeFactory } from "../../compiler/parser"; diff --git a/src/deprecatedCompat/deprecate.ts b/src/deprecatedCompat/deprecate.ts index 4f00e44d699d8..3dc484b53e025 100644 --- a/src/deprecatedCompat/deprecate.ts +++ b/src/deprecatedCompat/deprecate.ts @@ -1,6 +1,6 @@ +import * as Debug from "../compiler/debug"; import { noop } from "../compiler/core"; import { version } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { Version } from "../compiler/semver"; import { formatStringFromArgs } from "../compiler/utilities"; import { DeprecationOptions } from "./deprecations"; diff --git a/src/executeCommandLine/executeCommandLine.ts b/src/executeCommandLine/executeCommandLine.ts index 0a0a7cbbe9f9d..982573059545e 100644 --- a/src/executeCommandLine/executeCommandLine.ts +++ b/src/executeCommandLine/executeCommandLine.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { BuilderProgram, EmitAndSemanticDiagnosticsBuilderProgram, @@ -32,7 +33,6 @@ import { stringContains, } from "../compiler/core"; import { version } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { Diagnostics } from "../compiler/diagnosticInformationMap.generated"; import { combinePaths, diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index d141b9e899b92..b58016ab78d29 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { readConfigFile } from "../compiler/commandLineParser"; import { compareStringsCaseSensitive, @@ -16,7 +17,6 @@ import { MapLike, versionMajorMinor, } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { combinePaths, fileExtensionIs, diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 169b20a56a7a9..36de791109466 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { canJsonReportNoInputFiles, convertCompilerOptionsForTelemetry, @@ -42,7 +43,6 @@ import { ReadonlyCollection, version, } from "../compiler/corePublic"; -import { AssertionLevel, Debug } from "../compiler/debug"; import { parsePackageName } from "../compiler/moduleNameResolver"; import { parseJsonText } from "../compiler/parser"; import { @@ -1678,7 +1678,7 @@ export class ProjectService { project.print(/*writeProjectFileNames*/ true); project.close(); - if (Debug.shouldAssert(AssertionLevel.Normal)) { + if (Debug.shouldAssert(Debug.AssertionLevel.Normal)) { this.filenameToScriptInfo.forEach(info => Debug.assert( !info.isAttached(project), "Found script Info still attached to project", diff --git a/src/server/moduleSpecifierCache.ts b/src/server/moduleSpecifierCache.ts index c081948391815..6358ee0e41594 100644 --- a/src/server/moduleSpecifierCache.ts +++ b/src/server/moduleSpecifierCache.ts @@ -1,4 +1,4 @@ -import { Debug } from "../compiler/debug"; +import * as Debug from "../compiler/debug"; import { nodeModulesPathPart } from "../compiler/moduleNameResolver"; import { FileWatcher, diff --git a/src/server/packageJsonCache.ts b/src/server/packageJsonCache.ts index bcb8733779539..98d03eca06a87 100644 --- a/src/server/packageJsonCache.ts +++ b/src/server/packageJsonCache.ts @@ -1,4 +1,4 @@ -import { Debug } from "../compiler/debug"; +import * as Debug from "../compiler/debug"; import { combinePaths, forEachAncestorDirectory, diff --git a/src/server/project.ts b/src/server/project.ts index 475937184c439..9526f979cb28d 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { BuilderState } from "../compiler/builderState"; import { updateErrorForNoInputFiles } from "../compiler/commandLineParser"; import { @@ -28,7 +29,6 @@ import { startsWith, } from "../compiler/core"; import { SortedReadonlyArray } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { getAutomaticTypeDirectiveNames, getEffectiveTypeRoots, diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index fe197d56daff5..82298111c9954 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { assign, clear, @@ -8,7 +9,6 @@ import { stringContains, unorderedRemoveItem, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { directorySeparator, getBaseFileName, diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index c5b17dfcd386c..ee5cddabd5409 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -1,4 +1,4 @@ -import { Debug } from "../compiler/debug"; +import * as Debug from "../compiler/debug"; import { computeLineStarts } from "../compiler/scanner"; import { TextChangeRange, diff --git a/src/server/session.ts b/src/server/session.ts index b1733ef86b210..504098fa28c29 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { EmitOutput } from "../compiler/builderStatePublic"; import { arrayFrom, @@ -32,7 +33,6 @@ import { toFileNameLowerCase, } from "../compiler/core"; import { version } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { isIdentifier } from "../compiler/factory/nodeTests"; import { getEntrypointsFromPackageJsonInfo, diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 5e72d7c820e97..d8c822f6ea29b 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { getModuleInstanceState, ModuleInstanceState, @@ -7,7 +8,6 @@ import { forEach, lastOrUndefined, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { isDecorator, isVariableDeclarationList, diff --git a/src/services/callHierarchy.ts b/src/services/callHierarchy.ts index f4f1752b68806..7caf2f498aded 100644 --- a/src/services/callHierarchy.ts +++ b/src/services/callHierarchy.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { getNodeId } from "../compiler/checkerUtilities"; import { append, @@ -10,7 +11,6 @@ import { isArray, map, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { createPrinter } from "../compiler/emitter"; import { isArrowFunction, diff --git a/src/services/classifier.ts b/src/services/classifier.ts index fe2879ebda913..2d823371ccaa5 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { getModuleInstanceState, ModuleInstanceState, @@ -9,7 +10,6 @@ import { some, } from "../compiler/core"; import { Push } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { isIdentifier, isJSDoc, diff --git a/src/services/classifier2020.ts b/src/services/classifier2020.ts index 4006fa848e7cb..863b92943fdbb 100644 --- a/src/services/classifier2020.ts +++ b/src/services/classifier2020.ts @@ -1,4 +1,4 @@ -import { Debug } from "../compiler/debug"; +import * as Debug from "../compiler/debug"; import { isBindingElement, isCallExpression, diff --git a/src/services/codeFixProvider.ts b/src/services/codeFixProvider.ts index 98b9ffe32dee8..f264f57b3bc47 100644 --- a/src/services/codeFixProvider.ts +++ b/src/services/codeFixProvider.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { arrayFrom, cast, @@ -8,7 +9,6 @@ import { map, } from "../compiler/core"; import { Push } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { Diagnostic, DiagnosticWithLocation, diff --git a/src/services/codefixes/addMissingInvocationForDecorator.ts b/src/services/codefixes/addMissingInvocationForDecorator.ts index 4055032bba736..2b57e78d884eb 100644 --- a/src/services/codefixes/addMissingInvocationForDecorator.ts +++ b/src/services/codefixes/addMissingInvocationForDecorator.ts @@ -1,4 +1,4 @@ -import { Debug } from "../../compiler/debug"; +import * as Debug from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { isDecorator } from "../../compiler/factory/nodeTests"; diff --git a/src/services/codefixes/addNameToNamelessParameter.ts b/src/services/codefixes/addNameToNamelessParameter.ts index 9f194345433e8..2f57c3f802d2a 100644 --- a/src/services/codefixes/addNameToNamelessParameter.ts +++ b/src/services/codefixes/addNameToNamelessParameter.ts @@ -1,4 +1,4 @@ -import { Debug } from "../../compiler/debug"; +import * as Debug from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { isParameter } from "../../compiler/factory/nodeTests"; diff --git a/src/services/codefixes/annotateWithTypeFromJSDoc.ts b/src/services/codefixes/annotateWithTypeFromJSDoc.ts index 92d530bed4b10..20a630e598609 100644 --- a/src/services/codefixes/annotateWithTypeFromJSDoc.ts +++ b/src/services/codefixes/annotateWithTypeFromJSDoc.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { emptyArray, first, @@ -5,7 +6,6 @@ import { map, tryCast, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { setEmitFlags } from "../../compiler/factory/emitNode"; import { factory } from "../../compiler/factory/nodeFactory"; diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 241c1af610cf8..9460f13fb9113 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { getNodeId, getSymbolId, @@ -15,7 +16,6 @@ import { returnTrue, tryCast, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/convertToEsModule.ts b/src/services/codefixes/convertToEsModule.ts index 8e045178c2aed..de65fff5d1934 100644 --- a/src/services/codefixes/convertToEsModule.ts +++ b/src/services/codefixes/convertToEsModule.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { isExportsOrModuleExportsOrAlias } from "../../compiler/binder"; import { arrayFrom, @@ -14,7 +15,6 @@ import { some, } from "../../compiler/core"; import { ReadonlyCollection } from "../../compiler/corePublic"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts b/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts index 0c57d3c4bb8fa..7ad41677926aa 100644 --- a/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts +++ b/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts @@ -1,4 +1,4 @@ -import { Debug } from "../../compiler/debug"; +import * as Debug from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index b2f217da74921..bf54e55bd31f2 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { getNodeId } from "../../compiler/checkerUtilities"; import { arrayFrom, @@ -18,7 +19,6 @@ import { some, tryCast, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts b/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts index f41d825a31cc8..bd1b02ac34b13 100644 --- a/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts +++ b/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts @@ -1,4 +1,4 @@ -import { Debug } from "../../compiler/debug"; +import * as Debug from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts index e7b7961e00c7f..b56ff15cdfa46 100644 --- a/src/services/codefixes/fixCannotFindModule.ts +++ b/src/services/codefixes/fixCannotFindModule.ts @@ -1,5 +1,5 @@ +import * as Debug from "../../compiler/debug"; import { tryCast } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { isStringLiteral } from "../../compiler/factory/nodeTests"; import { diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 609fa0598d4e2..08fd925606636 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -1,10 +1,10 @@ +import * as Debug from "../../compiler/debug"; import { getNodeId } from "../../compiler/checkerUtilities"; import { and, find, mapDefined, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { isConstructorDeclaration } from "../../compiler/factory/nodeTests"; import { diff --git a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts index 246e7e2c717f0..7c7a5a2615173 100644 --- a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts +++ b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts @@ -1,5 +1,5 @@ +import * as Debug from "../../compiler/debug"; import { emptyArray } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { isConstructorDeclaration } from "../../compiler/factory/nodeTests"; diff --git a/src/services/codefixes/fixImplicitThis.ts b/src/services/codefixes/fixImplicitThis.ts index c97af2a3a2c8f..798378a548e45 100644 --- a/src/services/codefixes/fixImplicitThis.ts +++ b/src/services/codefixes/fixImplicitThis.ts @@ -1,5 +1,5 @@ +import * as Debug from "../../compiler/debug"; import { emptyArray } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/fixOverrideModifier.ts b/src/services/codefixes/fixOverrideModifier.ts index 75fdb3840327d..68a49af0dd701 100644 --- a/src/services/codefixes/fixOverrideModifier.ts +++ b/src/services/codefixes/fixOverrideModifier.ts @@ -1,10 +1,10 @@ +import * as Debug from "../../compiler/debug"; import { emptyArray, find, findLast, not, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/fixPropertyOverrideAccessor.ts b/src/services/codefixes/fixPropertyOverrideAccessor.ts index b699611599a35..830c7f38fd189 100644 --- a/src/services/codefixes/fixPropertyOverrideAccessor.ts +++ b/src/services/codefixes/fixPropertyOverrideAccessor.ts @@ -1,5 +1,5 @@ +import * as Debug from "../../compiler/debug"; import { singleOrUndefined } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { SourceFile } from "../../compiler/types"; import { diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts index d98a3c92a9613..23f5c66727f50 100644 --- a/src/services/codefixes/fixSpelling.ts +++ b/src/services/codefixes/fixSpelling.ts @@ -1,4 +1,4 @@ -import { Debug } from "../../compiler/debug"; +import * as Debug from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/fixStrictClassInitialization.ts b/src/services/codefixes/fixStrictClassInitialization.ts index 3023cce2b7b0c..c3a0edd169b5a 100644 --- a/src/services/codefixes/fixStrictClassInitialization.ts +++ b/src/services/codefixes/fixStrictClassInitialization.ts @@ -1,8 +1,8 @@ +import * as Debug from "../../compiler/debug"; import { append, firstDefined, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/fixUnreachableCode.ts b/src/services/codefixes/fixUnreachableCode.ts index 8a642126fd361..1decd48c4de76 100644 --- a/src/services/codefixes/fixUnreachableCode.ts +++ b/src/services/codefixes/fixUnreachableCode.ts @@ -1,8 +1,8 @@ +import * as Debug from "../../compiler/debug"; import { emptyArray, first, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { isBlock } from "../../compiler/factory/nodeTests"; diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index dd9a4d96067b9..b974475d71da5 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { cast, first, @@ -5,7 +6,6 @@ import { map, tryCast, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index b91d9f103353a..1f7b678388f64 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { append, arrayFrom, @@ -11,7 +12,6 @@ import { some, tryCast, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/importAdder.ts b/src/services/codefixes/importAdder.ts index 175d328e7ea24..d98ed5deb2c15 100644 --- a/src/services/codefixes/importAdder.ts +++ b/src/services/codefixes/importAdder.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { getNodeId, getSymbolId, @@ -29,7 +30,6 @@ import { tryCast, } from "../../compiler/core"; import { Comparison } from "../../compiler/corePublic"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index c87b65d3c91ed..0be274be3396a 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { cast, createMultiMap, @@ -15,7 +16,6 @@ import { singleOrUndefined, tryCast, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { setEmitFlags } from "../../compiler/factory/emitNode"; import { factory } from "../../compiler/factory/nodeFactory"; diff --git a/src/services/codefixes/requireInTs.ts b/src/services/codefixes/requireInTs.ts index 476cb407bfde4..04302ecc404ca 100644 --- a/src/services/codefixes/requireInTs.ts +++ b/src/services/codefixes/requireInTs.ts @@ -1,9 +1,9 @@ +import * as Debug from "../../compiler/debug"; import { cast, first, tryCast, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/returnValueCorrect.ts b/src/services/codefixes/returnValueCorrect.ts index 4cf059d940e6a..1b5d12b500dd9 100644 --- a/src/services/codefixes/returnValueCorrect.ts +++ b/src/services/codefixes/returnValueCorrect.ts @@ -1,9 +1,9 @@ +import * as Debug from "../../compiler/debug"; import { append, first, length, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/codefixes/splitTypeOnlyImport.ts b/src/services/codefixes/splitTypeOnlyImport.ts index 1aebcfa32584e..d088a1fda3d01 100644 --- a/src/services/codefixes/splitTypeOnlyImport.ts +++ b/src/services/codefixes/splitTypeOnlyImport.ts @@ -1,4 +1,4 @@ -import { Debug } from "../../compiler/debug"; +import * as Debug from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { isImportDeclaration } from "../../compiler/factory/nodeTests"; diff --git a/src/services/completions.ts b/src/services/completions.ts index 3793c78b868a1..19e0e6c4a5f81 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { getSymbolId } from "../compiler/checkerUtilities"; import { append, @@ -34,7 +35,6 @@ import { Comparison, SortedArray, } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { Diagnostics } from "../compiler/diagnosticInformationMap.generated"; import { createPrinter } from "../compiler/emitter"; import { setSnippetElement } from "../compiler/factory/emitNode"; diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index be86f017eb5f0..1d633fcd0382d 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { arrayFrom, arrayToMultiMap, @@ -14,7 +15,6 @@ import { tryCast, } from "../compiler/core"; import { Push } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { isAwaitExpression, isBlock, diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index 19f4d08d7a07a..70535cbcde68d 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { sourceFileAffectingCompilerOptions, } from "../compiler/commandLineParser"; @@ -8,14 +9,16 @@ import { getOrUpdate, identity, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { getKeyForCompilerOptions } from "../compiler/moduleNameResolver"; import { CreateSourceFileOptions, isDeclarationFileName, } from "../compiler/parser"; import { toPath } from "../compiler/path"; -import { getImpliedNodeFormatForFile, getSetExternalModuleIndicator } from "../compiler/program"; +import { + getImpliedNodeFormatForFile, + getSetExternalModuleIndicator, +} from "../compiler/program"; import { tracing } from "../compiler/tracing"; import { CompilerOptions, diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index 654e17e5e052d..2bc98e7539aab 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { getSymbolId } from "../compiler/checkerUtilities"; import { arrayIsEqualTo, @@ -11,7 +12,6 @@ import { stringContains, tryCast, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { isExportAssignment, isExportSpecifier, diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index b23bdb0c32ff4..8675def74e088 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { getNodeId, getSymbolId, @@ -24,7 +25,6 @@ import { tryCast, } from "../compiler/core"; import { Push } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { isBinaryExpression, isBindingElement, diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 53d8f615892ee..b87fba826b513 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { find, findIndex, @@ -6,7 +7,6 @@ import { isWhiteSpaceSingleLine, last, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { isDecorator } from "../../compiler/factory/nodeTests"; import { canHaveModifiers } from "../../compiler/factory/utilitiesPublic"; import { forEachChild } from "../../compiler/parser"; diff --git a/src/services/formatting/formattingContext.ts b/src/services/formatting/formattingContext.ts index 566dd3ba8ff12..1296811698f8d 100644 --- a/src/services/formatting/formattingContext.ts +++ b/src/services/formatting/formattingContext.ts @@ -1,4 +1,4 @@ -import { Debug } from "../../compiler/debug"; +import * as Debug from "../../compiler/debug"; import { Node, SourceFileLike, diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index fccb55a8edd3a..1ca1728d19484 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -1,8 +1,8 @@ +import * as Debug from "../../compiler/debug"; import { append, last, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { isJsxAttribute, isJsxElement, diff --git a/src/services/formatting/rulesMap.ts b/src/services/formatting/rulesMap.ts index ea51325686fd3..519dd27bdf051 100644 --- a/src/services/formatting/rulesMap.ts +++ b/src/services/formatting/rulesMap.ts @@ -1,5 +1,5 @@ +import * as Debug from "../../compiler/debug"; import { every } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { SyntaxKind } from "../../compiler/types"; import { FormattingContext } from "./formattingContext"; import { diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index b2d6618118dbf..66a59be95428c 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -1,10 +1,10 @@ +import * as Debug from "../../compiler/debug"; import { contains, find, isWhiteSpaceLike, isWhiteSpaceSingleLine, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { isCallExpression, isConditionalExpression, diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index c4ac0063f44e6..966646a0ee147 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { getOptionFromName } from "../compiler/commandLineParser"; import { createGetCanonicalFileName, @@ -9,7 +10,6 @@ import { last, mapDefined, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { factory } from "../compiler/factory/nodeFactory"; import { isArrayLiteralExpression, diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index e1297056041a5..9f87c6bec4389 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { concatenate, emptyArray, @@ -13,7 +14,6 @@ import { some, tryCast, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { isBindingElement, isClassExpression, diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 5534fb49900ab..40683724118fb 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { getSymbolId } from "../compiler/checkerUtilities"; import { cast, @@ -5,7 +6,6 @@ import { some, tryCast, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { isBinaryExpression, isBindingElement, diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts index 86d36185d2ae6..114d85d5989f5 100644 --- a/src/services/inlayHints.ts +++ b/src/services/inlayHints.ts @@ -1,8 +1,8 @@ +import * as Debug from "../compiler/debug"; import { equateStringsCaseInsensitive, some, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { createPrinter } from "../compiler/emitter"; import { isArrowFunction, diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 8d13732d1d485..86dc56c2c2793 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { compareStringsCaseSensitiveUI, compareValues, @@ -9,7 +10,6 @@ import { map, mapDefined, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { factory } from "../compiler/factory/nodeFactory"; import { isArrowFunction, diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 5bcf5ac0d3f20..4ee7e84c44d39 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -1,10 +1,10 @@ +import * as Debug from "../compiler/debug"; import { startsWith, trimString, trimStringStart, } from "../compiler/core"; import { Push } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { isArrayLiteralExpression, isBinaryExpression, diff --git a/src/services/refactors/addOrRemoveBracesToArrowFunction.ts b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts index a0d9ecfe74beb..65d5ef4e15bb8 100644 --- a/src/services/refactors/addOrRemoveBracesToArrowFunction.ts +++ b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts @@ -1,8 +1,8 @@ +import * as Debug from "../../compiler/debug"; import { emptyArray, first, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts index 9bd15d8b2a4c4..4a44c784c6120 100644 --- a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts +++ b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts @@ -1,9 +1,9 @@ +import * as Debug from "../../compiler/debug"; import { emptyArray, first, length, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/refactors/convertExport.ts b/src/services/refactors/convertExport.ts index 8228a443e8814..3e642e9028db8 100644 --- a/src/services/refactors/convertExport.ts +++ b/src/services/refactors/convertExport.ts @@ -1,8 +1,8 @@ +import * as Debug from "../../compiler/debug"; import { emptyArray, first, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/refactors/convertImport.ts b/src/services/refactors/convertImport.ts index 94494a7c7e557..8336a46971d7b 100644 --- a/src/services/refactors/convertImport.ts +++ b/src/services/refactors/convertImport.ts @@ -1,10 +1,10 @@ +import * as Debug from "../../compiler/debug"; import { arrayFrom, emptyArray, getOwnValues, some, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/refactors/convertOverloadListToSingleSignature.ts b/src/services/refactors/convertOverloadListToSingleSignature.ts index d917a48ea095d..34e340ad2d623 100644 --- a/src/services/refactors/convertOverloadListToSingleSignature.ts +++ b/src/services/refactors/convertOverloadListToSingleSignature.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { emptyArray, every, @@ -6,7 +7,6 @@ import { mapDefined, some, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { getSyntheticLeadingComments, diff --git a/src/services/refactors/convertParamsToDestructuredObject.ts b/src/services/refactors/convertParamsToDestructuredObject.ts index 5049c24d1cb65..00f6b1599d4d0 100644 --- a/src/services/refactors/convertParamsToDestructuredObject.ts +++ b/src/services/refactors/convertParamsToDestructuredObject.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { compareValues, contains, @@ -12,7 +13,6 @@ import { sortAndDeduplicate, tryCast, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { addEmitFlags } from "../../compiler/factory/emitNode"; import { factory } from "../../compiler/factory/nodeFactory"; diff --git a/src/services/refactors/convertStringOrTemplateLiteral.ts b/src/services/refactors/convertStringOrTemplateLiteral.ts index 3afbd3650597a..a3bec9e9a31f7 100644 --- a/src/services/refactors/convertStringOrTemplateLiteral.ts +++ b/src/services/refactors/convertStringOrTemplateLiteral.ts @@ -1,8 +1,8 @@ +import * as Debug from "../../compiler/debug"; import { emptyArray, map, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/refactors/convertToOptionalChainExpression.ts b/src/services/refactors/convertToOptionalChainExpression.ts index 0ae38bf75f4b9..3c51ed529345a 100644 --- a/src/services/refactors/convertToOptionalChainExpression.ts +++ b/src/services/refactors/convertToOptionalChainExpression.ts @@ -1,5 +1,5 @@ +import * as Debug from "../../compiler/debug"; import { emptyArray } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 452dc20144236..21ee0d7d05e79 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { getNodeId, getSymbolId, @@ -18,7 +19,6 @@ import { map, singleOrUndefined, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { setEmitFlags } from "../../compiler/factory/emitNode"; import { factory } from "../../compiler/factory/nodeFactory"; diff --git a/src/services/refactors/extractType.ts b/src/services/refactors/extractType.ts index 8c37fec35924c..7451469f869ae 100644 --- a/src/services/refactors/extractType.ts +++ b/src/services/refactors/extractType.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { addRange, append, @@ -7,7 +8,6 @@ import { forEach, pushIfUnique, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { ignoreSourceNewlines, diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index 0b7f330445339..d32857780d514 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -1,5 +1,5 @@ +import * as Debug from "../../compiler/debug"; import { emptyArray } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { isIdentifier, diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index b94fc54892b0e..94837fcc58088 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -1,3 +1,4 @@ +import * as Debug from "../../compiler/debug"; import { getSymbolId } from "../../compiler/checkerUtilities"; import { append, @@ -18,7 +19,6 @@ import { takeWhile, tryCast, } from "../../compiler/core"; -import { Debug } from "../../compiler/debug"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { diff --git a/src/services/services.ts b/src/services/services.ts index 27c7a5e3e939c..3b0b988c43425 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { getFileEmitOutput } from "../compiler/builderState"; import { ParseConfigFileHost, @@ -35,7 +36,6 @@ import { Push, SortedArray, } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { isComputedPropertyName, isIdentifier, diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index b545f29c4e5bd..1b6b3f64955fe 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { contains, countWhere, @@ -12,7 +13,6 @@ import { map, tryCast, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { createPrinter } from "../compiler/emitter"; import { factory } from "../compiler/factory/nodeFactory"; import { diff --git a/src/services/smartSelection.ts b/src/services/smartSelection.ts index 94b46aa4430c9..77b4b18632f20 100644 --- a/src/services/smartSelection.ts +++ b/src/services/smartSelection.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { compact, contains, @@ -7,7 +8,6 @@ import { or, singleOrUndefined, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { isBindingElement, isBlock, diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 3c9dd47be6882..4c8cee92c566a 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { readJson } from "../compiler/commandLineParserUtilities"; import { arrayFrom, @@ -32,7 +33,6 @@ import { Comparison, MapLike, } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { isCallExpression, isIdentifier, diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index da36a3c3b90f4..e8f7cf8e30440 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { addRange, arrayFrom, @@ -10,7 +11,6 @@ import { length, some, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { createPrinter } from "../compiler/emitter"; import { isArrowFunction, diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 536cc8b21a54b..8a6c94a75202b 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { getNodeId } from "../compiler/checkerUtilities"; import { concatenate, @@ -25,7 +26,6 @@ import { singleOrUndefined, stableSort, } from "../compiler/core"; -import { Debug } from "../compiler/debug"; import { createPrinter } from "../compiler/emitter"; import { createNodeFactory, diff --git a/src/services/transpile.ts b/src/services/transpile.ts index bd93db8382a9f..95a4f79b63be1 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { createCompilerDiagnosticForInvalidCustomType, optionDeclarations, @@ -11,7 +12,6 @@ import { isString, } from "../compiler/core"; import { MapLike } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { createSourceFile } from "../compiler/parser"; import { fileExtensionIs, diff --git a/src/services/utilities.ts b/src/services/utilities.ts index efd19ff6cd6a5..d0c92541bb88a 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1,3 +1,4 @@ +import * as Debug from "../compiler/debug"; import { getModuleInstanceState, ModuleInstanceState, @@ -40,7 +41,6 @@ import { tryCast, } from "../compiler/core"; import { Comparison } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { createPrinter } from "../compiler/emitter"; import { addEmitFlags, diff --git a/src/testRunner/runner.ts b/src/testRunner/runner.ts index 65af002657a19..90783565f1225 100644 --- a/src/testRunner/runner.ts +++ b/src/testRunner/runner.ts @@ -264,11 +264,11 @@ function handleTestConfig() { } function beginTests() { - ts.Debug.loggingHost = { + ts.Debug.setLoggingHost({ log(_level, s) { console.log(s || ""); } - }; + }); if (ts.Debug.isDebugging) { ts.Debug.enableDebugInfo(); diff --git a/src/testRunner/unittests/debugDeprecation.ts b/src/testRunner/unittests/debugDeprecation.ts index 2da30337b141e..5eff4bc9b545c 100644 --- a/src/testRunner/unittests/debugDeprecation.ts +++ b/src/testRunner/unittests/debugDeprecation.ts @@ -2,12 +2,12 @@ import * as ts from "../_namespaces/ts"; import { deprecate } from "../../deprecatedCompat/deprecate"; describe("unittests:: debugDeprecation", () => { - let loggingHost: ts.LoggingHost | undefined; + let loggingHost: ts.Debug.LoggingHost | undefined; beforeEach(() => { loggingHost = ts.Debug.loggingHost; }); afterEach(() => { - ts.Debug.loggingHost = loggingHost; + ts.Debug.setLoggingHost(loggingHost); loggingHost = undefined; }); describe("deprecateFunction", () => { @@ -17,11 +17,11 @@ describe("unittests:: debugDeprecation", () => { typeScriptVersion: "3.8" }); let logWritten = false; - ts.Debug.loggingHost = { + ts.Debug.setLoggingHost({ log() { logWritten = true; } - }; + }); deprecation(); assert.isFalse(logWritten); }); @@ -31,11 +31,11 @@ describe("unittests:: debugDeprecation", () => { typeScriptVersion: "3.9" }); let logWritten = false; - ts.Debug.loggingHost = { + ts.Debug.setLoggingHost({ log() { logWritten = true; } - }; + }); deprecation(); assert.isTrue(logWritten); }); @@ -44,11 +44,11 @@ describe("unittests:: debugDeprecation", () => { typeScriptVersion: "3.9" }); let logWritten = false; - ts.Debug.loggingHost = { + ts.Debug.setLoggingHost({ log() { logWritten = true; } - }; + }); deprecation(); assert.isTrue(logWritten); }); @@ -57,11 +57,11 @@ describe("unittests:: debugDeprecation", () => { typeScriptVersion: "3.9" }); let logWrites = 0; - ts.Debug.loggingHost = { + ts.Debug.setLoggingHost({ log() { logWrites++; } - }; + }); deprecation(); deprecation(); assert.equal(logWrites, 1); @@ -73,11 +73,11 @@ describe("unittests:: debugDeprecation", () => { typeScriptVersion: "3.9" }); let logWritten = false; - ts.Debug.loggingHost = { + ts.Debug.setLoggingHost({ log() { logWritten = true; } - }; + }); expect(deprecation).throws(); assert.isFalse(logWritten); }); @@ -86,11 +86,11 @@ describe("unittests:: debugDeprecation", () => { error: true, }); let logWritten = false; - ts.Debug.loggingHost = { + ts.Debug.setLoggingHost({ log() { logWritten = true; } - }; + }); expect(deprecation).throws(); assert.isFalse(logWritten); }); diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index ce8b356b685d9..a3d29a941e794 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -3,11 +3,11 @@ import * as ts from "./_namespaces/ts"; // This file actually uses arguments passed on commandline and executes it // enable deprecation logging -ts.Debug.loggingHost = { +ts.Debug.setLoggingHost({ log(_level, s) { ts.sys.write(`${s || ""}${ts.sys.newLine}`); } -}; +}); if (ts.Debug.isDebugging) { ts.Debug.enableDebugInfo(); diff --git a/src/tsserver/nodeServer.ts b/src/tsserver/nodeServer.ts index 3939e508dfd5b..a18e31d0ce73f 100644 --- a/src/tsserver/nodeServer.ts +++ b/src/tsserver/nodeServer.ts @@ -306,18 +306,18 @@ export function initializeNodeSystem(): StartInput { const logger = createLogger(); // enable deprecation logging - Debug.loggingHost = { + Debug.setLoggingHost({ log(level, s) { switch (level) { - case ts.LogLevel.Error: - case ts.LogLevel.Warning: + case Debug.LogLevel.Error: + case Debug.LogLevel.Warning: return logger.msg(s, Msg.Err); - case ts.LogLevel.Info: - case ts.LogLevel.Verbose: + case Debug.LogLevel.Info: + case Debug.LogLevel.Verbose: return logger.msg(s, Msg.Info); } } - }; + }); const pending = createQueue(); let canWrite = true; diff --git a/src/typescript/typescript.ts b/src/typescript/typescript.ts index 9f1934f652a2c..510cca1ecd8b2 100644 --- a/src/typescript/typescript.ts +++ b/src/typescript/typescript.ts @@ -1,22 +1,20 @@ -import { - Debug, - LogLevel, -} from "./_namespaces/ts"; +import * as Debug from "../compiler/debug"; import * as ts from "./_namespaces/ts"; // enable deprecation logging declare const console: any; + if (typeof console !== "undefined") { - Debug.loggingHost = { + Debug.setLoggingHost({ log(level, s) { switch (level) { - case LogLevel.Error: return console.error(s); - case LogLevel.Warning: return console.warn(s); - case LogLevel.Info: return console.log(s); - case LogLevel.Verbose: return console.log(s); + case Debug.LogLevel.Error: return console.error(s); + case Debug.LogLevel.Warning: return console.warn(s); + case Debug.LogLevel.Info: return console.log(s); + case Debug.LogLevel.Verbose: return console.log(s); } } - }; + }); } export = ts; diff --git a/src/typingsInstaller/nodeTypingsInstaller.ts b/src/typingsInstaller/nodeTypingsInstaller.ts index 29617b8c63bb5..1f3cf87696b7d 100644 --- a/src/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/typingsInstaller/nodeTypingsInstaller.ts @@ -1,5 +1,6 @@ import * as fs from "fs"; import * as path from "path"; +import * as Debug from "../compiler/debug"; import { createGetCanonicalFileName, stringContains, @@ -8,7 +9,6 @@ import { MapLike, version, } from "../compiler/corePublic"; -import { Debug } from "../compiler/debug"; import { combinePaths, forEachAncestorDirectory, From 8631a5690e085df7bc571cf218f0405585dee7fd Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 18 Jan 2023 11:59:38 +0200 Subject: [PATCH 07/24] add Debug to the core --- src/compiler/core.ts | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index f9288ecffaf94..79748438e7fdc 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1,3 +1,4 @@ +import * as Debug from "./debug"; import { Comparer, Comparison, @@ -7,7 +8,6 @@ import { SortedArray, SortedReadonlyArray, } from "./corePublic"; -// import { Debug } from "./debug"; import { __String, CharacterCodes, @@ -16,7 +16,6 @@ import { UnderscoreEscapedMap, } from "./types"; - /** @internal */ export const emptyArray: never[] = [] as never[]; /** @internal */ @@ -111,7 +110,7 @@ export function reduceLeftIterator(iterator: Iterable | undefined, f: ( /** @internal */ 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); + Debug.assertEqual(arrayA.length, arrayB.length); for (let i = 0; i < arrayA.length; i++) { result.push(callback(arrayA[i], arrayB[i], i)); } @@ -235,8 +234,7 @@ export function findMap(array: readonly T[], callback: (element: T, index: return result; } } - throw new Error(); - // return Debug.fail(); + return Debug.fail(); } /** @internal */ @@ -803,8 +801,7 @@ function deduplicateSorted(array: SortedReadonlyArray, comparer: EqualityC case Comparison.LessThan: // If `array` is sorted, `next` should **never** be less than `last`. - // return Debug.fail("Array is unsorted."); - throw new Error("Array is unsorted."); + return Debug.fail("Array is unsorted."); } deduplicated.push(last = next); @@ -962,14 +959,14 @@ export function relativeComplement(arrayA: T[] | undefined, arrayB: T[] | und 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); + Debug.assertGreaterThanOrEqual(comparer(arrayB[offsetB], arrayB[offsetB - 1]), 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); + Debug.assertGreaterThanOrEqual(comparer(arrayA[offsetA], arrayA[offsetA - 1]), Comparison.EqualTo); } switch (comparer(arrayB[offsetB], arrayA[offsetA])) { @@ -1199,7 +1196,7 @@ export function firstOrUndefinedIterator(iter: Iterable | undefined): T | /** @internal */ export function first(array: readonly T[]): T { - // Debug.assert(array.length !== 0); + Debug.assert(array.length !== 0); return array[0]; } @@ -1208,8 +1205,7 @@ export function firstIterator(iter: Iterable): T { for (const value of iter) { return value; } - throw new Error("iterator is empty"); - // Debug.fail("iterator is empty"); + Debug.fail("iterator is empty"); } /** @@ -1223,7 +1219,7 @@ export function lastOrUndefined(array: readonly T[] | undefined): T | undefin /** @internal */ export function last(array: readonly T[]): T { - // Debug.assert(array.length !== 0); + Debug.assert(array.length !== 0); return array[array.length - 1]; } @@ -1244,12 +1240,7 @@ export function singleOrUndefined(array: readonly T[] | undefined): T | undef * @internal */ export function single(array: readonly T[]): T { - // return Debug.checkDefined(singleOrUndefined(array)); - const result = singleOrUndefined(array); - if (result === undefined) { - throw new Error(); - } - return result; + return Debug.checkDefined(singleOrUndefined(array)); } /** @@ -1897,8 +1888,7 @@ export function tryCast(value: TIn | undefined, tes /** @internal */ 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)}'.`); - throw new Error("Invalid cast."); + return Debug.fail(`Invalid cast. The supplied value ${value} did not pass the test '${Debug.getFunctionName(test)}'.`); } /** @@ -2368,7 +2358,7 @@ export function getSpellingSuggestion(name: string, candidates: T[], getName: continue; } - // Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined + Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined bestDistance = distance; bestCandidate = candidate; } @@ -2582,7 +2572,7 @@ export function patternText({ prefix, suffix }: Pattern): string { * @internal */ export function matchedText(pattern: Pattern, candidate: string): string { - // Debug.assert(isPatternMatch(pattern, candidate)); + Debug.assert(isPatternMatch(pattern, candidate)); return candidate.substring(pattern.prefix.length, candidate.length - pattern.suffix.length); } From 86b87be14a6509f2cbd5c3b06f42619795e30e7d Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 18 Jan 2023 12:07:10 +0200 Subject: [PATCH 08/24] move hasTabstop from compiler/utilities to services/services --- src/compiler/utilities.ts | 7 ------- src/services/services.ts | 7 ++++++- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index d8a76f50d7083..cbf0b8aa0429c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -61,7 +61,6 @@ import { version, } from "./corePublic"; import { Diagnostics } from "./diagnosticInformationMap.generated"; -import { getSnippetElement } from "./factory/emitNode"; import { isArrayLiteralExpression, isArrowFunction, @@ -400,7 +399,6 @@ import { SignatureDeclaration, SignatureFlags, SignatureKind, - SnippetKind, SourceFile, SourceFileLike, SourceFileMayBeEmittedHost, @@ -8218,11 +8216,6 @@ export function canUsePropertyAccess(name: string, languageVersion: ScriptTarget isIdentifierStart(firstChar, languageVersion); } -/** @internal */ -export function hasTabstop(node: Node): boolean { - return getSnippetElement(node)?.kind === SnippetKind.TabStop; -} - /** @internal */ export function isJSDocOptionalParameter(node: ParameterDeclaration) { return isInJSFile(node) && ( diff --git a/src/services/services.ts b/src/services/services.ts index 3b0b988c43425..8d5f66d399306 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -53,6 +53,7 @@ import { isPrivateIdentifier, isPropertyAccessExpression, } from "../compiler/factory/nodeTests"; +import { getSnippetElement } from "../compiler/factory/emitNode"; import { ModeAwareCache } from "../compiler/moduleNameResolver"; import { ObjectAllocator, @@ -153,6 +154,7 @@ import { SignatureDeclaration, SignatureFlags, SignatureKind, + SnippetKind, SourceFile, SourceFileLike, SourceMapSource, @@ -193,7 +195,6 @@ import { getTokenPosOfNode, hasStaticModifier, hasSyntacticModifier, - hasTabstop, hostGetCanonicalFileName, hostUsesCaseSensitiveFileNames, isDeclarationName, @@ -557,6 +558,10 @@ function addSyntheticNodes(nodes: Push, pos: number, end: number, parent: } } +function hasTabstop(node: Node): boolean { + return getSnippetElement(node)?.kind === SnippetKind.TabStop; +} + function createSyntaxList(nodes: NodeArray, parent: Node): Node { const list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, parent) as any as SyntaxList; list._children = []; From 89789159d47a6334bdb7d4a3e646cdbd95a5302f Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 18 Jan 2023 23:10:15 +0200 Subject: [PATCH 09/24] move isNodeLikeSystem from core to platform --- src/compiler/performanceCore.ts | 2 +- src/compiler/platform.ts | 15 +++++++++++++++ src/compiler/sys.ts | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 src/compiler/platform.ts diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index 081bc134ac8a3..fac05a9ea6272 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -1,4 +1,4 @@ -import { isNodeLikeSystem } from "./core"; +import { isNodeLikeSystem } from "./platform"; // The following definitions provide the minimum compatible support for the Web Performance User Timings API // between browsers and NodeJS: diff --git a/src/compiler/platform.ts b/src/compiler/platform.ts new file mode 100644 index 0000000000000..5099976084b91 --- /dev/null +++ b/src/compiler/platform.ts @@ -0,0 +1,15 @@ +declare const process: any; + +/** @internal */ +export function isNodeLikeSystem(): boolean { + // This is defined here rather than in sys.ts to prevent a cycle from its + // use in performanceCore.ts. + // + // We don't use the presence of `require` to check if we are in Node; + // when bundled using esbuild, this function will be rewritten to `__require` + // and definitely exist. + return typeof process !== "undefined" + && process.nextTick + && !process.browser + && typeof module === "object"; +} diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index bed3cc6a575d5..033e6488a2157 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -1,5 +1,6 @@ import * as Debug from "./debug"; import { matchesExclude } from "./commandLineParser"; +import { isNodeLikeSystem } from "./platform"; import { contains, createGetCanonicalFileName, @@ -9,7 +10,6 @@ import { enumerateInsertsAndDeletes, getStringComparer, isArray, - isNodeLikeSystem, isString, mapDefined, memoize, From 34fb0951c8fdb7d11b720f6238fb97df34c8e3a1 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 19 Jan 2023 00:08:45 +0200 Subject: [PATCH 10/24] move extensions utils that depends on the core from utilities to the extension module --- src/compiler/_namespaces/ts.ts | 1 + src/compiler/checker.ts | 2 +- src/compiler/commandLineParser.ts | 6 +- src/compiler/emitter.ts | 2 +- src/compiler/extension.ts | 132 +++++++++++++++++++ src/compiler/moduleNameResolver.ts | 8 +- src/compiler/moduleSpecifiers.ts | 8 +- src/compiler/moduleSpecifiersUtilities.ts | 8 +- src/compiler/parser.ts | 2 +- src/compiler/performance.ts | 4 +- src/compiler/program.ts | 10 +- src/compiler/sourcemap.ts | 4 +- src/compiler/utilities.ts | 96 +------------- src/compiler/watchUtilities.ts | 3 +- src/executeCommandLine/executeCommandLine.ts | 6 +- src/jsTyping/jsTyping.ts | 6 +- src/server/editorServices.ts | 2 +- src/server/scriptInfo.ts | 6 +- src/services/jsDoc.ts | 2 +- src/services/stringCompletions.ts | 8 +- 20 files changed, 182 insertions(+), 134 deletions(-) create mode 100644 src/compiler/extension.ts diff --git a/src/compiler/_namespaces/ts.ts b/src/compiler/_namespaces/ts.ts index d8d2822f0ee1f..4c9cc2f741e5e 100644 --- a/src/compiler/_namespaces/ts.ts +++ b/src/compiler/_namespaces/ts.ts @@ -2,6 +2,7 @@ export * from "../corePublic"; export * from "../core"; +export * from "../extension"; export * from "../semver"; export * from "../performanceCore"; export * from "../perfLogger"; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 77642085499c7..23e696300231c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -982,7 +982,6 @@ import { skipParentheses, skipTypeChecking, stripQuotes, - tryExtractTSExtension, tryGetClassImplementingOrExtendingExpressionWithTypeArguments, tryGetExtensionFromPath, tryGetJSDocSatisfiesTypeNode, @@ -1094,6 +1093,7 @@ import { visitNode, visitNodes, } from "./visitorPublic"; +import { tryExtractTSExtension } from "./extension"; const ambientModuleSymbolRegex = /^".+"$/; const anon = "(anonymous)" as __String & string; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index c6b1a5e124180..17933046853cb 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -123,8 +123,6 @@ import { createDiagnosticForNodeInSourceFile, forEachEntry, getLocaleSpecificMessage, - getSupportedExtensions, - getSupportedExtensionsWithJsonIfResolveJsonModule, getTextOfPropertyName, getTsConfigPropArray, getTsConfigPropArrayElementValue, @@ -132,6 +130,10 @@ import { isStringDoubleQuoted, } from "./utilities"; import { unescapeLeadingUnderscores } from "./utilitiesPublic"; +import { + getSupportedExtensions, + getSupportedExtensionsWithJsonIfResolveJsonModule, +} from "./extension"; /** @internal */ export const compileOnSaveCommandLineOption: CommandLineOption = { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 97a9b740a9c69..890f959f2dea5 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -456,7 +456,6 @@ import { removeFileExtension, setTextRangePosEnd, setTextRangePosWidth, - supportedJSExtensionsFlat, writeCommentRange, writeFile, } from "./utilities"; @@ -487,6 +486,7 @@ import { getNewLineCharacter } from "./sysUtilities"; import { getSourceFilesToEmit } from "./emitterUtilities"; import { setEachParent, setParent } from "./parserUtilities"; import { readJsonOrUndefined } from "./commandLineParserUtilities"; +import { supportedJSExtensionsFlat } from "./extension"; const brackets = createBracketsMap(); diff --git a/src/compiler/extension.ts b/src/compiler/extension.ts new file mode 100644 index 0000000000000..d45d4dbd89129 --- /dev/null +++ b/src/compiler/extension.ts @@ -0,0 +1,132 @@ +import { + find, + firstDefined, + flatten, + mapDefined, + or, + some, +} from "./core"; +import { + fileExtensionIs, + pathIsRelative, +} from "./path"; +import { + CompilerOptions, + Extension, + FileExtensionInfo, + ScriptKind, + SourceFile, +} from "./types"; +import { + getAllowJSCompilerOption, + getResolveJsonModule, + isJSLike, +} from "./utilities"; + +/** + * Groups of supported extensions in order of file resolution precedence. (eg, TS > TSX > DTS and seperately, CTS > DCTS) + * + * @internal + */ +export const supportedTSExtensions: readonly Extension[][] = [[Extension.Ts, Extension.Tsx, Extension.Dts], [Extension.Cts, Extension.Dcts], [Extension.Mts, Extension.Dmts]]; + +/** @internal */ +export const supportedTSExtensionsFlat: readonly Extension[] = flatten(supportedTSExtensions); + +/** @internal */ +export const supportedTSExtensionsWithJson: readonly Extension[][] = [...supportedTSExtensions, [Extension.Json]]; + +/** + * Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". + * @internal + */ +export const supportedTSExtensionsForExtractExtension: readonly Extension[] = [Extension.Dts, Extension.Dcts, Extension.Dmts, Extension.Cts, Extension.Mts, Extension.Ts, Extension.Tsx, Extension.Cts, Extension.Mts]; + +/** @internal */ +export const supportedJSExtensions: readonly Extension[][] = [[Extension.Js, Extension.Jsx], [Extension.Mjs], [Extension.Cjs]]; + +/** @internal */ +export const supportedJSExtensionsFlat: readonly Extension[] = flatten(supportedJSExtensions); + +/** @internal */ +export const allSupportedExtensions: readonly Extension[][] = [[Extension.Ts, Extension.Tsx, Extension.Dts, Extension.Js, Extension.Jsx], [Extension.Cts, Extension.Dcts, Extension.Cjs], [Extension.Mts, Extension.Dmts, Extension.Mjs]]; + +/** @internal */ +export const allSupportedExtensionsWithJson: readonly Extension[][] = [...allSupportedExtensions, [Extension.Json]]; + +/** @internal */ +export const supportedDeclarationExtensions: readonly Extension[] = [Extension.Dts, Extension.Dcts, Extension.Dmts]; + +/** @internal */ +export const supportedTSImplementationExtensions: readonly Extension[] = [Extension.Ts, Extension.Cts, Extension.Mts, Extension.Tsx]; + +/** + * Return ".ts", ".d.ts", or ".tsx", if that is the extension. + * + * @internal + */ +export function tryExtractTSExtension(fileName: string): string | undefined { + return find(supportedTSExtensionsForExtractExtension, extension => fileExtensionIs(fileName, extension)); +} + +/** @internal */ +export function getSupportedExtensions(options?: CompilerOptions): readonly Extension[][]; +/** @internal */ +export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]): readonly string[][]; +/** @internal */ +export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]): readonly string[][] { + const needJsExtensions = options && getAllowJSCompilerOption(options); + + if (!extraFileExtensions || extraFileExtensions.length === 0) { + return needJsExtensions ? allSupportedExtensions : supportedTSExtensions; + } + + const builtins = needJsExtensions ? allSupportedExtensions : supportedTSExtensions; + const flatBuiltins = flatten(builtins); + const extensions = [ + ...builtins, + ...mapDefined(extraFileExtensions, x => x.scriptKind === ScriptKind.Deferred || needJsExtensions && isJSLike(x.scriptKind) && flatBuiltins.indexOf(x.extension as Extension) === -1 ? [x.extension] : undefined) + ]; + + return extensions; +} + +/** @internal */ +export function getSupportedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: readonly Extension[][]): readonly Extension[][]; +/** @internal */ +export function getSupportedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: readonly string[][]): readonly string[][]; +/** @internal */ +export function getSupportedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: readonly string[][]): readonly string[][] { + if (!options || !getResolveJsonModule(options)) return supportedExtensions; + if (supportedExtensions === allSupportedExtensions) return allSupportedExtensionsWithJson; + if (supportedExtensions === supportedTSExtensions) return supportedTSExtensionsWithJson; + return [...supportedExtensions, [Extension.Json]]; +} + +/** @internal */ +export function hasJSFileExtension(fileName: string): boolean { + return some(supportedJSExtensionsFlat, extension => fileExtensionIs(fileName, extension)); +} + +/** @internal */ +export function hasTSFileExtension(fileName: string): boolean { + return some(supportedTSExtensionsFlat, extension => fileExtensionIs(fileName, extension)); +} + +/** @internal */ +export function usesExtensionsOnImports({ imports }: SourceFile, hasExtension: (text: string) => boolean = or(hasJSFileExtension, hasTSFileExtension)): boolean { + return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasExtension(text) : undefined) || false; +} + +/** @internal */ +export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]) { + if (!fileName) return false; + + const supportedExtensions = getSupportedExtensions(compilerOptions, extraFileExtensions); + for (const extension of flatten(getSupportedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions))) { + if (fileExtensionIs(fileName, extension)) { + return true; + } + } + return false; +} diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 8cc270169473a..e3b7743a3ee5f 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -110,15 +110,17 @@ import { packageIdToString, removeExtension, removeFileExtension, - supportedDeclarationExtensions, - supportedTSImplementationExtensions, - tryExtractTSExtension, tryGetExtensionFromPath, tryParsePatterns, } from "./utilities"; import { isExternalModuleNameRelative, } from "./utilitiesPublic"; +import { + supportedDeclarationExtensions, + supportedTSImplementationExtensions, + tryExtractTSExtension, +} from "./extension"; /** @internal */ export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void; diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index c0f8b32370f04..d52fc897c699d 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -107,10 +107,7 @@ import { getEmitModuleResolutionKind, getPathsBasePath, getSourceFileOfModule, - getSupportedExtensions, getTextOfIdentifierOrLiteral, - hasJSFileExtension, - hasTSFileExtension, hostGetCanonicalFileName, isAmbientModule, isExternalModuleAugmentation, @@ -123,6 +120,11 @@ import { tryParsePatterns, } from "./utilities"; import { isExternalModuleNameRelative } from "./utilitiesPublic"; +import { + getSupportedExtensions, + hasJSFileExtension, + hasTSFileExtension, +} from "./extension"; // Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers. diff --git a/src/compiler/moduleSpecifiersUtilities.ts b/src/compiler/moduleSpecifiersUtilities.ts index b052f0694cc55..fe0a136d5622d 100644 --- a/src/compiler/moduleSpecifiersUtilities.ts +++ b/src/compiler/moduleSpecifiersUtilities.ts @@ -3,6 +3,11 @@ import { concatenate, emptyArray, } from "./core"; +import { + hasJSFileExtension, + hasTSFileExtension, + usesExtensionsOnImports, +} from "./extension"; import { isExpressionStatement } from "./factory/nodeTests"; import { nodeModulesPathPart, @@ -18,13 +23,10 @@ import { UserPreferences, } from "./types"; import { - hasJSFileExtension, - hasTSFileExtension, isRequireCall, isRequireVariableStatement, isSourceFileJS, ModuleSpecifierEnding, - usesExtensionsOnImports, } from "./utilities"; /** @internal */ diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index c0da3abc204ff..376621a2882c2 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -393,7 +393,6 @@ import { setTextRangePos, setTextRangePosEnd, setTextRangePosWidth, - supportedDeclarationExtensions, } from "./utilities"; import { createTextChangeRange, @@ -409,6 +408,7 @@ import { textChangeRangeNewSpan, textSpanEnd, } from "./utilitiesPublic"; +import { supportedDeclarationExtensions } from "./extension"; const enum SignatureFlags { None = 0, diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index 2c7aaba18fe0a..896f9c7691070 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -23,7 +23,7 @@ export interface Timer { /** @internal */ export function createTimerIf(condition: boolean, measureName: string, startMarkName: string, endMarkName: string) { - return condition ? createTimer(measureName, startMarkName, endMarkName) : nullTimer; + return condition ? createTimer(measureName, startMarkName, endMarkName) : createNullTimer(); } /** @internal */ @@ -52,7 +52,7 @@ export function createTimer(measureName: string, startMarkName: string, endMarkN } /** @internal */ -export const nullTimer: Timer = { enter: noop, exit: noop }; +export const createNullTimer = (): Timer => ({ enter: noop, exit: noop }); let enabled = false; let timeorigin = timestamp(); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index b7c51900fde85..b137d72866de2 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -305,13 +305,10 @@ import { getResolvedModule, getResolveJsonModule, getStrictOptionValue, - getSupportedExtensions, - getSupportedExtensionsWithJsonIfResolveJsonModule, getTextOfIdentifierOrLiteral, getTsConfigObjectLiteralExpression, getTsConfigPropArray, getTsConfigPropArrayElementValue, - hasJSFileExtension, hasJsonModuleEmitEnabled, hasSyntacticModifier, hasZeroOrOneAsteriskCharacter, @@ -337,7 +334,6 @@ import { resolutionExtensionIsTSOrJson, skipTypeChecking, sourceFileMayBeEmitted, - supportedJSExtensionsFlat, typeDirectiveIsEqualTo, walkUpParenthesizedExpressions, writeFileEnsuringDirectories, @@ -359,6 +355,12 @@ import { } from "./watch"; import { ProgramHost } from "./watchPublic"; import { DirectoryStructureHost } from "./watchUtilities"; +import { + getSupportedExtensions, + getSupportedExtensionsWithJsonIfResolveJsonModule, + hasJSFileExtension, + supportedJSExtensionsFlat, +} from "./extension"; export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string | undefined { return forEachAncestorDirectory(searchPath, ancestor => { diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index b63468394cda0..ab76489bd09d0 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -1,4 +1,5 @@ import * as Debug from "./debug"; +import * as performance from "./performance"; import { arrayFrom, binarySearchKey, @@ -19,7 +20,6 @@ import { getNormalizedAbsolutePath, getRelativePathToDirectoryOrUrl, } from "./path"; -import * as performance from "./performance"; import { getPositionOfLineAndCharacter } from "./scanner"; import { CharacterCodes, @@ -41,7 +41,7 @@ export interface SourceMapGeneratorOptions { export function createSourceMapGenerator(host: EmitHost, file: string, sourceRoot: string, sourcesDirectoryPath: string, generatorOptions: SourceMapGeneratorOptions): SourceMapGenerator { const { enter, exit } = generatorOptions.extendedDiagnostics ? performance.createTimer("Source Map", "beforeSourcemap", "afterSourcemap") - : performance.nullTimer; + : performance.createNullTimer(); // Current source map file and its index in the sources list const rawSources: string[] = []; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index cbf0b8aa0429c..3bd3060d467a5 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -23,7 +23,6 @@ import { firstOrUndefined, flatMap, flatMapToMutable, - flatten, forEach, GetCanonicalFileName, getOwnKeys, @@ -40,7 +39,6 @@ import { length, mapDefined, noop, - or, Pattern, singleElementArray, singleOrUndefined, @@ -264,7 +262,6 @@ import { ExpressionWithTypeArguments, Extension, ExternalModuleReference, - FileExtensionInfo, FileWatcher, ForInOrOfStatement, ForInStatement, @@ -6168,14 +6165,6 @@ function isExportDefaultSymbol(symbol: Symbol): boolean { return symbol && length(symbol.declarations) > 0 && hasSyntacticModifier(symbol.declarations![0], ModifierFlags.Default); } -/** - * Return ".ts", ".d.ts", or ".tsx", if that is the extension. - * - * @internal - */ -export function tryExtractTSExtension(fileName: string): string | undefined { - return find(supportedTSExtensionsForExtractExtension, extension => fileExtensionIs(fileName, extension)); -} /** * Replace each instance of non-ascii characters by one, two, three, or four escape sequences * representing the UTF-8 encoding of the character, and return the expanded char code list. @@ -7506,76 +7495,11 @@ export function getScriptKindFromFileName(fileName: string): ScriptKind { } } -/** - * Groups of supported extensions in order of file resolution precedence. (eg, TS > TSX > DTS and seperately, CTS > DCTS) - * - * @internal - */ -export const supportedTSExtensions: readonly Extension[][] = [[Extension.Ts, Extension.Tsx, Extension.Dts], [Extension.Cts, Extension.Dcts], [Extension.Mts, Extension.Dmts]]; -/** @internal */ -export const supportedTSExtensionsFlat: readonly Extension[] = flatten(supportedTSExtensions); -const supportedTSExtensionsWithJson: readonly Extension[][] = [...supportedTSExtensions, [Extension.Json]]; -/** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */ -const supportedTSExtensionsForExtractExtension: readonly Extension[] = [Extension.Dts, Extension.Dcts, Extension.Dmts, Extension.Cts, Extension.Mts, Extension.Ts, Extension.Tsx, Extension.Cts, Extension.Mts]; -/** @internal */ -export const supportedJSExtensions: readonly Extension[][] = [[Extension.Js, Extension.Jsx], [Extension.Mjs], [Extension.Cjs]]; -/** @internal */ -export const supportedJSExtensionsFlat: readonly Extension[] = flatten(supportedJSExtensions); -const allSupportedExtensions: readonly Extension[][] = [[Extension.Ts, Extension.Tsx, Extension.Dts, Extension.Js, Extension.Jsx], [Extension.Cts, Extension.Dcts, Extension.Cjs], [Extension.Mts, Extension.Dmts, Extension.Mjs]]; -const allSupportedExtensionsWithJson: readonly Extension[][] = [...allSupportedExtensions, [Extension.Json]]; /** @internal */ -export const supportedDeclarationExtensions: readonly Extension[] = [Extension.Dts, Extension.Dcts, Extension.Dmts]; -/** @internal */ -export const supportedTSImplementationExtensions: readonly Extension[] = [Extension.Ts, Extension.Cts, Extension.Mts, Extension.Tsx]; - -/** @internal */ -export function getSupportedExtensions(options?: CompilerOptions): readonly Extension[][]; -/** @internal */ -export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]): readonly string[][]; -/** @internal */ -export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]): readonly string[][] { - const needJsExtensions = options && getAllowJSCompilerOption(options); - - if (!extraFileExtensions || extraFileExtensions.length === 0) { - return needJsExtensions ? allSupportedExtensions : supportedTSExtensions; - } - - const builtins = needJsExtensions ? allSupportedExtensions : supportedTSExtensions; - const flatBuiltins = flatten(builtins); - const extensions = [ - ...builtins, - ...mapDefined(extraFileExtensions, x => x.scriptKind === ScriptKind.Deferred || needJsExtensions && isJSLike(x.scriptKind) && flatBuiltins.indexOf(x.extension as Extension) === -1 ? [x.extension] : undefined) - ]; - - return extensions; -} - -/** @internal */ -export function getSupportedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: readonly Extension[][]): readonly Extension[][]; -/** @internal */ -export function getSupportedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: readonly string[][]): readonly string[][]; -/** @internal */ -export function getSupportedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: readonly string[][]): readonly string[][] { - if (!options || !getResolveJsonModule(options)) return supportedExtensions; - if (supportedExtensions === allSupportedExtensions) return allSupportedExtensionsWithJson; - if (supportedExtensions === supportedTSExtensions) return supportedTSExtensionsWithJson; - return [...supportedExtensions, [Extension.Json]]; -} - -function isJSLike(scriptKind: ScriptKind | undefined): boolean { +export function isJSLike(scriptKind: ScriptKind | undefined): boolean { return scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX; } -/** @internal */ -export function hasJSFileExtension(fileName: string): boolean { - return some(supportedJSExtensionsFlat, extension => fileExtensionIs(fileName, extension)); -} - -/** @internal */ -export function hasTSFileExtension(fileName: string): boolean { - return some(supportedTSExtensionsFlat, extension => fileExtensionIs(fileName, extension)); -} - /** * @internal * Corresponds to UserPreferences#importPathEnding @@ -7587,24 +7511,6 @@ export const enum ModuleSpecifierEnding { TsExtension, } -/** @internal */ -export function usesExtensionsOnImports({ imports }: SourceFile, hasExtension: (text: string) => boolean = or(hasJSFileExtension, hasTSFileExtension)): boolean { - return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasExtension(text) : undefined) || false; -} - -/** @internal */ -export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]) { - if (!fileName) return false; - - const supportedExtensions = getSupportedExtensions(compilerOptions, extraFileExtensions); - for (const extension of flatten(getSupportedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions))) { - if (fileExtensionIs(fileName, extension)) { - return true; - } - } - return false; -} - function numberOfDirectorySeparators(str: string) { const match = str.match(/\//g); return match ? match.length : 0; diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index 09a7501479dd3..01936f3126e95 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -61,13 +61,12 @@ import { } from "./types"; import { closeFileWatcher, - isSupportedSourceFileName, mutateMap, outFile, removeFileExtension, - supportedJSExtensionsFlat, } from "./utilities"; import { returnNoopFileWatcher } from "./watch"; +import { isSupportedSourceFileName, supportedJSExtensionsFlat } from "./extension"; /** * Partial interface of the System thats needed to support the caching of directory structure diff --git a/src/executeCommandLine/executeCommandLine.ts b/src/executeCommandLine/executeCommandLine.ts index 982573059545e..cde378707ae18 100644 --- a/src/executeCommandLine/executeCommandLine.ts +++ b/src/executeCommandLine/executeCommandLine.ts @@ -89,8 +89,6 @@ import { formatMessage, isIncrementalCompilation, isWatchSet, - supportedJSExtensionsFlat, - supportedTSExtensionsFlat, } from "../compiler/utilities"; import { validateLocaleAndSetLanguage } from "../compiler/utilitiesPublic"; import { @@ -109,6 +107,10 @@ import { createWatchProgram, WatchCompilerHost, } from "../compiler/watchPublic"; +import { + supportedJSExtensionsFlat, + supportedTSExtensionsFlat, +} from "../compiler/extension"; interface Statistic { name: string; diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index b58016ab78d29..fcc83b92c639f 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -34,10 +34,8 @@ import { Path, TypeAcquisition, } from "../compiler/types"; -import { - hasJSFileExtension, - removeFileExtension, -} from "../compiler/utilities"; +import { removeFileExtension } from "../compiler/utilities"; +import { hasJSFileExtension } from "../compiler/extension"; /** @internal */ export interface TypingResolutionHost { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 36de791109466..cba227e71165f 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -106,7 +106,6 @@ import { clearMap, forEachEntry, forEachKey, - hasTSFileExtension, isJsonEqual, removeFileExtension, } from "../compiler/utilities"; @@ -220,6 +219,7 @@ import { ProjectOptions, toNormalizedPath, } from "./utilitiesPublic"; +import { hasTSFileExtension } from "../compiler/extension"; export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024; /** @internal */ diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 82298111c9954..278c3e0c003be 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -32,10 +32,7 @@ import { SourceFileLike, TextSpan, } from "../compiler/types"; -import { - getScriptKindFromFileName, - hasTSFileExtension, -} from "../compiler/utilities"; +import { getScriptKindFromFileName } from "../compiler/utilities"; import { createTextSpanFromBounds } from "../compiler/utilitiesPublic"; import { closeFileWatcherOf } from "../compiler/watchUtilities"; import { @@ -70,6 +67,7 @@ import { Errors, NormalizedPath, } from "./utilitiesPublic"; +import { hasTSFileExtension } from "../compiler/extension"; export interface ScriptInfoVersion { svc: number; diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index b8044c8398b6e..3682234c2031d 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -14,6 +14,7 @@ import { mapDefined, startsWith, } from "../compiler/core"; +import { hasJSFileExtension } from "../compiler/extension"; import { isArrowFunction, isBlock, @@ -67,7 +68,6 @@ import { forEachAncestor, getAssignmentDeclarationKind, getJSDocCommentsAndTags, - hasJSFileExtension, } from "../compiler/utilities"; import { findAncestor, diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 4c8cee92c566a..08b79f48ae0e3 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -114,8 +114,6 @@ import { changeExtension, getEmitModuleResolutionKind, getResolvePackageJsonExports, - getSupportedExtensions, - getSupportedExtensionsWithJsonIfResolveJsonModule, hostGetCanonicalFileName, isImportCall, ModuleSpecifierEnding, @@ -123,7 +121,6 @@ import { signatureHasRestParameter, skipParentheses, stripQuotes, - supportedTSImplementationExtensions, tryGetExtensionFromPath, tryParsePattern, tryRemoveDirectoryPrefix, @@ -178,6 +175,11 @@ import { tryGetDirectories, tryReadDirectory, } from "./utilities"; +import { + getSupportedExtensions, + getSupportedExtensionsWithJsonIfResolveJsonModule, + supportedTSImplementationExtensions, +} from "../compiler/extension"; interface NameAndKindSet { add(value: NameAndKind): void; From 912b4c5648150b517a38f6379176ab78119a9ea2 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 19 Jan 2023 11:30:51 +0200 Subject: [PATCH 11/24] move usesExtensionsOnImports and isSupportedSourceFileName from extension module --- src/compiler/extension.ts | 22 ---------------------- src/compiler/moduleSpecifiersUtilities.ts | 7 ++++++- src/compiler/watchUtilities.ts | 20 +++++++++++++++++++- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/compiler/extension.ts b/src/compiler/extension.ts index d45d4dbd89129..c8daeae1312e4 100644 --- a/src/compiler/extension.ts +++ b/src/compiler/extension.ts @@ -1,21 +1,17 @@ import { find, - firstDefined, flatten, mapDefined, - or, some, } from "./core"; import { fileExtensionIs, - pathIsRelative, } from "./path"; import { CompilerOptions, Extension, FileExtensionInfo, ScriptKind, - SourceFile, } from "./types"; import { getAllowJSCompilerOption, @@ -112,21 +108,3 @@ export function hasJSFileExtension(fileName: string): boolean { export function hasTSFileExtension(fileName: string): boolean { return some(supportedTSExtensionsFlat, extension => fileExtensionIs(fileName, extension)); } - -/** @internal */ -export function usesExtensionsOnImports({ imports }: SourceFile, hasExtension: (text: string) => boolean = or(hasJSFileExtension, hasTSFileExtension)): boolean { - return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasExtension(text) : undefined) || false; -} - -/** @internal */ -export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]) { - if (!fileName) return false; - - const supportedExtensions = getSupportedExtensions(compilerOptions, extraFileExtensions); - for (const extension of flatten(getSupportedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions))) { - if (fileExtensionIs(fileName, extension)) { - return true; - } - } - return false; -} diff --git a/src/compiler/moduleSpecifiersUtilities.ts b/src/compiler/moduleSpecifiersUtilities.ts index fe0a136d5622d..aed9aba7bd45e 100644 --- a/src/compiler/moduleSpecifiersUtilities.ts +++ b/src/compiler/moduleSpecifiersUtilities.ts @@ -2,11 +2,12 @@ import { append, concatenate, emptyArray, + firstDefined, + or, } from "./core"; import { hasJSFileExtension, hasTSFileExtension, - usesExtensionsOnImports, } from "./extension"; import { isExpressionStatement } from "./factory/nodeTests"; import { @@ -165,3 +166,7 @@ function getRequiresAtTopOfFile(sourceFile: SourceFile): readonly RequireOrImpor } return requires || emptyArray; } + +function usesExtensionsOnImports({ imports }: SourceFile, hasExtension: (text: string) => boolean = or(hasJSFileExtension, hasTSFileExtension)): boolean { + return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasExtension(text) : undefined) || false; +} diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index 01936f3126e95..a11597d306ae3 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -12,6 +12,7 @@ import { createGetCanonicalFileName, emptyArray, find, + flatten, identity, insertSorted, isArray, @@ -31,6 +32,7 @@ import { import { isDeclarationFileName } from "./parser"; import { ensureTrailingDirectorySeparator, + fileExtensionIs, fileExtensionIsOneOf, getBaseFileName, getDirectoryPath, @@ -66,7 +68,11 @@ import { removeFileExtension, } from "./utilities"; import { returnNoopFileWatcher } from "./watch"; -import { isSupportedSourceFileName, supportedJSExtensionsFlat } from "./extension"; +import { + getSupportedExtensions, + getSupportedExtensionsWithJsonIfResolveJsonModule, + supportedJSExtensionsFlat, +} from "./extension"; /** * Partial interface of the System thats needed to support the caching of directory structure @@ -818,3 +824,15 @@ export function getFallbackOptions(options: WatchOptions | undefined): WatchOpti export function closeFileWatcherOf(objWithWatcher: T) { objWithWatcher.watcher.close(); } + +function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]) { + if (!fileName) return false; + + const supportedExtensions = getSupportedExtensions(compilerOptions, extraFileExtensions); + for (const extension of flatten(getSupportedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions))) { + if (fileExtensionIs(fileName, extension)) { + return true; + } + } + return false; +} From 09db1234accb94d82a40f4ae31a9931e32466190 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 19 Jan 2023 13:42:30 +0200 Subject: [PATCH 12/24] move extensions utils from utilities to the extension module. classify files by folders --- .../_namespaces/ts.moduleSpecifiers.ts | 2 +- src/compiler/_namespaces/ts.ts | 28 +-- src/compiler/binder.ts | 10 +- src/compiler/builder.ts | 12 +- src/compiler/builderState.ts | 2 +- src/compiler/{ => checker}/checker.ts | 72 +++---- .../utilities.ts} | 2 +- .../commandLineParser.ts | 34 ++-- .../utilities.ts} | 2 +- src/compiler/debug.ts | 4 +- src/compiler/{ => emitter}/emitter.ts | 85 ++++---- src/compiler/emitter/utilities.ts | 100 +++++++++ src/compiler/emitterUtilities.ts | 45 ----- src/compiler/extension.ts | 89 ++++++++ src/compiler/factory/nodeFactory.ts | 13 +- src/compiler/factory/utilities.ts | 8 +- .../moduleNameResolver.ts | 43 ++-- src/compiler/moduleNameResolver/utilities.ts | 66 ++++++ .../moduleSpecifiers.ts | 36 ++-- .../utilities.ts} | 14 +- src/compiler/{ => parser}/parser.ts | 42 ++-- .../utilities.ts} | 6 +- src/compiler/performanceCore.ts | 2 +- src/compiler/platform.ts | 15 -- src/compiler/{ => program}/program.ts | 77 +++---- .../utilities.ts} | 10 +- src/compiler/resolutionCache.ts | 12 +- .../keywords.ts} | 4 +- src/compiler/{ => scanner}/scanner.ts | 12 +- .../utilities.ts} | 2 +- src/compiler/sourcemap.ts | 2 +- src/compiler/symbolWalker.ts | 2 +- src/compiler/symlinkCache.ts | 4 +- src/compiler/{ => sys}/sys.ts | 26 +-- .../{sysUtilities.ts => sys/utilities.ts} | 4 +- src/compiler/tracing.ts | 2 +- src/compiler/transformers/declarations.ts | 20 +- src/compiler/transformers/es2015.ts | 4 +- src/compiler/transformers/es2017.ts | 2 +- src/compiler/transformers/es2018.ts | 2 +- src/compiler/transformers/generators.ts | 2 +- src/compiler/transformers/jsx.ts | 4 +- src/compiler/transformers/module/module.ts | 2 +- src/compiler/transformers/module/system.ts | 2 +- src/compiler/transformers/ts.ts | 6 +- src/compiler/transformers/typeSerializer.ts | 4 +- src/compiler/transformers/utilities.ts | 2 +- src/compiler/tsbuildPublic.ts | 10 +- src/compiler/types.ts | 6 +- src/compiler/utilities.ts | 190 +----------------- src/compiler/utilitiesPublic.ts | 2 +- src/compiler/watch.ts | 10 +- src/compiler/watchPublic.ts | 16 +- src/compiler/watchUtilities.ts | 8 +- .../4.0/nodeFactoryTopLevelExports.ts | 4 +- src/executeCommandLine/executeCommandLine.ts | 8 +- src/harness/fakesHosts.ts | 2 +- src/harness/harnessUtils.ts | 2 +- src/jsTyping/jsTyping.ts | 8 +- src/jsTyping/shared.ts | 2 +- src/server/editorServices.ts | 16 +- src/server/moduleSpecifierCache.ts | 2 +- src/server/project.ts | 17 +- src/server/scriptInfo.ts | 2 +- src/server/scriptVersionCache.ts | 2 +- src/server/session.ts | 12 +- src/services/breakpoints.ts | 2 +- src/services/callHierarchy.ts | 8 +- src/services/classifier.ts | 6 +- src/services/classifier2020.ts | 2 +- src/services/codefixes/addMissingAsync.ts | 2 +- src/services/codefixes/addMissingAwait.ts | 2 +- src/services/codefixes/convertConstToLet.ts | 2 +- .../codefixes/convertFunctionToEs6Class.ts | 2 +- .../codefixes/convertToAsyncFunction.ts | 8 +- src/services/codefixes/convertToEsModule.ts | 2 +- .../codefixes/convertToTypeOnlyExport.ts | 2 +- .../codefixes/disableJsDiagnostics.ts | 2 +- .../codefixes/fixAddMissingConstraint.ts | 4 +- src/services/codefixes/fixAddMissingMember.ts | 6 +- src/services/codefixes/fixAddVoidToPromise.ts | 2 +- .../codefixes/fixAwaitInSyncFunction.ts | 2 +- src/services/codefixes/fixCannotFindModule.ts | 2 +- ...sDoesntImplementInheritedAbstractMember.ts | 2 +- .../fixClassIncorrectlyImplementsInterface.ts | 2 +- .../fixClassSuperMustPrecedeThisAccess.ts | 4 +- src/services/codefixes/fixNaNEquality.ts | 2 +- src/services/codefixes/fixOverrideModifier.ts | 2 +- src/services/codefixes/fixSpelling.ts | 4 +- src/services/codefixes/fixUnusedLabel.ts | 2 +- src/services/codefixes/importAdder.ts | 10 +- src/services/completions.ts | 8 +- src/services/documentHighlights.ts | 4 +- src/services/documentRegistry.ts | 8 +- src/services/exportInfoMap.ts | 8 +- src/services/findAllReferences.ts | 10 +- src/services/formatting/formatting.ts | 2 +- src/services/formatting/formattingScanner.ts | 2 +- src/services/formatting/smartIndenter.ts | 2 +- src/services/getEditsForFileRename.ts | 8 +- src/services/goToDefinition.ts | 6 +- src/services/importTracker.ts | 2 +- src/services/inlayHints.ts | 6 +- src/services/jsDoc.ts | 2 +- src/services/navigationBar.ts | 4 +- src/services/organizeImports.ts | 2 +- src/services/outliningElementsCollector.ts | 2 +- src/services/patternMatcher.ts | 2 +- src/services/preProcess.ts | 2 +- ...onvertArrowFunctionOrFunctionExpression.ts | 2 +- .../convertStringOrTemplateLiteral.ts | 2 +- src/services/refactors/extractSymbol.ts | 6 +- src/services/refactors/extractType.ts | 4 +- src/services/refactors/moveToNewFile.ts | 6 +- src/services/rename.ts | 2 +- src/services/services.ts | 16 +- src/services/shims.ts | 10 +- src/services/signatureHelp.ts | 4 +- src/services/smartSelection.ts | 4 +- src/services/sourcemaps.ts | 10 +- src/services/stringCompletions.ts | 18 +- src/services/suggestionDiagnostics.ts | 4 +- src/services/symbolDisplay.ts | 2 +- src/services/textChanges.ts | 8 +- src/services/transpile.ts | 8 +- src/services/types.ts | 2 +- src/services/utilities.ts | 18 +- src/testRunner/unittests/parsePseudoBigInt.ts | 2 +- .../unittests/services/textChanges.ts | 2 +- .../unittests/tsserver/exportMapCache.ts | 2 +- src/typingsInstaller/nodeTypingsInstaller.ts | 2 +- 131 files changed, 796 insertions(+), 760 deletions(-) rename src/compiler/{ => checker}/checker.ts (98%) rename src/compiler/{checkerUtilities.ts => checker/utilities.ts} (98%) rename src/compiler/{ => commandLineParser}/commandLineParser.ts (97%) rename src/compiler/{commandLineParserUtilities.ts => commandLineParser/utilities.ts} (93%) rename src/compiler/{ => emitter}/emitter.ts (97%) create mode 100644 src/compiler/emitter/utilities.ts delete mode 100644 src/compiler/emitterUtilities.ts rename src/compiler/{ => moduleNameResolver}/moduleNameResolver.ts (97%) create mode 100644 src/compiler/moduleNameResolver/utilities.ts rename src/compiler/{ => moduleSpecifiers}/moduleSpecifiers.ts (97%) rename src/compiler/{moduleSpecifiersUtilities.ts => moduleSpecifiers/utilities.ts} (93%) rename src/compiler/{ => parser}/parser.ts (97%) rename src/compiler/{parserUtilities.ts => parser/utilities.ts} (96%) delete mode 100644 src/compiler/platform.ts rename src/compiler/{ => program}/program.ts (97%) rename src/compiler/{programUtilities.ts => program/utilities.ts} (92%) rename src/compiler/{scannerKeywords.ts => scanner/keywords.ts} (96%) rename src/compiler/{ => scanner}/scanner.ts (98%) rename src/compiler/{scannerUtilities.ts => scanner/utilities.ts} (96%) rename src/compiler/{ => sys}/sys.ts (97%) rename src/compiler/{sysUtilities.ts => sys/utilities.ts} (83%) diff --git a/src/compiler/_namespaces/ts.moduleSpecifiers.ts b/src/compiler/_namespaces/ts.moduleSpecifiers.ts index 47a204d4a72b9..05575b99f27c1 100644 --- a/src/compiler/_namespaces/ts.moduleSpecifiers.ts +++ b/src/compiler/_namespaces/ts.moduleSpecifiers.ts @@ -1,3 +1,3 @@ /* Generated file to emulate the ts.moduleSpecifiers namespace. */ -export * from "../moduleSpecifiers"; +export * from "../moduleSpecifiers/moduleSpecifiers"; diff --git a/src/compiler/_namespaces/ts.ts b/src/compiler/_namespaces/ts.ts index 4c9cc2f741e5e..538e434657df3 100644 --- a/src/compiler/_namespaces/ts.ts +++ b/src/compiler/_namespaces/ts.ts @@ -8,12 +8,12 @@ export * from "../performanceCore"; export * from "../perfLogger"; export * from "../tracing"; export * from "../types"; -export * from "../sys"; -export * from "../sysUtilities"; +export * from "../sys/sys"; +export * from "../sys/utilities"; export * from "../path"; export * from "../diagnosticInformationMap.generated"; -export * from "../scanner"; -export * from "../scannerUtilities"; +export * from "../scanner/scanner"; +export * from "../scanner/utilities"; export * from "../utilitiesPublic"; export * from "../utilities"; export * from "../factory/baseNodeFactory"; @@ -25,18 +25,18 @@ export * from "../factory/emitHelpers"; export * from "../factory/nodeTests"; export * from "../factory/utilities"; export * from "../factory/utilitiesPublic"; -export * from "../parser"; -export * from "../parserUtilities"; -export * from "../commandLineParser"; -export * from "../commandLineParserUtilities"; -export * from "../moduleNameResolver"; -export * from "../moduleSpecifiersUtilities"; +export * from "../parser/parser"; +export * from "../parser/utilities"; +export * from "../commandLineParser/commandLineParser"; +export * from "../commandLineParser/utilities"; +export * from "../moduleNameResolver/moduleNameResolver"; +export * from "../moduleSpecifiers/utilities"; export * from "../objectAllocator"; export * from "../binder"; export * from "../symbolWalker"; export * from "../symlinkCache"; -export * from "../checker"; -export * from "../checkerUtilities"; +export * from "../checker/checker"; +export * from "../checker/utilities"; export * from "../visitorPublic"; export * from "../sourcemap"; export * from "../transformers/utilities"; @@ -64,9 +64,9 @@ export * from "../transformers/module/node"; export * from "../transformers/declarations/diagnostics"; export * from "../transformers/declarations"; export * from "../transformer"; -export * from "../emitter"; +export * from "../emitter/emitter"; export * from "../watchUtilities"; -export * from "../program"; +export * from "../program/program"; export * from "../builderStatePublic"; export * from "../builderState"; export * from "../builder"; diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index ffb21754b7458..83916b8045e55 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1,5 +1,5 @@ import * as Debug from "./debug"; -import { getNodeId } from "./checkerUtilities"; +import { getNodeId } from "./checker/utilities"; import { append, appendIfUnique, @@ -51,14 +51,14 @@ import { isVariableStatement, } from "./factory/nodeTests"; import { objectAllocator } from "./objectAllocator"; -import { forEachChild } from "./parser"; +import { forEachChild } from "./parser/parser"; import { setParent, setParentRecursive, -} from "./parserUtilities"; +} from "./parser/utilities"; import { perfLogger } from "./perfLogger"; import * as performance from "./performance"; -import { tokenToString } from "./scanner"; +import { tokenToString } from "./scanner/scanner"; import { tracing, TracingNode, @@ -282,7 +282,6 @@ import { isVariableDeclarationInitializedToBareOrAccessedRequire, nodeIsMissing, nodeIsPresent, - removeFileExtension, setValueDeclaration, shouldPreserveConstEnums, skipParentheses, @@ -327,6 +326,7 @@ import { symbolName, unescapeLeadingUnderscores, } from "./utilitiesPublic"; +import { removeFileExtension } from "./extension"; /** @internal */ export const enum ModuleInstanceState { diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 94d5195e9dd58..1a780f29aa9ba 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -11,7 +11,7 @@ import { BuilderState } from "./builderState"; import { convertToOptionsWithAbsolutePaths, getOptionsNameMap, -} from "./commandLineParser"; +} from "./commandLineParser/commandLineParser"; import { addRange, arrayFrom, @@ -40,8 +40,8 @@ import { ReadonlyCollection } from "./corePublic"; import { createBuildInfo, getTsBuildInfoEmitOutputFilePath, -} from "./emitter"; -import { isDeclarationFileName } from "./parser"; +} from "./emitter/emitter"; +import { isDeclarationFileName } from "./parser/parser"; import { ensurePathIsNonModuleName, getDirectoryPath, @@ -54,13 +54,13 @@ import { emitSkippedWithNoDiagnostics, filterSemanticDiagnostics, handleNoEmitOptions, -} from "./program"; +} from "./program/program"; import { compilerOptionsAffectDeclarationPath, compilerOptionsAffectEmit, compilerOptionsAffectSemanticDiagnostics, -} from "./programUtilities"; -import { generateDjb2Hash } from "./sys"; +} from "./program/utilities"; +import { generateDjb2Hash } from "./sys/sys"; import { BuildInfo, BundleBuildInfo, diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts index ecfaaee5dc90c..f0efd1fe4e770 100644 --- a/src/compiler/builderState.ts +++ b/src/compiler/builderState.ts @@ -14,7 +14,7 @@ import { some, } from "./core"; import { isStringLiteral } from "./factory/nodeTests"; -import { isDeclarationFileName } from "./parser"; +import { isDeclarationFileName } from "./parser/parser"; import { getDirectoryPath, toPath, diff --git a/src/compiler/checker.ts b/src/compiler/checker/checker.ts similarity index 98% rename from src/compiler/checker.ts rename to src/compiler/checker/checker.ts index 04aa267915cb8..fe37ec3925352 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker/checker.ts @@ -1,16 +1,16 @@ -import * as Debug from "./debug"; +import * as Debug from "../debug"; import { bindSourceFile, getModuleInstanceState, ModuleInstanceState, -} from "./binder"; +} from "../binder"; import { CheckMode, getNodeId, getSymbolId, SignatureCheckMode, TypeFacts, -} from "./checkerUtilities"; +} from "./utilities"; import { addRange, and, @@ -79,13 +79,13 @@ import { stringContains, tryAddToSet, tryCast, -} from "./core"; -import { Comparison } from "./corePublic"; -import { Diagnostics } from "./diagnosticInformationMap.generated"; -import { createPrinter } from "./emitter"; +} from "../core"; +import { Comparison } from "../corePublic"; +import { Diagnostics } from "../diagnosticInformationMap.generated"; +import { createPrinter } from "../emitter/emitter"; import { createBinaryExpressionTrampoline, -} from "./factory/binaryExpressionStateMachine"; +} from "../factory/binaryExpressionStateMachine"; import { addSyntheticLeadingComment, getIdentifierGeneratedImportReference, @@ -94,8 +94,8 @@ import { setEmitFlags, setIdentifierTypeArguments, setSyntheticLeadingComments, -} from "./factory/emitNode"; -import { factory } from "./factory/nodeFactory"; +} from "../factory/emitNode"; +import { factory } from "../factory/nodeFactory"; import { isArrayBindingPattern, isArrayLiteralExpression, @@ -217,45 +217,45 @@ import { isVariableDeclaration, isVariableDeclarationList, isVariableStatement, -} from "./factory/nodeTests"; +} from "../factory/nodeTests"; import { canHaveIllegalModifiers, createEmptyExports, createPropertyNameNodeForIdentifierOrLiteral, getJSDocTypeAssertionType, isCommaSequence, -} from "./factory/utilities"; +} from "../factory/utilities"; import { canHaveDecorators, canHaveModifiers, setOriginalNode, setTextRange, -} from "./factory/utilitiesPublic"; +} from "../factory/utilitiesPublic"; import { createModeAwareCacheKey, getTypesPackageName, mangleScopedPackageName, nodeModulesPathPart, shouldAllowImportingTsExtension, -} from "./moduleNameResolver"; +} from "../moduleNameResolver/moduleNameResolver"; import { countPathComponents, getModuleSpecifiers, -} from "./moduleSpecifiers"; -import { objectAllocator } from "./objectAllocator"; +} from "../moduleSpecifiers/moduleSpecifiers"; +import { objectAllocator } from "../objectAllocator"; import { forEachChild, forEachChildRecursively, isDeclarationFileName, parseIsolatedEntityName, parseNodeFactory, -} from "./parser"; +} from "../parser/parser"; import { containsParseError, forEachReturnStatement, forEachYieldExpression, setParent, -} from "./parserUtilities"; +} from "../parser/utilities"; import { combinePaths, comparePaths, @@ -265,28 +265,28 @@ import { getNormalizedAbsolutePath, hasExtension, pathIsRelative, -} from "./path"; -import * as performance from "./performance"; +} from "../path"; +import * as performance from "../performance"; import { getModeForUsageLocation, getResolutionDiagnostic, getResolutionModeOverrideForClause, isExclusivelyTypeOnlyImportOrExport, resolveTripleslashReference, -} from "./program"; +} from "../program/program"; import { getLineAndCharacterOfPosition, isIdentifierText, skipTrivia, tokenToString, -} from "./scanner"; -import { parsePseudoBigInt } from "./scannerUtilities"; -import { createGetSymbolWalker } from "./symbolWalker"; +} from "../scanner/scanner"; +import { parsePseudoBigInt } from "../scanner/utilities"; +import { createGetSymbolWalker } from "../symbolWalker"; import { tracing, TracingNode, -} from "./tracing"; -import { nullTransformationContext } from "./transformer"; +} from "../tracing"; +import { nullTransformationContext } from "../transformer"; import { __String, AccessExpression, @@ -680,7 +680,7 @@ import { WideningContext, WithStatement, YieldExpression, -} from "./types"; +} from "../types"; import { addRelatedInfo, arrayIsHomogeneous, @@ -789,7 +789,6 @@ import { getParameterSymbolFromJSDoc, getPropertyAssignmentAliasLikeExpression, getPropertyNameForPropertyNameNode, - getResolvedExternalModuleName, getResolvedModule, getResolveJsonModule, getRestParameterElementType, @@ -968,8 +967,6 @@ import { pseudoBigIntToString, rangeOfNode, rangeOfTypeParameters, - removeExtension, - resolutionExtensionIsTSOrJson, resolvingEmptyArray, scanTokenAtPosition, setNodeFlags, @@ -983,7 +980,6 @@ import { skipTypeChecking, stripQuotes, tryGetClassImplementingOrExtendingExpressionWithTypeArguments, - tryGetExtensionFromPath, tryGetJSDocSatisfiesTypeNode, tryGetModuleSpecifierFromDeclaration, tryGetPropertyAccessOrIdentifierToString, @@ -991,7 +987,7 @@ import { walkUpParenthesizedExpressions, walkUpParenthesizedTypes, walkUpParenthesizedTypesAndGetParentAndChild, -} from "./utilities"; +} from "../utilities"; import { canHaveLocals, canHaveSymbol, @@ -1087,13 +1083,19 @@ import { textSpanEnd, unescapeLeadingUnderscores, walkUpBindingElementsAndPatterns, -} from "./utilitiesPublic"; +} from "../utilitiesPublic"; import { visitEachChild, visitNode, visitNodes, -} from "./visitorPublic"; -import { tryExtractTSExtension } from "./extension"; +} from "../visitorPublic"; +import { + removeExtension, + resolutionExtensionIsTSOrJson, + tryExtractTSExtension, + tryGetExtensionFromPath, +} from "../extension"; +import { getResolvedExternalModuleName } from "../moduleNameResolver/utilities"; const ambientModuleSymbolRegex = /^".+"$/; const anon = "(anonymous)" as __String & string; diff --git a/src/compiler/checkerUtilities.ts b/src/compiler/checker/utilities.ts similarity index 98% rename from src/compiler/checkerUtilities.ts rename to src/compiler/checker/utilities.ts index 4e8c96179e7b4..72367903a947c 100644 --- a/src/compiler/checkerUtilities.ts +++ b/src/compiler/checker/utilities.ts @@ -2,7 +2,7 @@ import { Node, Symbol, SymbolId, -} from "./types"; +} from "../types"; let nextSymbolId = 1; let nextNodeId = 1; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser/commandLineParser.ts similarity index 97% rename from src/compiler/commandLineParser.ts rename to src/compiler/commandLineParser/commandLineParser.ts index 17933046853cb..7db1080134ff8 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser/commandLineParser.ts @@ -1,4 +1,4 @@ -import * as Debug from "./debug"; +import * as Debug from "../debug"; import { append, arrayFrom, @@ -30,26 +30,26 @@ import { stringContains, toFileNameLowerCase, trimString, -} from "./core"; +} from "../core"; import { MapLike, Push, -} from "./corePublic"; -import { Diagnostics } from "./diagnosticInformationMap.generated"; +} from "../corePublic"; +import { Diagnostics } from "../diagnosticInformationMap.generated"; import { isArrayLiteralExpression, isObjectLiteralExpression, isStringLiteral, -} from "./factory/nodeTests"; +} from "../factory/nodeTests"; import { getFileMatcherPatterns, getRegexFromPattern, getRegularExpressionForWildcard, getRegularExpressionsForWildcards, isImplicitGlob, -} from "./fileMatcher"; -import { nodeNextJsonConfigResolver } from "./moduleNameResolver"; -import { parseJsonText } from "./parser"; +} from "../fileMatcher"; +import { nodeNextJsonConfigResolver } from "../moduleNameResolver/moduleNameResolver"; +import { parseJsonText } from "../parser/parser"; import { combinePaths, containsPath, @@ -68,10 +68,10 @@ import { normalizeSlashes, removeTrailingDirectorySeparator, toPath, -} from "./path"; -import { sys } from "./sys"; -import { tracing } from "./tracing"; -import { BuildOptions } from "./tsbuildPublic"; +} from "../path"; +import { sys } from "../sys/sys"; +import { tracing } from "../tracing"; +import { BuildOptions } from "../tsbuildPublic"; import { AlternateModeDiagnostics, ArrayLiteralExpression, @@ -116,9 +116,8 @@ import { WatchDirectoryKind, WatchFileKind, WatchOptions, -} from "./types"; +} from "../types"; import { - changeExtension, createCompilerDiagnostic, createDiagnosticForNodeInSourceFile, forEachEntry, @@ -128,12 +127,13 @@ import { getTsConfigPropArrayElementValue, isComputedNonLiteralName, isStringDoubleQuoted, -} from "./utilities"; -import { unescapeLeadingUnderscores } from "./utilitiesPublic"; +} from "../utilities"; +import { unescapeLeadingUnderscores } from "../utilitiesPublic"; import { + changeExtension, getSupportedExtensions, getSupportedExtensionsWithJsonIfResolveJsonModule, -} from "./extension"; +} from "../extension"; /** @internal */ export const compileOnSaveCommandLineOption: CommandLineOption = { diff --git a/src/compiler/commandLineParserUtilities.ts b/src/compiler/commandLineParser/utilities.ts similarity index 93% rename from src/compiler/commandLineParserUtilities.ts rename to src/compiler/commandLineParser/utilities.ts index cc7181c9c97df..97e1fabe9a7b8 100644 --- a/src/compiler/commandLineParserUtilities.ts +++ b/src/compiler/commandLineParser/utilities.ts @@ -1,5 +1,5 @@ import { parseConfigFileTextToJson } from "./commandLineParser"; -import { isString } from "./core"; +import { isString } from "../core"; /** @internal */ export function readJsonOrUndefined(path: string, hostOrText: { readFile(fileName: string): string | undefined } | string): object | undefined { diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index db2e773189ecb..00a03ca6acb83 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -1,13 +1,13 @@ /* eslint-disable */ import * as types from "./types"; -import * as checkerTypes from "./checkerUtilities"; +import * as checkerTypes from "./checker/utilities"; /* eslint-enable */ import { CheckMode, SignatureCheckMode, TypeFacts, -} from "./checkerUtilities"; +} from "./checker/utilities"; import { compareValues, every, diff --git a/src/compiler/emitter.ts b/src/compiler/emitter/emitter.ts similarity index 97% rename from src/compiler/emitter.ts rename to src/compiler/emitter/emitter.ts index 890f959f2dea5..5f8894c29e7e1 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter/emitter.ts @@ -1,15 +1,15 @@ /* eslint-disable */ -import * as types from "./types"; +import * as types from "../types"; /* eslint-enable */ -import * as Debug from "./debug"; +import * as Debug from "../debug"; import { computeSignature, ProgramBuildInfo, ProgramBundleEmitBuildInfo, -} from "./builder"; -import { OutputFile } from "./builderStatePublic"; -import { getNodeId } from "./checkerUtilities"; +} from "../builder"; +import { OutputFile } from "../builderStatePublic"; +import { getNodeId } from "../checker/utilities"; import { arrayToMap, cast, @@ -38,12 +38,12 @@ import { stableSort, stringContains, tryCast, -} from "./core"; -import { Comparison, version } from "./corePublic"; +} from "../core"; +import { Comparison, version } from "../corePublic"; import { createBinaryExpressionTrampoline, -} from "./factory/binaryExpressionStateMachine"; -import { compareEmitHelpers } from "./factory/emitHelpers"; +} from "../factory/binaryExpressionStateMachine"; +import { compareEmitHelpers } from "../factory/emitHelpers"; import { getCommentRange, getConstantValue, @@ -55,11 +55,11 @@ import { getSyntheticLeadingComments, getSyntheticTrailingComments, getTypeNode, -} from "./factory/emitNode"; +} from "../factory/emitNode"; import { createInputFilesWithFileTexts, factory, -} from "./factory/nodeFactory"; +} from "../factory/nodeFactory"; import { isArrowFunction, isBinaryExpression, @@ -83,23 +83,23 @@ import { isUnparsedPrepend, isUnparsedSource, isVariableStatement, -} from "./factory/nodeTests"; +} from "../factory/nodeTests"; import { formatGeneratedName, formatGeneratedNamePart, getExternalHelpersModuleName, getNodeForGeneratedName, hasRecordedExternalHelpers, -} from "./factory/utilities"; +} from "../factory/utilities"; import { setOriginalNode, setTextRange, -} from "./factory/utilitiesPublic"; +} from "../factory/utilitiesPublic"; import { forEachChild, isDeclarationFileName, isJSDocLikeText, -} from "./parser"; +} from "../parser/parser"; import { combinePaths, comparePaths, @@ -117,12 +117,12 @@ import { normalizePath, normalizeSlashes, resolvePath, -} from "./path"; -import * as performance from "./performance"; +} from "../path"; +import * as performance from "../performance"; import { computeCommonSourceDirectoryOfFilenames, createPrependNodes, -} from "./program"; +} from "../program/program"; import { computeLineStarts, forEachLeadingCommentRange, @@ -134,20 +134,20 @@ import { getTrailingCommentRanges, skipTrivia, tokenToString, -} from "./scanner"; +} from "../scanner/scanner"; import { createSourceMapGenerator, tryParseRawSourceMap, -} from "./sourcemap"; -import { sys } from "./sys"; -import { tracing } from "./tracing"; +} from "../sourcemap"; +import { sys } from "../sys/sys"; +import { tracing } from "../tracing"; import { getTransformers, noEmitNotification, noEmitSubstitution, transformNodes, -} from "./transformer"; -import { isInternalDeclaration } from "./transformers/declarations"; +} from "../transformer"; +import { isInternalDeclaration } from "../transformers/declarations"; import { AccessorDeclaration, ArrayBindingPattern, @@ -401,10 +401,9 @@ import { WithStatement, WriteFileCallbackData, YieldExpression, -} from "./types"; +} from "../types"; import { base64encode, - changeExtension, createDiagnosticCollection, createTextWriter, emitDetachedComments, @@ -415,8 +414,6 @@ import { escapeString, getAreDeclarationMapsEnabled, getContainingNodeArray, - getDeclarationEmitExtensionForPath, - getDeclarationEmitOutputFilePath, getEmitDeclarations, getEmitFlags, getEmitModuleKind, @@ -426,9 +423,7 @@ import { getLinesBetweenRangeEndAndRangeStart, getLiteralText, GetLiteralTextFlags, - getOwnEmitOutputFilePath, getSourceFileOfNode, - getSourceFilePathInNewDir, getSourceTextOfNodeFromSourceFile, getTrailingSemicolonDeferringWriter, isAccessExpression, @@ -453,12 +448,11 @@ import { rangeEndPositionsAreOnSameLine, rangeIsOnSingleLine, rangeStartPositionsAreOnSameLine, - removeFileExtension, setTextRangePosEnd, setTextRangePosWidth, writeCommentRange, writeFile, -} from "./utilities"; +} from "../utilities"; import { canHaveLocals, escapeLeadingUnderscores, @@ -480,13 +474,26 @@ import { isTokenKind, isUnparsedNode, skipPartiallyEmittedExpressions, -} from "./utilitiesPublic"; -import { positionIsSynthesized } from "./scannerUtilities"; -import { getNewLineCharacter } from "./sysUtilities"; -import { getSourceFilesToEmit } from "./emitterUtilities"; -import { setEachParent, setParent } from "./parserUtilities"; -import { readJsonOrUndefined } from "./commandLineParserUtilities"; -import { supportedJSExtensionsFlat } from "./extension"; +} from "../utilitiesPublic"; +import { positionIsSynthesized } from "../scanner/utilities"; +import { getNewLineCharacter } from "../sys/utilities"; +import { + getDeclarationEmitOutputFilePath, + getOwnEmitOutputFilePath, + getSourceFilePathInNewDir, + getSourceFilesToEmit, +} from "./utilities"; +import { + setEachParent, + setParent, +} from "../parser/utilities"; +import { readJsonOrUndefined } from "../commandLineParser/utilities"; +import { + changeExtension, + getDeclarationEmitExtensionForPath, + removeFileExtension, + supportedJSExtensionsFlat, +} from "../extension"; const brackets = createBracketsMap(); diff --git a/src/compiler/emitter/utilities.ts b/src/compiler/emitter/utilities.ts new file mode 100644 index 0000000000000..b9ca360715df7 --- /dev/null +++ b/src/compiler/emitter/utilities.ts @@ -0,0 +1,100 @@ +import { + filter, + GetCanonicalFileName, +} from "../core"; +import { + getDeclarationEmitExtensionForPath, + removeFileExtension, +} from "../extension"; +import { + combinePaths, + getNormalizedAbsolutePath, +} from "../path"; +import { + CompilerOptions, + EmitHost, + ModuleKind, + SourceFile, +} from "../types"; +import { + getEmitModuleKind, + isExternalModule, + outFile, + sourceFileMayBeEmitted, +} from "../utilities"; + +/** + * Gets the source files that are expected to have an emit output. + * + * Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support + * transformations. + * + * @param host An EmitHost. + * @param targetSourceFile An optional target source file to emit. + * + * @internal + */ +export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile, forceDtsEmit?: boolean): readonly SourceFile[] { + const options = host.getCompilerOptions(); + if (outFile(options)) { + const moduleKind = getEmitModuleKind(options); + const moduleEmitEnabled = options.emitDeclarationOnly || moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.System; + // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified + return filter( + host.getSourceFiles(), + sourceFile => + (moduleEmitEnabled || !isExternalModule(sourceFile)) && + sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit) + ); + } + else { + const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile]; + return filter( + sourceFiles, + sourceFile => sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit) + ); + } +} + +/** @internal */ +export function getDeclarationEmitOutputFilePath(fileName: string, host: EmitHost) { + return getDeclarationEmitOutputFilePathWorker(fileName, host.getCompilerOptions(), host.getCurrentDirectory(), host.getCommonSourceDirectory(), f => host.getCanonicalFileName(f)); +} + +/** @internal */ +export function getDeclarationEmitOutputFilePathWorker(fileName: string, options: CompilerOptions, currentDirectory: string, commonSourceDirectory: string, getCanonicalFileName: GetCanonicalFileName): string { + const outputDir = options.declarationDir || options.outDir; // Prefer declaration folder if specified + + const path = outputDir + ? getSourceFilePathInNewDirWorker(fileName, outputDir, currentDirectory, commonSourceDirectory, getCanonicalFileName) + : fileName; + const declarationExtension = getDeclarationEmitExtensionForPath(path); + return removeFileExtension(path) + declarationExtension; +} + +/** @internal */ +export function getSourceFilePathInNewDir(fileName: string, host: EmitHost, newDirPath: string): string { + return getSourceFilePathInNewDirWorker(fileName, newDirPath, host.getCurrentDirectory(), host.getCommonSourceDirectory(), f => host.getCanonicalFileName(f)); +} + +/** @internal */ +export function getSourceFilePathInNewDirWorker(fileName: string, newDirPath: string, currentDirectory: string, commonSourceDirectory: string, getCanonicalFileName: GetCanonicalFileName): string { + let sourceFilePath = getNormalizedAbsolutePath(fileName, currentDirectory); + const isSourceFileInCommonSourceDirectory = getCanonicalFileName(sourceFilePath).indexOf(getCanonicalFileName(commonSourceDirectory)) === 0; + sourceFilePath = isSourceFileInCommonSourceDirectory ? sourceFilePath.substring(commonSourceDirectory.length) : sourceFilePath; + return combinePaths(newDirPath, sourceFilePath); +} + +/** @internal */ +export function getOwnEmitOutputFilePath(fileName: string, host: EmitHost, extension: string) { + const compilerOptions = host.getCompilerOptions(); + let emitOutputFilePathWithoutExtension: string; + if (compilerOptions.outDir) { + emitOutputFilePathWithoutExtension = removeFileExtension(getSourceFilePathInNewDir(fileName, host, compilerOptions.outDir)); + } + else { + emitOutputFilePathWithoutExtension = removeFileExtension(fileName); + } + + return emitOutputFilePathWithoutExtension + extension; +} diff --git a/src/compiler/emitterUtilities.ts b/src/compiler/emitterUtilities.ts deleted file mode 100644 index 0a79870eb8291..0000000000000 --- a/src/compiler/emitterUtilities.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { filter } from "./core"; -import { - EmitHost, - ModuleKind, - SourceFile, -} from "./types"; -import { - getEmitModuleKind, - isExternalModule, - outFile, - sourceFileMayBeEmitted, -} from "./utilities"; - -/** - * Gets the source files that are expected to have an emit output. - * - * Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support - * transformations. - * - * @param host An EmitHost. - * @param targetSourceFile An optional target source file to emit. - * - * @internal - */ -export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile, forceDtsEmit?: boolean): readonly SourceFile[] { - const options = host.getCompilerOptions(); - if (outFile(options)) { - const moduleKind = getEmitModuleKind(options); - const moduleEmitEnabled = options.emitDeclarationOnly || moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.System; - // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified - return filter( - host.getSourceFiles(), - sourceFile => - (moduleEmitEnabled || !isExternalModule(sourceFile)) && - sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit) - ); - } - else { - const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile]; - return filter( - sourceFiles, - sourceFile => sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit) - ); - } -} diff --git a/src/compiler/extension.ts b/src/compiler/extension.ts index c8daeae1312e4..92a481623c69e 100644 --- a/src/compiler/extension.ts +++ b/src/compiler/extension.ts @@ -1,16 +1,22 @@ +import * as Debug from "./debug"; import { + endsWith, find, flatten, mapDefined, some, + startsWith, } from "./core"; import { + changeAnyExtension, fileExtensionIs, + fileExtensionIsOneOf, } from "./path"; import { CompilerOptions, Extension, FileExtensionInfo, + Path, ScriptKind, } from "./types"; import { @@ -56,6 +62,8 @@ export const supportedDeclarationExtensions: readonly Extension[] = [Extension.D /** @internal */ export const supportedTSImplementationExtensions: readonly Extension[] = [Extension.Ts, Extension.Cts, Extension.Mts, Extension.Tsx]; +const extensionsToRemove = [Extension.Dts, Extension.Dmts, Extension.Dcts, Extension.Mjs, Extension.Mts, Extension.Cjs, Extension.Cts, Extension.Ts, Extension.Js, Extension.Tsx, Extension.Jsx, Extension.Json]; + /** * Return ".ts", ".d.ts", or ".tsx", if that is the extension. * @@ -108,3 +116,84 @@ export function hasJSFileExtension(fileName: string): boolean { export function hasTSFileExtension(fileName: string): boolean { return some(supportedTSExtensionsFlat, extension => fileExtensionIs(fileName, extension)); } + +/** @internal */ +export function getDeclarationEmitExtensionForPath(path: string) { + return fileExtensionIsOneOf(path, [Extension.Mjs, Extension.Mts]) ? Extension.Dmts : + fileExtensionIsOneOf(path, [Extension.Cjs, Extension.Cts]) ? Extension.Dcts : + fileExtensionIsOneOf(path, [Extension.Json]) ? `.d.json.ts` : // Drive-by redefinition of json declaration file output name so if it's ever enabled, it behaves well + Extension.Dts; +} + +/** + * This function is an inverse of `getDeclarationEmitExtensionForPath`. + * + * @internal + */ +export function getPossibleOriginalInputExtensionForExtension(path: string) { + return fileExtensionIsOneOf(path, [Extension.Dmts, Extension.Mjs, Extension.Mts]) ? [Extension.Mts, Extension.Mjs] : + fileExtensionIsOneOf(path, [Extension.Dcts, Extension.Cjs, Extension.Cts]) ? [Extension.Cts, Extension.Cjs]: + fileExtensionIsOneOf(path, [`.d.json.ts`]) ? [Extension.Json] : + [Extension.Tsx, Extension.Ts, Extension.Jsx, Extension.Js]; +} + +/** @internal */ +export function removeFileExtension(path: string): string { + for (const ext of extensionsToRemove) { + const extensionless = tryRemoveExtension(path, ext); + if (extensionless !== undefined) { + return extensionless; + } + } + return path; +} + +/** @internal */ +export function tryRemoveExtension(path: string, extension: string): string | undefined { + return fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined; +} + +/** @internal */ +export function removeExtension(path: string, extension: string): string { + return path.substring(0, path.length - extension.length); +} + +/** @internal */ +export function changeExtension(path: T, newExtension: string): T { + return changeAnyExtension(path, newExtension, extensionsToRemove, /*ignoreCase*/ false) as T; +} + +/** + * True if an extension is one of the supported TypeScript extensions. + * + * @internal + */ +export function extensionIsTS(ext: string): boolean { + return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts || ext === Extension.Cts || ext === Extension.Mts || ext === Extension.Dmts || ext === Extension.Dcts || (startsWith(ext, ".d.") && endsWith(ext, ".ts")); +} + +/** @internal */ +export function resolutionExtensionIsTSOrJson(ext: string) { + return extensionIsTS(ext) || ext === Extension.Json; +} + +/** + * Gets the extension from a path. + * Path must have a valid extension. + * + * @internal + */ +export function extensionFromPath(path: string): Extension { + const ext = tryGetExtensionFromPath(path); + return ext !== undefined ? ext : Debug.fail(`File ${path} has unknown extension.`); +} + +/** @internal */ +export function isAnySupportedFileExtension(path: string): boolean { + return tryGetExtensionFromPath(path) !== undefined; +} + +/** @internal */ +export function tryGetExtensionFromPath(path: string): Extension | undefined { + return find(extensionsToRemove, e => fileExtensionIs(path, e)); +} diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 9ea515aca1363..03fbd65dadd45 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -1,5 +1,5 @@ import * as Debug from "../debug"; -import { getNodeId } from "../checkerUtilities"; +import { getNodeId } from "../checker/utilities"; import { addRange, append, @@ -22,16 +22,19 @@ import { startsWith, } from "../core"; import { Push } from "../corePublic"; -import { getBuildInfo } from "../emitter"; +import { getBuildInfo } from "../emitter/emitter"; import { objectAllocator } from "../objectAllocator"; -import { parseNodeFactory } from "../parser"; -import { setEachParent, setParent } from "../parserUtilities"; +import { parseNodeFactory } from "../parser/parser"; +import { + setEachParent, + setParent, +} from "../parser/utilities"; import { createScanner, getLineAndCharacterOfPosition, Scanner, stringToToken, -} from "../scanner"; +} from "../scanner/scanner"; import { __String, ArrayBindingElement, diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index 8d2729ef87a8e..73d398e47df8e 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -7,9 +7,9 @@ import { pushIfUnique, some, } from "../core"; -import { parseNodeFactory } from "../parser"; -import { setParent } from "../parserUtilities"; -import { isIdentifierText } from "../scanner"; +import { parseNodeFactory } from "../parser/parser"; +import { setParent } from "../parser/utilities"; +import { isIdentifierText } from "../scanner/scanner"; import { AccessorDeclaration, AdditiveOperator, @@ -111,7 +111,6 @@ import { getEmitModuleKind, getESModuleInterop, getExternalModuleName, - getExternalModuleNameFromPath, getNamespaceDeclarationNode, getSourceTextOfNodeFromSourceFile, isAssignmentExpression, @@ -171,6 +170,7 @@ import { setOriginalNode, setTextRange, } from "./utilitiesPublic"; +import { getExternalModuleNameFromPath } from "../moduleNameResolver/utilities"; // Compound nodes diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver/moduleNameResolver.ts similarity index 97% rename from src/compiler/moduleNameResolver.ts rename to src/compiler/moduleNameResolver/moduleNameResolver.ts index e3b7743a3ee5f..194eea5eeb7b0 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver/moduleNameResolver.ts @@ -1,6 +1,9 @@ -import * as Debug from "./debug"; -import { DiagnosticReporter, moduleResolutionOptionDeclarations } from "./commandLineParser"; -import { readJson } from "./commandLineParserUtilities"; +import * as Debug from "../debug"; +import { + DiagnosticReporter, + moduleResolutionOptionDeclarations, +} from "../commandLineParser/commandLineParser"; +import { readJson } from "../commandLineParser/utilities"; import { append, appendIfUnique, @@ -32,17 +35,17 @@ import { sort, startsWith, stringContains, -} from "./core"; +} from "../core"; import { Comparison, MapLike, Push, version, versionMajorMinor, -} from "./corePublic"; -import { Diagnostics } from "./diagnosticInformationMap.generated"; -import { getCommonSourceDirectory } from "./emitter"; -import { isDeclarationFileName } from "./parser"; +} from "../corePublic"; +import { Diagnostics } from "../diagnosticInformationMap.generated"; +import { getCommonSourceDirectory } from "../emitter/emitter"; +import { isDeclarationFileName } from "../parser/parser"; import { changeAnyExtension, combinePaths, @@ -66,12 +69,12 @@ import { normalizeSlashes, pathIsRelative, toPath, -} from "./path"; -import { perfLogger } from "./perfLogger"; +} from "../path"; +import { perfLogger } from "../perfLogger"; import { Version, VersionRange, -} from "./semver"; +} from "../semver"; import { CharacterCodes, CommandLineOption, @@ -93,34 +96,34 @@ import { ResolvedTypeReferenceDirective, ResolvedTypeReferenceDirectiveWithFailedLookupLocations, SourceFile, -} from "./types"; +} from "../types"; import { createCompilerDiagnostic, directoryProbablyExists, - extensionIsTS, formatMessage, getCompilerOptionValue, getEmitModuleKind, getEmitModuleResolutionKind, getPathsBasePath, - getPossibleOriginalInputExtensionForExtension, getResolveJsonModule, hostGetCanonicalFileName, matchPatternOrExact, packageIdToString, - removeExtension, - removeFileExtension, - tryGetExtensionFromPath, tryParsePatterns, -} from "./utilities"; +} from "../utilities"; import { isExternalModuleNameRelative, -} from "./utilitiesPublic"; +} from "../utilitiesPublic"; import { + extensionIsTS, + getPossibleOriginalInputExtensionForExtension, + removeExtension, + removeFileExtension, supportedDeclarationExtensions, supportedTSImplementationExtensions, tryExtractTSExtension, -} from "./extension"; + tryGetExtensionFromPath, +} from "../extension"; /** @internal */ export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void; diff --git a/src/compiler/moduleNameResolver/utilities.ts b/src/compiler/moduleNameResolver/utilities.ts new file mode 100644 index 0000000000000..7d61edf6ee710 --- /dev/null +++ b/src/compiler/moduleNameResolver/utilities.ts @@ -0,0 +1,66 @@ +import { removeFileExtension } from "../extension"; +import { + ensurePathIsNonModuleName, + ensureTrailingDirectorySeparator, + getDirectoryPath, + getNormalizedAbsolutePath, + getRelativePathToDirectoryOrUrl, + pathIsRelative, + toPath, +} from "../path"; +import { + EmitResolver, + ExportDeclaration, + ImportDeclaration, + ImportEqualsDeclaration, + ImportTypeNode, + ModuleDeclaration, + SourceFile, +} from "../types"; +import { getExternalModuleName } from "../utilities"; +import { isStringLiteralLike } from "../utilitiesPublic"; + +/** @internal */ +export interface ResolveModuleNameResolutionHost { + getCanonicalFileName(p: string): string; + getCommonSourceDirectory(): string; + getCurrentDirectory(): string; +} + +/** @internal */ +export function getResolvedExternalModuleName(host: ResolveModuleNameResolutionHost, file: SourceFile, referenceFile?: SourceFile): string { + return file.moduleName || getExternalModuleNameFromPath(host, file.fileName, referenceFile && referenceFile.fileName); +} + +function getCanonicalAbsolutePath(host: ResolveModuleNameResolutionHost, path: string) { + return host.getCanonicalFileName(getNormalizedAbsolutePath(path, host.getCurrentDirectory())); +} + +/** @internal */ +export function getExternalModuleNameFromDeclaration(host: ResolveModuleNameResolutionHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode): string | undefined { + const file = resolver.getExternalModuleFileFromDeclaration(declaration); + if (!file || file.isDeclarationFile) { + return undefined; + } + // If the declaration already uses a non-relative name, and is outside the common source directory, continue to use it + const specifier = getExternalModuleName(declaration); + if (specifier && isStringLiteralLike(specifier) && !pathIsRelative(specifier.text) && + getCanonicalAbsolutePath(host, file.path).indexOf(getCanonicalAbsolutePath(host, ensureTrailingDirectorySeparator(host.getCommonSourceDirectory()))) === -1) { + return undefined; + } + return getResolvedExternalModuleName(host, file); +} + +/** + * Resolves a local path to a path which is absolute to the base of the emit + * + * @internal + */ +export function getExternalModuleNameFromPath(host: ResolveModuleNameResolutionHost, fileName: string, referencePath?: string): string { + const getCanonicalFileName = (f: string) => host.getCanonicalFileName(f); + const dir = toPath(referencePath ? getDirectoryPath(referencePath) : host.getCommonSourceDirectory(), host.getCurrentDirectory(), getCanonicalFileName); + const filePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory()); + const relativePath = getRelativePathToDirectoryOrUrl(dir, filePath, dir, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); + const extensionless = removeFileExtension(relativePath); + return referencePath ? ensurePathIsNonModuleName(extensionless) : extensionless; +} diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers/moduleSpecifiers.ts similarity index 97% rename from src/compiler/moduleSpecifiers.ts rename to src/compiler/moduleSpecifiers/moduleSpecifiers.ts index d52fc897c699d..84f4ba748b284 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers/moduleSpecifiers.ts @@ -1,4 +1,4 @@ -import * as Debug from "./debug"; +import * as Debug from "../debug"; import { append, arrayFrom, @@ -21,16 +21,16 @@ import { some, startsWith, stringContains, -} from "./core"; +} from "../core"; import { Comparison, MapLike, -} from "./corePublic"; +} from "../corePublic"; import { isModuleBlock, isModuleDeclaration, isSourceFile, -} from "./factory/nodeTests"; +} from "../factory/nodeTests"; import { allKeysStartWithDot, getPackageJsonTypesVersionsPaths, @@ -38,13 +38,13 @@ import { isApplicableVersionedTypesKey, pathContainsNodeModules, shouldAllowImportingTsExtension, -} from "./moduleNameResolver"; +} from "../moduleNameResolver/moduleNameResolver"; import { getModuleSpecifierEndingPreference, getNodeModulePathParts, NodeModulePathParts, -} from "./moduleSpecifiersUtilities"; -import { isDeclarationFileName } from "./parser"; +} from "./utilities"; +import { isDeclarationFileName } from "../parser/parser"; import { combinePaths, comparePaths, @@ -66,12 +66,12 @@ import { resolvePath, startsWithDirectory, toPath, -} from "./path"; +} from "../path"; import { getModeForResolutionAtIndex, getModuleNameStringLiteralAt, -} from "./program"; -import { containsIgnoredPath } from "./sysUtilities"; +} from "../program/program"; +import { containsIgnoredPath } from "../sys/utilities"; import { __String, AmbientModuleDeclaration, @@ -100,10 +100,9 @@ import { SymbolFlags, TypeChecker, UserPreferences, -} from "./types"; +} from "../types"; import { compareNumberOfDirectorySeparators, - extensionFromPath, getEmitModuleResolutionKind, getPathsBasePath, getSourceFileOfModule, @@ -114,17 +113,18 @@ import { isNonGlobalAmbientModule, matchPatternOrExact, ModuleSpecifierEnding, - removeExtension, - removeFileExtension, - tryGetExtensionFromPath, tryParsePatterns, -} from "./utilities"; -import { isExternalModuleNameRelative } from "./utilitiesPublic"; +} from "../utilities"; +import { isExternalModuleNameRelative } from "../utilitiesPublic"; import { + extensionFromPath, getSupportedExtensions, hasJSFileExtension, hasTSFileExtension, -} from "./extension"; + removeExtension, + removeFileExtension, + tryGetExtensionFromPath, +} from "../extension"; // Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers. diff --git a/src/compiler/moduleSpecifiersUtilities.ts b/src/compiler/moduleSpecifiers/utilities.ts similarity index 93% rename from src/compiler/moduleSpecifiersUtilities.ts rename to src/compiler/moduleSpecifiers/utilities.ts index aed9aba7bd45e..5ce0699907193 100644 --- a/src/compiler/moduleSpecifiersUtilities.ts +++ b/src/compiler/moduleSpecifiers/utilities.ts @@ -4,17 +4,17 @@ import { emptyArray, firstDefined, or, -} from "./core"; +} from "../core"; import { hasJSFileExtension, hasTSFileExtension, -} from "./extension"; -import { isExpressionStatement } from "./factory/nodeTests"; +} from "../extension"; +import { isExpressionStatement } from "../factory/nodeTests"; import { nodeModulesPathPart, shouldAllowImportingTsExtension, -} from "./moduleNameResolver"; -import { pathIsRelative } from "./path"; +} from "../moduleNameResolver/moduleNameResolver"; +import { pathIsRelative } from "../path"; import { CompilerOptions, ModuleKind, @@ -22,13 +22,13 @@ import { ResolutionMode, SourceFile, UserPreferences, -} from "./types"; +} from "../types"; import { isRequireCall, isRequireVariableStatement, isSourceFileJS, ModuleSpecifierEnding, -} from "./utilities"; +} from "../utilities"; /** @internal */ export interface NodeModulePathParts { diff --git a/src/compiler/parser.ts b/src/compiler/parser/parser.ts similarity index 97% rename from src/compiler/parser.ts rename to src/compiler/parser/parser.ts index 376621a2882c2..87058b12d1547 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser/parser.ts @@ -1,5 +1,5 @@ -import * as Debug from "./debug"; -import { convertToObjectWorker } from "./commandLineParser"; +import * as Debug from "../debug"; +import { convertToObjectWorker } from "../commandLineParser/commandLineParser"; import { addRange, append, @@ -19,13 +19,13 @@ import { stringContains, toArray, trimString, -} from "./core"; -import { Diagnostics } from "./diagnosticInformationMap.generated"; -import { BaseNodeFactory } from "./factory/baseNodeFactory"; +} from "../core"; +import { Diagnostics } from "../diagnosticInformationMap.generated"; +import { BaseNodeFactory } from "../factory/baseNodeFactory"; import { createNodeFactory, NodeFactoryFlags, -} from "./factory/nodeFactory"; +} from "../factory/nodeFactory"; import { isAsyncModifier, isExportAssignment, @@ -49,27 +49,27 @@ import { isSetAccessorDeclaration, isTaggedTemplateExpression, isTypeReferenceNode, -} from "./factory/nodeTests"; +} from "../factory/nodeTests"; import { canHaveModifiers, setTextRange, -} from "./factory/utilitiesPublic"; -import { PackageJsonInfo } from "./moduleNameResolver"; -import { objectAllocator } from "./objectAllocator"; +} from "../factory/utilitiesPublic"; +import { PackageJsonInfo } from "../moduleNameResolver/moduleNameResolver"; +import { objectAllocator } from "../objectAllocator"; import { containsParseError, getLastChild, setParent, setParentRecursive, -} from "./parserUtilities"; +} from "./utilities"; import { fileExtensionIs, fileExtensionIsOneOf, getBaseFileName, normalizePath, -} from "./path"; -import { perfLogger } from "./perfLogger"; -import * as performance from "./performance"; +} from "../path"; +import { perfLogger } from "../perfLogger"; +import * as performance from "../performance"; import { createScanner, getLeadingCommentRanges, @@ -78,9 +78,9 @@ import { tokenIsIdentifierOrKeyword, tokenIsIdentifierOrKeywordOrGreaterThan, tokenToString, -} from "./scanner"; -import { textToKeywordObj } from "./scannerKeywords"; -import { tracing } from "./tracing"; +} from "../scanner/scanner"; +import { textToKeywordObj } from "../scanner/keywords"; +import { tracing } from "../tracing"; import { AccessorDeclaration, ArrayBindingElement, @@ -370,7 +370,7 @@ import { WhileStatement, WithStatement, YieldExpression, -} from "./types"; +} from "../types"; import { addRelatedInfo, attachFileToDiagnostics, @@ -393,7 +393,7 @@ import { setTextRangePos, setTextRangePosEnd, setTextRangePosWidth, -} from "./utilities"; +} from "../utilities"; import { createTextChangeRange, createTextSpanFromBounds, @@ -407,8 +407,8 @@ import { textChangeRangeIsUnchanged, textChangeRangeNewSpan, textSpanEnd, -} from "./utilitiesPublic"; -import { supportedDeclarationExtensions } from "./extension"; +} from "../utilitiesPublic"; +import { supportedDeclarationExtensions } from "../extension"; const enum SignatureFlags { None = 0, diff --git a/src/compiler/parserUtilities.ts b/src/compiler/parser/utilities.ts similarity index 96% rename from src/compiler/parserUtilities.ts rename to src/compiler/parser/utilities.ts index 8ef8f06349c76..664b78c8a0b6e 100644 --- a/src/compiler/parserUtilities.ts +++ b/src/compiler/parser/utilities.ts @@ -11,16 +11,16 @@ import { Statement, SyntaxKind, YieldExpression, -} from "./types"; +} from "../types"; import { isPartOfTypeNode, nodeIsPresent, -} from "./utilities"; +} from "../utilities"; import { hasJSDocNodes, isFunctionLike, isJSDocNode, -} from "./utilitiesPublic"; +} from "../utilitiesPublic"; function aggregateChildData(node: Node): void { if (!(node.flags & NodeFlags.HasAggregatedChildData)) { diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index fac05a9ea6272..6d7d368dcb9b1 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -1,4 +1,4 @@ -import { isNodeLikeSystem } from "./platform"; +import { isNodeLikeSystem } from "./sys/platform"; // The following definitions provide the minimum compatible support for the Web Performance User Timings API // between browsers and NodeJS: diff --git a/src/compiler/platform.ts b/src/compiler/platform.ts deleted file mode 100644 index 5099976084b91..0000000000000 --- a/src/compiler/platform.ts +++ /dev/null @@ -1,15 +0,0 @@ -declare const process: any; - -/** @internal */ -export function isNodeLikeSystem(): boolean { - // This is defined here rather than in sys.ts to prevent a cycle from its - // use in performanceCore.ts. - // - // We don't use the presence of `require` to check if we are in Node; - // when bundled using esbuild, this function will be rewritten to `__require` - // and definitely exist. - return typeof process !== "undefined" - && process.nextTick - && !process.browser - && typeof module === "object"; -} diff --git a/src/compiler/program.ts b/src/compiler/program/program.ts similarity index 97% rename from src/compiler/program.ts rename to src/compiler/program/program.ts index b137d72866de2..f8d849a141439 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program/program.ts @@ -1,6 +1,6 @@ -import * as Debug from "./debug"; -import { BuilderProgram } from "./builderPublic"; -import { createTypeChecker } from "./checker"; +import * as Debug from "../debug"; +import { BuilderProgram } from "../builderPublic"; +import { createTypeChecker } from "../checker/checker"; import { DiagnosticReporter, inverseJsxOptionMap, @@ -10,7 +10,7 @@ import { parseJsonSourceFileConfigFileContent, sourceFileAffectingCompilerOptions, targetOptionDeclaration, -} from "./commandLineParser"; +} from "../commandLineParser/commandLineParser"; import { addRange, append, @@ -55,13 +55,13 @@ import { stringContains, toFileNameLowerCase, trimStringEnd, -} from "./core"; +} from "../core"; import { Comparison, SortedReadonlyArray, versionMajorMinor, -} from "./corePublic"; -import { Diagnostics } from "./diagnosticInformationMap.generated"; +} from "../corePublic"; +import { Diagnostics } from "../diagnosticInformationMap.generated"; import { emitFiles, forEachEmittedFile, @@ -72,12 +72,12 @@ import { getTsBuildInfoEmitOutputFilePath, isBuildInfoFile, notImplementedResolver, -} from "./emitter"; -import { addEmitFlags } from "./factory/emitNode"; +} from "../emitter/emitter"; +import { addEmitFlags } from "../factory/emitNode"; import { createInputFilesWithFilePaths, factory, -} from "./factory/nodeFactory"; +} from "../factory/nodeFactory"; import { isArrayLiteralExpression, isDecorator, @@ -90,8 +90,8 @@ import { isModuleDeclaration, isObjectLiteralExpression, isStringLiteral, -} from "./factory/nodeTests"; -import { canHaveModifiers } from "./factory/utilitiesPublic"; +} from "../factory/nodeTests"; +import { canHaveModifiers } from "../factory/utilitiesPublic"; import { createModeAwareCache, createModeAwareCacheKey, @@ -111,7 +111,7 @@ import { trace, TypeReferenceDirectiveResolutionCache, zipToModeAwareCache, -} from "./moduleNameResolver"; +} from "../moduleNameResolver/moduleNameResolver"; import { createSourceFile, CreateSourceFileOptions, @@ -121,8 +121,11 @@ import { isFileProbablyExternalModule, parseIsolatedEntityName, parseNodeFactory, -} from "./parser"; -import { setParent, setParentRecursive } from "./parserUtilities"; +} from "../parser/parser"; +import { + setParent, + setParentRecursive, +} from "../parser/utilities"; import { combinePaths, comparePaths, @@ -146,15 +149,15 @@ import { pathIsAbsolute, pathIsRelative, toPath, -} from "./path"; -import * as performance from "./performance"; +} from "../path"; +import * as performance from "../performance"; import { changesAffectingProgramStructure, changesAffectModuleResolution, hasChangesInResolutions, setResolvedModule, setResolvedTypeReferenceDirective, -} from "./programUtilities"; +} from "./utilities"; import { computeLineAndCharacterOfPosition, getLineAndCharacterOfPosition, @@ -163,23 +166,23 @@ import { isIdentifierText, skipTrivia, tokenToString, -} from "./scanner"; +} from "../scanner/scanner"; import { createSymlinkCache, SymlinkCache, -} from "./symlinkCache"; -import { sys } from "./sys"; +} from "../symlinkCache"; +import { sys } from "../sys/sys"; import { containsIgnoredPath, getNewLineCharacter, -} from "./sysUtilities"; -import { tracing } from "./tracing"; +} from "../sys/utilities"; +import { tracing } from "../tracing"; import { getTransformers, noTransformers, -} from "./transformer"; -import { getDeclarationDiagnostics } from "./transformers/declarations"; -import { resolveConfigFileProjectName } from "./tsbuild"; +} from "../transformer"; +import { getDeclarationDiagnostics } from "../transformers/declarations"; +import { resolveConfigFileProjectName } from "../tsbuild"; import { __String, AsExpression, @@ -273,10 +276,9 @@ import { VariableStatement, WriteFileCallback, WriteFileCallbackData, -} from "./types"; +} from "../types"; import { chainDiagnosticMessages, - changeExtension, compareDataObjects, createCommentDirectivesMap, createCompilerDiagnostic, @@ -286,7 +288,6 @@ import { createDiagnosticForRange, createFileDiagnostic, createFileDiagnosticFromMessageChain, - extensionFromPath, externalHelpersModuleNameText, forEachEntry, forEachKey, @@ -330,14 +331,12 @@ import { packageIdToPackageName, packageIdToString, projectReferenceIsEqualTo, - removeFileExtension, - resolutionExtensionIsTSOrJson, skipTypeChecking, sourceFileMayBeEmitted, typeDirectiveIsEqualTo, walkUpParenthesizedExpressions, writeFileEnsuringDirectories, -} from "./utilities"; +} from "../utilities"; import { getDefaultLibFileName, hasJSDocNodes, @@ -346,21 +345,25 @@ import { isModifier, isStringLiteralLike, sortAndDeduplicateDiagnostics, -} from "./utilitiesPublic"; +} from "../utilitiesPublic"; import { explainIfFileIsRedirectAndImpliedFormat, fileIncludeReasonToDiagnostics, getMatchedFileSpec, getMatchedIncludeSpec, -} from "./watch"; -import { ProgramHost } from "./watchPublic"; -import { DirectoryStructureHost } from "./watchUtilities"; +} from "../watch"; +import { ProgramHost } from "../watchPublic"; +import { DirectoryStructureHost } from "../watchUtilities"; import { + changeExtension, + extensionFromPath, getSupportedExtensions, getSupportedExtensionsWithJsonIfResolveJsonModule, hasJSFileExtension, + removeFileExtension, + resolutionExtensionIsTSOrJson, supportedJSExtensionsFlat, -} from "./extension"; +} from "../extension"; export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string | undefined { return forEachAncestorDirectory(searchPath, ancestor => { diff --git a/src/compiler/programUtilities.ts b/src/compiler/program/utilities.ts similarity index 92% rename from src/compiler/programUtilities.ts rename to src/compiler/program/utilities.ts index 6aa4b9db4fb63..4f53a9417bb29 100644 --- a/src/compiler/programUtilities.ts +++ b/src/compiler/program/utilities.ts @@ -1,15 +1,15 @@ -import * as Debug from "./debug"; +import * as Debug from "../debug"; import { affectsDeclarationPathOptionDeclarations, affectsEmitOptionDeclarations, moduleResolutionOptionDeclarations, optionsAffectingProgramStructure, semanticDiagnosticsOptionDeclarations, -} from "./commandLineParser"; +} from "../commandLineParser/commandLineParser"; import { createModeAwareCache, ModeAwareCache, -} from "./moduleNameResolver"; +} from "../moduleNameResolver/moduleNameResolver"; import { CompilerOptions, ResolutionMode, @@ -17,8 +17,8 @@ import { ResolvedModuleWithFailedLookupLocations, ResolvedTypeReferenceDirectiveWithFailedLookupLocations, SourceFile, -} from "./types"; -import { optionsHaveChanges } from "./utilities"; +} from "../types"; +import { optionsHaveChanges } from "../utilities"; /** @internal */ export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModuleWithFailedLookupLocations, mode: ResolutionMode): void { diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index 719015899c1f8..5ac4da654627c 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -28,7 +28,7 @@ import { resolveModuleName, trace, updateResolutionField, -} from "./moduleNameResolver"; +} from "./moduleNameResolver/moduleNameResolver"; import { directorySeparator, fileExtensionIs, @@ -44,8 +44,8 @@ import { import { createTypeReferenceResolutionLoader, inferredTypesContainingFile, moduleResolutionNameAndModeGetter, ResolutionLoader, -} from "./program"; -import { ignoredPaths } from "./sysUtilities"; +} from "./program/program"; +import { ignoredPaths } from "./sys/utilities"; import { CharacterCodes, CompilerOptions, @@ -70,11 +70,9 @@ import { import { clearMap, closeFileWatcher, - extensionIsTS, isExternalOrCommonJsModule, mutateMap, packageIdToString, - resolutionExtensionIsTSOrJson, } from "./utilities"; import { isExternalModuleNameRelative, @@ -85,6 +83,10 @@ import { closeFileWatcherOf, isEmittedFileOfProgram, } from "./watchUtilities"; +import { + extensionIsTS, + resolutionExtensionIsTSOrJson, +} from "./extension"; /** * This is the cache of module/typedirectives resolution that can be retained across program diff --git a/src/compiler/scannerKeywords.ts b/src/compiler/scanner/keywords.ts similarity index 96% rename from src/compiler/scannerKeywords.ts rename to src/compiler/scanner/keywords.ts index 47c724101da61..32d3f9ddd0977 100644 --- a/src/compiler/scannerKeywords.ts +++ b/src/compiler/scanner/keywords.ts @@ -1,8 +1,8 @@ -import { MapLike } from "./corePublic"; +import { MapLike } from "../corePublic"; import { KeywordSyntaxKind, SyntaxKind, -} from "./types"; +} from "../types"; export const textToKeywordObj: MapLike = { abstract: SyntaxKind.AbstractKeyword, diff --git a/src/compiler/scanner.ts b/src/compiler/scanner/scanner.ts similarity index 98% rename from src/compiler/scanner.ts rename to src/compiler/scanner/scanner.ts index be03510c6a961..d90aae862f06d 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner/scanner.ts @@ -1,4 +1,4 @@ -import * as Debug from "./debug"; +import * as Debug from "../debug"; import { append, arraysEqual, @@ -9,13 +9,13 @@ import { isWhiteSpaceLike, isWhiteSpaceSingleLine, trimStringStart, -} from "./core"; -import { Diagnostics } from "./diagnosticInformationMap.generated"; -import { textToKeyword, textToToken } from "./scannerKeywords"; +} from "../core"; +import { Diagnostics } from "../diagnosticInformationMap.generated"; +import { textToKeyword, textToToken } from "./keywords"; import { parsePseudoBigInt, positionIsSynthesized, -} from "./scannerUtilities"; +} from "./utilities"; import { CharacterCodes, CommentDirective, @@ -32,7 +32,7 @@ import { SourceFileLike, SyntaxKind, TokenFlags, -} from "./types"; +} from "../types"; export type ErrorCallback = (message: DiagnosticMessage, length: number) => void; diff --git a/src/compiler/scannerUtilities.ts b/src/compiler/scanner/utilities.ts similarity index 96% rename from src/compiler/scannerUtilities.ts rename to src/compiler/scanner/utilities.ts index 5ce6ffc28dfdc..5b0d905cf06ea 100644 --- a/src/compiler/scannerUtilities.ts +++ b/src/compiler/scanner/utilities.ts @@ -1,4 +1,4 @@ -import { CharacterCodes } from "./types"; +import { CharacterCodes } from "../types"; /** @internal */ export function positionIsSynthesized(pos: number): boolean { diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index ab76489bd09d0..28d953130914a 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -20,7 +20,7 @@ import { getNormalizedAbsolutePath, getRelativePathToDirectoryOrUrl, } from "./path"; -import { getPositionOfLineAndCharacter } from "./scanner"; +import { getPositionOfLineAndCharacter } from "./scanner/scanner"; import { CharacterCodes, DocumentPosition, diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts index ccc1ee056fc0b..11402f67bc275 100644 --- a/src/compiler/symbolWalker.ts +++ b/src/compiler/symbolWalker.ts @@ -1,4 +1,4 @@ -import { getSymbolId } from "./checkerUtilities"; +import { getSymbolId } from "./checker/utilities"; import { clear, forEach, diff --git a/src/compiler/symlinkCache.ts b/src/compiler/symlinkCache.ts index 399764e07f1fd..52cad963d88a2 100644 --- a/src/compiler/symlinkCache.ts +++ b/src/compiler/symlinkCache.ts @@ -6,7 +6,7 @@ import { MultiMap, startsWith, } from "./core"; -import { ModeAwareCache } from "./moduleNameResolver"; +import { ModeAwareCache } from "./moduleNameResolver/moduleNameResolver"; import { ensureTrailingDirectorySeparator, getNormalizedAbsolutePath, @@ -14,7 +14,7 @@ import { getPathFromPathComponents, toPath, } from "./path"; -import { containsIgnoredPath } from "./sysUtilities"; +import { containsIgnoredPath } from "./sys/utilities"; import { Path, ResolvedModuleFull, diff --git a/src/compiler/sys.ts b/src/compiler/sys/sys.ts similarity index 97% rename from src/compiler/sys.ts rename to src/compiler/sys/sys.ts index 033e6488a2157..8ef22854a52e3 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys/sys.ts @@ -1,5 +1,5 @@ -import * as Debug from "./debug"; -import { matchesExclude } from "./commandLineParser"; +import * as Debug from "../debug"; +import { matchesExclude } from "../commandLineParser/commandLineParser"; import { isNodeLikeSystem } from "./platform"; import { contains, @@ -19,14 +19,14 @@ import { startsWith, stringContains, unorderedRemoveItem, -} from "./core"; -import { Comparison } from "./corePublic"; +} from "../core"; +import { Comparison } from "../corePublic"; import { emptyFileSystemEntries, FileSystemEntries, matchFiles, -} from "./fileMatcher"; -import { resolveJSModule } from "./moduleNameResolver"; +} from "../fileMatcher"; +import { resolveJSModule } from "../moduleNameResolver/moduleNameResolver"; import { combinePaths, containsPath, @@ -37,10 +37,10 @@ import { getRootLength, normalizePath, normalizeSlashes, -} from "./path"; -import { perfLogger } from "./perfLogger"; -import { timestamp } from "./performanceCore"; -import { ignoredPaths } from "./sysUtilities"; +} from "../path"; +import { perfLogger } from "../perfLogger"; +import { timestamp } from "../performanceCore"; +import { ignoredPaths } from "./utilities"; import { DirectoryWatcherCallback, FileWatcher, @@ -52,15 +52,15 @@ import { WatchDirectoryKind, WatchFileKind, WatchOptions, -} from "./types"; +} from "../types"; import { closeFileWatcher, writeFileEnsuringDirectories, -} from "./utilities"; +} from "../utilities"; import { closeFileWatcherOf, getFallbackOptions, -} from "./watchUtilities"; +} from "../watchUtilities"; declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any; declare function clearTimeout(handle: any): void; diff --git a/src/compiler/sysUtilities.ts b/src/compiler/sys/utilities.ts similarity index 83% rename from src/compiler/sysUtilities.ts rename to src/compiler/sys/utilities.ts index e999a7622aae1..7ecb25b283ce3 100644 --- a/src/compiler/sysUtilities.ts +++ b/src/compiler/sys/utilities.ts @@ -1,6 +1,6 @@ -import { some, stringContains } from "./core"; +import { some, stringContains } from "../core"; import { sys } from "./sys"; -import { CompilerOptions, NewLineKind, PrinterOptions } from "./types"; +import { CompilerOptions, NewLineKind, PrinterOptions } from "../types"; /** @internal */ export const ignoredPaths = ["/node_modules/.", "/.git", "/.#"]; diff --git a/src/compiler/tracing.ts b/src/compiler/tracing.ts index 4ba9756fdcd62..37dfa5931bdad 100644 --- a/src/compiler/tracing.ts +++ b/src/compiler/tracing.ts @@ -2,7 +2,7 @@ import * as performance from "./performance"; import * as Debug from "./debug"; import { combinePaths } from "./path"; import { timestamp } from "./performanceCore"; -import { getLineAndCharacterOfPosition } from "./scanner"; +import { getLineAndCharacterOfPosition } from "./scanner/scanner"; import { ConditionalType, EvolvingArrayType, diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 4ff356835d433..965ca514c4f3d 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -24,7 +24,7 @@ import { tryCast, } from "../core"; import { Diagnostics } from "../diagnosticInformationMap.generated"; -import { getOutputPathsFor } from "../emitter"; +import { getOutputPathsFor } from "../emitter/emitter"; import { getCommentRange, removeAllComments, @@ -73,10 +73,10 @@ import { setOriginalNode, setTextRange, } from "../factory/utilitiesPublic"; -import { pathContainsNodeModules } from "../moduleNameResolver"; -import { getModuleSpecifier } from "../moduleSpecifiers"; -import { parseNodeFactory } from "../parser"; -import { setParent } from "../parserUtilities"; +import { pathContainsNodeModules } from "../moduleNameResolver/moduleNameResolver"; +import { getModuleSpecifier } from "../moduleSpecifiers/moduleSpecifiers"; +import { parseNodeFactory } from "../parser/parser"; +import { setParent } from "../parser/utilities"; import { getDirectoryPath, getRelativePathToDirectoryOrUrl, @@ -85,13 +85,13 @@ import { pathIsRelative, toPath, } from "../path"; -import { getResolutionModeOverrideForClause } from "../program"; +import { getResolutionModeOverrideForClause } from "../program/program"; import { getLeadingCommentRanges, getLineAndCharacterOfPosition, getTrailingCommentRanges, skipTrivia, -} from "../scanner"; +} from "../scanner/scanner"; import { transformNodes } from "../transformer"; import { AccessorDeclaration, @@ -183,10 +183,8 @@ import { getEffectiveBaseTypeNode, getEffectiveModifierFlags, getExternalModuleImportEqualsDeclarationExpression, - getExternalModuleNameFromDeclaration, getFirstConstructorWithBody, getLeadingCommentRangesOfNode, - getResolvedExternalModuleName, getSetAccessorValueParameter, getSourceFileOfNode, getTextOfNode, @@ -241,6 +239,10 @@ import { GetSymbolAccessibilityDiagnostic, } from "./declarations/diagnostics"; import { getOriginalNodeId } from "./utilities"; +import { + getExternalModuleNameFromDeclaration, + getResolvedExternalModuleName, +} from "../moduleNameResolver/utilities"; /** @internal */ export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] | undefined { diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 1ebd60dd77b5d..a25a5d6dc5f0d 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -72,8 +72,8 @@ import { setOriginalNode, setTextRange, } from "../factory/utilitiesPublic"; -import { setParent } from "../parserUtilities"; -import { skipTrivia } from "../scanner"; +import { setParent } from "../parser/utilities"; +import { skipTrivia } from "../scanner/scanner"; import { __String, AccessorDeclaration, diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 4133ae08331a5..34be80b366a32 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -1,5 +1,5 @@ import * as Debug from "../debug"; -import { getNodeId } from "../checkerUtilities"; +import { getNodeId } from "../checker/utilities"; import { concatenate, forEach, diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index 11b2c0c30096d..9878efdb0b35e 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -1,5 +1,5 @@ import * as Debug from "../debug"; -import { getNodeId } from "../checkerUtilities"; +import { getNodeId } from "../checker/utilities"; import { addRange, append, diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 89dfb136d8f45..a4ad03f760070 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -26,7 +26,7 @@ import { setOriginalNode, setTextRange, } from "../factory/utilitiesPublic"; -import { setParent } from "../parserUtilities"; +import { setParent } from "../parser/utilities"; import { AccessorDeclaration, ArrayLiteralExpression, diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index d5589c98388c8..8963de1655671 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -34,11 +34,11 @@ import { startOnNewLine, } from "../factory/utilities"; import { setTextRange } from "../factory/utilitiesPublic"; -import { setParentRecursive } from "../parserUtilities"; +import { setParentRecursive } from "../parser/utilities"; import { getLineAndCharacterOfPosition, utf16EncodeAsString, -} from "../scanner"; +} from "../scanner/scanner"; import { Bundle, Expression, diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index c236ffdde3bc0..50098755c667a 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1,5 +1,5 @@ import * as Debug from "../../debug"; -import { getNodeId } from "../../checkerUtilities"; +import { getNodeId } from "../../checker/utilities"; import { addRange, append, diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index e4b5c48afd20b..86e7e64b05db0 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -1,5 +1,5 @@ import * as Debug from "../../debug"; -import { getNodeId } from "../../checkerUtilities"; +import { getNodeId } from "../../checker/utilities"; import { addRange, append, diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 8111f40a6ab4c..a45552f4e9dcd 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1,5 +1,5 @@ import * as Debug from "../debug"; -import { isInstantiatedModule } from "../checker"; +import { isInstantiatedModule } from "../checker/checker"; import { addRange, append, @@ -55,8 +55,8 @@ import { setOriginalNode, setTextRange, } from "../factory/utilitiesPublic"; -import { setParent } from "../parserUtilities"; -import { skipTrivia } from "../scanner"; +import { setParent } from "../parser/utilities"; +import { skipTrivia } from "../scanner/scanner"; import { __String, AccessorDeclaration, diff --git a/src/compiler/transformers/typeSerializer.ts b/src/compiler/transformers/typeSerializer.ts index 0d96dd50f83ac..d763be4ea0852 100644 --- a/src/compiler/transformers/typeSerializer.ts +++ b/src/compiler/transformers/typeSerializer.ts @@ -14,8 +14,8 @@ import { isVoidExpression, } from "../factory/nodeTests"; import { setTextRange } from "../factory/utilitiesPublic"; -import { parseNodeFactory } from "../parser"; -import { setParent } from "../parserUtilities"; +import { parseNodeFactory } from "../parser/parser"; +import { setParent } from "../parser/utilities"; import { AccessorDeclaration, ArrayLiteralExpression, diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 5fea7bafea613..444e183ffde73 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -1,4 +1,4 @@ -import { getNodeId } from "../checkerUtilities"; +import { getNodeId } from "../checker/utilities"; import { append, cast, diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index be8c2d2461413..ad18eeb32369b 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -22,7 +22,7 @@ import { getParsedCommandLineOfConfigFile, ParseConfigFileHost, updateErrorForNoInputFiles, -} from "./commandLineParser"; +} from "./commandLineParser/commandLineParser"; import { arrayToMap, assertType, @@ -49,13 +49,13 @@ import { getBuildInfo, getFirstProjectOutput, getTsBuildInfoEmitOutputFilePath, -} from "./emitter"; +} from "./emitter/emitter"; import { createModuleResolutionCache, createTypeReferenceDirectiveResolutionCache, ModuleResolutionCache, TypeReferenceDirectiveResolutionCache, -} from "./moduleNameResolver"; +} from "./moduleNameResolver/moduleNameResolver"; import { convertToRelativePath, getDirectoryPath, @@ -75,13 +75,13 @@ import { loadWithModeAwareCache, parseConfigHostFromCompilerHostLike, resolveProjectReferencePath, -} from "./program"; +} from "./program/program"; import { getModifiedTime, missingFileModifiedTime, PollingInterval, sys, -} from "./sys"; +} from "./sys/sys"; import { resolveConfigFileProjectName, Status, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b33e34b92ca7a..b0836e334197d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1,5 +1,5 @@ import { ProgramBuildInfo } from "./builder"; -import { OptionsNameMap } from "./commandLineParser"; +import { OptionsNameMap } from "./commandLineParser/commandLineParser"; import { GetCanonicalFileName, MultiMap, @@ -17,8 +17,8 @@ import { ModuleResolutionCache, PackageJsonInfo, PackageJsonInfoCache, -} from "./moduleNameResolver"; -import { CreateSourceFileOptions } from "./parser"; +} from "./moduleNameResolver/moduleNameResolver"; +import { CreateSourceFileOptions } from "./parser/parser"; import { SymlinkCache } from "./symlinkCache"; import { ThisContainer } from "./utilities"; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 3bd3060d467a5..41767ffadaacc 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1,5 +1,5 @@ import * as Debug from "./debug"; -import { getSymbolId } from "./checkerUtilities"; +import { getSymbolId } from "./checker/utilities"; import { addRange, arrayFrom, @@ -11,7 +11,6 @@ import { contains, createGetCanonicalFileName, emptyArray, - endsWith, equalOwnProperties, equateValues, every, @@ -139,22 +138,12 @@ import { canHaveModifiers, } from "./factory/utilitiesPublic"; import { - changeAnyExtension, - combinePaths, - ensurePathIsNonModuleName, - ensureTrailingDirectorySeparator, - fileExtensionIs, - fileExtensionIsOneOf, forEachAncestorDirectory, getBaseFileName, getDirectoryPath, - getNormalizedAbsolutePath, - getRelativePathToDirectoryOrUrl, getRootLength, isAnyDirectorySeparator, normalizePath, - pathIsRelative, - toPath, } from "./path"; import { computeLineAndCharacterOfPosition, @@ -170,11 +159,11 @@ import { skipTrivia, stringToToken, tokenToString, -} from "./scanner"; +} from "./scanner/scanner"; import { parsePseudoBigInt, positionIsSynthesized, -} from "./scannerUtilities"; +} from "./scanner/utilities"; import { __String, AccessExpression, @@ -246,8 +235,6 @@ import { DynamicNamedDeclaration, ElementAccessExpression, EmitFlags, - EmitHost, - EmitResolver, EmitTextWriter, EntityName, EntityNameExpression, @@ -363,7 +350,6 @@ import { ParenthesizedExpression, ParenthesizedTypeNode, PartiallyEmittedExpression, - Path, PostfixUnaryExpression, PrefixUnaryExpression, PrintHandlers, @@ -5177,101 +5163,6 @@ export function hostGetCanonicalFileName(host: { useCaseSensitiveFileNames?(): b return createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(host)); } -/** @internal */ -export interface ResolveModuleNameResolutionHost { - getCanonicalFileName(p: string): string; - getCommonSourceDirectory(): string; - getCurrentDirectory(): string; -} - -/** @internal */ -export function getResolvedExternalModuleName(host: ResolveModuleNameResolutionHost, file: SourceFile, referenceFile?: SourceFile): string { - return file.moduleName || getExternalModuleNameFromPath(host, file.fileName, referenceFile && referenceFile.fileName); -} - -function getCanonicalAbsolutePath(host: ResolveModuleNameResolutionHost, path: string) { - return host.getCanonicalFileName(getNormalizedAbsolutePath(path, host.getCurrentDirectory())); -} - -/** @internal */ -export function getExternalModuleNameFromDeclaration(host: ResolveModuleNameResolutionHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode): string | undefined { - const file = resolver.getExternalModuleFileFromDeclaration(declaration); - if (!file || file.isDeclarationFile) { - return undefined; - } - // If the declaration already uses a non-relative name, and is outside the common source directory, continue to use it - const specifier = getExternalModuleName(declaration); - if (specifier && isStringLiteralLike(specifier) && !pathIsRelative(specifier.text) && - getCanonicalAbsolutePath(host, file.path).indexOf(getCanonicalAbsolutePath(host, ensureTrailingDirectorySeparator(host.getCommonSourceDirectory()))) === -1) { - return undefined; - } - return getResolvedExternalModuleName(host, file); -} - -/** - * Resolves a local path to a path which is absolute to the base of the emit - * - * @internal - */ -export function getExternalModuleNameFromPath(host: ResolveModuleNameResolutionHost, fileName: string, referencePath?: string): string { - const getCanonicalFileName = (f: string) => host.getCanonicalFileName(f); - const dir = toPath(referencePath ? getDirectoryPath(referencePath) : host.getCommonSourceDirectory(), host.getCurrentDirectory(), getCanonicalFileName); - const filePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory()); - const relativePath = getRelativePathToDirectoryOrUrl(dir, filePath, dir, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); - const extensionless = removeFileExtension(relativePath); - return referencePath ? ensurePathIsNonModuleName(extensionless) : extensionless; -} - -/** @internal */ -export function getOwnEmitOutputFilePath(fileName: string, host: EmitHost, extension: string) { - const compilerOptions = host.getCompilerOptions(); - let emitOutputFilePathWithoutExtension: string; - if (compilerOptions.outDir) { - emitOutputFilePathWithoutExtension = removeFileExtension(getSourceFilePathInNewDir(fileName, host, compilerOptions.outDir)); - } - else { - emitOutputFilePathWithoutExtension = removeFileExtension(fileName); - } - - return emitOutputFilePathWithoutExtension + extension; -} - -/** @internal */ -export function getDeclarationEmitOutputFilePath(fileName: string, host: EmitHost) { - return getDeclarationEmitOutputFilePathWorker(fileName, host.getCompilerOptions(), host.getCurrentDirectory(), host.getCommonSourceDirectory(), f => host.getCanonicalFileName(f)); -} - -/** @internal */ -export function getDeclarationEmitOutputFilePathWorker(fileName: string, options: CompilerOptions, currentDirectory: string, commonSourceDirectory: string, getCanonicalFileName: GetCanonicalFileName): string { - const outputDir = options.declarationDir || options.outDir; // Prefer declaration folder if specified - - const path = outputDir - ? getSourceFilePathInNewDirWorker(fileName, outputDir, currentDirectory, commonSourceDirectory, getCanonicalFileName) - : fileName; - const declarationExtension = getDeclarationEmitExtensionForPath(path); - return removeFileExtension(path) + declarationExtension; -} - -/** @internal */ -export function getDeclarationEmitExtensionForPath(path: string) { - return fileExtensionIsOneOf(path, [Extension.Mjs, Extension.Mts]) ? Extension.Dmts : - fileExtensionIsOneOf(path, [Extension.Cjs, Extension.Cts]) ? Extension.Dcts : - fileExtensionIsOneOf(path, [Extension.Json]) ? `.d.json.ts` : // Drive-by redefinition of json declaration file output name so if it's ever enabled, it behaves well - Extension.Dts; -} - -/** - * This function is an inverse of `getDeclarationEmitExtensionForPath`. - * - * @internal - */ -export function getPossibleOriginalInputExtensionForExtension(path: string) { - return fileExtensionIsOneOf(path, [Extension.Dmts, Extension.Mjs, Extension.Mts]) ? [Extension.Mts, Extension.Mjs] : - fileExtensionIsOneOf(path, [Extension.Dcts, Extension.Cjs, Extension.Cts]) ? [Extension.Cts, Extension.Cjs]: - fileExtensionIsOneOf(path, [`.d.json.ts`]) ? [Extension.Json] : - [Extension.Tsx, Extension.Ts, Extension.Jsx, Extension.Js]; -} - /** @internal */ export function outFile(options: CompilerOptions) { return options.outFile || options.out; @@ -5312,19 +5203,6 @@ export function sourceFileMayBeEmitted(sourceFile: SourceFile, host: SourceFileM )); } -/** @internal */ -export function getSourceFilePathInNewDir(fileName: string, host: EmitHost, newDirPath: string): string { - return getSourceFilePathInNewDirWorker(fileName, newDirPath, host.getCurrentDirectory(), host.getCommonSourceDirectory(), f => host.getCanonicalFileName(f)); -} - -/** @internal */ -export function getSourceFilePathInNewDirWorker(fileName: string, newDirPath: string, currentDirectory: string, commonSourceDirectory: string, getCanonicalFileName: GetCanonicalFileName): string { - let sourceFilePath = getNormalizedAbsolutePath(fileName, currentDirectory); - const isSourceFileInCommonSourceDirectory = getCanonicalFileName(sourceFilePath).indexOf(getCanonicalFileName(commonSourceDirectory)) === 0; - sourceFilePath = isSourceFileInCommonSourceDirectory ? sourceFilePath.substring(commonSourceDirectory.length) : sourceFilePath; - return combinePaths(newDirPath, sourceFilePath); -} - /** @internal */ export function writeFile(host: { writeFile: WriteFileCallback; }, diagnostics: DiagnosticCollection, fileName: string, text: string, writeByteOrderMark: boolean, sourceFiles?: readonly SourceFile[], data?: WriteFileCallbackData) { host.writeFile(fileName, text, writeByteOrderMark, hostErrorMessage => { @@ -7524,33 +7402,6 @@ export function compareNumberOfDirectorySeparators(path1: string, path2: string) ); } -const extensionsToRemove = [Extension.Dts, Extension.Dmts, Extension.Dcts, Extension.Mjs, Extension.Mts, Extension.Cjs, Extension.Cts, Extension.Ts, Extension.Js, Extension.Tsx, Extension.Jsx, Extension.Json]; -/** @internal */ -export function removeFileExtension(path: string): string { - for (const ext of extensionsToRemove) { - const extensionless = tryRemoveExtension(path, ext); - if (extensionless !== undefined) { - return extensionless; - } - } - return path; -} - -/** @internal */ -export function tryRemoveExtension(path: string, extension: string): string | undefined { - return fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined; -} - -/** @internal */ -export function removeExtension(path: string, extension: string): string { - return path.substring(0, path.length - extension.length); -} - -/** @internal */ -export function changeExtension(path: T, newExtension: string): T { - return changeAnyExtension(path, newExtension, extensionsToRemove, /*ignoreCase*/ false) as T; -} - /** * Returns the input if there are no stars, a pattern if there is exactly one, * and undefined if there are more. @@ -7575,41 +7426,6 @@ export function tryParsePatterns(paths: MapLike): (string | Pattern)[] return mapDefined(getOwnKeys(paths), path => tryParsePattern(path)); } -/** - * True if an extension is one of the supported TypeScript extensions. - * - * @internal - */ -export function extensionIsTS(ext: string): boolean { - return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts || ext === Extension.Cts || ext === Extension.Mts || ext === Extension.Dmts || ext === Extension.Dcts || (startsWith(ext, ".d.") && endsWith(ext, ".ts")); -} - -/** @internal */ -export function resolutionExtensionIsTSOrJson(ext: string) { - return extensionIsTS(ext) || ext === Extension.Json; -} - -/** - * Gets the extension from a path. - * Path must have a valid extension. - * - * @internal - */ -export function extensionFromPath(path: string): Extension { - const ext = tryGetExtensionFromPath(path); - return ext !== undefined ? ext : Debug.fail(`File ${path} has unknown extension.`); -} - -/** @internal */ -export function isAnySupportedFileExtension(path: string): boolean { - return tryGetExtensionFromPath(path) !== undefined; -} - -/** @internal */ -export function tryGetExtensionFromPath(path: string): Extension | undefined { - return find(extensionsToRemove, e => fileExtensionIs(path, e)); -} - /** @internal */ export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) { return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs; diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 104286a9249c6..3408e5811a253 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -84,7 +84,7 @@ import { normalizePath, pathIsRelative, } from "./path"; -import { stringToToken } from "./scanner"; +import { stringToToken } from "./scanner/scanner"; import { __String, AccessExpression, diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 07629b8bfabdb..a8c21b4c6fecf 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -10,7 +10,7 @@ import { getParsedCommandLineOfConfigFile, ParseConfigFileHost, targetOptionDeclaration, -} from "./commandLineParser"; +} from "./commandLineParser/commandLineParser"; import { addRange, contains, @@ -57,8 +57,8 @@ import { getReferencedFileLocation, isReferencedFile, isReferenceFileLocation, -} from "./program"; -import { getLineAndCharacterOfPosition } from "./scanner"; +} from "./program/program"; +import { getLineAndCharacterOfPosition } from "./scanner/scanner"; import { sourceMapCommentRegExp, sourceMapCommentRegExpDontCareLineStart, @@ -67,8 +67,8 @@ import { import { generateDjb2Hash, sys, -} from "./sys"; -import { getNewLineCharacter } from "./sysUtilities"; +} from "./sys/sys"; +import { getNewLineCharacter } from "./sys/utilities"; import { ReportEmitErrorSummary, ReportFileInError, diff --git a/src/compiler/watchPublic.ts b/src/compiler/watchPublic.ts index c8500ed9b99f5..bb8b70bc7342f 100644 --- a/src/compiler/watchPublic.ts +++ b/src/compiler/watchPublic.ts @@ -13,7 +13,7 @@ import { getFileNamesFromConfigSpecs, getParsedCommandLineOfConfigFile, updateErrorForNoInputFiles, -} from "./commandLineParser"; +} from "./commandLineParser/commandLineParser"; import { createGetCanonicalFileName, isArray, @@ -30,9 +30,9 @@ import { Diagnostics } from "./diagnosticInformationMap.generated"; import { getBuildInfo, getTsBuildInfoEmitOutputFilePath, -} from "./emitter"; -import { ModuleResolutionCache } from "./moduleNameResolver"; -import { CreateSourceFileOptions } from "./parser"; +} from "./emitter/emitter"; +import { ModuleResolutionCache } from "./moduleNameResolver/moduleNameResolver"; +import { CreateSourceFileOptions } from "./parser/parser"; import { getDirectoryPath, getNormalizedAbsolutePath, @@ -45,8 +45,8 @@ import { getConfigFileParsingDiagnostics, isProgramUptoDate, parseConfigHostFromCompilerHostLike, -} from "./program"; -import { changesAffectModuleResolution } from "./programUtilities"; +} from "./program/program"; +import { changesAffectModuleResolution } from "./program/utilities"; import { createResolutionCache, ResolutionCacheHost, @@ -54,8 +54,8 @@ import { import { PollingInterval, sys, -} from "./sys"; -import { getNewLineCharacter } from "./sysUtilities"; +} from "./sys/sys"; +import { getNewLineCharacter } from "./sys/utilities"; import { BuildInfo, CompilerHost, diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index a11597d306ae3..21d9ba40da5f7 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -4,7 +4,7 @@ import { ExtendedConfigCacheEntry, isExcludedFile, matchesExclude, -} from "./commandLineParser"; +} from "./commandLineParser/commandLineParser"; import { arrayToMap, binarySearch, @@ -29,7 +29,7 @@ import { FileSystemEntries, matchFiles, } from "./fileMatcher"; -import { isDeclarationFileName } from "./parser"; +import { isDeclarationFileName } from "./parser/parser"; import { ensureTrailingDirectorySeparator, fileExtensionIs, @@ -46,7 +46,7 @@ import { removeIgnoredPath } from "./resolutionCache"; import { PollingInterval, setSysLog, -} from "./sys"; +} from "./sys/sys"; import { CompilerOptions, DirectoryWatcherCallback, @@ -65,12 +65,12 @@ import { closeFileWatcher, mutateMap, outFile, - removeFileExtension, } from "./utilities"; import { returnNoopFileWatcher } from "./watch"; import { getSupportedExtensions, getSupportedExtensionsWithJsonIfResolveJsonModule, + removeFileExtension, supportedJSExtensionsFlat, } from "./extension"; diff --git a/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts b/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts index ddeb221db4bfb..eaae28bacf94b 100644 --- a/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts +++ b/src/deprecatedCompat/4.0/nodeFactoryTopLevelExports.ts @@ -1,8 +1,8 @@ import * as Debug from "../../compiler/debug"; import { factory } from "../../compiler/factory/nodeFactory"; import { setTextRange } from "../../compiler/factory/utilitiesPublic"; -import { parseBaseNodeFactory } from "../../compiler/parser"; -import { setParent } from "../../compiler/parserUtilities"; +import { parseBaseNodeFactory } from "../../compiler/parser/parser"; +import { setParent } from "../../compiler/parser/utilities"; import { ArrowFunction, AsteriskToken, diff --git a/src/executeCommandLine/executeCommandLine.ts b/src/executeCommandLine/executeCommandLine.ts index cde378707ae18..7228822259bc2 100644 --- a/src/executeCommandLine/executeCommandLine.ts +++ b/src/executeCommandLine/executeCommandLine.ts @@ -17,7 +17,7 @@ import { optionsForWatch, parseBuildCommand, parseCommandLine, -} from "../compiler/commandLineParser"; +} from "../compiler/commandLineParser/commandLineParser"; import { arrayFrom, compareStringsCaseInsensitive, @@ -49,9 +49,9 @@ import { createProgram, findConfigFile, getConfigFileParsingDiagnostics, -} from "../compiler/program"; -import { getLineStarts } from "../compiler/scanner"; -import { sys } from "../compiler/sys"; +} from "../compiler/program/program"; +import { getLineStarts } from "../compiler/scanner/scanner"; +import { sys } from "../compiler/sys/sys"; import { dumpTracingLegend, startTracing, diff --git a/src/harness/fakesHosts.ts b/src/harness/fakesHosts.ts index 7fd58dde74680..f95b71b5cc593 100644 --- a/src/harness/fakesHosts.ts +++ b/src/harness/fakesHosts.ts @@ -5,7 +5,7 @@ import * as vpath from "./_namespaces/vpath"; import * as documents from "./_namespaces/documents"; import * as collections from "./_namespaces/collections"; import * as Harness from "./_namespaces/Harness"; -import { getNewLineCharacter } from "../compiler/sysUtilities"; +import { getNewLineCharacter } from "../compiler/sys/utilities"; import { FileSystemEntries, matchFiles } from "../compiler/fileMatcher"; /** diff --git a/src/harness/harnessUtils.ts b/src/harness/harnessUtils.ts index 9dcbcd71a3ae7..9ae8bcfb4b9d5 100644 --- a/src/harness/harnessUtils.ts +++ b/src/harness/harnessUtils.ts @@ -1,6 +1,6 @@ import * as ts from "./_namespaces/ts"; import * as Harness from "./_namespaces/Harness"; -import { containsParseError } from "../compiler/parserUtilities"; +import { containsParseError } from "../compiler/parser/utilities"; export function encodeString(s: string): string { return ts.sys.bufferFrom!(s).toString("utf8"); diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index fcc83b92c639f..3f6002feecf5b 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { readConfigFile } from "../compiler/commandLineParser"; +import { readConfigFile } from "../compiler/commandLineParser/commandLineParser"; import { compareStringsCaseSensitive, deduplicate, @@ -34,8 +34,10 @@ import { Path, TypeAcquisition, } from "../compiler/types"; -import { removeFileExtension } from "../compiler/utilities"; -import { hasJSFileExtension } from "../compiler/extension"; +import { + hasJSFileExtension, + removeFileExtension, +} from "../compiler/extension"; /** @internal */ export interface TypingResolutionHost { diff --git a/src/jsTyping/shared.ts b/src/jsTyping/shared.ts index a85cbef5ae772..6e4a58a0342e2 100644 --- a/src/jsTyping/shared.ts +++ b/src/jsTyping/shared.ts @@ -1,5 +1,5 @@ import { padLeft } from "../compiler/core"; -import { sys } from "../compiler/sys"; +import { sys } from "../compiler/sys/sys"; export type ActionSet = "action::set"; export type ActionInvalidate = "action::invalidate"; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index cba227e71165f..6090aabc0b3b7 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -11,7 +11,7 @@ import { parseJsonSourceFileConfigFileContent, tryReadFile, typeAcquisitionDeclarations, -} from "../compiler/commandLineParser"; +} from "../compiler/commandLineParser/commandLineParser"; import { arrayFrom, arrayToMap, @@ -43,8 +43,8 @@ import { ReadonlyCollection, version, } from "../compiler/corePublic"; -import { parsePackageName } from "../compiler/moduleNameResolver"; -import { parseJsonText } from "../compiler/parser"; +import { parsePackageName } from "../compiler/moduleNameResolver/moduleNameResolver"; +import { parseJsonText } from "../compiler/parser/parser"; import { combinePaths, containsPath, @@ -66,7 +66,7 @@ import { import { forEachResolvedProjectReference, resolveProjectReferencePath, -} from "../compiler/program"; +} from "../compiler/program/program"; import { canWatchDirectoryOrFile, removeIgnoredPath, @@ -75,7 +75,7 @@ import { getFileWatcherEventKind, missingFileModifiedTime, PollingInterval, -} from "../compiler/sys"; +} from "../compiler/sys/sys"; import { tracing } from "../compiler/tracing"; import { CommandLineOption, @@ -107,7 +107,6 @@ import { forEachEntry, forEachKey, isJsonEqual, - removeFileExtension, } from "../compiler/utilities"; import { returnNoopFileWatcher, @@ -219,7 +218,10 @@ import { ProjectOptions, toNormalizedPath, } from "./utilitiesPublic"; -import { hasTSFileExtension } from "../compiler/extension"; +import { + hasTSFileExtension, + removeFileExtension, +} from "../compiler/extension"; export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024; /** @internal */ diff --git a/src/server/moduleSpecifierCache.ts b/src/server/moduleSpecifierCache.ts index 6358ee0e41594..1b0cc7245a66c 100644 --- a/src/server/moduleSpecifierCache.ts +++ b/src/server/moduleSpecifierCache.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { nodeModulesPathPart } from "../compiler/moduleNameResolver"; +import { nodeModulesPathPart } from "../compiler/moduleNameResolver/moduleNameResolver"; import { FileWatcher, ModulePath, diff --git a/src/server/project.ts b/src/server/project.ts index 9243a05271a97..71ae5f4e54a1d 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1,6 +1,6 @@ import * as Debug from "../compiler/debug"; import { BuilderState } from "../compiler/builderState"; -import { updateErrorForNoInputFiles } from "../compiler/commandLineParser"; +import { updateErrorForNoInputFiles } from "../compiler/commandLineParser/commandLineParser"; import { addRange, append, @@ -37,8 +37,8 @@ import { PackageJsonInfo, parsePackageName, resolvePackageNameToPackageJson, -} from "../compiler/moduleNameResolver"; -import { isDeclarationFileName } from "../compiler/parser"; +} from "../compiler/moduleNameResolver/moduleNameResolver"; +import { isDeclarationFileName } from "../compiler/parser/parser"; import { combinePaths, fileExtensionIs, @@ -50,7 +50,7 @@ import { } from "../compiler/path"; import { perfLogger } from "../compiler/perfLogger"; import { timestamp } from "../compiler/performanceCore"; -import { inferredTypesContainingFile } from "../compiler/program"; +import { inferredTypesContainingFile } from "../compiler/program/program"; import { createResolutionCache, ResolutionCache, @@ -58,7 +58,7 @@ import { import { generateDjb2Hash, PollingInterval, -} from "../compiler/sys"; +} from "../compiler/sys/sys"; import { tracing } from "../compiler/tracing"; import { CompilerHost, @@ -95,11 +95,8 @@ import { forEachEntry, forEachKey, getAllowJSCompilerOption, - getDeclarationEmitOutputFilePathWorker, getEmitDeclarations, outFile, - removeFileExtension, - resolutionExtensionIsTSOrJson, stripQuotes, } from "../compiler/utilities"; import { @@ -177,7 +174,9 @@ import { createSymlinkCache, SymlinkCache, } from "../compiler/symlinkCache"; -import { changesAffectModuleResolution } from "../compiler/programUtilities"; +import { changesAffectModuleResolution } from "../compiler/program/utilities"; +import { removeFileExtension, resolutionExtensionIsTSOrJson } from "./_namespaces/ts"; +import { getDeclarationEmitOutputFilePathWorker } from "../compiler/emitter/utilities"; export enum ProjectKind { Inferred, diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 278c3e0c003be..0970c291bf93a 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -17,7 +17,7 @@ import { computeLineAndCharacterOfPosition, computeLineStarts, computePositionOfLineAndCharacter, -} from "../compiler/scanner"; +} from "../compiler/scanner/scanner"; import { getLineInfo, LineInfo, diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index ee5cddabd5409..72b7dc1b2faec 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { computeLineStarts } from "../compiler/scanner"; +import { computeLineStarts } from "../compiler/scanner/scanner"; import { TextChangeRange, TextSpan, diff --git a/src/server/session.ts b/src/server/session.ts index 504098fa28c29..135cb5d8fe6a3 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -41,20 +41,20 @@ import { getTemporaryModuleResolutionState, nodeModulesPathPart, unmangleScopedPackageName, -} from "../compiler/moduleNameResolver"; -import { getNodeModulePathParts } from "../compiler/moduleSpecifiersUtilities"; -import { isDeclarationFileName } from "../compiler/parser"; +} from "../compiler/moduleNameResolver/moduleNameResolver"; +import { getNodeModulePathParts } from "../compiler/moduleSpecifiers/utilities"; +import { isDeclarationFileName } from "../compiler/parser/parser"; import { getNormalizedAbsolutePath, normalizePath, } from "../compiler/path"; import { perfLogger } from "../compiler/perfLogger"; -import { flattenDiagnosticMessageText } from "../compiler/program"; +import { flattenDiagnosticMessageText } from "../compiler/program/program"; import { computeLineAndCharacterOfPosition, computeLineStarts, getLineAndCharacterOfPosition, -} from "../compiler/scanner"; +} from "../compiler/scanner/scanner"; import { tracing } from "../compiler/tracing"; import { BufferEncoding, @@ -84,7 +84,6 @@ import { getTextOfIdentifierOrLiteral, isAccessExpression, outFile, - removeFileExtension, } from "../compiler/utilities"; import { createTextSpan, @@ -203,6 +202,7 @@ import { NormalizedPath, toNormalizedPath, } from "./utilitiesPublic"; +import { removeFileExtension } from "../compiler/extension"; interface StackTraceError extends Error { stack?: string; diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index d8c822f6ea29b..7ff68c5d9ee9b 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -13,7 +13,7 @@ import { isVariableDeclarationList, } from "../compiler/factory/nodeTests"; import { canHaveDecorators } from "../compiler/factory/utilitiesPublic"; -import { skipTrivia } from "../compiler/scanner"; +import { skipTrivia } from "../compiler/scanner/scanner"; import { ArrayLiteralExpression, BinaryExpression, diff --git a/src/services/callHierarchy.ts b/src/services/callHierarchy.ts index 7caf2f498aded..4bb291f6be9b1 100644 --- a/src/services/callHierarchy.ts +++ b/src/services/callHierarchy.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { getNodeId } from "../compiler/checkerUtilities"; +import { getNodeId } from "../compiler/checker/utilities"; import { append, compareStringsCaseSensitive, @@ -11,7 +11,7 @@ import { isArray, map, } from "../compiler/core"; -import { createPrinter } from "../compiler/emitter"; +import { createPrinter } from "../compiler/emitter/emitter"; import { isArrowFunction, isClassDeclaration, @@ -34,8 +34,8 @@ import { isVariableDeclaration, } from "../compiler/factory/nodeTests"; import { canHaveModifiers } from "../compiler/factory/utilitiesPublic"; -import { forEachChild } from "../compiler/parser"; -import { skipTrivia } from "../compiler/scanner"; +import { forEachChild } from "../compiler/parser/parser"; +import { skipTrivia } from "../compiler/scanner/scanner"; import { AccessExpression, ArrowFunction, diff --git a/src/services/classifier.ts b/src/services/classifier.ts index 2d823371ccaa5..46747418baa51 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -15,13 +15,13 @@ import { isJSDoc, isModuleDeclaration, } from "../compiler/factory/nodeTests"; -import { parseIsolatedJSDocComment } from "../compiler/parser"; -import { setParent } from "../compiler/parserUtilities"; +import { parseIsolatedJSDocComment } from "../compiler/parser/parser"; +import { setParent } from "../compiler/parser/utilities"; import { couldStartTrivia, createScanner, Scanner, -} from "../compiler/scanner"; +} from "../compiler/scanner/scanner"; import { __String, CancellationToken, diff --git a/src/services/classifier2020.ts b/src/services/classifier2020.ts index 863b92943fdbb..66c3c511b7d4d 100644 --- a/src/services/classifier2020.ts +++ b/src/services/classifier2020.ts @@ -16,7 +16,7 @@ import { isSourceFile, isVariableDeclaration, } from "../compiler/factory/nodeTests"; -import { forEachChild } from "../compiler/parser"; +import { forEachChild } from "../compiler/parser/parser"; import { BindingElement, CancellationToken, diff --git a/src/services/codefixes/addMissingAsync.ts b/src/services/codefixes/addMissingAsync.ts index a02c001a25264..4eaea1c329209 100644 --- a/src/services/codefixes/addMissingAsync.ts +++ b/src/services/codefixes/addMissingAsync.ts @@ -1,4 +1,4 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; +import { getNodeId } from "../../compiler/checker/utilities"; import { find, isNumber, diff --git a/src/services/codefixes/addMissingAwait.ts b/src/services/codefixes/addMissingAwait.ts index 63f6c4c26c995..3f19ac2ad285b 100644 --- a/src/services/codefixes/addMissingAwait.ts +++ b/src/services/codefixes/addMissingAwait.ts @@ -1,4 +1,4 @@ -import { getSymbolId } from "../../compiler/checkerUtilities"; +import { getSymbolId } from "../../compiler/checker/utilities"; import { compact, contains, diff --git a/src/services/codefixes/convertConstToLet.ts b/src/services/codefixes/convertConstToLet.ts index 88c855a96529a..b214a4c2dc401 100644 --- a/src/services/codefixes/convertConstToLet.ts +++ b/src/services/codefixes/convertConstToLet.ts @@ -1,4 +1,4 @@ -import { getSymbolId } from "../../compiler/checkerUtilities"; +import { getSymbolId } from "../../compiler/checker/utilities"; import { tryCast } from "../../compiler/core"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; diff --git a/src/services/codefixes/convertFunctionToEs6Class.ts b/src/services/codefixes/convertFunctionToEs6Class.ts index f2902fdd7e775..40e36182d5004 100644 --- a/src/services/codefixes/convertFunctionToEs6Class.ts +++ b/src/services/codefixes/convertFunctionToEs6Class.ts @@ -23,7 +23,7 @@ import { isVariableDeclarationList, } from "../../compiler/factory/nodeTests"; import { canHaveModifiers } from "../../compiler/factory/utilitiesPublic"; -import { isIdentifierText } from "../../compiler/scanner"; +import { isIdentifierText } from "../../compiler/scanner/scanner"; import { __String, AccessExpression, diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 9460f13fb9113..2da3015859658 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -2,7 +2,7 @@ import * as Debug from "../../compiler/debug"; import { getNodeId, getSymbolId, -} from "../../compiler/checkerUtilities"; +} from "../../compiler/checker/utilities"; import { concatenate, createMultiMap, @@ -30,9 +30,9 @@ import { isReturnStatement, isVariableDeclaration, } from "../../compiler/factory/nodeTests"; -import { forEachChild } from "../../compiler/parser"; -import { forEachReturnStatement } from "../../compiler/parserUtilities"; -import { skipTrivia } from "../../compiler/scanner"; +import { forEachChild } from "../../compiler/parser/parser"; +import { forEachReturnStatement } from "../../compiler/parser/utilities"; +import { skipTrivia } from "../../compiler/scanner/scanner"; import { ArrowFunction, AwaitExpression, diff --git a/src/services/codefixes/convertToEsModule.ts b/src/services/codefixes/convertToEsModule.ts index de65fff5d1934..68a342670fa7c 100644 --- a/src/services/codefixes/convertToEsModule.ts +++ b/src/services/codefixes/convertToEsModule.ts @@ -27,7 +27,7 @@ import { isPropertyAccessExpression, isVariableStatement, } from "../../compiler/factory/nodeTests"; -import { getModeForUsageLocation } from "../../compiler/program"; +import { getModeForUsageLocation } from "../../compiler/program/program"; import { __String, ArrowFunction, diff --git a/src/services/codefixes/convertToTypeOnlyExport.ts b/src/services/codefixes/convertToTypeOnlyExport.ts index 3c34f40563ad1..b102a5f2f3a6b 100644 --- a/src/services/codefixes/convertToTypeOnlyExport.ts +++ b/src/services/codefixes/convertToTypeOnlyExport.ts @@ -1,4 +1,4 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; +import { getNodeId } from "../../compiler/checker/utilities"; import { contains, filter, diff --git a/src/services/codefixes/disableJsDiagnostics.ts b/src/services/codefixes/disableJsDiagnostics.ts index f189fb4b31480..1a77b53487b6b 100644 --- a/src/services/codefixes/disableJsDiagnostics.ts +++ b/src/services/codefixes/disableJsDiagnostics.ts @@ -3,7 +3,7 @@ import { tryAddToSet, } from "../../compiler/core"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; -import { getLineAndCharacterOfPosition } from "../../compiler/scanner"; +import { getLineAndCharacterOfPosition } from "../../compiler/scanner/scanner"; import { DiagnosticCategory, SourceFile, diff --git a/src/services/codefixes/fixAddMissingConstraint.ts b/src/services/codefixes/fixAddMissingConstraint.ts index 64f75f6eb9d4e..054381f4c96a9 100644 --- a/src/services/codefixes/fixAddMissingConstraint.ts +++ b/src/services/codefixes/fixAddMissingConstraint.ts @@ -1,4 +1,4 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; +import { getNodeId } from "../../compiler/checker/utilities"; import { find, isString, @@ -10,7 +10,7 @@ import { isMappedTypeNode, isTypeParameterDeclaration, } from "../../compiler/factory/nodeTests"; -import { flattenDiagnosticMessageText } from "../../compiler/program"; +import { flattenDiagnosticMessageText } from "../../compiler/program/program"; import { DiagnosticMessageChain, Node, diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index bf54e55bd31f2..cb28fa2c30952 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -1,5 +1,5 @@ import * as Debug from "../../compiler/debug"; -import { getNodeId } from "../../compiler/checkerUtilities"; +import { getNodeId } from "../../compiler/checker/utilities"; import { arrayFrom, concatenate, @@ -45,8 +45,8 @@ import { isTypeLiteralNode, } from "../../compiler/factory/nodeTests"; import { createPropertyNameNodeForIdentifierOrLiteral } from "../../compiler/factory/utilities"; -import { setParent } from "../../compiler/parserUtilities"; -import { isIdentifierText } from "../../compiler/scanner"; +import { setParent } from "../../compiler/parser/utilities"; +import { isIdentifierText } from "../../compiler/scanner/scanner"; import { __String, BigIntLiteralType, diff --git a/src/services/codefixes/fixAddVoidToPromise.ts b/src/services/codefixes/fixAddVoidToPromise.ts index 424a2bfac4bd8..73dbfc0e8d8b7 100644 --- a/src/services/codefixes/fixAddVoidToPromise.ts +++ b/src/services/codefixes/fixAddVoidToPromise.ts @@ -11,7 +11,7 @@ import { isTypeReferenceNode, isUnionTypeNode, } from "../../compiler/factory/nodeTests"; -import { skipTrivia } from "../../compiler/scanner"; +import { skipTrivia } from "../../compiler/scanner/scanner"; import { NewExpression, ParameterDeclaration, diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts index 1176287bd550e..24381ef27e996 100644 --- a/src/services/codefixes/fixAwaitInSyncFunction.ts +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -1,4 +1,4 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; +import { getNodeId } from "../../compiler/checker/utilities"; import { first } from "../../compiler/core"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts index b56ff15cdfa46..ce61ebe6ea048 100644 --- a/src/services/codefixes/fixCannotFindModule.ts +++ b/src/services/codefixes/fixCannotFindModule.ts @@ -5,7 +5,7 @@ import { isStringLiteral } from "../../compiler/factory/nodeTests"; import { getTypesPackageName, parsePackageName, -} from "../../compiler/moduleNameResolver"; +} from "../../compiler/moduleNameResolver/moduleNameResolver"; import { SourceFile } from "../../compiler/types"; import { isExternalModuleNameRelative } from "../../compiler/utilitiesPublic"; import { nodeCoreModules } from "../../jsTyping/jsTyping"; diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index 8d51f696d812a..b5098e9fe04bb 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -1,4 +1,4 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; +import { getNodeId } from "../../compiler/checker/utilities"; import { cast, first, diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 08fd925606636..703f143b93487 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -1,5 +1,5 @@ import * as Debug from "../../compiler/debug"; -import { getNodeId } from "../../compiler/checkerUtilities"; +import { getNodeId } from "../../compiler/checker/utilities"; import { and, find, diff --git a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts index 0f68e5064e616..2f9f394559c70 100644 --- a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts +++ b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts @@ -1,10 +1,10 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; +import { getNodeId } from "../../compiler/checker/utilities"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { isExpressionStatement, isPropertyAccessExpression, } from "../../compiler/factory/nodeTests"; -import { forEachChild } from "../../compiler/parser"; +import { forEachChild } from "../../compiler/parser/parser"; import { CallExpression, ConstructorDeclaration, diff --git a/src/services/codefixes/fixNaNEquality.ts b/src/services/codefixes/fixNaNEquality.ts index e444e47a32752..2f5c876fef5ab 100644 --- a/src/services/codefixes/fixNaNEquality.ts +++ b/src/services/codefixes/fixNaNEquality.ts @@ -2,7 +2,7 @@ import { find } from "../../compiler/core"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { isBinaryExpression } from "../../compiler/factory/nodeTests"; -import { flattenDiagnosticMessageText } from "../../compiler/program"; +import { flattenDiagnosticMessageText } from "../../compiler/program/program"; import { BinaryExpression, DiagnosticMessageChain, diff --git a/src/services/codefixes/fixOverrideModifier.ts b/src/services/codefixes/fixOverrideModifier.ts index 68a49af0dd701..ff9c39b8483b5 100644 --- a/src/services/codefixes/fixOverrideModifier.ts +++ b/src/services/codefixes/fixOverrideModifier.ts @@ -14,7 +14,7 @@ import { isOverrideModifier, isStaticModifier, } from "../../compiler/factory/nodeTests"; -import { skipTrivia } from "../../compiler/scanner"; +import { skipTrivia } from "../../compiler/scanner/scanner"; import { ConstructorDeclaration, DiagnosticMessage, diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts index 23f5c66727f50..10526f3f038b3 100644 --- a/src/services/codefixes/fixSpelling.ts +++ b/src/services/codefixes/fixSpelling.ts @@ -11,8 +11,8 @@ import { isPropertyAccessExpression, isQualifiedName, } from "../../compiler/factory/nodeTests"; -import { getModeForUsageLocation } from "../../compiler/program"; -import { isIdentifierText } from "../../compiler/scanner"; +import { getModeForUsageLocation } from "../../compiler/program/program"; +import { isIdentifierText } from "../../compiler/scanner/scanner"; import { ImportDeclaration, ModifierFlags, diff --git a/src/services/codefixes/fixUnusedLabel.ts b/src/services/codefixes/fixUnusedLabel.ts index d49b68b66e0ea..172d45cbc8f5c 100644 --- a/src/services/codefixes/fixUnusedLabel.ts +++ b/src/services/codefixes/fixUnusedLabel.ts @@ -1,7 +1,7 @@ import { cast } from "../../compiler/core"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { isLabeledStatement } from "../../compiler/factory/nodeTests"; -import { skipTrivia } from "../../compiler/scanner"; +import { skipTrivia } from "../../compiler/scanner/scanner"; import { SourceFile, SyntaxKind, diff --git a/src/services/codefixes/importAdder.ts b/src/services/codefixes/importAdder.ts index d98ed5deb2c15..74ec798461a42 100644 --- a/src/services/codefixes/importAdder.ts +++ b/src/services/codefixes/importAdder.ts @@ -2,7 +2,7 @@ import * as Debug from "../../compiler/debug"; import { getNodeId, getSymbolId, -} from "../../compiler/checkerUtilities"; +} from "../../compiler/checker/utilities"; import { arrayFrom, cast, @@ -42,11 +42,11 @@ import { isNamespaceImport, isStringLiteral, } from "../../compiler/factory/nodeTests"; -import { pathContainsNodeModules } from "../../compiler/moduleNameResolver"; +import { pathContainsNodeModules } from "../../compiler/moduleNameResolver/moduleNameResolver"; import { getModuleSpecifiersWithCacheInfo, tryGetModuleSpecifiersFromCache, -} from "../../compiler/moduleSpecifiers"; +} from "../../compiler/moduleSpecifiers/moduleSpecifiers"; import { getBaseFileName, getDirectoryPath, @@ -56,7 +56,7 @@ import { import { isIdentifierPart, isIdentifierStart, -} from "../../compiler/scanner"; +} from "../../compiler/scanner/scanner"; import { AnyImportOrRequire, AnyImportOrRequireStatement, @@ -109,7 +109,6 @@ import { isValidTypeOnlyAliasUseSite, isVariableDeclarationInitializedToRequire, nodeIsMissing, - removeFileExtension, skipAlias, stripQuotes, tryGetModuleSpecifierFromDeclaration, @@ -167,6 +166,7 @@ import { SemanticMeaning, shouldUseUriStyleNodeCoreModules, } from "../utilities"; +import { removeFileExtension } from "../../compiler/extension"; /** @internal */ export const fixName = "import"; diff --git a/src/services/completions.ts b/src/services/completions.ts index 19e0e6c4a5f81..8a2c28f5cdd01 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { getSymbolId } from "../compiler/checkerUtilities"; +import { getSymbolId } from "../compiler/checker/utilities"; import { append, cast, @@ -36,7 +36,7 @@ import { SortedArray, } from "../compiler/corePublic"; import { Diagnostics } from "../compiler/diagnosticInformationMap.generated"; -import { createPrinter } from "../compiler/emitter"; +import { createPrinter } from "../compiler/emitter/emitter"; import { setSnippetElement } from "../compiler/factory/emitNode"; import { factory } from "../compiler/factory/nodeFactory"; import { @@ -101,8 +101,8 @@ import { isIdentifierText, stringToToken, tokenToString, -} from "../compiler/scanner"; -import { getNewLineCharacter } from "../compiler/sysUtilities"; +} from "../compiler/scanner/scanner"; +import { getNewLineCharacter } from "../compiler/sys/utilities"; import { isInitializedProperty } from "../compiler/transformers/utilities"; import { __String, diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index 1d633fcd0382d..0fa7995928370 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -36,8 +36,8 @@ import { isVariableStatement, isYieldExpression, } from "../compiler/factory/nodeTests"; -import { forEachChild } from "../compiler/parser"; -import { forEachReturnStatement } from "../compiler/parserUtilities"; +import { forEachChild } from "../compiler/parser/parser"; +import { forEachReturnStatement } from "../compiler/parser/utilities"; import { toPath } from "../compiler/path"; import { __String, diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index 70535cbcde68d..b32f35b9353d3 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -1,7 +1,7 @@ import * as Debug from "../compiler/debug"; import { sourceFileAffectingCompilerOptions, -} from "../compiler/commandLineParser"; +} from "../compiler/commandLineParser/commandLineParser"; import { arrayFrom, createGetCanonicalFileName, @@ -9,16 +9,16 @@ import { getOrUpdate, identity, } from "../compiler/core"; -import { getKeyForCompilerOptions } from "../compiler/moduleNameResolver"; +import { getKeyForCompilerOptions } from "../compiler/moduleNameResolver/moduleNameResolver"; import { CreateSourceFileOptions, isDeclarationFileName, -} from "../compiler/parser"; +} from "../compiler/parser/parser"; import { toPath } from "../compiler/path"; import { getImpliedNodeFormatForFile, getSetExternalModuleIndicator, -} from "../compiler/program"; +} from "../compiler/program/program"; import { tracing } from "../compiler/tracing"; import { CompilerOptions, diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index 2bc98e7539aab..d047cb1348a3c 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { getSymbolId } from "../compiler/checkerUtilities"; +import { getSymbolId } from "../compiler/checker/utilities"; import { arrayIsEqualTo, createMultiMap, @@ -25,9 +25,9 @@ import { getPackageNameFromTypesPackageName, nodeModulesPathPart, unmangleScopedPackageName, -} from "../compiler/moduleNameResolver"; -import { forEachFileNameOfModule } from "../compiler/moduleSpecifiers"; -import { getNodeModulePathParts } from "../compiler/moduleSpecifiersUtilities"; +} from "../compiler/moduleNameResolver/moduleNameResolver"; +import { forEachFileNameOfModule } from "../compiler/moduleSpecifiers/moduleSpecifiers"; +import { getNodeModulePathParts } from "../compiler/moduleSpecifiers/utilities"; import { forEachAncestorDirectory, getBaseFileName, diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 8675def74e088..e30c45235892f 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -2,7 +2,7 @@ import * as Debug from "../compiler/debug"; import { getNodeId, getSymbolId, -} from "../compiler/checkerUtilities"; +} from "../compiler/checker/utilities"; import { append, cast, @@ -63,18 +63,18 @@ import { isUnionTypeNode, isVoidExpression, } from "../compiler/factory/nodeTests"; -import { forEachChild } from "../compiler/parser"; -import { forEachReturnStatement } from "../compiler/parserUtilities"; +import { forEachChild } from "../compiler/parser/parser"; +import { forEachReturnStatement } from "../compiler/parser/utilities"; import { getModeForUsageLocation, getReferencedFileLocation, isReferencedFile, isReferenceFileLocation, -} from "../compiler/program"; +} from "../compiler/program/program"; import { isIdentifierPart, tokenToString, -} from "../compiler/scanner"; +} from "../compiler/scanner/scanner"; import { __String, AssignmentDeclarationKind, diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index b87fba826b513..b9de579257967 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -9,7 +9,7 @@ import { } from "../../compiler/core"; import { isDecorator } from "../../compiler/factory/nodeTests"; import { canHaveModifiers } from "../../compiler/factory/utilitiesPublic"; -import { forEachChild } from "../../compiler/parser"; +import { forEachChild } from "../../compiler/parser/parser"; import { Block, CallExpression, diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index 1ca1728d19484..73de8c7b578af 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -8,7 +8,7 @@ import { isJsxElement, isJsxText, } from "../../compiler/factory/nodeTests"; -import { createScanner } from "../../compiler/scanner"; +import { createScanner } from "../../compiler/scanner/scanner"; import { LanguageVariant, Node, diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 66a59be95428c..cee053369d6d1 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -12,7 +12,7 @@ import { import { getLineAndCharacterOfPosition, skipTrivia, -} from "../../compiler/scanner"; +} from "../../compiler/scanner/scanner"; import { ArrayBindingPattern, ArrayLiteralExpression, diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index 966646a0ee147..339634d49f28f 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { getOptionFromName } from "../compiler/commandLineParser"; +import { getOptionFromName } from "../compiler/commandLineParser/commandLineParser"; import { createGetCanonicalFileName, emptyArray, @@ -22,8 +22,8 @@ import { getFileMatcherPatterns, getRegexFromPattern, } from "../compiler/fileMatcher"; -import { resolveModuleName } from "../compiler/moduleNameResolver"; -import { updateModuleSpecifier } from "../compiler/moduleSpecifiers"; +import { resolveModuleName } from "../compiler/moduleNameResolver/moduleNameResolver"; +import { updateModuleSpecifier } from "../compiler/moduleSpecifiers/moduleSpecifiers"; import { combinePaths, ensurePathIsNonModuleName, @@ -33,7 +33,7 @@ import { normalizePath, pathIsRelative, } from "../compiler/path"; -import { getModeForUsageLocation } from "../compiler/program"; +import { getModeForUsageLocation } from "../compiler/program/program"; import { Expression, ModuleResolutionHost, diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 9f87c6bec4389..9add5e2ecd6d8 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -26,13 +26,13 @@ import { isStaticModifier, isVariableDeclaration, } from "../compiler/factory/nodeTests"; -import { isDeclarationFileName } from "../compiler/parser"; +import { isDeclarationFileName } from "../compiler/parser/parser"; import { getDirectoryPath, resolvePath, } from "../compiler/path"; -import { getModeForUsageLocation } from "../compiler/program"; -import { skipTrivia } from "../compiler/scanner"; +import { getModeForUsageLocation } from "../compiler/program/program"; +import { skipTrivia } from "../compiler/scanner/scanner"; import { AssignmentDeclarationKind, AssignmentExpression, diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 40683724118fb..d4b417779dcc5 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { getSymbolId } from "../compiler/checkerUtilities"; +import { getSymbolId } from "../compiler/checker/utilities"; import { cast, forEach, diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts index 114d85d5989f5..41805065820ec 100644 --- a/src/services/inlayHints.ts +++ b/src/services/inlayHints.ts @@ -3,7 +3,7 @@ import { equateStringsCaseInsensitive, some, } from "../compiler/core"; -import { createPrinter } from "../compiler/emitter"; +import { createPrinter } from "../compiler/emitter/emitter"; import { isArrowFunction, isCallExpression, @@ -21,11 +21,11 @@ import { isPropertyDeclaration, isVariableDeclaration, } from "../compiler/factory/nodeTests"; -import { forEachChild } from "../compiler/parser"; +import { forEachChild } from "../compiler/parser/parser"; import { getLeadingCommentRanges, isIdentifierText, -} from "../compiler/scanner"; +} from "../compiler/scanner/scanner"; import { __String, ArrowFunction, diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 3682234c2031d..1e991ffa7a56d 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -25,7 +25,7 @@ import { isJSDoc, isJSDocParameterTag, } from "../compiler/factory/nodeTests"; -import { forEachReturnStatement } from "../compiler/parserUtilities"; +import { forEachReturnStatement } from "../compiler/parser/utilities"; import { ArrowFunction, AssignmentDeclarationKind, diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 86dc56c2c2793..5cd2be07fcdc9 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -30,7 +30,7 @@ import { isVariableDeclaration, } from "../compiler/factory/nodeTests"; import { setTextRange } from "../compiler/factory/utilitiesPublic"; -import { forEachChild } from "../compiler/parser"; +import { forEachChild } from "../compiler/parser/parser"; import { getBaseFileName, normalizePath, @@ -97,7 +97,6 @@ import { isJSDocTypeAlias, isPropertyNameLiteral, isStatic, - removeFileExtension, } from "../compiler/utilities"; import { getNameOfDeclaration, @@ -123,6 +122,7 @@ import { getNodeKind, getNodeModifiers, } from "./utilities"; +import { removeFileExtension } from "../compiler/extension"; /** * Matches all whitespace characters in a string. Eg: diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index 8ab34110e8cd0..4ea027406c373 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -35,7 +35,7 @@ import { import { createScanner, Scanner, -} from "../compiler/scanner"; +} from "../compiler/scanner/scanner"; import { AnyImportOrRequireStatement, EmitFlags, diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 4ee7e84c44d39..a75c89f3b4e08 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -21,7 +21,7 @@ import { isTupleTypeNode, isVariableStatement, } from "../compiler/factory/nodeTests"; -import { getLeadingCommentRanges } from "../compiler/scanner"; +import { getLeadingCommentRanges } from "../compiler/scanner/scanner"; import { ArrowFunction, AssertClause, diff --git a/src/services/patternMatcher.ts b/src/services/patternMatcher.ts index 22717693aa4eb..f94a6bf4afdb8 100644 --- a/src/services/patternMatcher.ts +++ b/src/services/patternMatcher.ts @@ -6,7 +6,7 @@ import { startsWith, } from "../compiler/core"; import { Comparison } from "../compiler/corePublic"; -import { isUnicodeIdentifierStart } from "../compiler/scanner"; +import { isUnicodeIdentifierStart } from "../compiler/scanner/scanner"; import { CharacterCodes, ScriptTarget, diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 0a70897ae0a0c..30ac5b13e5b05 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -6,7 +6,7 @@ import { import { processCommentPragmas, processPragmasIntoFields, -} from "../compiler/parser"; +} from "../compiler/parser/parser"; import { FileReference, PragmaContext, diff --git a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts index 4a44c784c6120..a1cf564b81081 100644 --- a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts +++ b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts @@ -16,7 +16,7 @@ import { isVariableDeclarationList, isVariableStatement, } from "../../compiler/factory/nodeTests"; -import { forEachChild } from "../../compiler/parser"; +import { forEachChild } from "../../compiler/parser/parser"; import { ArrowFunction, Block, diff --git a/src/services/refactors/convertStringOrTemplateLiteral.ts b/src/services/refactors/convertStringOrTemplateLiteral.ts index a3bec9e9a31f7..adc49f1e9a4fd 100644 --- a/src/services/refactors/convertStringOrTemplateLiteral.ts +++ b/src/services/refactors/convertStringOrTemplateLiteral.ts @@ -14,7 +14,7 @@ import { isTemplateHead, isTemplateMiddle, } from "../../compiler/factory/nodeTests"; -import { getTrailingCommentRanges } from "../../compiler/scanner"; +import { getTrailingCommentRanges } from "../../compiler/scanner/scanner"; import { BinaryExpression, BinaryOperator, diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 21ee0d7d05e79..5bc15d69b498f 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -2,7 +2,7 @@ import * as Debug from "../../compiler/debug"; import { getNodeId, getSymbolId, -} from "../../compiler/checkerUtilities"; +} from "../../compiler/checker/utilities"; import { arrayFrom, assertType, @@ -53,8 +53,8 @@ import { isVariableStatement, } from "../../compiler/factory/nodeTests"; import { canHaveModifiers } from "../../compiler/factory/utilitiesPublic"; -import { forEachChild } from "../../compiler/parser"; -import { positionIsSynthesized } from "../../compiler/scannerUtilities"; +import { forEachChild } from "../../compiler/parser/parser"; +import { positionIsSynthesized } from "../../compiler/scanner/utilities"; import { nullTransformationContext } from "../../compiler/transformer"; import { __String, diff --git a/src/services/refactors/extractType.ts b/src/services/refactors/extractType.ts index 7451469f869ae..96f7fcf39e8e8 100644 --- a/src/services/refactors/extractType.ts +++ b/src/services/refactors/extractType.ts @@ -31,11 +31,11 @@ import { isTypeReferenceNode, } from "../../compiler/factory/nodeTests"; import { setTextRange } from "../../compiler/factory/utilitiesPublic"; -import { forEachChild } from "../../compiler/parser"; +import { forEachChild } from "../../compiler/parser/parser"; import { getLineAndCharacterOfPosition, skipTrivia, -} from "../../compiler/scanner"; +} from "../../compiler/scanner/scanner"; import { EmitFlags, JSDocTag, diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index 94837fcc58088..d18838c2992a6 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -1,5 +1,5 @@ import * as Debug from "../../compiler/debug"; -import { getSymbolId } from "../../compiler/checkerUtilities"; +import { getSymbolId } from "../../compiler/checker/utilities"; import { append, cast, @@ -44,7 +44,7 @@ import { canHaveDecorators, canHaveModifiers, } from "../../compiler/factory/utilitiesPublic"; -import { getModuleSpecifier } from "../../compiler/moduleSpecifiers"; +import { getModuleSpecifier } from "../../compiler/moduleSpecifiers/moduleSpecifiers"; import { combinePaths, getBaseFileName, @@ -102,7 +102,6 @@ import { } from "../../compiler/types"; import { copyEntries, - extensionFromPath, forEachEntry, getAssignmentDeclarationKind, getLocaleSpecificMessage, @@ -146,6 +145,7 @@ import { rangeContainsRange, symbolNameNoDefault, } from "../utilities"; +import { extensionFromPath } from "../../compiler/extension"; const refactorName = "Move to a new file"; const description = getLocaleSpecificMessage(Diagnostics.Move_to_a_new_file); diff --git a/src/services/rename.ts b/src/services/rename.ts index d538d595a0356..eca3c205f3ca7 100644 --- a/src/services/rename.ts +++ b/src/services/rename.ts @@ -8,6 +8,7 @@ import { } from "../compiler/core"; import { Comparison } from "../compiler/corePublic"; import { Diagnostics } from "../compiler/diagnosticInformationMap.generated"; +import { removeFileExtension } from "../compiler/extension"; import { isIdentifier, isImportSpecifier, @@ -40,7 +41,6 @@ import { getTextOfIdentifierOrLiteral, getTextOfNode, isStringOrNumericLiteralLike, - removeFileExtension, stripQuotes, tryGetImportFromModuleSpecifier, } from "../compiler/utilities"; diff --git a/src/services/services.ts b/src/services/services.ts index 00187e3dd83b6..1d2555aa525e7 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3,7 +3,7 @@ import { getFileEmitOutput } from "../compiler/builderState"; import { ParseConfigFileHost, parseJsonSourceFileConfigFileContent, -} from "../compiler/commandLineParser"; +} from "../compiler/commandLineParser/commandLineParser"; import { compareValues, createGetCanonicalFileName, @@ -54,7 +54,7 @@ import { isPropertyAccessExpression, } from "../compiler/factory/nodeTests"; import { getSnippetElement } from "../compiler/factory/emitNode"; -import { ModeAwareCache } from "../compiler/moduleNameResolver"; +import { ModeAwareCache } from "../compiler/moduleNameResolver/moduleNameResolver"; import { ObjectAllocator, setObjectAllocator, @@ -65,7 +65,7 @@ import { forEachChild, tagNamesAreEquivalent, updateSourceFile, -} from "../compiler/parser"; +} from "../compiler/parser/parser"; import { combinePaths, getDirectoryPath, @@ -80,15 +80,15 @@ import { getImpliedNodeFormatForFile, getSetExternalModuleIndicator, isProgramUptoDate, -} from "../compiler/program"; +} from "../compiler/program/program"; import { computePositionOfLineAndCharacter, getLineAndCharacterOfPosition, getLineStarts, -} from "../compiler/scanner"; -import { positionIsSynthesized } from "../compiler/scannerUtilities"; -import { sys } from "../compiler/sys"; -import { getNewLineCharacter } from "../compiler/sysUtilities"; +} from "../compiler/scanner/scanner"; +import { positionIsSynthesized } from "../compiler/scanner/utilities"; +import { sys } from "../compiler/sys/sys"; +import { getNewLineCharacter } from "../compiler/sys/utilities"; import { tracing } from "../compiler/tracing"; import { __String, diff --git a/src/services/shims.ts b/src/services/shims.ts index 5123ff31604a6..e1d1feee471f6 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -1,7 +1,7 @@ import { EmitOutput } from "../compiler/builderStatePublic"; import { parseJsonSourceFileConfigFileContent, -} from "../compiler/commandLineParser"; +} from "../compiler/commandLineParser/commandLineParser"; import { clear, createGetCanonicalFileName, @@ -12,20 +12,21 @@ import { toFileNameLowerCase, } from "../compiler/core"; import { MapLike } from "../compiler/corePublic"; +import { extensionFromPath } from "../compiler/extension"; import { getFileMatcherPatterns } from "../compiler/fileMatcher"; import { getAutomaticTypeDirectiveNames, resolveModuleName, resolveTypeReferenceDirective, -} from "../compiler/moduleNameResolver"; -import { parseJsonText } from "../compiler/parser"; +} from "../compiler/moduleNameResolver/moduleNameResolver"; +import { parseJsonText } from "../compiler/parser/parser"; import { getDirectoryPath, normalizeSlashes, toPath, } from "../compiler/path"; import { timestamp } from "../compiler/performanceCore"; -import { flattenDiagnosticMessageText } from "../compiler/program"; +import { flattenDiagnosticMessageText } from "../compiler/program/program"; import { CompilerOptions, Diagnostic, @@ -44,7 +45,6 @@ import { TypeAcquisition, UserPreferences, } from "../compiler/types"; -import { extensionFromPath } from "../compiler/utilities"; import { createTextChangeRange, createTextSpan, diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 1b6b3f64955fe..b873f8fe481eb 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -13,7 +13,7 @@ import { map, tryCast, } from "../compiler/core"; -import { createPrinter } from "../compiler/emitter"; +import { createPrinter } from "../compiler/emitter/emitter"; import { factory } from "../compiler/factory/nodeFactory"; import { isBinaryExpression, @@ -29,7 +29,7 @@ import { isTemplateSpan, isTemplateTail, } from "../compiler/factory/nodeTests"; -import { skipTrivia } from "../compiler/scanner"; +import { skipTrivia } from "../compiler/scanner/scanner"; import { ArrowFunction, BinaryExpression, diff --git a/src/services/smartSelection.ts b/src/services/smartSelection.ts index 77b4b18632f20..bdcf8d3b06656 100644 --- a/src/services/smartSelection.ts +++ b/src/services/smartSelection.ts @@ -29,8 +29,8 @@ import { isVariableDeclarationList, isVariableStatement, } from "../compiler/factory/nodeTests"; -import { parseNodeFactory } from "../compiler/parser"; -import { getTrailingCommentRanges } from "../compiler/scanner"; +import { parseNodeFactory } from "../compiler/parser/parser"; +import { getTrailingCommentRanges } from "../compiler/scanner/scanner"; import { CharacterCodes, Node, diff --git a/src/services/sourcemaps.ts b/src/services/sourcemaps.ts index 7b37a9bcdec70..d9c82473a0ebb 100644 --- a/src/services/sourcemaps.ts +++ b/src/services/sourcemaps.ts @@ -2,7 +2,9 @@ import { createGetCanonicalFileName, isString, } from "../compiler/core"; -import { isDeclarationFileName } from "../compiler/parser"; +import { getDeclarationEmitOutputFilePathWorker } from "../compiler/emitter/utilities"; +import { removeFileExtension } from "../compiler/extension"; +import { isDeclarationFileName } from "../compiler/parser/parser"; import { getDirectoryPath, getNormalizedAbsolutePath, @@ -11,7 +13,7 @@ import { import { computeLineAndCharacterOfPosition, getLineStarts, -} from "../compiler/scanner"; +} from "../compiler/scanner/scanner"; import { createDocumentPositionMapper, getLineInfo, @@ -20,7 +22,7 @@ import { tryGetSourceMappingURL, tryParseRawSourceMap, } from "../compiler/sourcemap"; -import { sys } from "../compiler/sys"; +import { sys } from "../compiler/sys/sys"; import { DocumentPosition, DocumentPositionMapper, @@ -32,9 +34,7 @@ import { } from "../compiler/types"; import { base64decode, - getDeclarationEmitOutputFilePathWorker, outFile, - removeFileExtension, } from "../compiler/utilities"; const base64UrlRegExp = /^data:(?:application\/json(?:;charset=[uU][tT][fF]-8);base64,([A-Za-z0-9+\/=]+)$)?/; diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 08b79f48ae0e3..6b38adb9df8fd 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { readJson } from "../compiler/commandLineParserUtilities"; +import { readJson } from "../compiler/commandLineParser/utilities"; import { arrayFrom, compareStringsCaseSensitive, @@ -48,9 +48,9 @@ import { getPackageJsonTypesVersionsPaths, isApplicableVersionedTypesKey, unmangleScopedPackageName, -} from "../compiler/moduleNameResolver"; -import { tryGetJSExtensionForFile, tryGetRealFileNameForNonJsDeclarationFileName } from "../compiler/moduleSpecifiers"; -import { getModuleSpecifierEndingPreference } from "../compiler/moduleSpecifiersUtilities"; +} from "../compiler/moduleNameResolver/moduleNameResolver"; +import { tryGetJSExtensionForFile, tryGetRealFileNameForNonJsDeclarationFileName } from "../compiler/moduleSpecifiers/moduleSpecifiers"; +import { getModuleSpecifierEndingPreference } from "../compiler/moduleSpecifiers/utilities"; import { altDirectorySeparator, combinePaths, @@ -71,11 +71,11 @@ import { removeTrailingDirectorySeparator, resolvePath, } from "../compiler/path"; -import { getModeForUsageLocation } from "../compiler/program"; +import { getModeForUsageLocation } from "../compiler/program/program"; import { getLeadingCommentRanges, isIdentifierText, -} from "../compiler/scanner"; +} from "../compiler/scanner/scanner"; import { CallLikeExpression, CancellationToken, @@ -111,17 +111,14 @@ import { } from "../compiler/types"; import { addToSeen, - changeExtension, getEmitModuleResolutionKind, getResolvePackageJsonExports, hostGetCanonicalFileName, isImportCall, ModuleSpecifierEnding, - removeFileExtension, signatureHasRestParameter, skipParentheses, stripQuotes, - tryGetExtensionFromPath, tryParsePattern, tryRemoveDirectoryPrefix, walkUpParenthesizedExpressions, @@ -176,9 +173,12 @@ import { tryReadDirectory, } from "./utilities"; import { + changeExtension, getSupportedExtensions, getSupportedExtensionsWithJsonIfResolveJsonModule, + removeFileExtension, supportedTSImplementationExtensions, + tryGetExtensionFromPath, } from "../compiler/extension"; interface NameAndKindSet { diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 5e57564732ee4..77af348759ad8 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -18,9 +18,9 @@ import { isVariableDeclaration, isVariableStatement, } from "../compiler/factory/nodeTests"; -import { forEachReturnStatement } from "../compiler/parserUtilities"; +import { forEachReturnStatement } from "../compiler/parser/utilities"; import { fileExtensionIsOneOf } from "../compiler/path"; -import { getModeForUsageLocation } from "../compiler/program"; +import { getModeForUsageLocation } from "../compiler/program/program"; import { AnyValidImportOrReExport, ArrowFunction, diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index e8f7cf8e30440..42f73e130e311 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -11,7 +11,7 @@ import { length, some, } from "../compiler/core"; -import { createPrinter } from "../compiler/emitter"; +import { createPrinter } from "../compiler/emitter/emitter"; import { isArrowFunction, isBindingElement, diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 8a6c94a75202b..11e9c07979d99 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { getNodeId } from "../compiler/checkerUtilities"; +import { getNodeId } from "../compiler/checker/utilities"; import { concatenate, contains, @@ -26,7 +26,7 @@ import { singleOrUndefined, stableSort, } from "../compiler/core"; -import { createPrinter } from "../compiler/emitter"; +import { createPrinter } from "../compiler/emitter/emitter"; import { createNodeFactory, factory, @@ -51,7 +51,7 @@ import { isStringLiteral, isVariableDeclaration, } from "../compiler/factory/nodeTests"; -import { createSourceFile } from "../compiler/parser"; +import { createSourceFile } from "../compiler/parser/parser"; import { getLeadingCommentRanges, getLineAndCharacterOfPosition, @@ -59,7 +59,7 @@ import { getTrailingCommentRanges, skipTrivia, tokenToString, -} from "../compiler/scanner"; +} from "../compiler/scanner/scanner"; import { nullTransformationContext } from "../compiler/transformer"; import { ArrowFunction, diff --git a/src/services/transpile.ts b/src/services/transpile.ts index 95a4f79b63be1..ae0433bebf8f2 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -4,7 +4,7 @@ import { optionDeclarations, parseCustomTypeOption, transpileOptionValueCompilerOptions, -} from "../compiler/commandLineParser"; +} from "../compiler/commandLineParser/commandLineParser"; import { addRange, filter, @@ -12,7 +12,7 @@ import { isString, } from "../compiler/core"; import { MapLike } from "../compiler/corePublic"; -import { createSourceFile } from "../compiler/parser"; +import { createSourceFile } from "../compiler/parser/parser"; import { fileExtensionIs, normalizePath, @@ -22,8 +22,8 @@ import { createProgram, getImpliedNodeFormatForFile, getSetExternalModuleIndicator, -} from "../compiler/program"; -import { getNewLineCharacter } from "../compiler/sysUtilities"; +} from "../compiler/program/program"; +import { getNewLineCharacter } from "../compiler/sys/utilities"; import { CommandLineOptionOfCustomType, CompilerHost, diff --git a/src/services/types.ts b/src/services/types.ts index 5c4e59b510537..c46871d7bf80a 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -1,5 +1,5 @@ import { EmitOutput } from "../compiler/builderStatePublic"; -import { ModuleResolutionCache } from "../compiler/moduleNameResolver"; +import { ModuleResolutionCache } from "../compiler/moduleNameResolver/moduleNameResolver"; import { SymlinkCache } from "../compiler/symlinkCache"; import { __String, diff --git a/src/services/utilities.ts b/src/services/utilities.ts index d0c92541bb88a..fdb3ba0619c91 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -6,8 +6,8 @@ import { import { getNodeId, getSymbolId, -} from "../compiler/checkerUtilities"; -import { setConfigFileInOptions } from "../compiler/commandLineParser"; +} from "../compiler/checker/utilities"; +import { setConfigFileInOptions } from "../compiler/commandLineParser/commandLineParser"; import { assertType, binarySearchKey, @@ -41,7 +41,7 @@ import { tryCast, } from "../compiler/core"; import { Comparison } from "../compiler/corePublic"; -import { createPrinter } from "../compiler/emitter"; +import { createPrinter } from "../compiler/emitter/emitter"; import { addEmitFlags, addSyntheticLeadingComment, @@ -131,10 +131,10 @@ import { import { getPackageNameFromTypesPackageName, getTypesPackageName, -} from "../compiler/moduleNameResolver"; -import { getNodeModulesPackageName } from "../compiler/moduleSpecifiers"; -import { forEachChild } from "../compiler/parser"; -import { getLastChild } from "../compiler/parserUtilities"; +} from "../compiler/moduleNameResolver/moduleNameResolver"; +import { getNodeModulesPackageName } from "../compiler/moduleSpecifiers/moduleSpecifiers"; +import { forEachChild } from "../compiler/parser/parser"; +import { getLastChild } from "../compiler/parser/utilities"; import { combinePaths, forEachAncestorDirectory, @@ -144,7 +144,7 @@ import { normalizePath, pathIsRelative, } from "../compiler/path"; -import { findConfigFile } from "../compiler/program"; +import { findConfigFile } from "../compiler/program/program"; import { createScanner, forEachLeadingCommentRange, @@ -155,7 +155,7 @@ import { Scanner, stringToToken, tokenToString, -} from "../compiler/scanner"; +} from "../compiler/scanner/scanner"; import { nullTransformationContext } from "../compiler/transformer"; import { __String, diff --git a/src/testRunner/unittests/parsePseudoBigInt.ts b/src/testRunner/unittests/parsePseudoBigInt.ts index cadf1f566f584..d4625067862fe 100644 --- a/src/testRunner/unittests/parsePseudoBigInt.ts +++ b/src/testRunner/unittests/parsePseudoBigInt.ts @@ -1,4 +1,4 @@ -import { parsePseudoBigInt } from "../../compiler/scannerUtilities"; +import { parsePseudoBigInt } from "../../compiler/scanner/utilities"; describe("unittests:: BigInt literal base conversions", () => { describe("parsePseudoBigInt", () => { diff --git a/src/testRunner/unittests/services/textChanges.ts b/src/testRunner/unittests/services/textChanges.ts index 68eda3aab8427..0acbb31c5e340 100644 --- a/src/testRunner/unittests/services/textChanges.ts +++ b/src/testRunner/unittests/services/textChanges.ts @@ -4,7 +4,7 @@ import { notImplementedHost } from "./extract/helpers"; import { applyChanges, ChangeTracker, deleteNode, LeadingTriviaOption, TrailingTriviaOption } from "../../../services/textChanges"; import { FormatContext } from "../../../services/types"; import { getFormatContext } from "../../../services/formatting/formatting"; -import { getNewLineCharacter } from "../../../compiler/sysUtilities"; +import { getNewLineCharacter } from "../../../compiler/sys/utilities"; // Some tests have trailing whitespace diff --git a/src/testRunner/unittests/tsserver/exportMapCache.ts b/src/testRunner/unittests/tsserver/exportMapCache.ts index bdafc5fcc4774..b8e41c64c8542 100644 --- a/src/testRunner/unittests/tsserver/exportMapCache.ts +++ b/src/testRunner/unittests/tsserver/exportMapCache.ts @@ -1,5 +1,5 @@ import * as ts from "../../_namespaces/ts"; -import { getSymbolId } from "../../../compiler/checkerUtilities"; +import { getSymbolId } from "../../../compiler/checker/utilities"; import { createServerHost, File, diff --git a/src/typingsInstaller/nodeTypingsInstaller.ts b/src/typingsInstaller/nodeTypingsInstaller.ts index 1f3cf87696b7d..f45f4c4624288 100644 --- a/src/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/typingsInstaller/nodeTypingsInstaller.ts @@ -17,7 +17,7 @@ import { normalizeSlashes, toPath, } from "../compiler/path"; -import { sys } from "../compiler/sys"; +import { sys } from "../compiler/sys/sys"; import { ActionPackageInstalled, Arguments, From a5988f73d4064228bec3a53c937bc9833558508b Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 19 Jan 2023 13:45:41 +0200 Subject: [PATCH 13/24] add missed files --- src/compiler/sys/platform.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/compiler/sys/platform.ts diff --git a/src/compiler/sys/platform.ts b/src/compiler/sys/platform.ts new file mode 100644 index 0000000000000..5099976084b91 --- /dev/null +++ b/src/compiler/sys/platform.ts @@ -0,0 +1,15 @@ +declare const process: any; + +/** @internal */ +export function isNodeLikeSystem(): boolean { + // This is defined here rather than in sys.ts to prevent a cycle from its + // use in performanceCore.ts. + // + // We don't use the presence of `require` to check if we are in Node; + // when bundled using esbuild, this function will be rewritten to `__require` + // and definitely exist. + return typeof process !== "undefined" + && process.nextTick + && !process.browser + && typeof module === "object"; +} From 5e260f3e7c5643fc2363080e091ec908b8f2ba7e Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 19 Jan 2023 13:59:18 +0200 Subject: [PATCH 14/24] fix tests --- src/testRunner/unittests/tsserver/versionCache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testRunner/unittests/tsserver/versionCache.ts b/src/testRunner/unittests/tsserver/versionCache.ts index 37179f926172d..aa7414d211fbf 100644 --- a/src/testRunner/unittests/tsserver/versionCache.ts +++ b/src/testRunner/unittests/tsserver/versionCache.ts @@ -211,7 +211,7 @@ describe(`unittests:: tsserver:: VersionCache stress test`, () => { before(() => { // Use scanner.ts, decent size, does not change frequently - const testFileName = "src/compiler/scanner.ts"; + const testFileName = "src/compiler/scanner/scanner.ts"; testContent = Harness.IO.readFile(testFileName)!; const totalChars = testContent.length; assert.isTrue(totalChars > 0, "Failed to read test file."); From 482e57aaf5bea6be342c9a5f80e1b2f14b97d11e Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 19 Jan 2023 14:45:38 +0200 Subject: [PATCH 15/24] fix codeql errors --- src/compiler/moduleNameResolver/moduleNameResolver.ts | 2 +- src/compiler/moduleSpecifiers/moduleSpecifiers.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/moduleNameResolver/moduleNameResolver.ts b/src/compiler/moduleNameResolver/moduleNameResolver.ts index 194eea5eeb7b0..e3052162187b4 100644 --- a/src/compiler/moduleNameResolver/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver/moduleNameResolver.ts @@ -2899,7 +2899,7 @@ function tryLoadModuleUsingPaths(extensions: Extensions, moduleName: string, bas trace(state.host, Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText); } const resolved = forEach(paths[matchedPatternText], subst => { - const path = matchedStar ? subst.replace("*", matchedStar) : subst; + const path = matchedStar ? subst.replace(/\*/g, 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)); if (state.traceEnabled) { diff --git a/src/compiler/moduleSpecifiers/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers/moduleSpecifiers.ts index 84f4ba748b284..a046719a080d5 100644 --- a/src/compiler/moduleSpecifiers/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers/moduleSpecifiers.ts @@ -778,7 +778,7 @@ function tryGetModuleNameFromPaths(relativeToBaseUrl: string, paths: MapLike Date: Thu, 19 Jan 2023 16:12:01 +0200 Subject: [PATCH 16/24] use direct imports in tsc and identifierProperties --- .../5.0/identifierProperties.ts | 11 ++++----- src/tsc/tsc.ts | 23 +++++++++++-------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/deprecatedCompat/5.0/identifierProperties.ts b/src/deprecatedCompat/5.0/identifierProperties.ts index fbbfc5ee55d15..2b90ba57f8470 100644 --- a/src/deprecatedCompat/5.0/identifierProperties.ts +++ b/src/deprecatedCompat/5.0/identifierProperties.ts @@ -1,10 +1,7 @@ -import { - addObjectAllocatorPatcher, - hasProperty, - Identifier, - identifierToKeywordKind, - NodeFlags, -} from "../_namespaces/ts"; +import { hasProperty } from "../../compiler/core"; +import { addObjectAllocatorPatcher } from "../../compiler/objectAllocator"; +import { Identifier, NodeFlags } from "../../compiler/types"; +import { identifierToKeywordKind } from "../../compiler/utilitiesPublic"; import { deprecate } from "../deprecate"; declare module "../../compiler/types" { diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index a3d29a941e794..0612e80b413ec 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -1,24 +1,27 @@ -import * as ts from "./_namespaces/ts"; +import * as Debug from "../compiler/debug"; +import { noop } from "../compiler/core"; +import { sys } from "../compiler/sys/sys"; +import { executeCommandLine } from "../executeCommandLine/executeCommandLine"; // This file actually uses arguments passed on commandline and executes it // enable deprecation logging -ts.Debug.setLoggingHost({ +Debug.setLoggingHost({ log(_level, s) { - ts.sys.write(`${s || ""}${ts.sys.newLine}`); + sys.write(`${s || ""}${sys.newLine}`); } }); -if (ts.Debug.isDebugging) { - ts.Debug.enableDebugInfo(); +if (Debug.isDebugging) { + Debug.enableDebugInfo(); } -if (ts.sys.tryEnableSourceMapsForHost && /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))) { - ts.sys.tryEnableSourceMapsForHost(); +if (sys.tryEnableSourceMapsForHost && /^development$/i.test(sys.getEnvironmentVariable("NODE_ENV"))) { + sys.tryEnableSourceMapsForHost(); } -if (ts.sys.setBlocking) { - ts.sys.setBlocking(); +if (sys.setBlocking) { + sys.setBlocking(); } -ts.executeCommandLine(ts.sys, ts.noop, ts.sys.args); +executeCommandLine(sys, noop, sys.args); From c0fba6fb6eeecbbd6711d50523cd06152cd3bc66 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 19 Jan 2023 19:34:20 +0200 Subject: [PATCH 17/24] revert codeql errors --- src/compiler/moduleNameResolver/moduleNameResolver.ts | 2 +- src/compiler/moduleSpecifiers/moduleSpecifiers.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/moduleNameResolver/moduleNameResolver.ts b/src/compiler/moduleNameResolver/moduleNameResolver.ts index e3052162187b4..194eea5eeb7b0 100644 --- a/src/compiler/moduleNameResolver/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver/moduleNameResolver.ts @@ -2899,7 +2899,7 @@ function tryLoadModuleUsingPaths(extensions: Extensions, moduleName: string, bas trace(state.host, Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText); } const resolved = forEach(paths[matchedPatternText], subst => { - const path = matchedStar ? subst.replace(/\*/g, matchedStar) : 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)); if (state.traceEnabled) { diff --git a/src/compiler/moduleSpecifiers/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers/moduleSpecifiers.ts index a046719a080d5..84f4ba748b284 100644 --- a/src/compiler/moduleSpecifiers/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers/moduleSpecifiers.ts @@ -778,7 +778,7 @@ function tryGetModuleNameFromPaths(relativeToBaseUrl: string, paths: MapLike Date: Thu, 19 Jan 2023 22:30:04 +0200 Subject: [PATCH 18/24] use direct imports in typingsInstallerCore --- src/typingsInstallerCore/typingsInstaller.ts | 98 ++++++++++++-------- 1 file changed, 61 insertions(+), 37 deletions(-) diff --git a/src/typingsInstallerCore/typingsInstaller.ts b/src/typingsInstallerCore/typingsInstaller.ts index f65e735ffe6db..dc931b688e1aa 100644 --- a/src/typingsInstallerCore/typingsInstaller.ts +++ b/src/typingsInstallerCore/typingsInstaller.ts @@ -1,53 +1,77 @@ import { - clearMap, - closeFileWatcher, - combinePaths, compareStringsCaseInsensitive, - Comparison, - containsPath, - copyEntries, createGetCanonicalFileName, - directorySeparator, - Extension, - fileExtensionIs, - FileWatcher, - getBaseFileName, GetCanonicalFileName, - getDirectoryPath, getProperty, - getWatchFactory, hasProperty, - JsTyping, - mangleScopedPackageName, mapDefined, - MapLike, - ModuleResolutionKind, noop, - Path, - PollingInterval, - resolveModuleName, +} from "../compiler/core"; +import { + Comparison, + MapLike, version, - Version, versionMajorMinor, +} from "../compiler/corePublic"; +import { + mangleScopedPackageName, + resolveModuleName, +} from "../compiler/moduleNameResolver/moduleNameResolver"; +import { + combinePaths, + containsPath, + directorySeparator, + fileExtensionIs, + getBaseFileName, + getDirectoryPath, +} from "../compiler/path"; +import { Version } from "../compiler/semver"; +import { PollingInterval } from "../compiler/sys/sys"; +import { + Extension, + FileWatcher, + ModuleResolutionKind, + Path, WatchDirectoryFlags, + WatchOptions, +} from "../compiler/types"; +import { + clearMap, + closeFileWatcher, + copyEntries, +} from "../compiler/utilities"; +import { + getWatchFactory, WatchFactory, WatchFactoryHost, WatchLogLevel, - WatchOptions, -} from "./_namespaces/ts"; +} from "../compiler/watchUtilities"; +import { + CachedTyping, + discoverTypings, + isTypingUpToDate, + loadSafeList, + loadTypesMap, + NameValidationResult, + renderPackageNameValidationFailure, + SafeList, + validatePackageName, +} from "../jsTyping/jsTyping"; import { ActionInvalidate, ActionSet, + EventBeginInstallTypes, + EventEndInstallTypes, +} from "../jsTyping/shared"; +import { BeginInstallTypes, CloseProject, DiscoverTypings, EndInstallTypes, - EventBeginInstallTypes, - EventEndInstallTypes, InstallTypingHost, InvalidateCachedTypings, SetTypings, -} from "./_namespaces/ts.server"; +} from "../jsTyping/types"; interface NpmConfig { devDependencies: MapLike; @@ -141,11 +165,11 @@ function getDetailWatchInfo(projectName: string, watchers: ProjectWatchers | und } export abstract class TypingsInstaller { - private readonly packageNameToTypingLocation = new Map(); + private readonly packageNameToTypingLocation = new Map(); private readonly missingTypingsSet = new Set(); private readonly knownCachesSet = new Set(); private readonly projectWatchers = new Map(); - private safeList: JsTyping.SafeList | undefined; + private safeList: SafeList | undefined; readonly pendingRunRequests: PendingRequest[] = []; private readonly toCanonicalFileName: GetCanonicalFileName; private readonly globalCachePackageJsonPath: string; @@ -213,7 +237,7 @@ export abstract class TypingsInstaller { if (this.safeList === undefined) { this.initializeSafeList(); } - const discoverTypingsResult = JsTyping.discoverTypings( + const discoverTypingsResult = discoverTypings( this.installTypingHost, this.log.isEnabled() ? (s => this.log.writeLine(s)) : undefined, req.fileNames, @@ -247,7 +271,7 @@ export abstract class TypingsInstaller { private initializeSafeList() { // Prefer the safe list from the types map if it exists if (this.typesMapLocation) { - const safeListFromMap = JsTyping.loadTypesMap(this.installTypingHost, this.typesMapLocation); + const safeListFromMap = loadTypesMap(this.installTypingHost, this.typesMapLocation); if (safeListFromMap) { this.log.writeLine(`Loaded safelist from types map file '${this.typesMapLocation}'`); this.safeList = safeListFromMap; @@ -255,7 +279,7 @@ export abstract class TypingsInstaller { } this.log.writeLine(`Failed to load safelist from types map file '${this.typesMapLocation}'`); } - this.safeList = JsTyping.loadSafeList(this.installTypingHost, this.safeListPath); + this.safeList = loadSafeList(this.installTypingHost, this.safeListPath); } private processCacheLocation(cacheLocation: string) { @@ -315,7 +339,7 @@ export abstract class TypingsInstaller { continue; } - const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: new Version(version) }; + const newTyping: CachedTyping = { typingLocation: typingFile, version: new Version(version) }; this.packageNameToTypingLocation.set(packageName, newTyping); } } @@ -333,18 +357,18 @@ export abstract class TypingsInstaller { if (this.log.isEnabled()) this.log.writeLine(`'${typing}':: '${typingKey}' is in missingTypingsSet - skipping...`); return undefined; } - const validationResult = JsTyping.validatePackageName(typing); - if (validationResult !== JsTyping.NameValidationResult.Ok) { + const validationResult = validatePackageName(typing); + if (validationResult !== NameValidationResult.Ok) { // add typing name to missing set so we won't process it again this.missingTypingsSet.add(typingKey); - if (this.log.isEnabled()) this.log.writeLine(JsTyping.renderPackageNameValidationFailure(validationResult, typing)); + if (this.log.isEnabled()) this.log.writeLine(renderPackageNameValidationFailure(validationResult, typing)); return undefined; } if (!this.typesRegistry.has(typingKey)) { if (this.log.isEnabled()) this.log.writeLine(`'${typing}':: Entry for package '${typingKey}' does not exist in local types registry - skipping...`); return undefined; } - if (this.packageNameToTypingLocation.get(typingKey) && JsTyping.isTypingUpToDate(this.packageNameToTypingLocation.get(typingKey)!, this.typesRegistry.get(typingKey)!)) { + if (this.packageNameToTypingLocation.get(typingKey) && isTypingUpToDate(this.packageNameToTypingLocation.get(typingKey)!, this.typesRegistry.get(typingKey)!)) { if (this.log.isEnabled()) this.log.writeLine(`'${typing}':: '${typingKey}' already has an up-to-date typing - skipping...`); return undefined; } @@ -420,7 +444,7 @@ export abstract class TypingsInstaller { // packageName is guaranteed to exist in typesRegistry by filterTypings const distTags = this.typesRegistry.get(packageName)!; const newVersion = new Version(distTags[`ts${versionMajorMinor}`] || distTags[this.latestDistTag]); - const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: newVersion }; + const newTyping: CachedTyping = { typingLocation: typingFile, version: newVersion }; this.packageNameToTypingLocation.set(packageName, newTyping); installedTypingFiles.push(typingFile); } From 8d2ebf03396b1dfb63a9483c27a6ddd75eeba7e2 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Sun, 22 Jan 2023 12:00:39 +0200 Subject: [PATCH 19/24] use direct imports in tsserver --- src/server/types.ts | 8 ++- src/tsserver/common.ts | 10 +-- src/tsserver/nodeServer.ts | 138 ++++++++++++++++++++++--------------- src/tsserver/server.ts | 25 +++---- 4 files changed, 109 insertions(+), 72 deletions(-) diff --git a/src/server/types.ts b/src/server/types.ts index 1eba4a2255b63..383425b34f6dd 100644 --- a/src/server/types.ts +++ b/src/server/types.ts @@ -1,4 +1,10 @@ -import { DirectoryWatcherCallback, FileWatcher, FileWatcherCallback, System, WatchOptions } from "../compiler/types"; +import { + DirectoryWatcherCallback, + FileWatcher, + FileWatcherCallback, + System, + WatchOptions, +} from "../compiler/types"; export interface CompressedData { length: number; diff --git a/src/tsserver/common.ts b/src/tsserver/common.ts index 857e276fb050c..8eb88814e1444 100644 --- a/src/tsserver/common.ts +++ b/src/tsserver/common.ts @@ -1,10 +1,12 @@ +import { LanguageServiceMode } from "../services/types"; import { - Logger, - LogLevel, ServerCancellationToken, SessionOptions, -} from "./_namespaces/ts.server"; -import { LanguageServiceMode } from "./_namespaces/ts"; +} from "../server/session"; +import { + Logger, + LogLevel, +} from "../server/utilitiesPublic"; /** @internal */ export function getLogLevel(level: string | undefined) { diff --git a/src/tsserver/nodeServer.ts b/src/tsserver/nodeServer.ts index 784d0a8d41756..e338f16198a85 100644 --- a/src/tsserver/nodeServer.ts +++ b/src/tsserver/nodeServer.ts @@ -1,82 +1,110 @@ -import * as ts from "./_namespaces/ts"; -import * as server from "./_namespaces/ts.server"; +import * as Debug from "../compiler/debug"; +import * as protocol from "../server/protocol"; +import { + Event, + formatMessage, + nullCancellationToken, + ServerCancellationToken, + Session, + toEvent, +} from "../server/session"; import { ActionInvalidate, ActionPackageInstalled, ActionSet, Arguments, - BeginInstallTypes, - createInstallTypingsRequest, - EndInstallTypes, EventBeginInstallTypes, EventEndInstallTypes, EventInitializationFailed, EventTypesRegistry, findArgument, - formatMessage, - getLogLevel, hasArgument, - indent, + nowString, +} from "../jsTyping/shared"; +import { + BeginInstallTypes, + EndInstallTypes, InitializationFailedResponse, - InstallPackageOptionsWithProject, InstallPackageRequest, InvalidateCachedTypings, - ITypingsInstaller, + PackageInstalledResponse, + SetTypings, + TypesRegistryResponse, + TypingInstallerRequestUnion, +} from "../jsTyping/types"; +import { + NameValidationResult, + validatePackageName, +} from "../jsTyping/jsTyping"; +import { + createInstallTypingsRequest, Logger, LogLevel, - ModuleImportResult, Msg, - nowString, - nullCancellationToken, +} from "../server/utilitiesPublic"; +import { + indent, + stringifyIndented, +} from "../server/utilities"; +import { + InstallPackageOptionsWithProject, + ITypingsInstaller, nullTypingsInstaller, - PackageInstalledResponse, - Project, - ProjectService, - ServerCancellationToken, +} from "../server/typingsCache"; +import { Project } from "../server/project"; +import { + ModuleImportResult, ServerHost, - Session, - SetTypings, +} from "../server/types"; +import { ProjectService } from "../server/editorServices"; +import { + ApplyCodeActionCommandResult, + LanguageServiceMode, +} from "../services/types"; +import { + getLogLevel, StartInput, StartSessionOptions, - stringifyIndented, - toEvent, - TypesRegistryResponse, - TypingInstallerRequestUnion, -} from "./_namespaces/ts.server"; +} from "./common"; import { - ApplyCodeActionCommandResult, assertType, - CharacterCodes, - combinePaths, createQueue, - Debug, + noop, + toFileNameLowerCase, +} from "../compiler/core"; +import { + MapLike, + SortedReadonlyArray, + versionMajorMinor, +} from "../compiler/corePublic"; +import { resolveJSModule } from "../compiler/moduleNameResolver/moduleNameResolver"; +import { + combinePaths, directorySeparator, - DirectoryWatcherCallback, - FileWatcher, getDirectoryPath, - getNodeMajorVersion, getRootLength, - JsTyping, - LanguageServiceMode, - MapLike, - noop, - noopFileWatcher, normalizePath, normalizeSlashes, - perfLogger, - resolveJSModule, - SortedReadonlyArray, - startTracing, - stripQuotes, - sys, - toFileNameLowerCase, - tracing, +} from "../compiler/path"; +import { perfLogger } from "../compiler/perfLogger"; +import { + getNodeMajorVersion, + sys as system, +} from "../compiler/sys/sys"; +import { + CharacterCodes, + DirectoryWatcherCallback, + FileWatcher, TypeAcquisition, - validateLocaleAndSetLanguage, - versionMajorMinor, WatchOptions, -} from "./_namespaces/ts"; -import * as protocol from "../server/protocol"; +} from "../compiler/types"; +import { + startTracing, + tracing, +} from "../compiler/tracing"; +import { stripQuotes } from "../compiler/utilities"; +import { validateLocaleAndSetLanguage } from "../compiler/utilitiesPublic"; +import { noopFileWatcher } from "../compiler/watch"; interface LogOptions { file?: string; @@ -168,7 +196,7 @@ function parseServerMode(): LanguageServiceMode | string | undefined { /** @internal */ export function initializeNodeSystem(): StartInput { - const sys = Debug.checkDefined(ts.sys) as ServerHost; + const sys = Debug.checkDefined(system) as ServerHost; const childProcess: { execFileSync(file: string, args: string[], options: { stdio: "ignore", env: MapLike }): string | Buffer; } = require("child_process"); @@ -564,13 +592,13 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella readonly typesMapLocation: string, private readonly npmLocation: string | undefined, private readonly validateDefaultNpmLocation: boolean, - private event: server.Event) { + private event: Event) { } isKnownTypesPackageName(name: string): boolean { // We want to avoid looking this up in the registry as that is expensive. So first check that it's actually an NPM package. - const validationResult = JsTyping.validatePackageName(name); - if (validationResult !== JsTyping.NameValidationResult.Ok) { + const validationResult = validatePackageName(name); + if (validationResult !== NameValidationResult.Ok) { return false; } @@ -631,7 +659,7 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella } } - const typingsInstaller = combinePaths(getDirectoryPath(sys.getExecutingFilePath()), "typingsInstaller.js"); + const typingsInstaller = combinePaths(getDirectoryPath(system.getExecutingFilePath()), "typingsInstaller.js"); this.installer = childProcess.fork(typingsInstaller, args, { execArgv }); this.installer.on("message", m => this.handleMessage(m)); @@ -805,7 +833,7 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella this.event(body, eventName); }; - const host = sys as ServerHost; + const host = system as ServerHost; const typingsInstaller = disableAutomaticTypingAcquisition ? undefined @@ -917,7 +945,7 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella const eventPort: number | undefined = parseEventPort(findArgument("--eventPort")); const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation)!; // TODO: GH#18217 - const typesMapLocation = findArgument(Arguments.TypesMapLocation) || combinePaths(getDirectoryPath(sys.getExecutingFilePath()), "typesMap.json"); + const typesMapLocation = findArgument(Arguments.TypesMapLocation) || combinePaths(getDirectoryPath(system.getExecutingFilePath()), "typesMap.json"); const npmLocation = findArgument(Arguments.NpmLocation); const validateDefaultNpmLocation = hasArgument(Arguments.ValidateDefaultNpmLocation); const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition"); diff --git a/src/tsserver/server.ts b/src/tsserver/server.ts index 81ba17e593718..95f497ca089ef 100644 --- a/src/tsserver/server.ts +++ b/src/tsserver/server.ts @@ -1,18 +1,20 @@ +import * as Debug from "../compiler/debug"; +import { version } from "../compiler/corePublic"; import { - emptyArray, - findArgument, - hasArgument, - initializeNodeSystem, - Msg, - StartInput, -} from "./_namespaces/ts.server"; -import { - Debug, getNodeMajorVersion, setStackTraceLimit, sys, - version, -} from "./_namespaces/ts"; +} from "../compiler/sys/sys"; +import { + findArgument, + hasArgument, +} from "../jsTyping/shared"; +import { + emptyArray, + Msg, +} from "../server/utilitiesPublic"; +import { StartInput } from "./common"; +import { initializeNodeSystem } from "./nodeServer"; export * from "./_namespaces/ts"; @@ -24,7 +26,6 @@ function findArgumentStringArray(argName: string): readonly string[] { return arg.split(",").filter(name => name !== ""); } - function start({ args, logger, cancellationToken, serverMode, unknownServerMode, startSession: startServer }: StartInput, platform: string) { logger.info(`Starting TS Server`); From a63bb0d1ddcce7f899ecaa1d507f81e349191c16 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Sun, 22 Jan 2023 12:18:40 +0200 Subject: [PATCH 20/24] use direct imports in loggedIO --- src/loggedIO/loggedIO.ts | 97 ++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 38 deletions(-) diff --git a/src/loggedIO/loggedIO.ts b/src/loggedIO/loggedIO.ts index 8ff19ab3b9489..94601d765c0be 100644 --- a/src/loggedIO/loggedIO.ts +++ b/src/loggedIO/loggedIO.ts @@ -1,5 +1,27 @@ -import * as ts from "./_namespaces/ts"; -import * as Harness from "./_namespaces/Harness"; +import { parseCommandLine } from "../compiler/commandLineParser/commandLineParser"; +import { + createGetCanonicalFileName, + flatMap, + forEach, + hasProperty, + startsWith, +} from "../compiler/core"; +import { + combinePaths, + isRootedDiskPath, + normalizePath, + normalizeSlashes, + toPath, +} from "../compiler/path"; +import { + AnyFunction, + CompilerOptions, + System, +} from "../compiler/types"; +import { + IO, + isDefaultLibraryFile, +} from "../harness/harnessIO"; interface FileInformation { contents?: string; @@ -96,7 +118,7 @@ interface Memoized { function memoize(func: (s: string) => T): Memoized { let lookup: { [s: string]: T } = {}; const run: Memoized = ((s: string) => { - if (ts.hasProperty(lookup, s)) return lookup[s]; + if (hasProperty(lookup, s)) return lookup[s]; return lookup[s] = func(s); }) as Memoized; run.reset = () => { @@ -106,9 +128,8 @@ function memoize(func: (s: string) => T): Memoized { return run; } -export interface PlaybackIO extends Harness.IO, PlaybackControl { } - -export interface PlaybackSystem extends ts.System, PlaybackControl { } +export interface PlaybackIO extends IO, PlaybackControl { } +export interface PlaybackSystem extends System, PlaybackControl { } function createEmptyLog(): IoLog { return { @@ -130,16 +151,16 @@ function createEmptyLog(): IoLog { }; } -export function newStyleLogIntoOldStyleLog(log: IoLog, host: ts.System | Harness.IO, baseName: string) { +export function newStyleLogIntoOldStyleLog(log: IoLog, host: System | IO, baseName: string) { for (const file of log.filesAppended) { if (file.contentsPath) { - file.contents = host.readFile(ts.combinePaths(baseName, file.contentsPath)); + file.contents = host.readFile(combinePaths(baseName, file.contentsPath)); delete file.contentsPath; } } for (const file of log.filesWritten) { if (file.contentsPath) { - file.contents = host.readFile(ts.combinePaths(baseName, file.contentsPath)); + file.contents = host.readFile(combinePaths(baseName, file.contentsPath)); delete file.contentsPath; } } @@ -148,28 +169,28 @@ export function newStyleLogIntoOldStyleLog(log: IoLog, host: ts.System | Harness if (result.contentsPath) { // `readFile` strips away a BOM (and actually reinerprets the file contents according to the correct encoding) // - but this has the unfortunate sideeffect of removing the BOM from any outputs based on the file, so we readd it here. - result.contents = (result.bom || "") + host.readFile(ts.combinePaths(baseName, result.contentsPath)); + result.contents = (result.bom || "") + host.readFile(combinePaths(baseName, result.contentsPath)); delete result.contentsPath; } } return log; } -const canonicalizeForHarness = ts.createGetCanonicalFileName(/*caseSensitive*/ false); // This is done so tests work on windows _and_ linux +const canonicalizeForHarness = createGetCanonicalFileName(/*caseSensitive*/ false); // This is done so tests work on windows _and_ linux function sanitizeTestFilePath(name: string) { - const path = ts.toPath(ts.normalizeSlashes(name.replace(/[\^<>:"|?*%]/g, "_")).replace(/\.\.\//g, "__dotdot/"), "", canonicalizeForHarness); - if (ts.startsWith(path, "/")) { + const path = toPath(normalizeSlashes(name.replace(/[\^<>:"|?*%]/g, "_")).replace(/\.\.\//g, "__dotdot/"), "", canonicalizeForHarness); + if (startsWith(path, "/")) { return path.substring(1); } return path; } -export function oldStyleLogIntoNewStyleLog(log: IoLog, writeFile: typeof Harness.IO.writeFile, baseTestName: string) { +export function oldStyleLogIntoNewStyleLog(log: IoLog, writeFile: typeof IO.writeFile, baseTestName: string) { if (log.filesAppended) { for (const file of log.filesAppended) { if (file.contents !== undefined) { - file.contentsPath = ts.combinePaths("appended", sanitizeTestFilePath(file.path)); - writeFile(ts.combinePaths(baseTestName, file.contentsPath), file.contents); + file.contentsPath = combinePaths("appended", sanitizeTestFilePath(file.path)); + writeFile(combinePaths(baseTestName, file.contentsPath), file.contents); delete file.contents; } } @@ -177,8 +198,8 @@ export function oldStyleLogIntoNewStyleLog(log: IoLog, writeFile: typeof Harness if (log.filesWritten) { for (const file of log.filesWritten) { if (file.contents !== undefined) { - file.contentsPath = ts.combinePaths("written", sanitizeTestFilePath(file.path)); - writeFile(ts.combinePaths(baseTestName, file.contentsPath), file.contents); + file.contentsPath = combinePaths("written", sanitizeTestFilePath(file.path)); + writeFile(combinePaths(baseTestName, file.contentsPath), file.contents); delete file.contents; } } @@ -188,8 +209,8 @@ export function oldStyleLogIntoNewStyleLog(log: IoLog, writeFile: typeof Harness const result = file.result!; // TODO: GH#18217 const { contents } = result; if (contents !== undefined) { - result.contentsPath = ts.combinePaths("read", sanitizeTestFilePath(file.path)); - writeFile(ts.combinePaths(baseTestName, result.contentsPath), contents); + result.contentsPath = combinePaths("read", sanitizeTestFilePath(file.path)); + writeFile(combinePaths(baseTestName, result.contentsPath), contents); const len = contents.length; if (len >= 2 && contents.charCodeAt(0) === 0xfeff) { result.bom = "\ufeff"; @@ -207,8 +228,8 @@ export function oldStyleLogIntoNewStyleLog(log: IoLog, writeFile: typeof Harness return log; } -export function initWrapper(...[wrapper, underlying]: [PlaybackSystem, ts.System] | [PlaybackIO, Harness.IO]): void { - ts.forEach(Object.keys(underlying), prop => { +export function initWrapper(...[wrapper, underlying]: [PlaybackSystem, System] | [PlaybackIO, IO]): void { + forEach(Object.keys(underlying), prop => { (wrapper as any)[prop] = (underlying as any)[prop]; }); @@ -221,7 +242,7 @@ export function initWrapper(...[wrapper, underlying]: [PlaybackSystem, ts.System replayLog.filesRead = replayLog.filesRead.filter(f => f.result!.contents !== undefined); replayFilesRead = new Map(); for (const file of replayLog.filesRead) { - replayFilesRead.set(ts.normalizeSlashes(file.path).toLowerCase(), file); + replayFilesRead.set(normalizeSlashes(file.path).toLowerCase(), file); } }; @@ -246,18 +267,18 @@ export function initWrapper(...[wrapper, underlying]: [PlaybackSystem, ts.System if (recordLog !== undefined) { let i = 0; const getBase = () => recordLogFileNameBase + i; - while (underlying.fileExists(ts.combinePaths(getBase(), "test.json"))) i++; + while (underlying.fileExists(combinePaths(getBase(), "test.json"))) i++; const newLog = oldStyleLogIntoNewStyleLog(recordLog, (path, str) => underlying.writeFile(path, str), getBase()); - underlying.writeFile(ts.combinePaths(getBase(), "test.json"), JSON.stringify(newLog, null, 4)); // eslint-disable-line no-null/no-null + underlying.writeFile(combinePaths(getBase(), "test.json"), JSON.stringify(newLog, null, 4)); // eslint-disable-line no-null/no-null const syntheticTsconfig = generateTsconfig(newLog); if (syntheticTsconfig) { - underlying.writeFile(ts.combinePaths(getBase(), "tsconfig.json"), JSON.stringify(syntheticTsconfig, null, 4)); // eslint-disable-line no-null/no-null + underlying.writeFile(combinePaths(getBase(), "tsconfig.json"), JSON.stringify(syntheticTsconfig, null, 4)); // eslint-disable-line no-null/no-null } recordLog = undefined; } }; - function generateTsconfig(newLog: IoLog): undefined | { compilerOptions: ts.CompilerOptions, files: string[] } { + function generateTsconfig(newLog: IoLog): undefined | { compilerOptions: CompilerOptions, files: string[] } { if (newLog.filesRead.some(file => /tsconfig.+json$/.test(file.path))) { return; } @@ -265,12 +286,12 @@ export function initWrapper(...[wrapper, underlying]: [PlaybackSystem, ts.System for (const file of newLog.filesRead) { const result = file.result!; if (result.contentsPath && - Harness.isDefaultLibraryFile(result.contentsPath) && + isDefaultLibraryFile(result.contentsPath) && /\.[tj]s$/.test(result.contentsPath)) { files.push(result.contentsPath); } } - return { compilerOptions: ts.parseCommandLine(newLog.arguments).options, files }; + return { compilerOptions: parseCommandLine(newLog.arguments).options, files }; } wrapper.fileExists = recordReplay(wrapper.fileExists, underlying)( @@ -312,7 +333,7 @@ export function initWrapper(...[wrapper, underlying]: [PlaybackSystem, ts.System wrapper.resolvePath = recordReplay(wrapper.resolvePath, underlying)( path => callAndRecord(underlying.resolvePath(path), recordLog!.pathsResolved, { path }), - memoize(path => findResultByFields(replayLog!.pathsResolved, { path }, !ts.isRootedDiskPath(ts.normalizeSlashes(path)) && replayLog!.currentDirectory ? replayLog!.currentDirectory + "/" + path : ts.normalizeSlashes(path)))); + memoize(path => findResultByFields(replayLog!.pathsResolved, { path }, !isRootedDiskPath(normalizeSlashes(path)) && replayLog!.currentDirectory ? replayLog!.currentDirectory + "/" + path : normalizeSlashes(path)))); wrapper.readFile = recordReplay(wrapper.readFile, underlying)( (path: string) => { @@ -325,7 +346,7 @@ export function initWrapper(...[wrapper, underlying]: [PlaybackSystem, ts.System wrapper.readDirectory = recordReplay(wrapper.readDirectory, underlying)( (path, extensions, exclude, include, depth) => { - const result = (underlying as ts.System).readDirectory(path, extensions, exclude, include, depth); + const result = (underlying as System).readDirectory(path, extensions, exclude, include, depth); recordLog!.directoriesRead.push({ path, extensions, exclude, include, depth, result }); return result; }, @@ -334,9 +355,9 @@ export function initWrapper(...[wrapper, underlying]: [PlaybackSystem, ts.System // if each of the directoriesRead has matched path with the given path (directory with same path but different extension will considered // different entry). // TODO (yuisu): We can certainly remove these once we recapture the RWC using new API - const normalizedPath = ts.normalizePath(path).toLowerCase(); - return ts.flatMap(replayLog!.directoriesRead, directory => { - if (ts.normalizeSlashes(directory.path).toLowerCase() === normalizedPath) { + const normalizedPath = normalizePath(path).toLowerCase(); + return flatMap(replayLog!.directoriesRead, directory => { + if (normalizeSlashes(directory.path).toLowerCase() === normalizedPath) { return directory.result; } }); @@ -361,7 +382,7 @@ export function initWrapper(...[wrapper, underlying]: [PlaybackSystem, ts.System }; } -function recordReplay(original: T, underlying: any) { +function recordReplay(original: T, underlying: any) { function createWrapper(record: T, replay: T): T { // eslint-disable-next-line local/only-arrow-functions return (function () { @@ -404,7 +425,7 @@ function findResultByFields(logArray: { result?: T }[], expectedFields: {}, d } function findFileByPath(expectedPath: string, throwFileNotFoundError: boolean): FileInformation | undefined { - const normalizedName = ts.normalizePath(expectedPath).toLowerCase(); + const normalizedName = normalizePath(expectedPath).toLowerCase(); // Try to find the result through normal fileName const result = replayFilesRead!.get(normalizedName); if (result) { @@ -424,7 +445,7 @@ function noOpReplay(_name: string) { // console.log("Swallowed write operation during replay: " + name); } -export function wrapIO(underlying: Harness.IO): PlaybackIO { +export function wrapIO(underlying: IO): PlaybackIO { const wrapper: PlaybackIO = {} as any; initWrapper(wrapper, underlying); @@ -441,7 +462,7 @@ export function wrapIO(underlying: Harness.IO): PlaybackIO { } } -export function wrapSystem(underlying: ts.System): PlaybackSystem { +export function wrapSystem(underlying: System): PlaybackSystem { const wrapper: PlaybackSystem = {} as any; initWrapper(wrapper, underlying); return wrapper; From 88d5f059306751c4f5ca3e0ede043ae56241eb7d Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 25 Jan 2023 22:21:30 +0200 Subject: [PATCH 21/24] revert classification of files by folders --- .../_namespaces/ts.moduleSpecifiers.ts | 2 +- src/compiler/_namespaces/ts.ts | 28 ++++---- src/compiler/binder.ts | 8 +-- src/compiler/builder.ts | 12 ++-- src/compiler/builderState.ts | 2 +- src/compiler/{checker => }/checker.ts | 66 +++++++++---------- .../utilities.ts => checkerUtilities.ts} | 2 +- .../commandLineParser.ts | 32 ++++----- ...ities.ts => commandLineParserUtilities.ts} | 2 +- src/compiler/debug.ts | 4 +- src/compiler/{emitter => }/emitter.ts | 64 +++++++++--------- .../utilities.ts => emitterUtilities.ts} | 10 +-- src/compiler/factory/nodeFactory.ts | 10 +-- src/compiler/factory/utilities.ts | 8 +-- .../moduleNameResolver.ts | 30 ++++----- ...ties.ts => moduleNameResolverUtilities.ts} | 10 +-- .../moduleSpecifiers.ts | 28 ++++---- ...lities.ts => moduleSpecifiersUtilities.ts} | 14 ++-- src/compiler/{parser => }/parser.ts | 42 ++++++------ .../utilities.ts => parserUtilities.ts} | 6 +- src/compiler/performanceCore.ts | 2 +- src/compiler/{sys => }/platform.ts | 0 src/compiler/{program => }/program.ts | 66 +++++++++---------- .../utilities.ts => programUtilities.ts} | 10 +-- src/compiler/resolutionCache.ts | 6 +- src/compiler/{scanner => }/scanner.ts | 12 ++-- .../keywords.ts => scannerKeywords.ts} | 4 +- .../utilities.ts => scannerUtilities.ts} | 2 +- src/compiler/sourcemap.ts | 2 +- src/compiler/symbolWalker.ts | 2 +- src/compiler/symlinkCache.ts | 4 +- src/compiler/{sys => }/sys.ts | 26 ++++---- .../{sys/utilities.ts => sysUtilities.ts} | 2 +- src/compiler/tracing.ts | 2 +- src/compiler/transformers/declarations.ts | 16 ++--- src/compiler/transformers/es2015.ts | 4 +- src/compiler/transformers/es2017.ts | 2 +- src/compiler/transformers/es2018.ts | 2 +- src/compiler/transformers/generators.ts | 2 +- src/compiler/transformers/jsx.ts | 4 +- src/compiler/transformers/module/module.ts | 2 +- src/compiler/transformers/module/system.ts | 2 +- src/compiler/transformers/ts.ts | 6 +- src/compiler/transformers/typeSerializer.ts | 4 +- src/compiler/transformers/utilities.ts | 2 +- src/compiler/tsbuildPublic.ts | 10 +-- src/compiler/types.ts | 6 +- src/compiler/utilities.ts | 6 +- src/compiler/utilitiesPublic.ts | 2 +- src/compiler/watch.ts | 8 +-- src/compiler/watchPublic.ts | 14 ++-- src/compiler/watchUtilities.ts | 6 +- src/executeCommandLine/executeCommandLine.ts | 8 +-- src/harness/harnessUtils.ts | 2 +- src/jsTyping/jsTyping.ts | 2 +- src/jsTyping/shared.ts | 2 +- src/loggedIO/loggedIO.ts | 2 +- src/server/editorServices.ts | 10 +-- src/server/moduleSpecifierCache.ts | 2 +- src/server/project.ts | 14 ++-- src/server/scriptInfo.ts | 2 +- src/server/scriptVersionCache.ts | 2 +- src/server/session.ts | 10 +-- src/services/breakpoints.ts | 2 +- src/services/callHierarchy.ts | 8 +-- src/services/classifier.ts | 6 +- src/services/classifier2020.ts | 2 +- src/services/codefixes/addMissingAsync.ts | 2 +- src/services/codefixes/addMissingAwait.ts | 2 +- src/services/codefixes/convertConstToLet.ts | 2 +- .../codefixes/convertFunctionToEs6Class.ts | 2 +- .../codefixes/convertToAsyncFunction.ts | 8 +-- src/services/codefixes/convertToEsModule.ts | 2 +- .../codefixes/convertToTypeOnlyExport.ts | 2 +- .../codefixes/disableJsDiagnostics.ts | 2 +- .../codefixes/fixAddMissingConstraint.ts | 4 +- src/services/codefixes/fixAddMissingMember.ts | 6 +- src/services/codefixes/fixAddVoidToPromise.ts | 2 +- .../codefixes/fixAwaitInSyncFunction.ts | 2 +- src/services/codefixes/fixCannotFindModule.ts | 2 +- ...sDoesntImplementInheritedAbstractMember.ts | 2 +- .../fixClassIncorrectlyImplementsInterface.ts | 2 +- .../fixClassSuperMustPrecedeThisAccess.ts | 4 +- src/services/codefixes/fixNaNEquality.ts | 2 +- src/services/codefixes/fixOverrideModifier.ts | 2 +- src/services/codefixes/fixSpelling.ts | 4 +- src/services/codefixes/fixUnusedLabel.ts | 2 +- src/services/codefixes/importAdder.ts | 8 +-- src/services/completions.ts | 6 +- src/services/documentHighlights.ts | 4 +- src/services/documentRegistry.ts | 8 +-- src/services/exportInfoMap.ts | 8 +-- src/services/findAllReferences.ts | 10 +-- src/services/formatting/formatting.ts | 2 +- src/services/formatting/formattingScanner.ts | 2 +- src/services/formatting/smartIndenter.ts | 2 +- src/services/getEditsForFileRename.ts | 8 +-- src/services/goToDefinition.ts | 6 +- src/services/importTracker.ts | 2 +- src/services/inlayHints.ts | 6 +- src/services/jsDoc.ts | 2 +- src/services/navigationBar.ts | 2 +- src/services/organizeImports.ts | 2 +- src/services/outliningElementsCollector.ts | 2 +- src/services/patternMatcher.ts | 2 +- src/services/preProcess.ts | 2 +- ...onvertArrowFunctionOrFunctionExpression.ts | 2 +- .../convertStringOrTemplateLiteral.ts | 2 +- src/services/refactors/extractSymbol.ts | 6 +- src/services/refactors/extractType.ts | 4 +- src/services/refactors/moveToNewFile.ts | 4 +- src/services/services.ts | 14 ++-- src/services/shims.ts | 8 +-- src/services/signatureHelp.ts | 4 +- src/services/smartSelection.ts | 4 +- src/services/sourcemaps.ts | 8 +-- src/services/stringCompletions.ts | 12 ++-- src/services/suggestionDiagnostics.ts | 4 +- src/services/symbolDisplay.ts | 2 +- src/services/textChanges.ts | 8 +-- src/services/transpile.ts | 6 +- src/services/types.ts | 2 +- src/services/utilities.ts | 18 ++--- src/testRunner/unittests/parsePseudoBigInt.ts | 2 +- .../unittests/tsserver/exportMapCache.ts | 2 +- src/tsc/tsc.ts | 2 +- src/tsserver/nodeServer.ts | 4 +- src/tsserver/server.ts | 2 +- src/typingsInstaller/nodeTypingsInstaller.ts | 2 +- src/typingsInstallerCore/typingsInstaller.ts | 4 +- 130 files changed, 479 insertions(+), 479 deletions(-) rename src/compiler/{checker => }/checker.ts (98%) rename src/compiler/{checker/utilities.ts => checkerUtilities.ts} (98%) rename src/compiler/{commandLineParser => }/commandLineParser.ts (97%) rename src/compiler/{commandLineParser/utilities.ts => commandLineParserUtilities.ts} (93%) rename src/compiler/{emitter => }/emitter.ts (97%) rename src/compiler/{emitter/utilities.ts => emitterUtilities.ts} (95%) rename src/compiler/{moduleNameResolver => }/moduleNameResolver.ts (97%) rename src/compiler/{moduleNameResolver/utilities.ts => moduleNameResolverUtilities.ts} (91%) rename src/compiler/{moduleSpecifiers => }/moduleSpecifiers.ts (97%) rename src/compiler/{moduleSpecifiers/utilities.ts => moduleSpecifiersUtilities.ts} (93%) rename src/compiler/{parser => }/parser.ts (97%) rename src/compiler/{parser/utilities.ts => parserUtilities.ts} (96%) rename src/compiler/{sys => }/platform.ts (100%) rename src/compiler/{program => }/program.ts (97%) rename src/compiler/{program/utilities.ts => programUtilities.ts} (92%) rename src/compiler/{scanner => }/scanner.ts (98%) rename src/compiler/{scanner/keywords.ts => scannerKeywords.ts} (96%) rename src/compiler/{scanner/utilities.ts => scannerUtilities.ts} (96%) rename src/compiler/{sys => }/sys.ts (97%) rename src/compiler/{sys/utilities.ts => sysUtilities.ts} (79%) diff --git a/src/compiler/_namespaces/ts.moduleSpecifiers.ts b/src/compiler/_namespaces/ts.moduleSpecifiers.ts index 05575b99f27c1..47a204d4a72b9 100644 --- a/src/compiler/_namespaces/ts.moduleSpecifiers.ts +++ b/src/compiler/_namespaces/ts.moduleSpecifiers.ts @@ -1,3 +1,3 @@ /* Generated file to emulate the ts.moduleSpecifiers namespace. */ -export * from "../moduleSpecifiers/moduleSpecifiers"; +export * from "../moduleSpecifiers"; diff --git a/src/compiler/_namespaces/ts.ts b/src/compiler/_namespaces/ts.ts index 10b6729de86d2..ede685de6c449 100644 --- a/src/compiler/_namespaces/ts.ts +++ b/src/compiler/_namespaces/ts.ts @@ -8,12 +8,12 @@ export * from "../performanceCore"; export * from "../perfLogger"; export * from "../tracing"; export * from "../types"; -export * from "../sys/sys"; -export * from "../sys/utilities"; +export * from "../sys"; +export * from "../sysUtilities"; export * from "../path"; export * from "../diagnosticInformationMap.generated"; -export * from "../scanner/scanner"; -export * from "../scanner/utilities"; +export * from "../scanner"; +export * from "../scannerUtilities"; export * from "../utilitiesPublic"; export * from "../utilities"; export * from "../factory/baseNodeFactory"; @@ -25,18 +25,18 @@ export * from "../factory/emitHelpers"; export * from "../factory/nodeTests"; export * from "../factory/utilities"; export * from "../factory/utilitiesPublic"; -export * from "../parser/parser"; -export * from "../parser/utilities"; -export * from "../commandLineParser/commandLineParser"; -export * from "../commandLineParser/utilities"; -export * from "../moduleNameResolver/moduleNameResolver"; -export * from "../moduleSpecifiers/utilities"; +export * from "../parser"; +export * from "../parserUtilities"; +export * from "../commandLineParser"; +export * from "../commandLineParserUtilities"; +export * from "../moduleNameResolver"; +export * from "../moduleSpecifiersUtilities"; export * from "../objectAllocator"; export * from "../binder"; export * from "../symbolWalker"; export * from "../symlinkCache"; -export * from "../checker/checker"; -export * from "../checker/utilities"; +export * from "../checker"; +export * from "../checkerUtilities"; export * from "../visitorPublic"; export * from "../sourcemap"; export * from "../transformers/utilities"; @@ -65,9 +65,9 @@ export * from "../transformers/module/node"; export * from "../transformers/declarations/diagnostics"; export * from "../transformers/declarations"; export * from "../transformer"; -export * from "../emitter/emitter"; +export * from "../emitter"; export * from "../watchUtilities"; -export * from "../program/program"; +export * from "../program"; export * from "../builderStatePublic"; export * from "../builderState"; export * from "../builder"; diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index f38c12594dac2..dd8c1a39e1b32 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1,5 +1,5 @@ import * as Debug from "./debug"; -import { getNodeId } from "./checker/utilities"; +import { getNodeId } from "./checkerUtilities"; import { append, appendIfUnique, @@ -51,14 +51,14 @@ import { isVariableStatement, } from "./factory/nodeTests"; import { objectAllocator } from "./objectAllocator"; -import { forEachChild } from "./parser/parser"; +import { forEachChild } from "./parser"; import { setParent, setParentRecursive, -} from "./parser/utilities"; +} from "./parserUtilities"; import { perfLogger } from "./perfLogger"; import * as performance from "./performance"; -import { tokenToString } from "./scanner/scanner"; +import { tokenToString } from "./scanner"; import { tracing, TracingNode, diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 90a1fc4950eef..568d4846e43fe 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -11,7 +11,7 @@ import { BuilderState } from "./builderState"; import { convertToOptionsWithAbsolutePaths, getOptionsNameMap, -} from "./commandLineParser/commandLineParser"; +} from "./commandLineParser"; import { addRange, arrayFrom, @@ -40,8 +40,8 @@ import { ReadonlyCollection } from "./corePublic"; import { createBuildInfo, getTsBuildInfoEmitOutputFilePath, -} from "./emitter/emitter"; -import { isDeclarationFileName } from "./parser/parser"; +} from "./emitter"; +import { isDeclarationFileName } from "./parser"; import { ensurePathIsNonModuleName, getDirectoryPath, @@ -54,13 +54,13 @@ import { emitSkippedWithNoDiagnostics, filterSemanticDiagnostics, handleNoEmitOptions, -} from "./program/program"; +} from "./program"; import { compilerOptionsAffectDeclarationPath, compilerOptionsAffectEmit, compilerOptionsAffectSemanticDiagnostics, -} from "./program/utilities"; -import { generateDjb2Hash } from "./sys/sys"; +} from "./programUtilities"; +import { generateDjb2Hash } from "./sys"; import { BuildInfo, BundleBuildInfo, diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts index f0efd1fe4e770..ecfaaee5dc90c 100644 --- a/src/compiler/builderState.ts +++ b/src/compiler/builderState.ts @@ -14,7 +14,7 @@ import { some, } from "./core"; import { isStringLiteral } from "./factory/nodeTests"; -import { isDeclarationFileName } from "./parser/parser"; +import { isDeclarationFileName } from "./parser"; import { getDirectoryPath, toPath, diff --git a/src/compiler/checker/checker.ts b/src/compiler/checker.ts similarity index 98% rename from src/compiler/checker/checker.ts rename to src/compiler/checker.ts index 5d21df358d45b..32c52c6d732f5 100644 --- a/src/compiler/checker/checker.ts +++ b/src/compiler/checker.ts @@ -1,16 +1,16 @@ -import * as Debug from "../debug"; +import * as Debug from "./debug"; import { bindSourceFile, getModuleInstanceState, ModuleInstanceState, -} from "../binder"; +} from "./binder"; import { CheckMode, getNodeId, getSymbolId, SignatureCheckMode, TypeFacts, -} from "./utilities"; +} from "./checkerUtilities"; import { addRange, and, @@ -79,13 +79,13 @@ import { stringContains, tryAddToSet, tryCast, -} from "../core"; -import { Comparison } from "../corePublic"; -import { Diagnostics } from "../diagnosticInformationMap.generated"; -import { createPrinter } from "../emitter/emitter"; +} from "./core"; +import { Comparison } from "./corePublic"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { createPrinter } from "./emitter"; import { createBinaryExpressionTrampoline, -} from "../factory/binaryExpressionStateMachine"; +} from "./factory/binaryExpressionStateMachine"; import { addSyntheticLeadingComment, getIdentifierGeneratedImportReference, @@ -94,8 +94,8 @@ import { setEmitFlags, setIdentifierTypeArguments, setSyntheticLeadingComments, -} from "../factory/emitNode"; -import { factory } from "../factory/nodeFactory"; +} from "./factory/emitNode"; +import { factory } from "./factory/nodeFactory"; import { isArrayBindingPattern, isArrayLiteralExpression, @@ -218,45 +218,45 @@ import { isVariableDeclaration, isVariableDeclarationList, isVariableStatement, -} from "../factory/nodeTests"; +} from "./factory/nodeTests"; import { canHaveIllegalModifiers, createEmptyExports, createPropertyNameNodeForIdentifierOrLiteral, getJSDocTypeAssertionType, isCommaSequence, -} from "../factory/utilities"; +} from "./factory/utilities"; import { canHaveDecorators, canHaveModifiers, setOriginalNode, setTextRange, -} from "../factory/utilitiesPublic"; +} from "./factory/utilitiesPublic"; import { createModeAwareCacheKey, getTypesPackageName, mangleScopedPackageName, nodeModulesPathPart, shouldAllowImportingTsExtension, -} from "../moduleNameResolver/moduleNameResolver"; +} from "./moduleNameResolver"; import { countPathComponents, getModuleSpecifiers, -} from "../moduleSpecifiers/moduleSpecifiers"; -import { objectAllocator } from "../objectAllocator"; +} from "./moduleSpecifiers"; +import { objectAllocator } from "./objectAllocator"; import { forEachChild, forEachChildRecursively, isDeclarationFileName, parseIsolatedEntityName, parseNodeFactory, -} from "../parser/parser"; +} from "./parser"; import { containsParseError, forEachReturnStatement, forEachYieldExpression, setParent, -} from "../parser/utilities"; +} from "./parserUtilities"; import { combinePaths, comparePaths, @@ -266,28 +266,28 @@ import { getNormalizedAbsolutePath, hasExtension, pathIsRelative, -} from "../path"; -import * as performance from "../performance"; +} from "./path"; +import * as performance from "./performance"; import { getModeForUsageLocation, getResolutionDiagnostic, getResolutionModeOverrideForClause, isExclusivelyTypeOnlyImportOrExport, resolveTripleslashReference, -} from "../program/program"; +} from "./program"; import { getLineAndCharacterOfPosition, isIdentifierText, skipTrivia, tokenToString, -} from "../scanner/scanner"; -import { parsePseudoBigInt } from "../scanner/utilities"; -import { createGetSymbolWalker } from "../symbolWalker"; +} from "./scanner"; +import { parsePseudoBigInt } from "./scannerUtilities"; +import { createGetSymbolWalker } from "./symbolWalker"; import { tracing, TracingNode, -} from "../tracing"; -import { nullTransformationContext } from "../transformer"; +} from "./tracing"; +import { nullTransformationContext } from "./transformer"; import { __String, AccessExpression, @@ -682,7 +682,7 @@ import { WideningContext, WithStatement, YieldExpression, -} from "../types"; +} from "./types"; import { addRelatedInfo, arrayIsHomogeneous, @@ -996,7 +996,7 @@ import { walkUpParenthesizedExpressions, walkUpParenthesizedTypes, walkUpParenthesizedTypesAndGetParentAndChild, -} from "../utilities"; +} from "./utilities"; import { canHaveLocals, canHaveSymbol, @@ -1093,20 +1093,20 @@ import { textSpanEnd, unescapeLeadingUnderscores, walkUpBindingElementsAndPatterns, -} from "../utilitiesPublic"; +} from "./utilitiesPublic"; import { visitEachChild, visitNode, visitNodes, -} from "../visitorPublic"; +} from "./visitorPublic"; import { removeExtension, resolutionExtensionIsTSOrJson, tryExtractTSExtension, tryGetExtensionFromPath, -} from "../extension"; -import { getResolvedExternalModuleName } from "../moduleNameResolver/utilities"; -import { isInitializedProperty } from "../transformers/utilities"; +} from "./extension"; +import { getResolvedExternalModuleName } from "./moduleNameResolverUtilities"; +import { isInitializedProperty } from "./transformers/utilities"; const ambientModuleSymbolRegex = /^".+"$/; const anon = "(anonymous)" as __String & string; diff --git a/src/compiler/checker/utilities.ts b/src/compiler/checkerUtilities.ts similarity index 98% rename from src/compiler/checker/utilities.ts rename to src/compiler/checkerUtilities.ts index 72367903a947c..4e8c96179e7b4 100644 --- a/src/compiler/checker/utilities.ts +++ b/src/compiler/checkerUtilities.ts @@ -2,7 +2,7 @@ import { Node, Symbol, SymbolId, -} from "../types"; +} from "./types"; let nextSymbolId = 1; let nextNodeId = 1; diff --git a/src/compiler/commandLineParser/commandLineParser.ts b/src/compiler/commandLineParser.ts similarity index 97% rename from src/compiler/commandLineParser/commandLineParser.ts rename to src/compiler/commandLineParser.ts index 34e014326ec34..3ef40cd33204b 100644 --- a/src/compiler/commandLineParser/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1,4 +1,4 @@ -import * as Debug from "../debug"; +import * as Debug from "./debug"; import { append, arrayFrom, @@ -30,26 +30,26 @@ import { stringContains, toFileNameLowerCase, trimString, -} from "../core"; +} from "./core"; import { MapLike, Push, -} from "../corePublic"; -import { Diagnostics } from "../diagnosticInformationMap.generated"; +} from "./corePublic"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; import { isArrayLiteralExpression, isObjectLiteralExpression, isStringLiteral, -} from "../factory/nodeTests"; +} from "./factory/nodeTests"; import { getFileMatcherPatterns, getRegexFromPattern, getRegularExpressionForWildcard, getRegularExpressionsForWildcards, isImplicitGlob, -} from "../fileMatcher"; -import { nodeNextJsonConfigResolver } from "../moduleNameResolver/moduleNameResolver"; -import { parseJsonText } from "../parser/parser"; +} from "./fileMatcher"; +import { nodeNextJsonConfigResolver } from "./moduleNameResolver"; +import { parseJsonText } from "./parser"; import { combinePaths, containsPath, @@ -68,10 +68,10 @@ import { normalizeSlashes, removeTrailingDirectorySeparator, toPath, -} from "../path"; -import { sys } from "../sys/sys"; -import { tracing } from "../tracing"; -import { BuildOptions } from "../tsbuildPublic"; +} from "./path"; +import { sys } from "./sys"; +import { tracing } from "./tracing"; +import { BuildOptions } from "./tsbuildPublic"; import { AlternateModeDiagnostics, ArrayLiteralExpression, @@ -116,7 +116,7 @@ import { WatchDirectoryKind, WatchFileKind, WatchOptions, -} from "../types"; +} from "./types"; import { createCompilerDiagnostic, createDiagnosticForNodeInSourceFile, @@ -127,13 +127,13 @@ import { getTsConfigPropArrayElementValue, isComputedNonLiteralName, isStringDoubleQuoted, -} from "../utilities"; -import { unescapeLeadingUnderscores } from "../utilitiesPublic"; +} from "./utilities"; +import { unescapeLeadingUnderscores } from "./utilitiesPublic"; import { changeExtension, getSupportedExtensions, getSupportedExtensionsWithJsonIfResolveJsonModule, -} from "../extension"; +} from "./extension"; /** @internal */ export const compileOnSaveCommandLineOption: CommandLineOption = { diff --git a/src/compiler/commandLineParser/utilities.ts b/src/compiler/commandLineParserUtilities.ts similarity index 93% rename from src/compiler/commandLineParser/utilities.ts rename to src/compiler/commandLineParserUtilities.ts index 97e1fabe9a7b8..cc7181c9c97df 100644 --- a/src/compiler/commandLineParser/utilities.ts +++ b/src/compiler/commandLineParserUtilities.ts @@ -1,5 +1,5 @@ import { parseConfigFileTextToJson } from "./commandLineParser"; -import { isString } from "../core"; +import { isString } from "./core"; /** @internal */ export function readJsonOrUndefined(path: string, hostOrText: { readFile(fileName: string): string | undefined } | string): object | undefined { diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index 00a03ca6acb83..db2e773189ecb 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -1,13 +1,13 @@ /* eslint-disable */ import * as types from "./types"; -import * as checkerTypes from "./checker/utilities"; +import * as checkerTypes from "./checkerUtilities"; /* eslint-enable */ import { CheckMode, SignatureCheckMode, TypeFacts, -} from "./checker/utilities"; +} from "./checkerUtilities"; import { compareValues, every, diff --git a/src/compiler/emitter/emitter.ts b/src/compiler/emitter.ts similarity index 97% rename from src/compiler/emitter/emitter.ts rename to src/compiler/emitter.ts index 9e6105e4063d6..b512f86a2153f 100644 --- a/src/compiler/emitter/emitter.ts +++ b/src/compiler/emitter.ts @@ -1,16 +1,16 @@ /* eslint-disable */ -import * as types from "../types"; +import * as types from "./types"; /* eslint-enable */ -import * as Debug from "../debug"; -import * as performance from "../performance"; +import * as Debug from "./debug"; +import * as performance from "./performance"; import { computeSignature, ProgramBuildInfo, ProgramBundleEmitBuildInfo, -} from "../builder"; -import { OutputFile } from "../builderStatePublic"; -import { getNodeId } from "../checker/utilities"; +} from "./builder"; +import { OutputFile } from "./builderStatePublic"; +import { getNodeId } from "./checkerUtilities"; import { arrayToMap, cast, @@ -39,12 +39,12 @@ import { stableSort, stringContains, tryCast, -} from "../core"; -import { Comparison, version } from "../corePublic"; +} from "./core"; +import { Comparison, version } from "./corePublic"; import { createBinaryExpressionTrampoline, -} from "../factory/binaryExpressionStateMachine"; -import { compareEmitHelpers } from "../factory/emitHelpers"; +} from "./factory/binaryExpressionStateMachine"; +import { compareEmitHelpers } from "./factory/emitHelpers"; import { getCommentRange, getConstantValue, @@ -56,11 +56,11 @@ import { getSyntheticLeadingComments, getSyntheticTrailingComments, getTypeNode, -} from "../factory/emitNode"; +} from "./factory/emitNode"; import { createInputFilesWithFileTexts, factory, -} from "../factory/nodeFactory"; +} from "./factory/nodeFactory"; import { isArrowFunction, isBinaryExpression, @@ -84,23 +84,23 @@ import { isUnparsedPrepend, isUnparsedSource, isVariableStatement, -} from "../factory/nodeTests"; +} from "./factory/nodeTests"; import { formatGeneratedName, formatGeneratedNamePart, getExternalHelpersModuleName, getNodeForGeneratedName, hasRecordedExternalHelpers, -} from "../factory/utilities"; +} from "./factory/utilities"; import { setOriginalNode, setTextRange, -} from "../factory/utilitiesPublic"; +} from "./factory/utilitiesPublic"; import { forEachChild, isDeclarationFileName, isJSDocLikeText, -} from "../parser/parser"; +} from "./parser"; import { combinePaths, comparePaths, @@ -118,11 +118,11 @@ import { normalizePath, normalizeSlashes, resolvePath, -} from "../path"; +} from "./path"; import { computeCommonSourceDirectoryOfFilenames, createPrependNodes, -} from "../program/program"; +} from "./program"; import { computeLineStarts, forEachLeadingCommentRange, @@ -134,20 +134,20 @@ import { getTrailingCommentRanges, skipTrivia, tokenToString, -} from "../scanner/scanner"; +} from "./scanner"; import { createSourceMapGenerator, tryParseRawSourceMap, -} from "../sourcemap"; -import { sys } from "../sys/sys"; -import { tracing } from "../tracing"; +} from "./sourcemap"; +import { sys } from "./sys"; +import { tracing } from "./tracing"; import { getTransformers, noEmitNotification, noEmitSubstitution, transformNodes, -} from "../transformer"; -import { isInternalDeclaration } from "../transformers/declarations"; +} from "./transformer"; +import { isInternalDeclaration } from "./transformers/declarations"; import { AccessorDeclaration, ArrayBindingPattern, @@ -402,7 +402,7 @@ import { WithStatement, WriteFileCallbackData, YieldExpression, -} from "../types"; +} from "./types"; import { base64encode, createDiagnosticCollection, @@ -456,7 +456,7 @@ import { setTextRangePosWidth, writeCommentRange, writeFile, -} from "../utilities"; +} from "./utilities"; import { canHaveLocals, escapeLeadingUnderscores, @@ -478,25 +478,25 @@ import { isTokenKind, isUnparsedNode, skipPartiallyEmittedExpressions, -} from "../utilitiesPublic"; -import { positionIsSynthesized } from "../scanner/utilities"; +} from "./utilitiesPublic"; +import { positionIsSynthesized } from "./scannerUtilities"; import { getDeclarationEmitOutputFilePath, getOwnEmitOutputFilePath, getSourceFilePathInNewDir, getSourceFilesToEmit, -} from "./utilities"; +} from "./emitterUtilities"; import { setEachParent, setParent, -} from "../parser/utilities"; -import { readJsonOrUndefined } from "../commandLineParser/utilities"; +} from "./parserUtilities"; +import { readJsonOrUndefined } from "./commandLineParserUtilities"; import { changeExtension, getDeclarationEmitExtensionForPath, removeFileExtension, supportedJSExtensionsFlat, -} from "../extension"; +} from "./extension"; const brackets = createBracketsMap(); diff --git a/src/compiler/emitter/utilities.ts b/src/compiler/emitterUtilities.ts similarity index 95% rename from src/compiler/emitter/utilities.ts rename to src/compiler/emitterUtilities.ts index b9ca360715df7..3e37c6cf0a906 100644 --- a/src/compiler/emitter/utilities.ts +++ b/src/compiler/emitterUtilities.ts @@ -1,27 +1,27 @@ import { filter, GetCanonicalFileName, -} from "../core"; +} from "./core"; import { getDeclarationEmitExtensionForPath, removeFileExtension, -} from "../extension"; +} from "./extension"; import { combinePaths, getNormalizedAbsolutePath, -} from "../path"; +} from "./path"; import { CompilerOptions, EmitHost, ModuleKind, SourceFile, -} from "../types"; +} from "./types"; import { getEmitModuleKind, isExternalModule, outFile, sourceFileMayBeEmitted, -} from "../utilities"; +} from "./utilities"; /** * Gets the source files that are expected to have an emit output. diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 7496105fe81fb..bad796c3dd051 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -1,5 +1,5 @@ import * as Debug from "../debug"; -import { getNodeId } from "../checker/utilities"; +import { getNodeId } from "../checkerUtilities"; import { addRange, append, @@ -22,19 +22,19 @@ import { startsWith, } from "../core"; import { Push } from "../corePublic"; -import { getBuildInfo } from "../emitter/emitter"; +import { getBuildInfo } from "../emitter"; import { objectAllocator } from "../objectAllocator"; -import { parseNodeFactory } from "../parser/parser"; +import { parseNodeFactory } from "../parser"; import { setEachParent, setParent, -} from "../parser/utilities"; +} from "../parserUtilities"; import { createScanner, getLineAndCharacterOfPosition, Scanner, stringToToken, -} from "../scanner/scanner"; +} from "../scanner"; import { __String, ArrayBindingElement, diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index 2f1e976735490..4932e054a34ae 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -7,9 +7,9 @@ import { pushIfUnique, some, } from "../core"; -import { parseNodeFactory } from "../parser/parser"; -import { setParent } from "../parser/utilities"; -import { isIdentifierText } from "../scanner/scanner"; +import { parseNodeFactory } from "../parser"; +import { setParent } from "../parserUtilities"; +import { isIdentifierText } from "../scanner"; import { AccessorDeclaration, AdditiveOperator, @@ -181,7 +181,7 @@ import { setOriginalNode, setTextRange, } from "./utilitiesPublic"; -import { getExternalModuleNameFromPath } from "../moduleNameResolver/utilities"; +import { getExternalModuleNameFromPath } from "../moduleNameResolverUtilities"; // Compound nodes diff --git a/src/compiler/moduleNameResolver/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts similarity index 97% rename from src/compiler/moduleNameResolver/moduleNameResolver.ts rename to src/compiler/moduleNameResolver.ts index 194eea5eeb7b0..8b163340eb6ef 100644 --- a/src/compiler/moduleNameResolver/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -1,9 +1,9 @@ -import * as Debug from "../debug"; +import * as Debug from "./debug"; import { DiagnosticReporter, moduleResolutionOptionDeclarations, -} from "../commandLineParser/commandLineParser"; -import { readJson } from "../commandLineParser/utilities"; +} from "./commandLineParser"; +import { readJson } from "./commandLineParserUtilities"; import { append, appendIfUnique, @@ -35,17 +35,17 @@ import { sort, startsWith, stringContains, -} from "../core"; +} from "./core"; import { Comparison, MapLike, Push, version, versionMajorMinor, -} from "../corePublic"; -import { Diagnostics } from "../diagnosticInformationMap.generated"; -import { getCommonSourceDirectory } from "../emitter/emitter"; -import { isDeclarationFileName } from "../parser/parser"; +} from "./corePublic"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { getCommonSourceDirectory } from "./emitter"; +import { isDeclarationFileName } from "./parser"; import { changeAnyExtension, combinePaths, @@ -69,12 +69,12 @@ import { normalizeSlashes, pathIsRelative, toPath, -} from "../path"; -import { perfLogger } from "../perfLogger"; +} from "./path"; +import { perfLogger } from "./perfLogger"; import { Version, VersionRange, -} from "../semver"; +} from "./semver"; import { CharacterCodes, CommandLineOption, @@ -96,7 +96,7 @@ import { ResolvedTypeReferenceDirective, ResolvedTypeReferenceDirectiveWithFailedLookupLocations, SourceFile, -} from "../types"; +} from "./types"; import { createCompilerDiagnostic, directoryProbablyExists, @@ -110,10 +110,10 @@ import { matchPatternOrExact, packageIdToString, tryParsePatterns, -} from "../utilities"; +} from "./utilities"; import { isExternalModuleNameRelative, -} from "../utilitiesPublic"; +} from "./utilitiesPublic"; import { extensionIsTS, getPossibleOriginalInputExtensionForExtension, @@ -123,7 +123,7 @@ import { supportedTSImplementationExtensions, tryExtractTSExtension, tryGetExtensionFromPath, -} from "../extension"; +} from "./extension"; /** @internal */ export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void; diff --git a/src/compiler/moduleNameResolver/utilities.ts b/src/compiler/moduleNameResolverUtilities.ts similarity index 91% rename from src/compiler/moduleNameResolver/utilities.ts rename to src/compiler/moduleNameResolverUtilities.ts index 7d61edf6ee710..3ee6e612784c1 100644 --- a/src/compiler/moduleNameResolver/utilities.ts +++ b/src/compiler/moduleNameResolverUtilities.ts @@ -1,4 +1,4 @@ -import { removeFileExtension } from "../extension"; +import { removeFileExtension } from "./extension"; import { ensurePathIsNonModuleName, ensureTrailingDirectorySeparator, @@ -7,7 +7,7 @@ import { getRelativePathToDirectoryOrUrl, pathIsRelative, toPath, -} from "../path"; +} from "./path"; import { EmitResolver, ExportDeclaration, @@ -16,9 +16,9 @@ import { ImportTypeNode, ModuleDeclaration, SourceFile, -} from "../types"; -import { getExternalModuleName } from "../utilities"; -import { isStringLiteralLike } from "../utilitiesPublic"; +} from "./types"; +import { getExternalModuleName } from "./utilities"; +import { isStringLiteralLike } from "./utilitiesPublic"; /** @internal */ export interface ResolveModuleNameResolutionHost { diff --git a/src/compiler/moduleSpecifiers/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts similarity index 97% rename from src/compiler/moduleSpecifiers/moduleSpecifiers.ts rename to src/compiler/moduleSpecifiers.ts index 84f4ba748b284..d45b23d7bf9ba 100644 --- a/src/compiler/moduleSpecifiers/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -1,4 +1,4 @@ -import * as Debug from "../debug"; +import * as Debug from "./debug"; import { append, arrayFrom, @@ -21,16 +21,16 @@ import { some, startsWith, stringContains, -} from "../core"; +} from "./core"; import { Comparison, MapLike, -} from "../corePublic"; +} from "./corePublic"; import { isModuleBlock, isModuleDeclaration, isSourceFile, -} from "../factory/nodeTests"; +} from "./factory/nodeTests"; import { allKeysStartWithDot, getPackageJsonTypesVersionsPaths, @@ -38,13 +38,13 @@ import { isApplicableVersionedTypesKey, pathContainsNodeModules, shouldAllowImportingTsExtension, -} from "../moduleNameResolver/moduleNameResolver"; +} from "./moduleNameResolver"; import { getModuleSpecifierEndingPreference, getNodeModulePathParts, NodeModulePathParts, -} from "./utilities"; -import { isDeclarationFileName } from "../parser/parser"; +} from "./moduleSpecifiersUtilities"; +import { isDeclarationFileName } from "./parser"; import { combinePaths, comparePaths, @@ -66,12 +66,12 @@ import { resolvePath, startsWithDirectory, toPath, -} from "../path"; +} from "./path"; import { getModeForResolutionAtIndex, getModuleNameStringLiteralAt, -} from "../program/program"; -import { containsIgnoredPath } from "../sys/utilities"; +} from "./program"; +import { containsIgnoredPath } from "./sysUtilities"; import { __String, AmbientModuleDeclaration, @@ -100,7 +100,7 @@ import { SymbolFlags, TypeChecker, UserPreferences, -} from "../types"; +} from "./types"; import { compareNumberOfDirectorySeparators, getEmitModuleResolutionKind, @@ -114,8 +114,8 @@ import { matchPatternOrExact, ModuleSpecifierEnding, tryParsePatterns, -} from "../utilities"; -import { isExternalModuleNameRelative } from "../utilitiesPublic"; +} from "./utilities"; +import { isExternalModuleNameRelative } from "./utilitiesPublic"; import { extensionFromPath, getSupportedExtensions, @@ -124,7 +124,7 @@ import { removeExtension, removeFileExtension, tryGetExtensionFromPath, -} from "../extension"; +} from "./extension"; // Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers. diff --git a/src/compiler/moduleSpecifiers/utilities.ts b/src/compiler/moduleSpecifiersUtilities.ts similarity index 93% rename from src/compiler/moduleSpecifiers/utilities.ts rename to src/compiler/moduleSpecifiersUtilities.ts index 5ce0699907193..aed9aba7bd45e 100644 --- a/src/compiler/moduleSpecifiers/utilities.ts +++ b/src/compiler/moduleSpecifiersUtilities.ts @@ -4,17 +4,17 @@ import { emptyArray, firstDefined, or, -} from "../core"; +} from "./core"; import { hasJSFileExtension, hasTSFileExtension, -} from "../extension"; -import { isExpressionStatement } from "../factory/nodeTests"; +} from "./extension"; +import { isExpressionStatement } from "./factory/nodeTests"; import { nodeModulesPathPart, shouldAllowImportingTsExtension, -} from "../moduleNameResolver/moduleNameResolver"; -import { pathIsRelative } from "../path"; +} from "./moduleNameResolver"; +import { pathIsRelative } from "./path"; import { CompilerOptions, ModuleKind, @@ -22,13 +22,13 @@ import { ResolutionMode, SourceFile, UserPreferences, -} from "../types"; +} from "./types"; import { isRequireCall, isRequireVariableStatement, isSourceFileJS, ModuleSpecifierEnding, -} from "../utilities"; +} from "./utilities"; /** @internal */ export interface NodeModulePathParts { diff --git a/src/compiler/parser/parser.ts b/src/compiler/parser.ts similarity index 97% rename from src/compiler/parser/parser.ts rename to src/compiler/parser.ts index ca27970dcdc98..daf57cb1c96c9 100644 --- a/src/compiler/parser/parser.ts +++ b/src/compiler/parser.ts @@ -1,5 +1,5 @@ -import * as Debug from "../debug"; -import { convertToObjectWorker } from "../commandLineParser/commandLineParser"; +import * as Debug from "./debug"; +import { convertToObjectWorker } from "./commandLineParser"; import { addRange, append, @@ -20,13 +20,13 @@ import { stringContains, toArray, trimString, -} from "../core"; -import { Diagnostics } from "../diagnosticInformationMap.generated"; -import { BaseNodeFactory } from "../factory/baseNodeFactory"; +} from "./core"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { BaseNodeFactory } from "./factory/baseNodeFactory"; import { createNodeFactory, NodeFactoryFlags, -} from "../factory/nodeFactory"; +} from "./factory/nodeFactory"; import { isAsyncModifier, isExportAssignment, @@ -50,27 +50,27 @@ import { isSetAccessorDeclaration, isTaggedTemplateExpression, isTypeReferenceNode, -} from "../factory/nodeTests"; +} from "./factory/nodeTests"; import { canHaveModifiers, setTextRange, -} from "../factory/utilitiesPublic"; -import { PackageJsonInfo } from "../moduleNameResolver/moduleNameResolver"; -import { objectAllocator } from "../objectAllocator"; +} from "./factory/utilitiesPublic"; +import { PackageJsonInfo } from "./moduleNameResolver"; +import { objectAllocator } from "./objectAllocator"; import { containsParseError, getLastChild, setParent, setParentRecursive, -} from "./utilities"; +} from "./parserUtilities"; import { fileExtensionIs, fileExtensionIsOneOf, getBaseFileName, normalizePath, -} from "../path"; -import { perfLogger } from "../perfLogger"; -import * as performance from "../performance"; +} from "./path"; +import { perfLogger } from "./perfLogger"; +import * as performance from "./performance"; import { createScanner, getLeadingCommentRanges, @@ -79,9 +79,9 @@ import { tokenIsIdentifierOrKeyword, tokenIsIdentifierOrKeywordOrGreaterThan, tokenToString, -} from "../scanner/scanner"; -import { textToKeywordObj } from "../scanner/keywords"; -import { tracing } from "../tracing"; +} from "./scanner"; +import { textToKeywordObj } from "./scannerKeywords"; +import { tracing } from "./tracing"; import { AccessorDeclaration, ArrayBindingElement, @@ -370,7 +370,7 @@ import { WhileStatement, WithStatement, YieldExpression, -} from "../types"; +} from "./types"; import { addRelatedInfo, attachFileToDiagnostics, @@ -393,7 +393,7 @@ import { setTextRangePos, setTextRangePosEnd, setTextRangePosWidth, -} from "../utilities"; +} from "./utilities"; import { createTextChangeRange, createTextSpanFromBounds, @@ -407,8 +407,8 @@ import { textChangeRangeIsUnchanged, textChangeRangeNewSpan, textSpanEnd, -} from "../utilitiesPublic"; -import { supportedDeclarationExtensions } from "../extension"; +} from "./utilitiesPublic"; +import { supportedDeclarationExtensions } from "./extension"; const enum SignatureFlags { None = 0, diff --git a/src/compiler/parser/utilities.ts b/src/compiler/parserUtilities.ts similarity index 96% rename from src/compiler/parser/utilities.ts rename to src/compiler/parserUtilities.ts index 664b78c8a0b6e..8ef8f06349c76 100644 --- a/src/compiler/parser/utilities.ts +++ b/src/compiler/parserUtilities.ts @@ -11,16 +11,16 @@ import { Statement, SyntaxKind, YieldExpression, -} from "../types"; +} from "./types"; import { isPartOfTypeNode, nodeIsPresent, -} from "../utilities"; +} from "./utilities"; import { hasJSDocNodes, isFunctionLike, isJSDocNode, -} from "../utilitiesPublic"; +} from "./utilitiesPublic"; function aggregateChildData(node: Node): void { if (!(node.flags & NodeFlags.HasAggregatedChildData)) { diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index 6d7d368dcb9b1..fac05a9ea6272 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -1,4 +1,4 @@ -import { isNodeLikeSystem } from "./sys/platform"; +import { isNodeLikeSystem } from "./platform"; // The following definitions provide the minimum compatible support for the Web Performance User Timings API // between browsers and NodeJS: diff --git a/src/compiler/sys/platform.ts b/src/compiler/platform.ts similarity index 100% rename from src/compiler/sys/platform.ts rename to src/compiler/platform.ts diff --git a/src/compiler/program/program.ts b/src/compiler/program.ts similarity index 97% rename from src/compiler/program/program.ts rename to src/compiler/program.ts index 5b56a0a1723a5..f88522012b5fc 100644 --- a/src/compiler/program/program.ts +++ b/src/compiler/program.ts @@ -1,6 +1,6 @@ -import * as Debug from "../debug"; -import { BuilderProgram } from "../builderPublic"; -import { createTypeChecker } from "../checker/checker"; +import * as Debug from "./debug"; +import { BuilderProgram } from "./builderPublic"; +import { createTypeChecker } from "./checker"; import { DiagnosticReporter, inverseJsxOptionMap, @@ -10,7 +10,7 @@ import { parseJsonSourceFileConfigFileContent, sourceFileAffectingCompilerOptions, targetOptionDeclaration, -} from "../commandLineParser/commandLineParser"; +} from "./commandLineParser"; import { addRange, append, @@ -56,13 +56,13 @@ import { stringContains, toFileNameLowerCase, trimStringEnd, -} from "../core"; +} from "./core"; import { Comparison, SortedReadonlyArray, versionMajorMinor, -} from "../corePublic"; -import { Diagnostics } from "../diagnosticInformationMap.generated"; +} from "./corePublic"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; import { emitFiles, forEachEmittedFile, @@ -73,12 +73,12 @@ import { getTsBuildInfoEmitOutputFilePath, isBuildInfoFile, notImplementedResolver, -} from "../emitter/emitter"; -import { addInternalEmitFlags } from "../factory/emitNode"; +} from "./emitter"; +import { addInternalEmitFlags } from "./factory/emitNode"; import { createInputFilesWithFilePaths, factory, -} from "../factory/nodeFactory"; +} from "./factory/nodeFactory"; import { isArrayLiteralExpression, isClassDeclaration, @@ -95,8 +95,8 @@ import { isObjectLiteralExpression, isParameter, isStringLiteral, -} from "../factory/nodeTests"; -import { canHaveDecorators } from "../factory/utilitiesPublic"; +} from "./factory/nodeTests"; +import { canHaveDecorators } from "./factory/utilitiesPublic"; import { createModeAwareCache, createModeAwareCacheKey, @@ -116,7 +116,7 @@ import { trace, TypeReferenceDirectiveResolutionCache, zipToModeAwareCache, -} from "../moduleNameResolver/moduleNameResolver"; +} from "./moduleNameResolver"; import { createSourceFile, CreateSourceFileOptions, @@ -126,11 +126,11 @@ import { isFileProbablyExternalModule, parseIsolatedEntityName, parseNodeFactory, -} from "../parser/parser"; +} from "./parser"; import { setParent, setParentRecursive, -} from "../parser/utilities"; +} from "./parserUtilities"; import { combinePaths, comparePaths, @@ -154,15 +154,15 @@ import { pathIsAbsolute, pathIsRelative, toPath, -} from "../path"; -import * as performance from "../performance"; +} from "./path"; +import * as performance from "./performance"; import { changesAffectingProgramStructure, changesAffectModuleResolution, hasChangesInResolutions, setResolvedModule, setResolvedTypeReferenceDirective, -} from "./utilities"; +} from "./programUtilities"; import { computeLineAndCharacterOfPosition, getLineAndCharacterOfPosition, @@ -171,20 +171,20 @@ import { isIdentifierText, skipTrivia, tokenToString, -} from "../scanner/scanner"; +} from "./scanner"; import { createSymlinkCache, SymlinkCache, -} from "../symlinkCache"; -import { sys } from "../sys/sys"; -import { containsIgnoredPath } from "../sys/utilities"; -import { tracing } from "../tracing"; +} from "./symlinkCache"; +import { sys } from "./sys"; +import { containsIgnoredPath } from "./sysUtilities"; +import { tracing } from "./tracing"; import { getTransformers, noTransformers, -} from "../transformer"; -import { getDeclarationDiagnostics } from "../transformers/declarations"; -import { resolveConfigFileProjectName } from "../tsbuild"; +} from "./transformer"; +import { getDeclarationDiagnostics } from "./transformers/declarations"; +import { resolveConfigFileProjectName } from "./tsbuild"; import { __String, AsExpression, @@ -278,7 +278,7 @@ import { VariableStatement, WriteFileCallback, WriteFileCallbackData, -} from "../types"; +} from "./types"; import { canHaveIllegalDecorators, chainDiagnosticMessages, @@ -341,7 +341,7 @@ import { typeDirectiveIsEqualTo, walkUpParenthesizedExpressions, writeFileEnsuringDirectories, -} from "../utilities"; +} from "./utilities"; import { getDefaultLibFileName, hasJSDocNodes, @@ -350,15 +350,15 @@ import { isModifier, isStringLiteralLike, sortAndDeduplicateDiagnostics, -} from "../utilitiesPublic"; +} from "./utilitiesPublic"; import { explainIfFileIsRedirectAndImpliedFormat, fileIncludeReasonToDiagnostics, getMatchedFileSpec, getMatchedIncludeSpec, -} from "../watch"; -import { ProgramHost } from "../watchPublic"; -import { DirectoryStructureHost } from "../watchUtilities"; +} from "./watch"; +import { ProgramHost } from "./watchPublic"; +import { DirectoryStructureHost } from "./watchUtilities"; import { changeExtension, extensionFromPath, @@ -368,7 +368,7 @@ import { removeFileExtension, resolutionExtensionIsTSOrJson, supportedJSExtensionsFlat, -} from "../extension"; +} from "./extension"; export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string | undefined { return forEachAncestorDirectory(searchPath, ancestor => { diff --git a/src/compiler/program/utilities.ts b/src/compiler/programUtilities.ts similarity index 92% rename from src/compiler/program/utilities.ts rename to src/compiler/programUtilities.ts index 4f53a9417bb29..6aa4b9db4fb63 100644 --- a/src/compiler/program/utilities.ts +++ b/src/compiler/programUtilities.ts @@ -1,15 +1,15 @@ -import * as Debug from "../debug"; +import * as Debug from "./debug"; import { affectsDeclarationPathOptionDeclarations, affectsEmitOptionDeclarations, moduleResolutionOptionDeclarations, optionsAffectingProgramStructure, semanticDiagnosticsOptionDeclarations, -} from "../commandLineParser/commandLineParser"; +} from "./commandLineParser"; import { createModeAwareCache, ModeAwareCache, -} from "../moduleNameResolver/moduleNameResolver"; +} from "./moduleNameResolver"; import { CompilerOptions, ResolutionMode, @@ -17,8 +17,8 @@ import { ResolvedModuleWithFailedLookupLocations, ResolvedTypeReferenceDirectiveWithFailedLookupLocations, SourceFile, -} from "../types"; -import { optionsHaveChanges } from "../utilities"; +} from "./types"; +import { optionsHaveChanges } from "./utilities"; /** @internal */ export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModuleWithFailedLookupLocations, mode: ResolutionMode): void { diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index 5ac4da654627c..44f3c1d007dd3 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -28,7 +28,7 @@ import { resolveModuleName, trace, updateResolutionField, -} from "./moduleNameResolver/moduleNameResolver"; +} from "./moduleNameResolver"; import { directorySeparator, fileExtensionIs, @@ -44,8 +44,8 @@ import { import { createTypeReferenceResolutionLoader, inferredTypesContainingFile, moduleResolutionNameAndModeGetter, ResolutionLoader, -} from "./program/program"; -import { ignoredPaths } from "./sys/utilities"; +} from "./program"; +import { ignoredPaths } from "./sysUtilities"; import { CharacterCodes, CompilerOptions, diff --git a/src/compiler/scanner/scanner.ts b/src/compiler/scanner.ts similarity index 98% rename from src/compiler/scanner/scanner.ts rename to src/compiler/scanner.ts index d90aae862f06d..be03510c6a961 100644 --- a/src/compiler/scanner/scanner.ts +++ b/src/compiler/scanner.ts @@ -1,4 +1,4 @@ -import * as Debug from "../debug"; +import * as Debug from "./debug"; import { append, arraysEqual, @@ -9,13 +9,13 @@ import { isWhiteSpaceLike, isWhiteSpaceSingleLine, trimStringStart, -} from "../core"; -import { Diagnostics } from "../diagnosticInformationMap.generated"; -import { textToKeyword, textToToken } from "./keywords"; +} from "./core"; +import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { textToKeyword, textToToken } from "./scannerKeywords"; import { parsePseudoBigInt, positionIsSynthesized, -} from "./utilities"; +} from "./scannerUtilities"; import { CharacterCodes, CommentDirective, @@ -32,7 +32,7 @@ import { SourceFileLike, SyntaxKind, TokenFlags, -} from "../types"; +} from "./types"; export type ErrorCallback = (message: DiagnosticMessage, length: number) => void; diff --git a/src/compiler/scanner/keywords.ts b/src/compiler/scannerKeywords.ts similarity index 96% rename from src/compiler/scanner/keywords.ts rename to src/compiler/scannerKeywords.ts index 32d3f9ddd0977..47c724101da61 100644 --- a/src/compiler/scanner/keywords.ts +++ b/src/compiler/scannerKeywords.ts @@ -1,8 +1,8 @@ -import { MapLike } from "../corePublic"; +import { MapLike } from "./corePublic"; import { KeywordSyntaxKind, SyntaxKind, -} from "../types"; +} from "./types"; export const textToKeywordObj: MapLike = { abstract: SyntaxKind.AbstractKeyword, diff --git a/src/compiler/scanner/utilities.ts b/src/compiler/scannerUtilities.ts similarity index 96% rename from src/compiler/scanner/utilities.ts rename to src/compiler/scannerUtilities.ts index 5b0d905cf06ea..5ce6ffc28dfdc 100644 --- a/src/compiler/scanner/utilities.ts +++ b/src/compiler/scannerUtilities.ts @@ -1,4 +1,4 @@ -import { CharacterCodes } from "../types"; +import { CharacterCodes } from "./types"; /** @internal */ export function positionIsSynthesized(pos: number): boolean { diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index 28d953130914a..ab76489bd09d0 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -20,7 +20,7 @@ import { getNormalizedAbsolutePath, getRelativePathToDirectoryOrUrl, } from "./path"; -import { getPositionOfLineAndCharacter } from "./scanner/scanner"; +import { getPositionOfLineAndCharacter } from "./scanner"; import { CharacterCodes, DocumentPosition, diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts index 11402f67bc275..ccc1ee056fc0b 100644 --- a/src/compiler/symbolWalker.ts +++ b/src/compiler/symbolWalker.ts @@ -1,4 +1,4 @@ -import { getSymbolId } from "./checker/utilities"; +import { getSymbolId } from "./checkerUtilities"; import { clear, forEach, diff --git a/src/compiler/symlinkCache.ts b/src/compiler/symlinkCache.ts index 52cad963d88a2..399764e07f1fd 100644 --- a/src/compiler/symlinkCache.ts +++ b/src/compiler/symlinkCache.ts @@ -6,7 +6,7 @@ import { MultiMap, startsWith, } from "./core"; -import { ModeAwareCache } from "./moduleNameResolver/moduleNameResolver"; +import { ModeAwareCache } from "./moduleNameResolver"; import { ensureTrailingDirectorySeparator, getNormalizedAbsolutePath, @@ -14,7 +14,7 @@ import { getPathFromPathComponents, toPath, } from "./path"; -import { containsIgnoredPath } from "./sys/utilities"; +import { containsIgnoredPath } from "./sysUtilities"; import { Path, ResolvedModuleFull, diff --git a/src/compiler/sys/sys.ts b/src/compiler/sys.ts similarity index 97% rename from src/compiler/sys/sys.ts rename to src/compiler/sys.ts index 8ef22854a52e3..033e6488a2157 100644 --- a/src/compiler/sys/sys.ts +++ b/src/compiler/sys.ts @@ -1,5 +1,5 @@ -import * as Debug from "../debug"; -import { matchesExclude } from "../commandLineParser/commandLineParser"; +import * as Debug from "./debug"; +import { matchesExclude } from "./commandLineParser"; import { isNodeLikeSystem } from "./platform"; import { contains, @@ -19,14 +19,14 @@ import { startsWith, stringContains, unorderedRemoveItem, -} from "../core"; -import { Comparison } from "../corePublic"; +} from "./core"; +import { Comparison } from "./corePublic"; import { emptyFileSystemEntries, FileSystemEntries, matchFiles, -} from "../fileMatcher"; -import { resolveJSModule } from "../moduleNameResolver/moduleNameResolver"; +} from "./fileMatcher"; +import { resolveJSModule } from "./moduleNameResolver"; import { combinePaths, containsPath, @@ -37,10 +37,10 @@ import { getRootLength, normalizePath, normalizeSlashes, -} from "../path"; -import { perfLogger } from "../perfLogger"; -import { timestamp } from "../performanceCore"; -import { ignoredPaths } from "./utilities"; +} from "./path"; +import { perfLogger } from "./perfLogger"; +import { timestamp } from "./performanceCore"; +import { ignoredPaths } from "./sysUtilities"; import { DirectoryWatcherCallback, FileWatcher, @@ -52,15 +52,15 @@ import { WatchDirectoryKind, WatchFileKind, WatchOptions, -} from "../types"; +} from "./types"; import { closeFileWatcher, writeFileEnsuringDirectories, -} from "../utilities"; +} from "./utilities"; import { closeFileWatcherOf, getFallbackOptions, -} from "../watchUtilities"; +} from "./watchUtilities"; declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any; declare function clearTimeout(handle: any): void; diff --git a/src/compiler/sys/utilities.ts b/src/compiler/sysUtilities.ts similarity index 79% rename from src/compiler/sys/utilities.ts rename to src/compiler/sysUtilities.ts index 86d37012402b4..0cc707e930bb6 100644 --- a/src/compiler/sys/utilities.ts +++ b/src/compiler/sysUtilities.ts @@ -1,4 +1,4 @@ -import { some, stringContains } from "../core"; +import { some, stringContains } from "./core"; /** @internal */ export const ignoredPaths = ["/node_modules/.", "/.git", "/.#"]; diff --git a/src/compiler/tracing.ts b/src/compiler/tracing.ts index 37dfa5931bdad..4ba9756fdcd62 100644 --- a/src/compiler/tracing.ts +++ b/src/compiler/tracing.ts @@ -2,7 +2,7 @@ import * as performance from "./performance"; import * as Debug from "./debug"; import { combinePaths } from "./path"; import { timestamp } from "./performanceCore"; -import { getLineAndCharacterOfPosition } from "./scanner/scanner"; +import { getLineAndCharacterOfPosition } from "./scanner"; import { ConditionalType, EvolvingArrayType, diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 1f3ba29cfba04..fab79bc03c32d 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -24,7 +24,7 @@ import { tryCast, } from "../core"; import { Diagnostics } from "../diagnosticInformationMap.generated"; -import { getOutputPathsFor } from "../emitter/emitter"; +import { getOutputPathsFor } from "../emitter"; import { getCommentRange, removeAllComments, @@ -73,10 +73,10 @@ import { setOriginalNode, setTextRange, } from "../factory/utilitiesPublic"; -import { pathContainsNodeModules } from "../moduleNameResolver/moduleNameResolver"; -import { getModuleSpecifier } from "../moduleSpecifiers/moduleSpecifiers"; -import { parseNodeFactory } from "../parser/parser"; -import { setParent } from "../parser/utilities"; +import { pathContainsNodeModules } from "../moduleNameResolver"; +import { getModuleSpecifier } from "../moduleSpecifiers"; +import { parseNodeFactory } from "../parser"; +import { setParent } from "../parserUtilities"; import { getDirectoryPath, getRelativePathToDirectoryOrUrl, @@ -85,13 +85,13 @@ import { pathIsRelative, toPath, } from "../path"; -import { getResolutionModeOverrideForClause } from "../program/program"; +import { getResolutionModeOverrideForClause } from "../program"; import { getLeadingCommentRanges, getLineAndCharacterOfPosition, getTrailingCommentRanges, skipTrivia, -} from "../scanner/scanner"; +} from "../scanner"; import { transformNodes } from "../transformer"; import { AccessorDeclaration, @@ -242,7 +242,7 @@ import { getOriginalNodeId } from "./utilities"; import { getExternalModuleNameFromDeclaration, getResolvedExternalModuleName, -} from "../moduleNameResolver/utilities"; +} from "../moduleNameResolverUtilities"; /** @internal */ export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] | undefined { diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 696785f5aa797..c07898eecf73a 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -72,8 +72,8 @@ import { setOriginalNode, setTextRange, } from "../factory/utilitiesPublic"; -import { setParent } from "../parser/utilities"; -import { skipTrivia } from "../scanner/scanner"; +import { setParent } from "../parserUtilities"; +import { skipTrivia } from "../scanner"; import { __String, AccessorDeclaration, diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 34be80b366a32..4133ae08331a5 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -1,5 +1,5 @@ import * as Debug from "../debug"; -import { getNodeId } from "../checker/utilities"; +import { getNodeId } from "../checkerUtilities"; import { concatenate, forEach, diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index 9878efdb0b35e..11b2c0c30096d 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -1,5 +1,5 @@ import * as Debug from "../debug"; -import { getNodeId } from "../checker/utilities"; +import { getNodeId } from "../checkerUtilities"; import { addRange, append, diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index a4ad03f760070..89dfb136d8f45 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -26,7 +26,7 @@ import { setOriginalNode, setTextRange, } from "../factory/utilitiesPublic"; -import { setParent } from "../parser/utilities"; +import { setParent } from "../parserUtilities"; import { AccessorDeclaration, ArrayLiteralExpression, diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 8963de1655671..d5589c98388c8 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -34,11 +34,11 @@ import { startOnNewLine, } from "../factory/utilities"; import { setTextRange } from "../factory/utilitiesPublic"; -import { setParentRecursive } from "../parser/utilities"; +import { setParentRecursive } from "../parserUtilities"; import { getLineAndCharacterOfPosition, utf16EncodeAsString, -} from "../scanner/scanner"; +} from "../scanner"; import { Bundle, Expression, diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index da79fee08299c..7ffdd78cb6873 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1,5 +1,5 @@ import * as Debug from "../../debug"; -import { getNodeId } from "../../checker/utilities"; +import { getNodeId } from "../../checkerUtilities"; import { addRange, append, diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 86e7e64b05db0..e4b5c48afd20b 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -1,5 +1,5 @@ import * as Debug from "../../debug"; -import { getNodeId } from "../../checker/utilities"; +import { getNodeId } from "../../checkerUtilities"; import { addRange, append, diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 3af6cc3539a91..69b15c849e1af 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1,5 +1,5 @@ import * as Debug from "../debug"; -import { isInstantiatedModule } from "../checker/checker"; +import { isInstantiatedModule } from "../checker"; import { addRange, append, @@ -54,8 +54,8 @@ import { setOriginalNode, setTextRange, } from "../factory/utilitiesPublic"; -import { setParent } from "../parser/utilities"; -import { skipTrivia } from "../scanner/scanner"; +import { setParent } from "../parserUtilities"; +import { skipTrivia } from "../scanner"; import { __String, AccessorDeclaration, diff --git a/src/compiler/transformers/typeSerializer.ts b/src/compiler/transformers/typeSerializer.ts index d763be4ea0852..0d96dd50f83ac 100644 --- a/src/compiler/transformers/typeSerializer.ts +++ b/src/compiler/transformers/typeSerializer.ts @@ -14,8 +14,8 @@ import { isVoidExpression, } from "../factory/nodeTests"; import { setTextRange } from "../factory/utilitiesPublic"; -import { parseNodeFactory } from "../parser/parser"; -import { setParent } from "../parser/utilities"; +import { parseNodeFactory } from "../parser"; +import { setParent } from "../parserUtilities"; import { AccessorDeclaration, ArrayLiteralExpression, diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index ff43d25b1d96a..5959ce646c406 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -1,4 +1,4 @@ -import { getNodeId } from "../checker/utilities"; +import { getNodeId } from "../checkerUtilities"; import { append, cast, diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 12103d04ad94c..64829a005987a 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -22,7 +22,7 @@ import { getParsedCommandLineOfConfigFile, ParseConfigFileHost, updateErrorForNoInputFiles, -} from "./commandLineParser/commandLineParser"; +} from "./commandLineParser"; import { arrayToMap, assertType, @@ -49,13 +49,13 @@ import { getBuildInfo, getFirstProjectOutput, getTsBuildInfoEmitOutputFilePath, -} from "./emitter/emitter"; +} from "./emitter"; import { createModuleResolutionCache, createTypeReferenceDirectiveResolutionCache, ModuleResolutionCache, TypeReferenceDirectiveResolutionCache, -} from "./moduleNameResolver/moduleNameResolver"; +} from "./moduleNameResolver"; import { convertToRelativePath, getDirectoryPath, @@ -75,13 +75,13 @@ import { loadWithModeAwareCache, parseConfigHostFromCompilerHostLike, resolveProjectReferencePath, -} from "./program/program"; +} from "./program"; import { getModifiedTime, missingFileModifiedTime, PollingInterval, sys, -} from "./sys/sys"; +} from "./sys"; import { resolveConfigFileProjectName, Status, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a66074060c922..269727c9fcdd3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1,5 +1,5 @@ import { ProgramBuildInfo } from "./builder"; -import { OptionsNameMap } from "./commandLineParser/commandLineParser"; +import { OptionsNameMap } from "./commandLineParser"; import { GetCanonicalFileName, MultiMap, @@ -17,8 +17,8 @@ import { ModuleResolutionCache, PackageJsonInfo, PackageJsonInfoCache, -} from "./moduleNameResolver/moduleNameResolver"; -import { CreateSourceFileOptions } from "./parser/parser"; +} from "./moduleNameResolver"; +import { CreateSourceFileOptions } from "./parser"; import { SymlinkCache } from "./symlinkCache"; import { ThisContainer } from "./utilities"; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 60c5a04ffcad2..3e005d1ac3d12 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1,5 +1,5 @@ import * as Debug from "./debug"; -import { getSymbolId } from "./checker/utilities"; +import { getSymbolId } from "./checkerUtilities"; import { addRange, arrayFrom, @@ -161,11 +161,11 @@ import { skipTrivia, stringToToken, tokenToString, -} from "./scanner/scanner"; +} from "./scanner"; import { parsePseudoBigInt, positionIsSynthesized, -} from "./scanner/utilities"; +} from "./scannerUtilities"; import { __String, AccessExpression, diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 8c4478bc69a13..c4ae80d07db64 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -84,7 +84,7 @@ import { normalizePath, pathIsRelative, } from "./path"; -import { stringToToken } from "./scanner/scanner"; +import { stringToToken } from "./scanner"; import { __String, AccessExpression, diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 8b39d02e8dcf2..a2fc1b2df7cd2 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -10,7 +10,7 @@ import { getParsedCommandLineOfConfigFile, ParseConfigFileHost, targetOptionDeclaration, -} from "./commandLineParser/commandLineParser"; +} from "./commandLineParser"; import { addRange, contains, @@ -57,8 +57,8 @@ import { getReferencedFileLocation, isReferencedFile, isReferenceFileLocation, -} from "./program/program"; -import { getLineAndCharacterOfPosition } from "./scanner/scanner"; +} from "./program"; +import { getLineAndCharacterOfPosition } from "./scanner"; import { sourceMapCommentRegExp, sourceMapCommentRegExpDontCareLineStart, @@ -67,7 +67,7 @@ import { import { generateDjb2Hash, sys, -} from "./sys/sys"; +} from "./sys"; import { ReportEmitErrorSummary, ReportFileInError, diff --git a/src/compiler/watchPublic.ts b/src/compiler/watchPublic.ts index 7a9db4cdaac6a..60498f3b62ad3 100644 --- a/src/compiler/watchPublic.ts +++ b/src/compiler/watchPublic.ts @@ -13,7 +13,7 @@ import { getFileNamesFromConfigSpecs, getParsedCommandLineOfConfigFile, updateErrorForNoInputFiles, -} from "./commandLineParser/commandLineParser"; +} from "./commandLineParser"; import { createGetCanonicalFileName, isArray, @@ -30,9 +30,9 @@ import { Diagnostics } from "./diagnosticInformationMap.generated"; import { getBuildInfo, getTsBuildInfoEmitOutputFilePath, -} from "./emitter/emitter"; -import { ModuleResolutionCache } from "./moduleNameResolver/moduleNameResolver"; -import { CreateSourceFileOptions } from "./parser/parser"; +} from "./emitter"; +import { ModuleResolutionCache } from "./moduleNameResolver"; +import { CreateSourceFileOptions } from "./parser"; import { getDirectoryPath, getNormalizedAbsolutePath, @@ -45,8 +45,8 @@ import { getConfigFileParsingDiagnostics, isProgramUptoDate, parseConfigHostFromCompilerHostLike, -} from "./program/program"; -import { changesAffectModuleResolution } from "./program/utilities"; +} from "./program"; +import { changesAffectModuleResolution } from "./programUtilities"; import { createResolutionCache, ResolutionCacheHost, @@ -54,7 +54,7 @@ import { import { PollingInterval, sys, -} from "./sys/sys"; +} from "./sys"; import { BuildInfo, CompilerHost, diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index 21d9ba40da5f7..7df99cb3f8b74 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -4,7 +4,7 @@ import { ExtendedConfigCacheEntry, isExcludedFile, matchesExclude, -} from "./commandLineParser/commandLineParser"; +} from "./commandLineParser"; import { arrayToMap, binarySearch, @@ -29,7 +29,7 @@ import { FileSystemEntries, matchFiles, } from "./fileMatcher"; -import { isDeclarationFileName } from "./parser/parser"; +import { isDeclarationFileName } from "./parser"; import { ensureTrailingDirectorySeparator, fileExtensionIs, @@ -46,7 +46,7 @@ import { removeIgnoredPath } from "./resolutionCache"; import { PollingInterval, setSysLog, -} from "./sys/sys"; +} from "./sys"; import { CompilerOptions, DirectoryWatcherCallback, diff --git a/src/executeCommandLine/executeCommandLine.ts b/src/executeCommandLine/executeCommandLine.ts index 7228822259bc2..cde378707ae18 100644 --- a/src/executeCommandLine/executeCommandLine.ts +++ b/src/executeCommandLine/executeCommandLine.ts @@ -17,7 +17,7 @@ import { optionsForWatch, parseBuildCommand, parseCommandLine, -} from "../compiler/commandLineParser/commandLineParser"; +} from "../compiler/commandLineParser"; import { arrayFrom, compareStringsCaseInsensitive, @@ -49,9 +49,9 @@ import { createProgram, findConfigFile, getConfigFileParsingDiagnostics, -} from "../compiler/program/program"; -import { getLineStarts } from "../compiler/scanner/scanner"; -import { sys } from "../compiler/sys/sys"; +} from "../compiler/program"; +import { getLineStarts } from "../compiler/scanner"; +import { sys } from "../compiler/sys"; import { dumpTracingLegend, startTracing, diff --git a/src/harness/harnessUtils.ts b/src/harness/harnessUtils.ts index 9ae8bcfb4b9d5..9dcbcd71a3ae7 100644 --- a/src/harness/harnessUtils.ts +++ b/src/harness/harnessUtils.ts @@ -1,6 +1,6 @@ import * as ts from "./_namespaces/ts"; import * as Harness from "./_namespaces/Harness"; -import { containsParseError } from "../compiler/parser/utilities"; +import { containsParseError } from "../compiler/parserUtilities"; export function encodeString(s: string): string { return ts.sys.bufferFrom!(s).toString("utf8"); diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index 3f6002feecf5b..a9a08b574dccb 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { readConfigFile } from "../compiler/commandLineParser/commandLineParser"; +import { readConfigFile } from "../compiler/commandLineParser"; import { compareStringsCaseSensitive, deduplicate, diff --git a/src/jsTyping/shared.ts b/src/jsTyping/shared.ts index 6e4a58a0342e2..a85cbef5ae772 100644 --- a/src/jsTyping/shared.ts +++ b/src/jsTyping/shared.ts @@ -1,5 +1,5 @@ import { padLeft } from "../compiler/core"; -import { sys } from "../compiler/sys/sys"; +import { sys } from "../compiler/sys"; export type ActionSet = "action::set"; export type ActionInvalidate = "action::invalidate"; diff --git a/src/loggedIO/loggedIO.ts b/src/loggedIO/loggedIO.ts index 94601d765c0be..dc8955a1212e4 100644 --- a/src/loggedIO/loggedIO.ts +++ b/src/loggedIO/loggedIO.ts @@ -1,4 +1,4 @@ -import { parseCommandLine } from "../compiler/commandLineParser/commandLineParser"; +import { parseCommandLine } from "../compiler/commandLineParser"; import { createGetCanonicalFileName, flatMap, diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 44477aaefacce..ccd825ed25d23 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -10,7 +10,7 @@ import { parseJsonSourceFileConfigFileContent, tryReadFile, typeAcquisitionDeclarations, -} from "../compiler/commandLineParser/commandLineParser"; +} from "../compiler/commandLineParser"; import { arrayFrom, arrayToMap, @@ -42,8 +42,8 @@ import { ReadonlyCollection, version, } from "../compiler/corePublic"; -import { parsePackageName } from "../compiler/moduleNameResolver/moduleNameResolver"; -import { parseJsonText } from "../compiler/parser/parser"; +import { parsePackageName } from "../compiler/moduleNameResolver"; +import { parseJsonText } from "../compiler/parser"; import { combinePaths, containsPath, @@ -65,7 +65,7 @@ import { import { forEachResolvedProjectReference, resolveProjectReferencePath, -} from "../compiler/program/program"; +} from "../compiler/program"; import { canWatchDirectoryOrFile, removeIgnoredPath, @@ -74,7 +74,7 @@ import { getFileWatcherEventKind, missingFileModifiedTime, PollingInterval, -} from "../compiler/sys/sys"; +} from "../compiler/sys"; import { tracing } from "../compiler/tracing"; import { CommandLineOption, diff --git a/src/server/moduleSpecifierCache.ts b/src/server/moduleSpecifierCache.ts index 1b0cc7245a66c..6358ee0e41594 100644 --- a/src/server/moduleSpecifierCache.ts +++ b/src/server/moduleSpecifierCache.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { nodeModulesPathPart } from "../compiler/moduleNameResolver/moduleNameResolver"; +import { nodeModulesPathPart } from "../compiler/moduleNameResolver"; import { FileWatcher, ModulePath, diff --git a/src/server/project.ts b/src/server/project.ts index 71ae5f4e54a1d..9085e3250a370 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1,6 +1,6 @@ import * as Debug from "../compiler/debug"; import { BuilderState } from "../compiler/builderState"; -import { updateErrorForNoInputFiles } from "../compiler/commandLineParser/commandLineParser"; +import { updateErrorForNoInputFiles } from "../compiler/commandLineParser"; import { addRange, append, @@ -37,8 +37,8 @@ import { PackageJsonInfo, parsePackageName, resolvePackageNameToPackageJson, -} from "../compiler/moduleNameResolver/moduleNameResolver"; -import { isDeclarationFileName } from "../compiler/parser/parser"; +} from "../compiler/moduleNameResolver"; +import { isDeclarationFileName } from "../compiler/parser"; import { combinePaths, fileExtensionIs, @@ -50,7 +50,7 @@ import { } from "../compiler/path"; import { perfLogger } from "../compiler/perfLogger"; import { timestamp } from "../compiler/performanceCore"; -import { inferredTypesContainingFile } from "../compiler/program/program"; +import { inferredTypesContainingFile } from "../compiler/program"; import { createResolutionCache, ResolutionCache, @@ -58,7 +58,7 @@ import { import { generateDjb2Hash, PollingInterval, -} from "../compiler/sys/sys"; +} from "../compiler/sys"; import { tracing } from "../compiler/tracing"; import { CompilerHost, @@ -174,9 +174,9 @@ import { createSymlinkCache, SymlinkCache, } from "../compiler/symlinkCache"; -import { changesAffectModuleResolution } from "../compiler/program/utilities"; +import { changesAffectModuleResolution } from "../compiler/programUtilities"; import { removeFileExtension, resolutionExtensionIsTSOrJson } from "./_namespaces/ts"; -import { getDeclarationEmitOutputFilePathWorker } from "../compiler/emitter/utilities"; +import { getDeclarationEmitOutputFilePathWorker } from "../compiler/emitterUtilities"; export enum ProjectKind { Inferred, diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 235ed3a45ee31..ffdb821dd6d40 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -18,7 +18,7 @@ import { computeLineAndCharacterOfPosition, computeLineStarts, computePositionOfLineAndCharacter, -} from "../compiler/scanner/scanner"; +} from "../compiler/scanner"; import { getLineInfo, LineInfo, diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index 4cf2eae8997ca..5bb009761a1cf 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -1,6 +1,6 @@ import * as Debug from "../compiler/debug"; import * as protocol from "./protocol"; -import { computeLineStarts } from "../compiler/scanner/scanner"; +import { computeLineStarts } from "../compiler/scanner"; import { TextChangeRange, TextSpan, diff --git a/src/server/session.ts b/src/server/session.ts index 51eb349a0d319..acdb37b3f7f8d 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -41,20 +41,20 @@ import { getTemporaryModuleResolutionState, nodeModulesPathPart, unmangleScopedPackageName, -} from "../compiler/moduleNameResolver/moduleNameResolver"; -import { getNodeModulePathParts } from "../compiler/moduleSpecifiers/utilities"; -import { isDeclarationFileName } from "../compiler/parser/parser"; +} from "../compiler/moduleNameResolver"; +import { getNodeModulePathParts } from "../compiler/moduleSpecifiersUtilities"; +import { isDeclarationFileName } from "../compiler/parser"; import { getNormalizedAbsolutePath, normalizePath, } from "../compiler/path"; import { perfLogger } from "../compiler/perfLogger"; -import { flattenDiagnosticMessageText } from "../compiler/program/program"; +import { flattenDiagnosticMessageText } from "../compiler/program"; import { computeLineAndCharacterOfPosition, computeLineStarts, getLineAndCharacterOfPosition, -} from "../compiler/scanner/scanner"; +} from "../compiler/scanner"; import { tracing } from "../compiler/tracing"; import { BufferEncoding, diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 7ff68c5d9ee9b..d8c822f6ea29b 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -13,7 +13,7 @@ import { isVariableDeclarationList, } from "../compiler/factory/nodeTests"; import { canHaveDecorators } from "../compiler/factory/utilitiesPublic"; -import { skipTrivia } from "../compiler/scanner/scanner"; +import { skipTrivia } from "../compiler/scanner"; import { ArrayLiteralExpression, BinaryExpression, diff --git a/src/services/callHierarchy.ts b/src/services/callHierarchy.ts index 4bb291f6be9b1..7caf2f498aded 100644 --- a/src/services/callHierarchy.ts +++ b/src/services/callHierarchy.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { getNodeId } from "../compiler/checker/utilities"; +import { getNodeId } from "../compiler/checkerUtilities"; import { append, compareStringsCaseSensitive, @@ -11,7 +11,7 @@ import { isArray, map, } from "../compiler/core"; -import { createPrinter } from "../compiler/emitter/emitter"; +import { createPrinter } from "../compiler/emitter"; import { isArrowFunction, isClassDeclaration, @@ -34,8 +34,8 @@ import { isVariableDeclaration, } from "../compiler/factory/nodeTests"; import { canHaveModifiers } from "../compiler/factory/utilitiesPublic"; -import { forEachChild } from "../compiler/parser/parser"; -import { skipTrivia } from "../compiler/scanner/scanner"; +import { forEachChild } from "../compiler/parser"; +import { skipTrivia } from "../compiler/scanner"; import { AccessExpression, ArrowFunction, diff --git a/src/services/classifier.ts b/src/services/classifier.ts index 46747418baa51..2d823371ccaa5 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -15,13 +15,13 @@ import { isJSDoc, isModuleDeclaration, } from "../compiler/factory/nodeTests"; -import { parseIsolatedJSDocComment } from "../compiler/parser/parser"; -import { setParent } from "../compiler/parser/utilities"; +import { parseIsolatedJSDocComment } from "../compiler/parser"; +import { setParent } from "../compiler/parserUtilities"; import { couldStartTrivia, createScanner, Scanner, -} from "../compiler/scanner/scanner"; +} from "../compiler/scanner"; import { __String, CancellationToken, diff --git a/src/services/classifier2020.ts b/src/services/classifier2020.ts index 66c3c511b7d4d..863b92943fdbb 100644 --- a/src/services/classifier2020.ts +++ b/src/services/classifier2020.ts @@ -16,7 +16,7 @@ import { isSourceFile, isVariableDeclaration, } from "../compiler/factory/nodeTests"; -import { forEachChild } from "../compiler/parser/parser"; +import { forEachChild } from "../compiler/parser"; import { BindingElement, CancellationToken, diff --git a/src/services/codefixes/addMissingAsync.ts b/src/services/codefixes/addMissingAsync.ts index 4eaea1c329209..a02c001a25264 100644 --- a/src/services/codefixes/addMissingAsync.ts +++ b/src/services/codefixes/addMissingAsync.ts @@ -1,4 +1,4 @@ -import { getNodeId } from "../../compiler/checker/utilities"; +import { getNodeId } from "../../compiler/checkerUtilities"; import { find, isNumber, diff --git a/src/services/codefixes/addMissingAwait.ts b/src/services/codefixes/addMissingAwait.ts index 3f19ac2ad285b..63f6c4c26c995 100644 --- a/src/services/codefixes/addMissingAwait.ts +++ b/src/services/codefixes/addMissingAwait.ts @@ -1,4 +1,4 @@ -import { getSymbolId } from "../../compiler/checker/utilities"; +import { getSymbolId } from "../../compiler/checkerUtilities"; import { compact, contains, diff --git a/src/services/codefixes/convertConstToLet.ts b/src/services/codefixes/convertConstToLet.ts index b214a4c2dc401..88c855a96529a 100644 --- a/src/services/codefixes/convertConstToLet.ts +++ b/src/services/codefixes/convertConstToLet.ts @@ -1,4 +1,4 @@ -import { getSymbolId } from "../../compiler/checker/utilities"; +import { getSymbolId } from "../../compiler/checkerUtilities"; import { tryCast } from "../../compiler/core"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; diff --git a/src/services/codefixes/convertFunctionToEs6Class.ts b/src/services/codefixes/convertFunctionToEs6Class.ts index 40e36182d5004..f2902fdd7e775 100644 --- a/src/services/codefixes/convertFunctionToEs6Class.ts +++ b/src/services/codefixes/convertFunctionToEs6Class.ts @@ -23,7 +23,7 @@ import { isVariableDeclarationList, } from "../../compiler/factory/nodeTests"; import { canHaveModifiers } from "../../compiler/factory/utilitiesPublic"; -import { isIdentifierText } from "../../compiler/scanner/scanner"; +import { isIdentifierText } from "../../compiler/scanner"; import { __String, AccessExpression, diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 2da3015859658..9460f13fb9113 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -2,7 +2,7 @@ import * as Debug from "../../compiler/debug"; import { getNodeId, getSymbolId, -} from "../../compiler/checker/utilities"; +} from "../../compiler/checkerUtilities"; import { concatenate, createMultiMap, @@ -30,9 +30,9 @@ import { isReturnStatement, isVariableDeclaration, } from "../../compiler/factory/nodeTests"; -import { forEachChild } from "../../compiler/parser/parser"; -import { forEachReturnStatement } from "../../compiler/parser/utilities"; -import { skipTrivia } from "../../compiler/scanner/scanner"; +import { forEachChild } from "../../compiler/parser"; +import { forEachReturnStatement } from "../../compiler/parserUtilities"; +import { skipTrivia } from "../../compiler/scanner"; import { ArrowFunction, AwaitExpression, diff --git a/src/services/codefixes/convertToEsModule.ts b/src/services/codefixes/convertToEsModule.ts index 68a342670fa7c..de65fff5d1934 100644 --- a/src/services/codefixes/convertToEsModule.ts +++ b/src/services/codefixes/convertToEsModule.ts @@ -27,7 +27,7 @@ import { isPropertyAccessExpression, isVariableStatement, } from "../../compiler/factory/nodeTests"; -import { getModeForUsageLocation } from "../../compiler/program/program"; +import { getModeForUsageLocation } from "../../compiler/program"; import { __String, ArrowFunction, diff --git a/src/services/codefixes/convertToTypeOnlyExport.ts b/src/services/codefixes/convertToTypeOnlyExport.ts index 83c98d516953a..3b5923d07f808 100644 --- a/src/services/codefixes/convertToTypeOnlyExport.ts +++ b/src/services/codefixes/convertToTypeOnlyExport.ts @@ -1,4 +1,4 @@ -import { getNodeId } from "../../compiler/checker/utilities"; +import { getNodeId } from "../../compiler/checkerUtilities"; import { contains, filter, diff --git a/src/services/codefixes/disableJsDiagnostics.ts b/src/services/codefixes/disableJsDiagnostics.ts index 1a77b53487b6b..f189fb4b31480 100644 --- a/src/services/codefixes/disableJsDiagnostics.ts +++ b/src/services/codefixes/disableJsDiagnostics.ts @@ -3,7 +3,7 @@ import { tryAddToSet, } from "../../compiler/core"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; -import { getLineAndCharacterOfPosition } from "../../compiler/scanner/scanner"; +import { getLineAndCharacterOfPosition } from "../../compiler/scanner"; import { DiagnosticCategory, SourceFile, diff --git a/src/services/codefixes/fixAddMissingConstraint.ts b/src/services/codefixes/fixAddMissingConstraint.ts index 054381f4c96a9..64f75f6eb9d4e 100644 --- a/src/services/codefixes/fixAddMissingConstraint.ts +++ b/src/services/codefixes/fixAddMissingConstraint.ts @@ -1,4 +1,4 @@ -import { getNodeId } from "../../compiler/checker/utilities"; +import { getNodeId } from "../../compiler/checkerUtilities"; import { find, isString, @@ -10,7 +10,7 @@ import { isMappedTypeNode, isTypeParameterDeclaration, } from "../../compiler/factory/nodeTests"; -import { flattenDiagnosticMessageText } from "../../compiler/program/program"; +import { flattenDiagnosticMessageText } from "../../compiler/program"; import { DiagnosticMessageChain, Node, diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index cb28fa2c30952..bf54e55bd31f2 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -1,5 +1,5 @@ import * as Debug from "../../compiler/debug"; -import { getNodeId } from "../../compiler/checker/utilities"; +import { getNodeId } from "../../compiler/checkerUtilities"; import { arrayFrom, concatenate, @@ -45,8 +45,8 @@ import { isTypeLiteralNode, } from "../../compiler/factory/nodeTests"; import { createPropertyNameNodeForIdentifierOrLiteral } from "../../compiler/factory/utilities"; -import { setParent } from "../../compiler/parser/utilities"; -import { isIdentifierText } from "../../compiler/scanner/scanner"; +import { setParent } from "../../compiler/parserUtilities"; +import { isIdentifierText } from "../../compiler/scanner"; import { __String, BigIntLiteralType, diff --git a/src/services/codefixes/fixAddVoidToPromise.ts b/src/services/codefixes/fixAddVoidToPromise.ts index 73dbfc0e8d8b7..424a2bfac4bd8 100644 --- a/src/services/codefixes/fixAddVoidToPromise.ts +++ b/src/services/codefixes/fixAddVoidToPromise.ts @@ -11,7 +11,7 @@ import { isTypeReferenceNode, isUnionTypeNode, } from "../../compiler/factory/nodeTests"; -import { skipTrivia } from "../../compiler/scanner/scanner"; +import { skipTrivia } from "../../compiler/scanner"; import { NewExpression, ParameterDeclaration, diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts index 24381ef27e996..1176287bd550e 100644 --- a/src/services/codefixes/fixAwaitInSyncFunction.ts +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -1,4 +1,4 @@ -import { getNodeId } from "../../compiler/checker/utilities"; +import { getNodeId } from "../../compiler/checkerUtilities"; import { first } from "../../compiler/core"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts index ce61ebe6ea048..b56ff15cdfa46 100644 --- a/src/services/codefixes/fixCannotFindModule.ts +++ b/src/services/codefixes/fixCannotFindModule.ts @@ -5,7 +5,7 @@ import { isStringLiteral } from "../../compiler/factory/nodeTests"; import { getTypesPackageName, parsePackageName, -} from "../../compiler/moduleNameResolver/moduleNameResolver"; +} from "../../compiler/moduleNameResolver"; import { SourceFile } from "../../compiler/types"; import { isExternalModuleNameRelative } from "../../compiler/utilitiesPublic"; import { nodeCoreModules } from "../../jsTyping/jsTyping"; diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index b5098e9fe04bb..8d51f696d812a 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -1,4 +1,4 @@ -import { getNodeId } from "../../compiler/checker/utilities"; +import { getNodeId } from "../../compiler/checkerUtilities"; import { cast, first, diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 703f143b93487..08fd925606636 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -1,5 +1,5 @@ import * as Debug from "../../compiler/debug"; -import { getNodeId } from "../../compiler/checker/utilities"; +import { getNodeId } from "../../compiler/checkerUtilities"; import { and, find, diff --git a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts index 2f9f394559c70..0f68e5064e616 100644 --- a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts +++ b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts @@ -1,10 +1,10 @@ -import { getNodeId } from "../../compiler/checker/utilities"; +import { getNodeId } from "../../compiler/checkerUtilities"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { isExpressionStatement, isPropertyAccessExpression, } from "../../compiler/factory/nodeTests"; -import { forEachChild } from "../../compiler/parser/parser"; +import { forEachChild } from "../../compiler/parser"; import { CallExpression, ConstructorDeclaration, diff --git a/src/services/codefixes/fixNaNEquality.ts b/src/services/codefixes/fixNaNEquality.ts index 2f5c876fef5ab..e444e47a32752 100644 --- a/src/services/codefixes/fixNaNEquality.ts +++ b/src/services/codefixes/fixNaNEquality.ts @@ -2,7 +2,7 @@ import { find } from "../../compiler/core"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; import { isBinaryExpression } from "../../compiler/factory/nodeTests"; -import { flattenDiagnosticMessageText } from "../../compiler/program/program"; +import { flattenDiagnosticMessageText } from "../../compiler/program"; import { BinaryExpression, DiagnosticMessageChain, diff --git a/src/services/codefixes/fixOverrideModifier.ts b/src/services/codefixes/fixOverrideModifier.ts index ff9c39b8483b5..68a49af0dd701 100644 --- a/src/services/codefixes/fixOverrideModifier.ts +++ b/src/services/codefixes/fixOverrideModifier.ts @@ -14,7 +14,7 @@ import { isOverrideModifier, isStaticModifier, } from "../../compiler/factory/nodeTests"; -import { skipTrivia } from "../../compiler/scanner/scanner"; +import { skipTrivia } from "../../compiler/scanner"; import { ConstructorDeclaration, DiagnosticMessage, diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts index 10526f3f038b3..23f5c66727f50 100644 --- a/src/services/codefixes/fixSpelling.ts +++ b/src/services/codefixes/fixSpelling.ts @@ -11,8 +11,8 @@ import { isPropertyAccessExpression, isQualifiedName, } from "../../compiler/factory/nodeTests"; -import { getModeForUsageLocation } from "../../compiler/program/program"; -import { isIdentifierText } from "../../compiler/scanner/scanner"; +import { getModeForUsageLocation } from "../../compiler/program"; +import { isIdentifierText } from "../../compiler/scanner"; import { ImportDeclaration, ModifierFlags, diff --git a/src/services/codefixes/fixUnusedLabel.ts b/src/services/codefixes/fixUnusedLabel.ts index 172d45cbc8f5c..d49b68b66e0ea 100644 --- a/src/services/codefixes/fixUnusedLabel.ts +++ b/src/services/codefixes/fixUnusedLabel.ts @@ -1,7 +1,7 @@ import { cast } from "../../compiler/core"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { isLabeledStatement } from "../../compiler/factory/nodeTests"; -import { skipTrivia } from "../../compiler/scanner/scanner"; +import { skipTrivia } from "../../compiler/scanner"; import { SourceFile, SyntaxKind, diff --git a/src/services/codefixes/importAdder.ts b/src/services/codefixes/importAdder.ts index 443d9ebe6f75a..a308d52415b84 100644 --- a/src/services/codefixes/importAdder.ts +++ b/src/services/codefixes/importAdder.ts @@ -2,7 +2,7 @@ import * as Debug from "../../compiler/debug"; import { getNodeId, getSymbolId, -} from "../../compiler/checker/utilities"; +} from "../../compiler/checkerUtilities"; import { arrayFrom, cast, @@ -42,11 +42,11 @@ import { isNamespaceImport, isStringLiteral, } from "../../compiler/factory/nodeTests"; -import { pathContainsNodeModules } from "../../compiler/moduleNameResolver/moduleNameResolver"; +import { pathContainsNodeModules } from "../../compiler/moduleNameResolver"; import { getModuleSpecifiersWithCacheInfo, tryGetModuleSpecifiersFromCache, -} from "../../compiler/moduleSpecifiers/moduleSpecifiers"; +} from "../../compiler/moduleSpecifiers"; import { getBaseFileName, getDirectoryPath, @@ -56,7 +56,7 @@ import { import { isIdentifierPart, isIdentifierStart, -} from "../../compiler/scanner/scanner"; +} from "../../compiler/scanner"; import { AnyImportOrRequire, AnyImportOrRequireStatement, diff --git a/src/services/completions.ts b/src/services/completions.ts index 69790900d28bf..b8642cd88c745 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { getSymbolId } from "../compiler/checker/utilities"; +import { getSymbolId } from "../compiler/checkerUtilities"; import { append, cast, @@ -35,7 +35,7 @@ import { SortedArray, } from "../compiler/corePublic"; import { Diagnostics } from "../compiler/diagnosticInformationMap.generated"; -import { createPrinter } from "../compiler/emitter/emitter"; +import { createPrinter } from "../compiler/emitter"; import { setSnippetElement } from "../compiler/factory/emitNode"; import { factory } from "../compiler/factory/nodeFactory"; import { @@ -100,7 +100,7 @@ import { isIdentifierText, stringToToken, tokenToString, -} from "../compiler/scanner/scanner"; +} from "../compiler/scanner"; import { isInitializedProperty } from "../compiler/transformers/utilities"; import { __String, diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index 0fa7995928370..1d633fcd0382d 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -36,8 +36,8 @@ import { isVariableStatement, isYieldExpression, } from "../compiler/factory/nodeTests"; -import { forEachChild } from "../compiler/parser/parser"; -import { forEachReturnStatement } from "../compiler/parser/utilities"; +import { forEachChild } from "../compiler/parser"; +import { forEachReturnStatement } from "../compiler/parserUtilities"; import { toPath } from "../compiler/path"; import { __String, diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index b32f35b9353d3..70535cbcde68d 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -1,7 +1,7 @@ import * as Debug from "../compiler/debug"; import { sourceFileAffectingCompilerOptions, -} from "../compiler/commandLineParser/commandLineParser"; +} from "../compiler/commandLineParser"; import { arrayFrom, createGetCanonicalFileName, @@ -9,16 +9,16 @@ import { getOrUpdate, identity, } from "../compiler/core"; -import { getKeyForCompilerOptions } from "../compiler/moduleNameResolver/moduleNameResolver"; +import { getKeyForCompilerOptions } from "../compiler/moduleNameResolver"; import { CreateSourceFileOptions, isDeclarationFileName, -} from "../compiler/parser/parser"; +} from "../compiler/parser"; import { toPath } from "../compiler/path"; import { getImpliedNodeFormatForFile, getSetExternalModuleIndicator, -} from "../compiler/program/program"; +} from "../compiler/program"; import { tracing } from "../compiler/tracing"; import { CompilerOptions, diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index 598f1a01acc88..b03c203931416 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { getSymbolId } from "../compiler/checker/utilities"; +import { getSymbolId } from "../compiler/checkerUtilities"; import { arrayIsEqualTo, createMultiMap, @@ -25,9 +25,9 @@ import { getPackageNameFromTypesPackageName, nodeModulesPathPart, unmangleScopedPackageName, -} from "../compiler/moduleNameResolver/moduleNameResolver"; -import { forEachFileNameOfModule } from "../compiler/moduleSpecifiers/moduleSpecifiers"; -import { getNodeModulePathParts } from "../compiler/moduleSpecifiers/utilities"; +} from "../compiler/moduleNameResolver"; +import { forEachFileNameOfModule } from "../compiler/moduleSpecifiers"; +import { getNodeModulePathParts } from "../compiler/moduleSpecifiersUtilities"; import { forEachAncestorDirectory, getBaseFileName, diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index e30c45235892f..8675def74e088 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -2,7 +2,7 @@ import * as Debug from "../compiler/debug"; import { getNodeId, getSymbolId, -} from "../compiler/checker/utilities"; +} from "../compiler/checkerUtilities"; import { append, cast, @@ -63,18 +63,18 @@ import { isUnionTypeNode, isVoidExpression, } from "../compiler/factory/nodeTests"; -import { forEachChild } from "../compiler/parser/parser"; -import { forEachReturnStatement } from "../compiler/parser/utilities"; +import { forEachChild } from "../compiler/parser"; +import { forEachReturnStatement } from "../compiler/parserUtilities"; import { getModeForUsageLocation, getReferencedFileLocation, isReferencedFile, isReferenceFileLocation, -} from "../compiler/program/program"; +} from "../compiler/program"; import { isIdentifierPart, tokenToString, -} from "../compiler/scanner/scanner"; +} from "../compiler/scanner"; import { __String, AssignmentDeclarationKind, diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index b9de579257967..b87fba826b513 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -9,7 +9,7 @@ import { } from "../../compiler/core"; import { isDecorator } from "../../compiler/factory/nodeTests"; import { canHaveModifiers } from "../../compiler/factory/utilitiesPublic"; -import { forEachChild } from "../../compiler/parser/parser"; +import { forEachChild } from "../../compiler/parser"; import { Block, CallExpression, diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index 73de8c7b578af..1ca1728d19484 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -8,7 +8,7 @@ import { isJsxElement, isJsxText, } from "../../compiler/factory/nodeTests"; -import { createScanner } from "../../compiler/scanner/scanner"; +import { createScanner } from "../../compiler/scanner"; import { LanguageVariant, Node, diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index cee053369d6d1..66a59be95428c 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -12,7 +12,7 @@ import { import { getLineAndCharacterOfPosition, skipTrivia, -} from "../../compiler/scanner/scanner"; +} from "../../compiler/scanner"; import { ArrayBindingPattern, ArrayLiteralExpression, diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index 339634d49f28f..966646a0ee147 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { getOptionFromName } from "../compiler/commandLineParser/commandLineParser"; +import { getOptionFromName } from "../compiler/commandLineParser"; import { createGetCanonicalFileName, emptyArray, @@ -22,8 +22,8 @@ import { getFileMatcherPatterns, getRegexFromPattern, } from "../compiler/fileMatcher"; -import { resolveModuleName } from "../compiler/moduleNameResolver/moduleNameResolver"; -import { updateModuleSpecifier } from "../compiler/moduleSpecifiers/moduleSpecifiers"; +import { resolveModuleName } from "../compiler/moduleNameResolver"; +import { updateModuleSpecifier } from "../compiler/moduleSpecifiers"; import { combinePaths, ensurePathIsNonModuleName, @@ -33,7 +33,7 @@ import { normalizePath, pathIsRelative, } from "../compiler/path"; -import { getModeForUsageLocation } from "../compiler/program/program"; +import { getModeForUsageLocation } from "../compiler/program"; import { Expression, ModuleResolutionHost, diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 9add5e2ecd6d8..9f87c6bec4389 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -26,13 +26,13 @@ import { isStaticModifier, isVariableDeclaration, } from "../compiler/factory/nodeTests"; -import { isDeclarationFileName } from "../compiler/parser/parser"; +import { isDeclarationFileName } from "../compiler/parser"; import { getDirectoryPath, resolvePath, } from "../compiler/path"; -import { getModeForUsageLocation } from "../compiler/program/program"; -import { skipTrivia } from "../compiler/scanner/scanner"; +import { getModeForUsageLocation } from "../compiler/program"; +import { skipTrivia } from "../compiler/scanner"; import { AssignmentDeclarationKind, AssignmentExpression, diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index d4b417779dcc5..40683724118fb 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { getSymbolId } from "../compiler/checker/utilities"; +import { getSymbolId } from "../compiler/checkerUtilities"; import { cast, forEach, diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts index 41805065820ec..114d85d5989f5 100644 --- a/src/services/inlayHints.ts +++ b/src/services/inlayHints.ts @@ -3,7 +3,7 @@ import { equateStringsCaseInsensitive, some, } from "../compiler/core"; -import { createPrinter } from "../compiler/emitter/emitter"; +import { createPrinter } from "../compiler/emitter"; import { isArrowFunction, isCallExpression, @@ -21,11 +21,11 @@ import { isPropertyDeclaration, isVariableDeclaration, } from "../compiler/factory/nodeTests"; -import { forEachChild } from "../compiler/parser/parser"; +import { forEachChild } from "../compiler/parser"; import { getLeadingCommentRanges, isIdentifierText, -} from "../compiler/scanner/scanner"; +} from "../compiler/scanner"; import { __String, ArrowFunction, diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index ae378f251760c..4dc7a6ad01ccd 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -25,7 +25,7 @@ import { isJSDoc, isJSDocParameterTag, } from "../compiler/factory/nodeTests"; -import { forEachReturnStatement } from "../compiler/parser/utilities"; +import { forEachReturnStatement } from "../compiler/parserUtilities"; import { ArrowFunction, AssignmentDeclarationKind, diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 5cd2be07fcdc9..cc6e7ab2f619d 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -30,7 +30,7 @@ import { isVariableDeclaration, } from "../compiler/factory/nodeTests"; import { setTextRange } from "../compiler/factory/utilitiesPublic"; -import { forEachChild } from "../compiler/parser/parser"; +import { forEachChild } from "../compiler/parser"; import { getBaseFileName, normalizePath, diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index 61f83a04bdfce..d1ca7a0379f9a 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -38,7 +38,7 @@ import { import { createScanner, Scanner, -} from "../compiler/scanner/scanner"; +} from "../compiler/scanner"; import { AnyImportOrRequireStatement, EmitFlags, diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index a75c89f3b4e08..4ee7e84c44d39 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -21,7 +21,7 @@ import { isTupleTypeNode, isVariableStatement, } from "../compiler/factory/nodeTests"; -import { getLeadingCommentRanges } from "../compiler/scanner/scanner"; +import { getLeadingCommentRanges } from "../compiler/scanner"; import { ArrowFunction, AssertClause, diff --git a/src/services/patternMatcher.ts b/src/services/patternMatcher.ts index f94a6bf4afdb8..22717693aa4eb 100644 --- a/src/services/patternMatcher.ts +++ b/src/services/patternMatcher.ts @@ -6,7 +6,7 @@ import { startsWith, } from "../compiler/core"; import { Comparison } from "../compiler/corePublic"; -import { isUnicodeIdentifierStart } from "../compiler/scanner/scanner"; +import { isUnicodeIdentifierStart } from "../compiler/scanner"; import { CharacterCodes, ScriptTarget, diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 30ac5b13e5b05..0a70897ae0a0c 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -6,7 +6,7 @@ import { import { processCommentPragmas, processPragmasIntoFields, -} from "../compiler/parser/parser"; +} from "../compiler/parser"; import { FileReference, PragmaContext, diff --git a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts index a1cf564b81081..4a44c784c6120 100644 --- a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts +++ b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts @@ -16,7 +16,7 @@ import { isVariableDeclarationList, isVariableStatement, } from "../../compiler/factory/nodeTests"; -import { forEachChild } from "../../compiler/parser/parser"; +import { forEachChild } from "../../compiler/parser"; import { ArrowFunction, Block, diff --git a/src/services/refactors/convertStringOrTemplateLiteral.ts b/src/services/refactors/convertStringOrTemplateLiteral.ts index adc49f1e9a4fd..a3bec9e9a31f7 100644 --- a/src/services/refactors/convertStringOrTemplateLiteral.ts +++ b/src/services/refactors/convertStringOrTemplateLiteral.ts @@ -14,7 +14,7 @@ import { isTemplateHead, isTemplateMiddle, } from "../../compiler/factory/nodeTests"; -import { getTrailingCommentRanges } from "../../compiler/scanner/scanner"; +import { getTrailingCommentRanges } from "../../compiler/scanner"; import { BinaryExpression, BinaryOperator, diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 5bc15d69b498f..21ee0d7d05e79 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -2,7 +2,7 @@ import * as Debug from "../../compiler/debug"; import { getNodeId, getSymbolId, -} from "../../compiler/checker/utilities"; +} from "../../compiler/checkerUtilities"; import { arrayFrom, assertType, @@ -53,8 +53,8 @@ import { isVariableStatement, } from "../../compiler/factory/nodeTests"; import { canHaveModifiers } from "../../compiler/factory/utilitiesPublic"; -import { forEachChild } from "../../compiler/parser/parser"; -import { positionIsSynthesized } from "../../compiler/scanner/utilities"; +import { forEachChild } from "../../compiler/parser"; +import { positionIsSynthesized } from "../../compiler/scannerUtilities"; import { nullTransformationContext } from "../../compiler/transformer"; import { __String, diff --git a/src/services/refactors/extractType.ts b/src/services/refactors/extractType.ts index 96f7fcf39e8e8..7451469f869ae 100644 --- a/src/services/refactors/extractType.ts +++ b/src/services/refactors/extractType.ts @@ -31,11 +31,11 @@ import { isTypeReferenceNode, } from "../../compiler/factory/nodeTests"; import { setTextRange } from "../../compiler/factory/utilitiesPublic"; -import { forEachChild } from "../../compiler/parser/parser"; +import { forEachChild } from "../../compiler/parser"; import { getLineAndCharacterOfPosition, skipTrivia, -} from "../../compiler/scanner/scanner"; +} from "../../compiler/scanner"; import { EmitFlags, JSDocTag, diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index 23ad14c249612..a6b058543de3e 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -1,5 +1,5 @@ import * as Debug from "../../compiler/debug"; -import { getSymbolId } from "../../compiler/checker/utilities"; +import { getSymbolId } from "../../compiler/checkerUtilities"; import { append, cast, @@ -44,7 +44,7 @@ import { canHaveDecorators, canHaveModifiers, } from "../../compiler/factory/utilitiesPublic"; -import { getModuleSpecifier } from "../../compiler/moduleSpecifiers/moduleSpecifiers"; +import { getModuleSpecifier } from "../../compiler/moduleSpecifiers"; import { combinePaths, getBaseFileName, diff --git a/src/services/services.ts b/src/services/services.ts index 7c1faa7ff46f9..10846bf0deb82 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3,7 +3,7 @@ import { getFileEmitOutput } from "../compiler/builderState"; import { ParseConfigFileHost, parseJsonSourceFileConfigFileContent, -} from "../compiler/commandLineParser/commandLineParser"; +} from "../compiler/commandLineParser"; import { compareValues, createGetCanonicalFileName, @@ -54,7 +54,7 @@ import { isPropertyAccessExpression, } from "../compiler/factory/nodeTests"; import { getSnippetElement } from "../compiler/factory/emitNode"; -import { ModeAwareCache } from "../compiler/moduleNameResolver/moduleNameResolver"; +import { ModeAwareCache } from "../compiler/moduleNameResolver"; import { ObjectAllocator, setObjectAllocator, @@ -65,7 +65,7 @@ import { forEachChild, tagNamesAreEquivalent, updateSourceFile, -} from "../compiler/parser/parser"; +} from "../compiler/parser"; import { combinePaths, getDirectoryPath, @@ -80,14 +80,14 @@ import { getImpliedNodeFormatForFile, getSetExternalModuleIndicator, isProgramUptoDate, -} from "../compiler/program/program"; +} from "../compiler/program"; import { computePositionOfLineAndCharacter, getLineAndCharacterOfPosition, getLineStarts, -} from "../compiler/scanner/scanner"; -import { positionIsSynthesized } from "../compiler/scanner/utilities"; -import { sys } from "../compiler/sys/sys"; +} from "../compiler/scanner"; +import { positionIsSynthesized } from "../compiler/scannerUtilities"; +import { sys } from "../compiler/sys"; import { tracing } from "../compiler/tracing"; import { __String, diff --git a/src/services/shims.ts b/src/services/shims.ts index c9d74f27e8f59..f8c5181675cca 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -1,7 +1,7 @@ import { EmitOutput } from "../compiler/builderStatePublic"; import { parseJsonSourceFileConfigFileContent, -} from "../compiler/commandLineParser/commandLineParser"; +} from "../compiler/commandLineParser"; import { clear, createGetCanonicalFileName, @@ -18,15 +18,15 @@ import { getAutomaticTypeDirectiveNames, resolveModuleName, resolveTypeReferenceDirective, -} from "../compiler/moduleNameResolver/moduleNameResolver"; -import { parseJsonText } from "../compiler/parser/parser"; +} from "../compiler/moduleNameResolver"; +import { parseJsonText } from "../compiler/parser"; import { getDirectoryPath, normalizeSlashes, toPath, } from "../compiler/path"; import { timestamp } from "../compiler/performanceCore"; -import { flattenDiagnosticMessageText } from "../compiler/program/program"; +import { flattenDiagnosticMessageText } from "../compiler/program"; import { CompilerOptions, Diagnostic, diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index b873f8fe481eb..1b6b3f64955fe 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -13,7 +13,7 @@ import { map, tryCast, } from "../compiler/core"; -import { createPrinter } from "../compiler/emitter/emitter"; +import { createPrinter } from "../compiler/emitter"; import { factory } from "../compiler/factory/nodeFactory"; import { isBinaryExpression, @@ -29,7 +29,7 @@ import { isTemplateSpan, isTemplateTail, } from "../compiler/factory/nodeTests"; -import { skipTrivia } from "../compiler/scanner/scanner"; +import { skipTrivia } from "../compiler/scanner"; import { ArrowFunction, BinaryExpression, diff --git a/src/services/smartSelection.ts b/src/services/smartSelection.ts index bdcf8d3b06656..77b4b18632f20 100644 --- a/src/services/smartSelection.ts +++ b/src/services/smartSelection.ts @@ -29,8 +29,8 @@ import { isVariableDeclarationList, isVariableStatement, } from "../compiler/factory/nodeTests"; -import { parseNodeFactory } from "../compiler/parser/parser"; -import { getTrailingCommentRanges } from "../compiler/scanner/scanner"; +import { parseNodeFactory } from "../compiler/parser"; +import { getTrailingCommentRanges } from "../compiler/scanner"; import { CharacterCodes, Node, diff --git a/src/services/sourcemaps.ts b/src/services/sourcemaps.ts index d9c82473a0ebb..1c3c87b955581 100644 --- a/src/services/sourcemaps.ts +++ b/src/services/sourcemaps.ts @@ -2,9 +2,9 @@ import { createGetCanonicalFileName, isString, } from "../compiler/core"; -import { getDeclarationEmitOutputFilePathWorker } from "../compiler/emitter/utilities"; +import { getDeclarationEmitOutputFilePathWorker } from "../compiler/emitterUtilities"; import { removeFileExtension } from "../compiler/extension"; -import { isDeclarationFileName } from "../compiler/parser/parser"; +import { isDeclarationFileName } from "../compiler/parser"; import { getDirectoryPath, getNormalizedAbsolutePath, @@ -13,7 +13,7 @@ import { import { computeLineAndCharacterOfPosition, getLineStarts, -} from "../compiler/scanner/scanner"; +} from "../compiler/scanner"; import { createDocumentPositionMapper, getLineInfo, @@ -22,7 +22,7 @@ import { tryGetSourceMappingURL, tryParseRawSourceMap, } from "../compiler/sourcemap"; -import { sys } from "../compiler/sys/sys"; +import { sys } from "../compiler/sys"; import { DocumentPosition, DocumentPositionMapper, diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 6b38adb9df8fd..ca8292934f3d1 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { readJson } from "../compiler/commandLineParser/utilities"; +import { readJson } from "../compiler/commandLineParserUtilities"; import { arrayFrom, compareStringsCaseSensitive, @@ -48,9 +48,9 @@ import { getPackageJsonTypesVersionsPaths, isApplicableVersionedTypesKey, unmangleScopedPackageName, -} from "../compiler/moduleNameResolver/moduleNameResolver"; -import { tryGetJSExtensionForFile, tryGetRealFileNameForNonJsDeclarationFileName } from "../compiler/moduleSpecifiers/moduleSpecifiers"; -import { getModuleSpecifierEndingPreference } from "../compiler/moduleSpecifiers/utilities"; +} from "../compiler/moduleNameResolver"; +import { tryGetJSExtensionForFile, tryGetRealFileNameForNonJsDeclarationFileName } from "../compiler/moduleSpecifiers"; +import { getModuleSpecifierEndingPreference } from "../compiler/moduleSpecifiersUtilities"; import { altDirectorySeparator, combinePaths, @@ -71,11 +71,11 @@ import { removeTrailingDirectorySeparator, resolvePath, } from "../compiler/path"; -import { getModeForUsageLocation } from "../compiler/program/program"; +import { getModeForUsageLocation } from "../compiler/program"; import { getLeadingCommentRanges, isIdentifierText, -} from "../compiler/scanner/scanner"; +} from "../compiler/scanner"; import { CallLikeExpression, CancellationToken, diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 77af348759ad8..5e57564732ee4 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -18,9 +18,9 @@ import { isVariableDeclaration, isVariableStatement, } from "../compiler/factory/nodeTests"; -import { forEachReturnStatement } from "../compiler/parser/utilities"; +import { forEachReturnStatement } from "../compiler/parserUtilities"; import { fileExtensionIsOneOf } from "../compiler/path"; -import { getModeForUsageLocation } from "../compiler/program/program"; +import { getModeForUsageLocation } from "../compiler/program"; import { AnyValidImportOrReExport, ArrowFunction, diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 42f73e130e311..e8f7cf8e30440 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -11,7 +11,7 @@ import { length, some, } from "../compiler/core"; -import { createPrinter } from "../compiler/emitter/emitter"; +import { createPrinter } from "../compiler/emitter"; import { isArrowFunction, isBindingElement, diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 11e9c07979d99..8a6c94a75202b 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1,5 +1,5 @@ import * as Debug from "../compiler/debug"; -import { getNodeId } from "../compiler/checker/utilities"; +import { getNodeId } from "../compiler/checkerUtilities"; import { concatenate, contains, @@ -26,7 +26,7 @@ import { singleOrUndefined, stableSort, } from "../compiler/core"; -import { createPrinter } from "../compiler/emitter/emitter"; +import { createPrinter } from "../compiler/emitter"; import { createNodeFactory, factory, @@ -51,7 +51,7 @@ import { isStringLiteral, isVariableDeclaration, } from "../compiler/factory/nodeTests"; -import { createSourceFile } from "../compiler/parser/parser"; +import { createSourceFile } from "../compiler/parser"; import { getLeadingCommentRanges, getLineAndCharacterOfPosition, @@ -59,7 +59,7 @@ import { getTrailingCommentRanges, skipTrivia, tokenToString, -} from "../compiler/scanner/scanner"; +} from "../compiler/scanner"; import { nullTransformationContext } from "../compiler/transformer"; import { ArrowFunction, diff --git a/src/services/transpile.ts b/src/services/transpile.ts index b2afb76aefdb6..2994731e7ff01 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -4,7 +4,7 @@ import { optionDeclarations, parseCustomTypeOption, transpileOptionValueCompilerOptions, -} from "../compiler/commandLineParser/commandLineParser"; +} from "../compiler/commandLineParser"; import { addRange, filter, @@ -12,7 +12,7 @@ import { isString, } from "../compiler/core"; import { MapLike } from "../compiler/corePublic"; -import { createSourceFile } from "../compiler/parser/parser"; +import { createSourceFile } from "../compiler/parser"; import { fileExtensionIs, normalizePath, @@ -22,7 +22,7 @@ import { createProgram, getImpliedNodeFormatForFile, getSetExternalModuleIndicator, -} from "../compiler/program/program"; +} from "../compiler/program"; import { CommandLineOptionOfCustomType, CompilerHost, diff --git a/src/services/types.ts b/src/services/types.ts index 1ba3333d0f575..bae0f07c22b76 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -1,5 +1,5 @@ import { EmitOutput } from "../compiler/builderStatePublic"; -import { ModuleResolutionCache } from "../compiler/moduleNameResolver/moduleNameResolver"; +import { ModuleResolutionCache } from "../compiler/moduleNameResolver"; import { SymlinkCache } from "../compiler/symlinkCache"; import { __String, diff --git a/src/services/utilities.ts b/src/services/utilities.ts index dcf66f062b5c3..bd7233f777551 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -6,8 +6,8 @@ import { import { getNodeId, getSymbolId, -} from "../compiler/checker/utilities"; -import { setConfigFileInOptions } from "../compiler/commandLineParser/commandLineParser"; +} from "../compiler/checkerUtilities"; +import { setConfigFileInOptions } from "../compiler/commandLineParser"; import { assertType, binarySearchKey, @@ -42,7 +42,7 @@ import { tryCast, } from "../compiler/core"; import { Comparison } from "../compiler/corePublic"; -import { createPrinter } from "../compiler/emitter/emitter"; +import { createPrinter } from "../compiler/emitter"; import { addEmitFlags, addSyntheticLeadingComment, @@ -132,10 +132,10 @@ import { import { getPackageNameFromTypesPackageName, getTypesPackageName, -} from "../compiler/moduleNameResolver/moduleNameResolver"; -import { getNodeModulesPackageName } from "../compiler/moduleSpecifiers/moduleSpecifiers"; -import { forEachChild } from "../compiler/parser/parser"; -import { getLastChild } from "../compiler/parser/utilities"; +} from "../compiler/moduleNameResolver"; +import { getNodeModulesPackageName } from "../compiler/moduleSpecifiers"; +import { forEachChild } from "../compiler/parser"; +import { getLastChild } from "../compiler/parserUtilities"; import { combinePaths, forEachAncestorDirectory, @@ -145,7 +145,7 @@ import { normalizePath, pathIsRelative, } from "../compiler/path"; -import { findConfigFile } from "../compiler/program/program"; +import { findConfigFile } from "../compiler/program"; import { createScanner, forEachLeadingCommentRange, @@ -156,7 +156,7 @@ import { Scanner, stringToToken, tokenToString, -} from "../compiler/scanner/scanner"; +} from "../compiler/scanner"; import { nullTransformationContext } from "../compiler/transformer"; import { __String, diff --git a/src/testRunner/unittests/parsePseudoBigInt.ts b/src/testRunner/unittests/parsePseudoBigInt.ts index d4625067862fe..cadf1f566f584 100644 --- a/src/testRunner/unittests/parsePseudoBigInt.ts +++ b/src/testRunner/unittests/parsePseudoBigInt.ts @@ -1,4 +1,4 @@ -import { parsePseudoBigInt } from "../../compiler/scanner/utilities"; +import { parsePseudoBigInt } from "../../compiler/scannerUtilities"; describe("unittests:: BigInt literal base conversions", () => { describe("parsePseudoBigInt", () => { diff --git a/src/testRunner/unittests/tsserver/exportMapCache.ts b/src/testRunner/unittests/tsserver/exportMapCache.ts index b8e41c64c8542..bdafc5fcc4774 100644 --- a/src/testRunner/unittests/tsserver/exportMapCache.ts +++ b/src/testRunner/unittests/tsserver/exportMapCache.ts @@ -1,5 +1,5 @@ import * as ts from "../../_namespaces/ts"; -import { getSymbolId } from "../../../compiler/checker/utilities"; +import { getSymbolId } from "../../../compiler/checkerUtilities"; import { createServerHost, File, diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index 0612e80b413ec..087f8eeb99f56 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -1,6 +1,6 @@ import * as Debug from "../compiler/debug"; import { noop } from "../compiler/core"; -import { sys } from "../compiler/sys/sys"; +import { sys } from "../compiler/sys"; import { executeCommandLine } from "../executeCommandLine/executeCommandLine"; // This file actually uses arguments passed on commandline and executes it diff --git a/src/tsserver/nodeServer.ts b/src/tsserver/nodeServer.ts index e338f16198a85..887f54f232d64 100644 --- a/src/tsserver/nodeServer.ts +++ b/src/tsserver/nodeServer.ts @@ -77,7 +77,7 @@ import { SortedReadonlyArray, versionMajorMinor, } from "../compiler/corePublic"; -import { resolveJSModule } from "../compiler/moduleNameResolver/moduleNameResolver"; +import { resolveJSModule } from "../compiler/moduleNameResolver"; import { combinePaths, directorySeparator, @@ -90,7 +90,7 @@ import { perfLogger } from "../compiler/perfLogger"; import { getNodeMajorVersion, sys as system, -} from "../compiler/sys/sys"; +} from "../compiler/sys"; import { CharacterCodes, DirectoryWatcherCallback, diff --git a/src/tsserver/server.ts b/src/tsserver/server.ts index 95f497ca089ef..2b2b2d43fa75a 100644 --- a/src/tsserver/server.ts +++ b/src/tsserver/server.ts @@ -4,7 +4,7 @@ import { getNodeMajorVersion, setStackTraceLimit, sys, -} from "../compiler/sys/sys"; +} from "../compiler/sys"; import { findArgument, hasArgument, diff --git a/src/typingsInstaller/nodeTypingsInstaller.ts b/src/typingsInstaller/nodeTypingsInstaller.ts index f45f4c4624288..1f3cf87696b7d 100644 --- a/src/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/typingsInstaller/nodeTypingsInstaller.ts @@ -17,7 +17,7 @@ import { normalizeSlashes, toPath, } from "../compiler/path"; -import { sys } from "../compiler/sys/sys"; +import { sys } from "../compiler/sys"; import { ActionPackageInstalled, Arguments, diff --git a/src/typingsInstallerCore/typingsInstaller.ts b/src/typingsInstallerCore/typingsInstaller.ts index dc931b688e1aa..a28463cfb6881 100644 --- a/src/typingsInstallerCore/typingsInstaller.ts +++ b/src/typingsInstallerCore/typingsInstaller.ts @@ -16,7 +16,7 @@ import { import { mangleScopedPackageName, resolveModuleName, -} from "../compiler/moduleNameResolver/moduleNameResolver"; +} from "../compiler/moduleNameResolver"; import { combinePaths, containsPath, @@ -26,7 +26,7 @@ import { getDirectoryPath, } from "../compiler/path"; import { Version } from "../compiler/semver"; -import { PollingInterval } from "../compiler/sys/sys"; +import { PollingInterval } from "../compiler/sys"; import { Extension, FileWatcher, From fa9b0480c1c19519e3c9ef735524fdc959164dc7 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 25 Jan 2023 23:02:16 +0200 Subject: [PATCH 22/24] fix tests --- src/testRunner/unittests/tsserver/versionCache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testRunner/unittests/tsserver/versionCache.ts b/src/testRunner/unittests/tsserver/versionCache.ts index aa7414d211fbf..37179f926172d 100644 --- a/src/testRunner/unittests/tsserver/versionCache.ts +++ b/src/testRunner/unittests/tsserver/versionCache.ts @@ -211,7 +211,7 @@ describe(`unittests:: tsserver:: VersionCache stress test`, () => { before(() => { // Use scanner.ts, decent size, does not change frequently - const testFileName = "src/compiler/scanner/scanner.ts"; + const testFileName = "src/compiler/scanner.ts"; testContent = Harness.IO.readFile(testFileName)!; const totalChars = testContent.length; assert.isTrue(totalChars > 0, "Failed to read test file."); From 9b52a6944b1994e735e80226412139a910ff00cf Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Mon, 13 Mar 2023 23:57:07 +0200 Subject: [PATCH 23/24] remove checkerUtilities --- src/compiler/_namespaces/ts.ts | 1 - src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 12 +- src/compiler/checkerUtilities.ts | 136 ------------------ src/compiler/debug.ts | 15 +- src/compiler/emitter.ts | 2 +- src/compiler/factory/nodeFactory.ts | 2 +- src/compiler/symbolWalker.ts | 2 +- src/compiler/transformers/es2017.ts | 2 +- src/compiler/transformers/es2018.ts | 2 +- src/compiler/transformers/module/module.ts | 2 +- src/compiler/transformers/module/system.ts | 2 +- src/compiler/transformers/utilities.ts | 2 +- src/compiler/types.ts | 111 ++++++++++++++ src/compiler/utilities.ts | 24 +++- src/services/callHierarchy.ts | 2 +- src/services/codefixes/addMissingAsync.ts | 3 +- src/services/codefixes/addMissingAwait.ts | 2 +- src/services/codefixes/convertConstToLet.ts | 3 +- .../codefixes/convertToAsyncFunction.ts | 6 +- .../codefixes/convertToTypeOnlyExport.ts | 3 +- .../codefixes/fixAddMissingConstraint.ts | 2 +- src/services/codefixes/fixAddMissingMember.ts | 2 +- .../codefixes/fixAwaitInSyncFunction.ts | 2 +- ...sDoesntImplementInheritedAbstractMember.ts | 2 +- .../fixClassIncorrectlyImplementsInterface.ts | 2 +- .../fixClassSuperMustPrecedeThisAccess.ts | 2 +- src/services/codefixes/importAdder.ts | 6 +- src/services/completions.ts | 2 +- src/services/exportInfoMap.ts | 2 +- src/services/findAllReferences.ts | 6 +- src/services/importTracker.ts | 2 +- src/services/refactors/extractSymbol.ts | 6 +- src/services/refactors/moveToNewFile.ts | 2 +- src/services/textChanges.ts | 2 +- src/services/utilities.ts | 6 +- .../unittests/tsserver/exportMapCache.ts | 2 +- 37 files changed, 181 insertions(+), 203 deletions(-) delete mode 100644 src/compiler/checkerUtilities.ts diff --git a/src/compiler/_namespaces/ts.ts b/src/compiler/_namespaces/ts.ts index ede685de6c449..63e4ae74e6cf4 100644 --- a/src/compiler/_namespaces/ts.ts +++ b/src/compiler/_namespaces/ts.ts @@ -36,7 +36,6 @@ export * from "../binder"; export * from "../symbolWalker"; export * from "../symlinkCache"; export * from "../checker"; -export * from "../checkerUtilities"; export * from "../visitorPublic"; export * from "../sourcemap"; export * from "../transformers/utilities"; diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b47133219545c..3b0fb87166c1a 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "./checkerUtilities"; import { append, appendIfUnique, @@ -222,6 +221,7 @@ import { getImmediatelyInvokedFunctionExpression, getLeftmostAccessExpression, getNameOrArgument, + getNodeId, getRightMostAssignedExpression, getSourceFileOfNode, getSourceTextOfNodeFromSourceFile, diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 539d4dbff9617..8210a9f480c4f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3,13 +3,6 @@ import { getModuleInstanceState, ModuleInstanceState, } from "./binder"; -import { - CheckMode, - getNodeId, - getSymbolId, - SignatureCheckMode, - TypeFacts, -} from "./checkerUtilities"; import { addRange, and, @@ -339,6 +332,7 @@ import { CaseOrDefaultClause, CharacterCodes, CheckFlags, + CheckMode, ClassDeclaration, ClassElement, ClassExpression, @@ -599,6 +593,7 @@ import { SetAccessorDeclaration, ShorthandPropertyAssignment, Signature, + SignatureCheckMode, SignatureDeclaration, SignatureFlags, SignatureKind, @@ -650,6 +645,7 @@ import { TypeCheckerHost, TypeComparer, TypeElement, + TypeFacts, TypeFlags, TypeFormatFlags, TypeId, @@ -801,6 +797,7 @@ import { getNameOfExpando, getNamespaceDeclarationNode, getNewTargetContainer, + getNodeId, getNonAugmentationDeclaration, getObjectFlags, getParameterSymbolFromJSDoc, @@ -820,6 +817,7 @@ import { getSpanOfTokenAtPosition, getStrictOptionValue, getSuperContainer, + getSymbolId, getSymbolNameForPrivateIdentifier, getTextOfIdentifierOrLiteral, getTextOfNode, diff --git a/src/compiler/checkerUtilities.ts b/src/compiler/checkerUtilities.ts deleted file mode 100644 index d5f4ff913350b..0000000000000 --- a/src/compiler/checkerUtilities.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { - Node, - Symbol, - SymbolId, -} from "./types"; - -let nextSymbolId = 1; -let nextNodeId = 1; - -/** @internal */ -export function getNodeId(node: Node): number { - if (!node.id) { - node.id = nextNodeId; - nextNodeId++; - } - return node.id; -} - -/** @internal */ -export function getSymbolId(symbol: Symbol): SymbolId { - if (!symbol.id) { - symbol.id = nextSymbolId; - nextSymbolId++; - } - - return symbol.id; -} - -/** @internal */ -export 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 -} - -/** @internal */ -export const enum SignatureCheckMode { - None = 0, - BivariantCallback = 1 << 0, - StrictCallback = 1 << 1, - IgnoreReturnTypes = 1 << 2, - StrictArity = 1 << 3, - StrictTopSignature = 1 << 4, - Callback = BivariantCallback | StrictCallback, -} - -/** @internal */ -export 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 - IsUndefined = 1 << 24, // Contains undefined or intersection with undefined - IsNull = 1 << 25, // Contains null or intersection with null - IsUndefinedOrNull = IsUndefined | IsNull, - All = (1 << 27) - 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 - // of that kind of type. - BaseStringStrictFacts = TypeofEQString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, - BaseStringFacts = BaseStringStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - StringStrictFacts = BaseStringStrictFacts | Truthy | Falsy, - StringFacts = BaseStringFacts | Truthy, - EmptyStringStrictFacts = BaseStringStrictFacts | Falsy, - EmptyStringFacts = BaseStringFacts, - NonEmptyStringStrictFacts = BaseStringStrictFacts | Truthy, - NonEmptyStringFacts = BaseStringFacts | Truthy, - BaseNumberStrictFacts = TypeofEQNumber | TypeofNEString | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, - BaseNumberFacts = BaseNumberStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - NumberStrictFacts = BaseNumberStrictFacts | Truthy | Falsy, - NumberFacts = BaseNumberFacts | Truthy, - ZeroNumberStrictFacts = BaseNumberStrictFacts | Falsy, - ZeroNumberFacts = BaseNumberFacts, - NonZeroNumberStrictFacts = BaseNumberStrictFacts | Truthy, - NonZeroNumberFacts = BaseNumberFacts | Truthy, - BaseBigIntStrictFacts = TypeofEQBigInt | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, - BaseBigIntFacts = BaseBigIntStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - BigIntStrictFacts = BaseBigIntStrictFacts | Truthy | Falsy, - BigIntFacts = BaseBigIntFacts | Truthy, - ZeroBigIntStrictFacts = BaseBigIntStrictFacts | Falsy, - ZeroBigIntFacts = BaseBigIntFacts, - NonZeroBigIntStrictFacts = BaseBigIntStrictFacts | Truthy, - NonZeroBigIntFacts = BaseBigIntFacts | Truthy, - BaseBooleanStrictFacts = TypeofEQBoolean | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, - BaseBooleanFacts = BaseBooleanStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - BooleanStrictFacts = BaseBooleanStrictFacts | Truthy | Falsy, - BooleanFacts = BaseBooleanFacts | Truthy, - FalseStrictFacts = BaseBooleanStrictFacts | Falsy, - FalseFacts = BaseBooleanFacts, - TrueStrictFacts = BaseBooleanStrictFacts | Truthy, - TrueFacts = BaseBooleanFacts | Truthy, - SymbolStrictFacts = TypeofEQSymbol | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy, - SymbolFacts = SymbolStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - ObjectStrictFacts = TypeofEQObject | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | NEUndefined | NENull | NEUndefinedOrNull | Truthy, - ObjectFacts = ObjectStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - FunctionStrictFacts = TypeofEQFunction | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy, - FunctionFacts = FunctionStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, - VoidFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy, - UndefinedFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy | IsUndefined, - NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy | IsNull, - EmptyObjectStrictFacts = All & ~(EQUndefined | EQNull | EQUndefinedOrNull | IsUndefinedOrNull), - EmptyObjectFacts = All & ~IsUndefinedOrNull, - UnknownFacts = All & ~IsUndefinedOrNull, - AllTypeofNE = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | NEUndefined, - // Masks - OrFactsMask = TypeofEQFunction | TypeofNEObject, - AndFactsMask = All & ~OrFactsMask, -} diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index db2e773189ecb..e942248316e23 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -1,13 +1,7 @@ /* eslint-disable */ import * as types from "./types"; -import * as checkerTypes from "./checkerUtilities"; /* eslint-enable */ -import { - CheckMode, - SignatureCheckMode, - TypeFacts, -} from "./checkerUtilities"; import { compareValues, every, @@ -88,6 +82,9 @@ import { TypeMapKind, TypeMapper, VarianceFlags, + CheckMode, + SignatureCheckMode, + TypeFacts, } from "./types"; import { getEffectiveModifierFlagsNoCache, @@ -586,17 +583,17 @@ export function formatRelationComparisonResult(result: RelationComparisonResult /** @internal */ export function formatCheckMode(mode: CheckMode | undefined): string { - return formatEnum(mode, (checkerTypes as any).CheckMode, /*isFlags*/ true); + return formatEnum(mode, (types as any).CheckMode, /*isFlags*/ true); } /** @internal */ export function formatSignatureCheckMode(mode: SignatureCheckMode | undefined): string { - return formatEnum(mode, (checkerTypes as any).SignatureCheckMode, /*isFlags*/ true); + return formatEnum(mode, (types as any).SignatureCheckMode, /*isFlags*/ true); } /** @internal */ export function formatTypeFacts(facts: TypeFacts | undefined): string { - return formatEnum(facts, (checkerTypes as any).TypeFacts, /*isFlags*/ true); + return formatEnum(facts, (types as any).TypeFacts, /*isFlags*/ true); } let isDebugInfoEnabled = false; diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 837bea51e5039..e9a62d1113390 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -10,7 +10,6 @@ import { ProgramBundleEmitBuildInfo, } from "./builder"; import { OutputFile } from "./builderStatePublic"; -import { getNodeId } from "./checkerUtilities"; import { arrayToMap, cast, @@ -426,6 +425,7 @@ import { getLiteralText, GetLiteralTextFlags, getNewLineCharacter, + getNodeId, getSourceFileOfNode, getSourceTextOfNodeFromSourceFile, getTrailingSemicolonDeferringWriter, diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 114bce32419b5..27d385cfdbb31 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../checkerUtilities"; import { addRange, append, @@ -371,6 +370,7 @@ import { import { findUseStrictPrologue, getEmitFlags, + getNodeId, getTextOfIdentifierOrLiteral, hasInvalidEscape, hasSyntacticModifier, diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts index ccc1ee056fc0b..234a4f951b192 100644 --- a/src/compiler/symbolWalker.ts +++ b/src/compiler/symbolWalker.ts @@ -1,4 +1,3 @@ -import { getSymbolId } from "./checkerUtilities"; import { clear, forEach, @@ -27,6 +26,7 @@ import { TypeReference, UnionOrIntersectionType, } from "./types"; +import { getSymbolId } from "./utilities"; /** @internal */ export function createGetSymbolWalker( diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index c5383a02c8b3f..9b5fa76048e78 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../checkerUtilities"; import { concatenate, forEach, @@ -86,6 +85,7 @@ import { getEntityNameFromTypeNode, getFunctionFlags, getInitializedVariables, + getNodeId, insertStatementsAfterStandardPrologue, isNodeWithPossibleHoistedDeclaration, isSuperProperty, diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index 81f88477b8643..725a729d85729 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../checkerUtilities"; import { addRange, append, @@ -94,6 +93,7 @@ import { FunctionFlags, getEmitScriptTarget, getFunctionFlags, + getNodeId, hasSyntacticModifier, insertStatementsAfterStandardPrologue, isDestructuringAssignment, diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index f2a00b1c1f477..497d5395c80a6 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../../checkerUtilities"; import { addRange, append, @@ -110,6 +109,7 @@ import { getESModuleInterop, getInternalEmitFlags, getNamespaceDeclarationNode, + getNodeId, getStrictOptionValue, getTextOfIdentifierOrLiteral, hasJsonModuleEmitEnabled, diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 75ae4bd3f1a13..d23e03b0a859f 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../../checkerUtilities"; import { addRange, append, @@ -103,6 +102,7 @@ import { } from "../../types"; import { getEmitFlags, + getNodeId, getStrictOptionValue, getTextOfIdentifierOrLiteral, hasSyntacticModifier, diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 2a00a100c23b6..7decf9f2d9521 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../checkerUtilities"; import { append, cast, @@ -77,6 +76,7 @@ import { getFirstConstructorWithBody, getIsolatedModules, getNamespaceDeclarationNode, + getNodeId, getStrictOptionValue, hasDecorators, hasStaticModifier, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 15cfe662e57a4..4da4a88559bce 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5686,6 +5686,117 @@ export interface EmitResolver { isImportRequiredByAugmentation(decl: ImportDeclaration): boolean; } + + +/** @internal */ +export 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 + IsUndefined = 1 << 24, // Contains undefined or intersection with undefined + IsNull = 1 << 25, // Contains null or intersection with null + IsUndefinedOrNull = IsUndefined | IsNull, + All = (1 << 27) - 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 + // of that kind of type. + BaseStringStrictFacts = TypeofEQString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, + BaseStringFacts = BaseStringStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + StringStrictFacts = BaseStringStrictFacts | Truthy | Falsy, + StringFacts = BaseStringFacts | Truthy, + EmptyStringStrictFacts = BaseStringStrictFacts | Falsy, + EmptyStringFacts = BaseStringFacts, + NonEmptyStringStrictFacts = BaseStringStrictFacts | Truthy, + NonEmptyStringFacts = BaseStringFacts | Truthy, + BaseNumberStrictFacts = TypeofEQNumber | TypeofNEString | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, + BaseNumberFacts = BaseNumberStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + NumberStrictFacts = BaseNumberStrictFacts | Truthy | Falsy, + NumberFacts = BaseNumberFacts | Truthy, + ZeroNumberStrictFacts = BaseNumberStrictFacts | Falsy, + ZeroNumberFacts = BaseNumberFacts, + NonZeroNumberStrictFacts = BaseNumberStrictFacts | Truthy, + NonZeroNumberFacts = BaseNumberFacts | Truthy, + BaseBigIntStrictFacts = TypeofEQBigInt | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, + BaseBigIntFacts = BaseBigIntStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + BigIntStrictFacts = BaseBigIntStrictFacts | Truthy | Falsy, + BigIntFacts = BaseBigIntFacts | Truthy, + ZeroBigIntStrictFacts = BaseBigIntStrictFacts | Falsy, + ZeroBigIntFacts = BaseBigIntFacts, + NonZeroBigIntStrictFacts = BaseBigIntStrictFacts | Truthy, + NonZeroBigIntFacts = BaseBigIntFacts | Truthy, + BaseBooleanStrictFacts = TypeofEQBoolean | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, + BaseBooleanFacts = BaseBooleanStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + BooleanStrictFacts = BaseBooleanStrictFacts | Truthy | Falsy, + BooleanFacts = BaseBooleanFacts | Truthy, + FalseStrictFacts = BaseBooleanStrictFacts | Falsy, + FalseFacts = BaseBooleanFacts, + TrueStrictFacts = BaseBooleanStrictFacts | Truthy, + TrueFacts = BaseBooleanFacts | Truthy, + SymbolStrictFacts = TypeofEQSymbol | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy, + SymbolFacts = SymbolStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + ObjectStrictFacts = TypeofEQObject | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | NEUndefined | NENull | NEUndefinedOrNull | Truthy, + ObjectFacts = ObjectStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + FunctionStrictFacts = TypeofEQFunction | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy, + FunctionFacts = FunctionStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + VoidFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy, + UndefinedFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy | IsUndefined, + NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy | IsNull, + EmptyObjectStrictFacts = All & ~(EQUndefined | EQNull | EQUndefinedOrNull | IsUndefinedOrNull), + EmptyObjectFacts = All & ~IsUndefinedOrNull, + UnknownFacts = All & ~IsUndefinedOrNull, + AllTypeofNE = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | NEUndefined, + // Masks + OrFactsMask = TypeofEQFunction | TypeofNEObject, + AndFactsMask = All & ~OrFactsMask, +} + +/** @internal */ +export 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 +} + +/** @internal */ +export const enum SignatureCheckMode { + None = 0, + BivariantCallback = 1 << 0, + StrictCallback = 1 << 1, + IgnoreReturnTypes = 1 << 2, + StrictArity = 1 << 3, + StrictTopSignature = 1 << 4, + Callback = BivariantCallback | StrictCallback, +} + export const enum SymbolFlags { None = 0, FunctionScopedVariable = 1 << 0, // Variable (var) or parameter diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 48c09be7e9fbc..4bc9b390ab659 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1,4 +1,3 @@ -import { getSymbolId } from "./checkerUtilities"; import { addRange, arrayFrom, @@ -406,6 +405,7 @@ import { SwitchStatement, Symbol, SymbolFlags, + SymbolId, SymbolTable, SyntaxKind, SyntaxList, @@ -513,6 +513,28 @@ function isCommonJSContainingModuleKind(kind: ModuleKind) { return kind === ModuleKind.CommonJS || kind === ModuleKind.Node16 || kind === ModuleKind.NodeNext; } +let nextSymbolId = 1; +let nextNodeId = 1; + +/** @internal */ +export function getNodeId(node: Node): number { + if (!node.id) { + node.id = nextNodeId; + nextNodeId++; + } + return node.id; +} + +/** @internal */ +export function getSymbolId(symbol: Symbol): SymbolId { + if (!symbol.id) { + symbol.id = nextSymbolId; + nextSymbolId++; + } + + return symbol.id; +} + /** @internal */ export const resolvingEmptyArray: never[] = []; diff --git a/src/services/callHierarchy.ts b/src/services/callHierarchy.ts index 1c1d562beec25..677dd918a27a0 100644 --- a/src/services/callHierarchy.ts +++ b/src/services/callHierarchy.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../compiler/checkerUtilities"; import { append, compareStringsCaseSensitive, @@ -79,6 +78,7 @@ import { import { getClassExtendsHeritageElement, getFirstConstructorWithBody, + getNodeId, hasSyntacticModifier, isAccessExpression, isDeclarationName, diff --git a/src/services/codefixes/addMissingAsync.ts b/src/services/codefixes/addMissingAsync.ts index a02c001a25264..c87717202ce37 100644 --- a/src/services/codefixes/addMissingAsync.ts +++ b/src/services/codefixes/addMissingAsync.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; import { find, isNumber, @@ -22,7 +21,7 @@ import { SourceFile, TextSpan, } from "../../compiler/types"; -import { getSyntacticModifierFlags } from "../../compiler/utilities"; +import { getNodeId, getSyntacticModifierFlags } from "../../compiler/utilities"; import { findAncestor, textSpanEnd, diff --git a/src/services/codefixes/addMissingAwait.ts b/src/services/codefixes/addMissingAwait.ts index 63f6c4c26c995..73f3f49c0ec0c 100644 --- a/src/services/codefixes/addMissingAwait.ts +++ b/src/services/codefixes/addMissingAwait.ts @@ -1,4 +1,3 @@ -import { getSymbolId } from "../../compiler/checkerUtilities"; import { compact, contains, @@ -38,6 +37,7 @@ import { } from "../../compiler/types"; import { getAncestor, + getSymbolId, hasSyntacticModifier, } from "../../compiler/utilities"; import { diff --git a/src/services/codefixes/convertConstToLet.ts b/src/services/codefixes/convertConstToLet.ts index 88c855a96529a..2ef8f78507715 100644 --- a/src/services/codefixes/convertConstToLet.ts +++ b/src/services/codefixes/convertConstToLet.ts @@ -1,4 +1,3 @@ -import { getSymbolId } from "../../compiler/checkerUtilities"; import { tryCast } from "../../compiler/core"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; @@ -10,7 +9,7 @@ import { SyntaxKind, Token, } from "../../compiler/types"; -import { addToSeen } from "../../compiler/utilities"; +import { addToSeen, getSymbolId } from "../../compiler/utilities"; import { createCodeFixActionMaybeFixAll, createCombinedCodeActions, diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index d63b65115809e..ab1f4b0bf49b1 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -1,7 +1,3 @@ -import { - getNodeId, - getSymbolId, -} from "../../compiler/checkerUtilities"; import { concatenate, createMultiMap, @@ -65,7 +61,9 @@ import { } from "../../compiler/types"; import { getContainingFunction, + getNodeId, getObjectFlags, + getSymbolId, isInJSFile, moveRangePastModifiers, } from "../../compiler/utilities"; diff --git a/src/services/codefixes/convertToTypeOnlyExport.ts b/src/services/codefixes/convertToTypeOnlyExport.ts index 3b5923d07f808..018a8961afa24 100644 --- a/src/services/codefixes/convertToTypeOnlyExport.ts +++ b/src/services/codefixes/convertToTypeOnlyExport.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; import { contains, filter, @@ -13,7 +12,7 @@ import { SyntaxKind, TextSpan, } from "../../compiler/types"; -import { addToSeen } from "../../compiler/utilities"; +import { addToSeen, getNodeId } from "../../compiler/utilities"; import { codeFixAll, createCodeFixAction, diff --git a/src/services/codefixes/fixAddMissingConstraint.ts b/src/services/codefixes/fixAddMissingConstraint.ts index 64f75f6eb9d4e..05947b9aeaaa4 100644 --- a/src/services/codefixes/fixAddMissingConstraint.ts +++ b/src/services/codefixes/fixAddMissingConstraint.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; import { find, isString, @@ -25,6 +24,7 @@ import { import { addToSeen, getEmitScriptTarget, + getNodeId, } from "../../compiler/utilities"; import { createTextSpan, diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 8c54734d1fe8b..b90cfde955597 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; import { arrayFrom, concatenate, @@ -95,6 +94,7 @@ import { getClassLikeDeclarationOfSymbol, getEmitScriptTarget, getFirstConstructorWithBody, + getNodeId, getObjectFlags, getSourceFileOfNode, hasAbstractModifier, diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts index 1176287bd550e..9e7ca896d0d2a 100644 --- a/src/services/codefixes/fixAwaitInSyncFunction.ts +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; import { first } from "../../compiler/core"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { factory } from "../../compiler/factory/nodeFactory"; @@ -20,6 +19,7 @@ import { addToSeen, getContainingFunction, getEntityNameFromTypeNode, + getNodeId, } from "../../compiler/utilities"; import { codeFixAll, diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index 8d51f696d812a..161c321799d16 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; import { cast, first, @@ -15,6 +14,7 @@ import { import { addToSeen, getEffectiveBaseTypeNode, + getNodeId, getSyntacticModifierFlags, } from "../../compiler/utilities"; import { isClassLike } from "../../compiler/utilitiesPublic"; diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 8a3e619e731c5..81b1a9ed6ad8e 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; import { and, find, @@ -28,6 +27,7 @@ import { getEffectiveBaseTypeNode, getEffectiveImplementsTypeNodes, getEffectiveModifierFlags, + getNodeId, } from "../../compiler/utilities"; import { codeFixAll, diff --git a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts index 0f68e5064e616..c17e1f3a7b9f2 100644 --- a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts +++ b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../../compiler/checkerUtilities"; import { Diagnostics } from "../../compiler/diagnosticInformationMap.generated"; import { isExpressionStatement, @@ -16,6 +15,7 @@ import { import { addToSeen, getContainingFunction, + getNodeId, isSuperCall, } from "../../compiler/utilities"; import { isFunctionLike } from "../../compiler/utilitiesPublic"; diff --git a/src/services/codefixes/importAdder.ts b/src/services/codefixes/importAdder.ts index 35450c2268f36..9e21e683780e0 100644 --- a/src/services/codefixes/importAdder.ts +++ b/src/services/codefixes/importAdder.ts @@ -1,7 +1,3 @@ -import { - getNodeId, - getSymbolId, -} from "../../compiler/checkerUtilities"; import { arrayFrom, cast, @@ -97,7 +93,9 @@ import { getEmitModuleKind, getEmitModuleResolutionKind, getEmitScriptTarget, + getNodeId, getSourceFileOfNode, + getSymbolId, hostGetCanonicalFileName, importFromModuleSpecifier, importNameElisionDisabled, diff --git a/src/services/completions.ts b/src/services/completions.ts index 6deee715d108e..aedddd4b4507a 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1,4 +1,3 @@ -import { getSymbolId } from "../compiler/checkerUtilities"; import { append, cast, @@ -224,6 +223,7 @@ import { getPropertyNameForPropertyNameNode, getRootDeclaration, getSourceFileOfModule, + getSymbolId, hasEffectiveModifier, isAbstractConstructorSymbol, isCheckJsEnabledForFile, diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index a12cb1dfec02e..5b1087c39dcb2 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -1,4 +1,3 @@ -import { getSymbolId } from "../compiler/checkerUtilities"; import { arrayIsEqualTo, createMultiMap, @@ -54,6 +53,7 @@ import { addToSeen, forEachEntry, getLocalSymbolForExportDefault, + getSymbolId, hostGetCanonicalFileName, hostUsesCaseSensitiveFileNames, isExternalOrCommonJsModule, diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 4f3343c6c9f7b..7ee2aec3fa1cd 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1,7 +1,3 @@ -import { - getNodeId, - getSymbolId, -} from "../compiler/checkerUtilities"; import { append, cast, @@ -140,7 +136,9 @@ import { getEffectiveModifierFlags, getLocalSymbolForExportDefault, getNextJSDocCommentLocation, + getNodeId, getSuperContainer, + getSymbolId, getSyntacticModifierFlags, getTextOfNode, getThisContainer, diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 23cf22f18456f..aa9c768450b5a 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -1,4 +1,3 @@ -import { getSymbolId } from "../compiler/checkerUtilities"; import { cast, forEach, @@ -70,6 +69,7 @@ import { getFirstIdentifier, getNameOfAccessExpression, getSourceFileOfNode, + getSymbolId, hasSyntacticModifier, importFromModuleSpecifier, isAccessExpression, diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index a560c5381a296..d144f208edff8 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1,7 +1,3 @@ -import { - getNodeId, - getSymbolId, -} from "../../compiler/checkerUtilities"; import { arrayFrom, assertType, @@ -121,6 +117,8 @@ import { getEmitScriptTarget, getEnclosingBlockScopeContainer, getLocaleSpecificMessage, + getNodeId, + getSymbolId, getThisContainer, hasEffectiveModifier, hasSyntacticModifier, diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index bcd4945027489..300d31df1da57 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -1,4 +1,3 @@ -import { getSymbolId } from "../../compiler/checkerUtilities"; import { append, cast, @@ -106,6 +105,7 @@ import { forEachEntry, getAssignmentDeclarationKind, getLocaleSpecificMessage, + getSymbolId, hasSyntacticModifier, hostGetCanonicalFileName, isDeclarationName, diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index a5103eb136a05..993a84c3438e6 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1,4 +1,3 @@ -import { getNodeId } from "../compiler/checkerUtilities"; import { concatenate, contains, @@ -126,6 +125,7 @@ import { getAncestor, getJSDocCommentRanges, getLineOfLocalPosition, + getNodeId, getScriptKindFromFileName, getStartPositionOfLine, indexOfNode, diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 961edf16e3c0c..9fdc3c945b716 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2,10 +2,6 @@ import { getModuleInstanceState, ModuleInstanceState, } from "../compiler/binder"; -import { - getNodeId, - getSymbolId, -} from "../compiler/checkerUtilities"; import { setConfigFileInOptions } from "../compiler/commandLineParser"; import { assertType, @@ -295,9 +291,11 @@ import { getIndentString, getLeadingCommentRangesOfNode, getLocaleSpecificMessage, + getNodeId, getRootDeclaration, getSourceFileOfNode, getSpanOfTokenAtPosition, + getSymbolId, getTextOfIdentifierOrLiteral, getTextOfNode, hasSyntacticModifier, diff --git a/src/testRunner/unittests/tsserver/exportMapCache.ts b/src/testRunner/unittests/tsserver/exportMapCache.ts index 26f14d6904aaa..30959369f5df9 100644 --- a/src/testRunner/unittests/tsserver/exportMapCache.ts +++ b/src/testRunner/unittests/tsserver/exportMapCache.ts @@ -1,4 +1,4 @@ -import { getSymbolId } from "../../../compiler/checkerUtilities"; +import { getSymbolId } from "../../../compiler/utilities"; import * as ts from "../../_namespaces/ts"; import { createServerHost, From 275f219df0c87cfcffed32131b75a6fbf36ff4af Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 27 Apr 2023 00:32:31 +0300 Subject: [PATCH 24/24] fix imports --- src/tsserver/nodeServer.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tsserver/nodeServer.ts b/src/tsserver/nodeServer.ts index 4aa5ee647051a..a23fa349c4b64 100644 --- a/src/tsserver/nodeServer.ts +++ b/src/tsserver/nodeServer.ts @@ -62,6 +62,7 @@ import { SetTypings, TypesRegistryResponse, TypingInstallerRequestUnion, + WatchTypingLocations, } from "../jsTyping/types"; import { ProjectService } from "../server/editorServices"; import { Project } from "../server/project"; @@ -696,7 +697,7 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella } } - private handleMessage(response: TypesRegistryResponse | PackageInstalledResponse | SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes | InitializationFailedResponse | server.WatchTypingLocations) { + private handleMessage(response: TypesRegistryResponse | PackageInstalledResponse | SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes | InitializationFailedResponse | WatchTypingLocations) { if (this.logger.hasLevel(LogLevel.verbose)) { this.logger.info(`Received response:${stringifyIndented(response)}`); }