Refactor emit substitution into transform (#42676)
* Refactor emit substitution into transform * Add reusable state machine for binary expressions * Allow emitBinary to use state machine for comments/sourcemaps * Switch core trampoline state back to arrays * Switch binder to parallel stacks, temporarily partially revert emitBinary * Add link to benchmark when posting perf results * Ensure work stacks are per-execution * Reenable comments and sourcemaps
This commit is contained in:
parent
df5ffc0ea1
commit
68b0323b72
|
@ -3,45 +3,86 @@
|
|||
// Must reference esnext.asynciterable lib, since octokit uses AsyncIterable internally
|
||||
const { Octokit } = require("@octokit/rest");
|
||||
const fs = require("fs");
|
||||
const ado = require("azure-devops-node-api");
|
||||
const { default: fetch } = require("node-fetch");
|
||||
|
||||
const requester = process.env.requesting_user;
|
||||
const source = process.env.source_issue;
|
||||
const postedComment = process.env.status_comment;
|
||||
console.log(`Loading fragment from ${process.argv[3]}...`);
|
||||
const outputTableText = fs.readFileSync(process.argv[3], { encoding: "utf8" });
|
||||
console.log(`Fragment contents:
|
||||
${outputTableText}`);
|
||||
|
||||
const gh = new Octokit({
|
||||
auth: process.argv[2]
|
||||
});
|
||||
gh.issues.createComment({
|
||||
issue_number: +source,
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
body: `@${requester}
|
||||
The results of the perf run you requested are in!
|
||||
<details><summary> Here they are:</summary><p>
|
||||
${outputTableText}
|
||||
</p></details>`
|
||||
}).then(async data => {
|
||||
console.log(`Results posted!`);
|
||||
const newCommentUrl = data.data.html_url;
|
||||
const comment = await gh.issues.getComment({
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
comment_id: +postedComment
|
||||
});
|
||||
const newBody = `${comment.data.body}
|
||||
async function main() {
|
||||
const source = process.env.SOURCE_ISSUE;
|
||||
if (!source) throw new Error("SOURCE_ISSUE environment variable not set.");
|
||||
|
||||
Update: [The results are in!](${newCommentUrl})`;
|
||||
return await gh.issues.updateComment({
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
comment_id: +postedComment,
|
||||
body: newBody
|
||||
});
|
||||
}).catch(e => {
|
||||
const requester = process.env.REQUESTING_USER;
|
||||
if (!requester) throw new Error("REQUESTING_USER environment variable not set.");
|
||||
|
||||
const buildId = process.env.BUILD_BUILDID;
|
||||
if (!requester) throw new Error("BUILD_BUILDID environment variable not set.");
|
||||
|
||||
const postedComment = process.env.STATUS_COMMENT;
|
||||
if (!postedComment) throw new Error("STATUS_COMMENT environment variable not set.");
|
||||
|
||||
const [auth, fragment, includeArtifact] = process.argv.slice(2);
|
||||
if (!auth) throw new Error("First argument must be a GitHub auth token.");
|
||||
if (!fragment) throw new Error("Second argument must be a path to an HTML fragment.");
|
||||
|
||||
const gh = new Octokit({ auth });
|
||||
try {
|
||||
console.log(`Loading fragment from ${fragment}...`);
|
||||
const outputTableText = fs.readFileSync(fragment, { encoding: "utf8" });
|
||||
console.log(`Fragment contents:\n${outputTableText}`);
|
||||
|
||||
let benchmarkText = "";
|
||||
if (includeArtifact === "--include-artifact") {
|
||||
// post a link to the benchmark file
|
||||
const cli = new ado.WebApi("https://typescript.visualstudio.com/defaultcollection", ado.getHandlerFromToken("")); // Empty token, anon auth
|
||||
const build = await cli.getBuildApi();
|
||||
const artifact = await build.getArtifact("typescript", +buildId, "benchmark");
|
||||
const updatedUrl = new URL(artifact.resource.url);
|
||||
updatedUrl.search = `artifactName=benchmark&fileId=${artifact.resource.data}&fileName=manifest`;
|
||||
const resp = await (await fetch(`${updatedUrl}`)).json();
|
||||
for (const file of resp.items) {
|
||||
if (/[\\/]linux\.benchmark$/.test(file.path)) {
|
||||
const benchmarkUrl = new URL(artifact.resource.url);
|
||||
benchmarkUrl.search = `artifactName=benchmark&fileId=${file.blob.id}&fileName=linux.benchmark`;
|
||||
benchmarkText = `\n<details><summary>Developer Information:</summary><p><a href="${benchmarkUrl.href}">Download Benchmark</a></p></details>\n`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const data = await gh.issues.createComment({
|
||||
issue_number: +source,
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
body: `@${requester}\nThe results of the perf run you requested are in!\n<details><summary> Here they are:</summary><p>\n${outputTableText}\n</p>${benchmarkText}</details>`
|
||||
});
|
||||
|
||||
console.log(`Results posted!`);
|
||||
const newCommentUrl = data.data.html_url;
|
||||
const comment = await gh.issues.getComment({
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
comment_id: +postedComment
|
||||
});
|
||||
const newBody = `${comment.data.body}\n\nUpdate: [The results are in!](${newCommentUrl})`;
|
||||
await gh.issues.updateComment({
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
comment_id: +postedComment,
|
||||
body: newBody
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
const gh = new Octokit({ auth });
|
||||
await gh.issues.createComment({
|
||||
issue_number: +source,
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
body: `Hey @${requester}, something went wrong when publishing results. ([You can check the log here](https://typescript.visualstudio.com/TypeScript/_build/index?buildId=${buildId}&_a=summary)).`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
|
@ -227,6 +227,7 @@ namespace ts {
|
|||
|
||||
const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable };
|
||||
const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable };
|
||||
const bindBinaryExpressionFlow = createBindBinaryExpressionFlow();
|
||||
|
||||
/**
|
||||
* Inside the binder, we may create a diagnostic for an as-yet unbound node (with potentially no parent pointers, implying no accessible source file)
|
||||
|
@ -1497,132 +1498,110 @@ namespace ts {
|
|||
bindAssignmentTargetFlow(node.left);
|
||||
}
|
||||
|
||||
const enum BindBinaryExpressionFlowState {
|
||||
BindThenBindChildren,
|
||||
MaybeBindLeft,
|
||||
BindToken,
|
||||
BindRight,
|
||||
FinishBind
|
||||
}
|
||||
|
||||
function bindBinaryExpressionFlow(node: BinaryExpression) {
|
||||
const workStacks: {
|
||||
expr: BinaryExpression[],
|
||||
state: BindBinaryExpressionFlowState[],
|
||||
inStrictMode: (boolean | undefined)[],
|
||||
parent: (Node | undefined)[],
|
||||
} = {
|
||||
expr: [node],
|
||||
state: [BindBinaryExpressionFlowState.MaybeBindLeft],
|
||||
inStrictMode: [undefined],
|
||||
parent: [undefined],
|
||||
};
|
||||
let stackIndex = 0;
|
||||
while (stackIndex >= 0) {
|
||||
node = workStacks.expr[stackIndex];
|
||||
switch (workStacks.state[stackIndex]) {
|
||||
case BindBinaryExpressionFlowState.BindThenBindChildren: {
|
||||
// This state is used only when recuring, to emulate the work that `bind` does before
|
||||
// reaching `bindChildren`. A normal call to `bindBinaryExpressionFlow` will already have done this work.
|
||||
setParent(node, parent);
|
||||
const saveInStrictMode = inStrictMode;
|
||||
bindWorker(node);
|
||||
const saveParent = parent;
|
||||
parent = node;
|
||||
|
||||
advanceState(BindBinaryExpressionFlowState.MaybeBindLeft, saveInStrictMode, saveParent);
|
||||
break;
|
||||
}
|
||||
case BindBinaryExpressionFlowState.MaybeBindLeft: {
|
||||
const operator = node.operatorToken.kind;
|
||||
// TODO: bindLogicalExpression is recursive - if we want to handle deeply nested `&&` expressions
|
||||
// we'll need to handle the `bindLogicalExpression` scenarios in this state machine, too
|
||||
// For now, though, since the common cases are chained `+`, leaving it recursive is fine
|
||||
if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken ||
|
||||
isLogicalOrCoalescingAssignmentOperator(operator)) {
|
||||
if (isTopLevelLogicalExpression(node)) {
|
||||
const postExpressionLabel = createBranchLabel();
|
||||
bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel);
|
||||
currentFlow = finishFlowLabel(postExpressionLabel);
|
||||
}
|
||||
else {
|
||||
bindLogicalLikeExpression(node, currentTrueTarget!, currentFalseTarget!);
|
||||
}
|
||||
completeNode();
|
||||
}
|
||||
else {
|
||||
advanceState(BindBinaryExpressionFlowState.BindToken);
|
||||
maybeBind(node.left);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BindBinaryExpressionFlowState.BindToken: {
|
||||
if (node.operatorToken.kind === SyntaxKind.CommaToken) {
|
||||
maybeBindExpressionFlowIfCall(node.left);
|
||||
}
|
||||
advanceState(BindBinaryExpressionFlowState.BindRight);
|
||||
maybeBind(node.operatorToken);
|
||||
break;
|
||||
}
|
||||
case BindBinaryExpressionFlowState.BindRight: {
|
||||
advanceState(BindBinaryExpressionFlowState.FinishBind);
|
||||
maybeBind(node.right);
|
||||
break;
|
||||
}
|
||||
case BindBinaryExpressionFlowState.FinishBind: {
|
||||
const operator = node.operatorToken.kind;
|
||||
if (isAssignmentOperator(operator) && !isAssignmentTarget(node)) {
|
||||
bindAssignmentTargetFlow(node.left);
|
||||
if (operator === SyntaxKind.EqualsToken && node.left.kind === SyntaxKind.ElementAccessExpression) {
|
||||
const elementAccess = <ElementAccessExpression>node.left;
|
||||
if (isNarrowableOperand(elementAccess.expression)) {
|
||||
currentFlow = createFlowMutation(FlowFlags.ArrayMutation, currentFlow, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
completeNode();
|
||||
break;
|
||||
}
|
||||
default: return Debug.fail(`Invalid state ${workStacks.state[stackIndex]} for bindBinaryExpressionFlow`);
|
||||
}
|
||||
function createBindBinaryExpressionFlow() {
|
||||
interface WorkArea {
|
||||
stackIndex: number;
|
||||
skip: boolean;
|
||||
inStrictModeStack: (boolean | undefined)[];
|
||||
parentStack: (Node | undefined)[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that `advanceState` sets the _current_ head state, and that `maybeBind` potentially pushes on a new
|
||||
* head state; so `advanceState` must be called before any `maybeBind` during a state's execution.
|
||||
*/
|
||||
function advanceState(state: BindBinaryExpressionFlowState, isInStrictMode?: boolean, parent?: Node) {
|
||||
workStacks.state[stackIndex] = state;
|
||||
if (isInStrictMode !== undefined) {
|
||||
workStacks.inStrictMode[stackIndex] = isInStrictMode;
|
||||
}
|
||||
if (parent !== undefined) {
|
||||
workStacks.parent[stackIndex] = parent;
|
||||
}
|
||||
}
|
||||
return createBinaryExpressionTrampoline(onEnter, onLeft, onOperator, onRight, onExit, /*foldState*/ undefined);
|
||||
|
||||
function completeNode() {
|
||||
if (workStacks.inStrictMode[stackIndex] !== undefined) {
|
||||
inStrictMode = workStacks.inStrictMode[stackIndex]!;
|
||||
parent = workStacks.parent[stackIndex]!;
|
||||
}
|
||||
stackIndex--;
|
||||
}
|
||||
|
||||
/**
|
||||
* If `node` is a BinaryExpression, adds it to the local work stack, otherwise recursively binds it
|
||||
*/
|
||||
function maybeBind(node: Node) {
|
||||
if (node && isBinaryExpression(node) && !isDestructuringAssignment(node)) {
|
||||
stackIndex++;
|
||||
workStacks.expr[stackIndex] = node;
|
||||
workStacks.state[stackIndex] = BindBinaryExpressionFlowState.BindThenBindChildren;
|
||||
workStacks.inStrictMode[stackIndex] = undefined;
|
||||
workStacks.parent[stackIndex] = undefined;
|
||||
function onEnter(node: BinaryExpression, state: WorkArea | undefined) {
|
||||
if (state) {
|
||||
state.stackIndex++;
|
||||
// Emulate the work that `bind` does before reaching `bindChildren`. A normal call to
|
||||
// `bindBinaryExpressionFlow` will already have done this work.
|
||||
setParent(node, parent);
|
||||
const saveInStrictMode = inStrictMode;
|
||||
bindWorker(node);
|
||||
const saveParent = parent;
|
||||
parent = node;
|
||||
state.skip = false;
|
||||
state.inStrictModeStack[state.stackIndex] = saveInStrictMode;
|
||||
state.parentStack[state.stackIndex] = saveParent;
|
||||
}
|
||||
else {
|
||||
bind(node);
|
||||
state = {
|
||||
stackIndex: 0,
|
||||
skip: false,
|
||||
inStrictModeStack: [undefined],
|
||||
parentStack: [undefined]
|
||||
};
|
||||
}
|
||||
// TODO: bindLogicalExpression is recursive - if we want to handle deeply nested `&&` expressions
|
||||
// we'll need to handle the `bindLogicalExpression` scenarios in this state machine, too
|
||||
// For now, though, since the common cases are chained `+`, leaving it recursive is fine
|
||||
const operator = node.operatorToken.kind;
|
||||
if (operator === SyntaxKind.AmpersandAmpersandToken ||
|
||||
operator === SyntaxKind.BarBarToken ||
|
||||
operator === SyntaxKind.QuestionQuestionToken ||
|
||||
isLogicalOrCoalescingAssignmentOperator(operator)) {
|
||||
if (isTopLevelLogicalExpression(node)) {
|
||||
const postExpressionLabel = createBranchLabel();
|
||||
bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel);
|
||||
currentFlow = finishFlowLabel(postExpressionLabel);
|
||||
}
|
||||
else {
|
||||
bindLogicalLikeExpression(node, currentTrueTarget!, currentFalseTarget!);
|
||||
}
|
||||
state.skip = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
function onLeft(left: Expression, state: WorkArea, _node: BinaryExpression) {
|
||||
if (!state.skip) {
|
||||
return maybeBind(left);
|
||||
}
|
||||
}
|
||||
|
||||
function onOperator(operatorToken: BinaryOperatorToken, state: WorkArea, node: BinaryExpression) {
|
||||
if (!state.skip) {
|
||||
if (operatorToken.kind === SyntaxKind.CommaToken) {
|
||||
maybeBindExpressionFlowIfCall(node.left);
|
||||
}
|
||||
bind(operatorToken);
|
||||
}
|
||||
}
|
||||
|
||||
function onRight(right: Expression, state: WorkArea, _node: BinaryExpression) {
|
||||
if (!state.skip) {
|
||||
return maybeBind(right);
|
||||
}
|
||||
}
|
||||
|
||||
function onExit(node: BinaryExpression, state: WorkArea) {
|
||||
if (!state.skip) {
|
||||
const operator = node.operatorToken.kind;
|
||||
if (isAssignmentOperator(operator) && !isAssignmentTarget(node)) {
|
||||
bindAssignmentTargetFlow(node.left);
|
||||
if (operator === SyntaxKind.EqualsToken && node.left.kind === SyntaxKind.ElementAccessExpression) {
|
||||
const elementAccess = <ElementAccessExpression>node.left;
|
||||
if (isNarrowableOperand(elementAccess.expression)) {
|
||||
currentFlow = createFlowMutation(FlowFlags.ArrayMutation, currentFlow, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const savedInStrictMode = state.inStrictModeStack[state.stackIndex];
|
||||
const savedParent = state.parentStack[state.stackIndex];
|
||||
if (savedInStrictMode !== undefined) {
|
||||
inStrictMode = savedInStrictMode;
|
||||
}
|
||||
if (savedParent !== undefined) {
|
||||
parent = savedParent;
|
||||
}
|
||||
state.skip = false;
|
||||
state.stackIndex--;
|
||||
}
|
||||
|
||||
function maybeBind(node: Node) {
|
||||
if (node && isBinaryExpression(node) && !isDestructuringAssignment(node)) {
|
||||
return node;
|
||||
}
|
||||
bind(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -275,6 +275,14 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts a value has the specified type in typespace only (does not perform a runtime assertion).
|
||||
* This is useful in cases where we switch on `node.kind` and can be reasonably sure the type is accurate, and
|
||||
* as a result can reduce the number of unnecessary casts.
|
||||
*/
|
||||
export function type<T>(value: unknown): asserts value is T;
|
||||
export function type(_value: unknown) { }
|
||||
|
||||
export function getFunctionName(func: AnyFunction) {
|
||||
if (typeof func !== "function") {
|
||||
return "";
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -39,12 +39,106 @@ namespace ts {
|
|||
return node.kind === SyntaxKind.TemplateTail;
|
||||
}
|
||||
|
||||
// Punctuation
|
||||
|
||||
export function isDotDotDotToken(node: Node): node is DotDotDotToken {
|
||||
return node.kind === SyntaxKind.DotDotDotToken;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isCommaToken(node: Node): node is Token<SyntaxKind.CommaToken> {
|
||||
return node.kind === SyntaxKind.CommaToken;
|
||||
}
|
||||
|
||||
export function isPlusToken(node: Node): node is PlusToken {
|
||||
return node.kind === SyntaxKind.PlusToken;
|
||||
}
|
||||
|
||||
export function isMinusToken(node: Node): node is MinusToken {
|
||||
return node.kind === SyntaxKind.MinusToken;
|
||||
}
|
||||
|
||||
export function isAsteriskToken(node: Node): node is AsteriskToken {
|
||||
return node.kind === SyntaxKind.AsteriskToken;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isExclamationToken(node: Node): node is ExclamationToken {
|
||||
return node.kind === SyntaxKind.ExclamationToken;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isQuestionToken(node: Node): node is QuestionToken {
|
||||
return node.kind === SyntaxKind.QuestionToken;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isColonToken(node: Node): node is ColonToken {
|
||||
return node.kind === SyntaxKind.ColonToken;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isQuestionDotToken(node: Node): node is QuestionDotToken {
|
||||
return node.kind === SyntaxKind.QuestionDotToken;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isEqualsGreaterThanToken(node: Node): node is EqualsGreaterThanToken {
|
||||
return node.kind === SyntaxKind.EqualsGreaterThanToken;
|
||||
}
|
||||
|
||||
// Identifiers
|
||||
|
||||
export function isIdentifier(node: Node): node is Identifier {
|
||||
return node.kind === SyntaxKind.Identifier;
|
||||
}
|
||||
|
||||
export function isPrivateIdentifier(node: Node): node is PrivateIdentifier {
|
||||
return node.kind === SyntaxKind.PrivateIdentifier;
|
||||
}
|
||||
|
||||
// Reserved Words
|
||||
|
||||
/* @internal */
|
||||
export function isExportModifier(node: Node): node is ExportKeyword {
|
||||
return node.kind === SyntaxKind.ExportKeyword;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isAsyncModifier(node: Node): node is AsyncKeyword {
|
||||
return node.kind === SyntaxKind.AsyncKeyword;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isAssertsKeyword(node: Node): node is AssertsKeyword {
|
||||
return node.kind === SyntaxKind.AssertsKeyword;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isAwaitKeyword(node: Node): node is AwaitKeyword {
|
||||
return node.kind === SyntaxKind.AwaitKeyword;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isReadonlyKeyword(node: Node): node is ReadonlyKeyword {
|
||||
return node.kind === SyntaxKind.ReadonlyKeyword;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isStaticModifier(node: Node): node is StaticKeyword {
|
||||
return node.kind === SyntaxKind.StaticKeyword;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isSuperKeyword(node: Node): node is SuperExpression {
|
||||
return node.kind === SyntaxKind.SuperKeyword;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isImportKeyword(node: Node): node is ImportExpression {
|
||||
return node.kind === SyntaxKind.ImportKeyword;
|
||||
}
|
||||
|
||||
// Names
|
||||
|
||||
export function isQualifiedName(node: Node): node is QualifiedName {
|
||||
|
@ -55,37 +149,6 @@ namespace ts {
|
|||
return node.kind === SyntaxKind.ComputedPropertyName;
|
||||
}
|
||||
|
||||
export function isPrivateIdentifier(node: Node): node is PrivateIdentifier {
|
||||
return node.kind === SyntaxKind.PrivateIdentifier;
|
||||
}
|
||||
|
||||
// Tokens
|
||||
|
||||
/*@internal*/
|
||||
export function isSuperKeyword(node: Node): node is Token<SyntaxKind.SuperKeyword> {
|
||||
return node.kind === SyntaxKind.SuperKeyword;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isImportKeyword(node: Node): node is Token<SyntaxKind.ImportKeyword> {
|
||||
return node.kind === SyntaxKind.ImportKeyword;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isCommaToken(node: Node): node is Token<SyntaxKind.CommaToken> {
|
||||
return node.kind === SyntaxKind.CommaToken;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isQuestionToken(node: Node): node is Token<SyntaxKind.QuestionToken> {
|
||||
return node.kind === SyntaxKind.QuestionToken;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isExclamationToken(node: Node): node is Token<SyntaxKind.ExclamationToken> {
|
||||
return node.kind === SyntaxKind.ExclamationToken;
|
||||
}
|
||||
|
||||
// Signature elements
|
||||
|
||||
export function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration {
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace ts {
|
|||
}
|
||||
else {
|
||||
const expression = setTextRange(
|
||||
isIdentifierOrPrivateIdentifier(memberName)
|
||||
isMemberName(memberName)
|
||||
? factory.createPropertyAccessExpression(target, memberName)
|
||||
: factory.createElementAccessExpression(target, memberName),
|
||||
memberName
|
||||
|
@ -412,7 +412,7 @@ namespace ts {
|
|||
const helperNames: string[] = [];
|
||||
for (const helper of helpers) {
|
||||
if (!helper.scoped) {
|
||||
const importName = (helper as UnscopedEmitHelper).importName;
|
||||
const importName = helper.importName;
|
||||
if (importName) {
|
||||
pushIfUnique(helperNames, importName);
|
||||
}
|
||||
|
@ -815,18 +815,300 @@ namespace ts {
|
|||
|| kind === SyntaxKind.ExportDeclaration;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isExportModifier(node: Modifier): node is ExportKeyword {
|
||||
return node.kind === SyntaxKind.ExportKeyword;
|
||||
export const isTypeNodeOrTypeParameterDeclaration = or(isTypeNode, isTypeParameterDeclaration) as (node: Node) => node is TypeNode | TypeParameterDeclaration;
|
||||
export const isQuestionOrExclamationToken = or(isQuestionToken, isExclamationToken) as (node: Node) => node is QuestionToken | ExclamationToken;
|
||||
export const isIdentifierOrThisTypeNode = or(isIdentifier, isThisTypeNode) as (node: Node) => node is Identifier | ThisTypeNode;
|
||||
export const isReadonlyKeywordOrPlusOrMinusToken = or(isReadonlyKeyword, isPlusToken, isMinusToken) as (node: Node) => node is ReadonlyKeyword | PlusToken | MinusToken;
|
||||
export const isQuestionOrPlusOrMinusToken = or(isQuestionToken, isPlusToken, isMinusToken) as (node: Node) => node is QuestionToken | PlusToken | MinusToken;
|
||||
export const isModuleName = or(isIdentifier, isStringLiteral) as (node: Node) => node is ModuleName;
|
||||
|
||||
export function isLiteralTypeLikeExpression(node: Node): node is NullLiteral | BooleanLiteral | LiteralExpression | PrefixUnaryExpression {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.NullKeyword
|
||||
|| kind === SyntaxKind.TrueKeyword
|
||||
|| kind === SyntaxKind.FalseKeyword
|
||||
|| isLiteralExpression(node)
|
||||
|| isPrefixUnaryExpression(node);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isAsyncModifier(node: Modifier): node is AsyncKeyword {
|
||||
return node.kind === SyntaxKind.AsyncKeyword;
|
||||
function isExponentiationOperator(kind: SyntaxKind): kind is ExponentiationOperator {
|
||||
return kind === SyntaxKind.AsteriskAsteriskToken;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isStaticModifier(node: Modifier): node is StaticKeyword {
|
||||
return node.kind === SyntaxKind.StaticKeyword;
|
||||
function isMultiplicativeOperator(kind: SyntaxKind): kind is MultiplicativeOperator {
|
||||
return kind === SyntaxKind.AsteriskToken
|
||||
|| kind === SyntaxKind.SlashToken
|
||||
|| kind === SyntaxKind.PercentToken;
|
||||
}
|
||||
|
||||
function isMultiplicativeOperatorOrHigher(kind: SyntaxKind): kind is MultiplicativeOperatorOrHigher {
|
||||
return isExponentiationOperator(kind)
|
||||
|| isMultiplicativeOperator(kind);
|
||||
}
|
||||
|
||||
function isAdditiveOperator(kind: SyntaxKind): kind is AdditiveOperator {
|
||||
return kind === SyntaxKind.PlusToken
|
||||
|| kind === SyntaxKind.MinusToken;
|
||||
}
|
||||
|
||||
function isAdditiveOperatorOrHigher(kind: SyntaxKind): kind is AdditiveOperatorOrHigher {
|
||||
return isAdditiveOperator(kind)
|
||||
|| isMultiplicativeOperatorOrHigher(kind);
|
||||
}
|
||||
|
||||
function isShiftOperator(kind: SyntaxKind): kind is ShiftOperator {
|
||||
return kind === SyntaxKind.LessThanLessThanToken
|
||||
|| kind === SyntaxKind.GreaterThanGreaterThanToken
|
||||
|| kind === SyntaxKind.GreaterThanGreaterThanGreaterThanToken;
|
||||
}
|
||||
|
||||
function isShiftOperatorOrHigher(kind: SyntaxKind): kind is ShiftOperatorOrHigher {
|
||||
return isShiftOperator(kind)
|
||||
|| isAdditiveOperatorOrHigher(kind);
|
||||
}
|
||||
|
||||
function isRelationalOperator(kind: SyntaxKind): kind is RelationalOperator {
|
||||
return kind === SyntaxKind.LessThanToken
|
||||
|| kind === SyntaxKind.LessThanEqualsToken
|
||||
|| kind === SyntaxKind.GreaterThanToken
|
||||
|| kind === SyntaxKind.GreaterThanEqualsToken
|
||||
|| kind === SyntaxKind.InstanceOfKeyword
|
||||
|| kind === SyntaxKind.InKeyword;
|
||||
}
|
||||
|
||||
function isRelationalOperatorOrHigher(kind: SyntaxKind): kind is RelationalOperatorOrHigher {
|
||||
return isRelationalOperator(kind)
|
||||
|| isShiftOperatorOrHigher(kind);
|
||||
}
|
||||
|
||||
function isEqualityOperator(kind: SyntaxKind): kind is EqualityOperator {
|
||||
return kind === SyntaxKind.EqualsEqualsToken
|
||||
|| kind === SyntaxKind.EqualsEqualsEqualsToken
|
||||
|| kind === SyntaxKind.ExclamationEqualsToken
|
||||
|| kind === SyntaxKind.ExclamationEqualsEqualsToken;
|
||||
}
|
||||
|
||||
function isEqualityOperatorOrHigher(kind: SyntaxKind): kind is EqualityOperatorOrHigher {
|
||||
return isEqualityOperator(kind)
|
||||
|| isRelationalOperatorOrHigher(kind);
|
||||
}
|
||||
|
||||
function isBitwiseOperator(kind: SyntaxKind): kind is BitwiseOperator {
|
||||
return kind === SyntaxKind.AmpersandToken
|
||||
|| kind === SyntaxKind.BarToken
|
||||
|| kind === SyntaxKind.CaretToken;
|
||||
}
|
||||
|
||||
function isBitwiseOperatorOrHigher(kind: SyntaxKind): kind is BitwiseOperatorOrHigher {
|
||||
return isBitwiseOperator(kind)
|
||||
|| isEqualityOperatorOrHigher(kind);
|
||||
}
|
||||
|
||||
// NOTE: The version in utilities includes ExclamationToken, which is not a binary operator.
|
||||
function isLogicalOperator(kind: SyntaxKind): kind is LogicalOperator {
|
||||
return kind === SyntaxKind.AmpersandAmpersandToken
|
||||
|| kind === SyntaxKind.BarBarToken;
|
||||
}
|
||||
|
||||
function isLogicalOperatorOrHigher(kind: SyntaxKind): kind is LogicalOperatorOrHigher {
|
||||
return isLogicalOperator(kind)
|
||||
|| isBitwiseOperatorOrHigher(kind);
|
||||
}
|
||||
|
||||
function isAssignmentOperatorOrHigher(kind: SyntaxKind): kind is AssignmentOperatorOrHigher {
|
||||
return kind === SyntaxKind.QuestionQuestionToken
|
||||
|| isLogicalOperatorOrHigher(kind)
|
||||
|| isAssignmentOperator(kind);
|
||||
}
|
||||
|
||||
function isBinaryOperator(kind: SyntaxKind): kind is BinaryOperator {
|
||||
return isAssignmentOperatorOrHigher(kind)
|
||||
|| kind === SyntaxKind.CommaToken;
|
||||
}
|
||||
|
||||
export function isBinaryOperatorToken(node: Node): node is BinaryOperatorToken {
|
||||
return isBinaryOperator(node.kind);
|
||||
}
|
||||
|
||||
type BinaryExpressionState = <TState, TResult>(machine: BinaryExpressionStateMachine<TState, TResult>, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], resultHolder: { value: TResult }) => number;
|
||||
|
||||
namespace BinaryExpressionState {
|
||||
/**
|
||||
* Handles walking into a `BinaryExpression`.
|
||||
* @param machine State machine handler functions
|
||||
* @param frame The current frame
|
||||
* @returns The new frame
|
||||
*/
|
||||
export function enter<TState, TResult>(machine: BinaryExpressionStateMachine<TState, TResult>, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], _resultHolder: { value: TResult }): number {
|
||||
const prevUserState = stackIndex > 0 ? userStateStack[stackIndex - 1] : undefined;
|
||||
Debug.assertEqual(stateStack[stackIndex], enter);
|
||||
userStateStack[stackIndex] = machine.onEnter(nodeStack[stackIndex], prevUserState);
|
||||
stateStack[stackIndex] = nextState(machine, enter);
|
||||
return stackIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles walking the `left` side of a `BinaryExpression`.
|
||||
* @param machine State machine handler functions
|
||||
* @param frame The current frame
|
||||
* @returns The new frame
|
||||
*/
|
||||
export function left<TState, TResult>(machine: BinaryExpressionStateMachine<TState, TResult>, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], _resultHolder: { value: TResult }): number {
|
||||
Debug.assertEqual(stateStack[stackIndex], left);
|
||||
Debug.assertIsDefined(machine.onLeft);
|
||||
stateStack[stackIndex] = nextState(machine, left);
|
||||
const nextNode = machine.onLeft(nodeStack[stackIndex].left, userStateStack[stackIndex], nodeStack[stackIndex]);
|
||||
if (nextNode) {
|
||||
checkCircularity(stackIndex, nodeStack, nextNode);
|
||||
return pushStack(stackIndex, stateStack, nodeStack, userStateStack, nextNode);
|
||||
}
|
||||
return stackIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles walking the `operatorToken` of a `BinaryExpression`.
|
||||
* @param machine State machine handler functions
|
||||
* @param frame The current frame
|
||||
* @returns The new frame
|
||||
*/
|
||||
export function operator<TState, TResult>(machine: BinaryExpressionStateMachine<TState, TResult>, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], _resultHolder: { value: TResult }): number {
|
||||
Debug.assertEqual(stateStack[stackIndex], operator);
|
||||
Debug.assertIsDefined(machine.onOperator);
|
||||
stateStack[stackIndex] = nextState(machine, operator);
|
||||
machine.onOperator(nodeStack[stackIndex].operatorToken, userStateStack[stackIndex], nodeStack[stackIndex]);
|
||||
return stackIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles walking the `right` side of a `BinaryExpression`.
|
||||
* @param machine State machine handler functions
|
||||
* @param frame The current frame
|
||||
* @returns The new frame
|
||||
*/
|
||||
export function right<TState, TResult>(machine: BinaryExpressionStateMachine<TState, TResult>, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], _resultHolder: { value: TResult }): number {
|
||||
Debug.assertEqual(stateStack[stackIndex], right);
|
||||
Debug.assertIsDefined(machine.onRight);
|
||||
stateStack[stackIndex] = nextState(machine, right);
|
||||
const nextNode = machine.onRight(nodeStack[stackIndex].right, userStateStack[stackIndex], nodeStack[stackIndex]);
|
||||
if (nextNode) {
|
||||
checkCircularity(stackIndex, nodeStack, nextNode);
|
||||
return pushStack(stackIndex, stateStack, nodeStack, userStateStack, nextNode);
|
||||
}
|
||||
return stackIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles walking out of a `BinaryExpression`.
|
||||
* @param machine State machine handler functions
|
||||
* @param frame The current frame
|
||||
* @returns The new frame
|
||||
*/
|
||||
export function exit<TState, TResult>(machine: BinaryExpressionStateMachine<TState, TResult>, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], resultHolder: { value: TResult }): number {
|
||||
Debug.assertEqual(stateStack[stackIndex], exit);
|
||||
stateStack[stackIndex] = nextState(machine, exit);
|
||||
const result = machine.onExit(nodeStack[stackIndex], userStateStack[stackIndex]);
|
||||
if (stackIndex > 0) {
|
||||
stackIndex--;
|
||||
if (machine.foldState) {
|
||||
const side = stateStack[stackIndex] === exit ? "right" : "left";
|
||||
userStateStack[stackIndex] = machine.foldState(userStateStack[stackIndex], result, side);
|
||||
}
|
||||
}
|
||||
else {
|
||||
resultHolder.value = result;
|
||||
}
|
||||
return stackIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a frame that is already done.
|
||||
* @returns The `done` state.
|
||||
*/
|
||||
export function done<TState, TResult>(_machine: BinaryExpressionStateMachine<TState, TResult>, stackIndex: number, stateStack: BinaryExpressionState[], _nodeStack: BinaryExpression[], _userStateStack: TState[], _resultHolder: { value: TResult }): number {
|
||||
Debug.assertEqual(stateStack[stackIndex], done);
|
||||
return stackIndex;
|
||||
}
|
||||
|
||||
export function nextState<TState, TResult>(machine: BinaryExpressionStateMachine<TState, TResult>, currentState: BinaryExpressionState) {
|
||||
switch (currentState) {
|
||||
case enter:
|
||||
if (machine.onLeft) return left;
|
||||
// falls through
|
||||
case left:
|
||||
if (machine.onOperator) return operator;
|
||||
// falls through
|
||||
case operator:
|
||||
if (machine.onRight) return right;
|
||||
// falls through
|
||||
case right: return exit;
|
||||
case exit: return done;
|
||||
case done: return done;
|
||||
default: Debug.fail("Invalid state");
|
||||
}
|
||||
}
|
||||
|
||||
function pushStack<TState>(stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], node: BinaryExpression) {
|
||||
stackIndex++;
|
||||
stateStack[stackIndex] = enter;
|
||||
nodeStack[stackIndex] = node;
|
||||
userStateStack[stackIndex] = undefined!;
|
||||
return stackIndex;
|
||||
}
|
||||
|
||||
function checkCircularity(stackIndex: number, nodeStack: BinaryExpression[], node: BinaryExpression) {
|
||||
if (Debug.shouldAssert(AssertionLevel.Aggressive)) {
|
||||
while (stackIndex >= 0) {
|
||||
Debug.assert(nodeStack[stackIndex] !== node, "Circular traversal detected.");
|
||||
stackIndex--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds state machine handler functions
|
||||
*/
|
||||
class BinaryExpressionStateMachine<TState, TResult> {
|
||||
constructor(
|
||||
readonly onEnter: (node: BinaryExpression, prev: TState | undefined) => TState,
|
||||
readonly onLeft: ((left: Expression, userState: TState, node: BinaryExpression) => BinaryExpression | void) | undefined,
|
||||
readonly onOperator: ((operatorToken: BinaryOperatorToken, userState: TState, node: BinaryExpression) => void) | undefined,
|
||||
readonly onRight: ((right: Expression, userState: TState, node: BinaryExpression) => BinaryExpression | void) | undefined,
|
||||
readonly onExit: (node: BinaryExpression, userState: TState) => TResult,
|
||||
readonly foldState: ((userState: TState, result: TResult, side: "left" | "right") => TState) | undefined,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a state machine that walks a `BinaryExpression` using the heap to reduce call-stack depth on a large tree.
|
||||
* @param onEnter Callback evaluated when entering a `BinaryExpression`. Returns new user-defined state to associate with the node while walking.
|
||||
* @param onLeft Callback evaluated when walking the left side of a `BinaryExpression`. Return a `BinaryExpression` to continue walking, or `void` to advance to the right side.
|
||||
* @param onRight Callback evaluated when walking the right side of a `BinaryExpression`. Return a `BinaryExpression` to continue walking, or `void` to advance to the end of the node.
|
||||
* @param onExit Callback evaluated when exiting a `BinaryExpression`. The result returned will either be folded into the parent's state, or returned from the walker if at the top frame.
|
||||
* @param foldState Callback evaluated when the result from a nested `onExit` should be folded into the state of that node's parent.
|
||||
* @returns A function that walks a `BinaryExpression` node using the above callbacks, returning the result of the call to `onExit` from the outermost `BinaryExpression` node.
|
||||
*/
|
||||
export function createBinaryExpressionTrampoline<TState, TResult>(
|
||||
onEnter: (node: BinaryExpression, prev: TState | undefined) => TState,
|
||||
onLeft: ((left: Expression, userState: TState, node: BinaryExpression) => BinaryExpression | void) | undefined,
|
||||
onOperator: ((operatorToken: BinaryOperatorToken, userState: TState, node: BinaryExpression) => void) | undefined,
|
||||
onRight: ((right: Expression, userState: TState, node: BinaryExpression) => BinaryExpression | void) | undefined,
|
||||
onExit: (node: BinaryExpression, userState: TState) => TResult,
|
||||
foldState: ((userState: TState, result: TResult, side: "left" | "right") => TState) | undefined,
|
||||
) {
|
||||
const machine = new BinaryExpressionStateMachine(onEnter, onLeft, onOperator, onRight, onExit, foldState);
|
||||
return (node: BinaryExpression) => {
|
||||
const resultHolder: { value: TResult } = { value: undefined! };
|
||||
const stateStack: BinaryExpressionState[] = [BinaryExpressionState.enter];
|
||||
const nodeStack: BinaryExpression[] = [node];
|
||||
const userStateStack: TState[] = [undefined!];
|
||||
let stackIndex = 0;
|
||||
while (stateStack[stackIndex] !== BinaryExpressionState.done) {
|
||||
stackIndex = stateStack[stackIndex](machine, stackIndex, stateStack, nodeStack, userStateStack, resultHolder);
|
||||
}
|
||||
Debug.assertEqual(stackIndex, 0);
|
||||
return resultHolder.value;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1864,17 +1864,22 @@ namespace ts {
|
|||
if (exportedNames) {
|
||||
let expression: Expression = node.kind === SyntaxKind.PostfixUnaryExpression
|
||||
? setTextRange(
|
||||
factory.createBinaryExpression(
|
||||
node.operand,
|
||||
factory.createToken(node.operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken),
|
||||
factory.createNumericLiteral(1)
|
||||
factory.createPrefixUnaryExpression(
|
||||
node.operator,
|
||||
node.operand
|
||||
),
|
||||
/*location*/ node)
|
||||
: node;
|
||||
for (const exportName of exportedNames) {
|
||||
// Mark the node to prevent triggering this rule again.
|
||||
noSubstitution[getNodeId(expression)] = true;
|
||||
expression = factory.createParenthesizedExpression(createExportExpression(exportName, expression));
|
||||
expression = createExportExpression(exportName, expression);
|
||||
}
|
||||
if (node.kind === SyntaxKind.PostfixUnaryExpression) {
|
||||
noSubstitution[getNodeId(expression)] = true;
|
||||
expression = node.operator === SyntaxKind.PlusPlusToken
|
||||
? factory.createSubtract(expression, factory.createNumericLiteral(1))
|
||||
: factory.createAdd(expression, factory.createNumericLiteral(1));
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
|
|
@ -361,17 +361,14 @@ namespace ts {
|
|||
// JSDoc nodes
|
||||
JSDocTypeExpression,
|
||||
JSDocNameReference,
|
||||
// The * type
|
||||
JSDocAllType,
|
||||
// The ? type
|
||||
JSDocUnknownType,
|
||||
JSDocAllType, // The * type
|
||||
JSDocUnknownType, // The ? type
|
||||
JSDocNullableType,
|
||||
JSDocNonNullableType,
|
||||
JSDocOptionalType,
|
||||
JSDocFunctionType,
|
||||
JSDocVariadicType,
|
||||
// https://jsdoc.app/about-namepaths.html
|
||||
JSDocNamepathType,
|
||||
JSDocNamepathType, // https://jsdoc.app/about-namepaths.html
|
||||
JSDocComment,
|
||||
JSDocTypeLiteral,
|
||||
JSDocSignature,
|
||||
|
@ -1118,6 +1115,8 @@ namespace ts {
|
|||
|
||||
export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier;
|
||||
|
||||
export type MemberName = Identifier | PrivateIdentifier;
|
||||
|
||||
export type DeclarationName =
|
||||
| Identifier
|
||||
| PrivateIdentifier
|
||||
|
@ -2224,7 +2223,7 @@ namespace ts {
|
|||
readonly kind: SyntaxKind.PropertyAccessExpression;
|
||||
readonly expression: LeftHandSideExpression;
|
||||
readonly questionDotToken?: QuestionDotToken;
|
||||
readonly name: Identifier | PrivateIdentifier;
|
||||
readonly name: MemberName;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
|
@ -2234,7 +2233,7 @@ namespace ts {
|
|||
|
||||
export interface PropertyAccessChain extends PropertyAccessExpression {
|
||||
_optionalChainBrand: any;
|
||||
readonly name: Identifier | PrivateIdentifier;
|
||||
readonly name: MemberName;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
@ -4124,9 +4123,9 @@ namespace ts {
|
|||
*/
|
||||
/* @internal */ tryGetMemberInModuleExportsAndProperties(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
|
||||
getApparentType(type: Type): Type;
|
||||
/* @internal */ getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined;
|
||||
/* @internal */ getSuggestedSymbolForNonexistentProperty(name: MemberName | string, containingType: Type): Symbol | undefined;
|
||||
/* @internal */ getSuggestedSymbolForNonexistentJSXAttribute(name: Identifier | string, containingType: Type): Symbol | undefined;
|
||||
/* @internal */ getSuggestionForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): string | undefined;
|
||||
/* @internal */ getSuggestionForNonexistentProperty(name: MemberName | string, containingType: Type): string | undefined;
|
||||
/* @internal */ getSuggestedSymbolForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): Symbol | undefined;
|
||||
/* @internal */ getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
|
||||
/* @internal */ getSuggestedSymbolForNonexistentModule(node: Identifier, target: Symbol): Symbol | undefined;
|
||||
|
@ -6570,7 +6569,7 @@ namespace ts {
|
|||
/*@internal*/ IgnoreSourceNewlines = 1 << 27, // Overrides `printerOptions.preserveSourceNewlines` to print this node (and all descendants) with default whitespace.
|
||||
}
|
||||
|
||||
export interface EmitHelper {
|
||||
export interface EmitHelperBase {
|
||||
readonly name: string; // A unique name for this helper.
|
||||
readonly scoped: boolean; // Indicates whether the helper MUST be emitted in the current scope.
|
||||
readonly text: string | ((node: EmitHelperUniqueNameCallback) => string); // ES3-compatible raw script text, or a function yielding such a string
|
||||
|
@ -6578,13 +6577,19 @@ namespace ts {
|
|||
readonly dependencies?: EmitHelper[]
|
||||
}
|
||||
|
||||
export interface UnscopedEmitHelper extends EmitHelper {
|
||||
export interface ScopedEmitHelper extends EmitHelperBase {
|
||||
readonly scoped: true;
|
||||
}
|
||||
|
||||
export interface UnscopedEmitHelper extends EmitHelperBase {
|
||||
readonly scoped: false; // Indicates whether the helper MUST be emitted in the current scope.
|
||||
/* @internal */
|
||||
readonly importName?: string; // The name of the helper to use when importing via `--importHelpers`.
|
||||
readonly text: string; // ES3-compatible raw script text, or a function yielding such a string
|
||||
}
|
||||
|
||||
export type EmitHelper = ScopedEmitHelper | UnscopedEmitHelper;
|
||||
|
||||
/* @internal */
|
||||
export type UniqueNameHandler = (baseName: string, checkFn?: (name: string) => boolean, optimistic?: boolean) => string;
|
||||
|
||||
|
@ -6943,10 +6948,10 @@ namespace ts {
|
|||
updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: readonly Expression[]): ArrayLiteralExpression;
|
||||
createObjectLiteralExpression(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean): ObjectLiteralExpression;
|
||||
updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression;
|
||||
createPropertyAccessExpression(expression: Expression, name: string | Identifier | PrivateIdentifier): PropertyAccessExpression;
|
||||
updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier): PropertyAccessExpression;
|
||||
createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier): PropertyAccessChain;
|
||||
updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier): PropertyAccessChain;
|
||||
createPropertyAccessExpression(expression: Expression, name: string | MemberName): PropertyAccessExpression;
|
||||
updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: MemberName): PropertyAccessExpression;
|
||||
createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | MemberName): PropertyAccessChain;
|
||||
updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: MemberName): PropertyAccessChain;
|
||||
createElementAccessExpression(expression: Expression, index: number | Expression): ElementAccessExpression;
|
||||
updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression;
|
||||
createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression): ElementAccessChain;
|
||||
|
@ -7782,13 +7787,13 @@ namespace ts {
|
|||
* });
|
||||
* ```
|
||||
*/
|
||||
onEmitNode?(hint: EmitHint, node: Node | undefined, emitCallback: (hint: EmitHint, node: Node | undefined) => void): void;
|
||||
onEmitNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
|
||||
/**
|
||||
* A hook used to check if an emit notification is required for a node.
|
||||
* @param node The node to emit.
|
||||
*/
|
||||
isEmitNotificationEnabled?(node: Node | undefined): boolean;
|
||||
isEmitNotificationEnabled?(node: Node): boolean;
|
||||
/**
|
||||
* A hook used by the Printer to perform just-in-time substitution of a node. This is
|
||||
* primarily used by node transformations that need to substitute one node for another,
|
||||
|
@ -7810,6 +7815,8 @@ namespace ts {
|
|||
/*@internal*/ onEmitSourceMapOfToken?: (node: Node | undefined, token: SyntaxKind, writer: (s: string) => void, pos: number, emitCallback: (token: SyntaxKind, writer: (s: string) => void, pos: number) => number) => number;
|
||||
/*@internal*/ onEmitSourceMapOfPosition?: (pos: number) => void;
|
||||
/*@internal*/ onSetSourceFile?: (node: SourceFile) => void;
|
||||
/*@internal*/ onBeforeEmitNode?: (node: Node | undefined) => void;
|
||||
/*@internal*/ onAfterEmitNode?: (node: Node | undefined) => void;
|
||||
/*@internal*/ onBeforeEmitNodeArray?: (nodes: NodeArray<any> | undefined) => void;
|
||||
/*@internal*/ onAfterEmitNodeArray?: (nodes: NodeArray<any> | undefined) => void;
|
||||
/*@internal*/ onBeforeEmitToken?: (node: Node) => void;
|
||||
|
|
|
@ -3186,11 +3186,11 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
export function getTextOfIdentifierOrLiteral(node: PropertyNameLiteral): string {
|
||||
return isIdentifierOrPrivateIdentifier(node) ? idText(node) : node.text;
|
||||
return isMemberName(node) ? idText(node) : node.text;
|
||||
}
|
||||
|
||||
export function getEscapedTextOfIdentifierOrLiteral(node: PropertyNameLiteral): __String {
|
||||
return isIdentifierOrPrivateIdentifier(node) ? node.escapedText : escapeLeadingUnderscores(node.text);
|
||||
return isMemberName(node) ? node.escapedText : escapeLeadingUnderscores(node.text);
|
||||
}
|
||||
|
||||
export function getPropertyNameForUniqueESSymbol(symbol: Symbol): __String {
|
||||
|
@ -3574,6 +3574,7 @@ namespace ts {
|
|||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
case SyntaxKind.MetaProperty:
|
||||
return OperatorPrecedence.Member;
|
||||
|
||||
case SyntaxKind.AsExpression:
|
||||
|
|
|
@ -930,7 +930,7 @@ namespace ts {
|
|||
|
||||
// #region
|
||||
|
||||
export function isIdentifierOrPrivateIdentifier(node: Node): node is Identifier | PrivateIdentifier {
|
||||
export function isMemberName(node: Node): node is MemberName {
|
||||
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PrivateIdentifier;
|
||||
}
|
||||
|
||||
|
@ -1055,13 +1055,22 @@ namespace ts {
|
|||
return kind >= SyntaxKind.FirstNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if kind is of some token syntax kind.
|
||||
* For example, this is true for an IfKeyword but not for an IfStatement.
|
||||
* Literals are considered tokens, except TemplateLiteral, but does include TemplateHead/Middle/Tail.
|
||||
*/
|
||||
export function isTokenKind(kind: SyntaxKind): boolean {
|
||||
return kind >= SyntaxKind.FirstToken && kind <= SyntaxKind.LastToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if node is of some token syntax kind.
|
||||
* For example, this is true for an IfKeyword but not for an IfStatement.
|
||||
* Literals are considered tokens, except TemplateLiteral, but does include TemplateHead/Middle/Tail.
|
||||
*/
|
||||
export function isToken(n: Node): boolean {
|
||||
return n.kind >= SyntaxKind.FirstToken && n.kind <= SyntaxKind.LastToken;
|
||||
return isTokenKind(n.kind);
|
||||
}
|
||||
|
||||
// Node Arrays
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1354,4 +1354,24 @@ namespace ts {
|
|||
export interface Map<T> extends ESMap<string, T> { }
|
||||
|
||||
// #endregion
|
||||
|
||||
// DEPRECATION: Renamed node tests
|
||||
// DEPRECATION PLAN:
|
||||
// - soft: 4.2
|
||||
// - warn: 4.3
|
||||
// - error: TBD
|
||||
// #region Renamed node Tests
|
||||
|
||||
/**
|
||||
* @deprecated Use `isMemberName` instead.
|
||||
*/
|
||||
export const isIdentifierOrPrivateIdentifier = Debug.deprecate(function isIdentifierOrPrivateIdentifier(node: Node): node is MemberName {
|
||||
return isMemberName(node);
|
||||
}, {
|
||||
since: "4.2",
|
||||
warnAfter: "4.3",
|
||||
message: "Use `isMemberName` instead."
|
||||
});
|
||||
|
||||
// #endregion Renamed node Tests
|
||||
}
|
|
@ -46,7 +46,7 @@ namespace ts.codefix {
|
|||
|
||||
let suggestedSymbol: Symbol | undefined;
|
||||
if (isPropertyAccessExpression(parent) && parent.name === node) {
|
||||
Debug.assert(isIdentifierOrPrivateIdentifier(node), "Expected an identifier for spelling (property access)");
|
||||
Debug.assert(isMemberName(node), "Expected an identifier for spelling (property access)");
|
||||
let containingType = checker.getTypeAtLocation(parent.expression);
|
||||
if (parent.flags & NodeFlags.OptionalChain) {
|
||||
containingType = checker.getNonNullableType(containingType);
|
||||
|
|
|
@ -977,7 +977,7 @@ namespace ts.Completions {
|
|||
|
||||
// Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS|
|
||||
// Skip this partial identifier and adjust the contextToken to the token that precedes it.
|
||||
if (contextToken && position <= contextToken.end && (isIdentifierOrPrivateIdentifier(contextToken) || isKeyword(contextToken.kind))) {
|
||||
if (contextToken && position <= contextToken.end && (isMemberName(contextToken) || isKeyword(contextToken.kind))) {
|
||||
const start = timestamp();
|
||||
contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined)!; // TODO: GH#18217
|
||||
log("getCompletionData: Get previous token 2: " + (timestamp() - start));
|
||||
|
|
|
@ -1037,11 +1037,12 @@ namespace ts.textChanges {
|
|||
let lastNonTriviaPosition = 0;
|
||||
|
||||
const writer = createTextWriter(newLine);
|
||||
const onEmitNode: PrintHandlers["onEmitNode"] = (hint, node, printCallback) => {
|
||||
const onBeforeEmitNode: PrintHandlers["onBeforeEmitNode"] = node => {
|
||||
if (node) {
|
||||
setPos(node, lastNonTriviaPosition);
|
||||
}
|
||||
printCallback(hint, node);
|
||||
};
|
||||
const onAfterEmitNode: PrintHandlers["onAfterEmitNode"] = node => {
|
||||
if (node) {
|
||||
setEnd(node, lastNonTriviaPosition);
|
||||
}
|
||||
|
@ -1163,7 +1164,8 @@ namespace ts.textChanges {
|
|||
}
|
||||
|
||||
return {
|
||||
onEmitNode,
|
||||
onBeforeEmitNode,
|
||||
onAfterEmitNode,
|
||||
onBeforeEmitNodeArray,
|
||||
onAfterEmitNodeArray,
|
||||
onBeforeEmitToken,
|
||||
|
|
|
@ -638,6 +638,7 @@ declare namespace ts {
|
|||
}
|
||||
export type EntityName = Identifier | QualifiedName;
|
||||
export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier;
|
||||
export type MemberName = Identifier | PrivateIdentifier;
|
||||
export type DeclarationName = Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | ElementAccessExpression | BindingPattern | EntityNameExpression;
|
||||
export interface Declaration extends Node {
|
||||
_declarationBrand: any;
|
||||
|
@ -1216,11 +1217,11 @@ declare namespace ts {
|
|||
readonly kind: SyntaxKind.PropertyAccessExpression;
|
||||
readonly expression: LeftHandSideExpression;
|
||||
readonly questionDotToken?: QuestionDotToken;
|
||||
readonly name: Identifier | PrivateIdentifier;
|
||||
readonly name: MemberName;
|
||||
}
|
||||
export interface PropertyAccessChain extends PropertyAccessExpression {
|
||||
_optionalChainBrand: any;
|
||||
readonly name: Identifier | PrivateIdentifier;
|
||||
readonly name: MemberName;
|
||||
}
|
||||
export interface SuperPropertyAccessExpression extends PropertyAccessExpression {
|
||||
readonly expression: SuperExpression;
|
||||
|
@ -3130,17 +3131,21 @@ declare namespace ts {
|
|||
Iterator = 8388608,
|
||||
NoAsciiEscaping = 16777216,
|
||||
}
|
||||
export interface EmitHelper {
|
||||
export interface EmitHelperBase {
|
||||
readonly name: string;
|
||||
readonly scoped: boolean;
|
||||
readonly text: string | ((node: EmitHelperUniqueNameCallback) => string);
|
||||
readonly priority?: number;
|
||||
readonly dependencies?: EmitHelper[];
|
||||
}
|
||||
export interface UnscopedEmitHelper extends EmitHelper {
|
||||
export interface ScopedEmitHelper extends EmitHelperBase {
|
||||
readonly scoped: true;
|
||||
}
|
||||
export interface UnscopedEmitHelper extends EmitHelperBase {
|
||||
readonly scoped: false;
|
||||
readonly text: string;
|
||||
}
|
||||
export type EmitHelper = ScopedEmitHelper | UnscopedEmitHelper;
|
||||
export type EmitHelperUniqueNameCallback = (name: string) => string;
|
||||
export enum EmitHint {
|
||||
SourceFile = 0,
|
||||
|
@ -3286,10 +3291,10 @@ declare namespace ts {
|
|||
updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: readonly Expression[]): ArrayLiteralExpression;
|
||||
createObjectLiteralExpression(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean): ObjectLiteralExpression;
|
||||
updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression;
|
||||
createPropertyAccessExpression(expression: Expression, name: string | Identifier | PrivateIdentifier): PropertyAccessExpression;
|
||||
updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier): PropertyAccessExpression;
|
||||
createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier): PropertyAccessChain;
|
||||
updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier): PropertyAccessChain;
|
||||
createPropertyAccessExpression(expression: Expression, name: string | MemberName): PropertyAccessExpression;
|
||||
updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: MemberName): PropertyAccessExpression;
|
||||
createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | MemberName): PropertyAccessChain;
|
||||
updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: MemberName): PropertyAccessChain;
|
||||
createElementAccessExpression(expression: Expression, index: number | Expression): ElementAccessExpression;
|
||||
updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression;
|
||||
createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression): ElementAccessChain;
|
||||
|
@ -3750,12 +3755,12 @@ declare namespace ts {
|
|||
* });
|
||||
* ```
|
||||
*/
|
||||
onEmitNode?(hint: EmitHint, node: Node | undefined, emitCallback: (hint: EmitHint, node: Node | undefined) => void): void;
|
||||
onEmitNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
/**
|
||||
* A hook used to check if an emit notification is required for a node.
|
||||
* @param node The node to emit.
|
||||
*/
|
||||
isEmitNotificationEnabled?(node: Node | undefined): boolean;
|
||||
isEmitNotificationEnabled?(node: Node): boolean;
|
||||
/**
|
||||
* A hook used by the Printer to perform just-in-time substitution of a node. This is
|
||||
* primarily used by node transformations that need to substitute one node for another,
|
||||
|
@ -4191,7 +4196,7 @@ declare namespace ts {
|
|||
*/
|
||||
function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): readonly TypeParameterDeclaration[];
|
||||
function getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode | undefined;
|
||||
function isIdentifierOrPrivateIdentifier(node: Node): node is Identifier | PrivateIdentifier;
|
||||
function isMemberName(node: Node): node is MemberName;
|
||||
function isPropertyAccessChain(node: Node): node is PropertyAccessChain;
|
||||
function isElementAccessChain(node: Node): node is ElementAccessChain;
|
||||
function isCallChain(node: Node): node is CallChain;
|
||||
|
@ -4206,6 +4211,12 @@ declare namespace ts {
|
|||
function isUnparsedTextLike(node: Node): node is UnparsedTextLike;
|
||||
function isUnparsedNode(node: Node): node is UnparsedNode;
|
||||
function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag;
|
||||
/**
|
||||
* True if kind is of some token syntax kind.
|
||||
* For example, this is true for an IfKeyword but not for an IfStatement.
|
||||
* Literals are considered tokens, except TemplateLiteral, but does include TemplateHead/Middle/Tail.
|
||||
*/
|
||||
function isTokenKind(kind: SyntaxKind): boolean;
|
||||
/**
|
||||
* True if node is of some token syntax kind.
|
||||
* For example, this is true for an IfKeyword but not for an IfStatement.
|
||||
|
@ -4348,10 +4359,14 @@ declare namespace ts {
|
|||
function isTemplateHead(node: Node): node is TemplateHead;
|
||||
function isTemplateMiddle(node: Node): node is TemplateMiddle;
|
||||
function isTemplateTail(node: Node): node is TemplateTail;
|
||||
function isDotDotDotToken(node: Node): node is DotDotDotToken;
|
||||
function isPlusToken(node: Node): node is PlusToken;
|
||||
function isMinusToken(node: Node): node is MinusToken;
|
||||
function isAsteriskToken(node: Node): node is AsteriskToken;
|
||||
function isIdentifier(node: Node): node is Identifier;
|
||||
function isPrivateIdentifier(node: Node): node is PrivateIdentifier;
|
||||
function isQualifiedName(node: Node): node is QualifiedName;
|
||||
function isComputedPropertyName(node: Node): node is ComputedPropertyName;
|
||||
function isPrivateIdentifier(node: Node): node is PrivateIdentifier;
|
||||
function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration;
|
||||
function isParameter(node: Node): node is ParameterDeclaration;
|
||||
function isDecorator(node: Node): node is Decorator;
|
||||
|
@ -10370,13 +10385,13 @@ declare namespace ts {
|
|||
/** @deprecated Use `factory.updateObjectLiteralExpression` or the factory supplied by your transformation context instead. */
|
||||
const updateObjectLiteral: (node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]) => ObjectLiteralExpression;
|
||||
/** @deprecated Use `factory.createPropertyAccessExpression` or the factory supplied by your transformation context instead. */
|
||||
const createPropertyAccess: (expression: Expression, name: string | Identifier | PrivateIdentifier) => PropertyAccessExpression;
|
||||
const createPropertyAccess: (expression: Expression, name: string | MemberName) => PropertyAccessExpression;
|
||||
/** @deprecated Use `factory.updatePropertyAccessExpression` or the factory supplied by your transformation context instead. */
|
||||
const updatePropertyAccess: (node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier) => PropertyAccessExpression;
|
||||
const updatePropertyAccess: (node: PropertyAccessExpression, expression: Expression, name: MemberName) => PropertyAccessExpression;
|
||||
/** @deprecated Use `factory.createPropertyAccessChain` or the factory supplied by your transformation context instead. */
|
||||
const createPropertyAccessChain: (expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier) => PropertyAccessChain;
|
||||
const createPropertyAccessChain: (expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | MemberName) => PropertyAccessChain;
|
||||
/** @deprecated Use `factory.updatePropertyAccessChain` or the factory supplied by your transformation context instead. */
|
||||
const updatePropertyAccessChain: (node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier) => PropertyAccessChain;
|
||||
const updatePropertyAccessChain: (node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: MemberName) => PropertyAccessChain;
|
||||
/** @deprecated Use `factory.createElementAccessExpression` or the factory supplied by your transformation context instead. */
|
||||
const createElementAccess: (expression: Expression, index: number | Expression) => ElementAccessExpression;
|
||||
/** @deprecated Use `factory.updateElementAccessExpression` or the factory supplied by your transformation context instead. */
|
||||
|
@ -10946,6 +10961,10 @@ declare namespace ts {
|
|||
*/
|
||||
interface Map<T> extends ESMap<string, T> {
|
||||
}
|
||||
/**
|
||||
* @deprecated Use `isMemberName` instead.
|
||||
*/
|
||||
const isIdentifierOrPrivateIdentifier: (node: Node) => node is MemberName;
|
||||
}
|
||||
|
||||
export = ts;
|
||||
|
|
51
tests/baselines/reference/api/typescript.d.ts
vendored
51
tests/baselines/reference/api/typescript.d.ts
vendored
|
@ -638,6 +638,7 @@ declare namespace ts {
|
|||
}
|
||||
export type EntityName = Identifier | QualifiedName;
|
||||
export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier;
|
||||
export type MemberName = Identifier | PrivateIdentifier;
|
||||
export type DeclarationName = Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | ElementAccessExpression | BindingPattern | EntityNameExpression;
|
||||
export interface Declaration extends Node {
|
||||
_declarationBrand: any;
|
||||
|
@ -1216,11 +1217,11 @@ declare namespace ts {
|
|||
readonly kind: SyntaxKind.PropertyAccessExpression;
|
||||
readonly expression: LeftHandSideExpression;
|
||||
readonly questionDotToken?: QuestionDotToken;
|
||||
readonly name: Identifier | PrivateIdentifier;
|
||||
readonly name: MemberName;
|
||||
}
|
||||
export interface PropertyAccessChain extends PropertyAccessExpression {
|
||||
_optionalChainBrand: any;
|
||||
readonly name: Identifier | PrivateIdentifier;
|
||||
readonly name: MemberName;
|
||||
}
|
||||
export interface SuperPropertyAccessExpression extends PropertyAccessExpression {
|
||||
readonly expression: SuperExpression;
|
||||
|
@ -3130,17 +3131,21 @@ declare namespace ts {
|
|||
Iterator = 8388608,
|
||||
NoAsciiEscaping = 16777216,
|
||||
}
|
||||
export interface EmitHelper {
|
||||
export interface EmitHelperBase {
|
||||
readonly name: string;
|
||||
readonly scoped: boolean;
|
||||
readonly text: string | ((node: EmitHelperUniqueNameCallback) => string);
|
||||
readonly priority?: number;
|
||||
readonly dependencies?: EmitHelper[];
|
||||
}
|
||||
export interface UnscopedEmitHelper extends EmitHelper {
|
||||
export interface ScopedEmitHelper extends EmitHelperBase {
|
||||
readonly scoped: true;
|
||||
}
|
||||
export interface UnscopedEmitHelper extends EmitHelperBase {
|
||||
readonly scoped: false;
|
||||
readonly text: string;
|
||||
}
|
||||
export type EmitHelper = ScopedEmitHelper | UnscopedEmitHelper;
|
||||
export type EmitHelperUniqueNameCallback = (name: string) => string;
|
||||
export enum EmitHint {
|
||||
SourceFile = 0,
|
||||
|
@ -3286,10 +3291,10 @@ declare namespace ts {
|
|||
updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: readonly Expression[]): ArrayLiteralExpression;
|
||||
createObjectLiteralExpression(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean): ObjectLiteralExpression;
|
||||
updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression;
|
||||
createPropertyAccessExpression(expression: Expression, name: string | Identifier | PrivateIdentifier): PropertyAccessExpression;
|
||||
updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier): PropertyAccessExpression;
|
||||
createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier): PropertyAccessChain;
|
||||
updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier): PropertyAccessChain;
|
||||
createPropertyAccessExpression(expression: Expression, name: string | MemberName): PropertyAccessExpression;
|
||||
updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: MemberName): PropertyAccessExpression;
|
||||
createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | MemberName): PropertyAccessChain;
|
||||
updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: MemberName): PropertyAccessChain;
|
||||
createElementAccessExpression(expression: Expression, index: number | Expression): ElementAccessExpression;
|
||||
updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression;
|
||||
createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression): ElementAccessChain;
|
||||
|
@ -3750,12 +3755,12 @@ declare namespace ts {
|
|||
* });
|
||||
* ```
|
||||
*/
|
||||
onEmitNode?(hint: EmitHint, node: Node | undefined, emitCallback: (hint: EmitHint, node: Node | undefined) => void): void;
|
||||
onEmitNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
/**
|
||||
* A hook used to check if an emit notification is required for a node.
|
||||
* @param node The node to emit.
|
||||
*/
|
||||
isEmitNotificationEnabled?(node: Node | undefined): boolean;
|
||||
isEmitNotificationEnabled?(node: Node): boolean;
|
||||
/**
|
||||
* A hook used by the Printer to perform just-in-time substitution of a node. This is
|
||||
* primarily used by node transformations that need to substitute one node for another,
|
||||
|
@ -4191,7 +4196,7 @@ declare namespace ts {
|
|||
*/
|
||||
function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): readonly TypeParameterDeclaration[];
|
||||
function getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode | undefined;
|
||||
function isIdentifierOrPrivateIdentifier(node: Node): node is Identifier | PrivateIdentifier;
|
||||
function isMemberName(node: Node): node is MemberName;
|
||||
function isPropertyAccessChain(node: Node): node is PropertyAccessChain;
|
||||
function isElementAccessChain(node: Node): node is ElementAccessChain;
|
||||
function isCallChain(node: Node): node is CallChain;
|
||||
|
@ -4206,6 +4211,12 @@ declare namespace ts {
|
|||
function isUnparsedTextLike(node: Node): node is UnparsedTextLike;
|
||||
function isUnparsedNode(node: Node): node is UnparsedNode;
|
||||
function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag;
|
||||
/**
|
||||
* True if kind is of some token syntax kind.
|
||||
* For example, this is true for an IfKeyword but not for an IfStatement.
|
||||
* Literals are considered tokens, except TemplateLiteral, but does include TemplateHead/Middle/Tail.
|
||||
*/
|
||||
function isTokenKind(kind: SyntaxKind): boolean;
|
||||
/**
|
||||
* True if node is of some token syntax kind.
|
||||
* For example, this is true for an IfKeyword but not for an IfStatement.
|
||||
|
@ -4348,10 +4359,14 @@ declare namespace ts {
|
|||
function isTemplateHead(node: Node): node is TemplateHead;
|
||||
function isTemplateMiddle(node: Node): node is TemplateMiddle;
|
||||
function isTemplateTail(node: Node): node is TemplateTail;
|
||||
function isDotDotDotToken(node: Node): node is DotDotDotToken;
|
||||
function isPlusToken(node: Node): node is PlusToken;
|
||||
function isMinusToken(node: Node): node is MinusToken;
|
||||
function isAsteriskToken(node: Node): node is AsteriskToken;
|
||||
function isIdentifier(node: Node): node is Identifier;
|
||||
function isPrivateIdentifier(node: Node): node is PrivateIdentifier;
|
||||
function isQualifiedName(node: Node): node is QualifiedName;
|
||||
function isComputedPropertyName(node: Node): node is ComputedPropertyName;
|
||||
function isPrivateIdentifier(node: Node): node is PrivateIdentifier;
|
||||
function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration;
|
||||
function isParameter(node: Node): node is ParameterDeclaration;
|
||||
function isDecorator(node: Node): node is Decorator;
|
||||
|
@ -6643,13 +6658,13 @@ declare namespace ts {
|
|||
/** @deprecated Use `factory.updateObjectLiteralExpression` or the factory supplied by your transformation context instead. */
|
||||
const updateObjectLiteral: (node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]) => ObjectLiteralExpression;
|
||||
/** @deprecated Use `factory.createPropertyAccessExpression` or the factory supplied by your transformation context instead. */
|
||||
const createPropertyAccess: (expression: Expression, name: string | Identifier | PrivateIdentifier) => PropertyAccessExpression;
|
||||
const createPropertyAccess: (expression: Expression, name: string | MemberName) => PropertyAccessExpression;
|
||||
/** @deprecated Use `factory.updatePropertyAccessExpression` or the factory supplied by your transformation context instead. */
|
||||
const updatePropertyAccess: (node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier) => PropertyAccessExpression;
|
||||
const updatePropertyAccess: (node: PropertyAccessExpression, expression: Expression, name: MemberName) => PropertyAccessExpression;
|
||||
/** @deprecated Use `factory.createPropertyAccessChain` or the factory supplied by your transformation context instead. */
|
||||
const createPropertyAccessChain: (expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier) => PropertyAccessChain;
|
||||
const createPropertyAccessChain: (expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | MemberName) => PropertyAccessChain;
|
||||
/** @deprecated Use `factory.updatePropertyAccessChain` or the factory supplied by your transformation context instead. */
|
||||
const updatePropertyAccessChain: (node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier) => PropertyAccessChain;
|
||||
const updatePropertyAccessChain: (node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: MemberName) => PropertyAccessChain;
|
||||
/** @deprecated Use `factory.createElementAccessExpression` or the factory supplied by your transformation context instead. */
|
||||
const createElementAccess: (expression: Expression, index: number | Expression) => ElementAccessExpression;
|
||||
/** @deprecated Use `factory.updateElementAccessExpression` or the factory supplied by your transformation context instead. */
|
||||
|
@ -7219,6 +7234,10 @@ declare namespace ts {
|
|||
*/
|
||||
interface Map<T> extends ESMap<string, T> {
|
||||
}
|
||||
/**
|
||||
* @deprecated Use `isMemberName` instead.
|
||||
*/
|
||||
const isIdentifierOrPrivateIdentifier: (node: Node) => node is MemberName;
|
||||
}
|
||||
|
||||
export = ts;
|
|
@ -32,6 +32,6 @@ exports.buzz = buzz;
|
|||
exports.buzz = buzz += 3;
|
||||
var bizz = 8;
|
||||
exports.bizz = bizz;
|
||||
(exports.bizz = bizz += 1); // compiles to exports.bizz = bizz += 1
|
||||
(exports.bizz = bizz -= 1); // similarly
|
||||
(exports.bizz = ++bizz); // compiles to exports.bizz = ++bizz
|
||||
(exports.bizz = ++bizz) - 1; // compiles to exports.bizz = bizz += 1
|
||||
(exports.bizz = --bizz) + 1; // similarly
|
||||
exports.bizz = ++bizz; // compiles to exports.bizz = ++bizz
|
||||
|
|
|
@ -101,8 +101,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.z = exports.y = exports.x = void 0;
|
||||
exports.x = (import.meta);
|
||||
exports.y = (import.metal);
|
||||
exports.x = import.meta;
|
||||
exports.y = import.metal;
|
||||
exports.z = import.import.import.malkovich;
|
||||
//// [scriptLookingFile01.js]
|
||||
"use strict";
|
||||
|
|
|
@ -55,8 +55,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.z = exports.y = exports.x = void 0;
|
||||
exports.x = (import.meta);
|
||||
exports.y = (import.metal);
|
||||
exports.x = import.meta;
|
||||
exports.y = import.metal;
|
||||
exports.z = import.import.import.malkovich;
|
||||
//// [scriptLookingFile01.js]
|
||||
"use strict";
|
||||
|
|
|
@ -112,8 +112,8 @@ System.register([], function (exports_1, context_1) {
|
|||
return {
|
||||
setters: [],
|
||||
execute: function () {
|
||||
exports_1("x", x = (context_1.meta));
|
||||
exports_1("y", y = (import.metal));
|
||||
exports_1("x", x = context_1.meta);
|
||||
exports_1("y", y = import.metal);
|
||||
exports_1("z", z = import.import.import.malkovich);
|
||||
}
|
||||
};
|
||||
|
@ -126,8 +126,8 @@ System.register([], function (exports_1, context_1) {
|
|||
return {
|
||||
setters: [],
|
||||
execute: function () {
|
||||
globalA = (context_1.meta);
|
||||
globalB = (import.metal);
|
||||
globalA = context_1.meta;
|
||||
globalB = import.metal;
|
||||
globalC = import.import.import.malkovich;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -66,8 +66,8 @@ System.register([], function (exports_1, context_1) {
|
|||
return {
|
||||
setters: [],
|
||||
execute: function () {
|
||||
exports_1("x", x = (context_1.meta));
|
||||
exports_1("y", y = (import.metal));
|
||||
exports_1("x", x = context_1.meta);
|
||||
exports_1("y", y = import.metal);
|
||||
exports_1("z", z = import.import.import.malkovich);
|
||||
}
|
||||
};
|
||||
|
@ -80,8 +80,8 @@ System.register([], function (exports_1, context_1) {
|
|||
return {
|
||||
setters: [],
|
||||
execute: function () {
|
||||
globalA = (context_1.meta);
|
||||
globalB = (import.metal);
|
||||
globalA = context_1.meta;
|
||||
globalB = import.metal;
|
||||
globalC = import.import.import.malkovich;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -161,6 +161,4 @@ var _brokenTree = renderer_1.dom(component_1.MySFC, { x: 1, y: 2 },
|
|||
renderer_1.dom(component_1.MyClass, { x: 3, y: 4 }),
|
||||
renderer_1.dom(component_1.MyClass, { x: 5, y: 6 }));
|
||||
// Should fail, nondom isn't allowed as children of dom
|
||||
var _brokenTree2 = renderer_1.dom(DOMSFC, { x: 1, y: 2 },
|
||||
component_1.tree,
|
||||
component_1.tree);
|
||||
var _brokenTree2 = renderer_1.dom(DOMSFC, { x: 1, y: 2 }, component_1.tree, component_1.tree);
|
||||
|
|
|
@ -23,5 +23,5 @@ let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
|
|||
exports.__esModule = true;
|
||||
var component_1 = require("./component");
|
||||
var React = require("react");
|
||||
var x = <component_1.MyComp />, <Prop> a={10} b="hi" />; // error, no type arguments in js
|
||||
</>;
|
||||
var x = (<component_1.MyComp />, <Prop> a={10} b="hi" />; // error, no type arguments in js
|
||||
</>);
|
||||
|
|
|
@ -23,17 +23,17 @@ exports.x = exports.foo = void 0;
|
|||
var x = 1;
|
||||
exports.x = x;
|
||||
function foo(y) {
|
||||
if (y <= (exports.x = x += 1))
|
||||
return y <= (exports.x = x += 1);
|
||||
if (y <= (exports.x = x -= 1))
|
||||
return y <= (exports.x = x -= 1);
|
||||
if (y <= (exports.x = ++x) - 1)
|
||||
return y <= (exports.x = ++x) - 1;
|
||||
if (y <= (exports.x = --x) + 1)
|
||||
return y <= (exports.x = --x) + 1;
|
||||
if (y <= (exports.x = ++x))
|
||||
return y <= (exports.x = ++x);
|
||||
if (y <= (exports.x = --x))
|
||||
return y <= (exports.x = --x);
|
||||
(exports.x = x += 1);
|
||||
(exports.x = x -= 1);
|
||||
(exports.x = ++x);
|
||||
(exports.x = --x);
|
||||
(exports.x = ++x) - 1;
|
||||
(exports.x = --x) + 1;
|
||||
exports.x = ++x;
|
||||
exports.x = --x;
|
||||
}
|
||||
exports.foo = foo;
|
||||
|
|
|
@ -35,8 +35,7 @@ var y = {
|
|||
"typeof":
|
||||
};
|
||||
var x = (_a = {
|
||||
a: a,
|
||||
: .b,
|
||||
a: a, : .b,
|
||||
a: a
|
||||
},
|
||||
_a["ss"] = ,
|
||||
|
|
|
@ -25,8 +25,7 @@ var n;
|
|||
(function (n) {
|
||||
var z = 10000;
|
||||
n.y = {
|
||||
m: m,
|
||||
: .x // error
|
||||
m: m, : .x // error
|
||||
};
|
||||
})(n || (n = {}));
|
||||
m.y.x;
|
||||
|
|
|
@ -42,6 +42,5 @@ var C2 = /** @class */ (function () {
|
|||
return C2;
|
||||
}());
|
||||
var b = {
|
||||
x: function () { },
|
||||
1: // error
|
||||
x: function () { }, 1: // error
|
||||
};
|
||||
|
|
|
@ -3,4 +3,5 @@ var v = { a
|
|||
return;
|
||||
|
||||
//// [parserErrorRecovery_ObjectLiteral2.js]
|
||||
var v = { a: a, "return": };
|
||||
var v = { a: a,
|
||||
"return": };
|
||||
|
|
Loading…
Reference in a new issue