Merge branch 'master' into abstract-semicolon-insertion

This commit is contained in:
Nathan Shively-Sanders 2015-10-02 15:46:02 -07:00
commit be9548ade9
21 changed files with 135 additions and 69 deletions

View file

@ -813,7 +813,6 @@ task("update-sublime", ["local", serverFile], function() {
var tslintRuleDir = "scripts/tslint";
var tslintRules = ([
"nextLineRule",
"noInferrableTypesRule",
"noNullRule",
"booleanTriviaRule"
]);

View file

@ -1,49 +0,0 @@
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
export class Rule extends Lint.Rules.AbstractRule {
public static FAILURE_STRING_FACTORY = (type: string) => `LHS type (${type}) inferred by RHS expression, remove type annotation`;
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new InferrableTypeWalker(sourceFile, this.getOptions()));
}
}
class InferrableTypeWalker extends Lint.RuleWalker {
visitVariableStatement(node: ts.VariableStatement) {
node.declarationList.declarations.forEach(e => {
if ((!!e.type) && (!!e.initializer)) {
let failure: string;
switch (e.type.kind) {
case ts.SyntaxKind.BooleanKeyword:
if (e.initializer.kind === ts.SyntaxKind.TrueKeyword || e.initializer.kind === ts.SyntaxKind.FalseKeyword) {
failure = 'boolean';
}
break;
case ts.SyntaxKind.NumberKeyword:
if (e.initializer.kind === ts.SyntaxKind.NumericLiteral) {
failure = 'number';
}
break;
case ts.SyntaxKind.StringKeyword:
switch (e.initializer.kind) {
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
case ts.SyntaxKind.TemplateExpression:
failure = 'string';
break;
default:
break;
}
break;
}
if (failure) {
this.addFailure(this.createFailure(e.type.getStart(), e.type.getWidth(), Rule.FAILURE_STRING_FACTORY(failure)));
}
}
});
super.visitVariableStatement(node);
}
}

View file

@ -14224,7 +14224,21 @@ namespace ts {
}
if (isHeritageClauseElementIdentifier(<EntityName>entityName)) {
let meaning = entityName.parent.kind === SyntaxKind.ExpressionWithTypeArguments ? SymbolFlags.Type : SymbolFlags.Namespace;
let meaning = SymbolFlags.None;
// In an interface or class, we're definitely interested in a type.
if (entityName.parent.kind === SyntaxKind.ExpressionWithTypeArguments) {
meaning = SymbolFlags.Type;
// In a class 'extends' clause we are also looking for a value.
if (isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) {
meaning |= SymbolFlags.Value;
}
}
else {
meaning = SymbolFlags.Namespace;
}
meaning |= SymbolFlags.Alias;
return resolveEntityName(<EntityName>entityName, meaning);
}

View file

