Skip to content

Commit a8b789c

Browse files
committed
Move UnparsedSource nodes to factory
1 parent 922ab41 commit a8b789c

24 files changed

+612
-462
lines changed

Diff for: src/compat/factory.ts renamed to src/compat/deprecations.ts

+57-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
namespace ts {
2-
// #region Node Factory compat (deprecated since 3.8)
2+
// The following are deprecations for the public API. Deprecated exports are removed from the compiler itself
3+
// and compatible implementations are added here, along with an appropriate deprecation warning using
4+
// the `@deprecated` JSDoc tag as well as the `Debug.deprecateExport` API.
5+
//
6+
// Deprecations fall into one of three categories:
7+
//
8+
// * "soft" - Soft deprecations are indicated with the `@deprecated` JSDoc Tag.
9+
// * "warn" - Warning deprecations are indicated with the `@deprecated` JSDoc Tag and a diagnostic message (assuming a compatible host)
10+
// * "error" - Error deprecations are indicated with the `@deprecated` JSDoc tag and will throw a `TypeError` when invoked.
11+
12+
// DEPRECATION: Node factory top-level exports
13+
// DEPRECATION PLAN:
14+
// - soft: 3.8
15+
// - warn: 3.9
16+
// - error: TBD
17+
// #region Node factory top-level exports
318

419
// #region export const { ... } = factory;
520
// NOTE: These exports are deprecated in favor of using a `NodeFactory` instance and exist here purely for backwards compatibility reasons.
@@ -1380,7 +1395,7 @@ namespace ts {
13801395
initializer?: Expression
13811396
): PropertySignature {
13821397
const node = factory.createPropertySignature(modifiers, name, questionToken, type);
1383-
node.initializer = initializer;
1398+
factory.trackExtraneousChildNode(node, node.initializer = initializer);
13841399
return node;
13851400
}
13861401

@@ -1395,13 +1410,14 @@ namespace ts {
13951410
type: TypeNode | undefined,
13961411
initializer: Expression | undefined
13971412
) {
1398-
return node.modifiers !== modifiers
1399-
|| node.name !== name
1400-
|| node.questionToken !== questionToken
1401-
|| node.type !== type
1402-
|| node.initializer !== initializer
1403-
? updateNode(createPropertySignature(modifiers, name, questionToken, type, initializer), node)
1404-
: node;
1413+
let updated = factory.updatePropertySignature(node, modifiers, name, questionToken, type);
1414+
if (node.initializer !== initializer) {
1415+
if (updated === node) {
1416+
updated = factory.cloneNode(node);
1417+
}
1418+
factory.trackExtraneousChildNode(updated, updated.initializer = initializer);
1419+
}
1420+
return updated;
14051421
}
14061422

14071423
/**
@@ -1905,9 +1921,38 @@ namespace ts {
19051921
warnAfter: "3.9"
19061922
});
19071923

1908-
// #endregion NodeFactory compat (deprecated in 3.8)
1924+
Debug.deprecateExport(ts, "createNode", {
1925+
message: "Use an appropriate `factory` method instead.",
1926+
since: "3.8",
1927+
warnAfter: "3.9"
1928+
});
1929+
1930+
/**
1931+
* Creates a shallow, memberwise clone of a node for mutation.
1932+
* @deprecated Use `factory.cloneNode` instead and set `pos`, `end`, and `parent` as needed.
1933+
*/
1934+
export function getMutableClone<T extends Node>(node: T): T {
1935+
const clone = factory.cloneNode(node);
1936+
clone.pos = node.pos;
1937+
clone.end = node.end;
1938+
clone.parent = node.parent;
1939+
return clone;
1940+
}
1941+
1942+
Debug.deprecateExport(ts, "getMutableClone", {
1943+
message: "Use `factory.cloneNode` instead and set `pos`, `end`, and `parent` as needed.",
1944+
since: "3.8",
1945+
warnAfter: "3.9"
1946+
});
1947+
1948+
// #endregion Node Factory top-level exports
19091949

1910-
// #region Node Test compat (deprecated since 3.8)
1950+
// DEPRECATION: Renamed node tests
1951+
// DEPRECATION PLAN:
1952+
// - soft: 3.8
1953+
// - warn: 3.9
1954+
// - error: TBD
1955+
// #region Renamed node Tests
19111956
/**
19121957
* @deprecated Use `isTypeAssertionExpression` instead.
19131958
*/
@@ -1921,5 +1966,5 @@ namespace ts {
19211966
warnAfter: "3.9"
19221967
});
19231968

