Skip to content

Commit

Permalink
Port #12027, #11980 and #11932 to master (#12037)
Browse files Browse the repository at this point in the history
* add test for the fix for overwrite emitting error

* cr feedback
  • Loading branch information
zhengbli committed Nov 4, 2016
1 parent 702efd5 commit 1c004bf
Show file tree
Hide file tree
Showing 43 changed files with 148 additions and 8 deletions.
12 changes: 12 additions & 0 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,18 @@ namespace ts {
};
}

export function createCompilerDiagnosticFromMessageChain(chain: DiagnosticMessageChain): Diagnostic {
return {
file: undefined,
start: undefined,
length: undefined,

code: chain.code,
category: chain.category,
messageText: chain.next ? chain : chain.messageText
};
}

export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: any[]): DiagnosticMessageChain;
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage): DiagnosticMessageChain {
let text = getLocaleSpecificMessage(message);
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3158,5 +3158,9 @@
"Implement inherited abstract class": {
"category": "Message",
"code": 90007
},
"Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig": {
"category": "Error",
"code": 90009
}
}
25 changes: 19 additions & 6 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,11 @@ namespace ts {
const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
const fileName = diagnostic.file.fileName;
const relativeFileName = convertToRelativePath(fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName));
output += `${ relativeFileName }(${ line + 1 },${ character + 1 }): `;
output += `${relativeFileName}(${line + 1},${character + 1}): `;
}

const category = DiagnosticCategory[diagnostic.category].toLowerCase();
output += `${ category } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) }${ host.getNewLine() }`;
output += `${category} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}${host.getNewLine()}`;
}
return output;
}
Expand Down Expand Up @@ -1685,13 +1685,24 @@ namespace ts {
const emitFilePath = toPath(emitFileName, currentDirectory, getCanonicalFileName);
// Report error if the output overwrites input file
if (filesByName.contains(emitFilePath)) {
createEmitBlockingDiagnostics(emitFileName, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file);
if (options.noEmitOverwritenFiles && !options.out && !options.outDir && !options.outFile) {
blockEmittingOfFile(emitFileName);
}
else {
let chain: DiagnosticMessageChain;
if (!options.configFilePath) {
// The program is from either an inferred project or an external project
chain = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig);
}
chain = chainDiagnosticMessages(chain, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName);
blockEmittingOfFile(emitFileName, createCompilerDiagnosticFromMessageChain(chain));
}
}

// Report error if multiple files write into same file
if (emitFilesSeen.contains(emitFilePath)) {
// Already seen the same emit file - report error
createEmitBlockingDiagnostics(emitFileName, Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files);
blockEmittingOfFile(emitFileName, createCompilerDiagnostic(Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName));
}
else {
emitFilesSeen.set(emitFilePath, true);
Expand All @@ -1700,9 +1711,11 @@ namespace ts {
}
}

function createEmitBlockingDiagnostics(emitFileName: string, message: DiagnosticMessage) {
function blockEmittingOfFile(emitFileName: string, diag?: Diagnostic) {
hasEmitBlockingDiagnostics.set(toPath(emitFileName, currentDirectory, getCanonicalFileName), true);
programDiagnostics.add(createCompilerDiagnostic(message, emitFileName));
if (diag) {
programDiagnostics.add(diag);
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3058,6 +3058,7 @@ namespace ts {
moduleResolution?: ModuleResolutionKind;
newLine?: NewLineKind;
noEmit?: boolean;
/*@internal*/noEmitOverwritenFiles?: boolean;
noEmitHelpers?: boolean;
noEmitOnError?: boolean;
noErrorTruncation?: boolean;
Expand Down
13 changes: 12 additions & 1 deletion src/harness/fourslash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1253,7 +1253,18 @@ namespace FourSlash {
resultString += "Diagnostics:" + Harness.IO.newLine();
const diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram());
for (const diagnostic of diagnostics) {
resultString += " " + diagnostic.messageText + Harness.IO.newLine();
if (typeof diagnostic.messageText !== "string") {
let chainedMessage = <ts.DiagnosticMessageChain>diagnostic.messageText;
let indentation = " ";
while (chainedMessage) {
resultString += indentation + chainedMessage.messageText + Harness.IO.newLine();
chainedMessage = chainedMessage.next;
indentation = indentation + " ";
}
}
else {
resultString += " " + diagnostic.messageText + Harness.IO.newLine();
}
}
}

Expand Down
24 changes: 24 additions & 0 deletions src/harness/unittests/tsserverProjectSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2505,4 +2505,28 @@ namespace ts.projectSystem {
checkProjectActualFiles(projectService.inferredProjects[0], [f.path]);
});
});

