Merge remote-tracking branch 'origin/master' into vladima/textChanges

This commit is contained in:
Vladimir Matveev
2017-03-07 15:10:41 -08:00
215 changed files with 6496 additions and 1377 deletions
+4 -4
View File
@@ -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
View File
@@ -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");
+2 -1
View File
@@ -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) {
+44 -34
View File
@@ -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));
}
}
}
}
}
}
+41 -35
View File
@@ -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);
}
}
}
+16
View File
@@ -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);
}
}
+6 -7
View File
@@ -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);
}
}
}
+35 -24
View File
@@ -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);
}
}
+5
View File
@@ -1,6 +1,11 @@
{
"compilerOptions": {
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strictNullChecks": true,
"module": "commonjs",
"outDir": "../../built/local/tslint"
}
+20 -18
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+7 -2
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/// <reference path="types.ts"/>
/// <reference path="types.ts"/>
/// <reference path="performance.ts" />
namespace ts {
+4
View File
@@ -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
+2 -2
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/// <reference path="core.ts"/>
/// <reference path="core.ts"/>
/// <reference path="utilities.ts"/>
namespace ts {
+44 -2
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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" />
+1 -1
View File
@@ -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 -1
View File
@@ -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
+12 -6
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/// <reference path="../../factory.ts" />
/// <reference path="../../factory.ts" />
/// <reference path="../../visitor.ts" />
/// <reference path="../destructuring.ts" />
+3 -2
View File
@@ -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
View File
@@ -1,4 +1,4 @@
/// <reference path="program.ts"/>
/// <reference path="program.ts"/>
/// <reference path="commandLineParser.ts"/>
namespace ts {
+8 -6
View File
@@ -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
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/// <reference path="checker.ts" />
/// <reference path="checker.ts" />
/// <reference path="factory.ts" />
/// <reference path="utilities.ts" />
+1 -1
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/// <reference path="..\harness.ts" />
/// <reference path="..\harness.ts" />
/// <reference path="..\..\compiler\commandLineParser.ts" />
namespace ts {
+3
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/// <reference path="../harness.ts" />
/// <reference path="../harness.ts" />
/// <reference path="./tsserverProjectSystem.ts" />
/// <reference path="../../server/typingsInstaller/typingsInstaller.ts" />
+8 -3
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/* @internal */
/* @internal */
namespace ts {
export interface CodeFix {
errorCodes: number[];
+1 -1
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/* @internal */
/* @internal */
namespace ts.GoToDefinition {
export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile, position: number): DefinitionInfo[] {
/// Triple slash reference comments
+1 -1
View File
@@ -1,4 +1,4 @@
/* @internal */
/* @internal */
namespace ts.JsDoc {
const jsDocTagNames = [
"augments",
+1 -1
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/* @internal */
/* @internal */
namespace ts.NavigateTo {
type RawNavigateToItem = { name: string; fileName: string; matchKind: PatternMatchKind; isCaseSensitive: boolean; declaration: Declaration };
+538
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
/// <reference path="..\compiler\program.ts"/>
/// <reference path="..\compiler\program.ts"/>
/// <reference path="..\compiler\commandLineParser.ts"/>
/// <reference path='types.ts' />
+1 -1
View File
@@ -1,4 +1,4 @@
namespace ts {
namespace ts {
export interface TranspileOptions {
compilerOptions?: CompilerOptions;
fileName?: string;
+1
View File
@@ -53,6 +53,7 @@
"navigateTo.ts",
"navigationBar.ts",
"outliningElementsCollector.ts",
"pathCompletions.ts",
"patternMatcher.ts",
"preProcess.ts",
"rename.ts",
+1 -1
View File
@@ -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;
@@ -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
+20 -20
View File
@@ -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
>{} : {}
>{} : {}
+20 -20
View File
@@ -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;
+37 -29
View File
@@ -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