@ -8,7 +8,7 @@ namespace ts {
write(s: string): void;
readFile(path: string, encoding?: string): string;
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
watchFile?(path: string, callback: (path: string) => void): FileWatcher;
watchFile?(path: string, callback: (path: string, removed: boolean) => void): FileWatcher;
resolvePath(path: string): string;
fileExists(path: string): boolean;
directoryExists(path: string): boolean;
@ -292,11 +292,16 @@ namespace ts {
};
function fileChanged(curr: any, prev: any) {
// mtime.getTime() equals 0 if file was removed
if (curr.mtime.getTime() === 0) {
callback(fileName, /* removed */ true);
return;
}
if (+curr.mtime <= +prev.mtime) {
return;
}
callback(fileName);
callback(fileName, /* removed */ false);
}
},
resolvePath: function (path: string): string {

View file

@ -275,7 +275,7 @@ namespace ts {
let sourceFile = hostGetSourceFile(fileName, languageVersion, onError);
if (sourceFile && compilerOptions.watch) {
// Attach a file watcher
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, () => sourceFileChanged(sourceFile));
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (fileName, removed) => sourceFileChanged(sourceFile, removed));
}
return sourceFile;
}
@ -297,9 +297,15 @@ namespace ts {
}
// If a source file changes, mark it as unwatched and start the recompilation timer
function sourceFileChanged(sourceFile: SourceFile) {
function sourceFileChanged(sourceFile: SourceFile, removed: boolean) {
sourceFile.fileWatcher.close();
sourceFile.fileWatcher = undefined;
if (removed) {
let index = rootFileNames.indexOf(sourceFile.fileName);
if (index >= 0) {
rootFileNames.splice(index, 1);
}
}
startTimer();
}
@ -531,8 +537,8 @@ namespace ts {
return;
function serializeCompilerOptions(options: CompilerOptions): Map<string|number|boolean> {
let result: Map<string|number|boolean> = {};
function serializeCompilerOptions(options: CompilerOptions): Map<string | number | boolean> {
let result: Map<string | number | boolean> = {};
let optionsNameMap = getOptionNameMap().optionNameMap;
for (let name in options) {

View file

@ -985,6 +985,7 @@ namespace ts {
return node === (<ComputedPropertyName>parent).expression;
case SyntaxKind.Decorator:
case SyntaxKind.JsxExpression:
case SyntaxKind.JsxSpreadAttribute:
return true;
case SyntaxKind.ExpressionWithTypeArguments:
return (<ExpressionWithTypeArguments>parent).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);

View file

@ -157,7 +157,7 @@ namespace FourSlash {
return true;
}
public setCancelled(numberOfCalls: number = 0): void {
public setCancelled(numberOfCalls = 0): void {
ts.Debug.assert(numberOfCalls >= 0);
this.numberOfCallsBeforeCancellation = numberOfCalls;
}
@ -761,7 +761,7 @@ namespace FourSlash {
this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${JSON.stringify(missingItem)} in the returned list: (${JSON.stringify(references)})`);
}
public verifyReferencesCountIs(count: number, localFilesOnly: boolean = true) {
public verifyReferencesCountIs(count: number, localFilesOnly = true) {
this.taoInvalidReason = "verifyReferences NYI";
let references = this.getReferencesAtCaret();

View file

@ -11,7 +11,7 @@ namespace ts.server {
input: process.stdin,
output: process.stdout,
terminal: false,
});
});
class Logger implements ts.server.Logger {
fd = -1;
@ -58,7 +58,7 @@ namespace ts.server {
isVerbose() {
return this.loggingEnabled() && (this.level == "verbose");
}
msg(s: string, type = "Err") {
if (this.fd < 0) {
@ -85,7 +85,7 @@ namespace ts.server {
interface WatchedFile {
fileName: string;
callback: (fileName: string) => void;
callback: (fileName: string, removed: boolean) => void;
mtime: Date;
}
@ -121,11 +121,11 @@ namespace ts.server {
fs.stat(watchedFile.fileName,(err, stats) => {
if (err) {
watchedFile.callback(watchedFile.fileName);
watchedFile.callback(watchedFile.fileName, /* removed */ false);
}
else if (watchedFile.mtime.getTime() !== stats.mtime.getTime()) {
watchedFile.mtime = WatchedFileSet.getModifiedTime(watchedFile.fileName);
watchedFile.callback(watchedFile.fileName);
watchedFile.callback(watchedFile.fileName, watchedFile.mtime.getTime() === 0);
}
});
}
@ -153,7 +153,7 @@ namespace ts.server {
}, this.interval);
}
addFile(fileName: string, callback: (fileName: string) => void ): WatchedFile {
addFile(fileName: string, callback: (fileName: string, removed: boolean) => void ): WatchedFile {
var file: WatchedFile = {
fileName,
callback,
@ -170,7 +170,7 @@ namespace ts.server {
removeFile(file: WatchedFile) {
this.watchedFiles = WatchedFileSet.copyListRemovingItem(file, this.watchedFiles);
}
}
}
class IOSession extends Session {
constructor(host: ServerHost, logger: ts.server.Logger) {
@ -243,11 +243,11 @@ namespace ts.server {
// TODO: check that this location is writable
var logger = createLoggerFromEnv();
// REVIEW: for now this implementation uses polling.
// The advantage of polling is that it works reliably
// on all os and with network mounted files.
// For 90 referenced files, the average time to detect
// For 90 referenced files, the average time to detect
// changes is 2*msInterval (by default 5 seconds).
// The overhead of this is .04 percent (1/2500) with
// average pause of < 1 millisecond (and max
@ -271,4 +271,4 @@ namespace ts.server {
});
// Start listening
ioSession.listen();
}
}

View file

@ -8,6 +8,7 @@ var x = foo1;
class y extends x {}
>y : Symbol(y, Decl(foo2.ts, 1, 13))
>x : Symbol(x, Decl(foo2.ts, 1, 3))
=== tests/cases/conformance/classes/classExpressions/foo1.ts ===
class x{}

View file

@ -9,4 +9,5 @@ var x = A;
class C extends x { } // error, could not find symbol xs
>C : Symbol(C, Decl(extendNonClassSymbol1.ts, 1, 10))
>x : Symbol(x, Decl(extendNonClassSymbol1.ts, 1, 3))

View file

@ -145,6 +145,7 @@ var x =
<Component { ... x } y
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>x : Symbol(x, Decl(jsxReactTestSuite.tsx, 10, 11), Decl(jsxReactTestSuite.tsx, 35, 3))
>y : Symbol(unknown)
={2 } z />;
@ -167,25 +168,31 @@ var x =
<Component {...x} />;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>x : Symbol(x, Decl(jsxReactTestSuite.tsx, 10, 11), Decl(jsxReactTestSuite.tsx, 35, 3))
<Component { ...x } y={2} />;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>x : Symbol(x, Decl(jsxReactTestSuite.tsx, 10, 11), Decl(jsxReactTestSuite.tsx, 35, 3))
>y : Symbol(unknown)
<Component { ... x } y={2} z />;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>x : Symbol(x, Decl(jsxReactTestSuite.tsx, 10, 11), Decl(jsxReactTestSuite.tsx, 35, 3))
>y : Symbol(unknown)
>z : Symbol(unknown)
<Component x={1} {...y} />;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>x : Symbol(unknown)
>y : Symbol(y, Decl(jsxReactTestSuite.tsx, 9, 11))
<Component x={1} y="2" {...z} {...z}><Child /></Component>;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>x : Symbol(unknown)
>y : Symbol(unknown)
>z : Symbol(z, Decl(jsxReactTestSuite.tsx, 11, 11))
>z : Symbol(z, Decl(jsxReactTestSuite.tsx, 11, 11))
>Child : Symbol(Child, Decl(jsxReactTestSuite.tsx, 5, 11))
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))

View file

@ -20,4 +20,5 @@ var x: any;
// Should be OK
<test1 {...x} />
>test1 : Symbol(JSX.IntrinsicElements.test1, Decl(tsxAttributeResolution8.tsx, 2, 30))
>x : Symbol(x, Decl(tsxAttributeResolution8.tsx, 7, 3))

View file

@ -21,12 +21,14 @@ var p1, p2, p3;
var spreads1 = <div {...p1}>{p2}</div>;
>spreads1 : Symbol(spreads1, Decl(tsxEmit2.tsx, 8, 3))
>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22))
>p1 : Symbol(p1, Decl(tsxEmit2.tsx, 7, 3))
>p2 : Symbol(p2, Decl(tsxEmit2.tsx, 7, 7))
>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22))
var spreads2 = <div {...p1}>{p2}</div>;
>spreads2 : Symbol(spreads2, Decl(tsxEmit2.tsx, 9, 3))
>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22))
>p1 : Symbol(p1, Decl(tsxEmit2.tsx, 7, 3))
>p2 : Symbol(p2, Decl(tsxEmit2.tsx, 7, 7))
>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22))
@ -35,12 +37,14 @@ var spreads3 = <div x={p3} {...p1}>{p2}</div>;
>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22))
>x : Symbol(unknown)
>p3 : Symbol(p3, Decl(tsxEmit2.tsx, 7, 11))
>p1 : Symbol(p1, Decl(tsxEmit2.tsx, 7, 3))
>p2 : Symbol(p2, Decl(tsxEmit2.tsx, 7, 7))
>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22))
var spreads4 = <div {...p1} x={p3} >{p2}</div>;
>spreads4 : Symbol(spreads4, Decl(tsxEmit2.tsx, 11, 3))
>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22))
>p1 : Symbol(p1, Decl(tsxEmit2.tsx, 7, 3))
>x : Symbol(unknown)
>p3 : Symbol(p3, Decl(tsxEmit2.tsx, 7, 11))
>p2 : Symbol(p2, Decl(tsxEmit2.tsx, 7, 7))
@ -51,6 +55,7 @@ var spreads5 = <div x={p2} {...p1} y={p3}>{p2}</div>;
>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22))
>x : Symbol(unknown)
>p2 : Symbol(p2, Decl(tsxEmit2.tsx, 7, 7))
>p1 : Symbol(p1, Decl(tsxEmit2.tsx, 7, 3))
>y : Symbol(unknown)
>p3 : Symbol(p3, Decl(tsxEmit2.tsx, 7, 11))
>p2 : Symbol(p2, Decl(tsxEmit2.tsx, 7, 7))

View file

@ -26,6 +26,7 @@ declare var Foo, React;
// Should see mod_1['default'] in emit here
<Foo {...Main}></Foo>;
>Foo : Symbol(Foo, Decl(app.tsx, 1, 11))
>Main : Symbol(Main, Decl(app.tsx, 0, 6))
>Foo : Symbol(Foo, Decl(app.tsx, 1, 11))

View file

@ -23,12 +23,14 @@ var p1, p2, p3;
var spreads1 = <div {...p1}>{p2}</div>;
>spreads1 : Symbol(spreads1, Decl(tsxReactEmit2.tsx, 9, 3))
>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22))
>p1 : Symbol(p1, Decl(tsxReactEmit2.tsx, 8, 3))
>p2 : Symbol(p2, Decl(tsxReactEmit2.tsx, 8, 7))
>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22))
var spreads2 = <div {...p1}>{p2}</div>;
>spreads2 : Symbol(spreads2, Decl(tsxReactEmit2.tsx, 10, 3))
>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22))
>p1 : Symbol(p1, Decl(tsxReactEmit2.tsx, 8, 3))
>p2 : Symbol(p2, Decl(tsxReactEmit2.tsx, 8, 7))
>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22))
@ -37,12 +39,14 @@ var spreads3 = <div x={p3} {...p1}>{p2}</div>;
>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22))
>x : Symbol(unknown)
>p3 : Symbol(p3, Decl(tsxReactEmit2.tsx, 8, 11))
>p1 : Symbol(p1, Decl(tsxReactEmit2.tsx, 8, 3))
>p2 : Symbol(p2, Decl(tsxReactEmit2.tsx, 8, 7))
>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22))
var spreads4 = <div {...p1} x={p3} >{p2}</div>;
>spreads4 : Symbol(spreads4, Decl(tsxReactEmit2.tsx, 12, 3))
>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22))
>p1 : Symbol(p1, Decl(tsxReactEmit2.tsx, 8, 3))
>x : Symbol(unknown)
>p3 : Symbol(p3, Decl(tsxReactEmit2.tsx, 8, 11))
>p2 : Symbol(p2, Decl(tsxReactEmit2.tsx, 8, 7))
@ -53,6 +57,7 @@ var spreads5 = <div x={p2} {...p1} y={p3}>{p2}</div>;
>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22))
>x : Symbol(unknown)
>p2 : Symbol(p2, Decl(tsxReactEmit2.tsx, 8, 7))
>p1 : Symbol(p1, Decl(tsxReactEmit2.tsx, 8, 3))
>y : Symbol(unknown)
>p3 : Symbol(p3, Decl(tsxReactEmit2.tsx, 8, 11))
>p2 : Symbol(p2, Decl(tsxReactEmit2.tsx, 8, 7))

View file

@ -31,5 +31,6 @@ var spread1 = <div x='' {...foo} y='' />;
>spread1 : Symbol(spread1, Decl(react-consumer.tsx, 4, 3))
>div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 2, 22))
>x : Symbol(unknown)
>foo : Symbol(foo, Decl(react-consumer.tsx, 3, 3))
>y : Symbol(unknown)

View file

@ -34,6 +34,7 @@ namespace M {
>spread1 : Symbol(spread1, Decl(react-consumer.tsx, 8, 4))
>div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 2, 22))
>x : Symbol(unknown)
>foo : Symbol(foo, Decl(react-consumer.tsx, 7, 4))
>y : Symbol(unknown)
}

View file

@ -0,0 +1,15 @@
/// <reference path="fourslash.ts"/>
////var [|Base|] = class { };
////class C extends [|Base|] { }
let ranges = test.ranges();
for (let range of ranges) {
goTo.position(range.start);
verify.referencesCountIs(ranges.length);
for (let expectedReference of ranges) {
verify.referencesAtPositionContains(expectedReference);
}
}

View file

@ -0,0 +1,17 @@
/// <reference path="fourslash.ts"/>
////interface [|Base|] { }
////namespace n {
//// var Base = class { };
//// interface I extends [|Base|] { }
////}
let ranges = test.ranges();
for (let range of ranges) {
goTo.position(range.start);
verify.referencesCountIs(ranges.length);
for (let expectedReference of ranges) {
verify.referencesAtPositionContains(expectedReference);
}
}

View file

@ -0,0 +1,10 @@
/// <reference path="fourslash.ts"/>
////var Base = class { };
////class C extends Base implements [|Base|] { }
let ranges = test.ranges();
for (let range of ranges) {
verify.referencesCountIs(0);
}

View file

@ -0,0 +1,25 @@
/// <reference path='fourslash.ts' />
//@Filename: file.tsx
//// declare module JSX {
//// interface Element { }
//// interface IntrinsicElements {
//// }
//// interface ElementAttributesProperty { props }
//// }
//// class MyClass {
//// props: {
//// name?: string;
//// size?: number;
//// }
//// }
////
//// var [|/*dst*/nn|]: {name?: string; size?: number};
//// var x = <MyClass {...[|n/*src*/n|]}></MyClass>;
goTo.marker('src');
goTo.definition();
verify.caretAtMarker('dst');
goTo.marker('src');
verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false);