Skip to content

Commit c3c758b

Browse files
committed
Merge branch 'master' into compute-common-source-dir
2 parents ecd4435 + d2d2213 commit c3c758b

36 files changed

Lines changed: 1888 additions & 198 deletions

src/compiler/binder.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,14 @@ namespace ts {
175175
symbol.members = {};
176176
}
177177

178-
if (symbolFlags & SymbolFlags.Value && !symbol.valueDeclaration) {
179-
symbol.valueDeclaration = node;
180-
}
178+
if (symbolFlags & SymbolFlags.Value) {
179+
const valueDeclaration = symbol.valueDeclaration;
180+
if (!valueDeclaration ||
181+
(valueDeclaration.kind !== node.kind && valueDeclaration.kind === SyntaxKind.ModuleDeclaration)) {
182+
// other kinds of value declarations take precedence over modules
183+
symbol.valueDeclaration = node;
184+
}
185+
}
181186
}
182187

183188
// Should not be called on a declaration with a computed property name,

src/compiler/checker.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ namespace ts {
200200
"symbol": {
201201
type: esSymbolType,
202202
flags: TypeFlags.ESSymbol
203+
},
204+
"undefined": {
205+
type: undefinedType,
206+
flags: TypeFlags.ContainsUndefinedOrNull
203207
}
204208
};
205209

