Move services to use 'factory' object

This commit is contained in:
Ron Buckton
2019-09-10 13:45:03 -07:00
parent ad5ab7cd55
commit 594a729540
80 changed files with 2810 additions and 1911 deletions
+1 -1
View File
@@ -124,7 +124,7 @@ const buildApi = (() => {
.pipe(newer("built/local/api.d.ts"))
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(transform(content => content.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, "$1$2enum $3 {$4")))
.pipe(transform(content => `${content}\nexport = typeof ts;\n`))
.pipe(transform(content => `${content}\nexport = ts;\n`))
.pipe(prependFile(copyright))
.pipe(rename("api.d.ts"))
.pipe(dest("built/local"));
@@ -1,19 +1,15 @@
namespace ts {
// NOTE: These exports are deprecated in favor of using a `NodeFactory` instance, and have been moved to services for backwards compatibility reasons.
// NOTE: These exports are deprecated in favor of using a `NodeFactory` instance and exist here purely for backwards compatibility reasons.
export const {
createNumericLiteral,
createBigIntLiteral,
createStringLiteral,
createStringLiteralFromNode,
createRegularExpressionLiteral,
createIdentifier,
/** @internal */ updateIdentifier,
createTempVariable,
createLoopVariable,
createUniqueName,
createOptimisticUniqueName,
createFileLevelUniqueName,
getGeneratedNameForNode,
createToken,
createSuper,
createThis,
@@ -46,9 +42,7 @@ namespace ts {
updateCallSignature,
createConstructSignature,
updateConstructSignature,
createIndexSignature,
updateIndexSignature,
/*@internal*/ createSignatureDeclaration,
createKeywordTypeNode,
createTypePredicateNode,
updateTypePredicateNode,
@@ -74,7 +68,6 @@ namespace ts {
updateUnionTypeNode,
createIntersectionTypeNode,
updateIntersectionTypeNode,
createUnionOrIntersectionTypeNode,
createConditionalTypeNode,
updateConditionalTypeNode,
createInferTypeNode,
@@ -303,17 +296,31 @@ namespace ts {
createLogicalNot,
createVoidZero,
createExportDefault,
createExternalModuleExport,
/*@internal*/ recreateOuterExpressions
} = syntheticNodeFactory;
createExternalModuleExport
} = factory;
export function createIdentifier(text: string) {
return factory.createIdentifier(text, /*typeArguments*/ undefined, /*originalKeywordKind*/ undefined);
}
export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier {
return factory.createTempVariable(recordTempVariable, /*reserveInNestedScopes*/ undefined);
}
export function getGeneratedNameForNode(node: Node | undefined): Identifier {
return factory.getGeneratedNameForNode(node, /*flags*/ undefined);
}
export function createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration {
return factory.createIndexSignature(decorators, modifiers, parameters, type);
}
/* @internal */ export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote: boolean): StringLiteral; // tslint:disable-line unified-signatures
/** If a node is passed, creates a string literal whose source text is read from a source node during emit. */
export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral;
export function createLiteral(value: number | PseudoBigInt): NumericLiteral;
export function createLiteral(value: boolean): BooleanLiteral;
export function createLiteral(value: string | number | PseudoBigInt | boolean): PrimaryExpression;
export function createLiteral(value: string | number | PseudoBigInt | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote?: boolean): PrimaryExpression {
export function createLiteral(value: string | number | PseudoBigInt | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): PrimaryExpression {
if (typeof value === "number") {
return createNumericLiteral(value + "");
}
@@ -324,9 +331,7 @@ namespace ts {
return value ? createTrue() : createFalse();
}
if (isString(value)) {
const res = createStringLiteral(value);
if (isSingleQuote) res.singleQuote = true;
return res;
return createStringLiteral(value, /*isSingleQuote*/ undefined);
}
return createStringLiteralFromNode(value);
}
@@ -338,7 +343,7 @@ namespace ts {
name: string | PropertyName,
questionToken: QuestionToken | undefined
) {
return syntheticNodeFactory.createMethodSignature(/*modifiers*/ undefined, name, questionToken, typeParameters, parameters, type);
return factory.createMethodSignature(/*modifiers*/ undefined, name, questionToken, typeParameters, parameters, type);
}
export function updateMethodSignature(
@@ -349,7 +354,7 @@ namespace ts {
name: PropertyName,
questionToken: QuestionToken | undefined
) {
return syntheticNodeFactory.updateMethodSignature(node, node.modifiers, name, questionToken, typeParameters, parameters, type);
return factory.updateMethodSignature(node, node.modifiers, name, questionToken, typeParameters, parameters, type);
}
export function createTypeOperatorNode(type: TypeNode): TypeOperatorNode;
@@ -363,14 +368,12 @@ namespace ts {
type = operatorOrType as TypeNode;
operator = SyntaxKind.KeyOfKeyword;
}
return syntheticNodeFactory.createTypeOperatorNode(operator, type);
return factory.createTypeOperatorNode(operator, type);
}
/** @deprecated */
export function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
export function createTaggedTemplate(tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression;
/** @internal */
export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: readonly TypeNode[] | TemplateLiteral | undefined, template?: TemplateLiteral): TaggedTemplateExpression;
export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: readonly TypeNode[] | TemplateLiteral | undefined, template?: TemplateLiteral) {
let typeArguments: readonly TypeNode[] | undefined;
if (template) {
@@ -379,7 +382,7 @@ namespace ts {
else {
template = typeArgumentsOrTemplate as TemplateLiteral;
}
return syntheticNodeFactory.createTaggedTemplate(tag, typeArguments, template);
return factory.createTaggedTemplate(tag, typeArguments, template);
}
/** @deprecated */
@@ -393,7 +396,7 @@ namespace ts {
else {
template = typeArgumentsOrTemplate as TemplateLiteral;
}
return syntheticNodeFactory.updateTaggedTemplate(node, tag, typeArguments, template);
return factory.updateTaggedTemplate(node, tag, typeArguments, template);
}
export function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression;
@@ -411,7 +414,7 @@ namespace ts {
questionToken = questionTokenOrWhenTrue as QuestionToken;
whenTrue = whenTrueOrWhenFalse;
}
return syntheticNodeFactory.createConditional(condition, questionToken, whenTrue, colonToken!, whenFalse);
return factory.createConditional(condition, questionToken, whenTrue, colonToken!, whenFalse);
}
export function createYield(expression?: Expression): YieldExpression;
@@ -424,7 +427,7 @@ namespace ts {
else {
expression = asteriskTokenOrExpression as Expression;
}
return syntheticNodeFactory.createYield(asteriskToken, expression);
return factory.createYield(asteriskToken, expression);
}
export function createClassExpression(
@@ -434,7 +437,7 @@ namespace ts {
heritageClauses: readonly HeritageClause[] | undefined,
members: readonly ClassElement[]
) {
return syntheticNodeFactory.createClassExpression(/*decorators*/ undefined, modifiers, name, typeParameters, heritageClauses, members);
return factory.createClassExpression(/*decorators*/ undefined, modifiers, name, typeParameters, heritageClauses, members);
}
export function updateClassExpression(
@@ -445,7 +448,7 @@ namespace ts {
heritageClauses: readonly HeritageClause[] | undefined,
members: readonly ClassElement[]
) {
return syntheticNodeFactory.updateClassExpression(node, /*decorators*/ undefined, modifiers, name, typeParameters, heritageClauses, members);
return factory.updateClassExpression(node, /*decorators*/ undefined, modifiers, name, typeParameters, heritageClauses, members);
}
export function createPropertySignature(
@@ -455,7 +458,7 @@ namespace ts {
type: TypeNode | undefined,
initializer?: Expression
): PropertySignature {
const node = syntheticNodeFactory.createPropertySignature(modifiers, name, questionToken, type);
const node = factory.createPropertySignature(modifiers, name, questionToken, type);
node.initializer = initializer;
return node;
}
@@ -478,48 +481,10 @@ namespace ts {
}
export function createExpressionWithTypeArguments(typeArguments: readonly TypeNode[] | undefined, expression: Expression) {
return syntheticNodeFactory.createExpressionWithTypeArguments(expression, typeArguments);
return factory.createExpressionWithTypeArguments(expression, typeArguments);
}
export function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: readonly TypeNode[] | undefined, expression: Expression) {
return syntheticNodeFactory.updateExpressionWithTypeArguments(node, expression, typeArguments);
}
}
/* @internal */
namespace ts {
const syntheticParenthesizerRules = syntheticNodeFactory.getParenthesizerRules();
export const {
parenthesizeConditionOfConditionalExpression: parenthesizeForConditionalHead,
parenthesizeBranchOfConditionalExpression: parenthesizeSubexpressionOfConditionalExpression,
parenthesizeExpressionOfExportDefault: parenthesizeDefaultExpression,
parenthesizeExpressionOfNew: parenthesizeForNew,
parenthesizeLeftSideOfAccess: parenthesizeForAccess,
parenthesizeOperandOfPrefixUnary: parenthesizePrefixOperand,
parenthesizeOperandOfPostfixUnary: parenthesizePostfixOperand,
parenthesizeExpressionsOfCommaDelimitedList: parenthesizeListElements,
parenthesizeExpressionForDisallowedComma: parenthesizeExpressionForList,
parenthesizeExpressionOfExpressionStatement: parenthesizeExpressionForExpressionStatement,
parenthesizeConciseBodyOfArrowFunction: parenthesizeConciseBody,
parenthesizeMemberOfConditionalType: parenthesizeConditionalTypeMember,
parenthesizeMemberOfElementType: parenthesizeElementTypeMember,
parenthesizeElementTypeOfArrayType: parenthesizeArrayTypeMember,
parenthesizeConstituentTypesOfUnionOrIntersectionType: parenthesizeElementTypeMembers,
parenthesizeTypeArguments: parenthesizeTypeParameters,
} = syntheticParenthesizerRules;
/**
* Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended
* order of operations.
*
* @param binaryOperator The operator for the BinaryExpression.
* @param operand The operand for the BinaryExpression.
* @param isLeftSideOfBinary A value indicating whether the operand is the left side of the
* BinaryExpression.
*/
export function parenthesizeBinaryOperand(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand?: Expression) {
return isLeftSideOfBinary ? syntheticParenthesizerRules.parenthesizeLeftSideOfBinary(binaryOperator, operand) :
syntheticParenthesizerRules.parenthesizeRightSideOfBinary(binaryOperator, leftOperand, operand);
return factory.updateExpressionWithTypeArguments(node, expression, typeArguments);
}
}
+12
View File
@@ -0,0 +1,12 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"outFile": "../../built/local/compat.js"
},
"references": [
{ "path": "../compiler" }
],
"files": [
"factory.ts"
]
}
+30 -26
View File
@@ -293,7 +293,6 @@ namespace ts {
const Signature = objectAllocator.getSignatureConstructor();
// tslint:enable variable-name
const factory = syntheticNodeFactory;
let typeCount = 0;
let symbolCount = 0;
let enumCount = 0;
@@ -356,8 +355,8 @@ namespace ts {
getMergedSymbol,
getDiagnostics,
getGlobalDiagnostics,
getTypeOfSymbolAtLocation: (symbol, location) => {
location = getParseTreeNode(location);
getTypeOfSymbolAtLocation: (symbol, locationIn) => {
const location = getParseTreeNode(locationIn);
return location ? getTypeOfSymbolAtLocation(symbol, location) : errorType;
},
getSymbolsOfParameterPropertyDeclaration: (parameterIn, parameterName) => {
@@ -392,16 +391,16 @@ namespace ts {
symbolToTypeParameterDeclarations: nodeBuilder.symbolToTypeParameterDeclarations,
symbolToParameterDeclaration: nodeBuilder.symbolToParameterDeclaration as (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => ParameterDeclaration, // TODO: GH#18217
typeParameterToDeclaration: nodeBuilder.typeParameterToDeclaration as (parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => TypeParameterDeclaration, // TODO: GH#18217
getSymbolsInScope: (location, meaning) => {
location = getParseTreeNode(location);
getSymbolsInScope: (locationIn, meaning) => {
const location = getParseTreeNode(locationIn);
return location ? getSymbolsInScope(location, meaning) : [];
},
getSymbolAtLocation: node => {
node = getParseTreeNode(node);
getSymbolAtLocation: nodeIn => {
const node = getParseTreeNode(nodeIn);
return node ? getSymbolAtLocation(node) : undefined;
},
getShorthandAssignmentValueSymbol: node => {
node = getParseTreeNode(node);
getShorthandAssignmentValueSymbol: nodeIn => {
const node = getParseTreeNode(nodeIn);
return node ? getShorthandAssignmentValueSymbol(node) : undefined;
},
getExportSpecifierLocalTargetSymbol: nodeIn => {
@@ -411,8 +410,8 @@ namespace ts {
getExportSymbolOfSymbol(symbol) {
return getMergedSymbol(symbol.exportSymbol || symbol);
},
getTypeAtLocation: node => {
node = getParseTreeNode(node);
getTypeAtLocation: nodeIn => {
const node = getParseTreeNode(nodeIn);
return node ? getTypeOfNode(node) : errorType;
},
getTypeOfAssignmentPattern: nodeIn => {
@@ -489,9 +488,9 @@ namespace ts {
const declaration = getParseTreeNode(declarationIn, isFunctionLike);
return declaration ? getSignatureFromDeclaration(declaration) : undefined;
},
isImplementationOfOverload: node => {
const parsed = getParseTreeNode(node, isFunctionLike);
return parsed ? isImplementationOfOverload(parsed) : undefined;
isImplementationOfOverload: nodeIn => {
const node = getParseTreeNode(nodeIn, isFunctionLike);
return node ? isImplementationOfOverload(node) : undefined;
},
getImmediateAliasedSymbol,
getAliasedSymbol: resolveAlias,
@@ -562,15 +561,16 @@ namespace ts {
getAccessibleSymbolChain,
getTypePredicateOfSignature: getTypePredicateOfSignature as (signature: Signature) => TypePredicate, // TODO: GH#18217
resolveExternalModuleSymbol,
tryGetThisTypeAt: (node, includeGlobalThis) => {
node = getParseTreeNode(node);
tryGetThisTypeAt: (nodeIn, includeGlobalThis) => {
const node = getParseTreeNode(nodeIn);
return node && tryGetThisTypeAt(node, includeGlobalThis);
},
getTypeArgumentConstraint: nodeIn => {
const node = getParseTreeNode(nodeIn, isTypeNode);
return node && getTypeArgumentConstraint(node);
},
getSuggestionDiagnostics: (file, ct) => {
getSuggestionDiagnostics: (fileIn, ct) => {
const file = getParseTreeNode(fileIn, isSourceFile) || Debug.fail("Could not determine parsed source file.");
if (skipTypeChecking(file, compilerOptions)) {
return emptyArray;
}
@@ -3739,7 +3739,7 @@ namespace ts {
}
const typeNodes = mapToTypeNodes(types, context, /*isBareList*/ true);
if (typeNodes && typeNodes.length > 0) {
const unionOrIntersectionTypeNode = factory.createUnionOrIntersectionTypeNode(type.flags & TypeFlags.Union ? SyntaxKind.UnionType : SyntaxKind.IntersectionType, typeNodes);
const unionOrIntersectionTypeNode = type.flags & TypeFlags.Union ? factory.createUnionTypeNode(typeNodes) : factory.createIntersectionTypeNode(typeNodes);
return unionOrIntersectionTypeNode;
}
else {
@@ -4247,7 +4247,11 @@ namespace ts {
returnTypeNode = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
}
context.approximateLength += 3; // Usually a signature contributes a few more characters than this, but 3 is the minimum
return factory.createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode, typeArguments);
const node = factory.createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode);
if (typeArguments) {
node.typeArguments = createNodeArray(typeArguments);
}
return node;
}
function typeParameterToDeclarationWithConstraint(type: TypeParameter, context: NodeBuilderContext, constraintNode: TypeNode | undefined): TypeParameterDeclaration {
@@ -4473,7 +4477,7 @@ namespace ts {
}
return getSourceFileOfNode(getNonAugmentationDeclaration(symbol)!).fileName; // A resolver may not be provided for baselines and errors - in those cases we use the fileName in full
}
const contextFile = getSourceFileOfNode(getOriginalNode(context.enclosingDeclaration));
const contextFile = getSourceFileOfNode(getParseTreeNode(context.enclosingDeclaration)) || Debug.fail("Could not determine parsed source file.");
const links = getSymbolLinks(symbol);
let specifier = links.specifierCache && links.specifierCache.get(contextFile.path);
if (!specifier) {
@@ -31920,19 +31924,19 @@ namespace ts {
getReferencedImportDeclaration,
getReferencedDeclarationWithCollidingName,
isDeclarationWithCollidingName,
isValueAliasDeclaration: node => {
node = getParseTreeNode(node);
isValueAliasDeclaration: nodeIn => {
const node = getParseTreeNode(nodeIn);
// Synthesized nodes are always treated like values.
return node ? isValueAliasDeclaration(node) : true;
},
hasGlobalName,
isReferencedAliasDeclaration: (node, checkChildren?) => {
node = getParseTreeNode(node);
isReferencedAliasDeclaration: (nodeIn, checkChildren?) => {
const node = getParseTreeNode(nodeIn);
// Synthesized nodes are always treated as referenced.
return node ? isReferencedAliasDeclaration(node, checkChildren) : true;
},
getNodeCheckFlags: node => {
node = getParseTreeNode(node);
getNodeCheckFlags: nodeIn => {
const node = getParseTreeNode(nodeIn);
return node ? getNodeCheckFlags(node) : 0;
},
isTopLevelValueImportEqualsWithEntityName,
+69
View File
@@ -2082,4 +2082,73 @@ namespace ts {
throw e;
}
}
export type Overload<This, A extends any[], R> = ((this: This, ...args: A) => R) & OverloadOptions<A>;
export type OverloadOptions<A extends any[]> = { minLength?: A["length"], maxLength?: A["length"] };
export type OverloadLengthOptions<A extends any[]> = { length: A["length"] };
export type OverloadParameters<O extends Overload<any, any, any>> = O extends unknown ? Parameters<O> : never;
export type OverloadList<This, O extends Overload<This, any, R>[], R> = (this: This, ...args: OverloadParameters<O[number]>) => R;
export function makeOverload<This, A extends any[], R>(fn: (this: This, ...args: A) => R, options?: OverloadOptions<A> | OverloadLengthOptions<A>) {
const overload = fn as Overload<This, A, R>;
if (options) {
if ("length" in options) {
overload.minLength = overload.maxLength = options.length;
}
else {
if ("minLength" in options) {
overload.minLength = options.minLength;
}
if ("maxLength" in options) {
overload.maxLength = options.maxLength;
}
}
}
return overload;
}
/**
* Create a function from a set of overloads differentiated by argument count.
*/
export function overloadList<This, O extends Overload<This, any, R>[], R>(...overloads: O) {
type F = O[number];
const overloadCache: F[] = [];
// sort by minLength descending
const sortedOverloads = stableSort(overloads, (a, b) => -compareValues(minLength(a), minLength(b)));
let lastLength = -1;
for (const overload of sortedOverloads) {
const overloadLength = minLength(overload);
Debug.assert(overloadLength !== lastLength, "Overloads must differ in minimum length");
lastLength = overloadLength;
}
Debug.assert(lastLength !== -1, "Overload list must not be empty");
return function () { return chooseOverload(arguments.length).apply(this, arguments); } as OverloadList<This, O, R>;
function chooseOverload(length: number) {
const cached = overloadCache[length];
if (cached) return cached;
for (const overload of sortedOverloads) {
if (length >= minLength(overload)) {
overloadCache[length] = overload;
return length <= maxLength(overload) ? overload : argumentCountMismatch;
}
}
return overloadCache[length] = argumentCountMismatch;
}
function minLength(overload: F) {
return typeof overload.minLength === "number" ? overload.minLength : overload.length;
}
function maxLength(overload: F) {
return typeof overload.maxLength === "number" ? overload.maxLength : overload.length;
}
}
function argumentCountMismatch() {
return Debug.fail("Argument count mismatch");
}
}
+1 -1
View File
@@ -248,7 +248,7 @@ namespace ts {
if (nodeIsSynthesized(this)) return "";
const parseNode = getParseTreeNode(this);
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode!, includeTrivia) : "";
}
}
});
+4
View File
@@ -3200,6 +3200,10 @@
"category": "Error",
"code": 5080
},
"Plugins are not supported in the current host environment.": {
"category": "Error",
"code": 5081
},
"Generates a sourcemap for each corresponding '.d.ts' file.": {
"category": "Message",
+5 -5
View File
@@ -28,7 +28,7 @@ namespace ts {
if (options.outFile || options.out) {
const prepends = host.getPrependNodes();
if (sourceFiles.length || prepends.length) {
const bundle = syntheticNodeFactory.createBundle(sourceFiles, prepends);
const bundle = factory.createBundle(sourceFiles, prepends);
const result = action(getOutputPathsFor(bundle, host, emitOnlyDtsFiles), bundle);
if (result) {
return result;
@@ -312,7 +312,7 @@ namespace ts {
return;
}
// Transform the source files
const transform = transformNodes(resolver, host, syntheticNodeFactory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
const transform = transformNodes(resolver, host, factory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
const printerOptions: PrinterOptions = {
removeComments: compilerOptions.removeComments,
@@ -357,13 +357,13 @@ namespace ts {
const sourceFiles = isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles;
// Setup and perform the transformation to retrieve declarations from the input files
const nonJsFiles = filter(sourceFiles, isSourceFileNotJS);
const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [syntheticNodeFactory.createBundle(nonJsFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : nonJsFiles;
const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [factory.createBundle(nonJsFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : nonJsFiles;
if (emitOnlyDtsFiles && !getEmitDeclarations(compilerOptions)) {
// Checker wont collect the linked aliases since thats only done when declaration is enabled.
// Do that here when emitting only dts files
nonJsFiles.forEach(collectLinkedAliases);
}
const declarationTransform = transformNodes(resolver, host, syntheticNodeFactory, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false);
const declarationTransform = transformNodes(resolver, host, factory, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false);
if (length(declarationTransform.diagnostics)) {
for (const diagnostic of declarationTransform.diagnostics!) {
emitterDiagnostics.add(diagnostic);
@@ -2183,7 +2183,7 @@ namespace ts {
const dotRangeStart = skipTrivia(currentSourceFile!.text, dotRangeFirstCommentStart);
const dotRangeEnd = dotRangeStart + 1;
if (!(getEmitFlags(node) & EmitFlags.NoIndentation)) {
const dotToken = syntheticNodeFactory.createToken(SyntaxKind.DotToken);
const dotToken = factory.createToken(SyntaxKind.DotToken);
dotToken.pos = node.expression.end;
dotToken.end = dotRangeEnd;
indentBeforeDot = needsIndentation(node, node.expression, dotToken);
+1942 -1261
View File
File diff suppressed because it is too large Load Diff
+17 -15
View File
@@ -31,7 +31,7 @@ namespace ts {
}
/* @internal */
export const parseNodeFactory = createNodeFactory(createNode, createParenthesizerRules, createNodeConverters);
export const parseNodeFactory = createNodeFactory(createNode, createParenthesizerRules, createNodeConverters, nullTreeStateObserver);
function visitNode<T>(cbNode: (node: Node) => T, node: Node | undefined): T | undefined {
return node && cbNode(node);
@@ -590,7 +590,7 @@ namespace ts {
// Share a single scanner across all calls to parse a source file. This helps speed things
// up by avoiding the cost of creating/compiling scanners over and over again.
const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true);
const factory = createNodeFactory(createNode, getNullParenthesizerRules, getNullNodeConverters);
const factory = createNodeFactory(createNode, getNullParenthesizerRules, getNullNodeConverters, nullTreeStateObserver);
const disallowInAndDecoratorContext = NodeFlags.DisallowInContext | NodeFlags.DecoratorContext;
// capture constructors in 'initializeState' to avoid null checks
@@ -736,6 +736,7 @@ namespace ts {
nextToken();
const pos = getNodePos();
if (token() === SyntaxKind.EndOfFileToken) {
// TODO(rbuckton): this does not create the tree correctly and transform flags won't be properly set
sourceFile.statements = createNodeArray([], pos, pos);
sourceFile.endOfFileToken = parseTokenNode<EndOfFileToken>();
}
@@ -770,6 +771,7 @@ namespace ts {
break;
}
// TODO(rbuckton): this does not create the tree correctly and transform flags won't be properly set
const statement = factory.createExpressionStatement(expression) as JsonObjectExpressionStatement;
finishNode(statement, pos);
sourceFile.statements = createNodeArray([statement], pos);
@@ -786,11 +788,6 @@ namespace ts {
return result;
}
function getLanguageVariant(scriptKind: ScriptKind) {
// .tsx and .jsx files are treated as jsx language variant.
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard;
}
function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor | undefined, scriptKind: ScriptKind) {
NodeConstructor = objectAllocator.getNodeConstructor();
TokenConstructor = objectAllocator.getTokenConstructor();
@@ -856,6 +853,7 @@ namespace ts {
processCommentPragmas(sourceFile as {} as PragmaContext, sourceText);
processPragmasIntoFields(sourceFile as {} as PragmaContext, reportPragmaDiagnostic);
// TODO(rbuckton): this does not create the tree correctly and transform flags won't be properly set
sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement);
Debug.assert(token() === SyntaxKind.EndOfFileToken);
sourceFile.endOfFileToken = addJSDocComment(parseTokenNode());
@@ -1375,7 +1373,8 @@ namespace ts {
isTemplateLiteralKind(kind) ? factory.createTemplateLiteralLikeNode(kind, "", "") :
kind === SyntaxKind.NumericLiteral ? factory.createNumericLiteral("", /*numericLiteralFlags*/ undefined) :
kind === SyntaxKind.StringLiteral ? factory.createStringLiteral("", /*isSingleQuote*/ undefined) :
factory.createNode(kind);
kind === SyntaxKind.MissingDeclaration ? factory.createMissingDeclaration() :
factory.createToken(kind);
return finishNode(result, pos) as T;
}
@@ -3238,7 +3237,11 @@ namespace ts {
return parsePostfixTypeOrHigher();
}
function parseUnionOrIntersectionType(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, parseConstituentType: () => TypeNode, operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken): TypeNode {
function parseUnionOrIntersectionType(
operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken,
parseConstituentType: () => TypeNode,
createTypeNode: (types: NodeArray<TypeNode>) => UnionOrIntersectionTypeNode
): TypeNode {
const pos = getNodePos();
const hasLeadingOperator = parseOptional(operator);
let type = parseConstituentType();
@@ -3247,17 +3250,17 @@ namespace ts {
while (parseOptional(operator)) {
types.push(parseConstituentType());
}
type = finishNode(factory.createUnionOrIntersectionTypeNode(kind, createNodeArray(types, pos)), pos);
type = finishNode(createTypeNode(createNodeArray(types, pos)), pos);
}
return type;
}
function parseIntersectionTypeOrHigher(): TypeNode {
return parseUnionOrIntersectionType(SyntaxKind.IntersectionType, parseTypeOperatorOrHigher, SyntaxKind.AmpersandToken);
return parseUnionOrIntersectionType(SyntaxKind.AmpersandToken, parseTypeOperatorOrHigher, factory.createIntersectionTypeNode);
}
function parseUnionTypeOrHigher(): TypeNode {
return parseUnionOrIntersectionType(SyntaxKind.UnionType, parseIntersectionTypeOrHigher, SyntaxKind.BarToken);
return parseUnionOrIntersectionType(SyntaxKind.BarToken, parseIntersectionTypeOrHigher, factory.createUnionTypeNode);
}
function isStartOfFunctionType(): boolean {
@@ -4888,7 +4891,7 @@ namespace ts {
const objectAssignmentInitializer = equalsToken ? allowInAnd(parseAssignmentExpressionOrHigher) : undefined;
node = factory.createShorthandPropertyAssignment(name as Identifier, objectAssignmentInitializer);
// Save equals token for error reporting.
// TODO(rbuckton): Consider manufacturing this when we need to report an error as its otherwise not useful.
// TODO(rbuckton): Consider manufacturing this when we need to report an error as it is otherwise not useful.
if (equalsToken) node.equalsToken = equalsToken;
}
else {
@@ -5654,8 +5657,7 @@ namespace ts {
}
const type = parseTypeAnnotation();
const initializer = isInOrOfKeyword(token()) ? undefined : parseInitializer();
const node = factory.createVariableDeclaration(name, type, initializer);
node.exclamationToken = exclamationToken;
const node = factory.createVariableDeclaration(name, exclamationToken, type, initializer);
return finishNode(node, pos);
}
+13 -2
View File
@@ -21,7 +21,6 @@ namespace ts {
| { error: Diagnostic, result: undefined }
| { error: undefined, result: T | undefined };
/*@internal*/
export interface GetPluginsResult {
plugins: CompilerPlugin[];
diagnostics?: Diagnostic[];
@@ -39,7 +38,6 @@ namespace ts {
/**
* Resolves the supplied plugins (and their dependencies) relative to an initial directory.
*/
/*@internal*/
export function getPlugins(host: ModuleLoaderHost, initialDir: string, plugins: ReadonlyArray<string | [string, any?]>) {
interface ResolvedModule {
getModule(): RequireResult;
@@ -185,6 +183,17 @@ namespace ts {
}
}
export function registerPluginApiModules(host: ModuleLoaderHost) {
host.registerModule(createPluginApiModuleFactory());
}
function createPluginApiModuleFactory(): ModuleFactory {
return {
id: ["typescript"],
load: () => ts
};
}
function findPackageJsonPath(host: ModuleResolutionHost, modulePath: string) {
while (true) {
const candidate = combinePaths(modulePath, "package.json");
@@ -402,10 +411,12 @@ namespace ts {
}
function createLoadDiagnostic(compilerPlugin: CompilerPlugin, error: { message?: string, stack?: string }) {
debugger;
return createCompilerDiagnostic(Diagnostics.Plugin_0_could_not_be_loaded, compilerPlugin.name, error.stack || error.message || error.toString());
}
function createUserCodeDiagnostic(compilerPlugin: CompilerPlugin, hook: Hook, error: { message?: string, stack?: string }) {
debugger;
return createCompilerDiagnostic(Diagnostics.Plugin_0_failed_while_executing_the_1_hook_Colon_2, compilerPlugin.name, hook, error.stack || error.message || error.toString());
}
}
+83 -35
View File
@@ -749,7 +749,36 @@ namespace ts {
dropTypeCheckers: () => void;
}
function createBaseProgram(createProgramOptions: CreateProgramOptions, preprocess?: Transformer<SourceFile>): CreateBaseProgramResult {
function changeCompilerHostToUsePreprocessor(host: CompilerHost, preprocess: Transformer<SourceFile>) {
const oldGetSourceFile = host.getSourceFile;
host.getSourceFile = function(fileName, languageVersion, onError, shouldCreateNewSourceFile) {
return getPreprocessedSourceFile(oldGetSourceFile.call(this, fileName, languageVersion, onError, shouldCreateNewSourceFile));
};
if (host.getSourceFileByPath) {
const oldGetSourceFileByPath = host.getSourceFileByPath;
// tslint:disable-next-line only-arrow-functions
host.getSourceFileByPath = function (fileName, path, languageVersion, onError, shouldCreateNewSourceFile) {
return getPreprocessedSourceFile(oldGetSourceFileByPath.call(this, fileName, path, languageVersion, onError, shouldCreateNewSourceFile));
};
}
if (host.onReleaseOldSourceFile) {
const oldOnReleaseOldSourceFile = host.onReleaseOldSourceFile;
// tslint:disable-next-line only-arrow-functions
host.onReleaseOldSourceFile = function (oldSourceFile, oldOptions, hasSourceFileByPath) {
return oldOnReleaseOldSourceFile.call(getUnprocessedSourceFile(oldSourceFile), oldOptions, hasSourceFileByPath);
};
}
function getPreprocessedSourceFile(file: SourceFile | undefined) {
if (!file) return;
if (file.preprocessInfo) return file.preprocessInfo.processed;
const processed = preprocess(file);
const preprocessInfo: PreprocessInfo = { unprocessed: file, processed };
file.preprocessInfo = processed.preprocessInfo = preprocessInfo;
return processed;
}
}
function createBaseProgram(createProgramOptions: CreateProgramOptions, host: CompilerHost): CreateBaseProgramResult {
const { options, configFileParsingDiagnostics } = createProgramOptions;
const { rootNames, projectReferences } = createProgramOptions;
let { oldProgram } = createProgramOptions;
@@ -772,8 +801,6 @@ namespace ts {
let resolvedTypeReferenceDirectives = createMap<ResolvedTypeReferenceDirective | undefined>();
const host = createProgramOptions.host || createCompilerHost(options);
// The below settings are to track if a .js file should be add to the program if loaded via searching under node_modules.
// This works as imported modules are discovered recursively in a depth first manner, specifically:
// - For each root file, findSourceFile is called.
@@ -2028,8 +2055,8 @@ namespace ts {
&& (options.isolatedModules || isExternalModuleFile)
&& !file.isDeclarationFile) {
// synthesize 'import "tslib"' declaration
const externalHelpersModuleReference = syntheticNodeFactory.createStringLiteral(externalHelpersModuleNameText);
const importDecl = syntheticNodeFactory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference);
const externalHelpersModuleReference = factory.createStringLiteral(externalHelpersModuleNameText);
const importDecl = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference);
addEmitFlags(importDecl, EmitFlags.NeverApplyImportHelper);
externalHelpersModuleReference.parent = importDecl;
importDecl.parent = file;
@@ -2093,19 +2120,43 @@ namespace ts {
}
function collectDynamicImportOrRequireCalls(file: SourceFile) {
if (isProcessedSourceFile(file)) {
// If the file has gone through a preprocessor, we need to walk the tree to find dynamic imports and require calls
collectDynamicImportOrRequireCallsInSubtree(getUnprocessedSourceFile(file), file);
}
else {
collectDynamicImportOrRequireCallsInRange(file, 0, file.text.length);
}
}
function collectDynamicImportOrRequireCallsInSubtree(unprocessedFile: SourceFile, node: Node) {
if (node.flags & NodeFlags.Preprocessed) {
collectDynamicImportOrRequireCallsOfNode(node);
forEachChild(node, child => collectDynamicImportOrRequireCallsInSubtree(unprocessedFile, child));
}
else {
collectDynamicImportOrRequireCallsInRange(unprocessedFile, node.pos, node.end);
}
}
function collectDynamicImportOrRequireCallsInRange(file: SourceFile, start: number, end: number) {
const r = /import|require/g;
while (r.exec(file.text) !== null) {
const node = getNodeAtPosition(file, r.lastIndex);
if (isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) {
imports = append(imports, node.arguments[0]);
}
// we have to check the argument list has length of 1. We will still have to process these even though we have parsing error.
else if (isImportCall(node) && node.arguments.length === 1 && isStringLiteralLike(node.arguments[0])) {
imports = append(imports, node.arguments[0] as StringLiteralLike);
}
else if (isLiteralImportTypeNode(node)) {
imports = append(imports, node.argument.literal);
}
const text = file.text.slice(start, end);
while (r.exec(text) !== null) {
collectDynamicImportOrRequireCallsOfNode(getNodeAtPosition(file, r.lastIndex + start));
}
}
function collectDynamicImportOrRequireCallsOfNode(node: Node) {
if (isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) {
imports = append(imports, node.arguments[0]);
}
// we have to check the argument list has length of 1. We will still have to process these even though we have parsing error.
else if (isImportCall(node) && node.arguments.length === 1 && isStringLiteralLike(node.arguments[0])) {
imports = append(imports, node.arguments[0] as StringLiteralLike);
}
else if (isLiteralImportTypeNode(node)) {
imports = append(imports, node.argument.literal);
}
}
@@ -2295,7 +2346,7 @@ namespace ts {
}
// We haven't looked for this file, do so now and cache result
let file = host.getSourceFile(
const file = host.getSourceFile(
fileName,
options.target!,
hostErrorMessage => fileProcessingDiagnostics.add(createRefFileDiagnostic(
@@ -2307,15 +2358,6 @@ namespace ts {
shouldCreateNewSourceFile
);
// Pass the file through a user-defined preprocessor (provided by plugins)
if (file && preprocess) {
const processed = preprocess(file);
if (processed !== file) {
processed.preprocessInfo = { unprocessed: file };
}
file = processed;
}
if (packageId) {
const packageIdKey = packageIdToString(packageId);
const fileFromPackageId = packageIdToSourceFile.get(packageIdKey);
@@ -3325,7 +3367,8 @@ namespace ts {
performance.mark("beforeProgram");
const { baseProgram, emitWorker, dropTypeCheckers } = createBaseProgram(createProgramOptions);
const host = createProgramOptions.host || createCompilerHost(createProgramOptions.options);
const { baseProgram, emitWorker, dropTypeCheckers } = createBaseProgram(createProgramOptions, host);
const program = baseProgram as Program;
program.emit = emit;
@@ -3339,6 +3382,14 @@ namespace ts {
}
}
function createPreprocessedNode(kind: SyntaxKind) {
const node = createNode(kind, -1, -1);
node.flags |= NodeFlags.Preprocessed;
return node;
}
const preprocessorNodeFactory = createNodeFactory(createPreprocessedNode, createParenthesizerRules, createNodeConverters, nullTreeStateObserver);
/**
* Create a new 'AsyncProgram' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions'
* that represent a compilation unit.
@@ -3369,7 +3420,6 @@ namespace ts {
projectReferences: createProgramOptions.projectReferences
});
let preprocess: Transformer<SourceFile> | undefined;
let preprocessDiagnostics: DiagnosticWithLocation[] | undefined;
let preprocessTransformer: NodeTransformer<SourceFile> | undefined;
let preprocessedNodes: Node[] | undefined;
@@ -3385,24 +3435,22 @@ namespace ts {
preprocessTransformer = createNodeTransformer(
/*resolver*/ undefined,
/*host*/ undefined,
parseNodeFactory,
preprocessorNodeFactory,
options,
preParseResult.preprocessors,
/*allowDtsFiles*/ true
);
preprocessDiagnostics = preprocessTransformer.diagnostics;
preprocessedNodes = [];
preprocess = node => {
changeCompilerHostToUsePreprocessor(host, node => {
disposeEmitNodes(getSourceFileOfNode(getParseTreeNode(node)));
preprocessedNodes!.push(node);
return preprocessTransformer!.transformNode(node);
};
});
}
}
// !!!!
// TODO(rbuckton): pass `parseTransform` to `createBaseProgram`
const { baseProgram, emitWorker, dropTypeCheckers } = createBaseProgram(createProgramOptions, preprocess);
const { baseProgram, emitWorker, dropTypeCheckers } = createBaseProgram(createProgramOptions, host);
if (preprocessDiagnostics) {
for (const diagnostic of preprocessDiagnostics) {
+27
View File
@@ -651,6 +651,7 @@ namespace ts {
base64decode?(input: string): string;
base64encode?(input: string): string;
/*@internal*/ bufferFrom?(input: string, encoding?: string): Buffer;
/*@internal*/ registerModule?(factory: ModuleFactory): void;
/*@internal*/ require?(baseDir: string, moduleName: string): RequireResult;
}
@@ -718,6 +719,7 @@ namespace ts {
const _fs = require("fs");
const _path = require("path");
const _os = require("os");
const _module = require("module");
// crypto can be absent on reduced node installations
let _crypto: typeof import("crypto") | undefined;
try {
@@ -749,6 +751,7 @@ namespace ts {
const tscWatchDirectory = process.env.TSC_WATCHDIRECTORY;
const fsWatchFile = memoize(() => createSingleFileWatcherPerName(fsWatchFileWorker, useCaseSensitiveFileNames));
let dynamicPollingWatchFile: HostWatchFile | undefined;
let factories: Map<ModuleFactory> | undefined;
const nodeSystem: System = {
args: process.argv.slice(2),
newLine: _os.EOL,
@@ -839,6 +842,7 @@ namespace ts {
bufferFrom,
base64decode: input => bufferFrom(input, "base64").toString("utf8"),
base64encode: input => bufferFrom(input).toString("base64"),
registerModule,
require: (baseDir, moduleName) => {
try {
// NOTE: 'require' may be called before `resolveJSModule` is available (i.e. when loading shims). If that is the case then
@@ -1337,6 +1341,29 @@ namespace ts {
hash.update(data);
return hash.digest("hex");
}
// based on:
// - https://github.com/microsoft/vscode/blob/master/src/vs/workbench/api/common/extHostRequireInterceptor.ts
// - https://github.com/microsoft/vscode/blob/master/src/vs/workbench/api/node/extHostExtensionService.ts
function registerModule(factory: ModuleFactory) {
if (!factories) {
factories = createMap<ModuleFactory>();
const load = _module._load as ModuleLoadFunction;
_module._load = function(request: string, parent: { filename: string }, isMain: boolean) {
const factory = factories!.get(request);
return factory ? factory.load(request, parent, isMain, (...args) => load.apply(this, args)) :
load.apply(this, arguments);
};
}
if (isArray(factory.id)) {
for (const id of factory.id) {
factories.set(id, factory);
}
}
else {
factories.set(factory.id, factory);
}
}
}
function getChakraSystem(): System {
+2 -2
View File
@@ -450,7 +450,7 @@ namespace ts {
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization.");
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
Debug.assert(!helper.scoped, "Cannot request a scoped emit helper.");
emitHelpers = append(emitHelpers, helper);
emitHelpers = appendIfUnique(emitHelpers, helper);
}
function readEmitHelpers(): EmitHelper[] | undefined {
@@ -528,7 +528,7 @@ namespace ts {
/* @internal */
export const nullTransformationContext: TransformationContext = {
factory: syntheticNodeFactory,
factory,
getEmitHelperFactory: notImplemented,
enableEmitNotification: noop,
enableSubstitution: noop,
+26 -17
View File
@@ -5,7 +5,7 @@ namespace ts {
return []; // No declaration diagnostics for js for now
}
const compilerOptions = host.getCompilerOptions();
const result = transformNodes(resolver, host, syntheticNodeFactory, compilerOptions, file ? [file] : filter(host.getSourceFiles(), isSourceFileNotJS), [transformDeclarations], /*allowDtsFiles*/ false);
const result = transformNodes(resolver, host, factory, compilerOptions, file ? [file] : filter(host.getSourceFiles(), isSourceFileNotJS), [transformDeclarations], /*allowDtsFiles*/ false);
return result.diagnostics;
}
@@ -839,24 +839,25 @@ namespace ts {
case SyntaxKind.Constructor: {
const isPrivate = hasModifier(input, ModifierFlags.Private);
// A constructor declaration may not have a type annotation
const ctor = factory.createSignatureDeclaration(
SyntaxKind.Constructor,
isPrivate ? undefined : ensureTypeParams(input, input.typeParameters),
// TODO: GH#18217
isPrivate ? undefined! : updateParamsList(input, input.parameters, ModifierFlags.None),
/*type*/ undefined
const ctor = factory.createConstructorDeclaration(
/*decorators*/ undefined,
factory.createNodeArray(ensureModifiers(input)),
isPrivate ? factory.createNodeArray() : updateParamsList(input, input.parameters, ModifierFlags.None),
/*body*/ undefined
);
ctor.modifiers = factory.createNodeArray(ensureModifiers(input));
return cleanup(ctor);
}
case SyntaxKind.MethodDeclaration: {
const sig = factory.createMethodSignature(
const sig = factory.createMethodDeclaration(
/*decorators*/ undefined,
ensureModifiers(input),
/*asteriskToken*/ undefined,
input.name,
input.questionToken,
ensureTypeParams(input, input.typeParameters),
updateParamsList(input, input.parameters),
ensureType(input, input.type)
ensureType(input, input.type),
/*body*/ undefined
);
return cleanup(sig);
}
@@ -1054,16 +1055,24 @@ namespace ts {
return input;
}
function stripExportModifiers(statement: Statement): Statement {
if (isImportEqualsDeclaration(statement) || hasModifier(statement, ModifierFlags.Default)) {
function stripExportModifiers(node: Statement): Statement {
if (isImportEqualsDeclaration(node) || hasModifier(node, ModifierFlags.Default)) {
// `export import` statements should remain as-is, as imports are _not_ implicitly exported in an ambient namespace
// Likewise, `export default` classes and the like and just be `default`, so we preserve their `export` modifiers, too
return statement;
return node;
}
const clone = getMutableClone(statement);
const modifiers = factory.createModifiersFromModifierFlags(getModifierFlags(statement) & (ModifierFlags.All ^ ModifierFlags.Export));
clone.modifiers = modifiers.length ? factory.createNodeArray(modifiers) : undefined;
return clone;
return isClassDeclaration(node) ? factory.updateClassDeclaration(node, node.decorators, visitNodes(node.modifiers, modifierVisitor), node.name, node.typeParameters, node.heritageClauses, node.members) :
isFunctionDeclaration(node) ? factory.updateFunctionDeclaration(node, node.decorators, visitNodes(node.modifiers, modifierVisitor), node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body) :
isModuleDeclaration(node) ? factory.updateModuleDeclaration(node, node.decorators, visitNodes(node.modifiers, modifierVisitor), node.name, node.body) :
isEnumDeclaration(node) ? factory.updateEnumDeclaration(node, node.decorators, visitNodes(node.modifiers, modifierVisitor), node.name, node.members) :
isInterfaceDeclaration(node) ? factory.updateInterfaceDeclaration(node, node.decorators, visitNodes(node.modifiers, modifierVisitor), node.name, node.typeParameters, node.heritageClauses, node.members) :
isTypeAliasDeclaration(node) ? factory.updateTypeAliasDeclaration(node, node.decorators, visitNodes(node.modifiers, modifierVisitor), node.name, node.typeParameters, node.type) :
isVariableStatement(node) ? factory.updateVariableStatement(node, visitNodes(node.modifiers, modifierVisitor), node.declarationList) :
node;
}
function modifierVisitor(node: Modifier) {
return node.kind === SyntaxKind.ExportKeyword ? undefined : node;
}
function transformTopLevelDeclaration(input: LateVisibilityPaintedStatement) {
+1 -3
View File
@@ -2161,9 +2161,7 @@ namespace ts {
}
if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) {
const clone = getMutableClone(node);
clone.initializer = factory.createVoidZero();
return clone;
return factory.updateVariableDeclaration(node, node.name, /*type*/ undefined, factory.createVoidZero());
}
return visitEachChild(node, visitor, context);
+6 -8
View File
@@ -785,10 +785,9 @@ namespace ts {
// .yield resumeLabel
// _a + %sent% + c()
const clone = getMutableClone(node);
clone.left = cacheExpression(visitNode(node.left, visitor, isExpression));
clone.right = visitNode(node.right, visitor, isExpression);
return clone;
return factory.updateBinary(node,
cacheExpression(visitNode(node.left, visitor, isExpression)),
visitNode(node.right, visitor, isExpression));
}
return visitEachChild(node, visitor, context);
@@ -1102,10 +1101,9 @@ namespace ts {
// .mark resumeLabel
// a = _a[%sent%]
const clone = getMutableClone(node);
clone.expression = cacheExpression(visitNode(node.expression, visitor, isLeftHandSideExpression));
clone.argumentExpression = visitNode(node.argumentExpression, visitor, isExpression);
return clone;
return factory.updateElementAccess(node,
cacheExpression(visitNode(node.expression, visitor, isLeftHandSideExpression)),
visitNode(node.argumentExpression, visitor, isExpression));
}
return visitEachChild(node, visitor, context);
+2 -2
View File
@@ -172,8 +172,8 @@ namespace ts {
else if (node.kind === SyntaxKind.StringLiteral) {
// Always recreate the literal to escape any escape sequences or newlines which may be in the original jsx string and which
// Need to be escaped to be handled correctly in a normal string
const literal = factory.createStringLiteral(tryDecodeEntities(node.text) || node.text);
literal.singleQuote = node.singleQuote !== undefined ? node.singleQuote : !isStringDoubleQuoted(node, currentSourceFile);
const singleQuote = node.singleQuote !== undefined ? node.singleQuote : !isStringDoubleQuoted(node, currentSourceFile);
const literal = factory.createStringLiteral(tryDecodeEntities(node.text) || node.text, singleQuote);
return setTextRange(literal, node);
}
else if (node.kind === SyntaxKind.JsxExpression) {
+1 -2
View File
@@ -278,9 +278,8 @@ namespace ts {
factory.createBlock(executeStatements, /*multiLine*/ true)
)
)
]);
], /*multiLine*/ true);
moduleObject.multiLine = true;
statements.push(factory.createReturn(moduleObject));
return factory.createBlock(statements, /*multiLine*/ true);
}
+1 -1
View File
@@ -1740,7 +1740,7 @@ namespace ts {
const name = getMutableClone(node);
name.flags &= ~NodeFlags.Synthesized;
name.original = undefined;
name.parent = getParseTreeNode(currentLexicalScope); // ensure the parent is set to a parse tree node.
name.parent = getParseTreeNode(currentLexicalScope)!; // ensure the parent is set to a parse tree node.
return name;
+1 -1
View File
@@ -60,6 +60,6 @@
"resolutionCache.ts",
"moduleSpecifiers.ts",
"watch.ts",
"tsbuild.ts",
"tsbuild.ts"
]
}
+31 -9
View File
@@ -529,6 +529,7 @@ namespace ts {
Let = 1 << 0, // Variable declaration
Const = 1 << 1, // Variable declaration
NestedNamespace = 1 << 2, // Namespace declaration
Preprocessed = 1 << 25, // Node was synthesized during preprocessing
Synthesized = 1 << 3, // Node was synthesized during transformation
Namespace = 1 << 4, // Namespace declaration
ExportContext = 1 << 5, // Export context (initialized by binding)
@@ -1289,6 +1290,7 @@ namespace ts {
}
export type StringLiteralLike = StringLiteral | NoSubstitutionTemplateLiteral;
export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral;
// Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing.
// Consider 'Expression'. Without the brand, 'Expression' is actually no different
@@ -2695,7 +2697,6 @@ namespace ts {
name?: string;
}
/* @internal */
/**
* Subset of properties from SourceFile that are used in multiple utility functions
*/
@@ -2724,6 +2725,10 @@ namespace ts {
* The source file prior to being passed to the preprocessor.
*/
readonly unprocessed: SourceFile;
/**
* The source file resulting from the preprocessor.
*/
readonly processed: SourceFile;
}
// Source files are declarations when they are external modules.
@@ -4992,7 +4997,7 @@ namespace ts {
/** Plugin dependencies that should be loaded before this plugin. */
pluginDependencies?: string[];
/** Loads the compiler plugin. */
loadPlugin(): RequireResult<CompilerPluginModule>;
/* @internal */ loadPlugin(): RequireResult<CompilerPluginModule>;
}
/**
@@ -5092,8 +5097,18 @@ namespace ts {
export interface CompilerPluginDeactivationResult extends CompilerPluginResult {
}
/*@internal*/
export type ModuleLoadFunction = (request: string, parent: { filename: string }, isMain: boolean) => unknown;
/*@internal*/
export interface ModuleFactory {
readonly id: string | readonly string[];
load(request: string, parent: { filename: string }, isMain: boolean, load: ModuleLoadFunction): unknown;
}
/* @internal */
export interface ModuleLoaderHost extends ModuleResolutionHost {
registerModule(factory: ModuleFactory): void;
require(initialDir: string, moduleName: string): RequireResult;
}
@@ -5723,7 +5738,6 @@ namespace ts {
export interface NodeFactory {
/* @internal */ getParenthesizerRules(): ParenthesizerRules;
/* @internal */ getConverters(): NodeConverters;
/* @internal */ createNode(kind: SyntaxKind): Node;
createNodeArray<T extends Node>(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray<T>;
//
@@ -5733,7 +5747,7 @@ namespace ts {
createNumericLiteral(value: string | number, numericLiteralFlags?: TokenFlags): NumericLiteral;
createBigIntLiteral(value: string | PseudoBigInt): BigIntLiteral;
createStringLiteral(text: string, isSingleQuote?: boolean): StringLiteral;
createStringLiteralFromNode(node: PropertyNameLiteral, isSingleQuote?: boolean): StringLiteral;
createStringLiteralFromNode(sourceNode: PropertyNameLiteral, isSingleQuote?: boolean): StringLiteral;
createRegularExpressionLiteral(text: string): RegularExpressionLiteral;
//
@@ -5829,7 +5843,7 @@ namespace ts {
updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): CallSignatureDeclaration;
createConstructSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): ConstructSignatureDeclaration;
updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): ConstructSignatureDeclaration;
/* @internal */ createSignatureDeclaration<T extends SignatureDeclaration>(kind: T["kind"], typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, typeArguments?: readonly TypeNode[] | undefined): T;
/* @internal */ createSignatureDeclaration<T extends SignatureDeclaration>(kind: T["kind"], typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): T;
createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration;
/* @internal */ createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): IndexSignatureDeclaration; // tslint:disable-line unified-signatures
updateIndexSignature(node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration;
@@ -5863,7 +5877,6 @@ namespace ts {
updateUnionTypeNode(node: UnionTypeNode, types: NodeArray<TypeNode>): UnionTypeNode;
createIntersectionTypeNode(types: readonly TypeNode[]): IntersectionTypeNode;
updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray<TypeNode>): IntersectionTypeNode;
/* @internal */ createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: readonly TypeNode[]): UnionOrIntersectionTypeNode;
createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode;
updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode;
createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode;
@@ -5886,7 +5899,6 @@ namespace ts {
// Binding Patterns
//
createObjectBindingPattern(elements: readonly BindingElement[]): ObjectBindingPattern;
createObjectBindingPattern(elements: readonly BindingElement[]): ObjectBindingPattern;
updateObjectBindingPattern(node: ObjectBindingPattern, elements: readonly BindingElement[]): ObjectBindingPattern;
createArrayBindingPattern(elements: readonly ArrayBindingElement[]): ArrayBindingPattern;
@@ -6019,8 +6031,8 @@ namespace ts {
createTry(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined): TryStatement;
updateTry(node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined): TryStatement;
createDebuggerStatement(): DebuggerStatement;
// TODO(rbuckton): Add `exclamationToken`:
createVariableDeclaration(name: string | BindingName, type?: TypeNode, initializer?: Expression): VariableDeclaration;
createVariableDeclaration(name: string | BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration;
updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration;
createVariableDeclarationList(declarations: readonly VariableDeclaration[], flags?: NodeFlags): VariableDeclarationList;
updateVariableDeclarationList(node: VariableDeclarationList, declarations: readonly VariableDeclaration[]): VariableDeclarationList;
@@ -6062,6 +6074,7 @@ namespace ts {
updateNamedExports(node: NamedExports, elements: readonly ExportSpecifier[]): NamedExports;
createExportSpecifier(propertyName: string | Identifier | undefined, name: string | Identifier): ExportSpecifier;
updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier): ExportSpecifier;
/* @internal*/ createMissingDeclaration(): MissingDeclaration;
//
// Module references
@@ -6281,7 +6294,7 @@ namespace ts {
// Utilities
//
// TODO(rbuckton): Rename to `restoreOuterExpression`.
// TODO(rbuckton): Rename to `restoreOuterExpressions`.
recreateOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds?: OuterExpressionKinds): Expression;
/* @internal */ restoreEnclosingLabel(node: Statement, outermostLabeledStatement: LabeledStatement | undefined, afterRestoreLabelCallback?: (node: LabeledStatement) => void): Statement;
/* @internal */ createUseStrictPrologue(): PrologueDirective;
@@ -6325,6 +6338,15 @@ namespace ts {
convertToAssignmentElementTarget(node: BindingOrAssignmentElementTarget): Expression;
}
/* @internal */
export interface TreeStateObserver {
onSetChild(parent: Node, child: Node): void;
onSetChildren(parent: Node, children: NodeArray<Node>): void;
onFinishNode(node: Node): void;
onUpdateNode(updated: Node, original: Node): void;
onReuseNode(node: Node): void;
}
export interface CoreTransformationContext {
readonly factory: NodeFactory;
+16 -9
View File
@@ -938,6 +938,9 @@ namespace ts {
}
export function getErrorSpanForNode(sourceFile: SourceFile, node: Node): TextSpan {
while (nodeIsSynthesized(node) && node.parent) {
node = node.parent;
}
let errorNode: Node | undefined = node;
switch (node.kind) {
case SyntaxKind.SourceFile:
@@ -2819,7 +2822,6 @@ namespace ts {
}
}
export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral;
export function isPropertyNameLiteral(node: Node): node is PropertyNameLiteral {
switch (node.kind) {
case SyntaxKind.Identifier:
@@ -5169,8 +5171,7 @@ namespace ts {
* @param node The original node.
* @returns The original parse tree node if found; otherwise, undefined.
*/
export function getParseTreeNode(node: Node): Node;
export function getParseTreeNode(node: Node | undefined): Node | undefined;
/**
* Gets the original parse tree node for a node.
*
@@ -5178,18 +5179,19 @@ namespace ts {
* @param nodeTest A callback used to ensure the correct type of parse tree node is returned.
* @returns The original parse tree node if found; otherwise, undefined.
*/
export function getParseTreeNode<T extends Node>(node: Node | undefined, nodeTest?: (node: Node) => node is T): T | undefined;
export function getParseTreeNode<T extends Node>(node: T | undefined, nodeTest: (node: Node) => node is T): T | undefined;
export function getParseTreeNode(node: Node | undefined, nodeTest?: (node: Node) => boolean): Node | undefined {
if (node === undefined || isParseTreeNode(node)) {
return node;
}
node = getOriginalNode(node);
if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) {
return node;
node = node.original;
while (node) {
if (isParseTreeNode(node)) {
return !nodeTest || nodeTest(node) ? node : undefined;
}
node = node.original;
}
return undefined;
}
@@ -7403,6 +7405,11 @@ namespace ts {
return Comparison.EqualTo;
}
export function getLanguageVariant(scriptKind: ScriptKind) {
// .tsx and .jsx files are treated as jsx language variant.
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard;
}
export function getEmitScriptTarget(compilerOptions: CompilerOptions) {
return compilerOptions.target || ScriptTarget.ES3;
}
+39 -11
View File
@@ -21,6 +21,7 @@ namespace fakes {
public readonly newLine: string;
public readonly useCaseSensitiveFileNames: boolean;
public exitCode: number | undefined;
public registerModule?: ts.System["registerModule"];
public require?: ts.System["require"];
private readonly _executingFilePath: string | undefined;
@@ -34,6 +35,7 @@ namespace fakes {
this._env = env;
if (useFakeLoader) {
const loader = new ModuleLoader(this.vfs);
this.registerModule = factory => loader.registerModule(factory);
this.require = (baseDir: string, moduleName: string): ts.RequireResult => {
try {
const modulePath = ts.resolveJSModule(moduleName, baseDir, this);
@@ -392,47 +394,73 @@ namespace fakes {
type ModuleWrapper = (require: Function, module: any, exports: any, dirname: string, filename: string) => void;
interface ModuleObject {
filename: string;
exports: any;
}
class ModuleLoader {
readonly vfs: vfs.FileSystem;
private _modules = ts.createMap<ModuleObject>();
private _factories = ts.createMap<ts.ModuleFactory>();
private _linker?: (modulePath: string, moduleContent: string) => ModuleWrapper;
constructor(vfs: vfs.FileSystem) {
this.vfs = vfs;
}
registerModule(factory: ts.ModuleFactory) {
if (ts.isArray(factory.id)) {
for (const id of factory.id) {
this._factories.set(id, factory);
}
}
else {
this._factories.set(factory.id, factory);
}
}
require(modulePath: string) {
// this is a very basic loader that is only intended to load a single file for now.
let module = this._modules.get(modulePath);
if (!module) {
module = { exports: {} };
module = { filename: modulePath, exports: {} };
this._modules.set(modulePath, module);
const moduleContent = this.vfs.readFileSync(modulePath, "utf8");
const linkedModule = this.link(modulePath, moduleContent);
linkedModule(ts.notImplemented, module, module.exports, ts.getDirectoryPath(modulePath), modulePath);
const require = (request: string) => this.load(request, module!, /*isMain*/ false);
linkedModule(require, module, module.exports, ts.getDirectoryPath(modulePath), modulePath);
}
return module.exports;
}
private load(request: string, parent: { filename: string }, isMain: boolean) {
const factory = this._factories.get(request);
if (factory) {
return factory.load(request, parent, isMain, ts.notImplemented);
}
return ts.notImplemented();
}
private link(modulePath: string, moduleContent: string) {
let vm: typeof import("vm") | undefined;
try {
vm = require("vm");
if (!this._linker) {
let vm: typeof import("vm") | undefined;
try {
vm = require("vm");
}
catch {
// ignore
}
this._linker = vm ? (modulePath, moduleContent) => this.linkUsingNodeVM(vm!, modulePath, moduleContent) :
(modulePath, moduleContent) => this.linkUsingIndirectEval(modulePath, moduleContent);
}
catch {
// ignore
}
return vm ? this.linkUsingNodeVM(vm, modulePath, moduleContent) :
this.linkUsingFunction(modulePath, moduleContent);
return this._linker(modulePath, moduleContent);
}
private linkUsingNodeVM(vm: typeof import("vm"), modulePath: string, moduleContent: string): ModuleWrapper {
return vm.runInThisContext(`(function (require, module, exports, __dirname, __filename) {${moduleContent}\n})`, { filename: modulePath });
}
private linkUsingFunction(modulePath: string, moduleContent: string): ModuleWrapper {
private linkUsingIndirectEval(modulePath: string, moduleContent: string): ModuleWrapper {
const indirectEval = eval;
return indirectEval(`(function (require, module, exports, __dirname, __filename) {${moduleContent}\n//# sourceURL=${modulePath}\n})`);
}
@@ -16,8 +16,8 @@ namespace ts.codefix {
const token = getTokenAtPosition(sourceFile, pos);
const assertion = Debug.assertDefined(findAncestor(token, (n): n is AsExpression | TypeAssertion => isAsExpression(n) || isTypeAssertion(n)));
const replacement = isAsExpression(assertion)
? createAsExpression(assertion.expression, createKeywordTypeNode(SyntaxKind.UnknownKeyword))
: createTypeAssertion(createKeywordTypeNode(SyntaxKind.UnknownKeyword), assertion.expression);
? factory.createAsExpression(assertion.expression, factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword))
: factory.createTypeAssertion(factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword), assertion.expression);
changeTracker.replaceNode(sourceFile, assertion.expression, replacement);
}
}
+5 -5
View File
@@ -152,8 +152,8 @@ namespace ts.codefix {
const { left, right } = insertionSite;
const leftType = checker.getTypeAtLocation(left);
const rightType = checker.getTypeAtLocation(right);
const newLeft = checker.getPromisedTypeOfPromise(leftType) ? createAwait(left) : left;
const newRight = checker.getPromisedTypeOfPromise(rightType) ? createAwait(right) : right;
const newLeft = checker.getPromisedTypeOfPromise(leftType) ? factory.createAwait(left) : left;
const newRight = checker.getPromisedTypeOfPromise(rightType) ? factory.createAwait(right) : right;
changeTracker.replaceNode(sourceFile, left, newLeft);
changeTracker.replaceNode(sourceFile, right, newRight);
}
@@ -161,13 +161,13 @@ namespace ts.codefix {
changeTracker.replaceNode(
sourceFile,
insertionSite.parent.expression,
createParen(createAwait(insertionSite.parent.expression)));
factory.createParen(factory.createAwait(insertionSite.parent.expression)));
}
else if (contains(callableConstructableErrorCodes, errorCode) && isCallOrNewExpression(insertionSite.parent)) {
changeTracker.replaceNode(sourceFile, insertionSite, createParen(createAwait(insertionSite)));
changeTracker.replaceNode(sourceFile, insertionSite, factory.createParen(factory.createAwait(insertionSite)));
}
else {
changeTracker.replaceNode(sourceFile, insertionSite, createAwait(insertionSite));
changeTracker.replaceNode(sourceFile, insertionSite, factory.createAwait(insertionSite));
}
}
}
@@ -16,7 +16,7 @@ namespace ts.codefix {
const token = getTokenAtPosition(sourceFile, pos);
const decorator = findAncestor(token, isDecorator)!;
Debug.assert(!!decorator, "Expected position to be owned by a decorator.");
const replacement = createCall(decorator.expression, /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
const replacement = factory.createCall(decorator.expression, /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
changeTracker.replaceNode(sourceFile, decorator.expression, replacement);
}
}
@@ -24,13 +24,13 @@ namespace ts.codefix {
const i = param.parent.parameters.indexOf(param);
Debug.assert(!param.type, "Tried to add a parameter name to a parameter that already had one.");
Debug.assert(i > -1, "Parameter not found in parent parameter list.");
const replacement = createParameter(
const replacement = factory.createParameterDeclaration(
/*decorators*/ undefined,
param.modifiers,
param.dotDotDotToken,
"arg" + i,
param.questionToken,
createTypeReferenceNode(token, /*typeArguments*/ undefined),
factory.createTypeReferenceNode(token, /*typeArguments*/ undefined),
param.initializer);
changeTracker.replaceNode(sourceFile, token, replacement);
}
@@ -46,14 +46,14 @@ namespace ts.codefix {
if (typeParameters.length) changes.insertTypeParameters(sourceFile, decl, typeParameters);
}
const needParens = isArrowFunction(decl) && !findChildOfKind(decl, SyntaxKind.OpenParenToken, sourceFile);
if (needParens) changes.insertNodeBefore(sourceFile, first(decl.parameters), createToken(SyntaxKind.OpenParenToken));
if (needParens) changes.insertNodeBefore(sourceFile, first(decl.parameters), factory.createToken(SyntaxKind.OpenParenToken));
for (const param of decl.parameters) {
if (!param.type) {
const paramType = getJSDocType(param);
if (paramType) changes.tryInsertTypeAnnotation(sourceFile, param, transformJSDocType(paramType));
}
}
if (needParens) changes.insertNodeAfter(sourceFile, last(decl.parameters), createToken(SyntaxKind.CloseParenToken));
if (needParens) changes.insertNodeAfter(sourceFile, last(decl.parameters), factory.createToken(SyntaxKind.CloseParenToken));
if (!decl.type) {
const returnType = getJSDocReturnType(decl);
if (returnType) changes.tryInsertTypeAnnotation(sourceFile, decl, transformJSDocType(returnType));
@@ -77,7 +77,7 @@ namespace ts.codefix {
switch (node.kind) {
case SyntaxKind.JSDocAllType:
case SyntaxKind.JSDocUnknownType:
return createTypeReferenceNode("any", emptyArray);
return factory.createTypeReferenceNode("any", emptyArray);
case SyntaxKind.JSDocOptionalType:
return transformJSDocOptionalType(node as JSDocOptionalType);
case SyntaxKind.JSDocNonNullableType:
@@ -98,27 +98,27 @@ namespace ts.codefix {
}
function transformJSDocOptionalType(node: JSDocOptionalType) {
return createUnionTypeNode([visitNode(node.type, transformJSDocType), createTypeReferenceNode("undefined", emptyArray)]);
return factory.createUnionTypeNode([visitNode(node.type, transformJSDocType), factory.createTypeReferenceNode("undefined", emptyArray)]);
}
function transformJSDocNullableType(node: JSDocNullableType) {
return createUnionTypeNode([visitNode(node.type, transformJSDocType), createTypeReferenceNode("null", emptyArray)]);
return factory.createUnionTypeNode([visitNode(node.type, transformJSDocType), factory.createTypeReferenceNode("null", emptyArray)]);
}
function transformJSDocVariadicType(node: JSDocVariadicType) {
return createArrayTypeNode(visitNode(node.type, transformJSDocType));
return factory.createArrayTypeNode(visitNode(node.type, transformJSDocType));
}
function transformJSDocFunctionType(node: JSDocFunctionType) {
return createFunctionTypeNode(emptyArray, node.parameters.map(transformJSDocParameter), node.type);
return factory.createFunctionTypeNode(emptyArray, node.parameters.map(transformJSDocParameter), node.type);
}
function transformJSDocParameter(node: ParameterDeclaration) {
const index = node.parent.parameters.indexOf(node);
const isRest = node.type!.kind === SyntaxKind.JSDocVariadicType && index === node.parent.parameters.length - 1; // TODO: GH#18217
const name = node.name || (isRest ? "rest" : "arg" + index);
const dotdotdot = isRest ? createToken(SyntaxKind.DotDotDotToken) : node.dotDotDotToken;
return createParameter(node.decorators, node.modifiers, dotdotdot, name, node.questionToken, visitNode(node.type, transformJSDocType), node.initializer);
const dotdotdot = isRest ? factory.createToken(SyntaxKind.DotDotDotToken) : node.dotDotDotToken;
return factory.createParameterDeclaration(node.decorators, node.modifiers, dotdotdot, name, node.questionToken, visitNode(node.type, transformJSDocType), node.initializer);
}
function transformJSDocTypeReference(node: TypeReferenceNode) {
@@ -142,27 +142,27 @@ namespace ts.codefix {
text = text[0].toUpperCase() + text.slice(1);
break;
}
name = createIdentifier(text);
name = factory.createIdentifier(text);
if ((text === "Array" || text === "Promise") && !node.typeArguments) {
args = createNodeArray([createTypeReferenceNode("any", emptyArray)]);
args = createNodeArray([factory.createTypeReferenceNode("any", emptyArray)]);
}
else {
args = visitNodes(node.typeArguments, transformJSDocType);
}
}
return createTypeReferenceNode(name, args);
return factory.createTypeReferenceNode(name, args);
}
function transformJSDocIndexSignature(node: TypeReferenceNode) {
const index = createParameter(
const index = factory.createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
node.typeArguments![0].kind === SyntaxKind.NumberKeyword ? "n" : "s",
/*questionToken*/ undefined,
createTypeReferenceNode(node.typeArguments![0].kind === SyntaxKind.NumberKeyword ? "number" : "string", []),
factory.createTypeReferenceNode(node.typeArguments![0].kind === SyntaxKind.NumberKeyword ? "number" : "string", []),
/*initializer*/ undefined);
const indexSignature = createTypeLiteralNode([createIndexSignature(/*decorators*/ undefined, /*modifiers*/ undefined, [index], node.typeArguments![1])]);
const indexSignature = factory.createTypeLiteralNode([factory.createIndexSignature(/*decorators*/ undefined, /*modifiers*/ undefined, [index], node.typeArguments![1])]);
setEmitFlags(indexSignature, EmitFlags.SingleLine);
return indexSignature;
}
@@ -68,7 +68,7 @@ namespace ts.codefix {
// all static members are stored in the "exports" array of symbol
if (symbol.exports) {
symbol.exports.forEach(member => {
const memberElement = createClassElement(member, [createToken(SyntaxKind.StaticKeyword)]);
const memberElement = createClassElement(member, [factory.createToken(SyntaxKind.StaticKeyword)]);
if (memberElement) {
memberElements.push(memberElement);
}
@@ -102,7 +102,7 @@ namespace ts.codefix {
changes.delete(sourceFile, nodeToDelete);
if (!assignmentBinaryExpression.right) {
return createProperty([], modifiers, symbol.name, /*questionToken*/ undefined,
return factory.createPropertyDeclaration([], modifiers, symbol.name, /*questionToken*/ undefined,
/*type*/ undefined, /*initializer*/ undefined);
}
@@ -110,7 +110,7 @@ namespace ts.codefix {
case SyntaxKind.FunctionExpression: {
const functionExpression = assignmentBinaryExpression.right as FunctionExpression;
const fullModifiers = concatenate(modifiers, getModifierKindFromSource(functionExpression, SyntaxKind.AsyncKeyword));
const method = createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined,
const method = factory.createMethodDeclaration(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined,
/*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body);
copyLeadingComments(assignmentBinaryExpression, method, sourceFile);
return method;
@@ -127,10 +127,10 @@ namespace ts.codefix {
}
// case 2: () => [1,2,3]
else {
bodyBlock = createBlock([createReturn(arrowFunctionBody)]);
bodyBlock = factory.createBlock([factory.createReturn(arrowFunctionBody)]);
}
const fullModifiers = concatenate(modifiers, getModifierKindFromSource(arrowFunction, SyntaxKind.AsyncKeyword));
const method = createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined,
const method = factory.createMethodDeclaration(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined,
/*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock);
copyLeadingComments(assignmentBinaryExpression, method, sourceFile);
return method;
@@ -141,7 +141,7 @@ namespace ts.codefix {
if (isSourceFileJS(sourceFile)) {
return;
}
const prop = createProperty(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined,
const prop = factory.createPropertyDeclaration(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined,
/*type*/ undefined, assignmentBinaryExpression.right);
copyLeadingComments(assignmentBinaryExpression.parent, prop, sourceFile);
return prop;
@@ -162,11 +162,11 @@ namespace ts.codefix {
const memberElements = createClassElementsFromSymbol(node.symbol);
if (initializer.body) {
memberElements.unshift(createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body));
memberElements.unshift(factory.createConstructorDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body));
}
const modifiers = getModifierKindFromSource(precedingNode!, SyntaxKind.ExportKeyword);
const cls = createClassDeclaration(/*decorators*/ undefined, modifiers, node.name,
const cls = factory.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name,
/*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements);
// Don't call copyComments here because we'll already leave them in place
return cls;
@@ -175,11 +175,11 @@ namespace ts.codefix {
function createClassFromFunctionDeclaration(node: FunctionDeclaration): ClassDeclaration {
const memberElements = createClassElementsFromSymbol(ctorSymbol);
if (node.body) {
memberElements.unshift(createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body));
memberElements.unshift(factory.createConstructorDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body));
}
const modifiers = getModifierKindFromSource(node, SyntaxKind.ExportKeyword);
const cls = createClassDeclaration(/*decorators*/ undefined, modifiers, node.name,
const cls = factory.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name,
/*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements);
// Don't call copyComments here because we'll already leave them in place
return cls;
@@ -197,7 +197,7 @@ namespace ts.codefix {
// Note - the choice of the last call signature is arbitrary
if (lastCallSignature && !isFunctionLikeDeclaration(node.parent) && !synthNamesMap.has(symbolIdString)) {
const firstParameter = firstOrUndefined(lastCallSignature.parameters);
const ident = firstParameter && isParameter(firstParameter.valueDeclaration) && tryCast(firstParameter.valueDeclaration.name, isIdentifier) || createOptimisticUniqueName("result");
const ident = firstParameter && isParameter(firstParameter.valueDeclaration) && tryCast(firstParameter.valueDeclaration.name, isIdentifier) || factory.createOptimisticUniqueName("result");
const synthName = getNewNameIfConflict(ident, collidingSymbolMap);
synthNamesMap.set(symbolIdString, synthName);
allVarNames.push({ identifier: synthName.identifier, symbol });
@@ -275,7 +275,7 @@ namespace ts.codefix {
function getNewNameIfConflict(name: Identifier, originalNames: ReadonlyMap<Symbol[]>): SynthIdentifier {
const numVarsSameName = (originalNames.get(name.text) || emptyArray).length;
const numberOfAssignmentsOriginal = 0;
const identifier = numVarsSameName === 0 ? name : createIdentifier(name.text + "_" + numVarsSameName);
const identifier = numVarsSameName === 0 ? name : factory.createIdentifier(name.text + "_" + numVarsSameName);
return createSynthIdentifier(identifier, [], numberOfAssignmentsOriginal);
}
@@ -328,7 +328,7 @@ namespace ts.codefix {
});
}
else {
possibleNameForVarDecl = createSynthIdentifier(createOptimisticUniqueName("result"), prevArgName.types);
possibleNameForVarDecl = createSynthIdentifier(factory.createOptimisticUniqueName("result"), prevArgName.types);
}
possibleNameForVarDecl.numberOfAssignmentsOriginal = 2; // Try block and catch block
@@ -338,12 +338,12 @@ namespace ts.codefix {
}
}
const tryBlock = createBlock(transformExpression(node.expression, transformer, node, possibleNameForVarDecl));
const tryBlock = factory.createBlock(transformExpression(node.expression, transformer, node, possibleNameForVarDecl));
const transformationBody = getTransformationBody(func, possibleNameForVarDecl, argName, node, transformer);
const catchArg = argName ? isSynthIdentifier(argName) ? argName.identifier.text : argName.bindingPattern : "e";
const catchVariableDeclaration = createVariableDeclaration(catchArg);
const catchClause = createCatchClause(catchVariableDeclaration, createBlock(transformationBody));
const catchVariableDeclaration = factory.createVariableDeclaration(catchArg);
const catchClause = factory.createCatchClause(catchVariableDeclaration, factory.createBlock(transformationBody));
/*
In order to avoid an implicit any, we will synthesize a type for the declaration using the unions of the types of both paths (try block and catch block)
@@ -355,13 +355,13 @@ namespace ts.codefix {
const typeArray: Type[] = possibleNameForVarDecl.types;
const unionType = transformer.checker.getUnionType(typeArray, UnionReduction.Subtype);
const unionTypeNode = transformer.isInJSFile ? undefined : transformer.checker.typeToTypeNode(unionType);
const varDecl = [createVariableDeclaration(varDeclIdentifier, unionTypeNode)];
varDeclList = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList(varDecl, NodeFlags.Let));
const varDecl = [factory.createVariableDeclaration(varDeclIdentifier, unionTypeNode)];
varDeclList = factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList(varDecl, NodeFlags.Let));
}
const tryStatement = createTry(tryBlock, catchClause, /*finallyBlock*/ undefined);
const tryStatement = factory.createTry(tryBlock, catchClause, /*finallyBlock*/ undefined);
const destructuredResult = prevArgName && varDeclIdentifier && isSynthBindingPattern(prevArgName)
&& createVariableStatement(/* modifiers */ undefined, createVariableDeclarationList([createVariableDeclaration(getSynthesizedDeepCloneWithRenames(prevArgName.bindingPattern), /* type */ undefined, varDeclIdentifier)], NodeFlags.Const));
&& factory.createVariableStatement(/* modifiers */ undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(getSynthesizedDeepCloneWithRenames(prevArgName.bindingPattern), /* type */ undefined, varDeclIdentifier)], NodeFlags.Const));
return compact([varDeclList, tryStatement, destructuredResult]);
}
@@ -374,7 +374,7 @@ namespace ts.codefix {
}
function createUniqueSynthName(prevArgName: SynthIdentifier): SynthIdentifier {
const renamedPrevArg = createOptimisticUniqueName(prevArgName.identifier.text);
const renamedPrevArg = factory.createOptimisticUniqueName(prevArgName.identifier.text);
return createSynthIdentifier(renamedPrevArg);
}
@@ -391,15 +391,15 @@ namespace ts.codefix {
if (rej) {
const argNameRej = getArgBindingName(rej, transformer);
const tryBlock = createBlock(transformExpression(node.expression, transformer, node, argNameRes).concat(transformationBody));
const tryBlock = factory.createBlock(transformExpression(node.expression, transformer, node, argNameRes).concat(transformationBody));
const transformationBody2 = getTransformationBody(rej, prevArgName, argNameRej, node, transformer);
const catchArg = argNameRej ? isSynthIdentifier(argNameRej) ? argNameRej.identifier.text : argNameRej.bindingPattern : "e";
const catchVariableDeclaration = createVariableDeclaration(catchArg);
const catchClause = createCatchClause(catchVariableDeclaration, createBlock(transformationBody2));
const catchVariableDeclaration = factory.createVariableDeclaration(catchArg);
const catchClause = factory.createCatchClause(catchVariableDeclaration, factory.createBlock(transformationBody2));
return [createTry(tryBlock, catchClause, /* finallyBlock */ undefined)];
return [factory.createTry(tryBlock, catchClause, /* finallyBlock */ undefined)];
}
return transformExpression(node.expression, transformer, node, argNameRes).concat(transformationBody);
@@ -416,28 +416,28 @@ namespace ts.codefix {
// the identifier is empty when the handler (.then()) ignores the argument - In this situation we do not need to save the result of the promise returning call
const originalNodeParent = node.original ? node.original.parent : node.parent;
if (prevArgName && !shouldReturn && (!originalNodeParent || isPropertyAccessExpression(originalNodeParent))) {
return createTransformedStatement(prevArgName, createAwait(node), transformer);
return createTransformedStatement(prevArgName, factory.createAwait(node), transformer);
}
else if (!prevArgName && !shouldReturn && (!originalNodeParent || isPropertyAccessExpression(originalNodeParent))) {
return [createStatement(createAwait(node))];
return [factory.createExpressionStatement(factory.createAwait(node))];
}
return [createReturn(getSynthesizedDeepClone(node))];
return [factory.createReturn(getSynthesizedDeepClone(node))];
}
function createTransformedStatement(prevArgName: SynthBindingName | undefined, rightHandSide: Expression, transformer: Transformer): ReadonlyArray<Statement> {
if (!prevArgName || isEmpty(prevArgName)) {
// if there's no argName to assign to, there still might be side effects
return [createStatement(rightHandSide)];
return [factory.createExpressionStatement(rightHandSide)];
}
if (isSynthIdentifier(prevArgName) && prevArgName.types.length < prevArgName.numberOfAssignmentsOriginal) {
// if the variable has already been declared, we don't need "let" or "const"
return [createStatement(createAssignment(getSynthesizedDeepClone(prevArgName.identifier), rightHandSide))];
return [factory.createExpressionStatement(factory.createAssignment(getSynthesizedDeepClone(prevArgName.identifier), rightHandSide))];
}
return [createVariableStatement(/*modifiers*/ undefined,
(createVariableDeclarationList([createVariableDeclaration(getSynthesizedDeepClone(getNode(prevArgName)), /*type*/ undefined, rightHandSide)], getFlagOfBindingName(prevArgName, transformer.constIdentifiers))))];
return [factory.createVariableStatement(/*modifiers*/ undefined,
(factory.createVariableDeclarationList([factory.createVariableDeclaration(getSynthesizedDeepClone(getNode(prevArgName)), /*type*/ undefined, rightHandSide)], getFlagOfBindingName(prevArgName, transformer.constIdentifiers))))];
}
// should be kept up to date with isFixablePromiseArgument in suggestionDiagnostics.ts
@@ -454,9 +454,9 @@ namespace ts.codefix {
break;
}
const synthCall = createCall(getSynthesizedDeepClone(func as Identifier), /*typeArguments*/ undefined, isSynthIdentifier(argName) ? [argName.identifier] : []);
const synthCall = factory.createCall(getSynthesizedDeepClone(func as Identifier), /*typeArguments*/ undefined, isSynthIdentifier(argName) ? [argName.identifier] : []);
if (shouldReturn) {
return [createReturn(synthCall)];
return [factory.createReturn(synthCall)];
}
const type = transformer.originalTypeMap.get(getNodeId(func).toString()) || transformer.checker.getTypeAtLocation(func);
@@ -467,7 +467,7 @@ namespace ts.codefix {
break;
}
const returnType = callSignatures[0].getReturnType();
const varDeclOrAssignment = createTransformedStatement(prevArgName, createAwait(synthCall), transformer);
const varDeclOrAssignment = createTransformedStatement(prevArgName, factory.createAwait(synthCall), transformer);
if (prevArgName) {
prevArgName.types.push(returnType);
}
@@ -502,7 +502,7 @@ namespace ts.codefix {
seenReturnStatement);
}
else {
const innerRetStmts = isFixablePromiseHandler(funcBody) ? [createReturn(funcBody)] : emptyArray;
const innerRetStmts = isFixablePromiseHandler(funcBody) ? [factory.createReturn(funcBody)] : emptyArray;
const innerCbBody = getInnerTransformationBody(transformer, innerRetStmts, prevArgName);
if (innerCbBody.length > 0) {
@@ -512,7 +512,7 @@ namespace ts.codefix {
const type = transformer.checker.getTypeAtLocation(func);
const returnType = getLastCallSignature(type, transformer.checker)!.getReturnType();
const rightHandSide = getSynthesizedDeepClone(funcBody);
const possiblyAwaitedRightHandSide = !!transformer.checker.getPromisedTypeOfPromise(returnType) ? createAwait(rightHandSide) : rightHandSide;
const possiblyAwaitedRightHandSide = !!transformer.checker.getPromisedTypeOfPromise(returnType) ? factory.createAwait(rightHandSide) : rightHandSide;
if (!shouldReturn) {
const transformedStatement = createTransformedStatement(prevArgName, possiblyAwaitedRightHandSide, transformer);
if (prevArgName) {
@@ -521,7 +521,7 @@ namespace ts.codefix {
return transformedStatement;
}
else {
return [createReturn(possiblyAwaitedRightHandSide)];
return [factory.createReturn(possiblyAwaitedRightHandSide)];
}
}
}
@@ -544,13 +544,13 @@ namespace ts.codefix {
for (const stmt of stmts) {
if (isReturnStatement(stmt)) {
if (stmt.expression) {
const possiblyAwaitedExpression = isPromiseReturningExpression(stmt.expression, transformer.checker) ? createAwait(stmt.expression) : stmt.expression;
const possiblyAwaitedExpression = isPromiseReturningExpression(stmt.expression, transformer.checker) ? factory.createAwait(stmt.expression) : stmt.expression;
if (prevArgName === undefined) {
ret.push(createExpressionStatement(possiblyAwaitedExpression));
ret.push(factory.createExpressionStatement(possiblyAwaitedExpression));
}
else {
ret.push(createVariableStatement(/*modifiers*/ undefined,
(createVariableDeclarationList([createVariableDeclaration(getNode(prevArgName), /*type*/ undefined, possiblyAwaitedExpression)], getFlagOfBindingName(prevArgName, transformer.constIdentifiers)))));
ret.push(factory.createVariableStatement(/*modifiers*/ undefined,
(factory.createVariableDeclarationList([factory.createVariableDeclaration(getNode(prevArgName), /*type*/ undefined, possiblyAwaitedExpression)], getFlagOfBindingName(prevArgName, transformer.constIdentifiers)))));
}
}
}
@@ -561,8 +561,8 @@ namespace ts.codefix {
// if block has no return statement, need to define prevArgName as undefined to prevent undeclared variables
if (!seenReturnStatement && prevArgName !== undefined) {
ret.push(createVariableStatement(/*modifiers*/ undefined,
(createVariableDeclarationList([createVariableDeclaration(getNode(prevArgName), /*type*/ undefined, createIdentifier("undefined"))], getFlagOfBindingName(prevArgName, transformer.constIdentifiers)))));
ret.push(factory.createVariableStatement(/*modifiers*/ undefined,
(factory.createVariableDeclarationList([factory.createVariableDeclaration(getNode(prevArgName), /*type*/ undefined, factory.createIdentifier("undefined"))], getFlagOfBindingName(prevArgName, transformer.constIdentifiers)))));
}
return ret;
+26 -26
View File
@@ -31,7 +31,7 @@ namespace ts.codefix {
break;
case SyntaxKind.CallExpression:
if (isRequireCall(importNode, /*checkArgumentIsStringLiteralLike*/ false)) {
changes.replaceNode(importingFile, importNode, createPropertyAccess(getSynthesizedDeepClone(importNode), "default"));
changes.replaceNode(importingFile, importNode, factory.createPropertyAccess(getSynthesizedDeepClone(importNode), "default"));
}
break;
}
@@ -81,7 +81,7 @@ namespace ts.codefix {
return;
}
const { text } = node.name;
changes.replaceNode(sourceFile, node, createIdentifier(exports.get(text) || text));
changes.replaceNode(sourceFile, node, factory.createIdentifier(exports.get(text) || text));
});
}
@@ -154,7 +154,7 @@ namespace ts.codefix {
}
}
// Move it out to its own variable statement. (This will not be used if `!foundImport`)
return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([decl], declarationList.flags));
return factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([decl], declarationList.flags));
});
if (foundImport) {
// useNonAdjustedEndPosition to ensure we don't eat the newline after the statement.
@@ -171,7 +171,7 @@ namespace ts.codefix {
const tmp = makeUniqueName(propertyName, identifiers);
return [
makeSingleImport(tmp, propertyName, moduleSpecifier, quotePreference),
makeConst(/*modifiers*/ undefined, name, createIdentifier(tmp)),
makeConst(/*modifiers*/ undefined, name, factory.createIdentifier(tmp)),
];
}
case SyntaxKind.Identifier:
@@ -236,7 +236,7 @@ namespace ts.codefix {
case SyntaxKind.PropertyAssignment:
return !isIdentifier(prop.name) ? undefined : convertExportsDotXEquals_replaceNode(prop.name.text, prop.initializer);
case SyntaxKind.MethodDeclaration:
return !isIdentifier(prop.name) ? undefined : functionExpressionToDeclaration(prop.name.text, [createToken(SyntaxKind.ExportKeyword)], prop);
return !isIdentifier(prop.name) ? undefined : functionExpressionToDeclaration(prop.name.text, [factory.createToken(SyntaxKind.ExportKeyword)], prop);
default:
Debug.assertNever(prop);
}
@@ -260,7 +260,7 @@ namespace ts.codefix {
*/
const newNodes = [
makeConst(/*modifiers*/ undefined, rename, assignment.right),
makeExportDeclaration([createExportSpecifier(rename, text)]),
makeExportDeclaration([factory.createExportSpecifier(rename, text)]),
];
changes.replaceNodeWithNodes(sourceFile, assignment.parent, newNodes);
}
@@ -285,14 +285,14 @@ namespace ts.codefix {
return makeExportDeclaration(/*exportClause*/ undefined, moduleSpecifier);
}
function reExportDefault(moduleSpecifier: string): ExportDeclaration {
return makeExportDeclaration([createExportSpecifier(/*propertyName*/ undefined, "default")], moduleSpecifier);
return makeExportDeclaration([factory.createExportSpecifier(/*propertyName*/ undefined, "default")], moduleSpecifier);
}
function convertExportsPropertyAssignment({ left, right, parent }: BinaryExpression & { left: PropertyAccessExpression }, sourceFile: SourceFile, changes: textChanges.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`.
changes.replaceRange(sourceFile, { pos: left.getStart(sourceFile), end: right.getStart(sourceFile) }, createToken(SyntaxKind.ExportKeyword), { suffix: " " });
changes.replaceRange(sourceFile, { pos: left.getStart(sourceFile), end: right.getStart(sourceFile) }, factory.createToken(SyntaxKind.ExportKeyword), { suffix: " " });
if (!right.name) changes.insertName(sourceFile, right, name);
@@ -302,14 +302,14 @@ namespace ts.codefix {
else {
// `exports.f = function g() {}` -> `export const f = function g() {}` -- just replace `exports.` with `export const `
changes.replaceNodeRangeWithNodes(sourceFile, left.expression, findChildOfKind(left, SyntaxKind.DotToken, sourceFile)!,
[createToken(SyntaxKind.ExportKeyword), createToken(SyntaxKind.ConstKeyword)],
[factory.createToken(SyntaxKind.ExportKeyword), factory.createToken(SyntaxKind.ConstKeyword)],
{ joiner: " ", suffix: " " });
}
}
// TODO: GH#22492 this will cause an error if a change has been made inside the body of the node.
function convertExportsDotXEquals_replaceNode(name: string | undefined, exported: Expression): Statement {
const modifiers = [createToken(SyntaxKind.ExportKeyword)];
const modifiers = [factory.createToken(SyntaxKind.ExportKeyword)];
switch (exported.kind) {
case SyntaxKind.FunctionExpression: {
const { name: expressionName } = exported as FunctionExpression;
@@ -331,7 +331,7 @@ namespace ts.codefix {
function exportConst() {
// `exports.x = 0;` --> `export const x = 0;`
return makeConst(modifiers, createIdentifier(name!), exported); // TODO: GH#18217
return makeConst(modifiers, factory.createIdentifier(name!), exported); // TODO: GH#18217
}
}
@@ -368,8 +368,8 @@ namespace ts.codefix {
*/
const tmp = makeUniqueName(moduleSpecifierToValidIdentifier(moduleSpecifier.text, target), identifiers);
return [
makeImport(createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier, quotePreference),
makeConst(/*modifiers*/ undefined, getSynthesizedDeepClone(name), createIdentifier(tmp)),
makeImport(factory.createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier, quotePreference),
makeConst(/*modifiers*/ undefined, getSynthesizedDeepClone(name), factory.createIdentifier(tmp)),
];
}
case SyntaxKind.Identifier:
@@ -405,7 +405,7 @@ namespace ts.codefix {
idName = makeUniqueName(propertyName, identifiers);
namedBindingsNames.set(propertyName, idName);
}
changes.replaceNode(file, parent, createIdentifier(idName));
changes.replaceNode(file, parent, factory.createIdentifier(idName));
}
else {
needDefaultImport = true;
@@ -413,7 +413,7 @@ namespace ts.codefix {
}
const namedBindings = namedBindingsNames.size === 0 ? undefined : arrayFrom(mapIterator(namedBindingsNames.entries(), ([propertyName, idName]) =>
createImportSpecifier(propertyName === idName ? undefined : createIdentifier(propertyName), createIdentifier(idName))));
factory.createImportSpecifier(propertyName === idName ? undefined : factory.createIdentifier(propertyName), factory.createIdentifier(idName))));
if (!namedBindings) {
// If it was unused, ensure that we at least import *something*.
needDefaultImport = true;
@@ -475,7 +475,7 @@ namespace ts.codefix {
// Node helpers
function functionExpressionToDeclaration(name: string | undefined, additionalModifiers: ReadonlyArray<Modifier>, fn: FunctionExpression | ArrowFunction | MethodDeclaration): FunctionDeclaration {
return createFunctionDeclaration(
return factory.createFunctionDeclaration(
getSynthesizedDeepClones(fn.decorators), // TODO: GH#19915 Don't think this is even legal.
concatenate(additionalModifiers, getSynthesizedDeepClones(fn.modifiers)),
getSynthesizedDeepClone(fn.asteriskToken),
@@ -483,11 +483,11 @@ namespace ts.codefix {
getSynthesizedDeepClones(fn.typeParameters),
getSynthesizedDeepClones(fn.parameters),
getSynthesizedDeepClone(fn.type),
syntheticNodeConverters.convertToFunctionBlock(getSynthesizedDeepClone(fn.body!)));
nodeConverters.convertToFunctionBlock(getSynthesizedDeepClone(fn.body!)));
}
function classExpressionToDeclaration(name: string | undefined, additionalModifiers: ReadonlyArray<Modifier>, cls: ClassExpression): ClassDeclaration {
return createClassDeclaration(
return factory.createClassDeclaration(
getSynthesizedDeepClones(cls.decorators), // TODO: GH#19915 Don't think this is even legal.
concatenate(additionalModifiers, getSynthesizedDeepClones(cls.modifiers)),
name,
@@ -498,27 +498,27 @@ namespace ts.codefix {
function makeSingleImport(localName: string, propertyName: string, moduleSpecifier: StringLiteralLike, quotePreference: QuotePreference): ImportDeclaration {
return propertyName === "default"
? makeImport(createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier, quotePreference)
? makeImport(factory.createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier, quotePreference)
: makeImport(/*name*/ undefined, [makeImportSpecifier(propertyName, localName)], moduleSpecifier, quotePreference);
}
function makeImportSpecifier(propertyName: string | undefined, name: string): ImportSpecifier {
return createImportSpecifier(propertyName !== undefined && propertyName !== name ? createIdentifier(propertyName) : undefined, createIdentifier(name));
return factory.createImportSpecifier(propertyName !== undefined && propertyName !== name ? factory.createIdentifier(propertyName) : undefined, factory.createIdentifier(name));
}
function makeConst(modifiers: ReadonlyArray<Modifier> | undefined, name: string | BindingName, init: Expression): VariableStatement {
return createVariableStatement(
return factory.createVariableStatement(
modifiers,
createVariableDeclarationList(
[createVariableDeclaration(name, /*type*/ undefined, init)],
factory.createVariableDeclarationList(
[factory.createVariableDeclaration(name, /*type*/ undefined, init)],
NodeFlags.Const));
}
function makeExportDeclaration(exportSpecifiers: ExportSpecifier[] | undefined, moduleSpecifier?: string): ExportDeclaration {
return createExportDeclaration(
return factory.createExportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
exportSpecifiers && createNamedExports(exportSpecifiers),
moduleSpecifier === undefined ? undefined : createLiteral(moduleSpecifier));
exportSpecifiers && factory.createNamedExports(exportSpecifiers),
moduleSpecifier === undefined ? undefined : factory.createStringLiteral(moduleSpecifier));
}
}
@@ -33,23 +33,23 @@ namespace ts.codefix {
}
function createTypeAliasFromInterface(declaration: FixableDeclaration, type: TypeNode): TypeAliasDeclaration {
return createTypeAliasDeclaration(declaration.decorators, declaration.modifiers, declaration.name, declaration.typeParameters, type);
return factory.createTypeAliasDeclaration(declaration.decorators, declaration.modifiers, declaration.name, declaration.typeParameters, type);
}
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { indexSignature, container }: Info): void {
const members = isInterfaceDeclaration(container) ? container.members : (<TypeLiteralNode>container.type).members;
const otherMembers = members.filter(member => !isIndexSignatureDeclaration(member));
const parameter = first(indexSignature.parameters);
const mappedTypeParameter = createTypeParameterDeclaration(cast(parameter.name, isIdentifier), parameter.type);
const mappedIntersectionType = createMappedTypeNode(
hasReadonlyModifier(indexSignature) ? createModifier(SyntaxKind.ReadonlyKeyword) : undefined,
const mappedTypeParameter = factory.createTypeParameterDeclaration(cast(parameter.name, isIdentifier), parameter.type);
const mappedIntersectionType = factory.createMappedTypeNode(
hasReadonlyModifier(indexSignature) ? factory.createModifier(SyntaxKind.ReadonlyKeyword) : undefined,
mappedTypeParameter,
indexSignature.questionToken,
indexSignature.type);
const intersectionType = createIntersectionTypeNode([
const intersectionType = factory.createIntersectionTypeNode([
...getAllSuperTypeNodes(container),
mappedIntersectionType,
...(otherMembers.length ? [createTypeLiteralNode(otherMembers)] : emptyArray),
...(otherMembers.length ? [factory.createTypeLiteralNode(otherMembers)] : emptyArray),
]);
changes.replaceNode(sourceFile, container, createTypeAliasFromInterface(container, intersectionType));
}
@@ -28,9 +28,9 @@ namespace ts.codefix {
function doChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, qualifiedName: QualifiedName): void {
const rightText = qualifiedName.right.text;
const replacement = createIndexedAccessTypeNode(
createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined),
createLiteralTypeNode(createLiteral(rightText)));
const replacement = factory.createIndexedAccessTypeNode(
factory.createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined),
factory.createLiteralTypeNode(factory.createStringLiteral(rightText)));
changeTracker.replaceNode(sourceFile, qualifiedName, replacement);
}
}
+11 -11
View File
@@ -157,7 +157,7 @@ namespace ts.codefix {
return;
}
const className = classDeclaration.name!.getText();
const staticInitialization = initializePropertyToUndefined(createIdentifier(className), tokenName);
const staticInitialization = initializePropertyToUndefined(factory.createIdentifier(className), tokenName);
changeTracker.insertNodeAfter(declSourceFile, classDeclaration, staticInitialization);
}
else {
@@ -165,13 +165,13 @@ namespace ts.codefix {
if (!classConstructor) {
return;
}
const propertyInitialization = initializePropertyToUndefined(createThis(), tokenName);
const propertyInitialization = initializePropertyToUndefined(factory.createThis(), tokenName);
changeTracker.insertNodeAtConstructorEnd(declSourceFile, classConstructor, propertyInitialization);
}
}
function initializePropertyToUndefined(obj: Expression, propertyName: string) {
return createStatement(createAssignment(createPropertyAccess(obj, propertyName), createIdentifier("undefined")));
return factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccess(obj, propertyName), factory.createIdentifier("undefined")));
}
function getActionsForAddMissingMemberInTypeScriptFile(context: CodeFixContext, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, token: Identifier, makeStatic: boolean): CodeFixAction[] | undefined {
@@ -192,7 +192,7 @@ namespace ts.codefix {
const contextualType = checker.getContextualType(token.parent as Expression);
typeNode = contextualType ? checker.typeToTypeNode(contextualType) : undefined;
}
return typeNode || createKeywordTypeNode(SyntaxKind.AnyKeyword);
return typeNode || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
}
function createAddPropertyDeclarationAction(context: CodeFixContext, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, makeStatic: boolean, tokenName: string, typeNode: TypeNode): CodeFixAction {
@@ -201,9 +201,9 @@ namespace ts.codefix {
}
function addPropertyDeclaration(changeTracker: textChanges.ChangeTracker, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, tokenName: string, typeNode: TypeNode, makeStatic: boolean): void {
const property = createProperty(
const property = factory.createPropertyDeclaration(
/*decorators*/ undefined,
/*modifiers*/ makeStatic ? [createToken(SyntaxKind.StaticKeyword)] : undefined,
/*modifiers*/ makeStatic ? [factory.createToken(SyntaxKind.StaticKeyword)] : undefined,
tokenName,
/*questionToken*/ undefined,
typeNode,
@@ -230,8 +230,8 @@ namespace ts.codefix {
function createAddIndexSignatureAction(context: CodeFixContext, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, tokenName: string, typeNode: TypeNode): CodeFixAction {
// Index signatures cannot have the static modifier.
const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword);
const indexingParameter = createParameter(
const stringTypeNode = factory.createKeywordTypeNode(SyntaxKind.StringKeyword);
const indexingParameter = factory.createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
@@ -239,7 +239,7 @@ namespace ts.codefix {
/*questionToken*/ undefined,
stringTypeNode,
/*initializer*/ undefined);
const indexSignature = createIndexSignature(
const indexSignature = factory.createIndexSignature(
/*decorators*/ undefined,
/*modifiers*/ undefined,
[indexingParameter],
@@ -297,8 +297,8 @@ namespace ts.codefix {
return !!(type && type.flags & TypeFlags.StringLike);
});
const enumMember = createEnumMember(token, hasStringInitializer ? createStringLiteral(token.text) : undefined);
changes.replaceNode(enumDeclaration.getSourceFile(), enumDeclaration, updateEnumDeclaration(
const enumMember = factory.createEnumMember(token, hasStringInitializer ? factory.createStringLiteral(token.text) : undefined);
changes.replaceNode(enumDeclaration.getSourceFile(), enumDeclaration, factory.updateEnumDeclaration(
enumDeclaration,
enumDeclaration.decorators,
enumDeclaration.modifiers,
@@ -16,7 +16,7 @@ namespace ts.codefix {
function addMissingNewOperator(changes: textChanges.ChangeTracker, sourceFile: SourceFile, span: TextSpan): void {
const call = cast(findAncestorMatchingSpan(sourceFile, span), isCallExpression);
const newExpression = createNew(call.expression, call.typeArguments, call.arguments);
const newExpression = factory.createNew(call.expression, call.typeArguments, call.arguments);
changes.replaceNode(sourceFile, call, newExpression);
}
@@ -25,7 +25,7 @@ namespace ts.codefix {
}
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, importType: ImportTypeNode) {
const newTypeNode = updateImportTypeNode(importType, importType.argument, importType.qualifier, importType.typeArguments, /* isTypeOf */ true);
const newTypeNode = factory.updateImportTypeNode(importType, importType.argument, importType.qualifier, importType.typeArguments, /* isTypeOf */ true);
changes.replaceNode(sourceFile, importType, newTypeNode);
}
}
@@ -70,7 +70,7 @@ namespace ts.codefix {
if (returnType) {
const entityName = getEntityNameFromTypeNode(returnType);
if (!entityName || entityName.kind !== SyntaxKind.Identifier || entityName.text !== "Promise") {
changes.replaceNode(sourceFile, returnType, createTypeReferenceNode("Promise", createNodeArray([returnType])));
changes.replaceNode(sourceFile, returnType, factory.createTypeReferenceNode("Promise", createNodeArray([returnType])));
}
}
changes.insertModifierBefore(sourceFile, SyntaxKind.AsyncKeyword, insertBefore);
@@ -22,7 +22,7 @@ namespace ts.codefix {
}
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, ctr: ConstructorDeclaration) {
const superCall = createStatement(createCall(createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray));
const superCall = factory.createExpressionStatement(factory.createCall(factory.createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray));
changes.insertNodeAtConstructorStart(sourceFile, ctr, superCall);
}
}
@@ -26,6 +26,6 @@ namespace ts.codefix {
});
function doChange(changeTracker: textChanges.ChangeTracker, configFile: TsConfigSourceFile) {
setJsonCompilerOptionValue(changeTracker, configFile, "experimentalDecorators", createTrue());
setJsonCompilerOptionValue(changeTracker, configFile, "experimentalDecorators", factory.createTrue());
}
}
@@ -27,7 +27,7 @@ namespace ts.codefix {
}
function doChanges(changes: textChanges.ChangeTracker, sourceFile: SourceFile, extendsToken: Node, heritageClauses: ReadonlyArray<HeritageClause>): void {
changes.replaceNode(sourceFile, extendsToken, createToken(SyntaxKind.ImplementsKeyword));
changes.replaceNode(sourceFile, extendsToken, factory.createToken(SyntaxKind.ImplementsKeyword));
// If there is already an implements clause, replace the implements keyword with a comma.
if (heritageClauses.length === 2 &&
@@ -36,7 +36,7 @@ namespace ts.codefix {
const implementsToken = heritageClauses[1].getFirstToken()!;
const implementsFullStart = implementsToken.getFullStart();
changes.replaceRange(sourceFile, { pos: implementsFullStart, end: implementsFullStart }, createToken(SyntaxKind.CommaToken));
changes.replaceRange(sourceFile, { pos: implementsFullStart, end: implementsFullStart }, factory.createToken(SyntaxKind.CommaToken));
// Rough heuristic: delete trailing whitespace after keyword so that it's not excessive.
// (Trailing because leading might be indentation, which is more sensitive.)
@@ -34,6 +34,6 @@ namespace ts.codefix {
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { node, className }: Info): void {
// TODO (https://github.com/Microsoft/TypeScript/issues/21246): use shared helper
suppressLeadingAndTrailingTrivia(node);
changes.replaceNode(sourceFile, node, createPropertyAccess(className ? createIdentifier(className) : createThis(), node));
changes.replaceNode(sourceFile, node, factory.createPropertyAccess(className ? factory.createIdentifier(className) : factory.createThis(), node));
}
}
@@ -13,11 +13,11 @@ namespace ts.codefix {
if (getEmitModuleKind(opts) === ModuleKind.CommonJS) {
// import Bluebird = require("bluebird");
variations.push(createAction(context, sourceFile, node, createImportEqualsDeclaration(
variations.push(createAction(context, sourceFile, node, factory.createImportEqualsDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
namespace.name,
createExternalModuleReference(node.moduleSpecifier)
factory.createExternalModuleReference(node.moduleSpecifier)
)));
}
@@ -88,7 +88,7 @@ namespace ts.codefix {
}
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, createPropertyAccess(expr, "default"), {}));
const changes = textChanges.ChangeTracker.with(context, t => t.replaceNode(sourceFile, expr, factory.createPropertyAccess(expr, "default"), {}));
fixes.push(createCodeFixActionNoFixId(fixName, changes, Diagnostics.Use_synthetic_default_member));
}
return fixes;
+2 -2
View File
@@ -60,10 +60,10 @@ namespace ts.codefix {
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, node: Node, suggestion: string, target: ScriptTarget) {
if (!isIdentifierText(suggestion, target) && isPropertyAccessExpression(node.parent)) {
changes.replaceNode(sourceFile, node.parent, createElementAccess(node.parent.expression, createLiteral(suggestion)));
changes.replaceNode(sourceFile, node.parent, factory.createElementAccess(node.parent.expression, factory.createStringLiteral(suggestion)));
}
else {
changes.replaceNode(sourceFile, node, createIdentifier(suggestion));
changes.replaceNode(sourceFile, node, factory.createIdentifier(suggestion));
}
}
@@ -58,12 +58,12 @@ namespace ts.codefix {
}
function addDefiniteAssignmentAssertion(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration): void {
const property = updateProperty(
const property = factory.updatePropertyDeclaration(
propertyDeclaration,
propertyDeclaration.decorators,
propertyDeclaration.modifiers,
propertyDeclaration.name,
createToken(SyntaxKind.ExclamationToken),
factory.createToken(SyntaxKind.ExclamationToken),
propertyDeclaration.type,
propertyDeclaration.initializer
);
@@ -76,10 +76,10 @@ namespace ts.codefix {
}
function addUndefinedType(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration): void {
const undefinedTypeNode = createKeywordTypeNode(SyntaxKind.UndefinedKeyword);
const undefinedTypeNode = factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword);
const type = propertyDeclaration.type!; // TODO: GH#18217
const types = isUnionTypeNode(type) ? type.types.concat(undefinedTypeNode) : [type, undefinedTypeNode];
changeTracker.replaceNode(propertyDeclarationSourceFile, type, createUnionTypeNode(types));
changeTracker.replaceNode(propertyDeclarationSourceFile, type, factory.createUnionTypeNode(types));
}
function getActionForAddMissingInitializer(context: CodeFixContext, propertyDeclaration: PropertyDeclaration): CodeFixAction | undefined {
@@ -92,7 +92,7 @@ namespace ts.codefix {
}
function addInitializer (changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration, initializer: Expression): void {
const property = updateProperty(
const property = factory.updatePropertyDeclaration(
propertyDeclaration,
propertyDeclaration.decorators,
propertyDeclaration.modifiers,
@@ -110,10 +110,16 @@ namespace ts.codefix {
function getDefaultValueFromType (checker: TypeChecker, type: Type): Expression | undefined {
if (type.flags & TypeFlags.BooleanLiteral) {
return (type === checker.getFalseType() || type === checker.getFalseType(/*fresh*/ true)) ? createFalse() : createTrue();
return (type === checker.getFalseType() || type === checker.getFalseType(/*fresh*/ true)) ? factory.createFalse() : factory.createTrue();
}
else if (type.isLiteral()) {
return createLiteral(type.value);
else if (type.isStringLiteral()) {
return factory.createStringLiteral(type.value);
}
else if (type.isNumberLiteral()) {
return factory.createNumericLiteral(type.value);
}
else if (type.flags & TypeFlags.BigIntLiteral) {
return factory.createBigIntLiteral((type as BigIntLiteralType).value);
}
else if (type.isUnion()) {
return firstDefined(type.types, t => getDefaultValueFromType(checker, t));
@@ -125,10 +131,10 @@ namespace ts.codefix {
const constructorDeclaration = getFirstConstructorWithBody(classDeclaration);
if (constructorDeclaration && constructorDeclaration.parameters.length) return undefined;
return createNew(createIdentifier(type.symbol.name), /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
return factory.createNew(factory.createIdentifier(type.symbol.name), /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
}
else if (checker.isArrayLikeType(type)) {
return createArrayLiteral();
return factory.createArrayLiteral();
}
return undefined;
}
+1 -1
View File
@@ -26,7 +26,7 @@ namespace ts.codefix {
break;
}
else {
changes.replaceNode(sourceFile, statement, createBlock(emptyArray));
changes.replaceNode(sourceFile, statement, factory.createBlock(emptyArray));
}
return;
}
@@ -109,7 +109,7 @@ namespace ts.codefix {
});
function changeInferToUnknown(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node): void {
changes.replaceNode(sourceFile, token.parent, createKeywordTypeNode(SyntaxKind.UnknownKeyword));
changes.replaceNode(sourceFile, token.parent, factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword));
}
function createDeleteFix(changes: FileTextChanges[], diag: DiagnosticAndArguments): CodeFixAction {
@@ -153,7 +153,7 @@ namespace ts.codefix {
token = cast(token.parent, isInferTypeNode).typeParameter.name;
}
if (isIdentifier(token) && canPrefix(token)) {
changes.replaceNode(sourceFile, token, createIdentifier(`_${token.text}`));
changes.replaceNode(sourceFile, token, factory.createIdentifier(`_${token.text}`));
}
}
+28 -28
View File
@@ -61,11 +61,11 @@ namespace ts.codefix {
case SyntaxKind.PropertySignature:
case SyntaxKind.PropertyDeclaration:
const typeNode = checker.typeToTypeNode(type, enclosingDeclaration, /*flags*/ undefined, getNoopSymbolTrackerWithResolver(context));
out(createProperty(
/*decorators*/undefined,
out(factory.createPropertyDeclaration(
/*decorators*/ undefined,
modifiers,
name,
optional ? createToken(SyntaxKind.QuestionToken) : undefined,
optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined,
typeNode,
/*initializer*/ undefined));
break;
@@ -78,7 +78,7 @@ namespace ts.codefix {
: [allAccessors.firstAccessor];
for (const accessor of orderedAccessors) {
if (isGetAccessorDeclaration(accessor)) {
out(createGetAccessor(
out(factory.createGetAccessorDeclaration(
/*decorators*/ undefined,
modifiers,
name,
@@ -90,7 +90,7 @@ namespace ts.codefix {
Debug.assertNode(accessor, isSetAccessorDeclaration);
const parameter = getSetAccessorValueParameter(accessor);
const parameterName = parameter && isIdentifier(parameter.name) ? idText(parameter.name) : undefined;
out(createSetAccessor(
out(factory.createSetAccessorDeclaration(
/*decorators*/ undefined,
modifiers,
name,
@@ -163,7 +163,7 @@ namespace ts.codefix {
signatureDeclaration.decorators = undefined;
signatureDeclaration.modifiers = modifiers;
signatureDeclaration.name = name;
signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined;
signatureDeclaration.questionToken = optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined;
signatureDeclaration.body = body;
return signatureDeclaration;
}
@@ -189,14 +189,14 @@ namespace ts.codefix {
isPropertyAccessExpression(arg) ? arg.name.text : undefined);
const contextualType = checker.getContextualType(call);
const returnType = (inJs || !contextualType) ? undefined : checker.typeToTypeNode(contextualType, contextNode, /*flags*/ undefined, tracker);
return createMethod(
return factory.createMethodDeclaration(
/*decorators*/ undefined,
/*modifiers*/ makeStatic ? [createToken(SyntaxKind.StaticKeyword)] : undefined,
/*asteriskToken*/ isYieldExpression(parent) ? createToken(SyntaxKind.AsteriskToken) : undefined,
/*modifiers*/ makeStatic ? [factory.createToken(SyntaxKind.StaticKeyword)] : undefined,
/*asteriskToken*/ isYieldExpression(parent) ? factory.createToken(SyntaxKind.AsteriskToken) : undefined,
methodName,
/*questionToken*/ undefined,
/*typeParameters*/ inJs ? undefined : map(typeArguments, (_, i) =>
createTypeParameterDeclaration(CharacterCodes.T + typeArguments!.length - 1 <= CharacterCodes.Z ? String.fromCharCode(CharacterCodes.T + i) : `T${i}`)),
factory.createTypeParameterDeclaration(CharacterCodes.T + typeArguments!.length - 1 <= CharacterCodes.Z ? String.fromCharCode(CharacterCodes.T + i) : `T${i}`)),
/*parameters*/ createDummyParameters(args.length, names, types, /*minArgumentCount*/ undefined, inJs),
/*type*/ returnType,
body ? createStubbedMethodBody(preferences) : undefined);
@@ -205,13 +205,13 @@ namespace ts.codefix {
function createDummyParameters(argCount: number, names: (string | undefined)[] | undefined, types: (TypeNode | undefined)[] | undefined, minArgumentCount: number | undefined, inJs: boolean): ParameterDeclaration[] {
const parameters: ParameterDeclaration[] = [];
for (let i = 0; i < argCount; i++) {
const newParameter = createParameter(
const newParameter = factory.createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
/*name*/ names && names[i] || `arg${i}`,
/*questionToken*/ minArgumentCount !== undefined && i >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined,
/*type*/ inJs ? undefined : types && types[i] || createKeywordTypeNode(SyntaxKind.AnyKeyword),
/*questionToken*/ minArgumentCount !== undefined && i >= minArgumentCount ? factory.createToken(SyntaxKind.QuestionToken) : undefined,
/*type*/ inJs ? undefined : types && types[i] || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword),
/*initializer*/ undefined);
parameters.push(newParameter);
}
@@ -247,13 +247,13 @@ namespace ts.codefix {
const parameters = createDummyParameters(maxNonRestArgs, maxArgsParameterSymbolNames, /* types */ undefined, minArgumentCount, /*inJs*/ false);
if (someSigHasRestParameter) {
const anyArrayType = createArrayTypeNode(createKeywordTypeNode(SyntaxKind.AnyKeyword));
const restParameter = createParameter(
const anyArrayType = factory.createArrayTypeNode(factory.createKeywordTypeNode(SyntaxKind.AnyKeyword));
const restParameter = factory.createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createToken(SyntaxKind.DotDotDotToken),
factory.createToken(SyntaxKind.DotDotDotToken),
maxArgsParameterSymbolNames[maxNonRestArgs] || "rest",
/*questionToken*/ maxNonRestArgs >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined,
/*questionToken*/ maxNonRestArgs >= minArgumentCount ? factory.createToken(SyntaxKind.QuestionToken) : undefined,
anyArrayType,
/*initializer*/ undefined);
parameters.push(restParameter);
@@ -278,12 +278,12 @@ namespace ts.codefix {
returnType: TypeNode | undefined,
preferences: UserPreferences
): MethodDeclaration {
return createMethod(
return factory.createMethodDeclaration(
/*decorators*/ undefined,
modifiers,
/*asteriskToken*/ undefined,
name,
optional ? createToken(SyntaxKind.QuestionToken) : undefined,
optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined,
typeParameters,
parameters,
returnType,
@@ -291,22 +291,22 @@ namespace ts.codefix {
}
function createStubbedMethodBody(preferences: UserPreferences): Block {
return createBlock(
[createThrow(
createNew(
createIdentifier("Error"),
return factory.createBlock(
[factory.createThrow(
factory.createNew(
factory.createIdentifier("Error"),
/*typeArguments*/ undefined,
// TODO Handle auto quote preference.
[createLiteral("Method not implemented.", /*isSingleQuote*/ preferences.quotePreference === "single")]))],
[factory.createStringLiteral("Method not implemented.", /*isSingleQuote*/ preferences.quotePreference === "single")]))],
/*multiline*/ true);
}
function createVisibilityModifier(flags: ModifierFlags): Modifier | undefined {
if (flags & ModifierFlags.Public) {
return createToken(SyntaxKind.PublicKeyword);
return factory.createToken(SyntaxKind.PublicKeyword);
}
else if (flags & ModifierFlags.Protected) {
return createToken(SyntaxKind.ProtectedKeyword);
return factory.createToken(SyntaxKind.ProtectedKeyword);
}
return undefined;
}
@@ -324,7 +324,7 @@ namespace ts.codefix {
if (compilerOptionsProperty === undefined) {
changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment(
"compilerOptions",
createObjectLiteral([
factory.createObjectLiteral([
createJsonPropertyAssignment(optionName, optionValue),
])));
return;
@@ -346,7 +346,7 @@ namespace ts.codefix {
}
export function createJsonPropertyAssignment(name: string, initializer: Expression) {
return createPropertyAssignment(createStringLiteral(name), initializer);
return factory.createPropertyAssignment(factory.createStringLiteral(name), initializer);
}
export function findJsonProperty(obj: ObjectLiteralExpression, name: string): PropertyAssignment | undefined {
+11 -11
View File
@@ -528,11 +528,11 @@ namespace ts.codefix {
function doAddExistingFix(changes: textChanges.ChangeTracker, sourceFile: SourceFile, clause: ImportClause, defaultImport: string | undefined, namedImports: ReadonlyArray<string>): void {
if (defaultImport) {
Debug.assert(!clause.name);
changes.insertNodeAt(sourceFile, clause.getStart(sourceFile), createIdentifier(defaultImport), { suffix: ", " });
changes.insertNodeAt(sourceFile, clause.getStart(sourceFile), factory.createIdentifier(defaultImport), { suffix: ", " });
}
if (namedImports.length) {
const specifiers = namedImports.map(name => createImportSpecifier(/*propertyName*/ undefined, createIdentifier(name)));
const specifiers = namedImports.map(name => factory.createImportSpecifier(/*propertyName*/ undefined, factory.createIdentifier(name)));
if (clause.namedBindings && cast(clause.namedBindings, isNamedImports).elements.length) {
for (const spec of specifiers) {
changes.insertNodeInListAfter(sourceFile, last(cast(clause.namedBindings, isNamedImports).elements), spec);
@@ -540,7 +540,7 @@ namespace ts.codefix {
}
else {
if (specifiers.length) {
const namedImports = createNamedImports(specifiers);
const namedImports = factory.createNamedImports(specifiers);
if (clause.namedBindings) {
changes.replaceNode(sourceFile, clause.namedBindings, namedImports);
}
@@ -578,25 +578,25 @@ namespace ts.codefix {
if (defaultImport !== undefined || namedImports.length) {
insertImport(changes, sourceFile,
makeImport(
defaultImport === undefined ? undefined : createIdentifier(defaultImport),
namedImports.map(n => createImportSpecifier(/*propertyName*/ undefined, createIdentifier(n))), moduleSpecifier, quotePreference));
defaultImport === undefined ? undefined : factory.createIdentifier(defaultImport),
namedImports.map(n => factory.createImportSpecifier(/*propertyName*/ undefined, factory.createIdentifier(n))), moduleSpecifier, quotePreference));
}
if (namespaceLikeImport) {
insertImport(
changes,
sourceFile,
namespaceLikeImport.importKind === ImportKind.Equals ? createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createIdentifier(namespaceLikeImport.name), createExternalModuleReference(quotedModuleSpecifier)) :
namespaceLikeImport.importKind === ImportKind.Equals ? factory.createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createIdentifier(namespaceLikeImport.name), factory.createExternalModuleReference(quotedModuleSpecifier)) :
namespaceLikeImport.importKind === ImportKind.ConstEquals ? createConstEqualsRequireDeclaration(namespaceLikeImport.name, quotedModuleSpecifier) :
createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createImportClause(/*name*/ undefined, createNamespaceImport(createIdentifier(namespaceLikeImport.name))), quotedModuleSpecifier));
factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createImportClause(/*name*/ undefined, factory.createNamespaceImport(factory.createIdentifier(namespaceLikeImport.name))), quotedModuleSpecifier));
}
}
function createConstEqualsRequireDeclaration(name: string, quotedModuleSpecifier: StringLiteral): VariableStatement {
return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([
createVariableDeclaration(
createIdentifier(name),
return factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([
factory.createVariableDeclaration(
factory.createIdentifier(name),
/*type*/ undefined,
createCall(createIdentifier("require"), /*typeArguments*/ undefined, [quotedModuleSpecifier])
factory.createCall(factory.createIdentifier("require"), /*typeArguments*/ undefined, [quotedModuleSpecifier])
)
], NodeFlags.Const));
}
+10 -10
View File
@@ -126,7 +126,7 @@ namespace ts.codefix {
const typeNode = getTypeNodeIfAccessible(type, parent, program, host);
if (typeNode) {
// Note that the codefix will never fire with an existing `@type` tag, so there is no need to merge tags
const typeTag = createJSDocTypeTag(/*tagName*/ undefined, createJSDocTypeExpression(typeNode), /*comment*/ "");
const typeTag = factory.createJSDocTypeTag(/*tagName*/ undefined, factory.createJSDocTypeExpression(typeNode), /*comment*/ "");
addJSDocTags(changes, sourceFile, cast(parent.parent.parent, isExpressionStatement), [typeTag]);
}
return parent;
@@ -218,13 +218,13 @@ namespace ts.codefix {
}
else {
const needParens = isArrowFunction(containingFunction) && !findChildOfKind(containingFunction, SyntaxKind.OpenParenToken, sourceFile);
if (needParens) changes.insertNodeBefore(sourceFile, first(containingFunction.parameters), createToken(SyntaxKind.OpenParenToken));
if (needParens) changes.insertNodeBefore(sourceFile, first(containingFunction.parameters), factory.createToken(SyntaxKind.OpenParenToken));
for (const { declaration, type } of parameterInferences) {
if (declaration && !declaration.type && !declaration.initializer) {
annotate(changes, sourceFile, declaration, type, program, host);
}
}
if (needParens) changes.insertNodeAfter(sourceFile, last(containingFunction.parameters), createToken(SyntaxKind.CloseParenToken));
if (needParens) changes.insertNodeAfter(sourceFile, last(containingFunction.parameters), factory.createToken(SyntaxKind.CloseParenToken));
}
}
@@ -254,7 +254,7 @@ namespace ts.codefix {
function annotateJSDocThis(changes: textChanges.ChangeTracker, sourceFile: SourceFile, containingFunction: FunctionLike, typeNode: TypeNode) {
addJSDocTags(changes, sourceFile, containingFunction, [
createJSDocThisTag(/*tagName*/ undefined, createJSDocTypeExpression(typeNode)),
factory.createJSDocThisTag(/*tagName*/ undefined, factory.createJSDocTypeExpression(typeNode)),
]);
}
@@ -282,8 +282,8 @@ namespace ts.codefix {
if (!parent) {
return;
}
const typeExpression = createJSDocTypeExpression(typeNode);
const typeTag = isGetAccessorDeclaration(declaration) ? createJSDocReturnTag(/*tagName*/ undefined, typeExpression, "") : createJSDocTypeTag(/*tagName*/ undefined, typeExpression, "");
const typeExpression = factory.createJSDocTypeExpression(typeNode);
const typeTag = isGetAccessorDeclaration(declaration) ? factory.createJSDocReturnTag(/*tagName*/ undefined, typeExpression, "") : factory.createJSDocTypeTag(/*tagName*/ undefined, typeExpression, "");
addJSDocTags(changes, sourceFile, parent, [typeTag]);
}
else {
@@ -305,7 +305,7 @@ namespace ts.codefix {
const typeNode = inference.type && getTypeNodeIfAccessible(inference.type, param, program, host);
const name = getSynthesizedClone(param.name);
setEmitFlags(name, EmitFlags.NoComments | EmitFlags.NoNestedComments);
return typeNode && syntheticNodeFactory.createJSDocParameterTag(/*tagName*/ undefined, name, !!inference.isOptional, createJSDocTypeExpression(typeNode), /*isNameFirst*/ undefined, "");
return typeNode && factory.createJSDocParameterTag(/*tagName*/ undefined, name, !!inference.isOptional, factory.createJSDocTypeExpression(typeNode), /*isNameFirst*/ undefined, "");
});
addJSDocTags(changes, sourceFile, signature, paramTags);
}
@@ -318,7 +318,7 @@ namespace ts.codefix {
if (merged) oldTags[i] = merged;
return !!merged;
}));
const tag = createJSDocComment(comments.join("\n"), createNodeArray([...(oldTags || emptyArray), ...unmergedNewTags]));
const tag = factory.createJSDocComment(comments.join("\n"), createNodeArray([...(oldTags || emptyArray), ...unmergedNewTags]));
const jsDocNode = parent.kind === SyntaxKind.ArrowFunction ? getJsDocNodeForArrowFunction(parent) : parent;
jsDocNode.jsDoc = parent.jsDoc;
jsDocNode.jsDocCache = parent.jsDocCache;
@@ -341,11 +341,11 @@ namespace ts.codefix {
const oldParam = oldTag as JSDocParameterTag;
const newParam = newTag as JSDocParameterTag;
return isIdentifier(oldParam.name) && isIdentifier(newParam.name) && oldParam.name.escapedText === newParam.name.escapedText
? syntheticNodeFactory.createJSDocParameterTag(/*tagName*/ undefined, newParam.name, newParam.isBracketed, newParam.typeExpression, /*isNameFirst*/ undefined, oldParam.comment)
? factory.createJSDocParameterTag(/*tagName*/ undefined, newParam.name, newParam.isBracketed, newParam.typeExpression, /*isNameFirst*/ undefined, oldParam.comment)
: undefined;
}
case SyntaxKind.JSDocReturnTag:
return createJSDocReturnTag(/*tagName*/ undefined, (newTag as JSDocReturnTag).typeExpression, oldTag.comment);
return factory.createJSDocReturnTag(/*tagName*/ undefined, (newTag as JSDocReturnTag).typeExpression, oldTag.comment);
}
}
+2 -2
View File
@@ -15,8 +15,8 @@ namespace ts.codefix {
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, program: Program) {
const { statement, name, required } = getInfo(sourceFile, pos);
changes.replaceNode(sourceFile, statement, getAllowSyntheticDefaultImports(program.getCompilerOptions())
? createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createImportClause(name, /*namedBindings*/ undefined), required)
: createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, name, createExternalModuleReference(required)));
? factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createImportClause(name, /*namedBindings*/ undefined), required)
: factory.createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, name, factory.createExternalModuleReference(required)));
}
interface Info { readonly statement: VariableStatement; readonly name: Identifier; readonly required: StringLiteralLike; }
+1 -1
View File
@@ -65,7 +65,7 @@ namespace ts {
// If there isn't some include for this, add a new one.
if (getRegexFromPattern(Debug.assertDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(oldFileOrDirPath) &&
!getRegexFromPattern(Debug.assertDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(newFileOrDirPath)) {
changeTracker.insertNodeAfter(configFile, last(property.initializer.elements), createStringLiteral(relativePath(newFileOrDirPath)));
changeTracker.insertNodeAfter(configFile, last(property.initializer.elements), factory.createStringLiteral(relativePath(newFileOrDirPath)));
}
}
break;
+10 -10
View File
@@ -116,7 +116,7 @@ namespace ts.OrganizeImports {
const newElements = namedBindings.elements.filter(e => isDeclarationUsed(e.name));
if (newElements.length < namedBindings.elements.length) {
namedBindings = newElements.length
? updateNamedImports(namedBindings, newElements)
? factory.updateNamedImports(namedBindings, newElements)
: undefined;
}
}
@@ -129,7 +129,7 @@ namespace ts.OrganizeImports {
else if (hasModuleDeclarationMatchingSpecifier(sourceFile, moduleSpecifier)) {
// If were in a declaration file, its safe to remove the import clause from it
if (sourceFile.isDeclarationFile) {
usedImports.push(createImportDeclaration(
usedImports.push(factory.createImportDeclaration(
importDecl.decorators,
importDecl.modifiers,
/*importClause*/ undefined,
@@ -214,7 +214,7 @@ namespace ts.OrganizeImports {
else {
for (const defaultImport of defaultImports) {
newImportSpecifiers.push(
createImportSpecifier(createIdentifier("default"), defaultImport.importClause!.name!)); // TODO: GH#18217
factory.createImportSpecifier(factory.createIdentifier("default"), defaultImport.importClause!.name!)); // TODO: GH#18217
}
}
@@ -229,10 +229,10 @@ namespace ts.OrganizeImports {
const newNamedImports = sortedImportSpecifiers.length === 0
? newDefaultImport
? undefined
: createNamedImports(emptyArray)
: factory.createNamedImports(emptyArray)
: namedImports.length === 0
? createNamedImports(sortedImportSpecifiers)
: updateNamedImports(namedImports[0].importClause!.namedBindings as NamedImports, sortedImportSpecifiers); // TODO: GH#18217
? factory.createNamedImports(sortedImportSpecifiers)
: factory.updateNamedImports(namedImports[0].importClause!.namedBindings as NamedImports, sortedImportSpecifiers); // TODO: GH#18217
coalescedImports.push(
updateImportDeclarationAndClause(importDecl, newDefaultImport, newNamedImports));
@@ -313,11 +313,11 @@ namespace ts.OrganizeImports {
const exportDecl = namedExports[0];
coalescedExports.push(
updateExportDeclaration(
factory.updateExportDeclaration(
exportDecl,
exportDecl.decorators,
exportDecl.modifiers,
updateNamedExports(exportDecl.exportClause!, sortedExportSpecifiers),
factory.updateNamedExports(exportDecl.exportClause!, sortedExportSpecifiers),
exportDecl.moduleSpecifier));
return coalescedExports;
@@ -354,11 +354,11 @@ namespace ts.OrganizeImports {
name: Identifier | undefined,
namedBindings: NamedImportBindings | undefined) {
return updateImportDeclaration(
return factory.updateImportDeclaration(
importDeclaration,
importDeclaration.decorators,
importDeclaration.modifiers,
updateImportClause(importDeclaration.importClause!, name, namedBindings), // TODO: GH#18217
factory.updateImportClause(importDeclaration.importClause!, name, namedBindings), // TODO: GH#18217
importDeclaration.moduleSpecifier);
}
@@ -45,14 +45,14 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction {
let body: ConciseBody;
if (actionName === addBracesActionName) {
const returnStatement = createReturn(expression);
body = createBlock([returnStatement], /* multiLine */ true);
const returnStatement = factory.createReturn(expression);
body = factory.createBlock([returnStatement], /* multiLine */ true);
suppressLeadingAndTrailingTrivia(body);
copyLeadingComments(expression!, returnStatement, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ true);
}
else if (actionName === removeBracesActionName && returnStatement) {
const actualExpression = expression || createVoidZero();
body = needsParentheses(actualExpression) ? createParen(actualExpression) : actualExpression;
const actualExpression = expression || factory.createVoidZero();
body = needsParentheses(actualExpression) ? factory.createParen(actualExpression) : actualExpression;
suppressLeadingAndTrailingTrivia(body);
copyLeadingComments(returnStatement, body, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false);
}
+9 -9
View File
@@ -86,13 +86,13 @@ namespace ts.refactor {
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
changes.insertNodeAfter(exportingSourceFile, exportKeyword, createToken(SyntaxKind.DefaultKeyword));
changes.insertNodeAfter(exportingSourceFile, exportKeyword, factory.createToken(SyntaxKind.DefaultKeyword));
break;
case SyntaxKind.VariableStatement:
// If 'x' isn't used in this file, `export const x = 0;` --> `export default 0;`
if (!FindAllReferences.Core.isSymbolReferencedInFile(exportName, checker, exportingSourceFile)) {
// We checked in `getInfo` that an initializer exists.
changes.replaceNode(exportingSourceFile, exportNode, createExportDefault(Debug.assertDefined(first(exportNode.declarationList.declarations).initializer)));
changes.replaceNode(exportingSourceFile, exportNode, factory.createExportDefault(Debug.assertDefined(first(exportNode.declarationList.declarations).initializer)));
break;
}
// falls through
@@ -101,7 +101,7 @@ namespace ts.refactor {
case SyntaxKind.ModuleDeclaration:
// `export type T = number;` -> `type T = number; export default T;`
changes.deleteModifier(exportingSourceFile, exportKeyword);
changes.insertNodeAfter(exportingSourceFile, exportNode, createExportDefault(createIdentifier(exportName.text)));
changes.insertNodeAfter(exportingSourceFile, exportNode, factory.createExportDefault(factory.createIdentifier(exportName.text)));
break;
default:
Debug.assertNever(exportNode);
@@ -128,7 +128,7 @@ namespace ts.refactor {
switch (parent.kind) {
case SyntaxKind.PropertyAccessExpression:
// `a.default` --> `a.foo`
changes.replaceNode(importingSourceFile, ref, createIdentifier(exportName));
changes.replaceNode(importingSourceFile, ref, factory.createIdentifier(exportName));
break;
case SyntaxKind.ImportSpecifier:
case SyntaxKind.ExportSpecifier: {
@@ -144,7 +144,7 @@ namespace ts.refactor {
const { namedBindings } = clause;
if (!namedBindings) {
// `import foo from "./a";` --> `import { foo } from "./a";`
changes.replaceNode(importingSourceFile, ref, createNamedImports([spec]));
changes.replaceNode(importingSourceFile, ref, factory.createNamedImports([spec]));
}
else if (namedBindings.kind === SyntaxKind.NamespaceImport) {
// `import foo, * as a from "./a";` --> `import * as a from ".a/"; import { foo } from "./a";`
@@ -170,12 +170,12 @@ namespace ts.refactor {
switch (parent.kind) {
case SyntaxKind.PropertyAccessExpression:
// `a.foo` --> `a.default`
changes.replaceNode(importingSourceFile, ref, createIdentifier("default"));
changes.replaceNode(importingSourceFile, ref, factory.createIdentifier("default"));
break;
case SyntaxKind.ImportSpecifier: {
// `import { foo } from "./a";` --> `import foo from "./a";`
// `import { foo as bar } from "./a";` --> `import bar from "./a";`
const defaultImport = createIdentifier(parent.name.text);
const defaultImport = factory.createIdentifier(parent.name.text);
if (parent.parent.elements.length === 1) {
changes.replaceNode(importingSourceFile, parent.parent, defaultImport);
}
@@ -200,10 +200,10 @@ namespace ts.refactor {
}
function makeImportSpecifier(propertyName: string, name: string): ImportSpecifier {
return createImportSpecifier(propertyName === name ? undefined : createIdentifier(propertyName), createIdentifier(name));
return factory.createImportSpecifier(propertyName === name ? undefined : factory.createIdentifier(propertyName), factory.createIdentifier(name));
}
function makeExportSpecifier(propertyName: string, name: string): ExportSpecifier {
return createExportSpecifier(propertyName === name ? undefined : createIdentifier(propertyName), createIdentifier(name));
return factory.createExportSpecifier(propertyName === name ? undefined : factory.createIdentifier(propertyName), factory.createIdentifier(name));
}
}
+9 -9
View File
@@ -69,12 +69,12 @@ namespace ts.refactor {
if (importName === undefined) {
exportNameToImportName.set(exportName, importName = conflictingNames.has(exportName) ? getUniqueName(exportName, sourceFile) : exportName);
}
changes.replaceNode(sourceFile, propertyAccess, createIdentifier(importName));
changes.replaceNode(sourceFile, propertyAccess, factory.createIdentifier(importName));
}
const importSpecifiers: ImportSpecifier[] = [];
exportNameToImportName.forEach((name, propertyName) => {
importSpecifiers.push(createImportSpecifier(name === propertyName ? undefined : createIdentifier(propertyName), createIdentifier(name)));
importSpecifiers.push(factory.createImportSpecifier(name === propertyName ? undefined : factory.createIdentifier(propertyName), factory.createIdentifier(name)));
});
const importDecl = toConvert.parent.parent;
@@ -83,7 +83,7 @@ namespace ts.refactor {
changes.insertNodeAfter(sourceFile, importDecl, updateImport(importDecl, /*defaultImportName*/ undefined, importSpecifiers));
}
else {
changes.replaceNode(sourceFile, importDecl, updateImport(importDecl, usedAsNamespaceOrDefault ? createIdentifier(toConvert.name.text) : undefined, importSpecifiers));
changes.replaceNode(sourceFile, importDecl, updateImport(importDecl, usedAsNamespaceOrDefault ? factory.createIdentifier(toConvert.name.text) : undefined, importSpecifiers));
}
}
@@ -102,13 +102,13 @@ namespace ts.refactor {
for (const element of toConvert.elements) {
const propertyName = (element.propertyName || element.name).text;
FindAllReferences.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, id => {
const access = createPropertyAccess(createIdentifier(namespaceImportName), propertyName);
const access = factory.createPropertyAccess(factory.createIdentifier(namespaceImportName), propertyName);
if (isShorthandPropertyAssignment(id.parent)) {
changes.replaceNode(sourceFile, id.parent, createPropertyAssignment(id.text, access));
changes.replaceNode(sourceFile, id.parent, factory.createPropertyAssignment(id.text, access));
}
else if (isExportSpecifier(id.parent) && !id.parent.propertyName) {
if (!neededNamedImports.some(n => n.name === element.name)) {
neededNamedImports.push(createImportSpecifier(element.propertyName && createIdentifier(element.propertyName.text), createIdentifier(element.name.text)));
neededNamedImports.push(factory.createImportSpecifier(element.propertyName && factory.createIdentifier(element.propertyName.text), factory.createIdentifier(element.name.text)));
}
}
else {
@@ -117,14 +117,14 @@ namespace ts.refactor {
});
}
changes.replaceNode(sourceFile, toConvert, createNamespaceImport(createIdentifier(namespaceImportName)));
changes.replaceNode(sourceFile, toConvert, factory.createNamespaceImport(factory.createIdentifier(namespaceImportName)));
if (neededNamedImports.length) {
changes.insertNodeAfter(sourceFile, toConvert.parent.parent, updateImport(importDecl, /*defaultImportName*/ undefined, neededNamedImports));
}
}
function updateImport(old: ImportDeclaration, defaultImportName: Identifier | undefined, elements: ReadonlyArray<ImportSpecifier> | undefined): ImportDeclaration {
return createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined,
createImportClause(defaultImportName, elements && elements.length ? createNamedImports(elements) : undefined), old.moduleSpecifier);
return factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined,
factory.createImportClause(defaultImportName, elements && elements.length ? factory.createNamedImports(elements) : undefined), old.moduleSpecifier);
}
}
@@ -363,9 +363,9 @@ namespace ts.refactor.convertParamsToDestructuredObject {
function createPropertyOrShorthandAssignment(name: string, initializer: Expression): PropertyAssignment | ShorthandPropertyAssignment {
if (isIdentifier(initializer) && getTextOfIdentifierOrLiteral(initializer) === name) {
return createShorthandPropertyAssignment(name);
return factory.createShorthandPropertyAssignment(name);
}
return createPropertyAssignment(name, initializer);
return factory.createPropertyAssignment(name, initializer);
}
function createNewArgument(functionDeclaration: ValidFunctionDeclaration, functionArguments: NodeArray<Expression>): ObjectLiteralExpression {
@@ -384,11 +384,11 @@ namespace ts.refactor.convertParamsToDestructuredObject {
if (hasRestParameter && functionArguments.length >= parameters.length) {
const restArguments = functionArguments.slice(parameters.length - 1);
const restProperty = createPropertyAssignment(getParameterName(last(parameters)), createArrayLiteral(restArguments));
const restProperty = factory.createPropertyAssignment(getParameterName(last(parameters)), factory.createArrayLiteral(restArguments));
properties.push(restProperty);
}
const objectLiteral = createObjectLiteral(properties, /*multiLine*/ false);
const objectLiteral = factory.createObjectLiteral(properties, /*multiLine*/ false);
return objectLiteral;
}
@@ -396,16 +396,16 @@ namespace ts.refactor.convertParamsToDestructuredObject {
const checker = program.getTypeChecker();
const refactorableParameters = getRefactorableParameters(functionDeclaration.parameters);
const bindingElements = map(refactorableParameters, createBindingElementFromParameterDeclaration);
const objectParameterName = createObjectBindingPattern(bindingElements);
const objectParameterName = factory.createObjectBindingPattern(bindingElements);
const objectParameterType = createParameterTypeNode(refactorableParameters);
let objectInitializer: Expression | undefined;
// If every parameter in the original function was optional, add an empty object initializer to the new object parameter
if (every(refactorableParameters, isOptionalParameter)) {
objectInitializer = createObjectLiteral();
objectInitializer = factory.createObjectLiteral();
}
const objectParameter = createParameter(
const objectParameter = factory.createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
@@ -416,7 +416,7 @@ namespace ts.refactor.convertParamsToDestructuredObject {
if (hasThisParameter(functionDeclaration.parameters)) {
const thisParameter = functionDeclaration.parameters[0];
const newThisParameter = createParameter(
const newThisParameter = factory.createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
@@ -436,11 +436,11 @@ namespace ts.refactor.convertParamsToDestructuredObject {
return createNodeArray([objectParameter]);
function createBindingElementFromParameterDeclaration(parameterDeclaration: ValidParameterDeclaration): BindingElement {
const element = createBindingElement(
const element = factory.createBindingElement(
/*dotDotDotToken*/ undefined,
/*propertyName*/ undefined,
getParameterName(parameterDeclaration),
isRestParameter(parameterDeclaration) && isOptionalParameter(parameterDeclaration) ? createArrayLiteral() : parameterDeclaration.initializer);
isRestParameter(parameterDeclaration) && isOptionalParameter(parameterDeclaration) ? factory.createArrayLiteral() : parameterDeclaration.initializer);
suppressLeadingAndTrailingTrivia(element);
if (parameterDeclaration.initializer && element.initializer) {
@@ -451,7 +451,7 @@ namespace ts.refactor.convertParamsToDestructuredObject {
function createParameterTypeNode(parameters: NodeArray<ValidParameterDeclaration>): TypeLiteralNode {
const members = map(parameters, createPropertySignatureFromParameterDeclaration);
const typeNode = addEmitFlags(createTypeLiteralNode(members), EmitFlags.SingleLine);
const typeNode = addEmitFlags(factory.createTypeLiteralNode(members), EmitFlags.SingleLine);
return typeNode;
}
@@ -461,12 +461,11 @@ namespace ts.refactor.convertParamsToDestructuredObject {
parameterType = getTypeNode(parameterDeclaration);
}
const propertySignature = createPropertySignature(
const propertySignature = factory.createPropertySignature(
/*modifiers*/ undefined,
getParameterName(parameterDeclaration),
isOptionalParameter(parameterDeclaration) ? createToken(SyntaxKind.QuestionToken) : parameterDeclaration.questionToken,
parameterType,
/*initializer*/ undefined);
isOptionalParameter(parameterDeclaration) ? factory.createToken(SyntaxKind.QuestionToken) : parameterDeclaration.questionToken,
parameterType);
suppressLeadingAndTrailingTrivia(propertySignature);
copyComments(parameterDeclaration.name, propertySignature.name);
+73 -74
View File
@@ -719,7 +719,7 @@ namespace ts.refactor.extractSymbol {
const functionNameText = getUniqueName(isClassLike(scope) ? "newMethod" : "newFunction", file);
const isJS = isInJSFile(scope);
const functionName = createIdentifier(functionNameText);
const functionName = factory.createIdentifier(functionNameText);
let returnType: TypeNode | undefined;
const parameters: ParameterDeclaration[] = [];
@@ -734,7 +734,7 @@ namespace ts.refactor.extractSymbol {
typeNode = checker.typeToTypeNode(type, scope, NodeBuilderFlags.NoTruncation);
}
const paramDecl = createParameter(
const paramDecl = factory.createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
@@ -746,7 +746,7 @@ namespace ts.refactor.extractSymbol {
if (usage.usage === Usage.Write) {
(writes || (writes = [])).push(usage);
}
callArguments.push(createIdentifier(name));
callArguments.push(factory.createIdentifier(name));
});
const typeParametersAndDeclarations = arrayFrom(typeParameterUsages.values()).map(type => ({ type, declaration: getFirstDeclaration(type) }));
@@ -759,7 +759,7 @@ namespace ts.refactor.extractSymbol {
// Strictly speaking, we should check whether each name actually binds to the appropriate type
// parameter. In cases of shadowing, they may not.
const callTypeArguments: ReadonlyArray<TypeNode> | undefined = typeParameters !== undefined
? typeParameters.map(decl => createTypeReferenceNode(decl.name, /*typeArguments*/ undefined))
? typeParameters.map(decl => factory.createTypeReferenceNode(decl.name, /*typeArguments*/ undefined))
: undefined;
// Provide explicit return types for contextually-typed functions
@@ -776,17 +776,17 @@ namespace ts.refactor.extractSymbol {
if (isClassLike(scope)) {
// always create private method in TypeScript files
const modifiers: Modifier[] = isJS ? [] : [createToken(SyntaxKind.PrivateKeyword)];
const modifiers: Modifier[] = isJS ? [] : [factory.createToken(SyntaxKind.PrivateKeyword)];
if (range.facts & RangeFacts.InStaticRegion) {
modifiers.push(createToken(SyntaxKind.StaticKeyword));
modifiers.push(factory.createToken(SyntaxKind.StaticKeyword));
}
if (range.facts & RangeFacts.IsAsyncFunction) {
modifiers.push(createToken(SyntaxKind.AsyncKeyword));
modifiers.push(factory.createToken(SyntaxKind.AsyncKeyword));
}
newFunction = createMethod(
newFunction = factory.createMethodDeclaration(
/*decorators*/ undefined,
modifiers.length ? modifiers : undefined,
range.facts & RangeFacts.IsGenerator ? createToken(SyntaxKind.AsteriskToken) : undefined,
range.facts & RangeFacts.IsGenerator ? factory.createToken(SyntaxKind.AsteriskToken) : undefined,
functionName,
/*questionToken*/ undefined,
typeParameters,
@@ -796,10 +796,10 @@ namespace ts.refactor.extractSymbol {
);
}
else {
newFunction = createFunctionDeclaration(
newFunction = factory.createFunctionDeclaration(
/*decorators*/ undefined,
range.facts & RangeFacts.IsAsyncFunction ? [createToken(SyntaxKind.AsyncKeyword)] : undefined,
range.facts & RangeFacts.IsGenerator ? createToken(SyntaxKind.AsteriskToken) : undefined,
range.facts & RangeFacts.IsAsyncFunction ? [factory.createToken(SyntaxKind.AsyncKeyword)] : undefined,
range.facts & RangeFacts.IsGenerator ? factory.createToken(SyntaxKind.AsteriskToken) : undefined,
functionName,
typeParameters,
parameters,
@@ -822,15 +822,15 @@ namespace ts.refactor.extractSymbol {
// replace range with function call
const called = getCalledExpression(scope, range, functionNameText);
let call: Expression = createCall(
let call: Expression = factory.createCall(
called,
callTypeArguments, // Note that no attempt is made to take advantage of type argument inference
callArguments);
if (range.facts & RangeFacts.IsGenerator) {
call = createYield(createToken(SyntaxKind.AsteriskToken), call);
call = factory.createYield(factory.createToken(SyntaxKind.AsteriskToken), call);
}
if (range.facts & RangeFacts.IsAsyncFunction) {
call = createAwait(call);
call = factory.createAwait(call);
}
if (exposedVariableDeclarations.length && !writes) {
@@ -843,10 +843,10 @@ namespace ts.refactor.extractSymbol {
if (exposedVariableDeclarations.length === 1) {
// Declaring exactly one variable: let x = newFunction();
const variableDeclaration = exposedVariableDeclarations[0];
newNodes.push(createVariableStatement(
newNodes.push(factory.createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
[createVariableDeclaration(getSynthesizedDeepClone(variableDeclaration.name), /*type*/ getSynthesizedDeepClone(variableDeclaration.type), /*initializer*/ call)], // TODO (acasey): test binding patterns
factory.createVariableDeclarationList(
[factory.createVariableDeclaration(getSynthesizedDeepClone(variableDeclaration.name), /*type*/ getSynthesizedDeepClone(variableDeclaration.type), /*initializer*/ call)], // TODO (acasey): test binding patterns
variableDeclaration.parent.flags)));
}
else {
@@ -857,7 +857,7 @@ namespace ts.refactor.extractSymbol {
let commonNodeFlags = exposedVariableDeclarations[0].parent.flags;
let sawExplicitType = false;
for (const variableDeclaration of exposedVariableDeclarations) {
bindingElements.push(createBindingElement(
bindingElements.push(factory.createBindingElement(
/*dotDotDotToken*/ undefined,
/*propertyName*/ undefined,
/*name*/ getSynthesizedDeepClone(variableDeclaration.name)));
@@ -868,26 +868,25 @@ namespace ts.refactor.extractSymbol {
scope,
NodeBuilderFlags.NoTruncation);
typeElements.push(createPropertySignature(
typeElements.push(factory.createPropertySignature(
/*modifiers*/ undefined,
/*name*/ variableDeclaration.symbol.name,
/*questionToken*/ undefined,
/*type*/ variableType,
/*initializer*/ undefined));
/*type*/ variableType));
sawExplicitType = sawExplicitType || variableDeclaration.type !== undefined;
commonNodeFlags = commonNodeFlags & variableDeclaration.parent.flags;
}
const typeLiteral: TypeLiteralNode | undefined = sawExplicitType ? createTypeLiteralNode(typeElements) : undefined;
const typeLiteral: TypeLiteralNode | undefined = sawExplicitType ? factory.createTypeLiteralNode(typeElements) : undefined;
if (typeLiteral) {
setEmitFlags(typeLiteral, EmitFlags.SingleLine);
}
newNodes.push(createVariableStatement(
newNodes.push(factory.createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
[createVariableDeclaration(
createObjectBindingPattern(bindingElements),
factory.createVariableDeclarationList(
[factory.createVariableDeclaration(
factory.createObjectBindingPattern(bindingElements),
/*type*/ typeLiteral,
/*initializer*/call)],
commonNodeFlags)));
@@ -902,26 +901,26 @@ namespace ts.refactor.extractSymbol {
flags = (flags & ~NodeFlags.Const) | NodeFlags.Let;
}
newNodes.push(createVariableStatement(
newNodes.push(factory.createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
[createVariableDeclaration(variableDeclaration.symbol.name, getTypeDeepCloneUnionUndefined(variableDeclaration.type))],
factory.createVariableDeclarationList(
[factory.createVariableDeclaration(variableDeclaration.symbol.name, getTypeDeepCloneUnionUndefined(variableDeclaration.type))],
flags)));
}
}
if (returnValueProperty) {
// has both writes and return, need to create variable declaration to hold return value;
newNodes.push(createVariableStatement(
newNodes.push(factory.createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
[createVariableDeclaration(returnValueProperty, getTypeDeepCloneUnionUndefined(returnType))],
factory.createVariableDeclarationList(
[factory.createVariableDeclaration(returnValueProperty, getTypeDeepCloneUnionUndefined(returnType))],
NodeFlags.Let)));
}
const assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
if (returnValueProperty) {
assignments.unshift(createShorthandPropertyAssignment(returnValueProperty));
assignments.unshift(factory.createShorthandPropertyAssignment(returnValueProperty));
}
// propagate writes back
@@ -930,28 +929,28 @@ namespace ts.refactor.extractSymbol {
// other assignments to make.
Debug.assert(!returnValueProperty);
newNodes.push(createStatement(createAssignment(assignments[0].name, call)));
newNodes.push(factory.createExpressionStatement(factory.createAssignment(assignments[0].name, call)));
if (range.facts & RangeFacts.HasReturn) {
newNodes.push(createReturn());
newNodes.push(factory.createReturn());
}
}
else {
// emit e.g.
// { a, b, __return } = newFunction(a, b);
// return __return;
newNodes.push(createStatement(createAssignment(createObjectLiteral(assignments), call)));
newNodes.push(factory.createExpressionStatement(factory.createAssignment(factory.createObjectLiteral(assignments), call)));
if (returnValueProperty) {
newNodes.push(createReturn(createIdentifier(returnValueProperty)));
newNodes.push(factory.createReturn(factory.createIdentifier(returnValueProperty)));
}
}
}
else {
if (range.facts & RangeFacts.HasReturn) {
newNodes.push(createReturn(call));
newNodes.push(factory.createReturn(call));
}
else if (isReadonlyArray(range.range)) {
newNodes.push(createStatement(call));
newNodes.push(factory.createExpressionStatement(call));
}
else {
newNodes.push(call);
@@ -984,7 +983,7 @@ namespace ts.refactor.extractSymbol {
}
return isUnionTypeNode(withoutParens) && find(withoutParens.types, t => t.kind === SyntaxKind.UndefinedKeyword)
? clone
: createUnionTypeNode([clone, createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]);
: factory.createUnionTypeNode([clone, factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]);
}
}
@@ -1018,13 +1017,13 @@ namespace ts.refactor.extractSymbol {
if (isClassLike(scope)) {
Debug.assert(!isJS); // See CannotExtractToJSClass
const modifiers: Modifier[] = [];
modifiers.push(createToken(SyntaxKind.PrivateKeyword));
modifiers.push(factory.createToken(SyntaxKind.PrivateKeyword));
if (rangeFacts & RangeFacts.InStaticRegion) {
modifiers.push(createToken(SyntaxKind.StaticKeyword));
modifiers.push(factory.createToken(SyntaxKind.StaticKeyword));
}
modifiers.push(createToken(SyntaxKind.ReadonlyKeyword));
modifiers.push(factory.createToken(SyntaxKind.ReadonlyKeyword));
const newVariable = createProperty(
const newVariable = factory.createPropertyDeclaration(
/*decorators*/ undefined,
modifiers,
localNameText,
@@ -1032,11 +1031,11 @@ namespace ts.refactor.extractSymbol {
variableType,
initializer);
const localReference = createPropertyAccess(
const localReference = factory.createPropertyAccess(
rangeFacts & RangeFacts.InStaticRegion
? createIdentifier(scope.name!.getText()) // TODO: GH#18217
: createThis(),
createIdentifier(localNameText));
? factory.createIdentifier(scope.name!.getText()) // TODO: GH#18217
: factory.createThis(),
factory.createIdentifier(localNameText));
// Declare
const maxInsertionPos = node.pos;
@@ -1047,7 +1046,7 @@ namespace ts.refactor.extractSymbol {
changeTracker.replaceNode(context.file, node, localReference);
}
else {
const newVariableDeclaration = createVariableDeclaration(localNameText, variableType, initializer);
const newVariableDeclaration = factory.createVariableDeclaration(localNameText, variableType, initializer);
// If the node is part of an initializer in a list of variable declarations, insert a new
// variable declaration into the list (in case it depends on earlier ones).
@@ -1060,21 +1059,21 @@ namespace ts.refactor.extractSymbol {
changeTracker.insertNodeBefore(context.file, oldVariableDeclaration, newVariableDeclaration);
// Consume
const localReference = createIdentifier(localNameText);
const localReference = factory.createIdentifier(localNameText);
changeTracker.replaceNode(context.file, node, localReference);
}
else if (node.parent.kind === SyntaxKind.ExpressionStatement && scope === findAncestor(node, isScope)) {
// If the parent is an expression statement and the target scope is the immediately enclosing one,
// replace the statement with the declaration.
const newVariableStatement = createVariableStatement(
const newVariableStatement = factory.createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const));
factory.createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const));
changeTracker.replaceNode(context.file, node.parent, newVariableStatement);
}
else {
const newVariableStatement = createVariableStatement(
const newVariableStatement = factory.createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const));
factory.createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const));
// Declare
const nodeToInsertBefore = getNodeToInsertConstantBefore(node, scope);
@@ -1091,7 +1090,7 @@ namespace ts.refactor.extractSymbol {
changeTracker.delete(context.file, node.parent);
}
else {
const localReference = createIdentifier(localNameText);
const localReference = factory.createIdentifier(localNameText);
changeTracker.replaceNode(context.file, node, localReference);
}
}
@@ -1147,10 +1146,10 @@ namespace ts.refactor.extractSymbol {
}
function getCalledExpression(scope: Node, range: TargetRange, functionNameText: string): Expression {
const functionReference = createIdentifier(functionNameText);
const functionReference = factory.createIdentifier(functionNameText);
if (isClassLike(scope)) {
const lhs = range.facts & RangeFacts.InStaticRegion ? createIdentifier(scope.name!.text) : createThis(); // TODO: GH#18217
return createPropertyAccess(lhs, functionReference);
const lhs = range.facts & RangeFacts.InStaticRegion ? factory.createIdentifier(scope.name!.text) : factory.createThis(); // TODO: GH#18217
return factory.createPropertyAccess(lhs, functionReference);
}
else {
return functionReference;
@@ -1161,11 +1160,11 @@ namespace ts.refactor.extractSymbol {
const hasWritesOrVariableDeclarations = writes !== undefined || exposedVariableDeclarations.length > 0;
if (isBlock(body) && !hasWritesOrVariableDeclarations && substitutions.size === 0) {
// already block, no declarations or writes to propagate back, no substitutions - can use node as is
return { body: createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined };
return { body: factory.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined };
}
let returnValueProperty: string | undefined;
let ignoreReturns = false;
const statements = createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : createReturn(<Expression>body)]);
const statements = createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : factory.createReturn(<Expression>body)]);
// rewrite body if either there are writes that should be propagated back via return statements or there are substitutions
if (hasWritesOrVariableDeclarations || substitutions.size) {
const rewrittenStatements = visitNodes(statements, visitor).slice();
@@ -1174,16 +1173,16 @@ namespace ts.refactor.extractSymbol {
// it is ok to know that range has at least one return since it we only allow unconditional returns
const assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes);
if (assignments.length === 1) {
rewrittenStatements.push(createReturn(assignments[0].name));
rewrittenStatements.push(factory.createReturn(assignments[0].name));
}
else {
rewrittenStatements.push(createReturn(createObjectLiteral(assignments)));
rewrittenStatements.push(factory.createReturn(factory.createObjectLiteral(assignments)));
}
}
return { body: createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty };
return { body: factory.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty };
}
else {
return { body: createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined };
return { body: factory.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined };
}
function visitor(node: Node): VisitResult<Node> {
@@ -1193,13 +1192,13 @@ namespace ts.refactor.extractSymbol {
if (!returnValueProperty) {
returnValueProperty = "__return";
}
assignments.unshift(createPropertyAssignment(returnValueProperty, visitNode((<ReturnStatement>node).expression!, visitor)));
assignments.unshift(factory.createPropertyAssignment(returnValueProperty, visitNode((<ReturnStatement>node).expression!, visitor)));
}
if (assignments.length === 1) {
return createReturn(assignments[0].name as Expression);
return factory.createReturn(assignments[0].name as Expression);
}
else {
return createReturn(createObjectLiteral(assignments));
return factory.createReturn(factory.createObjectLiteral(assignments));
}
}
else {
@@ -1317,8 +1316,8 @@ namespace ts.refactor.extractSymbol {
exposedVariableDeclarations: ReadonlyArray<VariableDeclaration>,
writes: ReadonlyArray<UsageEntry> | undefined
): ShorthandPropertyAssignment[] {
const variableAssignments = map(exposedVariableDeclarations, v => createShorthandPropertyAssignment(v.symbol.name));
const writeAssignments = map(writes, w => createShorthandPropertyAssignment(w.symbol.name));
const variableAssignments = map(exposedVariableDeclarations, v => factory.createShorthandPropertyAssignment(v.symbol.name));
const writeAssignments = map(writes, w => factory.createShorthandPropertyAssignment(w.symbol.name));
// TODO: GH#18217 `variableAssignments` not possibly undefined!
return variableAssignments === undefined
@@ -1433,7 +1432,7 @@ namespace ts.refactor.extractSymbol {
}
const seenUsages = createMap<Usage>();
const target = isReadonlyArray(targetRange.range) ? createBlock(targetRange.range) : targetRange.range;
const target = isReadonlyArray(targetRange.range) ? factory.createBlock(targetRange.range) : targetRange.range;
const unmodifiedNode = isReadonlyArray(targetRange.range) ? first(targetRange.range) : targetRange.range;
const inGenericContext = isInGenericContext(unmodifiedNode);
@@ -1730,15 +1729,15 @@ namespace ts.refactor.extractSymbol {
}
const decls = symbol.getDeclarations();
if (decls && decls.some(d => d.parent === scopeDecl)) {
return createIdentifier(symbol.name);
return factory.createIdentifier(symbol.name);
}
const prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode);
if (prefix === undefined) {
return undefined;
}
return isTypeNode
? createQualifiedName(<EntityName>prefix, createIdentifier(symbol.name))
: createPropertyAccess(<Expression>prefix, symbol.name);
? factory.createQualifiedName(<EntityName>prefix, factory.createIdentifier(symbol.name))
: factory.createPropertyAccess(<Expression>prefix, symbol.name);
}
}
+9 -9
View File
@@ -108,30 +108,30 @@ namespace ts.refactor {
}
function doTypeAliasChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, firstStatement: Statement, selection: TypeNode, typeParameters: ReadonlyArray<TypeParameterDeclaration>) {
const newTypeNode = createTypeAliasDeclaration(
const newTypeNode = factory.createTypeAliasDeclaration(
/* decorators */ undefined,
/* modifiers */ undefined,
name,
typeParameters.map(id => updateTypeParameterDeclaration(id, id.name, id.constraint, /* defaultType */ undefined)),
typeParameters.map(id => factory.updateTypeParameterDeclaration(id, id.name, id.constraint, /* defaultType */ undefined)),
selection
);
changes.insertNodeBefore(file, firstStatement, newTypeNode, /* blankLineBetween */ true);
changes.replaceNode(file, selection, createTypeReferenceNode(name, typeParameters.map(id => createTypeReferenceNode(id.name, /* typeArguments */ undefined))));
changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))));
}
function doTypedefChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, firstStatement: Statement, selection: TypeNode, typeParameters: ReadonlyArray<TypeParameterDeclaration>) {
const node = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag);
node.tagName = createIdentifier("typedef"); // TODO: jsdoc factory https://github.com/Microsoft/TypeScript/pull/29539
node.fullName = createIdentifier(name);
node.tagName = factory.createIdentifier("typedef"); // TODO: jsdoc factory https://github.com/Microsoft/TypeScript/pull/29539
node.fullName = factory.createIdentifier(name);
node.name = node.fullName;
node.typeExpression = createJSDocTypeExpression(selection);
node.typeExpression = factory.createJSDocTypeExpression(selection);
const templates: JSDocTemplateTag[] = [];
forEach(typeParameters, typeParameter => {
const constraint = getEffectiveConstraintOfTypeParameter(typeParameter);
const template = <JSDocTemplateTag>createNode(SyntaxKind.JSDocTemplateTag);
template.tagName = createIdentifier("template");
template.tagName = factory.createIdentifier("template");
template.constraint = constraint && cast(constraint, isJSDocTypeExpression);
const parameter = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter);
@@ -141,7 +141,7 @@ namespace ts.refactor {
templates.push(template);
});
changes.insertNodeBefore(file, firstStatement, createJSDocComment(/* comment */ undefined, createNodeArray(concatenate<JSDocTag>(templates, [node]))), /* blankLineBetween */ true);
changes.replaceNode(file, selection, createTypeReferenceNode(name, typeParameters.map(id => createTypeReferenceNode(id.name, /* typeArguments */ undefined))));
changes.insertNodeBefore(file, firstStatement, factory.createJSDocComment(/* comment */ undefined, createNodeArray(concatenate<JSDocTag>(templates, [node]))), /* blankLineBetween */ true);
changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))));
}
}
@@ -55,7 +55,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
const accessorModifiers = isInClassLike
? !modifierFlags || modifierFlags & ModifierFlags.Private
? getModifiers(isJS, isStatic, SyntaxKind.PublicKeyword)
: createNodeArray(createModifiersFromModifierFlags(modifierFlags))
: createNodeArray(factory.createModifiersFromModifierFlags(modifierFlags))
: undefined;
const fieldModifiers = isInClassLike ? getModifiers(isJS, isStatic, SyntaxKind.PrivateKeyword) : undefined;
@@ -96,18 +96,18 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
}
function createPropertyName (name: string, originalName: AcceptedNameType) {
return isIdentifier(originalName) ? createIdentifier(name) : createLiteral(name);
return isIdentifier(originalName) ? factory.createIdentifier(name) : factory.createStringLiteral(name);
}
function createAccessorAccessExpression (fieldName: AcceptedNameType, isStatic: boolean, container: ContainerDeclaration) {
const leftHead = isStatic ? (<ClassLikeDeclaration>container).name! : createThis(); // TODO: GH#18217
return isIdentifier(fieldName) ? createPropertyAccess(leftHead, fieldName) : createElementAccess(leftHead, createLiteral(fieldName));
const leftHead = isStatic ? (<ClassLikeDeclaration>container).name! : factory.createThis(); // TODO: GH#18217
return isIdentifier(fieldName) ? factory.createPropertyAccess(leftHead, fieldName) : factory.createElementAccess(leftHead, factory.createStringLiteralFromNode(fieldName));
}
function getModifiers(isJS: boolean, isStatic: boolean, accessModifier: SyntaxKind.PublicKeyword | SyntaxKind.PrivateKeyword): NodeArray<Modifier> | undefined {
const modifiers = append<Modifier>(
!isJS ? [createToken(accessModifier) as Token<SyntaxKind.PublicKeyword> | Token<SyntaxKind.PrivateKeyword>] : undefined,
isStatic ? createToken(SyntaxKind.StaticKeyword) : undefined
!isJS ? [factory.createToken(accessModifier) as Token<SyntaxKind.PublicKeyword> | Token<SyntaxKind.PrivateKeyword>] : undefined,
isStatic ? factory.createToken(SyntaxKind.StaticKeyword) : undefined
);
return modifiers && createNodeArray(modifiers);
}
@@ -144,14 +144,14 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
}
function generateGetAccessor(fieldName: AcceptedNameType, accessorName: AcceptedNameType, type: TypeNode | undefined, modifiers: ModifiersArray | undefined, isStatic: boolean, container: ContainerDeclaration) {
return createGetAccessor(
return factory.createGetAccessorDeclaration(
/*decorators*/ undefined,
modifiers,
accessorName,
/*parameters*/ undefined!, // TODO: GH#18217
type,
createBlock([
createReturn(
factory.createBlock([
factory.createReturn(
createAccessorAccessExpression(fieldName, isStatic, container)
)
], /*multiLine*/ true)
@@ -159,23 +159,23 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
}
function generateSetAccessor(fieldName: AcceptedNameType, accessorName: AcceptedNameType, type: TypeNode | undefined, modifiers: ModifiersArray | undefined, isStatic: boolean, container: ContainerDeclaration) {
return createSetAccessor(
return factory.createSetAccessorDeclaration(
/*decorators*/ undefined,
modifiers,
accessorName,
[createParameter(
[factory.createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
createIdentifier("value"),
factory.createIdentifier("value"),
/*questionToken*/ undefined,
type
)],
createBlock([
createStatement(
createAssignment(
factory.createBlock([
factory.createExpressionStatement(
factory.createAssignment(
createAccessorAccessExpression(fieldName, isStatic, container),
createIdentifier("value")
factory.createIdentifier("value")
)
)
], /*multiLine*/ true)
@@ -183,7 +183,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
}
function updatePropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyDeclaration, fieldName: AcceptedNameType, modifiers: ModifiersArray | undefined) {
const property = updateProperty(
const property = factory.updatePropertyDeclaration(
declaration,
declaration.decorators,
modifiers,
@@ -196,7 +196,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
}
function updatePropertyAssignmentDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyAssignment, fieldName: AcceptedNameType) {
const assignment = updatePropertyAssignment(declaration, fieldName, declaration.initializer);
const assignment = factory.updatePropertyAssignment(declaration, fieldName, declaration.initializer);
changeTracker.replacePropertyAssignment(file, declaration, assignment);
}
@@ -209,7 +209,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
}
else {
changeTracker.replaceNode(file, declaration,
updateParameter(declaration, declaration.decorators, modifiers, declaration.dotDotDotToken, cast(fieldName, isIdentifier), declaration.questionToken, declaration.type, declaration.initializer));
factory.updateParameterDeclaration(declaration, declaration.decorators, modifiers, declaration.dotDotDotToken, cast(fieldName, isIdentifier), declaration.questionToken, declaration.type, declaration.initializer));
}
}
@@ -229,10 +229,10 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
isStringLiteral(node.argumentExpression) &&
node.argumentExpression.text === originalName &&
isWriteAccess(node)) {
changeTracker.replaceNode(file, node.argumentExpression, createStringLiteral(fieldName));
changeTracker.replaceNode(file, node.argumentExpression, factory.createStringLiteral(fieldName));
}
if (isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.ThisKeyword && node.name.text === originalName && isWriteAccess(node)) {
changeTracker.replaceNode(file, node.name, createIdentifier(fieldName));
changeTracker.replaceNode(file, node.name, factory.createIdentifier(fieldName));
}
if (!isFunctionLike(node) && !isClassLike(node)) {
node.forEachChild(recur);
+32 -32
View File
@@ -103,7 +103,7 @@ namespace ts.refactor {
const filesProp = cfgObject && find(cfgObject.properties, (prop): prop is PropertyAssignment =>
isPropertyAssignment(prop) && isStringLiteral(prop.name) && prop.name.text === "files");
if (filesProp && isArrayLiteralExpression(filesProp.initializer)) {
changes.insertNodeInListAfter(cfg, last(filesProp.initializer.elements), createLiteral(newFilePath), filesProp.initializer.elements);
changes.insertNodeInListAfter(cfg, last(filesProp.initializer.elements), factory.createStringLiteral(newFilePath), filesProp.initializer.elements);
}
}
@@ -164,7 +164,7 @@ namespace ts.refactor {
};
deleteUnusedImports(sourceFile, importNode, changes, shouldMove); // These will be changed to imports from the new file
const newModuleSpecifier = combinePaths(getDirectoryPath(moduleSpecifierFromImport(importNode).text), newModuleName);
const newImportDeclaration = filterImport(importNode, createLiteral(newModuleSpecifier), shouldMove);
const newImportDeclaration = filterImport(importNode, factory.createStringLiteral(newModuleSpecifier), shouldMove);
if (newImportDeclaration) changes.insertNodeAfter(sourceFile, statement, newImportDeclaration);
const ns = getNamespaceLikeImport(importNode);
@@ -212,25 +212,25 @@ namespace ts.refactor {
if (toChange.length) {
const newNamespaceName = needUniqueName ? getUniqueName(preferredNewNamespaceName, sourceFile) : preferredNewNamespaceName;
for (const ref of toChange) {
changes.replaceNode(sourceFile, ref, createIdentifier(newNamespaceName));
changes.replaceNode(sourceFile, ref, factory.createIdentifier(newNamespaceName));
}
changes.insertNodeAfter(sourceFile, oldImportNode, updateNamespaceLikeImportNode(oldImportNode, newModuleName, newModuleSpecifier));
}
}
function updateNamespaceLikeImportNode(node: SupportedImport, newNamespaceName: string, newModuleSpecifier: string): Node {
const newNamespaceId = createIdentifier(newNamespaceName);
const newModuleString = createLiteral(newModuleSpecifier);
const newNamespaceId = factory.createIdentifier(newNamespaceName);
const newModuleString = factory.createStringLiteral(newModuleSpecifier);
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
return createImportDeclaration(
return factory.createImportDeclaration(
/*decorators*/ undefined, /*modifiers*/ undefined,
createImportClause(/*name*/ undefined, createNamespaceImport(newNamespaceId)),
factory.createImportClause(/*name*/ undefined, factory.createNamespaceImport(newNamespaceId)),
newModuleString);
case SyntaxKind.ImportEqualsDeclaration:
return createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newNamespaceId, createExternalModuleReference(newModuleString));
return factory.createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newNamespaceId, factory.createExternalModuleReference(newModuleString));
case SyntaxKind.VariableDeclaration:
return createVariableDeclaration(newNamespaceId, /*type*/ undefined, createRequireCall(newModuleString));
return factory.createVariableDeclaration(newNamespaceId, /*type*/ undefined, createRequireCall(newModuleString));
default:
return Debug.assertNever(node);
}
@@ -274,7 +274,7 @@ namespace ts.refactor {
const imports: string[] = [];
newFileNeedExport.forEach(symbol => {
if (symbol.escapedName === InternalSymbolName.Default) {
defaultImport = createIdentifier(symbolNameNoDefault(symbol)!); // TODO: GH#18217
defaultImport = factory.createIdentifier(symbolNameNoDefault(symbol)!); // TODO: GH#18217
}
else {
imports.push(symbol.name);
@@ -286,24 +286,24 @@ namespace ts.refactor {
function makeImportOrRequire(defaultImport: Identifier | undefined, imports: ReadonlyArray<string>, path: string, useEs6Imports: boolean, quotePreference: QuotePreference): Statement | undefined {
path = ensurePathIsNonModuleName(path);
if (useEs6Imports) {
const specifiers = imports.map(i => createImportSpecifier(/*propertyName*/ undefined, createIdentifier(i)));
const specifiers = imports.map(i => factory.createImportSpecifier(/*propertyName*/ undefined, factory.createIdentifier(i)));
return makeImportIfNecessary(defaultImport, specifiers, path, quotePreference);
}
else {
Debug.assert(!defaultImport); // If there's a default export, it should have been an es6 module.
const bindingElements = imports.map(i => createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i));
const bindingElements = imports.map(i => factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i));
return bindingElements.length
? makeVariableStatement(createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(createLiteral(path)))
? makeVariableStatement(factory.createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(factory.createStringLiteral(path)))
: undefined;
}
}
function makeVariableStatement(name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined, flags: NodeFlags = NodeFlags.Const) {
return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([createVariableDeclaration(name, type, initializer)], flags));
return factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(name, type, initializer)], flags));
}
function createRequireCall(moduleSpecifier: StringLiteralLike): CallExpression {
return createCall(createIdentifier("require"), /*typeArguments*/ undefined, [moduleSpecifier]);
return factory.createCall(factory.createIdentifier("require"), /*typeArguments*/ undefined, [moduleSpecifier]);
}
function addExports(sourceFile: SourceFile, toMove: ReadonlyArray<Statement>, needExport: ReadonlySymbolSet, useEs6Exports: boolean): ReadonlyArray<Statement> {
@@ -353,7 +353,7 @@ namespace ts.refactor {
changes.replaceNode(
sourceFile,
importDecl.importClause,
updateImportClause(importDecl.importClause, name, /*namedBindings*/ undefined)
factory.updateImportClause(importDecl.importClause, name, /*namedBindings*/ undefined)
);
}
else if (namedBindings.kind === SyntaxKind.NamedImports) {
@@ -555,7 +555,7 @@ namespace ts.refactor {
const defaultImport = clause.name && keep(clause.name) ? clause.name : undefined;
const namedBindings = clause.namedBindings && filterNamedBindings(clause.namedBindings, keep);
return defaultImport || namedBindings
? createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createImportClause(defaultImport, namedBindings), moduleSpecifier)
? factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createImportClause(defaultImport, namedBindings), moduleSpecifier)
: undefined;
}
case SyntaxKind.ImportEqualsDeclaration:
@@ -574,7 +574,7 @@ namespace ts.refactor {
}
else {
const newElements = namedBindings.elements.filter(e => keep(e.name));
return newElements.length ? createNamedImports(newElements) : undefined;
return newElements.length ? factory.createNamedImports(newElements) : undefined;
}
}
function filterBindingName(name: BindingName, keep: (name: Identifier) => boolean): BindingName | undefined {
@@ -586,7 +586,7 @@ namespace ts.refactor {
case SyntaxKind.ObjectBindingPattern: {
// We can't handle nested destructurings or property names well here, so just copy them all.
const newElements = name.elements.filter(prop => prop.propertyName || !isIdentifier(prop.name) || keep(prop.name));
return newElements.length ? createObjectBindingPattern(newElements) : undefined;
return newElements.length ? factory.createObjectBindingPattern(newElements) : undefined;
}
}
}
@@ -747,24 +747,24 @@ namespace ts.refactor {
return useEs6Exports ? [addEs6Export(decl)] : addCommonjsExport(decl);
}
function addEs6Export(d: TopLevelDeclarationStatement): TopLevelDeclarationStatement {
const modifiers = concatenate([createModifier(SyntaxKind.ExportKeyword)], d.modifiers);
const modifiers = concatenate([factory.createModifier(SyntaxKind.ExportKeyword)], d.modifiers);
switch (d.kind) {
case SyntaxKind.FunctionDeclaration:
return updateFunctionDeclaration(d, d.decorators, modifiers, d.asteriskToken, d.name, d.typeParameters, d.parameters, d.type, d.body);
return factory.updateFunctionDeclaration(d, d.decorators, modifiers, d.asteriskToken, d.name, d.typeParameters, d.parameters, d.type, d.body);
case SyntaxKind.ClassDeclaration:
return updateClassDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members);
return factory.updateClassDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members);
case SyntaxKind.VariableStatement:
return updateVariableStatement(d, modifiers, d.declarationList);
return factory.updateVariableStatement(d, modifiers, d.declarationList);
case SyntaxKind.ModuleDeclaration:
return updateModuleDeclaration(d, d.decorators, modifiers, d.name, d.body);
return factory.updateModuleDeclaration(d, d.decorators, modifiers, d.name, d.body);
case SyntaxKind.EnumDeclaration:
return updateEnumDeclaration(d, d.decorators, modifiers, d.name, d.members);
return factory.updateEnumDeclaration(d, d.decorators, modifiers, d.name, d.members);
case SyntaxKind.TypeAliasDeclaration:
return updateTypeAliasDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.type);
return factory.updateTypeAliasDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.type);
case SyntaxKind.InterfaceDeclaration:
return updateInterfaceDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members);
return factory.updateInterfaceDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members);
case SyntaxKind.ImportEqualsDeclaration:
return updateImportEqualsDeclaration(d, d.decorators, modifiers, d.name, d.moduleReference);
return factory.updateImportEqualsDeclaration(d, d.decorators, modifiers, d.name, d.moduleReference);
case SyntaxKind.ExpressionStatement:
return Debug.fail(); // Shouldn't try to add 'export' keyword to `exports.x = ...`
default:
@@ -796,10 +796,10 @@ namespace ts.refactor {
/** Creates `exports.x = x;` */
function createExportAssignment(name: string): Statement {
return createExpressionStatement(
createBinary(
createPropertyAccess(createIdentifier("exports"), createIdentifier(name)),
return factory.createExpressionStatement(
factory.createBinary(
factory.createPropertyAccess(factory.createIdentifier("exports"), factory.createIdentifier(name)),
SyntaxKind.EqualsToken,
createIdentifier(name)));
factory.createIdentifier(name)));
}
}
+12 -12
View File
@@ -331,7 +331,7 @@ namespace ts.textChanges {
public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void {
const pos = before.getStart(sourceFile);
this.insertNodeAt(sourceFile, pos, createToken(modifier), { suffix: " " });
this.insertNodeAt(sourceFile, pos, factory.createToken(modifier), { suffix: " " });
}
public insertLastModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void {
@@ -341,7 +341,7 @@ namespace ts.textChanges {
}
const pos = before.modifiers.end;
this.insertNodeAt(sourceFile, pos, createToken(modifier), { prefix: " " });
this.insertNodeAt(sourceFile, pos, factory.createToken(modifier), { prefix: " " });
}
public insertCommentBeforeLine(sourceFile: SourceFile, lineNumber: number, position: number, commentText: string): void {
@@ -449,7 +449,7 @@ namespace ts.textChanges {
}
private replaceConstructorBody(sourceFile: SourceFile, ctr: ConstructorDeclaration, statements: ReadonlyArray<Statement>): void {
this.replaceNode(sourceFile, ctr.body!, createBlock(statements, /*multiLine*/ true));
this.replaceNode(sourceFile, ctr.body!, factory.createBlock(statements, /*multiLine*/ true));
}
public insertNodeAtEndOfScope(sourceFile: SourceFile, scope: Node, newNode: Node): void {
@@ -515,7 +515,7 @@ namespace ts.textChanges {
// check if previous statement ends with semicolon
// if not - insert semicolon to preserve the code from changing the meaning due to ASI
if (sourceFile.text.charCodeAt(after.end - 1) !== CharacterCodes.semicolon) {
this.replaceRange(sourceFile, createRange(after.end), createToken(SyntaxKind.SemicolonToken));
this.replaceRange(sourceFile, createRange(after.end), factory.createToken(SyntaxKind.SemicolonToken));
}
}
const endPosition = getAdjustedEndPosition(sourceFile, after, {});
@@ -562,25 +562,25 @@ namespace ts.textChanges {
const lparen = findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile);
if (lparen) {
// `() => {}` --> `function f() {}`
this.insertNodesAt(sourceFile, lparen.getStart(sourceFile), [createToken(SyntaxKind.FunctionKeyword), createIdentifier(name)], { joiner: " " });
this.insertNodesAt(sourceFile, lparen.getStart(sourceFile), [factory.createToken(SyntaxKind.FunctionKeyword), factory.createIdentifier(name)], { joiner: " " });
deleteNode(this, sourceFile, arrow);
}
else {
// `x => {}` -> `function f(x) {}`
this.insertText(sourceFile, first(node.parameters).getStart(sourceFile), `function ${name}(`);
// Replacing full range of arrow to get rid of the leading space -- replace ` =>` with `)`
this.replaceRange(sourceFile, arrow, createToken(SyntaxKind.CloseParenToken));
this.replaceRange(sourceFile, arrow, factory.createToken(SyntaxKind.CloseParenToken));
}
if (node.body.kind !== SyntaxKind.Block) {
// `() => 0` => `function f() { return 0; }`
this.insertNodesAt(sourceFile, node.body.getStart(sourceFile), [createToken(SyntaxKind.OpenBraceToken), createToken(SyntaxKind.ReturnKeyword)], { joiner: " ", suffix: " " });
this.insertNodesAt(sourceFile, node.body.end, [createToken(SyntaxKind.SemicolonToken), createToken(SyntaxKind.CloseBraceToken)], { joiner: " " });
this.insertNodesAt(sourceFile, node.body.getStart(sourceFile), [factory.createToken(SyntaxKind.OpenBraceToken), factory.createToken(SyntaxKind.ReturnKeyword)], { joiner: " ", suffix: " " });
this.insertNodesAt(sourceFile, node.body.end, [factory.createToken(SyntaxKind.SemicolonToken), factory.createToken(SyntaxKind.CloseBraceToken)], { joiner: " " });
}
}
else {
const pos = findChildOfKind(node, node.kind === SyntaxKind.FunctionExpression ? SyntaxKind.FunctionKeyword : SyntaxKind.ClassKeyword, sourceFile)!.end;
this.insertNodeAt(sourceFile, pos, createIdentifier(name), { prefix: " " });
this.insertNodeAt(sourceFile, pos, factory.createIdentifier(name), { prefix: " " });
}
}
@@ -688,7 +688,7 @@ namespace ts.textChanges {
}
if (multilineList) {
// insert separator immediately following the 'after' node to preserve comments in trailing trivia
this.replaceRange(sourceFile, createRange(end), createToken(separator));
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);
// insert element before the line break on the line that contains 'after' element
@@ -705,7 +705,7 @@ namespace ts.textChanges {
}
public parenthesizeExpression(sourceFile: SourceFile, expression: Expression) {
this.replaceRange(sourceFile, rangeOfNode(expression), createParen(expression));
this.replaceRange(sourceFile, rangeOfNode(expression), factory.createParen(expression));
}
private finishClassesWithNodesInsertedAtStart(): void {
@@ -1250,7 +1250,7 @@ namespace ts.textChanges {
switch (gp.kind) {
case SyntaxKind.ForOfStatement:
case SyntaxKind.ForInStatement:
changes.replaceNode(sourceFile, node, createObjectLiteral());
changes.replaceNode(sourceFile, node, factory.createObjectLiteral());
break;
case SyntaxKind.ForStatement:
+1 -1
View File
@@ -9,7 +9,7 @@ namespace ts {
const diagnostics: DiagnosticWithLocation[] = [];
compilerOptions = fixupCompilerOptions(compilerOptions!, diagnostics); // TODO: GH#18217
const nodes = isArray(source) ? source : [source];
const result = transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, syntheticNodeFactory, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true);
const result = transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, factory, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true);
result.diagnostics = concatenate(result.diagnostics, diagnostics);
return result;
}
+1 -2
View File
@@ -94,7 +94,6 @@
"services.ts",
"breakpoints.ts",
"transform.ts",
"shims.ts",
"factoryCompat.ts",
"shims.ts"
]
}
+5 -5
View File
@@ -1301,17 +1301,17 @@ namespace ts {
}
export function makeImport(defaultImport: Identifier | undefined, namedImports: ReadonlyArray<ImportSpecifier> | undefined, moduleSpecifier: string | Expression, quotePreference: QuotePreference): ImportDeclaration {
return createImportDeclaration(
return factory.createImportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
defaultImport || namedImports
? createImportClause(defaultImport, namedImports && namedImports.length ? createNamedImports(namedImports) : undefined)
? factory.createImportClause(defaultImport, namedImports && namedImports.length ? factory.createNamedImports(namedImports) : undefined)
: undefined,
typeof moduleSpecifier === "string" ? makeStringLiteral(moduleSpecifier, quotePreference) : moduleSpecifier);
}
export function makeStringLiteral(text: string, quotePreference: QuotePreference): StringLiteral {
return createLiteral(text, quotePreference === QuotePreference.Single);
return factory.createStringLiteral(text, quotePreference === QuotePreference.Single);
}
export const enum QuotePreference { Single, Double }
@@ -1711,7 +1711,7 @@ namespace ts {
const renameInfo = symbol && renameMap.get(String(getSymbolId(symbol)));
if (renameInfo && renameInfo.text !== (node.name || node.propertyName).getText()) {
clone = createBindingElement(
clone = factory.createBindingElement(
node.dotDotDotToken,
node.propertyName || node.name,
renameInfo,
@@ -1723,7 +1723,7 @@ namespace ts {
const renameInfo = symbol && renameMap.get(String(getSymbolId(symbol)));
if (renameInfo) {
clone = createIdentifier(renameInfo.text);
clone = factory.createIdentifier(renameInfo.text);
}
}
+1
View File
@@ -18,6 +18,7 @@
{ "path": "../promiseShim", "prepend": true },
{ "path": "../compiler", "prepend": true },
{ "path": "../services", "prepend": true },
{ "path": "../compat", "prepend": true },
{ "path": "../jsTyping", "prepend": true },
{ "path": "../server", "prepend": true },
{ "path": "../typingsInstallerCore", "prepend": true },
+6 -3
View File
@@ -144,15 +144,18 @@ namespace ts {
}
let plugins: ReadonlyArray<CompilerPlugin> | undefined;
if (configParseResult.plugins) {
if (sys.require) {
if (sys.require && sys.registerModule) {
const result = getPlugins(sys as ModuleLoaderHost, getDirectoryPath(configFileName), configParseResult.plugins);
plugins = result.plugins;
if (some(result.diagnostics)) {
// TODO(rbuckton): report diagnostics
forEach(result.diagnostics, reportDiagnostic);
}
if (some(plugins)) {
registerPluginApiModules(sys as ModuleLoaderHost);
}
}
else {
// TODO(rbuckton): report diagnostic
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Plugins_are_not_supported_in_the_current_host_environment));
}
}
updateReportDiagnostic(configParseResult.options);
+2 -1
View File
@@ -10,6 +10,7 @@
{ "path": "../compiler", "prepend": true },
{ "path": "../jsTyping", "prepend": true },
{ "path": "../services", "prepend": true },
{ "path": "../server", "prepend": true }
{ "path": "../server", "prepend": true },
{ "path": "../compat", "prepend": true }
]
}
+2 -1
View File
@@ -9,6 +9,7 @@
"references": [
{ "path": "../compiler", "prepend": true },
{ "path": "../jsTyping", "prepend": true },
{ "path": "../services", "prepend": true }
{ "path": "../services", "prepend": true },
{ "path": "../compat", "prepend": true }
]
}
@@ -20,6 +20,7 @@
"transformFlags": 0,
"escapedText": "param"
},
"comment": "Doc doc",
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 34,
@@ -32,8 +33,8 @@
"end": 64,
"modifierFlagsCache": 0,
"transformFlags": 0,
"jsDocPropertyTags": [
{
"jsDocPropertyTags": {
"0": {
"kind": "JSDocParameterTag",
"pos": 34,
"end": 64,
@@ -47,6 +48,7 @@
"transformFlags": 0,
"escapedText": "param"
},
"comment": "Doc for f",
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 41,
@@ -85,10 +87,12 @@
}
},
"isNameFirst": false,
"isBracketed": false,
"comment": "Doc for f"
}
],
"isBracketed": false
},
"length": 1,
"pos": -1,
"end": -1
},
"isArrayType": false
}
},
@@ -101,8 +105,7 @@
"escapedText": "o"
},
"isNameFirst": true,
"isBracketed": false,
"comment": "Doc doc"
"isBracketed": false
},
"length": 1,
"pos": 6,
@@ -20,6 +20,7 @@
"transformFlags": 0,
"escapedText": "arg"
},
"comment": "Description",
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 13,
@@ -43,8 +44,7 @@
"escapedText": "name1"
},
"isNameFirst": false,
"isBracketed": false,
"comment": "Description"
"isBracketed": false
},
"length": 1,
"pos": 8,
@@ -20,6 +20,7 @@
"transformFlags": 0,
"escapedText": "argument"
},
"comment": "Description",
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 18,
@@ -43,8 +44,7 @@
"escapedText": "name1"
},
"isNameFirst": false,
"isBracketed": false,
"comment": "Description"
"isBracketed": false
},
"length": 1,
"pos": 8,
@@ -20,6 +20,7 @@
"transformFlags": 0,
"escapedText": "param"
},
"comment": "hi\n< > still part of the previous comment",
"name": {
"kind": "Identifier",
"pos": 14,
@@ -29,8 +30,7 @@
"escapedText": "x"
},
"isNameFirst": true,
"isBracketed": false,
"comment": "hi\n< > still part of the previous comment"
"isBracketed": false
},
"length": 1,
"pos": 7,
@@ -20,6 +20,7 @@
"transformFlags": 0,
"escapedText": "param"
},
"comment": "Description text follows",
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 15,
@@ -43,8 +44,7 @@
"escapedText": "name1"
},
"isNameFirst": false,
"isBracketed": false,
"comment": "Description text follows"
"isBracketed": false
},
"length": 1,
"pos": 8,
@@ -20,6 +20,7 @@
"transformFlags": 0,
"escapedText": "param"
},
"comment": "Description text follows",
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 15,
@@ -43,8 +44,7 @@
"escapedText": "name1"
},
"isNameFirst": false,
"isBracketed": true,
"comment": "Description text follows"
"isBracketed": true
},
"length": 1,
"pos": 8,
@@ -20,6 +20,7 @@
"transformFlags": 0,
"escapedText": "param"
},
"comment": "Description text follows",
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 15,
@@ -43,8 +44,7 @@
"escapedText": "name1"
},
"isNameFirst": false,
"isBracketed": true,
"comment": "Description text follows"
"isBracketed": true
},
"length": 1,
"pos": 8,
@@ -20,6 +20,7 @@
"transformFlags": 0,
"escapedText": "param"
},
"comment": "Description",
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 21,
@@ -43,8 +44,7 @@
"escapedText": "name1"
},
"isNameFirst": true,
"isBracketed": false,
"comment": "Description"
"isBracketed": false
},
"length": 1,
"pos": 8,
@@ -21,6 +21,7 @@
"originalKeywordKind": "ReturnKeyword",
"escapedText": "return"
},
"comment": "Description text follows",
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 16,
@@ -34,8 +35,7 @@
"modifierFlagsCache": 0,
"transformFlags": 0
}
},
"comment": "Description text follows"
}
},
"length": 1,
"pos": 8,
@@ -20,6 +20,7 @@
"transformFlags": 0,
"escapedText": "template"
},
"comment": "Description of type parameters.",
"typeParameters": {
"0": {
"kind": "TypeParameter",
@@ -54,8 +55,7 @@
"length": 2,
"pos": 18,
"end": 24
},
"comment": "Description of type parameters."
}
},
"length": 1,
"pos": 8,
@@ -26,8 +26,8 @@
"end": 100,
"modifierFlagsCache": 0,
"transformFlags": 0,
"jsDocPropertyTags": [
{
"jsDocPropertyTags": {
"0": {
"kind": "JSDocPropertyTag",
"pos": 47,
"end": 74,
@@ -66,7 +66,7 @@
"isNameFirst": false,
"isBracketed": false
},
{
"1": {
"kind": "JSDocPropertyTag",
"pos": 74,
"end": 100,
@@ -104,8 +104,11 @@
},
"isNameFirst": false,
"isBracketed": false
}
]
},
"length": 2,
"pos": -1,
"end": -1
}
},
"fullName": {
"kind": "Identifier",