describe("No overwrite emit error", () => {
it("for inferred project", () => {
const f1 = {
path: "/a/b/f1.js",
content: "function test1() { }"
};
const host = createServerHost([f1, libFile]);
const session = createSession(host);
openFilesForSession([f1], session);

const projectService = session.getProjectService();
checkNumberOfProjects(projectService, { inferredProjects: 1 });
const projectName = projectService.inferredProjects[0].getProjectName();

const diags = session.executeCommand(<server.protocol.CompilerOptionsDiagnosticsRequest>{
type: "request",
command: server.CommandNames.CompilerOptionsDiagnosticsFull,
seq: 2,
arguments: { projectFileName: projectName }
}).response;
assert.isTrue(diags.length === 0);
});
});
}
4 changes: 4 additions & 0 deletions src/server/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ namespace ts.server {
this.compilerOptions.allowNonTsExtensions = true;
}

if (this.projectKind === ProjectKind.Inferred) {
this.compilerOptions.noEmitOverwritenFiles = true;
}

if (languageServiceEnabled) {
this.enableLanguageService();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
EmitSkipped: true
Diagnostics:
Cannot write file '/tests/cases/fourslash/b.js' because it would overwrite input file.
Cannot write file '/tests/cases/fourslash/b.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig

EmitSkipped: false
FileName : /tests/cases/fourslash/a.js
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
error TS5055: Cannot write file 'tests/cases/compiler/a.d.ts' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig


!!! error TS5055: Cannot write file 'tests/cases/compiler/a.d.ts' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/a.d.ts (0 errors) ====

declare class c {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
error TS5055: Cannot write file 'tests/cases/compiler/out.d.ts' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig


!!! error TS5055: Cannot write file 'tests/cases/compiler/out.d.ts' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/out.d.ts (0 errors) ====

declare class c {
Expand Down
2 changes: 2 additions & 0 deletions tests/baselines/reference/exportDefaultInJsFile01.errors.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
error TS5055: Cannot write file 'tests/cases/conformance/salsa/myFile01.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig


!!! error TS5055: Cannot write file 'tests/cases/conformance/salsa/myFile01.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/conformance/salsa/myFile01.js (0 errors) ====

export default "hello";
2 changes: 2 additions & 0 deletions tests/baselines/reference/exportDefaultInJsFile02.errors.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
error TS5055: Cannot write file 'tests/cases/conformance/salsa/myFile02.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig


!!! error TS5055: Cannot write file 'tests/cases/conformance/salsa/myFile02.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/conformance/salsa/myFile02.js (0 errors) ====

export default "hello";
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
tests/cases/compiler/a.js(1,1): error TS8009: 'declare' can only be used in a .ts file.


!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/a.js (1 errors) ====
declare var v;
~~~~~~~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
error TS5056: Cannot write file 'tests/cases/compiler/a.js' because it would be overwritten by multiple input files.


!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
!!! error TS5056: Cannot write file 'tests/cases/compiler/a.js' because it would be overwritten by multiple input files.
==== tests/cases/compiler/a.ts (0 errors) ====
class c {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
tests/cases/compiler/a.js(1,6): error TS8015: 'enum declarations' can only be used in a .ts file.


!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/a.js (1 errors) ====
enum E { }
~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
error TS5055: Cannot write file 'tests/cases/compiler/c.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig


!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.
!!! error TS5055: Cannot write file 'tests/cases/compiler/c.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/a.ts (0 errors) ====
class c {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
tests/cases/compiler/a.js(1,1): error TS8003: 'export=' can only be used in a .ts file.


!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/a.js (1 errors) ====
export = b;
~~~~~~~~~~~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
tests/cases/compiler/a.js(1,9): error TS8005: 'implements clauses' can only be used in a .ts file.


!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/a.js (1 errors) ====
class C implements D { }
~~~~~~~~~~~~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
tests/cases/compiler/a.js(1,1): error TS8002: 'import ... =' can only be used in a .ts file.


!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/a.js (1 errors) ====
import a = b;
~~~~~~~~~~~~~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
tests/cases/compiler/a.js(1,11): error TS8006: 'interface declarations' can only be used in a .ts file.


!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/a.js (1 errors) ====
interface I { }
~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
tests/cases/compiler/a.js(1,8): error TS8007: 'module declarations' can only be used in a .ts file.


!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/a.js (1 errors) ====
module M { }
~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
error TS5055: Cannot write file 'tests/cases/compiler/c.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig


!!! error TS5055: Cannot write file 'tests/cases/compiler/c.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/a.ts (0 errors) ====
class c {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
tests/cases/compiler/a.js(1,13): error TS8009: '?' can only be used in a .ts file.


!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/a.js (1 errors) ====
function F(p?) { }
~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
tests/cases/compiler/a.js(2,5): error TS8009: 'public' can only be used in a .ts file.


!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
==== tests/cases/compiler/a.js (1 errors) ====
class C {
public foo() {
Expand Down
Loading

0 comments on commit 1c004bf

Please sign in to comment.