@@ -295,7 +299,12 @@ namespace ts {
295299
target.constEnumOnlyModule = false;
296300
}
297301
target.flags |= source.flags;
298-
if (!target.valueDeclaration && source.valueDeclaration) target.valueDeclaration = source.valueDeclaration;
302+
if (source.valueDeclaration &&
303+
(!target.valueDeclaration ||
304+
(target.valueDeclaration.kind === SyntaxKind.ModuleDeclaration && source.valueDeclaration.kind !== SyntaxKind.ModuleDeclaration))) {
305+
// other kinds of value declarations take precedence over modules
306+
target.valueDeclaration = source.valueDeclaration;
307+
}
299308
forEach(source.declarations, node => {
300309
target.declarations.push(node);
301310
});
@@ -6470,6 +6479,10 @@ namespace ts {
64706479
assumeTrue = !assumeTrue;
64716480
}
64726481
const typeInfo = primitiveTypeInfo[right.text];
6482+
// Don't narrow `undefined`
6483+
if (typeInfo && typeInfo.type === undefinedType) {
6484+
return type;
6485+
}
64736486
// If the type to be narrowed is any and we're checking a primitive with assumeTrue=true, return the primitive
64746487
if (!!(type.flags & TypeFlags.Any) && typeInfo && assumeTrue) {
64756488
return typeInfo.type;
@@ -11347,11 +11360,15 @@ namespace ts {
1134711360
const errorNode: Node = (<FunctionLikeDeclaration>subsequentNode).name || subsequentNode;
1134811361
// TODO(jfreeman): These are methods, so handle computed name case
1134911362
if (node.name && (<FunctionLikeDeclaration>subsequentNode).name && (<Identifier>node.name).text === (<Identifier>(<FunctionLikeDeclaration>subsequentNode).name).text) {
11350-
// the only situation when this is possible (same kind\same name but different symbol) - mixed static and instance class members
1135111363
Debug.assert(node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature);
11352-
Debug.assert((node.flags & NodeFlags.Static) !== (subsequentNode.flags & NodeFlags.Static));
11353-
const diagnostic = node.flags & NodeFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static;
11354-
error(errorNode, diagnostic);
11364+
// we can get here in two cases
11365+
// 1. mixed static and instance class members
11366+
// 2. something with the same name was defined before the set of overloads that prevents them from merging
11367+
// here we'll report error only for the first case since for second we should already report error in binder
11368+
if ((node.flags & NodeFlags.Static) !== (subsequentNode.flags & NodeFlags.Static)) {
11369+
const diagnostic = node.flags & NodeFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static;
11370+
error(errorNode, diagnostic);
11371+
}
1135511372
return;
1135611373
}
1135711374
else if (nodeIsPresent((<FunctionLikeDeclaration>subsequentNode).body)) {

src/compiler/emitter.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5003,8 +5003,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
50035003
increaseIndent();
50045004
writeLine();
50055005
emitLeadingComments(node.body);
5006+
emitStart(body);
50065007
write("return ");
50075008
emit(body);
5009+
emitEnd(body);
50085010
write(";");
50095011
emitTrailingComments(node.body);
50105012

src/harness/compilerRunner.ts

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class CompilerBaselineRunner extends RunnerBase {
4141
}
4242

4343
private makeUnitName(name: string, root: string) {
44-
return ts.isRootedDiskPath(name) ? name : (root + name);
44+
return ts.isRootedDiskPath(name) ? name : ts.combinePaths(root, name);
4545
};
4646

4747
public checkTestCodeOutput(fileName: string) {
@@ -58,20 +58,18 @@ class CompilerBaselineRunner extends RunnerBase {
5858
let program: ts.Program;
5959
let options: ts.CompilerOptions;
6060
// equivalent to the files that will be passed on the command line
61-
let toBeCompiled: { unitName: string; content: string }[];
61+
let toBeCompiled: Harness.Compiler.TestFile[];
6262
// equivalent to other files on the file system not directly passed to the compiler (ie things that are referenced by other files)
63-
let otherFiles: { unitName: string; content: string }[];
64-
let harnessCompiler: Harness.Compiler.HarnessCompiler;
63+
let otherFiles: Harness.Compiler.TestFile[];
6564

6665
before(() => {
6766
justName = fileName.replace(/^.*[\\\/]/, ""); // strips the fileName from the path.
6867
const content = Harness.IO.readFile(fileName);
6968
const testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName);
7069
const units = testCaseContent.testUnitData;
71-
tcSettings = testCaseContent.settings;
70+
harnessSettings = testCaseContent.settings;
7271
lastUnit = units[units.length - 1];
7372
const rootDir = lastUnit.originalFilePath.indexOf("conformance") === -1 ? "tests/cases/compiler/" : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf("/")) + "/";
74-
harnessCompiler = Harness.Compiler.getCompiler();
7573
// We need to assemble the list of input files for the compiler and other related files on the 'filesystem' (ie in a multi-file test)
7674
// If the last file in a test uses require or a triple slash reference we'll assume all other files will be brought in via references,
7775
// otherwise, assume all files are just meant to be in the same compilation session without explicit references to one another.
@@ -91,34 +89,32 @@ class CompilerBaselineRunner extends RunnerBase {
9189
});
9290
}
9391

94-
options = harnessCompiler.compileFiles(toBeCompiled, otherFiles, function (compileResult, _program) {
95-
result = compileResult;
96-
// The program will be used by typeWriter
97-
program = _program;
98-
}, function (settings) {
99-
harnessCompiler.setCompilerSettings(tcSettings);
100-
});
92+
const output = Harness.Compiler.HarnessCompiler.compileFiles(
93+
toBeCompiled, otherFiles, harnessSettings, /* options */ undefined, /* currentDirectory */ undefined);
94+
95+
options = output.options;
96+
result = output.result;
97+
program = output.program;
10198
});
10299

103100
after(() => {
104101
// Mocha holds onto the closure environment of the describe callback even after the test is done.
105102
// Therefore we have to clean out large objects after the test is done.
106103
justName = undefined;
107-
tcSettings = undefined;
104+
harnessSettings = undefined;
108105
lastUnit = undefined;
109106
result = undefined;
110107
program = undefined;
111108
options = undefined;
112109
toBeCompiled = undefined;
113110
otherFiles = undefined;
114-
harnessCompiler = undefined;
115111
});
116112

117113
function getByteOrderMarkText(file: Harness.Compiler.GeneratedFile): string {
118114
return file.writeByteOrderMark ? "\u00EF\u00BB\u00BF" : "";
119115
}
120116

121-
function getErrorBaseline(toBeCompiled: { unitName: string; content: string }[], otherFiles: { unitName: string; content: string }[], result: Harness.Compiler.CompilerResult) {
117+
function getErrorBaseline(toBeCompiled: Harness.Compiler.TestFile[], otherFiles: Harness.Compiler.TestFile[], result: Harness.Compiler.CompilerResult) {
122118
return Harness.Compiler.getErrorBaseline(toBeCompiled.concat(otherFiles), result.errors);
123119
}
124120

@@ -180,9 +176,9 @@ class CompilerBaselineRunner extends RunnerBase {
180176
}
181177
}
182178

183-
const declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) {
184-
harnessCompiler.setCompilerSettings(tcSettings);
185-
}, options);
179+
const declFileCompilationResult =
180+
Harness.Compiler.HarnessCompiler.compileDeclarationFiles(
181+
toBeCompiled, otherFiles, result, harnessSettings, options, /* currentDirectory */ undefined);
186182

