Merge branch 'master' into dynamicNames

This commit is contained in:
Ron Buckton
2017-11-03 22:10:28 -07:00
426 changed files with 5784 additions and 1946 deletions
+8
View File
@@ -59,3 +59,11 @@ internal/
.idea
yarn.lock
.parallelperf.*
tests/cases/user/*/package-lock.json
tests/cases/user/*/node_modules/
tests/cases/user/*/**/*.js
tests/cases/user/*/**/*.js.map
tests/cases/user/*/**/*.d.ts
!tests/cases/user/zone.js/
!tests/cases/user/bignumber.js/
!tests/cases/user/discord.js/
+1 -1
View File
@@ -2,8 +2,8 @@ language: node_js
node_js:
- 'stable'
- '8'
- '6'
- '4'
sudo: false
+25 -39
View File
@@ -123,15 +123,13 @@ const es2015LibrarySources = [
"es2015.symbol.wellknown.d.ts"
];
const es2015LibrarySourceMap = es2015LibrarySources.map(function(source) {
return { target: "lib." + source, sources: ["header.d.ts", source] };
});
const es2015LibrarySourceMap = es2015LibrarySources.map(source =>
({ target: "lib." + source, sources: ["header.d.ts", source] }));
const es2016LibrarySource = ["es2016.array.include.d.ts"];
const es2016LibrarySourceMap = es2016LibrarySource.map(function(source) {
return { target: "lib." + source, sources: ["header.d.ts", source] };
});
const es2016LibrarySourceMap = es2016LibrarySource.map(source =>
({ target: "lib." + source, sources: ["header.d.ts", source] }));
const es2017LibrarySource = [
"es2017.object.d.ts",
@@ -140,17 +138,15 @@ const es2017LibrarySource = [
"es2017.intl.d.ts",
];
const es2017LibrarySourceMap = es2017LibrarySource.map(function(source) {
return { target: "lib." + source, sources: ["header.d.ts", source] };
});
const es2017LibrarySourceMap = es2017LibrarySource.map(source =>
({ target: "lib." + source, sources: ["header.d.ts", source] }));
const esnextLibrarySource = [
"esnext.asynciterable.d.ts"
];
const esnextLibrarySourceMap = esnextLibrarySource.map(function (source) {
return { target: "lib." + source, sources: ["header.d.ts", source] };
});
const esnextLibrarySourceMap = esnextLibrarySource.map(source =>
({ target: "lib." + source, sources: ["header.d.ts", source] }));
const hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"];
@@ -171,14 +167,13 @@ const librarySourceMap = [
// JavaScript + all host library
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) },
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") },
{ target: "lib.es2016.full.d.ts", sources: ["header.d.ts", "es2016.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") },
{ target: "lib.es2017.full.d.ts", sources: ["header.d.ts", "es2017.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") },
{ target: "lib.esnext.full.d.ts", sources: ["header.d.ts", "esnext.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") },
{ target: "lib.es2016.full.d.ts", sources: ["header.d.ts", "es2016.d.ts"].concat(hostsLibrarySources, "dom.iterable.d.ts") },
{ target: "lib.es2017.full.d.ts", sources: ["header.d.ts", "es2017.d.ts"].concat(hostsLibrarySources, "dom.iterable.d.ts") },
{ target: "lib.esnext.full.d.ts", sources: ["header.d.ts", "esnext.d.ts"].concat(hostsLibrarySources, "dom.iterable.d.ts") },
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap, esnextLibrarySourceMap);
const libraryTargets = librarySourceMap.map(function(f) {
return path.join(builtLocalDirectory, f.target);
});
const libraryTargets = librarySourceMap.map(f =>
path.join(builtLocalDirectory, f.target));
/**
* .lcg file is what localization team uses to know what messages to localize.
@@ -193,22 +188,19 @@ const generatedLCGFile = path.join(builtLocalDirectory, "enu", "diagnosticMessag
* 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg'
* generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json
*/
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"].map(function (f) {
return path.join(builtLocalDirectory, f, "diagnosticMessages.generated.json");
}).concat(generatedLCGFile);
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"]
.map(f => path.join(builtLocalDirectory, f, "diagnosticMessages.generated.json"))
.concat(generatedLCGFile);
for (const i in libraryTargets) {
const entry = librarySourceMap[i];
const target = libraryTargets[i];
const sources = [copyright].concat(entry.sources.map(function(s) {
return path.join(libraryDirectory, s);
}));
gulp.task(target, /*help*/ false, [], function() {
return gulp.src(sources)
const sources = [copyright].concat(entry.sources.map(s => path.join(libraryDirectory, s)));
gulp.task(target, /*help*/ false, [], () =>
gulp.src(sources)
.pipe(newer(target))
.pipe(concat(target, { newLine: "\n\n" }))
.pipe(gulp.dest("."));
});
.pipe(gulp.dest(".")));
}
const configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js");
@@ -575,9 +567,7 @@ gulp.task(specMd, /*help*/ false, [word2mdJs], (done) => {
const specMDFullPath = path.resolve(specMd);
const cmd = "cscript //nologo " + word2mdJs + " \"" + specWordFullPath + "\" " + "\"" + specMDFullPath + "\"";
console.log(cmd);
cp.exec(cmd, function() {
done();
});
cp.exec(cmd, done);
});
gulp.task("generate-spec", "Generates a Markdown version of the Language Specification", [specMd]);
@@ -714,17 +704,13 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
}
args.push(run);
setNodeEnvToDevelopment();
exec(mocha, args, lintThenFinish, function(e, status) {
finish(e, status);
});
exec(mocha, args, lintThenFinish, finish);
}
else {
// run task to load all tests and partition them between workers
setNodeEnvToDevelopment();
exec(host, [run], lintThenFinish, function(e, status) {
finish(e, status);
});
exec(host, [run], lintThenFinish, finish);
}
});
@@ -1082,7 +1068,7 @@ function sendNextFile(files: {path: string}[], child: cp.ChildProcess, callback:
function spawnLintWorker(files: {path: string}[], callback: (failures: number) => void) {
const child = cp.fork("./scripts/parallel-lint");
let failures = 0;
child.on("message", function(data) {
child.on("message", data => {
switch (data.kind) {
case "result":
if (data.failures > 0) {
@@ -1106,7 +1092,7 @@ gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are:
const fileMatcher = cmdLineOptions.files;
const files = fileMatcher
? `src/**/${fileMatcher}`
: "Gulpfile.ts 'scripts/generateLocalizedDiagnosticMessages.ts' 'scripts/tslint/**/*.ts' 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts'";
: "Gulpfile.ts 'scripts/generateLocalizedDiagnosticMessages.ts' 'scripts/tslint/**/*.ts' 'src/**/*.ts' --exclude 'src/lib/*.d.ts'";
const cmd = `node node_modules/tslint/bin/tslint ${files} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish`;
console.log("Linting: " + cmd);
child_process.execSync(cmd, { stdio: [0, 1, 2] });
+2 -1
View File
@@ -105,6 +105,7 @@ var harnessCoreSources = [
"projectsRunner.ts",
"loggedIO.ts",
"rwcRunner.ts",
"userRunner.ts",
"test262Runner.ts",
"./parallel/shared.ts",
"./parallel/host.ts",
@@ -1282,7 +1283,7 @@ task("lint", ["build-rules"], () => {
const fileMatcher = process.env.f || process.env.file || process.env.files;
const files = fileMatcher
? `src/**/${fileMatcher}`
: "Gulpfile.ts 'scripts/generateLocalizedDiagnosticMessages.ts' 'scripts/tslint/**/*.ts' 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts'";
: "Gulpfile.ts 'scripts/generateLocalizedDiagnosticMessages.ts' 'scripts/tslint/**/*.ts' 'src/**/*.ts' --exclude 'src/lib/*.d.ts'";
const cmd = `node node_modules/tslint/bin/tslint ${files} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish`;
console.log("Linting: " + cmd);
jake.exec([cmd], { interactive: true }, () => {
+1 -1
View File
@@ -5,7 +5,7 @@ import jobs.generation.Utilities;
def project = GithubProject
def branch = GithubBranchName
def nodeVersions = ['stable', '6', '4']
def nodeVersions = ['stable', '8', '6']
nodeVersions.each { nodeVer ->
+2
View File
@@ -74,10 +74,12 @@
"q": "latest",
"run-sequence": "latest",
"sorcery": "latest",
"source-map-support": "latest",
"through2": "latest",
"travis-fold": "latest",
"ts-node": "latest",
"tslint": "latest",
"vinyl": "latest",
"colors": "latest",
"typescript": "next"
},
@@ -65,10 +65,11 @@ function main(): void {
* There are three exceptions, zh-CN, zh-TW and pt-BR.
*/
function getPreferedLocaleName(localeName: string) {
localeName = localeName.toLowerCase();
switch (localeName) {
case "zh-CN":
case "zh-TW":
case "pt-BR":
case "zh-cn":
case "zh-tw":
case "pt-br":
return localeName;
default:
return localeName.split("-")[0];
-1
View File
@@ -64,7 +64,6 @@ module Commands {
}
if (path.charAt(1) === ":") {
if (path.charAt(2) === directorySeparator) return 3;
return 2;
}
return 0;
}
+10 -7
View File
@@ -1550,7 +1550,7 @@ namespace ts {
function setExportContextFlag(node: ModuleDeclaration | SourceFile) {
// A declaration source file or ambient module declaration that contains no export declarations (but possibly regular
// declarations with export modifiers) is an export context in which declarations are implicitly exported.
if (isInAmbientContext(node) && !hasExportDeclarations(node)) {
if (node.flags & NodeFlags.Ambient && !hasExportDeclarations(node)) {
node.flags |= NodeFlags.ExportContext;
}
else {
@@ -1726,7 +1726,7 @@ namespace ts {
node.originalKeywordKind >= SyntaxKind.FirstFutureReservedWord &&
node.originalKeywordKind <= SyntaxKind.LastFutureReservedWord &&
!isIdentifierName(node) &&
!isInAmbientContext(node)) {
!(node.flags & NodeFlags.Ambient)) {
// Report error only if there are no parse errors in file
if (!file.parseDiagnostics.length) {
@@ -2481,7 +2481,7 @@ namespace ts {
}
function bindParameter(node: ParameterDeclaration) {
if (inStrictMode && !isInAmbientContext(node)) {
if (inStrictMode && !(node.flags & NodeFlags.Ambient)) {
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
checkStrictModeEvalOrArguments(node, node.name);
@@ -2503,7 +2503,7 @@ namespace ts {
}
function bindFunctionDeclaration(node: FunctionDeclaration) {
if (!file.isDeclarationFile && !isInAmbientContext(node)) {
if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient)) {
if (isAsyncFunction(node)) {
emitFlags |= NodeFlags.HasAsyncFunctions;
}
@@ -2520,7 +2520,7 @@ namespace ts {
}
function bindFunctionExpression(node: FunctionExpression) {
if (!file.isDeclarationFile && !isInAmbientContext(node)) {
if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient)) {
if (isAsyncFunction(node)) {
emitFlags |= NodeFlags.HasAsyncFunctions;
}
@@ -2534,7 +2534,7 @@ namespace ts {
}
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
if (!file.isDeclarationFile && !isInAmbientContext(node) && isAsyncFunction(node)) {
if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient) && isAsyncFunction(node)) {
emitFlags |= NodeFlags.HasAsyncFunctions;
}
@@ -2583,7 +2583,7 @@ namespace ts {
// On the other side we do want to report errors on non-initialized 'lets' because of TDZ
const reportUnreachableCode =
!options.allowUnreachableCode &&
!isInAmbientContext(node) &&
!(node.flags & NodeFlags.Ambient) &&
(
node.kind !== SyntaxKind.VariableStatement ||
getCombinedNodeFlags((<VariableStatement>node).declarationList) & NodeFlags.BlockScoped ||
@@ -3296,6 +3296,9 @@ namespace ts {
case SyntaxKind.JsxOpeningElement:
case SyntaxKind.JsxText:
case SyntaxKind.JsxClosingElement:
case SyntaxKind.JsxFragment:
case SyntaxKind.JsxOpeningFragment:
case SyntaxKind.JsxClosingFragment:
case SyntaxKind.JsxAttribute:
case SyntaxKind.JsxAttributes:
case SyntaxKind.JsxSpreadAttribute:
+126 -107
View File
@@ -700,7 +700,7 @@ namespace ts {
else {
// find a module that about to be augmented
// do not validate names of augmentations that are defined in ambient context
const moduleNotFoundError = !isInAmbientContext(moduleName.parent.parent)
const moduleNotFoundError = !(moduleName.parent.parent.flags & NodeFlags.Ambient)
? Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found
: undefined;
let mainModule = resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError, /*isForAugmentation*/ true);
@@ -805,7 +805,7 @@ namespace ts {
if ((modulekind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) ||
(!compilerOptions.outFile && !compilerOptions.out) ||
isInTypeQuery(usage) ||
isInAmbientContext(declaration)) {
declaration.flags & NodeFlags.Ambient) {
// nodes are in different files and order cannot be determined
return true;
}
@@ -1393,7 +1393,7 @@ namespace ts {
Debug.assert(declaration !== undefined, "Declaration to checkResolvedBlockScopedVariable is undefined");
if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
if (!(declaration.flags & NodeFlags.Ambient) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
if (result.flags & SymbolFlags.BlockScopedVariable) {
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(getNameOfDeclaration(declaration)));
}
@@ -2870,8 +2870,7 @@ namespace ts {
function mapToTypeNodes(types: Type[], context: NodeBuilderContext): TypeNode[] {
if (some(types)) {
const result = [];
for (let i = 0; i < types.length; ++i) {
const type = types[i];
for (const type of types) {
const typeNode = typeToTypeNodeHelper(type, context);
if (typeNode) {
result.push(typeNode);
@@ -3981,7 +3980,7 @@ namespace ts {
const parent = getDeclarationContainer(node);
// If the node is not exported or it is not ambient module element (except import declaration)
if (!(getCombinedModifierFlags(node) & ModifierFlags.Export) &&
!(node.kind !== SyntaxKind.ImportEqualsDeclaration && parent.kind !== SyntaxKind.SourceFile && isInAmbientContext(parent))) {
!(node.kind !== SyntaxKind.ImportEqualsDeclaration && parent.kind !== SyntaxKind.SourceFile && parent.flags & NodeFlags.Ambient)) {
return isGlobalSourceFile(parent);
}
// Exported members/ambient module elements (exception import declaration) are visible if parent is visible
@@ -4359,7 +4358,7 @@ namespace ts {
if ((noImplicitAny || isInJavaScriptFile(declaration)) &&
declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) &&
!(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !isInAmbientContext(declaration)) {
!(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !(declaration.flags & NodeFlags.Ambient)) {
// If --noImplicitAny is on or the declaration is in a Javascript file,
// use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no
// initializer or a 'null' or 'undefined' initializer.
@@ -5238,7 +5237,7 @@ namespace ts {
function isLiteralEnumMember(member: EnumMember) {
const expr = member.initializer;
if (!expr) {
return !isInAmbientContext(member);
return !(member.flags & NodeFlags.Ambient);
}
switch (expr.kind) {
case SyntaxKind.StringLiteral:
@@ -6836,7 +6835,7 @@ namespace ts {
if (!node) return false;
switch (node.kind) {
case SyntaxKind.Identifier:
return (<Identifier>node).escapedText === "arguments" && isPartOfExpression(node);
return (<Identifier>node).escapedText === "arguments" && isExpressionNode(node);
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.MethodDeclaration:
@@ -7702,9 +7701,12 @@ namespace ts {
return false;
}
function isSubtypeOfAny(candidate: Type, types: Type[]): boolean {
for (const type of types) {
if (candidate !== type && isTypeSubtypeOf(candidate, type)) {
function isSubtypeOfAny(source: Type, targets: Type[]): boolean {
for (const target of targets) {
if (source !== target && isTypeSubtypeOf(source, target) && (
!(getObjectFlags(getTargetType(source)) & ObjectFlags.Class) ||
!(getObjectFlags(getTargetType(target)) & ObjectFlags.Class) ||
isTypeDerivedFrom(source, target))) {
return true;
}
}
@@ -7852,11 +7854,11 @@ namespace ts {
}
}
// Add the given types to the given type set. Order is preserved, duplicates are removed,
// and nested types of the given kind are flattened into the set.
// Add the given types to the given type set. Order is preserved, freshness is removed from literal
// types, duplicates are removed, and nested types of the given kind are flattened into the set.
function addTypesToIntersection(typeSet: TypeSet, types: Type[]) {
for (const type of types) {
addTypeToIntersection(typeSet, type);
addTypeToIntersection(typeSet, getRegularTypeOfLiteralType(type));
}
}
@@ -8853,12 +8855,19 @@ namespace ts {
return isTypeRelatedTo(source, target, assignableRelation);
}
// A type S is considered to be an instance of a type T if S and T are the same type or if S is a
// subtype of T but not structurally identical to T. This specifically means that two distinct but
// structurally identical types (such as two classes) are not considered instances of each other.
function isTypeInstanceOf(source: Type, target: Type): boolean {
return getTargetType(source) === getTargetType(target) || isTypeSubtypeOf(source, target) && !isTypeIdenticalTo(source, target);
}
// An object type S is considered to be derived from an object type T if
// S is a union type and every constituent of S is derived from T,
// T is a union type and S is derived from at least one constituent of T, or
// T is one of the global types Object and Function and S is a subtype of T, or
// T occurs directly or indirectly in an 'extends' clause of S.
// Note that this check ignores type parameters and only considers the
// inheritance hierarchy.
function isTypeDerivedFrom(source: Type, target: Type): boolean {
return source.flags & TypeFlags.Union ? every((<UnionType>source).types, t => isTypeDerivedFrom(t, target)) :
target.flags & TypeFlags.Union ? some((<UnionType>target).types, t => isTypeDerivedFrom(source, t)) :
target === globalObjectType || target === globalFunctionType ? isTypeSubtypeOf(source, target) :
hasBaseType(source, getTargetType(target));
}
/**
* This is *not* a bi-directional relationship.
@@ -9894,7 +9903,7 @@ namespace ts {
if (relation === identityRelation) {
return propertiesIdenticalTo(source, target);
}
const requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source);
const requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source) && !isEmptyArrayLiteralType(source);
const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties);
if (unmatchedProperty) {
if (reportErrors) {
@@ -10602,6 +10611,11 @@ namespace ts {
!(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType);
}
function isEmptyArrayLiteralType(type: Type): boolean {
const elementType = isArrayType(type) ? (<TypeReference>type).typeArguments[0] : undefined;
return elementType === undefinedWideningType || elementType === neverType;
}
function isTupleLikeType(type: Type): boolean {
return !!getPropertyOfType(type, "0" as __String);
}
@@ -11107,7 +11121,7 @@ namespace ts {
}
function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean) {
const properties = getPropertiesOfObjectType(target);
const properties = target.flags & TypeFlags.Intersection ? getPropertiesOfUnionOrIntersectionType(<IntersectionType>target) : getPropertiesOfObjectType(target);
for (const targetProp of properties) {
if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional)) {
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
@@ -12731,7 +12745,7 @@ namespace ts {
}
if (targetType) {
return getNarrowedType(type, targetType, assumeTrue, isTypeInstanceOf);
return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom);
}
return type;
@@ -12838,7 +12852,7 @@ namespace ts {
if (isRightSideOfQualifiedNameOrPropertyAccess(location)) {
location = location.parent;
}
if (isPartOfExpression(location) && !isAssignmentTarget(location)) {
if (isExpressionNode(location) && !isAssignmentTarget(location)) {
const type = getTypeOfExpression(<Expression>location);
if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
return type;
@@ -13061,7 +13075,7 @@ namespace ts {
const assumeInitialized = isParameter || isAlias || isOuterVariable ||
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
node.parent.kind === SyntaxKind.NonNullExpression ||
isInAmbientContext(declaration);
declaration.flags & NodeFlags.Ambient;
const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, getRootDeclaration(declaration) as VariableLikeDeclaration) : type) :
type === autoType || type === autoArrayType ? undefinedType :
getNullableType(type, TypeFlags.Undefined);
@@ -13913,7 +13927,13 @@ namespace ts {
// JSX expression can appear in two position : JSX Element's children or JSX attribute
const jsxAttributes = isJsxAttributeLike(node.parent) ?
node.parent.parent :
node.parent.openingElement.attributes; // node.parent is JsxElement
isJsxElement(node.parent) ?
node.parent.openingElement.attributes :
undefined; // node.parent is JsxFragment with no attributes
if (!jsxAttributes) {
return undefined; // don't check children of a fragment
}
// When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
// which is a type of the parameter of the signature we are trying out.
@@ -14193,7 +14213,6 @@ namespace ts {
type.pattern = node;
return type;
}
const contextualType = getApparentTypeOfContextualType(node);
if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
const pattern = contextualType.pattern;
// If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
@@ -14498,13 +14517,13 @@ namespace ts {
}
function checkJsxSelfClosingElement(node: JsxSelfClosingElement): Type {
checkJsxOpeningLikeElement(node);
checkJsxOpeningLikeElementOrOpeningFragment(node);
return getJsxGlobalElementType() || anyType;
}
function checkJsxElement(node: JsxElement): Type {
// Check attributes
checkJsxOpeningLikeElement(node.openingElement);
checkJsxOpeningLikeElementOrOpeningFragment(node.openingElement);
// Perform resolution on the closing tag so that rename/go to definition/etc work
if (isJsxIntrinsicIdentifier(node.closingElement.tagName)) {
@@ -14517,6 +14536,16 @@ namespace ts {
return getJsxGlobalElementType() || anyType;
}
function checkJsxFragment(node: JsxFragment): Type {
checkJsxOpeningLikeElementOrOpeningFragment(node.openingFragment);
if (compilerOptions.jsx === JsxEmit.React && compilerOptions.jsxFactory) {
error(node, Diagnostics.JSX_fragment_is_not_supported_when_using_jsxFactory);
}
return getJsxGlobalElementType() || anyType;
}
/**
* Returns true iff the JSX element name would be a valid JS identifier, ignoring restrictions about keywords not being identifiers
*/
@@ -15180,14 +15209,19 @@ namespace ts {
}
}
function checkJsxOpeningLikeElement(node: JsxOpeningLikeElement) {
checkGrammarJsxElement(node);
function checkJsxOpeningLikeElementOrOpeningFragment(node: JsxOpeningLikeElement | JsxOpeningFragment) {
const isNodeOpeningLikeElement = isJsxOpeningLikeElement(node);
if (isNodeOpeningLikeElement) {
checkGrammarJsxElement(<JsxOpeningLikeElement>node);
}
checkJsxPreconditions(node);
// The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
// And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
const reactRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined;
const reactNamespace = getJsxNamespace();
const reactSym = resolveName(node.tagName, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace, /*isUse*/ true);
const reactLocation = isNodeOpeningLikeElement ? (<JsxOpeningLikeElement>node).tagName : node;
const reactSym = resolveName(reactLocation, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace, /*isUse*/ true);
if (reactSym) {
// Mark local symbol as referenced here because it might not have been marked
// if jsx emit was not react as there wont be error being emitted
@@ -15199,7 +15233,9 @@ namespace ts {
}
}
checkJsxAttributesAssignableToTagNameAttributes(node);
if (isNodeOpeningLikeElement) {
checkJsxAttributesAssignableToTagNameAttributes(<JsxOpeningLikeElement>node);
}
}
/**
@@ -15355,12 +15391,11 @@ namespace ts {
}
}
// Referencing Abstract Properties within Constructors is not allowed
if ((flags & ModifierFlags.Abstract) && symbolHasNonMethodDeclaration(prop)) {
// Referencing abstract properties within their own constructors is not allowed
if ((flags & ModifierFlags.Abstract) && isThisProperty(node) && symbolHasNonMethodDeclaration(prop)) {
const declaringClassDeclaration = <ClassLikeDeclaration>getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
if (declaringClassDeclaration && isNodeWithinConstructor(node, declaringClassDeclaration)) {
error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), typeToString(getDeclaringClass(prop)));
if (declaringClassDeclaration && isNodeWithinConstructorOfClass(node, declaringClassDeclaration)) {
error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), getTextOfIdentifierOrLiteral(declaringClassDeclaration.name));
return false;
}
}
@@ -15517,7 +15552,7 @@ namespace ts {
}
else if (valueDeclaration.kind === SyntaxKind.ClassDeclaration &&
node.parent.kind !== SyntaxKind.TypeReference &&
!isInAmbientContext(valueDeclaration) &&
!(valueDeclaration.flags & NodeFlags.Ambient) &&
!isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)) {
error(right, Diagnostics.Class_0_used_before_its_declaration, idText(right));
}
@@ -15532,7 +15567,7 @@ namespace ts {
// We might be in `a = { b: this.b }`, so keep looking. See `tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts`.
return false;
default:
return isPartOfExpression(node) ? false : "quit";
return isExpressionNode(node) ? false : "quit";
}
});
}
@@ -16916,21 +16951,9 @@ namespace ts {
* but is a subtype of the Function interface, the call is an untyped function call.
*/
function isUntypedFunctionCall(funcType: Type, apparentFuncType: Type, numCallSignatures: number, numConstructSignatures: number) {
if (isTypeAny(funcType)) {
return true;
}
if (isTypeAny(apparentFuncType) && funcType.flags & TypeFlags.TypeParameter) {
return true;
}
if (!numCallSignatures && !numConstructSignatures) {
// We exclude union types because we may have a union of function types that happen to have
// no common signatures.
if (funcType.flags & TypeFlags.Union) {
return false;
}
return isTypeAssignableTo(funcType, globalFunctionType);
}
return false;
// We exclude union types because we may have a union of function types that happen to have no common signatures.
return isTypeAny(funcType) || isTypeAny(apparentFuncType) && funcType.flags & TypeFlags.TypeParameter ||
!numCallSignatures && !numConstructSignatures && !(funcType.flags & (TypeFlags.Union | TypeFlags.Never)) && isTypeAssignableTo(funcType, globalFunctionType);
}
function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[]): Signature {
@@ -17410,7 +17433,7 @@ namespace ts {
return type;
}
function isCommonJsRequire(node: Node) {
function isCommonJsRequire(node: Node): boolean {
if (!isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
return false;
}
@@ -17435,7 +17458,7 @@ namespace ts {
if (targetDeclarationKind !== SyntaxKind.Unknown) {
const decl = getDeclarationOfKind(resolvedRequire, targetDeclarationKind);
// function/variable declaration should be ambient
return isInAmbientContext(decl);
return !!(decl.flags & NodeFlags.Ambient);
}
return false;
}
@@ -18418,14 +18441,6 @@ namespace ts {
return (target.flags & TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target);
}
function getBestChoiceType(type1: Type, type2: Type): Type {
const firstAssignableToSecond = isTypeAssignableTo(type1, type2);
const secondAssignableToFirst = isTypeAssignableTo(type2, type1);
return secondAssignableToFirst && !firstAssignableToSecond ? type1 :
firstAssignableToSecond && !secondAssignableToFirst ? type2 :
getUnionType([type1, type2], /*subtypeReduction*/ true);
}
function checkBinaryExpression(node: BinaryExpression, checkMode?: CheckMode) {
return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, checkMode, node);
}
@@ -18562,7 +18577,7 @@ namespace ts {
leftType;
case SyntaxKind.BarBarToken:
return getTypeFacts(leftType) & TypeFacts.Falsy ?
getBestChoiceType(removeDefinitelyFalsyTypes(leftType), rightType) :
getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], /*subtypeReduction*/ true) :
leftType;
case SyntaxKind.EqualsToken:
checkAssignmentOperator(rightType);
@@ -18722,7 +18737,7 @@ namespace ts {
checkExpression(node.condition);
const type1 = checkExpression(node.whenTrue, checkMode);
const type2 = checkExpression(node.whenFalse, checkMode);
return getBestChoiceType(type1, type2);
return getUnionType([type1, type2], /*subtypeReduction*/ true);
}
function checkTemplateExpression(node: TemplateExpression): Type {
@@ -19012,6 +19027,8 @@ namespace ts {
return checkJsxElement(<JsxElement>node);
case SyntaxKind.JsxSelfClosingElement:
return checkJsxSelfClosingElement(<JsxSelfClosingElement>node);
case SyntaxKind.JsxFragment:
return checkJsxFragment(<JsxFragment>node);
case SyntaxKind.JsxAttributes:
return checkJsxAttributes(<JsxAttributes>node, checkMode);
case SyntaxKind.JsxOpeningElement:
@@ -19569,7 +19586,7 @@ namespace ts {
checkDecorators(node);
checkSignatureDeclaration(node);
if (node.kind === SyntaxKind.GetAccessor) {
if (!isInAmbientContext(node) && nodeIsPresent(node.body) && (node.flags & NodeFlags.HasImplicitReturn)) {
if (!(node.flags & NodeFlags.Ambient) && nodeIsPresent(node.body) && (node.flags & NodeFlags.HasImplicitReturn)) {
if (!(node.flags & NodeFlags.HasExplicitReturn)) {
error(node.name, Diagnostics.A_get_accessor_must_return_a_value);
}
@@ -19757,7 +19774,7 @@ namespace ts {
}
function isPrivateWithinAmbient(node: Node): boolean {
return hasModifier(node, ModifierFlags.Private) && isInAmbientContext(node);
return hasModifier(node, ModifierFlags.Private) && !!(node.flags & NodeFlags.Ambient);
}
function getEffectiveDeclarationFlags(n: Node, flagsToCheck: ModifierFlags): ModifierFlags {
@@ -19768,7 +19785,7 @@ namespace ts {
if (n.parent.kind !== SyntaxKind.InterfaceDeclaration &&
n.parent.kind !== SyntaxKind.ClassDeclaration &&
n.parent.kind !== SyntaxKind.ClassExpression &&
isInAmbientContext(n)) {
n.flags & NodeFlags.Ambient) {
if (!(flags & ModifierFlags.Ambient)) {
// It is nested in an ambient context, which means it is automatically exported
flags |= ModifierFlags.Export;
@@ -19907,7 +19924,7 @@ namespace ts {
let multipleConstructorImplementation = false;
for (const current of declarations) {
const node = <FunctionLike>current;
const inAmbientContext = isInAmbientContext(node);
const inAmbientContext = node.flags & NodeFlags.Ambient;
const inAmbientContextOrInterface = node.parent.kind === SyntaxKind.InterfaceDeclaration || node.parent.kind === SyntaxKind.TypeLiteral || inAmbientContext;
if (inAmbientContextOrInterface) {
// check if declarations are consecutive only if they are non-ambient
@@ -20762,7 +20779,7 @@ namespace ts {
}
function checkUnusedLocalsAndParameters(node: Node): void {
if (node.parent.kind !== SyntaxKind.InterfaceDeclaration && noUnusedIdentifiers && !isInAmbientContext(node)) {
if (node.parent.kind !== SyntaxKind.InterfaceDeclaration && noUnusedIdentifiers && !(node.flags & NodeFlags.Ambient)) {
node.locals.forEach(local => {
if (!local.isReferenced) {
if (local.valueDeclaration && getRootDeclaration(local.valueDeclaration).kind === SyntaxKind.Parameter) {
@@ -20815,7 +20832,7 @@ namespace ts {
}
function checkUnusedClassMembers(node: ClassDeclaration | ClassExpression): void {
if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) {
if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) {
if (node.members) {
for (const member of node.members) {
if (member.kind === SyntaxKind.MethodDeclaration || member.kind === SyntaxKind.PropertyDeclaration) {
@@ -20836,7 +20853,7 @@ namespace ts {
}
function checkUnusedTypeParameters(node: ClassDeclaration | ClassExpression | FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction | ConstructorDeclaration | SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration) {
if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) {
if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) {
if (node.typeParameters) {
// Only report errors on the last declaration for the type parameter container;
// this ensures that all uses have been accounted for.
@@ -20855,7 +20872,7 @@ namespace ts {
}
function checkUnusedModuleMembers(node: ModuleDeclaration | SourceFile): void {
if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) {
if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) {
node.locals.forEach(local => {
if (!local.isReferenced && !local.exportSymbol) {
for (const declaration of local.declarations) {
@@ -20888,7 +20905,7 @@ namespace ts {
function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) {
// no rest parameters \ declaration context \ overload - no codegen impact
if (!hasRestParameter(node) || isInAmbientContext(node) || nodeIsMissing((<FunctionLikeDeclaration>node).body)) {
if (!hasRestParameter(node) || node.flags & NodeFlags.Ambient || nodeIsMissing((<FunctionLikeDeclaration>node).body)) {
return;
}
@@ -20914,7 +20931,7 @@ namespace ts {
return false;
}
if (isInAmbientContext(node)) {
if (node.flags & NodeFlags.Ambient) {
// ambient context - no codegen impact
return false;
}
@@ -20979,7 +20996,7 @@ namespace ts {
// bubble up and find containing type
const enclosingClass = getContainingClass(node);
// if containing type was not found or it is ambient - exit (no codegen)
if (!enclosingClass || isInAmbientContext(enclosingClass)) {
if (!enclosingClass || enclosingClass.flags & NodeFlags.Ambient) {
return;
}
@@ -22298,7 +22315,7 @@ namespace ts {
checkClassForDuplicateDeclarations(node);
// Only check for reserved static identifiers on non-ambient context.
if (!isInAmbientContext(node)) {
if (!(node.flags & NodeFlags.Ambient)) {
checkClassForStaticPropertyNameConflicts(node);
}
@@ -22604,7 +22621,7 @@ namespace ts {
}
// In ambient enum declarations that specify no const modifier, enum member declarations that omit
// a value are considered computed members (as opposed to having auto-incremented values).
if (isInAmbientContext(member.parent) && !isConst(member.parent)) {
if (member.parent.flags & NodeFlags.Ambient && !isConst(member.parent)) {
return undefined;
}
// If the member declaration specifies no value, the member is considered a constant enum member.
@@ -22637,7 +22654,7 @@ namespace ts {
else if (isConstEnum) {
error(initializer, Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression);
}
else if (isInAmbientContext(member.parent)) {
else if (member.parent.flags & NodeFlags.Ambient) {
error(initializer, Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression);
}
else {
@@ -22750,7 +22767,7 @@ namespace ts {
computeEnumMemberValues(node);
const enumIsConst = isConst(node);
if (compilerOptions.isolatedModules && enumIsConst && isInAmbientContext(node)) {
if (compilerOptions.isolatedModules && enumIsConst && node.flags & NodeFlags.Ambient) {
error(node.name, Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided);
}
@@ -22802,7 +22819,7 @@ namespace ts {
for (const declaration of declarations) {
if ((declaration.kind === SyntaxKind.ClassDeclaration ||
(declaration.kind === SyntaxKind.FunctionDeclaration && nodeIsPresent((<FunctionLikeDeclaration>declaration).body))) &&
!isInAmbientContext(declaration)) {
!(declaration.flags & NodeFlags.Ambient)) {
return declaration;
}
}
@@ -22827,7 +22844,7 @@ namespace ts {
if (produceDiagnostics) {
// Grammar checking
const isGlobalAugmentation = isGlobalScopeAugmentation(node);
const inAmbientContext = isInAmbientContext(node);
const inAmbientContext = node.flags & NodeFlags.Ambient;
if (isGlobalAugmentation && !inAmbientContext) {
error(node.name, Diagnostics.Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context);
}
@@ -23046,7 +23063,7 @@ namespace ts {
if (compilerOptions.isolatedModules
&& node.kind === SyntaxKind.ExportSpecifier
&& !(target.flags & SymbolFlags.Value)
&& !isInAmbientContext(node)) {
&& !(node.flags & NodeFlags.Ambient)) {
error(node, Diagnostics.Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided);
}
}
@@ -23097,7 +23114,7 @@ namespace ts {
if (hasModifier(node, ModifierFlags.Export)) {
markExportAsReferenced(node);
}
if (isInternalModuleImportEqualsDeclaration(node)) {
if (node.moduleReference.kind !== SyntaxKind.ExternalModuleReference) {
const target = resolveAlias(getSymbolOfNode(node));
if (target !== unknownSymbol) {
if (target.flags & SymbolFlags.Value) {
@@ -23113,7 +23130,7 @@ namespace ts {
}
}
else {
if (modulekind >= ModuleKind.ES2015 && !isInAmbientContext(node)) {
if (modulekind >= ModuleKind.ES2015 && !(node.flags & NodeFlags.Ambient)) {
// Import equals declaration is deprecated in es6 or above
grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead);
}
@@ -23139,7 +23156,7 @@ namespace ts {
const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(node.parent.parent);
const inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === SyntaxKind.ModuleBlock &&
!node.moduleSpecifier && isInAmbientContext(node);
!node.moduleSpecifier && node.flags & NodeFlags.Ambient;
if (node.parent.kind !== SyntaxKind.SourceFile && !inAmbientExternalModule && !inAmbientNamespaceDeclaration) {
error(node, Diagnostics.Export_declarations_are_not_permitted_in_a_namespace);
}
@@ -23212,11 +23229,11 @@ namespace ts {
checkExternalModuleExports(container);
if (isInAmbientContext(node) && !isEntityNameExpression(node.expression)) {
if ((node.flags & NodeFlags.Ambient) && !isEntityNameExpression(node.expression)) {
grammarErrorOnNode(node.expression, Diagnostics.The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context);
}
if (node.isExportEquals && !isInAmbientContext(node)) {
if (node.isExportEquals && !(node.flags & NodeFlags.Ambient)) {
if (modulekind >= ModuleKind.ES2015) {
// export assignment is not supported in es6 modules
grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead);
@@ -23508,7 +23525,7 @@ namespace ts {
checkDeferredNodes();
if (isExternalModule(node)) {
if (isExternalOrCommonJsModule(node)) {
registerForUnusedIdentifiersCheck(node);
}
@@ -23736,9 +23753,9 @@ namespace ts {
return result;
}
function isNodeWithinConstructor(node: Node, classDeclaration: ClassLikeDeclaration) {
function isNodeWithinConstructorOfClass(node: Node, classDeclaration: ClassLikeDeclaration) {
return findAncestor(node, element => {
if (isConstructorDeclaration(element) && nodeIsPresent(element.body)) {
if (isConstructorDeclaration(element) && nodeIsPresent(element.body) && element.parent === classDeclaration) {
return true;
}
else if (element === classDeclaration || isFunctionLikeDeclaration(element)) {
@@ -23849,7 +23866,7 @@ namespace ts {
return typeParameter && typeParameter.symbol;
}
if (isPartOfExpression(entityName)) {
if (isExpressionNode(entityName)) {
if (nodeIsMissing(entityName)) {
// Missing entity name.
return undefined;
@@ -23981,6 +23998,8 @@ namespace ts {
return objectType && getPropertyOfType(objectType, escapeLeadingUnderscores((node as StringLiteral | NumericLiteral).text));
case SyntaxKind.DefaultKeyword:
case SyntaxKind.FunctionKeyword:
case SyntaxKind.EqualsGreaterThanToken:
return getSymbolOfNode(node.parent);
default:
@@ -24023,7 +24042,7 @@ namespace ts {
return typeFromTypeNode;
}
if (isPartOfExpression(node)) {
if (isExpressionNode(node)) {
return getRegularTypeOfExpression(<Expression>node);
}
@@ -24854,7 +24873,7 @@ namespace ts {
function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) {
if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
const sourceFile = getSourceFileOfNode(location);
if (isEffectiveExternalModule(sourceFile, compilerOptions) && !isInAmbientContext(location)) {
if (isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & NodeFlags.Ambient)) {
const helpersModule = resolveHelpersModule(sourceFile, location);
if (helpersModule !== unknownSymbol) {
const uncheckedHelpers = helpers & ~requestedExternalEmitHelpers;
@@ -25056,7 +25075,7 @@ namespace ts {
else if (node.kind === SyntaxKind.Parameter) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare");
}
else if (isInAmbientContext(node.parent) && node.parent.kind === SyntaxKind.ModuleBlock) {
else if ((node.parent.flags & NodeFlags.Ambient) && node.parent.kind === SyntaxKind.ModuleBlock) {
return grammarErrorOnNode(modifier, Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context);
}
flags |= ModifierFlags.Ambient;
@@ -25092,7 +25111,7 @@ namespace ts {
if (flags & ModifierFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "async");
}
else if (flags & ModifierFlags.Ambient || isInAmbientContext(node.parent)) {
else if (flags & ModifierFlags.Ambient || node.parent.flags & NodeFlags.Ambient) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
}
else if (node.kind === SyntaxKind.Parameter) {
@@ -25440,7 +25459,7 @@ namespace ts {
node.kind === SyntaxKind.FunctionDeclaration ||
node.kind === SyntaxKind.FunctionExpression ||
node.kind === SyntaxKind.MethodDeclaration);
if (isInAmbientContext(node)) {
if (node.flags & NodeFlags.Ambient) {
return grammarErrorOnNode(node.asteriskToken, Diagnostics.Generators_are_not_allowed_in_an_ambient_context);
}
if (!node.body) {
@@ -25627,7 +25646,7 @@ namespace ts {
if (languageVersion < ScriptTarget.ES5) {
return grammarErrorOnNode(accessor.name, Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
}
else if (isInAmbientContext(accessor)) {
else if (accessor.flags & NodeFlags.Ambient) {
return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context);
}
else if (accessor.body === undefined && !hasModifier(accessor, ModifierFlags.Abstract)) {
@@ -25750,7 +25769,7 @@ namespace ts {
// However, property declarations disallow computed names in general,
// and accessors are not allowed in ambient contexts in general,
// so this error only really matters for methods.
if (isInAmbientContext(node)) {
if (node.flags & NodeFlags.Ambient) {
return checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
}
else if (!node.body) {
@@ -25845,7 +25864,7 @@ namespace ts {
function checkGrammarVariableDeclaration(node: VariableDeclaration) {
if (node.parent.parent.kind !== SyntaxKind.ForInStatement && node.parent.parent.kind !== SyntaxKind.ForOfStatement) {
if (isInAmbientContext(node)) {
if (node.flags & NodeFlags.Ambient) {
if (node.initializer) {
if (isConst(node) && !node.type) {
if (!isStringOrNumberLiteralExpression(node.initializer)) {
@@ -25875,7 +25894,7 @@ namespace ts {
}
if (compilerOptions.module !== ModuleKind.ES2015 && compilerOptions.module !== ModuleKind.ESNext && compilerOptions.module !== ModuleKind.System && !compilerOptions.noEmit &&
!isInAmbientContext(node.parent.parent) && hasModifier(node.parent.parent, ModifierFlags.Export)) {
!(node.parent.parent.flags & NodeFlags.Ambient) && hasModifier(node.parent.parent, ModifierFlags.Export)) {
checkESModuleMarker(node.name);
}
@@ -26034,7 +26053,7 @@ namespace ts {
}
}
if (isInAmbientContext(node) && node.initializer) {
if (node.flags & NodeFlags.Ambient && node.initializer) {
return grammarErrorOnFirstToken(node.initializer, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
}
}
@@ -26077,11 +26096,11 @@ namespace ts {
}
function checkGrammarSourceFile(node: SourceFile): boolean {
return isInAmbientContext(node) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
return !!(node.flags & NodeFlags.Ambient) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
}
function checkGrammarStatementInAmbientContext(node: Node): boolean {
if (isInAmbientContext(node)) {
if (node.flags & NodeFlags.Ambient) {
// An accessors is already reported about the ambient context
if (isAccessor(node.parent)) {
return getNodeLinks(node).hasReportedStatementInAmbientContext = true;
-27
View File
@@ -985,32 +985,6 @@ namespace ts {
return initial;
}
export function reduceRight<T, U>(array: ReadonlyArray<T>, f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U;
export function reduceRight<T>(array: ReadonlyArray<T>, f: (memo: T, value: T, i: number) => T): T;
export function reduceRight<T>(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T, start?: number, count?: number): T {
if (array) {
const size = array.length;
if (size > 0) {
let pos = start === undefined || start > size - 1 ? size - 1 : start;
const end = count === undefined || pos - count < 0 ? 0 : pos - count;
let result: T;
if (arguments.length <= 2) {
result = array[pos];
pos--;
}
else {
result = initial;
}
while (pos >= end) {
result = f(result, array[pos], pos);
pos--;
}
return result;
}
}
return initial;
}
const hasOwnProperty = Object.prototype.hasOwnProperty;
/**
@@ -1600,7 +1574,6 @@ namespace ts {
}
if (path.charCodeAt(1) === CharacterCodes.colon) {
if (path.charCodeAt(2) === CharacterCodes.slash) return 3;
return 2;
}
// Per RFC 1738 'file' URI schema has the shape file://<host>/<path>
// if <host> is omitted then it is assumed that host value is 'localhost',
+20
View File
@@ -3680,6 +3680,18 @@
"category": "Error",
"code": 17013
},
"JSX fragment has no corresponding closing tag.": {
"category": "Error",
"code": 17014
},
"Expected corresponding closing tag for JSX fragment.": {
"category": "Error",
"code": 17015
},
"JSX fragment is not supported when using --jsxFactory": {
"category": "Error",
"code":17016
},
"Circularity detected while resolving configuration: {0}": {
"category": "Error",
@@ -3846,5 +3858,13 @@
"Infer parameter types from usage.": {
"category": "Message",
"code": 95012
},
"Convert to default import": {
"category": "Message",
"code": 95013
},
"Install '{0}'": {
"category": "Message",
"code": 95014
}
}
+30 -20
View File
@@ -699,9 +699,11 @@ namespace ts {
case SyntaxKind.JsxText:
return emitJsxText(<JsxText>node);
case SyntaxKind.JsxOpeningElement:
return emitJsxOpeningElement(<JsxOpeningElement>node);
case SyntaxKind.JsxOpeningFragment:
return emitJsxOpeningElementOrFragment(<JsxOpeningElement>node);
case SyntaxKind.JsxClosingElement:
return emitJsxClosingElement(<JsxClosingElement>node);
case SyntaxKind.JsxClosingFragment:
return emitJsxClosingElementOrFragment(<JsxClosingElement>node);
case SyntaxKind.JsxAttribute:
return emitJsxAttribute(<JsxAttribute>node);
case SyntaxKind.JsxAttributes:
@@ -836,6 +838,8 @@ namespace ts {
return emitJsxElement(<JsxElement>node);
case SyntaxKind.JsxSelfClosingElement:
return emitJsxSelfClosingElement(<JsxSelfClosingElement>node);
case SyntaxKind.JsxFragment:
return emitJsxFragment(<JsxFragment>node);
// Transformation nodes
case SyntaxKind.PartiallyEmittedExpression:
@@ -2060,7 +2064,7 @@ namespace ts {
function emitJsxElement(node: JsxElement) {
emit(node.openingElement);
emitList(node, node.children, ListFormat.JsxElementChildren);
emitList(node, node.children, ListFormat.JsxElementOrFragmentChildren);
emit(node.closingElement);
}
@@ -2075,14 +2079,24 @@ namespace ts {
write("/>");
}
function emitJsxOpeningElement(node: JsxOpeningElement) {
function emitJsxFragment(node: JsxFragment) {
emit(node.openingFragment);
emitList(node, node.children, ListFormat.JsxElementOrFragmentChildren);
emit(node.closingFragment);
}
function emitJsxOpeningElementOrFragment(node: JsxOpeningElement | JsxOpeningFragment) {
write("<");
emitJsxTagName(node.tagName);
writeIfAny(node.attributes.properties, " ");
// We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap
if (node.attributes.properties && node.attributes.properties.length > 0) {
emit(node.attributes);
if (isJsxOpeningElement(node)) {
emitJsxTagName(node.tagName);
// We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap
if (node.attributes.properties && node.attributes.properties.length > 0) {
write(" ");
emit(node.attributes);
}
}
write(">");
}
@@ -2090,9 +2104,11 @@ namespace ts {
writer.writeLiteral(getTextOfNode(node, /*includeTrivia*/ true));
}
function emitJsxClosingElement(node: JsxClosingElement) {
function emitJsxClosingElementOrFragment(node: JsxClosingElement | JsxClosingFragment) {
write("</");
emitJsxTagName(node.tagName);
if (isJsxClosingElement(node)) {
emitJsxTagName(node.tagName);
}
write(">");
}
@@ -2611,12 +2627,6 @@ namespace ts {
writer.decreaseIndent();
}
function writeIfAny(nodes: NodeArray<Node>, text: string) {
if (some(nodes)) {
write(text);
}
}
function writeToken(token: SyntaxKind, pos: number, contextNode?: Node) {
return onEmitSourceMapOfToken
? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText)
@@ -2651,8 +2661,8 @@ namespace ts {
function writeLines(text: string): void {
const lines = text.split(/\r\n?|\n/g);
const indentation = guessIndentation(lines);
for (let i = 0; i < lines.length; i++) {
const line = indentation ? lines[i].slice(indentation) : lines[i];
for (const lineText of lines) {
const line = indentation ? lineText.slice(indentation) : lineText;
if (line.length) {
writeLine();
write(line);
@@ -3176,7 +3186,7 @@ namespace ts {
EnumMembers = CommaDelimited | Indented | MultiLine,
CaseBlockClauses = Indented | MultiLine,
NamedImportsOrExportsElements = CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | SingleLine | SpaceBetweenBraces,
JsxElementChildren = SingleLine | NoInterveningComments,
JsxElementOrFragmentChildren = SingleLine | NoInterveningComments,
JsxElementAttributes = SingleLine | SpaceBetweenSiblings | NoInterveningComments,
CaseOrDefaultClauseStatements = Indented | MultiLine | NoTrailingNewLine | OptionalIfEmpty,
HeritageClauseTypes = CommaDelimited | SpaceBetweenSiblings | SingleLine,
+73 -5
View File
@@ -1984,7 +1984,7 @@ namespace ts {
node.decorators = asNodeArray(decorators);
node.modifiers = asNodeArray(modifiers);
node.isExportEquals = isExportEquals;
node.expression = expression;
node.expression = isExportEquals ? parenthesizeBinaryOperand(SyntaxKind.EqualsToken, expression, /*isLeftSideOfBinary*/ false, /*leftOperand*/ undefined) : parenthesizeDefaultExpression(expression);
return node;
}
@@ -2117,6 +2117,22 @@ namespace ts {
: node;
}
export function createJsxFragment(openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment) {
const node = <JsxFragment>createSynthesizedNode(SyntaxKind.JsxFragment);
node.openingFragment = openingFragment;
node.children = createNodeArray(children);
node.closingFragment = closingFragment;
return node;
}
export function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment) {
return node.openingFragment !== openingFragment
|| node.children !== children
|| node.closingFragment !== closingFragment
? updateNode(createJsxFragment(openingFragment, children, closingFragment), node)
: node;
}
export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression) {
const node = <JsxAttribute>createSynthesizedNode(SyntaxKind.JsxAttribute);
node.name = name;
@@ -2627,7 +2643,7 @@ namespace ts {
/**
* Gets a custom text range to use when emitting source maps.
*/
export function getSourceMapRange(node: Node) {
export function getSourceMapRange(node: Node): SourceMapRange {
const emitNode = node.emitNode;
return (emitNode && emitNode.sourceMapRange) || node;
}
@@ -2953,7 +2969,7 @@ namespace ts {
);
}
function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement) {
function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment) {
// To ensure the emit resolver can properly resolve the namespace, we need to
// treat this identifier as if it were a source tree node by clearing the `Synthesized`
// flag and setting a parent node.
@@ -2965,7 +2981,7 @@ namespace ts {
return react;
}
function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement): Expression {
function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression {
if (isQualifiedName(jsxFactory)) {
const left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent);
const right = createIdentifier(idText(jsxFactory.right));
@@ -2977,7 +2993,7 @@ namespace ts {
}
}
function createJsxFactoryExpression(jsxFactoryEntity: EntityName, reactNamespace: string, parent: JsxOpeningLikeElement): Expression {
function createJsxFactoryExpression(jsxFactoryEntity: EntityName, reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression {
return jsxFactoryEntity ?
createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) :
createPropertyAccess(
@@ -3018,6 +3034,37 @@ namespace ts {
);
}
export function createExpressionForJsxFragment(jsxFactoryEntity: EntityName, reactNamespace: string, children: Expression[], parentElement: JsxOpeningFragment, location: TextRange): LeftHandSideExpression {
const tagName = createPropertyAccess(
createReactNamespace(reactNamespace, parentElement),
"Fragment"
);
const argumentsList = [<Expression>tagName];
argumentsList.push(createNull());
if (children && children.length > 0) {
if (children.length > 1) {
for (const child of children) {
child.startsOnNewLine = true;
argumentsList.push(child);
}
}
else {
argumentsList.push(children[0]);
}
}
return setTextRange(
createCall(
createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement),
/*typeArguments*/ undefined,
argumentsList
),
location
);
}
// Helpers
export function getHelperName(name: string) {
@@ -3887,6 +3934,27 @@ namespace ts {
: e;
}
/**
* [Per the spec](https://tc39.github.io/ecma262/#prod-ExportDeclaration), `export default` accepts _AssigmentExpression_ but
* has a lookahead restriction for `function`, `async function`, and `class`.
*
* Basically, that means we need to parenthesize in the following cases:
*
* - BinaryExpression of CommaToken
* - CommaList (synthetic list of multiple comma expressions)
* - FunctionExpression
* - ClassExpression
*/
export function parenthesizeDefaultExpression(e: Expression) {
const check = skipPartiallyEmittedExpressions(e);
return (check.kind === SyntaxKind.ClassExpression ||
check.kind === SyntaxKind.FunctionExpression ||
check.kind === SyntaxKind.CommaListExpression ||
isBinaryExpression(check) && check.operatorToken.kind === SyntaxKind.CommaToken)
? createParen(e)
: e;
}
/**
* Wraps an expression in parentheses if it is needed in order to use the expression
* as the expression of a NewExpression node.
+96 -19
View File
@@ -377,6 +377,10 @@ namespace ts {
return visitNode(cbNode, (<JsxElement>node).openingElement) ||
visitNodes(cbNode, cbNodes, (<JsxElement>node).children) ||
visitNode(cbNode, (<JsxElement>node).closingElement);
case SyntaxKind.JsxFragment:
return visitNode(cbNode, (<JsxFragment>node).openingFragment) ||
visitNodes(cbNode, cbNodes, (<JsxFragment>node).children) ||
visitNode(cbNode, (<JsxFragment>node).closingFragment);
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxOpeningElement:
return visitNode(cbNode, (<JsxOpeningLikeElement>node).tagName) ||
@@ -627,6 +631,7 @@ namespace ts {
}
export function parseIsolatedEntityName(content: string, languageVersion: ScriptTarget): EntityName {
// Choice of `isDeclarationFile` should be arbitrary
initializeState(content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS);
// Prime the scanner.
nextToken();
@@ -639,7 +644,7 @@ namespace ts {
export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile {
initializeState(sourceText, ScriptTarget.ES2015, /*syntaxCursor*/ undefined, ScriptKind.JSON);
// Set source file so that errors will be reported with this file name
sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON);
sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false);
const result = <JsonSourceFile>sourceFile;
// Prime the scanner.
@@ -681,7 +686,16 @@ namespace ts {
identifierCount = 0;
nodeCount = 0;
contextFlags = scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JSON ? NodeFlags.JavaScriptFile : NodeFlags.None;
switch (scriptKind) {
case ScriptKind.JS:
case ScriptKind.JSX:
case ScriptKind.JSON:
contextFlags = NodeFlags.JavaScriptFile;
break;
default:
contextFlags = NodeFlags.None;
break;
}
parseErrorBeforeNextFinishedNode = false;
// Initialize and prime the scanner before parsing the source elements.
@@ -705,7 +719,12 @@ namespace ts {
}
function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind): SourceFile {
sourceFile = createSourceFile(fileName, languageVersion, scriptKind);
const isDeclarationFile = isDeclarationFileName(fileName);
if (isDeclarationFile) {
contextFlags |= NodeFlags.Ambient;
}
sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile);
sourceFile.flags = contextFlags;
// Prime the scanner.
@@ -782,7 +801,7 @@ namespace ts {
}
}
function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind): SourceFile {
function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind, isDeclarationFile: boolean): SourceFile {
// code from createNode is inlined here so createNode won't have to deal with special case of creating source files
// this is quite rare comparing to other nodes and createNode should be as fast as possible
const sourceFile = <SourceFile>new SourceFileConstructor(SyntaxKind.SourceFile, /*pos*/ 0, /* end */ sourceText.length);
@@ -793,7 +812,7 @@ namespace ts {
sourceFile.languageVersion = languageVersion;
sourceFile.fileName = normalizePath(fileName);
sourceFile.languageVariant = getLanguageVariant(scriptKind);
sourceFile.isDeclarationFile = fileExtensionIs(sourceFile.fileName, Extension.Dts);
sourceFile.isDeclarationFile = isDeclarationFile;
sourceFile.scriptKind = scriptKind;
return sourceFile;
@@ -1423,6 +1442,11 @@ namespace ts {
return tokenIsIdentifierOrKeyword(token());
}
function nextTokenIsIdentifierOrKeywordOrGreaterThan() {
nextToken();
return tokenIsIdentifierOrKeywordOrGreaterThan(token());
}
function isHeritageClauseExtendsOrImplementsKeyword(): boolean {
if (token() === SyntaxKind.ImplementsKeyword ||
token() === SyntaxKind.ExtendsKeyword) {
@@ -3805,9 +3829,9 @@ namespace ts {
node.operand = parseLeftHandSideExpressionOrHigher();
return finishNode(node);
}
else if (sourceFile.languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeyword)) {
else if (sourceFile.languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) {
// JSXElement is part of primaryExpression
return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true);
return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true);
}
const expression = parseLeftHandSideExpressionOrHigher();
@@ -3962,14 +3986,14 @@ namespace ts {
}
function parseJsxElementOrSelfClosingElement(inExpressionContext: boolean): JsxElement | JsxSelfClosingElement {
const opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
let result: JsxElement | JsxSelfClosingElement;
function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean): JsxElement | JsxSelfClosingElement | JsxFragment {
const opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext);
let result: JsxElement | JsxSelfClosingElement | JsxFragment;
if (opening.kind === SyntaxKind.JsxOpeningElement) {
const node = <JsxElement>createNode(SyntaxKind.JsxElement, opening.pos);
node.openingElement = opening;
node.children = parseJsxChildren(node.openingElement.tagName);
node.children = parseJsxChildren(node.openingElement);
node.closingElement = parseJsxClosingElement(inExpressionContext);
if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) {
@@ -3978,6 +4002,14 @@ namespace ts {
result = finishNode(node);
}
else if (opening.kind === SyntaxKind.JsxOpeningFragment) {
const node = <JsxFragment>createNode(SyntaxKind.JsxFragment, opening.pos);
node.openingFragment = opening;
node.children = parseJsxChildren(node.openingFragment);
node.closingFragment = parseJsxClosingFragment(inExpressionContext);
result = finishNode(node);
}
else {
Debug.assert(opening.kind === SyntaxKind.JsxSelfClosingElement);
// Nothing else to do for self-closing elements
@@ -3992,7 +4024,7 @@ namespace ts {
// Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
// of one sort or another.
if (inExpressionContext && token() === SyntaxKind.LessThanToken) {
const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true));
const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true));
if (invalidElement) {
parseErrorAtCurrentToken(Diagnostics.JSX_expressions_must_have_one_parent_element);
const badNode = <BinaryExpression>createNode(SyntaxKind.BinaryExpression, result.pos);
@@ -4023,12 +4055,12 @@ namespace ts {
case SyntaxKind.OpenBraceToken:
return parseJsxExpression(/*inExpressionContext*/ false);
case SyntaxKind.LessThanToken:
return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false);
return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false);
}
Debug.fail("Unknown JSX child kind " + token());
}
function parseJsxChildren(openingTagName: LeftHandSideExpression): NodeArray<JsxChild> {
function parseJsxChildren(openingTag: JsxOpeningElement | JsxOpeningFragment): NodeArray<JsxChild> {
const list = [];
const listPos = getNodePos();
const saveParsingContext = parsingContext;
@@ -4043,7 +4075,13 @@ namespace ts {
else if (token() === SyntaxKind.EndOfFileToken) {
// If we hit EOF, issue the error at the tag that lacks the closing element
// rather than at the end of the file (which is useless)
parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTagName));
if (isJsxOpeningFragment(openingTag)) {
parseErrorAtPosition(openingTag.pos, openingTag.end - openingTag.pos, Diagnostics.JSX_fragment_has_no_corresponding_closing_tag);
}
else {
const openingTagName = openingTag.tagName;
parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTagName));
}
break;
}
else if (token() === SyntaxKind.ConflictMarkerTrivia) {
@@ -4066,11 +4104,17 @@ namespace ts {
return finishNode(jsxAttributes);
}
function parseJsxOpeningOrSelfClosingElement(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement {
function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement | JsxOpeningFragment {
const fullStart = scanner.getStartPos();
parseExpected(SyntaxKind.LessThanToken);
if (token() === SyntaxKind.GreaterThanToken) {
parseExpected(SyntaxKind.GreaterThanToken);
const node: JsxOpeningFragment = <JsxOpeningFragment>createNode(SyntaxKind.JsxOpeningFragment, fullStart);
return finishNode(node);
}
const tagName = parseJsxElementName();
const attributes = parseJsxAttributes();
@@ -4182,6 +4226,23 @@ namespace ts {
return finishNode(node);
}
function parseJsxClosingFragment(inExpressionContext: boolean): JsxClosingFragment {
const node = <JsxClosingFragment>createNode(SyntaxKind.JsxClosingFragment);
parseExpected(SyntaxKind.LessThanSlashToken);
if (tokenIsIdentifierOrKeyword(token())) {
const unexpectedTagName = parseJsxElementName();
parseErrorAtPosition(unexpectedTagName.pos, unexpectedTagName.end - unexpectedTagName.pos, Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment);
}
if (inExpressionContext) {
parseExpected(SyntaxKind.GreaterThanToken);
}
else {
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
scanJsxText();
}
return finishNode(node);
}
function parseTypeAssertion(): TypeAssertion {
const node = <TypeAssertion>createNode(SyntaxKind.TypeAssertionExpression);
parseExpected(SyntaxKind.LessThanToken);
@@ -5092,6 +5153,18 @@ namespace ts {
const fullStart = getNodePos();
const decorators = parseDecorators();
const modifiers = parseModifiers();
if (some(modifiers, m => m.kind === SyntaxKind.DeclareKeyword)) {
for (const m of modifiers) {
m.flags |= NodeFlags.Ambient;
}
return doInsideOfContext(NodeFlags.Ambient, () => parseDeclarationWorker(fullStart, decorators, modifiers));
}
else {
return parseDeclarationWorker(fullStart, decorators, modifiers);
}
}
function parseDeclarationWorker(fullStart: number, decorators: NodeArray<Decorator> | undefined, modifiers: NodeArray<Modifier> | undefined): Statement {
switch (token()) {
case SyntaxKind.VarKeyword:
case SyntaxKind.LetKeyword:
@@ -5449,8 +5522,8 @@ namespace ts {
return false;
}
function parseDecorators(): NodeArray<Decorator> {
let list: Decorator[];
function parseDecorators(): NodeArray<Decorator> | undefined {
let list: Decorator[] | undefined;
const listPos = getNodePos();
while (true) {
const decoratorStart = getNodePos();
@@ -6134,7 +6207,7 @@ namespace ts {
export namespace JSDocParser {
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number): { jsDocTypeExpression: JSDocTypeExpression, diagnostics: Diagnostic[] } | undefined {
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS);
sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false);
scanner.setText(content, start, length);
currentToken = scanner.scan();
const jsDocTypeExpression = parseJSDocTypeExpression();
@@ -7464,4 +7537,8 @@ namespace ts {
Value = -1
}
}
function isDeclarationFileName(fileName: string): boolean {
return fileExtensionIs(fileName, Extension.Dts);
}
}
+4 -12
View File
@@ -7,18 +7,10 @@ namespace ts {
const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/;
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string {
while (true) {
const fileName = combinePaths(searchPath, configName);
if (fileExists(fileName)) {
return fileName;
}
const parentPath = getDirectoryPath(searchPath);
if (parentPath === searchPath) {
break;
}
searchPath = parentPath;
}
return undefined;
return forEachAncestorDirectory(searchPath, ancestor => {
const fileName = combinePaths(ancestor, configName);
return fileExists(fileName) ? fileName : undefined;
});
}
export function resolveTripleslashReference(moduleName: string, containingFile: string): string {
+20 -7
View File
@@ -69,9 +69,8 @@ namespace ts {
export const maxNumberOfFilesToIterateForInvalidation = 256;
interface GetResolutionWithResolvedFileName<T extends ResolutionWithFailedLookupLocations = ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName = ResolutionWithResolvedFileName> {
(resolution: T): R;
}
type GetResolutionWithResolvedFileName<T extends ResolutionWithFailedLookupLocations = ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName = ResolutionWithResolvedFileName> =
(resolution: T) => R;
export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string): ResolutionCache {
let filesWithChangedSetOfUnresolvedImports: Path[] | undefined;
@@ -320,6 +319,10 @@ namespace ts {
return endsWith(dirPath, "/node_modules");
}
function isNodeModulesAtTypesDirectory(dirPath: Path) {
return endsWith(dirPath, "/node_modules/@types");
}
function isDirectoryAtleastAtLevelFromFSRoot(dirPath: Path, minLevels: number) {
for (let searchIndex = getRootLength(dirPath); minLevels > 0; minLevels--) {
searchIndex = dirPath.indexOf(directorySeparator, searchIndex) + 1;
@@ -560,11 +563,21 @@ namespace ts {
else {
// Some file or directory in the watching directory is created
// Return early if it does not have any of the watching extension or not the custom failed lookup path
if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) {
return false;
const dirOfFileOrDirectory = getDirectoryPath(fileOrDirectoryPath);
if (isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) {
// Invalidate any resolution from this directory
isChangedFailedLookupLocation = location => {
const locationPath = resolutionHost.toPath(location);
return locationPath === fileOrDirectoryPath || startsWith(resolutionHost.toPath(location), fileOrDirectoryPath);
};
}
else {
if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) {
return false;
}
// Resolution need to be invalidated if failed lookup location is same as the file or directory getting created
isChangedFailedLookupLocation = location => resolutionHost.toPath(location) === fileOrDirectoryPath;
}
// Resolution need to be invalidated if failed lookup location is same as the file or directory getting created
isChangedFailedLookupLocation = location => resolutionHost.toPath(location) === fileOrDirectoryPath;
}
const hasChangedFailedLookupLocation = (resolution: ResolutionWithFailedLookupLocations) => some(resolution.failedLookupLocations, isChangedFailedLookupLocation);
const invalidatedFilesCount = filesWithInvalidatedResolutions && filesWithInvalidatedResolutions.size;
+6 -3
View File
@@ -2,15 +2,18 @@
/// <reference path="diagnosticInformationMap.generated.ts"/>
namespace ts {
export interface ErrorCallback {
(message: DiagnosticMessage, length: number): void;
}
export type ErrorCallback = (message: DiagnosticMessage, length: number) => void;
/* @internal */
export function tokenIsIdentifierOrKeyword(token: SyntaxKind): boolean {
return token >= SyntaxKind.Identifier;
}
/* @internal */
export function tokenIsIdentifierOrKeywordOrGreaterThan(token: SyntaxKind): boolean {
return token === SyntaxKind.GreaterThanToken || tokenIsIdentifierOrKeyword(token);
}
export interface Scanner {
getStartPos(): number;
getToken(): SyntaxKind;
+2 -2
View File
@@ -124,7 +124,7 @@ namespace ts {
getEnvironmentVariable?(name: string): string;
};
export let sys: System = (function() {
export let sys: System = (() => {
function getNodeSystem(): System {
const _fs = require("fs");
const _path = require("path");
@@ -594,7 +594,7 @@ namespace ts {
if (sys) {
// patch writefile to create folder before writing the file
const originalWriteFile = sys.writeFile;
sys.writeFile = function(path, data, writeBom) {
sys.writeFile = (path, data, writeBom) => {
const directoryPath = getDirectoryPath(normalizeSlashes(path));
if (directoryPath && !sys.directoryExists(directoryPath)) {
recursiveCreateDirectory(directoryPath, sys);
+26
View File
@@ -41,6 +41,9 @@ namespace ts {
case SyntaxKind.JsxSelfClosingElement:
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node, /*isChild*/ false);
case SyntaxKind.JsxFragment:
return visitJsxFragment(<JsxFragment>node, /*isChild*/ false);
case SyntaxKind.JsxExpression:
return visitJsxExpression(<JsxExpression>node);
@@ -63,6 +66,9 @@ namespace ts {
case SyntaxKind.JsxSelfClosingElement:
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node, /*isChild*/ true);
case SyntaxKind.JsxFragment:
return visitJsxFragment(<JsxFragment>node, /*isChild*/ true);
default:
Debug.failBadSyntaxKind(node);
return undefined;
@@ -77,6 +83,10 @@ namespace ts {
return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node);
}
function visitJsxFragment(node: JsxFragment, isChild: boolean) {
return visitJsxOpeningFragment(node.openingFragment, node.children, isChild, /*location*/ node);
}
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: ReadonlyArray<JsxChild>, isChild: boolean, location: TextRange) {
const tagName = getTagName(node);
let objectProperties: Expression;
@@ -126,6 +136,22 @@ namespace ts {
return element;
}
function visitJsxOpeningFragment(node: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, isChild: boolean, location: TextRange) {
const element = createExpressionForJsxFragment(
context.getEmitResolver().getJsxFactoryEntity(),
compilerOptions.reactNamespace,
mapDefined(children, transformJsxChildToExpression),
node,
location
);
if (isChild) {
startOnNewLine(element);
}
return element;
}
function transformJsxSpreadAttributeToExpression(node: JsxSpreadAttribute) {
return visitNode(node.expression, visitor, isExpression);
}
+1 -2
View File
@@ -146,8 +146,7 @@ namespace ts {
function collectDependencyGroups(externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]) {
const groupIndices = createMap<number>();
const dependencyGroups: DependencyGroup[] = [];
for (let i = 0; i < externalImports.length; i++) {
const externalImport = externalImports[i];
for (const externalImport of externalImports) {
const externalModuleName = getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions);
if (externalModuleName) {
const text = externalModuleName.text;
+7
View File
@@ -225,6 +225,13 @@ namespace ts {
if (parsed !== node) {
// If the node has been transformed by a `before` transformer, perform no ellision on it
// As the type information we would attempt to lookup to perform ellision is potentially unavailable for the synthesized nodes
// We do not reuse `visitorWorker`, as the ellidable statement syntax kinds are technically unrecognized by the switch-case in `visitTypeScript`,
// and will trigger debug failures when debug verbosity is turned up
if (node.transformFlags & TransformFlags.ContainsTypeScript) {
// This node contains TypeScript, so we should visit its children.
return visitEachChild(node, visitor, context);
}
// Otherwise, we can just return the node
return node;
}
switch (node.kind) {
+1 -3
View File
@@ -305,9 +305,7 @@ namespace ts {
const optionsDescriptionMap = createMap<string[]>(); // Map between option.description and list of option.type if it is a kind
for (let i = 0; i < optsList.length; i++) {
const option = optsList[i];
for (const option of optsList) {
// If an option lacks a description,
// it is not officially supported.
if (!option.description) {
+37 -13
View File
@@ -329,6 +329,9 @@ namespace ts {
JsxSelfClosingElement,
JsxOpeningElement,
JsxClosingElement,
JsxFragment,
JsxOpeningFragment,
JsxClosingFragment,
JsxAttribute,
JsxAttributes,
JsxSpreadAttribute,
@@ -452,7 +455,8 @@ namespace ts {
/* @internal */
PossiblyContainsDynamicImport = 1 << 19,
JSDoc = 1 << 20, // If node was parsed inside jsdoc
/* @internal */ InWithStatement = 1 << 21, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
/* @internal */ Ambient = 1 << 21, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier.
/* @internal */ InWithStatement = 1 << 22, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
BlockScoped = Let | Const,
@@ -460,7 +464,7 @@ namespace ts {
ReachabilityAndEmitFlags = ReachabilityCheckFlags | HasAsyncFunctions,
// Parsing context flags
ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement,
ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement | Ambient,
// Exclude these flags when parsing a Type
TypeExcludesFlags = YieldContext | AwaitContext,
@@ -1643,7 +1647,7 @@ namespace ts {
closingElement: JsxClosingElement;
}
/// Either the opening tag in a <Tag>...</Tag> pair, or the lone <Tag /> in a self-closing form
/// Either the opening tag in a <Tag>...</Tag> pair or the lone <Tag /> in a self-closing form
export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement;
export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute;
@@ -1669,6 +1673,26 @@ namespace ts {
attributes: JsxAttributes;
}
/// A JSX expression of the form <>...</>
export interface JsxFragment extends PrimaryExpression {
kind: SyntaxKind.JsxFragment;
openingFragment: JsxOpeningFragment;
children: NodeArray<JsxChild>;
closingFragment: JsxClosingFragment;
}
/// The opening element of a <>...</> JsxFragment
export interface JsxOpeningFragment extends Expression {
kind: SyntaxKind.JsxOpeningFragment;
parent?: JsxFragment;
}
/// The closing element of a <>...</> JsxFragment
export interface JsxClosingFragment extends Expression {
kind: SyntaxKind.JsxClosingFragment;
parent?: JsxFragment;
}
export interface JsxAttribute extends ObjectLiteralElement {
kind: SyntaxKind.JsxAttribute;
parent?: JsxAttributes;
@@ -1702,7 +1726,7 @@ namespace ts {
parent?: JsxElement;
}
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment;
export interface Statement extends Node {
_statementBrand: any;
@@ -2471,9 +2495,13 @@ namespace ts {
readFile(path: string): string | undefined;
}
export interface WriteFileCallback {
(fileName: string, data: string, writeByteOrderMark: boolean, onError: ((message: string) => void) | undefined, sourceFiles: ReadonlyArray<SourceFile>): void;
}
export type WriteFileCallback = (
fileName: string,
data: string,
writeByteOrderMark: boolean,
onError: ((message: string) => void) | undefined,
sourceFiles: ReadonlyArray<SourceFile>,
) => void;
export class OperationCanceledException { }
@@ -3598,9 +3626,7 @@ namespace ts {
}
/* @internal */
export interface TypeMapper {
(t: TypeParameter): Type;
}
export type TypeMapper = (t: TypeParameter) => Type;
export const enum InferencePriority {
Contravariant = 1 << 0, // Inference from contravariant position
@@ -4208,9 +4234,7 @@ namespace ts {
}
/* @internal */
export interface HasInvalidatedResolution {
(sourceFile: Path): boolean;
}
export type HasInvalidatedResolution = (sourceFile: Path) => boolean;
export interface CompilerHost extends ModuleResolutionHost {
getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined;
+32 -17
View File
@@ -1149,7 +1149,7 @@ namespace ts {
}
/**
* Determines whether a node is a property or element access expression for super.
* Determines whether a node is a property or element access expression for `super`.
*/
export function isSuperProperty(node: Node): node is SuperProperty {
const kind = node.kind;
@@ -1157,7 +1157,16 @@ namespace ts {
&& (<PropertyAccessExpression | ElementAccessExpression>node).expression.kind === SyntaxKind.SuperKeyword;
}
export function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression {
/**
* Determines whether a node is a property or element access expression for `this`.
*/
export function isThisProperty(node: Node): boolean {
const kind = node.kind;
return (kind === SyntaxKind.PropertyAccessExpression || kind === SyntaxKind.ElementAccessExpression)
&& (<PropertyAccessExpression | ElementAccessExpression>node).expression.kind === SyntaxKind.ThisKeyword;
}
export function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression {
switch (node.kind) {
case SyntaxKind.TypeReference:
return (<TypeReferenceNode>node).typeName;
@@ -1245,7 +1254,7 @@ namespace ts {
return false;
}
export function isPartOfExpression(node: Node): boolean {
export function isExpressionNode(node: Node): boolean {
switch (node.kind) {
case SyntaxKind.SuperKeyword:
case SyntaxKind.NullKeyword:
@@ -1279,6 +1288,7 @@ namespace ts {
case SyntaxKind.OmittedExpression:
case SyntaxKind.JsxElement:
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxFragment:
case SyntaxKind.YieldExpression:
case SyntaxKind.AwaitExpression:
case SyntaxKind.MetaProperty:
@@ -1348,7 +1358,7 @@ namespace ts {
case SyntaxKind.ExpressionWithTypeArguments:
return (<ExpressionWithTypeArguments>parent).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);
default:
return isPartOfExpression(parent);
return isExpressionNode(parent);
}
}
@@ -1747,16 +1757,6 @@ namespace ts {
return false;
}
export function isInAmbientContext(node: Node): boolean {
while (node) {
if (hasModifier(node, ModifierFlags.Ambient) || (node.kind === SyntaxKind.SourceFile && (node as SourceFile).isDeclarationFile)) {
return true;
}
node = node.parent;
}
return false;
}
// True if the given identifier, string literal, or number literal is the name of a declaration node
export function isDeclarationName(name: Node): boolean {
switch (name.kind) {
@@ -2199,6 +2199,7 @@ namespace ts {
case SyntaxKind.ClassExpression:
case SyntaxKind.JsxElement:
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxFragment:
case SyntaxKind.RegularExpressionLiteral:
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.TemplateExpression:
@@ -3628,7 +3629,7 @@ namespace ts {
}
/** Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. */
export function forEachAncestorDirectory<T>(directory: string, callback: (directory: string) => T): T {
export function forEachAncestorDirectory<T>(directory: string, callback: (directory: string) => T | undefined): T | undefined {
while (true) {
const result = callback(directory);
if (result !== undefined) {
@@ -4831,6 +4832,18 @@ namespace ts {
return node.kind === SyntaxKind.JsxClosingElement;
}
export function isJsxFragment(node: Node): node is JsxFragment {
return node.kind === SyntaxKind.JsxFragment;
}
export function isJsxOpeningFragment(node: Node): node is JsxOpeningFragment {
return node.kind === SyntaxKind.JsxOpeningFragment;
}
export function isJsxClosingFragment(node: Node): node is JsxClosingFragment {
return node.kind === SyntaxKind.JsxClosingFragment;
}
export function isJsxAttribute(node: Node): node is JsxAttribute {
return node.kind === SyntaxKind.JsxAttribute;
}
@@ -5356,6 +5369,7 @@ namespace ts {
case SyntaxKind.CallExpression:
case SyntaxKind.JsxElement:
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxFragment:
case SyntaxKind.TaggedTemplateExpression:
case SyntaxKind.ArrayLiteralExpression:
case SyntaxKind.ParenthesizedExpression:
@@ -5418,7 +5432,7 @@ namespace ts {
/* @internal */
/**
* Determines whether a node is an expression based only on its kind.
* Use `isPartOfExpression` if not in transforms.
* Use `isExpressionNode` if not in transforms.
*/
export function isExpression(node: Node): node is Expression {
return isExpressionKind(skipPartiallyEmittedExpressions(node).kind);
@@ -5677,7 +5691,8 @@ namespace ts {
return kind === SyntaxKind.JsxElement
|| kind === SyntaxKind.JsxExpression
|| kind === SyntaxKind.JsxSelfClosingElement
|| kind === SyntaxKind.JsxText;
|| kind === SyntaxKind.JsxText
|| kind === SyntaxKind.JsxFragment;
}
/* @internal */
+12
View File
@@ -819,6 +819,12 @@ namespace ts {
return updateJsxClosingElement(<JsxClosingElement>node,
visitNode((<JsxClosingElement>node).tagName, visitor, isJsxTagNameExpression));
case SyntaxKind.JsxFragment:
return updateJsxFragment(<JsxFragment>node,
visitNode((<JsxFragment>node).openingFragment, visitor, isJsxOpeningFragment),
nodesVisitor((<JsxFragment>node).children, visitor, isJsxChild),
visitNode((<JsxFragment>node).closingFragment, visitor, isJsxClosingFragment));
case SyntaxKind.JsxAttribute:
return updateJsxAttribute(<JsxAttribute>node,
visitNode((<JsxAttribute>node).name, visitor, isIdentifier),
@@ -1334,6 +1340,12 @@ namespace ts {
result = reduceNode((<JsxElement>node).closingElement, cbNode, result);
break;
case SyntaxKind.JsxFragment:
result = reduceNode((<JsxFragment>node).openingFragment, cbNode, result);
result = reduceLeft((<JsxFragment>node).children, cbNode, result);
result = reduceNode((<JsxFragment>node).closingFragment, cbNode, result);
break;
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxOpeningElement:
result = reduceNode((<JsxSelfClosingElement | JsxOpeningElement>node).tagName, cbNode, result);
+2 -2
View File
@@ -211,8 +211,8 @@ class CompilerBaselineRunner extends RunnerBase {
this.emit = false;
const opts = this.options.split(",");
for (let i = 0; i < opts.length; i++) {
switch (opts[i]) {
for (const opt of opts) {
switch (opt) {
case "emit":
this.emit = true;
break;
+114 -44
View File
@@ -314,7 +314,7 @@ namespace FourSlash {
const languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions);
this.languageServiceAdapterHost = languageServiceAdapter.getHost();
this.languageService = languageServiceAdapter.getLanguageService();
this.languageService = memoWrap(languageServiceAdapter.getLanguageService(), this); // Wrap the LS to cache some expensive operations certain tests call repeatedly
if (startResolveFileRef) {
// Add the entry-point file itself into the languageServiceShimHost
@@ -381,6 +381,39 @@ namespace FourSlash {
// Open the first file by default
this.openFile(0);
function memoWrap(ls: ts.LanguageService, target: TestState): ts.LanguageService {
const cacheableMembers: (keyof typeof ls)[] = [
"getCompletionsAtPosition",
"getCompletionEntryDetails",
"getCompletionEntrySymbol",
"getQuickInfoAtPosition",
"getSignatureHelpItems",
"getReferencesAtPosition",
"getDocumentHighlights",
];
const proxy = {} as ts.LanguageService;
for (const k in ls) {
const key = k as keyof typeof ls;
if (cacheableMembers.indexOf(key) === -1) {
proxy[key] = (...args: any[]) => (ls[key] as Function)(...args);
continue;
}
const memo = Utils.memoize(
(_version: number, _active: string, _caret: number, _selectEnd: number, _marker: string, ...args: any[]) => (ls[key] as Function)(...args),
(...args) => args.join("|,|")
);
proxy[key] = (...args: any[]) => memo(
target.languageServiceAdapterHost.getScriptInfo(target.activeFile.fileName).version,
target.activeFile.fileName,
target.currentCaretPosition,
target.selectionEnd,
target.lastKnownMarker,
...args
);
}
return proxy;
}
}
private getFileContent(fileName: string): string {
@@ -437,6 +470,10 @@ namespace FourSlash {
public select(startMarker: string, endMarker: string) {
const start = this.getMarkerByName(startMarker), end = this.getMarkerByName(endMarker);
ts.Debug.assert(start.fileName === end.fileName);
if (this.activeFile.fileName !== start.fileName) {
this.openFile(start.fileName);
}
this.goToPosition(start.position);
this.selectionEnd = end.position;
}
@@ -583,19 +620,23 @@ namespace FourSlash {
}
public verifyGoToDefinition(arg0: any, endMarkerNames?: string | string[]) {
this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinition());
this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinitionAndBoundSpan());
}
private getGoToDefinition(): ts.DefinitionInfo[] {
return this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
}
private getGoToDefinitionAndBoundSpan(): ts.DefinitionInfoAndBoundSpan {
return this.languageService.getDefinitionAndBoundSpan(this.activeFile.fileName, this.currentCaretPosition);
}
public verifyGoToType(arg0: any, endMarkerNames?: string | string[]) {
this.verifyGoToX(arg0, endMarkerNames, () =>
this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition));
}
private verifyGoToX(arg0: any, endMarkerNames: string | string[] | undefined, getDefs: () => ts.DefinitionInfo[] | undefined) {
private verifyGoToX(arg0: any, endMarkerNames: string | string[] | undefined, getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
if (endMarkerNames) {
this.verifyGoToXPlain(arg0, endMarkerNames, getDefs);
}
@@ -615,7 +656,7 @@ namespace FourSlash {
}
}
private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
for (const start of toArray(startMarkerNames)) {
this.verifyGoToXSingle(start, endMarkerNames, getDefs);
}
@@ -627,26 +668,57 @@ namespace FourSlash {
}
}
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
this.goToMarker(startMarkerName);
this.verifyGoToXWorker(toArray(endMarkerNames), getDefs);
this.verifyGoToXWorker(toArray(endMarkerNames), getDefs, startMarkerName);
}
private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
const definitions = getDefs() || [];
private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined, startMarkerName?: string) {
const defs = getDefs();
let definitions: ts.DefinitionInfo[] | ReadonlyArray<ts.DefinitionInfo>;
let testName: string;
if (!defs || Array.isArray(defs)) {
definitions = defs as ts.DefinitionInfo[] || [];
testName = "goToDefinitions";
}
else {
this.verifyDefinitionTextSpan(defs, startMarkerName);
definitions = defs.definitions;
testName = "goToDefinitionsAndBoundSpan";
}
if (endMarkers.length !== definitions.length) {
this.raiseError(`goToDefinitions failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`);
this.raiseError(`${testName} failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`);
}
ts.zipWith(endMarkers, definitions, (endMarker, definition, i) => {
const marker = this.getMarkerByName(endMarker);
if (marker.fileName !== definition.fileName || marker.position !== definition.textSpan.start) {
this.raiseError(`goToDefinition failed for definition ${endMarker} (${i}): expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`);
this.raiseError(`${testName} failed for definition ${endMarker} (${i}): expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`);
}
});
}
private verifyDefinitionTextSpan(defs: ts.DefinitionInfoAndBoundSpan, startMarkerName: string) {
const range = this.testData.ranges.find(range => this.markerName(range.marker) === startMarkerName);
if (!range && !defs.textSpan) {
return;
}
if (!range) {
this.raiseError(`goToDefinitionsAndBoundSpan failed - found a TextSpan ${JSON.stringify(defs.textSpan)} when it wasn't expected.`);
}
else if (defs.textSpan.start !== range.start || defs.textSpan.length !== range.end - range.start) {
const expected: ts.TextSpan = {
start: range.start, length: range.end - range.start
};
this.raiseError(`goToDefinitionsAndBoundSpan failed - expected to find TextSpan ${JSON.stringify(expected)} but got ${JSON.stringify(defs.textSpan)}`);
}
}
public verifyGetEmitOutputForCurrentFile(expected: string): void {
const emit = this.languageService.getEmitOutput(this.activeFile.fileName);
if (emit.outputFiles.length !== 1) {
@@ -783,8 +855,8 @@ namespace FourSlash {
});
}
public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean) {
const completions = this.getCompletionListAtCaret();
public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean, options?: ts.GetCompletionsAtPositionOptions) {
const completions = this.getCompletionListAtCaret(options);
if (completions) {
this.assertItemInCompletionList(completions.entries, entryId, text, documentation, kind, spanIndex, hasAction);
}
@@ -804,38 +876,35 @@ namespace FourSlash {
* @param expectedKind the kind of symbol (see ScriptElementKind)
* @param spanIndex the index of the range that the completion item's replacement text span should match
*/
public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number) {
const that = this;
public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number, options?: ts.GetCompletionsAtPositionOptions) {
let replacementSpan: ts.TextSpan;
if (spanIndex !== undefined) {
replacementSpan = this.getTextSpanForRangeAtIndex(spanIndex);
}
function filterByTextOrDocumentation(entry: ts.CompletionEntry) {
const details = that.getCompletionEntryDetails(entry.name);
const documentation = details && ts.displayPartsToString(details.documentation);
const text = details && ts.displayPartsToString(details.displayParts);
// If any of the expected values are undefined, assume that users don't
// care about them.
if (replacementSpan && !TestState.textSpansEqual(replacementSpan, entry.replacementSpan)) {
return false;
}
else if (expectedText && text !== expectedText) {
return false;
}
else if (expectedDocumentation && documentation !== expectedDocumentation) {
return false;
}
return true;
}
const completions = this.getCompletionListAtCaret();
const completions = this.getCompletionListAtCaret(options);
if (completions) {
let filterCompletions = completions.entries.filter(e => e.name === entryId.name && e.source === entryId.source);
filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind) : filterCompletions;
filterCompletions = filterCompletions.filter(filterByTextOrDocumentation);
filterCompletions = filterCompletions.filter(entry => {
const details = this.getCompletionEntryDetails(entry.name);
const documentation = details && ts.displayPartsToString(details.documentation);
const text = details && ts.displayPartsToString(details.displayParts);
// If any of the expected values are undefined, assume that users don't
// care about them.
if (replacementSpan && !TestState.textSpansEqual(replacementSpan, entry.replacementSpan)) {
return false;
}
else if (expectedText && text !== expectedText) {
return false;
}
else if (expectedDocumentation && documentation !== expectedDocumentation) {
return false;
}
return true;
});
if (filterCompletions.length !== 0) {
// After filtered using all present criterion, if there are still symbol left in the list
// then these symbols must meet the criterion for Not supposed to be in the list. So we
@@ -1126,11 +1195,11 @@ Actual: ${stringify(fullActual)}`);
this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(references)})`);
}
private getCompletionListAtCaret() {
return this.languageService.getCompletionsAtPosition(this.activeFile.fileName, this.currentCaretPosition);
private getCompletionListAtCaret(options?: ts.GetCompletionsAtPositionOptions): ts.CompletionInfo {
return this.languageService.getCompletionsAtPosition(this.activeFile.fileName, this.currentCaretPosition, options);
}
private getCompletionEntryDetails(entryName: string, source?: string) {
private getCompletionEntryDetails(entryName: string, source?: string): ts.CompletionEntryDetails {
return this.languageService.getCompletionEntryDetails(this.activeFile.fileName, this.currentCaretPosition, entryName, this.formatCodeSettings, source);
}
@@ -1721,7 +1790,7 @@ Actual: ${stringify(fullActual)}`);
}
else if (prevChar === " " && /A-Za-z_/.test(ch)) {
/* Completions */
this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset);
this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset, { includeExternalModuleExports: false });
}
if (i % checkCadence === 0) {
@@ -2296,7 +2365,7 @@ Actual: ${stringify(fullActual)}`);
public applyCodeActionFromCompletion(markerName: string, options: FourSlashInterface.VerifyCompletionActionOptions) {
this.goToMarker(markerName);
const actualCompletion = this.getCompletionListAtCaret().entries.find(e => e.name === options.name && e.source === options.source);
const actualCompletion = this.getCompletionListAtCaret({ includeExternalModuleExports: true }).entries.find(e => e.name === options.name && e.source === options.source);
if (!actualCompletion.hasAction) {
this.raiseError(`Completion for ${options.name} does not have an associated action.`);
@@ -3734,15 +3803,15 @@ namespace FourSlashInterface {
// Verifies the completion list contains the specified symbol. The
// completion list is brought up if necessary
public completionListContains(entryId: string | ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean) {
public completionListContains(entryId: string | ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean, options?: ts.GetCompletionsAtPositionOptions) {
if (typeof entryId === "string") {
entryId = { name: entryId, source: undefined };
}
if (this.negative) {
this.state.verifyCompletionListDoesNotContain(entryId, text, documentation, kind, spanIndex);
this.state.verifyCompletionListDoesNotContain(entryId, text, documentation, kind, spanIndex, options);
}
else {
this.state.verifyCompletionListContains(entryId, text, documentation, kind, spanIndex, hasAction);
this.state.verifyCompletionListContains(entryId, text, documentation, kind, spanIndex, hasAction, options);
}
}
@@ -3900,6 +3969,7 @@ namespace FourSlashInterface {
}
public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[]): void;
public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[], range: FourSlash.Range): void;
public goToDefinition(startsAndEnds: [string | string[], string | string[]][]): void;
public goToDefinition(startsAndEnds: { [startMarkerName: string]: string | string[] }): void;
public goToDefinition(arg0: any, endMarkerName?: string | string[]) {
+18 -16
View File
@@ -479,7 +479,7 @@ namespace Utils {
}
namespace Harness {
export interface IO {
export interface Io {
newLine(): string;
getCurrentDirectory(): string;
useCaseSensitiveFileNames(): boolean;
@@ -502,7 +502,7 @@ namespace Harness {
tryEnableSourceMapsForHost?(): void;
getEnvironmentVariable?(name: string): string;
}
export let IO: IO;
export let IO: Io;
// harness always uses one kind of new line
// But note that `parseTestData` in `fourslash.ts` uses "\n"
@@ -575,14 +575,13 @@ namespace Harness {
function filesInFolder(folder: string): string[] {
let paths: string[] = [];
const files = fs.readdirSync(folder);
for (let i = 0; i < files.length; i++) {
const pathToFile = pathModule.join(folder, files[i]);
for (const file of fs.readdirSync(folder)) {
const pathToFile = pathModule.join(folder, file);
const stat = fs.statSync(pathToFile);
if (options.recursive && stat.isDirectory()) {
paths = paths.concat(filesInFolder(pathToFile));
}
else if (stat.isFile() && (!spec || files[i].match(spec))) {
else if (stat.isFile() && (!spec || file.match(spec))) {
paths.push(pathToFile);
}
}
@@ -784,9 +783,15 @@ namespace Harness {
? IO.newLine() + `//# sourceURL=${IO.resolvePath(tcServicesFileName)}`
: "");
export interface SourceMapEmitterCallback {
(emittedFile: string, emittedLine: number, emittedColumn: number, sourceFile: string, sourceLine: number, sourceColumn: number, sourceName: string): void;
}
export type SourceMapEmitterCallback = (
emittedFile: string,
emittedLine: number,
emittedColumn: number,
sourceFile: string,
sourceLine: number,
sourceColumn: number,
sourceName: string,
) => void;
// Settings
export let userSpecifiedRoot = "";
@@ -1575,10 +1580,8 @@ namespace Harness {
// Preserve legacy behavior
if (lastIndexWritten === undefined) {
for (let i = 0; i < codeLines.length; i++) {
const currentCodeLine = codeLines[i];
typeLines += currentCodeLine + "\r\n";
typeLines += "No type information for this code.";
for (const codeLine of codeLines) {
typeLines += codeLine + "\r\nNo type information for this code.";
}
}
else {
@@ -1864,8 +1867,7 @@ namespace Harness {
let currentFileName: any = undefined;
let refs: string[] = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
for (const line of lines) {
const testMetaData = optionRegex.exec(line);
if (testMetaData) {
// Comment line, check for global/file @options and record them
@@ -2145,7 +2147,7 @@ namespace Harness {
return filePath.indexOf(Harness.libFolder) === 0;
}
export function getDefaultLibraryFile(io: Harness.IO): Harness.Compiler.TestFile {
export function getDefaultLibraryFile(io: Harness.Io): Harness.Compiler.TestFile {
const libFile = Harness.userSpecifiedRoot + Harness.libFolder + Harness.Compiler.defaultLibFileName;
return { unitName: libFile, content: io.readFile(libFile) };
}
+12 -7
View File
@@ -413,8 +413,8 @@ namespace Harness.LanguageService {
getEncodedSemanticClassifications(fileName: string, span: ts.TextSpan): ts.Classifications {
return unwrapJSONCallResult(this.shim.getEncodedSemanticClassifications(fileName, span.start, span.length));
}
getCompletionsAtPosition(fileName: string, position: number): ts.CompletionInfo {
return unwrapJSONCallResult(this.shim.getCompletionsAtPosition(fileName, position));
getCompletionsAtPosition(fileName: string, position: number, options: ts.GetCompletionsAtPositionOptions | undefined): ts.CompletionInfo {
return unwrapJSONCallResult(this.shim.getCompletionsAtPosition(fileName, position, options));
}
getCompletionEntryDetails(fileName: string, position: number, entryName: string, options: ts.FormatCodeOptions | undefined, source: string | undefined): ts.CompletionEntryDetails {
return unwrapJSONCallResult(this.shim.getCompletionEntryDetails(fileName, position, entryName, JSON.stringify(options), source));
@@ -443,6 +443,9 @@ namespace Harness.LanguageService {
getDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] {
return unwrapJSONCallResult(this.shim.getDefinitionAtPosition(fileName, position));
}
getDefinitionAndBoundSpan(fileName: string, position: number): ts.DefinitionInfoAndBoundSpan {
return unwrapJSONCallResult(this.shim.getDefinitionAndBoundSpan(fileName, position));
}
getTypeDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] {
return unwrapJSONCallResult(this.shim.getTypeDefinitionAtPosition(fileName, position));
}
@@ -541,9 +544,9 @@ namespace Harness.LanguageService {
getClassifier(): ts.Classifier { return new ClassifierShimProxy(this.factory.createClassifierShim(this.host)); }
getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo {
let shimResult: {
referencedFiles: ts.IFileReference[];
typeReferenceDirectives: ts.IFileReference[];
importedFiles: ts.IFileReference[];
referencedFiles: ts.ShimsFileReference[];
typeReferenceDirectives: ts.ShimsFileReference[];
importedFiles: ts.ShimsFileReference[];
isLibFile: boolean;
};
@@ -754,6 +757,7 @@ namespace Harness.LanguageService {
create(info: ts.server.PluginCreateInfo) {
const proxy = makeDefaultProxy(info);
const langSvc: any = info.languageService;
// tslint:disable-next-line only-arrow-functions
proxy.getQuickInfoAtPosition = function () {
const parts = langSvc.getQuickInfoAtPosition.apply(langSvc, arguments);
if (parts.displayParts.length > 0) {
@@ -786,7 +790,7 @@ namespace Harness.LanguageService {
module: () => ({
create(info: ts.server.PluginCreateInfo) {
const proxy = makeDefaultProxy(info);
proxy.getSemanticDiagnostics = function (filename: string) {
proxy.getSemanticDiagnostics = filename => {
const prev = info.languageService.getSemanticDiagnostics(filename);
const sourceFile: ts.SourceFile = info.languageService.getSourceFile(filename);
prev.push({
@@ -812,11 +816,12 @@ namespace Harness.LanguageService {
};
}
function makeDefaultProxy(info: ts.server.PluginCreateInfo) {
function makeDefaultProxy(info: ts.server.PluginCreateInfo): ts.LanguageService {
// tslint:disable-next-line:no-null-keyword
const proxy = Object.create(/*prototype*/ null);
const langSvc: any = info.languageService;
for (const k of Object.keys(langSvc)) {
// tslint:disable-next-line only-arrow-functions
proxy[k] = function () {
return langSvc[k].apply(langSvc, arguments);
};
+16 -15
View File
@@ -14,19 +14,19 @@ interface FileInformation {
interface FindFileResult {
}
interface IOLogFile {
interface IoLogFile {
path: string;
codepage: number;
result?: FileInformation;
}
interface IOLog {
interface IoLog {
timestamp: string;
arguments: string[];
executingPath: string;
currentDirectory: string;
useCustomLibraryFile?: boolean;
filesRead: IOLogFile[];
filesRead: IoLogFile[];
filesWritten: {
path: string;
contents?: string;
@@ -80,16 +80,16 @@ interface IOLog {
interface PlaybackControl {
startReplayFromFile(logFileName: string): void;
startReplayFromString(logContents: string): void;
startReplayFromData(log: IOLog): void;
startReplayFromData(log: IoLog): void;
endReplay(): void;
startRecord(logFileName: string): void;
endRecord(): void;
}
namespace Playback {
let recordLog: IOLog = undefined;
let replayLog: IOLog = undefined;
let replayFilesRead: ts.Map<IOLogFile> | undefined = undefined;
let recordLog: IoLog = undefined;
let replayLog: IoLog = undefined;
let replayFilesRead: ts.Map<IoLogFile> | undefined = undefined;
let recordLogFileNameBase = "";
interface Memoized<T> {
@@ -110,11 +110,11 @@ namespace Playback {
return run;
}
export interface PlaybackIO extends Harness.IO, PlaybackControl { }
export interface PlaybackIO extends Harness.Io, PlaybackControl { }
export interface PlaybackSystem extends ts.System, PlaybackControl { }
function createEmptyLog(): IOLog {
function createEmptyLog(): IoLog {
return {
timestamp: (new Date()).toString(),
arguments: [],
@@ -134,7 +134,7 @@ namespace Playback {
};
}
export function newStyleLogIntoOldStyleLog(log: IOLog, host: ts.System | Harness.IO, baseName: string) {
export function newStyleLogIntoOldStyleLog(log: IoLog, host: ts.System | Harness.Io, baseName: string) {
for (const file of log.filesAppended) {
if (file.contentsPath) {
file.contents = host.readFile(ts.combinePaths(baseName, file.contentsPath));
@@ -167,7 +167,7 @@ namespace Playback {
return path;
}
export function oldStyleLogIntoNewStyleLog(log: IOLog, writeFile: typeof Harness.IO.writeFile, baseTestName: string) {
export function oldStyleLogIntoNewStyleLog(log: IoLog, writeFile: typeof Harness.IO.writeFile, baseTestName: string) {
if (log.filesAppended) {
for (const file of log.filesAppended) {
if (file.contents !== undefined) {
@@ -210,8 +210,8 @@ namespace Playback {
}
function initWrapper(wrapper: PlaybackSystem, underlying: ts.System): void;
function initWrapper(wrapper: PlaybackIO, underlying: Harness.IO): void;
function initWrapper(wrapper: PlaybackSystem | PlaybackIO, underlying: ts.System | Harness.IO): void {
function initWrapper(wrapper: PlaybackIO, underlying: Harness.Io): void;
function initWrapper(wrapper: PlaybackSystem | PlaybackIO, underlying: ts.System | Harness.Io): void {
ts.forEach(Object.keys(underlying), prop => {
(<any>wrapper)[prop] = (<any>underlying)[prop];
});
@@ -261,7 +261,7 @@ namespace Playback {
}
};
function generateTsconfig(newLog: IOLog): undefined | { compilerOptions: ts.CompilerOptions, files: string[] } {
function generateTsconfig(newLog: IoLog): undefined | { compilerOptions: ts.CompilerOptions, files: string[] } {
if (newLog.filesRead.some(file => /tsconfig.+json$/.test(file.path))) {
return;
}
@@ -366,6 +366,7 @@ namespace Playback {
function recordReplay<T extends Function>(original: T, underlying: any) {
function createWrapper(record: T, replay: T): T {
// tslint:disable-next-line only-arrow-functions
return <any>(function () {
if (replayLog !== undefined) {
return replay.apply(undefined, arguments);
@@ -426,7 +427,7 @@ namespace Playback {
// console.log("Swallowed write operation during replay: " + name);
}
export function wrapIO(underlying: Harness.IO): PlaybackIO {
export function wrapIO(underlying: Harness.Io): PlaybackIO {
const wrapper: PlaybackIO = <any>{};
initWrapper(wrapper, underlying);
+1 -2
View File
@@ -314,8 +314,7 @@ namespace Harness.Parallel.Host {
stats.failures = errorResults.length;
stats.tests = totalPassing + errorResults.length;
stats.duration = duration;
for (let j = 0; j < errorResults.length; j++) {
const failure = errorResults[j];
for (const failure of errorResults) {
failures.push(makeMochaTest(failure));
}
if (noColors) {
+5 -5
View File
@@ -140,12 +140,12 @@ class ProjectRunner extends RunnerBase {
// Clean up source map data that will be used in baselining
if (sourceMapData) {
for (let i = 0; i < sourceMapData.length; i++) {
for (let j = 0; j < sourceMapData[i].sourceMapSources.length; j++) {
sourceMapData[i].sourceMapSources[j] = cleanProjectUrl(sourceMapData[i].sourceMapSources[j]);
for (const data of sourceMapData) {
for (let j = 0; j < data.sourceMapSources.length; j++) {
data.sourceMapSources[j] = cleanProjectUrl(data.sourceMapSources[j]);
}
sourceMapData[i].jsSourceMappingURL = cleanProjectUrl(sourceMapData[i].jsSourceMappingURL);
sourceMapData[i].sourceMapSourceRoot = cleanProjectUrl(sourceMapData[i].sourceMapSourceRoot);
data.jsSourceMappingURL = cleanProjectUrl(data.jsSourceMappingURL);
data.sourceMapSourceRoot = cleanProjectUrl(data.sourceMapSourceRoot);
}
}
+15 -3
View File
@@ -18,6 +18,7 @@
/// <reference path="fourslashRunner.ts" />
/// <reference path="projectsRunner.ts" />
/// <reference path="rwcRunner.ts" />
/// <reference path="userRunner.ts" />
/// <reference path="harness.ts" />
/// <reference path="./parallel/shared.ts" />
@@ -26,8 +27,8 @@ let iterations = 1;
function runTests(runners: RunnerBase[]) {
for (let i = iterations; i > 0; i--) {
for (let j = 0; j < runners.length; j++) {
runners[j].initializeTests();
for (const runner of runners) {
runner.initializeTests();
}
}
}
@@ -59,6 +60,8 @@ function createRunner(kind: TestRunnerKind): RunnerBase {
return new RWCRunner();
case "test262":
return new Test262BaselineRunner();
case "user":
return new UserCodeRunner();
}
ts.Debug.fail(`Unknown runner kind ${kind}`);
}
@@ -175,6 +178,9 @@ function handleTestConfig() {
case "test262":
runners.push(new Test262BaselineRunner());
break;
case "user":
runners.push(new UserCodeRunner());
break;
}
}
}
@@ -196,6 +202,11 @@ function handleTestConfig() {
runners.push(new FourSlashRunner(FourSlashTestType.ShimsWithPreprocess));
runners.push(new FourSlashRunner(FourSlashTestType.Server));
// runners.push(new GeneratedFourslashRunner());
// CRON-only tests
if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser && process.env.TRAVIS_EVENT_TYPE === "cron") {
runners.push(new UserCodeRunner());
}
}
if (runUnitTests === undefined) {
runUnitTests = runners.length !== 1; // Don't run unit tests when running only one runner if unit tests were not explicitly asked for
@@ -215,8 +226,9 @@ function beginTests() {
}
}
let isWorker: boolean;
function startTestEnvironment() {
const isWorker = handleTestConfig();
isWorker = handleTestConfig();
if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser) {
if (isWorker) {
return Harness.Parallel.Worker.start();
+1 -1
View File
@@ -1,7 +1,7 @@
/// <reference path="harness.ts" />
type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262";
type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "user";
type CompilerTestKind = "conformance" | "compiler";
type FourslashTestKind = "fourslash" | "fourslash-shims" | "fourslash-shims-pp" | "fourslash-server";
+4 -6
View File
@@ -6,7 +6,7 @@
/* tslint:disable:no-null-keyword */
namespace RWC {
function runWithIOLog(ioLog: IOLog, fn: (oldIO: Harness.IO) => void) {
function runWithIOLog(ioLog: IoLog, fn: (oldIO: Harness.Io) => void) {
const oldIO = Harness.IO;
const wrappedIO = Playback.wrapIO(oldIO);
@@ -58,7 +58,7 @@ namespace RWC {
this.timeout(800000); // Allow long timeouts for RWC compilations
let opts: ts.ParsedCommandLine;
const ioLog: IOLog = Playback.newStyleLogIntoOldStyleLog(JSON.parse(Harness.IO.readFile(`internal/cases/rwc/${jsonPath}/test.json`)), Harness.IO, `internal/cases/rwc/${baseName}`);
const ioLog: IoLog = Playback.newStyleLogIntoOldStyleLog(JSON.parse(Harness.IO.readFile(`internal/cases/rwc/${jsonPath}/test.json`)), Harness.IO, `internal/cases/rwc/${baseName}`);
currentDirectory = ioLog.currentDirectory;
useCustomLibraryFile = ioLog.useCustomLibraryFile;
runWithIOLog(ioLog, () => {
@@ -245,10 +245,8 @@ class RWCRunner extends RunnerBase {
*/
public initializeTests(): void {
// Read in and evaluate the test list
const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles();
for (let i = 0; i < testList.length; i++) {
this.runTest(testList[i]);
for (const test of this.tests && this.tests.length ? this.tests : this.enumerateTestFiles()) {
this.runTest(test);
}
}
+3 -4
View File
@@ -386,9 +386,9 @@ namespace Harness.SourceMapRecorder {
if (currentSpan.decodeErrors) {
// If there are decode errors, write
for (let i = 0; i < currentSpan.decodeErrors.length; i++) {
for (const decodeError of currentSpan.decodeErrors) {
writeSourceMapIndent(prevEmittedCol, markerIds[index]);
sourceMapRecorder.WriteLine(currentSpan.decodeErrors[i]);
sourceMapRecorder.WriteLine(decodeError);
}
}
@@ -442,8 +442,7 @@ namespace Harness.SourceMapRecorder {
let prevSourceFile: ts.SourceFile;
SourceMapSpanWriter.initializeSourceMapSpanWriter(sourceMapRecorder, sourceMapData, jsFiles[i]);
for (let j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) {
const decodedSourceMapping = sourceMapData.sourceMapDecodedMappings[j];
for (const decodedSourceMapping of sourceMapData.sourceMapDecodedMappings) {
const currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]);
if (currentSourceFile !== prevSourceFile) {
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);
+1
View File
@@ -92,6 +92,7 @@
"projectsRunner.ts",
"loggedIO.ts",
"rwcRunner.ts",
"userRunner.ts",
"test262Runner.ts",
"./parallel/shared.ts",
"./parallel/host.ts",
+1 -1
View File
@@ -52,7 +52,7 @@ class TypeWriterWalker {
}
private *visitNode(node: ts.Node, isSymbolWalk: boolean): IterableIterator<TypeWriterResult> {
if (ts.isPartOfExpression(node) || node.kind === ts.SyntaxKind.Identifier) {
if (ts.isExpressionNode(node) || node.kind === ts.SyntaxKind.Identifier) {
const result = this.writeTypeOrSymbol(node, isSymbolWalk);
if (result) {
yield result;
+3 -3
View File
@@ -591,7 +591,7 @@ module m3 { }\
const index = 0;
const newTextAndChange = withInsert(oldText, index, "declare ");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 3);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
});
it("Insert function above arrow function with comment", () => {
@@ -674,7 +674,7 @@ module m3 { }\
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withInsert(oldText, 0, "{");
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
});
it("Removing block around function declarations", () => {
@@ -683,7 +683,7 @@ module m3 { }\
const oldText = ScriptSnapshot.fromString(source);
const newTextAndChange = withDelete(oldText, 0, "{".length);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
});
it("Moving methods from class to object literal", () => {
+29 -29
View File
@@ -6,7 +6,7 @@ interface ClassificationEntry {
position?: number;
}
describe("Colorization", function () {
describe("Colorization", () => {
// Use the shim adapter to ensure test coverage of the shim layer for the classifier
const languageServiceAdapter = new Harness.LanguageService.ShimLanguageServiceAdapter(/*preprocessToResolve*/ false);
const classifier = languageServiceAdapter.getClassifier();
@@ -55,8 +55,8 @@ describe("Colorization", function () {
}
}
describe("test getClassifications", function () {
it("Returns correct token classes", function () {
describe("test getClassifications", () => {
it("Returns correct token classes", () => {
testLexicalClassification("var x: string = \"foo\"; //Hello",
ts.EndOfLineState.None,
keyword("var"),
@@ -70,7 +70,7 @@ describe("Colorization", function () {
punctuation(";"));
});
it("correctly classifies a comment after a divide operator", function () {
it("correctly classifies a comment after a divide operator", () => {
testLexicalClassification("1 / 2 // comment",
ts.EndOfLineState.None,
numberLiteral("1"),
@@ -80,7 +80,7 @@ describe("Colorization", function () {
comment("// comment"));
});
it("correctly classifies a literal after a divide operator", function () {
it("correctly classifies a literal after a divide operator", () => {
testLexicalClassification("1 / 2, 3 / 4",
ts.EndOfLineState.None,
numberLiteral("1"),
@@ -92,131 +92,131 @@ describe("Colorization", function () {
operator(","));
});
it("correctly classifies a multi-line string with one backslash", function () {
it("correctly classifies a multi-line string with one backslash", () => {
testLexicalClassification("'line1\\",
ts.EndOfLineState.None,
stringLiteral("'line1\\"),
finalEndOfLineState(ts.EndOfLineState.InSingleQuoteStringLiteral));
});
it("correctly classifies a multi-line string with three backslashes", function () {
it("correctly classifies a multi-line string with three backslashes", () => {
testLexicalClassification("'line1\\\\\\",
ts.EndOfLineState.None,
stringLiteral("'line1\\\\\\"),
finalEndOfLineState(ts.EndOfLineState.InSingleQuoteStringLiteral));
});
it("correctly classifies an unterminated single-line string with no backslashes", function () {
it("correctly classifies an unterminated single-line string with no backslashes", () => {
testLexicalClassification("'line1",
ts.EndOfLineState.None,
stringLiteral("'line1"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies an unterminated single-line string with two backslashes", function () {
it("correctly classifies an unterminated single-line string with two backslashes", () => {
testLexicalClassification("'line1\\\\",
ts.EndOfLineState.None,
stringLiteral("'line1\\\\"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies an unterminated single-line string with four backslashes", function () {
it("correctly classifies an unterminated single-line string with four backslashes", () => {
testLexicalClassification("'line1\\\\\\\\",
ts.EndOfLineState.None,
stringLiteral("'line1\\\\\\\\"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies the continuing line of a multi-line string ending in one backslash", function () {
it("correctly classifies the continuing line of a multi-line string ending in one backslash", () => {
testLexicalClassification("\\",
ts.EndOfLineState.InDoubleQuoteStringLiteral,
stringLiteral("\\"),
finalEndOfLineState(ts.EndOfLineState.InDoubleQuoteStringLiteral));
});
it("correctly classifies the continuing line of a multi-line string ending in three backslashes", function () {
it("correctly classifies the continuing line of a multi-line string ending in three backslashes", () => {
testLexicalClassification("\\",
ts.EndOfLineState.InDoubleQuoteStringLiteral,
stringLiteral("\\"),
finalEndOfLineState(ts.EndOfLineState.InDoubleQuoteStringLiteral));
});
it("correctly classifies the last line of an unterminated multi-line string ending in no backslashes", function () {
it("correctly classifies the last line of an unterminated multi-line string ending in no backslashes", () => {
testLexicalClassification(" ",
ts.EndOfLineState.InDoubleQuoteStringLiteral,
stringLiteral(" "),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies the last line of an unterminated multi-line string ending in two backslashes", function () {
it("correctly classifies the last line of an unterminated multi-line string ending in two backslashes", () => {
testLexicalClassification("\\\\",
ts.EndOfLineState.InDoubleQuoteStringLiteral,
stringLiteral("\\\\"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies the last line of an unterminated multi-line string ending in four backslashes", function () {
it("correctly classifies the last line of an unterminated multi-line string ending in four backslashes", () => {
testLexicalClassification("\\\\\\\\",
ts.EndOfLineState.InDoubleQuoteStringLiteral,
stringLiteral("\\\\\\\\"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies the last line of a multi-line string", function () {
it("correctly classifies the last line of a multi-line string", () => {
testLexicalClassification("'",
ts.EndOfLineState.InSingleQuoteStringLiteral,
stringLiteral("'"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies an unterminated multiline comment", function () {
it("correctly classifies an unterminated multiline comment", () => {
testLexicalClassification("/*",
ts.EndOfLineState.None,
comment("/*"),
finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia));
});
it("correctly classifies the termination of a multiline comment", function () {
it("correctly classifies the termination of a multiline comment", () => {
testLexicalClassification(" */ ",
ts.EndOfLineState.InMultiLineCommentTrivia,
comment(" */"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("correctly classifies the continuation of a multiline comment", function () {
it("correctly classifies the continuation of a multiline comment", () => {
testLexicalClassification("LOREM IPSUM DOLOR ",
ts.EndOfLineState.InMultiLineCommentTrivia,
comment("LOREM IPSUM DOLOR "),
finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia));
});
it("correctly classifies an unterminated multiline comment on a line ending in '/*/'", function () {
it("correctly classifies an unterminated multiline comment on a line ending in '/*/'", () => {
testLexicalClassification(" /*/",
ts.EndOfLineState.None,
comment("/*/"),
finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia));
});
it("correctly classifies an unterminated multiline comment with trailing space", function () {
it("correctly classifies an unterminated multiline comment with trailing space", () => {
testLexicalClassification("/* ",
ts.EndOfLineState.None,
comment("/* "),
finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia));
});
it("correctly classifies a keyword after a dot", function () {
it("correctly classifies a keyword after a dot", () => {
testLexicalClassification("a.var",
ts.EndOfLineState.None,
identifier("var"));
});
it("correctly classifies a string literal after a dot", function () {
it("correctly classifies a string literal after a dot", () => {
testLexicalClassification("a.\"var\"",
ts.EndOfLineState.None,
stringLiteral("\"var\""));
});
it("correctly classifies a keyword after a dot separated by comment trivia", function () {
it("correctly classifies a keyword after a dot separated by comment trivia", () => {
testLexicalClassification("a./*hello world*/ var",
ts.EndOfLineState.None,
identifier("a"),
@@ -225,21 +225,21 @@ describe("Colorization", function () {
identifier("var"));
});
it("classifies a property access with whitespace around the dot", function () {
it("classifies a property access with whitespace around the dot", () => {
testLexicalClassification(" x .\tfoo ()",
ts.EndOfLineState.None,
identifier("x"),
identifier("foo"));
});
it("classifies a keyword after a dot on previous line", function () {
it("classifies a keyword after a dot on previous line", () => {
testLexicalClassification("var",
ts.EndOfLineState.None,
keyword("var"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("classifies multiple keywords properly", function () {
it("classifies multiple keywords properly", () => {
testLexicalClassification("public static",
ts.EndOfLineState.None,
keyword("public"),
@@ -353,7 +353,7 @@ describe("Colorization", function () {
}
});
it("classifies partially written generics correctly.", function () {
it("classifies partially written generics correctly.", () => {
testLexicalClassification("Foo<number",
ts.EndOfLineState.None,
identifier("Foo"),
@@ -466,7 +466,7 @@ class D { }\r\n\
finalEndOfLineState(ts.EndOfLineState.None));
});
it("'of' keyword", function () {
it("'of' keyword", () => {
testLexicalClassification("for (var of of of) { }",
ts.EndOfLineState.None,
keyword("for"),
@@ -1,7 +1,7 @@
/// <reference path="..\..\..\services\patternMatcher.ts" />
describe("PatternMatcher", function () {
describe("BreakIntoCharacterSpans", function () {
describe("PatternMatcher", () => {
describe("BreakIntoCharacterSpans", () => {
it("EmptyIdentifier", () => {
verifyBreakIntoCharacterSpans("");
});
@@ -55,7 +55,7 @@ describe("PatternMatcher", function () {
});
});
describe("BreakIntoWordSpans", function () {
describe("BreakIntoWordSpans", () => {
it("VarbatimIdentifier", () => {
verifyBreakIntoWordSpans("@int:", "int");
});
@@ -1,6 +1,6 @@
/// <reference path="..\..\harnessLanguageService.ts" />
describe("PreProcessFile:", function () {
describe("PreProcessFile:", () => {
function test(sourceText: string, readImportFile: boolean, detectJavaScriptImports: boolean, expectedPreProcess: ts.PreProcessedFileInfo): void {
const resultPreProcess = ts.preProcessFile(sourceText, readImportFile, detectJavaScriptImports);
@@ -31,8 +31,8 @@ describe("PreProcessFile:", function () {
}
}
describe("Test preProcessFiles,", function () {
it("Correctly return referenced files from triple slash", function () {
describe("Test preProcessFiles,", () => {
it("Correctly return referenced files from triple slash", () => {
test("///<reference path = \"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\"/>" + "\n" + "///<reference path=\"refFile3.ts\" />" + "\n" + "///<reference path= \"..\\refFile4d.ts\" />",
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
@@ -46,7 +46,7 @@ describe("PreProcessFile:", function () {
});
}),
it("Do not return reference path because of invalid triple-slash syntax", function () {
it("Do not return reference path because of invalid triple-slash syntax", () => {
test("///<reference path\"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\">" + "\n" + "///<referencepath=\"refFile3.ts\" />" + "\n" + "///<reference pat= \"refFile4d.ts\" />",
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
@@ -59,7 +59,7 @@ describe("PreProcessFile:", function () {
});
}),
it("Correctly return imported files", function () {
it("Correctly return imported files", () => {
test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");",
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
@@ -73,7 +73,7 @@ describe("PreProcessFile:", function () {
});
}),
it("Do not return imported files if readImportFiles argument is false", function () {
it("Do not return imported files if readImportFiles argument is false", () => {
test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");",
/*readImportFile*/ false,
/*detectJavaScriptImports*/ false,
@@ -86,7 +86,7 @@ describe("PreProcessFile:", function () {
});
}),
it("Do not return import path because of invalid import syntax", function () {
it("Do not return import path because of invalid import syntax", () => {
test("import i1 require(\"r1.ts\"); import = require(\"r2.ts\") import i3= require(\"r3.ts\"); import i5",
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
@@ -99,7 +99,7 @@ describe("PreProcessFile:", function () {
});
}),
it("Correctly return referenced files and import files", function () {
it("Correctly return referenced files and import files", () => {
test("///<reference path=\"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\"/>" + "\n" + "import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\");",
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
@@ -112,7 +112,7 @@ describe("PreProcessFile:", function () {
});
}),
it("Correctly return referenced files and import files even with some invalid syntax", function () {
it("Correctly return referenced files and import files even with some invalid syntax", () => {
test("///<reference path=\"refFile1.ts\" />" + "\n" + "///<reference path \"refFile2.ts\"/>" + "\n" + "import i1 = require(\"r1.ts\"); import = require(\"r2.ts\"); import i2 = require(\"r3.ts\");",
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
@@ -125,7 +125,7 @@ describe("PreProcessFile:", function () {
});
});
it("Correctly return ES6 imports", function () {
it("Correctly return ES6 imports", () => {
test("import * as ns from \"m1\";" + "\n" +
"import def, * as ns from \"m2\";" + "\n" +
"import def from \"m3\";" + "\n" +
@@ -152,7 +152,7 @@ describe("PreProcessFile:", function () {
});
});
it("Correctly return ES6 exports", function () {
it("Correctly return ES6 exports", () => {
test("export * from \"m1\";" + "\n" +
"export {a} from \"m2\";" + "\n" +
"export {a as A} from \"m3\";" + "\n" +
@@ -192,7 +192,7 @@ describe("PreProcessFile:", function () {
});
});
it("Correctly handles export import declarations", function () {
it("Correctly handles export import declarations", () => {
test("export import a = require(\"m1\");",
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
@@ -206,7 +206,7 @@ describe("PreProcessFile:", function () {
isLibFile: false
});
});
it("Correctly handles export require calls in JavaScript files", function () {
it("Correctly handles export require calls in JavaScript files", () => {
test(`
export import a = require("m1");
var x = require('m2');
@@ -228,7 +228,7 @@ describe("PreProcessFile:", function () {
isLibFile: false
});
});
it("Correctly handles dependency lists in define([deplist]) calls in JavaScript files", function () {
it("Correctly handles dependency lists in define([deplist]) calls in JavaScript files", () => {
test(`
define(["mod1", "mod2"], (m1, m2) => {
});
@@ -246,7 +246,7 @@ describe("PreProcessFile:", function () {
isLibFile: false
});
});
it("Correctly handles dependency lists in define(modName, [deplist]) calls in JavaScript files", function () {
it("Correctly handles dependency lists in define(modName, [deplist]) calls in JavaScript files", () => {
test(`
define("mod", ["mod1", "mod2"], (m1, m2) => {
});
+4 -2
View File
@@ -128,7 +128,7 @@ namespace ts.server {
body: undefined
});
});
it ("should handle literal types in request", () => {
it("should handle literal types in request", () => {
const configureRequest: protocol.ConfigureRequest = {
command: CommandNames.Configure,
seq: 0,
@@ -186,6 +186,8 @@ namespace ts.server {
CommandNames.Configure,
CommandNames.Definition,
CommandNames.DefinitionFull,
CommandNames.DefinitionAndBoundSpan,
CommandNames.DefinitionAndBoundSpanFull,
CommandNames.Implementation,
CommandNames.ImplementationFull,
CommandNames.Exit,
@@ -352,7 +354,7 @@ namespace ts.server {
session.addProtocolHandler(command, () => resp);
expect(() => session.addProtocolHandler(command, () => resp))
.to.throw(`Protocol handler already exists for command "${command}"`);
.to.throw(`Protocol handler already exists for command "${command}"`);
});
});
+23
View File
@@ -20,6 +20,15 @@ namespace ts {
};
return (file: ts.SourceFile) => file;
}
function replaceNumberWith2(context: ts.TransformationContext) {
function visitor(node: Node): Node {
if (isNumericLiteral(node)) {
return createNumericLiteral("2");
}
return visitEachChild(node, visitor, context);
}
return (file: ts.SourceFile) => visitNode(file, visitor);
}
function replaceIdentifiersNamedOldNameWithNewName(context: ts.TransformationContext) {
const previousOnSubstituteNode = context.onSubstituteNode;
@@ -101,6 +110,20 @@ namespace ts {
}).outputText;
});
testBaseline("transformTypesInExportDefault", () => {
return ts.transpileModule(`
export default (foo: string) => { return 1; }
`, {
transformers: {
before: [replaceNumberWith2],
},
compilerOptions: {
target: ts.ScriptTarget.ESNext,
newLine: NewLineKind.CarriageReturnLineFeed,
}
}).outputText;
});
testBaseline("synthesizedClassAndNamespaceCombination", () => {
return ts.transpileModule("", {
transformers: {
+1 -1
View File
@@ -1988,7 +1988,7 @@ declare module "fs" {
checkProgramActualFiles(watch(), mapDefined(files, f => f === configFile ? undefined : f.path));
file1.content = "var zz30 = 100;";
host.reloadFS(files, /*invokeDirectoryWatcherInsteadOfFileChanged*/ true);
host.reloadFS(files, { invokeDirectoryWatcherInsteadOfFileChanged: true });
host.runQueuedTimeoutCallbacks();
checkProgramActualFiles(watch(), mapDefined(files, f => f === configFile ? undefined : f.path));
+117 -6
View File
@@ -1248,13 +1248,13 @@ namespace ts.projectSystem {
service.checkNumberOfProjects({ externalProjects: 1 });
checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]);
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2);
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false });
// should contain completions for string
assert.isTrue(completions1.entries.some(e => e.name === "charAt"), "should contain 'charAt'");
assert.isFalse(completions1.entries.some(e => e.name === "toExponential"), "should not contain 'toExponential'");
service.closeClientFile(f2.path);
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2);
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false });
// should contain completions for string
assert.isFalse(completions2.entries.some(e => e.name === "charAt"), "should not contain 'charAt'");
assert.isTrue(completions2.entries.some(e => e.name === "toExponential"), "should contain 'toExponential'");
@@ -1280,11 +1280,11 @@ namespace ts.projectSystem {
service.checkNumberOfProjects({ externalProjects: 1 });
checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]);
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0);
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false });
assert.isTrue(completions1.entries.some(e => e.name === "somelongname"), "should contain 'somelongname'");
service.closeClientFile(f2.path);
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0);
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false });
assert.isFalse(completions2.entries.some(e => e.name === "somelongname"), "should not contain 'somelongname'");
const sf2 = service.externalProjects[0].getLanguageService().getProgram().getSourceFile(f2.path);
assert.equal(sf2.text, "");
@@ -1845,7 +1845,7 @@ namespace ts.projectSystem {
// Check identifiers defined in HTML content are available in .ts file
const project = configuredProjectAt(projectService, 0);
let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1);
let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1, { includeExternalModuleExports: false });
assert(completions && completions.entries[0].name === "hello", `expected entry hello to be in completion list`);
// Close HTML file
@@ -1859,7 +1859,7 @@ namespace ts.projectSystem {
checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]);
// Check identifiers defined in HTML content are not available in .ts file
completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5);
completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5, { includeExternalModuleExports: false });
assert(completions && completions.entries[0].name !== "hello", `unexpected hello entry in completion list`);
});
@@ -3445,6 +3445,117 @@ namespace ts.projectSystem {
diags = session.executeCommand(getErrRequest).response as server.protocol.Diagnostic[];
verifyNoDiagnostics(diags);
});
function assertEvent(actualOutput: string, expectedEvent: protocol.Event, host: TestServerHost) {
assert.equal(actualOutput, server.formatMessage(expectedEvent, nullLogger, Utils.byteLength, host.newLine));
}
function checkErrorMessage(host: TestServerHost, eventName: "syntaxDiag" | "semanticDiag", diagnostics: protocol.DiagnosticEventBody) {
const outputs = host.getOutput();
assert.isTrue(outputs.length >= 1, outputs.toString());
const event: protocol.Event = {
seq: 0,
type: "event",
event: eventName,
body: diagnostics
};
assertEvent(outputs[0], event, host);
}
function checkCompleteEvent(host: TestServerHost, numberOfCurrentEvents: number, expectedSequenceId: number) {
const outputs = host.getOutput();
assert.equal(outputs.length, numberOfCurrentEvents, outputs.toString());
const event: protocol.RequestCompletedEvent = {
seq: 0,
type: "event",
event: "requestCompleted",
body: {
request_seq: expectedSequenceId
}
};
assertEvent(outputs[numberOfCurrentEvents - 1], event, host);
}
function checkProjectUpdatedInBackgroundEvent(host: TestServerHost, openFiles: string[]) {
const outputs = host.getOutput();
assert.equal(outputs.length, 1, outputs.toString());
const event: protocol.ProjectsUpdatedInBackgroundEvent = {
seq: 0,
type: "event",
event: "projectsUpdatedInBackground",
body: {
openFiles
}
};
assertEvent(outputs[0], event, host);
}
it("npm install @types works", () => {
const folderPath = "/a/b/projects/temp";
const file1: FileOrFolder = {
path: `${folderPath}/a.ts`,
content: 'import f = require("pad")'
};
const files = [file1, libFile];
const host = createServerHost(files);
const session = createSession(host, { canUseEvents: true });
const service = session.getProjectService();
session.executeCommandSeq<protocol.OpenRequest>({
command: server.CommandNames.Open,
arguments: {
file: file1.path,
fileContent: file1.content,
scriptKindName: "TS",
projectRootPath: folderPath
}
});
checkNumberOfProjects(service, { inferredProjects: 1 });
host.clearOutput();
const expectedSequenceId = session.getNextSeq();
session.executeCommandSeq<protocol.GeterrRequest>({
command: server.CommandNames.Geterr,
arguments: {
delay: 0,
files: [file1.path]
}
});
host.checkTimeoutQueueLengthAndRun(1);
checkErrorMessage(host, "syntaxDiag", { file: file1.path, diagnostics: [] });
host.clearOutput();
host.runQueuedImmediateCallbacks();
const moduleNotFound = Diagnostics.Cannot_find_module_0;
const startOffset = file1.content.indexOf('"') + 1;
checkErrorMessage(host, "semanticDiag", {
file: file1.path, diagnostics: [{
start: { line: 1, offset: startOffset },
end: { line: 1, offset: startOffset + '"pad"'.length },
text: formatStringFromArgs(moduleNotFound.message, ["pad"]),
code: moduleNotFound.code,
category: DiagnosticCategory[moduleNotFound.category].toLowerCase()
}]
});
checkCompleteEvent(host, 2, expectedSequenceId);
host.clearOutput();
const padIndex: FileOrFolder = {
path: `${folderPath}/node_modules/@types/pad/index.d.ts`,
content: "export = pad;declare function pad(length: number, text: string, char ?: string): string;"
};
files.push(padIndex);
host.reloadFS(files, { ignoreWatchInvokedWithTriggerAsFileCreate: true });
host.runQueuedTimeoutCallbacks();
checkProjectUpdatedInBackgroundEvent(host, [file1.path]);
host.clearOutput();
host.runQueuedTimeoutCallbacks();
checkErrorMessage(host, "syntaxDiag", { file: file1.path, diagnostics: [] });
host.clearOutput();
host.runQueuedImmediateCallbacks();
checkErrorMessage(host, "semanticDiag", { file: file1.path, diagnostics: [] });
});
});
describe("Configure file diagnostics events", () => {
+51
View File
@@ -0,0 +1,51 @@
/// <reference path="harness.ts"/>
/// <reference path="runnerbase.ts" />
class UserCodeRunner extends RunnerBase {
private static readonly testDir = "tests/cases/user/";
public enumerateTestFiles() {
return Harness.IO.getDirectories(UserCodeRunner.testDir);
}
public kind(): TestRunnerKind {
return "user";
}
/** Setup the runner's tests so that they are ready to be executed by the harness
* The first test should be a describe/it block that sets up the harness's compiler instance appropriately
*/
public initializeTests(): void {
// Read in and evaluate the test list
const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles();
describe(`${this.kind()} code samples`, () => {
for (const test of testList) {
this.runTest(test);
}
});
}
private runTest(directoryName: string) {
describe(directoryName, () => {
const cp = require("child_process");
const path = require("path");
it("should build successfully", () => {
const cwd = path.join(__dirname, "../../", UserCodeRunner.testDir, directoryName);
const timeout = 600000; // 10 minutes
const stdio = isWorker ? "pipe" : "inherit";
const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio });
if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`);
Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => {
const result = cp.spawnSync(`node`, ["../../../../built/local/tsc.js"], { cwd, timeout, shell: true });
return `Exit Code: ${result.status}
Standard output:
${result.stdout.toString().replace(/\r\n/g, "\n")}
Standard error:
${result.stderr.toString().replace(/\r\n/g, "\n")}`;
});
});
});
}
}
+14 -6
View File
@@ -226,6 +226,11 @@ interface Array<T> {}`
directoryName: string;
}
export interface ReloadWatchInvokeOptions {
invokeDirectoryWatcherInsteadOfFileChanged: boolean;
ignoreWatchInvokedWithTriggerAsFileCreate: boolean;
}
export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost {
args: string[] = [];
@@ -270,7 +275,7 @@ interface Array<T> {}`
return s;
}
reloadFS(fileOrFolderList: ReadonlyArray<FileOrFolder>, invokeDirectoryWatcherInsteadOfFileChanged?: boolean) {
reloadFS(fileOrFolderList: ReadonlyArray<FileOrFolder>, options?: Partial<ReloadWatchInvokeOptions>) {
const mapNewLeaves = createMap<true>();
const isNewFs = this.fs.size === 0;
fileOrFolderList = fileOrFolderList.concat(this.withSafeList ? safeList : []);
@@ -291,7 +296,7 @@ interface Array<T> {}`
// Update file
if (currentEntry.content !== fileOrDirectory.content) {
currentEntry.content = fileOrDirectory.content;
if (invokeDirectoryWatcherInsteadOfFileChanged) {
if (options && options.invokeDirectoryWatcherInsteadOfFileChanged) {
this.invokeDirectoryWatcher(getDirectoryPath(currentEntry.fullPath), currentEntry.fullPath);
}
else {
@@ -314,7 +319,7 @@ interface Array<T> {}`
}
}
else {
this.ensureFileOrFolder(fileOrDirectory);
this.ensureFileOrFolder(fileOrDirectory, options && options.ignoreWatchInvokedWithTriggerAsFileCreate);
}
}
@@ -331,12 +336,12 @@ interface Array<T> {}`
}
}
ensureFileOrFolder(fileOrDirectory: FileOrFolder) {
ensureFileOrFolder(fileOrDirectory: FileOrFolder, ignoreWatchInvokedWithTriggerAsFileCreate?: boolean) {
if (isString(fileOrDirectory.content)) {
const file = this.toFile(fileOrDirectory);
Debug.assert(!this.fs.get(file.path));
const baseFolder = this.ensureFolder(getDirectoryPath(file.fullPath));
this.addFileOrFolderInFolder(baseFolder, file);
this.addFileOrFolderInFolder(baseFolder, file, ignoreWatchInvokedWithTriggerAsFileCreate);
}
else {
const fullPath = getNormalizedAbsolutePath(fileOrDirectory.path, this.currentDirectory);
@@ -365,10 +370,13 @@ interface Array<T> {}`
return folder;
}
private addFileOrFolderInFolder(folder: Folder, fileOrDirectory: File | Folder) {
private addFileOrFolderInFolder(folder: Folder, fileOrDirectory: File | Folder, ignoreWatch?: boolean) {
folder.entries.push(fileOrDirectory);
this.fs.set(fileOrDirectory.path, fileOrDirectory);
if (ignoreWatch) {
return;
}
if (isFile(fileOrDirectory)) {
this.invokeFileWatcher(fileOrDirectory.fullPath, FileWatcherEventKind.Created);
}
+779 -776
View File
File diff suppressed because it is too large Load Diff
+7 -1
View File
@@ -50,10 +50,16 @@ interface ArrayConstructor {
/**
* Creates an array from an array-like object.
* @param arrayLike An array-like object to convert to an array.
*/
from<T>(arrayLike: ArrayLike<T>): T[];
/**
* Creates an array from an iterable object.
* @param arrayLike An array-like object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from<T, U = T>(arrayLike: ArrayLike<T>, mapfn?: (v: T, k: number) => U, thisArg?: any): U[];
from<T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[];
/**
* Returns a new array from a set of elements.
+7 -1
View File
@@ -48,13 +48,19 @@ interface Array<T> {
}
interface ArrayConstructor {
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
*/
from<T>(iterable: Iterable<T>): T[];
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from<T, U = T>(iterable: Iterable<T>, mapfn?: (v: T, k: number) => U, thisArg?: any): U[];
from<T, U>(iterable: Iterable<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[];
}
interface ReadonlyArray<T> {
+91 -87
View File
@@ -37,7 +37,7 @@ interface IDBIndexParameters {
interface IDBObjectStoreParameters {
autoIncrement?: boolean;
keyPath?: IDBKeyPath | null;
keyPath?: string | string[];
}
interface KeyAlgorithm {
@@ -74,7 +74,7 @@ interface RequestInit {
body?: any;
cache?: RequestCache;
credentials?: RequestCredentials;
headers?: Headers | string[][];
headers?: HeadersInit;
integrity?: string;
keepalive?: boolean;
method?: string;
@@ -86,7 +86,7 @@ interface RequestInit {
}
interface ResponseInit {
headers?: Headers | string[][];
headers?: HeadersInit;
status?: number;
statusText?: string;
}
@@ -441,10 +441,10 @@ interface FileReader extends EventTarget, MSBaseReader {
readAsBinaryString(blob: Blob): void;
readAsDataURL(blob: Blob): void;
readAsText(blob: Blob, encoding?: string): void;
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var FileReader: {
@@ -472,7 +472,7 @@ interface Headers {
declare var Headers: {
prototype: Headers;
new(init?: Headers | string[][] | object): Headers;
new(init?: HeadersInit): Headers;
};
interface IDBCursor {
@@ -524,11 +524,12 @@ interface IDBDatabase extends EventTarget {
createObjectStore(name: string, optionalParameters?: IDBObjectStoreParameters): IDBObjectStore;
deleteObjectStore(name: string): void;
transaction(storeNames: string | string[], mode?: IDBTransactionMode): IDBTransaction;
addEventListener(type: "versionchange", listener: (ev: IDBVersionChangeEvent) => any, useCapture?: boolean): void;
addEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener(type: "versionchange", listener: (this: IDBDatabase, ev: IDBVersionChangeEvent) => any, options?: boolean | AddEventListenerOptions): void;
removeEventListener(type: "versionchange", listener: (this: IDBDatabase, ev: IDBVersionChangeEvent) => any, options?: boolean | EventListenerOptions): void;
addEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var IDBDatabase: {
@@ -612,10 +613,10 @@ interface IDBOpenDBRequestEventMap extends IDBRequestEventMap {
interface IDBOpenDBRequest extends IDBRequest {
onblocked: (this: IDBOpenDBRequest, ev: Event) => any;
onupgradeneeded: (this: IDBOpenDBRequest, ev: IDBVersionChangeEvent) => any;
addEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var IDBOpenDBRequest: {
@@ -636,10 +637,10 @@ interface IDBRequest extends EventTarget {
readonly result: any;
source: IDBObjectStore | IDBIndex | IDBCursor;
readonly transaction: IDBTransaction;
addEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var IDBRequest: {
@@ -665,10 +666,10 @@ interface IDBTransaction extends EventTarget {
readonly READ_ONLY: string;
readonly READ_WRITE: string;
readonly VERSION_CHANGE: string;
addEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var IDBTransaction: {
@@ -733,10 +734,10 @@ interface MessagePort extends EventTarget {
close(): void;
postMessage(message?: any, transfer?: any[]): void;
start(): void;
addEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var MessagePort: {
@@ -764,10 +765,10 @@ interface Notification extends EventTarget {
readonly tag: string;
readonly title: string;
close(): void;
addEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var Notification: {
@@ -994,10 +995,10 @@ interface ServiceWorker extends EventTarget, AbstractWorker {
readonly scriptURL: USVString;
readonly state: ServiceWorkerState;
postMessage(message: any, transfer?: any[]): void;
addEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var ServiceWorker: {
@@ -1021,10 +1022,10 @@ interface ServiceWorkerRegistration extends EventTarget {
showNotification(title: string, options?: NotificationOptions): Promise<void>;
unregister(): Promise<boolean>;
update(): Promise<void>;
addEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var ServiceWorkerRegistration: {
@@ -1089,10 +1090,10 @@ interface WebSocket extends EventTarget {
readonly CLOSING: number;
readonly CONNECTING: number;
readonly OPEN: number;
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var WebSocket: {
@@ -1112,10 +1113,10 @@ interface Worker extends EventTarget, AbstractWorker {
onmessage: (this: Worker, ev: MessageEvent) => any;
postMessage(message: any, transfer?: any[]): void;
terminate(): void;
addEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var Worker: {
@@ -1155,10 +1156,10 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
readonly LOADING: number;
readonly OPENED: number;
readonly UNSENT: number;
addEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var XMLHttpRequest: {
@@ -1172,10 +1173,10 @@ declare var XMLHttpRequest: {
};
interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget {
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var XMLHttpRequestUpload: {
@@ -1189,10 +1190,10 @@ interface AbstractWorkerEventMap {
interface AbstractWorker {
onerror: (this: AbstractWorker, ev: ErrorEvent) => any;
addEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
interface Body {
@@ -1229,10 +1230,10 @@ interface MSBaseReader {
readonly DONE: number;
readonly EMPTY: number;
readonly LOADING: number;
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
interface NavigatorBeacon {
@@ -1286,10 +1287,10 @@ interface XMLHttpRequestEventTarget {
onloadstart: (this: XMLHttpRequest, ev: Event) => any;
onprogress: (this: XMLHttpRequest, ev: ProgressEvent) => any;
ontimeout: (this: XMLHttpRequest, ev: ProgressEvent) => any;
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
interface Client {
@@ -1324,10 +1325,10 @@ interface DedicatedWorkerGlobalScope extends WorkerGlobalScope {
onmessage: (this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any;
close(): void;
postMessage(message: any, transfer?: any[]): void;
addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var DedicatedWorkerGlobalScope: {
@@ -1437,10 +1438,10 @@ interface ServiceWorkerGlobalScope extends WorkerGlobalScope {
onsync: (this: ServiceWorkerGlobalScope, ev: SyncEvent) => any;
readonly registration: ServiceWorkerRegistration;
skipWaiting(): Promise<void>;
addEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var ServiceWorkerGlobalScope: {
@@ -1484,10 +1485,10 @@ interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, Glo
msWriteProfilerMark(profilerMarkName: string): void;
createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
addEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
removeEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var WorkerGlobalScope: {
@@ -1544,8 +1545,10 @@ interface BroadcastChannel extends EventTarget {
onmessageerror: (ev: MessageEvent) => any;
close(): void;
postMessage(message: any): void;
addEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
addEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare var BroadcastChannel: {
@@ -1875,10 +1878,10 @@ declare function btoa(rawString: string): string;
declare var console: Console;
declare function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
declare function dispatchEvent(evt: Event): boolean;
declare function addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
declare function removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
declare function addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
declare function removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
type AlgorithmIdentifier = string | Algorithm;
type BodyInit = any;
type IDBKeyPath = string;
@@ -1887,6 +1890,7 @@ type USVString = string;
type IDBValidKey = number | string | Date | IDBArrayKey;
type BufferSource = ArrayBuffer | ArrayBufferView;
type FormDataEntryValue = string | File;
type HeadersInit = string[][] | { [key: string]: string };
type IDBCursorDirection = "next" | "nextunique" | "prev" | "prevunique";
type IDBRequestReadyState = "pending" | "done";
type IDBTransactionMode = "readonly" | "readwrite" | "versionchange";
@@ -2961,6 +2961,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Expected_corresponding_closing_tag_for_JSX_fragment_17015" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Expected corresponding closing tag for JSX fragment.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Expected_type_of_0_field_in_package_json_to_be_string_got_1_6105" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Expected type of '{0}' field in 'package.json' to be 'string', got '{1}'.]]></Val>
@@ -3184,7 +3190,7 @@
<Str Cat="Text">
<Val><![CDATA[Extract to {0} in {1}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Nach {0} in {1} extrahieren]]></Val>
<Val><![CDATA[Als {0} nach {1} extrahieren]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -3193,7 +3199,7 @@
<Str Cat="Text">
<Val><![CDATA[Extract to {0} in {1} scope]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Nach {0} in {1}-Bereich extrahieren]]></Val>
<Val><![CDATA[Als {0} in {1}-Bereich extrahieren]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -3202,7 +3208,7 @@
<Str Cat="Text">
<Val><![CDATA[Extract to {0} in enclosing scope]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Nach {0} in einschließenden Bereich extrahieren]]></Val>
<Val><![CDATA[Als {0} in einschließenden Bereich extrahieren]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -4200,6 +4206,18 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";JSX_fragment_has_no_corresponding_closing_tag_17014" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[JSX fragment has no corresponding closing tag.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";JSX_fragment_is_not_supported_when_using_jsxFactory_17016" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[JSX fragment is not supported when using --jsxFactory]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";JSX_spread_child_must_be_an_array_type_2609" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[JSX spread child must be an array type.]]></Val>
@@ -823,12 +823,12 @@
</Item>
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0} öğesini {1} konumundaki mevcut içeri aktarma bildirimine ekleyin.]]></Val>
<Val><![CDATA['{0}' öğesini "{1}" konumundaki mevcut içeri aktarma bildirimine ekleyin.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
@@ -2891,6 +2891,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0}-{1} türünde bağımsız değişkenler bekleniyordu; bunları bir '@extends' etiketiyle sağlayın.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
@@ -2918,6 +2927,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0} türünde bağımsız değişkenler bekleniyordu; bunları bir '@extends' etiketiyle sağlayın.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
@@ -3673,12 +3691,12 @@
</Item>
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Import {0} from {1}.]]></Val>
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0} öğesini {1} kaynağından içeri aktarın.]]></Val>
<Val><![CDATA['{0}' öğesini "{1}" kaynağından içeri aktarın.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Import {0} from {1}]]></Val>
<Val><![CDATA[Import {0} from {1}.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
@@ -6359,11 +6377,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Ardışık değişken bildirimleri aynı türe sahip olmalıdır. '{0}' değişkeni '{1}' türünde olmalıdır, ancak burada '{2}' türüne sahip.]]></Val>
<Val><![CDATA[Ardışık değişken bildirimleri aynı türe sahip olmalıdır. '{0}' değişkeni {2} konumunda '{1}' türüne sahip olmasına rağmen burada '{3}' türüne sahip.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
+24 -5
View File
@@ -170,8 +170,8 @@ namespace ts.server {
};
}
getCompletionsAtPosition(fileName: string, position: number): CompletionInfo {
const args: protocol.CompletionsRequestArgs = this.createFileLocationRequestArgs(fileName, position);
getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): CompletionInfo {
const args: protocol.CompletionsRequestArgs = { ...this.createFileLocationRequestArgs(fileName, position), ...options };
const request = this.processRequest<protocol.CompletionsRequest>(CommandNames.Completions, args);
const response = this.processResponse<protocol.CompletionsResponse>(request);
@@ -192,8 +192,8 @@ namespace ts.server {
};
}
getCompletionEntryDetails(fileName: string, position: number, entryName: string): CompletionEntryDetails {
const args: protocol.CompletionDetailsRequestArgs = { ...this.createFileLocationRequestArgs(fileName, position), entryNames: [entryName] };
getCompletionEntryDetails(fileName: string, position: number, entryName: string, _options: FormatCodeOptions | FormatCodeSettings | undefined, source: string | undefined): CompletionEntryDetails {
const args: protocol.CompletionDetailsRequestArgs = { ...this.createFileLocationRequestArgs(fileName, position), entryNames: [{ name: entryName, source }] };
const request = this.processRequest<protocol.CompletionDetailsRequest>(CommandNames.CompletionDetails, args);
const response = this.processResponse<protocol.CompletionDetailsResponse>(request);
@@ -270,6 +270,25 @@ namespace ts.server {
}));
}
getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan {
const args: protocol.FileLocationRequestArgs = this.createFileLocationRequestArgs(fileName, position);
const request = this.processRequest<protocol.DefinitionRequest>(CommandNames.DefinitionAndBoundSpan, args);
const response = this.processResponse<protocol.DefinitionInfoAndBoundSpanReponse>(request);
return {
definitions: response.body.definitions.map(entry => ({
containerKind: ScriptElementKind.unknown,
containerName: "",
fileName: entry.file,
textSpan: this.decodeSpan(entry),
kind: ScriptElementKind.unknown,
name: ""
})),
textSpan: this.decodeSpan(response.body.textSpan, request.arguments.file)
};
}
getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
const args: protocol.FileLocationRequestArgs = this.createFileLocationRequestArgs(fileName, position);
@@ -324,7 +343,7 @@ namespace ts.server {
}
getSyntacticDiagnostics(file: string): Diagnostic[] {
const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file, includeLinePosition: true };
const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file, includeLinePosition: true };
const request = this.processRequest<protocol.SyntacticDiagnosticsSyncRequest>(CommandNames.SyntacticDiagnosticsSync, args);
const response = this.processResponse<protocol.SyntacticDiagnosticsSyncResponse>(request);
+19 -3
View File
@@ -78,9 +78,7 @@ namespace ts.server {
export type ProjectServiceEvent = ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent;
export interface ProjectServiceEventHandler {
(event: ProjectServiceEvent): void;
}
export type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void;
export interface SafeList {
[name: string]: { match: RegExp, exclude?: (string | number)[][], types?: string[] };
@@ -1373,24 +1371,42 @@ namespace ts.server {
this.projectToSizeMap.forEach(val => (availableSpace -= (val || 0)));
let totalNonTsFileSize = 0;
for (const f of fileNames) {
const fileName = propertyReader.getFileName(f);
if (hasTypeScriptFileExtension(fileName)) {
continue;
}
totalNonTsFileSize += this.host.getFileSize(fileName);
if (totalNonTsFileSize > maxProgramSizeForNonTsFiles) {
this.logger.info(getExceedLimitMessage({ propertyReader, hasTypeScriptFileExtension, host: this.host }, totalNonTsFileSize));
// Keep the size as zero since it's disabled
return true;
}
}
if (totalNonTsFileSize > availableSpace) {
this.logger.info(getExceedLimitMessage({ propertyReader, hasTypeScriptFileExtension, host: this.host }, totalNonTsFileSize));
return true;
}
this.projectToSizeMap.set(name, totalNonTsFileSize);
return false;
function getExceedLimitMessage(context: { propertyReader: FilePropertyReader<any>, hasTypeScriptFileExtension: (filename: string) => boolean, host: ServerHost }, totalNonTsFileSize: number) {
const files = getTop5LargestFiles(context);
return `Non TS file size exceeded limit (${totalNonTsFileSize}). Largest files: ${files.map(file => `${file.name}:${file.size}`).join(", ")}`;
}
function getTop5LargestFiles({ propertyReader, hasTypeScriptFileExtension, host }: { propertyReader: FilePropertyReader<any>, hasTypeScriptFileExtension: (filename: string) => boolean, host: ServerHost }) {
return fileNames.map(f => propertyReader.getFileName(f))
.filter(name => hasTypeScriptFileExtension(name))
.map(name => ({ name, size: host.getFileSize(name) }))
.sort((a, b) => b.size - a.size)
.slice(0, 5);
}
}
private createExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typeAcquisition: TypeAcquisition) {
+1 -3
View File
@@ -98,9 +98,7 @@ namespace ts.server {
getExternalFiles?(proj: Project): string[];
}
export interface PluginModuleFactory {
(mod: { typescript: typeof ts }): PluginModule;
}
export type PluginModuleFactory = (mod: { typescript: typeof ts }) => PluginModule;
/**
* The project root can be script info - if root is present,
+19
View File
@@ -15,12 +15,17 @@ namespace ts.server.protocol {
/* @internal */
CompletionsFull = "completions-full",
CompletionDetails = "completionEntryDetails",
/* @internal */
CompletionDetailsFull = "completionEntryDetailsFull",
CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList",
CompileOnSaveEmitFile = "compileOnSaveEmitFile",
Configure = "configure",
Definition = "definition",
/* @internal */
DefinitionFull = "definition-full",
DefinitionAndBoundSpan = "definitionAndBoundSpan",
/* @internal */
DefinitionAndBoundSpanFull = "definitionAndBoundSpan-full",
Implementation = "implementation",
/* @internal */
ImplementationFull = "implementation-full",
@@ -708,6 +713,11 @@ namespace ts.server.protocol {
file: string;
}
export interface DefinitionInfoAndBoundSpan {
definitions: ReadonlyArray<FileSpan>;
textSpan: TextSpan;
}
/**
* Definition response message. Gives text range for definition.
*/
@@ -715,6 +725,10 @@ namespace ts.server.protocol {
body?: FileSpan[];
}
export interface DefinitionInfoAndBoundSpanReponse extends Response {
body?: DefinitionInfoAndBoundSpan;
}
/**
* Definition response message. Gives text range for definition.
*/
@@ -1605,6 +1619,11 @@ namespace ts.server.protocol {
* Optional prefix to apply to possible completions.
*/
prefix?: string;
/**
* If enabled, TypeScript will search through all external modules' exports and add them to the completions list.
* This affects lone identifier completions but not completions on the right hand side of `obj.`.
*/
includeExternalModuleExports: boolean;
}
/**
+9 -9
View File
@@ -10,7 +10,7 @@ namespace ts.server {
charCount(): number;
lineCount(): number;
isLeaf(): this is LineLeaf;
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker): void;
walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker): void;
}
export interface AbsolutePositionAndLineText {
@@ -27,7 +27,7 @@ namespace ts.server {
PostEnd
}
interface ILineIndexWalker {
interface LineIndexWalker {
goSubtree: boolean;
done: boolean;
leaf(relativeStart: number, relativeLength: number, lineCollection: LineLeaf): void;
@@ -37,7 +37,7 @@ namespace ts.server {
parent: LineNode, nodeType: CharRangeSection): void;
}
class EditWalker implements ILineIndexWalker {
class EditWalker implements LineIndexWalker {
goSubtree = true;
get done() { return false; }
@@ -429,7 +429,7 @@ namespace ts.server {
}
}
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker) {
walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker) {
this.root.walk(rangeStart, rangeLength, walkFns);
}
@@ -458,7 +458,7 @@ namespace ts.server {
const walkFns = {
goSubtree: true,
done: false,
leaf(this: ILineIndexWalker, relativeStart: number, relativeLength: number, ll: LineLeaf) {
leaf(this: LineIndexWalker, relativeStart: number, relativeLength: number, ll: LineLeaf) {
if (!f(ll, relativeStart, relativeLength)) {
this.done = true;
}
@@ -580,7 +580,7 @@ namespace ts.server {
}
}
private execWalk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker, childIndex: number, nodeType: CharRangeSection) {
private execWalk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker, childIndex: number, nodeType: CharRangeSection) {
if (walkFns.pre) {
walkFns.pre(rangeStart, rangeLength, this.children[childIndex], this, nodeType);
}
@@ -596,14 +596,14 @@ namespace ts.server {
return walkFns.done;
}
private skipChild(relativeStart: number, relativeLength: number, childIndex: number, walkFns: ILineIndexWalker, nodeType: CharRangeSection) {
private skipChild(relativeStart: number, relativeLength: number, childIndex: number, walkFns: LineIndexWalker, nodeType: CharRangeSection) {
if (walkFns.pre && (!walkFns.done)) {
walkFns.pre(relativeStart, relativeLength, this.children[childIndex], this, nodeType);
walkFns.goSubtree = true;
}
}
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker) {
walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker) {
// assume (rangeStart < this.totalChars) && (rangeLength <= this.totalChars)
let childIndex = 0;
let childCharCount = this.children[childIndex].charCount();
@@ -814,7 +814,7 @@ namespace ts.server {
return true;
}
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker) {
walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker) {
walkFns.leaf(rangeStart, rangeLength, this);
}
+5 -5
View File
@@ -3,7 +3,7 @@
/// <reference path="session.ts" />
namespace ts.server {
interface IOSessionOptions {
interface IoSessionOptions {
host: ServerHost;
cancellationToken: ServerCancellationToken;
canUseEvents: boolean;
@@ -529,7 +529,7 @@ namespace ts.server {
}
class IOSession extends Session {
constructor(options: IOSessionOptions) {
constructor(options: IoSessionOptions) {
const { host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, canUseEvents } = options;
const typingsInstaller = disableAutomaticTypingAcquisition
? undefined
@@ -816,7 +816,7 @@ namespace ts.server {
if (useWatchGuard) {
const currentDrive = extractWatchDirectoryCacheKey(sys.resolvePath(sys.getCurrentDirectory()), /*currentDriveKey*/ undefined);
const statusCache = createMap<boolean>();
sys.watchDirectory = function (path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher {
sys.watchDirectory = (path, callback, recursive) => {
const cacheKey = extractWatchDirectoryCacheKey(path, currentDrive);
let status = cacheKey && statusCache.get(cacheKey);
if (status === undefined) {
@@ -933,7 +933,7 @@ namespace ts.server {
const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition");
const telemetryEnabled = hasArgument(Arguments.EnableTelemetry);
const options: IOSessionOptions = {
const options: IoSessionOptions = {
host: sys,
cancellationToken,
installerEventPort: eventPort,
@@ -953,7 +953,7 @@ namespace ts.server {
};
const ioSession = new IOSession(options);
process.on("uncaughtException", function (err: Error) {
process.on("uncaughtException", err => {
ioSession.logError(err, "unknown");
});
// See https://github.com/Microsoft/TypeScript/issues/11348
+80 -61
View File
@@ -167,7 +167,7 @@ namespace ts.server {
private timerHandle: any;
private immediateId: number | undefined;
constructor(private readonly operationHost: MultistepOperationHost) {}
constructor(private readonly operationHost: MultistepOperationHost) { }
public startNew(action: (next: NextStep) => void) {
this.complete();
@@ -587,7 +587,7 @@ namespace ts.server {
private getDiagnosticsWorker(
args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => ReadonlyArray<Diagnostic>, includeLinePosition: boolean
): ReadonlyArray<protocol.DiagnosticWithLinePosition> | ReadonlyArray<protocol.Diagnostic> {
): ReadonlyArray<protocol.DiagnosticWithLinePosition> | ReadonlyArray<protocol.Diagnostic> {
const { project, file } = this.getFileAndProject(args);
if (isSemantic && isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) {
return emptyArray;
@@ -609,20 +609,51 @@ namespace ts.server {
}
if (simplifiedResult) {
return definitions.map(def => {
const defScriptInfo = project.getScriptInfo(def.fileName);
return {
file: def.fileName,
start: defScriptInfo.positionToLineOffset(def.textSpan.start),
end: defScriptInfo.positionToLineOffset(textSpanEnd(def.textSpan))
};
});
return this.mapDefinitionInfo(definitions, project);
}
else {
return definitions;
}
}
private getDefinitionAndBoundSpan(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.DefinitionInfoAndBoundSpan | DefinitionInfoAndBoundSpan {
const { file, project } = this.getFileAndProject(args);
const position = this.getPositionInFile(args, file);
const scriptInfo = project.getScriptInfo(file);
const definitionAndBoundSpan = project.getLanguageService().getDefinitionAndBoundSpan(file, position);
if (!definitionAndBoundSpan || !definitionAndBoundSpan.definitions) {
return {
definitions: emptyArray,
textSpan: undefined
};
}
if (simplifiedResult) {
return {
definitions: this.mapDefinitionInfo(definitionAndBoundSpan.definitions, project),
textSpan: this.toLocationTextSpan(definitionAndBoundSpan.textSpan, scriptInfo)
};
}
return definitionAndBoundSpan;
}
private mapDefinitionInfo(definitions: ReadonlyArray<DefinitionInfo>, project: Project): ReadonlyArray<protocol.FileSpan> {
return definitions.map(def => this.toFileSpan(def.fileName, def.textSpan, project));
}
private toFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan {
const scriptInfo = project.getScriptInfo(fileName);
return {
file: fileName,
start: scriptInfo.positionToLineOffset(textSpan.start),
end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan))
};
}
private getTypeDefinition(args: protocol.FileLocationRequestArgs): ReadonlyArray<protocol.FileSpan> {
const { file, project } = this.getFileAndProject(args);
const position = this.getPositionInFile(args, file);
@@ -632,14 +663,7 @@ namespace ts.server {
return emptyArray;
}
return definitions.map(def => {
const defScriptInfo = project.getScriptInfo(def.fileName);
return {
file: def.fileName,
start: defScriptInfo.positionToLineOffset(def.textSpan.start),
end: defScriptInfo.positionToLineOffset(textSpanEnd(def.textSpan))
};
});
return this.mapDefinitionInfo(definitions, project);
}
private getImplementation(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.FileSpan> | ReadonlyArray<ImplementationLocation> {
@@ -650,14 +674,7 @@ namespace ts.server {
return emptyArray;
}
if (simplifiedResult) {
return implementations.map(({ fileName, textSpan }) => {
const scriptInfo = project.getScriptInfo(fileName);
return {
file: fileName,
start: scriptInfo.positionToLineOffset(textSpan.start),
end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan))
};
});
return implementations.map(({ fileName, textSpan }) => this.toFileSpan(fileName, textSpan, project));
}
else {
return implementations;
@@ -666,6 +683,7 @@ namespace ts.server {
private getOccurrences(args: protocol.FileLocationRequestArgs): ReadonlyArray<protocol.OccurrencesResponseItem> {
const { file, project } = this.getFileAndProject(args);
const position = this.getPositionInFile(args, file);
const occurrences = project.getLanguageService().getOccurrencesAtPosition(file, position);
@@ -677,11 +695,9 @@ namespace ts.server {
return occurrences.map(occurrence => {
const { fileName, isWriteAccess, textSpan, isInString } = occurrence;
const scriptInfo = project.getScriptInfo(fileName);
const start = scriptInfo.positionToLineOffset(textSpan.start);
const end = scriptInfo.positionToLineOffset(textSpanEnd(textSpan));
const result: protocol.OccurrencesResponseItem = {
start,
end,
start: scriptInfo.positionToLineOffset(textSpan.start),
end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)),
file: fileName,
isWriteAccess,
};
@@ -1184,12 +1200,12 @@ namespace ts.server {
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
const completions = project.getLanguageService().getCompletionsAtPosition(file, position);
const completions = project.getLanguageService().getCompletionsAtPosition(file, position, args);
if (simplifiedResult) {
return mapDefined<CompletionEntry, protocol.CompletionEntry>(completions && completions.entries, entry => {
if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) {
if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) {
const { name, kind, kindModifiers, sortText, replacementSpan, hasAction, source } = entry;
const convertedSpan = replacementSpan ? this.decorateSpan(replacementSpan, scriptInfo) : undefined;
const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined;
// Use `hasAction || undefined` to avoid serializing `false`.
return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source };
}
@@ -1200,23 +1216,19 @@ namespace ts.server {
}
}
private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs): ReadonlyArray<protocol.CompletionEntryDetails> {
private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CompletionEntryDetails> | ReadonlyArray<CompletionEntryDetails> {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
const formattingOptions = project.projectService.getFormatCodeOptions(file);
return mapDefined<string | protocol.CompletionEntryIdentifier, protocol.CompletionEntryDetails>(args.entryNames, entryName => {
const result = mapDefined(args.entryNames, entryName => {
const { name, source } = typeof entryName === "string" ? { name: entryName, source: undefined } : entryName;
const details = project.getLanguageService().getCompletionEntryDetails(file, position, name, formattingOptions, source);
if (details) {
const mappedCodeActions = map(details.codeActions, action => this.mapCodeAction(action, scriptInfo));
return { ...details, codeActions: mappedCodeActions };
}
else {
return undefined;
}
return project.getLanguageService().getCompletionEntryDetails(file, position, name, formattingOptions, source);
});
return simplifiedResult
? result.map(details => ({ ...details, codeActions: map(details.codeActions, action => this.mapCodeAction(action, scriptInfo)) }))
: result;
}
private getCompileOnSaveAffectedFileList(args: protocol.FileRequestArgs): ReadonlyArray<protocol.CompileOnSaveAffectedFileListSingleProject> {
@@ -1337,13 +1349,13 @@ namespace ts.server {
this.projectService.closeClientFile(file);
}
private decorateNavigationBarItems(items: NavigationBarItem[], scriptInfo: ScriptInfo): protocol.NavigationBarItem[] {
private mapLocationNavigationBarItems(items: NavigationBarItem[], scriptInfo: ScriptInfo): protocol.NavigationBarItem[] {
return map(items, item => ({
text: item.text,
kind: item.kind,
kindModifiers: item.kindModifiers,
spans: item.spans.map(span => this.decorateSpan(span, scriptInfo)),
childItems: this.decorateNavigationBarItems(item.childItems, scriptInfo),
spans: item.spans.map(span => this.toLocationTextSpan(span, scriptInfo)),
childItems: this.mapLocationNavigationBarItems(item.childItems, scriptInfo),
indent: item.indent
}));
}
@@ -1354,21 +1366,21 @@ namespace ts.server {
return !items
? undefined
: simplifiedResult
? this.decorateNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file))
? this.mapLocationNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file))
: items;
}
private decorateNavigationTree(tree: NavigationTree, scriptInfo: ScriptInfo): protocol.NavigationTree {
private toLocationNavigationTree(tree: NavigationTree, scriptInfo: ScriptInfo): protocol.NavigationTree {
return {
text: tree.text,
kind: tree.kind,
kindModifiers: tree.kindModifiers,
spans: tree.spans.map(span => this.decorateSpan(span, scriptInfo)),
childItems: map(tree.childItems, item => this.decorateNavigationTree(item, scriptInfo))
spans: tree.spans.map(span => this.toLocationTextSpan(span, scriptInfo)),
childItems: map(tree.childItems, item => this.toLocationNavigationTree(item, scriptInfo))
};
}
private decorateSpan(span: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan {
private toLocationTextSpan(span: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan {
return {
start: scriptInfo.positionToLineOffset(span.start),
end: scriptInfo.positionToLineOffset(textSpanEnd(span))
@@ -1381,7 +1393,7 @@ namespace ts.server {
return !tree
? undefined
: simplifiedResult
? this.decorateNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file))
? this.toLocationNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file))
: tree;
}
@@ -1400,14 +1412,12 @@ namespace ts.server {
return navItems.map((navItem) => {
const scriptInfo = project.getScriptInfo(navItem.fileName);
const start = scriptInfo.positionToLineOffset(navItem.textSpan.start);
const end = scriptInfo.positionToLineOffset(textSpanEnd(navItem.textSpan));
const bakedItem: protocol.NavtoItem = {
name: navItem.name,
kind: navItem.kind,
file: navItem.fileName,
start,
end,
start: scriptInfo.positionToLineOffset(navItem.textSpan.start),
end: scriptInfo.positionToLineOffset(textSpanEnd(navItem.textSpan))
};
if (navItem.kindModifiers && (navItem.kindModifiers !== "")) {
bakedItem.kindModifiers = navItem.kindModifiers;
@@ -1594,7 +1604,7 @@ namespace ts.server {
fileName: change.fileName,
textChanges: change.textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo))
}));
return { description, changes, commands };
return { description, changes, commands };
}
private mapTextChangesToCodeEdits(project: Project, textChanges: FileTextChanges): protocol.FileCodeEdits {
@@ -1622,7 +1632,7 @@ namespace ts.server {
return !spans
? undefined
: simplifiedResult
? spans.map(span => this.decorateSpan(span, scriptInfo))
? spans.map(span => this.toLocationTextSpan(span, scriptInfo))
: spans;
}
@@ -1738,6 +1748,12 @@ namespace ts.server {
[CommandNames.DefinitionFull]: (request: protocol.DefinitionRequest) => {
return this.requiredResponse(this.getDefinition(request.arguments, /*simplifiedResult*/ false));
},
[CommandNames.DefinitionAndBoundSpan]: (request: protocol.DefinitionRequest) => {
return this.requiredResponse(this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ true));
},
[CommandNames.DefinitionAndBoundSpanFull]: (request: protocol.DefinitionRequest) => {
return this.requiredResponse(this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ false));
},
[CommandNames.TypeDefinition]: (request: protocol.FileLocationRequest) => {
return this.requiredResponse(this.getTypeDefinition(request.arguments));
},
@@ -1815,14 +1831,17 @@ namespace ts.server {
[CommandNames.FormatRangeFull]: (request: protocol.FormatRequest) => {
return this.requiredResponse(this.getFormattingEditsForRangeFull(request.arguments));
},
[CommandNames.Completions]: (request: protocol.CompletionDetailsRequest) => {
[CommandNames.Completions]: (request: protocol.CompletionsRequest) => {
return this.requiredResponse(this.getCompletions(request.arguments, /*simplifiedResult*/ true));
},
[CommandNames.CompletionsFull]: (request: protocol.CompletionDetailsRequest) => {
[CommandNames.CompletionsFull]: (request: protocol.CompletionsRequest) => {
return this.requiredResponse(this.getCompletions(request.arguments, /*simplifiedResult*/ false));
},
[CommandNames.CompletionDetails]: (request: protocol.CompletionDetailsRequest) => {
return this.requiredResponse(this.getCompletionEntryDetails(request.arguments));
return this.requiredResponse(this.getCompletionEntryDetails(request.arguments, /*simplifiedResult*/ true));
},
[CommandNames.CompletionDetailsFull]: (request: protocol.CompletionDetailsRequest) => {
return this.requiredResponse(this.getCompletionEntryDetails(request.arguments, /*simplifiedResult*/ false));
},
[CommandNames.CompileOnSaveAffectedFileList]: (request: protocol.CompileOnSaveAffectedFileListRequest) => {
return this.requiredResponse(this.getCompileOnSaveAffectedFileList(request.arguments));
+1
View File
@@ -5,6 +5,7 @@ namespace ts.server {
projectRootPath: Path;
}
// tslint:disable-next-line interface-name (for backwards-compatibility)
export interface ITypingsInstaller {
isKnownTypesPackageName(name: string): boolean;
installPackage(options: InstallPackageOptionsWithProjectRootPath): Promise<ApplyCodeActionCommandResult>;
@@ -248,7 +248,7 @@ namespace ts.server.typingsInstaller {
this.log.writeLine(`Npm config file: '${npmConfigPath}' is missing, creating new one...`);
}
this.ensureDirectoryExists(directory, this.installTypingHost);
this.installTypingHost.writeFile(npmConfigPath, "{}");
this.installTypingHost.writeFile(npmConfigPath, '{ "description": "", "repository": "", "license": "" }');
}
}
+2 -2
View File
@@ -31,7 +31,7 @@ namespace ts.BreakpointResolver {
}
// Cannot set breakpoint in ambient declarations
if (isInAmbientContext(tokenAtLocation)) {
if (tokenAtLocation.flags & NodeFlags.Ambient) {
return undefined;
}
@@ -297,7 +297,7 @@ namespace ts.BreakpointResolver {
}
}
if (isPartOfExpression(node)) {
if (isExpressionNode(node)) {
switch (node.parent.kind) {
case SyntaxKind.DoStatement:
// Set span as if on while keyword
@@ -26,7 +26,7 @@ namespace ts.codefix {
const typesPackageName = getTypesPackageName(packageName);
return {
description: `Install '${typesPackageName}'`,
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Install_0), [typesPackageName]),
changes: [],
commands: [{ type: "install package", packageName: typesPackageName }],
};
@@ -20,8 +20,8 @@ namespace ts.codefix {
// i.e. super(this.a), since in that case we won't suggest a fix
if (superCall.expression && superCall.expression.kind === SyntaxKind.CallExpression) {
const expressionArguments = (<CallExpression>superCall.expression).arguments;
for (let i = 0; i < expressionArguments.length; i++) {
if ((<PropertyAccessExpression>expressionArguments[i]).expression === token) {
for (const arg of expressionArguments) {
if ((<PropertyAccessExpression>arg).expression === token) {
return undefined;
}
}
+2 -4
View File
@@ -104,8 +104,7 @@ namespace ts.codefix {
}
const signatureDeclarations: MethodDeclaration[] = [];
for (let i = 0; i < signatures.length; i++) {
const signature = signatures[i];
for (const signature of signatures) {
const methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration);
if (methodDeclaration) {
signatureDeclarations.push(methodDeclaration);
@@ -194,8 +193,7 @@ namespace ts.codefix {
let maxArgsSignature = signatures[0];
let minArgumentCount = signatures[0].minArgumentCount;
let someSigHasRestParameter = false;
for (let i = 0; i < signatures.length; i++) {
const sig = signatures[i];
for (const sig of signatures) {
minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount);
if (sig.hasRestParameter) {
someSigHasRestParameter = true;
+1 -1
View File
@@ -368,7 +368,7 @@ namespace ts.codefix {
}
function inferTypeFromContextualType(node: Expression, checker: TypeChecker, usageContext: UsageContext): void {
if (isPartOfExpression(node)) {
if (isExpressionNode(node)) {
addCandidateType(usageContext, checker.getContextualType(node));
}
}
+28 -6
View File
@@ -28,16 +28,18 @@ namespace ts.Completions {
sourceFile: SourceFile,
position: number,
allSourceFiles: ReadonlyArray<SourceFile>,
options: GetCompletionsAtPositionOptions,
): CompletionInfo | undefined {
if (isInReferenceComment(sourceFile, position)) {
return PathCompletions.getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host);
const entries = PathCompletions.getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host);
return entries && pathCompletionsInfo(entries);
}
if (isInString(sourceFile, position)) {
return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log);
}
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles);
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options);
if (!completionData) {
return undefined;
}
@@ -241,12 +243,17 @@ namespace ts.Completions {
// a['/*completion position*/']
return getStringLiteralCompletionEntriesFromElementAccess(node.parent, typeChecker, compilerOptions.target, log);
}
else if (node.parent.kind === SyntaxKind.ImportDeclaration || isExpressionOfExternalModuleImportEqualsDeclaration(node) || isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) {
else if (node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration
|| isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || isImportCall(node.parent)
|| isExpressionOfExternalModuleImportEqualsDeclaration(node)) {
// Get all known external module names or complete a path to a module
// i.e. import * as ns from "/*completion position*/";
// var y = import("/*completion position*/");
// import x = require("/*completion position*/");
// var y = require("/*completion position*/");
return PathCompletions.getStringLiteralCompletionEntriesFromModuleNames(<StringLiteral>node, compilerOptions, host, typeChecker);
// export * from "/*completion position*/";
const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(<StringLiteral>node, compilerOptions, host, typeChecker);
return pathCompletionsInfo(entries);
}
else if (isEqualityExpression(node.parent)) {
// Get completions from the type of the other operand
@@ -275,6 +282,18 @@ namespace ts.Completions {
}
}
function pathCompletionsInfo(entries: CompletionEntry[]): CompletionInfo {
return {
// We don't want the editor to offer any other completions, such as snippets, inside a comment.
isGlobalCompletion: false,
isMemberCompletion: false,
// The user may type in a path that doesn't yet exist, creating a "new identifier"
// with respect to the collection of identifiers the server is aware of.
isNewIdentifierLocation: true,
entries,
};
}
function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined {
const type = typeChecker.getContextualType((<ObjectLiteralExpression>element.parent));
const entries: CompletionEntry[] = [];
@@ -362,7 +381,7 @@ namespace ts.Completions {
{ name, source }: CompletionEntryIdentifier,
allSourceFiles: ReadonlyArray<SourceFile>,
): { type: "symbol", symbol: Symbol, location: Node, symbolToOriginInfoMap: SymbolOriginInfoMap } | { type: "request", request: Request } | { type: "none" } {
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles);
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, { includeExternalModuleExports: true });
if (!completionData) {
return { type: "none" };
}
@@ -503,6 +522,7 @@ namespace ts.Completions {
sourceFile: SourceFile,
position: number,
allSourceFiles: ReadonlyArray<SourceFile>,
options: GetCompletionsAtPositionOptions,
): CompletionData | undefined {
const isJavaScriptFile = isSourceFileJavaScript(sourceFile);
@@ -900,7 +920,9 @@ namespace ts.Completions {
const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : "");
if (options.includeExternalModuleExports) {
getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : "");
}
filterGlobalCompletion(symbols);
return true;
+10 -3
View File
@@ -714,6 +714,11 @@ namespace ts.formatting {
processNode(child, childContextNode, childStartLine, undecoratedChildStartLine, childIndentation.indentation, childIndentation.delta);
if (child.kind === SyntaxKind.JsxText) {
const range: TextRange = { pos: child.getStart(), end: child.getEnd() };
indentMultilineCommentOrJsxText(range, childIndentation.indentation, /*firstLineIsIndented*/ true, /*indentFinalLine*/ false);
}
childContextNode = node;
if (isFirstListItem && parent.kind === SyntaxKind.ArrayLiteralExpression && inheritedIndentation === Constants.Unknown) {
@@ -833,7 +838,7 @@ namespace ts.formatting {
switch (triviaItem.kind) {
case SyntaxKind.MultiLineCommentTrivia:
if (triviaInRange) {
indentMultilineComment(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia);
indentMultilineCommentOrJsxText(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia);
}
indentNextTokenOrTrivia = false;
break;
@@ -985,7 +990,7 @@ namespace ts.formatting {
return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length);
}
function indentMultilineComment(commentRange: TextRange, indentation: number, firstLineIsIndented: boolean) {
function indentMultilineCommentOrJsxText(commentRange: TextRange, indentation: number, firstLineIsIndented: boolean, indentFinalLine = true) {
// split comment in lines
let startLine = sourceFile.getLineAndCharacterOfPosition(commentRange.pos).line;
const endLine = sourceFile.getLineAndCharacterOfPosition(commentRange.end).line;
@@ -1006,7 +1011,9 @@ namespace ts.formatting {
startPos = getStartPositionOfLine(line + 1, sourceFile);
}
parts.push({ pos: startPos, end: commentRange.end });
if (indentFinalLine) {
parts.push({ pos: startPos, end: commentRange.end });
}
}
const startLinePos = getStartPositionOfLine(startLine, sourceFile);
@@ -4,9 +4,9 @@
namespace ts.formatting {
export class RuleOperationContext {
private readonly customContextChecks: { (context: FormattingContext): boolean; }[];
private readonly customContextChecks: ((context: FormattingContext) => boolean)[];
constructor(...funcs: { (context: FormattingContext): boolean; }[]) {
constructor(...funcs: ((context: FormattingContext) => boolean)[]) {
this.customContextChecks = funcs;
}
+1 -1
View File
@@ -849,7 +849,7 @@ namespace ts.formatting {
}
static NodeIsInDecoratorContext(node: Node): boolean {
while (isPartOfExpression(node)) {
while (isExpressionNode(node)) {
node = node.parent;
}
return node.kind === SyntaxKind.Decorator;
+23 -1
View File
@@ -88,7 +88,7 @@ namespace ts.GoToDefinition {
// }
// bar<Test>(({pr/*goto*/op1})=>{});
if (isPropertyName(node) && isBindingElement(node.parent) && isObjectBindingPattern(node.parent.parent) &&
(node === (node.parent.propertyName || node.parent.name))) {
(node === (node.parent.propertyName || node.parent.name))) {
const type = typeChecker.getTypeAtLocation(node.parent.parent);
if (type) {
const propSymbols = getPropertySymbolsFromType(type, node);
@@ -149,6 +149,28 @@ namespace ts.GoToDefinition {
return getDefinitionFromSymbol(typeChecker, type.symbol, node);
}
export function getDefinitionAndBoundSpan(program: Program, sourceFile: SourceFile, position: number): DefinitionInfoAndBoundSpan {
const definitions = getDefinitionAtPosition(program, sourceFile, position);
if (!definitions || definitions.length === 0) {
return undefined;
}
// Check if position is on triple slash reference.
const comment = findReferenceInPosition(sourceFile.referencedFiles, position) || findReferenceInPosition(sourceFile.typeReferenceDirectives, position);
if (comment) {
return {
definitions,
textSpan: createTextSpanFromBounds(comment.pos, comment.end)
};
}
const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
const textSpan = createTextSpan(node.getStart(), node.getWidth());
return { definitions, textSpan };
}
// Go to the original declaration for cases:
//
// (1) when the aliased symbol was declared in the location(parent).
+46 -81
View File
@@ -1,34 +1,27 @@
/* @internal */
namespace ts.Completions.PathCompletions {
export function getStringLiteralCompletionEntriesFromModuleNames(node: StringLiteral, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionInfo {
export function getStringLiteralCompletionsFromModuleNames(node: StringLiteral, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionEntry[] {
const literalValue = normalizeSlashes(node.text);
const scriptPath = node.getSourceFile().path;
const scriptDirectory = getDirectoryPath(scriptPath);
const span = getDirectoryFragmentTextSpan((<StringLiteral>node).text, node.getStart() + 1);
let entries: CompletionEntry[];
if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) {
const extensions = getSupportedExtensions(compilerOptions);
if (compilerOptions.rootDirs) {
entries = getCompletionEntriesForDirectoryFragmentWithRootDirs(
return getCompletionEntriesForDirectoryFragmentWithRootDirs(
compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, compilerOptions, host, scriptPath);
}
else {
entries = getCompletionEntriesForDirectoryFragment(
return getCompletionEntriesForDirectoryFragment(
literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, host, scriptPath);
}
}
else {
// Check for node modules
entries = getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span, compilerOptions, host, typeChecker);
return getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span, compilerOptions, host, typeChecker);
}
return {
isGlobalCompletion: false,
isMemberCompletion: false,
isNewIdentifierLocation: true,
entries
};
}
/**
@@ -37,14 +30,14 @@ namespace ts.Completions.PathCompletions {
*/
function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptPath: string, ignoreCase: boolean): string[] {
// Make all paths absolute/normalized if they are not already
rootDirs = map(rootDirs, rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory)));
rootDirs = rootDirs.map(rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory)));
// Determine the path to the directory containing the script relative to the root directory it is contained within
const relativeDirectory = forEach(rootDirs, rootDirectory =>
const relativeDirectory = firstDefined(rootDirs, rootDirectory =>
containsPath(rootDirectory, scriptPath, basePath, ignoreCase) ? scriptPath.substr(rootDirectory.length) : undefined);
// Now find a path for each potential directory that is to be merged with the one containing the script
return deduplicate(map(rootDirs, rootDirectory => combinePaths(rootDirectory, relativeDirectory)));
return deduplicate(rootDirs.map(rootDirectory => combinePaths(rootDirectory, relativeDirectory)));
}
function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptPath: string, extensions: ReadonlyArray<string>, includeExtensions: boolean, span: TextSpan, compilerOptions: CompilerOptions, host: LanguageServiceHost, exclude?: string): CompletionEntry[] {
@@ -144,8 +137,8 @@ namespace ts.Completions.PathCompletions {
let result: CompletionEntry[];
const fileExtensions = getSupportedExtensions(compilerOptions);
if (baseUrl) {
const fileExtensions = getSupportedExtensions(compilerOptions);
const projectDir = compilerOptions.project || host.getCurrentDirectory();
const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl);
result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/ false, span, host);
@@ -176,6 +169,15 @@ namespace ts.Completions.PathCompletions {
result = [];
}
if (compilerOptions.moduleResolution === ts.ModuleResolutionKind.NodeJs) {
forEachAncestorDirectory(scriptPath, ancestor => {
const nodeModules = combinePaths(ancestor, "node_modules");
if (host.directoryExists(nodeModules)) {
getCompletionEntriesForDirectoryFragment(fragment, nodeModules, fileExtensions, /*includeExtensions*/ false, span, host, /*exclude*/ undefined, result);
}
});
}
getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span, result);
for (const moduleName of enumeratePotentialNonRelativeModules(fragment, scriptPath, compilerOptions, typeChecker, host)) {
@@ -274,61 +276,35 @@ namespace ts.Completions.PathCompletions {
return deduplicate(nonRelativeModuleNames);
}
export function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): CompletionInfo {
export function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): CompletionEntry[] | undefined {
const token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
if (!token) {
return undefined;
}
const commentRanges: CommentRange[] = getLeadingCommentRanges(sourceFile.text, token.pos);
if (!commentRanges || !commentRanges.length) {
return undefined;
}
const range = forEach(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end && commentRange);
const commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos);
const range = commentRanges && find(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end);
if (!range) {
return undefined;
}
const completionInfo: CompletionInfo = {
/**
* We don't want the editor to offer any other completions, such as snippets, inside a comment.
*/
isGlobalCompletion: false,
isMemberCompletion: false,
/**
* The user may type in a path that doesn't yet exist, creating a "new identifier"
* with respect to the collection of identifiers the server is aware of.
*/
isNewIdentifierLocation: true,
entries: []
};
const text = sourceFile.text.substr(range.pos, position - range.pos);
const text = sourceFile.text.slice(range.pos, position);
const match = tripleSlashDirectiveFragmentRegex.exec(text);
if (match) {
const prefix = match[1];
const kind = match[2];
const toComplete = match[3];
const scriptPath = getDirectoryPath(sourceFile.path);
if (kind === "path") {
// Give completions for a relative path
const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/ true, span, host, sourceFile.path);
}
else {
// Give completions based on the typings available
const span: TextSpan = { start: range.pos + prefix.length, length: match[0].length - prefix.length };
completionInfo.entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span);
}
if (!match) {
return undefined;
}
return completionInfo;
const [, prefix, kind, toComplete] = match;
const scriptPath = getDirectoryPath(sourceFile.path);
switch (kind) {
case "path": {
// Give completions for a relative path
const span = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
return getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/ true, span, host, sourceFile.path);
}
case "types": {
// Give completions based on the typings available
const span = createTextSpan(range.pos + prefix.length, match[0].length - prefix.length);
return getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span);
}
default:
return undefined;
}
}
function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] {
@@ -376,26 +352,15 @@ namespace ts.Completions.PathCompletions {
}
}
function findPackageJsons(currentDir: string, host: LanguageServiceHost): string[] {
function findPackageJsons(directory: string, host: LanguageServiceHost): string[] {
const paths: string[] = [];
let currentConfigPath: string;
while (true) {
currentConfigPath = findConfigFile(currentDir, (f) => tryFileExists(host, f), "package.json");
if (currentConfigPath) {
paths.push(currentConfigPath);
currentDir = getDirectoryPath(currentConfigPath);
const parent = getDirectoryPath(currentDir);
if (currentDir === parent) {
break;
}
currentDir = parent;
forEachAncestorDirectory(directory, ancestor => {
const currentConfigPath = findConfigFile(ancestor, (f) => tryFileExists(host, f), "package.json");
if (!currentConfigPath) {
return true; // break out
}
else {
break;
}
}
paths.push(currentConfigPath);
});
return paths;
}
+3 -3
View File
@@ -331,11 +331,11 @@ namespace ts.refactor.extractSymbol {
Continue = 1 << 1,
Return = 1 << 2
}
if (!isStatement(nodeToCheck) && !(isPartOfExpression(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
if (!isStatement(nodeToCheck) && !(isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
return [createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)];
}
if (isInAmbientContext(nodeToCheck)) {
if (nodeToCheck.flags & NodeFlags.Ambient) {
return [createDiagnosticForNode(nodeToCheck, Messages.CannotExtractAmbientBlock)];
}
@@ -491,7 +491,7 @@ namespace ts.refactor.extractSymbol {
if (isStatement(node)) {
return [node];
}
else if (isPartOfExpression(node)) {
else if (isExpressionNode(node)) {
// If our selection is the expression in an ExpressionStatement, expand
// the selection to include the enclosing Statement (this stops us
// from trying to care about the return value of the extracted function
+1
View File
@@ -2,3 +2,4 @@
/// <reference path="convertFunctionToEs6Class.ts" />
/// <reference path="extractSymbol.ts" />
/// <reference path="installTypesForPackage.ts" />
/// <reference path="useDefaultImport.ts" />
@@ -0,0 +1,96 @@
/* @internal */
namespace ts.refactor.installTypesForPackage {
const actionName = "Convert to default import";
const useDefaultImport: Refactor = {
name: actionName,
description: getLocaleSpecificMessage(Diagnostics.Convert_to_default_import),
getEditsForAction,
getAvailableActions,
};
registerRefactor(useDefaultImport);
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
const { file, startPosition, program } = context;
if (!program.getCompilerOptions().allowSyntheticDefaultImports) {
return undefined;
}
const importInfo = getConvertibleImportAtPosition(file, startPosition);
if (!importInfo) {
return undefined;
}
const module = ts.getResolvedModule(file, importInfo.moduleSpecifier.text);
const resolvedFile = program.getSourceFile(module.resolvedFileName);
if (!(resolvedFile.externalModuleIndicator && isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals)) {
return undefined;
}
return [
{
name: useDefaultImport.name,
description: useDefaultImport.description,
actions: [
{
description: useDefaultImport.description,
name: actionName,
},
],
},
];
}
function getEditsForAction(context: RefactorContext, _actionName: string): RefactorEditInfo | undefined {
const { file, startPosition } = context;
Debug.assertEqual(actionName, _actionName);
const importInfo = getConvertibleImportAtPosition(file, startPosition);
if (!importInfo) {
return undefined;
}
const { importStatement, name, moduleSpecifier } = importInfo;
const newImportClause = createImportClause(name, /*namedBindings*/ undefined);
const newImportStatement = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newImportClause, moduleSpecifier);
return {
edits: textChanges.ChangeTracker.with(context, t => t.replaceNode(file, importStatement, newImportStatement)),
renameFilename: undefined,
renameLocation: undefined,
};
}
function getConvertibleImportAtPosition(
file: SourceFile,
startPosition: number,
): { importStatement: AnyImportSyntax, name: Identifier, moduleSpecifier: StringLiteral } | undefined {
let node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
while (true) {
switch (node.kind) {
case SyntaxKind.ImportEqualsDeclaration:
const eq = node as ImportEqualsDeclaration;
const { moduleReference } = eq;
return moduleReference.kind === SyntaxKind.ExternalModuleReference && isStringLiteral(moduleReference.expression)
? { importStatement: eq, name: eq.name, moduleSpecifier: moduleReference.expression }
: undefined;
case SyntaxKind.ImportDeclaration:
const d = node as ImportDeclaration;
const { importClause } = d;
return !importClause.name && importClause.namedBindings.kind === SyntaxKind.NamespaceImport && isStringLiteral(d.moduleSpecifier)
? { importStatement: d, name: importClause.namedBindings.name, moduleSpecifier: d.moduleSpecifier }
: undefined;
// For known child node kinds of convertible imports, try again with parent node.
case SyntaxKind.NamespaceImport:
case SyntaxKind.ExternalModuleReference:
case SyntaxKind.ImportKeyword:
case SyntaxKind.Identifier:
case SyntaxKind.StringLiteral:
case SyntaxKind.AsteriskToken:
break;
default:
return undefined;
}
node = node.parent;
}
}
}
+24 -6
View File
@@ -31,7 +31,7 @@
namespace ts {
/** The version of the language service API */
export const servicesVersion = "0.6";
export const servicesVersion = "0.7";
/* @internal */
let ruleProvider: formatting.RulesProvider;
@@ -41,6 +41,7 @@ namespace ts {
kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) :
new TokenObject(kind, pos, end);
node.parent = parent;
node.flags = parent.flags & NodeFlags.ContextFlags;
return node;
}
@@ -276,7 +277,10 @@ namespace ts {
}
public getText(sourceFile?: SourceFile): string {
return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd());
if (!sourceFile) {
sourceFile = this.getSourceFile();
}
return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd());
}
public getChildCount(): number {
@@ -724,9 +728,9 @@ namespace ts {
case SyntaxKind.BinaryExpression:
if (getSpecialPropertyAssignmentKind(node as BinaryExpression) !== SpecialPropertyAssignmentKind.None) {
addDeclaration(node as BinaryExpression);
addDeclaration(node as BinaryExpression);
}
// falls through
// falls through
default:
forEachChild(node, visit);
@@ -1322,9 +1326,17 @@ namespace ts {
return [...program.getOptionsDiagnostics(cancellationToken), ...program.getGlobalDiagnostics(cancellationToken)];
}
function getCompletionsAtPosition(fileName: string, position: number): CompletionInfo {
function getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions = { includeExternalModuleExports: false }): CompletionInfo {
synchronizeHostData();
return Completions.getCompletionsAtPosition(host, program.getTypeChecker(), log, program.getCompilerOptions(), getValidSourceFile(fileName), position, program.getSourceFiles());
return Completions.getCompletionsAtPosition(
host,
program.getTypeChecker(),
log,
program.getCompilerOptions(),
getValidSourceFile(fileName),
position,
program.getSourceFiles(),
options);
}
function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions?: FormatCodeSettings, source?: string): CompletionEntryDetails {
@@ -1428,6 +1440,11 @@ namespace ts {
return GoToDefinition.getDefinitionAtPosition(program, getValidSourceFile(fileName), position);
}
function getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan {
synchronizeHostData();
return GoToDefinition.getDefinitionAndBoundSpan(program, getValidSourceFile(fileName), position);
}
function getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
synchronizeHostData();
return GoToDefinition.getTypeDefinitionAtPosition(program.getTypeChecker(), getValidSourceFile(fileName), position);
@@ -2040,6 +2057,7 @@ namespace ts {
getSignatureHelpItems,
getQuickInfoAtPosition,
getDefinitionAtPosition,
getDefinitionAndBoundSpan,
getImplementationAtPosition,
getTypeDefinitionAtPosition,
getReferencesAtPosition,
+20 -7
View File
@@ -106,7 +106,7 @@ namespace ts {
///
// Note: This is being using by the host (VS) and is marshaled back and forth.
// When changing this make sure the changes are reflected in the managed side as well
export interface IFileReference {
export interface ShimsFileReference {
path: string;
position: number;
length: number;
@@ -140,7 +140,7 @@ namespace ts {
getEncodedSyntacticClassifications(fileName: string, start: number, length: number): string;
getEncodedSemanticClassifications(fileName: string, start: number, length: number): string;
getCompletionsAtPosition(fileName: string, position: number): string;
getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): string;
getCompletionEntryDetails(fileName: string, position: number, entryName: string, options: string/*Services.FormatCodeOptions*/, source: string | undefined): string;
getQuickInfoAtPosition(fileName: string, position: number): string;
@@ -170,6 +170,8 @@ namespace ts {
*/
getDefinitionAtPosition(fileName: string, position: number): string;
getDefinitionAndBoundSpan(fileName: string, position: number): string;
/**
* Returns a JSON-encoded value of the type:
* { fileName: string; textSpan: { start: number; length: number}; kind: string; name: string; containerKind: string; containerName: string }
@@ -772,6 +774,17 @@ namespace ts {
);
}
/**
* Computes the definition location and file for the symbol
* at the requested position.
*/
public getDefinitionAndBoundSpan(fileName: string, position: number): string {
return this.forwardJSONCall(
`getDefinitionAndBoundSpan('${fileName}', ${position})`,
() => this.languageService.getDefinitionAndBoundSpan(fileName, position)
);
}
/// GOTO Type
/**
@@ -885,10 +898,10 @@ namespace ts {
* to provide at the given source position and providing a member completion
* list if requested.
*/
public getCompletionsAtPosition(fileName: string, position: number) {
public getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined) {
return this.forwardJSONCall(
`getCompletionsAtPosition('${fileName}', ${position})`,
() => this.languageService.getCompletionsAtPosition(fileName, position)
`getCompletionsAtPosition('${fileName}', ${position}, ${options})`,
() => this.languageService.getCompletionsAtPosition(fileName, position, options)
);
}
@@ -1091,11 +1104,11 @@ namespace ts {
);
}
private convertFileReferences(refs: FileReference[]): IFileReference[] {
private convertFileReferences(refs: FileReference[]): ShimsFileReference[] {
if (!refs) {
return undefined;
}
const result: IFileReference[] = [];
const result: ShimsFileReference[] = [];
for (const ref of refs) {
result.push({
path: normalizeSlashes(ref.fileName),
+4 -2
View File
@@ -489,8 +489,10 @@ namespace ts.SymbolDisplay {
addNewLineIfDisplayPartsExist();
if (symbolKind) {
pushTypePart(symbolKind);
displayParts.push(spacePart());
addFullSymbolName(symbol);
if (!some(symbol.declarations, d => isArrowFunction(d) || (isFunctionExpression(d) || isClassExpression(d)) && !d.name)) {
displayParts.push(spacePart());
addFullSymbolName(symbol);
}
}
}
+12 -1
View File
@@ -86,6 +86,7 @@ namespace ts {
* snapshot is observably immutable. i.e. the same calls with the same parameters will return
* the same values.
*/
// tslint:disable-next-line interface-name
export interface IScriptSnapshot {
/** Gets a portion of the script snapshot specified by [start, end). */
getText(start: number, end: number): string;
@@ -236,7 +237,7 @@ namespace ts {
getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications;
getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications;
getCompletionsAtPosition(fileName: string, position: number): CompletionInfo;
getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): CompletionInfo;
// "options" and "source" are optional only for backwards-compatibility
getCompletionEntryDetails(
fileName: string,
@@ -259,6 +260,7 @@ namespace ts {
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[];
getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[];
getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan;
getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[];
getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[];
@@ -308,6 +310,10 @@ namespace ts {
dispose(): void;
}
export interface GetCompletionsAtPositionOptions {
includeExternalModuleExports: boolean;
}
export interface ApplyCodeActionCommandResult {
successMessage: string;
}
@@ -581,6 +587,11 @@ namespace ts {
containerName: string;
}
export interface DefinitionInfoAndBoundSpan {
definitions: ReadonlyArray<DefinitionInfo>;
textSpan: TextSpan;
}
export interface ReferencedSymbolDefinitionInfo extends DefinitionInfo {
displayParts: SymbolDisplayPart[];
}
+2 -2
View File
@@ -178,7 +178,7 @@ namespace ts {
switch (node.kind) {
case SyntaxKind.ThisKeyword:
return !isPartOfExpression(node);
return !isExpressionNode(node);
case SyntaxKind.ThisType:
return true;
}
@@ -947,7 +947,7 @@ namespace ts {
if (flags & ModifierFlags.Static) result.push(ScriptElementKindModifier.staticModifier);
if (flags & ModifierFlags.Abstract) result.push(ScriptElementKindModifier.abstractModifier);
if (flags & ModifierFlags.Export) result.push(ScriptElementKindModifier.exportedModifier);
if (isInAmbientContext(node)) result.push(ScriptElementKindModifier.ambientModifier);
if (node.flags & NodeFlags.Ambient) result.push(ScriptElementKindModifier.ambientModifier);
return result.length > 0 ? result.join(",") : ScriptElementKindModifier.none;
}
@@ -5,7 +5,7 @@ tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstr
==== tests/cases/compiler/abstractPropertyInConstructor.ts (3 errors) ====
abstract class AbstractClass {
constructor(str: string) {
constructor(str: string, other: AbstractClass) {
this.method(parseInt(str));
let val = this.prop.toLowerCase();
~~~~
@@ -20,9 +20,13 @@ tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstr
~~
!!! error TS2715: Abstract property 'cb' in class 'AbstractClass' cannot be accessed in the constructor.
// OK, reference is inside function
const innerFunction = () => {
return this.prop;
}
// OK, references are to another instance
other.cb(other.prop);
}
abstract prop: string;
@@ -34,4 +38,13 @@ tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstr
this.prop = this.prop + "!";
}
}
class User {
constructor(a: AbstractClass) {
a.prop;
a.cb("hi");
a.method(12);
a.method2();
}
}
@@ -1,6 +1,6 @@
//// [abstractPropertyInConstructor.ts]
abstract class AbstractClass {
constructor(str: string) {
constructor(str: string, other: AbstractClass) {
this.method(parseInt(str));
let val = this.prop.toLowerCase();
@@ -9,9 +9,13 @@ abstract class AbstractClass {
}
this.cb(str);
// OK, reference is inside function
const innerFunction = () => {
return this.prop;
}
// OK, references are to another instance
other.cb(other.prop);
}
abstract prop: string;
@@ -23,11 +27,20 @@ abstract class AbstractClass {
this.prop = this.prop + "!";
}
}
class User {
constructor(a: AbstractClass) {
a.prop;
a.cb("hi");
a.method(12);
a.method2();
}
}
//// [abstractPropertyInConstructor.js]
var AbstractClass = /** @class */ (function () {
function AbstractClass(str) {
function AbstractClass(str, other) {
var _this = this;
this.method(parseInt(str));
var val = this.prop.toLowerCase();
@@ -35,12 +48,24 @@ var AbstractClass = /** @class */ (function () {
this.prop = "Hello World";
}
this.cb(str);
// OK, reference is inside function
var innerFunction = function () {
return _this.prop;
};
// OK, references are to another instance
other.cb(other.prop);
}
AbstractClass.prototype.method2 = function () {
this.prop = this.prop + "!";
};
return AbstractClass;
}());
var User = /** @class */ (function () {
function User(a) {
a.prop;
a.cb("hi");
a.method(12);
a.method2();
}
return User;
}());
@@ -2,69 +2,110 @@
abstract class AbstractClass {
>AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
constructor(str: string) {
constructor(str: string, other: AbstractClass) {
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16))
>other : Symbol(other, Decl(abstractPropertyInConstructor.ts, 1, 28))
>AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
this.method(parseInt(str));
>this.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37))
>this.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37))
>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37))
>parseInt : Symbol(parseInt, Decl(lib.d.ts, --, --))
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16))
let val = this.prop.toLowerCase();
>val : Symbol(val, Decl(abstractPropertyInConstructor.ts, 3, 11))
>this.prop.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --))
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
>toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --))
if (!str) {
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16))
this.prop = "Hello World";
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
}
this.cb(str);
>this.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26))
>this.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26))
>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16))
// OK, reference is inside function
const innerFunction = () => {
>innerFunction : Symbol(innerFunction, Decl(abstractPropertyInConstructor.ts, 10, 13))
>innerFunction : Symbol(innerFunction, Decl(abstractPropertyInConstructor.ts, 11, 13))
return this.prop;
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
}
// OK, references are to another instance
other.cb(other.prop);
>other.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
>other : Symbol(other, Decl(abstractPropertyInConstructor.ts, 1, 28))
>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
>other.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
>other : Symbol(other, Decl(abstractPropertyInConstructor.ts, 1, 28))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
}
abstract prop: string;
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
abstract cb: (s: string) => void;
>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26))
>s : Symbol(s, Decl(abstractPropertyInConstructor.ts, 16, 18))
>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
>s : Symbol(s, Decl(abstractPropertyInConstructor.ts, 20, 18))
abstract method(num: number): void;
>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37))
>num : Symbol(num, Decl(abstractPropertyInConstructor.ts, 18, 20))
>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37))
>num : Symbol(num, Decl(abstractPropertyInConstructor.ts, 22, 20))
method2() {
>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 18, 39))
>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 22, 39))
this.prop = this.prop + "!";
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
}
}
class User {
>User : Symbol(User, Decl(abstractPropertyInConstructor.ts, 27, 1))
constructor(a: AbstractClass) {
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16))
>AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
a.prop;
>a.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
a.cb("hi");
>a.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16))
>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
a.method(12);
>a.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16))
>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37))
a.method2();
>a.method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 22, 39))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16))
>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 22, 39))
}
}
@@ -2,8 +2,10 @@
abstract class AbstractClass {
>AbstractClass : AbstractClass
constructor(str: string) {
constructor(str: string, other: AbstractClass) {
>str : string
>other : AbstractClass
>AbstractClass : AbstractClass
this.method(parseInt(str));
>this.method(parseInt(str)) : void
@@ -41,6 +43,7 @@ abstract class AbstractClass {
>cb : (s: string) => void
>str : string
// OK, reference is inside function
const innerFunction = () => {
>innerFunction : () => string
>() => { return this.prop; } : () => string
@@ -50,6 +53,16 @@ abstract class AbstractClass {
>this : this
>prop : string
}
// OK, references are to another instance
other.cb(other.prop);
>other.cb(other.prop) : void
>other.cb : (s: string) => void
>other : AbstractClass
>cb : (s: string) => void
>other.prop : string
>other : AbstractClass
>prop : string
}
abstract prop: string;
@@ -79,3 +92,37 @@ abstract class AbstractClass {
}
}
class User {
>User : User
constructor(a: AbstractClass) {
>a : AbstractClass
>AbstractClass : AbstractClass
a.prop;
>a.prop : string
>a : AbstractClass
>prop : string
a.cb("hi");
>a.cb("hi") : void
>a.cb : (s: string) => void
>a : AbstractClass
>cb : (s: string) => void
>"hi" : "hi"
a.method(12);
>a.method(12) : void
>a.method : (num: number) => void
>a : AbstractClass
>method : (num: number) => void
>12 : 12
a.method2();
>a.method2() : void
>a.method2 : () => void
>a : AbstractClass
>method2 : () => void
}
}
+104 -66
View File
@@ -314,46 +314,49 @@ declare namespace ts {
JsxSelfClosingElement = 251,
JsxOpeningElement = 252,
JsxClosingElement = 253,
JsxAttribute = 254,
JsxAttributes = 255,
JsxSpreadAttribute = 256,
JsxExpression = 257,
CaseClause = 258,
DefaultClause = 259,
HeritageClause = 260,
CatchClause = 261,
PropertyAssignment = 262,
ShorthandPropertyAssignment = 263,
SpreadAssignment = 264,
EnumMember = 265,
SourceFile = 266,
Bundle = 267,
JSDocTypeExpression = 268,
JSDocAllType = 269,
JSDocUnknownType = 270,
JSDocNullableType = 271,
JSDocNonNullableType = 272,
JSDocOptionalType = 273,
JSDocFunctionType = 274,
JSDocVariadicType = 275,
JSDocComment = 276,
JSDocTypeLiteral = 277,
JSDocTag = 278,
JSDocAugmentsTag = 279,
JSDocClassTag = 280,
JSDocParameterTag = 281,
JSDocReturnTag = 282,
JSDocTypeTag = 283,
JSDocTemplateTag = 284,
JSDocTypedefTag = 285,
JSDocPropertyTag = 286,
SyntaxList = 287,
NotEmittedStatement = 288,
PartiallyEmittedExpression = 289,
CommaListExpression = 290,
MergeDeclarationMarker = 291,
EndOfDeclarationMarker = 292,
Count = 293,
JsxFragment = 254,
JsxOpeningFragment = 255,
JsxClosingFragment = 256,
JsxAttribute = 257,
JsxAttributes = 258,
JsxSpreadAttribute = 259,
JsxExpression = 260,
CaseClause = 261,
DefaultClause = 262,
HeritageClause = 263,
CatchClause = 264,
PropertyAssignment = 265,
ShorthandPropertyAssignment = 266,
SpreadAssignment = 267,
EnumMember = 268,
SourceFile = 269,
Bundle = 270,
JSDocTypeExpression = 271,
JSDocAllType = 272,
JSDocUnknownType = 273,
JSDocNullableType = 274,
JSDocNonNullableType = 275,
JSDocOptionalType = 276,
JSDocFunctionType = 277,
JSDocVariadicType = 278,
JSDocComment = 279,
JSDocTypeLiteral = 280,
JSDocTag = 281,
JSDocAugmentsTag = 282,
JSDocClassTag = 283,
JSDocParameterTag = 284,
JSDocReturnTag = 285,
JSDocTypeTag = 286,
JSDocTemplateTag = 287,
JSDocTypedefTag = 288,
JSDocPropertyTag = 289,
SyntaxList = 290,
NotEmittedStatement = 291,
PartiallyEmittedExpression = 292,
CommaListExpression = 293,
MergeDeclarationMarker = 294,
EndOfDeclarationMarker = 295,
Count = 296,
FirstAssignment = 58,
LastAssignment = 70,
FirstCompoundAssignment = 59,
@@ -379,10 +382,10 @@ declare namespace ts {
FirstBinaryOperator = 27,
LastBinaryOperator = 70,
FirstNode = 144,
FirstJSDocNode = 268,
LastJSDocNode = 286,
FirstJSDocTagNode = 278,
LastJSDocTagNode = 286,
FirstJSDocNode = 271,
LastJSDocNode = 289,
FirstJSDocTagNode = 281,
LastJSDocTagNode = 289,
}
enum NodeFlags {
None = 0,
@@ -409,7 +412,7 @@ declare namespace ts {
BlockScoped = 3,
ReachabilityCheckFlags = 384,
ReachabilityAndEmitFlags = 1408,
ContextFlags = 2193408,
ContextFlags = 6387712,
TypeExcludesFlags = 20480,
}
enum ModifierFlags {
@@ -1062,6 +1065,20 @@ declare namespace ts {
tagName: JsxTagNameExpression;
attributes: JsxAttributes;
}
interface JsxFragment extends PrimaryExpression {
kind: SyntaxKind.JsxFragment;
openingFragment: JsxOpeningFragment;
children: NodeArray<JsxChild>;
closingFragment: JsxClosingFragment;
}
interface JsxOpeningFragment extends Expression {
kind: SyntaxKind.JsxOpeningFragment;
parent?: JsxFragment;
}
interface JsxClosingFragment extends Expression {
kind: SyntaxKind.JsxClosingFragment;
parent?: JsxFragment;
}
interface JsxAttribute extends ObjectLiteralElement {
kind: SyntaxKind.JsxAttribute;
parent?: JsxAttributes;
@@ -1089,7 +1106,7 @@ declare namespace ts {
containsOnlyWhiteSpaces: boolean;
parent?: JsxElement;
}
type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment;
interface Statement extends Node {
_statementBrand: any;
}
@@ -1607,9 +1624,7 @@ declare namespace ts {
fileExists(path: string): boolean;
readFile(path: string): string | undefined;
}
interface WriteFileCallback {
(fileName: string, data: string, writeByteOrderMark: boolean, onError: ((message: string) => void) | undefined, sourceFiles: ReadonlyArray<SourceFile>): void;
}
type WriteFileCallback = (fileName: string, data: string, writeByteOrderMark: boolean, onError: ((message: string) => void) | undefined, sourceFiles: ReadonlyArray<SourceFile>) => void;
class OperationCanceledException {
}
interface CancellationToken {
@@ -3009,6 +3024,9 @@ declare namespace ts {
function isJsxSelfClosingElement(node: Node): node is JsxSelfClosingElement;
function isJsxOpeningElement(node: Node): node is JsxOpeningElement;
function isJsxClosingElement(node: Node): node is JsxClosingElement;
function isJsxFragment(node: Node): node is JsxFragment;
function isJsxOpeningFragment(node: Node): node is JsxOpeningFragment;
function isJsxClosingFragment(node: Node): node is JsxClosingFragment;
function isJsxAttribute(node: Node): node is JsxAttribute;
function isJsxAttributes(node: Node): node is JsxAttributes;
function isJsxSpreadAttribute(node: Node): node is JsxSpreadAttribute;
@@ -3082,9 +3100,7 @@ declare namespace ts {
function isGetAccessor(node: Node): node is GetAccessorDeclaration;
}
declare namespace ts {
interface ErrorCallback {
(message: DiagnosticMessage, length: number): void;
}
type ErrorCallback = (message: DiagnosticMessage, length: number) => void;
interface Scanner {
getStartPos(): number;
getToken(): SyntaxKind;
@@ -3509,6 +3525,8 @@ declare namespace ts {
function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributes): JsxOpeningElement;
function createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement;
function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement;
function createJsxFragment(openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment): JsxFragment;
function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment): JsxFragment;
function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute;
function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute;
function createJsxAttributes(properties: ReadonlyArray<JsxAttributeLike>): JsxAttributes;
@@ -3923,7 +3941,7 @@ declare namespace ts {
getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[];
getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications;
getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications;
getCompletionsAtPosition(fileName: string, position: number): CompletionInfo;
getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): CompletionInfo;
getCompletionEntryDetails(fileName: string, position: number, name: string, options: FormatCodeOptions | FormatCodeSettings | undefined, source: string | undefined): CompletionEntryDetails;
getCompletionEntrySymbol(fileName: string, position: number, name: string, source: string | undefined): Symbol;
getQuickInfoAtPosition(fileName: string, position: number): QuickInfo;
@@ -3933,6 +3951,7 @@ declare namespace ts {
getRenameInfo(fileName: string, position: number): RenameInfo;
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[];
getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[];
getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan;
getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[];
getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[];
getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[];
@@ -3961,6 +3980,9 @@ declare namespace ts {
getProgram(): Program;
dispose(): void;
}
interface GetCompletionsAtPositionOptions {
includeExternalModuleExports: boolean;
}
interface ApplyCodeActionCommandResult {
successMessage: string;
}
@@ -4196,6 +4218,10 @@ declare namespace ts {
containerKind: ScriptElementKind;
containerName: string;
}
interface DefinitionInfoAndBoundSpan {
definitions: ReadonlyArray<DefinitionInfo>;
textSpan: TextSpan;
}
interface ReferencedSymbolDefinitionInfo extends DefinitionInfo {
displayParts: SymbolDisplayPart[];
}
@@ -4607,7 +4633,7 @@ declare namespace ts {
}
declare namespace ts {
/** The version of the language service API */
const servicesVersion = "0.6";
const servicesVersion = "0.7";
interface DisplayPartsSymbolWriter extends SymbolWriter {
displayParts(): SymbolDisplayPart[];
}
@@ -4831,6 +4857,7 @@ declare namespace ts.server.protocol {
CompileOnSaveEmitFile = "compileOnSaveEmitFile",
Configure = "configure",
Definition = "definition",
DefinitionAndBoundSpan = "definitionAndBoundSpan",
Implementation = "implementation",
Exit = "exit",
Format = "format",
@@ -5350,12 +5377,19 @@ declare namespace ts.server.protocol {
*/
file: string;
}
interface DefinitionInfoAndBoundSpan {
definitions: ReadonlyArray<FileSpan>;
textSpan: TextSpan;
}
/**
* Definition response message. Gives text range for definition.
*/
interface DefinitionResponse extends Response {
body?: FileSpan[];
}
interface DefinitionInfoAndBoundSpanReponse extends Response {
body?: DefinitionInfoAndBoundSpan;
}
/**
* Definition response message. Gives text range for definition.
*/
@@ -6024,6 +6058,11 @@ declare namespace ts.server.protocol {
* Optional prefix to apply to possible completions.
*/
prefix?: string;
/**
* If enabled, TypeScript will search through all external modules' exports and add them to the completions list.
* This affects lone identifier completions but not completions on the right hand side of `obj.`.
*/
includeExternalModuleExports: boolean;
}
/**
* Completions request; value of command field is "completions".
@@ -6931,6 +6970,9 @@ declare namespace ts.server {
private convertToDiagnosticsWithLinePosition(diagnostics, scriptInfo);
private getDiagnosticsWorker(args, isSemantic, selector, includeLinePosition);
private getDefinition(args, simplifiedResult);
private getDefinitionAndBoundSpan(args, simplifiedResult);
private mapDefinitionInfo(definitions, project);
private toFileSpan(fileName, textSpan, project);
private getTypeDefinition(args);
private getImplementation(args, simplifiedResult);
private getOccurrences(args);
@@ -6970,7 +7012,7 @@ declare namespace ts.server {
private getFormattingEditsAfterKeystrokeFull(args);
private getFormattingEditsAfterKeystroke(args);
private getCompletions(args, simplifiedResult);
private getCompletionEntryDetails(args);
private getCompletionEntryDetails(args, simplifiedResult);
private getCompileOnSaveAffectedFileList(args);
private emitFile(args);
private getSignatureHelpItems(args, simplifiedResult);
@@ -6980,10 +7022,10 @@ declare namespace ts.server {
private reload(args, reqSeq);
private saveToTmp(fileName, tempFileName);
private closeClientFile(fileName);
private decorateNavigationBarItems(items, scriptInfo);
private mapLocationNavigationBarItems(items, scriptInfo);
private getNavigationBarItems(args, simplifiedResult);
private decorateNavigationTree(tree, scriptInfo);
private decorateSpan(span, scriptInfo);
private toLocationNavigationTree(tree, scriptInfo);
private toLocationTextSpan(span, scriptInfo);
private getNavigationTree(args, simplifiedResult);
private getNavigateToItems(args, simplifiedResult);
private getSupportedCodeFixes();
@@ -7114,11 +7156,9 @@ declare namespace ts.server {
create(createInfo: PluginCreateInfo): LanguageService;
getExternalFiles?(proj: Project): string[];
}
interface PluginModuleFactory {
(mod: {
typescript: typeof ts;
}): PluginModule;
}
type PluginModuleFactory = (mod: {
typescript: typeof ts;
}) => PluginModule;
/**
* The project root can be script info - if root is present,
* or it could be just normalized path if root wasnt present on the host(only for non inferred project)
@@ -7388,9 +7428,7 @@ declare namespace ts.server {
readonly dts: number;
}
type ProjectServiceEvent = ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent;
interface ProjectServiceEventHandler {
(event: ProjectServiceEvent): void;
}
type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void;
interface SafeList {
[name: string]: {
match: RegExp;
+80 -54
View File
@@ -314,46 +314,49 @@ declare namespace ts {
JsxSelfClosingElement = 251,
JsxOpeningElement = 252,
JsxClosingElement = 253,
JsxAttribute = 254,
JsxAttributes = 255,
JsxSpreadAttribute = 256,
JsxExpression = 257,
CaseClause = 258,
DefaultClause = 259,
HeritageClause = 260,
CatchClause = 261,
PropertyAssignment = 262,
ShorthandPropertyAssignment = 263,
SpreadAssignment = 264,
EnumMember = 265,
SourceFile = 266,
Bundle = 267,
JSDocTypeExpression = 268,
JSDocAllType = 269,
JSDocUnknownType = 270,
JSDocNullableType = 271,
JSDocNonNullableType = 272,
JSDocOptionalType = 273,
JSDocFunctionType = 274,
JSDocVariadicType = 275,
JSDocComment = 276,
JSDocTypeLiteral = 277,
JSDocTag = 278,
JSDocAugmentsTag = 279,
JSDocClassTag = 280,
JSDocParameterTag = 281,
JSDocReturnTag = 282,
JSDocTypeTag = 283,
JSDocTemplateTag = 284,
JSDocTypedefTag = 285,
JSDocPropertyTag = 286,
SyntaxList = 287,
NotEmittedStatement = 288,
PartiallyEmittedExpression = 289,
CommaListExpression = 290,
MergeDeclarationMarker = 291,
EndOfDeclarationMarker = 292,
Count = 293,
JsxFragment = 254,
JsxOpeningFragment = 255,
JsxClosingFragment = 256,
JsxAttribute = 257,
JsxAttributes = 258,
JsxSpreadAttribute = 259,
JsxExpression = 260,
CaseClause = 261,
DefaultClause = 262,
HeritageClause = 263,
CatchClause = 264,
PropertyAssignment = 265,
ShorthandPropertyAssignment = 266,
SpreadAssignment = 267,
EnumMember = 268,
SourceFile = 269,
Bundle = 270,
JSDocTypeExpression = 271,
JSDocAllType = 272,
JSDocUnknownType = 273,
JSDocNullableType = 274,
JSDocNonNullableType = 275,
JSDocOptionalType = 276,
JSDocFunctionType = 277,
JSDocVariadicType = 278,
JSDocComment = 279,
JSDocTypeLiteral = 280,
JSDocTag = 281,
JSDocAugmentsTag = 282,
JSDocClassTag = 283,
JSDocParameterTag = 284,
JSDocReturnTag = 285,
JSDocTypeTag = 286,
JSDocTemplateTag = 287,
JSDocTypedefTag = 288,
JSDocPropertyTag = 289,
SyntaxList = 290,
NotEmittedStatement = 291,
PartiallyEmittedExpression = 292,
CommaListExpression = 293,
MergeDeclarationMarker = 294,
EndOfDeclarationMarker = 295,
Count = 296,
FirstAssignment = 58,
LastAssignment = 70,
FirstCompoundAssignment = 59,
@@ -379,10 +382,10 @@ declare namespace ts {
FirstBinaryOperator = 27,
LastBinaryOperator = 70,
FirstNode = 144,
FirstJSDocNode = 268,
LastJSDocNode = 286,
FirstJSDocTagNode = 278,
LastJSDocTagNode = 286,
FirstJSDocNode = 271,
LastJSDocNode = 289,
FirstJSDocTagNode = 281,
LastJSDocTagNode = 289,
}
enum NodeFlags {
None = 0,
@@ -409,7 +412,7 @@ declare namespace ts {
BlockScoped = 3,
ReachabilityCheckFlags = 384,
ReachabilityAndEmitFlags = 1408,
ContextFlags = 2193408,
ContextFlags = 6387712,
TypeExcludesFlags = 20480,
}
enum ModifierFlags {
@@ -1062,6 +1065,20 @@ declare namespace ts {
tagName: JsxTagNameExpression;
attributes: JsxAttributes;
}
interface JsxFragment extends PrimaryExpression {
kind: SyntaxKind.JsxFragment;
openingFragment: JsxOpeningFragment;
children: NodeArray<JsxChild>;
closingFragment: JsxClosingFragment;
}
interface JsxOpeningFragment extends Expression {
kind: SyntaxKind.JsxOpeningFragment;
parent?: JsxFragment;
}
interface JsxClosingFragment extends Expression {
kind: SyntaxKind.JsxClosingFragment;
parent?: JsxFragment;
}
interface JsxAttribute extends ObjectLiteralElement {
kind: SyntaxKind.JsxAttribute;
parent?: JsxAttributes;
@@ -1089,7 +1106,7 @@ declare namespace ts {
containsOnlyWhiteSpaces: boolean;
parent?: JsxElement;
}
type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment;
interface Statement extends Node {
_statementBrand: any;
}
@@ -1607,9 +1624,7 @@ declare namespace ts {
fileExists(path: string): boolean;
readFile(path: string): string | undefined;
}
interface WriteFileCallback {
(fileName: string, data: string, writeByteOrderMark: boolean, onError: ((message: string) => void) | undefined, sourceFiles: ReadonlyArray<SourceFile>): void;
}
type WriteFileCallback = (fileName: string, data: string, writeByteOrderMark: boolean, onError: ((message: string) => void) | undefined, sourceFiles: ReadonlyArray<SourceFile>) => void;
class OperationCanceledException {
}
interface CancellationToken {
@@ -2748,9 +2763,7 @@ declare namespace ts {
let sys: System;
}
declare namespace ts {
interface ErrorCallback {
(message: DiagnosticMessage, length: number): void;
}
type ErrorCallback = (message: DiagnosticMessage, length: number) => void;
interface Scanner {
getStartPos(): number;
getToken(): SyntaxKind;
@@ -3064,6 +3077,9 @@ declare namespace ts {
function isJsxSelfClosingElement(node: Node): node is JsxSelfClosingElement;
function isJsxOpeningElement(node: Node): node is JsxOpeningElement;
function isJsxClosingElement(node: Node): node is JsxClosingElement;
function isJsxFragment(node: Node): node is JsxFragment;
function isJsxOpeningFragment(node: Node): node is JsxOpeningFragment;
function isJsxClosingFragment(node: Node): node is JsxClosingFragment;
function isJsxAttribute(node: Node): node is JsxAttribute;
function isJsxAttributes(node: Node): node is JsxAttributes;
function isJsxSpreadAttribute(node: Node): node is JsxSpreadAttribute;
@@ -3456,6 +3472,8 @@ declare namespace ts {
function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributes): JsxOpeningElement;
function createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement;
function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement;
function createJsxFragment(openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment): JsxFragment;
function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment): JsxFragment;
function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute;
function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute;
function createJsxAttributes(properties: ReadonlyArray<JsxAttributeLike>): JsxAttributes;
@@ -3923,7 +3941,7 @@ declare namespace ts {
getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[];
getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications;
getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications;
getCompletionsAtPosition(fileName: string, position: number): CompletionInfo;
getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): CompletionInfo;
getCompletionEntryDetails(fileName: string, position: number, name: string, options: FormatCodeOptions | FormatCodeSettings | undefined, source: string | undefined): CompletionEntryDetails;
getCompletionEntrySymbol(fileName: string, position: number, name: string, source: string | undefined): Symbol;
getQuickInfoAtPosition(fileName: string, position: number): QuickInfo;
@@ -3933,6 +3951,7 @@ declare namespace ts {
getRenameInfo(fileName: string, position: number): RenameInfo;
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[];
getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[];
getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan;
getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[];
getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[];
getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[];
@@ -3961,6 +3980,9 @@ declare namespace ts {
getProgram(): Program;
dispose(): void;
}
interface GetCompletionsAtPositionOptions {
includeExternalModuleExports: boolean;
}
interface ApplyCodeActionCommandResult {
successMessage: string;
}
@@ -4196,6 +4218,10 @@ declare namespace ts {
containerKind: ScriptElementKind;
containerName: string;
}
interface DefinitionInfoAndBoundSpan {
definitions: ReadonlyArray<DefinitionInfo>;
textSpan: TextSpan;
}
interface ReferencedSymbolDefinitionInfo extends DefinitionInfo {
displayParts: SymbolDisplayPart[];
}
@@ -4607,7 +4633,7 @@ declare namespace ts {
}
declare namespace ts {
/** The version of the language service API */
const servicesVersion = "0.6";
const servicesVersion = "0.7";
interface DisplayPartsSymbolWriter extends SymbolWriter {
displayParts(): SymbolDisplayPart[];
}
@@ -55,8 +55,8 @@ var myList: MyList<number>;
>MyList : MyList<T>
var xs = [list, myList]; // {}[]
>xs : List<number>[]
>[list, myList] : List<number>[]
>xs : (List<number> | MyList<number>)[]
>[list, myList] : (List<number> | MyList<number>)[]
>list : List<number>
>myList : MyList<number>
@@ -0,0 +1,56 @@
tests/cases/conformance/jsx/file.tsx(42,27): error TS2322: Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'.
Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'SingleChildProp'.
Types of property 'children' are incompatible.
Type 'Element[]' is not assignable to type 'Element'.
Property 'type' is missing in type 'Element[]'.
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
import React = require('react');
interface Prop {
a: number,
b: string,
children: JSX.Element | JSX.Element[];
}
class Button extends React.Component<any, any> {
render() {
return (<div>My Button</div>)
}
}
function AnotherButton(p: any) {
return <h1>Just Another Button</h1>;
}
function Comp(p: Prop) {
return <div>{p.b}</div>;
}
// OK
let k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>;
let k2 = <Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp>;
let k3 = <Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp>;
interface SingleChildProp {
a: number,
b: string,
children: JSX.Element;
}
function SingleChildComp(p: SingleChildProp) {
return <div>{p.b}</div>;
}
// OK
let k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>;
// Error
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
~~~~~~~~~~~~~
!!! error TS2322: Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'.
!!! error TS2322: Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'SingleChildProp'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type 'Element[]' is not assignable to type 'Element'.
!!! error TS2322: Property 'type' is missing in type 'Element[]'.
@@ -0,0 +1,85 @@
//// [file.tsx]
import React = require('react');
interface Prop {
a: number,
b: string,
children: JSX.Element | JSX.Element[];
}
class Button extends React.Component<any, any> {
render() {
return (<div>My Button</div>)
}
}
function AnotherButton(p: any) {
return <h1>Just Another Button</h1>;
}
function Comp(p: Prop) {
return <div>{p.b}</div>;
}
// OK
let k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>;
let k2 = <Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp>;
let k3 = <Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp>;
interface SingleChildProp {
a: number,
b: string,
children: JSX.Element;
}
function SingleChildComp(p: SingleChildProp) {
return <div>{p.b}</div>;
}
// OK
let k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>;
// Error
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
//// [file.jsx]
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
exports.__esModule = true;
var React = require("react");
var Button = /** @class */ (function (_super) {
__extends(Button, _super);
function Button() {
return _super !== null && _super.apply(this, arguments) || this;
}
Button.prototype.render = function () {
return (<div>My Button</div>);
};
return Button;
}(React.Component));
function AnotherButton(p) {
return <h1>Just Another Button</h1>;
}
function Comp(p) {
return <div>{p.b}</div>;
}
// OK
var k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>;
var k2 = <Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp>;
var k3 = <Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp>;
function SingleChildComp(p) {
return <div>{p.b}</div>;
}
// OK
var k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>;
// Error
var k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
@@ -0,0 +1,134 @@
=== tests/cases/conformance/jsx/file.tsx ===
import React = require('react');
>React : Symbol(React, Decl(file.tsx, 0, 0))
interface Prop {
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
a: number,
>a : Symbol(Prop.a, Decl(file.tsx, 2, 16))
b: string,
>b : Symbol(Prop.b, Decl(file.tsx, 3, 14))
children: JSX.Element | JSX.Element[];
>children : Symbol(Prop.children, Decl(file.tsx, 4, 14))
>JSX : Symbol(JSX, Decl(react.d.ts, 2353, 1))
>Element : Symbol(JSX.Element, Decl(react.d.ts, 2356, 27))
>JSX : Symbol(JSX, Decl(react.d.ts, 2353, 1))
>Element : Symbol(JSX.Element, Decl(react.d.ts, 2356, 27))
}
class Button extends React.Component<any, any> {
>Button : Symbol(Button, Decl(file.tsx, 6, 1))
>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66))
>React : Symbol(React, Decl(file.tsx, 0, 0))
>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66))
render() {
>render : Symbol(Button.render, Decl(file.tsx, 8, 48))
return (<div>My Button</div>)
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
}
}
function AnotherButton(p: any) {
>AnotherButton : Symbol(AnotherButton, Decl(file.tsx, 12, 1))
>p : Symbol(p, Decl(file.tsx, 14, 23))
return <h1>Just Another Button</h1>;
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2410, 47))
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2410, 47))
}
function Comp(p: Prop) {
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
>p : Symbol(p, Decl(file.tsx, 18, 14))
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
return <div>{p.b}</div>;
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
>p.b : Symbol(Prop.b, Decl(file.tsx, 3, 14))
>p : Symbol(p, Decl(file.tsx, 18, 14))
>b : Symbol(Prop.b, Decl(file.tsx, 3, 14))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
}
// OK
let k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>;
>k1 : Symbol(k1, Decl(file.tsx, 23, 3))
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
>a : Symbol(a, Decl(file.tsx, 23, 14))
>b : Symbol(b, Decl(file.tsx, 23, 21))
>Button : Symbol(Button, Decl(file.tsx, 6, 1))
>AnotherButton : Symbol(AnotherButton, Decl(file.tsx, 12, 1))
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
let k2 = <Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp>;
>k2 : Symbol(k2, Decl(file.tsx, 24, 3))
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
>a : Symbol(a, Decl(file.tsx, 24, 14))
>b : Symbol(b, Decl(file.tsx, 24, 21))
>Button : Symbol(Button, Decl(file.tsx, 6, 1))
>AnotherButton : Symbol(AnotherButton, Decl(file.tsx, 12, 1))
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
let k3 = <Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp>;
>k3 : Symbol(k3, Decl(file.tsx, 25, 3))
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
>a : Symbol(a, Decl(file.tsx, 25, 14))
>b : Symbol(b, Decl(file.tsx, 25, 21))
>Button : Symbol(Button, Decl(file.tsx, 6, 1))
>AnotherButton : Symbol(AnotherButton, Decl(file.tsx, 12, 1))
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
interface SingleChildProp {
>SingleChildProp : Symbol(SingleChildProp, Decl(file.tsx, 25, 69))
a: number,
>a : Symbol(SingleChildProp.a, Decl(file.tsx, 27, 27))
b: string,
>b : Symbol(SingleChildProp.b, Decl(file.tsx, 28, 14))
children: JSX.Element;
>children : Symbol(SingleChildProp.children, Decl(file.tsx, 29, 14))
>JSX : Symbol(JSX, Decl(react.d.ts, 2353, 1))
>Element : Symbol(JSX.Element, Decl(react.d.ts, 2356, 27))
}
function SingleChildComp(p: SingleChildProp) {
>SingleChildComp : Symbol(SingleChildComp, Decl(file.tsx, 31, 1))
>p : Symbol(p, Decl(file.tsx, 33, 25))
>SingleChildProp : Symbol(SingleChildProp, Decl(file.tsx, 25, 69))
return <div>{p.b}</div>;
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
>p.b : Symbol(SingleChildProp.b, Decl(file.tsx, 28, 14))
>p : Symbol(p, Decl(file.tsx, 33, 25))
>b : Symbol(SingleChildProp.b, Decl(file.tsx, 28, 14))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
}
// OK
let k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>;
>k4 : Symbol(k4, Decl(file.tsx, 38, 3))
>SingleChildComp : Symbol(SingleChildComp, Decl(file.tsx, 31, 1))
>a : Symbol(a, Decl(file.tsx, 38, 25))
>b : Symbol(b, Decl(file.tsx, 38, 32))
>Button : Symbol(Button, Decl(file.tsx, 6, 1))
>AnotherButton : Symbol(AnotherButton, Decl(file.tsx, 12, 1))
>SingleChildComp : Symbol(SingleChildComp, Decl(file.tsx, 31, 1))
// Error
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
>k5 : Symbol(k5, Decl(file.tsx, 41, 3))
>SingleChildComp : Symbol(SingleChildComp, Decl(file.tsx, 31, 1))
>a : Symbol(a, Decl(file.tsx, 41, 25))
>b : Symbol(b, Decl(file.tsx, 41, 32))
>Button : Symbol(Button, Decl(file.tsx, 6, 1))
>AnotherButton : Symbol(AnotherButton, Decl(file.tsx, 12, 1))
>SingleChildComp : Symbol(SingleChildComp, Decl(file.tsx, 31, 1))
@@ -0,0 +1,164 @@
=== tests/cases/conformance/jsx/file.tsx ===
import React = require('react');
>React : typeof React
interface Prop {
>Prop : Prop
a: number,
>a : number
b: string,
>b : string
children: JSX.Element | JSX.Element[];
>children : JSX.Element | JSX.Element[]
>JSX : any
>Element : JSX.Element
>JSX : any
>Element : JSX.Element
}
class Button extends React.Component<any, any> {
>Button : Button
>React.Component : React.Component<any, any>
>React : typeof React
>Component : typeof React.Component
render() {
>render : () => JSX.Element
return (<div>My Button</div>)
>(<div>My Button</div>) : JSX.Element
><div>My Button</div> : JSX.Element
>div : any
>div : any
}
}
function AnotherButton(p: any) {
>AnotherButton : (p: any) => JSX.Element
>p : any
return <h1>Just Another Button</h1>;
><h1>Just Another Button</h1> : JSX.Element
>h1 : any
>h1 : any
}
function Comp(p: Prop) {
>Comp : (p: Prop) => JSX.Element
>p : Prop
>Prop : Prop
return <div>{p.b}</div>;
><div>{p.b}</div> : JSX.Element
>div : any
>p.b : string
>p : Prop
>b : string
>div : any
}
// OK
let k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>;
>k1 : JSX.Element
><Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp> : JSX.Element
>Comp : (p: Prop) => JSX.Element
>a : number
>10 : 10
>b : string
><></> : JSX.Element
><Button /> : JSX.Element
>Button : typeof Button
><AnotherButton /> : JSX.Element
>AnotherButton : (p: any) => JSX.Element
>Comp : (p: Prop) => JSX.Element
let k2 = <Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp>;
>k2 : JSX.Element
><Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp> : JSX.Element
>Comp : (p: Prop) => JSX.Element
>a : number
>10 : 10
>b : string
><><Button /></> : JSX.Element
><Button /> : JSX.Element
>Button : typeof Button
><AnotherButton /> : JSX.Element
>AnotherButton : (p: any) => JSX.Element
>Comp : (p: Prop) => JSX.Element
let k3 = <Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp>;
>k3 : JSX.Element
><Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp> : JSX.Element
>Comp : (p: Prop) => JSX.Element
>a : number
>10 : 10
>b : string
><><Button /><AnotherButton /></> : JSX.Element
><Button /> : JSX.Element
>Button : typeof Button
><AnotherButton /> : JSX.Element
>AnotherButton : (p: any) => JSX.Element
>Comp : (p: Prop) => JSX.Element
interface SingleChildProp {
>SingleChildProp : SingleChildProp
a: number,
>a : number
b: string,
>b : string
children: JSX.Element;
>children : JSX.Element
>JSX : any
>Element : JSX.Element
}
function SingleChildComp(p: SingleChildProp) {
>SingleChildComp : (p: SingleChildProp) => JSX.Element
>p : SingleChildProp
>SingleChildProp : SingleChildProp
return <div>{p.b}</div>;
><div>{p.b}</div> : JSX.Element
>div : any
>p.b : string
>p : SingleChildProp
>b : string
>div : any
}
// OK
let k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>;
>k4 : JSX.Element
><SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp> : JSX.Element
>SingleChildComp : (p: SingleChildProp) => JSX.Element
>a : number
>10 : 10
>b : string
><><Button /><AnotherButton /></> : JSX.Element
><Button /> : JSX.Element
>Button : typeof Button
><AnotherButton /> : JSX.Element
>AnotherButton : (p: any) => JSX.Element
>SingleChildComp : (p: SingleChildProp) => JSX.Element
// Error
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
>k5 : JSX.Element
><SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp> : JSX.Element
>SingleChildComp : (p: SingleChildProp) => JSX.Element
>a : number
>10 : 10
>b : string
><></> : JSX.Element
><Button /> : JSX.Element
>Button : typeof Button
><AnotherButton /> : JSX.Element
>AnotherButton : (p: any) => JSX.Element
>SingleChildComp : (p: SingleChildProp) => JSX.Element
@@ -0,0 +1,9 @@
/a.js(1,7): error TS6133: 'x' is declared but its value is never read.
==== /a.js (1 errors) ====
const x = 0;
~
!!! error TS6133: 'x' is declared but its value is never read.
exports.y = 1;
@@ -0,0 +1,9 @@
=== /a.js ===
const x = 0;
>x : Symbol(x, Decl(a.js, 0, 5))
exports.y = 1;
>exports.y : Symbol(y, Decl(a.js, 0, 12))
>exports : Symbol(y, Decl(a.js, 0, 12))
>y : Symbol(y, Decl(a.js, 0, 12))
@@ -0,0 +1,12 @@
=== /a.js ===
const x = 0;
>x : 0
>0 : 0
exports.y = 1;
>exports.y = 1 : 1
>exports.y : number
>exports : typeof "/a"
>y : number
>1 : 1
@@ -0,0 +1,13 @@
tests/cases/compiler/declarationEmitRelativeModuleError.ts(5,16): error TS2436: Ambient module declaration cannot specify relative module name.
==== tests/cases/compiler/declarationEmitRelativeModuleError.ts (1 errors) ====
declare module "b:block" { // <-- no error anymore
}
declare module "b:/block" { // <-- still an error
~~~~~~~~~~
!!! error TS2436: Ambient module declaration cannot specify relative module name.
}
@@ -0,0 +1,10 @@
//// [declarationEmitRelativeModuleError.ts]
declare module "b:block" { // <-- no error anymore
}
declare module "b:/block" { // <-- still an error
}
//// [declarationEmitRelativeModuleError.js]
@@ -0,0 +1,9 @@
=== tests/cases/compiler/declarationEmitRelativeModuleError.ts ===
declare module "b:block" { // <-- no error anymore
No type information for this code.
No type information for this code.}
No type information for this code.
No type information for this code.declare module "b:/block" { // <-- still an error
No type information for this code.
No type information for this code.}
No type information for this code.

Some files were not shown because too many files have changed in this diff Show More