mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 01:00:41 -05:00
Merge branch 'master' into stricterGenericChecks
# Conflicts: # src/compiler/checker.ts
This commit is contained in:
37
Gulpfile.ts
37
Gulpfile.ts
@@ -39,25 +39,25 @@ Error.stackTraceLimit = 1000;
|
||||
|
||||
const cmdLineOptions = minimist(process.argv.slice(2), {
|
||||
boolean: ["debug", "inspect", "light", "colors", "lint", "soft"],
|
||||
string: ["browser", "tests", "host", "reporter", "stackTraceLimit"],
|
||||
string: ["browser", "tests", "host", "reporter", "stackTraceLimit", "timeout"],
|
||||
alias: {
|
||||
b: "browser",
|
||||
d: "debug",
|
||||
t: "tests",
|
||||
test: "tests",
|
||||
d: "debug", "debug-brk": "debug",
|
||||
i: "inspect", "inspect-brk": "inspect",
|
||||
t: "tests", test: "tests",
|
||||
r: "reporter",
|
||||
color: "colors",
|
||||
f: "files",
|
||||
file: "files",
|
||||
c: "colors", color: "colors",
|
||||
f: "files", file: "files",
|
||||
w: "workers",
|
||||
},
|
||||
default: {
|
||||
soft: false,
|
||||
colors: process.env.colors || process.env.color || true,
|
||||
debug: process.env.debug || process.env.d,
|
||||
inspect: process.env.inspect,
|
||||
debug: process.env.debug || process.env["debug-brk"] || process.env.d,
|
||||
inspect: process.env.inspect || process.env["inspect-brk"] || process.env.i,
|
||||
host: process.env.TYPESCRIPT_HOST || process.env.host || "node",
|
||||
browser: process.env.browser || process.env.b || "IE",
|
||||
timeout: process.env.timeout || 40000,
|
||||
tests: process.env.test || process.env.tests || process.env.t,
|
||||
light: process.env.light || false,
|
||||
reporter: process.env.reporter || process.env.r,
|
||||
@@ -594,11 +594,11 @@ function restoreSavedNodeEnv() {
|
||||
process.env.NODE_ENV = savedNodeEnv;
|
||||
}
|
||||
|
||||
let testTimeout = 40000;
|
||||
function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: (e?: any) => void) {
|
||||
const lintFlag = cmdLineOptions["lint"];
|
||||
cleanTestDirs((err) => {
|
||||
if (err) { console.error(err); failWithStatus(err, 1); }
|
||||
let testTimeout = cmdLineOptions["timeout"];
|
||||
const debug = cmdLineOptions["debug"];
|
||||
const inspect = cmdLineOptions["inspect"];
|
||||
const tests = cmdLineOptions["tests"];
|
||||
@@ -637,12 +637,6 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
||||
if (!runInParallel) {
|
||||
const args = [];
|
||||
if (inspect) {
|
||||
args.push("--inspect");
|
||||
}
|
||||
if (inspect || debug) {
|
||||
args.push("--debug-brk");
|
||||
}
|
||||
args.push("-R", reporter);
|
||||
if (tests) {
|
||||
args.push("-g", `"${tests}"`);
|
||||
@@ -653,7 +647,15 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
else {
|
||||
args.push("--no-colors");
|
||||
}
|
||||
args.push("-t", testTimeout);
|
||||
if (inspect) {
|
||||
args.unshift("--inspect-brk");
|
||||
}
|
||||
else if (debug) {
|
||||
args.unshift("--debug-brk");
|
||||
}
|
||||
else {
|
||||
args.push("-t", testTimeout);
|
||||
}
|
||||
args.push(run);
|
||||
setNodeEnvToDevelopment();
|
||||
exec(mocha, args, lintThenFinish, function(e, status) {
|
||||
@@ -838,6 +840,7 @@ gulp.task("runtests-browser", "Runs the tests using the built run.js file like '
|
||||
});
|
||||
|
||||
gulp.task("generate-code-coverage", "Generates code coverage data via istanbul", ["tests"], (done) => {
|
||||
const testTimeout = cmdLineOptions["timeout"];
|
||||
exec("istanbul", ["cover", "node_modules/mocha/bin/_mocha", "--", "-R", "min", "-t", testTimeout.toString(), run], done, done);
|
||||
});
|
||||
|
||||
|
||||
31
Jakefile.js
31
Jakefile.js
@@ -25,6 +25,8 @@ var LKGDirectory = "lib/";
|
||||
var copyright = "CopyrightNotice.txt";
|
||||
var thirdParty = "ThirdPartyNoticeText.txt";
|
||||
|
||||
var defaultTestTimeout = 40000;
|
||||
|
||||
// add node_modules to path so we don't need global modules, prefer the modules by adding them first
|
||||
var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter;
|
||||
if (process.env.path !== undefined) {
|
||||
@@ -74,6 +76,10 @@ function measure(marker) {
|
||||
console.log("travis_time:end:" + marker.id + ":start=" + toNs(marker.stamp) + ",finish=" + toNs(total) + ",duration=" + toNs(diff) + "\r");
|
||||
}
|
||||
|
||||
function removeConstModifierFromEnumDeclarations(text) {
|
||||
return text.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4');
|
||||
}
|
||||
|
||||
var compilerSources = filesFromConfig("./src/compiler/tsconfig.json");
|
||||
var servicesSources = filesFromConfig("./src/services/tsconfig.json");
|
||||
var cancellationTokenSources = filesFromConfig(path.join(serverDirectory, "cancellationToken/tsconfig.json"));
|
||||
@@ -551,7 +557,7 @@ compileFile(servicesFile, servicesSources, [builtLocalDirectory, copyright].conc
|
||||
// Stanalone/web definition file using global 'ts' namespace
|
||||
jake.cpR(standaloneDefinitionsFile, nodeDefinitionsFile, { silent: true });
|
||||
var definitionFileContents = fs.readFileSync(nodeDefinitionsFile).toString();
|
||||
definitionFileContents = definitionFileContents.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4');
|
||||
definitionFileContents = removeConstModifierFromEnumDeclarations(definitionFileContents)
|
||||
fs.writeFileSync(standaloneDefinitionsFile, definitionFileContents);
|
||||
|
||||
// Official node package definition file, pointed to by 'typings' in package.json
|
||||
@@ -611,6 +617,7 @@ compileFile(
|
||||
fs.readFileSync(tsserverLibraryDefinitionFile).toString() +
|
||||
"\r\nexport = ts;" +
|
||||
"\r\nexport as namespace ts;";
|
||||
tsserverLibraryDefinitionFileContents = removeConstModifierFromEnumDeclarations(tsserverLibraryDefinitionFileContents);
|
||||
|
||||
fs.writeFileSync(tsserverLibraryDefinitionFile, tsserverLibraryDefinitionFileContents);
|
||||
});
|
||||
@@ -800,8 +807,8 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
cleanTestDirs();
|
||||
}
|
||||
|
||||
var debug = process.env.debug || process.env.d;
|
||||
var inspect = process.env.inspect;
|
||||
var debug = process.env.debug || process.env["debug-brk"] || process.env.d;
|
||||
var inspect = process.env.inspect || process.env["inspect-brk"] || process.env.i;
|
||||
var testTimeout = process.env.timeout || defaultTestTimeout;
|
||||
var tests = process.env.test || process.env.tests || process.env.t;
|
||||
var light = process.env.light || false;
|
||||
@@ -842,12 +849,6 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
if (!runInParallel) {
|
||||
var startTime = mark();
|
||||
var args = [];
|
||||
if (inspect) {
|
||||
args.push("--inspect");
|
||||
}
|
||||
if (inspect || debug) {
|
||||
args.push("--debug-brk");
|
||||
}
|
||||
args.push("-R", reporter);
|
||||
if (tests) {
|
||||
args.push("-g", `"${tests}"`);
|
||||
@@ -861,7 +862,15 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
if (bail) {
|
||||
args.push("--bail");
|
||||
}
|
||||
args.push("-t", testTimeout);
|
||||
if (inspect) {
|
||||
args.unshift("--inspect-brk");
|
||||
}
|
||||
else if (debug) {
|
||||
args.unshift("--debug-brk");
|
||||
}
|
||||
else {
|
||||
args.push("-t", testTimeout);
|
||||
}
|
||||
args.push(run);
|
||||
|
||||
var cmd = "mocha " + args.join(" ");
|
||||
@@ -926,7 +935,6 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
}
|
||||
}
|
||||
|
||||
var defaultTestTimeout = 22000;
|
||||
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true.");
|
||||
task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], function () {
|
||||
runConsoleTests('min', /*runInParallel*/ true);
|
||||
@@ -939,6 +947,7 @@ task("runtests", ["build-rules", "tests", builtLocalDirectory], function() {
|
||||
|
||||
desc("Generates code coverage data via instanbul");
|
||||
task("generate-code-coverage", ["tests", builtLocalDirectory], function () {
|
||||
var testTimeout = process.env.timeout || defaultTestTimeout;
|
||||
var cmd = 'istanbul cover node_modules/mocha/bin/_mocha -- -R min -t ' + testTimeout + ' ' + run;
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
|
||||
@@ -1521,7 +1521,7 @@ namespace ts {
|
||||
// All the children of these container types are never visible through another
|
||||
// symbol (i.e. through another symbol's 'exports' or 'members'). Instead,
|
||||
// they're only accessed 'lexically' (i.e. from code that exists underneath
|
||||
// their container in the tree. To accomplish this, we simply add their declared
|
||||
// their container in the tree). To accomplish this, we simply add their declared
|
||||
// symbol to the 'locals' of the container. These symbols can then be found as
|
||||
// the type checker walks up the containers, checking them for matching names.
|
||||
return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
@@ -2053,7 +2053,10 @@ namespace ts {
|
||||
case SyntaxKind.TypePredicate:
|
||||
return checkTypePredicate(node as TypePredicateNode);
|
||||
case SyntaxKind.TypeParameter:
|
||||
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
|
||||
if (node.parent.kind !== ts.SyntaxKind.JSDocTemplateTag || isInJavaScriptFile(node)) {
|
||||
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
|
||||
}
|
||||
return;
|
||||
case SyntaxKind.Parameter:
|
||||
return bindParameter(<ParameterDeclaration>node);
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
|
||||
@@ -4200,16 +4200,6 @@ namespace ts {
|
||||
|
||||
// Return the inferred type for a variable, parameter, or property declaration
|
||||
function getTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration, includeOptionality: boolean): Type {
|
||||
if (declaration.flags & NodeFlags.JavaScriptFile) {
|
||||
// If this is a variable in a JavaScript file, then use the JSDoc type (if it has
|
||||
// one as its type), otherwise fallback to the below standard TS codepaths to
|
||||
// try to figure it out.
|
||||
const type = getTypeForDeclarationFromJSDocComment(declaration);
|
||||
if (type && type !== unknownType) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
// A variable declared in a for..in statement is of type string, or of type keyof T when the
|
||||
// right hand expression is of a type parameter type.
|
||||
if (declaration.parent.parent.kind === SyntaxKind.ForInStatement) {
|
||||
@@ -4231,8 +4221,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Use type from type annotation if one is present
|
||||
if (declaration.type) {
|
||||
const declaredType = getTypeFromTypeNode(declaration.type);
|
||||
const typeNode = getEffectiveTypeAnnotationNode(declaration);
|
||||
if (typeNode) {
|
||||
const declaredType = getTypeFromTypeNode(typeNode);
|
||||
return addOptionality(declaredType, /*optional*/ declaration.questionToken && includeOptionality);
|
||||
}
|
||||
|
||||
@@ -4523,10 +4514,11 @@ namespace ts {
|
||||
function getAnnotatedAccessorType(accessor: AccessorDeclaration): Type {
|
||||
if (accessor) {
|
||||
if (accessor.kind === SyntaxKind.GetAccessor) {
|
||||
return accessor.type && getTypeFromTypeNode(accessor.type);
|
||||
const getterTypeAnnotation = getEffectiveReturnTypeNode(accessor);
|
||||
return getterTypeAnnotation && getTypeFromTypeNode(getterTypeAnnotation);
|
||||
}
|
||||
else {
|
||||
const setterTypeAnnotation = getSetAccessorTypeAnnotationNode(accessor);
|
||||
const setterTypeAnnotation = getEffectiveSetAccessorTypeAnnotationNode(accessor);
|
||||
return setterTypeAnnotation && getTypeFromTypeNode(setterTypeAnnotation);
|
||||
}
|
||||
}
|
||||
@@ -4679,7 +4671,7 @@ namespace ts {
|
||||
|
||||
function reportCircularityError(symbol: Symbol) {
|
||||
// Check if variable has type annotation that circularly references the variable itself
|
||||
if ((<VariableLikeDeclaration>symbol.valueDeclaration).type) {
|
||||
if (getEffectiveTypeAnnotationNode(<VariableLikeDeclaration>symbol.valueDeclaration)) {
|
||||
error(symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation,
|
||||
symbolToString(symbol));
|
||||
return unknownType;
|
||||
@@ -5265,14 +5257,18 @@ namespace ts {
|
||||
// A variable-like declaration is considered independent (free of this references) if it has a type annotation
|
||||
// that specifies an independent type, or if it has no type annotation and no initializer (and thus of type any).
|
||||
function isIndependentVariableLikeDeclaration(node: VariableLikeDeclaration): boolean {
|
||||
return node.type && isIndependentType(node.type) || !node.type && !node.initializer;
|
||||
const typeNode = getEffectiveTypeAnnotationNode(node);
|
||||
return typeNode ? isIndependentType(typeNode) : !node.initializer;
|
||||
}
|
||||
|
||||
// A function-like declaration is considered independent (free of this references) if it has a return type
|
||||
// annotation that is considered independent and if each parameter is considered independent.
|
||||
function isIndependentFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
|
||||
if (node.kind !== SyntaxKind.Constructor && (!node.type || !isIndependentType(node.type))) {
|
||||
return false;
|
||||
if (node.kind !== SyntaxKind.Constructor) {
|
||||
const typeNode = getEffectiveReturnTypeNode(node);
|
||||
if (!typeNode || !isIndependentType(typeNode)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (const parameter of node.parameters) {
|
||||
if (!isIndependentVariableLikeDeclaration(parameter)) {
|
||||
@@ -6424,15 +6420,10 @@ namespace ts {
|
||||
else if (classType) {
|
||||
return classType;
|
||||
}
|
||||
else if (declaration.type) {
|
||||
return getTypeFromTypeNode(declaration.type);
|
||||
}
|
||||
|
||||
if (declaration.flags & NodeFlags.JavaScriptFile) {
|
||||
const type = getReturnTypeFromJSDocComment(declaration);
|
||||
if (type && type !== unknownType) {
|
||||
return type;
|
||||
}
|
||||
const typeNode = getEffectiveReturnTypeNode(declaration);
|
||||
if (typeNode) {
|
||||
return getTypeFromTypeNode(typeNode);
|
||||
}
|
||||
|
||||
// TypeScript 1.0 spec (April 2014):
|
||||
@@ -8333,7 +8324,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
// Functions with any parameters that lack type annotations are context sensitive.
|
||||
if (forEach(node.parameters, p => !p.type)) {
|
||||
if (forEach(node.parameters, p => !getEffectiveTypeAnnotationNode(p))) {
|
||||
return true;
|
||||
}
|
||||
// For arrow functions we now know we're not context sensitive.
|
||||
@@ -8976,7 +8967,9 @@ namespace ts {
|
||||
reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(target));
|
||||
}
|
||||
else {
|
||||
errorNode = prop.valueDeclaration;
|
||||
if (prop.valueDeclaration) {
|
||||
errorNode = prop.valueDeclaration;
|
||||
}
|
||||
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1,
|
||||
symbolToString(prop), typeToString(target));
|
||||
}
|
||||
@@ -12761,8 +12754,15 @@ namespace ts {
|
||||
function getContextualTypeForInitializerExpression(node: Expression): Type {
|
||||
const declaration = <VariableLikeDeclaration>node.parent;
|
||||
if (node === declaration.initializer) {
|
||||
if (declaration.type) {
|
||||
return getTypeFromTypeNode(declaration.type);
|
||||
const typeNode = getEffectiveTypeAnnotationNode(declaration);
|
||||
if (typeNode) {
|
||||
return getTypeFromTypeNode(typeNode);
|
||||
}
|
||||
if (isInJavaScriptFile(declaration)) {
|
||||
const jsDocType = getTypeForDeclarationFromJSDocComment(declaration);
|
||||
if (jsDocType) {
|
||||
return jsDocType;
|
||||
}
|
||||
}
|
||||
if (declaration.kind === SyntaxKind.Parameter) {
|
||||
const type = getContextuallyTypedParameterType(<ParameterDeclaration>declaration);
|
||||
@@ -12776,12 +12776,13 @@ namespace ts {
|
||||
if (isBindingPattern(declaration.parent)) {
|
||||
const parentDeclaration = declaration.parent.parent;
|
||||
const name = declaration.propertyName || declaration.name;
|
||||
if (parentDeclaration.kind !== SyntaxKind.BindingElement &&
|
||||
parentDeclaration.type &&
|
||||
!isBindingPattern(name)) {
|
||||
const text = getTextOfPropertyName(name);
|
||||
if (text) {
|
||||
return getTypeOfPropertyOfType(getTypeFromTypeNode(parentDeclaration.type), text);
|
||||
if (parentDeclaration.kind !== SyntaxKind.BindingElement) {
|
||||
const parentTypeNode = getEffectiveTypeAnnotationNode(parentDeclaration);
|
||||
if (parentTypeNode && !isBindingPattern(name)) {
|
||||
const text = getTextOfPropertyName(name);
|
||||
if (text) {
|
||||
return getTypeOfPropertyOfType(getTypeFromTypeNode(parentTypeNode), text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12835,9 +12836,9 @@ namespace ts {
|
||||
function getContextualReturnType(functionDecl: FunctionLikeDeclaration): Type {
|
||||
// If the containing function has a return type annotation, is a constructor, or is a get accessor whose
|
||||
// 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(getDeclarationOfKind<SetAccessorDeclaration>(functionDecl.symbol, SyntaxKind.SetAccessor))) {
|
||||
if (functionDecl.kind === SyntaxKind.Constructor ||
|
||||
getEffectiveReturnTypeNode(functionDecl) ||
|
||||
isGetAccessorWithAnnotatedSetAccessor(functionDecl)) {
|
||||
return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
|
||||
}
|
||||
|
||||
@@ -14234,9 +14235,13 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Check if a property with the given name is known anywhere in the given type. In an object type, a property
|
||||
* is considered known if the object type is empty and the check is for assignability, if the object type has
|
||||
* index signatures, or if the property is actually declared in the object type. In a union or intersection
|
||||
* type, a property is considered known if it is known in any constituent type.
|
||||
* is considered known if
|
||||
* 1. the object type is empty and the check is for assignability, or
|
||||
* 2. if the object type has index signatures, or
|
||||
* 3. if the property is actually declared in the object type
|
||||
* (this means that 'toString', for example, is not usually a known property).
|
||||
* 4. In a union or intersection type,
|
||||
* a property is considered known if it is known in any constituent type.
|
||||
* @param targetType a type to search a given name in
|
||||
* @param name a property name to search
|
||||
* @param isComparingJsxAttributes a boolean flag indicating whether we are searching in JsxAttributesType
|
||||
@@ -14246,7 +14251,7 @@ namespace ts {
|
||||
const resolved = resolveStructuredTypeMembers(<ObjectType>targetType);
|
||||
if (resolved.stringIndexInfo ||
|
||||
resolved.numberIndexInfo && isNumericLiteralName(name) ||
|
||||
getPropertyOfType(targetType, name) ||
|
||||
getPropertyOfObjectType(targetType, name) ||
|
||||
isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) {
|
||||
// For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known.
|
||||
return true;
|
||||
@@ -16374,7 +16379,10 @@ namespace ts {
|
||||
for (let i = 0; i < len; i++) {
|
||||
const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
|
||||
if (declaration.type) {
|
||||
inferTypes((<InferenceContext>mapper).inferences, getTypeFromTypeNode(declaration.type), getTypeAtPosition(context, i));
|
||||
const typeNode = getEffectiveTypeAnnotationNode(declaration);
|
||||
if (typeNode) {
|
||||
inferTypes((<InferenceContext>mapper).inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16393,14 +16401,14 @@ namespace ts {
|
||||
const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
||||
for (let i = 0; i < len; i++) {
|
||||
const parameter = signature.parameters[i];
|
||||
if (!(<ParameterDeclaration>parameter.valueDeclaration).type) {
|
||||
if (!getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
|
||||
const contextualParameterType = getTypeAtPosition(context, i);
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
|
||||
}
|
||||
}
|
||||
if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) {
|
||||
const parameter = lastOrUndefined(signature.parameters);
|
||||
if (!(<ParameterDeclaration>parameter.valueDeclaration).type) {
|
||||
if (!getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
|
||||
const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters));
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
|
||||
}
|
||||
@@ -16436,15 +16444,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getReturnTypeFromJSDocComment(func: SignatureDeclaration | FunctionDeclaration): Type {
|
||||
const returnTag = getJSDocReturnTag(func);
|
||||
if (returnTag && returnTag.typeExpression) {
|
||||
return getTypeFromTypeNode(returnTag.typeExpression.type);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function createPromiseType(promisedType: Type): Type {
|
||||
// creates a `Promise<T>` type where `T` is the promisedType argument
|
||||
const globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
|
||||
@@ -16670,16 +16669,16 @@ namespace ts {
|
||||
const hasExplicitReturn = func.flags & NodeFlags.HasExplicitReturn;
|
||||
|
||||
if (returnType && returnType.flags & TypeFlags.Never) {
|
||||
error(func.type, Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
|
||||
error(getEffectiveReturnTypeNode(func), Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
|
||||
}
|
||||
else if (returnType && !hasExplicitReturn) {
|
||||
// minimal check: function has syntactic return type annotation and no explicit return statements in the body
|
||||
// this function does not conform to the specification.
|
||||
// NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
|
||||
error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
|
||||
error(getEffectiveReturnTypeNode(func), Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
|
||||
}
|
||||
else if (returnType && strictNullChecks && !isTypeAssignableTo(undefinedType, returnType)) {
|
||||
error(func.type, Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined);
|
||||
error(getEffectiveReturnTypeNode(func), Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined);
|
||||
}
|
||||
else if (compilerOptions.noImplicitReturns) {
|
||||
if (!returnType) {
|
||||
@@ -16694,7 +16693,7 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
}
|
||||
error(func.type || func, Diagnostics.Not_all_code_paths_return_a_value);
|
||||
error(getEffectiveReturnTypeNode(func) || func, Diagnostics.Not_all_code_paths_return_a_value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16735,7 +16734,7 @@ namespace ts {
|
||||
contextualSignature : instantiateSignature(contextualSignature, contextualMapper);
|
||||
assignContextualParameterTypes(signature, instantiatedContextualSignature);
|
||||
}
|
||||
if (!node.type && !signature.resolvedReturnType) {
|
||||
if (!getEffectiveReturnTypeNode(node) && !signature.resolvedReturnType) {
|
||||
const returnType = getReturnTypeFromBody(node, checkMode);
|
||||
if (!signature.resolvedReturnType) {
|
||||
signature.resolvedReturnType = returnType;
|
||||
@@ -16760,10 +16759,11 @@ namespace ts {
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
|
||||
|
||||
const functionFlags = getFunctionFlags(node);
|
||||
const returnOrPromisedType = node.type &&
|
||||
const returnTypeNode = getEffectiveReturnTypeNode(node);
|
||||
const returnOrPromisedType = returnTypeNode &&
|
||||
((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async ?
|
||||
checkAsyncFunctionReturnType(node) : // Async function
|
||||
getTypeFromTypeNode(node.type)); // AsyncGenerator function, Generator function, or normal function
|
||||
getTypeFromTypeNode(returnTypeNode)); // AsyncGenerator function, Generator function, or normal function
|
||||
|
||||
if ((functionFlags & FunctionFlags.Generator) === 0) { // Async function or normal function
|
||||
// return is not necessary in the body of generators
|
||||
@@ -16771,7 +16771,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (node.body) {
|
||||
if (!node.type) {
|
||||
if (!returnTypeNode) {
|
||||
// There are some checks that are only performed in getReturnTypeFromBody, that may produce errors
|
||||
// we need. An example is the noImplicitAny errors resulting from widening the return expression
|
||||
// of a function. Because checking of function expression bodies is deferred, there was never an
|
||||
@@ -17557,8 +17557,9 @@ namespace ts {
|
||||
// There is no point in doing an assignability check if the function
|
||||
// has no explicit return type because the return type is directly computed
|
||||
// from the yield expressions.
|
||||
if (func.type) {
|
||||
const signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(func.type), (functionFlags & FunctionFlags.Async) !== 0) || anyType;
|
||||
const returnType = getEffectiveReturnTypeNode(func);
|
||||
if (returnType) {
|
||||
const signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(returnType), (functionFlags & FunctionFlags.Async) !== 0) || anyType;
|
||||
if (nodeIsYieldStar) {
|
||||
checkTypeAssignableTo(
|
||||
functionFlags & FunctionFlags.Async
|
||||
@@ -18086,13 +18087,15 @@ namespace ts {
|
||||
|
||||
forEach(node.parameters, checkParameter);
|
||||
|
||||
// TODO(rbuckton): Should we start checking JSDoc types?
|
||||
if (node.type) {
|
||||
checkSourceElement(node.type);
|
||||
}
|
||||
|
||||
if (produceDiagnostics) {
|
||||
checkCollisionWithArgumentsInGeneratedCode(node);
|
||||
if (noImplicitAny && !node.type) {
|
||||
const returnTypeNode = getEffectiveReturnTypeNode(node);
|
||||
if (noImplicitAny && !returnTypeNode) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ConstructSignature:
|
||||
error(node, Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
|
||||
@@ -18103,12 +18106,12 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (node.type) {
|
||||
if (returnTypeNode) {
|
||||
const functionFlags = getFunctionFlags(<FunctionDeclaration>node);
|
||||
if ((functionFlags & (FunctionFlags.Invalid | FunctionFlags.Generator)) === FunctionFlags.Generator) {
|
||||
const returnType = getTypeFromTypeNode(node.type);
|
||||
const returnType = getTypeFromTypeNode(returnTypeNode);
|
||||
if (returnType === voidType) {
|
||||
error(node.type, Diagnostics.A_generator_cannot_have_a_void_type_annotation);
|
||||
error(returnTypeNode, Diagnostics.A_generator_cannot_have_a_void_type_annotation);
|
||||
}
|
||||
else {
|
||||
const generatorElementType = getIteratedTypeOfGenerator(returnType, (functionFlags & FunctionFlags.Async) !== 0) || anyType;
|
||||
@@ -18122,7 +18125,7 @@ namespace ts {
|
||||
// interface BadGenerator extends Iterable<number>, Iterator<string> { }
|
||||
// function* g(): BadGenerator { } // Iterable and Iterator have different types!
|
||||
//
|
||||
checkTypeAssignableTo(iterableIteratorInstantiation, returnType, node.type);
|
||||
checkTypeAssignableTo(iterableIteratorInstantiation, returnType, returnTypeNode);
|
||||
}
|
||||
}
|
||||
else if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) {
|
||||
@@ -19134,7 +19137,8 @@ namespace ts {
|
||||
// then<U>(...): Promise<U>;
|
||||
// }
|
||||
//
|
||||
const returnType = getTypeFromTypeNode(node.type);
|
||||
const returnTypeNode = getEffectiveReturnTypeNode(node);
|
||||
const returnType = getTypeFromTypeNode(returnTypeNode);
|
||||
|
||||
if (languageVersion >= ScriptTarget.ES2015) {
|
||||
if (returnType === unknownType) {
|
||||
@@ -19144,21 +19148,21 @@ namespace ts {
|
||||
if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) {
|
||||
// The promise type was not a valid type reference to the global promise type, so we
|
||||
// report an error and return the unknown type.
|
||||
error(node.type, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
|
||||
error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
|
||||
return unknownType;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Always mark the type node as referenced if it points to a value
|
||||
markTypeNodeAsReferenced(node.type);
|
||||
markTypeNodeAsReferenced(returnTypeNode);
|
||||
|
||||
if (returnType === unknownType) {
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
const promiseConstructorName = getEntityNameFromTypeNode(node.type);
|
||||
const promiseConstructorName = getEntityNameFromTypeNode(returnTypeNode);
|
||||
if (promiseConstructorName === undefined) {
|
||||
error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType));
|
||||
error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType));
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
@@ -19166,10 +19170,10 @@ namespace ts {
|
||||
const promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : unknownType;
|
||||
if (promiseConstructorType === unknownType) {
|
||||
if (promiseConstructorName.kind === SyntaxKind.Identifier && promiseConstructorName.text === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) {
|
||||
error(node.type, Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
|
||||
error(returnTypeNode, Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
|
||||
}
|
||||
else {
|
||||
error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName));
|
||||
error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName));
|
||||
}
|
||||
return unknownType;
|
||||
}
|
||||
@@ -19178,11 +19182,11 @@ namespace ts {
|
||||
if (globalPromiseConstructorLikeType === emptyObjectType) {
|
||||
// If we couldn't resolve the global PromiseConstructorLike type we cannot verify
|
||||
// compatibility with __awaiter.
|
||||
error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName));
|
||||
error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName));
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node.type,
|
||||
if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode,
|
||||
Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) {
|
||||
return unknownType;
|
||||
}
|
||||
@@ -19327,7 +19331,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getParameterTypeNodeForDecoratorCheck(node: ParameterDeclaration): TypeNode {
|
||||
return node.dotDotDotToken ? getRestParameterElementType(node.type) : node.type;
|
||||
const typeNode = getEffectiveTypeAnnotationNode(node);
|
||||
return isRestParameter(node) ? getRestParameterElementType(typeNode) : typeNode;
|
||||
}
|
||||
|
||||
/** Check the decorators of a node */
|
||||
@@ -19373,14 +19378,15 @@ namespace ts {
|
||||
markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
|
||||
}
|
||||
|
||||
markDecoratorMedataDataTypeNodeAsReferenced((<FunctionLikeDeclaration>node).type);
|
||||
markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveReturnTypeNode(<FunctionLikeDeclaration>node));
|
||||
break;
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(<ParameterDeclaration>node));
|
||||
markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveTypeAnnotationNode(<ParameterDeclaration>node));
|
||||
break;
|
||||
|
||||
case SyntaxKind.Parameter:
|
||||
markDecoratorMedataDataTypeNodeAsReferenced((<PropertyDeclaration>node).type);
|
||||
markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(<ParameterDeclaration>node));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -19445,14 +19451,15 @@ namespace ts {
|
||||
|
||||
checkSourceElement(node.body);
|
||||
|
||||
const returnTypeNode = getEffectiveReturnTypeNode(node);
|
||||
if ((functionFlags & FunctionFlags.Generator) === 0) { // Async function or normal function
|
||||
const returnOrPromisedType = node.type && (functionFlags & FunctionFlags.Async
|
||||
const returnOrPromisedType = returnTypeNode && (functionFlags & FunctionFlags.Async
|
||||
? checkAsyncFunctionReturnType(node) // Async function
|
||||
: getTypeFromTypeNode(node.type)); // normal function
|
||||
: getTypeFromTypeNode(returnTypeNode)); // normal function
|
||||
checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
|
||||
}
|
||||
|
||||
if (produceDiagnostics && !node.type) {
|
||||
if (produceDiagnostics && !returnTypeNode) {
|
||||
// Report an implicit any error if there is no body, no explicit return type, and node is not a private method
|
||||
// in an ambient context
|
||||
if (noImplicitAny && nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) {
|
||||
@@ -20582,7 +20589,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isGetAccessorWithAnnotatedSetAccessor(node: FunctionLikeDeclaration) {
|
||||
return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind<SetAccessorDeclaration>(node.symbol, SyntaxKind.SetAccessor)));
|
||||
return node.kind === SyntaxKind.GetAccessor
|
||||
&& getEffectiveSetAccessorTypeAnnotationNode(getDeclarationOfKind<SetAccessorDeclaration>(node.symbol, SyntaxKind.SetAccessor)) !== undefined;
|
||||
}
|
||||
|
||||
function isUnwrappedReturnTypeVoidOrAny(func: FunctionLikeDeclaration, returnType: Type): boolean {
|
||||
@@ -20626,7 +20634,7 @@ namespace ts {
|
||||
error(node, Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class);
|
||||
}
|
||||
}
|
||||
else if (func.type || isGetAccessorWithAnnotatedSetAccessor(func)) {
|
||||
else if (getEffectiveReturnTypeNode(func) || isGetAccessorWithAnnotatedSetAccessor(func)) {
|
||||
if (functionFlags & FunctionFlags.Async) { // Async function
|
||||
const promisedType = getPromisedTypeOfPromise(returnType);
|
||||
const awaitedType = checkAwaitedType(exprType, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
|
||||
@@ -21764,7 +21772,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Don't allow to re-export something with no value side when `--isolatedModules` is set.
|
||||
if (node.kind === SyntaxKind.ExportSpecifier && compilerOptions.isolatedModules && !(target.flags & SymbolFlags.Value)) {
|
||||
if (compilerOptions.isolatedModules
|
||||
&& node.kind === SyntaxKind.ExportSpecifier
|
||||
&& !(target.flags & SymbolFlags.Value)
|
||||
&& !isInAmbientContext(node)) {
|
||||
error(node, Diagnostics.Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided);
|
||||
}
|
||||
}
|
||||
@@ -22526,10 +22537,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (entityName.parent!.kind === SyntaxKind.JSDocParameterTag) {
|
||||
const parameter = ts.getParameterFromJSDoc(entityName.parent as JSDocParameterTag);
|
||||
const parameter = getParameterFromJSDoc(entityName.parent as JSDocParameterTag);
|
||||
return parameter && parameter.symbol;
|
||||
}
|
||||
|
||||
if (entityName.parent.kind === SyntaxKind.TypeParameter && entityName.parent.parent.kind === SyntaxKind.JSDocTemplateTag) {
|
||||
Debug.assert(!isInJavaScriptFile(entityName)); // Otherwise `isDeclarationName` would have been true.
|
||||
const typeParameter = getTypeParameterFromJsDoc(entityName.parent as TypeParameterDeclaration & { parent: JSDocTemplateTag });
|
||||
return typeParameter && typeParameter.symbol;
|
||||
}
|
||||
|
||||
if (isPartOfExpression(entityName)) {
|
||||
if (nodeIsMissing(entityName)) {
|
||||
// Missing entity name.
|
||||
@@ -24796,7 +24813,6 @@ namespace ts {
|
||||
// falls through
|
||||
default:
|
||||
return isDeclarationName(name);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,7 +596,7 @@ namespace ts {
|
||||
currentIdentifiers = node.identifiers;
|
||||
isCurrentFileExternalModule = isExternalModule(node);
|
||||
enclosingDeclaration = node;
|
||||
emitDetachedComments(currentText, currentLineMap, writer, writeCommentRange, node, newLine, /*removeComents*/ true);
|
||||
emitDetachedComments(currentText, currentLineMap, writer, writeCommentRange, node, newLine, /*removeComments*/ true);
|
||||
emitLines(node.statements);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace ts {
|
||||
else if (kind === SyntaxKind.Identifier) {
|
||||
return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, pos, end);
|
||||
}
|
||||
else if (kind < SyntaxKind.FirstNode) {
|
||||
else if (!isNodeKind(kind)) {
|
||||
return new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, pos, end);
|
||||
}
|
||||
else {
|
||||
@@ -481,7 +481,11 @@ namespace ts {
|
||||
// becoming detached from any SourceFile). It is recommended that this SourceFile not
|
||||
// be used once 'update' is called on it.
|
||||
export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile {
|
||||
return IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
|
||||
const newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
|
||||
// Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import.
|
||||
// We will manually port the flag to the new source file.
|
||||
newSourceFile.flags |= (sourceFile.flags & NodeFlags.PossiblyContainsDynamicImport);
|
||||
return newSourceFile;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -1099,7 +1103,7 @@ namespace ts {
|
||||
pos = scanner.getStartPos();
|
||||
}
|
||||
|
||||
return kind >= SyntaxKind.FirstNode ? new NodeConstructor(kind, pos, pos) :
|
||||
return isNodeKind(kind) ? new NodeConstructor(kind, pos, pos) :
|
||||
kind === SyntaxKind.Identifier ? new IdentifierConstructor(kind, pos, pos) :
|
||||
new TokenConstructor(kind, pos, pos);
|
||||
}
|
||||
@@ -3701,7 +3705,7 @@ namespace ts {
|
||||
// For example:
|
||||
// var foo3 = require("subfolder
|
||||
// import * as foo1 from "module-from-node -> we want this import to be a statement rather than import call expression
|
||||
sourceFile.flags |= NodeFlags.PossiblyContainDynamicImport;
|
||||
sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport;
|
||||
expression = parseTokenNode<PrimaryExpression>();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1379,7 +1379,7 @@ namespace ts {
|
||||
|
||||
for (const node of file.statements) {
|
||||
collectModuleReferences(node, /*inAmbientModule*/ false);
|
||||
if ((file.flags & NodeFlags.PossiblyContainDynamicImport) || isJavaScriptFile) {
|
||||
if ((file.flags & NodeFlags.PossiblyContainsDynamicImport) || isJavaScriptFile) {
|
||||
collectDynamicImportOrRequireCalls(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ namespace ts {
|
||||
getDirectories(path: string): string[];
|
||||
readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[];
|
||||
getModifiedTime?(path: string): Date;
|
||||
/**
|
||||
* This should be cryptographically secure.
|
||||
* A good implementation is node.js' `crypto.createHash`. (https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm)
|
||||
*/
|
||||
createHash?(data: string): string;
|
||||
getMemoryUsage?(): number;
|
||||
exit(exitCode?: number): void;
|
||||
|
||||
@@ -239,7 +239,7 @@ namespace ts {
|
||||
function hoistVariableDeclaration(name: Identifier): void {
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
const decl = createVariableDeclaration(name);
|
||||
const decl = setEmitFlags(createVariableDeclaration(name), EmitFlags.NoNestedSourceMaps);
|
||||
if (!lexicalEnvironmentVariableDeclarations) {
|
||||
lexicalEnvironmentVariableDeclarations = [decl];
|
||||
}
|
||||
|
||||
@@ -640,10 +640,13 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return createStatement(
|
||||
inlineExpressions(
|
||||
map(variables, transformInitializedVariable)
|
||||
)
|
||||
return setSourceMapRange(
|
||||
createStatement(
|
||||
inlineExpressions(
|
||||
map(variables, transformInitializedVariable)
|
||||
)
|
||||
),
|
||||
node
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1281,9 +1284,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function transformInitializedVariable(node: VariableDeclaration) {
|
||||
return createAssignment(
|
||||
<Identifier>getSynthesizedClone(node.name),
|
||||
visitNode(node.initializer, visitor, isExpression)
|
||||
return setSourceMapRange(
|
||||
createAssignment(
|
||||
setSourceMapRange(<Identifier>getSynthesizedClone(node.name), node.name),
|
||||
visitNode(node.initializer, visitor, isExpression)
|
||||
),
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -514,14 +514,14 @@ namespace ts {
|
||||
|
||||
function visitImportCallExpression(node: ImportCall): Expression {
|
||||
switch (compilerOptions.module) {
|
||||
case ModuleKind.CommonJS:
|
||||
return transformImportCallExpressionCommonJS(node);
|
||||
case ModuleKind.AMD:
|
||||
return transformImportCallExpressionAMD(node);
|
||||
case ModuleKind.UMD:
|
||||
return transformImportCallExpressionUMD(node);
|
||||
case ModuleKind.CommonJS:
|
||||
default:
|
||||
return transformImportCallExpressionCommonJS(node);
|
||||
}
|
||||
Debug.fail("All supported module kind in this transformation step should have been handled");
|
||||
}
|
||||
|
||||
function transformImportCallExpressionUMD(node: ImportCall): Expression {
|
||||
|
||||
@@ -662,6 +662,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (ts.Debug.isDebugging) {
|
||||
ts.Debug.enableDebugInfo();
|
||||
}
|
||||
|
||||
if (ts.sys.tryEnableSourceMapsForHost && /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))) {
|
||||
ts.sys.tryEnableSourceMapsForHost();
|
||||
}
|
||||
|
||||
@@ -451,13 +451,16 @@ namespace ts {
|
||||
ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error
|
||||
HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node
|
||||
|
||||
// This flag will be set to true when the parse encounter dynamic import so that post-parsing process of module resolution
|
||||
// will not walk the tree if the flag is not set. However, this flag is just a approximation because once it is set, the flag never get reset.
|
||||
// (hence it is named "possiblyContainDynamicImport").
|
||||
// During editing, if dynamic import is remove, incremental parsing will *NOT* update this flag. This will then causes walking of the tree during module resolution.
|
||||
// However, the removal operation should not occur often and in the case of the removal, it is likely that users will add back the import anyway.
|
||||
// The advantage of this approach is its simplicity. For the case of batch compilation, we garuntee that users won't have to pay the price of walking the tree if dynamic import isn't used.
|
||||
PossiblyContainDynamicImport = 1 << 19,
|
||||
// This flag will be set when the parser encounters a dynamic import expression so that module resolution
|
||||
// will not have to walk the tree if the flag is not set. However, this flag is just a approximation because
|
||||
// once it is set, the flag never gets cleared (hence why it's named "PossiblyContainsDynamicImport").
|
||||
// During editing, if dynamic import is removed, incremental parsing will *NOT* update this flag. This means that the tree will always be traversed
|
||||
// during module resolution. However, the removal operation should not occur often and in the case of the
|
||||
// removal, it is likely that users will add the import anyway.
|
||||
// The advantage of this approach is its simplicity. For the case of batch compilation,
|
||||
// we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used.
|
||||
/* @internal */
|
||||
PossiblyContainsDynamicImport = 1 << 19,
|
||||
|
||||
BlockScoped = Let | Const,
|
||||
|
||||
@@ -1794,7 +1797,7 @@ namespace ts {
|
||||
block: Block;
|
||||
}
|
||||
|
||||
export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration;
|
||||
export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
|
||||
export interface ClassLikeDeclaration extends NamedDeclaration {
|
||||
name?: Identifier;
|
||||
|
||||
@@ -1546,6 +1546,12 @@ namespace ts {
|
||||
p.name.kind === SyntaxKind.Identifier && p.name.text === name);
|
||||
}
|
||||
|
||||
export function getTypeParameterFromJsDoc(node: TypeParameterDeclaration & { parent: JSDocTemplateTag }): TypeParameterDeclaration | undefined {
|
||||
const name = node.name.text;
|
||||
const { typeParameters } = (node.parent.parent.parent as ts.SignatureDeclaration | ts.InterfaceDeclaration | ts.ClassDeclaration);
|
||||
return find(typeParameters, p => p.name.text === name);
|
||||
}
|
||||
|
||||
export function getJSDocType(node: Node): JSDocType {
|
||||
let tag: JSDocTypeTag | JSDocParameterTag = getFirstJSDocTag(node, SyntaxKind.JSDocTypeTag) as JSDocTypeTag;
|
||||
if (!tag && node.kind === SyntaxKind.Parameter) {
|
||||
@@ -1570,6 +1576,11 @@ namespace ts {
|
||||
return getFirstJSDocTag(node, SyntaxKind.JSDocReturnTag) as JSDocReturnTag;
|
||||
}
|
||||
|
||||
export function getJSDocReturnType(node: Node): JSDocType {
|
||||
const returnTag = getJSDocReturnTag(node);
|
||||
return returnTag && returnTag.typeExpression && returnTag.typeExpression.type;
|
||||
}
|
||||
|
||||
export function getJSDocTemplateTag(node: Node): JSDocTemplateTag {
|
||||
return getFirstJSDocTag(node, SyntaxKind.JSDocTemplateTag) as JSDocTemplateTag;
|
||||
}
|
||||
@@ -2615,14 +2626,19 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
/** Get the type annotaion for the value parameter. */
|
||||
export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode {
|
||||
function getSetAccessorValueParameter(accessor: SetAccessorDeclaration): ParameterDeclaration | undefined {
|
||||
if (accessor && accessor.parameters.length > 0) {
|
||||
const hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]);
|
||||
return accessor.parameters[hasThis ? 1 : 0].type;
|
||||
return accessor.parameters[hasThis ? 1 : 0];
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the type annotation for the value parameter. */
|
||||
export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode {
|
||||
const parameter = getSetAccessorValueParameter(accessor);
|
||||
return parameter && parameter.type;
|
||||
}
|
||||
|
||||
export function getThisParameter(signature: SignatureDeclaration): ParameterDeclaration | undefined {
|
||||
if (signature.parameters.length) {
|
||||
const thisParameter = signature.parameters[0];
|
||||
@@ -2701,6 +2717,41 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the effective type annotation of a variable, parameter, or property. If the node was
|
||||
* parsed in a JavaScript file, gets the type annotation from JSDoc.
|
||||
*/
|
||||
export function getEffectiveTypeAnnotationNode(node: VariableLikeDeclaration): TypeNode {
|
||||
if (node.type) {
|
||||
return node.type;
|
||||
}
|
||||
if (node.flags & NodeFlags.JavaScriptFile) {
|
||||
return getJSDocType(node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the effective return type annotation of a signature. If the node was parsed in a
|
||||
* JavaScript file, gets the return type annotation from JSDoc.
|
||||
*/
|
||||
export function getEffectiveReturnTypeNode(node: SignatureDeclaration): TypeNode {
|
||||
if (node.type) {
|
||||
return node.type;
|
||||
}
|
||||
if (node.flags & NodeFlags.JavaScriptFile) {
|
||||
return getJSDocReturnType(node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the effective type annotation of the value parameter of a set accessor. If the node
|
||||
* was parsed in a JavaScript file, gets the type annotation from JSDoc.
|
||||
*/
|
||||
export function getEffectiveSetAccessorTypeAnnotationNode(node: SetAccessorDeclaration): TypeNode {
|
||||
const parameter = getSetAccessorValueParameter(node);
|
||||
return parameter && getEffectiveTypeAnnotationNode(parameter);
|
||||
}
|
||||
|
||||
export function emitNewLineBeforeLeadingComments(lineMap: number[], writer: EmitTextWriter, node: TextRange, leadingComments: CommentRange[]) {
|
||||
emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, node.pos, leadingComments);
|
||||
}
|
||||
@@ -4670,6 +4721,16 @@ namespace ts {
|
||||
// All node tests in the following list should *not* reference parent pointers so that
|
||||
// they may be used with transformations.
|
||||
namespace ts {
|
||||
/* @internal */
|
||||
export function isNode(node: Node) {
|
||||
return isNodeKind(node.kind);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isNodeKind(kind: SyntaxKind) {
|
||||
return kind >= SyntaxKind.FirstNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if node is of some token syntax kind.
|
||||
* For example, this is true for an IfKeyword but not for an IfStatement.
|
||||
@@ -5219,6 +5280,10 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function isDeclaration(node: Node): node is NamedDeclaration {
|
||||
if (node.kind === SyntaxKind.TypeParameter) {
|
||||
return node.parent.kind !== SyntaxKind.JSDocTemplateTag || isInJavaScriptFile(node);
|
||||
}
|
||||
|
||||
return isDeclarationKind(node.kind);
|
||||
}
|
||||
|
||||
@@ -5308,6 +5373,11 @@ namespace ts {
|
||||
return node.kind >= SyntaxKind.FirstJSDocNode && node.kind <= SyntaxKind.LastJSDocNode;
|
||||
}
|
||||
|
||||
/** True if node is of a kind that may contain comment text. */
|
||||
export function isJSDocCommentContainingNode(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.JSDocComment || isJSDocTag(node);
|
||||
}
|
||||
|
||||
// TODO: determine what this does before making it public.
|
||||
/* @internal */
|
||||
export function isJSDocTag(node: Node): boolean {
|
||||
|
||||
@@ -1517,35 +1517,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export namespace Debug {
|
||||
if (isDebugging) {
|
||||
// Add additional properties in debug mode to assist with debugging.
|
||||
Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, {
|
||||
"__debugFlags": { get(this: Symbol) { return formatSymbolFlags(this.flags); } }
|
||||
});
|
||||
|
||||
Object.defineProperties(objectAllocator.getTypeConstructor().prototype, {
|
||||
"__debugFlags": { get(this: Type) { return formatTypeFlags(this.flags); } },
|
||||
"__debugObjectFlags": { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((<ObjectType>this).objectFlags) : ""; } },
|
||||
"__debugTypeToString": { value(this: Type) { return this.checker.typeToString(this); } },
|
||||
});
|
||||
|
||||
for (const ctor of [objectAllocator.getNodeConstructor(), objectAllocator.getIdentifierConstructor(), objectAllocator.getTokenConstructor(), objectAllocator.getSourceFileConstructor()]) {
|
||||
if (!ctor.prototype.hasOwnProperty("__debugKind")) {
|
||||
Object.defineProperties(ctor.prototype, {
|
||||
"__debugKind": { get(this: Node) { return formatSyntaxKind(this.kind); } },
|
||||
"__debugModifierFlags": { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } },
|
||||
"__debugTransformFlags": { get(this: Node) { return formatTransformFlags(this.transformFlags); } },
|
||||
"__debugEmitFlags": { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } },
|
||||
"__debugGetText": { value(this: Node, includeTrivia?: boolean) {
|
||||
if (nodeIsSynthesized(this)) return "";
|
||||
const parseNode = getParseTreeNode(this);
|
||||
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
|
||||
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
|
||||
} }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
let isDebugInfoEnabled = false;
|
||||
|
||||
export const failBadSyntaxKind = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node, message?: string): void => fail(
|
||||
@@ -1592,5 +1564,51 @@ namespace ts {
|
||||
() => `Node ${formatSyntaxKind(node.kind)} was unexpected'.`,
|
||||
assertMissingNode)
|
||||
: noop;
|
||||
|
||||
/**
|
||||
* Injects debug information into frequently used types.
|
||||
*/
|
||||
export function enableDebugInfo() {
|
||||
if (isDebugInfoEnabled) return;
|
||||
|
||||
// Add additional properties in debug mode to assist with debugging.
|
||||
Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, {
|
||||
"__debugFlags": { get(this: Symbol) { return formatSymbolFlags(this.flags); } }
|
||||
});
|
||||
|
||||
Object.defineProperties(objectAllocator.getTypeConstructor().prototype, {
|
||||
"__debugFlags": { get(this: Type) { return formatTypeFlags(this.flags); } },
|
||||
"__debugObjectFlags": { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((<ObjectType>this).objectFlags) : ""; } },
|
||||
"__debugTypeToString": { value(this: Type) { return this.checker.typeToString(this); } },
|
||||
});
|
||||
|
||||
const nodeConstructors = [
|
||||
objectAllocator.getNodeConstructor(),
|
||||
objectAllocator.getIdentifierConstructor(),
|
||||
objectAllocator.getTokenConstructor(),
|
||||
objectAllocator.getSourceFileConstructor()
|
||||
];
|
||||
|
||||
for (const ctor of nodeConstructors) {
|
||||
if (!ctor.prototype.hasOwnProperty("__debugKind")) {
|
||||
Object.defineProperties(ctor.prototype, {
|
||||
"__debugKind": { get(this: Node) { return formatSyntaxKind(this.kind); } },
|
||||
"__debugModifierFlags": { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } },
|
||||
"__debugTransformFlags": { get(this: Node) { return formatTransformFlags(this.transformFlags); } },
|
||||
"__debugEmitFlags": { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } },
|
||||
"__debugGetText": {
|
||||
value(this: Node, includeTrivia?: boolean) {
|
||||
if (nodeIsSynthesized(this)) return "";
|
||||
const parseNode = getParseTreeNode(this);
|
||||
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
|
||||
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
isDebugInfoEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -731,7 +731,7 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
|
||||
createHash(s: string) {
|
||||
return s;
|
||||
return mockHash(s);
|
||||
}
|
||||
|
||||
require(_initialDir: string, _moduleName: string): ts.server.RequireResult {
|
||||
@@ -856,4 +856,8 @@ namespace Harness.LanguageService {
|
||||
getClassifier(): ts.Classifier { throw new Error("getClassifier is not available using the server interface."); }
|
||||
getPreProcessedFileInfo(): ts.PreProcessedFileInfo { throw new Error("getPreProcessedFileInfo is not available using the server interface."); }
|
||||
}
|
||||
|
||||
export function mockHash(s: string): string {
|
||||
return `hash-${s}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,6 +222,10 @@ if (taskConfigsFolder) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ts.Debug.isDebugging) {
|
||||
ts.Debug.enableDebugInfo();
|
||||
}
|
||||
|
||||
runTests(runners);
|
||||
}
|
||||
if (!runUnitTests) {
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace ts {
|
||||
clearTimeout,
|
||||
setImmediate: typeof setImmediate !== "undefined" ? setImmediate : action => setTimeout(action, 0),
|
||||
clearImmediate: typeof clearImmediate !== "undefined" ? clearImmediate : clearTimeout,
|
||||
createHash: s => s
|
||||
createHash: Harness.LanguageService.mockHash,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace ts.server {
|
||||
clearTimeout: noop,
|
||||
setImmediate: () => 0,
|
||||
clearImmediate: noop,
|
||||
createHash: s => s
|
||||
createHash: Harness.LanguageService.mockHash,
|
||||
};
|
||||
|
||||
const mockLogger: Logger = {
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace ts.projectSystem {
|
||||
et.service.openClientFile(file.path);
|
||||
assert.equal(et.getEvents().length, 0);
|
||||
});
|
||||
|
||||
it("only sends an event once", () => {
|
||||
const file = makeFile("/a.ts");
|
||||
const tsconfig = makeFile("/tsconfig.json", {});
|
||||
@@ -46,12 +47,13 @@ namespace ts.projectSystem {
|
||||
const et = new EventTracker([file1]);
|
||||
const compilerOptions: ts.CompilerOptions = { strict: true };
|
||||
|
||||
const projectFileName = "foo.csproj";
|
||||
const projectFileName = "/hunter2/foo.csproj";
|
||||
|
||||
open();
|
||||
|
||||
// TODO: Apparently compilerOptions is mutated, so have to repeat it here!
|
||||
et.assertProjectInfoTelemetryEvent({
|
||||
projectId: Harness.LanguageService.mockHash("/hunter2/foo.csproj"),
|
||||
compilerOptions: { strict: true },
|
||||
compileOnSave: true,
|
||||
// These properties can't be present for an external project, so they are undefined instead of false.
|
||||
@@ -195,6 +197,7 @@ namespace ts.projectSystem {
|
||||
const et = new EventTracker([jsconfig, file]);
|
||||
et.service.openClientFile(file.path);
|
||||
et.assertProjectInfoTelemetryEvent({
|
||||
projectId: Harness.LanguageService.mockHash("/jsconfig.json"),
|
||||
fileStats: fileStats({ js: 1 }),
|
||||
compilerOptions: autoJsCompilerOptions,
|
||||
typeAcquisition: {
|
||||
@@ -214,6 +217,7 @@ namespace ts.projectSystem {
|
||||
et.service.openClientFile(file.path);
|
||||
et.getEvent<server.ProjectLanguageServiceStateEvent>(server.ProjectLanguageServiceStateEvent, /*mayBeMore*/ true);
|
||||
et.assertProjectInfoTelemetryEvent({
|
||||
projectId: Harness.LanguageService.mockHash("/jsconfig.json"),
|
||||
fileStats: fileStats({ js: 1 }),
|
||||
compilerOptions: autoJsCompilerOptions,
|
||||
configFileName: "jsconfig.json",
|
||||
@@ -248,7 +252,26 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
assertProjectInfoTelemetryEvent(partial: Partial<server.ProjectInfoTelemetryEventData>): void {
|
||||
assert.deepEqual(this.getEvent<server.ProjectInfoTelemetryEvent>(ts.server.ProjectInfoTelemetryEvent), makePayload(partial));
|
||||
assert.deepEqual(this.getEvent<server.ProjectInfoTelemetryEvent>(ts.server.ProjectInfoTelemetryEvent), {
|
||||
projectId: Harness.LanguageService.mockHash("/tsconfig.json"),
|
||||
fileStats: fileStats({ ts: 1 }),
|
||||
compilerOptions: {},
|
||||
extends: false,
|
||||
files: false,
|
||||
include: false,
|
||||
exclude: false,
|
||||
compileOnSave: false,
|
||||
typeAcquisition: {
|
||||
enable: false,
|
||||
exclude: false,
|
||||
include: false,
|
||||
},
|
||||
configFileName: "tsconfig.json",
|
||||
projectType: "configured",
|
||||
languageServiceEnabled: true,
|
||||
version: ts.version,
|
||||
...partial,
|
||||
});
|
||||
}
|
||||
|
||||
getEvent<T extends server.ProjectServiceEvent>(eventName: T["eventName"], mayBeMore = false): T["data"] {
|
||||
@@ -260,28 +283,6 @@ namespace ts.projectSystem {
|
||||
}
|
||||
}
|
||||
|
||||
function makePayload(partial: Partial<server.ProjectInfoTelemetryEventData>): server.ProjectInfoTelemetryEventData {
|
||||
return {
|
||||
fileStats: fileStats({ ts: 1 }),
|
||||
compilerOptions: {},
|
||||
extends: false,
|
||||
files: false,
|
||||
include: false,
|
||||
exclude: false,
|
||||
compileOnSave: false,
|
||||
typeAcquisition: {
|
||||
enable: false,
|
||||
exclude: false,
|
||||
include: false,
|
||||
},
|
||||
configFileName: "tsconfig.json",
|
||||
projectType: "configured",
|
||||
languageServiceEnabled: true,
|
||||
version: ts.version,
|
||||
...partial
|
||||
};
|
||||
}
|
||||
|
||||
function makeFile(path: string, content: {} = ""): projectSystem.FileOrFolder {
|
||||
return { path, content: typeof content === "string" ? "" : JSON.stringify(content) };
|
||||
}
|
||||
|
||||
@@ -472,7 +472,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
createHash(s: string): string {
|
||||
return s;
|
||||
return Harness.LanguageService.mockHash(s);
|
||||
}
|
||||
|
||||
triggerDirectoryWatcherCallback(directoryName: string, fileName: string): void {
|
||||
|
||||
@@ -37,6 +37,8 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
export interface ProjectInfoTelemetryEventData {
|
||||
/** Cryptographically secure hash of project file location. */
|
||||
readonly projectId: string;
|
||||
/** Count of file extensions seen in the project. */
|
||||
readonly fileStats: FileStats;
|
||||
/**
|
||||
@@ -1049,6 +1051,7 @@ namespace ts.server {
|
||||
if (!this.eventHandler) return;
|
||||
|
||||
const data: ProjectInfoTelemetryEventData = {
|
||||
projectId: this.host.createHash(projectKey),
|
||||
fileStats: countEachFileTypes(project.getScriptInfos()),
|
||||
compilerOptions: convertCompilerOptionsForTelemetry(project.getCompilerOptions()),
|
||||
typeAcquisition: convertTypeAcquisition(project.getTypeAcquisition()),
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace ts.server {
|
||||
} = require("os");
|
||||
|
||||
function getGlobalTypingsCacheLocation() {
|
||||
const versionMajorMinor = ts.version.match(/\d+\.\d+/)[0];
|
||||
switch (process.platform) {
|
||||
case "win32": {
|
||||
const basePath = process.env.LOCALAPPDATA ||
|
||||
@@ -43,7 +44,7 @@ namespace ts.server {
|
||||
process.env.USERPROFILE ||
|
||||
(process.env.HOMEDRIVE && process.env.HOMEPATH && normalizeSlashes(process.env.HOMEDRIVE + process.env.HOMEPATH)) ||
|
||||
os.tmpdir();
|
||||
return combinePaths(normalizeSlashes(basePath), "Microsoft/TypeScript");
|
||||
return combinePaths(combinePaths(normalizeSlashes(basePath), "Microsoft/TypeScript"), versionMajorMinor);
|
||||
}
|
||||
case "openbsd":
|
||||
case "freebsd":
|
||||
@@ -51,7 +52,7 @@ namespace ts.server {
|
||||
case "linux":
|
||||
case "android": {
|
||||
const cacheLocation = getNonWindowsCacheLocation(process.platform === "darwin");
|
||||
return combinePaths(cacheLocation, "typescript");
|
||||
return combinePaths(combinePaths(cacheLocation, "typescript"), versionMajorMinor);
|
||||
}
|
||||
default:
|
||||
Debug.fail(`unsupported platform '${process.platform}'`);
|
||||
|
||||
@@ -724,8 +724,8 @@ namespace ts {
|
||||
pushCommentRange(pos, tag.pos - pos);
|
||||
}
|
||||
|
||||
pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, ClassificationType.punctuation);
|
||||
pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, ClassificationType.docCommentTagName);
|
||||
pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, ClassificationType.punctuation); // "@"
|
||||
pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, ClassificationType.docCommentTagName); // e.g. "param"
|
||||
|
||||
pos = tag.tagName.end;
|
||||
|
||||
@@ -814,7 +814,7 @@ namespace ts {
|
||||
* False will mean that node is not classified and traverse routine should recurse into node contents.
|
||||
*/
|
||||
function tryClassifyNode(node: Node): boolean {
|
||||
if (isJSDocNode(node)) {
|
||||
if (isJSDoc(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -445,7 +445,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
start = timestamp();
|
||||
const previousToken = findPrecedingToken(position, sourceFile);
|
||||
const previousToken = findPrecedingToken(position, sourceFile, /*startNode*/ undefined, /*includeJsDoc*/ true);
|
||||
log("getCompletionData: Get previous token 1: " + (timestamp() - start));
|
||||
|
||||
// The decision to provide completion depends on the contextToken, which is determined through the previousToken.
|
||||
@@ -456,7 +456,7 @@ namespace ts.Completions {
|
||||
// Skip this partial identifier and adjust the contextToken to the token that precedes it.
|
||||
if (contextToken && position <= contextToken.end && isWord(contextToken.kind)) {
|
||||
const start = timestamp();
|
||||
contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile);
|
||||
contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined, /*includeJsDoc*/ true);
|
||||
log("getCompletionData: Get previous token 2: " + (timestamp() - start));
|
||||
}
|
||||
|
||||
|
||||
@@ -784,8 +784,8 @@ namespace ts.FindAllReferences.Core {
|
||||
return;
|
||||
}
|
||||
|
||||
const fullStart = state.options.findInComments || container.jsDoc !== undefined || forEach(search.symbol.declarations, d => d.kind === ts.SyntaxKind.JSDocTypedefTag);
|
||||
for (const position of getPossibleSymbolReferencePositions(sourceFile, search.text, container, fullStart)) {
|
||||
// Need to search in the full start of the node in case there is a reference inside JSDoc.
|
||||
for (const position of getPossibleSymbolReferencePositions(sourceFile, search.text, container, /*fullStart*/ true)) {
|
||||
getReferencesAtLocation(sourceFile, position, search, state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,9 +95,16 @@ namespace ts {
|
||||
function tryConsumeImport(): boolean {
|
||||
let token = scanner.getToken();
|
||||
if (token === SyntaxKind.ImportKeyword) {
|
||||
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
if (token === SyntaxKind.OpenParenToken) {
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
// import("mod");
|
||||
recordModuleName();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (token === SyntaxKind.StringLiteral) {
|
||||
// import "mod";
|
||||
recordModuleName();
|
||||
return true;
|
||||
@@ -297,7 +304,8 @@ namespace ts {
|
||||
// import * as NS from "mod"
|
||||
// import d, {a, b as B} from "mod"
|
||||
// import i = require("mod");
|
||||
//
|
||||
// import("mod");
|
||||
|
||||
// export * from "mod"
|
||||
// export {a as b} from "mod"
|
||||
// export import i = require("mod")
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace ts {
|
||||
let ruleProvider: formatting.RulesProvider;
|
||||
|
||||
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) :
|
||||
const node = isNodeKind(kind) ? new NodeObject(kind, pos, end) :
|
||||
kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) :
|
||||
new TokenObject(kind, pos, end);
|
||||
node.parent = parent;
|
||||
@@ -103,10 +103,10 @@ namespace ts {
|
||||
return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd());
|
||||
}
|
||||
|
||||
private addSyntheticNodes(nodes: Node[], pos: number, end: number, useJSDocScanner?: boolean): number {
|
||||
private addSyntheticNodes(nodes: Node[], pos: number, end: number): number {
|
||||
scanner.setTextPos(pos);
|
||||
while (pos < end) {
|
||||
const token = useJSDocScanner ? scanner.scanJSDocToken() : scanner.scan();
|
||||
const token = scanner.scan();
|
||||
Debug.assert(token !== SyntaxKind.EndOfFileToken); // Else it would infinitely loop
|
||||
const textPos = scanner.getTextPos();
|
||||
if (textPos <= end) {
|
||||
@@ -136,54 +136,50 @@ namespace ts {
|
||||
}
|
||||
|
||||
private createChildren(sourceFile?: SourceFileLike) {
|
||||
if (this.kind === SyntaxKind.JSDocComment || isJSDocTag(this)) {
|
||||
if (!isNodeKind(this.kind)) {
|
||||
this._children = emptyArray;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isJSDocCommentContainingNode(this)) {
|
||||
/** Don't add trivia for "tokens" since this is in a comment. */
|
||||
const children: Node[] = [];
|
||||
this.forEachChild(child => { children.push(child); });
|
||||
this._children = children;
|
||||
return;
|
||||
}
|
||||
else if (this.kind >= SyntaxKind.FirstNode) {
|
||||
const children: Node[] = [];
|
||||
scanner.setText((sourceFile || this.getSourceFile()).text);
|
||||
let pos = this.pos;
|
||||
const useJSDocScanner = isJSDocNode(this);
|
||||
const processNode = (node: Node) => {
|
||||
const isJSDocTagNode = isJSDocNode(node);
|
||||
if (!isJSDocTagNode && pos < node.pos) {
|
||||
pos = this.addSyntheticNodes(children, pos, node.pos, useJSDocScanner);
|
||||
}
|
||||
children.push(node);
|
||||
if (!isJSDocTagNode) {
|
||||
pos = node.end;
|
||||
}
|
||||
};
|
||||
const processNodes = (nodes: NodeArray<Node>) => {
|
||||
if (pos < nodes.pos) {
|
||||
pos = this.addSyntheticNodes(children, pos, nodes.pos, useJSDocScanner);
|
||||
}
|
||||
children.push(this.createSyntaxList(nodes));
|
||||
pos = nodes.end;
|
||||
};
|
||||
// jsDocComments need to be the first children
|
||||
if (this.jsDoc) {
|
||||
for (const jsDocComment of this.jsDoc) {
|
||||
processNode(jsDocComment);
|
||||
}
|
||||
|
||||
const children: Node[] = [];
|
||||
scanner.setText((sourceFile || this.getSourceFile()).text);
|
||||
let pos = this.pos;
|
||||
const processNode = (node: Node) => {
|
||||
pos = this.addSyntheticNodes(children, pos, node.pos);
|
||||
children.push(node);
|
||||
pos = node.end;
|
||||
};
|
||||
const processNodes = (nodes: NodeArray<Node>) => {
|
||||
if (pos < nodes.pos) {
|
||||
pos = this.addSyntheticNodes(children, pos, nodes.pos);
|
||||
}
|
||||
// For syntactic classifications, all trivia are classcified together, including jsdoc comments.
|
||||
// For that to work, the jsdoc comments should still be the leading trivia of the first child.
|
||||
// Restoring the scanner position ensures that.
|
||||
pos = this.pos;
|
||||
forEachChild(this, processNode, processNodes);
|
||||
if (pos < this.end) {
|
||||
this.addSyntheticNodes(children, pos, this.end);
|
||||
children.push(this.createSyntaxList(nodes));
|
||||
pos = nodes.end;
|
||||
};
|
||||
// jsDocComments need to be the first children
|
||||
if (this.jsDoc) {
|
||||
for (const jsDocComment of this.jsDoc) {
|
||||
processNode(jsDocComment);
|
||||
}
|
||||
scanner.setText(undefined);
|
||||
this._children = children;
|
||||
}
|
||||
else {
|
||||
this._children = emptyArray;
|
||||
// For syntactic classifications, all trivia are classcified together, including jsdoc comments.
|
||||
// For that to work, the jsdoc comments should still be the leading trivia of the first child.
|
||||
// Restoring the scanner position ensures that.
|
||||
pos = this.pos;
|
||||
forEachChild(this, processNode, processNodes);
|
||||
if (pos < this.end) {
|
||||
this.addSyntheticNodes(children, pos, this.end);
|
||||
}
|
||||
scanner.setText(undefined);
|
||||
this._children = children;
|
||||
}
|
||||
|
||||
public getChildCount(sourceFile?: SourceFile): number {
|
||||
|
||||
@@ -94,6 +94,10 @@ namespace ts {
|
||||
else if (isNamespaceReference(node)) {
|
||||
return SemanticMeaning.Namespace;
|
||||
}
|
||||
else if (isTypeParameter(node.parent)) {
|
||||
Debug.assert(isJSDocTemplateTag(node.parent.parent)); // Else would be handled by isDeclarationName
|
||||
return SemanticMeaning.Type;
|
||||
}
|
||||
else {
|
||||
return SemanticMeaning.Value;
|
||||
}
|
||||
@@ -710,7 +714,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function findPrecedingToken(position: number, sourceFile: SourceFile, startNode?: Node): Node {
|
||||
export function findPrecedingToken(position: number, sourceFile: SourceFile, startNode?: Node, includeJsDoc?: boolean): Node {
|
||||
return find(startNode || sourceFile);
|
||||
|
||||
function findRightmostToken(n: Node): Node {
|
||||
@@ -741,7 +745,7 @@ namespace ts {
|
||||
// NOTE: JsxText is a weird kind of node that can contain only whitespaces (since they are not counted as trivia).
|
||||
// if this is the case - then we should assume that token in question is located in previous child.
|
||||
if (position < child.end && (nodeHasTokens(child) || child.kind === SyntaxKind.JsxText)) {
|
||||
const start = child.getStart(sourceFile);
|
||||
const start = (includeJsDoc && child.jsDoc ? child.jsDoc[0] : child).getStart(sourceFile);
|
||||
const lookInPreviousChild =
|
||||
(start >= position) || // cursor in the leading trivia
|
||||
(child.kind === SyntaxKind.JsxText && start === child.end); // whitespace only JsxText
|
||||
@@ -758,7 +762,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
Debug.assert(startNode !== undefined || n.kind === SyntaxKind.SourceFile);
|
||||
Debug.assert(startNode !== undefined || n.kind === SyntaxKind.SourceFile || isJSDocCommentContainingNode(n));
|
||||
|
||||
// Here we know that none of child token nodes embrace the position,
|
||||
// the only known case is when position is at the end of the file.
|
||||
|
||||
25
tests/baselines/reference/checkJsdocReturnTag2.errors.txt
Normal file
25
tests/baselines/reference/checkJsdocReturnTag2.errors.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
tests/cases/conformance/jsdoc/returns.js(6,5): error TS2322: Type '5' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsdoc/returns.js(13,5): error TS2322: Type 'true | 5' is not assignable to type 'string | number'.
|
||||
Type 'true' is not assignable to type 'string | number'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/returns.js (2 errors) ====
|
||||
// @ts-check
|
||||
/**
|
||||
* @returns {string} This comment is not currently exposed
|
||||
*/
|
||||
function f() {
|
||||
return 5;
|
||||
~~~~~~~~~
|
||||
!!! error TS2322: Type '5' is not assignable to type 'string'.
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string | number} This comment is not currently exposed
|
||||
*/
|
||||
function f1() {
|
||||
return 5 || true;
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'true | 5' is not assignable to type 'string | number'.
|
||||
!!! error TS2322: Type 'true' is not assignable to type 'string | number'.
|
||||
}
|
||||
@@ -61,10 +61,10 @@ x(1);
|
||||
/** @type {function (number)} */
|
||||
const x1 = (a) => a + 1;
|
||||
>x1 : (arg0: number) => any
|
||||
>(a) => a + 1 : (a: any) => any
|
||||
>a : any
|
||||
>a + 1 : any
|
||||
>a : any
|
||||
>(a) => a + 1 : (a: number) => number
|
||||
>a : number
|
||||
>a + 1 : number
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
x1(0);
|
||||
@@ -75,10 +75,10 @@ x1(0);
|
||||
/** @type {function (number): number} */
|
||||
const x2 = (a) => a + 1;
|
||||
>x2 : (arg0: number) => number
|
||||
>(a) => a + 1 : (a: any) => any
|
||||
>a : any
|
||||
>a + 1 : any
|
||||
>a : any
|
||||
>(a) => a + 1 : (a: number) => number
|
||||
>a : number
|
||||
>a + 1 : number
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
x2(0);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
tests/cases/conformance/jsdoc/0.js(3,5): error TS2322: Type 'true' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsdoc/0.js(6,5): error TS2322: Type '"hello"' is not assignable to type 'number'.
|
||||
tests/cases/conformance/jsdoc/0.js(10,4): error TS2345: Argument of type '"string"' is not assignable to parameter of type 'number'.
|
||||
tests/cases/conformance/jsdoc/0.js(13,7): error TS2451: Cannot redeclare block-scoped variable 'x2'.
|
||||
tests/cases/conformance/jsdoc/0.js(17,1): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsdoc/0.js(20,7): error TS2451: Cannot redeclare block-scoped variable 'x2'.
|
||||
tests/cases/conformance/jsdoc/0.js(20,21): error TS2339: Property 'concat' does not exist on type 'number'.
|
||||
tests/cases/conformance/jsdoc/0.js(24,7): error TS2322: Type '(a: number) => number' is not assignable to type '(arg0: number) => string'.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/0.js (6 errors) ====
|
||||
@@ -26,8 +27,6 @@ tests/cases/conformance/jsdoc/0.js(20,7): error TS2451: Cannot redeclare block-s
|
||||
|
||||
/** @type {function (number): number} */
|
||||
const x2 = (a) => a + 1;
|
||||
~~
|
||||
!!! error TS2451: Cannot redeclare block-scoped variable 'x2'.
|
||||
|
||||
/** @type {string} */
|
||||
var a;
|
||||
@@ -36,7 +35,14 @@ tests/cases/conformance/jsdoc/0.js(20,7): error TS2451: Cannot redeclare block-s
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
|
||||
/** @type {function (number): number} */
|
||||
const x2 = (a) => a.concat("hi");
|
||||
const x3 = (a) => a.concat("hi");
|
||||
~~~~~~
|
||||
!!! error TS2339: Property 'concat' does not exist on type 'number'.
|
||||
x3(0);
|
||||
|
||||
/** @type {function (number): string} */
|
||||
const x4 = (a) => a + 1;
|
||||
~~
|
||||
!!! error TS2451: Cannot redeclare block-scoped variable 'x2'.
|
||||
x2(0);
|
||||
!!! error TS2322: Type '(a: number) => number' is not assignable to type '(arg0: number) => string'.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
x4(0);
|
||||
@@ -18,8 +18,12 @@ var a;
|
||||
a = x2(0);
|
||||
|
||||
/** @type {function (number): number} */
|
||||
const x2 = (a) => a.concat("hi");
|
||||
x2(0);
|
||||
const x3 = (a) => a.concat("hi");
|
||||
x3(0);
|
||||
|
||||
/** @type {function (number): string} */
|
||||
const x4 = (a) => a + 1;
|
||||
x4(0);
|
||||
|
||||
//// [0.js]
|
||||
// @ts-check
|
||||
@@ -36,5 +40,8 @@ var x2 = function (a) { return a + 1; };
|
||||
var a;
|
||||
a = x2(0);
|
||||
/** @type {function (number): number} */
|
||||
var x2 = function (a) { return a.concat("hi"); };
|
||||
x2(0);
|
||||
var x3 = function (a) { return a.concat("hi"); };
|
||||
x3(0);
|
||||
/** @type {function (number): string} */
|
||||
var x4 = function (a) { return a + 1; };
|
||||
x4(0);
|
||||
|
||||
48
tests/baselines/reference/contextualTypeFromJSDoc.symbols
Normal file
48
tests/baselines/reference/contextualTypeFromJSDoc.symbols
Normal file
@@ -0,0 +1,48 @@
|
||||
=== tests/cases/conformance/types/contextualTypes/jsdoc/index.js ===
|
||||
/** @type {Array<[string, {x?:number, y?:number}]>} */
|
||||
const arr = [
|
||||
>arr : Symbol(arr, Decl(index.js, 1, 5))
|
||||
|
||||
['a', { x: 1 }],
|
||||
>x : Symbol(x, Decl(index.js, 2, 11))
|
||||
|
||||
['b', { y: 2 }]
|
||||
>y : Symbol(y, Decl(index.js, 3, 11))
|
||||
|
||||
];
|
||||
|
||||
/** @return {Array<[string, {x?:number, y?:number}]>} */
|
||||
function f() {
|
||||
>f : Symbol(f, Decl(index.js, 4, 2))
|
||||
|
||||
return [
|
||||
['a', { x: 1 }],
|
||||
>x : Symbol(x, Decl(index.js, 9, 15))
|
||||
|
||||
['b', { y: 2 }]
|
||||
>y : Symbol(y, Decl(index.js, 10, 15))
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(index.js, 12, 1))
|
||||
|
||||
/** @param {Array<[string, {x?:number, y?:number}]>} value */
|
||||
set x(value) { }
|
||||
>x : Symbol(C.x, Decl(index.js, 14, 9), Decl(index.js, 16, 20))
|
||||
>value : Symbol(value, Decl(index.js, 16, 10))
|
||||
|
||||
get x() {
|
||||
>x : Symbol(C.x, Decl(index.js, 14, 9), Decl(index.js, 16, 20))
|
||||
|
||||
return [
|
||||
['a', { x: 1 }],
|
||||
>x : Symbol(x, Decl(index.js, 19, 19))
|
||||
|
||||
['b', { y: 2 }]
|
||||
>y : Symbol(y, Decl(index.js, 20, 19))
|
||||
|
||||
];
|
||||
}
|
||||
}
|
||||
77
tests/baselines/reference/contextualTypeFromJSDoc.types
Normal file
77
tests/baselines/reference/contextualTypeFromJSDoc.types
Normal file
@@ -0,0 +1,77 @@
|
||||
=== tests/cases/conformance/types/contextualTypes/jsdoc/index.js ===
|
||||
/** @type {Array<[string, {x?:number, y?:number}]>} */
|
||||
const arr = [
|
||||
>arr : [string, { x?: number; y?: number; }][]
|
||||
>[ ['a', { x: 1 }], ['b', { y: 2 }]] : ([string, { x: number; }] | [string, { y: number; }])[]
|
||||
|
||||
['a', { x: 1 }],
|
||||
>['a', { x: 1 }] : [string, { x: number; }]
|
||||
>'a' : "a"
|
||||
>{ x: 1 } : { x: number; }
|
||||
>x : number
|
||||
>1 : 1
|
||||
|
||||
['b', { y: 2 }]
|
||||
>['b', { y: 2 }] : [string, { y: number; }]
|
||||
>'b' : "b"
|
||||
>{ y: 2 } : { y: number; }
|
||||
>y : number
|
||||
>2 : 2
|
||||
|
||||
];
|
||||
|
||||
/** @return {Array<[string, {x?:number, y?:number}]>} */
|
||||
function f() {
|
||||
>f : () => [string, { x?: number; y?: number; }][]
|
||||
|
||||
return [
|
||||
>[ ['a', { x: 1 }], ['b', { y: 2 }] ] : ([string, { x: number; }] | [string, { y: number; }])[]
|
||||
|
||||
['a', { x: 1 }],
|
||||
>['a', { x: 1 }] : [string, { x: number; }]
|
||||
>'a' : "a"
|
||||
>{ x: 1 } : { x: number; }
|
||||
>x : number
|
||||
>1 : 1
|
||||
|
||||
['b', { y: 2 }]
|
||||
>['b', { y: 2 }] : [string, { y: number; }]
|
||||
>'b' : "b"
|
||||
>{ y: 2 } : { y: number; }
|
||||
>y : number
|
||||
>2 : 2
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
/** @param {Array<[string, {x?:number, y?:number}]>} value */
|
||||
set x(value) { }
|
||||
>x : [string, { x?: number; y?: number; }][]
|
||||
>value : [string, { x?: number; y?: number; }][]
|
||||
|
||||
get x() {
|
||||
>x : [string, { x?: number; y?: number; }][]
|
||||
|
||||
return [
|
||||
>[ ['a', { x: 1 }], ['b', { y: 2 }] ] : ([string, { x: number; }] | [string, { y: number; }])[]
|
||||
|
||||
['a', { x: 1 }],
|
||||
>['a', { x: 1 }] : [string, { x: number; }]
|
||||
>'a' : "a"
|
||||
>{ x: 1 } : { x: number; }
|
||||
>x : number
|
||||
>1 : 1
|
||||
|
||||
['b', { y: 2 }]
|
||||
>['b', { y: 2 }] : [string, { y: number; }]
|
||||
>'b' : "b"
|
||||
>{ y: 2 } : { y: number; }
|
||||
>y : number
|
||||
>2 : 2
|
||||
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
tests/cases/compiler/excessPropertyCheckWithSpread.ts(6,3): error TS2345: Argument of type '{ n: number; a: number; }' is not assignable to parameter of type '{ a: any; }'.
|
||||
Object literal may only specify known properties, and 'n' does not exist in type '{ a: any; }'.
|
||||
tests/cases/compiler/excessPropertyCheckWithSpread.ts(16,3): error TS2345: Argument of type '{ opt: string | number; a: number; }' is not assignable to parameter of type '{ a: any; }'.
|
||||
Object literal may only specify known properties, and 'opt' does not exist in type '{ a: any; }'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/excessPropertyCheckWithSpread.ts (2 errors) ====
|
||||
declare function f({ a: number }): void
|
||||
interface I {
|
||||
readonly n: number;
|
||||
}
|
||||
declare let i: I;
|
||||
f({ a: 1, ...i });
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '{ n: number; a: number; }' is not assignable to parameter of type '{ a: any; }'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'n' does not exist in type '{ a: any; }'.
|
||||
|
||||
interface R {
|
||||
opt?: number
|
||||
}
|
||||
interface L {
|
||||
opt: string
|
||||
}
|
||||
declare let l: L;
|
||||
declare let r: R;
|
||||
f({ a: 1, ...l, ...r });
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '{ opt: string | number; a: number; }' is not assignable to parameter of type '{ a: any; }'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'opt' does not exist in type '{ a: any; }'.
|
||||
|
||||
30
tests/baselines/reference/excessPropertyCheckWithSpread.js
Normal file
30
tests/baselines/reference/excessPropertyCheckWithSpread.js
Normal file
@@ -0,0 +1,30 @@
|
||||
//// [excessPropertyCheckWithSpread.ts]
|
||||
declare function f({ a: number }): void
|
||||
interface I {
|
||||
readonly n: number;
|
||||
}
|
||||
declare let i: I;
|
||||
f({ a: 1, ...i });
|
||||
|
||||
interface R {
|
||||
opt?: number
|
||||
}
|
||||
interface L {
|
||||
opt: string
|
||||
}
|
||||
declare let l: L;
|
||||
declare let r: R;
|
||||
f({ a: 1, ...l, ...r });
|
||||
|
||||
|
||||
//// [excessPropertyCheckWithSpread.js]
|
||||
var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
f(__assign({ a: 1 }, i));
|
||||
f(__assign({ a: 1 }, l, r));
|
||||
@@ -1,11 +1,12 @@
|
||||
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(24,14): error TS2322: Type '(a: State | 1) => IterableIterator<State | 1>' is not assignable to type 'Strategy<State>'.
|
||||
Type 'IterableIterator<State | 1>' is not assignable to type 'IterableIterator<State>'.
|
||||
Type 'State | 1' is not assignable to type 'State'.
|
||||
Type '1' is not assignable to type 'State'.
|
||||
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(24,61): error TS2345: Argument of type '(state: State) => IterableIterator<State | 1>' is not assignable to parameter of type '(a: StrategicState) => IterableIterator<StrategicState>'.
|
||||
Type 'IterableIterator<State | 1>' is not assignable to type 'IterableIterator<StrategicState>'.
|
||||
Type 'State | 1' is not assignable to type 'StrategicState'.
|
||||
Type '1' has no properties in common with type 'StrategicState'.
|
||||
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(29,70): error TS7025: Generator implicitly has type 'IterableIterator<any>' because it does not yield any values. Consider supplying a return type.
|
||||
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(32,42): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
|
||||
Type argument candidate 'State' is not a valid type argument because it is not a supertype of candidate '1'.
|
||||
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(36,14): error TS2322: Type '(a: State | 1) => IterableIterator<State | 1>' is not assignable to type 'Strategy<State>'.
|
||||
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(36,62): error TS2345: Argument of type '(state: State) => IterableIterator<State | 1>' is not assignable to parameter of type '(a: StrategicState) => IterableIterator<StrategicState>'.
|
||||
Type 'IterableIterator<State | 1>' is not assignable to type 'IterableIterator<StrategicState>'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts (4 errors) ====
|
||||
@@ -33,11 +34,11 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(36,14): err
|
||||
}
|
||||
|
||||
export const Nothing: Strategy<State> = strategy("Nothing", function* (state: State) {
|
||||
~~~~~~~
|
||||
!!! error TS2322: Type '(a: State | 1) => IterableIterator<State | 1>' is not assignable to type 'Strategy<State>'.
|
||||
!!! error TS2322: Type 'IterableIterator<State | 1>' is not assignable to type 'IterableIterator<State>'.
|
||||
!!! error TS2322: Type 'State | 1' is not assignable to type 'State'.
|
||||
!!! error TS2322: Type '1' is not assignable to type 'State'.
|
||||
~~~~~~~~
|
||||
!!! error TS2345: Argument of type '(state: State) => IterableIterator<State | 1>' is not assignable to parameter of type '(a: StrategicState) => IterableIterator<StrategicState>'.
|
||||
!!! error TS2345: Type 'IterableIterator<State | 1>' is not assignable to type 'IterableIterator<StrategicState>'.
|
||||
!!! error TS2345: Type 'State | 1' is not assignable to type 'StrategicState'.
|
||||
!!! error TS2345: Type '1' has no properties in common with type 'StrategicState'.
|
||||
yield 1;
|
||||
return state;
|
||||
});
|
||||
@@ -55,8 +56,9 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(36,14): err
|
||||
});
|
||||
|
||||
export const Nothing3: Strategy<State> = strategy("Nothing", function* (state: State) {
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type '(a: State | 1) => IterableIterator<State | 1>' is not assignable to type 'Strategy<State>'.
|
||||
~~~~~~~~
|
||||
!!! error TS2345: Argument of type '(state: State) => IterableIterator<State | 1>' is not assignable to parameter of type '(a: StrategicState) => IterableIterator<StrategicState>'.
|
||||
!!! error TS2345: Type 'IterableIterator<State | 1>' is not assignable to type 'IterableIterator<StrategicState>'.
|
||||
yield state;
|
||||
return 1;
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
error TS2468: Cannot find global value 'Promise'.
|
||||
tests/cases/conformance/dynamicImport/2.ts(3,24): error TS2712: A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
|
||||
tests/cases/conformance/dynamicImport/2.ts(7,12): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
|
||||
tests/cases/conformance/dynamicImport/2.ts(9,29): error TS2712: A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
|
||||
|
||||
|
||||
!!! error TS2468: Cannot find global value 'Promise'.
|
||||
==== tests/cases/conformance/dynamicImport/0.ts (0 errors) ====
|
||||
export class B {
|
||||
print() { return "I am B"}
|
||||
}
|
||||
|
||||
export function foo() { return "foo" }
|
||||
|
||||
==== tests/cases/conformance/dynamicImport/1.ts (0 errors) ====
|
||||
export function backup() { return "backup"; }
|
||||
|
||||
==== tests/cases/conformance/dynamicImport/2.ts (3 errors) ====
|
||||
declare var console: any;
|
||||
class C {
|
||||
private myModule = import("./0");
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2712: A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
|
||||
method() {
|
||||
this.myModule.then(Zero => {
|
||||
console.log(Zero.foo());
|
||||
}, async err => {
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
|
||||
console.log(err);
|
||||
let one = await import("./1");
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2712: A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
|
||||
console.log(one.backup());
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
//// [tests/cases/conformance/dynamicImport/importCallExpressionNoModuleKindSpecified.ts] ////
|
||||
|
||||
//// [0.ts]
|
||||
export class B {
|
||||
print() { return "I am B"}
|
||||
}
|
||||
|
||||
export function foo() { return "foo" }
|
||||
|
||||
//// [1.ts]
|
||||
export function backup() { return "backup"; }
|
||||
|
||||
//// [2.ts]
|
||||
declare var console: any;
|
||||
class C {
|
||||
private myModule = import("./0");
|
||||
method() {
|
||||
this.myModule.then(Zero => {
|
||||
console.log(Zero.foo());
|
||||
}, async err => {
|
||||
console.log(err);
|
||||
let one = await import("./1");
|
||||
console.log(one.backup());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//// [0.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var B = (function () {
|
||||
function B() {
|
||||
}
|
||||
B.prototype.print = function () { return "I am B"; };
|
||||
return B;
|
||||
}());
|
||||
exports.B = B;
|
||||
function foo() { return "foo"; }
|
||||
exports.foo = foo;
|
||||
//// [1.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function backup() { return "backup"; }
|
||||
exports.backup = backup;
|
||||
//// [2.js]
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [0, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var C = (function () {
|
||||
function C() {
|
||||
this.myModule = Promise.resolve().then(function () { return require("./0"); });
|
||||
}
|
||||
C.prototype.method = function () {
|
||||
var _this = this;
|
||||
this.myModule.then(function (Zero) {
|
||||
console.log(Zero.foo());
|
||||
}, function (err) { return __awaiter(_this, void 0, void 0, function () {
|
||||
var one;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
console.log(err);
|
||||
return [4 /*yield*/, Promise.resolve().then(function () { return require("./1"); })];
|
||||
case 1:
|
||||
one = _a.sent();
|
||||
console.log(one.backup());
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
};
|
||||
return C;
|
||||
}());
|
||||
@@ -35,4 +35,14 @@
|
||||
declare type T = number;
|
||||
export = T;
|
||||
|
||||
==== /node_modules/foo/bar.d.ts (0 errors) ====
|
||||
export type T = number;
|
||||
|
||||
==== /node_modules/foo/index.d.ts (0 errors) ====
|
||||
export { T } from "./bar"; // In a declaration file, so not an error.
|
||||
|
||||
==== /node_modules/baz/index.d.ts (0 errors) ====
|
||||
declare module "baz" {
|
||||
export { T } from "foo"; // Also allowed.
|
||||
}
|
||||
|
||||
@@ -9,7 +9,17 @@ export class C {}
|
||||
//// [exportEqualsT.ts]
|
||||
declare type T = number;
|
||||
export = T;
|
||||
|
||||
|
||||
//// [bar.d.ts]
|
||||
export type T = number;
|
||||
|
||||
//// [index.d.ts]
|
||||
export { T } from "./bar"; // In a declaration file, so not an error.
|
||||
|
||||
//// [index.d.ts]
|
||||
declare module "baz" {
|
||||
export { T } from "foo"; // Also allowed.
|
||||
}
|
||||
|
||||
//// [user.ts]
|
||||
// Error, can't re-export something that's only a type.
|
||||
|
||||
@@ -43,7 +43,16 @@ tests/cases/compiler/jsdocInTypeScript.ts(30,3): error TS2339: Property 'x' does
|
||||
// @type has no effect either.
|
||||
/** @type {{ x?: number }} */
|
||||
const z = {};
|
||||
z.x = 1;
|
||||
z.x = 1; // Error
|
||||
~
|
||||
!!! error TS2339: Property 'x' does not exist on type '{}'.
|
||||
|
||||
// @template tag should not interfere with constraint or default.
|
||||
/** @template T */
|
||||
interface I<T extends number = 0> {}
|
||||
|
||||
/** @template T */
|
||||
function tem<T extends number>(t: T): I<T> { return {}; }
|
||||
|
||||
let i: I; // Should succeed thanks to type parameter default
|
||||
|
||||
@@ -28,7 +28,16 @@ f(1); f(true).length;
|
||||
// @type has no effect either.
|
||||
/** @type {{ x?: number }} */
|
||||
const z = {};
|
||||
z.x = 1;
|
||||
z.x = 1; // Error
|
||||
|
||||
// @template tag should not interfere with constraint or default.
|
||||
/** @template T */
|
||||
interface I<T extends number = 0> {}
|
||||
|
||||
/** @template T */
|
||||
function tem<T extends number>(t: T): I<T> { return {}; }
|
||||
|
||||
let i: I; // Should succeed thanks to type parameter default
|
||||
|
||||
|
||||
//// [jsdocInTypeScript.js]
|
||||
@@ -50,4 +59,7 @@ f(true).length;
|
||||
// @type has no effect either.
|
||||
/** @type {{ x?: number }} */
|
||||
var z = {};
|
||||
z.x = 1;
|
||||
z.x = 1; // Error
|
||||
/** @template T */
|
||||
function tem(t) { return {}; }
|
||||
var i; // Should succeed thanks to type parameter default
|
||||
|
||||
@@ -4,12 +4,12 @@ tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(9,4): error TS
|
||||
Property 'doStuff' is missing in type '{ value: string; }'.
|
||||
tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(10,17): error TS2345: Argument of type '{ value: string; what: number; }' is not assignable to parameter of type 'I2'.
|
||||
Object literal may only specify known properties, and 'what' does not exist in type 'I2'.
|
||||
tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(11,4): error TS2345: Argument of type '{ toString: (s: any) => any; }' is not assignable to parameter of type 'I2'.
|
||||
Property 'value' is missing in type '{ toString: (s: any) => any; }'.
|
||||
tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(12,4): error TS2345: Argument of type '{ toString: (s: string) => string; }' is not assignable to parameter of type 'I2'.
|
||||
Property 'value' is missing in type '{ toString: (s: string) => string; }'.
|
||||
tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(13,4): error TS2345: Argument of type '{ value: string; toString: (s: any) => any; }' is not assignable to parameter of type 'I2'.
|
||||
Property 'doStuff' is missing in type '{ value: string; toString: (s: any) => any; }'.
|
||||
tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(11,6): error TS2345: Argument of type '{ toString: (s: any) => any; }' is not assignable to parameter of type 'I2'.
|
||||
Object literal may only specify known properties, and 'toString' does not exist in type 'I2'.
|
||||
tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(12,6): error TS2345: Argument of type '{ toString: (s: string) => string; }' is not assignable to parameter of type 'I2'.
|
||||
Object literal may only specify known properties, and 'toString' does not exist in type 'I2'.
|
||||
tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(13,17): error TS2345: Argument of type '{ value: string; toString: (s: any) => any; }' is not assignable to parameter of type 'I2'.
|
||||
Object literal may only specify known properties, and 'toString' does not exist in type 'I2'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts (6 errors) ====
|
||||
@@ -33,14 +33,14 @@ tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(13,4): error T
|
||||
!!! error TS2345: Argument of type '{ value: string; what: number; }' is not assignable to parameter of type 'I2'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'what' does not exist in type 'I2'.
|
||||
f2({ toString: (s) => s })
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '{ toString: (s: any) => any; }' is not assignable to parameter of type 'I2'.
|
||||
!!! error TS2345: Property 'value' is missing in type '{ toString: (s: any) => any; }'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'toString' does not exist in type 'I2'.
|
||||
f2({ toString: (s: string) => s })
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '{ toString: (s: string) => string; }' is not assignable to parameter of type 'I2'.
|
||||
!!! error TS2345: Property 'value' is missing in type '{ toString: (s: string) => string; }'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'toString' does not exist in type 'I2'.
|
||||
f2({ value: '', toString: (s) => s.uhhh })
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '{ value: string; toString: (s: any) => any; }' is not assignable to parameter of type 'I2'.
|
||||
!!! error TS2345: Property 'doStuff' is missing in type '{ value: string; toString: (s: any) => any; }'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'toString' does not exist in type 'I2'.
|
||||
@@ -0,0 +1,14 @@
|
||||
//// [sourceMapValidationVarInDownLevelGenerator.ts]
|
||||
function * f() {
|
||||
var x = 1, y;
|
||||
}
|
||||
|
||||
//// [sourceMapValidationVarInDownLevelGenerator.js]
|
||||
function f() {
|
||||
var x, y;
|
||||
return __generator(this, function (_a) {
|
||||
x = 1;
|
||||
return [2 /*return*/];
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=sourceMapValidationVarInDownLevelGenerator.js.map
|
||||
@@ -0,0 +1,2 @@
|
||||
//// [sourceMapValidationVarInDownLevelGenerator.js.map]
|
||||
{"version":3,"file":"sourceMapValidationVarInDownLevelGenerator.js","sourceRoot":"","sources":["sourceMapValidationVarInDownLevelGenerator.ts"],"names":[],"mappings":"AAAA;;;QACQ,CAAC,GAAG,CAAC,CAAI;;;CAChB"}
|
||||
@@ -0,0 +1,47 @@
|
||||
===================================================================
|
||||
JsFile: sourceMapValidationVarInDownLevelGenerator.js
|
||||
mapUrl: sourceMapValidationVarInDownLevelGenerator.js.map
|
||||
sourceRoot:
|
||||
sources: sourceMapValidationVarInDownLevelGenerator.ts
|
||||
===================================================================
|
||||
-------------------------------------------------------------------
|
||||
emittedFile:tests/cases/compiler/sourceMapValidationVarInDownLevelGenerator.js
|
||||
sourceFile:sourceMapValidationVarInDownLevelGenerator.ts
|
||||
-------------------------------------------------------------------
|
||||
>>>function f() {
|
||||
1 >
|
||||
2 >^^^^^^^^^^^^^^->
|
||||
1 >
|
||||
1 >Emitted(1, 1) Source(1, 1) + SourceIndex(0)
|
||||
---
|
||||
>>> var x, y;
|
||||
>>> return __generator(this, function (_a) {
|
||||
>>> x = 1;
|
||||
1->^^^^^^^^
|
||||
2 > ^
|
||||
3 > ^^^
|
||||
4 > ^
|
||||
5 > ^
|
||||
6 > ^^^^^^^^^^^^^^^^^->
|
||||
1->function * f() {
|
||||
> var
|
||||
2 > x
|
||||
3 > =
|
||||
4 > 1
|
||||
5 > , y;
|
||||
1->Emitted(4, 9) Source(2, 9) + SourceIndex(0)
|
||||
2 >Emitted(4, 10) Source(2, 10) + SourceIndex(0)
|
||||
3 >Emitted(4, 13) Source(2, 13) + SourceIndex(0)
|
||||
4 >Emitted(4, 14) Source(2, 14) + SourceIndex(0)
|
||||
5 >Emitted(4, 15) Source(2, 18) + SourceIndex(0)
|
||||
---
|
||||
>>> return [2 /*return*/];
|
||||
>>> });
|
||||
>>>}
|
||||
1->^
|
||||
2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^->
|
||||
1->
|
||||
>}
|
||||
1->Emitted(7, 2) Source(3, 2) + SourceIndex(0)
|
||||
---
|
||||
>>>//# sourceMappingURL=sourceMapValidationVarInDownLevelGenerator.js.map
|
||||
@@ -0,0 +1,8 @@
|
||||
=== tests/cases/compiler/sourceMapValidationVarInDownLevelGenerator.ts ===
|
||||
function * f() {
|
||||
>f : Symbol(f, Decl(sourceMapValidationVarInDownLevelGenerator.ts, 0, 0))
|
||||
|
||||
var x = 1, y;
|
||||
>x : Symbol(x, Decl(sourceMapValidationVarInDownLevelGenerator.ts, 1, 7))
|
||||
>y : Symbol(y, Decl(sourceMapValidationVarInDownLevelGenerator.ts, 1, 14))
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
=== tests/cases/compiler/sourceMapValidationVarInDownLevelGenerator.ts ===
|
||||
function * f() {
|
||||
>f : () => IterableIterator<any>
|
||||
|
||||
var x = 1, y;
|
||||
>x : number
|
||||
>1 : 1
|
||||
>y : any
|
||||
}
|
||||
@@ -7,11 +7,12 @@ class Poisoned extends React.Component<{}, {}> {
|
||||
}
|
||||
}
|
||||
|
||||
const obj: Object = {};
|
||||
const obj = {};
|
||||
|
||||
// OK
|
||||
let p = <Poisoned {...obj} />;
|
||||
let y = <Poisoned />;
|
||||
let y = <Poisoned />;
|
||||
|
||||
|
||||
//// [file.jsx]
|
||||
"use strict";
|
||||
|
||||
@@ -17,9 +17,8 @@ class Poisoned extends React.Component<{}, {}> {
|
||||
}
|
||||
}
|
||||
|
||||
const obj: Object = {};
|
||||
const obj = {};
|
||||
>obj : Symbol(obj, Decl(file.tsx, 8, 5))
|
||||
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
// OK
|
||||
let p = <Poisoned {...obj} />;
|
||||
|
||||
@@ -18,9 +18,8 @@ class Poisoned extends React.Component<{}, {}> {
|
||||
}
|
||||
}
|
||||
|
||||
const obj: Object = {};
|
||||
>obj : Object
|
||||
>Object : Object
|
||||
const obj = {};
|
||||
>obj : {}
|
||||
>{} : {}
|
||||
|
||||
// OK
|
||||
@@ -28,7 +27,7 @@ let p = <Poisoned {...obj} />;
|
||||
>p : JSX.Element
|
||||
><Poisoned {...obj} /> : JSX.Element
|
||||
>Poisoned : typeof Poisoned
|
||||
>obj : Object
|
||||
>obj : {}
|
||||
|
||||
let y = <Poisoned />;
|
||||
>y : JSX.Element
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
tests/cases/compiler/weakType.ts(31,18): error TS2559: Type '{ error?: number; }' has no properties in common with type 'ChangeOptions'.
|
||||
tests/cases/compiler/weakType.ts(56,5): error TS2322: Type '{ properties: { wrong: string; }; }' is not assignable to type 'Weak & Spoiler'.
|
||||
tests/cases/compiler/weakType.ts(16,13): error TS2559: Type '12' has no properties in common with type 'Settings'.
|
||||
tests/cases/compiler/weakType.ts(17,13): error TS2559: Type '"completely wrong"' has no properties in common with type 'Settings'.
|
||||
tests/cases/compiler/weakType.ts(18,13): error TS2559: Type 'false' has no properties in common with type 'Settings'.
|
||||
tests/cases/compiler/weakType.ts(35,18): error TS2559: Type '{ error?: number; }' has no properties in common with type 'ChangeOptions'.
|
||||
tests/cases/compiler/weakType.ts(60,5): error TS2322: Type '{ properties: { wrong: string; }; }' is not assignable to type 'Weak & Spoiler'.
|
||||
Type '{ properties: { wrong: string; }; }' is not assignable to type 'Weak'.
|
||||
Types of property 'properties' are incompatible.
|
||||
Type '{ wrong: string; }' has no properties in common with type '{ b?: number; }'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/weakType.ts (2 errors) ====
|
||||
==== tests/cases/compiler/weakType.ts (5 errors) ====
|
||||
interface Settings {
|
||||
timeout?: number;
|
||||
onError?(): void;
|
||||
@@ -16,10 +19,20 @@ tests/cases/compiler/weakType.ts(56,5): error TS2322: Type '{ properties: { wron
|
||||
}
|
||||
|
||||
function doSomething(settings: Settings) { /* ... */ }
|
||||
|
||||
// forgot to call `getDefaultSettings`
|
||||
// but it is not caught because we don't check for call signatures
|
||||
doSomething(getDefaultSettings);
|
||||
// same for arrow expressions:
|
||||
doSomething(() => { });
|
||||
doSomething(12);
|
||||
~~
|
||||
!!! error TS2559: Type '12' has no properties in common with type 'Settings'.
|
||||
doSomething('completely wrong');
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2559: Type '"completely wrong"' has no properties in common with type 'Settings'.
|
||||
doSomething(false);
|
||||
~~~~~
|
||||
!!! error TS2559: Type 'false' has no properties in common with type 'Settings'.
|
||||
|
||||
// this is an oddly popular way of defining settings
|
||||
// this example is from services/textChanges.ts
|
||||
|
||||
@@ -9,10 +9,14 @@ function getDefaultSettings() {
|
||||
}
|
||||
|
||||
function doSomething(settings: Settings) { /* ... */ }
|
||||
|
||||
// forgot to call `getDefaultSettings`
|
||||
// but it is not caught because we don't check for call signatures
|
||||
doSomething(getDefaultSettings);
|
||||
// same for arrow expressions:
|
||||
doSomething(() => { });
|
||||
doSomething(12);
|
||||
doSomething('completely wrong');
|
||||
doSomething(false);
|
||||
|
||||
// this is an oddly popular way of defining settings
|
||||
// this example is from services/textChanges.ts
|
||||
@@ -65,6 +69,11 @@ function doSomething(settings) { }
|
||||
// forgot to call `getDefaultSettings`
|
||||
// but it is not caught because we don't check for call signatures
|
||||
doSomething(getDefaultSettings);
|
||||
// same for arrow expressions:
|
||||
doSomething(function () { });
|
||||
doSomething(12);
|
||||
doSomething('completely wrong');
|
||||
doSomething(false);
|
||||
function del(options, error) {
|
||||
if (options === void 0) { options = {}; }
|
||||
if (error === void 0) { error = {}; }
|
||||
|
||||
16
tests/cases/compiler/excessPropertyCheckWithSpread.ts
Normal file
16
tests/cases/compiler/excessPropertyCheckWithSpread.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
declare function f({ a: number }): void
|
||||
interface I {
|
||||
readonly n: number;
|
||||
}
|
||||
declare let i: I;
|
||||
f({ a: 1, ...i });
|
||||
|
||||
interface R {
|
||||
opt?: number
|
||||
}
|
||||
interface L {
|
||||
opt: string
|
||||
}
|
||||
declare let l: L;
|
||||
declare let r: R;
|
||||
f({ a: 1, ...l, ...r });
|
||||
@@ -10,6 +10,16 @@ export class C {}
|
||||
declare type T = number;
|
||||
export = T;
|
||||
|
||||
// @Filename: /node_modules/foo/bar.d.ts
|
||||
export type T = number;
|
||||
|
||||
// @Filename: /node_modules/foo/index.d.ts
|
||||
export { T } from "./bar"; // In a declaration file, so not an error.
|
||||
|
||||
// @Filename: /node_modules/baz/index.d.ts
|
||||
declare module "baz" {
|
||||
export { T } from "foo"; // Also allowed.
|
||||
}
|
||||
|
||||
// @Filename: /user.ts
|
||||
// Error, can't re-export something that's only a type.
|
||||
|
||||
@@ -27,4 +27,13 @@ f(1); f(true).length;
|
||||
// @type has no effect either.
|
||||
/** @type {{ x?: number }} */
|
||||
const z = {};
|
||||
z.x = 1;
|
||||
z.x = 1; // Error
|
||||
|
||||
// @template tag should not interfere with constraint or default.
|
||||
/** @template T */
|
||||
interface I<T extends number = 0> {}
|
||||
|
||||
/** @template T */
|
||||
function tem<T extends number>(t: T): I<T> { return {}; }
|
||||
|
||||
let i: I; // Should succeed thanks to type parameter default
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// @sourcemap: true
|
||||
// @downlevelIteration: true
|
||||
// @noEmitHelpers: true
|
||||
// @lib: es2015
|
||||
function * f() {
|
||||
var x = 1, y;
|
||||
}
|
||||
@@ -8,10 +8,14 @@ function getDefaultSettings() {
|
||||
}
|
||||
|
||||
function doSomething(settings: Settings) { /* ... */ }
|
||||
|
||||
// forgot to call `getDefaultSettings`
|
||||
// but it is not caught because we don't check for call signatures
|
||||
doSomething(getDefaultSettings);
|
||||
// same for arrow expressions:
|
||||
doSomething(() => { });
|
||||
doSomething(12);
|
||||
doSomething('completely wrong');
|
||||
doSomething(false);
|
||||
|
||||
// this is an oddly popular way of defining settings
|
||||
// this example is from services/textChanges.ts
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// @filename: 0.ts
|
||||
export class B {
|
||||
print() { return "I am B"}
|
||||
}
|
||||
|
||||
export function foo() { return "foo" }
|
||||
|
||||
// @filename: 1.ts
|
||||
export function backup() { return "backup"; }
|
||||
|
||||
// @filename: 2.ts
|
||||
declare var console: any;
|
||||
class C {
|
||||
private myModule = import("./0");
|
||||
method() {
|
||||
this.myModule.then(Zero => {
|
||||
console.log(Zero.foo());
|
||||
}, async err => {
|
||||
console.log(err);
|
||||
let one = await import("./1");
|
||||
console.log(one.backup());
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -21,5 +21,9 @@ var a;
|
||||
a = x2(0);
|
||||
|
||||
/** @type {function (number): number} */
|
||||
const x2 = (a) => a.concat("hi");
|
||||
x2(0);
|
||||
const x3 = (a) => a.concat("hi");
|
||||
x3(0);
|
||||
|
||||
/** @type {function (number): string} */
|
||||
const x4 = (a) => a + 1;
|
||||
x4(0);
|
||||
@@ -11,8 +11,8 @@ class Poisoned extends React.Component<{}, {}> {
|
||||
}
|
||||
}
|
||||
|
||||
const obj: Object = {};
|
||||
const obj = {};
|
||||
|
||||
// OK
|
||||
let p = <Poisoned {...obj} />;
|
||||
let y = <Poisoned />;
|
||||
let y = <Poisoned />;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @filename: index.js
|
||||
// @target: esnext
|
||||
|
||||
/** @type {Array<[string, {x?:number, y?:number}]>} */
|
||||
const arr = [
|
||||
['a', { x: 1 }],
|
||||
['b', { y: 2 }]
|
||||
];
|
||||
|
||||
/** @return {Array<[string, {x?:number, y?:number}]>} */
|
||||
function f() {
|
||||
return [
|
||||
['a', { x: 1 }],
|
||||
['b', { y: 2 }]
|
||||
];
|
||||
}
|
||||
|
||||
class C {
|
||||
/** @param {Array<[string, {x?:number, y?:number}]>} value */
|
||||
set x(value) { }
|
||||
get x() {
|
||||
return [
|
||||
['a', { x: 1 }],
|
||||
['b', { y: 2 }]
|
||||
];
|
||||
}
|
||||
}
|
||||
15
tests/cases/fourslash/completionInJsDocQualifiedNames.ts
Normal file
15
tests/cases/fourslash/completionInJsDocQualifiedNames.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowJs: true
|
||||
|
||||
// @Filename: /node_modules/foo/index.d.ts
|
||||
/////** tee */
|
||||
////export type T = number;
|
||||
|
||||
// @Filename: /a.js
|
||||
////import * as Foo from "foo";
|
||||
/////** @type {Foo./**/} */
|
||||
////const x = 0;
|
||||
|
||||
goTo.marker();
|
||||
verify.completionListContains("T", "type T = number", "tee ", "type");
|
||||
@@ -0,0 +1,6 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
/////** @template [|T|] */
|
||||
////class C<[|{| "isWriteAccess": true, "isDefinition": true |}T|]> {}
|
||||
|
||||
verify.singleReferenceGroup("(type parameter) T in C<T>");
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @allowJs: true
|
||||
// @Filename: /a.js
|
||||
|
||||
// TODO: https://github.com/Microsoft/TypeScript/issues/16411
|
||||
// Both uses of T should be referenced.
|
||||
|
||||
/////** @template [|{| "isWriteAccess": true, "isDefinition": true |}T|] */
|
||||
////class C {
|
||||
//// constructor() {
|
||||
//// /** @type {T} */
|
||||
//// this.x = null;
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.singleReferenceGroup("(type parameter) T in C");
|
||||
@@ -0,0 +1,6 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
/////** @template [|{| "isWriteAccess": false, "isDefinition": false |}T|] */
|
||||
////function f<[|{| "isWriteAccess": true, "isDefinition": true |}T|]>() {}
|
||||
|
||||
verify.singleReferenceGroup("(type parameter) T in f<T>(): void");
|
||||
@@ -0,0 +1,12 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @allowJs: true
|
||||
// @Filename: /a.js
|
||||
|
||||
/////**
|
||||
//// * @template [|{| "isWriteAccess": true, "isDefinition": true |}T|]
|
||||
//// * @return {[|T|]}
|
||||
//// */
|
||||
////function f() {}
|
||||
|
||||
verify.singleReferenceGroup("(type parameter) T"); // TODO:GH#??? should be "(type parameter) T in f<T>(): void"
|
||||
17
tests/cases/fourslash/incrementalParsingDynamicImport1.ts
Normal file
17
tests/cases/fourslash/incrementalParsingDynamicImport1.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/// <reference path="fourslash.ts"/>
|
||||
|
||||
// @lib: es6
|
||||
|
||||
// @Filename: ./foo.ts
|
||||
//// export function bar() { return 1; }
|
||||
|
||||
//// var x1 = import("./foo");
|
||||
//// x1.then(foo => {
|
||||
//// var s: string = foo.bar();
|
||||
//// })
|
||||
//// /*1*/
|
||||
|
||||
verify.numberOfErrorsInCurrentFile(1);
|
||||
goTo.marker("1");
|
||||
edit.insert(" ");
|
||||
verify.numberOfErrorsInCurrentFile(1);
|
||||
Reference in New Issue
Block a user