187183
if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) {
188184
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
@@ -363,7 +359,6 @@ class CompilerBaselineRunner extends RunnerBase {
363359
public initializeTests() {
364360
describe(this.testSuiteName + " tests", () => {
365361
describe("Setup compiler for compiler baselines", () => {
366-
const harnessCompiler = Harness.Compiler.getCompiler();
367362
this.parseOptions();
368363
});
369364

src/harness/fourslash.ts

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -385,17 +385,17 @@ namespace FourSlash {
385385
}
386386

387387
// Opens a file given its 0-based index or fileName
388-
public openFile(index: number): void;
389-
public openFile(name: string): void;
390-
public openFile(indexOrName: any) {
388+
public openFile(index: number, content?: string): void;
389+
public openFile(name: string, content?: string): void;
390+
public openFile(indexOrName: any, content?: string) {
391391
const fileToOpen: FourSlashFile = this.findFile(indexOrName);
392392
fileToOpen.fileName = ts.normalizeSlashes(fileToOpen.fileName);
393393
this.activeFile = fileToOpen;
394394
const fileName = fileToOpen.fileName.replace(Harness.IO.directoryName(fileToOpen.fileName), "").substr(1);
395395
this.scenarioActions.push(`<OpenFile FileName="" SrcFileId="${fileName}" FileId="${fileName}" />`);
396396

397397
// Let the host know that this file is now open
398-
this.languageServiceAdapterHost.openFile(fileToOpen.fileName);
398+
this.languageServiceAdapterHost.openFile(fileToOpen.fileName, content);
399399
}
400400

401401
public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, negative: boolean) {
@@ -2383,10 +2383,16 @@ namespace FourSlash {
23832383
// here we cache the JS output and reuse it for every test.
23842384
let fourslashJsOutput: string;
23852385
{
2386-
const host = Harness.Compiler.createCompilerHost([{ unitName: Harness.Compiler.fourslashFileName, content: undefined }],
2386+
const fourslashFile: Harness.Compiler.TestFileWithPath = {
2387+
unitName: Harness.Compiler.fourslashFileName,
2388+
content: undefined,
2389+
path: ts.toPath(Harness.Compiler.fourslashFileName, Harness.IO.getCurrentDirectory(), Harness.Compiler.getCanonicalFileName)
2390+
};
2391+
const host = Harness.Compiler.createCompilerHost([fourslashFile],
23872392
(fn, contents) => fourslashJsOutput = contents,
23882393
ts.ScriptTarget.Latest,
2389-
Harness.IO.useCaseSensitiveFileNames());
2394+
Harness.IO.useCaseSensitiveFileNames(),
2395+
Harness.IO.getCurrentDirectory());
23902396

23912397
const program = ts.createProgram([Harness.Compiler.fourslashFileName], { noResolve: true, target: ts.ScriptTarget.ES3 }, host);
23922398

@@ -2400,15 +2406,28 @@ namespace FourSlash {
24002406

24012407
currentTestState = new TestState(basePath, testType, testData);
24022408

2409+
const currentDirectory = Harness.IO.getCurrentDirectory();
2410+
const useCaseSensitiveFileNames = Harness.IO.useCaseSensitiveFileNames();
2411+
const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
2412+
24032413
let result = "";
2414+
const fourslashFile: Harness.Compiler.TestFileWithPath = {
2415+
unitName: Harness.Compiler.fourslashFileName,
2416+
content: undefined,
2417+
path: ts.toPath(Harness.Compiler.fourslashFileName, currentDirectory, getCanonicalFileName)
2418+
};
2419+
const testFile: Harness.Compiler.TestFileWithPath = {
2420+
unitName: fileName,
2421+
content: content,
2422+
path: ts.toPath(fileName, currentDirectory, getCanonicalFileName)
2423+
};
2424+
24042425
const host = Harness.Compiler.createCompilerHost(
2405-
[
2406-
{ unitName: Harness.Compiler.fourslashFileName, content: undefined },
2407-
{ unitName: fileName, content: content }
2408-
],
2426+
[ fourslashFile, testFile ],
24092427
(fn, contents) => result = contents,
24102428
ts.ScriptTarget.Latest,
2411-
Harness.IO.useCaseSensitiveFileNames());
2429+
useCaseSensitiveFileNames,
2430+
currentDirectory);
24122431

24132432
const program = ts.createProgram([Harness.Compiler.fourslashFileName, fileName], { outFile: "fourslashTestOutput.js", noResolve: true, target: ts.ScriptTarget.ES3 }, host);
24142433

0 commit comments

Comments
 (0)