Skip to content

Commit a500fd9

Browse files
committed
Merge branch 'master' into es2017-target
2 parents b871b53 + 31a55e6 commit a500fd9

File tree

325 files changed

+8183
-1557
lines changed

Some content is hidden

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

325 files changed

+8183
-1557
lines changed

Gulpfile.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -725,16 +725,16 @@ declare module "convert-source-map" {
725725
}
726726

727727
gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => {
728-
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "built/local/bundle.js" }, /*useBuiltCompiler*/ true));
728+
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "../../built/local/bundle.js" }, /*useBuiltCompiler*/ true));
729729
return testProject.src()
730730
.pipe(newer("built/local/bundle.js"))
731731
.pipe(sourcemaps.init())
732-
.pipe(testProject)
732+
.pipe(testProject())
733733
.pipe(through2.obj((file, enc, next) => {
734734
const originalMap = file.sourceMap;
735735
const prebundledContent = file.contents.toString();
736736
// Make paths absolute to help sorcery deal with all the terrible paths being thrown around
737-
originalMap.sources = originalMap.sources.map(s => path.resolve("src", s));
737+
originalMap.sources = originalMap.sources.map(s => path.resolve(s));
738738
// intoStream (below) makes browserify think the input file is named this, so this is what it puts in the sourcemap
739739
originalMap.file = "built/local/_stream_0.js";
740740

Jakefile.js

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ var serverCoreSources = [
176176
"lsHost.ts",
177177
"project.ts",
178178
"editorServices.ts",
179-
"protocol.d.ts",
179+
"protocol.ts",
180180
"session.ts",
181181
"server.ts"
182182
].map(function (f) {
@@ -200,14 +200,13 @@ var typingsInstallerSources = [
200200
var serverSources = serverCoreSources.concat(servicesSources);
201201

202202
var languageServiceLibrarySources = [
203-
"protocol.d.ts",
203+
"protocol.ts",
204204
"utilities.ts",
205205
"scriptVersionCache.ts",
206206
"scriptInfo.ts",
207207
"lsHost.ts",
208208
"project.ts",
209209
"editorServices.ts",
210-
"protocol.d.ts",
211210
"session.ts",
212211

213212
].map(function (f) {
@@ -261,15 +260,14 @@ var harnessSources = harnessCoreSources.concat([
261260
].map(function (f) {
262261
return path.join(unittestsDirectory, f);
263262
})).concat([
264-
"protocol.d.ts",
263+
"protocol.ts",
265264
"utilities.ts",
266265
"scriptVersionCache.ts",
267266
"scriptInfo.ts",
268267
"lsHost.ts",
269268
"project.ts",
270269
"typingsCache.ts",
271270
"editorServices.ts",
272-
"protocol.d.ts",
273271
"session.ts",
274272
].map(function (f) {
275273
return path.join(serverDirectory, f);
@@ -520,6 +518,40 @@ compileFile(processDiagnosticMessagesJs,
520518
[],
521519
/*useBuiltCompiler*/ false);
522520

521+
var buildProtocolTs = path.join(scriptsDirectory, "buildProtocol.ts");
522+
var buildProtocolJs = path.join(scriptsDirectory, "buildProtocol.js");
523+
var buildProtocolDts = path.join(builtLocalDirectory, "protocol.d.ts");
524+
var typescriptServicesDts = path.join(builtLocalDirectory, "typescriptServices.d.ts");
525+
526+
file(buildProtocolTs);
527+
528+
compileFile(buildProtocolJs,
529+
[buildProtocolTs],
530+
[buildProtocolTs],
531+
[],
532+
/*useBuiltCompiler*/ false,
533+
{noOutFile: true});
534+
535+
file(buildProtocolDts, [buildProtocolTs, buildProtocolJs, typescriptServicesDts], function() {
536+
537+
var protocolTs = path.join(serverDirectory, "protocol.ts");
538+
539+
var cmd = host + " " + buildProtocolJs + " "+ protocolTs + " " + typescriptServicesDts + " " + buildProtocolDts;
540+
console.log(cmd);
541+
var ex = jake.createExec([cmd]);
542+
// Add listeners for output and error
543+
ex.addListener("stdout", function (output) {
544+
process.stdout.write(output);
545+
});
546+
ex.addListener("stderr", function (error) {
547+
process.stderr.write(error);
548+
});
549+
ex.addListener("cmdEnd", function () {
550+
complete();
551+
});
552+
ex.run();
553+
}, { async: true })
554+
523555
// The generated diagnostics map; built for the compiler and for the 'generate-diagnostics' task
524556
file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], function () {
525557
var cmd = host + " " + processDiagnosticMessagesJs + " " + diagnosticMessagesJson;
@@ -657,6 +689,8 @@ compileFile(
657689
inlineSourceMap: true
658690
});
659691

692+
file(typescriptServicesDts, [servicesFile]);
693+
660694
var cancellationTokenFile = path.join(builtLocalDirectory, "cancellationToken.js");
661695
compileFile(cancellationTokenFile, cancellationTokenSources, [builtLocalDirectory].concat(cancellationTokenSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { outDir: builtLocalDirectory, noOutFile: true });
662696

@@ -691,7 +725,7 @@ task("build-fold-end", [], function () {
691725

692726
// Local target to build the compiler and services
693727
desc("Builds the full compiler and services");
694-
task("local", ["build-fold-start", "generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile, builtGeneratedDiagnosticMessagesJSON, "lssl", "build-fold-end"]);
728+
task("local", ["build-fold-start", "generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile, buildProtocolDts, builtGeneratedDiagnosticMessagesJSON, "lssl", "build-fold-end"]);
695729

696730
// Local target to build only tsc.js
697731
desc("Builds only the compiler");
@@ -747,7 +781,7 @@ task("generate-spec", [specMd]);
747781
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
748782
desc("Makes a new LKG out of the built js files");
749783
task("LKG", ["clean", "release", "local"].concat(libraryTargets), function () {
750-
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile].concat(libraryTargets);
784+
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile, buildProtocolDts].concat(libraryTargets);
751785
var missingFiles = expectedFiles.filter(function (f) {
752786
return !fs.existsSync(f);
753787
});

scripts/buildProtocol.ts

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/// <reference types="node"/>
2+
3+
import * as ts from "../lib/typescript";
4+
import * as path from "path";
5+
6+
function endsWith(s: string, suffix: string) {
7+
return s.lastIndexOf(suffix, s.length - suffix.length) !== -1;
8+
}
9+
10+
class DeclarationsWalker {
11+
private visitedTypes: ts.Type[] = [];
12+
private text = "";
13+
private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) {
14+
}
15+
16+
static getExtraDeclarations(typeChecker: ts.TypeChecker, protocolFile: ts.SourceFile): string {
17+
let text = "declare namespace ts.server.protocol {\n";
18+
var walker = new DeclarationsWalker(typeChecker, protocolFile);
19+
walker.visitTypeNodes(protocolFile);
20+
return walker.text
21+
? `declare namespace ts.server.protocol {\n${walker.text}}`
22+
: "";
23+
}
24+
25+
private processType(type: ts.Type): void {
26+
if (this.visitedTypes.indexOf(type) >= 0) {
27+
return;
28+
}
29+
this.visitedTypes.push(type);
30+
let s = type.aliasSymbol || type.getSymbol();
31+
if (!s) {
32+
return;
33+
}
34+
if (s.name === "Array") {
35+
// we should process type argument instead
36+
return this.processType((<any>type).typeArguments[0]);
37+
}
38+
else {
39+
for (const decl of s.getDeclarations()) {
40+
const sourceFile = decl.getSourceFile();
41+
if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
42+
return;
43+
}
44+
// splice declaration in final d.ts file
45+
const text = decl.getFullText();
46+
this.text += `${text}\n`;
47+
48+
// recursively pull all dependencies into result dts file
49+
this.visitTypeNodes(decl);
50+
}
51+
}
52+
}
53+
54+
private visitTypeNodes(node: ts.Node) {
55+
if (node.parent) {
56+
switch (node.parent.kind) {
57+
case ts.SyntaxKind.VariableDeclaration:
58+
case ts.SyntaxKind.MethodDeclaration:
59+
case ts.SyntaxKind.MethodSignature:
60+
case ts.SyntaxKind.PropertyDeclaration:
61+
case ts.SyntaxKind.PropertySignature:
62+
case ts.SyntaxKind.Parameter:
63+
case ts.SyntaxKind.IndexSignature:
64+
if (((<ts.VariableDeclaration | ts.MethodDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration | ts.PropertySignature | ts.MethodSignature | ts.IndexSignatureDeclaration>node.parent).type) === node) {
65+
const type = this.typeChecker.getTypeAtLocation(node);
66+
if (type && !(type.flags & ts.TypeFlags.TypeParameter)) {
67+
this.processType(type);
68+
}
69+
}
70+
break;
71+
}
72+
}
73+
ts.forEachChild(node, n => this.visitTypeNodes(n));
74+
}
75+
}
76+
77+
function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string): string {
78+
const options = { target: ts.ScriptTarget.ES5, declaration: true, noResolve: true, types: <string[]>[], stripInternal: true };
79+
80+
/**
81+
* 1st pass - generate a program from protocol.ts and typescriptservices.d.ts and emit core version of protocol.d.ts with all internal members stripped
82+
* @return text of protocol.d.t.s
83+
*/
84+
function getInitialDtsFileForProtocol() {
85+
const program = ts.createProgram([protocolTs, typeScriptServicesDts], options);
86+
87+
let protocolDts: string;
88+
program.emit(program.getSourceFile(protocolTs), (file, content) => {
89+
if (endsWith(file, ".d.ts")) {
90+
protocolDts = content;
91+
}
92+
});
93+
if (protocolDts === undefined) {
94+
throw new Error(`Declaration file for protocol.ts is not generated`)
95+
}
96+
return protocolDts;
97+
}
98+
99+
const protocolFileName = "protocol.d.ts";
100+
/**
101+
* Second pass - generate a program from protocol.d.ts and typescriptservices.d.ts, then augment core protocol.d.ts with extra types from typescriptservices.d.ts
102+
*/
103+
function getProgramWithProtocolText(protocolDts: string, includeTypeScriptServices: boolean) {
104+
const host = ts.createCompilerHost(options);
105+
const originalGetSourceFile = host.getSourceFile;
106+
host.getSourceFile = (fileName) => {
107+
if (fileName === protocolFileName) {
108+
return ts.createSourceFile(fileName, protocolDts, options.target);
109+
}
110+
return originalGetSourceFile.apply(host, [fileName]);
111+
}
112+
const rootFiles = includeTypeScriptServices ? [protocolFileName, typeScriptServicesDts] : [protocolFileName];
113+
return ts.createProgram(rootFiles, options, host);
114+
}
115+
116+
let protocolDts = getInitialDtsFileForProtocol();
117+
const program = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ true);
118+
119+
const protocolFile = program.getSourceFile("protocol.d.ts");
120+
const extraDeclarations = DeclarationsWalker.getExtraDeclarations(program.getTypeChecker(), protocolFile);
121+
if (extraDeclarations) {
122+
protocolDts += extraDeclarations;
123+
}
124+
// do sanity check and try to compile generated text as standalone program
125+
const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false);
126+
const diagnostics = [...program.getSyntacticDiagnostics(), ...program.getSemanticDiagnostics(), ...program.getGlobalDiagnostics()];
127+
if (diagnostics.length) {
128+
const flattenedDiagnostics = diagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, "\n")).join("\n");
129+
throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`);
130+
}
131+
return protocolDts;
132+
}
133+
134+
if (process.argv.length < 5) {
135+
console.log(`Expected 3 arguments: path to 'protocol.ts', path to 'typescriptservices.d.ts' and path to output file`);
136+
process.exit(1);
137+
}
138+
139+
const protocolTs = process.argv[2];
140+
const typeScriptServicesDts = process.argv[3];
141+
const outputFile = process.argv[4];
142+
const generatedProtocolDts = generateProtocolFile(protocolTs, typeScriptServicesDts);
143+
ts.sys.writeFile(outputFile, generatedProtocolDts);

scripts/tslint/preferConstRule.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ class PreferConstWalker extends Lint.RuleWalker {
126126
visitModuleDeclaration(node: ts.ModuleDeclaration) {
127127
if (node.body.kind === ts.SyntaxKind.ModuleBlock) {
128128
// For some reason module blocks are left out of the visit block traversal
129-
this.visitBlock(node.body as ts.ModuleBlock);
129+
this.visitBlock(node.body as any as ts.Block);
130130
}
131131
super.visitModuleDeclaration(node);
132132
}

scripts/tslint/typeOperatorSpacingRule.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ class TypeOperatorSpacingWalker extends Lint.RuleWalker {
1818
for (let i = 1; i < types.length; i++) {
1919
const currentType = types[i];
2020
if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
21-
const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
22-
this.addFailure(failure);
21+
const sourceFile = currentType.getSourceFile();
22+
const previousTypeEndPos = sourceFile.getLineAndCharacterOfPosition(types[i - 1].end);
23+
const currentTypeStartPos = sourceFile.getLineAndCharacterOfPosition(currentType.pos);
24+
if (previousTypeEndPos.line === currentTypeStartPos.line) {
25+
const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
26+
this.addFailure(failure);
27+
}
2328
}
2429
expectedStart = currentType.end + 2;
2530
}

src/compiler/binder.ts

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -355,11 +355,24 @@ namespace ts {
355355
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
356356
: Diagnostics.Duplicate_identifier_0;
357357

358-
forEach(symbol.declarations, declaration => {
359-
if (hasModifier(declaration, ModifierFlags.Default)) {
358+
if (symbol.declarations && symbol.declarations.length) {
359+
// If the current node is a default export of some sort, then check if
360+
// there are any other default exports that we need to error on.
361+
// We'll know whether we have other default exports depending on if `symbol` already has a declaration list set.
362+
if (isDefaultExport) {
360363
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
361364
}
362-
});
365+
else {
366+
// This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration.
367+
// Error on multiple export default in the following case:
368+
// 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default
369+
// 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers)
370+
if (symbol.declarations && symbol.declarations.length &&
371+
(isDefaultExport || (node.kind === SyntaxKind.ExportAssignment && !(<ExportAssignment>node).isExportEquals))) {
372+
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
373+
}
374+
}
375+
}
363376

364377
forEach(symbol.declarations, declaration => {
365378
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
@@ -1111,7 +1124,7 @@ namespace ts {
11111124
}
11121125
else {
11131126
forEachChild(node, bind);
1114-
if (node.operator === SyntaxKind.PlusEqualsToken || node.operator === SyntaxKind.MinusMinusToken) {
1127+
if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) {
11151128
bindAssignmentTargetFlow(node.operand);
11161129
}
11171130
}
@@ -1360,7 +1373,7 @@ namespace ts {
13601373
function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean {
13611374
const body = node.kind === SyntaxKind.SourceFile ? node : (<ModuleDeclaration>node).body;
13621375
if (body && (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock)) {
1363-
for (const stat of (<Block>body).statements) {
1376+
for (const stat of (<BlockLike>body).statements) {
13641377
if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) {
13651378
return true;
13661379
}
@@ -1944,12 +1957,15 @@ namespace ts {
19441957
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
19451958
}
19461959
else {
1960+
// An export default clause with an expression exports a value
1961+
// We want to exclude both class and function here, this is necessary to issue an error when there are both
1962+
// default export-assignment and default export function and class declaration.
19471963
const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node)
19481964
// An export default clause with an EntityNameExpression exports all meanings of that identifier
19491965
? SymbolFlags.Alias
19501966
// An export default clause with any other expression exports a value
19511967
: SymbolFlags.Property;
1952-
declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
1968+
declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.Property | SymbolFlags.AliasExcludes | SymbolFlags.Class | SymbolFlags.Function);
19531969
}
19541970
}
19551971

@@ -2207,9 +2223,9 @@ namespace ts {
22072223
if (currentFlow) {
22082224
node.flowNode = currentFlow;
22092225
}
2210-
checkStrictModeFunctionName(<FunctionExpression>node);
2211-
const bindingName = (<FunctionExpression>node).name ? (<FunctionExpression>node).name.text : "__function";
2212-
return bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, bindingName);
2226+
checkStrictModeFunctionName(node);
2227+
const bindingName = node.name ? node.name.text : "__function";
2228+
return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName);
22132229
}
22142230

22152231
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
@@ -2432,8 +2448,7 @@ namespace ts {
24322448
}
24332449

24342450
// If the parameter's name is 'this', then it is TypeScript syntax.
2435-
if (subtreeFlags & TransformFlags.ContainsDecorators
2436-
|| (name && isIdentifier(name) && name.originalKeywordKind === SyntaxKind.ThisKeyword)) {
2451+
if (subtreeFlags & TransformFlags.ContainsDecorators || isThisIdentifier(name)) {
24372452
transformFlags |= TransformFlags.AssertTypeScript;
24382453
}
24392454

0 commit comments

Comments
 (0)