1924-
// #endregion NodeTest compat (deprecated since 3.8)
1969+
// #endregion Renamed node Tests
19251970
}

Diff for: src/compat/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
{ "path": "../compiler" }
88
],
99
"files": [
10-
"factory.ts"
10+
"deprecations.ts"
1111
]
1212
}

Diff for: src/compiler/checker.ts

+12-15
Original file line numberDiff line numberDiff line change
@@ -4450,12 +4450,12 @@ namespace ts {
44504450
}
44514451
const parameterTypeNode = typeToTypeNodeHelper(parameterType, context);
44524452

4453-
const modifiers = !(context.flags & NodeBuilderFlags.OmitParameterModifiers) && preserveModifierFlags && parameterDeclaration && parameterDeclaration.modifiers ? parameterDeclaration.modifiers.map(getSynthesizedClone) : undefined;
4453+
const modifiers = !(context.flags & NodeBuilderFlags.OmitParameterModifiers) && preserveModifierFlags && parameterDeclaration && parameterDeclaration.modifiers ? parameterDeclaration.modifiers.map(factory.cloneNode) : undefined;
44544454
const isRest = parameterDeclaration && isRestParameter(parameterDeclaration) || getCheckFlags(parameterSymbol) & CheckFlags.RestParameter;
44554455
const dotDotDotToken = isRest ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined;
44564456
const name = parameterDeclaration ? parameterDeclaration.name ?
4457-
parameterDeclaration.name.kind === SyntaxKind.Identifier ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) :
4458-
parameterDeclaration.name.kind === SyntaxKind.QualifiedName ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name.right), EmitFlags.NoAsciiEscaping) :
4457+
parameterDeclaration.name.kind === SyntaxKind.Identifier ? setEmitFlags(factory.cloneNode(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) :
4458+
parameterDeclaration.name.kind === SyntaxKind.QualifiedName ? setEmitFlags(factory.cloneNode(parameterDeclaration.name.right), EmitFlags.NoAsciiEscaping) :
44594459
cloneBindingName(parameterDeclaration.name) :
44604460
symbolName(parameterSymbol) :
44614461
symbolName(parameterSymbol);
@@ -4479,7 +4479,7 @@ namespace ts {
44794479
trackComputedName(node.expression, context.enclosingDeclaration, context);
44804480
}
44814481
const visited = visitEachChild(node, elideInitializerAndSetEmitFlags, nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags)!;
4482-
const clone = nodeIsSynthesized(visited) ? visited : getSynthesizedClone(visited);
4482+
const clone = nodeIsSynthesized(visited) ? visited : factory.cloneNode(visited);
44834483
if (clone.kind === SyntaxKind.BindingElement) {
44844484
(<BindingElement>clone).initializer = undefined;
44854485
}
@@ -5935,7 +5935,7 @@ namespace ts {
59355935
// try to reuse the existing annotation
59365936
const existing = getEffectiveTypeAnnotationNode(declWithExistingAnnotation)!;
59375937
const transformed = visitNode(existing, visitExistingNodeTreeSymbols);
5938-
return transformed === existing ? getMutableClone(existing) : transformed;
5938+
return transformed === existing ? setTextRange(factory.cloneNode(existing), existing) : transformed;
59395939
}
59405940
const oldFlags = context.flags;
59415941
if (type.flags & TypeFlags.UniqueESSymbol &&
@@ -6689,13 +6689,10 @@ namespace ts {
66896689
if (parentAccess && parentAccess.flowNode) {
66906690
const propName = getDestructuringPropertyName(node);
66916691
if (propName) {
6692-
const result = <ElementAccessExpression>createNode(SyntaxKind.ElementAccessExpression, node.pos, node.end);
6693-
result.parent = node;
6694-
result.expression = <LeftHandSideExpression>parentAccess;
6695-
const literal = <StringLiteral>createNode(SyntaxKind.StringLiteral, node.pos, node.end);
6692+
const literal = setTextRange(parseNodeFactory.createStringLiteral(propName), node);
6693+
const result = setTextRange(parseNodeFactory.createElementAccess(parentAccess, literal), node);
66966694
literal.parent = result;
6697-
literal.text = propName;
6698-
result.argumentExpression = literal;
6695+
result.parent = node;
66996696
result.flowNode = parentAccess.flowNode;
67006697
return result;
67016698
}
@@ -20231,7 +20228,8 @@ namespace ts {
2023120228
if (returnType && returnType.flags & TypeFlags.Union) {
2023220229
const unionTypes = (<UnionTypeNode>funcTypeNode.type).types;
2023320230
if (unionTypes && unionTypes[unionTypes.length - 1].kind === SyntaxKind.UndefinedKeyword) {
20234-
const parenedFuncType = getMutableClone(funcTypeNode);
20231+
// TODO(rbuckton): Does this need to be parented?
20232+
const parenedFuncType = setParent(setTextRange(factory.cloneNode(funcTypeNode), funcTypeNode), funcTypeNode.parent);
2023520233
// Highlight to the end of the second to last constituent of the union
2023620234
parenedFuncType.end = unionTypes[unionTypes.length - 2].end;
2023720235
addRelatedInfo(diag, createDiagnosticForNode(parenedFuncType, Diagnostics.Did_you_mean_to_parenthesize_this_function_type));
@@ -23901,10 +23899,9 @@ namespace ts {
2390123899
}
2390223900

2390323901
function createSyntheticExpression(parent: Node, type: Type, isSpread?: boolean) {
23904-
const result = <SyntheticExpression>createNode(SyntaxKind.SyntheticExpression, parent.pos, parent.end);
23902+
const result = parseNodeFactory.createSyntheticExpression(type, isSpread);
23903+
setTextRange(result, parent);
2390523904
result.parent = parent;
23906-
result.type = type;
23907-
result.isSpread = isSpread || false;
2390823905
return result;
2390923906
}
2391023907

Diff for: src/compiler/emitter.ts

+21-17
Original file line numberDiff line numberDiff line change
@@ -674,30 +674,34 @@ namespace ts {
674674
}
675675

676676
function createSourceFilesFromBundleBuildInfo(bundle: BundleBuildInfo, buildInfoDirectory: string, host: EmitUsingBuildInfoHost): readonly SourceFile[] {
677-
const sourceFiles = bundle.sourceFiles.map(fileName => {
678-
const sourceFile = createNode(SyntaxKind.SourceFile, 0, 0) as SourceFile;
677+
const jsBundle = Debug.assertDefined(bundle.js);
678+
const prologueMap = jsBundle.sources?.prologues && arrayToMap(jsBundle.sources.prologues, prologueInfo => "" + prologueInfo.file);
679+
return bundle.sourceFiles.map((fileName, index) => {
680+
const prologueInfo = prologueMap?.get("" + index);
681+
const statements = prologueInfo?.directives.map(directive => {
682+
const literal = setTextRange(factory.createStringLiteral(directive.expression.text), directive.expression);
683+
const statement = setTextRange(factory.createExpressionStatement(literal), directive);
684+
literal.parent = statement;
685+
return statement;
686+
});
687+
const eofToken = factory.createToken(SyntaxKind.EndOfFileToken);
688+
const sourceFile = factory.createSourceFile(statements ?? [], eofToken);
679689
sourceFile.fileName = getRelativePathFromDirectory(
680690
host.getCurrentDirectory(),
681691
getNormalizedAbsolutePath(fileName, buildInfoDirectory),
682692
!host.useCaseSensitiveFileNames()
683693
);
684-
sourceFile.text = "";
685-
sourceFile.statements = factory.createNodeArray();
694+
sourceFile.text = prologueInfo?.text ?? "";
695+
sourceFile.pos = 0;
696+
sourceFile.end = prologueInfo?.text.length ?? 0;
697+
for (const statement of sourceFile.statements) {
698+
statement.parent = sourceFile;
699+
}
700+
eofToken.pos = sourceFile.end;
701+
eofToken.end = sourceFile.end;
702+
eofToken.parent = sourceFile;
686703
return sourceFile;
687704
});
688-
const jsBundle = Debug.assertDefined(bundle.js);
689-
forEach(jsBundle.sources && jsBundle.sources.prologues, prologueInfo => {
690-
const sourceFile = sourceFiles[prologueInfo.file];
691-
sourceFile.text = prologueInfo.text;
692-
sourceFile.end = prologueInfo.text.length;
693-
sourceFile.statements = factory.createNodeArray(prologueInfo.directives.map(directive => {
694-
const statement = createNode(SyntaxKind.ExpressionStatement, directive.pos, directive.end) as PrologueDirective;
695-
statement.expression = createNode(SyntaxKind.StringLiteral, directive.expression.pos, directive.expression.end) as StringLiteral;
696-
statement.expression.text = directive.expression.text;
697-
return statement;
698-
}));
699-
});
700-
return sourceFiles;
701705
}
702706

703707
/*@internal*/

0 commit comments

Comments
 (0)