Skip to content

Commit 1349a19

Browse files
committed
Merge branch 'master' of https://github.com/Microsoft/TypeScript into for-ofES5
2 parents b15d8aa + f747e5a commit 1349a19

File tree

7 files changed

+226
-128
lines changed

7 files changed

+226
-128
lines changed

src/compiler/emitter.ts

Lines changed: 84 additions & 98 deletions
Large diffs are not rendered by default.

src/harness/compilerRunner.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ class CompilerBaselineRunner extends RunnerBase {
152152
if (this.errors) {
153153
Harness.Baseline.runBaseline('Correct errors for ' + fileName, justName.replace(/\.ts$/, '.errors.txt'), (): string => {
154154
if (result.errors.length === 0) return null;
155-
156155
return getErrorBaseline(toBeCompiled, otherFiles, result);
157156
});
158157
}

src/harness/harness.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ module Harness {
835835
// Register input files
836836
function register(file: { unitName: string; content: string; }) {
837837
if (file.content !== undefined) {
838-
var fileName = ts.normalizeSlashes(file.unitName);
838+
var fileName = ts.normalizePath(file.unitName);
839839
filemap[getCanonicalFileName(fileName)] = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget);
840840
}
841841
};
@@ -844,6 +844,7 @@ module Harness {
844844
return {
845845
getCurrentDirectory,
846846
getSourceFile: (fn, languageVersion) => {
847+
fn = ts.normalizePath(fn);
847848
if (Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(fn))) {
848849
return filemap[getCanonicalFileName(fn)];
849850
}
@@ -1078,16 +1079,6 @@ module Harness {
10781079
}
10791080
});
10801081

1081-
var filemap: { [name: string]: ts.SourceFile; } = {};
1082-
var register = (file: { unitName: string; content: string; }) => {
1083-
if (file.content !== undefined) {
1084-
var fileName = ts.normalizeSlashes(file.unitName);
1085-
filemap[getCanonicalFileName(fileName)] = createSourceFileAndAssertInvariants(fileName, file.content, options.target, assertInvariants);
1086-
}
1087-
};
1088-
inputFiles.forEach(register);
1089-
otherFiles.forEach(register);
1090-
10911082
var fileOutputs: GeneratedFile[] = [];
10921083

10931084
var programFiles = inputFiles.map(file => file.unitName);

src/harness/harnessLanguageService.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ module Harness.LanguageService {
469469
this.writeMessage(message);
470470
}
471471

472+
472473
readFile(fileName: string): string {
473474
if (fileName.indexOf(Harness.Compiler.defaultLibFileName) >= 0) {
474475
fileName = Harness.Compiler.defaultLibFileName;
@@ -526,6 +527,15 @@ module Harness.LanguageService {
526527
msg(message: string) {
527528
return this.host.log(message);
528529
}
530+
531+
loggingEnabled() {
532+
return true;
533+
}
534+
535+
isVerbose() {
536+
return false;
537+
}
538+
529539

530540
endGroup(): void {
531541
}

src/server/editorServices.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
module ts.server {
66
export interface Logger {
77
close(): void;
8+
isVerbose(): boolean;
9+
loggingEnabled(): boolean;
810
perftrc(s: string): void;
911
info(s: string): void;
1012
startGroup(): void;
@@ -1071,6 +1073,7 @@ module ts.server {
10711073

10721074
static changeNumberThreshold = 8;
10731075
static changeLengthThreshold = 256;
1076+
static maxVersions = 8;
10741077

10751078
// REVIEW: can optimize by coalescing simple edits
10761079
edit(pos: number, deleteLen: number, insertedText?: string) {
@@ -1131,6 +1134,13 @@ module ts.server {
11311134
this.currentVersion = snap.version;
11321135
this.versions[snap.version] = snap;
11331136
this.changes = [];
1137+
if ((this.currentVersion - this.minVersion) >= ScriptVersionCache.maxVersions) {
1138+
var oldMin = this.minVersion;
1139+
this.minVersion = (this.currentVersion - ScriptVersionCache.maxVersions) + 1;
1140+
for (var j = oldMin; j < this.minVersion; j++) {
1141+
this.versions[j] = undefined;
1142+
}
1143+
}
11341144
}
11351145
return snap;
11361146
}

src/server/server.ts

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module ts.server {
1919
inGroup = false;
2020
firstInGroup = true;
2121

22-
constructor(public logFilename: string) {
22+
constructor(public logFilename: string, public level: string) {
2323
}
2424

2525
static padStringRight(str: string, padding: string) {
@@ -51,9 +51,20 @@ module ts.server {
5151
this.firstInGroup = true;
5252
}
5353

54+
loggingEnabled() {
55+
return !!this.logFilename;
56+
}
57+
58+
isVerbose() {
59+
return this.loggingEnabled() && (this.level == "verbose");
60+
}
61+
62+
5463
msg(s: string, type = "Err") {
5564
if (this.fd < 0) {
56-
this.fd = fs.openSync(this.logFilename, "w");
65+
if (this.logFilename) {
66+
this.fd = fs.openSync(this.logFilename, "w");
67+
}
5768
}
5869
if (this.fd >= 0) {
5970
s = s + "\n";
@@ -173,17 +184,61 @@ module ts.server {
173184
});
174185

175186
rl.on('close',() => {
176-
this.projectService.closeLog();
177187
this.projectService.log("Exiting...");
188+
this.projectService.closeLog();
178189
process.exit(0);
179190
});
180191
}
181192
}
182193

194+
interface LogOptions {
195+
file?: string;
196+
detailLevel?: string;
197+
}
198+
199+
function parseLoggingEnvironmentString(logEnvStr: string): LogOptions {
200+
var logEnv: LogOptions = {};
201+
var args = logEnvStr.split(' ');
202+
for (var i = 0, len = args.length; i < (len - 1); i += 2) {
203+
var option = args[i];
204+
var value = args[i + 1];
205+
if (option && value) {
206+
switch (option) {
207+
case "-file":
208+
logEnv.file = value;
209+
break;
210+
case "-level":
211+
logEnv.detailLevel = value;
212+
break;
213+
}
214+
}
215+
}
216+
return logEnv;
217+
}
218+
219+
// TSS_LOG "{ level: "normal | verbose | terse", file?: string}"
220+
function createLoggerFromEnv() {
221+
var fileName: string = undefined;
222+
var detailLevel = "normal";
223+
var logEnvStr = process.env["TSS_LOG"];
224+
if (logEnvStr) {
225+
var logEnv = parseLoggingEnvironmentString(logEnvStr);
226+
if (logEnv.file) {
227+
fileName = logEnv.file;
228+
}
229+
else {
230+
fileName = __dirname + "/.log" + process.pid.toString();
231+
}
232+
if (logEnv.detailLevel) {
233+
detailLevel = logEnv.detailLevel;
234+
}
235+
}
236+
return new Logger(fileName, detailLevel);
237+
}
183238
// This places log file in the directory containing editorServices.js
184239
// TODO: check that this location is writable
185-
var logger = new Logger(__dirname + "/.log" + process.pid.toString());
186240

241+
var logger = createLoggerFromEnv();
187242

188243
// REVIEW: for now this implementation uses polling.
189244
// The advantage of polling is that it works reliably

src/server/session.ts

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ module ts.server {
145145

146146
send(msg: NodeJS._debugger.Message) {
147147
var json = JSON.stringify(msg);
148+
if (this.logger.isVerbose()) {
149+
this.logger.info(msg.type + ": " + json);
150+
}
148151
this.sendLineToClient('Content-Length: ' + (1 + Buffer.byteLength(json, 'utf8')) +
149152
'\r\n\r\n' + json);
150153
}
@@ -461,19 +464,49 @@ module ts.server {
461464
var compilerService = project.compilerService;
462465
var position = compilerService.host.lineColToPosition(file, line, col);
463466
var edits = compilerService.languageService.getFormattingEditsAfterKeystroke(file, position, key,
464-
compilerService.formatCodeOptions);
467+
compilerService.formatCodeOptions);
468+
// Check whether we should auto-indent. This will be when
469+
// the position is on a line containing only whitespace.
470+
// This should leave the edits returned from
471+
// getFormattingEditsAfterKeytroke either empty or pertaining
472+
// only to the previous line. If all this is true, then
473+
// add edits necessary to properly indent the current line.
465474
if ((key == "\n") && ((!edits) || (edits.length == 0) || allEditsBeforePos(edits, position))) {
466-
// TODO: get these options from host
467-
var editorOptions: ts.EditorOptions = {
468-
IndentSize: 4,
469-
TabSize: 4,
470-
NewLineCharacter: "\n",
471-
ConvertTabsToSpaces: true,
472-
};
473-
var indentPosition = compilerService.languageService.getIndentationAtPosition(file, position, editorOptions);
474-
var spaces = generateSpaces(indentPosition);
475-
if (indentPosition > 0) {
476-
edits.push({ span: ts.createTextSpanFromBounds(position, position), newText: spaces });
475+
var scriptInfo = compilerService.host.getScriptInfo(file);
476+
if (scriptInfo) {
477+
var lineInfo = scriptInfo.getLineInfo(line);
478+
if (lineInfo && (lineInfo.leaf) && (lineInfo.leaf.text)) {
479+
var lineText = lineInfo.leaf.text;
480+
if (lineText.search("\\S") < 0) {
481+
// TODO: get these options from host
482+
var editorOptions: ts.EditorOptions = {
483+
IndentSize: 4,
484+
TabSize: 4,
485+
NewLineCharacter: "\n",
486+
ConvertTabsToSpaces: true,
487+
};
488+
var indentPosition =
489+
compilerService.languageService.getIndentationAtPosition(file, position, editorOptions);
490+
for (var i = 0, len = lineText.length; i < len; i++) {
491+
if (lineText.charAt(i) == " ") {
492+
indentPosition--;
493+
}
494+
else {
495+
break;
496+
}
497+
}
498+
if (indentPosition > 0) {
499+
var spaces = generateSpaces(indentPosition);
500+
edits.push({ span: ts.createTextSpanFromBounds(position, position), newText: spaces });
501+
}
502+
else if (indentPosition < 0) {
503+
edits.push({
504+
span: ts.createTextSpanFromBounds(position, position - indentPosition),
505+
newText: ""
506+
});
507+
}
508+
}
509+
}
477510
}
478511
}
479512

@@ -491,7 +524,7 @@ module ts.server {
491524
};
492525
});
493526
}
494-
527+
495528
getCompletions(line: number, col: number, prefix: string, fileName: string): protocol.CompletionEntry[] {
496529
if (!prefix) {
497530
prefix = "";
@@ -693,6 +726,10 @@ module ts.server {
693726
}
694727

695728
onMessage(message: string) {
729+
if (this.logger.isVerbose()) {
730+
this.logger.info("request: " + message);
731+
var start = process.hrtime();
732+
}
696733
try {
697734
var request = <protocol.Request>JSON.parse(message);
698735
var response: any;
@@ -798,13 +835,23 @@ module ts.server {
798835
}
799836
}
800837

838+
if (this.logger.isVerbose()) {
839+
var elapsed = process.hrtime(start);
840+
var seconds = elapsed[0]
841+
var nanoseconds = elapsed[1];
842+
var elapsedMs = ((1e9 * seconds) + nanoseconds)/1000000.0;
843+
var leader = "Elapsed time (in milliseconds)";
844+
if (!responseRequired) {
845+
leader = "Async elapsed time (in milliseconds)";
846+
}
847+
this.logger.msg(leader + ": " + elapsedMs.toFixed(4).toString(), "Perf");
848+
}
801849
if (response) {
802850
this.output(response, request.command, request.seq);
803851
}
804852
else if (responseRequired) {
805853
this.output(undefined, request.command, request.seq, "No content available.");
806854
}
807-
808855
} catch (err) {
809856
if (err instanceof OperationCanceledException) {
810857
// Handle cancellation exceptions

0 commit comments

Comments
 (0)