Skip to content

Commit 26e7cb6

Browse files
committed
Merge branch 'main' into timestamps
2 parents b32d2eb + 94cb657 commit 26e7cb6

File tree

52 files changed

+717
-121
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+717
-121
lines changed

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/compiler/checker.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27986,6 +27986,7 @@ namespace ts {
2798627986
}
2798727987
}
2798827988
else {
27989+
error(attributeDecl.expression, Diagnostics.Spread_types_may_only_be_created_from_object_types);
2798927990
typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
2799027991
}
2799127992
}
@@ -30500,6 +30501,7 @@ namespace ts {
3050030501
// decorators are applied to a declaration by the emitter, and not to an expression.
3050130502
const isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters;
3050230503
let argCheckMode = !isDecorator && !isSingleNonGenericCandidate && some(args, isContextSensitive) ? CheckMode.SkipContextSensitive : CheckMode.Normal;
30504+
argCheckMode |= checkMode & CheckMode.IsForStringLiteralArgumentCompletions;
3050330505

3050430506
// The following variables are captured and modified by calls to chooseOverload.
3050530507
// If overload resolution or type argument inference fails, we want to report the
@@ -30725,7 +30727,7 @@ namespace ts {
3072530727
// If one or more context sensitive arguments were excluded, we start including
3072630728
// them now (and keeping do so for any subsequent candidates) and perform a second
3072730729
// round of type inference and applicability checking for this particular candidate.
30728-
argCheckMode = CheckMode.Normal;
30730+
argCheckMode = checkMode & CheckMode.IsForStringLiteralArgumentCompletions;
3072930731
if (inferenceContext) {
3073030732
const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
3073130733
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
@@ -41982,15 +41984,20 @@ namespace ts {
4198241984
return propertyDeclaration;
4198341985
}
4198441986
}
41985-
else if (isMetaProperty(parent)) {
41986-
const parentType = getTypeOfNode(parent);
41987-
const propertyDeclaration = getPropertyOfType(parentType, (node as Identifier).escapedText);
41988-
if (propertyDeclaration) {
41989-
return propertyDeclaration;
41990-
}
41991-
if (parent.keywordToken === SyntaxKind.NewKeyword) {
41987+
else if (isMetaProperty(parent) && parent.name === node) {
41988+
if (parent.keywordToken === SyntaxKind.NewKeyword && idText(node as Identifier) === "target") {
41989+
// `target` in `new.target`
4199241990
return checkNewTargetMetaProperty(parent).symbol;
4199341991
}
41992+
// The `meta` in `import.meta` could be given `getTypeOfNode(parent).symbol` (the `ImportMeta` interface symbol), but
41993+
// we have a fake expression type made for other reasons already, whose transient `meta`
41994+
// member should more exactly be the kind of (declarationless) symbol we want.
41995+
// (See #44364 and #45031 for relevant implementation PRs)
41996+
if (parent.keywordToken === SyntaxKind.ImportKeyword && idText(node as Identifier) === "meta") {
41997+
return getGlobalImportMetaExpressionType().members!.get("meta" as __String);
41998+
}
41999+
// no other meta properties are valid syntax, thus no others should have symbols
42000+
return undefined;
4199442001
}
4199542002
}
4199642003

src/compiler/transformers/classFields.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,7 +1294,7 @@ namespace ts {
12941294
resumeLexicalEnvironment();
12951295

12961296
const needsSyntheticConstructor = !constructor && isDerivedClass;
1297-
let indexOfFirstStatementAfterSuper = 0;
1297+
let indexOfFirstStatementAfterSuperAndPrologue = 0;
12981298
let prologueStatementCount = 0;
12991299
let superStatementIndex = -1;
13001300
let statements: Statement[] = [];
@@ -1305,13 +1305,16 @@ namespace ts {
13051305

13061306
// If there was a super call, visit existing statements up to and including it
13071307
if (superStatementIndex >= 0) {
1308-
indexOfFirstStatementAfterSuper = superStatementIndex + 1;
1308+
indexOfFirstStatementAfterSuperAndPrologue = superStatementIndex + 1;
13091309
statements = [
13101310
...statements.slice(0, prologueStatementCount),
1311-
...visitNodes(constructor.body.statements, visitor, isStatement, prologueStatementCount, indexOfFirstStatementAfterSuper - prologueStatementCount),
1311+
...visitNodes(constructor.body.statements, visitor, isStatement, prologueStatementCount, indexOfFirstStatementAfterSuperAndPrologue - prologueStatementCount),
13121312
...statements.slice(prologueStatementCount),
13131313
];
13141314
}
1315+
else if (prologueStatementCount >= 0) {
1316+
indexOfFirstStatementAfterSuperAndPrologue = prologueStatementCount;
1317+
}
13151318
}
13161319

13171320
if (needsSyntheticConstructor) {
@@ -1354,26 +1357,25 @@ namespace ts {
13541357
}
13551358
}
13561359
if (parameterPropertyDeclarationCount > 0) {
1357-
const parameterProperties = visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatementAfterSuper, parameterPropertyDeclarationCount);
1360+
const parameterProperties = visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatementAfterSuperAndPrologue, parameterPropertyDeclarationCount);
13581361

13591362
// If there was a super() call found, add parameter properties immediately after it
13601363
if (superStatementIndex >= 0) {
13611364
addRange(statements, parameterProperties);
13621365
}
1363-
// If a synthetic super() call was added, add them just after it
1364-
else if (needsSyntheticConstructor) {
1366+
else {
1367+
// Add add parameter properties to the top of the constructor after the prologue
1368+
let superAndPrologueStatementCount = prologueStatementCount;
1369+
// If a synthetic super() call was added, need to account for that
1370+
if (needsSyntheticConstructor) superAndPrologueStatementCount++;
13651371
statements = [
1366-
statements[0],
1372+
...statements.slice(0, superAndPrologueStatementCount),
13671373
...parameterProperties,
1368-
...statements.slice(1),
1374+
...statements.slice(superAndPrologueStatementCount),
13691375
];
13701376
}
1371-
// Since there wasn't a super() call, add them to the top of the constructor
1372-
else {
1373-
statements = [...parameterProperties, ...statements];
1374-
}
13751377

1376-
indexOfFirstStatementAfterSuper += parameterPropertyDeclarationCount;
1378+
indexOfFirstStatementAfterSuperAndPrologue += parameterPropertyDeclarationCount;
13771379
}
13781380
}
13791381
}
@@ -1385,7 +1387,7 @@ namespace ts {
13851387

13861388
// Add existing statements after the initial prologues and super call
13871389
if (constructor) {
1388-
addRange(statements, visitNodes(constructor.body!.statements, visitBodyStatement, isStatement, indexOfFirstStatementAfterSuper + prologueStatementCount));
1390+
addRange(statements, visitNodes(constructor.body!.statements, visitBodyStatement, isStatement, indexOfFirstStatementAfterSuperAndPrologue));
13891391
}
13901392

13911393
statements = factory.mergeLexicalEnvironment(statements, endLexicalEnvironment());

src/services/completions.ts

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,31 +1199,59 @@ namespace ts.Completions {
11991199
function createSnippetPrinter(
12001200
printerOptions: PrinterOptions,
12011201
) {
1202+
let escapes: TextChange[] | undefined;
12021203
const baseWriter = textChanges.createWriter(getNewLineCharacter(printerOptions));
12031204
const printer = createPrinter(printerOptions, baseWriter);
12041205
const writer: EmitTextWriter = {
12051206
...baseWriter,
1206-
write: s => baseWriter.write(escapeSnippetText(s)),
1207+
write: s => escapingWrite(s, () => baseWriter.write(s)),
12071208
nonEscapingWrite: baseWriter.write,
1208-
writeLiteral: s => baseWriter.writeLiteral(escapeSnippetText(s)),
1209-
writeStringLiteral: s => baseWriter.writeStringLiteral(escapeSnippetText(s)),
1210-
writeSymbol: (s, symbol) => baseWriter.writeSymbol(escapeSnippetText(s), symbol),
1211-
writeParameter: s => baseWriter.writeParameter(escapeSnippetText(s)),
1212-
writeComment: s => baseWriter.writeComment(escapeSnippetText(s)),
1213-
writeProperty: s => baseWriter.writeProperty(escapeSnippetText(s)),
1209+
writeLiteral: s => escapingWrite(s, () => baseWriter.writeLiteral(s)),
1210+
writeStringLiteral: s => escapingWrite(s, () => baseWriter.writeStringLiteral(s)),
1211+
writeSymbol: (s, symbol) => escapingWrite(s, () => baseWriter.writeSymbol(s, symbol)),
1212+
writeParameter: s => escapingWrite(s, () => baseWriter.writeParameter(s)),
1213+
writeComment: s => escapingWrite(s, () => baseWriter.writeComment(s)),
1214+
writeProperty: s => escapingWrite(s, () => baseWriter.writeProperty(s)),
12141215
};
12151216

12161217
return {
12171218
printSnippetList,
12181219
printAndFormatSnippetList,
12191220
};
12201221

1222+
// The formatter/scanner will have issues with snippet-escaped text,
1223+
// so instead of writing the escaped text directly to the writer,
1224+
// generate a set of changes that can be applied to the unescaped text
1225+
// to escape it post-formatting.
1226+
function escapingWrite(s: string, write: () => void) {
1227+
const escaped = escapeSnippetText(s);
1228+
if (escaped !== s) {
1229+
const start = baseWriter.getTextPos();
1230+
write();
1231+
const end = baseWriter.getTextPos();
1232+
escapes = append(escapes ||= [], { newText: escaped, span: { start, length: end - start } });
1233+
}
1234+
else {
1235+
write();
1236+
}
1237+
}
1238+
12211239
/* Snippet-escaping version of `printer.printList`. */
12221240
function printSnippetList(
12231241
format: ListFormat,
12241242
list: NodeArray<Node>,
12251243
sourceFile: SourceFile | undefined,
12261244
): string {
1245+
const unescaped = printUnescapedSnippetList(format, list, sourceFile);
1246+
return escapes ? textChanges.applyChanges(unescaped, escapes) : unescaped;
1247+
}
1248+
1249+
function printUnescapedSnippetList(
1250+
format: ListFormat,
1251+
list: NodeArray<Node>,
1252+
sourceFile: SourceFile | undefined,
1253+
): string {
1254+
escapes = undefined;
12271255
writer.clear();
12281256
printer.writeList(format, list, sourceFile, writer);
12291257
return writer.getText();
@@ -1236,7 +1264,7 @@ namespace ts.Completions {
12361264
formatContext: formatting.FormatContext,
12371265
): string {
12381266
const syntheticFile = {
1239-
text: printSnippetList(
1267+
text: printUnescapedSnippetList(
12401268
format,
12411269
list,
12421270
sourceFile),
@@ -1256,7 +1284,11 @@ namespace ts.Completions {
12561284
/* delta */ 0,
12571285
{ ...formatContext, options: formatOptions });
12581286
});
1259-
return textChanges.applyChanges(syntheticFile.text, changes);
1287+
1288+
const allChanges = escapes
1289+
? stableSort(concatenate(changes, escapes), (a, b) => compareTextSpans(a.span, b.span))
1290+
: changes;
1291+
return textChanges.applyChanges(syntheticFile.text, allChanges);
12601292
}
12611293
}
12621294

src/testRunner/unittests/tsbuild/configFileErrors.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace ts {
99
});
1010

1111
describe("unittests:: tsbuild:: configFileErrors:: reports syntax errors in config file", () => {
12-
function descripencyExplaination() {
12+
function discrepancyExplanation() {
1313
return [
1414
"During incremental build, tsbuildinfo is not emitted, so declaration option is not present",
1515
"Clean build has declaration option in tsbuildinfo",
@@ -39,14 +39,14 @@ namespace ts {
3939
modifyFs: fs => replaceText(fs, "/src/tsconfig.json", ",", `,
4040
"declaration": true,`),
4141
subScenario: "reports syntax errors after change to config file",
42-
descripencyExplaination
42+
discrepancyExplanation
4343
},
4444
{
4545
modifyFs: fs => appendText(fs, "/src/a.ts", "export function fooBar() { }"),
4646
subScenario: "reports syntax errors after change to ts file",
47-
descripencyExplaination,
47+
discrepancyExplanation,
4848
},
49-
{ ...noChangeRun, descripencyExplaination },
49+
{ ...noChangeRun, discrepancyExplanation },
5050
{
5151
modifyFs: fs => fs.writeFileSync(
5252
"/src/tsconfig.json",

src/testRunner/unittests/tsbuild/helpers.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ interface Symbol {
329329
const text = baselineRecorder.lines.join("\r\n");
330330
sys.writeFile(`${buildInfoPath}.baseline.txt`, text);
331331
}
332-
interface VerifyTscEditDescripanciesInput {
332+
interface VerifyTscEditDiscrepanciesInput {
333333
index: number;
334334
scenario: TestTscCompile["scenario"];
335335
subScenario: TestTscCompile["subScenario"];
@@ -339,13 +339,13 @@ interface Symbol {
339339
editFs: TestTscEdit["modifyFs"];
340340
baseFs: vfs.FileSystem;
341341
newSys: TscCompileSystem;
342-
descripencyExplaination: TestTscEdit["descripencyExplaination"];
342+
discrepancyExplanation: TestTscEdit["discrepancyExplanation"];
343343
}
344-
function verifyTscEditDescripancies({
344+
function verifyTscEditDiscrepancies({
345345
index, scenario, subScenario, commandLineArgs,
346-
descripencyExplaination, baselines,
346+
discrepancyExplanation, baselines,
347347
modifyFs, editFs, baseFs, newSys
348-
}: VerifyTscEditDescripanciesInput): string[] | undefined {
348+
}: VerifyTscEditDiscrepanciesInput): string[] | undefined {
349349
const sys = testTscCompile({
350350
scenario,
351351
subScenario,
@@ -431,11 +431,11 @@ interface Symbol {
431431
}
432432
}
433433
}
434-
if (!headerAdded && descripencyExplaination) addBaseline("*** Supplied descripency explaination but didnt file any difference");
434+
if (!headerAdded && discrepancyExplanation) addBaseline("*** Supplied discrepancy explanation but didnt file any difference");
435435
return baselines;
436436

437437
function verifyTextEqual(incrementalText: string | undefined, cleanText: string | undefined, message: string) {
438-
if (incrementalText !== cleanText) writeIncorretness(incrementalText, cleanText, message);
438+
if (incrementalText !== cleanText) writeNotEqual(incrementalText, cleanText, message);
439439
}
440440

441441
function verifyMapLike<T>(incremental: MapLike<T> | undefined, clean: MapLike<T> | undefined, verifyValue: (key: string, incrementalValue: T, cleanValue: T) => string[] | undefined, message: string) {
@@ -474,10 +474,10 @@ interface Symbol {
474474
else {
475475
if (actual !== undefined) return;
476476
}
477-
writeIncorretness(actual, expected, message);
477+
writeNotEqual(actual, expected, message);
478478
}
479479

480-
function writeIncorretness<T>(actual: T | undefined, expected: T | undefined, message: string) {
480+
function writeNotEqual<T>(actual: T | undefined, expected: T | undefined, message: string) {
481481
addBaseline(
482482
message,
483483
"CleanBuild:",
@@ -489,7 +489,7 @@ interface Symbol {
489489

490490
function addBaseline(...text: string[]) {
491491
if (!baselines || !headerAdded) {
492-
(baselines ||= []).push(`${index}:: ${subScenario}`, ...(descripencyExplaination?.()|| ["*** Needs explaination"]));
492+
(baselines ||= []).push(`${index}:: ${subScenario}`, ...(discrepancyExplanation?.()|| ["*** Needs explanation"]));
493493
headerAdded = true;
494494
}
495495
baselines.push(...text);
@@ -540,7 +540,8 @@ interface Symbol {
540540
modifyFs: (fs: vfs.FileSystem) => void;
541541
subScenario: string;
542542
commandLineArgs?: readonly string[];
543-
descripencyExplaination?: () => readonly string[];
543+
/** An array of lines to be printed in order when a discrepancy is detected */
544+
discrepancyExplanation?: () => readonly string[];
544545
}
545546

546547
export interface VerifyTscWithEditsInput extends TestTscCompile {
@@ -610,15 +611,15 @@ interface Symbol {
610611
it("tsc invocation after edit and clean build correctness", () => {
611612
let baselines: string[] | undefined;
612613
for (let index = 0; index < edits.length; index++) {
613-
baselines = verifyTscEditDescripancies({
614+
baselines = verifyTscEditDiscrepancies({
614615
index,
615616
scenario,
616617
subScenario: edits[index].subScenario,
617618
baselines,
618619
baseFs,
619620
newSys: editsSys[index],
620621
commandLineArgs: edits[index].commandLineArgs || commandLineArgs,
621-
descripencyExplaination: edits[index].descripencyExplaination,
622+
discrepancyExplanation: edits[index].discrepancyExplanation,
622623
editFs: fs => {
623624
for (let i = 0; i <= index; i++) {
624625
edits[i].modifyFs(fs);

src/testRunner/unittests/tsbuild/noEmitOnError.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ const a: string = "hello";`, "utf-8"),
7373
const a: string = 10;`, "utf-8"),
7474
commandLineArgs: ["--b", "/src/tsconfig.json", "--incremental"],
7575
edits: [
76-
noChangeWithExportsDescripencyRun,
76+
noChangeWithExportsDiscrepancyRun,
7777
{
7878
subScenario: "Fix error",
7979
modifyFs: fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db";

0 commit comments

Comments
 (0)