mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge remote-tracking branch 'origin/master' into vladima/textChanges
This commit is contained in:
+4
-4
@@ -416,7 +416,7 @@ gulp.task(servicesFile, false, ["lib", "generate-diagnostics"], () => {
|
||||
file.path = nodeDefinitionsFile;
|
||||
return content + "\r\nexport = ts;";
|
||||
}))
|
||||
.pipe(gulp.dest(".")),
|
||||
.pipe(gulp.dest("src/services")),
|
||||
completedDts.pipe(clone())
|
||||
.pipe(insert.transform((content, file) => {
|
||||
file.path = nodeStandaloneDefinitionsFile;
|
||||
@@ -477,12 +477,12 @@ gulp.task(tsserverLibraryFile, false, [servicesFile], (done) => {
|
||||
return merge2([
|
||||
js.pipe(prependCopyright())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest(".")),
|
||||
.pipe(gulp.dest("src/server")),
|
||||
dts.pipe(prependCopyright(/*outputCopyright*/true))
|
||||
.pipe(insert.transform((content) => {
|
||||
return content + "\r\nexport = ts;\r\nexport as namespace ts;";
|
||||
}))
|
||||
.pipe(gulp.dest("."))
|
||||
.pipe(gulp.dest("src/server"))
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -960,7 +960,7 @@ gulp.task("update-sublime", "Updates the sublime plugin's tsserver", ["local", s
|
||||
});
|
||||
|
||||
gulp.task("build-rules", "Compiles tslint rules to js", () => {
|
||||
const settings: tsc.Settings = getCompilerSettings({ module: "commonjs" }, /*useBuiltCompiler*/ false);
|
||||
const settings: tsc.Settings = getCompilerSettings({ module: "commonjs", "lib": ["es6"] }, /*useBuiltCompiler*/ false);
|
||||
const dest = path.join(builtLocalDirectory, "tslint");
|
||||
return gulp.src("scripts/tslint/**/*.ts")
|
||||
.pipe(newer({
|
||||
|
||||
+11
-4
@@ -325,8 +325,14 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
|
||||
if (opts.stripInternal) {
|
||||
options += " --stripInternal";
|
||||
}
|
||||
|
||||
options += " --target es5 --lib es5,scripthost --noUnusedLocals --noUnusedParameters";
|
||||
options += " --target es5";
|
||||
if (opts.lib) {
|
||||
options += " --lib " + opts.lib
|
||||
}
|
||||
else {
|
||||
options += " --lib es5,scripthost"
|
||||
}
|
||||
options += " --noUnusedLocals --noUnusedParameters";
|
||||
|
||||
var cmd = host + " " + compilerPath + " " + options + " ";
|
||||
cmd = cmd + sources.join(" ");
|
||||
@@ -1095,7 +1101,8 @@ var tslintRules = [
|
||||
"noInOperatorRule",
|
||||
"noIncrementDecrementRule",
|
||||
"objectLiteralSurroundingSpaceRule",
|
||||
"noTypeAssertionWhitespaceRule"
|
||||
"noTypeAssertionWhitespaceRule",
|
||||
"noBomRule"
|
||||
];
|
||||
var tslintRulesFiles = tslintRules.map(function (p) {
|
||||
return path.join(tslintRuleDir, p + ".ts");
|
||||
@@ -1107,7 +1114,7 @@ desc("Compiles tslint rules to js");
|
||||
task("build-rules", ["build-rules-start"].concat(tslintRulesOutFiles).concat(["build-rules-end"]));
|
||||
tslintRulesFiles.forEach(function (ruleFile, i) {
|
||||
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false,
|
||||
{ noOutFile: true, generateDeclarations: false, outDir: path.join(builtLocalDirectory, "tslint") });
|
||||
{ noOutFile: true, generateDeclarations: false, outDir: path.join(builtLocalDirectory, "tslint"), lib: "es6" });
|
||||
});
|
||||
|
||||
desc("Emit the start of the build-rules fold");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
var tslint = require("tslint");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
|
||||
function getLinterOptions() {
|
||||
return {
|
||||
@@ -9,7 +10,7 @@ function getLinterOptions() {
|
||||
};
|
||||
}
|
||||
function getLinterConfiguration() {
|
||||
return require("../tslint.json");
|
||||
return tslint.Configuration.loadConfigurationFromPath(path.join(__dirname, "../tslint.json"));
|
||||
}
|
||||
|
||||
function lintFileContents(options, configuration, path, contents) {
|
||||
|
||||
@@ -2,52 +2,62 @@ import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static FAILURE_STRING_FACTORY = (name: string, currently: string) => `Tag boolean argument as '${name}' (currently '${currently}')`;
|
||||
public static FAILURE_STRING_FACTORY(name: string, currently?: string): string {
|
||||
const current = currently ? ` (currently '${currently}')` : "";
|
||||
return `Tag boolean argument as '${name}'${current}`;
|
||||
}
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
// Cheat to get type checker
|
||||
const program = ts.createProgram([sourceFile.fileName], Lint.createCompilerOptions());
|
||||
const checker = program.getTypeChecker();
|
||||
return this.applyWithWalker(new BooleanTriviaWalker(checker, program.getSourceFile(sourceFile.fileName), this.getOptions()));
|
||||
return this.applyWithFunction(program.getSourceFile(sourceFile.fileName), ctx => walk(ctx, checker));
|
||||
}
|
||||
}
|
||||
|
||||
class BooleanTriviaWalker extends Lint.RuleWalker {
|
||||
constructor(private checker: ts.TypeChecker, file: ts.SourceFile, opts: Lint.IOptions) {
|
||||
super(file, opts);
|
||||
function walk(ctx: Lint.WalkContext<void>, checker: ts.TypeChecker): void {
|
||||
ts.forEachChild(ctx.sourceFile, recur);
|
||||
function recur(node: ts.Node): void {
|
||||
if (node.kind === ts.SyntaxKind.CallExpression) {
|
||||
checkCall(node as ts.CallExpression);
|
||||
}
|
||||
ts.forEachChild(node, recur);
|
||||
}
|
||||
|
||||
visitCallExpression(node: ts.CallExpression) {
|
||||
super.visitCallExpression(node);
|
||||
if (node.arguments && node.arguments.some(arg => arg.kind === ts.SyntaxKind.TrueKeyword || arg.kind === ts.SyntaxKind.FalseKeyword)) {
|
||||
const targetCallSignature = this.checker.getResolvedSignature(node);
|
||||
if (!!targetCallSignature) {
|
||||
const targetParameters = targetCallSignature.getParameters();
|
||||
const source = this.getSourceFile();
|
||||
for (let index = 0; index < targetParameters.length; index++) {
|
||||
const param = targetParameters[index];
|
||||
const arg = node.arguments[index];
|
||||
if (!(arg && param)) {
|
||||
continue;
|
||||
}
|
||||
function checkCall(node: ts.CallExpression): void {
|
||||
if (!node.arguments || !node.arguments.some(arg => arg.kind === ts.SyntaxKind.TrueKeyword || arg.kind === ts.SyntaxKind.FalseKeyword)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const argType = this.checker.getContextualType(arg);
|
||||
if (argType && (argType.getFlags() & ts.TypeFlags.Boolean)) {
|
||||
if (arg.kind !== ts.SyntaxKind.TrueKeyword && arg.kind !== ts.SyntaxKind.FalseKeyword) {
|
||||
continue;
|
||||
}
|
||||
let triviaContent: string;
|
||||
const ranges = ts.getLeadingCommentRanges(arg.getFullText(), 0);
|
||||
if (ranges && ranges.length === 1 && ranges[0].kind === ts.SyntaxKind.MultiLineCommentTrivia) {
|
||||
triviaContent = arg.getFullText().slice(ranges[0].pos + 2, ranges[0].end - 2); // +/-2 to remove /**/
|
||||
}
|
||||
const targetCallSignature = checker.getResolvedSignature(node);
|
||||
if (!targetCallSignature) {
|
||||
return;
|
||||
}
|
||||
|
||||
const paramName = param.getName();
|
||||
if (triviaContent !== paramName && triviaContent !== paramName + ":") {
|
||||
this.addFailure(this.createFailure(arg.getStart(source), arg.getWidth(source), Rule.FAILURE_STRING_FACTORY(param.getName(), triviaContent)));
|
||||
}
|
||||
}
|
||||
const targetParameters = targetCallSignature.getParameters();
|
||||
for (let index = 0; index < targetParameters.length; index++) {
|
||||
const param = targetParameters[index];
|
||||
const arg = node.arguments[index];
|
||||
if (!(arg && param)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const argType = checker.getContextualType(arg);
|
||||
if (argType && (argType.getFlags() & ts.TypeFlags.Boolean)) {
|
||||
if (arg.kind !== ts.SyntaxKind.TrueKeyword && arg.kind !== ts.SyntaxKind.FalseKeyword) {
|
||||
continue;
|
||||
}
|
||||
let triviaContent: string | undefined;
|
||||
const ranges = ts.getLeadingCommentRanges(arg.getFullText(), 0);
|
||||
if (ranges && ranges.length === 1 && ranges[0].kind === ts.SyntaxKind.MultiLineCommentTrivia) {
|
||||
triviaContent = arg.getFullText().slice(ranges[0].pos + 2, ranges[0].end - 2); // +/-2 to remove /**/
|
||||
}
|
||||
|
||||
const paramName = param.getName();
|
||||
if (triviaContent !== paramName && triviaContent !== paramName + ":") {
|
||||
ctx.addFailureAtNode(arg, Rule.FAILURE_STRING_FACTORY(param.getName(), triviaContent));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,50 +9,56 @@ export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static ELSE_FAILURE_STRING = "'else' should not be on the same line as the preceeding block's curly brace";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new NextLineWalker(sourceFile, this.getOptions()));
|
||||
const options = this.getOptions().ruleArguments;
|
||||
const checkCatch = options.indexOf(OPTION_CATCH) !== -1;
|
||||
const checkElse = options.indexOf(OPTION_ELSE) !== -1;
|
||||
return this.applyWithFunction(sourceFile, ctx => walk(ctx, checkCatch, checkElse));
|
||||
}
|
||||
}
|
||||
|
||||
class NextLineWalker extends Lint.RuleWalker {
|
||||
public visitIfStatement(node: ts.IfStatement) {
|
||||
const sourceFile = node.getSourceFile();
|
||||
const thenStatement = node.thenStatement;
|
||||
|
||||
const elseStatement = node.elseStatement;
|
||||
if (!!elseStatement) {
|
||||
// find the else keyword
|
||||
const elseKeyword = getFirstChildOfKind(node, ts.SyntaxKind.ElseKeyword);
|
||||
if (this.hasOption(OPTION_ELSE) && !!elseKeyword) {
|
||||
const thenStatementEndLoc = sourceFile.getLineAndCharacterOfPosition(thenStatement.getEnd());
|
||||
const elseKeywordLoc = sourceFile.getLineAndCharacterOfPosition(elseKeyword.getStart(sourceFile));
|
||||
if (thenStatementEndLoc.line === elseKeywordLoc.line) {
|
||||
const failure = this.createFailure(elseKeyword.getStart(sourceFile), elseKeyword.getWidth(sourceFile), Rule.ELSE_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
}
|
||||
function walk(ctx: Lint.WalkContext<void>, checkCatch: boolean, checkElse: boolean): void {
|
||||
const { sourceFile } = ctx;
|
||||
function recur(node: ts.Node): void {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.IfStatement:
|
||||
checkIf(node as ts.IfStatement);
|
||||
break;
|
||||
case ts.SyntaxKind.TryStatement:
|
||||
checkTry(node as ts.TryStatement);
|
||||
break;
|
||||
}
|
||||
|
||||
super.visitIfStatement(node);
|
||||
ts.forEachChild(node, recur);
|
||||
}
|
||||
|
||||
public visitTryStatement(node: ts.TryStatement) {
|
||||
const sourceFile = node.getSourceFile();
|
||||
const catchClause = node.catchClause;
|
||||
function checkIf(node: ts.IfStatement): void {
|
||||
const { thenStatement, elseStatement } = node;
|
||||
if (!elseStatement) {
|
||||
return;
|
||||
}
|
||||
|
||||
// "visit" try block
|
||||
const tryBlock = node.tryBlock;
|
||||
|
||||
if (this.hasOption(OPTION_CATCH) && !!catchClause) {
|
||||
const tryClosingBrace = tryBlock.getLastToken(sourceFile);
|
||||
const catchKeyword = catchClause.getFirstToken(sourceFile);
|
||||
const tryClosingBraceLoc = sourceFile.getLineAndCharacterOfPosition(tryClosingBrace.getEnd());
|
||||
const catchKeywordLoc = sourceFile.getLineAndCharacterOfPosition(catchKeyword.getStart(sourceFile));
|
||||
if (tryClosingBraceLoc.line === catchKeywordLoc.line) {
|
||||
const failure = this.createFailure(catchKeyword.getStart(sourceFile), catchKeyword.getWidth(sourceFile), Rule.CATCH_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
// find the else keyword
|
||||
const elseKeyword = getFirstChildOfKind(node, ts.SyntaxKind.ElseKeyword);
|
||||
if (checkElse && !!elseKeyword) {
|
||||
const thenStatementEndLoc = sourceFile.getLineAndCharacterOfPosition(thenStatement.getEnd());
|
||||
const elseKeywordLoc = sourceFile.getLineAndCharacterOfPosition(elseKeyword.getStart(sourceFile));
|
||||
if (thenStatementEndLoc.line === elseKeywordLoc.line) {
|
||||
ctx.addFailureAtNode(elseKeyword, Rule.ELSE_FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
super.visitTryStatement(node);
|
||||
}
|
||||
|
||||
function checkTry({ tryBlock, catchClause }: ts.TryStatement): void {
|
||||
if (!checkCatch || !catchClause) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tryClosingBrace = tryBlock.getLastToken(sourceFile);
|
||||
const catchKeyword = catchClause.getFirstToken(sourceFile);
|
||||
const tryClosingBraceLoc = sourceFile.getLineAndCharacterOfPosition(tryClosingBrace.getEnd());
|
||||
const catchKeywordLoc = sourceFile.getLineAndCharacterOfPosition(catchKeyword.getStart(sourceFile));
|
||||
if (tryClosingBraceLoc.line === catchKeywordLoc.line) {
|
||||
ctx.addFailureAtNode(catchKeyword, Rule.CATCH_FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static FAILURE_STRING = "This file has a BOM.";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithFunction(sourceFile, walk);
|
||||
}
|
||||
}
|
||||
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
if (ctx.sourceFile.text[0] === "\ufeff") {
|
||||
ctx.addFailure(0, 1, Rule.FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,19 @@
|
||||
import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static FAILURE_STRING = "Don't use the 'in' keyword - use 'hasProperty' to check for key presence instead";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new InWalker(sourceFile, this.getOptions()));
|
||||
return this.applyWithFunction(sourceFile, walk);
|
||||
}
|
||||
}
|
||||
|
||||
class InWalker extends Lint.RuleWalker {
|
||||
visitNode(node: ts.Node) {
|
||||
super.visitNode(node);
|
||||
if (node.kind === ts.SyntaxKind.InKeyword && node.parent && node.parent.kind === ts.SyntaxKind.BinaryExpression) {
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
ts.forEachChild(ctx.sourceFile, recur);
|
||||
function recur(node: ts.Node): void {
|
||||
if (node.kind === ts.SyntaxKind.InKeyword && node.parent.kind === ts.SyntaxKind.BinaryExpression) {
|
||||
ctx.addFailureAtNode(node, Rule.FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +1,55 @@
|
||||
import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static POSTFIX_FAILURE_STRING = "Don't use '++' or '--' postfix operators outside statements or for loops.";
|
||||
public static PREFIX_FAILURE_STRING = "Don't use '++' or '--' prefix operators.";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new IncrementDecrementWalker(sourceFile, this.getOptions()));
|
||||
return this.applyWithFunction(sourceFile, walk);
|
||||
}
|
||||
}
|
||||
|
||||
class IncrementDecrementWalker extends Lint.RuleWalker {
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
ts.forEachChild(ctx.sourceFile, recur);
|
||||
function recur(node: ts.Node): void {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.PrefixUnaryExpression:
|
||||
const { operator } = node as ts.PrefixUnaryExpression;
|
||||
if (operator === ts.SyntaxKind.PlusPlusToken || operator === ts.SyntaxKind.MinusMinusToken) {
|
||||
check(node as ts.PrefixUnaryExpression);
|
||||
}
|
||||
break;
|
||||
|
||||
visitPostfixUnaryExpression(node: ts.PostfixUnaryExpression) {
|
||||
super.visitPostfixUnaryExpression(node);
|
||||
if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator == ts.SyntaxKind.MinusMinusToken) {
|
||||
this.visitIncrementDecrement(node);
|
||||
case ts.SyntaxKind.PostfixUnaryExpression:
|
||||
check(node as ts.PostfixUnaryExpression);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
visitPrefixUnaryExpression(node: ts.PrefixUnaryExpression) {
|
||||
super.visitPrefixUnaryExpression(node);
|
||||
if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator == ts.SyntaxKind.MinusMinusToken) {
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.PREFIX_FAILURE_STRING));
|
||||
function check(node: ts.UnaryExpression): void {
|
||||
if (!isAllowedLocation(node.parent!)) {
|
||||
ctx.addFailureAtNode(node, Rule.POSTFIX_FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visitIncrementDecrement(node: ts.UnaryExpression) {
|
||||
if (node.parent && (
|
||||
// Can be a statement
|
||||
node.parent.kind === ts.SyntaxKind.ExpressionStatement ||
|
||||
// Can be directly in a for-statement
|
||||
node.parent.kind === ts.SyntaxKind.ForStatement ||
|
||||
// Can be in a comma operator in a for statement (`for (let a = 0, b = 10; a < b; a++, b--)`)
|
||||
node.parent.kind === ts.SyntaxKind.BinaryExpression &&
|
||||
(<ts.BinaryExpression>node.parent).operatorToken.kind === ts.SyntaxKind.CommaToken &&
|
||||
node.parent.parent.kind === ts.SyntaxKind.ForStatement)) {
|
||||
return;
|
||||
}
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.POSTFIX_FAILURE_STRING));
|
||||
function isAllowedLocation(node: ts.Node): boolean {
|
||||
switch (node.kind) {
|
||||
// Can be a statement
|
||||
case ts.SyntaxKind.ExpressionStatement:
|
||||
return true;
|
||||
|
||||
// Can be directly in a for-statement
|
||||
case ts.SyntaxKind.ForStatement:
|
||||
return true;
|
||||
|
||||
// Can be in a comma operator in a for statement (`for (let a = 0, b = 10; a < b; a++, b--)`)
|
||||
case ts.SyntaxKind.BinaryExpression:
|
||||
return (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.CommaToken &&
|
||||
node.parent!.kind === ts.SyntaxKind.ForStatement;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static TRAILING_FAILURE_STRING = "Excess trailing whitespace found around type assertion.";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new TypeAssertionWhitespaceWalker(sourceFile, this.getOptions()));
|
||||
return this.applyWithFunction(sourceFile, walk);
|
||||
}
|
||||
}
|
||||
|
||||
class TypeAssertionWhitespaceWalker extends Lint.RuleWalker {
|
||||
public visitNode(node: ts.Node) {
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
ts.forEachChild(ctx.sourceFile, recur);
|
||||
function recur(node: ts.Node) {
|
||||
if (node.kind === ts.SyntaxKind.TypeAssertionExpression) {
|
||||
const refined = node as ts.TypeAssertion;
|
||||
const leftSideWhitespaceStart = refined.type.getEnd() + 1;
|
||||
const rightSideWhitespaceEnd = refined.expression.getStart();
|
||||
if (leftSideWhitespaceStart !== rightSideWhitespaceEnd) {
|
||||
this.addFailure(this.createFailure(leftSideWhitespaceStart, rightSideWhitespaceEnd, Rule.TRAILING_FAILURE_STRING));
|
||||
ctx.addFailure(leftSideWhitespaceStart, rightSideWhitespaceEnd, Rule.TRAILING_FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
super.visitNode(node);
|
||||
ts.forEachChild(node, recur);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static LEADING_FAILURE_STRING = "No leading whitespace found on single-line object literal.";
|
||||
public static TRAILING_FAILURE_STRING = "No trailing whitespace found on single-line object literal.";
|
||||
@@ -9,34 +8,37 @@ export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static TRAILING_EXCESS_FAILURE_STRING = "Excess trailing whitespace found on single-line object literal.";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new ObjectLiteralSpaceWalker(sourceFile, this.getOptions()));
|
||||
return this.applyWithFunction(sourceFile, walk);
|
||||
}
|
||||
}
|
||||
|
||||
class ObjectLiteralSpaceWalker extends Lint.RuleWalker {
|
||||
public visitNode(node: ts.Node) {
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
const { sourceFile } = ctx;
|
||||
ts.forEachChild(sourceFile, recur);
|
||||
function recur(node: ts.Node): void {
|
||||
if (node.kind === ts.SyntaxKind.ObjectLiteralExpression) {
|
||||
const literal = node as ts.ObjectLiteralExpression;
|
||||
const text = literal.getText();
|
||||
if (text.match(/^{[^\n]+}$/g)) {
|
||||
if (text.charAt(1) !== " ") {
|
||||
const failure = this.createFailure(node.pos, node.getWidth(), Rule.LEADING_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
if (text.charAt(2) === " ") {
|
||||
const failure = this.createFailure(node.pos + 2, 1, Rule.LEADING_EXCESS_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
if (text.charAt(text.length - 2) !== " ") {
|
||||
const failure = this.createFailure(node.pos, node.getWidth(), Rule.TRAILING_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
if (text.charAt(text.length - 3) === " ") {
|
||||
const failure = this.createFailure(node.pos + node.getWidth() - 3, 1, Rule.TRAILING_EXCESS_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
}
|
||||
check(node as ts.ObjectLiteralExpression);
|
||||
}
|
||||
ts.forEachChild(node, recur);
|
||||
}
|
||||
|
||||
function check(node: ts.ObjectLiteralExpression): void {
|
||||
const text = node.getText(sourceFile);
|
||||
if (!text.match(/^{[^\n]+}$/g)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (text.charAt(1) !== " ") {
|
||||
ctx.addFailureAtNode(node, Rule.LEADING_FAILURE_STRING);
|
||||
}
|
||||
if (text.charAt(2) === " ") {
|
||||
ctx.addFailureAt(node.pos + 2, 1, Rule.LEADING_EXCESS_FAILURE_STRING);
|
||||
}
|
||||
if (text.charAt(text.length - 2) !== " ") {
|
||||
ctx.addFailureAtNode(node, Rule.TRAILING_FAILURE_STRING);
|
||||
}
|
||||
if (text.charAt(text.length - 3) === " ") {
|
||||
ctx.addFailureAt(node.pos + node.getWidth() - 3, 1, Rule.TRAILING_EXCESS_FAILURE_STRING);
|
||||
}
|
||||
super.visitNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"strictNullChecks": true,
|
||||
"module": "commonjs",
|
||||
"outDir": "../../built/local/tslint"
|
||||
}
|
||||
|
||||
@@ -1,34 +1,36 @@
|
||||
import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static FAILURE_STRING = "The '|' and '&' operators must be surrounded by single spaces";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new TypeOperatorSpacingWalker(sourceFile, this.getOptions()));
|
||||
return this.applyWithFunction(sourceFile, walk);
|
||||
}
|
||||
}
|
||||
|
||||
class TypeOperatorSpacingWalker extends Lint.RuleWalker {
|
||||
public visitNode(node: ts.Node) {
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
const { sourceFile } = ctx;
|
||||
ts.forEachChild(sourceFile, recur);
|
||||
function recur(node: ts.Node): void {
|
||||
if (node.kind === ts.SyntaxKind.UnionType || node.kind === ts.SyntaxKind.IntersectionType) {
|
||||
const types = (<ts.UnionOrIntersectionTypeNode>node).types;
|
||||
let expectedStart = types[0].end + 2; // space, | or &
|
||||
for (let i = 1; i < types.length; i++) {
|
||||
const currentType = types[i];
|
||||
if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
|
||||
const sourceFile = currentType.getSourceFile();
|
||||
const previousTypeEndPos = sourceFile.getLineAndCharacterOfPosition(types[i - 1].end);
|
||||
const currentTypeStartPos = sourceFile.getLineAndCharacterOfPosition(currentType.pos);
|
||||
if (previousTypeEndPos.line === currentTypeStartPos.line) {
|
||||
const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
check((node as ts.UnionOrIntersectionTypeNode).types);
|
||||
}
|
||||
ts.forEachChild(node, recur);
|
||||
}
|
||||
|
||||
function check(types: ts.TypeNode[]): void {
|
||||
let expectedStart = types[0].end + 2; // space, | or &
|
||||
for (let i = 1; i < types.length; i++) {
|
||||
const currentType = types[i];
|
||||
if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
|
||||
const previousTypeEndPos = sourceFile.getLineAndCharacterOfPosition(types[i - 1].end);
|
||||
const currentTypeStartPos = sourceFile.getLineAndCharacterOfPosition(currentType.pos);
|
||||
if (previousTypeEndPos.line === currentTypeStartPos.line) {
|
||||
ctx.addFailureAtNode(currentType, Rule.FAILURE_STRING);
|
||||
}
|
||||
expectedStart = currentType.end + 2;
|
||||
}
|
||||
expectedStart = currentType.end + 2;
|
||||
}
|
||||
super.visitNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
+69
-20
@@ -182,7 +182,7 @@ namespace ts {
|
||||
return bindSourceFile;
|
||||
|
||||
function bindInStrictMode(file: SourceFile, opts: CompilerOptions): boolean {
|
||||
if (opts.alwaysStrict && !isDeclarationFile(file)) {
|
||||
if ((opts.alwaysStrict === undefined ? opts.strict : opts.alwaysStrict) && !isDeclarationFile(file)) {
|
||||
// bind in strict mode source files with alwaysStrict option
|
||||
return true;
|
||||
}
|
||||
@@ -1903,7 +1903,7 @@ namespace ts {
|
||||
|
||||
// Even though in the AST the jsdoc @typedef node belongs to the current node,
|
||||
// its symbol might be in the same scope with the current node's symbol. Consider:
|
||||
//
|
||||
//
|
||||
// /** @typedef {string | number} MyType */
|
||||
// function foo();
|
||||
//
|
||||
@@ -2289,7 +2289,42 @@ namespace ts {
|
||||
declareSymbol(file.symbol.exports, file.symbol, <PropertyAccessExpression>node.left, SymbolFlags.Property | SymbolFlags.Export, SymbolFlags.None);
|
||||
}
|
||||
|
||||
function isExportsOrModuleExportsOrAlias(node: Node): boolean {
|
||||
return isExportsIdentifier(node) ||
|
||||
isModuleExportsPropertyAccessExpression(node) ||
|
||||
isNameOfExportsOrModuleExportsAliasDeclaration(node);
|
||||
}
|
||||
|
||||
function isNameOfExportsOrModuleExportsAliasDeclaration(node: Node) {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
const symbol = container.locals.get((<Identifier>node).text);
|
||||
if (symbol && symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.VariableDeclaration) {
|
||||
const declaration = symbol.valueDeclaration as VariableDeclaration;
|
||||
if (declaration.initializer) {
|
||||
return isExportsOrModuleExportsOrAliasOrAssignemnt(declaration.initializer);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isExportsOrModuleExportsOrAliasOrAssignemnt(node: Node): boolean {
|
||||
return isExportsOrModuleExportsOrAlias(node) ||
|
||||
(isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (isExportsOrModuleExportsOrAliasOrAssignemnt(node.left) || isExportsOrModuleExportsOrAliasOrAssignemnt(node.right)));
|
||||
}
|
||||
|
||||
function bindModuleExportsAssignment(node: BinaryExpression) {
|
||||
// A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports'
|
||||
// is still pointing to 'module.exports'.
|
||||
// We do not want to consider this as 'export=' since a module can have only one of these.
|
||||
// Similarlly we do not want to treat 'module.exports = exports' as an 'export='.
|
||||
const assignedExpression = getRightMostAssignedExpression(node.right);
|
||||
if (isEmptyObjectLiteral(assignedExpression) || isExportsOrModuleExportsOrAlias(assignedExpression)) {
|
||||
// Mark it as a module in case there are no other exports in the file
|
||||
setCommonJsModuleIndicator(node);
|
||||
return;
|
||||
}
|
||||
|
||||
// 'module.exports = expr' assignment
|
||||
setCommonJsModuleIndicator(node);
|
||||
declareSymbol(file.symbol.exports, file.symbol, node, SymbolFlags.Property | SymbolFlags.Export | SymbolFlags.ValueModule, SymbolFlags.None);
|
||||
@@ -2297,23 +2332,28 @@ namespace ts {
|
||||
|
||||
function bindThisPropertyAssignment(node: BinaryExpression) {
|
||||
Debug.assert(isInJavaScriptFile(node));
|
||||
// Declare a 'member' if the container is an ES5 class or ES6 constructor
|
||||
if (container.kind === SyntaxKind.FunctionDeclaration || container.kind === SyntaxKind.FunctionExpression) {
|
||||
container.symbol.members = container.symbol.members || createMap<Symbol>();
|
||||
// It's acceptable for multiple 'this' assignments of the same identifier to occur
|
||||
declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
|
||||
}
|
||||
else if (container.kind === SyntaxKind.Constructor) {
|
||||
// this.foo assignment in a JavaScript class
|
||||
// Bind this property to the containing class
|
||||
const saveContainer = container;
|
||||
container = container.parent;
|
||||
const symbol = bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.None);
|
||||
if (symbol) {
|
||||
// constructor-declared symbols can be overwritten by subsequent method declarations
|
||||
(symbol as Symbol).isReplaceableByMethod = true;
|
||||
}
|
||||
container = saveContainer;
|
||||
switch (container.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
// Declare a 'member' if the container is an ES5 class or ES6 constructor
|
||||
container.symbol.members = container.symbol.members || createMap<Symbol>();
|
||||
// It's acceptable for multiple 'this' assignments of the same identifier to occur
|
||||
declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
|
||||
break;
|
||||
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
// this.foo assignment in a JavaScript class
|
||||
// Bind this property to the containing class
|
||||
const containingClass = container.parent;
|
||||
const symbol = declareSymbol(hasModifier(container, ModifierFlags.Static) ? containingClass.symbol.exports : containingClass.symbol.members, containingClass.symbol, node, SymbolFlags.Property, SymbolFlags.None);
|
||||
if (symbol) {
|
||||
// symbols declared through 'this' property assignements can be overwritten by subsequent method declarations
|
||||
(symbol as Symbol).isReplaceableByMethod = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2346,11 +2386,20 @@ namespace ts {
|
||||
leftSideOfAssignment.parent = node;
|
||||
target.parent = leftSideOfAssignment;
|
||||
|
||||
bindPropertyAssignment(target.text, leftSideOfAssignment, /*isPrototypeProperty*/ false);
|
||||
if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) {
|
||||
// This can be an alias for the 'exports' or 'module.exports' names, e.g.
|
||||
// var util = module.exports;
|
||||
// util.property = function ...
|
||||
bindExportsPropertyAssignment(node);
|
||||
}
|
||||
else {
|
||||
bindPropertyAssignment(target.text, leftSideOfAssignment, /*isPrototypeProperty*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
function bindPropertyAssignment(functionName: string, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean) {
|
||||
let targetSymbol = container.locals.get(functionName);
|
||||
|
||||
if (targetSymbol && isDeclarationOfFunctionOrClassExpression(targetSymbol)) {
|
||||
targetSymbol = (targetSymbol.valueDeclaration as VariableDeclaration).initializer.symbol;
|
||||
}
|
||||
|
||||
+307
-222
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
/// <reference path="sys.ts"/>
|
||||
/// <reference path="sys.ts"/>
|
||||
/// <reference path="types.ts"/>
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="diagnosticInformationMap.generated.ts"/>
|
||||
@@ -467,6 +467,11 @@ namespace ts {
|
||||
type: "boolean",
|
||||
description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
|
||||
},
|
||||
{
|
||||
name: "strict",
|
||||
type: "boolean",
|
||||
description: Diagnostics.Enable_all_strict_type_checks
|
||||
},
|
||||
{
|
||||
// A list of plugins to load in the language service
|
||||
name: "plugins",
|
||||
@@ -520,7 +525,7 @@ namespace ts {
|
||||
export const defaultInitCompilerOptions: CompilerOptions = {
|
||||
module: ModuleKind.CommonJS,
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
strict: true,
|
||||
sourceMap: false,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="types.ts"/>
|
||||
/// <reference path="types.ts"/>
|
||||
/// <reference path="performance.ts" />
|
||||
|
||||
namespace ts {
|
||||
|
||||
@@ -3045,6 +3045,10 @@
|
||||
"category": "Message",
|
||||
"code": 6149
|
||||
},
|
||||
"Enable all strict type checks.": {
|
||||
"category": "Message",
|
||||
"code": 6150
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="checker.ts" />
|
||||
/// <reference path="checker.ts" />
|
||||
/// <reference path="transformer.ts" />
|
||||
/// <reference path="declarationEmitter.ts" />
|
||||
/// <reference path="sourcemap.ts" />
|
||||
@@ -826,8 +826,8 @@ namespace ts {
|
||||
writeIfPresent(node.dotDotDotToken, "...");
|
||||
emit(node.name);
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
emitExpressionWithPrefix(" = ", node.initializer);
|
||||
emitWithPrefix(": ", node.type);
|
||||
emitExpressionWithPrefix(" = ", node.initializer);
|
||||
}
|
||||
|
||||
function emitDecorator(decorator: Decorator) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="utilities.ts"/>
|
||||
|
||||
namespace ts {
|
||||
|
||||
+44
-2
@@ -290,6 +290,11 @@ namespace ts {
|
||||
return resolutions;
|
||||
}
|
||||
|
||||
interface DiagnosticCache {
|
||||
perFile?: FileMap<Diagnostic[]>;
|
||||
allDiagnostics?: Diagnostic[];
|
||||
}
|
||||
|
||||
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program {
|
||||
let program: Program;
|
||||
let files: SourceFile[] = [];
|
||||
@@ -298,6 +303,9 @@ namespace ts {
|
||||
let noDiagnosticsTypeChecker: TypeChecker;
|
||||
let classifiableNames: Map<string>;
|
||||
|
||||
let cachedSemanticDiagnosticsForFile: DiagnosticCache = {};
|
||||
let cachedDeclarationDiagnosticsForFile: DiagnosticCache = {};
|
||||
|
||||
let resolvedTypeReferenceDirectives = createMap<ResolvedTypeReferenceDirective>();
|
||||
let fileProcessingDiagnostics = createDiagnosticCollection();
|
||||
|
||||
@@ -899,6 +907,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedSemanticDiagnosticsForFile, getSemanticDiagnosticsForFileNoCache);
|
||||
}
|
||||
|
||||
function getSemanticDiagnosticsForFileNoCache(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return runWithCancellationToken(() => {
|
||||
const typeChecker = getDiagnosticsProducingTypeChecker();
|
||||
|
||||
@@ -1094,7 +1106,11 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function getDeclarationDiagnosticsWorker(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getDeclarationDiagnosticsWorker(sourceFile: SourceFile | undefined, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedDeclarationDiagnosticsForFile, getDeclarationDiagnosticsForFileNoCache);
|
||||
}
|
||||
|
||||
function getDeclarationDiagnosticsForFileNoCache(sourceFile: SourceFile| undefined, cancellationToken: CancellationToken) {
|
||||
return runWithCancellationToken(() => {
|
||||
const resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
|
||||
// Don't actually write any files since we're just getting diagnostics.
|
||||
@@ -1102,6 +1118,32 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function getAndCacheDiagnostics(
|
||||
sourceFile: SourceFile | undefined,
|
||||
cancellationToken: CancellationToken,
|
||||
cache: DiagnosticCache,
|
||||
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[]) {
|
||||
|
||||
const cachedResult = sourceFile
|
||||
? cache.perFile && cache.perFile.get(sourceFile.path)
|
||||
: cache.allDiagnostics;
|
||||
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
const result = getDiagnostics(sourceFile, cancellationToken) || emptyArray;
|
||||
if (sourceFile) {
|
||||
if (!cache.perFile) {
|
||||
cache.perFile = createFileMap<Diagnostic[]>();
|
||||
}
|
||||
cache.perFile.set(sourceFile.path, result);
|
||||
}
|
||||
else {
|
||||
cache.allDiagnostics = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return isDeclarationFile(sourceFile) ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
|
||||
}
|
||||
@@ -1630,7 +1672,7 @@ namespace ts {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib"));
|
||||
}
|
||||
|
||||
if (options.noImplicitUseStrict && options.alwaysStrict) {
|
||||
if (options.noImplicitUseStrict && (options.alwaysStrict === undefined ? options.strict : options.alwaysStrict)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict"));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="core.ts"/>
|
||||
|
||||
declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any;
|
||||
declare function clearTimeout(handle: any): void;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="visitor.ts" />
|
||||
/// <reference path="visitor.ts" />
|
||||
/// <reference path="transformers/ts.ts" />
|
||||
/// <reference path="transformers/jsx.ts" />
|
||||
/// <reference path="transformers/esnext.ts" />
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace ts {
|
||||
let value: Expression;
|
||||
if (isDestructuringAssignment(node)) {
|
||||
value = node.right;
|
||||
while (isEmptyObjectLiteralOrArrayLiteral(node.left)) {
|
||||
while (isEmptyArrayLiteral(node.left) || isEmptyObjectLiteral(node.left)) {
|
||||
if (isDestructuringAssignment(value)) {
|
||||
location = node = value;
|
||||
value = node.right;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
|
||||
// Transforms generator functions into a compatible ES5 representation with similar runtime
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../visitor.ts" />
|
||||
/// <reference path="../destructuring.ts" />
|
||||
|
||||
@@ -55,9 +55,7 @@ namespace ts {
|
||||
* @param node The SourceFile node.
|
||||
*/
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
if (isDeclarationFile(node)
|
||||
|| !(isExternalModule(node)
|
||||
|| compilerOptions.isolatedModules)) {
|
||||
if (isDeclarationFile(node) || !(isExternalModule(node) || compilerOptions.isolatedModules)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -74,6 +72,14 @@ namespace ts {
|
||||
return aggregateTransformFlags(updated);
|
||||
}
|
||||
|
||||
|
||||
function shouldEmitUnderscoreUnderscoreESModule() {
|
||||
if (!currentModuleInfo.exportEquals && isExternalModule(currentSourceFile)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a SourceFile into a CommonJS module.
|
||||
*
|
||||
@@ -85,7 +91,7 @@ namespace ts {
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
|
||||
|
||||
if (!currentModuleInfo.exportEquals) {
|
||||
if (shouldEmitUnderscoreUnderscoreESModule()) {
|
||||
append(statements, createUnderscoreUnderscoreESModule());
|
||||
}
|
||||
|
||||
@@ -378,7 +384,7 @@ namespace ts {
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
|
||||
|
||||
if (!currentModuleInfo.exportEquals) {
|
||||
if (shouldEmitUnderscoreUnderscoreESModule()) {
|
||||
append(statements, createUnderscoreUnderscoreESModule());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../visitor.ts" />
|
||||
/// <reference path="../destructuring.ts" />
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
/// <reference path="./destructuring.ts" />
|
||||
|
||||
@@ -472,7 +472,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitSourceFile(node: SourceFile) {
|
||||
const alwaysStrict = compilerOptions.alwaysStrict && !(isExternalModule(node) && moduleKind === ModuleKind.ES2015);
|
||||
const alwaysStrict = (compilerOptions.alwaysStrict === undefined ? compilerOptions.strict : compilerOptions.alwaysStrict) &&
|
||||
!(isExternalModule(node) && moduleKind === ModuleKind.ES2015);
|
||||
return updateSourceFileNode(
|
||||
node,
|
||||
visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict));
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/// <reference path="program.ts"/>
|
||||
/// <reference path="program.ts"/>
|
||||
/// <reference path="commandLineParser.ts"/>
|
||||
|
||||
namespace ts {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace ts {
|
||||
namespace ts {
|
||||
/**
|
||||
* Type of objects whose values are all of the same type.
|
||||
* The `in` and `for-in` operators can *not* be safely used,
|
||||
@@ -519,6 +519,8 @@
|
||||
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
|
||||
/* @internal */ flowNode?: FlowNode; // Associated FlowNode (initialized by binding)
|
||||
/* @internal */ emitNode?: EmitNode; // Associated EmitNode (initialized by transforms)
|
||||
/* @internal */ contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution
|
||||
/* @internal */ contextualMapper?: TypeMapper; // Mapper for contextual type
|
||||
}
|
||||
|
||||
export interface NodeArray<T extends Node> extends Array<T>, TextRange {
|
||||
@@ -963,7 +965,6 @@
|
||||
|
||||
export interface Expression extends Node {
|
||||
_expressionBrand: any;
|
||||
contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution
|
||||
}
|
||||
|
||||
export interface OmittedExpression extends Expression {
|
||||
@@ -3318,7 +3319,7 @@
|
||||
allowSyntheticDefaultImports?: boolean;
|
||||
allowUnreachableCode?: boolean;
|
||||
allowUnusedLabels?: boolean;
|
||||
alwaysStrict?: boolean;
|
||||
alwaysStrict?: boolean; // Always combine with strict property
|
||||
baseUrl?: string;
|
||||
charset?: string;
|
||||
/* @internal */ configFilePath?: string;
|
||||
@@ -3354,9 +3355,9 @@
|
||||
noEmitOnError?: boolean;
|
||||
noErrorTruncation?: boolean;
|
||||
noFallthroughCasesInSwitch?: boolean;
|
||||
noImplicitAny?: boolean;
|
||||
noImplicitAny?: boolean; // Always combine with strict property
|
||||
noImplicitReturns?: boolean;
|
||||
noImplicitThis?: boolean;
|
||||
noImplicitThis?: boolean; // Always combine with strict property
|
||||
noUnusedLocals?: boolean;
|
||||
noUnusedParameters?: boolean;
|
||||
noImplicitUseStrict?: boolean;
|
||||
@@ -3379,7 +3380,8 @@
|
||||
skipDefaultLibCheck?: boolean;
|
||||
sourceMap?: boolean;
|
||||
sourceRoot?: string;
|
||||
strictNullChecks?: boolean;
|
||||
strict?: boolean;
|
||||
strictNullChecks?: boolean; // Always combine with strict property
|
||||
/* @internal */ stripInternal?: boolean;
|
||||
suppressExcessPropertyErrors?: boolean;
|
||||
suppressImplicitAnyIndexErrors?: boolean;
|
||||
|
||||
+24
-10
@@ -1,4 +1,4 @@
|
||||
/// <reference path="sys.ts" />
|
||||
/// <reference path="sys.ts" />
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
@@ -1429,6 +1429,21 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getRightMostAssignedExpression(node: Node) {
|
||||
while (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true)) {
|
||||
node = node.right;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
export function isExportsIdentifier(node: Node) {
|
||||
return isIdentifier(node) && node.text === "exports";
|
||||
}
|
||||
|
||||
export function isModuleExportsPropertyAccessExpression(node: Node) {
|
||||
return isPropertyAccessExpression(node) && isIdentifier(node.expression) && node.expression.text === "module" && node.name.text === "exports";
|
||||
}
|
||||
|
||||
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
|
||||
/// assignments we treat as special in the binder
|
||||
export function getSpecialPropertyAssignmentKind(expression: Node): SpecialPropertyAssignmentKind {
|
||||
@@ -3152,15 +3167,14 @@ namespace ts {
|
||||
(node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).name === node);
|
||||
}
|
||||
|
||||
export function isEmptyObjectLiteralOrArrayLiteral(expression: Node): boolean {
|
||||
const kind = expression.kind;
|
||||
if (kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
return (<ObjectLiteralExpression>expression).properties.length === 0;
|
||||
}
|
||||
if (kind === SyntaxKind.ArrayLiteralExpression) {
|
||||
return (<ArrayLiteralExpression>expression).elements.length === 0;
|
||||
}
|
||||
return false;
|
||||
export function isEmptyObjectLiteral(expression: Node): boolean {
|
||||
return expression.kind === SyntaxKind.ObjectLiteralExpression &&
|
||||
(<ObjectLiteralExpression>expression).properties.length === 0;
|
||||
}
|
||||
|
||||
export function isEmptyArrayLiteral(expression: Node): boolean {
|
||||
return expression.kind === SyntaxKind.ArrayLiteralExpression &&
|
||||
(<ArrayLiteralExpression>expression).elements.length === 0;
|
||||
}
|
||||
|
||||
export function getLocalSymbolForExportDefault(symbol: Symbol) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="checker.ts" />
|
||||
/// <reference path="checker.ts" />
|
||||
/// <reference path="factory.ts" />
|
||||
/// <reference path="utilities.ts" />
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
interface File {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\..\compiler\commandLineParser.ts" />
|
||||
|
||||
namespace ts {
|
||||
|
||||
@@ -45,6 +45,9 @@ namespace ts {
|
||||
|
||||
// comment9
|
||||
console.log(1 + 2);
|
||||
|
||||
// comment10
|
||||
function functionWithDefaultArgValue(argument: string = "defaultValue"): void { }
|
||||
`, ScriptTarget.ES2015);
|
||||
|
||||
printsCorrectly("default", {}, printer => printer.printFile(sourceFile));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\..\harness\harnessLanguageService.ts" />
|
||||
|
||||
namespace ts {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\..\harnessLanguageService.ts" />
|
||||
/// <reference path="..\..\harnessLanguageService.ts" />
|
||||
|
||||
interface ClassificationEntry {
|
||||
value: any;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\..\harnessLanguageService.ts" />
|
||||
/// <reference path="..\..\harnessLanguageService.ts" />
|
||||
|
||||
describe("PreProcessFile:", function () {
|
||||
function test(sourceText: string, readImportFile: boolean, detectJavaScriptImports: boolean, expectedPreProcess: ts.PreProcessedFileInfo): void {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
const expect: typeof _chai.expect = _chai.expect;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="../../server/typingsInstaller/typingsInstaller.ts" />
|
||||
|
||||
namespace ts.projectSystem {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="../harness.ts" />
|
||||
/// <reference path="../harness.ts" />
|
||||
/// <reference path="./tsserverProjectSystem.ts" />
|
||||
/// <reference path="../../server/typingsInstaller/typingsInstaller.ts" />
|
||||
|
||||
|
||||
Vendored
+8
-3
@@ -147,7 +147,7 @@ interface ObjectConstructor {
|
||||
* @param o Object to use as a prototype. May be null
|
||||
* @param properties JavaScript object that contains one or more property descriptors.
|
||||
*/
|
||||
create(o: object | null, properties: PropertyDescriptorMap): any;
|
||||
create(o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;
|
||||
|
||||
/**
|
||||
* Adds a property to an object, or modifies attributes of an existing property.
|
||||
@@ -155,14 +155,14 @@ interface ObjectConstructor {
|
||||
* @param p The property name.
|
||||
* @param attributes Descriptor for the property. It can be for a data property or an accessor property.
|
||||
*/
|
||||
defineProperty(o: any, p: string, attributes: PropertyDescriptor): any;
|
||||
defineProperty(o: any, p: string, attributes: PropertyDescriptor & ThisType<any>): any;
|
||||
|
||||
/**
|
||||
* Adds one or more properties to an object, and/or modifies attributes of existing properties.
|
||||
* @param o Object on which to add or modify the properties. This can be a native JavaScript object or a DOM object.
|
||||
* @param properties JavaScript object that contains one or more descriptor objects. Each descriptor object describes a data property or an accessor property.
|
||||
*/
|
||||
defineProperties(o: any, properties: PropertyDescriptorMap): any;
|
||||
defineProperties(o: any, properties: PropertyDescriptorMap & ThisType<any>): any;
|
||||
|
||||
/**
|
||||
* Prevents the modification of attributes of existing properties, and prevents the addition of new properties.
|
||||
@@ -1366,6 +1366,11 @@ type Record<K extends string, T> = {
|
||||
[P in K]: T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marker for contextual 'this' type
|
||||
*/
|
||||
interface ThisType<T> { }
|
||||
|
||||
/**
|
||||
* Represents a raw buffer of binary data, which is used to store data for the
|
||||
* different typed arrays. ArrayBuffers cannot be read from or written to directly,
|
||||
|
||||
@@ -37,7 +37,7 @@ function createCancellationToken(args: string[]): ServerCancellationToken {
|
||||
// when client wants to signal cancellation it should create a named pipe with name=<cancellationPipeName>
|
||||
// server will synchronously check the presence of the pipe and treat its existance as indicator that current request should be canceled.
|
||||
// in case if client prefers to use more fine-grained schema than one name for all request it can add '*' to the end of cancelellationPipeName.
|
||||
// in this case pipe name will be build dynamically as <cancellationPipeName><request_seq>.
|
||||
// in this case pipe name will be build dynamically as <cancellationPipeName><request_seq>.
|
||||
if (cancellationPipeName.charAt(cancellationPipeName.length - 1) === "*") {
|
||||
const namePrefix = cancellationPipeName.slice(0, -1);
|
||||
if (namePrefix.length === 0 || namePrefix.indexOf("*") >= 0) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\compiler\commandLineParser.ts" />
|
||||
/// <reference path="..\compiler\commandLineParser.ts" />
|
||||
/// <reference path="..\services\services.ts" />
|
||||
/// <reference path="utilities.ts" />
|
||||
/// <reference path="session.ts" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\services\services.ts" />
|
||||
/// <reference path="..\services\services.ts" />
|
||||
/// <reference path="utilities.ts"/>
|
||||
/// <reference path="scriptInfo.ts"/>
|
||||
/// <reference path="lsHost.ts"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="typingsInstaller.ts"/>
|
||||
/// <reference path="typingsInstaller.ts"/>
|
||||
/// <reference types="node" />
|
||||
|
||||
namespace ts.server.typingsInstaller {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="../../compiler/core.ts" />
|
||||
/// <reference path="../../compiler/core.ts" />
|
||||
/// <reference path="../../compiler/moduleNameResolver.ts" />
|
||||
/// <reference path="../../services/jsTyping.ts"/>
|
||||
/// <reference path="../types.ts"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* @internal */
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export interface CodeFix {
|
||||
errorCodes: number[];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* @internal */
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
|
||||
type ImportCodeActionKind = "CodeChange" | "InsertingIntoExistingImport" | "NewImport";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* @internal */
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: [
|
||||
|
||||
+13
-549
@@ -1,10 +1,12 @@
|
||||
/// <reference path="./pathCompletions.ts" />
|
||||
|
||||
/* @internal */
|
||||
namespace ts.Completions {
|
||||
export type Log = (message: string) => void;
|
||||
|
||||
export function getCompletionsAtPosition(host: LanguageServiceHost, typeChecker: TypeChecker, log: Log, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number): CompletionInfo | undefined {
|
||||
if (isInReferenceComment(sourceFile, position)) {
|
||||
return getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host);
|
||||
return PathCompletions.getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host);
|
||||
}
|
||||
|
||||
if (isInString(sourceFile, position)) {
|
||||
@@ -176,7 +178,7 @@ namespace ts.Completions {
|
||||
// i.e. import * as ns from "/*completion position*/";
|
||||
// import x = require("/*completion position*/");
|
||||
// var y = require("/*completion position*/");
|
||||
return getStringLiteralCompletionEntriesFromModuleNames(<StringLiteral>node, compilerOptions, host, typeChecker);
|
||||
return PathCompletions.getStringLiteralCompletionEntriesFromModuleNames(<StringLiteral>node, compilerOptions, host, typeChecker);
|
||||
}
|
||||
else if (isEqualityExpression(node.parent)) {
|
||||
// Get completions from the type of the other operand
|
||||
@@ -278,489 +280,6 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntriesFromModuleNames(node: StringLiteral, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionInfo {
|
||||
const literalValue = normalizeSlashes(node.text);
|
||||
|
||||
const scriptPath = node.getSourceFile().path;
|
||||
const scriptDirectory = getDirectoryPath(scriptPath);
|
||||
|
||||
const span = getDirectoryFragmentTextSpan((<StringLiteral>node).text, node.getStart() + 1);
|
||||
let entries: CompletionEntry[];
|
||||
if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) {
|
||||
const extensions = getSupportedExtensions(compilerOptions);
|
||||
if (compilerOptions.rootDirs) {
|
||||
entries = getCompletionEntriesForDirectoryFragmentWithRootDirs(
|
||||
compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/false, span, compilerOptions, host, scriptPath);
|
||||
}
|
||||
else {
|
||||
entries = getCompletionEntriesForDirectoryFragment(
|
||||
literalValue, scriptDirectory, extensions, /*includeExtensions*/false, span, host, scriptPath);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Check for node modules
|
||||
entries = getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span, compilerOptions, host, typeChecker);
|
||||
}
|
||||
return {
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
isNewIdentifierLocation: true,
|
||||
entries
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a script path and returns paths for all potential folders that could be merged with its
|
||||
* containing folder via the "rootDirs" compiler option
|
||||
*/
|
||||
function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptPath: string, ignoreCase: boolean): string[] {
|
||||
// Make all paths absolute/normalized if they are not already
|
||||
rootDirs = map(rootDirs, rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory)));
|
||||
|
||||
// Determine the path to the directory containing the script relative to the root directory it is contained within
|
||||
let relativeDirectory: string;
|
||||
for (const rootDirectory of rootDirs) {
|
||||
if (containsPath(rootDirectory, scriptPath, basePath, ignoreCase)) {
|
||||
relativeDirectory = scriptPath.substr(rootDirectory.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Now find a path for each potential directory that is to be merged with the one containing the script
|
||||
return deduplicate(map(rootDirs, rootDirectory => combinePaths(rootDirectory, relativeDirectory)));
|
||||
}
|
||||
|
||||
function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptPath: string, extensions: string[], includeExtensions: boolean, span: TextSpan, compilerOptions: CompilerOptions, host: LanguageServiceHost, exclude?: string): CompletionEntry[] {
|
||||
const basePath = compilerOptions.project || host.getCurrentDirectory();
|
||||
const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
|
||||
const baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase);
|
||||
|
||||
const result: CompletionEntry[] = [];
|
||||
|
||||
for (const baseDirectory of baseDirectories) {
|
||||
getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensions, includeExtensions, span, host, exclude, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename.
|
||||
*/
|
||||
function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, extensions: string[], includeExtensions: boolean, span: TextSpan, host: LanguageServiceHost, exclude?: string, result: CompletionEntry[] = []): CompletionEntry[] {
|
||||
if (fragment === undefined) {
|
||||
fragment = "";
|
||||
}
|
||||
|
||||
fragment = normalizeSlashes(fragment);
|
||||
|
||||
/**
|
||||
* Remove the basename from the path. Note that we don't use the basename to filter completions;
|
||||
* the client is responsible for refining completions.
|
||||
*/
|
||||
fragment = getDirectoryPath(fragment);
|
||||
|
||||
if (fragment === "") {
|
||||
fragment = "." + directorySeparator;
|
||||
}
|
||||
|
||||
fragment = ensureTrailingDirectorySeparator(fragment);
|
||||
|
||||
const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment));
|
||||
const baseDirectory = getDirectoryPath(absolutePath);
|
||||
const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
|
||||
|
||||
if (tryDirectoryExists(host, baseDirectory)) {
|
||||
// Enumerate the available files if possible
|
||||
const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/undefined, /*include*/["./*"]);
|
||||
|
||||
if (files) {
|
||||
/**
|
||||
* Multiple file entries might map to the same truncated name once we remove extensions
|
||||
* (happens iff includeExtensions === false)so we use a set-like data structure. Eg:
|
||||
*
|
||||
* both foo.ts and foo.tsx become foo
|
||||
*/
|
||||
const foundFiles = createMap<boolean>();
|
||||
for (let filePath of files) {
|
||||
filePath = normalizePath(filePath);
|
||||
if (exclude && comparePaths(filePath, exclude, scriptPath, ignoreCase) === Comparison.EqualTo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const foundFileName = includeExtensions ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath));
|
||||
|
||||
if (!foundFiles.get(foundFileName)) {
|
||||
foundFiles.set(foundFileName, true);
|
||||
}
|
||||
}
|
||||
|
||||
forEachKey(foundFiles, foundFile => {
|
||||
result.push(createCompletionEntryForModule(foundFile, ScriptElementKind.scriptElement, span));
|
||||
});
|
||||
}
|
||||
|
||||
// If possible, get folder completion as well
|
||||
const directories = tryGetDirectories(host, baseDirectory);
|
||||
|
||||
if (directories) {
|
||||
for (const directory of directories) {
|
||||
const directoryName = getBaseFileName(normalizePath(directory));
|
||||
|
||||
result.push(createCompletionEntryForModule(directoryName, ScriptElementKind.directory, span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check all of the declared modules and those in node modules. Possible sources of modules:
|
||||
* Modules that are found by the type checker
|
||||
* Modules found relative to "baseUrl" compliler options (including patterns from "paths" compiler option)
|
||||
* Modules from node_modules (i.e. those listed in package.json)
|
||||
* This includes all files that are found in node_modules/moduleName/ with acceptable file extensions
|
||||
*/
|
||||
function getCompletionEntriesForNonRelativeModules(fragment: string, scriptPath: string, span: TextSpan, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionEntry[] {
|
||||
const { baseUrl, paths } = compilerOptions;
|
||||
|
||||
let result: CompletionEntry[];
|
||||
|
||||
if (baseUrl) {
|
||||
const fileExtensions = getSupportedExtensions(compilerOptions);
|
||||
const projectDir = compilerOptions.project || host.getCurrentDirectory();
|
||||
const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl);
|
||||
result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/false, span, host);
|
||||
|
||||
if (paths) {
|
||||
for (const path in paths) {
|
||||
if (paths.hasOwnProperty(path)) {
|
||||
if (path === "*") {
|
||||
if (paths[path]) {
|
||||
for (const pattern of paths[path]) {
|
||||
for (const match of getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host)) {
|
||||
result.push(createCompletionEntryForModule(match, ScriptElementKind.externalModuleName, span));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (startsWith(path, fragment)) {
|
||||
const entry = paths[path] && paths[path].length === 1 && paths[path][0];
|
||||
if (entry) {
|
||||
result.push(createCompletionEntryForModule(path, ScriptElementKind.externalModuleName, span));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = [];
|
||||
}
|
||||
|
||||
getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span, result);
|
||||
|
||||
for (const moduleName of enumeratePotentialNonRelativeModules(fragment, scriptPath, compilerOptions, typeChecker, host)) {
|
||||
result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getModulesForPathsPattern(fragment: string, baseUrl: string, pattern: string, fileExtensions: string[], host: LanguageServiceHost): string[] {
|
||||
if (host.readDirectory) {
|
||||
const parsed = hasZeroOrOneAsteriskCharacter(pattern) ? tryParsePattern(pattern) : undefined;
|
||||
if (parsed) {
|
||||
// The prefix has two effective parts: the directory path and the base component after the filepath that is not a
|
||||
// full directory component. For example: directory/path/of/prefix/base*
|
||||
const normalizedPrefix = normalizeAndPreserveTrailingSlash(parsed.prefix);
|
||||
const normalizedPrefixDirectory = getDirectoryPath(normalizedPrefix);
|
||||
const normalizedPrefixBase = getBaseFileName(normalizedPrefix);
|
||||
|
||||
const fragmentHasPath = fragment.indexOf(directorySeparator) !== -1;
|
||||
|
||||
// Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call
|
||||
const expandedPrefixDirectory = fragmentHasPath ? combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + getDirectoryPath(fragment)) : normalizedPrefixDirectory;
|
||||
|
||||
const normalizedSuffix = normalizePath(parsed.suffix);
|
||||
const baseDirectory = combinePaths(baseUrl, expandedPrefixDirectory);
|
||||
const completePrefix = fragmentHasPath ? baseDirectory : ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase;
|
||||
|
||||
// If we have a suffix, then we need to read the directory all the way down. We could create a glob
|
||||
// that encodes the suffix, but we would have to escape the character "?" which readDirectory
|
||||
// doesn't support. For now, this is safer but slower
|
||||
const includeGlob = normalizedSuffix ? "**/*" : "./*";
|
||||
|
||||
const matches = tryReadDirectory(host, baseDirectory, fileExtensions, undefined, [includeGlob]);
|
||||
if (matches) {
|
||||
const result: string[] = [];
|
||||
|
||||
// Trim away prefix and suffix
|
||||
for (const match of matches) {
|
||||
const normalizedMatch = normalizePath(match);
|
||||
if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const start = completePrefix.length;
|
||||
const length = normalizedMatch.length - start - normalizedSuffix.length;
|
||||
|
||||
result.push(removeFileExtension(normalizedMatch.substr(start, length)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function enumeratePotentialNonRelativeModules(fragment: string, scriptPath: string, options: CompilerOptions, typeChecker: TypeChecker, host: LanguageServiceHost): string[] {
|
||||
// Check If this is a nested module
|
||||
const isNestedModule = fragment.indexOf(directorySeparator) !== -1;
|
||||
const moduleNameFragment = isNestedModule ? fragment.substr(0, fragment.lastIndexOf(directorySeparator)) : undefined;
|
||||
|
||||
// Get modules that the type checker picked up
|
||||
const ambientModules = map(typeChecker.getAmbientModules(), sym => stripQuotes(sym.name));
|
||||
let nonRelativeModules = filter(ambientModules, moduleName => startsWith(moduleName, fragment));
|
||||
|
||||
// Nested modules of the form "module-name/sub" need to be adjusted to only return the string
|
||||
// after the last '/' that appears in the fragment because that's where the replacement span
|
||||
// starts
|
||||
if (isNestedModule) {
|
||||
const moduleNameWithSeperator = ensureTrailingDirectorySeparator(moduleNameFragment);
|
||||
nonRelativeModules = map(nonRelativeModules, moduleName => {
|
||||
if (startsWith(fragment, moduleNameWithSeperator)) {
|
||||
return moduleName.substr(moduleNameWithSeperator.length);
|
||||
}
|
||||
return moduleName;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (!options.moduleResolution || options.moduleResolution === ModuleResolutionKind.NodeJs) {
|
||||
for (const visibleModule of enumerateNodeModulesVisibleToScript(host, scriptPath)) {
|
||||
if (!isNestedModule) {
|
||||
nonRelativeModules.push(visibleModule.moduleName);
|
||||
}
|
||||
else if (startsWith(visibleModule.moduleName, moduleNameFragment)) {
|
||||
const nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/undefined, /*include*/["./*"]);
|
||||
if (nestedFiles) {
|
||||
for (let f of nestedFiles) {
|
||||
f = normalizePath(f);
|
||||
const nestedModule = removeFileExtension(getBaseFileName(f));
|
||||
nonRelativeModules.push(nestedModule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return deduplicate(nonRelativeModules);
|
||||
}
|
||||
|
||||
function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): CompletionInfo {
|
||||
const token = getTokenAtPosition(sourceFile, position);
|
||||
if (!token) {
|
||||
return undefined;
|
||||
}
|
||||
const commentRanges: CommentRange[] = getLeadingCommentRanges(sourceFile.text, token.pos);
|
||||
|
||||
if (!commentRanges || !commentRanges.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const range = forEach(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end && commentRange);
|
||||
|
||||
if (!range) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const completionInfo: CompletionInfo = {
|
||||
/**
|
||||
* We don't want the editor to offer any other completions, such as snippets, inside a comment.
|
||||
*/
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
/**
|
||||
* The user may type in a path that doesn't yet exist, creating a "new identifier"
|
||||
* with respect to the collection of identifiers the server is aware of.
|
||||
*/
|
||||
isNewIdentifierLocation: true,
|
||||
|
||||
entries: []
|
||||
};
|
||||
|
||||
const text = sourceFile.text.substr(range.pos, position - range.pos);
|
||||
|
||||
const match = tripleSlashDirectiveFragmentRegex.exec(text);
|
||||
|
||||
if (match) {
|
||||
const prefix = match[1];
|
||||
const kind = match[2];
|
||||
const toComplete = match[3];
|
||||
|
||||
const scriptPath = getDirectoryPath(sourceFile.path);
|
||||
if (kind === "path") {
|
||||
// Give completions for a relative path
|
||||
const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
|
||||
completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/true, span, host, sourceFile.path);
|
||||
}
|
||||
else {
|
||||
// Give completions based on the typings available
|
||||
const span: TextSpan = { start: range.pos + prefix.length, length: match[0].length - prefix.length };
|
||||
completionInfo.entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span);
|
||||
}
|
||||
}
|
||||
|
||||
return completionInfo;
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] {
|
||||
// Check for typings specified in compiler options
|
||||
if (options.types) {
|
||||
for (const moduleName of options.types) {
|
||||
result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span));
|
||||
}
|
||||
}
|
||||
else if (host.getDirectories) {
|
||||
let typeRoots: string[];
|
||||
try {
|
||||
// Wrap in try catch because getEffectiveTypeRoots touches the filesystem
|
||||
typeRoots = getEffectiveTypeRoots(options, host);
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
if (typeRoots) {
|
||||
for (const root of typeRoots) {
|
||||
getCompletionEntriesFromDirectories(host, root, span, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (host.getDirectories) {
|
||||
// Also get all @types typings installed in visible node_modules directories
|
||||
for (const packageJson of findPackageJsons(scriptPath, host)) {
|
||||
const typesDir = combinePaths(getDirectoryPath(packageJson), "node_modules/@types");
|
||||
getCompletionEntriesFromDirectories(host, typesDir, span, result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromDirectories(host: LanguageServiceHost, directory: string, span: TextSpan, result: Push<CompletionEntry>) {
|
||||
if (host.getDirectories && tryDirectoryExists(host, directory)) {
|
||||
const directories = tryGetDirectories(host, directory);
|
||||
if (directories) {
|
||||
for (let typeDirectory of directories) {
|
||||
typeDirectory = normalizePath(typeDirectory);
|
||||
result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName, span));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findPackageJsons(currentDir: string, host: LanguageServiceHost): string[] {
|
||||
const paths: string[] = [];
|
||||
let currentConfigPath: string;
|
||||
while (true) {
|
||||
currentConfigPath = findConfigFile(currentDir, (f) => tryFileExists(host, f), "package.json");
|
||||
if (currentConfigPath) {
|
||||
paths.push(currentConfigPath);
|
||||
|
||||
currentDir = getDirectoryPath(currentConfigPath);
|
||||
const parent = getDirectoryPath(currentDir);
|
||||
if (currentDir === parent) {
|
||||
break;
|
||||
}
|
||||
currentDir = parent;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
function enumerateNodeModulesVisibleToScript(host: LanguageServiceHost, scriptPath: string) {
|
||||
const result: VisibleModuleInfo[] = [];
|
||||
|
||||
if (host.readFile && host.fileExists) {
|
||||
for (const packageJson of findPackageJsons(scriptPath, host)) {
|
||||
const contents = tryReadingPackageJson(packageJson);
|
||||
if (!contents) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nodeModulesDir = combinePaths(getDirectoryPath(packageJson), "node_modules");
|
||||
const foundModuleNames: string[] = [];
|
||||
|
||||
// Provide completions for all non @types dependencies
|
||||
for (const key of nodeModulesDependencyKeys) {
|
||||
addPotentialPackageNames(contents[key], foundModuleNames);
|
||||
}
|
||||
|
||||
for (const moduleName of foundModuleNames) {
|
||||
const moduleDir = combinePaths(nodeModulesDir, moduleName);
|
||||
result.push({
|
||||
moduleName,
|
||||
moduleDir
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
function tryReadingPackageJson(filePath: string) {
|
||||
try {
|
||||
const fileText = tryReadFile(host, filePath);
|
||||
return fileText ? JSON.parse(fileText) : undefined;
|
||||
}
|
||||
catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function addPotentialPackageNames(dependencies: any, result: string[]) {
|
||||
if (dependencies) {
|
||||
for (const dep in dependencies) {
|
||||
if (dependencies.hasOwnProperty(dep) && !startsWith(dep, "@types/")) {
|
||||
result.push(dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createCompletionEntryForModule(name: string, kind: string, replacementSpan: TextSpan): CompletionEntry {
|
||||
return { name, kind, kindModifiers: ScriptElementKindModifier.none, sortText: name, replacementSpan };
|
||||
}
|
||||
|
||||
// Replace everything after the last directory seperator that appears
|
||||
function getDirectoryFragmentTextSpan(text: string, textStart: number): TextSpan {
|
||||
const index = text.lastIndexOf(directorySeparator);
|
||||
const offset = index !== -1 ? index + 1 : 0;
|
||||
return { start: textStart + offset, length: text.length - offset };
|
||||
}
|
||||
|
||||
// Returns true if the path is explicitly relative to the script (i.e. relative to . or ..)
|
||||
function isPathRelativeToScript(path: string) {
|
||||
if (path && path.length >= 2 && path.charCodeAt(0) === CharacterCodes.dot) {
|
||||
const slashIndex = path.length >= 3 && path.charCodeAt(1) === CharacterCodes.dot ? 2 : 1;
|
||||
const slashCharCode = path.charCodeAt(slashIndex);
|
||||
return slashCharCode === CharacterCodes.slash || slashCharCode === CharacterCodes.backslash;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function normalizeAndPreserveTrailingSlash(path: string) {
|
||||
return hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(normalizePath(path)) : normalizePath(path);
|
||||
}
|
||||
|
||||
export function getCompletionEntryDetails(typeChecker: TypeChecker, log: (message: string) => void, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number, entryName: string): CompletionEntryDetails {
|
||||
// Compute all the completion symbols again.
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position);
|
||||
@@ -1487,20 +1006,18 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function isFunction(kind: SyntaxKind): boolean {
|
||||
if (!isFunctionLikeKind(kind)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.FunctionType:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1778,59 +1295,6 @@ namespace ts.Completions {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches a triple slash reference directive with an incomplete string literal for its path. Used
|
||||
* to determine if the caret is currently within the string literal and capture the literal fragment
|
||||
* for completions.
|
||||
* For example, this matches
|
||||
*
|
||||
* /// <reference path="fragment
|
||||
*
|
||||
* but not
|
||||
*
|
||||
* /// <reference path="fragment"
|
||||
*/
|
||||
const tripleSlashDirectiveFragmentRegex = /^(\/\/\/\s*<reference\s+(path|types)\s*=\s*(?:'|"))([^\3"]*)$/;
|
||||
|
||||
interface VisibleModuleInfo {
|
||||
moduleName: string;
|
||||
moduleDir: string;
|
||||
}
|
||||
|
||||
const nodeModulesDependencyKeys = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
|
||||
|
||||
function tryGetDirectories(host: LanguageServiceHost, directoryName: string): string[] {
|
||||
return tryIOAndConsumeErrors(host, host.getDirectories, directoryName);
|
||||
}
|
||||
|
||||
function tryReadDirectory(host: LanguageServiceHost, path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] {
|
||||
return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include);
|
||||
}
|
||||
|
||||
function tryReadFile(host: LanguageServiceHost, path: string): string {
|
||||
return tryIOAndConsumeErrors(host, host.readFile, path);
|
||||
}
|
||||
|
||||
function tryFileExists(host: LanguageServiceHost, path: string): boolean {
|
||||
return tryIOAndConsumeErrors(host, host.fileExists, path);
|
||||
}
|
||||
|
||||
function tryDirectoryExists(host: LanguageServiceHost, path: string): boolean {
|
||||
try {
|
||||
return directoryProbablyExists(path, host);
|
||||
}
|
||||
catch (e) {}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryIOAndConsumeErrors<T>(host: LanguageServiceHost, toApply: (...a: any[]) => T, ...args: any[]) {
|
||||
try {
|
||||
return toApply && toApply.apply(host, args);
|
||||
}
|
||||
catch (e) {}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isEqualityExpression(node: Node): node is BinaryExpression {
|
||||
return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace ts {
|
||||
namespace ts {
|
||||
/**
|
||||
* The document registry represents a store of SourceFile objects that can be shared between
|
||||
* multiple LanguageService instances. A LanguageService instance holds on the SourceFile (AST)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* @internal */
|
||||
/* @internal */
|
||||
namespace ts.FindAllReferences {
|
||||
export function findReferencedSymbols(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFiles: SourceFile[], sourceFile: SourceFile, position: number, findInStrings: boolean, findInComments: boolean, isForRename: boolean): ReferencedSymbol[] | undefined {
|
||||
const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* @internal */
|
||||
/* @internal */
|
||||
namespace ts.GoToDefinition {
|
||||
export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile, position: number): DefinitionInfo[] {
|
||||
/// Triple slash reference comments
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* @internal */
|
||||
/* @internal */
|
||||
namespace ts.JsDoc {
|
||||
const jsDocTagNames = [
|
||||
"augments",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
|
||||
// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
|
||||
// See LICENSE.txt in the project root for complete license information.
|
||||
|
||||
/// <reference path='../compiler/types.ts' />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* @internal */
|
||||
/* @internal */
|
||||
namespace ts.NavigateTo {
|
||||
type RawNavigateToItem = { name: string; fileName: string; matchKind: PatternMatchKind; isCaseSensitive: boolean; declaration: Declaration };
|
||||
|
||||
|
||||
@@ -0,0 +1,538 @@
|
||||
/* @internal */
|
||||
namespace ts.Completions.PathCompletions {
|
||||
export function getStringLiteralCompletionEntriesFromModuleNames(node: StringLiteral, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionInfo {
|
||||
const literalValue = normalizeSlashes(node.text);
|
||||
|
||||
const scriptPath = node.getSourceFile().path;
|
||||
const scriptDirectory = getDirectoryPath(scriptPath);
|
||||
|
||||
const span = getDirectoryFragmentTextSpan((<StringLiteral>node).text, node.getStart() + 1);
|
||||
let entries: CompletionEntry[];
|
||||
if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) {
|
||||
const extensions = getSupportedExtensions(compilerOptions);
|
||||
if (compilerOptions.rootDirs) {
|
||||
entries = getCompletionEntriesForDirectoryFragmentWithRootDirs(
|
||||
compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/false, span, compilerOptions, host, scriptPath);
|
||||
}
|
||||
else {
|
||||
entries = getCompletionEntriesForDirectoryFragment(
|
||||
literalValue, scriptDirectory, extensions, /*includeExtensions*/false, span, host, scriptPath);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Check for node modules
|
||||
entries = getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span, compilerOptions, host, typeChecker);
|
||||
}
|
||||
return {
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
isNewIdentifierLocation: true,
|
||||
entries
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a script path and returns paths for all potential folders that could be merged with its
|
||||
* containing folder via the "rootDirs" compiler option
|
||||
*/
|
||||
function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptPath: string, ignoreCase: boolean): string[] {
|
||||
// Make all paths absolute/normalized if they are not already
|
||||
rootDirs = map(rootDirs, rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory)));
|
||||
|
||||
// Determine the path to the directory containing the script relative to the root directory it is contained within
|
||||
let relativeDirectory: string;
|
||||
for (const rootDirectory of rootDirs) {
|
||||
if (containsPath(rootDirectory, scriptPath, basePath, ignoreCase)) {
|
||||
relativeDirectory = scriptPath.substr(rootDirectory.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Now find a path for each potential directory that is to be merged with the one containing the script
|
||||
return deduplicate(map(rootDirs, rootDirectory => combinePaths(rootDirectory, relativeDirectory)));
|
||||
}
|
||||
|
||||
function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptPath: string, extensions: string[], includeExtensions: boolean, span: TextSpan, compilerOptions: CompilerOptions, host: LanguageServiceHost, exclude?: string): CompletionEntry[] {
|
||||
const basePath = compilerOptions.project || host.getCurrentDirectory();
|
||||
const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
|
||||
const baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase);
|
||||
|
||||
const result: CompletionEntry[] = [];
|
||||
|
||||
for (const baseDirectory of baseDirectories) {
|
||||
getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensions, includeExtensions, span, host, exclude, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename.
|
||||
*/
|
||||
function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, extensions: string[], includeExtensions: boolean, span: TextSpan, host: LanguageServiceHost, exclude?: string, result: CompletionEntry[] = []): CompletionEntry[] {
|
||||
if (fragment === undefined) {
|
||||
fragment = "";
|
||||
}
|
||||
|
||||
fragment = normalizeSlashes(fragment);
|
||||
|
||||
/**
|
||||
* Remove the basename from the path. Note that we don't use the basename to filter completions;
|
||||
* the client is responsible for refining completions.
|
||||
*/
|
||||
fragment = getDirectoryPath(fragment);
|
||||
|
||||
if (fragment === "") {
|
||||
fragment = "." + directorySeparator;
|
||||
}
|
||||
|
||||
fragment = ensureTrailingDirectorySeparator(fragment);
|
||||
|
||||
const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment));
|
||||
const baseDirectory = getDirectoryPath(absolutePath);
|
||||
const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
|
||||
|
||||
if (tryDirectoryExists(host, baseDirectory)) {
|
||||
// Enumerate the available files if possible
|
||||
const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/undefined, /*include*/["./*"]);
|
||||
|
||||
if (files) {
|
||||
/**
|
||||
* Multiple file entries might map to the same truncated name once we remove extensions
|
||||
* (happens iff includeExtensions === false)so we use a set-like data structure. Eg:
|
||||
*
|
||||
* both foo.ts and foo.tsx become foo
|
||||
*/
|
||||
const foundFiles = createMap<boolean>();
|
||||
for (let filePath of files) {
|
||||
filePath = normalizePath(filePath);
|
||||
if (exclude && comparePaths(filePath, exclude, scriptPath, ignoreCase) === Comparison.EqualTo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const foundFileName = includeExtensions ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath));
|
||||
|
||||
if (!foundFiles.get(foundFileName)) {
|
||||
foundFiles.set(foundFileName, true);
|
||||
}
|
||||
}
|
||||
|
||||
forEachKey(foundFiles, foundFile => {
|
||||
result.push(createCompletionEntryForModule(foundFile, ScriptElementKind.scriptElement, span));
|
||||
});
|
||||
}
|
||||
|
||||
// If possible, get folder completion as well
|
||||
const directories = tryGetDirectories(host, baseDirectory);
|
||||
|
||||
if (directories) {
|
||||
for (const directory of directories) {
|
||||
const directoryName = getBaseFileName(normalizePath(directory));
|
||||
|
||||
result.push(createCompletionEntryForModule(directoryName, ScriptElementKind.directory, span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check all of the declared modules and those in node modules. Possible sources of modules:
|
||||
* Modules that are found by the type checker
|
||||
* Modules found relative to "baseUrl" compliler options (including patterns from "paths" compiler option)
|
||||
* Modules from node_modules (i.e. those listed in package.json)
|
||||
* This includes all files that are found in node_modules/moduleName/ with acceptable file extensions
|
||||
*/
|
||||
function getCompletionEntriesForNonRelativeModules(fragment: string, scriptPath: string, span: TextSpan, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionEntry[] {
|
||||
const { baseUrl, paths } = compilerOptions;
|
||||
|
||||
let result: CompletionEntry[];
|
||||
|
||||
if (baseUrl) {
|
||||
const fileExtensions = getSupportedExtensions(compilerOptions);
|
||||
const projectDir = compilerOptions.project || host.getCurrentDirectory();
|
||||
const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl);
|
||||
result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/false, span, host);
|
||||
|
||||
if (paths) {
|
||||
for (const path in paths) {
|
||||
if (paths.hasOwnProperty(path)) {
|
||||
if (path === "*") {
|
||||
if (paths[path]) {
|
||||
for (const pattern of paths[path]) {
|
||||
for (const match of getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host)) {
|
||||
result.push(createCompletionEntryForModule(match, ScriptElementKind.externalModuleName, span));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (startsWith(path, fragment)) {
|
||||
const entry = paths[path] && paths[path].length === 1 && paths[path][0];
|
||||
if (entry) {
|
||||
result.push(createCompletionEntryForModule(path, ScriptElementKind.externalModuleName, span));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = [];
|
||||
}
|
||||
|
||||
getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span, result);
|
||||
|
||||
for (const moduleName of enumeratePotentialNonRelativeModules(fragment, scriptPath, compilerOptions, typeChecker, host)) {
|
||||
result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getModulesForPathsPattern(fragment: string, baseUrl: string, pattern: string, fileExtensions: string[], host: LanguageServiceHost): string[] {
|
||||
if (host.readDirectory) {
|
||||
const parsed = hasZeroOrOneAsteriskCharacter(pattern) ? tryParsePattern(pattern) : undefined;
|
||||
if (parsed) {
|
||||
// The prefix has two effective parts: the directory path and the base component after the filepath that is not a
|
||||
// full directory component. For example: directory/path/of/prefix/base*
|
||||
const normalizedPrefix = normalizeAndPreserveTrailingSlash(parsed.prefix);
|
||||
const normalizedPrefixDirectory = getDirectoryPath(normalizedPrefix);
|
||||
const normalizedPrefixBase = getBaseFileName(normalizedPrefix);
|
||||
|
||||
const fragmentHasPath = fragment.indexOf(directorySeparator) !== -1;
|
||||
|
||||
// Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call
|
||||
const expandedPrefixDirectory = fragmentHasPath ? combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + getDirectoryPath(fragment)) : normalizedPrefixDirectory;
|
||||
|
||||
const normalizedSuffix = normalizePath(parsed.suffix);
|
||||
const baseDirectory = combinePaths(baseUrl, expandedPrefixDirectory);
|
||||
const completePrefix = fragmentHasPath ? baseDirectory : ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase;
|
||||
|
||||
// If we have a suffix, then we need to read the directory all the way down. We could create a glob
|
||||
// that encodes the suffix, but we would have to escape the character "?" which readDirectory
|
||||
// doesn't support. For now, this is safer but slower
|
||||
const includeGlob = normalizedSuffix ? "**/*" : "./*";
|
||||
|
||||
const matches = tryReadDirectory(host, baseDirectory, fileExtensions, undefined, [includeGlob]);
|
||||
if (matches) {
|
||||
const result: string[] = [];
|
||||
|
||||
// Trim away prefix and suffix
|
||||
for (const match of matches) {
|
||||
const normalizedMatch = normalizePath(match);
|
||||
if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const start = completePrefix.length;
|
||||
const length = normalizedMatch.length - start - normalizedSuffix.length;
|
||||
|
||||
result.push(removeFileExtension(normalizedMatch.substr(start, length)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function enumeratePotentialNonRelativeModules(fragment: string, scriptPath: string, options: CompilerOptions, typeChecker: TypeChecker, host: LanguageServiceHost): string[] {
|
||||
// Check If this is a nested module
|
||||
const isNestedModule = fragment.indexOf(directorySeparator) !== -1;
|
||||
const moduleNameFragment = isNestedModule ? fragment.substr(0, fragment.lastIndexOf(directorySeparator)) : undefined;
|
||||
|
||||
// Get modules that the type checker picked up
|
||||
const ambientModules = map(typeChecker.getAmbientModules(), sym => stripQuotes(sym.name));
|
||||
let nonRelativeModules = filter(ambientModules, moduleName => startsWith(moduleName, fragment));
|
||||
|
||||
// Nested modules of the form "module-name/sub" need to be adjusted to only return the string
|
||||
// after the last '/' that appears in the fragment because that's where the replacement span
|
||||
// starts
|
||||
if (isNestedModule) {
|
||||
const moduleNameWithSeperator = ensureTrailingDirectorySeparator(moduleNameFragment);
|
||||
nonRelativeModules = map(nonRelativeModules, moduleName => {
|
||||
if (startsWith(fragment, moduleNameWithSeperator)) {
|
||||
return moduleName.substr(moduleNameWithSeperator.length);
|
||||
}
|
||||
return moduleName;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (!options.moduleResolution || options.moduleResolution === ModuleResolutionKind.NodeJs) {
|
||||
for (const visibleModule of enumerateNodeModulesVisibleToScript(host, scriptPath)) {
|
||||
if (!isNestedModule) {
|
||||
nonRelativeModules.push(visibleModule.moduleName);
|
||||
}
|
||||
else if (startsWith(visibleModule.moduleName, moduleNameFragment)) {
|
||||
const nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/undefined, /*include*/["./*"]);
|
||||
if (nestedFiles) {
|
||||
for (let f of nestedFiles) {
|
||||
f = normalizePath(f);
|
||||
const nestedModule = removeFileExtension(getBaseFileName(f));
|
||||
nonRelativeModules.push(nestedModule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return deduplicate(nonRelativeModules);
|
||||
}
|
||||
|
||||
export function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): CompletionInfo {
|
||||
const token = getTokenAtPosition(sourceFile, position);
|
||||
if (!token) {
|
||||
return undefined;
|
||||
}
|
||||
const commentRanges: CommentRange[] = getLeadingCommentRanges(sourceFile.text, token.pos);
|
||||
|
||||
if (!commentRanges || !commentRanges.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const range = forEach(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end && commentRange);
|
||||
|
||||
if (!range) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const completionInfo: CompletionInfo = {
|
||||
/**
|
||||
* We don't want the editor to offer any other completions, such as snippets, inside a comment.
|
||||
*/
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
/**
|
||||
* The user may type in a path that doesn't yet exist, creating a "new identifier"
|
||||
* with respect to the collection of identifiers the server is aware of.
|
||||
*/
|
||||
isNewIdentifierLocation: true,
|
||||
|
||||
entries: []
|
||||
};
|
||||
|
||||
const text = sourceFile.text.substr(range.pos, position - range.pos);
|
||||
|
||||
const match = tripleSlashDirectiveFragmentRegex.exec(text);
|
||||
|
||||
if (match) {
|
||||
const prefix = match[1];
|
||||
const kind = match[2];
|
||||
const toComplete = match[3];
|
||||
|
||||
const scriptPath = getDirectoryPath(sourceFile.path);
|
||||
if (kind === "path") {
|
||||
// Give completions for a relative path
|
||||
const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
|
||||
completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/true, span, host, sourceFile.path);
|
||||
}
|
||||
else {
|
||||
// Give completions based on the typings available
|
||||
const span: TextSpan = { start: range.pos + prefix.length, length: match[0].length - prefix.length };
|
||||
completionInfo.entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span);
|
||||
}
|
||||
}
|
||||
|
||||
return completionInfo;
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] {
|
||||
// Check for typings specified in compiler options
|
||||
if (options.types) {
|
||||
for (const moduleName of options.types) {
|
||||
result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span));
|
||||
}
|
||||
}
|
||||
else if (host.getDirectories) {
|
||||
let typeRoots: string[];
|
||||
try {
|
||||
// Wrap in try catch because getEffectiveTypeRoots touches the filesystem
|
||||
typeRoots = getEffectiveTypeRoots(options, host);
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
if (typeRoots) {
|
||||
for (const root of typeRoots) {
|
||||
getCompletionEntriesFromDirectories(host, root, span, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (host.getDirectories) {
|
||||
// Also get all @types typings installed in visible node_modules directories
|
||||
for (const packageJson of findPackageJsons(scriptPath, host)) {
|
||||
const typesDir = combinePaths(getDirectoryPath(packageJson), "node_modules/@types");
|
||||
getCompletionEntriesFromDirectories(host, typesDir, span, result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromDirectories(host: LanguageServiceHost, directory: string, span: TextSpan, result: Push<CompletionEntry>) {
|
||||
if (host.getDirectories && tryDirectoryExists(host, directory)) {
|
||||
const directories = tryGetDirectories(host, directory);
|
||||
if (directories) {
|
||||
for (let typeDirectory of directories) {
|
||||
typeDirectory = normalizePath(typeDirectory);
|
||||
result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName, span));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findPackageJsons(currentDir: string, host: LanguageServiceHost): string[] {
|
||||
const paths: string[] = [];
|
||||
let currentConfigPath: string;
|
||||
while (true) {
|
||||
currentConfigPath = findConfigFile(currentDir, (f) => tryFileExists(host, f), "package.json");
|
||||
if (currentConfigPath) {
|
||||
paths.push(currentConfigPath);
|
||||
|
||||
currentDir = getDirectoryPath(currentConfigPath);
|
||||
const parent = getDirectoryPath(currentDir);
|
||||
if (currentDir === parent) {
|
||||
break;
|
||||
}
|
||||
currentDir = parent;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
function enumerateNodeModulesVisibleToScript(host: LanguageServiceHost, scriptPath: string) {
|
||||
const result: VisibleModuleInfo[] = [];
|
||||
|
||||
if (host.readFile && host.fileExists) {
|
||||
for (const packageJson of findPackageJsons(scriptPath, host)) {
|
||||
const contents = tryReadingPackageJson(packageJson);
|
||||
if (!contents) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nodeModulesDir = combinePaths(getDirectoryPath(packageJson), "node_modules");
|
||||
const foundModuleNames: string[] = [];
|
||||
|
||||
// Provide completions for all non @types dependencies
|
||||
for (const key of nodeModulesDependencyKeys) {
|
||||
addPotentialPackageNames(contents[key], foundModuleNames);
|
||||
}
|
||||
|
||||
for (const moduleName of foundModuleNames) {
|
||||
const moduleDir = combinePaths(nodeModulesDir, moduleName);
|
||||
result.push({
|
||||
moduleName,
|
||||
moduleDir
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
function tryReadingPackageJson(filePath: string) {
|
||||
try {
|
||||
const fileText = tryReadFile(host, filePath);
|
||||
return fileText ? JSON.parse(fileText) : undefined;
|
||||
}
|
||||
catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function addPotentialPackageNames(dependencies: any, result: string[]) {
|
||||
if (dependencies) {
|
||||
for (const dep in dependencies) {
|
||||
if (dependencies.hasOwnProperty(dep) && !startsWith(dep, "@types/")) {
|
||||
result.push(dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createCompletionEntryForModule(name: string, kind: string, replacementSpan: TextSpan): CompletionEntry {
|
||||
return { name, kind, kindModifiers: ScriptElementKindModifier.none, sortText: name, replacementSpan };
|
||||
}
|
||||
|
||||
// Replace everything after the last directory seperator that appears
|
||||
function getDirectoryFragmentTextSpan(text: string, textStart: number): TextSpan {
|
||||
const index = text.lastIndexOf(directorySeparator);
|
||||
const offset = index !== -1 ? index + 1 : 0;
|
||||
return { start: textStart + offset, length: text.length - offset };
|
||||
}
|
||||
|
||||
// Returns true if the path is explicitly relative to the script (i.e. relative to . or ..)
|
||||
function isPathRelativeToScript(path: string) {
|
||||
if (path && path.length >= 2 && path.charCodeAt(0) === CharacterCodes.dot) {
|
||||
const slashIndex = path.length >= 3 && path.charCodeAt(1) === CharacterCodes.dot ? 2 : 1;
|
||||
const slashCharCode = path.charCodeAt(slashIndex);
|
||||
return slashCharCode === CharacterCodes.slash || slashCharCode === CharacterCodes.backslash;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function normalizeAndPreserveTrailingSlash(path: string) {
|
||||
return hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(normalizePath(path)) : normalizePath(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches a triple slash reference directive with an incomplete string literal for its path. Used
|
||||
* to determine if the caret is currently within the string literal and capture the literal fragment
|
||||
* for completions.
|
||||
* For example, this matches
|
||||
*
|
||||
* /// <reference path="fragment
|
||||
*
|
||||
* but not
|
||||
*
|
||||
* /// <reference path="fragment"
|
||||
*/
|
||||
const tripleSlashDirectiveFragmentRegex = /^(\/\/\/\s*<reference\s+(path|types)\s*=\s*(?:'|"))([^\3"]*)$/;
|
||||
|
||||
interface VisibleModuleInfo {
|
||||
moduleName: string;
|
||||
moduleDir: string;
|
||||
}
|
||||
|
||||
const nodeModulesDependencyKeys = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
|
||||
|
||||
function tryGetDirectories(host: LanguageServiceHost, directoryName: string): string[] {
|
||||
return tryIOAndConsumeErrors(host, host.getDirectories, directoryName);
|
||||
}
|
||||
|
||||
function tryReadDirectory(host: LanguageServiceHost, path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] {
|
||||
return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include);
|
||||
}
|
||||
|
||||
function tryReadFile(host: LanguageServiceHost, path: string): string {
|
||||
return tryIOAndConsumeErrors(host, host.readFile, path);
|
||||
}
|
||||
|
||||
function tryFileExists(host: LanguageServiceHost, path: string): boolean {
|
||||
return tryIOAndConsumeErrors(host, host.fileExists, path);
|
||||
}
|
||||
|
||||
function tryDirectoryExists(host: LanguageServiceHost, path: string): boolean {
|
||||
try {
|
||||
return directoryProbablyExists(path, host);
|
||||
}
|
||||
catch (e) {}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryIOAndConsumeErrors<T>(host: LanguageServiceHost, toApply: (...a: any[]) => T, ...args: any[]) {
|
||||
try {
|
||||
return toApply && toApply.apply(host, args);
|
||||
}
|
||||
catch (e) {}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\compiler\program.ts"/>
|
||||
/// <reference path="..\compiler\program.ts"/>
|
||||
/// <reference path="..\compiler\commandLineParser.ts"/>
|
||||
|
||||
/// <reference path='types.ts' />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace ts {
|
||||
namespace ts {
|
||||
export interface TranspileOptions {
|
||||
compilerOptions?: CompilerOptions;
|
||||
fileName?: string;
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
"navigateTo.ts",
|
||||
"navigationBar.ts",
|
||||
"outliningElementsCollector.ts",
|
||||
"pathCompletions.ts",
|
||||
"patternMatcher.ts",
|
||||
"preProcess.ts",
|
||||
"rename.ts",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// These utilities are common to multiple language service features.
|
||||
// These utilities are common to multiple language service features.
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export const scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
const fs = require("fs");
|
||||
>fs : typeof "fs"
|
||||
>require("fs") : any
|
||||
>require("fs") : typeof "fs"
|
||||
>require : (moduleName: string) => any
|
||||
>"fs" : "fs"
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//// [circularInferredTypeOfVariable.ts]
|
||||
|
||||
// Repro from #14428
|
||||
|
||||
(async () => {
|
||||
function foo(p: string[]): string[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
function bar(p: string[]): string[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
let a1: string[] | undefined = [];
|
||||
|
||||
while (true) {
|
||||
let a2 = foo(a1!);
|
||||
a1 = await bar(a2);
|
||||
}
|
||||
});
|
||||
|
||||
//// [circularInferredTypeOfVariable.js]
|
||||
// Repro from #14428
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
(() => __awaiter(this, void 0, void 0, function* () {
|
||||
function foo(p) {
|
||||
return [];
|
||||
}
|
||||
function bar(p) {
|
||||
return [];
|
||||
}
|
||||
let a1 = [];
|
||||
while (true) {
|
||||
let a2 = foo(a1);
|
||||
a1 = yield bar(a2);
|
||||
}
|
||||
}));
|
||||
@@ -0,0 +1,34 @@
|
||||
=== tests/cases/compiler/circularInferredTypeOfVariable.ts ===
|
||||
|
||||
// Repro from #14428
|
||||
|
||||
(async () => {
|
||||
function foo(p: string[]): string[] {
|
||||
>foo : Symbol(foo, Decl(circularInferredTypeOfVariable.ts, 3, 14))
|
||||
>p : Symbol(p, Decl(circularInferredTypeOfVariable.ts, 4, 17))
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function bar(p: string[]): string[] {
|
||||
>bar : Symbol(bar, Decl(circularInferredTypeOfVariable.ts, 6, 5))
|
||||
>p : Symbol(p, Decl(circularInferredTypeOfVariable.ts, 8, 17))
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
let a1: string[] | undefined = [];
|
||||
>a1 : Symbol(a1, Decl(circularInferredTypeOfVariable.ts, 12, 7))
|
||||
|
||||
while (true) {
|
||||
let a2 = foo(a1!);
|
||||
>a2 : Symbol(a2, Decl(circularInferredTypeOfVariable.ts, 15, 11))
|
||||
>foo : Symbol(foo, Decl(circularInferredTypeOfVariable.ts, 3, 14))
|
||||
>a1 : Symbol(a1, Decl(circularInferredTypeOfVariable.ts, 12, 7))
|
||||
|
||||
a1 = await bar(a2);
|
||||
>a1 : Symbol(a1, Decl(circularInferredTypeOfVariable.ts, 12, 7))
|
||||
>bar : Symbol(bar, Decl(circularInferredTypeOfVariable.ts, 6, 5))
|
||||
>a2 : Symbol(a2, Decl(circularInferredTypeOfVariable.ts, 15, 11))
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
=== tests/cases/compiler/circularInferredTypeOfVariable.ts ===
|
||||
|
||||
// Repro from #14428
|
||||
|
||||
(async () => {
|
||||
>(async () => { function foo(p: string[]): string[] { return []; } function bar(p: string[]): string[] { return []; } let a1: string[] | undefined = []; while (true) { let a2 = foo(a1!); a1 = await bar(a2); }}) : () => Promise<never>
|
||||
>async () => { function foo(p: string[]): string[] { return []; } function bar(p: string[]): string[] { return []; } let a1: string[] | undefined = []; while (true) { let a2 = foo(a1!); a1 = await bar(a2); }} : () => Promise<never>
|
||||
|
||||
function foo(p: string[]): string[] {
|
||||
>foo : (p: string[]) => string[]
|
||||
>p : string[]
|
||||
|
||||
return [];
|
||||
>[] : undefined[]
|
||||
}
|
||||
|
||||
function bar(p: string[]): string[] {
|
||||
>bar : (p: string[]) => string[]
|
||||
>p : string[]
|
||||
|
||||
return [];
|
||||
>[] : undefined[]
|
||||
}
|
||||
|
||||
let a1: string[] | undefined = [];
|
||||
>a1 : string[]
|
||||
>[] : undefined[]
|
||||
|
||||
while (true) {
|
||||
>true : true
|
||||
|
||||
let a2 = foo(a1!);
|
||||
>a2 : string[]
|
||||
>foo(a1!) : string[]
|
||||
>foo : (p: string[]) => string[]
|
||||
>a1! : string[]
|
||||
>a1 : string[]
|
||||
|
||||
a1 = await bar(a2);
|
||||
>a1 = await bar(a2) : string[]
|
||||
>a1 : string[]
|
||||
>await bar(a2) : string[]
|
||||
>bar(a2) : string[]
|
||||
>bar : (p: string[]) => string[]
|
||||
>a2 : string[]
|
||||
}
|
||||
});
|
||||
@@ -6,15 +6,9 @@ tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(35,17): error
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(46,17): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(77,13): error TS7022: 'y' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
|
||||
tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(77,26): error TS2345: Argument of type 'string | number | boolean' is not assignable to parameter of type 'string | number'.
|
||||
Type 'true' is not assignable to type 'string | number'.
|
||||
tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(88,13): error TS7022: 'y' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
|
||||
tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(88,26): error TS2345: Argument of type 'string | number | boolean' is not assignable to parameter of type 'string | number'.
|
||||
Type 'true' is not assignable to type 'string | number'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts (8 errors) ====
|
||||
==== tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts (4 errors) ====
|
||||
|
||||
let cond: boolean;
|
||||
|
||||
@@ -104,11 +98,6 @@ tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(88,26): error
|
||||
x = "0";
|
||||
while (cond) {
|
||||
let y = asNumber(x);
|
||||
~
|
||||
!!! error TS7022: 'y' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
|
||||
~
|
||||
!!! error TS2345: Argument of type 'string | number | boolean' is not assignable to parameter of type 'string | number'.
|
||||
!!! error TS2345: Type 'true' is not assignable to type 'string | number'.
|
||||
x = y + 1;
|
||||
x;
|
||||
}
|
||||
@@ -120,11 +109,6 @@ tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(88,26): error
|
||||
while (cond) {
|
||||
x;
|
||||
let y = asNumber(x);
|
||||
~
|
||||
!!! error TS7022: 'y' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
|
||||
~
|
||||
!!! error TS2345: Argument of type 'string | number | boolean' is not assignable to parameter of type 'string | number'.
|
||||
!!! error TS2345: Type 'true' is not assignable to type 'string | number'.
|
||||
x = y + 1;
|
||||
x;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredic
|
||||
m(): this is Foo {
|
||||
~~~~
|
||||
!!! error TS2526: A 'this' type is available only in a non-static member of a class or interface.
|
||||
let dis = this as Foo;
|
||||
let dis = this as {} as Foo;
|
||||
return dis.a != null && dis.b != null && dis.c != null;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ export interface Foo {
|
||||
|
||||
export const obj = {
|
||||
m(): this is Foo {
|
||||
let dis = this as Foo;
|
||||
let dis = this as {} as Foo;
|
||||
return dis.a != null && dis.b != null && dis.c != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredic
|
||||
m(): this is Foo {
|
||||
~~~~
|
||||
!!! error TS2526: A 'this' type is available only in a non-static member of a class or interface.
|
||||
let dis = this as Foo;
|
||||
let dis = this as {} as Foo;
|
||||
return dis.a != null && dis.b != null && dis.c != null;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ interface Foo {
|
||||
|
||||
export const obj = {
|
||||
m(): this is Foo {
|
||||
let dis = this as Foo;
|
||||
let dis = this as {} as Foo;
|
||||
return dis.a != null && dis.b != null && dis.c != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,12 +18,21 @@ function foo2(x = "string", b: number) {
|
||||
|
||||
function foo3(x: string | undefined = "string", b: number) {
|
||||
x.length; // ok, should be string
|
||||
x = undefined;
|
||||
}
|
||||
|
||||
function foo4(x: string | undefined = undefined, b: number) {
|
||||
x; // should be string | undefined
|
||||
x = undefined;
|
||||
}
|
||||
|
||||
type OptionalNullableString = string | null | undefined;
|
||||
function allowsNull(val: OptionalNullableString = "") {
|
||||
val = null;
|
||||
val = 'string and null are both ok';
|
||||
}
|
||||
allowsNull(null); // still allows passing null
|
||||
|
||||
|
||||
|
||||
// .d.ts should have `string | undefined` for foo1, foo2, foo3 and foo4
|
||||
@@ -72,11 +81,19 @@ function foo2(x, b) {
|
||||
function foo3(x, b) {
|
||||
if (x === void 0) { x = "string"; }
|
||||
x.length; // ok, should be string
|
||||
x = undefined;
|
||||
}
|
||||
function foo4(x, b) {
|
||||
if (x === void 0) { x = undefined; }
|
||||
x; // should be string | undefined
|
||||
x = undefined;
|
||||
}
|
||||
function allowsNull(val) {
|
||||
if (val === void 0) { val = ""; }
|
||||
val = null;
|
||||
val = 'string and null are both ok';
|
||||
}
|
||||
allowsNull(null); // still allows passing null
|
||||
// .d.ts should have `string | undefined` for foo1, foo2, foo3 and foo4
|
||||
foo1(undefined, 1);
|
||||
foo2(undefined, 1);
|
||||
@@ -107,6 +124,8 @@ declare function foo1(x: string | undefined, b: number): void;
|
||||
declare function foo2(x: string | undefined, b: number): void;
|
||||
declare function foo3(x: string | undefined, b: number): void;
|
||||
declare function foo4(x: string | undefined, b: number): void;
|
||||
declare type OptionalNullableString = string | null | undefined;
|
||||
declare function allowsNull(val?: OptionalNullableString): void;
|
||||
declare function removeUndefinedButNotFalse(x?: boolean): false | undefined;
|
||||
declare const cond: boolean;
|
||||
declare function removeNothing(y?: boolean | undefined): boolean;
|
||||
|
||||
+41
-16
@@ -66,18 +66,43 @@ function foo3(x: string | undefined = "string", b: number) {
|
||||
>x.length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 17, 14))
|
||||
>length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
|
||||
x = undefined;
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 17, 14))
|
||||
>undefined : Symbol(undefined)
|
||||
}
|
||||
|
||||
function foo4(x: string | undefined = undefined, b: number) {
|
||||
>foo4 : Symbol(foo4, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 19, 1))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 21, 14))
|
||||
>foo4 : Symbol(foo4, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 20, 1))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 22, 14))
|
||||
>undefined : Symbol(undefined)
|
||||
>b : Symbol(b, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 21, 48))
|
||||
>b : Symbol(b, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 22, 48))
|
||||
|
||||
x; // should be string | undefined
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 21, 14))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 22, 14))
|
||||
|
||||
x = undefined;
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 22, 14))
|
||||
>undefined : Symbol(undefined)
|
||||
}
|
||||
|
||||
type OptionalNullableString = string | null | undefined;
|
||||
>OptionalNullableString : Symbol(OptionalNullableString, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 25, 1))
|
||||
|
||||
function allowsNull(val: OptionalNullableString = "") {
|
||||
>allowsNull : Symbol(allowsNull, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 27, 56))
|
||||
>val : Symbol(val, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 28, 20))
|
||||
>OptionalNullableString : Symbol(OptionalNullableString, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 25, 1))
|
||||
|
||||
val = null;
|
||||
>val : Symbol(val, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 28, 20))
|
||||
|
||||
val = 'string and null are both ok';
|
||||
>val : Symbol(val, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 28, 20))
|
||||
}
|
||||
allowsNull(null); // still allows passing null
|
||||
>allowsNull : Symbol(allowsNull, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 27, 56))
|
||||
|
||||
|
||||
|
||||
// .d.ts should have `string | undefined` for foo1, foo2, foo3 and foo4
|
||||
@@ -94,40 +119,40 @@ foo3(undefined, 1);
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
foo4(undefined, 1);
|
||||
>foo4 : Symbol(foo4, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 19, 1))
|
||||
>foo4 : Symbol(foo4, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 20, 1))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
|
||||
function removeUndefinedButNotFalse(x = true) {
|
||||
>removeUndefinedButNotFalse : Symbol(removeUndefinedButNotFalse, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 31, 19))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 34, 36))
|
||||
>removeUndefinedButNotFalse : Symbol(removeUndefinedButNotFalse, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 40, 19))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 43, 36))
|
||||
|
||||
if (x === false) {
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 34, 36))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 43, 36))
|
||||
|
||||
return x;
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 34, 36))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 43, 36))
|
||||
}
|
||||
}
|
||||
|
||||
declare const cond: boolean;
|
||||
>cond : Symbol(cond, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 40, 13))
|
||||
>cond : Symbol(cond, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 49, 13))
|
||||
|
||||
function removeNothing(y = cond ? true : undefined) {
|
||||
>removeNothing : Symbol(removeNothing, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 40, 28))
|
||||
>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 41, 23))
|
||||
>cond : Symbol(cond, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 40, 13))
|
||||
>removeNothing : Symbol(removeNothing, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 49, 28))
|
||||
>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 50, 23))
|
||||
>cond : Symbol(cond, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 49, 13))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
if (y !== undefined) {
|
||||
>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 41, 23))
|
||||
>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 50, 23))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
if (y === false) {
|
||||
>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 41, 23))
|
||||
>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 50, 23))
|
||||
|
||||
return y;
|
||||
>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 41, 23))
|
||||
>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 50, 23))
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -86,7 +86,7 @@ function foo2(x = "string", b: number) {
|
||||
|
||||
function foo3(x: string | undefined = "string", b: number) {
|
||||
>foo3 : (x: string | undefined, b: number) => void
|
||||
>x : string
|
||||
>x : string | undefined
|
||||
>"string" : "string"
|
||||
>b : number
|
||||
|
||||
@@ -94,6 +94,11 @@ function foo3(x: string | undefined = "string", b: number) {
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
|
||||
x = undefined;
|
||||
>x = undefined : undefined
|
||||
>x : string | undefined
|
||||
>undefined : undefined
|
||||
}
|
||||
|
||||
function foo4(x: string | undefined = undefined, b: number) {
|
||||
@@ -104,8 +109,38 @@ function foo4(x: string | undefined = undefined, b: number) {
|
||||
|
||||
x; // should be string | undefined
|
||||
>x : string | undefined
|
||||
|
||||
x = undefined;
|
||||
>x = undefined : undefined
|
||||
>x : string | undefined
|
||||
>undefined : undefined
|
||||
}
|
||||
|
||||
type OptionalNullableString = string | null | undefined;
|
||||
>OptionalNullableString : OptionalNullableString
|
||||
>null : null
|
||||
|
||||
function allowsNull(val: OptionalNullableString = "") {
|
||||
>allowsNull : (val?: OptionalNullableString) => void
|
||||
>val : OptionalNullableString
|
||||
>OptionalNullableString : OptionalNullableString
|
||||
>"" : ""
|
||||
|
||||
val = null;
|
||||
>val = null : null
|
||||
>val : OptionalNullableString
|
||||
>null : null
|
||||
|
||||
val = 'string and null are both ok';
|
||||
>val = 'string and null are both ok' : "string and null are both ok"
|
||||
>val : OptionalNullableString
|
||||
>'string and null are both ok' : "string and null are both ok"
|
||||
}
|
||||
allowsNull(null); // still allows passing null
|
||||
>allowsNull(null) : void
|
||||
>allowsNull : (val?: OptionalNullableString) => void
|
||||
>null : null
|
||||
|
||||
|
||||
|
||||
// .d.ts should have `string | undefined` for foo1, foo2, foo3 and foo4
|
||||
|
||||
@@ -9,9 +9,9 @@ function setFunc(v){}
|
||||
|
||||
Object.defineProperty({}, "0", <PropertyDescriptor>({
|
||||
>Object.defineProperty({}, "0", <PropertyDescriptor>({ get: getFunc, set: setFunc, configurable: true })) : any
|
||||
>Object.defineProperty : (o: any, p: string, attributes: PropertyDescriptor) => any
|
||||
>Object.defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType<any>) => any
|
||||
>Object : ObjectConstructor
|
||||
>defineProperty : (o: any, p: string, attributes: PropertyDescriptor) => any
|
||||
>defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType<any>) => any
|
||||
>{} : {}
|
||||
>"0" : "0"
|
||||
><PropertyDescriptor>({ get: getFunc, set: setFunc, configurable: true }) : PropertyDescriptor
|
||||
|
||||
@@ -7,11 +7,10 @@ tests/cases/compiler/implicitAnyFromCircularInference.ts(18,10): error TS7024: F
|
||||
tests/cases/compiler/implicitAnyFromCircularInference.ts(23,10): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
|
||||
tests/cases/compiler/implicitAnyFromCircularInference.ts(26,10): error TS7023: 'h' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
|
||||
tests/cases/compiler/implicitAnyFromCircularInference.ts(28,14): error TS7023: 'foo' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
|
||||
tests/cases/compiler/implicitAnyFromCircularInference.ts(41,5): error TS7022: 's' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
|
||||
tests/cases/compiler/implicitAnyFromCircularInference.ts(46,9): error TS7023: 'x' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
|
||||
|
||||
|
||||
==== tests/cases/compiler/implicitAnyFromCircularInference.ts (11 errors) ====
|
||||
==== tests/cases/compiler/implicitAnyFromCircularInference.ts (10 errors) ====
|
||||
|
||||
// Error expected
|
||||
var a: typeof a;
|
||||
@@ -71,8 +70,6 @@ tests/cases/compiler/implicitAnyFromCircularInference.ts(46,9): error TS7023: 'x
|
||||
class C {
|
||||
// Error expected
|
||||
s = foo(this);
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS7022: 's' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
|
||||
}
|
||||
|
||||
class D {
|
||||
|
||||
@@ -69,7 +69,6 @@ C = tslib_1.__decorate([
|
||||
], C);
|
||||
//// [script.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var tslib_1 = require("tslib");
|
||||
var A = (function () {
|
||||
function A() {
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
//// [tests/cases/conformance/salsa/inferringClassMembersFromAssignments.ts] ////
|
||||
|
||||
//// [a.js]
|
||||
|
||||
class C {
|
||||
constructor() {
|
||||
if (Math.random()) {
|
||||
this.inConstructor = 0;
|
||||
}
|
||||
else {
|
||||
this.inConstructor = "string"
|
||||
}
|
||||
this.inMultiple = 0;
|
||||
}
|
||||
method() {
|
||||
if (Math.random()) {
|
||||
this.inMethod = 0;
|
||||
}
|
||||
else {
|
||||
this.inMethod = "string"
|
||||
}
|
||||
this.inMultiple = "string";
|
||||
}
|
||||
get() {
|
||||
if (Math.random()) {
|
||||
this.inGetter = 0;
|
||||
}
|
||||
else {
|
||||
this.inGetter = "string"
|
||||
}
|
||||
this.inMultiple = false;
|
||||
}
|
||||
set() {
|
||||
if (Math.random()) {
|
||||
this.inSetter = 0;
|
||||
}
|
||||
else {
|
||||
this.inSetter = "string"
|
||||
}
|
||||
}
|
||||
static method() {
|
||||
if (Math.random()) {
|
||||
this.inStaticMethod = 0;
|
||||
}
|
||||
else {
|
||||
this.inStaticMethod = "string"
|
||||
}
|
||||
}
|
||||
static get() {
|
||||
if (Math.random()) {
|
||||
this.inStaticGetter = 0;
|
||||
}
|
||||
else {
|
||||
this.inStaticGetter = "string"
|
||||
}
|
||||
}
|
||||
static set() {
|
||||
if (Math.random()) {
|
||||
this.inStaticSetter = 0;
|
||||
}
|
||||
else {
|
||||
this.inStaticSetter = "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//// [b.ts]
|
||||
var c = new C();
|
||||
|
||||
var stringOrNumber: string | number;
|
||||
var stringOrNumber = c.inConstructor;
|
||||
|
||||
var stringOrNumberOrUndefined: string | number | undefined;
|
||||
|
||||
var stringOrNumberOrUndefined = c.inMethod;
|
||||
var stringOrNumberOrUndefined = c.inGetter;
|
||||
var stringOrNumberOrUndefined = c.inSetter;
|
||||
|
||||
var stringOrNumberOrBoolean: string | number | boolean;
|
||||
|
||||
var stringOrNumberOrBoolean = c.inMultiple;
|
||||
|
||||
|
||||
var stringOrNumberOrUndefined = C.inStaticMethod;
|
||||
var stringOrNumberOrUndefined = C.inStaticGetter;
|
||||
var stringOrNumberOrUndefined = C.inStaticSetter;
|
||||
|
||||
|
||||
//// [output.js]
|
||||
var C = (function () {
|
||||
function C() {
|
||||
if (Math.random()) {
|
||||
this.inConstructor = 0;
|
||||
}
|
||||
else {
|
||||
this.inConstructor = "string";
|
||||
}
|
||||
this.inMultiple = 0;
|
||||
}
|
||||
C.prototype.method = function () {
|
||||
if (Math.random()) {
|
||||
this.inMethod = 0;
|
||||
}
|
||||
else {
|
||||
this.inMethod = "string";
|
||||
}
|
||||
this.inMultiple = "string";
|
||||
};
|
||||
C.prototype.get = function () {
|
||||
if (Math.random()) {
|
||||
this.inGetter = 0;
|
||||
}
|
||||
else {
|
||||
this.inGetter = "string";
|
||||
}
|
||||
this.inMultiple = false;
|
||||
};
|
||||
C.prototype.set = function () {
|
||||
if (Math.random()) {
|
||||
this.inSetter = 0;
|
||||
}
|
||||
else {
|
||||
this.inSetter = "string";
|
||||
}
|
||||
};
|
||||
C.method = function () {
|
||||
if (Math.random()) {
|
||||
this.inStaticMethod = 0;
|
||||
}
|
||||
else {
|
||||
this.inStaticMethod = "string";
|
||||
}
|
||||
};
|
||||
C.get = function () {
|
||||
if (Math.random()) {
|
||||
this.inStaticGetter = 0;
|
||||
}
|
||||
else {
|
||||
this.inStaticGetter = "string";
|
||||
}
|
||||
};
|
||||
C.set = function () {
|
||||
if (Math.random()) {
|
||||
this.inStaticSetter = 0;
|
||||
}
|
||||
else {
|
||||
this.inStaticSetter = "string";
|
||||
}
|
||||
};
|
||||
return C;
|
||||
}());
|
||||
var c = new C();
|
||||
var stringOrNumber;
|
||||
var stringOrNumber = c.inConstructor;
|
||||
var stringOrNumberOrUndefined;
|
||||
var stringOrNumberOrUndefined = c.inMethod;
|
||||
var stringOrNumberOrUndefined = c.inGetter;
|
||||
var stringOrNumberOrUndefined = c.inSetter;
|
||||
var stringOrNumberOrBoolean;
|
||||
var stringOrNumberOrBoolean = c.inMultiple;
|
||||
var stringOrNumberOrUndefined = C.inStaticMethod;
|
||||
var stringOrNumberOrUndefined = C.inStaticGetter;
|
||||
var stringOrNumberOrUndefined = C.inStaticSetter;
|
||||
@@ -0,0 +1,220 @@
|
||||
=== tests/cases/conformance/salsa/a.js ===
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(a.js, 0, 0))
|
||||
|
||||
constructor() {
|
||||
if (Math.random()) {
|
||||
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
|
||||
this.inConstructor = 0;
|
||||
>this.inConstructor : Symbol(C.inConstructor, Decl(a.js, 3, 28), Decl(a.js, 6, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inConstructor : Symbol(C.inConstructor, Decl(a.js, 3, 28), Decl(a.js, 6, 14))
|
||||
}
|
||||
else {
|
||||
this.inConstructor = "string"
|
||||
>this.inConstructor : Symbol(C.inConstructor, Decl(a.js, 3, 28), Decl(a.js, 6, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inConstructor : Symbol(C.inConstructor, Decl(a.js, 3, 28), Decl(a.js, 6, 14))
|
||||
}
|
||||
this.inMultiple = 0;
|
||||
>this.inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||
}
|
||||
method() {
|
||||
>method : Symbol(C.method, Decl(a.js, 10, 5))
|
||||
|
||||
if (Math.random()) {
|
||||
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
|
||||
this.inMethod = 0;
|
||||
>this.inMethod : Symbol(C.inMethod, Decl(a.js, 12, 28), Decl(a.js, 15, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inMethod : Symbol(C.inMethod, Decl(a.js, 12, 28), Decl(a.js, 15, 14))
|
||||
}
|
||||
else {
|
||||
this.inMethod = "string"
|
||||
>this.inMethod : Symbol(C.inMethod, Decl(a.js, 12, 28), Decl(a.js, 15, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inMethod : Symbol(C.inMethod, Decl(a.js, 12, 28), Decl(a.js, 15, 14))
|
||||
}
|
||||
this.inMultiple = "string";
|
||||
>this.inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||
}
|
||||
get() {
|
||||
>get : Symbol(C.get, Decl(a.js, 19, 5))
|
||||
|
||||
if (Math.random()) {
|
||||
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
|
||||
this.inGetter = 0;
|
||||
>this.inGetter : Symbol(C.inGetter, Decl(a.js, 21, 28), Decl(a.js, 24, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inGetter : Symbol(C.inGetter, Decl(a.js, 21, 28), Decl(a.js, 24, 14))
|
||||
}
|
||||
else {
|
||||
this.inGetter = "string"
|
||||
>this.inGetter : Symbol(C.inGetter, Decl(a.js, 21, 28), Decl(a.js, 24, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inGetter : Symbol(C.inGetter, Decl(a.js, 21, 28), Decl(a.js, 24, 14))
|
||||
}
|
||||
this.inMultiple = false;
|
||||
>this.inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||
}
|
||||
set() {
|
||||
>set : Symbol(C.set, Decl(a.js, 28, 5))
|
||||
|
||||
if (Math.random()) {
|
||||
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
|
||||
this.inSetter = 0;
|
||||
>this.inSetter : Symbol(C.inSetter, Decl(a.js, 30, 28), Decl(a.js, 33, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inSetter : Symbol(C.inSetter, Decl(a.js, 30, 28), Decl(a.js, 33, 14))
|
||||
}
|
||||
else {
|
||||
this.inSetter = "string"
|
||||
>this.inSetter : Symbol(C.inSetter, Decl(a.js, 30, 28), Decl(a.js, 33, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inSetter : Symbol(C.inSetter, Decl(a.js, 30, 28), Decl(a.js, 33, 14))
|
||||
}
|
||||
}
|
||||
static method() {
|
||||
>method : Symbol(C.method, Decl(a.js, 36, 5))
|
||||
|
||||
if (Math.random()) {
|
||||
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
|
||||
this.inStaticMethod = 0;
|
||||
>this.inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
|
||||
}
|
||||
else {
|
||||
this.inStaticMethod = "string"
|
||||
>this.inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
|
||||
}
|
||||
}
|
||||
static get() {
|
||||
>get : Symbol(C.get, Decl(a.js, 44, 5))
|
||||
|
||||
if (Math.random()) {
|
||||
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
|
||||
this.inStaticGetter = 0;
|
||||
>this.inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
|
||||
}
|
||||
else {
|
||||
this.inStaticGetter = "string"
|
||||
>this.inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
|
||||
}
|
||||
}
|
||||
static set() {
|
||||
>set : Symbol(C.set, Decl(a.js, 52, 5))
|
||||
|
||||
if (Math.random()) {
|
||||
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
|
||||
this.inStaticSetter = 0;
|
||||
>this.inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
|
||||
}
|
||||
else {
|
||||
this.inStaticSetter = "string"
|
||||
>this.inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
|
||||
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/salsa/b.ts ===
|
||||
var c = new C();
|
||||
>c : Symbol(c, Decl(b.ts, 0, 3))
|
||||
>C : Symbol(C, Decl(a.js, 0, 0))
|
||||
|
||||
var stringOrNumber: string | number;
|
||||
>stringOrNumber : Symbol(stringOrNumber, Decl(b.ts, 2, 3), Decl(b.ts, 3, 3))
|
||||
|
||||
var stringOrNumber = c.inConstructor;
|
||||
>stringOrNumber : Symbol(stringOrNumber, Decl(b.ts, 2, 3), Decl(b.ts, 3, 3))
|
||||
>c.inConstructor : Symbol(C.inConstructor, Decl(a.js, 3, 28), Decl(a.js, 6, 14))
|
||||
>c : Symbol(c, Decl(b.ts, 0, 3))
|
||||
>inConstructor : Symbol(C.inConstructor, Decl(a.js, 3, 28), Decl(a.js, 6, 14))
|
||||
|
||||
var stringOrNumberOrUndefined: string | number | undefined;
|
||||
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||
|
||||
var stringOrNumberOrUndefined = c.inMethod;
|
||||
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||
>c.inMethod : Symbol(C.inMethod, Decl(a.js, 12, 28), Decl(a.js, 15, 14))
|
||||
>c : Symbol(c, Decl(b.ts, 0, 3))
|
||||
>inMethod : Symbol(C.inMethod, Decl(a.js, 12, 28), Decl(a.js, 15, 14))
|
||||
|
||||
var stringOrNumberOrUndefined = c.inGetter;
|
||||
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||
>c.inGetter : Symbol(C.inGetter, Decl(a.js, 21, 28), Decl(a.js, 24, 14))
|
||||
>c : Symbol(c, Decl(b.ts, 0, 3))
|
||||
>inGetter : Symbol(C.inGetter, Decl(a.js, 21, 28), Decl(a.js, 24, 14))
|
||||
|
||||
var stringOrNumberOrUndefined = c.inSetter;
|
||||
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||
>c.inSetter : Symbol(C.inSetter, Decl(a.js, 30, 28), Decl(a.js, 33, 14))
|
||||
>c : Symbol(c, Decl(b.ts, 0, 3))
|
||||
>inSetter : Symbol(C.inSetter, Decl(a.js, 30, 28), Decl(a.js, 33, 14))
|
||||
|
||||
var stringOrNumberOrBoolean: string | number | boolean;
|
||||
>stringOrNumberOrBoolean : Symbol(stringOrNumberOrBoolean, Decl(b.ts, 11, 3), Decl(b.ts, 13, 3))
|
||||
|
||||
var stringOrNumberOrBoolean = c.inMultiple;
|
||||
>stringOrNumberOrBoolean : Symbol(stringOrNumberOrBoolean, Decl(b.ts, 11, 3), Decl(b.ts, 13, 3))
|
||||
>c.inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||
>c : Symbol(c, Decl(b.ts, 0, 3))
|
||||
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||
|
||||
|
||||
var stringOrNumberOrUndefined = C.inStaticMethod;
|
||||
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||
>C.inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
|
||||
>C : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
|
||||
|
||||
var stringOrNumberOrUndefined = C.inStaticGetter;
|
||||
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||
>C.inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
|
||||
>C : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
|
||||
|
||||
var stringOrNumberOrUndefined = C.inStaticSetter;
|
||||
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||
>C.inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
|
||||
>C : Symbol(C, Decl(a.js, 0, 0))
|
||||
>inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
=== tests/cases/conformance/salsa/a.js ===
|
||||
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
constructor() {
|
||||
if (Math.random()) {
|
||||
>Math.random() : number
|
||||
>Math.random : () => number
|
||||
>Math : Math
|
||||
>random : () => number
|
||||
|
||||
this.inConstructor = 0;
|
||||
>this.inConstructor = 0 : 0
|
||||
>this.inConstructor : string | number
|
||||
>this : this
|
||||
>inConstructor : string | number
|
||||
>0 : 0
|
||||
}
|
||||
else {
|
||||
this.inConstructor = "string"
|
||||
>this.inConstructor = "string" : "string"
|
||||
>this.inConstructor : string | number
|
||||
>this : this
|
||||
>inConstructor : string | number
|
||||
>"string" : "string"
|
||||
}
|
||||
this.inMultiple = 0;
|
||||
>this.inMultiple = 0 : 0
|
||||
>this.inMultiple : string | number | boolean
|
||||
>this : this
|
||||
>inMultiple : string | number | boolean
|
||||
>0 : 0
|
||||
}
|
||||
method() {
|
||||
>method : () => void
|
||||
|
||||
if (Math.random()) {
|
||||
>Math.random() : number
|
||||
>Math.random : () => number
|
||||
>Math : Math
|
||||
>random : () => number
|
||||
|
||||
this.inMethod = 0;
|
||||
>this.inMethod = 0 : 0
|
||||
>this.inMethod : string | number | undefined
|
||||
>this : this
|
||||
>inMethod : string | number | undefined
|
||||
>0 : 0
|
||||
}
|
||||
else {
|
||||
this.inMethod = "string"
|
||||
>this.inMethod = "string" : "string"
|
||||
>this.inMethod : string | number | undefined
|
||||
>this : this
|
||||
>inMethod : string | number | undefined
|
||||
>"string" : "string"
|
||||
}
|
||||
this.inMultiple = "string";
|
||||
>this.inMultiple = "string" : "string"
|
||||
>this.inMultiple : string | number | boolean
|
||||
>this : this
|
||||
>inMultiple : string | number | boolean
|
||||
>"string" : "string"
|
||||
}
|
||||
get() {
|
||||
>get : () => void
|
||||
|
||||
if (Math.random()) {
|
||||
>Math.random() : number
|
||||
>Math.random : () => number
|
||||
>Math : Math
|
||||
>random : () => number
|
||||
|
||||
this.inGetter = 0;
|
||||
>this.inGetter = 0 : 0
|
||||
>this.inGetter : string | number | undefined
|
||||
>this : this
|
||||
>inGetter : string | number | undefined
|
||||
>0 : 0
|
||||
}
|
||||
else {
|
||||
this.inGetter = "string"
|
||||
>this.inGetter = "string" : "string"
|
||||
>this.inGetter : string | number | undefined
|
||||
>this : this
|
||||
>inGetter : string | number | undefined
|
||||
>"string" : "string"
|
||||
}
|
||||
this.inMultiple = false;
|
||||
>this.inMultiple = false : false
|
||||
>this.inMultiple : string | number | boolean
|
||||
>this : this
|
||||
>inMultiple : string | number | boolean
|
||||
>false : false
|
||||
}
|
||||
set() {
|
||||
>set : () => void
|
||||
|
||||
if (Math.random()) {
|
||||
>Math.random() : number
|
||||
>Math.random : () => number
|
||||
>Math : Math
|
||||
>random : () => number
|
||||
|
||||
this.inSetter = 0;
|
||||
>this.inSetter = 0 : 0
|
||||
>this.inSetter : string | number | undefined
|
||||
>this : this
|
||||
>inSetter : string | number | undefined
|
||||
>0 : 0
|
||||
}
|
||||
else {
|
||||
this.inSetter = "string"
|
||||
>this.inSetter = "string" : "string"
|
||||
>this.inSetter : string | number | undefined
|
||||
>this : this
|
||||
>inSetter : string | number | undefined
|
||||
>"string" : "string"
|
||||
}
|
||||
}
|
||||
static method() {
|
||||
>method : () => void
|
||||
|
||||
if (Math.random()) {
|
||||
>Math.random() : number
|
||||
>Math.random : () => number
|
||||
>Math : Math
|
||||
>random : () => number
|
||||
|
||||
this.inStaticMethod = 0;
|
||||
>this.inStaticMethod = 0 : 0
|
||||
>this.inStaticMethod : string | number | undefined
|
||||
>this : typeof C
|
||||
>inStaticMethod : string | number | undefined
|
||||
>0 : 0
|
||||
}
|
||||
else {
|
||||
this.inStaticMethod = "string"
|
||||
>this.inStaticMethod = "string" : "string"
|
||||
>this.inStaticMethod : string | number | undefined
|
||||
>this : typeof C
|
||||
>inStaticMethod : string | number | undefined
|
||||
>"string" : "string"
|
||||
}
|
||||
}
|
||||
static get() {
|
||||
>get : () => void
|
||||
|
||||
if (Math.random()) {
|
||||
>Math.random() : number
|
||||
>Math.random : () => number
|
||||
>Math : Math
|
||||
>random : () => number
|
||||
|
||||
this.inStaticGetter = 0;
|
||||
>this.inStaticGetter = 0 : 0
|
||||
>this.inStaticGetter : string | number | undefined
|
||||
>this : typeof C
|
||||
>inStaticGetter : string | number | undefined
|
||||
>0 : 0
|
||||
}
|
||||
else {
|
||||
this.inStaticGetter = "string"
|
||||
>this.inStaticGetter = "string" : "string"
|
||||
>this.inStaticGetter : string | number | undefined
|
||||
>this : typeof C
|
||||
>inStaticGetter : string | number | undefined
|
||||
>"string" : "string"
|
||||
}
|
||||
}
|
||||
static set() {
|
||||
>set : () => void
|
||||
|
||||
if (Math.random()) {
|
||||
>Math.random() : number
|
||||
>Math.random : () => number
|
||||
>Math : Math
|
||||
>random : () => number
|
||||
|
||||
this.inStaticSetter = 0;
|
||||
>this.inStaticSetter = 0 : 0
|
||||
>this.inStaticSetter : string | number | undefined
|
||||
>this : typeof C
|
||||
>inStaticSetter : string | number | undefined
|
||||
>0 : 0
|
||||
}
|
||||
else {
|
||||
this.inStaticSetter = "string"
|
||||
>this.inStaticSetter = "string" : "string"
|
||||
>this.inStaticSetter : string | number | undefined
|
||||
>this : typeof C
|
||||
>inStaticSetter : string | number | undefined
|
||||
>"string" : "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/salsa/b.ts ===
|
||||
var c = new C();
|
||||
>c : C
|
||||
>new C() : C
|
||||
>C : typeof C
|
||||
|
||||
var stringOrNumber: string | number;
|
||||
>stringOrNumber : string | number
|
||||
|
||||
var stringOrNumber = c.inConstructor;
|
||||
>stringOrNumber : string | number
|
||||
>c.inConstructor : string | number
|
||||
>c : C
|
||||
>inConstructor : string | number
|
||||
|
||||
var stringOrNumberOrUndefined: string | number | undefined;
|
||||
>stringOrNumberOrUndefined : string | number | undefined
|
||||
|
||||
var stringOrNumberOrUndefined = c.inMethod;
|
||||
>stringOrNumberOrUndefined : string | number | undefined
|
||||
>c.inMethod : string | number | undefined
|
||||
>c : C
|
||||
>inMethod : string | number | undefined
|
||||
|
||||
var stringOrNumberOrUndefined = c.inGetter;
|
||||
>stringOrNumberOrUndefined : string | number | undefined
|
||||
>c.inGetter : string | number | undefined
|
||||
>c : C
|
||||
>inGetter : string | number | undefined
|
||||
|
||||
var stringOrNumberOrUndefined = c.inSetter;
|
||||
>stringOrNumberOrUndefined : string | number | undefined
|
||||
>c.inSetter : string | number | undefined
|
||||
>c : C
|
||||
>inSetter : string | number | undefined
|
||||
|
||||
var stringOrNumberOrBoolean: string | number | boolean;
|
||||
>stringOrNumberOrBoolean : string | number | boolean
|
||||
|
||||
var stringOrNumberOrBoolean = c.inMultiple;
|
||||
>stringOrNumberOrBoolean : string | number | boolean
|
||||
>c.inMultiple : string | number | boolean
|
||||
>c : C
|
||||
>inMultiple : string | number | boolean
|
||||
|
||||
|
||||
var stringOrNumberOrUndefined = C.inStaticMethod;
|
||||
>stringOrNumberOrUndefined : string | number | undefined
|
||||
>C.inStaticMethod : string | number | undefined
|
||||
>C : typeof C
|
||||
>inStaticMethod : string | number | undefined
|
||||
|
||||
var stringOrNumberOrUndefined = C.inStaticGetter;
|
||||
>stringOrNumberOrUndefined : string | number | undefined
|
||||
>C.inStaticGetter : string | number | undefined
|
||||
>C : typeof C
|
||||
>inStaticGetter : string | number | undefined
|
||||
|
||||
var stringOrNumberOrUndefined = C.inStaticSetter;
|
||||
>stringOrNumberOrUndefined : string | number | undefined
|
||||
>C.inStaticSetter : string | number | undefined
|
||||
>C : typeof C
|
||||
>inStaticSetter : string | number | undefined
|
||||
|
||||
@@ -7,6 +7,5 @@ run(1);
|
||||
//// [isolatedModulesPlainFile-AMD.js]
|
||||
define(["require", "exports"], function (require, exports) {
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
run(1);
|
||||
});
|
||||
|
||||
@@ -6,5 +6,4 @@ run(1);
|
||||
|
||||
//// [isolatedModulesPlainFile-CommonJS.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
run(1);
|
||||
|
||||
@@ -15,6 +15,5 @@ run(1);
|
||||
}
|
||||
})(function (require, exports) {
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
run(1);
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
=== tests/cases/compiler/a.js ===
|
||||
|
||||
function foo() {
|
||||
>foo : () => { a: number; b: string; }
|
||||
>foo : () => { [x: string]: any; a: number; b: string; }
|
||||
|
||||
var a = 10;
|
||||
>a : number
|
||||
@@ -12,7 +12,7 @@ function foo() {
|
||||
>"Hello" : "Hello"
|
||||
|
||||
return {
|
||||
>{ a, b } : { a: number; b: string; }
|
||||
>{ a, b } : { [x: string]: any; a: number; b: string; }
|
||||
|
||||
a,
|
||||
>a : number
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
//// [tests/cases/conformance/salsa/jsObjectsMarkedAsOpenEnded.ts] ////
|
||||
|
||||
//// [a.js]
|
||||
|
||||
var variable = {};
|
||||
variable.a = 0;
|
||||
|
||||
class C {
|
||||
initializedMember = {};
|
||||
constructor() {
|
||||
this.member = {};
|
||||
this.member.a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var obj = {
|
||||
property: {}
|
||||
};
|
||||
|
||||
obj.property.a = 0;
|
||||
|
||||
var arr = [{}];
|
||||
|
||||
function getObj() {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
//// [b.ts]
|
||||
variable.a = 1;
|
||||
(new C()).member.a = 1;
|
||||
(new C()).initializedMember.a = 1;
|
||||
obj.property.a = 1;
|
||||
arr[0].a = 1;
|
||||
getObj().a = 1;
|
||||
|
||||
|
||||
|
||||
//// [output.js]
|
||||
var variable = {};
|
||||
variable.a = 0;
|
||||
var C = (function () {
|
||||
function C() {
|
||||
this.initializedMember = {};
|
||||
this.member = {};
|
||||
this.member.a = 0;
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
var obj = {
|
||||
property: {}
|
||||
};
|
||||
obj.property.a = 0;
|
||||
var arr = [{}];
|
||||
function getObj() {
|
||||
return {};
|
||||
}
|
||||
variable.a = 1;
|
||||
(new C()).member.a = 1;
|
||||
(new C()).initializedMember.a = 1;
|
||||
obj.property.a = 1;
|
||||
arr[0].a = 1;
|
||||
getObj().a = 1;
|
||||
@@ -0,0 +1,76 @@
|
||||
=== tests/cases/conformance/salsa/a.js ===
|
||||
|
||||
var variable = {};
|
||||
>variable : Symbol(variable, Decl(a.js, 1, 3))
|
||||
|
||||
variable.a = 0;
|
||||
>variable : Symbol(variable, Decl(a.js, 1, 3))
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(a.js, 2, 15))
|
||||
|
||||
initializedMember = {};
|
||||
>initializedMember : Symbol(C.initializedMember, Decl(a.js, 4, 9))
|
||||
|
||||
constructor() {
|
||||
this.member = {};
|
||||
>this.member : Symbol(C.member, Decl(a.js, 6, 19))
|
||||
>this : Symbol(C, Decl(a.js, 2, 15))
|
||||
>member : Symbol(C.member, Decl(a.js, 6, 19))
|
||||
|
||||
this.member.a = 0;
|
||||
>this.member : Symbol(C.member, Decl(a.js, 6, 19))
|
||||
>this : Symbol(C, Decl(a.js, 2, 15))
|
||||
>member : Symbol(C.member, Decl(a.js, 6, 19))
|
||||
}
|
||||
}
|
||||
|
||||
var obj = {
|
||||
>obj : Symbol(obj, Decl(a.js, 12, 3))
|
||||
|
||||
property: {}
|
||||
>property : Symbol(property, Decl(a.js, 12, 11))
|
||||
|
||||
};
|
||||
|
||||
obj.property.a = 0;
|
||||
>obj.property : Symbol(property, Decl(a.js, 12, 11))
|
||||
>obj : Symbol(obj, Decl(a.js, 12, 3))
|
||||
>property : Symbol(property, Decl(a.js, 12, 11))
|
||||
|
||||
var arr = [{}];
|
||||
>arr : Symbol(arr, Decl(a.js, 18, 3))
|
||||
|
||||
function getObj() {
|
||||
>getObj : Symbol(getObj, Decl(a.js, 18, 15))
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
=== tests/cases/conformance/salsa/b.ts ===
|
||||
variable.a = 1;
|
||||
>variable : Symbol(variable, Decl(a.js, 1, 3))
|
||||
|
||||
(new C()).member.a = 1;
|
||||
>(new C()).member : Symbol(C.member, Decl(a.js, 6, 19))
|
||||
>C : Symbol(C, Decl(a.js, 2, 15))
|
||||
>member : Symbol(C.member, Decl(a.js, 6, 19))
|
||||
|
||||
(new C()).initializedMember.a = 1;
|
||||
>(new C()).initializedMember : Symbol(C.initializedMember, Decl(a.js, 4, 9))
|
||||
>C : Symbol(C, Decl(a.js, 2, 15))
|
||||
>initializedMember : Symbol(C.initializedMember, Decl(a.js, 4, 9))
|
||||
|
||||
obj.property.a = 1;
|
||||
>obj.property : Symbol(property, Decl(a.js, 12, 11))
|
||||
>obj : Symbol(obj, Decl(a.js, 12, 3))
|
||||
>property : Symbol(property, Decl(a.js, 12, 11))
|
||||
|
||||
arr[0].a = 1;
|
||||
>arr : Symbol(arr, Decl(a.js, 18, 3))
|
||||
|
||||
getObj().a = 1;
|
||||
>getObj : Symbol(getObj, Decl(a.js, 18, 15))
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
=== tests/cases/conformance/salsa/a.js ===
|
||||
|
||||
var variable = {};
|
||||
>variable : { [x: string]: any; }
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
variable.a = 0;
|
||||
>variable.a = 0 : 0
|
||||
>variable.a : any
|
||||
>variable : { [x: string]: any; }
|
||||
>a : any
|
||||
>0 : 0
|
||||
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
initializedMember = {};
|
||||
>initializedMember : { [x: string]: any; }
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
constructor() {
|
||||
this.member = {};
|
||||
>this.member = {} : { [x: string]: any; }
|
||||
>this.member : { [x: string]: any; }
|
||||
>this : this
|
||||
>member : { [x: string]: any; }
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
this.member.a = 0;
|
||||
>this.member.a = 0 : 0
|
||||
>this.member.a : any
|
||||
>this.member : { [x: string]: any; }
|
||||
>this : this
|
||||
>member : { [x: string]: any; }
|
||||
>a : any
|
||||
>0 : 0
|
||||
}
|
||||
}
|
||||
|
||||
var obj = {
|
||||
>obj : { [x: string]: any; property: { [x: string]: any; }; }
|
||||
>{ property: {}} : { [x: string]: any; property: { [x: string]: any; }; }
|
||||
|
||||
property: {}
|
||||
>property : { [x: string]: any; }
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
};
|
||||
|
||||
obj.property.a = 0;
|
||||
>obj.property.a = 0 : 0
|
||||
>obj.property.a : any
|
||||
>obj.property : { [x: string]: any; }
|
||||
>obj : { [x: string]: any; property: { [x: string]: any; }; }
|
||||
>property : { [x: string]: any; }
|
||||
>a : any
|
||||
>0 : 0
|
||||
|
||||
var arr = [{}];
|
||||
>arr : { [x: string]: any; }[]
|
||||
>[{}] : { [x: string]: any; }[]
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
function getObj() {
|
||||
>getObj : () => { [x: string]: any; }
|
||||
|
||||
return {};
|
||||
>{} : { [x: string]: any; }
|
||||
}
|
||||
|
||||
|
||||
=== tests/cases/conformance/salsa/b.ts ===
|
||||
variable.a = 1;
|
||||
>variable.a = 1 : 1
|
||||
>variable.a : any
|
||||
>variable : { [x: string]: any; }
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
(new C()).member.a = 1;
|
||||
>(new C()).member.a = 1 : 1
|
||||
>(new C()).member.a : any
|
||||
>(new C()).member : { [x: string]: any; }
|
||||
>(new C()) : C
|
||||
>new C() : C
|
||||
>C : typeof C
|
||||
>member : { [x: string]: any; }
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
(new C()).initializedMember.a = 1;
|
||||
>(new C()).initializedMember.a = 1 : 1
|
||||
>(new C()).initializedMember.a : any
|
||||
>(new C()).initializedMember : { [x: string]: any; }
|
||||
>(new C()) : C
|
||||
>new C() : C
|
||||
>C : typeof C
|
||||
>initializedMember : { [x: string]: any; }
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
obj.property.a = 1;
|
||||
>obj.property.a = 1 : 1
|
||||
>obj.property.a : any
|
||||
>obj.property : { [x: string]: any; }
|
||||
>obj : { [x: string]: any; property: { [x: string]: any; }; }
|
||||
>property : { [x: string]: any; }
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
arr[0].a = 1;
|
||||
>arr[0].a = 1 : 1
|
||||
>arr[0].a : any
|
||||
>arr[0] : { [x: string]: any; }
|
||||
>arr : { [x: string]: any; }[]
|
||||
>0 : 0
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
getObj().a = 1;
|
||||
>getObj().a = 1 : 1
|
||||
>getObj().a : any
|
||||
>getObj() : { [x: string]: any; }
|
||||
>getObj : () => { [x: string]: any; }
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(21,1): error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(this: void, m: number) => number'.
|
||||
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(22,1): error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(this: void, m: number) => number'.
|
||||
The 'this' types of each signature are incompatible.
|
||||
Type 'void' is not assignable to type 'C'.
|
||||
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(33,28): error TS2339: Property 'length' does not exist on type 'number'.
|
||||
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(37,9): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'I'.
|
||||
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(46,20): error TS2339: Property 'length' does not exist on type 'number'.
|
||||
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(26,27): error TS2339: Property 'length' does not exist on type 'number'.
|
||||
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(34,28): error TS2339: Property 'length' does not exist on type 'number'.
|
||||
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(38,9): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'I'.
|
||||
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(47,20): error TS2339: Property 'length' does not exist on type 'number'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts (4 errors) ====
|
||||
==== tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts (5 errors) ====
|
||||
|
||||
interface I {
|
||||
n: number;
|
||||
explicitThis(this: this, m: number): number;
|
||||
@@ -36,6 +38,8 @@ tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(46,20): error
|
||||
n: 101,
|
||||
explicitThis: function (m: number) {
|
||||
return m + this.n.length; // error, 'length' does not exist on 'number'
|
||||
~~~~~~
|
||||
!!! error TS2339: Property 'length' does not exist on type 'number'.
|
||||
},
|
||||
implicitThis(m: number): number { return m; }
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//// [looseThisTypeInFunctions.ts]
|
||||
|
||||
interface I {
|
||||
n: number;
|
||||
explicitThis(this: this, m: number): number;
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
=== tests/cases/conformance/salsa/a.ts ===
|
||||
|
||||
import b = require("./b.js");
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
|
||||
b.func1;
|
||||
>b.func1 : Symbol(b.func1, Decl(b.js, 0, 27))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func1 : Symbol(b.func1, Decl(b.js, 0, 27))
|
||||
|
||||
b.func2;
|
||||
>b.func2 : Symbol(b.func2, Decl(b.js, 1, 37))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func2 : Symbol(b.func2, Decl(b.js, 1, 37))
|
||||
|
||||
b.func3;
|
||||
>b.func3 : Symbol(b.func3, Decl(b.js, 4, 40))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func3 : Symbol(b.func3, Decl(b.js, 4, 40))
|
||||
|
||||
b.func4;
|
||||
>b.func4 : Symbol(b.func4, Decl(b.js, 5, 43))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func4 : Symbol(b.func4, Decl(b.js, 5, 43))
|
||||
|
||||
b.func5;
|
||||
>b.func5 : Symbol(b.func5, Decl(b.js, 8, 57))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func5 : Symbol(b.func5, Decl(b.js, 8, 57))
|
||||
|
||||
b.func6;
|
||||
>b.func6 : Symbol(b.func6, Decl(b.js, 11, 57))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func6 : Symbol(b.func6, Decl(b.js, 11, 57))
|
||||
|
||||
b.func7;
|
||||
>b.func7 : Symbol(b.func7, Decl(b.js, 15, 60))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func7 : Symbol(b.func7, Decl(b.js, 15, 60))
|
||||
|
||||
b.func8;
|
||||
>b.func8 : Symbol(b.func8, Decl(b.js, 18, 67))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func8 : Symbol(b.func8, Decl(b.js, 18, 67))
|
||||
|
||||
b.func9;
|
||||
>b.func9 : Symbol(b.func9, Decl(b.js, 21, 62))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func9 : Symbol(b.func9, Decl(b.js, 21, 62))
|
||||
|
||||
b.func10;
|
||||
>b.func10 : Symbol(b.func10, Decl(b.js, 24, 62))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func10 : Symbol(b.func10, Decl(b.js, 24, 62))
|
||||
|
||||
b.func11;
|
||||
>b.func11 : Symbol(b.func11, Decl(b.js, 27, 50), Decl(b.js, 31, 50))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func11 : Symbol(b.func11, Decl(b.js, 27, 50), Decl(b.js, 31, 50))
|
||||
|
||||
b.func12;
|
||||
>b.func12 : Symbol(b.func12, Decl(b.js, 28, 33), Decl(b.js, 32, 33))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func12 : Symbol(b.func12, Decl(b.js, 28, 33), Decl(b.js, 32, 33))
|
||||
|
||||
b.func13;
|
||||
>b.func13 : Symbol(b.func13, Decl(b.js, 35, 30))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func13 : Symbol(b.func13, Decl(b.js, 35, 30))
|
||||
|
||||
b.func14;
|
||||
>b.func14 : Symbol(b.func14, Decl(b.js, 36, 33))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func14 : Symbol(b.func14, Decl(b.js, 36, 33))
|
||||
|
||||
b.func15;
|
||||
>b.func15 : Symbol(b.func15, Decl(b.js, 39, 30))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func15 : Symbol(b.func15, Decl(b.js, 39, 30))
|
||||
|
||||
b.func16;
|
||||
>b.func16 : Symbol(b.func16, Decl(b.js, 40, 33))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func16 : Symbol(b.func16, Decl(b.js, 40, 33))
|
||||
|
||||
b.func17;
|
||||
>b.func17 : Symbol(b.func17, Decl(b.js, 43, 30))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func17 : Symbol(b.func17, Decl(b.js, 43, 30))
|
||||
|
||||
b.func18;
|
||||
>b.func18 : Symbol(b.func18, Decl(b.js, 44, 33))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func18 : Symbol(b.func18, Decl(b.js, 44, 33))
|
||||
|
||||
b.func19;
|
||||
>b.func19 : Symbol(b.func19, Decl(b.js, 47, 20))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func19 : Symbol(b.func19, Decl(b.js, 47, 20))
|
||||
|
||||
b.func20;
|
||||
>b.func20 : Symbol(b.func20, Decl(b.js, 48, 33))
|
||||
>b : Symbol(b, Decl(a.ts, 0, 0))
|
||||
>func20 : Symbol(b.func20, Decl(b.js, 48, 33))
|
||||
|
||||
|
||||
=== tests/cases/conformance/salsa/b.js ===
|
||||
var exportsAlias = exports;
|
||||
>exportsAlias : Symbol(exportsAlias, Decl(b.js, 0, 3))
|
||||
|
||||
exportsAlias.func1 = function () { };
|
||||
>exportsAlias : Symbol(exportsAlias, Decl(b.js, 0, 3))
|
||||
|
||||
exports.func2 = function () { };
|
||||
>exports : Symbol(func2, Decl(b.js, 1, 37))
|
||||
>func2 : Symbol(func2, Decl(b.js, 1, 37))
|
||||
|
||||
var moduleExportsAlias = module.exports;
|
||||
>moduleExportsAlias : Symbol(moduleExportsAlias, Decl(b.js, 4, 3))
|
||||
|
||||
moduleExportsAlias.func3 = function () { };
|
||||
>moduleExportsAlias : Symbol(moduleExportsAlias, Decl(b.js, 4, 3))
|
||||
|
||||
module.exports.func4 = function () { };
|
||||
>module.exports : Symbol(func4, Decl(b.js, 5, 43))
|
||||
>func4 : Symbol(func4, Decl(b.js, 5, 43))
|
||||
|
||||
var multipleDeclarationAlias1 = exports = module.exports;
|
||||
>multipleDeclarationAlias1 : Symbol(multipleDeclarationAlias1, Decl(b.js, 8, 3))
|
||||
|
||||
multipleDeclarationAlias1.func5 = function () { };
|
||||
>multipleDeclarationAlias1 : Symbol(multipleDeclarationAlias1, Decl(b.js, 8, 3))
|
||||
|
||||
var multipleDeclarationAlias2 = module.exports = exports;
|
||||
>multipleDeclarationAlias2 : Symbol(multipleDeclarationAlias2, Decl(b.js, 11, 3))
|
||||
|
||||
multipleDeclarationAlias2.func6 = function () { };
|
||||
>multipleDeclarationAlias2 : Symbol(multipleDeclarationAlias2, Decl(b.js, 11, 3))
|
||||
|
||||
var someOtherVariable;
|
||||
>someOtherVariable : Symbol(someOtherVariable, Decl(b.js, 14, 3))
|
||||
|
||||
var multipleDeclarationAlias3 = someOtherVariable = exports;
|
||||
>multipleDeclarationAlias3 : Symbol(multipleDeclarationAlias3, Decl(b.js, 15, 3))
|
||||
>someOtherVariable : Symbol(someOtherVariable, Decl(b.js, 14, 3))
|
||||
|
||||
multipleDeclarationAlias3.func7 = function () { };
|
||||
>multipleDeclarationAlias3 : Symbol(multipleDeclarationAlias3, Decl(b.js, 15, 3))
|
||||
|
||||
var multipleDeclarationAlias4 = someOtherVariable = module.exports;
|
||||
>multipleDeclarationAlias4 : Symbol(multipleDeclarationAlias4, Decl(b.js, 18, 3))
|
||||
>someOtherVariable : Symbol(someOtherVariable, Decl(b.js, 14, 3))
|
||||
|
||||
multipleDeclarationAlias4.func8 = function () { };
|
||||
>multipleDeclarationAlias4 : Symbol(multipleDeclarationAlias4, Decl(b.js, 18, 3))
|
||||
|
||||
var multipleDeclarationAlias5 = module.exports = exports = {};
|
||||
>multipleDeclarationAlias5 : Symbol(multipleDeclarationAlias5, Decl(b.js, 21, 3))
|
||||
|
||||
multipleDeclarationAlias5.func9 = function () { };
|
||||
>multipleDeclarationAlias5 : Symbol(multipleDeclarationAlias5, Decl(b.js, 21, 3))
|
||||
|
||||
var multipleDeclarationAlias6 = exports = module.exports = {};
|
||||
>multipleDeclarationAlias6 : Symbol(multipleDeclarationAlias6, Decl(b.js, 24, 3))
|
||||
|
||||
multipleDeclarationAlias6.func10 = function () { };
|
||||
>multipleDeclarationAlias6 : Symbol(multipleDeclarationAlias6, Decl(b.js, 24, 3))
|
||||
|
||||
exports = module.exports = someOtherVariable = {};
|
||||
>someOtherVariable : Symbol(someOtherVariable, Decl(b.js, 14, 3))
|
||||
|
||||
exports.func11 = function () { };
|
||||
>exports : Symbol(func11, Decl(b.js, 27, 50), Decl(b.js, 31, 50))
|
||||
>func11 : Symbol(func11, Decl(b.js, 27, 50), Decl(b.js, 31, 50))
|
||||
|
||||
module.exports.func12 = function () { };
|
||||
>module.exports : Symbol(func12, Decl(b.js, 28, 33), Decl(b.js, 32, 33))
|
||||
>func12 : Symbol(func12, Decl(b.js, 28, 33), Decl(b.js, 32, 33))
|
||||
|
||||
exports = module.exports = someOtherVariable = {};
|
||||
>someOtherVariable : Symbol(someOtherVariable, Decl(b.js, 14, 3))
|
||||
|
||||
exports.func11 = function () { };
|
||||
>exports : Symbol(func11, Decl(b.js, 27, 50), Decl(b.js, 31, 50))
|
||||
>func11 : Symbol(func11, Decl(b.js, 27, 50), Decl(b.js, 31, 50))
|
||||
|
||||
module.exports.func12 = function () { };
|
||||
>module.exports : Symbol(func12, Decl(b.js, 28, 33), Decl(b.js, 32, 33))
|
||||
>func12 : Symbol(func12, Decl(b.js, 28, 33), Decl(b.js, 32, 33))
|
||||
|
||||
exports = module.exports = {};
|
||||
exports.func13 = function () { };
|
||||
>exports : Symbol(func13, Decl(b.js, 35, 30))
|
||||
>func13 : Symbol(func13, Decl(b.js, 35, 30))
|
||||
|
||||
module.exports.func14 = function () { };
|
||||
>module.exports : Symbol(func14, Decl(b.js, 36, 33))
|
||||
>func14 : Symbol(func14, Decl(b.js, 36, 33))
|
||||
|
||||
exports = module.exports = {};
|
||||
exports.func15 = function () { };
|
||||
>exports : Symbol(func15, Decl(b.js, 39, 30))
|
||||
>func15 : Symbol(func15, Decl(b.js, 39, 30))
|
||||
|
||||
module.exports.func16 = function () { };
|
||||
>module.exports : Symbol(func16, Decl(b.js, 40, 33))
|
||||
>func16 : Symbol(func16, Decl(b.js, 40, 33))
|
||||
|
||||
module.exports = exports = {};
|
||||
exports.func17 = function () { };
|
||||
>exports : Symbol(func17, Decl(b.js, 43, 30))
|
||||
>func17 : Symbol(func17, Decl(b.js, 43, 30))
|
||||
|
||||
module.exports.func18 = function () { };
|
||||
>module.exports : Symbol(func18, Decl(b.js, 44, 33))
|
||||
>func18 : Symbol(func18, Decl(b.js, 44, 33))
|
||||
|
||||
module.exports = {};
|
||||
exports.func19 = function () { };
|
||||
>exports : Symbol(func19, Decl(b.js, 47, 20))
|
||||
>func19 : Symbol(func19, Decl(b.js, 47, 20))
|
||||
|
||||
module.exports.func20 = function () { };
|
||||
>module.exports : Symbol(func20, Decl(b.js, 48, 33))
|
||||
>func20 : Symbol(func20, Decl(b.js, 48, 33))
|
||||
|
||||
|
||||
@@ -0,0 +1,395 @@
|
||||
=== tests/cases/conformance/salsa/a.ts ===
|
||||
|
||||
import b = require("./b.js");
|
||||
>b : typeof b
|
||||
|
||||
b.func1;
|
||||
>b.func1 : () => void
|
||||
>b : typeof b
|
||||
>func1 : () => void
|
||||
|
||||
b.func2;
|
||||
>b.func2 : () => void
|
||||
>b : typeof b
|
||||
>func2 : () => void
|
||||
|
||||
b.func3;
|
||||
>b.func3 : () => void
|
||||
>b : typeof b
|
||||
>func3 : () => void
|
||||
|
||||
b.func4;
|
||||
>b.func4 : () => void
|
||||
>b : typeof b
|
||||
>func4 : () => void
|
||||
|
||||
b.func5;
|
||||
>b.func5 : () => void
|
||||
>b : typeof b
|
||||
>func5 : () => void
|
||||
|
||||
b.func6;
|
||||
>b.func6 : () => void
|
||||
>b : typeof b
|
||||
>func6 : () => void
|
||||
|
||||
b.func7;
|
||||
>b.func7 : () => void
|
||||
>b : typeof b
|
||||
>func7 : () => void
|
||||
|
||||
b.func8;
|
||||
>b.func8 : () => void
|
||||
>b : typeof b
|
||||
>func8 : () => void
|
||||
|
||||
b.func9;
|
||||
>b.func9 : () => void
|
||||
>b : typeof b
|
||||
>func9 : () => void
|
||||
|
||||
b.func10;
|
||||
>b.func10 : () => void
|
||||
>b : typeof b
|
||||
>func10 : () => void
|
||||
|
||||
b.func11;
|
||||
>b.func11 : () => void
|
||||
>b : typeof b
|
||||
>func11 : () => void
|
||||
|
||||
b.func12;
|
||||
>b.func12 : () => void
|
||||
>b : typeof b
|
||||
>func12 : () => void
|
||||
|
||||
b.func13;
|
||||
>b.func13 : () => void
|
||||
>b : typeof b
|
||||
>func13 : () => void
|
||||
|
||||
b.func14;
|
||||
>b.func14 : () => void
|
||||
>b : typeof b
|
||||
>func14 : () => void
|
||||
|
||||
b.func15;
|
||||
>b.func15 : () => void
|
||||
>b : typeof b
|
||||
>func15 : () => void
|
||||
|
||||
b.func16;
|
||||
>b.func16 : () => void
|
||||
>b : typeof b
|
||||
>func16 : () => void
|
||||
|
||||
b.func17;
|
||||
>b.func17 : () => void
|
||||
>b : typeof b
|
||||
>func17 : () => void
|
||||
|
||||
b.func18;
|
||||
>b.func18 : () => void
|
||||
>b : typeof b
|
||||
>func18 : () => void
|
||||
|
||||
b.func19;
|
||||
>b.func19 : () => void
|
||||
>b : typeof b
|
||||
>func19 : () => void
|
||||
|
||||
b.func20;
|
||||
>b.func20 : () => void
|
||||
>b : typeof b
|
||||
>func20 : () => void
|
||||
|
||||
|
||||
=== tests/cases/conformance/salsa/b.js ===
|
||||
var exportsAlias = exports;
|
||||
>exportsAlias : any
|
||||
>exports : any
|
||||
|
||||
exportsAlias.func1 = function () { };
|
||||
>exportsAlias.func1 = function () { } : () => void
|
||||
>exportsAlias.func1 : any
|
||||
>exportsAlias : any
|
||||
>func1 : any
|
||||
>function () { } : () => void
|
||||
|
||||
exports.func2 = function () { };
|
||||
>exports.func2 = function () { } : () => void
|
||||
>exports.func2 : any
|
||||
>exports : any
|
||||
>func2 : any
|
||||
>function () { } : () => void
|
||||
|
||||
var moduleExportsAlias = module.exports;
|
||||
>moduleExportsAlias : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
|
||||
moduleExportsAlias.func3 = function () { };
|
||||
>moduleExportsAlias.func3 = function () { } : () => void
|
||||
>moduleExportsAlias.func3 : any
|
||||
>moduleExportsAlias : any
|
||||
>func3 : any
|
||||
>function () { } : () => void
|
||||
|
||||
module.exports.func4 = function () { };
|
||||
>module.exports.func4 = function () { } : () => void
|
||||
>module.exports.func4 : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>func4 : any
|
||||
>function () { } : () => void
|
||||
|
||||
var multipleDeclarationAlias1 = exports = module.exports;
|
||||
>multipleDeclarationAlias1 : any
|
||||
>exports = module.exports : any
|
||||
>exports : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
|
||||
multipleDeclarationAlias1.func5 = function () { };
|
||||
>multipleDeclarationAlias1.func5 = function () { } : () => void
|
||||
>multipleDeclarationAlias1.func5 : any
|
||||
>multipleDeclarationAlias1 : any
|
||||
>func5 : any
|
||||
>function () { } : () => void
|
||||
|
||||
var multipleDeclarationAlias2 = module.exports = exports;
|
||||
>multipleDeclarationAlias2 : any
|
||||
>module.exports = exports : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>exports : any
|
||||
|
||||
multipleDeclarationAlias2.func6 = function () { };
|
||||
>multipleDeclarationAlias2.func6 = function () { } : () => void
|
||||
>multipleDeclarationAlias2.func6 : any
|
||||
>multipleDeclarationAlias2 : any
|
||||
>func6 : any
|
||||
>function () { } : () => void
|
||||
|
||||
var someOtherVariable;
|
||||
>someOtherVariable : any
|
||||
|
||||
var multipleDeclarationAlias3 = someOtherVariable = exports;
|
||||
>multipleDeclarationAlias3 : any
|
||||
>someOtherVariable = exports : any
|
||||
>someOtherVariable : any
|
||||
>exports : any
|
||||
|
||||
multipleDeclarationAlias3.func7 = function () { };
|
||||
>multipleDeclarationAlias3.func7 = function () { } : () => void
|
||||
>multipleDeclarationAlias3.func7 : any
|
||||
>multipleDeclarationAlias3 : any
|
||||
>func7 : any
|
||||
>function () { } : () => void
|
||||
|
||||
var multipleDeclarationAlias4 = someOtherVariable = module.exports;
|
||||
>multipleDeclarationAlias4 : any
|
||||
>someOtherVariable = module.exports : any
|
||||
>someOtherVariable : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
|
||||
multipleDeclarationAlias4.func8 = function () { };
|
||||
>multipleDeclarationAlias4.func8 = function () { } : () => void
|
||||
>multipleDeclarationAlias4.func8 : any
|
||||
>multipleDeclarationAlias4 : any
|
||||
>func8 : any
|
||||
>function () { } : () => void
|
||||
|
||||
var multipleDeclarationAlias5 = module.exports = exports = {};
|
||||
>multipleDeclarationAlias5 : {}
|
||||
>module.exports = exports = {} : {}
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>exports = {} : {}
|
||||
>exports : any
|
||||
>{} : {}
|
||||
|
||||
multipleDeclarationAlias5.func9 = function () { };
|
||||
>multipleDeclarationAlias5.func9 = function () { } : () => void
|
||||
>multipleDeclarationAlias5.func9 : any
|
||||
>multipleDeclarationAlias5 : {}
|
||||
>func9 : any
|
||||
>function () { } : () => void
|
||||
|
||||
var multipleDeclarationAlias6 = exports = module.exports = {};
|
||||
>multipleDeclarationAlias6 : { [x: string]: any; }
|
||||
>exports = module.exports = {} : { [x: string]: any; }
|
||||
>exports : any
|
||||
>module.exports = {} : { [x: string]: any; }
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
multipleDeclarationAlias6.func10 = function () { };
|
||||
>multipleDeclarationAlias6.func10 = function () { } : () => void
|
||||
>multipleDeclarationAlias6.func10 : any
|
||||
>multipleDeclarationAlias6 : { [x: string]: any; }
|
||||
>func10 : any
|
||||
>function () { } : () => void
|
||||
|
||||
exports = module.exports = someOtherVariable = {};
|
||||
>exports = module.exports = someOtherVariable = {} : {}
|
||||
>exports : any
|
||||
>module.exports = someOtherVariable = {} : {}
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>someOtherVariable = {} : {}
|
||||
>someOtherVariable : any
|
||||
>{} : {}
|
||||
|
||||
exports.func11 = function () { };
|
||||
>exports.func11 = function () { } : () => void
|
||||
>exports.func11 : any
|
||||
>exports : any
|
||||
>func11 : any
|
||||
>function () { } : () => void
|
||||
|
||||
module.exports.func12 = function () { };
|
||||
>module.exports.func12 = function () { } : () => void
|
||||
>module.exports.func12 : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>func12 : any
|
||||
>function () { } : () => void
|
||||
|
||||
exports = module.exports = someOtherVariable = {};
|
||||
>exports = module.exports = someOtherVariable = {} : {}
|
||||
>exports : any
|
||||
>module.exports = someOtherVariable = {} : {}
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>someOtherVariable = {} : {}
|
||||
>someOtherVariable : any
|
||||
>{} : {}
|
||||
|
||||
exports.func11 = function () { };
|
||||
>exports.func11 = function () { } : () => void
|
||||
>exports.func11 : any
|
||||
>exports : any
|
||||
>func11 : any
|
||||
>function () { } : () => void
|
||||
|
||||
module.exports.func12 = function () { };
|
||||
>module.exports.func12 = function () { } : () => void
|
||||
>module.exports.func12 : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>func12 : any
|
||||
>function () { } : () => void
|
||||
|
||||
exports = module.exports = {};
|
||||
>exports = module.exports = {} : { [x: string]: any; }
|
||||
>exports : any
|
||||
>module.exports = {} : { [x: string]: any; }
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
exports.func13 = function () { };
|
||||
>exports.func13 = function () { } : () => void
|
||||
>exports.func13 : any
|
||||
>exports : any
|
||||
>func13 : any
|
||||
>function () { } : () => void
|
||||
|
||||
module.exports.func14 = function () { };
|
||||
>module.exports.func14 = function () { } : () => void
|
||||
>module.exports.func14 : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>func14 : any
|
||||
>function () { } : () => void
|
||||
|
||||
exports = module.exports = {};
|
||||
>exports = module.exports = {} : { [x: string]: any; }
|
||||
>exports : any
|
||||
>module.exports = {} : { [x: string]: any; }
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
exports.func15 = function () { };
|
||||
>exports.func15 = function () { } : () => void
|
||||
>exports.func15 : any
|
||||
>exports : any
|
||||
>func15 : any
|
||||
>function () { } : () => void
|
||||
|
||||
module.exports.func16 = function () { };
|
||||
>module.exports.func16 = function () { } : () => void
|
||||
>module.exports.func16 : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>func16 : any
|
||||
>function () { } : () => void
|
||||
|
||||
module.exports = exports = {};
|
||||
>module.exports = exports = {} : {}
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>exports = {} : {}
|
||||
>exports : any
|
||||
>{} : {}
|
||||
|
||||
exports.func17 = function () { };
|
||||
>exports.func17 = function () { } : () => void
|
||||
>exports.func17 : any
|
||||
>exports : any
|
||||
>func17 : any
|
||||
>function () { } : () => void
|
||||
|
||||
module.exports.func18 = function () { };
|
||||
>module.exports.func18 = function () { } : () => void
|
||||
>module.exports.func18 : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>func18 : any
|
||||
>function () { } : () => void
|
||||
|
||||
module.exports = {};
|
||||
>module.exports = {} : { [x: string]: any; }
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
exports.func19 = function () { };
|
||||
>exports.func19 = function () { } : () => void
|
||||
>exports.func19 : any
|
||||
>exports : any
|
||||
>func19 : any
|
||||
>function () { } : () => void
|
||||
|
||||
module.exports.func20 = function () { };
|
||||
>module.exports.func20 = function () { } : () => void
|
||||
>module.exports.func20 : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>func20 : any
|
||||
>function () { } : () => void
|
||||
|
||||
|
||||
@@ -9,17 +9,17 @@ declare var union: null | { a: number, b: string };
|
||||
var n = Object.create(null); // object
|
||||
>n : any
|
||||
>Object.create(null) : any
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>null : null
|
||||
|
||||
var t = Object.create({ a: 1, b: "" }); // {a: number, b: string }
|
||||
>t : any
|
||||
>Object.create({ a: 1, b: "" }) : any
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>{ a: 1, b: "" } : { a: number; b: string; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
@@ -29,43 +29,43 @@ var t = Object.create({ a: 1, b: "" }); // {a: number, b: string }
|
||||
var u = Object.create(union); // object | {a: number, b: string }
|
||||
>u : any
|
||||
>Object.create(union) : any
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>union : { a: number; b: string; } | null
|
||||
|
||||
var e = Object.create({}); // {}
|
||||
>e : any
|
||||
>Object.create({}) : any
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>{} : {}
|
||||
|
||||
var o = Object.create(<object>{}); // object
|
||||
>o : any
|
||||
>Object.create(<object>{}) : any
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
><object>{} : object
|
||||
>{} : {}
|
||||
|
||||
var a = Object.create(null, {}); // any
|
||||
>a : any
|
||||
>Object.create(null, {}) : any
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>null : null
|
||||
>{} : {}
|
||||
|
||||
var a = Object.create({ a: 1, b: "" }, {});
|
||||
>a : any
|
||||
>Object.create({ a: 1, b: "" }, {}) : any
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>{ a: 1, b: "" } : { a: number; b: string; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
@@ -76,27 +76,27 @@ var a = Object.create({ a: 1, b: "" }, {});
|
||||
var a = Object.create(union, {});
|
||||
>a : any
|
||||
>Object.create(union, {}) : any
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>union : { a: number; b: string; } | null
|
||||
>{} : {}
|
||||
|
||||
var a = Object.create({}, {});
|
||||
>a : any
|
||||
>Object.create({}, {}) : any
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>{} : {}
|
||||
>{} : {}
|
||||
|
||||
var a = Object.create(<object>{}, {});
|
||||
>a : any
|
||||
>Object.create(<object>{}, {}) : any
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
><object>{} : object
|
||||
>{} : {}
|
||||
>{} : {}
|
||||
|
||||
@@ -9,17 +9,17 @@ declare var union: null | { a: number, b: string };
|
||||
var n = Object.create(null); // any
|
||||
>n : any
|
||||
>Object.create(null) : any
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>null : null
|
||||
|
||||
var t = Object.create({ a: 1, b: "" }); // {a: number, b: string }
|
||||
>t : any
|
||||
>Object.create({ a: 1, b: "" }) : any
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>{ a: 1, b: "" } : { a: number; b: string; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
@@ -29,43 +29,43 @@ var t = Object.create({ a: 1, b: "" }); // {a: number, b: string }
|
||||
var u = Object.create(union); // {a: number, b: string }
|
||||
>u : any
|
||||
>Object.create(union) : any
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>union : { a: number; b: string; }
|
||||
|
||||
var e = Object.create({}); // {}
|
||||
>e : any
|
||||
>Object.create({}) : any
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>{} : {}
|
||||
|
||||
var o = Object.create(<object>{}); // object
|
||||
>o : any
|
||||
>Object.create(<object>{}) : any
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
><object>{} : object
|
||||
>{} : {}
|
||||
|
||||
var a = Object.create(null, {}); // any
|
||||
>a : any
|
||||
>Object.create(null, {}) : any
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>null : null
|
||||
>{} : {}
|
||||
|
||||
var a = Object.create({ a: 1, b: "" }, {});
|
||||
>a : any
|
||||
>Object.create({ a: 1, b: "" }, {}) : any
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>{ a: 1, b: "" } : { a: number; b: string; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
@@ -76,27 +76,27 @@ var a = Object.create({ a: 1, b: "" }, {});
|
||||
var a = Object.create(union, {});
|
||||
>a : any
|
||||
>Object.create(union, {}) : any
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>union : { a: number; b: string; }
|
||||
>{} : {}
|
||||
|
||||
var a = Object.create({}, {});
|
||||
>a : any
|
||||
>Object.create({}, {}) : any
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>{} : {}
|
||||
>{} : {}
|
||||
|
||||
var a = Object.create(<object>{}, {});
|
||||
>a : any
|
||||
>Object.create(<object>{}, {}) : any
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
>Object : ObjectConstructor
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; }
|
||||
>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType<any>): any; }
|
||||
><object>{} : object
|
||||
>{} : {}
|
||||
>{} : {}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
Object.defineProperty(obj, "accProperty", <PropertyDescriptor>({
|
||||
>Object.defineProperty(obj, "accProperty", <PropertyDescriptor>({ get: function () { eval("public = 1;"); return 11; }, set: function (v) { } })) : any
|
||||
>Object.defineProperty : (o: any, p: string, attributes: PropertyDescriptor) => any
|
||||
>Object.defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType<any>) => any
|
||||
>Object : ObjectConstructor
|
||||
>defineProperty : (o: any, p: string, attributes: PropertyDescriptor) => any
|
||||
>defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType<any>) => any
|
||||
>obj : {}
|
||||
>"accProperty" : "accProperty"
|
||||
><PropertyDescriptor>({ get: function () { eval("public = 1;"); return 11; }, set: function (v) { } }) : PropertyDescriptor
|
||||
|
||||
@@ -23,3 +23,5 @@ const enum E2 {
|
||||
}
|
||||
// comment9
|
||||
console.log(1 + 2);
|
||||
// comment10
|
||||
function functionWithDefaultArgValue(argument: string = "defaultValue"): void { }
|
||||
|
||||
@@ -15,3 +15,4 @@ const enum E2 {
|
||||
second
|
||||
}
|
||||
console.log(1 + 2);
|
||||
function functionWithDefaultArgValue(argument: string = "defaultValue"): void { }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//// [selfInLambdas.ts]
|
||||
|
||||
interface MouseEvent {
|
||||
x: number;
|
||||
y: number;
|
||||
|
||||
@@ -1,44 +1,52 @@
|
||||
=== tests/cases/compiler/selfInLambdas.ts ===
|
||||
|
||||
interface MouseEvent {
|
||||
>MouseEvent : Symbol(MouseEvent, Decl(selfInLambdas.ts, 0, 0))
|
||||
|
||||
x: number;
|
||||
>x : Symbol(MouseEvent.x, Decl(selfInLambdas.ts, 0, 22))
|
||||
>x : Symbol(MouseEvent.x, Decl(selfInLambdas.ts, 1, 22))
|
||||
|
||||
y: number;
|
||||
>y : Symbol(MouseEvent.y, Decl(selfInLambdas.ts, 1, 14))
|
||||
>y : Symbol(MouseEvent.y, Decl(selfInLambdas.ts, 2, 14))
|
||||
}
|
||||
|
||||
declare var window: Window;
|
||||
>window : Symbol(window, Decl(selfInLambdas.ts, 5, 11))
|
||||
>Window : Symbol(Window, Decl(selfInLambdas.ts, 5, 27))
|
||||
>window : Symbol(window, Decl(selfInLambdas.ts, 6, 11))
|
||||
>Window : Symbol(Window, Decl(selfInLambdas.ts, 6, 27))
|
||||
|
||||
interface Window {
|
||||
>Window : Symbol(Window, Decl(selfInLambdas.ts, 5, 27))
|
||||
>Window : Symbol(Window, Decl(selfInLambdas.ts, 6, 27))
|
||||
|
||||
onmousemove: (ev: MouseEvent) => any;
|
||||
>onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 6, 18))
|
||||
>ev : Symbol(ev, Decl(selfInLambdas.ts, 7, 18))
|
||||
>onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 7, 18))
|
||||
>ev : Symbol(ev, Decl(selfInLambdas.ts, 8, 18))
|
||||
>MouseEvent : Symbol(MouseEvent, Decl(selfInLambdas.ts, 0, 0))
|
||||
|
||||
}
|
||||
var o = {
|
||||
>o : Symbol(o, Decl(selfInLambdas.ts, 10, 3))
|
||||
>o : Symbol(o, Decl(selfInLambdas.ts, 11, 3))
|
||||
|
||||
counter: 0,
|
||||
>counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9))
|
||||
>counter : Symbol(counter, Decl(selfInLambdas.ts, 11, 9))
|
||||
|
||||
start: function() {
|
||||
>start : Symbol(start, Decl(selfInLambdas.ts, 12, 15))
|
||||
>start : Symbol(start, Decl(selfInLambdas.ts, 13, 15))
|
||||
|
||||
window.onmousemove = () => {
|
||||
>window.onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 6, 18))
|
||||
>window : Symbol(window, Decl(selfInLambdas.ts, 5, 11))
|
||||
>onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 6, 18))
|
||||
>window.onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 7, 18))
|
||||
>window : Symbol(window, Decl(selfInLambdas.ts, 6, 11))
|
||||
>onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 7, 18))
|
||||
|
||||
this.counter++
|
||||
>this.counter : Symbol(counter, Decl(selfInLambdas.ts, 11, 9))
|
||||
>this : Symbol(o, Decl(selfInLambdas.ts, 11, 7))
|
||||
>counter : Symbol(counter, Decl(selfInLambdas.ts, 11, 9))
|
||||
|
||||
var f = () => this.counter;
|
||||
>f : Symbol(f, Decl(selfInLambdas.ts, 18, 15))
|
||||
>f : Symbol(f, Decl(selfInLambdas.ts, 19, 15))
|
||||
>this.counter : Symbol(counter, Decl(selfInLambdas.ts, 11, 9))
|
||||
>this : Symbol(o, Decl(selfInLambdas.ts, 11, 7))
|
||||
>counter : Symbol(counter, Decl(selfInLambdas.ts, 11, 9))
|
||||
|
||||
}
|
||||
|
||||
@@ -49,39 +57,39 @@ var o = {
|
||||
|
||||
|
||||
class X {
|
||||
>X : Symbol(X, Decl(selfInLambdas.ts, 24, 1))
|
||||
>X : Symbol(X, Decl(selfInLambdas.ts, 25, 1))
|
||||
|
||||
private value = "value";
|
||||
>value : Symbol(X.value, Decl(selfInLambdas.ts, 28, 9))
|
||||
>value : Symbol(X.value, Decl(selfInLambdas.ts, 29, 9))
|
||||
|
||||
public foo() {
|
||||
>foo : Symbol(X.foo, Decl(selfInLambdas.ts, 29, 25))
|
||||
>foo : Symbol(X.foo, Decl(selfInLambdas.ts, 30, 25))
|
||||
|
||||
var outer= () => {
|
||||
>outer : Symbol(outer, Decl(selfInLambdas.ts, 32, 5))
|
||||
>outer : Symbol(outer, Decl(selfInLambdas.ts, 33, 5))
|
||||
|
||||
var x = this.value;
|
||||
>x : Symbol(x, Decl(selfInLambdas.ts, 33, 15))
|
||||
>this.value : Symbol(X.value, Decl(selfInLambdas.ts, 28, 9))
|
||||
>this : Symbol(X, Decl(selfInLambdas.ts, 24, 1))
|
||||
>value : Symbol(X.value, Decl(selfInLambdas.ts, 28, 9))
|
||||
>x : Symbol(x, Decl(selfInLambdas.ts, 34, 15))
|
||||
>this.value : Symbol(X.value, Decl(selfInLambdas.ts, 29, 9))
|
||||
>this : Symbol(X, Decl(selfInLambdas.ts, 25, 1))
|
||||
>value : Symbol(X.value, Decl(selfInLambdas.ts, 29, 9))
|
||||
|
||||
var inner = () => {
|
||||
>inner : Symbol(inner, Decl(selfInLambdas.ts, 34, 15))
|
||||
>inner : Symbol(inner, Decl(selfInLambdas.ts, 35, 15))
|
||||
|
||||
var y = this.value;
|
||||
>y : Symbol(y, Decl(selfInLambdas.ts, 35, 19))
|
||||
>this.value : Symbol(X.value, Decl(selfInLambdas.ts, 28, 9))
|
||||
>this : Symbol(X, Decl(selfInLambdas.ts, 24, 1))
|
||||
>value : Symbol(X.value, Decl(selfInLambdas.ts, 28, 9))
|
||||
>y : Symbol(y, Decl(selfInLambdas.ts, 36, 19))
|
||||
>this.value : Symbol(X.value, Decl(selfInLambdas.ts, 29, 9))
|
||||
>this : Symbol(X, Decl(selfInLambdas.ts, 25, 1))
|
||||
>value : Symbol(X.value, Decl(selfInLambdas.ts, 29, 9))
|
||||
}
|
||||
|
||||
inner();
|
||||
>inner : Symbol(inner, Decl(selfInLambdas.ts, 34, 15))
|
||||
>inner : Symbol(inner, Decl(selfInLambdas.ts, 35, 15))
|
||||
|
||||
};
|
||||
outer();
|
||||
>outer : Symbol(outer, Decl(selfInLambdas.ts, 32, 5))
|
||||
>outer : Symbol(outer, Decl(selfInLambdas.ts, 33, 5))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
=== tests/cases/compiler/selfInLambdas.ts ===
|
||||
|
||||
interface MouseEvent {
|
||||
>MouseEvent : MouseEvent
|
||||
|
||||
@@ -43,16 +44,16 @@ var o = {
|
||||
|
||||
this.counter++
|
||||
>this.counter++ : number
|
||||
>this.counter : any
|
||||
>this : any
|
||||
>counter : any
|
||||
>this.counter : number
|
||||
>this : { counter: number; start: () => void; }
|
||||
>counter : number
|
||||
|
||||
var f = () => this.counter;
|
||||
>f : () => any
|
||||
>() => this.counter : () => any
|
||||
>this.counter : any
|
||||
>this : any
|
||||
>counter : any
|
||||
>f : () => number
|
||||
>() => this.counter : () => number
|
||||
>this.counter : number
|
||||
>this : { counter: number; start: () => void; }
|
||||
>counter : number
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
tests/cases/compiler/thisBinding2.ts(11,11): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
|
||||
|
||||
|
||||
==== tests/cases/compiler/thisBinding2.ts (1 errors) ====
|
||||
|
||||
class C {
|
||||
x: number;
|
||||
constructor() {
|
||||
this.x = (() => {
|
||||
var x = 1;
|
||||
return this.x;
|
||||
})();
|
||||
this.x = function() {
|
||||
var x = 1;
|
||||
return this.x;
|
||||
~~~~
|
||||
!!! error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
|
||||
}();
|
||||
}
|
||||
}
|
||||
declare function setTimeout(expression: any, msec?: number, language?: any): number;
|
||||
var messenger = {
|
||||
message: "Hello World",
|
||||
start: function () {
|
||||
return setTimeout(() => { var x = this.message; }, 3000);
|
||||
}
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user