mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into es2017-target
This commit is contained in:
+3
-3
@@ -725,16 +725,16 @@ declare module "convert-source-map" {
|
||||
}
|
||||
|
||||
gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => {
|
||||
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "built/local/bundle.js" }, /*useBuiltCompiler*/ true));
|
||||
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "../../built/local/bundle.js" }, /*useBuiltCompiler*/ true));
|
||||
return testProject.src()
|
||||
.pipe(newer("built/local/bundle.js"))
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(testProject)
|
||||
.pipe(testProject())
|
||||
.pipe(through2.obj((file, enc, next) => {
|
||||
const originalMap = file.sourceMap;
|
||||
const prebundledContent = file.contents.toString();
|
||||
// Make paths absolute to help sorcery deal with all the terrible paths being thrown around
|
||||
originalMap.sources = originalMap.sources.map(s => path.resolve("src", s));
|
||||
originalMap.sources = originalMap.sources.map(s => path.resolve(s));
|
||||
// intoStream (below) makes browserify think the input file is named this, so this is what it puts in the sourcemap
|
||||
originalMap.file = "built/local/_stream_0.js";
|
||||
|
||||
|
||||
+41
-7
@@ -176,7 +176,7 @@ var serverCoreSources = [
|
||||
"lsHost.ts",
|
||||
"project.ts",
|
||||
"editorServices.ts",
|
||||
"protocol.d.ts",
|
||||
"protocol.ts",
|
||||
"session.ts",
|
||||
"server.ts"
|
||||
].map(function (f) {
|
||||
@@ -200,14 +200,13 @@ var typingsInstallerSources = [
|
||||
var serverSources = serverCoreSources.concat(servicesSources);
|
||||
|
||||
var languageServiceLibrarySources = [
|
||||
"protocol.d.ts",
|
||||
"protocol.ts",
|
||||
"utilities.ts",
|
||||
"scriptVersionCache.ts",
|
||||
"scriptInfo.ts",
|
||||
"lsHost.ts",
|
||||
"project.ts",
|
||||
"editorServices.ts",
|
||||
"protocol.d.ts",
|
||||
"session.ts",
|
||||
|
||||
].map(function (f) {
|
||||
@@ -261,7 +260,7 @@ var harnessSources = harnessCoreSources.concat([
|
||||
].map(function (f) {
|
||||
return path.join(unittestsDirectory, f);
|
||||
})).concat([
|
||||
"protocol.d.ts",
|
||||
"protocol.ts",
|
||||
"utilities.ts",
|
||||
"scriptVersionCache.ts",
|
||||
"scriptInfo.ts",
|
||||
@@ -269,7 +268,6 @@ var harnessSources = harnessCoreSources.concat([
|
||||
"project.ts",
|
||||
"typingsCache.ts",
|
||||
"editorServices.ts",
|
||||
"protocol.d.ts",
|
||||
"session.ts",
|
||||
].map(function (f) {
|
||||
return path.join(serverDirectory, f);
|
||||
@@ -520,6 +518,40 @@ compileFile(processDiagnosticMessagesJs,
|
||||
[],
|
||||
/*useBuiltCompiler*/ false);
|
||||
|
||||
var buildProtocolTs = path.join(scriptsDirectory, "buildProtocol.ts");
|
||||
var buildProtocolJs = path.join(scriptsDirectory, "buildProtocol.js");
|
||||
var buildProtocolDts = path.join(builtLocalDirectory, "protocol.d.ts");
|
||||
var typescriptServicesDts = path.join(builtLocalDirectory, "typescriptServices.d.ts");
|
||||
|
||||
file(buildProtocolTs);
|
||||
|
||||
compileFile(buildProtocolJs,
|
||||
[buildProtocolTs],
|
||||
[buildProtocolTs],
|
||||
[],
|
||||
/*useBuiltCompiler*/ false,
|
||||
{noOutFile: true});
|
||||
|
||||
file(buildProtocolDts, [buildProtocolTs, buildProtocolJs, typescriptServicesDts], function() {
|
||||
|
||||
var protocolTs = path.join(serverDirectory, "protocol.ts");
|
||||
|
||||
var cmd = host + " " + buildProtocolJs + " "+ protocolTs + " " + typescriptServicesDts + " " + buildProtocolDts;
|
||||
console.log(cmd);
|
||||
var ex = jake.createExec([cmd]);
|
||||
// Add listeners for output and error
|
||||
ex.addListener("stdout", function (output) {
|
||||
process.stdout.write(output);
|
||||
});
|
||||
ex.addListener("stderr", function (error) {
|
||||
process.stderr.write(error);
|
||||
});
|
||||
ex.addListener("cmdEnd", function () {
|
||||
complete();
|
||||
});
|
||||
ex.run();
|
||||
}, { async: true })
|
||||
|
||||
// The generated diagnostics map; built for the compiler and for the 'generate-diagnostics' task
|
||||
file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], function () {
|
||||
var cmd = host + " " + processDiagnosticMessagesJs + " " + diagnosticMessagesJson;
|
||||
@@ -657,6 +689,8 @@ compileFile(
|
||||
inlineSourceMap: true
|
||||
});
|
||||
|
||||
file(typescriptServicesDts, [servicesFile]);
|
||||
|
||||
var cancellationTokenFile = path.join(builtLocalDirectory, "cancellationToken.js");
|
||||
compileFile(cancellationTokenFile, cancellationTokenSources, [builtLocalDirectory].concat(cancellationTokenSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { outDir: builtLocalDirectory, noOutFile: true });
|
||||
|
||||
@@ -691,7 +725,7 @@ task("build-fold-end", [], function () {
|
||||
|
||||
// Local target to build the compiler and services
|
||||
desc("Builds the full compiler and services");
|
||||
task("local", ["build-fold-start", "generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile, builtGeneratedDiagnosticMessagesJSON, "lssl", "build-fold-end"]);
|
||||
task("local", ["build-fold-start", "generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile, buildProtocolDts, builtGeneratedDiagnosticMessagesJSON, "lssl", "build-fold-end"]);
|
||||
|
||||
// Local target to build only tsc.js
|
||||
desc("Builds only the compiler");
|
||||
@@ -747,7 +781,7 @@ task("generate-spec", [specMd]);
|
||||
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
|
||||
desc("Makes a new LKG out of the built js files");
|
||||
task("LKG", ["clean", "release", "local"].concat(libraryTargets), function () {
|
||||
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile].concat(libraryTargets);
|
||||
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile, buildProtocolDts].concat(libraryTargets);
|
||||
var missingFiles = expectedFiles.filter(function (f) {
|
||||
return !fs.existsSync(f);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/// <reference types="node"/>
|
||||
|
||||
import * as ts from "../lib/typescript";
|
||||
import * as path from "path";
|
||||
|
||||
function endsWith(s: string, suffix: string) {
|
||||
return s.lastIndexOf(suffix, s.length - suffix.length) !== -1;
|
||||
}
|
||||
|
||||
class DeclarationsWalker {
|
||||
private visitedTypes: ts.Type[] = [];
|
||||
private text = "";
|
||||
private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) {
|
||||
}
|
||||
|
||||
static getExtraDeclarations(typeChecker: ts.TypeChecker, protocolFile: ts.SourceFile): string {
|
||||
let text = "declare namespace ts.server.protocol {\n";
|
||||
var walker = new DeclarationsWalker(typeChecker, protocolFile);
|
||||
walker.visitTypeNodes(protocolFile);
|
||||
return walker.text
|
||||
? `declare namespace ts.server.protocol {\n${walker.text}}`
|
||||
: "";
|
||||
}
|
||||
|
||||
private processType(type: ts.Type): void {
|
||||
if (this.visitedTypes.indexOf(type) >= 0) {
|
||||
return;
|
||||
}
|
||||
this.visitedTypes.push(type);
|
||||
let s = type.aliasSymbol || type.getSymbol();
|
||||
if (!s) {
|
||||
return;
|
||||
}
|
||||
if (s.name === "Array") {
|
||||
// we should process type argument instead
|
||||
return this.processType((<any>type).typeArguments[0]);
|
||||
}
|
||||
else {
|
||||
for (const decl of s.getDeclarations()) {
|
||||
const sourceFile = decl.getSourceFile();
|
||||
if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
|
||||
return;
|
||||
}
|
||||
// splice declaration in final d.ts file
|
||||
const text = decl.getFullText();
|
||||
this.text += `${text}\n`;
|
||||
|
||||
// recursively pull all dependencies into result dts file
|
||||
this.visitTypeNodes(decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private visitTypeNodes(node: ts.Node) {
|
||||
if (node.parent) {
|
||||
switch (node.parent.kind) {
|
||||
case ts.SyntaxKind.VariableDeclaration:
|
||||
case ts.SyntaxKind.MethodDeclaration:
|
||||
case ts.SyntaxKind.MethodSignature:
|
||||
case ts.SyntaxKind.PropertyDeclaration:
|
||||
case ts.SyntaxKind.PropertySignature:
|
||||
case ts.SyntaxKind.Parameter:
|
||||
case ts.SyntaxKind.IndexSignature:
|
||||
if (((<ts.VariableDeclaration | ts.MethodDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration | ts.PropertySignature | ts.MethodSignature | ts.IndexSignatureDeclaration>node.parent).type) === node) {
|
||||
const type = this.typeChecker.getTypeAtLocation(node);
|
||||
if (type && !(type.flags & ts.TypeFlags.TypeParameter)) {
|
||||
this.processType(type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
ts.forEachChild(node, n => this.visitTypeNodes(n));
|
||||
}
|
||||
}
|
||||
|
||||
function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string): string {
|
||||
const options = { target: ts.ScriptTarget.ES5, declaration: true, noResolve: true, types: <string[]>[], stripInternal: true };
|
||||
|
||||
/**
|
||||
* 1st pass - generate a program from protocol.ts and typescriptservices.d.ts and emit core version of protocol.d.ts with all internal members stripped
|
||||
* @return text of protocol.d.t.s
|
||||
*/
|
||||
function getInitialDtsFileForProtocol() {
|
||||
const program = ts.createProgram([protocolTs, typeScriptServicesDts], options);
|
||||
|
||||
let protocolDts: string;
|
||||
program.emit(program.getSourceFile(protocolTs), (file, content) => {
|
||||
if (endsWith(file, ".d.ts")) {
|
||||
protocolDts = content;
|
||||
}
|
||||
});
|
||||
if (protocolDts === undefined) {
|
||||
throw new Error(`Declaration file for protocol.ts is not generated`)
|
||||
}
|
||||
return protocolDts;
|
||||
}
|
||||
|
||||
const protocolFileName = "protocol.d.ts";
|
||||
/**
|
||||
* Second pass - generate a program from protocol.d.ts and typescriptservices.d.ts, then augment core protocol.d.ts with extra types from typescriptservices.d.ts
|
||||
*/
|
||||
function getProgramWithProtocolText(protocolDts: string, includeTypeScriptServices: boolean) {
|
||||
const host = ts.createCompilerHost(options);
|
||||
const originalGetSourceFile = host.getSourceFile;
|
||||
host.getSourceFile = (fileName) => {
|
||||
if (fileName === protocolFileName) {
|
||||
return ts.createSourceFile(fileName, protocolDts, options.target);
|
||||
}
|
||||
return originalGetSourceFile.apply(host, [fileName]);
|
||||
}
|
||||
const rootFiles = includeTypeScriptServices ? [protocolFileName, typeScriptServicesDts] : [protocolFileName];
|
||||
return ts.createProgram(rootFiles, options, host);
|
||||
}
|
||||
|
||||
let protocolDts = getInitialDtsFileForProtocol();
|
||||
const program = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ true);
|
||||
|
||||
const protocolFile = program.getSourceFile("protocol.d.ts");
|
||||
const extraDeclarations = DeclarationsWalker.getExtraDeclarations(program.getTypeChecker(), protocolFile);
|
||||
if (extraDeclarations) {
|
||||
protocolDts += extraDeclarations;
|
||||
}
|
||||
// do sanity check and try to compile generated text as standalone program
|
||||
const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false);
|
||||
const diagnostics = [...program.getSyntacticDiagnostics(), ...program.getSemanticDiagnostics(), ...program.getGlobalDiagnostics()];
|
||||
if (diagnostics.length) {
|
||||
const flattenedDiagnostics = diagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, "\n")).join("\n");
|
||||
throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`);
|
||||
}
|
||||
return protocolDts;
|
||||
}
|
||||
|
||||
if (process.argv.length < 5) {
|
||||
console.log(`Expected 3 arguments: path to 'protocol.ts', path to 'typescriptservices.d.ts' and path to output file`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const protocolTs = process.argv[2];
|
||||
const typeScriptServicesDts = process.argv[3];
|
||||
const outputFile = process.argv[4];
|
||||
const generatedProtocolDts = generateProtocolFile(protocolTs, typeScriptServicesDts);
|
||||
ts.sys.writeFile(outputFile, generatedProtocolDts);
|
||||
@@ -126,7 +126,7 @@ class PreferConstWalker extends Lint.RuleWalker {
|
||||
visitModuleDeclaration(node: ts.ModuleDeclaration) {
|
||||
if (node.body.kind === ts.SyntaxKind.ModuleBlock) {
|
||||
// For some reason module blocks are left out of the visit block traversal
|
||||
this.visitBlock(node.body as ts.ModuleBlock);
|
||||
this.visitBlock(node.body as any as ts.Block);
|
||||
}
|
||||
super.visitModuleDeclaration(node);
|
||||
}
|
||||
|
||||
@@ -18,8 +18,13 @@ class TypeOperatorSpacingWalker extends Lint.RuleWalker {
|
||||
for (let i = 1; i < types.length; i++) {
|
||||
const currentType = types[i];
|
||||
if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
|
||||
const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
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);
|
||||
}
|
||||
}
|
||||
expectedStart = currentType.end + 2;
|
||||
}
|
||||
|
||||
+26
-11
@@ -355,11 +355,24 @@ namespace ts {
|
||||
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
|
||||
: Diagnostics.Duplicate_identifier_0;
|
||||
|
||||
forEach(symbol.declarations, declaration => {
|
||||
if (hasModifier(declaration, ModifierFlags.Default)) {
|
||||
if (symbol.declarations && symbol.declarations.length) {
|
||||
// If the current node is a default export of some sort, then check if
|
||||
// there are any other default exports that we need to error on.
|
||||
// We'll know whether we have other default exports depending on if `symbol` already has a declaration list set.
|
||||
if (isDefaultExport) {
|
||||
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
|
||||
}
|
||||
});
|
||||
else {
|
||||
// This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration.
|
||||
// Error on multiple export default in the following case:
|
||||
// 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default
|
||||
// 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers)
|
||||
if (symbol.declarations && symbol.declarations.length &&
|
||||
(isDefaultExport || (node.kind === SyntaxKind.ExportAssignment && !(<ExportAssignment>node).isExportEquals))) {
|
||||
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forEach(symbol.declarations, declaration => {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
|
||||
@@ -1111,7 +1124,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
forEachChild(node, bind);
|
||||
if (node.operator === SyntaxKind.PlusEqualsToken || node.operator === SyntaxKind.MinusMinusToken) {
|
||||
if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) {
|
||||
bindAssignmentTargetFlow(node.operand);
|
||||
}
|
||||
}
|
||||
@@ -1360,7 +1373,7 @@ namespace ts {
|
||||
function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean {
|
||||
const body = node.kind === SyntaxKind.SourceFile ? node : (<ModuleDeclaration>node).body;
|
||||
if (body && (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock)) {
|
||||
for (const stat of (<Block>body).statements) {
|
||||
for (const stat of (<BlockLike>body).statements) {
|
||||
if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) {
|
||||
return true;
|
||||
}
|
||||
@@ -1944,12 +1957,15 @@ namespace ts {
|
||||
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
|
||||
}
|
||||
else {
|
||||
// An export default clause with an expression exports a value
|
||||
// We want to exclude both class and function here, this is necessary to issue an error when there are both
|
||||
// default export-assignment and default export function and class declaration.
|
||||
const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node)
|
||||
// An export default clause with an EntityNameExpression exports all meanings of that identifier
|
||||
? SymbolFlags.Alias
|
||||
// An export default clause with any other expression exports a value
|
||||
: SymbolFlags.Property;
|
||||
declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
|
||||
declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.Property | SymbolFlags.AliasExcludes | SymbolFlags.Class | SymbolFlags.Function);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2207,9 +2223,9 @@ namespace ts {
|
||||
if (currentFlow) {
|
||||
node.flowNode = currentFlow;
|
||||
}
|
||||
checkStrictModeFunctionName(<FunctionExpression>node);
|
||||
const bindingName = (<FunctionExpression>node).name ? (<FunctionExpression>node).name.text : "__function";
|
||||
return bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, bindingName);
|
||||
checkStrictModeFunctionName(node);
|
||||
const bindingName = node.name ? node.name.text : "__function";
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName);
|
||||
}
|
||||
|
||||
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
@@ -2432,8 +2448,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// If the parameter's name is 'this', then it is TypeScript syntax.
|
||||
if (subtreeFlags & TransformFlags.ContainsDecorators
|
||||
|| (name && isIdentifier(name) && name.originalKeywordKind === SyntaxKind.ThisKeyword)) {
|
||||
if (subtreeFlags & TransformFlags.ContainsDecorators || isThisIdentifier(name)) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
|
||||
+93
-56
@@ -120,6 +120,7 @@ namespace ts {
|
||||
const resolvingSymbol = createSymbol(SymbolFlags.Transient, "__resolving__");
|
||||
|
||||
const anyType = createIntrinsicType(TypeFlags.Any, "any");
|
||||
const autoType = createIntrinsicType(TypeFlags.Any, "any");
|
||||
const unknownType = createIntrinsicType(TypeFlags.Any, "unknown");
|
||||
const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined");
|
||||
const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsWideningType, "undefined");
|
||||
@@ -921,7 +922,7 @@ namespace ts {
|
||||
if (result && isInExternalModule && (meaning & SymbolFlags.Value) === SymbolFlags.Value) {
|
||||
const decls = result.declarations;
|
||||
if (decls && decls.length === 1 && decls[0].kind === SyntaxKind.NamespaceExportDeclaration) {
|
||||
error(errorLocation, Diagnostics.Identifier_0_must_be_imported_from_a_module, name);
|
||||
error(errorLocation, Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1464,6 +1465,10 @@ namespace ts {
|
||||
|
||||
function getExportsForModule(moduleSymbol: Symbol): SymbolTable {
|
||||
const visitedSymbols: Symbol[] = [];
|
||||
|
||||
// A module defined by an 'export=' consists on one export that needs to be resolved
|
||||
moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
|
||||
|
||||
return visit(moduleSymbol) || moduleSymbol.exports;
|
||||
|
||||
// The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example,
|
||||
@@ -2183,9 +2188,14 @@ namespace ts {
|
||||
// The specified symbol flags need to be reinterpreted as type flags
|
||||
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
|
||||
}
|
||||
else if (!(flags & TypeFormatFlags.InTypeAlias) && type.flags & (TypeFlags.Anonymous | TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
|
||||
else if (!(flags & TypeFormatFlags.InTypeAlias) && ((type.flags & TypeFlags.Anonymous && !(<AnonymousType>type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
|
||||
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
|
||||
// Only write out inferred type with its corresponding type-alias if type-alias is visible
|
||||
// We emit inferred type as type-alias at the current localtion if all the following is true
|
||||
// the input type is has alias symbol that is accessible
|
||||
// the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
|
||||
// e.g.: export type Bar<X, Y> = () => [X, Y];
|
||||
// export type Foo<Y> = Bar<any, Y>;
|
||||
// export const y = (x: Foo<string>) => 1 // we want to emit as ...x: () => [any, string])
|
||||
const typeArguments = type.aliasTypeArguments;
|
||||
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
|
||||
}
|
||||
@@ -3051,6 +3061,11 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isAutoVariableInitializer(initializer: Expression) {
|
||||
const expr = initializer && skipParentheses(initializer);
|
||||
return !expr || expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(<Identifier>expr) === undefinedSymbol;
|
||||
}
|
||||
|
||||
function addOptionality(type: Type, optional: boolean): Type {
|
||||
return strictNullChecks && optional ? includeFalsyTypes(type, TypeFlags.Undefined) : type;
|
||||
}
|
||||
@@ -3089,6 +3104,14 @@ namespace ts {
|
||||
return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality);
|
||||
}
|
||||
|
||||
// Use control flow type inference for non-ambient, non-exported var or let variables with no initializer
|
||||
// or a 'null' or 'undefined' initializer.
|
||||
if (declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) &&
|
||||
!(getCombinedNodeFlags(declaration) & NodeFlags.Const) && !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) &&
|
||||
!isInAmbientContext(declaration) && isAutoVariableInitializer(declaration.initializer)) {
|
||||
return autoType;
|
||||
}
|
||||
|
||||
if (declaration.kind === SyntaxKind.Parameter) {
|
||||
const func = <FunctionLikeDeclaration>declaration.parent;
|
||||
// For a parameter of a set accessor, use the type of the get accessor if one is present
|
||||
@@ -3887,7 +3910,7 @@ namespace ts {
|
||||
if (!links.declaredType) {
|
||||
const enumType = <EnumType>getDeclaredTypeOfEnum(getParentOfSymbol(symbol));
|
||||
links.declaredType = enumType.flags & TypeFlags.Union ?
|
||||
enumType.memberTypes[getEnumMemberValue(<EnumDeclaration>symbol.valueDeclaration)] :
|
||||
enumType.memberTypes[getEnumMemberValue(<EnumMember>symbol.valueDeclaration)] :
|
||||
enumType;
|
||||
}
|
||||
return links.declaredType;
|
||||
@@ -6070,7 +6093,7 @@ namespace ts {
|
||||
return !node.typeParameters && areAllParametersUntyped && !isNullaryArrow;
|
||||
}
|
||||
|
||||
function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | MethodDeclaration {
|
||||
function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration {
|
||||
return (isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func);
|
||||
}
|
||||
|
||||
@@ -8455,7 +8478,9 @@ namespace ts {
|
||||
if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) {
|
||||
return declaredType;
|
||||
}
|
||||
const initialType = assumeInitialized ? declaredType : includeFalsyTypes(declaredType, TypeFlags.Undefined);
|
||||
const initialType = assumeInitialized ? declaredType :
|
||||
declaredType === autoType ? undefinedType :
|
||||
includeFalsyTypes(declaredType, TypeFlags.Undefined);
|
||||
const visitedFlowStart = visitedFlowCount;
|
||||
const result = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
|
||||
visitedFlowCount = visitedFlowStart;
|
||||
@@ -8529,9 +8554,12 @@ namespace ts {
|
||||
// Assignments only narrow the computed type if the declared type is a union type. Thus, we
|
||||
// only need to evaluate the assigned type if the declared type is a union type.
|
||||
if (isMatchingReference(reference, node)) {
|
||||
const isIncrementOrDecrement = node.parent.kind === SyntaxKind.PrefixUnaryExpression || node.parent.kind === SyntaxKind.PostfixUnaryExpression;
|
||||
return declaredType.flags & TypeFlags.Union && !isIncrementOrDecrement ?
|
||||
getAssignmentReducedType(<UnionType>declaredType, getInitialOrAssignedType(node)) :
|
||||
if (node.parent.kind === SyntaxKind.PrefixUnaryExpression || node.parent.kind === SyntaxKind.PostfixUnaryExpression) {
|
||||
const flowType = getTypeAtFlowNode(flow.antecedent);
|
||||
return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
|
||||
}
|
||||
return declaredType === autoType ? getBaseTypeOfLiteralType(getInitialOrAssignedType(node)) :
|
||||
declaredType.flags & TypeFlags.Union ? getAssignmentReducedType(<UnionType>declaredType, getInitialOrAssignedType(node)) :
|
||||
declaredType;
|
||||
}
|
||||
// We didn't have a direct match. However, if the reference is a dotted name, this
|
||||
@@ -8975,7 +9003,7 @@ namespace ts {
|
||||
if (isRightSideOfQualifiedNameOrPropertyAccess(location)) {
|
||||
location = location.parent;
|
||||
}
|
||||
if (isExpression(location) && !isAssignmentTarget(location)) {
|
||||
if (isPartOfExpression(location) && !isAssignmentTarget(location)) {
|
||||
const type = checkExpression(<Expression>location);
|
||||
if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
|
||||
return type;
|
||||
@@ -9146,13 +9174,23 @@ namespace ts {
|
||||
// We only look for uninitialized variables in strict null checking mode, and only when we can analyze
|
||||
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
|
||||
// declaration container are the same).
|
||||
const assumeInitialized = !strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isParameter ||
|
||||
isOuterVariable || isInAmbientContext(declaration);
|
||||
const assumeInitialized = isParameter || isOuterVariable ||
|
||||
type !== autoType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0) ||
|
||||
isInAmbientContext(declaration);
|
||||
const flowType = getFlowTypeOfReference(node, type, assumeInitialized, flowContainer);
|
||||
// A variable is considered uninitialized when it is possible to analyze the entire control flow graph
|
||||
// from declaration to use, and when the variable's declared type doesn't include undefined but the
|
||||
// control flow based type does include undefined.
|
||||
if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
|
||||
if (type === autoType) {
|
||||
if (flowType === autoType) {
|
||||
if (compilerOptions.noImplicitAny) {
|
||||
error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_any_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol));
|
||||
error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(anyType));
|
||||
}
|
||||
return anyType;
|
||||
}
|
||||
}
|
||||
else if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
|
||||
error(node, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol));
|
||||
// Return the declared type to reduce follow-on errors
|
||||
return type;
|
||||
@@ -9266,7 +9304,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function findFirstSuperCall(n: Node): Node {
|
||||
if (isSuperCallExpression(n)) {
|
||||
if (isSuperCall(n)) {
|
||||
return n;
|
||||
}
|
||||
else if (isFunctionLike(n)) {
|
||||
@@ -9373,7 +9411,7 @@ namespace ts {
|
||||
captureLexicalThis(node, container);
|
||||
}
|
||||
if (isFunctionLike(container) &&
|
||||
(!isInParameterInitializerBeforeContainingFunction(node) || getFunctionLikeThisParameter(container))) {
|
||||
(!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) {
|
||||
// Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
|
||||
|
||||
// If this is a function in a JS file, it might be a class method. Check if it's the RHS
|
||||
@@ -9775,7 +9813,7 @@ namespace ts {
|
||||
// corresponding set accessor has a type annotation, return statements in the function are contextually typed
|
||||
if (functionDecl.type ||
|
||||
functionDecl.kind === SyntaxKind.Constructor ||
|
||||
functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(<AccessorDeclaration>getDeclarationOfKind(functionDecl.symbol, SyntaxKind.SetAccessor))) {
|
||||
functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(<SetAccessorDeclaration>getDeclarationOfKind(functionDecl.symbol, SyntaxKind.SetAccessor))) {
|
||||
return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
|
||||
}
|
||||
|
||||
@@ -10044,7 +10082,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression {
|
||||
function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction {
|
||||
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction;
|
||||
}
|
||||
|
||||
@@ -10055,7 +10093,7 @@ namespace ts {
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function getContextualTypeForFunctionLikeDeclaration(node: FunctionExpression | MethodDeclaration) {
|
||||
function getContextualTypeForFunctionLikeDeclaration(node: FunctionExpression | ArrowFunction | MethodDeclaration) {
|
||||
return isObjectLiteralMethod(node) ?
|
||||
getContextualTypeForObjectLiteralMethod(node) :
|
||||
getApparentTypeOfContextualType(node);
|
||||
@@ -10066,7 +10104,7 @@ namespace ts {
|
||||
// If the contextual type is a union type, get the signature from each type possible and if they are
|
||||
// all identical ignoring their return type, the result is same signature but with return type as
|
||||
// union type of return types from these signatures
|
||||
function getContextualSignature(node: FunctionExpression | MethodDeclaration): Signature {
|
||||
function getContextualSignature(node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature {
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
|
||||
const type = getContextualTypeForFunctionLikeDeclaration(node);
|
||||
if (!type) {
|
||||
@@ -11418,7 +11456,7 @@ namespace ts {
|
||||
argCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature);
|
||||
}
|
||||
else {
|
||||
const callExpression = <CallExpression>node;
|
||||
const callExpression = <CallExpression | NewExpression>node;
|
||||
if (!callExpression.arguments) {
|
||||
// This only happens when we have something of the form: 'new C'
|
||||
Debug.assert(callExpression.kind === SyntaxKind.NewExpression);
|
||||
@@ -11429,7 +11467,7 @@ namespace ts {
|
||||
argCount = signatureHelpTrailingComma ? args.length + 1 : args.length;
|
||||
|
||||
// If we are missing the close paren, the call is incomplete.
|
||||
callIsIncomplete = (<CallExpression>callExpression).arguments.end === callExpression.end;
|
||||
callIsIncomplete = callExpression.arguments.end === callExpression.end;
|
||||
|
||||
typeArguments = callExpression.typeArguments;
|
||||
spreadArgIndex = getSpreadArgumentIndex(args);
|
||||
@@ -12516,7 +12554,7 @@ namespace ts {
|
||||
* @param node The call/new expression to be checked.
|
||||
* @returns On success, the expression's signature's return type. On failure, anyType.
|
||||
*/
|
||||
function checkCallExpression(node: CallExpression): Type {
|
||||
function checkCallExpression(node: CallExpression | NewExpression): Type {
|
||||
// Grammar checking; stop grammar-checking if checkGrammarTypeArguments return true
|
||||
checkGrammarTypeArguments(node, node.typeArguments) || checkGrammarArguments(node, node.arguments);
|
||||
|
||||
@@ -12766,7 +12804,10 @@ namespace ts {
|
||||
if (!contextualSignature) {
|
||||
reportErrorsFromWidening(func, type);
|
||||
}
|
||||
if (isUnitType(type) && !(contextualSignature && isLiteralContextualType(getReturnTypeOfSignature(contextualSignature)))) {
|
||||
if (isUnitType(type) &&
|
||||
!(contextualSignature &&
|
||||
isLiteralContextualType(
|
||||
contextualSignature === getSignatureFromDeclaration(func) ? type : getReturnTypeOfSignature(contextualSignature)))) {
|
||||
type = getWidenedLiteralType(type);
|
||||
}
|
||||
|
||||
@@ -12971,7 +13012,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (produceDiagnostics && node.kind !== SyntaxKind.MethodDeclaration && node.kind !== SyntaxKind.MethodSignature) {
|
||||
if (produceDiagnostics && node.kind !== SyntaxKind.MethodDeclaration) {
|
||||
checkCollisionWithCapturedSuperVariable(node, (<FunctionExpression>node).name);
|
||||
checkCollisionWithCapturedThisVariable(node, (<FunctionExpression>node).name);
|
||||
}
|
||||
@@ -14433,7 +14474,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function containsSuperCall(n: Node): boolean {
|
||||
if (isSuperCallExpression(n)) {
|
||||
if (isSuperCall(n)) {
|
||||
return true;
|
||||
}
|
||||
else if (isFunctionLike(n)) {
|
||||
@@ -14489,7 +14530,7 @@ namespace ts {
|
||||
let superCallStatement: ExpressionStatement;
|
||||
|
||||
for (const statement of statements) {
|
||||
if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((<ExpressionStatement>statement).expression)) {
|
||||
if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((<ExpressionStatement>statement).expression)) {
|
||||
superCallStatement = <ExpressionStatement>statement;
|
||||
break;
|
||||
}
|
||||
@@ -15557,10 +15598,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function parameterIsThisKeyword(parameter: ParameterDeclaration) {
|
||||
return parameter.name && (<Identifier>parameter.name).originalKeywordKind === SyntaxKind.ThisKeyword;
|
||||
}
|
||||
|
||||
function parameterNameStartsWithUnderscore(parameter: ParameterDeclaration) {
|
||||
return parameter.name && parameter.name.kind === SyntaxKind.Identifier && (<Identifier>parameter.name).text.charCodeAt(0) === CharacterCodes._;
|
||||
}
|
||||
@@ -15902,6 +15939,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function convertAutoToAny(type: Type) {
|
||||
return type === autoType ? anyType : type;
|
||||
}
|
||||
|
||||
// Check variable, parameter, or property declaration
|
||||
function checkVariableLikeDeclaration(node: VariableLikeDeclaration) {
|
||||
checkDecorators(node);
|
||||
@@ -15952,7 +15993,7 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
const symbol = getSymbolOfNode(node);
|
||||
const type = getTypeOfVariableOrParameterOrProperty(symbol);
|
||||
const type = convertAutoToAny(getTypeOfVariableOrParameterOrProperty(symbol));
|
||||
if (node === symbol.valueDeclaration) {
|
||||
// Node is the primary declaration of the symbol, just validate the initializer
|
||||
// Don't validate for-in initializer as it is already an error
|
||||
@@ -15964,7 +16005,7 @@ namespace ts {
|
||||
else {
|
||||
// Node is a secondary declaration, check that type is identical to primary declaration and check that
|
||||
// initializer is consistent with type associated with the node
|
||||
const declarationType = getWidenedTypeForVariableLikeDeclaration(node);
|
||||
const declarationType = convertAutoToAny(getWidenedTypeForVariableLikeDeclaration(node));
|
||||
if (type !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(type, declarationType)) {
|
||||
error(node.name, Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, declarationNameToString(node.name), typeToString(type), typeToString(declarationType));
|
||||
}
|
||||
@@ -16453,7 +16494,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isGetAccessorWithAnnotatedSetAccessor(node: FunctionLikeDeclaration) {
|
||||
return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(<AccessorDeclaration>getDeclarationOfKind(node.symbol, SyntaxKind.SetAccessor)));
|
||||
return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(<SetAccessorDeclaration>getDeclarationOfKind(node.symbol, SyntaxKind.SetAccessor)));
|
||||
}
|
||||
|
||||
function isUnwrappedReturnTypeVoidOrAny(func: FunctionLikeDeclaration, returnType: Type): boolean {
|
||||
@@ -17445,9 +17486,12 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
checkCollisionWithCapturedThisVariable(node, node.name);
|
||||
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
|
||||
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
|
||||
if (isIdentifier(node.name)) {
|
||||
checkCollisionWithCapturedThisVariable(node, node.name);
|
||||
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
|
||||
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
|
||||
}
|
||||
|
||||
checkExportsOnMergedDeclarations(node);
|
||||
const symbol = getSymbolOfNode(node);
|
||||
|
||||
@@ -17849,7 +17893,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isNotOverload(declaration: Declaration): boolean {
|
||||
return declaration.kind !== SyntaxKind.FunctionDeclaration || !!(declaration as FunctionDeclaration).body;
|
||||
return (declaration.kind !== SyntaxKind.FunctionDeclaration && declaration.kind !== SyntaxKind.MethodDeclaration) ||
|
||||
!!(declaration as FunctionDeclaration).body;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18455,6 +18500,9 @@ namespace ts {
|
||||
(<ImportDeclaration>node.parent).moduleSpecifier === node)) {
|
||||
return resolveExternalModuleName(node, <LiteralExpression>node);
|
||||
}
|
||||
if (isInJavaScriptFile(node) && isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) {
|
||||
return resolveExternalModuleName(node, <LiteralExpression>node);
|
||||
}
|
||||
// Fall through
|
||||
|
||||
case SyntaxKind.NumericLiteral:
|
||||
@@ -19066,7 +19114,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isLiteralConstDeclaration(node: VariableDeclaration): boolean {
|
||||
function isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean {
|
||||
if (isConst(node)) {
|
||||
const type = getTypeOfSymbol(getSymbolOfNode(node));
|
||||
return !!(type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral);
|
||||
@@ -19074,7 +19122,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function writeLiteralConstValue(node: VariableDeclaration, writer: SymbolWriter) {
|
||||
function writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: SymbolWriter) {
|
||||
const type = getTypeOfSymbol(getSymbolOfNode(node));
|
||||
writer.writeStringLiteral(literalTypeToString(<LiteralType>type));
|
||||
}
|
||||
@@ -19811,7 +19859,7 @@ namespace ts {
|
||||
checkGrammarForAtLeastOneTypeArgument(node, typeArguments);
|
||||
}
|
||||
|
||||
function checkGrammarForOmittedArgument(node: CallExpression, args: NodeArray<Expression>): boolean {
|
||||
function checkGrammarForOmittedArgument(node: CallExpression | NewExpression, args: NodeArray<Expression>): boolean {
|
||||
if (args) {
|
||||
const sourceFile = getSourceFileOfNode(node);
|
||||
for (const arg of args) {
|
||||
@@ -19822,7 +19870,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function checkGrammarArguments(node: CallExpression, args: NodeArray<Expression>): boolean {
|
||||
function checkGrammarArguments(node: CallExpression | NewExpression, args: NodeArray<Expression>): boolean {
|
||||
return checkGrammarForOmittedArgument(node, args);
|
||||
}
|
||||
|
||||
@@ -19944,8 +19992,7 @@ namespace ts {
|
||||
|
||||
for (const prop of node.properties) {
|
||||
const name = prop.name;
|
||||
if (prop.kind === SyntaxKind.OmittedExpression ||
|
||||
name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
// If the name is not a ComputedPropertyName, the grammar checking will skip it
|
||||
checkGrammarComputedPropertyName(<ComputedPropertyName>name);
|
||||
}
|
||||
@@ -19992,7 +20039,7 @@ namespace ts {
|
||||
currentKind = SetAccessor;
|
||||
}
|
||||
else {
|
||||
Debug.fail("Unexpected syntax kind:" + prop.kind);
|
||||
Debug.fail("Unexpected syntax kind:" + (<Node>prop).kind);
|
||||
}
|
||||
|
||||
const effectiveName = getPropertyNameForPropertyNameNode(name);
|
||||
@@ -20141,18 +20188,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getAccessorThisParameter(accessor: AccessorDeclaration): ParameterDeclaration {
|
||||
if (accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 1 : 2) &&
|
||||
accessor.parameters[0].name.kind === SyntaxKind.Identifier &&
|
||||
(<Identifier>accessor.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword) {
|
||||
return accessor.parameters[0];
|
||||
}
|
||||
}
|
||||
|
||||
function getFunctionLikeThisParameter(func: FunctionLikeDeclaration) {
|
||||
if (func.parameters.length &&
|
||||
func.parameters[0].name.kind === SyntaxKind.Identifier &&
|
||||
(<Identifier>func.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword) {
|
||||
return func.parameters[0];
|
||||
if (accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 1 : 2)) {
|
||||
return getThisParameter(accessor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -977,7 +977,7 @@ namespace ts {
|
||||
basePath: string, errors: Diagnostic[], configFileName?: string): CompilerOptions {
|
||||
|
||||
const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json"
|
||||
? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true }
|
||||
? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true }
|
||||
: {};
|
||||
convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors);
|
||||
return options;
|
||||
|
||||
+17
-5
@@ -1097,7 +1097,9 @@ namespace ts {
|
||||
return path.replace(/\\/g, "/");
|
||||
}
|
||||
|
||||
// Returns length of path root (i.e. length of "/", "x:/", "//server/share/, file:///user/files")
|
||||
/**
|
||||
* Returns length of path root (i.e. length of "/", "x:/", "//server/share/, file:///user/files")
|
||||
*/
|
||||
export function getRootLength(path: string): number {
|
||||
if (path.charCodeAt(0) === CharacterCodes.slash) {
|
||||
if (path.charCodeAt(1) !== CharacterCodes.slash) return 1;
|
||||
@@ -1126,9 +1128,14 @@ namespace ts {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internally, we represent paths as strings with '/' as the directory separator.
|
||||
* When we make system calls (eg: LanguageServiceHost.getDirectory()),
|
||||
* we expect the host to correctly handle paths in our specified format.
|
||||
*/
|
||||
export const directorySeparator = "/";
|
||||
const directorySeparatorCharCode = CharacterCodes.slash;
|
||||
function getNormalizedParts(normalizedSlashedPath: string, rootLength: number) {
|
||||
function getNormalizedParts(normalizedSlashedPath: string, rootLength: number): string[] {
|
||||
const parts = normalizedSlashedPath.substr(rootLength).split(directorySeparator);
|
||||
const normalized: string[] = [];
|
||||
for (const part of parts) {
|
||||
@@ -1168,6 +1175,11 @@ namespace ts {
|
||||
return path.charCodeAt(path.length - 1) === directorySeparatorCharCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path except for its basename. Eg:
|
||||
*
|
||||
* /path/to/file.ext -> /path/to
|
||||
*/
|
||||
export function getDirectoryPath(path: Path): Path;
|
||||
export function getDirectoryPath(path: string): string;
|
||||
export function getDirectoryPath(path: string): any {
|
||||
@@ -1813,9 +1825,9 @@ namespace ts {
|
||||
|
||||
export interface ObjectAllocator {
|
||||
getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node;
|
||||
getTokenConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token;
|
||||
getIdentifierConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token;
|
||||
getSourceFileConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => SourceFile;
|
||||
getTokenConstructor(): new <TKind extends SyntaxKind>(kind: TKind, pos?: number, end?: number) => Token<TKind>;
|
||||
getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos?: number, end?: number) => Identifier;
|
||||
getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile;
|
||||
getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol;
|
||||
getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
|
||||
getSignatureConstructor(): new (checker: TypeChecker) => Signature;
|
||||
|
||||
@@ -1121,7 +1121,7 @@ namespace ts {
|
||||
writeLine();
|
||||
}
|
||||
|
||||
function emitVariableDeclaration(node: VariableDeclaration) {
|
||||
function emitVariableDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration) {
|
||||
// If we are emitting property it isn't moduleElement and hence we already know it needs to be emitted
|
||||
// so there is no check needed to see if declaration is visible
|
||||
if (node.kind !== SyntaxKind.VariableDeclaration || resolver.isDeclarationVisible(node)) {
|
||||
@@ -1136,7 +1136,7 @@ namespace ts {
|
||||
// If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor
|
||||
// we don't want to emit property declaration with "?"
|
||||
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature ||
|
||||
(node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) {
|
||||
(node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(<ParameterDeclaration>node))) && hasQuestionToken(node)) {
|
||||
write("?");
|
||||
}
|
||||
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) {
|
||||
@@ -1626,8 +1626,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitBindingElement(bindingElement: BindingElement) {
|
||||
|
||||
function emitBindingElement(bindingElement: BindingElement | OmittedExpression) {
|
||||
if (bindingElement.kind === SyntaxKind.OmittedExpression) {
|
||||
// If bindingElement is an omittedExpression (i.e. containing elision),
|
||||
// we will emit blank space (although this may differ from users' original code,
|
||||
|
||||
@@ -1923,7 +1923,7 @@
|
||||
"category": "Error",
|
||||
"code": 2685
|
||||
},
|
||||
"Identifier '{0}' must be imported from a module": {
|
||||
"'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead.": {
|
||||
"category": "Error",
|
||||
"code": 2686
|
||||
},
|
||||
@@ -2957,6 +2957,10 @@
|
||||
"category": "Error",
|
||||
"code": 7033
|
||||
},
|
||||
"Variable '{0}' implicitly has type 'any' in some locations where its type cannot be determined.": {
|
||||
"category": "Error",
|
||||
"code": 7034
|
||||
},
|
||||
"You cannot rename this element.": {
|
||||
"category": "Error",
|
||||
"code": 8000
|
||||
@@ -3069,7 +3073,6 @@
|
||||
"category": "Error",
|
||||
"code": 17010
|
||||
},
|
||||
|
||||
"Circularity detected while resolving configuration: {0}": {
|
||||
"category": "Error",
|
||||
"code": 18000
|
||||
@@ -3077,5 +3080,33 @@
|
||||
"The path in an 'extends' options must be relative or rooted.": {
|
||||
"category": "Error",
|
||||
"code": 18001
|
||||
},
|
||||
"Add missing 'super()' call.": {
|
||||
"category": "Message",
|
||||
"code": 90001
|
||||
},
|
||||
"Make 'super()' call the first statement in the constructor.": {
|
||||
"category": "Message",
|
||||
"code": 90002
|
||||
},
|
||||
"Change 'extends' to 'implements'": {
|
||||
"category": "Message",
|
||||
"code": 90003
|
||||
},
|
||||
"Remove unused identifiers": {
|
||||
"category": "Message",
|
||||
"code": 90004
|
||||
},
|
||||
"Implement interface on reference": {
|
||||
"category": "Message",
|
||||
"code": 90005
|
||||
},
|
||||
"Implement interface on class": {
|
||||
"category": "Message",
|
||||
"code": 90006
|
||||
},
|
||||
"Implement inherited abstract class": {
|
||||
"category": "Message",
|
||||
"code": 90007
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
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 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());
|
||||
});
|
||||
@@ -655,7 +655,7 @@ const _super = (function (geti, seti) {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return emitModuleDeclaration(<ModuleDeclaration>node);
|
||||
case SyntaxKind.ModuleBlock:
|
||||
return emitModuleBlock(<Block>node);
|
||||
return emitModuleBlock(<ModuleBlock>node);
|
||||
case SyntaxKind.CaseBlock:
|
||||
return emitCaseBlock(<CaseBlock>node);
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
@@ -1394,7 +1394,7 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
}
|
||||
|
||||
function emitBlockStatements(node: Block) {
|
||||
function emitBlockStatements(node: BlockLike) {
|
||||
if (getEmitFlags(node) & EmitFlags.SingleLine) {
|
||||
emitList(node, node.statements, ListFormat.SingleLineBlockStatements);
|
||||
}
|
||||
@@ -1795,7 +1795,7 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
|
||||
function emitModuleBlock(node: ModuleBlock) {
|
||||
if (isSingleLineEmptyBlock(node)) {
|
||||
if (isEmptyBlock(node)) {
|
||||
write("{ }");
|
||||
}
|
||||
else {
|
||||
@@ -2618,7 +2618,11 @@ const _super = (function (geti, seti) {
|
||||
|
||||
function isSingleLineEmptyBlock(block: Block) {
|
||||
return !block.multiLine
|
||||
&& block.statements.length === 0
|
||||
&& isEmptyBlock(block);
|
||||
}
|
||||
|
||||
function isEmptyBlock(block: BlockLike) {
|
||||
return block.statements.length === 0
|
||||
&& rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile);
|
||||
}
|
||||
|
||||
|
||||
+28
-27
@@ -105,6 +105,7 @@ namespace ts {
|
||||
export function createLiteral(textSource: StringLiteral | Identifier, location?: TextRange): StringLiteral;
|
||||
export function createLiteral(value: string, location?: TextRange): StringLiteral;
|
||||
export function createLiteral(value: number, location?: TextRange): NumericLiteral;
|
||||
export function createLiteral(value: boolean, location?: TextRange): BooleanLiteral;
|
||||
export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression;
|
||||
export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression {
|
||||
if (typeof value === "number") {
|
||||
@@ -120,7 +121,7 @@ namespace ts {
|
||||
node.text = value;
|
||||
return node;
|
||||
}
|
||||
else {
|
||||
else if (value) {
|
||||
const node = <StringLiteral>createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined);
|
||||
node.textSourceNode = value;
|
||||
node.text = value.text;
|
||||
@@ -187,8 +188,8 @@ namespace ts {
|
||||
|
||||
// Punctuation
|
||||
|
||||
export function createToken(token: SyntaxKind) {
|
||||
return createNode(token);
|
||||
export function createToken<TKind extends SyntaxKind>(token: TKind) {
|
||||
return <Token<TKind>>createNode(token);
|
||||
}
|
||||
|
||||
// Reserved words
|
||||
@@ -238,7 +239,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: Node, name: string | Identifier | BindingPattern, questionToken: Node, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) {
|
||||
export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) {
|
||||
const node = <ParameterDeclaration>createNode(SyntaxKind.Parameter, location, flags);
|
||||
node.decorators = decorators ? createNodeArray(decorators) : undefined;
|
||||
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
|
||||
@@ -260,7 +261,7 @@ namespace ts {
|
||||
|
||||
// Type members
|
||||
|
||||
export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: Node, type: TypeNode, initializer: Expression, location?: TextRange) {
|
||||
export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange) {
|
||||
const node = <PropertyDeclaration>createNode(SyntaxKind.PropertyDeclaration, location);
|
||||
node.decorators = decorators ? createNodeArray(decorators) : undefined;
|
||||
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
|
||||
@@ -278,7 +279,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
const node = <MethodDeclaration>createNode(SyntaxKind.MethodDeclaration, location, flags);
|
||||
node.decorators = decorators ? createNodeArray(decorators) : undefined;
|
||||
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
|
||||
@@ -381,7 +382,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: Node, name: string | BindingName, initializer?: Expression, location?: TextRange) {
|
||||
export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: DotDotDotToken, name: string | BindingName, initializer?: Expression, location?: TextRange) {
|
||||
const node = <BindingElement>createNode(SyntaxKind.BindingElement, location);
|
||||
node.propertyName = typeof propertyName === "string" ? createIdentifier(propertyName) : propertyName;
|
||||
node.dotDotDotToken = dotDotDotToken;
|
||||
@@ -497,14 +498,14 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createTaggedTemplate(tag: Expression, template: Template, location?: TextRange) {
|
||||
export function createTaggedTemplate(tag: Expression, template: TemplateLiteral, location?: TextRange) {
|
||||
const node = <TaggedTemplateExpression>createNode(SyntaxKind.TaggedTemplateExpression, location);
|
||||
node.tag = parenthesizeForAccess(tag);
|
||||
node.template = template;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: Template) {
|
||||
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral) {
|
||||
if (node.tag !== tag || node.template !== template) {
|
||||
return updateNode(createTaggedTemplate(tag, template, node), node);
|
||||
}
|
||||
@@ -524,7 +525,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createFunctionExpression(modifiers: Modifier[], asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
export function createFunctionExpression(modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
const node = <FunctionExpression>createNode(SyntaxKind.FunctionExpression, location, flags);
|
||||
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
|
||||
node.asteriskToken = asteriskToken;
|
||||
@@ -543,13 +544,13 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: Node, body: ConciseBody, location?: TextRange, flags?: NodeFlags) {
|
||||
export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody, location?: TextRange, flags?: NodeFlags) {
|
||||
const node = <ArrowFunction>createNode(SyntaxKind.ArrowFunction, location, flags);
|
||||
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
|
||||
node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined;
|
||||
node.parameters = createNodeArray(parameters);
|
||||
node.type = type;
|
||||
node.equalsGreaterThanToken = equalsGreaterThanToken || createNode(SyntaxKind.EqualsGreaterThanToken);
|
||||
node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(SyntaxKind.EqualsGreaterThanToken);
|
||||
node.body = parenthesizeConciseBody(body);
|
||||
return node;
|
||||
}
|
||||
@@ -613,7 +614,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createPrefix(operator: SyntaxKind, operand: Expression, location?: TextRange) {
|
||||
export function createPrefix(operator: PrefixUnaryOperator, operand: Expression, location?: TextRange) {
|
||||
const node = <PrefixUnaryExpression>createNode(SyntaxKind.PrefixUnaryExpression, location);
|
||||
node.operator = operator;
|
||||
node.operand = parenthesizePrefixOperand(operand);
|
||||
@@ -627,7 +628,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createPostfix(operand: Expression, operator: SyntaxKind, location?: TextRange) {
|
||||
export function createPostfix(operand: Expression, operator: PostfixUnaryOperator, location?: TextRange) {
|
||||
const node = <PostfixUnaryExpression>createNode(SyntaxKind.PostfixUnaryExpression, location);
|
||||
node.operand = parenthesizePostfixOperand(operand);
|
||||
node.operator = operator;
|
||||
@@ -641,8 +642,8 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createBinary(left: Expression, operator: SyntaxKind | Node, right: Expression, location?: TextRange) {
|
||||
const operatorToken = typeof operator === "number" ? createSynthesizedNode(operator) : operator;
|
||||
export function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression, location?: TextRange) {
|
||||
const operatorToken = typeof operator === "number" ? createToken(operator) : operator;
|
||||
const operatorKind = operatorToken.kind;
|
||||
const node = <BinaryExpression>createNode(SyntaxKind.BinaryExpression, location);
|
||||
node.left = parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined);
|
||||
@@ -658,7 +659,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createConditional(condition: Expression, questionToken: Node, whenTrue: Expression, colonToken: Node, whenFalse: Expression, location?: TextRange) {
|
||||
export function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression, location?: TextRange) {
|
||||
const node = <ConditionalExpression>createNode(SyntaxKind.ConditionalExpression, location);
|
||||
node.condition = condition;
|
||||
node.questionToken = questionToken;
|
||||
@@ -675,21 +676,21 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createTemplateExpression(head: TemplateLiteralFragment, templateSpans: TemplateSpan[], location?: TextRange) {
|
||||
export function createTemplateExpression(head: TemplateHead, templateSpans: TemplateSpan[], location?: TextRange) {
|
||||
const node = <TemplateExpression>createNode(SyntaxKind.TemplateExpression, location);
|
||||
node.head = head;
|
||||
node.templateSpans = createNodeArray(templateSpans);
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateTemplateExpression(node: TemplateExpression, head: TemplateLiteralFragment, templateSpans: TemplateSpan[]) {
|
||||
export function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: TemplateSpan[]) {
|
||||
if (node.head !== head || node.templateSpans !== templateSpans) {
|
||||
return updateNode(createTemplateExpression(head, templateSpans, node), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createYield(asteriskToken: Node, expression: Expression, location?: TextRange) {
|
||||
export function createYield(asteriskToken: AsteriskToken, expression: Expression, location?: TextRange) {
|
||||
const node = <YieldExpression>createNode(SyntaxKind.YieldExpression, location);
|
||||
node.asteriskToken = asteriskToken;
|
||||
node.expression = expression;
|
||||
@@ -756,14 +757,14 @@ namespace ts {
|
||||
|
||||
// Misc
|
||||
|
||||
export function createTemplateSpan(expression: Expression, literal: TemplateLiteralFragment, location?: TextRange) {
|
||||
export function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail, location?: TextRange) {
|
||||
const node = <TemplateSpan>createNode(SyntaxKind.TemplateSpan, location);
|
||||
node.expression = expression;
|
||||
node.literal = literal;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateLiteralFragment) {
|
||||
export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) {
|
||||
if (node.expression !== expression || node.literal !== literal) {
|
||||
return updateNode(createTemplateSpan(expression, literal, node), node);
|
||||
}
|
||||
@@ -932,14 +933,14 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateForOf(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) {
|
||||
export function updateForOf(node: ForOfStatement, initializer: ForInitializer, expression: Expression, statement: Statement) {
|
||||
if (node.initializer !== initializer || node.expression !== expression || node.statement !== statement) {
|
||||
return updateNode(createForOf(initializer, expression, statement, node), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createContinue(label?: Identifier, location?: TextRange): BreakStatement {
|
||||
export function createContinue(label?: Identifier, location?: TextRange): ContinueStatement {
|
||||
const node = <ContinueStatement>createNode(SyntaxKind.ContinueStatement, location);
|
||||
if (label) {
|
||||
node.label = label;
|
||||
@@ -1065,7 +1066,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
|
||||
const node = <FunctionDeclaration>createNode(SyntaxKind.FunctionDeclaration, location, flags);
|
||||
node.decorators = decorators ? createNodeArray(decorators) : undefined;
|
||||
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
|
||||
@@ -1560,7 +1561,7 @@ namespace ts {
|
||||
return createParameterDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createSynthesizedNode(SyntaxKind.DotDotDotToken),
|
||||
createToken(SyntaxKind.DotDotDotToken),
|
||||
name,
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
@@ -1736,7 +1737,7 @@ namespace ts {
|
||||
export function createAwaiterHelper(externalHelpersModuleName: Identifier | undefined, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) {
|
||||
const generatorFunc = createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
createNode(SyntaxKind.AsteriskToken),
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ [],
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace ts {
|
||||
currentDirectory = host.getCurrentDirectory();
|
||||
}
|
||||
|
||||
return currentDirectory && getDefaultTypeRoots(currentDirectory, host);
|
||||
return currentDirectory !== undefined && getDefaultTypeRoots(currentDirectory, host);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -675,23 +675,33 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function loadModuleFromNodeModules(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean): string {
|
||||
return loadModuleFromNodeModulesWorker(moduleName, directory, failedLookupLocations, state, checkOneLevel, /*typesOnly*/ false);
|
||||
}
|
||||
|
||||
function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string {
|
||||
return loadModuleFromNodeModulesWorker(moduleName, directory, failedLookupLocations, state, /*checkOneLevel*/ false, /*typesOnly*/ true);
|
||||
}
|
||||
|
||||
function loadModuleFromNodeModulesWorker(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean, typesOnly: boolean): string {
|
||||
directory = normalizeSlashes(directory);
|
||||
while (true) {
|
||||
const baseName = getBaseFileName(directory);
|
||||
if (baseName !== "node_modules") {
|
||||
// Try to load source from the package
|
||||
const packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state);
|
||||
if (packageResult && hasTypeScriptFileExtension(packageResult)) {
|
||||
// Always prefer a TypeScript (.ts, .tsx, .d.ts) file shipped with the package
|
||||
return packageResult;
|
||||
}
|
||||
else {
|
||||
// Else prefer a types package over non-TypeScript results (e.g. JavaScript files)
|
||||
const typesResult = loadModuleFromNodeModulesFolder(combinePaths("@types", moduleName), directory, failedLookupLocations, state);
|
||||
if (typesResult || packageResult) {
|
||||
return typesResult || packageResult;
|
||||
let packageResult: string | undefined;
|
||||
if (!typesOnly) {
|
||||
// Try to load source from the package
|
||||
packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state);
|
||||
if (packageResult && hasTypeScriptFileExtension(packageResult)) {
|
||||
// Always prefer a TypeScript (.ts, .tsx, .d.ts) file shipped with the package
|
||||
return packageResult;
|
||||
}
|
||||
}
|
||||
|
||||
// Else prefer a types package over non-TypeScript results (e.g. JavaScript files)
|
||||
const typesResult = loadModuleFromNodeModulesFolder(combinePaths("@types", moduleName), directory, failedLookupLocations, state);
|
||||
if (typesResult || packageResult) {
|
||||
return typesResult || packageResult;
|
||||
}
|
||||
}
|
||||
|
||||
const parentPath = getDirectoryPath(directory);
|
||||
@@ -709,7 +719,7 @@ namespace ts {
|
||||
const state = { compilerOptions, host, traceEnabled, skipTsx: !compilerOptions.jsx };
|
||||
const failedLookupLocations: string[] = [];
|
||||
const supportedExtensions = getSupportedExtensions(compilerOptions);
|
||||
let containingDirectory = getDirectoryPath(containingFile);
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
|
||||
const resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, supportedExtensions, state);
|
||||
if (resolvedFileName) {
|
||||
@@ -718,18 +728,9 @@ namespace ts {
|
||||
|
||||
let referencedSourceFile: string;
|
||||
if (moduleHasNonRelativeName(moduleName)) {
|
||||
while (true) {
|
||||
const searchName = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||
referencedSourceFile = loadModuleFromFile(searchName, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
|
||||
if (referencedSourceFile) {
|
||||
break;
|
||||
}
|
||||
const parentPath = getDirectoryPath(containingDirectory);
|
||||
if (parentPath === containingDirectory) {
|
||||
break;
|
||||
}
|
||||
containingDirectory = parentPath;
|
||||
}
|
||||
referencedSourceFile = referencedSourceFile = loadModuleFromAncestorDirectories(moduleName, containingDirectory, supportedExtensions, failedLookupLocations, state) ||
|
||||
// If we didn't find the file normally, look it up in @types.
|
||||
loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state);
|
||||
}
|
||||
else {
|
||||
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||
@@ -741,4 +742,20 @@ namespace ts {
|
||||
? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations }
|
||||
: { resolvedModule: undefined, failedLookupLocations };
|
||||
}
|
||||
|
||||
/** Climb up parent directories looking for a module. */
|
||||
function loadModuleFromAncestorDirectories(moduleName: string, containingDirectory: string, supportedExtensions: string[], failedLookupLocations: string[], state: ModuleResolutionState): string | undefined {
|
||||
while (true) {
|
||||
const searchName = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||
const referencedSourceFile = loadModuleFromFile(searchName, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
|
||||
if (referencedSourceFile) {
|
||||
return referencedSourceFile;
|
||||
}
|
||||
const parentPath = getDirectoryPath(containingDirectory);
|
||||
if (parentPath === containingDirectory) {
|
||||
return undefined;
|
||||
}
|
||||
containingDirectory = parentPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
+51
-39
@@ -637,7 +637,7 @@ namespace ts {
|
||||
|
||||
sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement);
|
||||
Debug.assert(token() === SyntaxKind.EndOfFileToken);
|
||||
sourceFile.endOfFileToken = parseTokenNode();
|
||||
sourceFile.endOfFileToken = <EndOfFileToken>parseTokenNode();
|
||||
|
||||
setExternalModuleIndicator(sourceFile);
|
||||
|
||||
@@ -1004,6 +1004,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function parseOptionalToken<TKind extends SyntaxKind>(t: TKind): Token<TKind>;
|
||||
function parseOptionalToken(t: SyntaxKind): Node {
|
||||
if (token() === t) {
|
||||
return parseTokenNode();
|
||||
@@ -1011,6 +1012,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseExpectedToken<TKind extends SyntaxKind>(t: TKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Token<TKind>;
|
||||
function parseExpectedToken(t: SyntaxKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Node {
|
||||
return parseOptionalToken(t) ||
|
||||
createMissingNode(t, reportAtCurrentPosition, diagnosticMessage, arg0);
|
||||
@@ -1047,7 +1049,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// note: this function creates only node
|
||||
function createNode(kind: SyntaxKind, pos?: number): Node | Token | Identifier {
|
||||
function createNode<TKind extends SyntaxKind>(kind: TKind, pos?: number): Node | Token<TKind> | Identifier {
|
||||
nodeCount++;
|
||||
if (!(pos >= 0)) {
|
||||
pos = scanner.getStartPos();
|
||||
@@ -1394,8 +1396,8 @@ namespace ts {
|
||||
// Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
|
||||
return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.CloseBracketToken /*|| token === SyntaxKind.OpenBraceToken*/;
|
||||
case ParsingContext.TypeArguments:
|
||||
// Tokens other than '>' are here for better error recovery
|
||||
return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.OpenParenToken;
|
||||
// All other tokens should cause the type-argument to terminate except comma token
|
||||
return token() !== SyntaxKind.CommaToken;
|
||||
case ParsingContext.HeritageClauses:
|
||||
return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.CloseBraceToken;
|
||||
case ParsingContext.JsxAttributes:
|
||||
@@ -1920,7 +1922,7 @@ namespace ts {
|
||||
function parseTemplateExpression(): TemplateExpression {
|
||||
const template = <TemplateExpression>createNode(SyntaxKind.TemplateExpression);
|
||||
|
||||
template.head = parseTemplateLiteralFragment();
|
||||
template.head = parseTemplateHead();
|
||||
Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
|
||||
|
||||
const templateSpans = createNodeArray<TemplateSpan>();
|
||||
@@ -1940,14 +1942,13 @@ namespace ts {
|
||||
const span = <TemplateSpan>createNode(SyntaxKind.TemplateSpan);
|
||||
span.expression = allowInAnd(parseExpression);
|
||||
|
||||
let literal: TemplateLiteralFragment;
|
||||
|
||||
let literal: TemplateMiddle | TemplateTail;
|
||||
if (token() === SyntaxKind.CloseBraceToken) {
|
||||
reScanTemplateToken();
|
||||
literal = parseTemplateLiteralFragment();
|
||||
literal = parseTemplateMiddleOrTemplateTail();
|
||||
}
|
||||
else {
|
||||
literal = <TemplateLiteralFragment>parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken));
|
||||
literal = <TemplateTail>parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken));
|
||||
}
|
||||
|
||||
span.literal = literal;
|
||||
@@ -1958,8 +1959,16 @@ namespace ts {
|
||||
return <LiteralExpression>parseLiteralLikeNode(token(), internName);
|
||||
}
|
||||
|
||||
function parseTemplateLiteralFragment(): TemplateLiteralFragment {
|
||||
return <TemplateLiteralFragment>parseLiteralLikeNode(token(), /*internName*/ false);
|
||||
function parseTemplateHead(): TemplateHead {
|
||||
const fragment = parseLiteralLikeNode(token(), /*internName*/ false);
|
||||
Debug.assert(fragment.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
|
||||
return <TemplateHead>fragment;
|
||||
}
|
||||
|
||||
function parseTemplateMiddleOrTemplateTail(): TemplateMiddle | TemplateTail {
|
||||
const fragment = parseLiteralLikeNode(token(), /*internName*/ false);
|
||||
Debug.assert(fragment.kind === SyntaxKind.TemplateMiddle || fragment.kind === SyntaxKind.TemplateTail, "Template fragment has wrong token kind");
|
||||
return <TemplateMiddle | TemplateTail>fragment;
|
||||
}
|
||||
|
||||
function parseLiteralLikeNode(kind: SyntaxKind, internName: boolean): LiteralLikeNode {
|
||||
@@ -2719,7 +2728,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
let expr = parseAssignmentExpressionOrHigher();
|
||||
let operatorToken: Node;
|
||||
let operatorToken: BinaryOperatorToken;
|
||||
while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) {
|
||||
expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
|
||||
}
|
||||
@@ -2812,7 +2821,7 @@ namespace ts {
|
||||
// Note: we call reScanGreaterToken so that we get an appropriately merged token
|
||||
// for cases like > > = becoming >>=
|
||||
if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) {
|
||||
return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
|
||||
return makeBinaryExpression(expr, <BinaryOperatorToken>parseTokenNode(), parseAssignmentExpressionOrHigher());
|
||||
}
|
||||
|
||||
// It wasn't an assignment or a lambda. This is a conditional expression:
|
||||
@@ -3247,7 +3256,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
|
||||
leftOperand = makeBinaryExpression(leftOperand, <BinaryOperatorToken>parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3307,7 +3316,7 @@ namespace ts {
|
||||
return -1;
|
||||
}
|
||||
|
||||
function makeBinaryExpression(left: Expression, operatorToken: Node, right: Expression): BinaryExpression {
|
||||
function makeBinaryExpression(left: Expression, operatorToken: BinaryOperatorToken, right: Expression): BinaryExpression {
|
||||
const node = <BinaryExpression>createNode(SyntaxKind.BinaryExpression, left.pos);
|
||||
node.left = left;
|
||||
node.operatorToken = operatorToken;
|
||||
@@ -3324,7 +3333,7 @@ namespace ts {
|
||||
|
||||
function parsePrefixUnaryExpression() {
|
||||
const node = <PrefixUnaryExpression>createNode(SyntaxKind.PrefixUnaryExpression);
|
||||
node.operator = token();
|
||||
node.operator = <PrefixUnaryOperator>token();
|
||||
nextToken();
|
||||
node.operand = parseSimpleUnaryExpression();
|
||||
|
||||
@@ -3511,7 +3520,7 @@ namespace ts {
|
||||
function parseIncrementExpression(): IncrementExpression {
|
||||
if (token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) {
|
||||
const node = <PrefixUnaryExpression>createNode(SyntaxKind.PrefixUnaryExpression);
|
||||
node.operator = token();
|
||||
node.operator = <PrefixUnaryOperator>token();
|
||||
nextToken();
|
||||
node.operand = parseLeftHandSideExpressionOrHigher();
|
||||
return finishNode(node);
|
||||
@@ -3527,7 +3536,7 @@ namespace ts {
|
||||
if ((token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) {
|
||||
const node = <PostfixUnaryExpression>createNode(SyntaxKind.PostfixUnaryExpression, expression.pos);
|
||||
node.operand = expression;
|
||||
node.operator = token();
|
||||
node.operator = <PostfixUnaryOperator>token();
|
||||
nextToken();
|
||||
return finishNode(node);
|
||||
}
|
||||
@@ -3700,7 +3709,7 @@ namespace ts {
|
||||
badNode.end = invalidElement.end;
|
||||
badNode.left = result;
|
||||
badNode.right = invalidElement;
|
||||
badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
|
||||
badNode.operatorToken = <BinaryOperatorToken>createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
|
||||
badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
|
||||
return <JsxElement><Node>badNode;
|
||||
}
|
||||
@@ -3836,7 +3845,7 @@ namespace ts {
|
||||
if (token() === SyntaxKind.EqualsToken) {
|
||||
switch (scanJsxAttributeValue()) {
|
||||
case SyntaxKind.StringLiteral:
|
||||
node.initializer = parseLiteralNode();
|
||||
node.initializer = <StringLiteral>parseLiteralNode();
|
||||
break;
|
||||
default:
|
||||
node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
|
||||
@@ -3921,7 +3930,7 @@ namespace ts {
|
||||
const tagExpression = <TaggedTemplateExpression>createNode(SyntaxKind.TaggedTemplateExpression, expression.pos);
|
||||
tagExpression.tag = expression;
|
||||
tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral
|
||||
? parseLiteralNode()
|
||||
? <NoSubstitutionTemplateLiteral>parseLiteralNode()
|
||||
: parseTemplateExpression();
|
||||
expression = finishNode(tagExpression);
|
||||
continue;
|
||||
@@ -4959,7 +4968,7 @@ namespace ts {
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
function parseMethodDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, asteriskToken: Node, name: PropertyName, questionToken: Node, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
|
||||
function parseMethodDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, asteriskToken: AsteriskToken, name: PropertyName, questionToken: QuestionToken, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
|
||||
const method = <MethodDeclaration>createNode(SyntaxKind.MethodDeclaration, fullStart);
|
||||
method.decorators = decorators;
|
||||
method.modifiers = modifiers;
|
||||
@@ -4973,7 +4982,7 @@ namespace ts {
|
||||
return addJSDocComment(finishNode(method));
|
||||
}
|
||||
|
||||
function parsePropertyDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, name: PropertyName, questionToken: Node): ClassElement {
|
||||
function parsePropertyDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, name: PropertyName, questionToken: QuestionToken): ClassElement {
|
||||
const property = <PropertyDeclaration>createNode(SyntaxKind.PropertyDeclaration, fullStart);
|
||||
property.decorators = decorators;
|
||||
property.modifiers = modifiers;
|
||||
@@ -5343,7 +5352,7 @@ namespace ts {
|
||||
parseExpected(SyntaxKind.EqualsToken);
|
||||
node.type = parseType();
|
||||
parseSemicolon();
|
||||
return finishNode(node);
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
// In an ambient declaration, the grammar only allows integer literals as initializers.
|
||||
@@ -5395,7 +5404,7 @@ namespace ts {
|
||||
node.flags |= flags;
|
||||
node.name = parseIdentifier();
|
||||
node.body = parseOptional(SyntaxKind.DotToken)
|
||||
? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag)
|
||||
? <NamespaceDeclaration>parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag)
|
||||
: parseModuleBlock();
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
@@ -5574,8 +5583,10 @@ namespace ts {
|
||||
return finishNode(namespaceImport);
|
||||
}
|
||||
|
||||
function parseNamedImportsOrExports(kind: SyntaxKind.NamedImports): NamedImports;
|
||||
function parseNamedImportsOrExports(kind: SyntaxKind.NamedExports): NamedExports;
|
||||
function parseNamedImportsOrExports(kind: SyntaxKind): NamedImportsOrExports {
|
||||
const node = <NamedImports>createNode(kind);
|
||||
const node = <NamedImports | NamedExports>createNode(kind);
|
||||
|
||||
// NamedImports:
|
||||
// { }
|
||||
@@ -5585,7 +5596,7 @@ namespace ts {
|
||||
// ImportsList:
|
||||
// ImportSpecifier
|
||||
// ImportsList, ImportSpecifier
|
||||
node.elements = parseBracketedList(ParsingContext.ImportOrExportSpecifiers,
|
||||
node.elements = <NodeArray<ImportSpecifier> | NodeArray<ExportSpecifier>>parseBracketedList(ParsingContext.ImportOrExportSpecifiers,
|
||||
kind === SyntaxKind.NamedImports ? parseImportSpecifier : parseExportSpecifier,
|
||||
SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken);
|
||||
return finishNode(node);
|
||||
@@ -5969,14 +5980,15 @@ namespace ts {
|
||||
const parameter = <ParameterDeclaration>createNode(SyntaxKind.Parameter);
|
||||
parameter.type = parseJSDocType();
|
||||
if (parseOptional(SyntaxKind.EqualsToken)) {
|
||||
parameter.questionToken = createNode(SyntaxKind.EqualsToken);
|
||||
// TODO(rbuckton): Can this be changed to SyntaxKind.QuestionToken?
|
||||
parameter.questionToken = <QuestionToken>createNode(SyntaxKind.EqualsToken);
|
||||
}
|
||||
return finishNode(parameter);
|
||||
}
|
||||
|
||||
function parseJSDocTypeReference(): JSDocTypeReference {
|
||||
const result = <JSDocTypeReference>createNode(SyntaxKind.JSDocTypeReference);
|
||||
result.name = parseSimplePropertyName();
|
||||
result.name = <Identifier>parseSimplePropertyName();
|
||||
|
||||
if (token() === SyntaxKind.LessThanToken) {
|
||||
result.typeArguments = parseTypeArguments();
|
||||
@@ -6304,7 +6316,7 @@ namespace ts {
|
||||
|
||||
function parseTag(indent: number) {
|
||||
Debug.assert(token() === SyntaxKind.AtToken);
|
||||
const atToken = createNode(SyntaxKind.AtToken, scanner.getTokenPos());
|
||||
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getTokenPos());
|
||||
atToken.end = scanner.getTextPos();
|
||||
nextJSDocToken();
|
||||
|
||||
@@ -6410,7 +6422,7 @@ namespace ts {
|
||||
return comments;
|
||||
}
|
||||
|
||||
function parseUnknownTag(atToken: Node, tagName: Identifier) {
|
||||
function parseUnknownTag(atToken: AtToken, tagName: Identifier) {
|
||||
const result = <JSDocTag>createNode(SyntaxKind.JSDocTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
result.tagName = tagName;
|
||||
@@ -6440,7 +6452,7 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function parseParamTag(atToken: Node, tagName: Identifier) {
|
||||
function parseParamTag(atToken: AtToken, tagName: Identifier) {
|
||||
let typeExpression = tryParseTypeExpression();
|
||||
skipWhitespace();
|
||||
|
||||
@@ -6491,7 +6503,7 @@ namespace ts {
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function parseReturnTag(atToken: Node, tagName: Identifier): JSDocReturnTag {
|
||||
function parseReturnTag(atToken: AtToken, tagName: Identifier): JSDocReturnTag {
|
||||
if (forEach(tags, t => t.kind === SyntaxKind.JSDocReturnTag)) {
|
||||
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
|
||||
}
|
||||
@@ -6503,7 +6515,7 @@ namespace ts {
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function parseTypeTag(atToken: Node, tagName: Identifier): JSDocTypeTag {
|
||||
function parseTypeTag(atToken: AtToken, tagName: Identifier): JSDocTypeTag {
|
||||
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTypeTag)) {
|
||||
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
|
||||
}
|
||||
@@ -6515,7 +6527,7 @@ namespace ts {
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function parsePropertyTag(atToken: Node, tagName: Identifier): JSDocPropertyTag {
|
||||
function parsePropertyTag(atToken: AtToken, tagName: Identifier): JSDocPropertyTag {
|
||||
const typeExpression = tryParseTypeExpression();
|
||||
skipWhitespace();
|
||||
const name = parseJSDocIdentifierName();
|
||||
@@ -6533,7 +6545,7 @@ namespace ts {
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function parseTypedefTag(atToken: Node, tagName: Identifier): JSDocTypedefTag {
|
||||
function parseTypedefTag(atToken: AtToken, tagName: Identifier): JSDocTypedefTag {
|
||||
const typeExpression = tryParseTypeExpression();
|
||||
skipWhitespace();
|
||||
|
||||
@@ -6555,7 +6567,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
if (!typedefTag.jsDocTypeLiteral) {
|
||||
typedefTag.jsDocTypeLiteral = typeExpression.type;
|
||||
typedefTag.jsDocTypeLiteral = <JSDocTypeLiteral>typeExpression.type;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -6607,7 +6619,7 @@ namespace ts {
|
||||
|
||||
function tryParseChildTag(parentTag: JSDocTypeLiteral): boolean {
|
||||
Debug.assert(token() === SyntaxKind.AtToken);
|
||||
const atToken = createNode(SyntaxKind.AtToken, scanner.getStartPos());
|
||||
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getStartPos());
|
||||
atToken.end = scanner.getTextPos();
|
||||
nextJSDocToken();
|
||||
|
||||
@@ -6637,7 +6649,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function parseTemplateTag(atToken: Node, tagName: Identifier): JSDocTemplateTag {
|
||||
function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag {
|
||||
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) {
|
||||
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ namespace ts {
|
||||
// load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders
|
||||
const typeReferences: string[] = getAutomaticTypeDirectiveNames(options, host);
|
||||
|
||||
if (typeReferences) {
|
||||
if (typeReferences.length) {
|
||||
// This containingFilename needs to match with the one used in managed-side
|
||||
const containingFilename = combinePaths(host.getCurrentDirectory(), "__inferred type names__.ts");
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
|
||||
@@ -473,6 +473,7 @@ namespace ts {
|
||||
(oldOptions.configFilePath !== options.configFilePath) ||
|
||||
(oldOptions.baseUrl !== options.baseUrl) ||
|
||||
(oldOptions.maxNodeModuleJsDepth !== options.maxNodeModuleJsDepth) ||
|
||||
!arrayIsEqualTo(oldOptions.lib, options.lib) ||
|
||||
!arrayIsEqualTo(oldOptions.typeRoots, oldOptions.typeRoots) ||
|
||||
!arrayIsEqualTo(oldOptions.rootDirs, options.rootDirs) ||
|
||||
!equalOwnProperties(oldOptions.paths, options.paths)) {
|
||||
@@ -1310,7 +1311,6 @@ namespace ts {
|
||||
for (let i = 0; i < moduleNames.length; i++) {
|
||||
const resolution = resolutions[i];
|
||||
setResolvedModule(file, moduleNames[i], resolution);
|
||||
const resolvedPath = resolution ? toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName) : undefined;
|
||||
|
||||
// add file to program only if:
|
||||
// - resolution was successful
|
||||
@@ -1332,7 +1332,7 @@ namespace ts {
|
||||
}
|
||||
else if (shouldAddFile) {
|
||||
findSourceFile(resolution.resolvedFileName,
|
||||
resolvedPath,
|
||||
toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName),
|
||||
/*isDefaultLib*/ false, /*isReference*/ false,
|
||||
file,
|
||||
skipTrivia(file.text, file.imports[i].pos),
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace ts {
|
||||
|
||||
function flattenDestructuring(
|
||||
context: TransformationContext,
|
||||
root: BindingElement | BinaryExpression,
|
||||
root: VariableDeclaration | ParameterDeclaration | BindingElement | BinaryExpression,
|
||||
value: Expression,
|
||||
location: TextRange,
|
||||
emitAssignment: (name: Identifier, value: Expression, location: TextRange, original: Node) => void,
|
||||
@@ -320,7 +320,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitBindingElement(target: BindingElement, value: Expression) {
|
||||
function emitBindingElement(target: VariableDeclaration | ParameterDeclaration | BindingElement, value: Expression) {
|
||||
// Any temporary assignments needed to emit target = value should point to target
|
||||
const initializer = visitor ? visitNode(target.initializer, visitor, isExpression) : target.initializer;
|
||||
if (initializer) {
|
||||
|
||||
@@ -983,7 +983,7 @@ namespace ts {
|
||||
if (statementOffset < ctorStatements.length) {
|
||||
firstStatement = ctorStatements[statementOffset];
|
||||
|
||||
if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((firstStatement as ExpressionStatement).expression)) {
|
||||
if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCall((firstStatement as ExpressionStatement).expression)) {
|
||||
const superCall = (firstStatement as ExpressionStatement).expression as CallExpression;
|
||||
superCallExpression = setOriginalNode(
|
||||
saveStateAndInvoke(superCall, visitImmediateSuperCallInBody),
|
||||
@@ -3201,7 +3201,7 @@ namespace ts {
|
||||
* @param node The declaration.
|
||||
* @param allowComments Allow comments for the name.
|
||||
*/
|
||||
function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
|
||||
function getDeclarationName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
|
||||
if (node.name && !isGeneratedIdentifier(node.name)) {
|
||||
const name = getMutableClone(node.name);
|
||||
emitFlags |= getEmitFlags(node.name);
|
||||
|
||||
@@ -529,7 +529,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitAccessorDeclaration(node: GetAccessorDeclaration) {
|
||||
function visitAccessorDeclaration(node: AccessorDeclaration) {
|
||||
const savedInGeneratorFunctionBody = inGeneratorFunctionBody;
|
||||
const savedInStatementContainingYield = inStatementContainingYield;
|
||||
inGeneratorFunctionBody = false;
|
||||
@@ -661,12 +661,12 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isCompoundAssignment(kind: SyntaxKind) {
|
||||
function isCompoundAssignment(kind: BinaryOperator): kind is CompoundAssignmentOperator {
|
||||
return kind >= SyntaxKind.FirstCompoundAssignment
|
||||
&& kind <= SyntaxKind.LastCompoundAssignment;
|
||||
}
|
||||
|
||||
function getOperatorForCompoundAssignment(kind: SyntaxKind) {
|
||||
function getOperatorForCompoundAssignment(kind: CompoundAssignmentOperator): BitwiseOperatorOrHigher {
|
||||
switch (kind) {
|
||||
case SyntaxKind.PlusEqualsToken: return SyntaxKind.PlusToken;
|
||||
case SyntaxKind.MinusEqualsToken: return SyntaxKind.MinusToken;
|
||||
|
||||
@@ -600,7 +600,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
statements.push(
|
||||
createExportStatement(node.name, setEmitFlags(getSynthesizedClone(node.name), EmitFlags.LocalName), /*location*/ node)
|
||||
createExportStatement(<Identifier>node.name, setEmitFlags(getSynthesizedClone(node.name), EmitFlags.LocalName), /*location*/ node)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -799,7 +799,7 @@ namespace ts {
|
||||
addVarForExportedEnumOrNamespaceDeclaration(statements, original);
|
||||
}
|
||||
|
||||
addExportMemberAssignments(statements, original.name);
|
||||
addExportMemberAssignments(statements, <Identifier>original.name);
|
||||
|
||||
return statements;
|
||||
}
|
||||
@@ -822,7 +822,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getDeclarationName(node: DeclarationStatement) {
|
||||
return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node);
|
||||
return node.name ? getSynthesizedClone(<Identifier>node.name) : getGeneratedNameForNode(node);
|
||||
}
|
||||
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
@@ -919,7 +919,7 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.PostfixUnaryExpression) {
|
||||
transformedUnaryExpression = createBinary(
|
||||
operand,
|
||||
createNode(operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken),
|
||||
createToken(operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken),
|
||||
createLiteral(1),
|
||||
/*location*/ node
|
||||
);
|
||||
|
||||
@@ -1206,7 +1206,7 @@ namespace ts {
|
||||
* @param node The declaration statement.
|
||||
*/
|
||||
function getDeclarationName(node: DeclarationStatement) {
|
||||
return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node);
|
||||
return node.name ? getSynthesizedClone(<Identifier>node.name) : getGeneratedNameForNode(node);
|
||||
}
|
||||
|
||||
function addExportStarFunction(statements: Statement[], localNames: Identifier) {
|
||||
|
||||
@@ -972,7 +972,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const statement = statements[index];
|
||||
if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((<ExpressionStatement>statement).expression)) {
|
||||
if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((<ExpressionStatement>statement).expression)) {
|
||||
result.push(visitNode(statement, visitor, isStatement));
|
||||
return index + 1;
|
||||
}
|
||||
@@ -1784,10 +1784,41 @@ namespace ts {
|
||||
case SyntaxKind.TypeReference:
|
||||
return serializeTypeReferenceNode(<TypeReferenceNode>node);
|
||||
|
||||
case SyntaxKind.IntersectionType:
|
||||
case SyntaxKind.UnionType:
|
||||
{
|
||||
const unionOrIntersection = <UnionOrIntersectionTypeNode>node;
|
||||
let serializedUnion: Identifier;
|
||||
for (const typeNode of unionOrIntersection.types) {
|
||||
const serializedIndividual = serializeTypeNode(typeNode) as Identifier;
|
||||
// Non identifier
|
||||
if (serializedIndividual.kind !== SyntaxKind.Identifier) {
|
||||
serializedUnion = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
// One of the individual is global object, return immediately
|
||||
if (serializedIndividual.text === "Object") {
|
||||
return serializedIndividual;
|
||||
}
|
||||
|
||||
// Different types
|
||||
if (serializedUnion && serializedUnion.text !== serializedIndividual.text) {
|
||||
serializedUnion = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
serializedUnion = serializedIndividual;
|
||||
}
|
||||
|
||||
// If we were able to find common type
|
||||
if (serializedUnion) {
|
||||
return serializedUnion;
|
||||
}
|
||||
}
|
||||
// Fallthrough
|
||||
case SyntaxKind.TypeQuery:
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.UnionType:
|
||||
case SyntaxKind.IntersectionType:
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.ThisType:
|
||||
break;
|
||||
@@ -2284,7 +2315,7 @@ namespace ts {
|
||||
* @param node The parameter declaration node.
|
||||
*/
|
||||
function visitParameter(node: ParameterDeclaration) {
|
||||
if (node.name && isIdentifier(node.name) && node.name.originalKeywordKind === SyntaxKind.ThisKeyword) {
|
||||
if (parameterIsThisKeyword(node)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -2963,7 +2994,7 @@ namespace ts {
|
||||
return createStatement(expression, /*location*/ undefined);
|
||||
}
|
||||
|
||||
function addExportMemberAssignment(statements: Statement[], node: DeclarationStatement) {
|
||||
function addExportMemberAssignment(statements: Statement[], node: ClassDeclaration | FunctionDeclaration) {
|
||||
const expression = createAssignment(
|
||||
getExportName(node),
|
||||
getLocalName(node, /*noSourceMaps*/ true)
|
||||
@@ -3041,7 +3072,7 @@ namespace ts {
|
||||
* @param noSourceMaps A value indicating whether source maps may not be emitted for the name.
|
||||
* @param allowComments A value indicating whether comments may be emitted for the name.
|
||||
*/
|
||||
function getLocalName(node: DeclarationStatement | ClassExpression, noSourceMaps?: boolean, allowComments?: boolean) {
|
||||
function getLocalName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, noSourceMaps?: boolean, allowComments?: boolean) {
|
||||
return getDeclarationName(node, allowComments, !noSourceMaps, EmitFlags.LocalName);
|
||||
}
|
||||
|
||||
@@ -3055,7 +3086,7 @@ namespace ts {
|
||||
* @param noSourceMaps A value indicating whether source maps may not be emitted for the name.
|
||||
* @param allowComments A value indicating whether comments may be emitted for the name.
|
||||
*/
|
||||
function getExportName(node: DeclarationStatement | ClassExpression, noSourceMaps?: boolean, allowComments?: boolean) {
|
||||
function getExportName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, noSourceMaps?: boolean, allowComments?: boolean) {
|
||||
if (isNamespaceExport(node)) {
|
||||
return getNamespaceMemberName(getDeclarationName(node), allowComments, !noSourceMaps);
|
||||
}
|
||||
@@ -3071,9 +3102,9 @@ namespace ts {
|
||||
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
|
||||
* @param emitFlags Additional NodeEmitFlags to specify for the name.
|
||||
*/
|
||||
function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
|
||||
function getDeclarationName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
|
||||
if (node.name) {
|
||||
const name = getMutableClone(node.name);
|
||||
const name = getMutableClone(<Identifier>node.name);
|
||||
emitFlags |= getEmitFlags(node.name);
|
||||
if (!allowSourceMaps) {
|
||||
emitFlags |= EmitFlags.NoSourceMap;
|
||||
|
||||
+481
-258
File diff suppressed because it is too large
Load Diff
+35
-15
@@ -609,7 +609,7 @@ namespace ts {
|
||||
return !!(getCombinedNodeFlags(node) & NodeFlags.Let);
|
||||
}
|
||||
|
||||
export function isSuperCallExpression(n: Node): boolean {
|
||||
export function isSuperCall(n: Node): n is SuperCall {
|
||||
return n.kind === SyntaxKind.CallExpression && (<CallExpression>n).expression.kind === SyntaxKind.SuperKeyword;
|
||||
}
|
||||
|
||||
@@ -1047,7 +1047,7 @@ namespace ts {
|
||||
/**
|
||||
* Determines whether a node is a property or element access expression for super.
|
||||
*/
|
||||
export function isSuperProperty(node: Node): node is (PropertyAccessExpression | ElementAccessExpression) {
|
||||
export function isSuperProperty(node: Node): node is SuperProperty {
|
||||
const kind = node.kind;
|
||||
return (kind === SyntaxKind.PropertyAccessExpression || kind === SyntaxKind.ElementAccessExpression)
|
||||
&& (<PropertyAccessExpression | ElementAccessExpression>node).expression.kind === SyntaxKind.SuperKeyword;
|
||||
@@ -1375,7 +1375,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
|
||||
export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): ImportEqualsDeclaration | NamespaceImport {
|
||||
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
return <ImportEqualsDeclaration>node;
|
||||
}
|
||||
@@ -2459,7 +2459,7 @@ namespace ts {
|
||||
return file.moduleName || getExternalModuleNameFromPath(host, file.fileName);
|
||||
}
|
||||
|
||||
export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration): string {
|
||||
export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): string {
|
||||
const file = resolver.getExternalModuleFileFromDeclaration(declaration);
|
||||
if (!file || isDeclarationFile(file)) {
|
||||
return undefined;
|
||||
@@ -2707,15 +2707,35 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
export function getSetAccessorTypeAnnotationNode(accessor: AccessorDeclaration): TypeNode {
|
||||
/** Get the type annotaion for the value parameter. */
|
||||
export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode {
|
||||
if (accessor && accessor.parameters.length > 0) {
|
||||
const hasThis = accessor.parameters.length === 2 &&
|
||||
accessor.parameters[0].name.kind === SyntaxKind.Identifier &&
|
||||
(accessor.parameters[0].name as Identifier).originalKeywordKind === SyntaxKind.ThisKeyword;
|
||||
const hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]);
|
||||
return accessor.parameters[hasThis ? 1 : 0].type;
|
||||
}
|
||||
}
|
||||
|
||||
export function getThisParameter(signature: SignatureDeclaration): ParameterDeclaration | undefined {
|
||||
if (signature.parameters.length) {
|
||||
const thisParameter = signature.parameters[0];
|
||||
if (parameterIsThisKeyword(thisParameter)) {
|
||||
return thisParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function parameterIsThisKeyword(parameter: ParameterDeclaration): boolean {
|
||||
return isThisIdentifier(parameter.name);
|
||||
}
|
||||
|
||||
export function isThisIdentifier(node: Node | undefined): boolean {
|
||||
return node && node.kind === SyntaxKind.Identifier && identifierIsThisKeyword(node as Identifier);
|
||||
}
|
||||
|
||||
export function identifierIsThisKeyword(id: Identifier): boolean {
|
||||
return id.originalKeywordKind === SyntaxKind.ThisKeyword;
|
||||
}
|
||||
|
||||
export interface AllAccessorDeclarations {
|
||||
firstAccessor: AccessorDeclaration;
|
||||
secondAccessor: AccessorDeclaration;
|
||||
@@ -3605,14 +3625,14 @@ namespace ts {
|
||||
return SyntaxKind.FirstTemplateToken <= kind && kind <= SyntaxKind.LastTemplateToken;
|
||||
}
|
||||
|
||||
function isTemplateLiteralFragmentKind(kind: SyntaxKind) {
|
||||
return kind === SyntaxKind.TemplateHead
|
||||
|| kind === SyntaxKind.TemplateMiddle
|
||||
|| kind === SyntaxKind.TemplateTail;
|
||||
export function isTemplateHead(node: Node): node is TemplateHead {
|
||||
return node.kind === SyntaxKind.TemplateHead;
|
||||
}
|
||||
|
||||
export function isTemplateLiteralFragment(node: Node): node is TemplateLiteralFragment {
|
||||
return isTemplateLiteralFragmentKind(node.kind);
|
||||
export function isTemplateMiddleOrTemplateTail(node: Node): node is TemplateMiddle | TemplateTail {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.TemplateMiddle
|
||||
|| kind === SyntaxKind.TemplateTail;
|
||||
}
|
||||
|
||||
// Identifiers
|
||||
@@ -3777,7 +3797,7 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.CallExpression;
|
||||
}
|
||||
|
||||
export function isTemplate(node: Node): node is Template {
|
||||
export function isTemplateLiteral(node: Node): node is TemplateLiteral {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.TemplateExpression
|
||||
|| kind === SyntaxKind.NoSubstitutionTemplateLiteral;
|
||||
|
||||
@@ -799,7 +799,7 @@ namespace ts {
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
return updateTaggedTemplate(<TaggedTemplateExpression>node,
|
||||
visitNode((<TaggedTemplateExpression>node).tag, visitor, isExpression),
|
||||
visitNode((<TaggedTemplateExpression>node).template, visitor, isTemplate));
|
||||
visitNode((<TaggedTemplateExpression>node).template, visitor, isTemplateLiteral));
|
||||
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return updateParen(<ParenthesizedExpression>node,
|
||||
@@ -863,7 +863,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.TemplateExpression:
|
||||
return updateTemplateExpression(<TemplateExpression>node,
|
||||
visitNode((<TemplateExpression>node).head, visitor, isTemplateLiteralFragment),
|
||||
visitNode((<TemplateExpression>node).head, visitor, isTemplateHead),
|
||||
visitNodes((<TemplateExpression>node).templateSpans, visitor, isTemplateSpan));
|
||||
|
||||
case SyntaxKind.YieldExpression:
|
||||
@@ -891,7 +891,7 @@ namespace ts {
|
||||
case SyntaxKind.TemplateSpan:
|
||||
return updateTemplateSpan(<TemplateSpan>node,
|
||||
visitNode((<TemplateSpan>node).expression, visitor, isExpression),
|
||||
visitNode((<TemplateSpan>node).literal, visitor, isTemplateLiteralFragment));
|
||||
visitNode((<TemplateSpan>node).literal, visitor, isTemplateMiddleOrTemplateTail));
|
||||
|
||||
// Element
|
||||
case SyntaxKind.Block:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -427,7 +427,7 @@ namespace FourSlash {
|
||||
|
||||
if (exists !== negative) {
|
||||
this.printErrorLog(negative, this.getAllDiagnostics());
|
||||
throw new Error("Failure between markers: " + startMarkerName + ", " + endMarkerName);
|
||||
throw new Error(`Failure between markers: '${startMarkerName}', '${endMarkerName}'`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -742,7 +742,6 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public verifyCompletionListAllowsNewIdentifier(negative: boolean) {
|
||||
const completions = this.getCompletionListAtCaret();
|
||||
|
||||
@@ -1611,7 +1610,7 @@ namespace FourSlash {
|
||||
if (isFormattingEdit) {
|
||||
const newContent = this.getFileContent(fileName);
|
||||
|
||||
if (newContent.replace(/\s/g, "") !== oldContent.replace(/\s/g, "")) {
|
||||
if (this.removeWhitespace(newContent) !== this.removeWhitespace(oldContent)) {
|
||||
this.raiseError("Formatting operation destroyed non-whitespace content");
|
||||
}
|
||||
}
|
||||
@@ -1677,6 +1676,10 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
private removeWhitespace(text: string): string {
|
||||
return text.replace(/\s/g, "");
|
||||
}
|
||||
|
||||
public goToBOF() {
|
||||
this.goToPosition(0);
|
||||
}
|
||||
@@ -2038,6 +2041,47 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
private getCodeFixes(errorCode?: number) {
|
||||
const fileName = this.activeFile.fileName;
|
||||
const diagnostics = this.getDiagnostics(fileName);
|
||||
|
||||
if (diagnostics.length === 0) {
|
||||
this.raiseError("Errors expected.");
|
||||
}
|
||||
|
||||
if (diagnostics.length > 1 && errorCode !== undefined) {
|
||||
this.raiseError("When there's more than one error, you must specify the errror to fix.");
|
||||
}
|
||||
|
||||
const diagnostic = !errorCode ? diagnostics[0] : ts.find(diagnostics, d => d.code == errorCode);
|
||||
|
||||
return this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.length, [diagnostic.code]);
|
||||
}
|
||||
|
||||
public verifyCodeFixAtPosition(expectedText: string, errorCode?: number) {
|
||||
const ranges = this.getRanges();
|
||||
if (ranges.length == 0) {
|
||||
this.raiseError("At least one range should be specified in the testfile.");
|
||||
}
|
||||
|
||||
const actual = this.getCodeFixes(errorCode);
|
||||
|
||||
if (!actual || actual.length == 0) {
|
||||
this.raiseError("No codefixes returned.");
|
||||
}
|
||||
|
||||
if (actual.length > 1) {
|
||||
this.raiseError("More than 1 codefix returned.");
|
||||
}
|
||||
|
||||
this.applyEdits(actual[0].changes[0].fileName, actual[0].changes[0].textChanges, /*isFormattingEdit*/ false);
|
||||
const actualText = this.rangeText(ranges[0]);
|
||||
|
||||
if (this.removeWhitespace(actualText) !== this.removeWhitespace(expectedText)) {
|
||||
this.raiseError(`Actual text doesn't match expected text. Actual: '${actualText}' Expected: '${expectedText}'`);
|
||||
}
|
||||
}
|
||||
|
||||
public verifyDocCommentTemplate(expected?: ts.TextInsertion) {
|
||||
const name = "verifyDocCommentTemplate";
|
||||
const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
@@ -2211,6 +2255,18 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyNavigationTree(json: any) {
|
||||
const tree = this.languageService.getNavigationTree(this.activeFile.fileName);
|
||||
if (JSON.stringify(tree, replacer) !== JSON.stringify(json)) {
|
||||
this.raiseError(`verifyNavigationTree failed - expected: ${stringify(json)}, got: ${stringify(tree, replacer)}`);
|
||||
}
|
||||
|
||||
function replacer(key: string, value: any) {
|
||||
// Don't check "spans", and omit falsy values.
|
||||
return key === "spans" ? undefined : (value || undefined);
|
||||
}
|
||||
}
|
||||
|
||||
public printNavigationItems(searchValue: string) {
|
||||
const items = this.languageService.getNavigateToItems(searchValue);
|
||||
const length = items && items.length;
|
||||
@@ -2309,6 +2365,18 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyCodeFixAvailable(negative: boolean, errorCode?: number) {
|
||||
const fixes = this.getCodeFixes(errorCode);
|
||||
|
||||
if (negative && fixes && fixes.length > 0) {
|
||||
this.raiseError(`verifyCodeFixAvailable failed - expected no fixes, actual: ${fixes.length}`);
|
||||
}
|
||||
|
||||
if (!negative && (fixes === undefined || fixes.length === 0)) {
|
||||
this.raiseError(`verifyCodeFixAvailable failed - expected code fixes, actual: 0`);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the text of the entire line the caret is currently at
|
||||
private getCurrentLineContent() {
|
||||
const text = this.getFileContent(this.activeFile.fileName);
|
||||
@@ -3096,6 +3164,10 @@ namespace FourSlashInterface {
|
||||
public isValidBraceCompletionAtPosition(openingBrace: string) {
|
||||
this.state.verifyBraceCompletionAtPosition(this.negative, openingBrace);
|
||||
}
|
||||
|
||||
public codeFixAvailable(errorCode?: number) {
|
||||
this.state.verifyCodeFixAvailable(this.negative, errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
export class Verify extends VerifyNegatable {
|
||||
@@ -3275,10 +3347,18 @@ namespace FourSlashInterface {
|
||||
this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, /*empty*/ true);
|
||||
}
|
||||
|
||||
public codeFixAtPosition(expectedText: string, errorCode?: number): void {
|
||||
this.state.verifyCodeFixAtPosition(expectedText, errorCode);
|
||||
}
|
||||
|
||||
public navigationBar(json: any) {
|
||||
this.state.verifyNavigationBar(json);
|
||||
}
|
||||
|
||||
public navigationTree(json: any) {
|
||||
this.state.verifyNavigationTree(json);
|
||||
}
|
||||
|
||||
public navigationItemsListCount(count: number, searchValue: string, matchKind?: string, fileName?: string) {
|
||||
this.state.verifyNavigationItemsCount(count, searchValue, matchKind, fileName);
|
||||
}
|
||||
|
||||
@@ -459,6 +459,10 @@ namespace Harness.LanguageService {
|
||||
getNavigationBarItems(fileName: string): ts.NavigationBarItem[] {
|
||||
return unwrapJSONCallResult(this.shim.getNavigationBarItems(fileName));
|
||||
}
|
||||
getNavigationTree(fileName: string): ts.NavigationTree {
|
||||
return unwrapJSONCallResult(this.shim.getNavigationTree(fileName));
|
||||
}
|
||||
|
||||
getOutliningSpans(fileName: string): ts.OutliningSpan[] {
|
||||
return unwrapJSONCallResult(this.shim.getOutliningSpans(fileName));
|
||||
}
|
||||
@@ -486,6 +490,9 @@ namespace Harness.LanguageService {
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean {
|
||||
return unwrapJSONCallResult(this.shim.isValidBraceCompletionAtPosition(fileName, position, openingBrace));
|
||||
}
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[]): ts.CodeAction[] {
|
||||
throw new Error("Not supported on the shim.");
|
||||
}
|
||||
getEmitOutput(fileName: string): ts.EmitOutput {
|
||||
return unwrapJSONCallResult(this.shim.getEmitOutput(fileName));
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
/// <reference path="../../server/typingsInstaller/typingsInstaller.ts" />
|
||||
|
||||
namespace ts.projectSystem {
|
||||
import CommandNames = server.CommandNames;
|
||||
|
||||
function createTestTypingsInstaller(host: server.ServerHost) {
|
||||
return new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
|
||||
}
|
||||
@@ -75,7 +77,7 @@ namespace ts.projectSystem {
|
||||
};
|
||||
|
||||
// Change the content of file1 to `export var T: number;export function Foo() { };`
|
||||
changeModuleFile1ShapeRequest1 = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
|
||||
changeModuleFile1ShapeRequest1 = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
|
||||
file: moduleFile1.path,
|
||||
line: 1,
|
||||
offset: 1,
|
||||
@@ -85,7 +87,7 @@ namespace ts.projectSystem {
|
||||
});
|
||||
|
||||
// Change the content of file1 to `export var T: number;export function Foo() { };`
|
||||
changeModuleFile1InternalRequest1 = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
|
||||
changeModuleFile1InternalRequest1 = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
|
||||
file: moduleFile1.path,
|
||||
line: 1,
|
||||
offset: 1,
|
||||
@@ -95,7 +97,7 @@ namespace ts.projectSystem {
|
||||
});
|
||||
|
||||
// Change the content of file1 to `export var T: number;export function Foo() { };`
|
||||
changeModuleFile1ShapeRequest2 = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
|
||||
changeModuleFile1ShapeRequest2 = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
|
||||
file: moduleFile1.path,
|
||||
line: 1,
|
||||
offset: 1,
|
||||
@@ -104,7 +106,7 @@ namespace ts.projectSystem {
|
||||
insertString: `export var T2: number;`
|
||||
});
|
||||
|
||||
moduleFile1FileListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path, projectFileName: configFile.path });
|
||||
moduleFile1FileListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path, projectFileName: configFile.path });
|
||||
});
|
||||
|
||||
it("should contains only itself if a module file's shape didn't change, and all files referencing it if its shape changed", () => {
|
||||
@@ -120,7 +122,7 @@ namespace ts.projectSystem {
|
||||
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]);
|
||||
|
||||
// Change the content of file1 to `export var T: number;export function Foo() { console.log('hi'); };`
|
||||
const changeFile1InternalRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
|
||||
const changeFile1InternalRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
|
||||
file: moduleFile1.path,
|
||||
line: 1,
|
||||
offset: 46,
|
||||
@@ -143,7 +145,7 @@ namespace ts.projectSystem {
|
||||
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]);
|
||||
|
||||
// Change file2 content to `let y = Foo();`
|
||||
const removeFile1Consumer1ImportRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
|
||||
const removeFile1Consumer1ImportRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
|
||||
file: file1Consumer1.path,
|
||||
line: 1,
|
||||
offset: 1,
|
||||
@@ -156,7 +158,7 @@ namespace ts.projectSystem {
|
||||
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer2] }]);
|
||||
|
||||
// Add the import statements back to file2
|
||||
const addFile2ImportRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
|
||||
const addFile2ImportRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
|
||||
file: file1Consumer1.path,
|
||||
line: 1,
|
||||
offset: 1,
|
||||
@@ -167,7 +169,7 @@ namespace ts.projectSystem {
|
||||
session.executeCommand(addFile2ImportRequest);
|
||||
|
||||
// Change the content of file1 to `export var T2: string;export var T: number;export function Foo() { };`
|
||||
const changeModuleFile1ShapeRequest2 = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
|
||||
const changeModuleFile1ShapeRequest2 = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
|
||||
file: moduleFile1.path,
|
||||
line: 1,
|
||||
offset: 1,
|
||||
@@ -272,7 +274,7 @@ namespace ts.projectSystem {
|
||||
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
|
||||
|
||||
openFilesForSession([globalFile3], session);
|
||||
const changeGlobalFile3ShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
|
||||
const changeGlobalFile3ShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
|
||||
file: globalFile3.path,
|
||||
line: 1,
|
||||
offset: 1,
|
||||
@@ -283,7 +285,7 @@ namespace ts.projectSystem {
|
||||
|
||||
// check after file1 shape changes
|
||||
session.executeCommand(changeGlobalFile3ShapeRequest);
|
||||
const globalFile3FileListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: globalFile3.path });
|
||||
const globalFile3FileListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: globalFile3.path });
|
||||
sendAffectedFileRequestAndCheckResult(session, globalFile3FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2] }]);
|
||||
});
|
||||
|
||||
@@ -316,7 +318,7 @@ namespace ts.projectSystem {
|
||||
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
|
||||
openFilesForSession([moduleFile1], session);
|
||||
|
||||
const file1ChangeShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
|
||||
const file1ChangeShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
|
||||
file: moduleFile1.path,
|
||||
line: 1,
|
||||
offset: 27,
|
||||
@@ -345,7 +347,7 @@ namespace ts.projectSystem {
|
||||
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
|
||||
openFilesForSession([moduleFile1], session);
|
||||
|
||||
const file1ChangeShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
|
||||
const file1ChangeShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
|
||||
file: moduleFile1.path,
|
||||
line: 1,
|
||||
offset: 27,
|
||||
@@ -369,7 +371,7 @@ namespace ts.projectSystem {
|
||||
openFilesForSession([moduleFile1, file1Consumer1], session);
|
||||
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer1Consumer1] }]);
|
||||
|
||||
const changeFile1Consumer1ShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(server.CommandNames.Change, {
|
||||
const changeFile1Consumer1ShapeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
|
||||
file: file1Consumer1.path,
|
||||
line: 2,
|
||||
offset: 1,
|
||||
@@ -400,7 +402,7 @@ namespace ts.projectSystem {
|
||||
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
|
||||
|
||||
openFilesForSession([file1, file2], session);
|
||||
const file1AffectedListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
|
||||
const file1AffectedListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
|
||||
sendAffectedFileRequestAndCheckResult(session, file1AffectedListRequest, [{ projectFileName: configFile.path, files: [file1, file2] }]);
|
||||
});
|
||||
|
||||
@@ -415,7 +417,7 @@ namespace ts.projectSystem {
|
||||
const session = createSession(host);
|
||||
|
||||
openFilesForSession([file1, file2, file3], session);
|
||||
const file1AffectedListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
|
||||
const file1AffectedListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
|
||||
|
||||
sendAffectedFileRequestAndCheckResult(session, file1AffectedListRequest, [
|
||||
{ projectFileName: configFile1.path, files: [file1, file2] },
|
||||
@@ -437,11 +439,11 @@ namespace ts.projectSystem {
|
||||
host.reloadFS([referenceFile1, configFile]);
|
||||
host.triggerFileWatcherCallback(moduleFile1.path, /*removed*/ true);
|
||||
|
||||
const request = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
|
||||
const request = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
|
||||
sendAffectedFileRequestAndCheckResult(session, request, [
|
||||
{ projectFileName: configFile.path, files: [referenceFile1] }
|
||||
]);
|
||||
const requestForMissingFile = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path });
|
||||
const requestForMissingFile = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path });
|
||||
sendAffectedFileRequestAndCheckResult(session, requestForMissingFile, []);
|
||||
});
|
||||
|
||||
@@ -456,7 +458,7 @@ namespace ts.projectSystem {
|
||||
const session = createSession(host);
|
||||
|
||||
openFilesForSession([referenceFile1], session);
|
||||
const request = makeSessionRequest<server.protocol.FileRequestArgs>(server.CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
|
||||
const request = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
|
||||
sendAffectedFileRequestAndCheckResult(session, request, [
|
||||
{ projectFileName: configFile.path, files: [referenceFile1] }
|
||||
]);
|
||||
@@ -483,7 +485,7 @@ namespace ts.projectSystem {
|
||||
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
|
||||
|
||||
openFilesForSession([file1, file2], session);
|
||||
const compileFileRequest = makeSessionRequest<server.protocol.CompileOnSaveEmitFileRequestArgs>(server.CommandNames.CompileOnSaveEmitFile, { file: file1.path, projectFileName: configFile.path });
|
||||
const compileFileRequest = makeSessionRequest<server.protocol.CompileOnSaveEmitFileRequestArgs>(CommandNames.CompileOnSaveEmitFile, { file: file1.path, projectFileName: configFile.path });
|
||||
session.executeCommand(compileFileRequest);
|
||||
|
||||
const expectedEmittedFileName = "/a/b/f1.js";
|
||||
|
||||
@@ -405,6 +405,7 @@ namespace ts {
|
||||
allowJs: true,
|
||||
maxNodeModuleJsDepth: 2,
|
||||
allowSyntheticDefaultImports: true,
|
||||
skipLibCheck: true,
|
||||
module: ModuleKind.CommonJS,
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
@@ -433,6 +434,7 @@ namespace ts {
|
||||
allowJs: false,
|
||||
maxNodeModuleJsDepth: 2,
|
||||
allowSyntheticDefaultImports: true,
|
||||
skipLibCheck: true,
|
||||
module: ModuleKind.CommonJS,
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
@@ -456,7 +458,8 @@ namespace ts {
|
||||
{
|
||||
allowJs: true,
|
||||
maxNodeModuleJsDepth: 2,
|
||||
allowSyntheticDefaultImports: true
|
||||
allowSyntheticDefaultImports: true,
|
||||
skipLibCheck: true
|
||||
},
|
||||
errors: [{
|
||||
file: undefined,
|
||||
@@ -477,7 +480,8 @@ namespace ts {
|
||||
{
|
||||
allowJs: true,
|
||||
maxNodeModuleJsDepth: 2,
|
||||
allowSyntheticDefaultImports: true
|
||||
allowSyntheticDefaultImports: true,
|
||||
skipLibCheck: true
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="../../server/typingsInstaller/typingsInstaller.ts" />
|
||||
|
||||
namespace ts.projectSystem {
|
||||
import TI = server.typingsInstaller;
|
||||
import protocol = server.protocol;
|
||||
import CommandNames = server.CommandNames;
|
||||
|
||||
const safeList = {
|
||||
path: <Path>"/safeList.json",
|
||||
@@ -128,7 +130,7 @@ namespace ts.projectSystem {
|
||||
return combinePaths(getDirectoryPath(libFile.path), "tsc.js");
|
||||
}
|
||||
|
||||
export function toExternalFile(fileName: string): server.protocol.ExternalFile {
|
||||
export function toExternalFile(fileName: string): protocol.ExternalFile {
|
||||
return { fileName };
|
||||
}
|
||||
|
||||
@@ -136,6 +138,19 @@ namespace ts.projectSystem {
|
||||
return map(fileNames, toExternalFile);
|
||||
}
|
||||
|
||||
export class TestServerEventManager {
|
||||
private events: server.ProjectServiceEvent[] = [];
|
||||
|
||||
handler: server.ProjectServiceEventHandler = (event: server.ProjectServiceEvent) => {
|
||||
this.events.push(event);
|
||||
}
|
||||
|
||||
checkEventCountOfType(eventType: "context" | "configFileDiag", expectedCount: number) {
|
||||
const eventsOfType = filter(this.events, e => e.eventName === eventType);
|
||||
assert.equal(eventsOfType.length, expectedCount, `The actual event counts of type ${eventType} is ${eventsOfType.length}, while expected ${expectedCount}`);
|
||||
}
|
||||
}
|
||||
|
||||
export interface TestServerHostCreationParameters {
|
||||
useCaseSensitiveFileNames?: boolean;
|
||||
executingFilePath?: string;
|
||||
@@ -159,11 +174,11 @@ namespace ts.projectSystem {
|
||||
return host;
|
||||
}
|
||||
|
||||
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller) {
|
||||
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler) {
|
||||
if (typingsInstaller === undefined) {
|
||||
typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
|
||||
}
|
||||
return new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
|
||||
return new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
|
||||
}
|
||||
|
||||
export interface CreateProjectServiceParameters {
|
||||
@@ -514,7 +529,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
export function makeSessionRequest<T>(command: string, args: T) {
|
||||
const newRequest: server.protocol.Request = {
|
||||
const newRequest: protocol.Request = {
|
||||
seq: 0,
|
||||
type: "request",
|
||||
command,
|
||||
@@ -525,7 +540,7 @@ namespace ts.projectSystem {
|
||||
|
||||
export function openFilesForSession(files: FileOrFolder[], session: server.Session) {
|
||||
for (const file of files) {
|
||||
const request = makeSessionRequest<server.protocol.OpenRequestArgs>(server.CommandNames.Open, { file: file.path });
|
||||
const request = makeSessionRequest<protocol.OpenRequestArgs>(CommandNames.Open, { file: file.path });
|
||||
session.executeCommand(request);
|
||||
}
|
||||
}
|
||||
@@ -1738,7 +1753,7 @@ namespace ts.projectSystem {
|
||||
});
|
||||
|
||||
describe("navigate-to for javascript project", () => {
|
||||
function containsNavToItem(items: server.protocol.NavtoItem[], itemName: string, itemKind: string) {
|
||||
function containsNavToItem(items: protocol.NavtoItem[], itemName: string, itemKind: string) {
|
||||
return find(items, item => item.name === itemName && item.kind === itemKind) !== undefined;
|
||||
}
|
||||
|
||||
@@ -1756,12 +1771,12 @@ namespace ts.projectSystem {
|
||||
openFilesForSession([file1], session);
|
||||
|
||||
// Try to find some interface type defined in lib.d.ts
|
||||
const libTypeNavToRequest = makeSessionRequest<server.protocol.NavtoRequestArgs>(server.CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path });
|
||||
const items: server.protocol.NavtoItem[] = session.executeCommand(libTypeNavToRequest).response;
|
||||
const libTypeNavToRequest = makeSessionRequest<protocol.NavtoRequestArgs>(CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path });
|
||||
const items: protocol.NavtoItem[] = session.executeCommand(libTypeNavToRequest).response;
|
||||
assert.isFalse(containsNavToItem(items, "Document", "interface"), `Found lib.d.ts symbol in JavaScript project nav to request result.`);
|
||||
|
||||
const localFunctionNavToRequst = makeSessionRequest<server.protocol.NavtoRequestArgs>(server.CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path });
|
||||
const items2: server.protocol.NavtoItem[] = session.executeCommand(localFunctionNavToRequst).response;
|
||||
const localFunctionNavToRequst = makeSessionRequest<protocol.NavtoRequestArgs>(CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path });
|
||||
const items2: protocol.NavtoItem[] = session.executeCommand(localFunctionNavToRequst).response;
|
||||
assert.isTrue(containsNavToItem(items2, "foo", "function"), `Cannot find function symbol "foo".`);
|
||||
});
|
||||
});
|
||||
@@ -1898,6 +1913,64 @@ namespace ts.projectSystem {
|
||||
projectService.closeExternalProject(projectName);
|
||||
projectService.checkNumberOfProjects({});
|
||||
});
|
||||
|
||||
it("correctly handles changes in lib section of config file", () => {
|
||||
const libES5 = {
|
||||
path: "/compiler/lib.es5.d.ts",
|
||||
content: "declare const eval: any"
|
||||
};
|
||||
const libES2015Promise = {
|
||||
path: "/compiler/lib.es2015.promise.d.ts",
|
||||
content: "declare class Promise<T> {}"
|
||||
};
|
||||
const app = {
|
||||
path: "/src/app.ts",
|
||||
content: "var x: Promise<string>;"
|
||||
};
|
||||
const config1 = {
|
||||
path: "/src/tsconfig.json",
|
||||
content: JSON.stringify(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": true,
|
||||
"sourceMap": false,
|
||||
"lib": [
|
||||
"es5"
|
||||
]
|
||||
}
|
||||
})
|
||||
};
|
||||
const config2 = {
|
||||
path: config1.path,
|
||||
content: JSON.stringify(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": true,
|
||||
"sourceMap": false,
|
||||
"lib": [
|
||||
"es5",
|
||||
"es2015.promise"
|
||||
]
|
||||
}
|
||||
})
|
||||
};
|
||||
const host = createServerHost([libES5, libES2015Promise, app, config1], { executingFilePath: "/compiler/tsc.js" });
|
||||
const projectService = createProjectService(host);
|
||||
projectService.openClientFile(app.path);
|
||||
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, app.path]);
|
||||
|
||||
host.reloadFS([libES5, libES2015Promise, app, config2]);
|
||||
host.triggerFileWatcherCallback(config1.path);
|
||||
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, libES2015Promise.path, app.path]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("prefer typings to js", () => {
|
||||
@@ -2026,7 +2099,7 @@ namespace ts.projectSystem {
|
||||
const projectFileName = "externalProject";
|
||||
const host = createServerHost([f]);
|
||||
const projectService = createProjectService(host);
|
||||
// create a project
|
||||
// create a project
|
||||
projectService.openExternalProject({ projectFileName, rootFiles: [toExternalFile(f.path)], options: {} });
|
||||
projectService.checkNumberOfProjects({ externalProjects: 1 });
|
||||
|
||||
@@ -2063,4 +2136,255 @@ namespace ts.projectSystem {
|
||||
projectService.inferredProjects[0].getLanguageService().getProgram();
|
||||
});
|
||||
});
|
||||
|
||||
describe("rename a module file and rename back", () => {
|
||||
it("should restore the states for inferred projects", () => {
|
||||
const moduleFile = {
|
||||
path: "/a/b/moduleFile.ts",
|
||||
content: "export function bar() { };"
|
||||
};
|
||||
const file1 = {
|
||||
path: "/a/b/file1.ts",
|
||||
content: "import * as T from './moduleFile'; T.bar();"
|
||||
};
|
||||
const host = createServerHost([moduleFile, file1]);
|
||||
const session = createSession(host);
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
const getErrRequest = makeSessionRequest<server.protocol.SemanticDiagnosticsSyncRequestArgs>(
|
||||
server.CommandNames.SemanticDiagnosticsSync,
|
||||
{ file: file1.path }
|
||||
);
|
||||
let diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
|
||||
assert.equal(diags.length, 0);
|
||||
|
||||
const moduleFileOldPath = moduleFile.path;
|
||||
const moduleFileNewPath = "/a/b/moduleFile1.ts";
|
||||
moduleFile.path = moduleFileNewPath;
|
||||
host.reloadFS([moduleFile, file1]);
|
||||
host.triggerFileWatcherCallback(moduleFileOldPath);
|
||||
host.triggerDirectoryWatcherCallback("/a/b", moduleFile.path);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
|
||||
assert.equal(diags.length, 1);
|
||||
|
||||
moduleFile.path = moduleFileOldPath;
|
||||
host.reloadFS([moduleFile, file1]);
|
||||
host.triggerFileWatcherCallback(moduleFileNewPath);
|
||||
host.triggerDirectoryWatcherCallback("/a/b", moduleFile.path);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
// Make a change to trigger the program rebuild
|
||||
const changeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(
|
||||
server.CommandNames.Change,
|
||||
{ file: file1.path, line: 1, offset: 44, endLine: 1, endOffset: 44, insertString: "\n" }
|
||||
);
|
||||
session.executeCommand(changeRequest);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
|
||||
assert.equal(diags.length, 0);
|
||||
});
|
||||
|
||||
it("should restore the states for configured projects", () => {
|
||||
const moduleFile = {
|
||||
path: "/a/b/moduleFile.ts",
|
||||
content: "export function bar() { };"
|
||||
};
|
||||
const file1 = {
|
||||
path: "/a/b/file1.ts",
|
||||
content: "import * as T from './moduleFile'; T.bar();"
|
||||
};
|
||||
const configFile = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: `{}`
|
||||
};
|
||||
const host = createServerHost([moduleFile, file1, configFile]);
|
||||
const session = createSession(host);
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
const getErrRequest = makeSessionRequest<server.protocol.SemanticDiagnosticsSyncRequestArgs>(
|
||||
server.CommandNames.SemanticDiagnosticsSync,
|
||||
{ file: file1.path }
|
||||
);
|
||||
let diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
|
||||
assert.equal(diags.length, 0);
|
||||
|
||||
const moduleFileOldPath = moduleFile.path;
|
||||
const moduleFileNewPath = "/a/b/moduleFile1.ts";
|
||||
moduleFile.path = moduleFileNewPath;
|
||||
host.reloadFS([moduleFile, file1, configFile]);
|
||||
host.triggerFileWatcherCallback(moduleFileOldPath);
|
||||
host.triggerDirectoryWatcherCallback("/a/b", moduleFile.path);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
|
||||
assert.equal(diags.length, 1);
|
||||
|
||||
moduleFile.path = moduleFileOldPath;
|
||||
host.reloadFS([moduleFile, file1, configFile]);
|
||||
host.triggerFileWatcherCallback(moduleFileNewPath);
|
||||
host.triggerDirectoryWatcherCallback("/a/b", moduleFile.path);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
|
||||
assert.equal(diags.length, 0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("add the missing module file for inferred project", () => {
|
||||
it("should remove the `module not found` error", () => {
|
||||
const moduleFile = {
|
||||
path: "/a/b/moduleFile.ts",
|
||||
content: "export function bar() { };"
|
||||
};
|
||||
const file1 = {
|
||||
path: "/a/b/file1.ts",
|
||||
content: "import * as T from './moduleFile'; T.bar();"
|
||||
};
|
||||
const host = createServerHost([file1]);
|
||||
const session = createSession(host);
|
||||
openFilesForSession([file1], session);
|
||||
const getErrRequest = makeSessionRequest<server.protocol.SemanticDiagnosticsSyncRequestArgs>(
|
||||
server.CommandNames.SemanticDiagnosticsSync,
|
||||
{ file: file1.path }
|
||||
);
|
||||
let diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
|
||||
assert.equal(diags.length, 1);
|
||||
|
||||
host.reloadFS([file1, moduleFile]);
|
||||
host.triggerDirectoryWatcherCallback(getDirectoryPath(file1.path), moduleFile.path);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
// Make a change to trigger the program rebuild
|
||||
const changeRequest = makeSessionRequest<server.protocol.ChangeRequestArgs>(
|
||||
server.CommandNames.Change,
|
||||
{ file: file1.path, line: 1, offset: 44, endLine: 1, endOffset: 44, insertString: "\n" }
|
||||
);
|
||||
session.executeCommand(changeRequest);
|
||||
|
||||
// Recheck
|
||||
diags = <server.protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
|
||||
assert.equal(diags.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Configure file diagnostics events", () => {
|
||||
|
||||
it("are generated when the config file has errors", () => {
|
||||
const serverEventManager = new TestServerEventManager();
|
||||
const file = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let x = 10"
|
||||
};
|
||||
const configFile = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: `{
|
||||
"compilerOptions": {
|
||||
"foo": "bar",
|
||||
"allowJS": true
|
||||
}
|
||||
}`
|
||||
};
|
||||
|
||||
const host = createServerHost([file, configFile]);
|
||||
const session = createSession(host, /*typingsInstaller*/ undefined, serverEventManager.handler);
|
||||
openFilesForSession([file], session);
|
||||
serverEventManager.checkEventCountOfType("configFileDiag", 1);
|
||||
});
|
||||
|
||||
it("are generated when the config file doesn't have errors", () => {
|
||||
const serverEventManager = new TestServerEventManager();
|
||||
const file = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let x = 10"
|
||||
};
|
||||
const configFile = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: `{
|
||||
"compilerOptions": {}
|
||||
}`
|
||||
};
|
||||
|
||||
const host = createServerHost([file, configFile]);
|
||||
const session = createSession(host, /*typingsInstaller*/ undefined, serverEventManager.handler);
|
||||
openFilesForSession([file], session);
|
||||
serverEventManager.checkEventCountOfType("configFileDiag", 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("skipLibCheck", () => {
|
||||
it("should be turned on for js-only inferred projects", () => {
|
||||
const file1 = {
|
||||
path: "/a/b/file1.js",
|
||||
content: `
|
||||
/// <reference path="file2.d.ts" />
|
||||
var x = 1;`
|
||||
};
|
||||
const file2 = {
|
||||
path: "/a/b/file2.d.ts",
|
||||
content: `
|
||||
interface T {
|
||||
name: string;
|
||||
};
|
||||
interface T {
|
||||
name: number;
|
||||
};`
|
||||
};
|
||||
const host = createServerHost([file1, file2]);
|
||||
const session = createSession(host);
|
||||
openFilesForSession([file1, file2], session);
|
||||
|
||||
const file2GetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
|
||||
CommandNames.SemanticDiagnosticsSync,
|
||||
{ file: file2.path }
|
||||
);
|
||||
let errorResult = <protocol.Diagnostic[]>session.executeCommand(file2GetErrRequest).response;
|
||||
assert.isTrue(errorResult.length === 0);
|
||||
|
||||
const closeFileRequest = makeSessionRequest<protocol.FileRequestArgs>(CommandNames.Close, { file: file1.path });
|
||||
session.executeCommand(closeFileRequest);
|
||||
errorResult = <protocol.Diagnostic[]>session.executeCommand(file2GetErrRequest).response;
|
||||
assert.isTrue(errorResult.length !== 0);
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
errorResult = <protocol.Diagnostic[]>session.executeCommand(file2GetErrRequest).response;
|
||||
assert.isTrue(errorResult.length === 0);
|
||||
});
|
||||
|
||||
it("should be turned on for js-only external projects", () => {
|
||||
const jsFile = {
|
||||
path: "/a/b/file1.js",
|
||||
content: "let x =1;"
|
||||
};
|
||||
const dTsFile = {
|
||||
path: "/a/b/file2.d.ts",
|
||||
content: `
|
||||
interface T {
|
||||
name: string;
|
||||
};
|
||||
interface T {
|
||||
name: number;
|
||||
};`
|
||||
};
|
||||
const host = createServerHost([jsFile, dTsFile]);
|
||||
const session = createSession(host);
|
||||
|
||||
const openExternalProjectRequest = makeSessionRequest<protocol.OpenExternalProjectArgs>(
|
||||
CommandNames.OpenExternalProject,
|
||||
{
|
||||
projectFileName: "project1",
|
||||
rootFiles: toExternalFiles([jsFile.path, dTsFile.path]),
|
||||
options: {}
|
||||
}
|
||||
);
|
||||
session.executeCommand(openExternalProjectRequest);
|
||||
|
||||
const dTsFileGetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
|
||||
CommandNames.SemanticDiagnosticsSync,
|
||||
{ file: dTsFile.path }
|
||||
);
|
||||
const errorResult = <protocol.Diagnostic[]>session.executeCommand(dTsFileGetErrRequest).response;
|
||||
assert.isTrue(errorResult.length === 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
/// <reference path="..\compiler\commandLineParser.ts" />
|
||||
/// <reference path="..\services\services.ts" />
|
||||
/// <reference path="protocol.d.ts" />
|
||||
/// <reference path="session.ts" />
|
||||
/// <reference types="node" />
|
||||
|
||||
|
||||
+95
-13
@@ -1,7 +1,6 @@
|
||||
/// <reference path="session.ts" />
|
||||
|
||||
namespace ts.server {
|
||||
|
||||
export interface SessionClientHost extends LanguageServiceHost {
|
||||
writeMessage(message: string): void;
|
||||
}
|
||||
@@ -425,11 +424,35 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getSyntacticDiagnostics(fileName: string): Diagnostic[] {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file: fileName };
|
||||
|
||||
const request = this.processRequest<protocol.SyntacticDiagnosticsSyncRequest>(CommandNames.SyntacticDiagnosticsSync, args);
|
||||
const response = this.processResponse<protocol.SyntacticDiagnosticsSyncResponse>(request);
|
||||
|
||||
return (<protocol.Diagnostic[]>response.body).map(entry => this.convertDiagnostic(entry, fileName));
|
||||
}
|
||||
|
||||
getSemanticDiagnostics(fileName: string): Diagnostic[] {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
const args: protocol.SemanticDiagnosticsSyncRequestArgs = { file: fileName };
|
||||
|
||||
const request = this.processRequest<protocol.SemanticDiagnosticsSyncRequest>(CommandNames.SemanticDiagnosticsSync, args);
|
||||
const response = this.processResponse<protocol.SemanticDiagnosticsSyncResponse>(request);
|
||||
|
||||
return (<protocol.Diagnostic[]>response.body).map(entry => this.convertDiagnostic(entry, fileName));
|
||||
}
|
||||
|
||||
convertDiagnostic(entry: protocol.Diagnostic, fileName: string): Diagnostic {
|
||||
const start = this.lineOffsetToPosition(fileName, entry.start);
|
||||
const end = this.lineOffsetToPosition(fileName, entry.end);
|
||||
|
||||
return {
|
||||
file: undefined,
|
||||
start: start,
|
||||
length: end - start,
|
||||
messageText: entry.text,
|
||||
category: undefined,
|
||||
code: entry.code
|
||||
};
|
||||
}
|
||||
|
||||
getCompilerOptionsDiagnostics(): Diagnostic[] {
|
||||
@@ -488,7 +511,7 @@ namespace ts.server {
|
||||
return this.lastRenameEntry.locations;
|
||||
}
|
||||
|
||||
decodeNavigationBarItems(items: protocol.NavigationBarItem[], fileName: string, lineMap: number[]): NavigationBarItem[] {
|
||||
private decodeNavigationBarItems(items: protocol.NavigationBarItem[], fileName: string, lineMap: number[]): NavigationBarItem[] {
|
||||
if (!items) {
|
||||
return [];
|
||||
}
|
||||
@@ -497,10 +520,7 @@ namespace ts.server {
|
||||
text: item.text,
|
||||
kind: item.kind,
|
||||
kindModifiers: item.kindModifiers || "",
|
||||
spans: item.spans.map(span =>
|
||||
createTextSpanFromBounds(
|
||||
this.lineOffsetToPosition(fileName, span.start, lineMap),
|
||||
this.lineOffsetToPosition(fileName, span.end, lineMap))),
|
||||
spans: item.spans.map(span => this.decodeSpan(span, fileName, lineMap)),
|
||||
childItems: this.decodeNavigationBarItems(item.childItems, fileName, lineMap),
|
||||
indent: item.indent,
|
||||
bolded: false,
|
||||
@@ -509,17 +529,37 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getNavigationBarItems(fileName: string): NavigationBarItem[] {
|
||||
const args: protocol.FileRequestArgs = {
|
||||
file: fileName
|
||||
};
|
||||
|
||||
const request = this.processRequest<protocol.NavBarRequest>(CommandNames.NavBar, args);
|
||||
const request = this.processRequest<protocol.NavBarRequest>(CommandNames.NavBar, { file: fileName });
|
||||
const response = this.processResponse<protocol.NavBarResponse>(request);
|
||||
|
||||
const lineMap = this.getLineMap(fileName);
|
||||
return this.decodeNavigationBarItems(response.body, fileName, lineMap);
|
||||
}
|
||||
|
||||
private decodeNavigationTree(tree: protocol.NavigationTree, fileName: string, lineMap: number[]): NavigationTree {
|
||||
return {
|
||||
text: tree.text,
|
||||
kind: tree.kind,
|
||||
kindModifiers: tree.kindModifiers,
|
||||
spans: tree.spans.map(span => this.decodeSpan(span, fileName, lineMap)),
|
||||
childItems: map(tree.childItems, item => this.decodeNavigationTree(item, fileName, lineMap))
|
||||
};
|
||||
}
|
||||
|
||||
getNavigationTree(fileName: string): NavigationTree {
|
||||
const request = this.processRequest<protocol.NavTreeRequest>(CommandNames.NavTree, { file: fileName });
|
||||
const response = this.processResponse<protocol.NavTreeResponse>(request);
|
||||
|
||||
const lineMap = this.getLineMap(fileName);
|
||||
return this.decodeNavigationTree(response.body, fileName, lineMap);
|
||||
}
|
||||
|
||||
private decodeSpan(span: protocol.TextSpan, fileName: string, lineMap: number[]) {
|
||||
return createTextSpanFromBounds(
|
||||
this.lineOffsetToPosition(fileName, span.start, lineMap),
|
||||
this.lineOffsetToPosition(fileName, span.end, lineMap));
|
||||
}
|
||||
|
||||
getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
}
|
||||
@@ -630,6 +670,48 @@ namespace ts.server {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
}
|
||||
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[]): CodeAction[] {
|
||||
const startLineOffset = this.positionToOneBasedLineOffset(fileName, start);
|
||||
const endLineOffset = this.positionToOneBasedLineOffset(fileName, end);
|
||||
|
||||
const args: protocol.CodeFixRequestArgs = {
|
||||
file: fileName,
|
||||
startLine: startLineOffset.line,
|
||||
startOffset: startLineOffset.offset,
|
||||
endLine: endLineOffset.line,
|
||||
endOffset: endLineOffset.offset,
|
||||
errorCodes: errorCodes,
|
||||
};
|
||||
|
||||
const request = this.processRequest<protocol.CodeFixRequest>(CommandNames.GetCodeFixes, args);
|
||||
const response = this.processResponse<protocol.CodeFixResponse>(request);
|
||||
|
||||
return response.body.map(entry => this.convertCodeActions(entry, fileName));
|
||||
}
|
||||
|
||||
convertCodeActions(entry: protocol.CodeAction, fileName: string): CodeAction {
|
||||
return {
|
||||
description: entry.description,
|
||||
changes: entry.changes.map(change => ({
|
||||
fileName: change.fileName,
|
||||
textChanges: change.textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, fileName))
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
convertTextChangeToCodeEdit(change: protocol.CodeEdit, fileName: string): ts.TextChange {
|
||||
const start = this.lineOffsetToPosition(fileName, change.start);
|
||||
const end = this.lineOffsetToPosition(fileName, change.end);
|
||||
|
||||
return {
|
||||
span: {
|
||||
start: start,
|
||||
length: end - start
|
||||
},
|
||||
newText: change.newText ? change.newText : ""
|
||||
};
|
||||
}
|
||||
|
||||
getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[] {
|
||||
const lineOffset = this.positionToOneBasedLineOffset(fileName, position);
|
||||
const args: protocol.FileLocationRequestArgs = {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/// <reference path="..\compiler\commandLineParser.ts" />
|
||||
/// <reference path="..\services\services.ts" />
|
||||
/// <reference path="protocol.d.ts" />
|
||||
/// <reference path="utilities.ts" />
|
||||
/// <reference path="session.ts" />
|
||||
/// <reference path="scriptVersionCache.ts"/>
|
||||
@@ -180,6 +179,8 @@ namespace ts.server {
|
||||
|
||||
private toCanonicalFileName: (f: string) => string;
|
||||
|
||||
public lastDeletedFile: ScriptInfo;
|
||||
|
||||
constructor(public readonly host: ServerHost,
|
||||
public readonly logger: Logger,
|
||||
public readonly cancellationToken: HostCancellationToken,
|
||||
@@ -272,7 +273,7 @@ namespace ts.server {
|
||||
else {
|
||||
projectsToUpdate = [];
|
||||
for (const f of this.changedFiles) {
|
||||
projectsToUpdate = projectsToUpdate.concat(f.containingProjects);
|
||||
projectsToUpdate = projectsToUpdate.concat(f.containingProjects);
|
||||
}
|
||||
}
|
||||
this.updateProjectGraphs(projectsToUpdate);
|
||||
@@ -342,6 +343,7 @@ namespace ts.server {
|
||||
|
||||
if (!info.isOpen) {
|
||||
this.filenameToScriptInfo.remove(info.path);
|
||||
this.lastDeletedFile = info;
|
||||
|
||||
// capture list of projects since detachAllProjects will wipe out original list
|
||||
const containingProjects = info.containingProjects.slice();
|
||||
@@ -350,6 +352,7 @@ namespace ts.server {
|
||||
|
||||
// update projects to make sure that set of referenced files is correct
|
||||
this.updateProjectGraphs(containingProjects);
|
||||
this.lastDeletedFile = undefined;
|
||||
|
||||
if (!this.eventHandler) {
|
||||
return;
|
||||
@@ -755,12 +758,14 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private reportConfigFileDiagnostics(configFileName: string, diagnostics: Diagnostic[], triggerFile?: string) {
|
||||
if (diagnostics && diagnostics.length > 0) {
|
||||
this.eventHandler({
|
||||
eventName: "configFileDiag",
|
||||
data: { configFileName, diagnostics, triggerFile }
|
||||
});
|
||||
if (!this.eventHandler) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.eventHandler({
|
||||
eventName: "configFileDiag",
|
||||
data: { configFileName, diagnostics: diagnostics || [], triggerFile }
|
||||
});
|
||||
}
|
||||
|
||||
private createAndAddConfiguredProject(configFileName: NormalizedPath, projectOptions: ProjectOptions, configFileErrors: Diagnostic[], clientFileName?: string) {
|
||||
|
||||
+13
-5
@@ -52,7 +52,7 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
private resolveNamesWithLocalCache<T extends { failedLookupLocations: string[] }, R>(
|
||||
private resolveNamesWithLocalCache<T extends { failedLookupLocations: string[] }, R extends { resolvedFileName?: string }>(
|
||||
names: string[],
|
||||
containingFile: string,
|
||||
cache: ts.FileMap<Map<T>>,
|
||||
@@ -65,6 +65,7 @@ namespace ts.server {
|
||||
const newResolutions: Map<T> = createMap<T>();
|
||||
const resolvedModules: R[] = [];
|
||||
const compilerOptions = this.getCompilationSettings();
|
||||
const lastDeletedFileName = this.project.projectService.lastDeletedFile && this.project.projectService.lastDeletedFile.fileName;
|
||||
|
||||
for (const name of names) {
|
||||
// check if this is a duplicate entry in the list
|
||||
@@ -94,8 +95,11 @@ namespace ts.server {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getResult(resolution)) {
|
||||
// TODO: consider checking failedLookupLocations
|
||||
const result = getResult(resolution);
|
||||
if (result) {
|
||||
if (result.resolvedFileName && result.resolvedFileName === lastDeletedFileName) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -171,12 +175,16 @@ namespace ts.server {
|
||||
return this.host.fileExists(path);
|
||||
}
|
||||
|
||||
readFile(fileName: string): string {
|
||||
return this.host.readFile(fileName);
|
||||
}
|
||||
|
||||
directoryExists(path: string): boolean {
|
||||
return this.host.directoryExists(path);
|
||||
}
|
||||
|
||||
readFile(fileName: string): string {
|
||||
return this.host.readFile(fileName);
|
||||
readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] {
|
||||
return this.host.readDirectory(path, extensions, exclude, include);
|
||||
}
|
||||
|
||||
getDirectories(path: string): string[] {
|
||||
|
||||
+36
-5
@@ -20,16 +20,42 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
function isJsOrDtsFile(info: ScriptInfo) {
|
||||
return info.scriptKind === ScriptKind.JS || info.scriptKind == ScriptKind.JSX || fileExtensionIs(info.fileName, ".d.ts");
|
||||
function countEachFileTypes(infos: ScriptInfo[]): { js: number, jsx: number, ts: number, tsx: number, dts: number } {
|
||||
const result = { js: 0, jsx: 0, ts: 0, tsx: 0, dts: 0 };
|
||||
for (const info of infos) {
|
||||
switch (info.scriptKind) {
|
||||
case ScriptKind.JS:
|
||||
result.js += 1;
|
||||
break;
|
||||
case ScriptKind.JSX:
|
||||
result.jsx += 1;
|
||||
break;
|
||||
case ScriptKind.TS:
|
||||
fileExtensionIs(info.fileName, ".d.ts")
|
||||
? result.dts += 1
|
||||
: result.ts += 1;
|
||||
break;
|
||||
case ScriptKind.TSX:
|
||||
result.tsx += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function hasOneOrMoreJsAndNoTsFiles(project: Project) {
|
||||
const counts = countEachFileTypes(project.getScriptInfos());
|
||||
return counts.js > 0 && counts.ts === 0 && counts.tsx === 0;
|
||||
}
|
||||
|
||||
export function allRootFilesAreJsOrDts(project: Project): boolean {
|
||||
return project.getRootScriptInfos().every(isJsOrDtsFile);
|
||||
const counts = countEachFileTypes(project.getRootScriptInfos());
|
||||
return counts.ts === 0 && counts.tsx === 0;
|
||||
}
|
||||
|
||||
export function allFilesAreJsOrDts(project: Project): boolean {
|
||||
return project.getScriptInfos().every(isJsOrDtsFile);
|
||||
const counts = countEachFileTypes(project.getScriptInfos());
|
||||
return counts.ts === 0 && counts.tsx === 0;
|
||||
}
|
||||
|
||||
export interface ProjectFilesWithTSDiagnostics extends protocol.ProjectFiles {
|
||||
@@ -71,11 +97,16 @@ namespace ts.server {
|
||||
|
||||
public typesVersion = 0;
|
||||
|
||||
public isJsOnlyProject() {
|
||||
public isNonTsProject() {
|
||||
this.updateGraph();
|
||||
return allFilesAreJsOrDts(this);
|
||||
}
|
||||
|
||||
public isJsOnlyProject() {
|
||||
this.updateGraph();
|
||||
return hasOneOrMoreJsAndNoTsFiles(this);
|
||||
}
|
||||
|
||||
constructor(
|
||||
readonly projectKind: ProjectKind,
|
||||
readonly projectService: ProjectService,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ namespace ts.server {
|
||||
|
||||
export class ScriptInfo {
|
||||
/**
|
||||
* All projects that include this file
|
||||
* All projects that include this file
|
||||
*/
|
||||
readonly containingProjects: Project[] = [];
|
||||
private formatCodeSettings: ts.FormatCodeSettings;
|
||||
@@ -91,7 +91,7 @@ namespace ts.server {
|
||||
return this.containingProjects[0];
|
||||
}
|
||||
|
||||
setFormatOptions(formatSettings: protocol.FormatOptions): void {
|
||||
setFormatOptions(formatSettings: FormatCodeSettings): void {
|
||||
if (formatSettings) {
|
||||
if (!this.formatCodeSettings) {
|
||||
this.formatCodeSettings = getDefaultFormatCodeSettings(this.host);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/// <reference path="..\compiler\commandLineParser.ts" />
|
||||
/// <reference path="..\services\services.ts" />
|
||||
/// <reference path="protocol.d.ts" />
|
||||
/// <reference path="session.ts" />
|
||||
|
||||
namespace ts.server {
|
||||
|
||||
+222
-136
@@ -1,6 +1,6 @@
|
||||
/// <reference path="..\compiler\commandLineParser.ts" />
|
||||
/// <reference path="..\compiler\commandLineParser.ts" />
|
||||
/// <reference path="..\services\services.ts" />
|
||||
/// <reference path="protocol.d.ts" />
|
||||
/// <reference path="protocol.ts" />
|
||||
/// <reference path="editorServices.ts" />
|
||||
|
||||
namespace ts.server {
|
||||
@@ -14,6 +14,17 @@ namespace ts.server {
|
||||
return ((1e9 * seconds) + nanoseconds) / 1000000.0;
|
||||
}
|
||||
|
||||
function shouldSkipSematicCheck(project: Project) {
|
||||
if (project.getCompilerOptions().skipLibCheck !== undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((project.projectKind === ProjectKind.Inferred || project.projectKind === ProjectKind.External) && project.isJsOnlyProject()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
interface FileStart {
|
||||
file: string;
|
||||
start: ILineInfo;
|
||||
@@ -44,7 +55,8 @@ namespace ts.server {
|
||||
return {
|
||||
start: scriptInfo.positionToLineOffset(diag.start),
|
||||
end: scriptInfo.positionToLineOffset(diag.start + diag.length),
|
||||
text: ts.flattenDiagnosticMessageText(diag.messageText, "\n")
|
||||
text: ts.flattenDiagnosticMessageText(diag.messageText, "\n"),
|
||||
code: diag.code
|
||||
};
|
||||
}
|
||||
|
||||
@@ -71,69 +83,74 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
export namespace CommandNames {
|
||||
export const Brace = "brace";
|
||||
export const BraceFull = "brace-full";
|
||||
export const BraceCompletion = "braceCompletion";
|
||||
export const Change = "change";
|
||||
export const Close = "close";
|
||||
export const Completions = "completions";
|
||||
export const CompletionsFull = "completions-full";
|
||||
export const CompletionDetails = "completionEntryDetails";
|
||||
export const CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList";
|
||||
export const CompileOnSaveEmitFile = "compileOnSaveEmitFile";
|
||||
export const Configure = "configure";
|
||||
export const Definition = "definition";
|
||||
export const DefinitionFull = "definition-full";
|
||||
export const Exit = "exit";
|
||||
export const Format = "format";
|
||||
export const Formatonkey = "formatonkey";
|
||||
export const FormatFull = "format-full";
|
||||
export const FormatonkeyFull = "formatonkey-full";
|
||||
export const FormatRangeFull = "formatRange-full";
|
||||
export const Geterr = "geterr";
|
||||
export const GeterrForProject = "geterrForProject";
|
||||
export const Implementation = "implementation";
|
||||
export const ImplementationFull = "implementation-full";
|
||||
export const SemanticDiagnosticsSync = "semanticDiagnosticsSync";
|
||||
export const SyntacticDiagnosticsSync = "syntacticDiagnosticsSync";
|
||||
export const NavBar = "navbar";
|
||||
export const NavBarFull = "navbar-full";
|
||||
export const Navto = "navto";
|
||||
export const NavtoFull = "navto-full";
|
||||
export const Occurrences = "occurrences";
|
||||
export const DocumentHighlights = "documentHighlights";
|
||||
export const DocumentHighlightsFull = "documentHighlights-full";
|
||||
export const Open = "open";
|
||||
export const Quickinfo = "quickinfo";
|
||||
export const QuickinfoFull = "quickinfo-full";
|
||||
export const References = "references";
|
||||
export const ReferencesFull = "references-full";
|
||||
export const Reload = "reload";
|
||||
export const Rename = "rename";
|
||||
export const RenameInfoFull = "rename-full";
|
||||
export const RenameLocationsFull = "renameLocations-full";
|
||||
export const Saveto = "saveto";
|
||||
export const SignatureHelp = "signatureHelp";
|
||||
export const SignatureHelpFull = "signatureHelp-full";
|
||||
export const TypeDefinition = "typeDefinition";
|
||||
export const ProjectInfo = "projectInfo";
|
||||
export const ReloadProjects = "reloadProjects";
|
||||
export const Unknown = "unknown";
|
||||
export const OpenExternalProject = "openExternalProject";
|
||||
export const OpenExternalProjects = "openExternalProjects";
|
||||
export const CloseExternalProject = "closeExternalProject";
|
||||
export const SynchronizeProjectList = "synchronizeProjectList";
|
||||
export const ApplyChangedToOpenFiles = "applyChangedToOpenFiles";
|
||||
export const EncodedSemanticClassificationsFull = "encodedSemanticClassifications-full";
|
||||
export const Cleanup = "cleanup";
|
||||
export const OutliningSpans = "outliningSpans";
|
||||
export const TodoComments = "todoComments";
|
||||
export const Indentation = "indentation";
|
||||
export const DocCommentTemplate = "docCommentTemplate";
|
||||
export const CompilerOptionsDiagnosticsFull = "compilerOptionsDiagnostics-full";
|
||||
export const NameOrDottedNameSpan = "nameOrDottedNameSpan";
|
||||
export const BreakpointStatement = "breakpointStatement";
|
||||
export const CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects";
|
||||
export const Brace: protocol.CommandTypes.Brace = "brace";
|
||||
export const BraceFull: protocol.CommandTypes.BraceFull = "brace-full";
|
||||
export const BraceCompletion: protocol.CommandTypes.BraceCompletion = "braceCompletion";
|
||||
export const Change: protocol.CommandTypes.Change = "change";
|
||||
export const Close: protocol.CommandTypes.Close = "close";
|
||||
export const Completions: protocol.CommandTypes.Completions = "completions";
|
||||
export const CompletionsFull: protocol.CommandTypes.CompletionsFull = "completions-full";
|
||||
export const CompletionDetails: protocol.CommandTypes.CompletionDetails = "completionEntryDetails";
|
||||
export const CompileOnSaveAffectedFileList: protocol.CommandTypes.CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList";
|
||||
export const CompileOnSaveEmitFile: protocol.CommandTypes.CompileOnSaveEmitFile = "compileOnSaveEmitFile";
|
||||
export const Configure: protocol.CommandTypes.Configure = "configure";
|
||||
export const Definition: protocol.CommandTypes.Definition = "definition";
|
||||
export const DefinitionFull: protocol.CommandTypes.DefinitionFull = "definition-full";
|
||||
export const Exit: protocol.CommandTypes.Exit = "exit";
|
||||
export const Format: protocol.CommandTypes.Format = "format";
|
||||
export const Formatonkey: protocol.CommandTypes.Formatonkey = "formatonkey";
|
||||
export const FormatFull: protocol.CommandTypes.FormatFull = "format-full";
|
||||
export const FormatonkeyFull: protocol.CommandTypes.FormatonkeyFull = "formatonkey-full";
|
||||
export const FormatRangeFull: protocol.CommandTypes.FormatRangeFull = "formatRange-full";
|
||||
export const Geterr: protocol.CommandTypes.Geterr = "geterr";
|
||||
export const GeterrForProject: protocol.CommandTypes.GeterrForProject = "geterrForProject";
|
||||
export const Implementation: protocol.CommandTypes.Implementation = "implementation";
|
||||
export const ImplementationFull: protocol.CommandTypes.ImplementationFull = "implementation-full";
|
||||
export const SemanticDiagnosticsSync: protocol.CommandTypes.SemanticDiagnosticsSync = "semanticDiagnosticsSync";
|
||||
export const SyntacticDiagnosticsSync: protocol.CommandTypes.SyntacticDiagnosticsSync = "syntacticDiagnosticsSync";
|
||||
export const NavBar: protocol.CommandTypes.NavBar = "navbar";
|
||||
export const NavBarFull: protocol.CommandTypes.NavBarFull = "navbar-full";
|
||||
export const NavTree: protocol.CommandTypes.NavTree = "navtree";
|
||||
export const NavTreeFull: protocol.CommandTypes.NavTreeFull = "navtree-full";
|
||||
export const Navto: protocol.CommandTypes.Navto = "navto";
|
||||
export const NavtoFull: protocol.CommandTypes.NavtoFull = "navto-full";
|
||||
export const Occurrences: protocol.CommandTypes.Occurrences = "occurrences";
|
||||
export const DocumentHighlights: protocol.CommandTypes.DocumentHighlights = "documentHighlights";
|
||||
export const DocumentHighlightsFull: protocol.CommandTypes.DocumentHighlightsFull = "documentHighlights-full";
|
||||
export const Open: protocol.CommandTypes.Open = "open";
|
||||
export const Quickinfo: protocol.CommandTypes.Quickinfo = "quickinfo";
|
||||
export const QuickinfoFull: protocol.CommandTypes.QuickinfoFull = "quickinfo-full";
|
||||
export const References: protocol.CommandTypes.References = "references";
|
||||
export const ReferencesFull: protocol.CommandTypes.ReferencesFull = "references-full";
|
||||
export const Reload: protocol.CommandTypes.Reload = "reload";
|
||||
export const Rename: protocol.CommandTypes.Rename = "rename";
|
||||
export const RenameInfoFull: protocol.CommandTypes.RenameInfoFull = "rename-full";
|
||||
export const RenameLocationsFull: protocol.CommandTypes.RenameLocationsFull = "renameLocations-full";
|
||||
export const Saveto: protocol.CommandTypes.Saveto = "saveto";
|
||||
export const SignatureHelp: protocol.CommandTypes.SignatureHelp = "signatureHelp";
|
||||
export const SignatureHelpFull: protocol.CommandTypes.SignatureHelpFull = "signatureHelp-full";
|
||||
export const TypeDefinition: protocol.CommandTypes.TypeDefinition = "typeDefinition";
|
||||
export const ProjectInfo: protocol.CommandTypes.ProjectInfo = "projectInfo";
|
||||
export const ReloadProjects: protocol.CommandTypes.ReloadProjects = "reloadProjects";
|
||||
export const Unknown: protocol.CommandTypes.Unknown = "unknown";
|
||||
export const OpenExternalProject: protocol.CommandTypes.OpenExternalProject = "openExternalProject";
|
||||
export const OpenExternalProjects: protocol.CommandTypes.OpenExternalProjects = "openExternalProjects";
|
||||
export const CloseExternalProject: protocol.CommandTypes.CloseExternalProject = "closeExternalProject";
|
||||
export const SynchronizeProjectList: protocol.CommandTypes.SynchronizeProjectList = "synchronizeProjectList";
|
||||
export const ApplyChangedToOpenFiles: protocol.CommandTypes.ApplyChangedToOpenFiles = "applyChangedToOpenFiles";
|
||||
export const EncodedSemanticClassificationsFull: protocol.CommandTypes.EncodedSemanticClassificationsFull = "encodedSemanticClassifications-full";
|
||||
export const Cleanup: protocol.CommandTypes.Cleanup = "cleanup";
|
||||
export const OutliningSpans: protocol.CommandTypes.OutliningSpans = "outliningSpans";
|
||||
export const TodoComments: protocol.CommandTypes.TodoComments = "todoComments";
|
||||
export const Indentation: protocol.CommandTypes.Indentation = "indentation";
|
||||
export const DocCommentTemplate: protocol.CommandTypes.DocCommentTemplate = "docCommentTemplate";
|
||||
export const CompilerOptionsDiagnosticsFull: protocol.CommandTypes.CompilerOptionsDiagnosticsFull = "compilerOptionsDiagnostics-full";
|
||||
export const NameOrDottedNameSpan: protocol.CommandTypes.NameOrDottedNameSpan = "nameOrDottedNameSpan";
|
||||
export const BreakpointStatement: protocol.CommandTypes.BreakpointStatement = "breakpointStatement";
|
||||
export const CompilerOptionsForInferredProjects: protocol.CommandTypes.CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects";
|
||||
export const GetCodeFixes: protocol.CommandTypes.GetCodeFixes = "getCodeFixes";
|
||||
export const GetCodeFixesFull: protocol.CommandTypes.GetCodeFixesFull = "getCodeFixes-full";
|
||||
export const GetSupportedCodeFixes: protocol.CommandTypes.GetSupportedCodeFixes = "getSupportedCodeFixes";
|
||||
}
|
||||
|
||||
export function formatMessage<T extends protocol.Message>(msg: T, logger: server.Logger, byteLength: (s: string, encoding: string) => number, newLine: string): string {
|
||||
@@ -155,6 +172,8 @@ namespace ts.server {
|
||||
private immediateId: any;
|
||||
private changeSeq = 0;
|
||||
|
||||
private eventHander: ProjectServiceEventHandler;
|
||||
|
||||
constructor(
|
||||
private host: ServerHost,
|
||||
cancellationToken: HostCancellationToken,
|
||||
@@ -163,17 +182,18 @@ namespace ts.server {
|
||||
private byteLength: (buf: string, encoding?: string) => number,
|
||||
private hrtime: (start?: number[]) => number[],
|
||||
protected logger: Logger,
|
||||
protected readonly canUseEvents: boolean) {
|
||||
protected readonly canUseEvents: boolean,
|
||||
eventHandler?: ProjectServiceEventHandler) {
|
||||
|
||||
const eventHandler: ProjectServiceEventHandler = canUseEvents
|
||||
? event => this.handleEvent(event)
|
||||
this.eventHander = canUseEvents
|
||||
? eventHandler || (event => this.defaultEventHandler(event))
|
||||
: undefined;
|
||||
|
||||
this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, eventHandler);
|
||||
this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, this.eventHander);
|
||||
this.gcTimer = new GcTimer(host, /*delay*/ 7000, logger);
|
||||
}
|
||||
|
||||
private handleEvent(event: ProjectServiceEvent) {
|
||||
private defaultEventHandler(event: ProjectServiceEvent) {
|
||||
switch (event.eventName) {
|
||||
case "context":
|
||||
const { project, fileName } = event.data;
|
||||
@@ -252,12 +272,13 @@ namespace ts.server {
|
||||
|
||||
private semanticCheck(file: NormalizedPath, project: Project) {
|
||||
try {
|
||||
const diags = project.getLanguageService().getSemanticDiagnostics(file);
|
||||
|
||||
if (diags) {
|
||||
const bakedDiags = diags.map((diag) => formatDiag(file, project, diag));
|
||||
this.event({ file: file, diagnostics: bakedDiags }, "semanticDiag");
|
||||
let diags: Diagnostic[] = [];
|
||||
if (!shouldSkipSematicCheck(project)) {
|
||||
diags = project.getLanguageService().getSemanticDiagnostics(file);
|
||||
}
|
||||
|
||||
const bakedDiags = diags.map((diag) => formatDiag(file, project, diag));
|
||||
this.event({ file: file, diagnostics: bakedDiags }, "semanticDiag");
|
||||
}
|
||||
catch (err) {
|
||||
this.logError(err, "semantic check");
|
||||
@@ -342,7 +363,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private getEncodedSemanticClassifications(args: protocol.FileSpanRequestArgs) {
|
||||
private getEncodedSemanticClassifications(args: protocol.EncodedSemanticClassificationsRequestArgs) {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
return project.getLanguageService().getEncodedSemanticClassifications(file, args);
|
||||
}
|
||||
@@ -351,7 +372,7 @@ namespace ts.server {
|
||||
return projectFileName && this.projectService.findProject(projectFileName);
|
||||
}
|
||||
|
||||
private getCompilerOptionsDiagnostics(args: protocol.ProjectRequestArgs) {
|
||||
private getCompilerOptionsDiagnostics(args: protocol.CompilerOptionsDiagnosticsRequestArgs) {
|
||||
const project = this.getProject(args.projectFileName);
|
||||
return this.convertToDiagnosticsWithLinePosition(project.getLanguageService().getCompilerOptionsDiagnostics(), /*scriptInfo*/ undefined);
|
||||
}
|
||||
@@ -370,6 +391,9 @@ namespace ts.server {
|
||||
|
||||
private getDiagnosticsWorker(args: protocol.FileRequestArgs, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) {
|
||||
const { project, file } = this.getFileAndProject(args);
|
||||
if (shouldSkipSematicCheck(project)) {
|
||||
return [];
|
||||
}
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
|
||||
const diagnostics = selector(project, file);
|
||||
return includeLinePosition
|
||||
@@ -547,7 +571,7 @@ namespace ts.server {
|
||||
const scriptInfo = this.projectService.getScriptInfo(args.file);
|
||||
projects = scriptInfo.containingProjects;
|
||||
}
|
||||
// ts.filter handles case when 'projects' is undefined
|
||||
// ts.filter handles case when 'projects' is undefined
|
||||
projects = filter(projects, p => p.languageServiceEnabled);
|
||||
if (!projects || !projects.length) {
|
||||
return Errors.ThrowNoProject();
|
||||
@@ -734,8 +758,11 @@ namespace ts.server {
|
||||
*/
|
||||
private openClientFile(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind) {
|
||||
const { configFileName, configFileErrors } = this.projectService.openClientFileWithNormalizedPath(fileName, fileContent, scriptKind);
|
||||
if (configFileErrors) {
|
||||
this.configFileDiagnosticEvent(fileName, configFileName, configFileErrors);
|
||||
if (this.eventHander) {
|
||||
this.eventHander({
|
||||
eventName: "configFileDiag",
|
||||
data: { fileName, configFileName, diagnostics: configFileErrors || [] }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -751,7 +778,7 @@ namespace ts.server {
|
||||
return this.getFileAndProjectWorker(args.file, args.projectFileName, /*refreshInferredProjects*/ false, errorOnMissingProject);
|
||||
}
|
||||
|
||||
private getFileAndProjectWorker(uncheckedFileName: string, projectFileName: string, refreshInferredProjects: boolean, errorOnMissingProject: boolean) {
|
||||
private getFileAndProjectWorker(uncheckedFileName: string, projectFileName: string, refreshInferredProjects: boolean, errorOnMissingProject: boolean) {
|
||||
const file = toNormalizedPath(uncheckedFileName);
|
||||
const project: Project = this.getProject(projectFileName) || this.projectService.getDefaultProjectForFile(file, refreshInferredProjects);
|
||||
if (!project && errorOnMissingProject) {
|
||||
@@ -842,13 +869,7 @@ namespace ts.server {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return edits.map((edit) => {
|
||||
return {
|
||||
start: scriptInfo.positionToLineOffset(edit.span.start),
|
||||
end: scriptInfo.positionToLineOffset(ts.textSpanEnd(edit.span)),
|
||||
newText: edit.newText ? edit.newText : ""
|
||||
};
|
||||
});
|
||||
return edits.map(edit => this.convertTextChangeToCodeEdit(edit, scriptInfo));
|
||||
}
|
||||
|
||||
private getFormattingEditsForRangeFull(args: protocol.FormatRequestArgs) {
|
||||
@@ -941,15 +962,8 @@ namespace ts.server {
|
||||
return completions.entries.reduce((result: protocol.CompletionEntry[], entry: ts.CompletionEntry) => {
|
||||
if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) {
|
||||
const { name, kind, kindModifiers, sortText, replacementSpan } = entry;
|
||||
|
||||
let convertedSpan: protocol.TextSpan = undefined;
|
||||
if (replacementSpan) {
|
||||
convertedSpan = {
|
||||
start: scriptInfo.positionToLineOffset(replacementSpan.start),
|
||||
end: scriptInfo.positionToLineOffset(replacementSpan.start + replacementSpan.length)
|
||||
};
|
||||
}
|
||||
|
||||
const convertedSpan: protocol.TextSpan =
|
||||
replacementSpan ? this.decorateSpan(replacementSpan, scriptInfo) : undefined;
|
||||
result.push({ name, kind, kindModifiers, sortText, replacementSpan: convertedSpan });
|
||||
}
|
||||
return result;
|
||||
@@ -1087,38 +1101,54 @@ namespace ts.server {
|
||||
this.projectService.closeClientFile(file);
|
||||
}
|
||||
|
||||
private decorateNavigationBarItem(project: Project, fileName: NormalizedPath, items: ts.NavigationBarItem[]): protocol.NavigationBarItem[] {
|
||||
if (!items) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(fileName);
|
||||
|
||||
return items.map(item => ({
|
||||
private decorateNavigationBarItems(items: ts.NavigationBarItem[], scriptInfo: ScriptInfo): protocol.NavigationBarItem[] {
|
||||
return map(items, item => ({
|
||||
text: item.text,
|
||||
kind: item.kind,
|
||||
kindModifiers: item.kindModifiers,
|
||||
spans: item.spans.map(span => ({
|
||||
start: scriptInfo.positionToLineOffset(span.start),
|
||||
end: scriptInfo.positionToLineOffset(ts.textSpanEnd(span))
|
||||
})),
|
||||
childItems: this.decorateNavigationBarItem(project, fileName, item.childItems),
|
||||
spans: item.spans.map(span => this.decorateSpan(span, scriptInfo)),
|
||||
childItems: this.decorateNavigationBarItems(item.childItems, scriptInfo),
|
||||
indent: item.indent
|
||||
}));
|
||||
}
|
||||
|
||||
private getNavigationBarItems(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationBarItem[] | NavigationBarItem[] {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const items = project.getLanguageService().getNavigationBarItems(file);
|
||||
if (!items) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return simplifiedResult
|
||||
? this.decorateNavigationBarItem(project, file, items)
|
||||
const items = project.getLanguageService(/*ensureSynchronized*/ false).getNavigationBarItems(file);
|
||||
return !items
|
||||
? undefined
|
||||
: simplifiedResult
|
||||
? this.decorateNavigationBarItems(items, project.getScriptInfoForNormalizedPath(file))
|
||||
: items;
|
||||
}
|
||||
|
||||
private decorateNavigationTree(tree: ts.NavigationTree, scriptInfo: ScriptInfo): protocol.NavigationTree {
|
||||
return {
|
||||
text: tree.text,
|
||||
kind: tree.kind,
|
||||
kindModifiers: tree.kindModifiers,
|
||||
spans: tree.spans.map(span => this.decorateSpan(span, scriptInfo)),
|
||||
childItems: map(tree.childItems, item => this.decorateNavigationTree(item, scriptInfo))
|
||||
};
|
||||
}
|
||||
|
||||
private decorateSpan(span: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan {
|
||||
return {
|
||||
start: scriptInfo.positionToLineOffset(span.start),
|
||||
end: scriptInfo.positionToLineOffset(ts.textSpanEnd(span))
|
||||
};
|
||||
}
|
||||
|
||||
private getNavigationTree(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationTree | NavigationTree {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const tree = project.getLanguageService(/*ensureSynchronized*/ false).getNavigationTree(file);
|
||||
return !tree
|
||||
? undefined
|
||||
: simplifiedResult
|
||||
? this.decorateNavigationTree(tree, project.getScriptInfoForNormalizedPath(file))
|
||||
: tree;
|
||||
}
|
||||
|
||||
private getNavigateToItems(args: protocol.NavtoRequestArgs, simplifiedResult: boolean): protocol.NavtoItem[] | NavigateToItem[] {
|
||||
const projects = this.getProjects(args);
|
||||
|
||||
@@ -1127,7 +1157,7 @@ namespace ts.server {
|
||||
return combineProjectOutput(
|
||||
projects,
|
||||
project => {
|
||||
const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isJsOnlyProject());
|
||||
const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject());
|
||||
if (!navItems) {
|
||||
return [];
|
||||
}
|
||||
@@ -1165,7 +1195,7 @@ namespace ts.server {
|
||||
else {
|
||||
return combineProjectOutput(
|
||||
projects,
|
||||
project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isJsOnlyProject()),
|
||||
project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject()),
|
||||
/*comparer*/ undefined,
|
||||
navigateToItemIsEqualTo);
|
||||
}
|
||||
@@ -1199,6 +1229,55 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private getSupportedCodeFixes(): string[] {
|
||||
return ts.getSupportedCodeFixes();
|
||||
}
|
||||
|
||||
private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): protocol.CodeAction[] | CodeAction[] {
|
||||
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
|
||||
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
|
||||
const startPosition = getStartPosition();
|
||||
const endPosition = getEndPosition();
|
||||
|
||||
const codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes);
|
||||
if (!codeActions) {
|
||||
return undefined;
|
||||
}
|
||||
if (simplifiedResult) {
|
||||
return codeActions.map(codeAction => this.mapCodeAction(codeAction, scriptInfo));
|
||||
}
|
||||
else {
|
||||
return codeActions;
|
||||
}
|
||||
|
||||
function getStartPosition() {
|
||||
return args.startPosition !== undefined ? args.startPosition : scriptInfo.lineOffsetToPosition(args.startLine, args.startOffset);
|
||||
}
|
||||
|
||||
function getEndPosition() {
|
||||
return args.endPosition !== undefined ? args.endPosition : scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
|
||||
}
|
||||
}
|
||||
|
||||
private mapCodeAction(codeAction: CodeAction, scriptInfo: ScriptInfo): protocol.CodeAction {
|
||||
return {
|
||||
description: codeAction.description,
|
||||
changes: codeAction.changes.map(change => ({
|
||||
fileName: change.fileName,
|
||||
textChanges: change.textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo))
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
private convertTextChangeToCodeEdit(change: ts.TextChange, scriptInfo: ScriptInfo): protocol.CodeEdit {
|
||||
return {
|
||||
start: scriptInfo.positionToLineOffset(change.span.start),
|
||||
end: scriptInfo.positionToLineOffset(change.span.start + change.span.length),
|
||||
newText: change.newText ? change.newText : ""
|
||||
};
|
||||
}
|
||||
|
||||
private getBraceMatching(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.TextSpan[] | TextSpan[] {
|
||||
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
|
||||
|
||||
@@ -1206,19 +1285,11 @@ namespace ts.server {
|
||||
const position = this.getPosition(args, scriptInfo);
|
||||
|
||||
const spans = project.getLanguageService(/*ensureSynchronized*/ false).getBraceMatchingAtPosition(file, position);
|
||||
if (!spans) {
|
||||
return undefined;
|
||||
}
|
||||
if (simplifiedResult) {
|
||||
|
||||
return spans.map(span => ({
|
||||
start: scriptInfo.positionToLineOffset(span.start),
|
||||
end: scriptInfo.positionToLineOffset(span.start + span.length)
|
||||
}));
|
||||
}
|
||||
else {
|
||||
return spans;
|
||||
}
|
||||
return !spans
|
||||
? undefined
|
||||
: simplifiedResult
|
||||
? spans.map(span => this.decorateSpan(span, scriptInfo))
|
||||
: spans;
|
||||
}
|
||||
|
||||
getDiagnosticsForProject(delay: number, fileName: string) {
|
||||
@@ -1399,7 +1470,7 @@ namespace ts.server {
|
||||
[CommandNames.BraceCompletion]: (request: protocol.BraceCompletionRequest) => {
|
||||
return this.requiredResponse(this.isValidBraceCompletion(request.arguments));
|
||||
},
|
||||
[CommandNames.DocCommentTemplate]: (request: protocol.FileLocationRequest) => {
|
||||
[CommandNames.DocCommentTemplate]: (request: protocol.DocCommentTemplateRequest) => {
|
||||
return this.requiredResponse(this.getDocCommentTemplate(request.arguments));
|
||||
},
|
||||
[CommandNames.Format]: (request: protocol.FormatRequest) => {
|
||||
@@ -1438,10 +1509,10 @@ namespace ts.server {
|
||||
[CommandNames.SignatureHelpFull]: (request: protocol.SignatureHelpRequest) => {
|
||||
return this.requiredResponse(this.getSignatureHelpItems(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
[CommandNames.CompilerOptionsDiagnosticsFull]: (request: protocol.ProjectRequest) => {
|
||||
[CommandNames.CompilerOptionsDiagnosticsFull]: (request: protocol.CompilerOptionsDiagnosticsRequest) => {
|
||||
return this.requiredResponse(this.getCompilerOptionsDiagnostics(request.arguments));
|
||||
},
|
||||
[CommandNames.EncodedSemanticClassificationsFull]: (request: protocol.FileSpanRequest) => {
|
||||
[CommandNames.EncodedSemanticClassificationsFull]: (request: protocol.EncodedSemanticClassificationsRequest) => {
|
||||
return this.requiredResponse(this.getEncodedSemanticClassifications(request.arguments));
|
||||
},
|
||||
[CommandNames.Cleanup]: (request: protocol.Request) => {
|
||||
@@ -1503,6 +1574,12 @@ namespace ts.server {
|
||||
[CommandNames.NavBarFull]: (request: protocol.FileRequest) => {
|
||||
return this.requiredResponse(this.getNavigationBarItems(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
[CommandNames.NavTree]: (request: protocol.FileRequest) => {
|
||||
return this.requiredResponse(this.getNavigationTree(request.arguments, /*simplifiedResult*/ true));
|
||||
},
|
||||
[CommandNames.NavTreeFull]: (request: protocol.FileRequest) => {
|
||||
return this.requiredResponse(this.getNavigationTree(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
[CommandNames.Occurrences]: (request: protocol.FileLocationRequest) => {
|
||||
return this.requiredResponse(this.getOccurrences(request.arguments));
|
||||
},
|
||||
@@ -1521,6 +1598,15 @@ namespace ts.server {
|
||||
[CommandNames.ReloadProjects]: (request: protocol.ReloadProjectsRequest) => {
|
||||
this.projectService.reloadProjects();
|
||||
return this.notRequired();
|
||||
},
|
||||
[CommandNames.GetCodeFixes]: (request: protocol.CodeFixRequest) => {
|
||||
return this.requiredResponse(this.getCodeFixes(request.arguments, /*simplifiedResult*/ true));
|
||||
},
|
||||
[CommandNames.GetCodeFixesFull]: (request: protocol.CodeFixRequest) => {
|
||||
return this.requiredResponse(this.getCodeFixes(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
[CommandNames.GetSupportedCodeFixes]: (request: protocol.Request) => {
|
||||
return this.requiredResponse(this.getSupportedCodeFixes());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"typingsCache.ts",
|
||||
"project.ts",
|
||||
"editorServices.ts",
|
||||
"protocol.d.ts",
|
||||
"protocol.ts",
|
||||
"session.ts",
|
||||
"server.ts"
|
||||
]
|
||||
|
||||
+44
-42
@@ -157,51 +157,53 @@ namespace ts.server {
|
||||
}
|
||||
};
|
||||
}
|
||||
function throwLanguageServiceIsDisabledError() {
|
||||
function throwLanguageServiceIsDisabledError(): never {
|
||||
throw new Error("LanguageService is disabled");
|
||||
}
|
||||
|
||||
export const nullLanguageService: LanguageService = {
|
||||
cleanupSemanticCache: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getSyntacticDiagnostics: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getSemanticDiagnostics: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getCompilerOptionsDiagnostics: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getSyntacticClassifications: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getEncodedSyntacticClassifications: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getSemanticClassifications: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getEncodedSemanticClassifications: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getCompletionsAtPosition: (): any => throwLanguageServiceIsDisabledError(),
|
||||
findReferences: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getCompletionEntryDetails: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getQuickInfoAtPosition: (): any => throwLanguageServiceIsDisabledError(),
|
||||
findRenameLocations: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getNameOrDottedNameSpan: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getBreakpointStatementAtPosition: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getBraceMatchingAtPosition: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getSignatureHelpItems: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getDefinitionAtPosition: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getRenameInfo: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getTypeDefinitionAtPosition: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getReferencesAtPosition: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getDocumentHighlights: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getOccurrencesAtPosition: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getNavigateToItems: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getNavigationBarItems: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getOutliningSpans: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getTodoComments: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getIndentationAtPosition: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getFormattingEditsForRange: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getFormattingEditsForDocument: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getFormattingEditsAfterKeystroke: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getDocCommentTemplateAtPosition: (): any => throwLanguageServiceIsDisabledError(),
|
||||
isValidBraceCompletionAtPosition: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getEmitOutput: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getProgram: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getNonBoundSourceFile: (): any => throwLanguageServiceIsDisabledError(),
|
||||
dispose: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getCompletionEntrySymbol: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getImplementationAtPosition: (): any => throwLanguageServiceIsDisabledError(),
|
||||
getSourceFile: (): any => throwLanguageServiceIsDisabledError()
|
||||
cleanupSemanticCache: throwLanguageServiceIsDisabledError,
|
||||
getSyntacticDiagnostics: throwLanguageServiceIsDisabledError,
|
||||
getSemanticDiagnostics: throwLanguageServiceIsDisabledError,
|
||||
getCompilerOptionsDiagnostics: throwLanguageServiceIsDisabledError,
|
||||
getSyntacticClassifications: throwLanguageServiceIsDisabledError,
|
||||
getEncodedSyntacticClassifications: throwLanguageServiceIsDisabledError,
|
||||
getSemanticClassifications: throwLanguageServiceIsDisabledError,
|
||||
getEncodedSemanticClassifications: throwLanguageServiceIsDisabledError,
|
||||
getCompletionsAtPosition: throwLanguageServiceIsDisabledError,
|
||||
findReferences: throwLanguageServiceIsDisabledError,
|
||||
getCompletionEntryDetails: throwLanguageServiceIsDisabledError,
|
||||
getQuickInfoAtPosition: throwLanguageServiceIsDisabledError,
|
||||
findRenameLocations: throwLanguageServiceIsDisabledError,
|
||||
getNameOrDottedNameSpan: throwLanguageServiceIsDisabledError,
|
||||
getBreakpointStatementAtPosition: throwLanguageServiceIsDisabledError,
|
||||
getBraceMatchingAtPosition: throwLanguageServiceIsDisabledError,
|
||||
getSignatureHelpItems: throwLanguageServiceIsDisabledError,
|
||||
getDefinitionAtPosition: throwLanguageServiceIsDisabledError,
|
||||
getRenameInfo: throwLanguageServiceIsDisabledError,
|
||||
getTypeDefinitionAtPosition: throwLanguageServiceIsDisabledError,
|
||||
getReferencesAtPosition: throwLanguageServiceIsDisabledError,
|
||||
getDocumentHighlights: throwLanguageServiceIsDisabledError,
|
||||
getOccurrencesAtPosition: throwLanguageServiceIsDisabledError,
|
||||
getNavigateToItems: throwLanguageServiceIsDisabledError,
|
||||
getNavigationBarItems: throwLanguageServiceIsDisabledError,
|
||||
getNavigationTree: throwLanguageServiceIsDisabledError,
|
||||
getOutliningSpans: throwLanguageServiceIsDisabledError,
|
||||
getTodoComments: throwLanguageServiceIsDisabledError,
|
||||
getIndentationAtPosition: throwLanguageServiceIsDisabledError,
|
||||
getFormattingEditsForRange: throwLanguageServiceIsDisabledError,
|
||||
getFormattingEditsForDocument: throwLanguageServiceIsDisabledError,
|
||||
getFormattingEditsAfterKeystroke: throwLanguageServiceIsDisabledError,
|
||||
getDocCommentTemplateAtPosition: throwLanguageServiceIsDisabledError,
|
||||
isValidBraceCompletionAtPosition: throwLanguageServiceIsDisabledError,
|
||||
getEmitOutput: throwLanguageServiceIsDisabledError,
|
||||
getProgram: throwLanguageServiceIsDisabledError,
|
||||
getNonBoundSourceFile: throwLanguageServiceIsDisabledError,
|
||||
dispose: throwLanguageServiceIsDisabledError,
|
||||
getCompletionEntrySymbol: throwLanguageServiceIsDisabledError,
|
||||
getImplementationAtPosition: throwLanguageServiceIsDisabledError,
|
||||
getSourceFile: throwLanguageServiceIsDisabledError,
|
||||
getCodeFixesAtPosition: throwLanguageServiceIsDisabledError
|
||||
};
|
||||
|
||||
export interface ServerLanguageServiceHost {
|
||||
@@ -248,7 +250,7 @@ namespace ts.server {
|
||||
// another operation was already scheduled for this id - cancel it
|
||||
this.host.clearTimeout(this.pendingTimeouts[operationId]);
|
||||
}
|
||||
// schedule new operation, pass arguments
|
||||
// schedule new operation, pass arguments
|
||||
this.pendingTimeouts[operationId] = this.host.setTimeout(ThrottledOperations.run, delay, this, operationId, cb);
|
||||
}
|
||||
|
||||
|
||||
@@ -954,8 +954,7 @@ namespace ts {
|
||||
return;
|
||||
case SyntaxKind.Parameter:
|
||||
if ((<ParameterDeclaration>token.parent).name === token) {
|
||||
const isThis = token.kind === SyntaxKind.Identifier && (<Identifier>token).originalKeywordKind === SyntaxKind.ThisKeyword;
|
||||
return isThis ? ClassificationType.keyword : ClassificationType.parameterName;
|
||||
return isThisIdentifier(token) ? ClassificationType.keyword : ClassificationType.parameterName;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export interface CodeFix {
|
||||
errorCodes: number[];
|
||||
getCodeActions(context: CodeFixContext): CodeAction[] | undefined;
|
||||
}
|
||||
|
||||
export interface CodeFixContext {
|
||||
errorCode: number;
|
||||
sourceFile: SourceFile;
|
||||
span: TextSpan;
|
||||
program: Program;
|
||||
newLineCharacter: string;
|
||||
}
|
||||
|
||||
export namespace codefix {
|
||||
const codeFixes = createMap<CodeFix[]>();
|
||||
|
||||
export function registerCodeFix(action: CodeFix) {
|
||||
forEach(action.errorCodes, error => {
|
||||
let fixes = codeFixes[error];
|
||||
if (!fixes) {
|
||||
fixes = [];
|
||||
codeFixes[error] = fixes;
|
||||
}
|
||||
fixes.push(action);
|
||||
});
|
||||
}
|
||||
|
||||
export function getSupportedErrorCodes() {
|
||||
return Object.keys(codeFixes);
|
||||
}
|
||||
|
||||
export function getFixes(context: CodeFixContext): CodeAction[] {
|
||||
const fixes = codeFixes[context.errorCode];
|
||||
let allActions: CodeAction[] = [];
|
||||
|
||||
forEach(fixes, f => {
|
||||
const actions = f.getCodeActions(context);
|
||||
if (actions && actions.length > 0) {
|
||||
allActions = allActions.concat(actions);
|
||||
}
|
||||
});
|
||||
|
||||
return allActions;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
///<reference path='superFixes.ts' />
|
||||
@@ -0,0 +1,81 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
function getOpenBraceEnd(constructor: ConstructorDeclaration, sourceFile: SourceFile) {
|
||||
// First token is the open curly, this is where we want to put the 'super' call.
|
||||
return constructor.body.getFirstToken(sourceFile).getEnd();
|
||||
}
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call.code],
|
||||
getCodeActions: (context: CodeFixContext) => {
|
||||
const sourceFile = context.sourceFile;
|
||||
const token = getTokenAtPosition(sourceFile, context.span.start);
|
||||
|
||||
if (token.kind !== SyntaxKind.ConstructorKeyword) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const newPosition = getOpenBraceEnd(<ConstructorDeclaration>token.parent, sourceFile);
|
||||
return [{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Add_missing_super_call),
|
||||
changes: [{ fileName: sourceFile.fileName, textChanges: [{ newText: "super();", span: { start: newPosition, length: 0 } }] }]
|
||||
}];
|
||||
}
|
||||
});
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class.code],
|
||||
getCodeActions: (context: CodeFixContext) => {
|
||||
const sourceFile = context.sourceFile;
|
||||
|
||||
const token = getTokenAtPosition(sourceFile, context.span.start);
|
||||
if (token.kind !== SyntaxKind.ThisKeyword) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const constructor = getContainingFunction(token);
|
||||
const superCall = findSuperCall((<ConstructorDeclaration>constructor).body);
|
||||
if (!superCall) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// figure out if the this access is actuall inside the supercall
|
||||
// i.e. super(this.a), since in that case we won't suggest a fix
|
||||
if (superCall.expression && superCall.expression.kind == SyntaxKind.CallExpression) {
|
||||
const arguments = (<CallExpression>superCall.expression).arguments;
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
if ((<PropertyAccessExpression>arguments[i]).expression === token) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const newPosition = getOpenBraceEnd(<ConstructorDeclaration>constructor, sourceFile);
|
||||
const changes = [{
|
||||
fileName: sourceFile.fileName, textChanges: [{
|
||||
newText: superCall.getText(sourceFile),
|
||||
span: { start: newPosition, length: 0 }
|
||||
},
|
||||
{
|
||||
newText: "",
|
||||
span: { start: superCall.getStart(sourceFile), length: superCall.getWidth(sourceFile) }
|
||||
}]
|
||||
}];
|
||||
|
||||
return [{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Make_super_call_the_first_statement_in_the_constructor),
|
||||
changes
|
||||
}];
|
||||
|
||||
function findSuperCall(n: Node): ExpressionStatement {
|
||||
if (n.kind === SyntaxKind.ExpressionStatement && isSuperCall((<ExpressionStatement>n).expression)) {
|
||||
return <ExpressionStatement>n;
|
||||
}
|
||||
if (isFunctionLike(n)) {
|
||||
return undefined;
|
||||
}
|
||||
return forEachChild(n, findSuperCall);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
+56
-20
@@ -24,7 +24,7 @@ namespace ts.Completions {
|
||||
const entries: CompletionEntry[] = [];
|
||||
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ false);
|
||||
const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true);
|
||||
addRange(entries, getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames));
|
||||
}
|
||||
else {
|
||||
@@ -138,7 +138,9 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (node.parent.kind === SyntaxKind.PropertyAssignment && node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
if (node.parent.kind === SyntaxKind.PropertyAssignment &&
|
||||
node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression &&
|
||||
(<PropertyAssignment>node.parent).name === node) {
|
||||
// Get quoted name of properties of the object literal expression
|
||||
// i.e. interface ConfigFiles {
|
||||
// 'jspm:dev': string
|
||||
@@ -323,15 +325,28 @@ namespace ts.Completions {
|
||||
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, 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 = "./";
|
||||
}
|
||||
else {
|
||||
fragment = ensureTrailingDirectorySeparator(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());
|
||||
@@ -341,6 +356,12 @@ namespace ts.Completions {
|
||||
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);
|
||||
@@ -537,36 +558,44 @@ namespace ts.Completions {
|
||||
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);
|
||||
let entries: CompletionEntry[];
|
||||
if (kind === "path") {
|
||||
// Give completions for a relative path
|
||||
const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
|
||||
entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/true, span, sourceFile.path);
|
||||
completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/true, span, sourceFile.path);
|
||||
}
|
||||
else {
|
||||
// Give completions based on the typings available
|
||||
const span: TextSpan = { start: range.pos + prefix.length, length: match[0].length - prefix.length };
|
||||
entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span);
|
||||
completionInfo.entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span);
|
||||
}
|
||||
|
||||
return {
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
isNewIdentifierLocation: true,
|
||||
entries
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return completionInfo;
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] {
|
||||
@@ -1001,6 +1030,7 @@ namespace ts.Completions {
|
||||
if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) {
|
||||
// Cursor is inside a JSX self-closing element or opening element
|
||||
attrsType = typeChecker.getJsxElementAttributesType(<JsxOpeningLikeElement>jsxContainer);
|
||||
isGlobalCompletion = false;
|
||||
|
||||
if (attrsType) {
|
||||
symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (<JsxOpeningLikeElement>jsxContainer).attributes);
|
||||
@@ -1671,9 +1701,15 @@ 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
|
||||
* For example, this matches
|
||||
*
|
||||
* /// <reference path="fragment
|
||||
*
|
||||
* but not
|
||||
*
|
||||
* /// <reference path="fragment"
|
||||
*/
|
||||
const tripleSlashDirectiveFragmentRegex = /^(\/\/\/\s*<reference\s+(path|types)\s*=\s*(?:'|"))([^\3]*)$/;
|
||||
const tripleSlashDirectiveFragmentRegex = /^(\/\/\/\s*<reference\s+(path|types)\s*=\s*(?:'|"))([^\3"]*)$/;
|
||||
|
||||
interface VisibleModuleInfo {
|
||||
moduleName: string;
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace ts.formatting {
|
||||
return rangeContainsRange((<InterfaceDeclaration>parent).members, node);
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
const body = (<ModuleDeclaration>parent).body;
|
||||
return body && body.kind === SyntaxKind.Block && rangeContainsRange((<Block>body).statements, node);
|
||||
return body && body.kind === SyntaxKind.ModuleBlock && rangeContainsRange((<ModuleBlock>body).statements, node);
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.Block:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
|
||||
@@ -332,7 +332,7 @@ namespace ts.formatting {
|
||||
(<CallExpression>node.parent).expression !== node) {
|
||||
|
||||
const fullCallOrNewExpression = (<CallExpression | NewExpression>node.parent).expression;
|
||||
const startingExpression = getStartingExpression(<PropertyAccessExpression | CallExpression | ElementAccessExpression>fullCallOrNewExpression);
|
||||
const startingExpression = getStartingExpression(fullCallOrNewExpression);
|
||||
|
||||
if (fullCallOrNewExpression === startingExpression) {
|
||||
return Value.Unknown;
|
||||
@@ -350,15 +350,14 @@ namespace ts.formatting {
|
||||
|
||||
return Value.Unknown;
|
||||
|
||||
function getStartingExpression(node: PropertyAccessExpression | CallExpression | ElementAccessExpression) {
|
||||
function getStartingExpression(node: Expression) {
|
||||
while (true) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
|
||||
node = <PropertyAccessExpression | CallExpression | ElementAccessExpression | PropertyAccessExpression>node.expression;
|
||||
node = (<PropertyAccessExpression | CallExpression | NewExpression | ElementAccessExpression | PropertyAccessExpression>node).expression;
|
||||
break;
|
||||
default:
|
||||
return node;
|
||||
|
||||
@@ -21,6 +21,13 @@ namespace ts.NavigationBar {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getNavigationTree(sourceFile: SourceFile): NavigationTree {
|
||||
curSourceFile = sourceFile;
|
||||
const result = convertToTree(rootNavigationBarNode(sourceFile));
|
||||
curSourceFile = undefined;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Keep sourceFile handy so we don't have to search for it every time we need to call `getText`.
|
||||
let curSourceFile: SourceFile;
|
||||
function nodeText(node: Node): string {
|
||||
@@ -324,7 +331,7 @@ namespace ts.NavigationBar {
|
||||
}
|
||||
|
||||
// More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
|
||||
const collator: { compare(a: string, b: string): number } = typeof Intl === "undefined" ? undefined : new Intl.Collator();
|
||||
const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined;
|
||||
// Intl is missing in Safari, and node 0.10 treats "a" as greater than "B".
|
||||
const localeCompareIsCorrect = collator && collator.compare("a", "B") < 0;
|
||||
const localeCompareFix: (a: string, b: string) => number = localeCompareIsCorrect ? collator.compare : function(a, b) {
|
||||
@@ -502,6 +509,16 @@ namespace ts.NavigationBar {
|
||||
// NavigationBarItem requires an array, but will not mutate it, so just give it this for performance.
|
||||
const emptyChildItemArray: NavigationBarItem[] = [];
|
||||
|
||||
function convertToTree(n: NavigationBarNode): NavigationTree {
|
||||
return {
|
||||
text: getItemName(n.node),
|
||||
kind: getNodeKind(n.node),
|
||||
kindModifiers: getNodeModifiers(n.node),
|
||||
spans: getSpans(n),
|
||||
childItems: map(n.children, convertToTree)
|
||||
};
|
||||
}
|
||||
|
||||
function convertToTopLevelItem(n: NavigationBarNode): NavigationBarItem {
|
||||
return {
|
||||
text: getItemName(n.node),
|
||||
@@ -526,16 +543,16 @@ namespace ts.NavigationBar {
|
||||
grayed: false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getSpans(n: NavigationBarNode): TextSpan[] {
|
||||
const spans = [getNodeSpan(n.node)];
|
||||
if (n.additionalNodes) {
|
||||
for (const node of n.additionalNodes) {
|
||||
spans.push(getNodeSpan(node));
|
||||
}
|
||||
function getSpans(n: NavigationBarNode): TextSpan[] {
|
||||
const spans = [getNodeSpan(n.node)];
|
||||
if (n.additionalNodes) {
|
||||
for (const node of n.additionalNodes) {
|
||||
spans.push(getNodeSpan(node));
|
||||
}
|
||||
return spans;
|
||||
}
|
||||
return spans;
|
||||
}
|
||||
|
||||
function getModuleName(moduleDeclaration: ModuleDeclaration): string {
|
||||
|
||||
+75
-14
@@ -24,14 +24,16 @@
|
||||
/// <reference path='transpile.ts' />
|
||||
/// <reference path='formatting\formatting.ts' />
|
||||
/// <reference path='formatting\smartIndenter.ts' />
|
||||
/// <reference path='codefixes\codeFixProvider.ts' />
|
||||
/// <reference path='codefixes\fixes.ts' />
|
||||
|
||||
namespace ts {
|
||||
/** The version of the language service API */
|
||||
export const servicesVersion = "0.5";
|
||||
|
||||
function createNode(kind: SyntaxKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject | IdentifierObject {
|
||||
function createNode<TKind extends SyntaxKind>(kind: TKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject<TKind> | IdentifierObject {
|
||||
const node = kind >= SyntaxKind.FirstNode ? new NodeObject(kind, pos, end) :
|
||||
kind === SyntaxKind.Identifier ? new IdentifierObject(kind, pos, end) :
|
||||
kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) :
|
||||
new TokenObject(kind, pos, end);
|
||||
node.parent = parent;
|
||||
return node;
|
||||
@@ -210,14 +212,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
class TokenOrIdentifierObject implements Token {
|
||||
class TokenOrIdentifierObject implements Node {
|
||||
public kind: SyntaxKind;
|
||||
public pos: number;
|
||||
public end: number;
|
||||
public flags: NodeFlags;
|
||||
public parent: Node;
|
||||
public jsDocComments: JSDoc[];
|
||||
public __tokenTag: any;
|
||||
|
||||
constructor(pos: number, end: number) {
|
||||
// Set properties in same order as NodeObject
|
||||
@@ -319,16 +320,25 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
class TokenObject extends TokenOrIdentifierObject {
|
||||
public kind: SyntaxKind;
|
||||
constructor(kind: SyntaxKind, pos: number, end: number) {
|
||||
class TokenObject<TKind extends SyntaxKind> extends TokenOrIdentifierObject implements Token<TKind> {
|
||||
public kind: TKind;
|
||||
|
||||
constructor(kind: TKind, pos: number, end: number) {
|
||||
super(pos, end);
|
||||
this.kind = kind;
|
||||
}
|
||||
}
|
||||
|
||||
class IdentifierObject extends TokenOrIdentifierObject {
|
||||
constructor(kind: SyntaxKind, pos: number, end: number) {
|
||||
class IdentifierObject extends TokenOrIdentifierObject implements Identifier {
|
||||
public kind: SyntaxKind.Identifier;
|
||||
public text: string;
|
||||
_primaryExpressionBrand: any;
|
||||
_memberExpressionBrand: any;
|
||||
_leftHandSideExpressionBrand: any;
|
||||
_incrementExpressionBrand: any;
|
||||
_unaryExpressionBrand: any;
|
||||
_expressionBrand: any;
|
||||
constructor(kind: SyntaxKind.Identifier, pos: number, end: number) {
|
||||
super(pos, end);
|
||||
}
|
||||
}
|
||||
@@ -424,6 +434,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
class SourceFileObject extends NodeObject implements SourceFile {
|
||||
public kind: SyntaxKind.SourceFile;
|
||||
public _declarationBrand: any;
|
||||
public fileName: string;
|
||||
public path: Path;
|
||||
@@ -432,7 +443,7 @@ namespace ts {
|
||||
public lineMap: number[];
|
||||
|
||||
public statements: NodeArray<Statement>;
|
||||
public endOfFileToken: Node;
|
||||
public endOfFileToken: Token<SyntaxKind.EndOfFileToken>;
|
||||
|
||||
public amdDependencies: { name: string; path: string }[];
|
||||
public moduleName: string;
|
||||
@@ -655,6 +666,7 @@ namespace ts {
|
||||
return {
|
||||
getNodeConstructor: () => NodeObject,
|
||||
getTokenConstructor: () => TokenObject,
|
||||
|
||||
getIdentifierConstructor: () => IdentifierObject,
|
||||
getSourceFileConstructor: () => SourceFileObject,
|
||||
getSymbolConstructor: () => SymbolObject,
|
||||
@@ -721,9 +733,13 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
// Cache host information about script should be refreshed
|
||||
export function getSupportedCodeFixes() {
|
||||
return codefix.getSupportedErrorCodes();
|
||||
}
|
||||
|
||||
// Cache host information about script Should be refreshed
|
||||
// at each language service public entry point, since we don't know when
|
||||
// set of scripts handled by the host changes.
|
||||
// the set of scripts handled by the host changes.
|
||||
class HostCache {
|
||||
private fileNameToEntry: FileMap<HostFileInformation>;
|
||||
private _compilationSettings: CompilerOptions;
|
||||
@@ -1507,17 +1523,32 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getNavigationBarItems(fileName: string): NavigationBarItem[] {
|
||||
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName));
|
||||
}
|
||||
|
||||
return NavigationBar.getNavigationBarItems(sourceFile);
|
||||
function getNavigationTree(fileName: string): NavigationTree {
|
||||
return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName));
|
||||
}
|
||||
|
||||
function isTsOrTsxFile(fileName: string): boolean {
|
||||
const kind = getScriptKind(fileName, host);
|
||||
return kind === ScriptKind.TS || kind === ScriptKind.TSX;
|
||||
}
|
||||
|
||||
function getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] {
|
||||
if (!isTsOrTsxFile(fileName)) {
|
||||
// do not run semantic classification on non-ts-or-tsx files
|
||||
return [];
|
||||
}
|
||||
synchronizeHostData();
|
||||
return ts.getSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span);
|
||||
}
|
||||
|
||||
function getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications {
|
||||
if (!isTsOrTsxFile(fileName)) {
|
||||
// do not run semantic classification on non-ts-or-tsx files
|
||||
return { spans: [], endOfLineState: EndOfLineState.None };
|
||||
}
|
||||
synchronizeHostData();
|
||||
return ts.getEncodedSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span);
|
||||
}
|
||||
@@ -1632,6 +1663,34 @@ namespace ts {
|
||||
return [];
|
||||
}
|
||||
|
||||
function getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[]): CodeAction[] {
|
||||
synchronizeHostData();
|
||||
const sourceFile = getValidSourceFile(fileName);
|
||||
const span = { start, length: end - start };
|
||||
const newLineChar = getNewLineOrDefaultFromHost(host);
|
||||
|
||||
let allFixes: CodeAction[] = [];
|
||||
|
||||
forEach(errorCodes, error => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
const context = {
|
||||
errorCode: error,
|
||||
sourceFile: sourceFile,
|
||||
span: span,
|
||||
program: program,
|
||||
newLineCharacter: newLineChar
|
||||
};
|
||||
|
||||
const fixes = codefix.getFixes(context);
|
||||
if (fixes) {
|
||||
allFixes = allFixes.concat(fixes);
|
||||
}
|
||||
});
|
||||
|
||||
return allFixes;
|
||||
}
|
||||
|
||||
function getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion {
|
||||
return JsDoc.getDocCommentTemplateAtPosition(getNewLineOrDefaultFromHost(host), syntaxTreeCache.getCurrentSourceFile(fileName), position);
|
||||
}
|
||||
@@ -1846,6 +1905,7 @@ namespace ts {
|
||||
getRenameInfo,
|
||||
findRenameLocations,
|
||||
getNavigationBarItems,
|
||||
getNavigationTree,
|
||||
getOutliningSpans,
|
||||
getTodoComments,
|
||||
getBraceMatchingAtPosition,
|
||||
@@ -1855,6 +1915,7 @@ namespace ts {
|
||||
getFormattingEditsAfterKeystroke,
|
||||
getDocCommentTemplateAtPosition,
|
||||
isValidBraceCompletionAtPosition,
|
||||
getCodeFixesAtPosition,
|
||||
getEmitOutput,
|
||||
getNonBoundSourceFile,
|
||||
getSourceFile,
|
||||
|
||||
@@ -224,6 +224,9 @@ namespace ts {
|
||||
*/
|
||||
getNavigationBarItems(fileName: string): string;
|
||||
|
||||
/** Returns a JSON-encoded value of the type ts.NavigationTree. */
|
||||
getNavigationTree(fileName: string): string;
|
||||
|
||||
/**
|
||||
* Returns a JSON-encoded value of the type:
|
||||
* { textSpan: { start: number, length: number }; hintSpan: { start: number, length: number }; bannerText: string; autoCollapse: boolean } [] = [];
|
||||
@@ -971,6 +974,13 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
public getNavigationTree(fileName: string): string {
|
||||
return this.forwardJSONCall(
|
||||
`getNavigationTree('${fileName}')`,
|
||||
() => this.languageService.getNavigationTree(fileName)
|
||||
);
|
||||
}
|
||||
|
||||
public getOutliningSpans(fileName: string): string {
|
||||
return this.forwardJSONCall(
|
||||
`getOutliningSpans('${fileName}')`,
|
||||
|
||||
@@ -114,12 +114,12 @@ namespace ts.SymbolDisplay {
|
||||
}
|
||||
|
||||
// try get the call/construct signature from the type if it matches
|
||||
let callExpression: CallExpression;
|
||||
let callExpression: CallExpression | NewExpression;
|
||||
if (location.kind === SyntaxKind.CallExpression || location.kind === SyntaxKind.NewExpression) {
|
||||
callExpression = <CallExpression>location;
|
||||
callExpression = <CallExpression | NewExpression>location;
|
||||
}
|
||||
else if (isCallExpressionTarget(location) || isNewExpressionTarget(location)) {
|
||||
callExpression = <CallExpression>location.parent;
|
||||
callExpression = <CallExpression | NewExpression>location.parent;
|
||||
}
|
||||
|
||||
if (callExpression) {
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
"formatting/rulesMap.ts",
|
||||
"formatting/rulesProvider.ts",
|
||||
"formatting/smartIndenter.ts",
|
||||
"formatting/tokenRange.ts"
|
||||
"formatting/tokenRange.ts",
|
||||
"codeFixes/codeFixProvider.ts",
|
||||
"codeFixes/fixes.ts"
|
||||
]
|
||||
}
|
||||
|
||||
+62
-17
@@ -225,6 +225,7 @@ namespace ts {
|
||||
|
||||
getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string, excludeDtsFiles?: boolean): NavigateToItem[];
|
||||
getNavigationBarItems(fileName: string): NavigationBarItem[];
|
||||
getNavigationTree(fileName: string): NavigationTree;
|
||||
|
||||
getOutliningSpans(fileName: string): OutliningSpan[];
|
||||
getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[];
|
||||
@@ -239,6 +240,8 @@ namespace ts {
|
||||
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
|
||||
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[]): CodeAction[];
|
||||
|
||||
getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput;
|
||||
|
||||
getProgram(): Program;
|
||||
@@ -264,6 +267,12 @@ namespace ts {
|
||||
classificationType: string; // ClassificationTypeNames
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigation bar interface designed for visual studio's dual-column layout.
|
||||
* This does not form a proper tree.
|
||||
* The navbar is returned as a list of top-level items, each of which has a list of child items.
|
||||
* Child items always have an empty array for their `childItems`.
|
||||
*/
|
||||
export interface NavigationBarItem {
|
||||
text: string;
|
||||
kind: string;
|
||||
@@ -275,6 +284,26 @@ namespace ts {
|
||||
grayed: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Node in a tree of nested declarations in a file.
|
||||
* The top node is always a script or module node.
|
||||
*/
|
||||
export interface NavigationTree {
|
||||
/** Name of the declaration, or a short description, e.g. "<class>". */
|
||||
text: string;
|
||||
/** A ScriptElementKind */
|
||||
kind: string;
|
||||
/** ScriptElementKindModifier separated by commas, e.g. "public,abstract" */
|
||||
kindModifiers: string;
|
||||
/**
|
||||
* Spans of the nodes that generated this declaration.
|
||||
* There will be more than one if this is the result of merging.
|
||||
*/
|
||||
spans: TextSpan[];
|
||||
/** Present if non-empty */
|
||||
childItems?: NavigationTree[];
|
||||
}
|
||||
|
||||
export interface TodoCommentDescriptor {
|
||||
text: string;
|
||||
priority: number;
|
||||
@@ -291,6 +320,18 @@ namespace ts {
|
||||
newText: string;
|
||||
}
|
||||
|
||||
export interface FileTextChanges {
|
||||
fileName: string;
|
||||
textChanges: TextChange[];
|
||||
}
|
||||
|
||||
export interface CodeAction {
|
||||
/** Description of the code action to display in the UI of the editor */
|
||||
description: string;
|
||||
/** Text changes to apply to each file as part of the code action */
|
||||
changes: FileTextChanges[];
|
||||
}
|
||||
|
||||
export interface TextInsertion {
|
||||
newText: string;
|
||||
/** The position in newText the caret should point to after the insertion. */
|
||||
@@ -362,11 +403,11 @@ namespace ts {
|
||||
|
||||
export interface EditorSettings {
|
||||
baseIndentSize?: number;
|
||||
indentSize: number;
|
||||
tabSize: number;
|
||||
newLineCharacter: string;
|
||||
convertTabsToSpaces: boolean;
|
||||
indentStyle: IndentStyle;
|
||||
indentSize?: number;
|
||||
tabSize?: number;
|
||||
newLineCharacter?: string;
|
||||
convertTabsToSpaces?: boolean;
|
||||
indentStyle?: IndentStyle;
|
||||
}
|
||||
|
||||
/* @deprecated - consider using FormatCodeSettings instead */
|
||||
@@ -387,19 +428,19 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface FormatCodeSettings extends EditorSettings {
|
||||
insertSpaceAfterCommaDelimiter: boolean;
|
||||
insertSpaceAfterSemicolonInForStatements: boolean;
|
||||
insertSpaceBeforeAndAfterBinaryOperators: boolean;
|
||||
insertSpaceAfterKeywordsInControlFlowStatements: boolean;
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean;
|
||||
insertSpaceAfterCommaDelimiter?: boolean;
|
||||
insertSpaceAfterSemicolonInForStatements?: boolean;
|
||||
insertSpaceBeforeAndAfterBinaryOperators?: boolean;
|
||||
insertSpaceAfterKeywordsInControlFlowStatements?: boolean;
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
|
||||
insertSpaceAfterTypeAssertion?: boolean;
|
||||
placeOpenBraceOnNewLineForFunctions: boolean;
|
||||
placeOpenBraceOnNewLineForControlBlocks: boolean;
|
||||
placeOpenBraceOnNewLineForFunctions?: boolean;
|
||||
placeOpenBraceOnNewLineForControlBlocks?: boolean;
|
||||
}
|
||||
|
||||
export interface DefinitionInfo {
|
||||
@@ -505,7 +546,11 @@ namespace ts {
|
||||
export interface CompletionInfo {
|
||||
isGlobalCompletion: boolean;
|
||||
isMemberCompletion: boolean;
|
||||
isNewIdentifierLocation: boolean; // true when the current location also allows for a new identifier
|
||||
|
||||
/**
|
||||
* true when the current location also allows for a new identifier
|
||||
*/
|
||||
isNewIdentifierLocation: boolean;
|
||||
entries: CompletionEntry[];
|
||||
}
|
||||
|
||||
|
||||
@@ -376,7 +376,7 @@ namespace ts {
|
||||
return true;
|
||||
case SyntaxKind.Identifier:
|
||||
// 'this' as a parameter
|
||||
return (node as Identifier).originalKeywordKind === SyntaxKind.ThisKeyword && node.parent.kind === SyntaxKind.Parameter;
|
||||
return identifierIsThisKeyword(node as Identifier) && node.parent.kind === SyntaxKind.Parameter;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ tests/cases/conformance/Symbols/ES5SymbolProperty2.ts(10,11): error TS2304: Cann
|
||||
|
||||
==== tests/cases/conformance/Symbols/ES5SymbolProperty2.ts (2 errors) ====
|
||||
module M {
|
||||
var Symbol;
|
||||
var Symbol: any;
|
||||
|
||||
export class C {
|
||||
[Symbol.iterator]() { }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//// [ES5SymbolProperty2.ts]
|
||||
module M {
|
||||
var Symbol;
|
||||
var Symbol: any;
|
||||
|
||||
export class C {
|
||||
[Symbol.iterator]() { }
|
||||
|
||||
@@ -2,7 +2,7 @@ tests/cases/conformance/Symbols/ES5SymbolProperty3.ts(4,6): error TS2471: A comp
|
||||
|
||||
|
||||
==== tests/cases/conformance/Symbols/ES5SymbolProperty3.ts (1 errors) ====
|
||||
var Symbol;
|
||||
var Symbol: any;
|
||||
|
||||
class C {
|
||||
[Symbol.iterator]() { }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//// [ES5SymbolProperty3.ts]
|
||||
var Symbol;
|
||||
var Symbol: any;
|
||||
|
||||
class C {
|
||||
[Symbol.iterator]() { }
|
||||
|
||||
@@ -1,10 +1,31 @@
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,1): error TS2304: Cannot find name 'Foo'.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,1): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,1): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,5): error TS2304: Cannot find name 'A'.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,7): error TS2304: Cannot find name 'B'.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,9): error TS1127: Invalid character.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,11): error TS2304: Cannot find name 'C'.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,14): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,14): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
|
||||
|
||||
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts (2 errors) ====
|
||||
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts (9 errors) ====
|
||||
Foo<A,B,\ C>(4, 5, 6);
|
||||
~~~
|
||||
!!! error TS2304: Cannot find name 'Foo'.
|
||||
~~~~~
|
||||
!!! error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
~~~~~~~
|
||||
!!! error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'A'.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'B'.
|
||||
|
||||
!!! error TS1127: Invalid character.
|
||||
!!! error TS1127: Invalid character.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'C'.
|
||||
~
|
||||
!!! error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
~~~~
|
||||
!!! error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
@@ -2,4 +2,5 @@
|
||||
Foo<A,B,\ C>(4, 5, 6);
|
||||
|
||||
//// [TypeArgumentList1.js]
|
||||
Foo(4, 5, 6);
|
||||
Foo < A, B, ;
|
||||
C > (4, 5, 6);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//// [anyPlusAny1.ts]
|
||||
var x;
|
||||
var x: any;
|
||||
x.name = "hello";
|
||||
var z = x + x;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
=== tests/cases/compiler/anyPlusAny1.ts ===
|
||||
var x;
|
||||
var x: any;
|
||||
>x : Symbol(x, Decl(anyPlusAny1.ts, 0, 3))
|
||||
|
||||
x.name = "hello";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
=== tests/cases/compiler/anyPlusAny1.ts ===
|
||||
var x;
|
||||
var x: any;
|
||||
>x : any
|
||||
|
||||
x.name = "hello";
|
||||
|
||||
@@ -10,10 +10,10 @@ var Foo;
|
||||
>Foo : any
|
||||
|
||||
type
|
||||
>type : any
|
||||
>type : undefined
|
||||
|
||||
Foo = string;
|
||||
>Foo = string : any
|
||||
>Foo = string : undefined
|
||||
>Foo : any
|
||||
>string : any
|
||||
>string : undefined
|
||||
|
||||
|
||||
@@ -59,9 +59,9 @@ var e = undefined;
|
||||
>undefined : undefined
|
||||
|
||||
x = e;
|
||||
>x = e : any
|
||||
>x = e : undefined
|
||||
>x : any
|
||||
>e : any
|
||||
>e : undefined
|
||||
|
||||
var e2: typeof undefined;
|
||||
>e2 : any
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//// [assignmentLHSIsReference.ts]
|
||||
var value;
|
||||
var value: any;
|
||||
|
||||
// identifiers: variable and parameter
|
||||
var x1: number;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
=== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsReference.ts ===
|
||||
var value;
|
||||
var value: any;
|
||||
>value : Symbol(value, Decl(assignmentLHSIsReference.ts, 0, 3))
|
||||
|
||||
// identifiers: variable and parameter
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
=== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsReference.ts ===
|
||||
var value;
|
||||
var value: any;
|
||||
>value : any
|
||||
|
||||
// identifiers: variable and parameter
|
||||
|
||||
@@ -41,7 +41,7 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(7
|
||||
|
||||
==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (39 errors) ====
|
||||
// expected error for all the LHS of assignments
|
||||
var value;
|
||||
var value: any;
|
||||
|
||||
// this
|
||||
class C {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//// [assignmentLHSIsValue.ts]
|
||||
// expected error for all the LHS of assignments
|
||||
var value;
|
||||
var value: any;
|
||||
|
||||
// this
|
||||
class C {
|
||||
|
||||
@@ -44,7 +44,7 @@ module M {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -43,7 +43,7 @@ module M {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -43,7 +43,7 @@ module M {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -43,7 +43,7 @@ module M {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ async () => {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ async function fAsyncExplicit(): Promise<[number, boolean]> {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ export const b = {
|
||||
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 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());
|
||||
});
|
||||
@@ -34,7 +34,7 @@ export const b = {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -30,7 +30,7 @@ async function sample2(x?: number) {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -29,7 +29,7 @@ exports.Task = Task;
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ exports.Task = Task;
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ function g() { }
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ function g() { }
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ async function bar4() {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -24,7 +24,7 @@ async function bar4() {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -16,7 +16,7 @@ async function bar3() {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ async function bar4() {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -39,7 +39,7 @@ for (let x = 0; x < 1; ++x) {
|
||||
}
|
||||
|
||||
switch (x) {
|
||||
>x : any
|
||||
>x : undefined
|
||||
|
||||
case 1:
|
||||
>1 : 1
|
||||
|
||||
@@ -40,7 +40,7 @@ for (let x = 0; x < 1; ++x) {
|
||||
}
|
||||
|
||||
switch (x) {
|
||||
>x : any
|
||||
>x : undefined
|
||||
|
||||
case 1:
|
||||
>1 : 1
|
||||
|
||||
@@ -12,7 +12,7 @@ async function f() {
|
||||
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 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());
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ foo(/*c2*/ 1, /*d2*/ 1 + 2, /*e1*/ a + b);
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>a + b : any
|
||||
>a : any
|
||||
>a : undefined
|
||||
>b : any
|
||||
|
||||
foo(/*c3*/ function () { }, /*d2*/() => { }, /*e2*/ a + /*e3*/ b);
|
||||
@@ -26,7 +26,7 @@ foo(/*c3*/ function () { }, /*d2*/() => { }, /*e2*/ a + /*e3*/ b);
|
||||
>function () { } : () => void
|
||||
>() => { } : () => void
|
||||
>a + /*e3*/ b : any
|
||||
>a : any
|
||||
>a : undefined
|
||||
>b : any
|
||||
|
||||
foo(/*c3*/ function () { }, /*d3*/() => { }, /*e3*/(a + b));
|
||||
@@ -36,7 +36,7 @@ foo(/*c3*/ function () { }, /*d3*/() => { }, /*e3*/(a + b));
|
||||
>() => { } : () => void
|
||||
>(a + b) : any
|
||||
>a + b : any
|
||||
>a : any
|
||||
>a : undefined
|
||||
>b : any
|
||||
|
||||
foo(
|
||||
|
||||
@@ -9,12 +9,12 @@ var x1: number;
|
||||
x1 *= value;
|
||||
>x1 *= value : number
|
||||
>x1 : number
|
||||
>value : any
|
||||
>value : undefined
|
||||
|
||||
x1 += value;
|
||||
>x1 += value : any
|
||||
>x1 += value : number
|
||||
>x1 : number
|
||||
>value : any
|
||||
>value : undefined
|
||||
|
||||
function fn1(x2: number) {
|
||||
>fn1 : (x2: number) => void
|
||||
@@ -41,41 +41,41 @@ x3.a *= value;
|
||||
>x3.a : number
|
||||
>x3 : { a: number; }
|
||||
>a : number
|
||||
>value : any
|
||||
>value : undefined
|
||||
|
||||
x3.a += value;
|
||||
>x3.a += value : any
|
||||
>x3.a += value : number
|
||||
>x3.a : number
|
||||
>x3 : { a: number; }
|
||||
>a : number
|
||||
>value : any
|
||||
>value : undefined
|
||||
|
||||
x3['a'] *= value;
|
||||
>x3['a'] *= value : number
|
||||
>x3['a'] : number
|
||||
>x3 : { a: number; }
|
||||
>'a' : "a"
|
||||
>value : any
|
||||
>value : undefined
|
||||
|
||||
x3['a'] += value;
|
||||
>x3['a'] += value : any
|
||||
>x3['a'] += value : number
|
||||
>x3['a'] : number
|
||||
>x3 : { a: number; }
|
||||
>'a' : "a"
|
||||
>value : any
|
||||
>value : undefined
|
||||
|
||||
// parentheses, the contained expression is reference
|
||||
(x1) *= value;
|
||||
>(x1) *= value : number
|
||||
>(x1) : number
|
||||
>x1 : number
|
||||
>value : any
|
||||
>value : undefined
|
||||
|
||||
(x1) += value;
|
||||
>(x1) += value : any
|
||||
>(x1) += value : number
|
||||
>(x1) : number
|
||||
>x1 : number
|
||||
>value : any
|
||||
>value : undefined
|
||||
|
||||
function fn2(x4: number) {
|
||||
>fn2 : (x4: number) => void
|
||||
@@ -100,15 +100,15 @@ function fn2(x4: number) {
|
||||
>x3.a : number
|
||||
>x3 : { a: number; }
|
||||
>a : number
|
||||
>value : any
|
||||
>value : undefined
|
||||
|
||||
(x3.a) += value;
|
||||
>(x3.a) += value : any
|
||||
>(x3.a) += value : number
|
||||
>(x3.a) : number
|
||||
>x3.a : number
|
||||
>x3 : { a: number; }
|
||||
>a : number
|
||||
>value : any
|
||||
>value : undefined
|
||||
|
||||
(x3['a']) *= value;
|
||||
>(x3['a']) *= value : number
|
||||
@@ -116,13 +116,13 @@ function fn2(x4: number) {
|
||||
>x3['a'] : number
|
||||
>x3 : { a: number; }
|
||||
>'a' : "a"
|
||||
>value : any
|
||||
>value : undefined
|
||||
|
||||
(x3['a']) += value;
|
||||
>(x3['a']) += value : any
|
||||
>(x3['a']) += value : number
|
||||
>(x3['a']) : number
|
||||
>x3['a'] : number
|
||||
>x3 : { a: number; }
|
||||
>'a' : "a"
|
||||
>value : any
|
||||
>value : undefined
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsVa
|
||||
==== tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts (74 errors) ====
|
||||
|
||||
// expected error for all the LHS of compound assignments (arithmetic and addition)
|
||||
var value;
|
||||
var value: any;
|
||||
|
||||
// this
|
||||
class C {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//// [compoundAssignmentLHSIsValue.ts]
|
||||
|
||||
// expected error for all the LHS of compound assignments (arithmetic and addition)
|
||||
var value;
|
||||
var value: any;
|
||||
|
||||
// this
|
||||
class C {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//// [compoundExponentiationAssignmentLHSIsReference.ts]
|
||||
var value;
|
||||
var value: any;
|
||||
|
||||
// identifiers: variable and parameter
|
||||
var x1: number;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
=== tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsReference.ts ===
|
||||
var value;
|
||||
var value: any;
|
||||
>value : Symbol(value, Decl(compoundExponentiationAssignmentLHSIsReference.ts, 0, 3))
|
||||
|
||||
// identifiers: variable and parameter
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
=== tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsReference.ts ===
|
||||
var value;
|
||||
var value: any;
|
||||
>value : any
|
||||
|
||||
// identifiers: variable and parameter
|
||||
|
||||
@@ -40,7 +40,7 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm
|
||||
|
||||
==== tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts (38 errors) ====
|
||||
// expected error for all the LHS of compound assignments (arithmetic and addition)
|
||||
var value;
|
||||
var value: any;
|
||||
|
||||
// this
|
||||
class C {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//// [compoundExponentiationAssignmentLHSIsValue.ts]
|
||||
// expected error for all the LHS of compound assignments (arithmetic and addition)
|
||||
var value;
|
||||
var value: any;
|
||||
|
||||
// this
|
||||
class C {
|
||||
|
||||
@@ -35,20 +35,20 @@ var a;
|
||||
>a : any
|
||||
|
||||
foo(a);
|
||||
>foo(a) : any
|
||||
>foo(a) : undefined
|
||||
>foo : <T extends String>(x: T) => T
|
||||
>a : any
|
||||
>a : undefined
|
||||
|
||||
foo2(a);
|
||||
>foo2(a) : any
|
||||
>foo2(a) : undefined
|
||||
>foo2 : <T extends { x: number; }>(x: T) => T
|
||||
>a : any
|
||||
>a : undefined
|
||||
|
||||
//foo3(a);
|
||||
foo4(a);
|
||||
>foo4(a) : any
|
||||
>foo4(a) : undefined
|
||||
>foo4 : <T extends <T>(x: T) => void>(x: T) => T
|
||||
>a : any
|
||||
>a : undefined
|
||||
|
||||
var b: number;
|
||||
>b : number
|
||||
@@ -84,10 +84,10 @@ class C<T extends String> {
|
||||
}
|
||||
|
||||
var c1 = new C(a);
|
||||
>c1 : C<any>
|
||||
>new C(a) : C<any>
|
||||
>c1 : C<undefined>
|
||||
>new C(a) : C<undefined>
|
||||
>C : typeof C
|
||||
>a : any
|
||||
>a : undefined
|
||||
|
||||
var c2 = new C<any>(b);
|
||||
>c2 : C<any>
|
||||
@@ -106,10 +106,10 @@ class C2<T extends { x: number }> {
|
||||
}
|
||||
|
||||
var c3 = new C2(a);
|
||||
>c3 : C2<any>
|
||||
>new C2(a) : C2<any>
|
||||
>c3 : C2<undefined>
|
||||
>new C2(a) : C2<undefined>
|
||||
>C2 : typeof C2
|
||||
>a : any
|
||||
>a : undefined
|
||||
|
||||
var c4 = new C2<any>(b);
|
||||
>c4 : C2<any>
|
||||
@@ -138,10 +138,10 @@ class C4<T extends <T>(x:T) => T> {
|
||||
}
|
||||
|
||||
var c7 = new C4(a);
|
||||
>c7 : C4<any>
|
||||
>new C4(a) : C4<any>
|
||||
>c7 : C4<undefined>
|
||||
>new C4(a) : C4<undefined>
|
||||
>C4 : typeof C4
|
||||
>a : any
|
||||
>a : undefined
|
||||
|
||||
var c8 = new C4<any>(b);
|
||||
>c8 : C4<any>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user