mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge master into release-2.9 (#24228)
* Optimize intersections of unions of unit types * Add regression test * Accept new baselines * LEGO: check in for master to temporary branch. * Add Unicode ThirdPartyNotice * Properly handle edge cases * Sort the whole diagnostic, plus giving up on isolating tests (#24186) * Sort the whole diagnostic * Also strip references to our repos node_modules, since removing it is hard * LEGO: check in for master to temporary branch. * add quick fix for import type missing typeof * Add callback tag, with type parameters (#23947) * Add initial tests * Add types * Half of parsing (builds but does not pass tests) * Parsing done; types are uglier; doesn't crash but doesn't pass * Bind callback tag Builds but tests still don't pass * Only bind param tags inside callback tags * Fix binding switch to only handle param tags once * Checking is 1/3 done or so. Now I'm going to go rename some members to be more uniform. I hate unnnecessary conditionals. * Rename typeExpression to type (for some jsdoc) (maybe I'll rename more later) * Rename the rest of typeExpressions Turns out there is a constraint in services such that they all need to be named the same. * Few more checker changes * Revert "Rename the rest of typeExpressions" This reverts commitf41a96b24d. * Revert "Rename typeExpression to type (for some jsdoc)" This reverts commit7d2233a00e. * Finish undoing typeExpression rename * Rename and improve getTypeParametersForAliasSymbol Plus some other small fixes * Core checking works, but is flabbergastingly messy I'm serious. * Callback return types work now * Fix crash in services * Make github diff smaller * Try to make github diff even smaller * Fix rename for callback tag * Fix nav bar for callback tag Also clean up some now-redundant code there to find the name of typedefs. * Handle ooorder callback tags Also get rid of redundant typedef name code *in the binder*. It's everywhere! * Add ooorder callback tag test * Parse comments for typedef/callback+display param comments * Always export callbacks This requires almost no new code since it is basically the same as typedefs * Update baselines * Fix support for nested namespaced callbacks And add test * Callbacks support type parameters 1. Haven't run it with all tests 2. Haven't tested typedef tags yet 3. Still allows shared symbols when on function or class declarations. * Template tags are now bound correctly * Test oorder template tags It works. * Parser cleanup * Cleanup types and utilities As much as possible, and not as much as I would like. * Handle callback more often in services * Cleanup of binder and checker * More checker cleanup * Remove TODOs and one more cleanup * Support parameter-less callback tags * Remove extra bind call on template type parameters * Bind template tag containers Doesn't quite work with typedefs, but that's because it's now stricter, without the typedef fixes. I'm going to merge with jsdoc/callback and see how it goes. * Fix fourslash failures * Stop pre-binding js type aliases Next up, stop pre-binding js type parameters * Further cleanup of delayed js type alias binding * Stop prebinding template tags too This gets rid of prebinding entirely * Remove TODO * Fix lint * Finish merge with use-jsdoc-aliases * Update callback tag baselines * Rename getTypeParametersForAliasSymbol The real fix is *probably* to rename Type.aliasTypeArguments to aliasTypeParameters, but I want to make sure and then put it in a separate PR. * moveToNewFile: Don't move imports (#24177) * Reduce map lookups (#24203) * Fix jsdoc type resolution [merge to master] (#24204) * Fix JSDoc type resolution Breaks type parameter resolution that is looked up through prototype methods, though. I need to fix that still. * Check for prototype method assignments first * Undo dedupe changes to getJSDocTags * JS Type aliases can't refer to host type params Previously, js type aliases (@typedef and @callback) could refer to type paremeters defined in @template tags in a *different* jsdoc tag, as long as both tags were hosted on the same signature. * Reduce dedupe changes+update baseline The only reason I had undone them was to merge successfully with an older state of master. * Add undefined guard * moveToNewFile: Fix bug for VariableDeclaration missing initializer (#24214) * Use import types to refer to declarations in declaration emit (#24071) * Stand up a simple implementation using import types for exports of modules which are otherwise inaccessible * Ensure references exist to link to modules containing utilized ambient modules * Accept baselines with new import type usage * Fix lint * Accept changed baseline (#24222) * fixUnusedIdentifier: Don't delete node whose ancestor was already deleted (#24207) * More robust circularity detection in node builder (#24225) * Improve ChangeTracker#deleteNodeInList (#24221) * moveToNewFile: Fix bug for missing importClause (#24224) * Set startPos at EOF in jsdoc token scanner so node end positions for nodes terminated at EoF are right (#24184) * Set startPos at EOF in jsdoc token scanner to node end positions for nodes terminated at EoF are right * More complete nonwhitespace token check, fix syntactica jsdoc classifier * Use loop and no nested lookahead * Do thigns unrelated to the bug in the test * Fix typo move return * Patch up typedef end pos * Fix indentation, make end pos target more obvious
This commit is contained in:
+76
-15
@@ -1,35 +1,96 @@
|
||||
/*!----------------- TypeScript ThirdPartyNotices -------------------------------------------------------
|
||||
|
||||
The TypeScript software is based on or incorporates material and code from the projects listed below
|
||||
(collectively "Third Party Code"). Microsoft is not the original author of the
|
||||
Third Party Code. The original copyright notice and the license, under which
|
||||
Microsoft received such Third Party Code, are set forth below. Such license and
|
||||
notices are provided for informational purposes only. Microsoft licenses the Third
|
||||
The TypeScript software is based on or incorporates material and code from the projects listed below
|
||||
(collectively "Third Party Code"). Microsoft is not the original author of the
|
||||
Third Party Code. The original copyright notice and the license, under which
|
||||
Microsoft received such Third Party Code, are set forth below. Such license and
|
||||
notices are provided for informational purposes only. Microsoft licenses the Third
|
||||
Party Code to you under the terms of the Apache 2.0 License.
|
||||
All Third Party Code licensed by Microsoft under the Apache License, Version 2.0 (the "License"); you
|
||||
may not use this file except in compliance with the License. You may obtain a copy
|
||||
All Third Party Code licensed by Microsoft under the Apache License, Version 2.0 (the "License"); you
|
||||
may not use this file except in compliance with the License. You may obtain a copy
|
||||
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
|
||||
CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
|
||||
CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions and
|
||||
See the Apache Version 2.0 License for specific language governing permissions and
|
||||
limitations under the License.
|
||||
---------------------------------------------
|
||||
Third Party Code Components
|
||||
--------------------------------------------
|
||||
|
||||
------------------- DefinitelyTyped --------------------
|
||||
This file is based on or incorporates material from the projects listed below (collectively "Third Party Code"). Microsoft is not the original author of the Third Party Code. The original copyright notice and the license, under which Microsoft received such Third Party Code, are set forth below. Such licenses and notices are provided for informational purposes only. Microsoft, not the third party, licenses the Third Party Code to you under the terms set forth in the EULA for the Microsoft Product. Microsoft reserves all other rights not expressly granted under this agreement, whether by implication, estoppel or otherwise.
|
||||
This file is based on or incorporates material from the projects listed below (collectively "Third Party Code"). Microsoft is not the original author of the Third Party Code. The original copyright notice and the license, under which Microsoft received such Third Party Code, are set forth below. Such licenses and notices are provided for informational purposes only. Microsoft, not the third party, licenses the Third Party Code to you under the terms set forth in the EULA for the Microsoft Product. Microsoft reserves all other rights not expressly granted under this agreement, whether by implication, estoppel or otherwise.
|
||||
DefinitelyTyped
|
||||
This project is licensed under the MIT license.
|
||||
Copyrights are respective of each contributor listed at the beginning of each definition file.
|
||||
Provided for Informational Purposes Only
|
||||
|
||||
MIT License
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
MIT License
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
------------------- Unicode --------------------
|
||||
UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
|
||||
|
||||
Unicode Data Files include all data files under the directories
|
||||
http://www.unicode.org/Public/, http://www.unicode.org/reports/,
|
||||
http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/, and
|
||||
http://www.unicode.org/utility/trac/browser/.
|
||||
|
||||
Unicode Data Files do not include PDF online code charts under the
|
||||
directory http://www.unicode.org/Public/.
|
||||
|
||||
Software includes any source code published in the Unicode Standard
|
||||
or under the directories
|
||||
http://www.unicode.org/Public/, http://www.unicode.org/reports/,
|
||||
http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/, and
|
||||
http://www.unicode.org/utility/trac/browser/.
|
||||
|
||||
NOTICE TO USER: Carefully read the following legal agreement.
|
||||
BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
|
||||
DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
|
||||
YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
|
||||
TERMS AND CONDITIONS OF THIS AGREEMENT.
|
||||
IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
|
||||
THE DATA FILES OR SOFTWARE.
|
||||
|
||||
COPYRIGHT AND PERMISSION NOTICE
|
||||
|
||||
Copyright (c) 1991-2017 Unicode, Inc. All rights reserved.
|
||||
Distributed under the Terms of Use in http://www.unicode.org/copyright.html.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Unicode data files and any associated documentation
|
||||
(the "Data Files") or Unicode software and any associated documentation
|
||||
(the "Software") to deal in the Data Files or Software
|
||||
without restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, and/or sell copies of
|
||||
the Data Files or Software, and to permit persons to whom the Data Files
|
||||
or Software are furnished to do so, provided that either
|
||||
(a) this copyright and permission notice appear with all copies
|
||||
of the Data Files or Software, or
|
||||
(b) this copyright and permission notice appear in associated
|
||||
Documentation.
|
||||
|
||||
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
|
||||
NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THE DATA FILES OR SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of a copyright holder
|
||||
shall not be used in advertising or otherwise to promote the sale,
|
||||
use or other dealings in these Data Files or Software without prior
|
||||
written authorization of the copyright holder.
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
------------- End of ThirdPartyNotices --------------------------------------------------- */
|
||||
|
||||
+75
-88
@@ -118,7 +118,7 @@ namespace ts {
|
||||
let thisParentContainer: Node; // Container one level up
|
||||
let blockScopeContainer: Node;
|
||||
let lastContainer: Node;
|
||||
let delayedTypedefs: { typedef: JSDocTypedefTag, container: Node, lastContainer: Node, blockScopeContainer: Node, parent: Node }[];
|
||||
let delayedTypeAliases: (JSDocTypedefTag | JSDocCallbackTag)[];
|
||||
let seenThisKeyword: boolean;
|
||||
|
||||
// state used by control flow analysis
|
||||
@@ -188,7 +188,7 @@ namespace ts {
|
||||
thisParentContainer = undefined;
|
||||
blockScopeContainer = undefined;
|
||||
lastContainer = undefined;
|
||||
delayedTypedefs = undefined;
|
||||
delayedTypeAliases = undefined;
|
||||
seenThisKeyword = false;
|
||||
currentFlow = undefined;
|
||||
currentBreakTarget = undefined;
|
||||
@@ -273,6 +273,7 @@ namespace ts {
|
||||
return InternalSymbolName.Constructor;
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.JSDocSignature:
|
||||
return InternalSymbolName.Call;
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
@@ -301,9 +302,6 @@ namespace ts {
|
||||
const functionType = <JSDocFunctionType>node.parent;
|
||||
const index = functionType.parameters.indexOf(node as ParameterDeclaration);
|
||||
return "arg" + index as __String;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
const name = getNameOfJSDocTypedef(node as JSDocTypedefTag);
|
||||
return typeof name !== "undefined" ? name.escapedText : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,8 +454,8 @@ namespace ts {
|
||||
// during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
|
||||
// and this case is specially handled. Module augmentations should only be merged with original module definition
|
||||
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
|
||||
if (node.kind === SyntaxKind.JSDocTypedefTag) Debug.assert(isInJavaScriptFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
|
||||
if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypedefTag(node)) {
|
||||
if (isJSDocTypeAlias(node)) Debug.assert(isInJavaScriptFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
|
||||
if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypeAlias(node)) {
|
||||
if (hasModifier(node, ModifierFlags.Default) && !getDeclarationName(node)) {
|
||||
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); // No local symbol for an unnamed default!
|
||||
}
|
||||
@@ -628,22 +626,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindChildrenWorker(node: Node): void {
|
||||
// Binding of JsDocComment should be done before the current block scope container changes.
|
||||
// because the scope of JsDocComment should not be affected by whether the current node is a
|
||||
// container or not.
|
||||
if (hasJSDocNodes(node)) {
|
||||
if (isInJavaScriptFile(node)) {
|
||||
for (const j of node.jsDoc) {
|
||||
bind(j);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const j of node.jsDoc) {
|
||||
setParentPointers(node, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (checkUnreachable(node)) {
|
||||
bindEachChild(node);
|
||||
return;
|
||||
@@ -709,11 +691,9 @@ namespace ts {
|
||||
case SyntaxKind.CallExpression:
|
||||
bindCallExpressionFlow(<CallExpression>node);
|
||||
break;
|
||||
case SyntaxKind.JSDocComment:
|
||||
bindJSDocComment(<JSDoc>node);
|
||||
break;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
bindJSDocTypedefTag(<JSDocTypedefTag>node);
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
bindJSDocTypeAlias(node as JSDocTypedefTag | JSDocCallbackTag);
|
||||
break;
|
||||
// In source files and blocks, bind functions first to match hoisting that occurs at runtime
|
||||
case SyntaxKind.SourceFile:
|
||||
@@ -728,6 +708,7 @@ namespace ts {
|
||||
bindEachChild(node);
|
||||
break;
|
||||
}
|
||||
bindJSDoc(node);
|
||||
}
|
||||
|
||||
function isNarrowingExpression(expr: Expression): boolean {
|
||||
@@ -1379,24 +1360,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function bindJSDocComment(node: JSDoc) {
|
||||
forEachChild(node, n => {
|
||||
if (n.kind !== SyntaxKind.JSDocTypedefTag) {
|
||||
bind(n);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function bindJSDocTypedefTag(node: JSDocTypedefTag) {
|
||||
forEachChild(node, n => {
|
||||
// if the node has a fullName "A.B.C", that means symbol "C" was already bound
|
||||
// when we visit "fullName"; so when we visit the name "C" as the next child of
|
||||
// the jsDocTypedefTag, we should skip binding it.
|
||||
if (node.fullName && n === node.name && node.fullName.kind !== SyntaxKind.Identifier) {
|
||||
return;
|
||||
}
|
||||
bind(n);
|
||||
});
|
||||
function bindJSDocTypeAlias(node: JSDocTypedefTag | JSDocCallbackTag) {
|
||||
if (node.fullName) {
|
||||
setParentPointers(node, node.fullName);
|
||||
}
|
||||
}
|
||||
|
||||
function bindCallExpressionFlow(node: CallExpression) {
|
||||
@@ -1456,6 +1423,7 @@ namespace ts {
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.JSDocSignature:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
@@ -1545,6 +1513,7 @@ namespace ts {
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.JSDocSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
@@ -1555,6 +1524,8 @@ namespace ts {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.MappedType:
|
||||
// All the children of these container types are never visible through another
|
||||
@@ -1650,7 +1621,7 @@ namespace ts {
|
||||
return state;
|
||||
}
|
||||
|
||||
function bindFunctionOrConstructorType(node: SignatureDeclaration): void {
|
||||
function bindFunctionOrConstructorType(node: SignatureDeclaration | JSDocSignature): void {
|
||||
// For a given function symbol "<...>(...) => T" we want to generate a symbol identical
|
||||
// to the one we would get for: { <...>(...): T }
|
||||
//
|
||||
@@ -1752,21 +1723,34 @@ namespace ts {
|
||||
}
|
||||
|
||||
function delayedBindJSDocTypedefTag() {
|
||||
if (!delayedTypedefs) {
|
||||
if (!delayedTypeAliases) {
|
||||
return;
|
||||
}
|
||||
const saveContainer = container;
|
||||
const saveLastContainer = lastContainer;
|
||||
const saveBlockScopeContainer = blockScopeContainer;
|
||||
const saveParent = parent;
|
||||
for (const delay of delayedTypedefs) {
|
||||
({ container, lastContainer, blockScopeContainer, parent } = delay);
|
||||
bindBlockScopedDeclaration(delay.typedef, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
|
||||
const saveCurrentFlow = currentFlow;
|
||||
for (const typeAlias of delayedTypeAliases) {
|
||||
const host = getJSDocHost(typeAlias);
|
||||
container = findAncestor(host.parent, n => !!(getContainerFlags(n) & ContainerFlags.IsContainer)) || file;
|
||||
blockScopeContainer = getEnclosingBlockScopeContainer(host) || file;
|
||||
currentFlow = { flags: FlowFlags.Start };
|
||||
parent = typeAlias;
|
||||
bind(typeAlias.typeExpression);
|
||||
if (!typeAlias.fullName || typeAlias.fullName.kind === SyntaxKind.Identifier) {
|
||||
parent = typeAlias.parent;
|
||||
bindBlockScopedDeclaration(typeAlias, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
|
||||
}
|
||||
else {
|
||||
bind(typeAlias.fullName);
|
||||
}
|
||||
}
|
||||
container = saveContainer;
|
||||
lastContainer = saveLastContainer;
|
||||
blockScopeContainer = saveBlockScopeContainer;
|
||||
parent = saveParent;
|
||||
currentFlow = saveCurrentFlow;
|
||||
}
|
||||
|
||||
// The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
|
||||
@@ -1946,7 +1930,6 @@ namespace ts {
|
||||
// Here the current node is "foo", which is a container, but the scope of "MyType" should
|
||||
// not be inside "foo". Therefore we always bind @typedef before bind the parent node,
|
||||
// and skip binding this tag later when binding all the other jsdoc tags.
|
||||
if (isInJavaScriptFile(node)) bindJSDocTypedefTagIfAny(node);
|
||||
|
||||
// First we bind declaration nodes to a symbol if possible. We'll both create a symbol
|
||||
// and then potentially add the symbol to an appropriate symbol table. Possible
|
||||
@@ -1978,26 +1961,21 @@ namespace ts {
|
||||
}
|
||||
else if (!skipTransformFlagAggregation && (node.transformFlags & TransformFlags.HasComputedFlags) === 0) {
|
||||
subtreeTransformFlags |= computeTransformFlagsForNode(node, 0);
|
||||
bindJSDoc(node);
|
||||
}
|
||||
inStrictMode = saveInStrictMode;
|
||||
}
|
||||
|
||||
function bindJSDocTypedefTagIfAny(node: Node) {
|
||||
if (!hasJSDocNodes(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const jsDoc of node.jsDoc) {
|
||||
if (!jsDoc.tags) {
|
||||
continue;
|
||||
function bindJSDoc(node: Node) {
|
||||
if (hasJSDocNodes(node)) {
|
||||
if (isInJavaScriptFile(node)) {
|
||||
for (const j of node.jsDoc) {
|
||||
bind(j);
|
||||
}
|
||||
}
|
||||
|
||||
for (const tag of jsDoc.tags) {
|
||||
if (tag.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
const savedParent = parent;
|
||||
parent = jsDoc;
|
||||
bind(tag);
|
||||
parent = savedParent;
|
||||
else {
|
||||
for (const j of node.jsDoc) {
|
||||
setParentPointers(node, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2036,10 +2014,10 @@ namespace ts {
|
||||
// current "blockScopeContainer" needs to be set to its immediate namespace parent.
|
||||
if ((<Identifier>node).isInJSDocNamespace) {
|
||||
let parentNode = node.parent;
|
||||
while (parentNode && parentNode.kind !== SyntaxKind.JSDocTypedefTag) {
|
||||
while (parentNode && !isJSDocTypeAlias(parentNode)) {
|
||||
parentNode = parentNode.parent;
|
||||
}
|
||||
bindBlockScopedDeclaration(<Declaration>parentNode, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
|
||||
bindBlockScopedDeclaration(parentNode as Declaration, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
|
||||
break;
|
||||
}
|
||||
// falls through
|
||||
@@ -2141,8 +2119,9 @@ namespace ts {
|
||||
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes);
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.JSDocSignature:
|
||||
case SyntaxKind.ConstructorType:
|
||||
return bindFunctionOrConstructorType(<SignatureDeclaration>node);
|
||||
return bindFunctionOrConstructorType(<SignatureDeclaration | JSDocSignature>node);
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.MappedType:
|
||||
@@ -2205,6 +2184,9 @@ namespace ts {
|
||||
return updateStrictModeStatementList((<Block | ModuleBlock>node).statements);
|
||||
|
||||
case SyntaxKind.JSDocParameterTag:
|
||||
if (node.parent.kind === SyntaxKind.JSDocSignature) {
|
||||
return bindParameter(node as JSDocParameterTag);
|
||||
}
|
||||
if (node.parent.kind !== SyntaxKind.JSDocTypeLiteral) {
|
||||
break;
|
||||
}
|
||||
@@ -2215,13 +2197,9 @@ namespace ts {
|
||||
SymbolFlags.Property | SymbolFlags.Optional :
|
||||
SymbolFlags.Property;
|
||||
return declareSymbolAndAddToSymbolTable(propTag, flags, SymbolFlags.PropertyExcludes);
|
||||
case SyntaxKind.JSDocTypedefTag: {
|
||||
const { fullName } = node as JSDocTypedefTag;
|
||||
if (!fullName || fullName.kind === SyntaxKind.Identifier) {
|
||||
(delayedTypedefs || (delayedTypedefs = [])).push({ typedef: node as JSDocTypedefTag, container, lastContainer, blockScopeContainer, parent });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
return (delayedTypeAliases || (delayedTypeAliases = [])).push(node as JSDocTypedefTag | JSDocCallbackTag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2622,7 +2600,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function bindParameter(node: ParameterDeclaration) {
|
||||
function bindParameter(node: ParameterDeclaration | JSDocParameterTag) {
|
||||
if (node.kind === SyntaxKind.JSDocParameterTag && container.kind !== SyntaxKind.JSDocSignature) {
|
||||
return;
|
||||
}
|
||||
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)
|
||||
@@ -2630,7 +2611,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (isBindingPattern(node.name)) {
|
||||
bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, "__" + node.parent.parameters.indexOf(node) as __String);
|
||||
bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, "__" + (node as ParameterDeclaration).parent.parameters.indexOf(node as ParameterDeclaration) as __String);
|
||||
}
|
||||
else {
|
||||
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
|
||||
@@ -2690,18 +2671,24 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getInferTypeContainer(node: Node): ConditionalTypeNode {
|
||||
while (node) {
|
||||
const parent = node.parent;
|
||||
if (parent && parent.kind === SyntaxKind.ConditionalType && (<ConditionalTypeNode>parent).extendsType === node) {
|
||||
return <ConditionalTypeNode>parent;
|
||||
}
|
||||
node = parent;
|
||||
}
|
||||
return undefined;
|
||||
const extendsType = findAncestor(node, n => n.parent && isConditionalTypeNode(n.parent) && n.parent.extendsType === n);
|
||||
return extendsType && extendsType.parent as ConditionalTypeNode;
|
||||
}
|
||||
|
||||
function bindTypeParameter(node: TypeParameterDeclaration) {
|
||||
if (node.parent.kind === SyntaxKind.InferType) {
|
||||
if (isJSDocTemplateTag(node.parent)) {
|
||||
const container = find((node.parent.parent as JSDoc).tags, isJSDocTypeAlias) || getHostSignatureFromJSDoc(node.parent);
|
||||
if (container) {
|
||||
if (!container.locals) {
|
||||
container.locals = createSymbolTable();
|
||||
}
|
||||
declareSymbol(container.locals, /*parent*/ undefined, node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
|
||||
}
|
||||
else {
|
||||
declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
|
||||
}
|
||||
}
|
||||
else if (node.parent.kind === SyntaxKind.InferType) {
|
||||
const container = getInferTypeContainer(node.parent);
|
||||
if (container) {
|
||||
if (!container.locals) {
|
||||
@@ -3804,6 +3791,6 @@ namespace ts {
|
||||
*/
|
||||
function setParentPointers(parent: Node, child: Node): void {
|
||||
child.parent = parent;
|
||||
forEachChild(child, (childsChild) => setParentPointers(child, childsChild));
|
||||
forEachChild(child, grandchild => setParentPointers(child, grandchild));
|
||||
}
|
||||
}
|
||||
|
||||
+268
-153
@@ -1453,6 +1453,12 @@ namespace ts {
|
||||
location = location.parent;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
// js type aliases do not resolve names from their host, so skip past it
|
||||
lastLocation = location;
|
||||
location = getJSDocHost(location).parent;
|
||||
continue;
|
||||
}
|
||||
if (isSelfReferenceLocation(location)) {
|
||||
lastSelfReferenceLocation = location;
|
||||
@@ -1577,9 +1583,11 @@ namespace ts {
|
||||
|
||||
function isTypeParameterSymbolDeclaredInContainer(symbol: Symbol, container: Node) {
|
||||
for (const decl of symbol.declarations) {
|
||||
const parent = isJSDocTemplateTag(decl.parent) ? getJSDocHost(decl.parent) : decl.parent;
|
||||
if (decl.kind === SyntaxKind.TypeParameter && parent === container) {
|
||||
return true;
|
||||
if (decl.kind === SyntaxKind.TypeParameter) {
|
||||
const parent = isJSDocTemplateTag(decl.parent) ? getJSDocHost(decl.parent) : decl.parent;
|
||||
if (parent === container) {
|
||||
return !(isJSDocTemplateTag(decl.parent) && find((decl.parent.parent as JSDoc).tags, isJSDocTypeAlias));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2089,7 +2097,7 @@ namespace ts {
|
||||
let symbol: Symbol;
|
||||
if (name.kind === SyntaxKind.Identifier) {
|
||||
const message = meaning === namespaceMeaning ? Diagnostics.Cannot_find_namespace_0 : Diagnostics.Cannot_find_name_0;
|
||||
const symbolFromJSPrototype = isInJavaScriptFile(name) ? resolveEntityNameFromJSPrototype(name, meaning) : undefined;
|
||||
const symbolFromJSPrototype = isInJavaScriptFile(name) ? resolveEntityNameFromJSSpecialAssignment(name, meaning) : undefined;
|
||||
symbol = resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true);
|
||||
if (!symbol) {
|
||||
return symbolFromJSPrototype;
|
||||
@@ -2144,25 +2152,40 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* For prototype-property methods like `A.prototype.m = function () ...`, try to resolve names in the scope of `A` too.
|
||||
* 1. For prototype-property methods like `A.prototype.m = function () ...`, try to resolve names in the scope of `A` too.
|
||||
* Note that prototype-property assignment to locations outside the current file (eg globals) doesn't work, so
|
||||
* name resolution won't work either.
|
||||
* 2. For property assignments like `{ x: function f () { } }`, try to resolve names in the scope of `f` too.
|
||||
*/
|
||||
function resolveEntityNameFromJSPrototype(name: Identifier, meaning: SymbolFlags) {
|
||||
if (isJSDocTypeReference(name.parent) && isJSDocTag(name.parent.parent.parent)) {
|
||||
const host = getJSDocHost(name.parent.parent.parent as JSDocTag);
|
||||
if (isExpressionStatement(host) &&
|
||||
isBinaryExpression(host.expression) &&
|
||||
getSpecialPropertyAssignmentKind(host.expression) === SpecialPropertyAssignmentKind.PrototypeProperty) {
|
||||
const symbol = getSymbolOfNode(host.expression.left);
|
||||
if (symbol) {
|
||||
const secondaryLocation = symbol.parent.valueDeclaration;
|
||||
return resolveName(secondaryLocation, name.escapedText, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ true);
|
||||
}
|
||||
function resolveEntityNameFromJSSpecialAssignment(name: Identifier, meaning: SymbolFlags) {
|
||||
if (isJSDocTypeReference(name.parent)) {
|
||||
const secondaryLocation = getJSSpecialAssignmentLocation(name.parent);
|
||||
if (secondaryLocation) {
|
||||
return resolveName(secondaryLocation, name.escapedText, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getJSSpecialAssignmentLocation(node: TypeReferenceNode): Declaration | undefined {
|
||||
const typeAlias = findAncestor(node, node => !(isJSDocNode(node) || node.flags & NodeFlags.JSDoc) ? "quit" : isJSDocTypeAlias(node));
|
||||
if (typeAlias) {
|
||||
return;
|
||||
}
|
||||
const host = getJSDocHost(node);
|
||||
if (host &&
|
||||
isExpressionStatement(host) &&
|
||||
isBinaryExpression(host.expression) &&
|
||||
getSpecialPropertyAssignmentKind(host.expression) === SpecialPropertyAssignmentKind.PrototypeProperty) {
|
||||
const symbol = getSymbolOfNode(host.expression.left);
|
||||
return symbol && symbol.parent.valueDeclaration;
|
||||
}
|
||||
const sig = getHostSignatureFromJSDocHost(host);
|
||||
if (sig) {
|
||||
const symbol = getSymbolOfNode(sig);
|
||||
return symbol && symbol.valueDeclaration;
|
||||
}
|
||||
}
|
||||
|
||||
function resolveExternalModuleName(location: Node, moduleReferenceExpression: Expression): Symbol {
|
||||
return resolveExternalModuleNameWorker(location, moduleReferenceExpression, Diagnostics.Cannot_find_module_0);
|
||||
}
|
||||
@@ -2771,6 +2794,14 @@ namespace ts {
|
||||
}
|
||||
return hasAccessibleDeclarations;
|
||||
}
|
||||
else {
|
||||
if (some(symbol.declarations, hasExternalModuleSymbol)) {
|
||||
// Any meaning of a module symbol is always accessible via an `import` type
|
||||
return {
|
||||
accessibility: SymbolAccessibility.Accessible
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// If we haven't got the accessible symbol, it doesn't mean the symbol is actually inaccessible.
|
||||
// It could be a qualified symbol and hence verify the path
|
||||
@@ -3029,7 +3060,7 @@ namespace ts {
|
||||
flags,
|
||||
tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: noop },
|
||||
encounteredError: false,
|
||||
symbolStack: undefined,
|
||||
visitedSymbols: undefined,
|
||||
inferTypeParameters: undefined
|
||||
};
|
||||
}
|
||||
@@ -3141,9 +3172,9 @@ namespace ts {
|
||||
return createTypeReferenceNode(name, /*typeArguments*/ undefined);
|
||||
}
|
||||
if (!inTypeAlias && type.aliasSymbol && (context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope || isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration))) {
|
||||
const name = symbolToTypeReferenceName(type.aliasSymbol);
|
||||
const typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context);
|
||||
return createTypeReferenceNode(name, typeArgumentNodes);
|
||||
if (isReservedMemberName(type.aliasSymbol.escapedName) && !(type.aliasSymbol.flags & SymbolFlags.Class)) return createTypeReferenceNode(createIdentifier(""), typeArgumentNodes);
|
||||
return symbolToTypeNode(type.aliasSymbol, context, SymbolFlags.Type, typeArgumentNodes);
|
||||
}
|
||||
if (type.flags & (TypeFlags.Union | TypeFlags.Intersection)) {
|
||||
const types = type.flags & TypeFlags.Union ? formatUnionTypes((<UnionType>type).types) : (<IntersectionType>type).types;
|
||||
@@ -3211,7 +3242,10 @@ namespace ts {
|
||||
|
||||
function createAnonymousTypeNode(type: ObjectType): TypeNode {
|
||||
const symbol = type.symbol;
|
||||
let id: string;
|
||||
if (symbol) {
|
||||
const isConstructorObject = getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.Class;
|
||||
id = (isConstructorObject ? "+" : "") + getSymbolId(symbol);
|
||||
if (isJavaScriptConstructor(symbol.valueDeclaration)) {
|
||||
// Instance and static types share the same symbol; only add 'typeof' for the static side.
|
||||
const isInstanceType = type === getInferredClassType(symbol) ? SymbolFlags.Type : SymbolFlags.Value;
|
||||
@@ -3223,7 +3257,7 @@ namespace ts {
|
||||
shouldWriteTypeOfFunctionSymbol()) {
|
||||
return symbolToTypeNode(symbol, context, SymbolFlags.Value);
|
||||
}
|
||||
else if (contains(context.symbolStack, symbol)) {
|
||||
else if (context.visitedSymbols && context.visitedSymbols.has(id)) {
|
||||
// If type is an anonymous type literal in a type alias declaration, use type alias name
|
||||
const typeAlias = getTypeAliasForTypeLiteral(type);
|
||||
if (typeAlias) {
|
||||
@@ -3237,20 +3271,14 @@ namespace ts {
|
||||
else {
|
||||
// Since instantiations of the same anonymous type have the same symbol, tracking symbols instead
|
||||
// of types allows us to catch circular references to instantiations of the same anonymous type
|
||||
if (!context.symbolStack) {
|
||||
context.symbolStack = [];
|
||||
if (!context.visitedSymbols) {
|
||||
context.visitedSymbols = createMap<true>();
|
||||
}
|
||||
|
||||
const isConstructorObject = getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.Class;
|
||||
if (isConstructorObject) {
|
||||
return createTypeNodeFromObjectType(type);
|
||||
}
|
||||
else {
|
||||
context.symbolStack.push(symbol);
|
||||
const result = createTypeNodeFromObjectType(type);
|
||||
context.symbolStack.pop();
|
||||
return result;
|
||||
}
|
||||
context.visitedSymbols.set(id, true);
|
||||
const result = createTypeNodeFromObjectType(type);
|
||||
context.visitedSymbols.delete(id);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -3267,7 +3295,7 @@ namespace ts {
|
||||
declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock));
|
||||
if (isStaticMethodSymbol || isNonLocalFunctionSymbol) {
|
||||
// typeof is allowed only for static/non local functions
|
||||
return (!!(context.flags & NodeBuilderFlags.UseTypeOfFunction) || contains(context.symbolStack, symbol)) && // it is type of the symbol uses itself recursively
|
||||
return (!!(context.flags & NodeBuilderFlags.UseTypeOfFunction) || (context.visitedSymbols && context.visitedSymbols.has(id))) && // it is type of the symbol uses itself recursively
|
||||
(!(context.flags & NodeBuilderFlags.UseStructuralFallback) || isValueSymbolAccessible(symbol, context.enclosingDeclaration)); // And the build is going to succeed without visibility error or there is no structural fallback allowed
|
||||
}
|
||||
}
|
||||
@@ -3306,12 +3334,6 @@ namespace ts {
|
||||
return setEmitFlags(typeLiteralNode, (context.flags & NodeBuilderFlags.MultilineObjectLiterals) ? 0 : EmitFlags.SingleLine);
|
||||
}
|
||||
|
||||
function symbolToTypeReferenceName(symbol: Symbol) {
|
||||
// Unnamed function expressions and arrow functions have reserved names that we don't want to display
|
||||
const entityName = symbol.flags & SymbolFlags.Class || !isReservedMemberName(symbol.escapedName) ? symbolToName(symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false) : createIdentifier("");
|
||||
return entityName;
|
||||
}
|
||||
|
||||
function typeReferenceToTypeNode(type: TypeReference) {
|
||||
const typeArguments: Type[] = type.typeArguments || emptyArray;
|
||||
if (type.target === globalArrayType) {
|
||||
@@ -3346,7 +3368,7 @@ namespace ts {
|
||||
else {
|
||||
const outerTypeParameters = type.target.outerTypeParameters;
|
||||
let i = 0;
|
||||
let qualifiedName: QualifiedName | undefined;
|
||||
let resultType: TypeReferenceNode | ImportTypeNode;
|
||||
if (outerTypeParameters) {
|
||||
const length = outerTypeParameters.length;
|
||||
while (i < length) {
|
||||
@@ -3360,64 +3382,66 @@ namespace ts {
|
||||
// the default outer type arguments), we don't show the group.
|
||||
if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) {
|
||||
const typeArgumentSlice = mapToTypeNodes(typeArguments.slice(start, i), context);
|
||||
const typeArgumentNodes = typeArgumentSlice && createNodeArray(typeArgumentSlice);
|
||||
const namePart = symbolToTypeReferenceName(parent);
|
||||
(namePart.kind === SyntaxKind.Identifier ? namePart : namePart.right).typeArguments = typeArgumentNodes;
|
||||
|
||||
if (qualifiedName) {
|
||||
Debug.assert(!qualifiedName.right);
|
||||
qualifiedName = addToQualifiedNameMissingRightIdentifier(qualifiedName, namePart);
|
||||
qualifiedName = createQualifiedName(qualifiedName, /*right*/ undefined);
|
||||
}
|
||||
else {
|
||||
qualifiedName = createQualifiedName(namePart, /*right*/ undefined);
|
||||
}
|
||||
const flags = context.flags;
|
||||
context.flags |= NodeBuilderFlags.ForbidIndexedAccessSymbolReferences;
|
||||
const ref = symbolToTypeNode(parent, context, SymbolFlags.Type, typeArgumentSlice) as TypeReferenceNode | ImportTypeNode;
|
||||
context.flags = flags;
|
||||
resultType = !resultType ? ref : appendReferenceToType(resultType, ref as TypeReferenceNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let entityName: EntityName;
|
||||
const nameIdentifier = symbolToTypeReferenceName(type.symbol);
|
||||
if (qualifiedName) {
|
||||
Debug.assert(!qualifiedName.right);
|
||||
qualifiedName = addToQualifiedNameMissingRightIdentifier(qualifiedName, nameIdentifier);
|
||||
entityName = qualifiedName;
|
||||
}
|
||||
else {
|
||||
entityName = nameIdentifier;
|
||||
}
|
||||
|
||||
let typeArgumentNodes: ReadonlyArray<TypeNode> | undefined;
|
||||
if (typeArguments.length > 0) {
|
||||
const typeParameterCount = (type.target.typeParameters || emptyArray).length;
|
||||
typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context);
|
||||
}
|
||||
|
||||
if (typeArgumentNodes) {
|
||||
const lastIdentifier = entityName.kind === SyntaxKind.Identifier ? entityName : entityName.right;
|
||||
lastIdentifier.typeArguments = undefined;
|
||||
}
|
||||
|
||||
return createTypeReferenceNode(entityName, typeArgumentNodes);
|
||||
const flags = context.flags;
|
||||
context.flags |= NodeBuilderFlags.ForbidIndexedAccessSymbolReferences;
|
||||
const finalRef = symbolToTypeNode(type.symbol, context, SymbolFlags.Type, typeArgumentNodes);
|
||||
context.flags = flags;
|
||||
return !resultType ? finalRef : appendReferenceToType(resultType, finalRef as TypeReferenceNode);
|
||||
}
|
||||
}
|
||||
|
||||
function addToQualifiedNameMissingRightIdentifier(left: QualifiedName, right: Identifier | QualifiedName) {
|
||||
Debug.assert(left.right === undefined);
|
||||
|
||||
if (right.kind === SyntaxKind.Identifier) {
|
||||
left.right = right;
|
||||
return left;
|
||||
function appendReferenceToType(root: TypeReferenceNode | ImportTypeNode, ref: TypeReferenceNode): TypeReferenceNode | ImportTypeNode {
|
||||
if (isImportTypeNode(root)) {
|
||||
// first shift type arguments
|
||||
const innerParams = root.typeArguments;
|
||||
if (root.qualifier) {
|
||||
(isIdentifier(root.qualifier) ? root.qualifier : root.qualifier.right).typeArguments = innerParams;
|
||||
}
|
||||
root.typeArguments = ref.typeArguments;
|
||||
// then move qualifiers
|
||||
const ids = getAccessStack(ref);
|
||||
for (const id of ids) {
|
||||
root.qualifier = root.qualifier ? createQualifiedName(root.qualifier, id) : id;
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
let rightPart = right;
|
||||
while (rightPart.left.kind !== SyntaxKind.Identifier) {
|
||||
rightPart = rightPart.left;
|
||||
else {
|
||||
// first shift type arguments
|
||||
const innerParams = root.typeArguments;
|
||||
(isIdentifier(root.typeName) ? root.typeName : root.typeName.right).typeArguments = innerParams;
|
||||
root.typeArguments = ref.typeArguments;
|
||||
// then move qualifiers
|
||||
const ids = getAccessStack(ref);
|
||||
for (const id of ids) {
|
||||
root.typeName = createQualifiedName(root.typeName, id);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
left.right = rightPart.left;
|
||||
rightPart.left = left;
|
||||
return right;
|
||||
function getAccessStack(ref: TypeReferenceNode): Identifier[] {
|
||||
let state = ref.typeName;
|
||||
const ids = [];
|
||||
while (!isIdentifier(state)) {
|
||||
ids.unshift(state.right);
|
||||
state = state.left;
|
||||
}
|
||||
ids.unshift(state);
|
||||
return ids;
|
||||
}
|
||||
|
||||
function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] {
|
||||
@@ -3606,8 +3630,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function symbolToParameterDeclaration(parameterSymbol: Symbol, context: NodeBuilderContext, preserveModifierFlags?: boolean): ParameterDeclaration {
|
||||
const parameterDeclaration = getDeclarationOfKind<ParameterDeclaration>(parameterSymbol, SyntaxKind.Parameter);
|
||||
Debug.assert(!!parameterDeclaration || isTransientSymbol(parameterSymbol));
|
||||
let parameterDeclaration: ParameterDeclaration | JSDocParameterTag = getDeclarationOfKind<ParameterDeclaration>(parameterSymbol, SyntaxKind.Parameter);
|
||||
if (!parameterDeclaration && !isTransientSymbol(parameterSymbol)) {
|
||||
parameterDeclaration = getDeclarationOfKind<JSDocParameterTag>(parameterSymbol, SyntaxKind.JSDocParameterTag);
|
||||
}
|
||||
|
||||
let parameterType = getTypeOfSymbol(parameterSymbol);
|
||||
if (parameterDeclaration && isRequiredInitializedParameter(parameterDeclaration)) {
|
||||
@@ -3620,8 +3646,8 @@ namespace ts {
|
||||
const dotDotDotToken = isRest ? createToken(SyntaxKind.DotDotDotToken) : undefined;
|
||||
const name = parameterDeclaration
|
||||
? parameterDeclaration.name ?
|
||||
parameterDeclaration.name.kind === SyntaxKind.Identifier ?
|
||||
setEmitFlags(getSynthesizedClone(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) :
|
||||
parameterDeclaration.name.kind === SyntaxKind.Identifier ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) :
|
||||
parameterDeclaration.name.kind === SyntaxKind.QualifiedName ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name.right), EmitFlags.NoAsciiEscaping) :
|
||||
cloneBindingName(parameterDeclaration.name) :
|
||||
symbolName(parameterSymbol)
|
||||
: symbolName(parameterSymbol);
|
||||
@@ -3649,7 +3675,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function lookupSymbolChain(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags) {
|
||||
function lookupSymbolChain(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, yieldModuleSymbol?: boolean) {
|
||||
context.tracker.trackSymbol(symbol, context.enclosingDeclaration, meaning);
|
||||
// Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration.
|
||||
let chain: Symbol[];
|
||||
@@ -3689,7 +3715,7 @@ namespace ts {
|
||||
// If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols.
|
||||
endOfChain ||
|
||||
// If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.)
|
||||
!(!parentSymbol && forEach(symbol.declarations, hasExternalModuleSymbol)) &&
|
||||
(yieldModuleSymbol || !(!parentSymbol && forEach(symbol.declarations, hasExternalModuleSymbol))) &&
|
||||
// If a parent symbol is an anonymous type, don't write it.
|
||||
!(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral))) {
|
||||
|
||||
@@ -3737,8 +3763,8 @@ namespace ts {
|
||||
return top;
|
||||
}
|
||||
|
||||
function symbolToTypeNode(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags): TypeNode {
|
||||
const chain = lookupSymbolChain(symbol, context, meaning);
|
||||
function symbolToTypeNode(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, overrideTypeArguments?: ReadonlyArray<TypeNode>): TypeNode {
|
||||
const chain = lookupSymbolChain(symbol, context, meaning, !(context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope)); // If we're using aliases outside the current scope, dont bother with the module
|
||||
|
||||
context.flags |= NodeBuilderFlags.InInitialEntityName;
|
||||
const rootName = getNameOfSymbolAsWritten(chain[0], context);
|
||||
@@ -3748,9 +3774,13 @@ namespace ts {
|
||||
if (ambientModuleSymbolRegex.test(rootName)) {
|
||||
// module is root, must use `ImportTypeNode`
|
||||
const nonRootParts = chain.length > 1 ? createAccessFromSymbolChain(chain, chain.length - 1, 1) : undefined;
|
||||
const typeParameterNodes = lookupTypeParameterNodes(chain, 0, context);
|
||||
const typeParameterNodes = overrideTypeArguments || lookupTypeParameterNodes(chain, 0, context);
|
||||
const lit = createLiteralTypeNode(createLiteral(rootName.substring(1, rootName.length - 1)));
|
||||
if (!nonRootParts || isEntityName(nonRootParts)) {
|
||||
if (nonRootParts) {
|
||||
const lastId = isIdentifier(nonRootParts) ? nonRootParts : (nonRootParts as QualifiedName).right;
|
||||
lastId.typeArguments = undefined;
|
||||
}
|
||||
return createImportTypeNode(lit, nonRootParts as EntityName, typeParameterNodes as ReadonlyArray<TypeNode>, isTypeOf);
|
||||
}
|
||||
else {
|
||||
@@ -3764,10 +3794,18 @@ namespace ts {
|
||||
if (isIndexedAccessTypeNode(entityName)) {
|
||||
return entityName; // Indexed accesses can never be `typeof`
|
||||
}
|
||||
return isTypeOf ? createTypeQueryNode(entityName) : createTypeReferenceNode(entityName, /*typeArguments*/ undefined);
|
||||
if (isTypeOf) {
|
||||
return createTypeQueryNode(entityName);
|
||||
}
|
||||
else {
|
||||
const lastId = isIdentifier(entityName) ? entityName : entityName.right;
|
||||
const lastTypeArgs = lastId.typeArguments;
|
||||
lastId.typeArguments = undefined;
|
||||
return createTypeReferenceNode(entityName, lastTypeArgs as NodeArray<TypeNode>);
|
||||
}
|
||||
|
||||
function createAccessFromSymbolChain(chain: Symbol[], index: number, stopper: number): EntityName | IndexedAccessTypeNode {
|
||||
const typeParameterNodes = lookupTypeParameterNodes(chain, index, context);
|
||||
const typeParameterNodes = index === (chain.length - 1) ? overrideTypeArguments : lookupTypeParameterNodes(chain, index, context);
|
||||
const symbol = chain[index];
|
||||
|
||||
if (index === 0) {
|
||||
@@ -3779,7 +3817,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const parent = chain[index - 1];
|
||||
if (parent && getMembersOfSymbol(parent) && getMembersOfSymbol(parent).get(symbol.escapedName) === symbol) {
|
||||
if (!(context.flags & NodeBuilderFlags.ForbidIndexedAccessSymbolReferences) && parent && getMembersOfSymbol(parent) && getMembersOfSymbol(parent).get(symbol.escapedName) === symbol) {
|
||||
// Should use an indexed access
|
||||
const LHS = createAccessFromSymbolChain(chain, index - 1, stopper);
|
||||
if (isIndexedAccessTypeNode(LHS)) {
|
||||
@@ -3956,7 +3994,7 @@ namespace ts {
|
||||
|
||||
// State
|
||||
encounteredError: boolean;
|
||||
symbolStack: Symbol[] | undefined;
|
||||
visitedSymbols: Map<true> | undefined;
|
||||
inferTypeParameters: TypeParameter[] | undefined;
|
||||
}
|
||||
|
||||
@@ -3982,6 +4020,23 @@ namespace ts {
|
||||
return "default";
|
||||
}
|
||||
if (symbol.declarations && symbol.declarations.length) {
|
||||
if (some(symbol.declarations, hasExternalModuleSymbol) && context.enclosingDeclaration) {
|
||||
const file = getDeclarationOfKind<SourceFile>(symbol, SyntaxKind.SourceFile);
|
||||
if (!file || !context.tracker.moduleResolverHost) {
|
||||
if (context.tracker.trackReferencedAmbientModule) {
|
||||
const ambientDecls = filter(symbol.declarations, isAmbientModule);
|
||||
if (length(ambientDecls)) {
|
||||
for (const decl of ambientDecls) {
|
||||
context.tracker.trackReferencedAmbientModule(decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
// ambient module, just use declaration/symbol name (fallthrough)
|
||||
}
|
||||
else {
|
||||
return `"${getResolvedExternalModuleName(context.tracker.moduleResolverHost, file, getSourceFileOfNode(getOriginalNode(context.enclosingDeclaration)))}"`;
|
||||
}
|
||||
}
|
||||
const declaration = symbol.declarations[0];
|
||||
const name = getNameOfDeclaration(declaration);
|
||||
if (name) {
|
||||
@@ -4026,8 +4081,9 @@ namespace ts {
|
||||
|
||||
function determineIfDeclarationIsVisible() {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
// Top-level jsdoc typedefs are considered exported
|
||||
// Top-level jsdoc type aliases are considered exported
|
||||
// First parent is comment node, second is hosting declaration or token; we only care about those tokens or declarations whose parent is a source file
|
||||
return !!(node.parent && node.parent.parent && node.parent.parent.parent && isSourceFile(node.parent.parent.parent));
|
||||
case SyntaxKind.BindingElement:
|
||||
@@ -4802,7 +4858,7 @@ namespace ts {
|
||||
if (symbol.flags & SymbolFlags.Prototype) {
|
||||
return links.type = getTypeOfPrototypeProperty(symbol);
|
||||
}
|
||||
// CommonsJS require/module/exports all have type any.
|
||||
// CommonsJS require and module both have type any.
|
||||
if (symbol === requireSymbol || symbol === moduleSymbol) {
|
||||
return links.type = anyType;
|
||||
}
|
||||
@@ -4837,7 +4893,7 @@ namespace ts {
|
||||
declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) {
|
||||
type = getWidenedTypeFromJSSpecialPropertyDeclarations(symbol);
|
||||
}
|
||||
else if (isJSDocPropertyTag(declaration)
|
||||
else if (isJSDocPropertyLikeTag(declaration)
|
||||
|| isPropertyAccessExpression(declaration)
|
||||
|| isIdentifier(declaration)
|
||||
|| (isMethodDeclaration(declaration) && !isObjectLiteralMethod(declaration))
|
||||
@@ -5139,6 +5195,8 @@ namespace ts {
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
case SyntaxKind.MappedType:
|
||||
case SyntaxKind.ConditionalType:
|
||||
const outerTypeParameters = getOuterTypeParameters(node, includeThisTypes);
|
||||
@@ -5168,9 +5226,11 @@ namespace ts {
|
||||
function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol: Symbol): TypeParameter[] {
|
||||
let result: TypeParameter[];
|
||||
for (const node of symbol.declarations) {
|
||||
if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.ClassDeclaration ||
|
||||
node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.TypeAliasDeclaration || node.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
const declaration = <InterfaceDeclaration | TypeAliasDeclaration | JSDocTypedefTag>node;
|
||||
if (node.kind === SyntaxKind.InterfaceDeclaration ||
|
||||
node.kind === SyntaxKind.ClassDeclaration ||
|
||||
node.kind === SyntaxKind.ClassExpression ||
|
||||
isTypeAlias(node)) {
|
||||
const declaration = <InterfaceDeclaration | TypeAliasDeclaration | JSDocTypedefTag | JSDocCallbackTag>node;
|
||||
const typeParameters = getEffectiveTypeParameterDeclarations(declaration);
|
||||
if (typeParameters) {
|
||||
result = appendTypeParameters(result, typeParameters);
|
||||
@@ -5466,9 +5526,9 @@ namespace ts {
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
const declaration = <JSDocTypedefTag | TypeAliasDeclaration>find(symbol.declarations, d =>
|
||||
d.kind === SyntaxKind.JSDocTypedefTag || d.kind === SyntaxKind.TypeAliasDeclaration);
|
||||
const typeNode = declaration.kind === SyntaxKind.JSDocTypedefTag ? declaration.typeExpression : declaration.type;
|
||||
const declaration = <JSDocTypedefTag | JSDocCallbackTag | TypeAliasDeclaration>find(symbol.declarations, d =>
|
||||
isJSDocTypeAlias(d) || d.kind === SyntaxKind.TypeAliasDeclaration);
|
||||
const typeNode = isJSDocTypeAlias(declaration) ? declaration.typeExpression : declaration.type;
|
||||
// If typeNode is missing, we will error in checkJSDocTypedefTag.
|
||||
let type = typeNode ? getTypeFromTypeNode(typeNode) : unknownType;
|
||||
|
||||
@@ -6036,7 +6096,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createSignature(
|
||||
declaration: SignatureDeclaration,
|
||||
declaration: SignatureDeclaration | JSDocSignature,
|
||||
typeParameters: TypeParameter[],
|
||||
thisParameter: Symbol | undefined,
|
||||
parameters: Symbol[],
|
||||
@@ -7046,8 +7106,8 @@ namespace ts {
|
||||
return symbol && withAugmentations ? getMergedSymbol(symbol) : symbol;
|
||||
}
|
||||
|
||||
function isOptionalParameter(node: ParameterDeclaration) {
|
||||
if (hasQuestionToken(node) || isJSDocOptionalParameter(node)) {
|
||||
function isOptionalParameter(node: ParameterDeclaration | JSDocParameterTag) {
|
||||
if (hasQuestionToken(node) || isOptionalJSDocParameterTag(node) || isJSDocOptionalParameter(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -7067,6 +7127,14 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isOptionalJSDocParameterTag(node: Node): node is JSDocParameterTag {
|
||||
if (!isJSDocParameterTag(node)) {
|
||||
return false;
|
||||
}
|
||||
const { isBracketed, typeExpression } = node;
|
||||
return isBracketed || !!typeExpression && typeExpression.type.kind === SyntaxKind.JSDocOptionalType;
|
||||
}
|
||||
|
||||
function createTypePredicateFromTypePredicateNode(node: TypePredicateNode): IdentifierTypePredicate | ThisTypePredicate {
|
||||
const { parameterName } = node;
|
||||
const type = getTypeFromTypeNode(node.type);
|
||||
@@ -7142,7 +7210,7 @@ namespace ts {
|
||||
return typeArguments;
|
||||
}
|
||||
|
||||
function getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature {
|
||||
function getSignatureFromDeclaration(declaration: SignatureDeclaration | JSDocSignature): Signature {
|
||||
const links = getNodeLinks(declaration);
|
||||
if (!links.resolvedSignature) {
|
||||
const parameters: Symbol[] = [];
|
||||
@@ -7165,6 +7233,7 @@ namespace ts {
|
||||
const param = declaration.parameters[i];
|
||||
|
||||
let paramSymbol = param.symbol;
|
||||
const type = isJSDocParameterTag(param) ? (param.typeExpression && param.typeExpression.type) : param.type;
|
||||
// Include parameter symbol instead of property symbol in the signature
|
||||
if (paramSymbol && !!(paramSymbol.flags & SymbolFlags.Property) && !isBindingPattern(param.name)) {
|
||||
const resolvedSymbol = resolveName(param, paramSymbol.escapedName, SymbolFlags.Value, undefined, undefined, /*isUse*/ false);
|
||||
@@ -7178,13 +7247,14 @@ namespace ts {
|
||||
parameters.push(paramSymbol);
|
||||
}
|
||||
|
||||
if (param.type && param.type.kind === SyntaxKind.LiteralType) {
|
||||
if (type && type.kind === SyntaxKind.LiteralType) {
|
||||
hasLiteralTypes = true;
|
||||
}
|
||||
|
||||
// Record a new minimum argument count if this is not an optional parameter
|
||||
const isOptionalParameter = param.initializer || param.questionToken || param.dotDotDotToken ||
|
||||
iife && parameters.length > iife.arguments.length && !param.type ||
|
||||
const isOptionalParameter = isOptionalJSDocParameterTag(param) ||
|
||||
param.initializer || param.questionToken || param.dotDotDotToken ||
|
||||
iife && parameters.length > iife.arguments.length && !type ||
|
||||
isUntypedSignatureInJSFile ||
|
||||
isJSDocOptionalParameter(param);
|
||||
if (!isOptionalParameter) {
|
||||
@@ -7220,8 +7290,8 @@ namespace ts {
|
||||
* OR
|
||||
* 2. It has at least one parameter, and the last parameter has a matching `@param` with a type that starts with `...`
|
||||
*/
|
||||
function maybeAddJsSyntheticRestParameter(declaration: SignatureDeclaration, parameters: Symbol[]): boolean {
|
||||
if (!containsArgumentsReference(declaration)) {
|
||||
function maybeAddJsSyntheticRestParameter(declaration: SignatureDeclaration | JSDocSignature, parameters: Symbol[]): boolean {
|
||||
if (isJSDocSignature(declaration) || !containsArgumentsReference(declaration)) {
|
||||
return false;
|
||||
}
|
||||
const lastParam = lastOrUndefined(declaration.parameters);
|
||||
@@ -7240,9 +7310,9 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function getSignatureReturnTypeFromDeclaration(declaration: SignatureDeclaration, isJSConstructSignature: boolean, classType: Type) {
|
||||
function getSignatureReturnTypeFromDeclaration(declaration: SignatureDeclaration | JSDocSignature, isJSConstructSignature: boolean, classType: Type) {
|
||||
if (isJSConstructSignature) {
|
||||
return getTypeFromTypeNode(declaration.parameters[0].type);
|
||||
return getTypeFromTypeNode((declaration.parameters[0] as ParameterDeclaration).type);
|
||||
}
|
||||
else if (classType) {
|
||||
return classType;
|
||||
@@ -7656,11 +7726,11 @@ namespace ts {
|
||||
const missingAugmentsTag = isJs && node.parent.kind !== SyntaxKind.JSDocAugmentsTag;
|
||||
const diag = minTypeArgumentCount === typeParameters.length
|
||||
? missingAugmentsTag
|
||||
? Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag
|
||||
: Diagnostics.Generic_type_0_requires_1_type_argument_s
|
||||
: missingAugmentsTag
|
||||
? Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag
|
||||
: Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments;
|
||||
? Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag
|
||||
: Diagnostics.Generic_type_0_requires_1_type_argument_s
|
||||
: missingAugmentsTag
|
||||
? Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag
|
||||
: Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments;
|
||||
const typeStr = typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType);
|
||||
error(node, diag, typeStr, minTypeArgumentCount, typeParameters.length);
|
||||
if (!isJs) {
|
||||
@@ -7675,7 +7745,7 @@ namespace ts {
|
||||
return createTypeReference(<GenericType>type, typeArguments);
|
||||
}
|
||||
return checkNoTypeArguments(node, symbol) ? type : unknownType;
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeAliasInstantiation(symbol: Symbol, typeArguments: Type[]): Type {
|
||||
const type = getDeclaredTypeOfSymbol(symbol);
|
||||
@@ -7702,18 +7772,18 @@ namespace ts {
|
||||
const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
|
||||
if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) {
|
||||
error(node,
|
||||
minTypeArgumentCount === typeParameters.length
|
||||
? Diagnostics.Generic_type_0_requires_1_type_argument_s
|
||||
: Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments,
|
||||
symbolToString(symbol),
|
||||
minTypeArgumentCount,
|
||||
typeParameters.length);
|
||||
minTypeArgumentCount === typeParameters.length
|
||||
? Diagnostics.Generic_type_0_requires_1_type_argument_s
|
||||
: Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments,
|
||||
symbolToString(symbol),
|
||||
minTypeArgumentCount,
|
||||
typeParameters.length);
|
||||
return unknownType;
|
||||
}
|
||||
return getTypeAliasInstantiation(symbol, typeArguments);
|
||||
}
|
||||
return checkNoTypeArguments(node, symbol) ? type : unknownType;
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeReferenceName(node: TypeReferenceType): EntityNameOrEntityNameExpression | undefined {
|
||||
switch (node.kind) {
|
||||
@@ -7828,7 +7898,7 @@ namespace ts {
|
||||
|
||||
function getConstrainedTypeVariable(typeVariable: TypeVariable, node: Node) {
|
||||
let constraints: Type[];
|
||||
while (node && !isStatement(node)) {
|
||||
while (node && !isStatement(node) && node.kind !== SyntaxKind.JSDocComment) {
|
||||
const parent = node.parent;
|
||||
if (parent.kind === SyntaxKind.ConditionalType && node === (<ConditionalTypeNode>parent).trueType) {
|
||||
const constraint = getImpliedConstraint(typeVariable, (<ConditionalTypeNode>parent).checkType, (<ConditionalTypeNode>parent).extendsType);
|
||||
@@ -8327,7 +8397,7 @@ namespace ts {
|
||||
includes & TypeFlags.Undefined ? includes & TypeFlags.NonWideningType ? undefinedType : undefinedWideningType :
|
||||
neverType;
|
||||
}
|
||||
return getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments);
|
||||
return getUnionTypeFromSortedList(typeSet, includes & TypeFlags.NotUnit ? 0 : TypeFlags.UnionOfUnitTypes, aliasSymbol, aliasTypeArguments);
|
||||
}
|
||||
|
||||
function getUnionTypePredicate(signatures: ReadonlyArray<Signature>): TypePredicate {
|
||||
@@ -8367,7 +8437,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// This function assumes the constituent type list is sorted and deduplicated.
|
||||
function getUnionTypeFromSortedList(types: Type[], aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
|
||||
function getUnionTypeFromSortedList(types: Type[], unionOfUnitTypes: TypeFlags, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
|
||||
if (types.length === 0) {
|
||||
return neverType;
|
||||
}
|
||||
@@ -8378,7 +8448,7 @@ namespace ts {
|
||||
let type = unionTypes.get(id);
|
||||
if (!type) {
|
||||
const propagatedFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable);
|
||||
type = <UnionType>createType(TypeFlags.Union | propagatedFlags);
|
||||
type = <UnionType>createType(TypeFlags.Union | propagatedFlags | unionOfUnitTypes);
|
||||
unionTypes.set(id, type);
|
||||
type.types = types;
|
||||
/*
|
||||
@@ -8396,8 +8466,9 @@ namespace ts {
|
||||
function getTypeFromUnionTypeNode(node: UnionTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
const aliasSymbol = getAliasSymbolForTypeNode(node);
|
||||
links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), UnionReduction.Literal,
|
||||
getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node));
|
||||
aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
@@ -8449,6 +8520,29 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
// When intersecting unions of unit types we can simply intersect based on type identity.
|
||||
// Here we remove all unions of unit types from the given list and replace them with a
|
||||
// a single union containing an intersection of the unit types.
|
||||
function intersectUnionsOfUnitTypes(types: Type[]) {
|
||||
const unionIndex = findIndex(types, t => (t.flags & TypeFlags.UnionOfUnitTypes) !== 0);
|
||||
const unionType = <UnionType>types[unionIndex];
|
||||
let intersection = unionType.types;
|
||||
let i = types.length - 1;
|
||||
while (i > unionIndex) {
|
||||
const t = types[i];
|
||||
if (t.flags & TypeFlags.UnionOfUnitTypes) {
|
||||
intersection = filter(intersection, u => containsType((<UnionType>t).types, u));
|
||||
orderedRemoveItemAt(types, i);
|
||||
}
|
||||
i--;
|
||||
}
|
||||
if (intersection === unionType.types) {
|
||||
return false;
|
||||
}
|
||||
types[unionIndex] = getUnionTypeFromSortedList(intersection, unionType.flags & TypeFlags.UnionOfUnitTypes);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We normalize combinations of intersection and union types based on the distributive property of the '&'
|
||||
// operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection
|
||||
// types with union type constituents into equivalent union types with intersection type constituents and
|
||||
@@ -8483,6 +8577,12 @@ namespace ts {
|
||||
return typeSet[0];
|
||||
}
|
||||
if (includes & TypeFlags.Union) {
|
||||
if (includes & TypeFlags.UnionOfUnitTypes && intersectUnionsOfUnitTypes(typeSet)) {
|
||||
// When the intersection creates a reduced set (which might mean that *all* union types have
|
||||
// disappeared), we restart the operation to get a new set of combined flags. Once we have
|
||||
// reduced we'll never reduce again, so this occurs at most once.
|
||||
return getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
|
||||
}
|
||||
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
|
||||
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
|
||||
const unionIndex = findIndex(typeSet, t => (t.flags & TypeFlags.Union) !== 0);
|
||||
@@ -8506,8 +8606,9 @@ namespace ts {
|
||||
function getTypeFromIntersectionTypeNode(node: IntersectionTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
const aliasSymbol = getAliasSymbolForTypeNode(node);
|
||||
links.resolvedType = getIntersectionType(map(node.types, getTypeFromTypeNode),
|
||||
getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node));
|
||||
aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
@@ -8816,7 +8917,7 @@ namespace ts {
|
||||
const type = <MappedType>createObjectType(ObjectFlags.Mapped, node.symbol);
|
||||
type.declaration = node;
|
||||
type.aliasSymbol = getAliasSymbolForTypeNode(node);
|
||||
type.aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node);
|
||||
type.aliasTypeArguments = getTypeArgumentsForAliasSymbol(type.aliasSymbol);
|
||||
links.resolvedType = type;
|
||||
// Eagerly resolve the constraint type which forces an error if the constraint type circularly
|
||||
// references itself through one or more type aliases.
|
||||
@@ -8924,7 +9025,8 @@ namespace ts {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
const checkType = getTypeFromTypeNode(node.checkType);
|
||||
const aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node);
|
||||
const aliasSymbol = getAliasSymbolForTypeNode(node);
|
||||
const aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
|
||||
const allOuterTypeParameters = getOuterTypeParameters(node, /*includeThisTypes*/ true);
|
||||
const outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : filter(allOuterTypeParameters, tp => isPossiblyReferencedInConditionalType(tp, node));
|
||||
const root: ConditionalRoot = {
|
||||
@@ -8937,7 +9039,7 @@ namespace ts {
|
||||
inferTypeParameters: getInferTypeParameters(node),
|
||||
outerTypeParameters,
|
||||
instantiations: undefined,
|
||||
aliasSymbol: getAliasSymbolForTypeNode(node),
|
||||
aliasSymbol,
|
||||
aliasTypeArguments
|
||||
};
|
||||
links.resolvedType = getConditionalType(root, /*mapper*/ undefined);
|
||||
@@ -9041,7 +9143,7 @@ namespace ts {
|
||||
else {
|
||||
let type = createObjectType(ObjectFlags.Anonymous, node.symbol);
|
||||
type.aliasSymbol = aliasSymbol;
|
||||
type.aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node);
|
||||
type.aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
|
||||
if (isJSDocTypeLiteral(node) && node.isArrayType) {
|
||||
type = createArrayType(type);
|
||||
}
|
||||
@@ -9052,11 +9154,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getAliasSymbolForTypeNode(node: TypeNode) {
|
||||
return (node.parent.kind === SyntaxKind.TypeAliasDeclaration || node.parent.kind === SyntaxKind.JSDocTypedefTag) ? getSymbolOfNode(node.parent) : undefined;
|
||||
return isTypeAlias(node.parent) ? getSymbolOfNode(node.parent) : undefined;
|
||||
}
|
||||
|
||||
function getAliasTypeArgumentsForTypeNode(node: TypeNode) {
|
||||
const symbol = getAliasSymbolForTypeNode(node);
|
||||
function getTypeArgumentsForAliasSymbol(symbol: Symbol) {
|
||||
return symbol ? getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) : undefined;
|
||||
}
|
||||
|
||||
@@ -9314,6 +9415,7 @@ namespace ts {
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.JSDocSignature:
|
||||
return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
|
||||
case SyntaxKind.TypeOperator:
|
||||
return getTypeFromTypeOperatorNode(<TypeOperatorNode>node);
|
||||
@@ -9523,7 +9625,16 @@ namespace ts {
|
||||
// parameters that are in scope (and therefore potentially referenced). For type literals that
|
||||
// aren't the right hand side of a generic type alias declaration we optimize by reducing the
|
||||
// set of type parameters to those that are possibly referenced in the literal.
|
||||
const declaration = symbol.declarations[0];
|
||||
let declaration = symbol.declarations[0];
|
||||
if (isInJavaScriptFile(declaration)) {
|
||||
const paramTag = findAncestor(declaration, isJSDocParameterTag);
|
||||
if (paramTag) {
|
||||
const paramSymbol = getParameterSymbolFromJSDoc(paramTag);
|
||||
if (paramSymbol) {
|
||||
declaration = paramSymbol.valueDeclaration;
|
||||
}
|
||||
}
|
||||
}
|
||||
let outerTypeParameters = getOuterTypeParameters(declaration, /*includeThisTypes*/ true);
|
||||
if (isJavaScriptConstructor(declaration)) {
|
||||
const templateTagParameters = getTypeParametersFromDeclaration(declaration as DeclarationWithTypeParameters);
|
||||
@@ -9991,8 +10102,8 @@ namespace ts {
|
||||
function compareTypePredicateRelatedTo(
|
||||
source: TypePredicate,
|
||||
target: TypePredicate,
|
||||
sourceDeclaration: SignatureDeclaration,
|
||||
targetDeclaration: SignatureDeclaration,
|
||||
sourceDeclaration: SignatureDeclaration | JSDocSignature,
|
||||
targetDeclaration: SignatureDeclaration | JSDocSignature,
|
||||
reportErrors: boolean,
|
||||
errorReporter: ErrorReporter,
|
||||
compareTypes: (s: Type, t: Type, reportErrors?: boolean) => Ternary): Ternary {
|
||||
@@ -13246,7 +13357,7 @@ namespace ts {
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
const types = (<UnionType>type).types;
|
||||
const filtered = filter(types, f);
|
||||
return filtered === types ? type : getUnionTypeFromSortedList(filtered);
|
||||
return filtered === types ? type : getUnionTypeFromSortedList(filtered, type.flags & TypeFlags.UnionOfUnitTypes);
|
||||
}
|
||||
return f(type) ? type : neverType;
|
||||
}
|
||||
@@ -15366,10 +15477,11 @@ namespace ts {
|
||||
links.resolvedSignatures = createMap();
|
||||
}
|
||||
const cacheKey = "" + getTypeId(valueType);
|
||||
if (links.resolvedSignatures.get(cacheKey) && links.resolvedSignatures.get(cacheKey) !== resolvingSignaturesArray) {
|
||||
signatures = links.resolvedSignatures.get(cacheKey);
|
||||
const cachedResolved = links.resolvedSignatures.get(cacheKey);
|
||||
if (cachedResolved && cachedResolved !== resolvingSignaturesArray) {
|
||||
signatures = cachedResolved;
|
||||
}
|
||||
else if (!links.resolvedSignatures.get(cacheKey)) {
|
||||
else if (!cachedResolved) {
|
||||
links.resolvedSignatures.set(cacheKey, resolvingSignaturesArray);
|
||||
links.resolvedSignatures.set(cacheKey, signatures = instantiateJsxSignatures(context, signatures));
|
||||
}
|
||||
@@ -21761,8 +21873,9 @@ namespace ts {
|
||||
switch (d.kind) {
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
// A jsdoc typedef is, by definition, a type alias
|
||||
// A jsdoc typedef and callback are, by definition, type aliases
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
return DeclarationSpaces.ExportType;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return isAmbientModule(d as ModuleDeclaration) || getModuleInstanceState(d as ModuleDeclaration) !== ModuleInstanceState.NonInstantiated
|
||||
@@ -22297,7 +22410,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function checkJSDocTypedefTag(node: JSDocTypedefTag) {
|
||||
function checkJSDocTypeAliasTag(node: JSDocTypedefTag | JSDocCallbackTag) {
|
||||
if (!node.typeExpression) {
|
||||
// If the node had `@property` tags, `typeExpression` would have been set to the first property tag.
|
||||
error(node.name, Diagnostics.JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags);
|
||||
@@ -25212,7 +25325,8 @@ namespace ts {
|
||||
case SyntaxKind.JSDocAugmentsTag:
|
||||
return checkJSDocAugmentsTag(node as JSDocAugmentsTag);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return checkJSDocTypedefTag(node as JSDocTypedefTag);
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
return checkJSDocTypeAliasTag(node as JSDocTypedefTag);
|
||||
case SyntaxKind.JSDocParameterTag:
|
||||
return checkJSDocParameterTag(node as JSDocParameterTag);
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
@@ -26423,9 +26537,10 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isRequiredInitializedParameter(parameter: ParameterDeclaration) {
|
||||
function isRequiredInitializedParameter(parameter: ParameterDeclaration | JSDocParameterTag) {
|
||||
return strictNullChecks &&
|
||||
!isOptionalParameter(parameter) &&
|
||||
!isJSDocParameterTag(parameter) &&
|
||||
parameter.initializer &&
|
||||
!hasModifier(parameter, ModifierFlags.ParameterPropertyModifier);
|
||||
}
|
||||
|
||||
@@ -320,6 +320,15 @@ namespace ts {
|
||||
return -1;
|
||||
}
|
||||
|
||||
export function findLastIndex<T>(array: ReadonlyArray<T>, predicate: (element: T, index: number) => boolean, startIndex?: number): number {
|
||||
for (let i = startIndex === undefined ? array.length - 1 : startIndex; i >= 0; i--) {
|
||||
if (predicate(array[i], i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first truthy result of `callback`, or else fails.
|
||||
* This is like `forEach`, but never returns undefined.
|
||||
@@ -696,6 +705,23 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Calls the callback with (start, afterEnd) index pairs for each range where 'pred' is true. */
|
||||
export function getRangesWhere<T>(arr: ReadonlyArray<T>, pred: (t: T) => boolean, cb: (start: number, afterEnd: number) => void): void {
|
||||
let start: number | undefined;
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (pred(arr[i])) {
|
||||
start = start === undefined ? i : start;
|
||||
}
|
||||
else {
|
||||
if (start !== undefined) {
|
||||
cb(start, i);
|
||||
start = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (start !== undefined) cb(start, arr.length);
|
||||
}
|
||||
|
||||
export function concatenate<T>(array1: T[], array2: T[]): T[];
|
||||
export function concatenate<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>): ReadonlyArray<T>;
|
||||
export function concatenate<T>(array1: T[], array2: T[]): T[] {
|
||||
|
||||
@@ -4257,5 +4257,9 @@
|
||||
"Remove all unreachable code": {
|
||||
"category": "Message",
|
||||
"code": 95051
|
||||
},
|
||||
"Add missing typeof": {
|
||||
"category": "Message",
|
||||
"code": 95052
|
||||
}
|
||||
}
|
||||
|
||||
+117
-41
@@ -489,6 +489,15 @@ namespace ts {
|
||||
return visitNode(cbNode, (<JSDocTypedefTag>node).fullName) ||
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression);
|
||||
}
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
return visitNode(cbNode, (node as JSDocCallbackTag).fullName) ||
|
||||
visitNode(cbNode, (node as JSDocCallbackTag).typeExpression);
|
||||
case SyntaxKind.JSDocSignature:
|
||||
return visitNodes(cbNode, cbNodes, node.decorators) ||
|
||||
visitNodes(cbNode, cbNodes, node.modifiers) ||
|
||||
visitNodes(cbNode, cbNodes, (<SignatureDeclaration>node).typeParameters) ||
|
||||
visitNodes(cbNode, cbNodes, (<SignatureDeclaration>node).parameters) ||
|
||||
visitNode(cbNode, (<SignatureDeclaration>node).type);
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
if ((node as JSDocTypeLiteral).jsDocPropertyTags) {
|
||||
for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags) {
|
||||
@@ -6331,8 +6340,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
const enum PropertyLikeParse {
|
||||
Property,
|
||||
Parameter,
|
||||
Property = 1 << 0,
|
||||
Parameter = 1 << 1,
|
||||
CallbackParameter = 1 << 2,
|
||||
}
|
||||
|
||||
export function parseJSDocCommentWorker(start: number, length: number): JSDoc {
|
||||
@@ -6386,7 +6396,7 @@ namespace ts {
|
||||
case SyntaxKind.AtToken:
|
||||
if (state === JSDocState.BeginningOfLine || state === JSDocState.SawAsterisk) {
|
||||
removeTrailingNewlines(comments);
|
||||
parseTag(indent);
|
||||
addTag(parseTag(indent));
|
||||
// NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag.
|
||||
// Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning
|
||||
// for malformed examples like `/** @param {string} x @returns {number} the length */`
|
||||
@@ -6471,7 +6481,25 @@ namespace ts {
|
||||
return finishNode(result, end);
|
||||
}
|
||||
|
||||
function isNextNonwhitespaceTokenEndOfFile(): boolean {
|
||||
// We must use infinite lookahead, as there could be any number of newlines :(
|
||||
while (true) {
|
||||
nextJSDocToken();
|
||||
if (token() === SyntaxKind.EndOfFileToken) {
|
||||
return true;
|
||||
}
|
||||
if (!(token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function skipWhitespace(): void {
|
||||
if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
|
||||
if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
|
||||
return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
|
||||
}
|
||||
}
|
||||
while (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
|
||||
nextJSDocToken();
|
||||
}
|
||||
@@ -6503,8 +6531,7 @@ namespace ts {
|
||||
case "arg":
|
||||
case "argument":
|
||||
case "param":
|
||||
addTag(parseParameterOrPropertyTag(atToken, tagName, PropertyLikeParse.Parameter, indent));
|
||||
return;
|
||||
return parseParameterOrPropertyTag(atToken, tagName, PropertyLikeParse.Parameter, indent);
|
||||
case "return":
|
||||
case "returns":
|
||||
tag = parseReturnTag(atToken, tagName);
|
||||
@@ -6516,7 +6543,10 @@ namespace ts {
|
||||
tag = parseTypeTag(atToken, tagName);
|
||||
break;
|
||||
case "typedef":
|
||||
tag = parseTypedefTag(atToken, tagName);
|
||||
tag = parseTypedefTag(atToken, tagName, indent);
|
||||
break;
|
||||
case "callback":
|
||||
tag = parseCallbackTag(atToken, tagName, indent);
|
||||
break;
|
||||
default:
|
||||
tag = parseUnknownTag(atToken, tagName);
|
||||
@@ -6531,8 +6561,11 @@ namespace ts {
|
||||
// a badly malformed tag should not be added to the list of tags
|
||||
return;
|
||||
}
|
||||
tag.comment = parseTagComments(indent + tag.end - tag.pos);
|
||||
addTag(tag);
|
||||
if (!tag.comment) {
|
||||
// some tags, like typedef and callback, have already parsed their comments earlier
|
||||
tag.comment = parseTagComments(indent + tag.end - tag.pos);
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
function parseTagComments(indent: number): string | undefined {
|
||||
@@ -6605,6 +6638,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function addTag(tag: JSDocTag): void {
|
||||
if (!tag) {
|
||||
return;
|
||||
}
|
||||
if (!tags) {
|
||||
tags = [tag];
|
||||
tagsPos = tag.pos;
|
||||
@@ -6665,9 +6701,9 @@ namespace ts {
|
||||
typeExpression = tryParseTypeExpression();
|
||||
}
|
||||
|
||||
const result = target === PropertyLikeParse.Parameter ?
|
||||
<JSDocParameterTag>createNode(SyntaxKind.JSDocParameterTag, atToken.pos) :
|
||||
<JSDocPropertyTag>createNode(SyntaxKind.JSDocPropertyTag, atToken.pos);
|
||||
const result = target === PropertyLikeParse.Property ?
|
||||
<JSDocPropertyTag>createNode(SyntaxKind.JSDocPropertyTag, atToken.pos) :
|
||||
<JSDocParameterTag>createNode(SyntaxKind.JSDocParameterTag, atToken.pos);
|
||||
let comment: string | undefined;
|
||||
if (indent !== undefined) comment = parseTagComments(indent + scanner.getStartPos() - atToken.pos);
|
||||
const nestedTypeLiteral = parseNestedTypeLiteral(typeExpression, name, target);
|
||||
@@ -6771,29 +6807,20 @@ namespace ts {
|
||||
return finishNode(tag);
|
||||
}
|
||||
|
||||
function parseTypedefTag(atToken: AtToken, tagName: Identifier): JSDocTypedefTag {
|
||||
function parseTypedefTag(atToken: AtToken, tagName: Identifier, indent: number): JSDocTypedefTag {
|
||||
const typeExpression = tryParseTypeExpression();
|
||||
skipWhitespace();
|
||||
|
||||
const typedefTag = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag, atToken.pos);
|
||||
typedefTag.atToken = atToken;
|
||||
typedefTag.tagName = tagName;
|
||||
typedefTag.fullName = parseJSDocTypeNameWithNamespace(/*flags*/ 0);
|
||||
if (typedefTag.fullName) {
|
||||
let rightNode = typedefTag.fullName;
|
||||
while (true) {
|
||||
if (rightNode.kind === SyntaxKind.Identifier || !rightNode.body) {
|
||||
// if node is identifier - use it as name
|
||||
// otherwise use name of the rightmost part that we were able to parse
|
||||
typedefTag.name = rightNode.kind === SyntaxKind.Identifier ? rightNode : rightNode.name;
|
||||
break;
|
||||
}
|
||||
rightNode = rightNode.body;
|
||||
}
|
||||
}
|
||||
typedefTag.fullName = parseJSDocTypeNameWithNamespace();
|
||||
typedefTag.name = getJSDocTypeAliasName(typedefTag.fullName);
|
||||
skipWhitespace();
|
||||
typedefTag.comment = parseTagComments(indent);
|
||||
|
||||
typedefTag.typeExpression = typeExpression;
|
||||
let end: number;
|
||||
if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
|
||||
let child: JSDocTypeTag | JSDocPropertyTag | false;
|
||||
let jsdocTypeLiteral: JSDocTypeLiteral;
|
||||
@@ -6822,27 +6849,75 @@ namespace ts {
|
||||
typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ?
|
||||
childTypeTag.typeExpression :
|
||||
finishNode(jsdocTypeLiteral);
|
||||
end = typedefTag.typeExpression.end;
|
||||
}
|
||||
}
|
||||
|
||||
return finishNode(typedefTag);
|
||||
// Only include the characters between the name end and the next token if a comment was actually parsed out - otherwise it's just whitespace
|
||||
return finishNode(typedefTag, end || typedefTag.comment !== undefined ? scanner.getStartPos() : (typedefTag.fullName || typedefTag.typeExpression || typedefTag.tagName).end);
|
||||
}
|
||||
|
||||
function parseJSDocTypeNameWithNamespace(flags: NodeFlags) {
|
||||
const pos = scanner.getTokenPos();
|
||||
const typeNameOrNamespaceName = parseJSDocIdentifierName();
|
||||
function parseJSDocTypeNameWithNamespace(nested?: boolean) {
|
||||
const pos = scanner.getTokenPos();
|
||||
const typeNameOrNamespaceName = parseJSDocIdentifierName();
|
||||
|
||||
if (typeNameOrNamespaceName && parseOptional(SyntaxKind.DotToken)) {
|
||||
const jsDocNamespaceNode = <JSDocNamespaceDeclaration>createNode(SyntaxKind.ModuleDeclaration, pos);
|
||||
jsDocNamespaceNode.flags |= flags;
|
||||
jsDocNamespaceNode.name = typeNameOrNamespaceName;
|
||||
jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(NodeFlags.NestedNamespace);
|
||||
return finishNode(jsDocNamespaceNode);
|
||||
if (typeNameOrNamespaceName && parseOptional(SyntaxKind.DotToken)) {
|
||||
const jsDocNamespaceNode = <JSDocNamespaceDeclaration>createNode(SyntaxKind.ModuleDeclaration, pos);
|
||||
if (nested) {
|
||||
jsDocNamespaceNode.flags |= NodeFlags.NestedNamespace;
|
||||
}
|
||||
jsDocNamespaceNode.name = typeNameOrNamespaceName;
|
||||
jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(/*nested*/ true);
|
||||
return finishNode(jsDocNamespaceNode);
|
||||
}
|
||||
|
||||
if (typeNameOrNamespaceName && flags & NodeFlags.NestedNamespace) {
|
||||
typeNameOrNamespaceName.isInJSDocNamespace = true;
|
||||
if (typeNameOrNamespaceName && nested) {
|
||||
typeNameOrNamespaceName.isInJSDocNamespace = true;
|
||||
}
|
||||
return typeNameOrNamespaceName;
|
||||
}
|
||||
|
||||
function parseCallbackTag(atToken: AtToken, tagName: Identifier, indent: number): JSDocCallbackTag {
|
||||
const callbackTag = createNode(SyntaxKind.JSDocCallbackTag, atToken.pos) as JSDocCallbackTag;
|
||||
callbackTag.atToken = atToken;
|
||||
callbackTag.tagName = tagName;
|
||||
callbackTag.fullName = parseJSDocTypeNameWithNamespace();
|
||||
callbackTag.name = getJSDocTypeAliasName(callbackTag.fullName);
|
||||
skipWhitespace();
|
||||
callbackTag.comment = parseTagComments(indent);
|
||||
|
||||
let child: JSDocParameterTag | false;
|
||||
const start = scanner.getStartPos();
|
||||
const jsdocSignature = createNode(SyntaxKind.JSDocSignature, start) as JSDocSignature;
|
||||
jsdocSignature.parameters = [];
|
||||
while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.CallbackParameter) as JSDocParameterTag)) {
|
||||
jsdocSignature.parameters = append(jsdocSignature.parameters as MutableNodeArray<JSDocParameterTag>, child);
|
||||
}
|
||||
const returnTag = tryParse(() => {
|
||||
if (token() === SyntaxKind.AtToken) {
|
||||
nextJSDocToken();
|
||||
const tag = parseTag(indent);
|
||||
if (tag && tag.kind === SyntaxKind.JSDocReturnTag) {
|
||||
return tag as JSDocReturnTag;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (returnTag) {
|
||||
jsdocSignature.type = returnTag;
|
||||
}
|
||||
callbackTag.typeExpression = finishNode(jsdocSignature);
|
||||
return finishNode(callbackTag);
|
||||
}
|
||||
|
||||
function getJSDocTypeAliasName(fullName: JSDocNamespaceBody | undefined) {
|
||||
if (fullName) {
|
||||
let rightNode = fullName;
|
||||
while (true) {
|
||||
if (ts.isIdentifier(rightNode) || !rightNode.body) {
|
||||
return ts.isIdentifier(rightNode) ? rightNode : rightNode.name;
|
||||
}
|
||||
rightNode = rightNode.body;
|
||||
}
|
||||
return typeNameOrNamespaceName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6872,6 +6947,7 @@ namespace ts {
|
||||
if (canParseTag) {
|
||||
const child = tryParseChildTag(target);
|
||||
if (child && child.kind === SyntaxKind.JSDocParameterTag &&
|
||||
target !== PropertyLikeParse.CallbackParameter &&
|
||||
(ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) {
|
||||
return false;
|
||||
}
|
||||
@@ -6920,12 +6996,12 @@ namespace ts {
|
||||
case "arg":
|
||||
case "argument":
|
||||
case "param":
|
||||
t = PropertyLikeParse.Parameter;
|
||||
t = PropertyLikeParse.Parameter | PropertyLikeParse.CallbackParameter;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (target !== t) {
|
||||
if (!(target & t)) {
|
||||
return false;
|
||||
}
|
||||
const tag = parseParameterOrPropertyTag(atToken, tagName, target, /*indent*/ undefined);
|
||||
@@ -7020,7 +7096,7 @@ namespace ts {
|
||||
const pos = scanner.getTokenPos();
|
||||
const end = scanner.getTextPos();
|
||||
const result = <Identifier>createNode(SyntaxKind.Identifier, pos);
|
||||
result.escapedText = escapeLeadingUnderscores(content.substring(pos, end));
|
||||
result.escapedText = escapeLeadingUnderscores(scanner.getTokenText());
|
||||
finishNode(result, end);
|
||||
|
||||
nextJSDocToken();
|
||||
|
||||
@@ -1928,13 +1928,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function scanJSDocToken(): JsDocSyntaxKind {
|
||||
startPos = tokenPos = pos;
|
||||
if (pos >= end) {
|
||||
return token = SyntaxKind.EndOfFileToken;
|
||||
}
|
||||
|
||||
startPos = pos;
|
||||
tokenPos = pos;
|
||||
|
||||
const ch = text.charCodeAt(pos);
|
||||
pos++;
|
||||
switch (ch) {
|
||||
|
||||
@@ -37,20 +37,23 @@ namespace ts {
|
||||
let lateStatementReplacementMap: Map<VisitResult<LateVisibilityPaintedStatement>>;
|
||||
let suppressNewDiagnosticContexts: boolean;
|
||||
|
||||
const host = context.getEmitHost();
|
||||
const symbolTracker: SymbolTracker = {
|
||||
trackSymbol,
|
||||
reportInaccessibleThisError,
|
||||
reportInaccessibleUniqueSymbolError,
|
||||
reportPrivateInBaseOfClassExpression
|
||||
reportPrivateInBaseOfClassExpression,
|
||||
moduleResolverHost: host,
|
||||
trackReferencedAmbientModule,
|
||||
};
|
||||
let errorNameNode: DeclarationName | undefined;
|
||||
|
||||
let currentSourceFile: SourceFile;
|
||||
let refs: Map<SourceFile>;
|
||||
const resolver = context.getEmitResolver();
|
||||
const options = context.getCompilerOptions();
|
||||
const newLine = getNewLineCharacter(options);
|
||||
const { noResolve, stripInternal } = options;
|
||||
const host = context.getEmitHost();
|
||||
return transformRoot;
|
||||
|
||||
function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives: string[]): void {
|
||||
@@ -63,6 +66,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function trackReferencedAmbientModule(node: ModuleDeclaration) {
|
||||
const container = getSourceFileOfNode(node);
|
||||
refs.set("" + getOriginalNodeId(container), container);
|
||||
}
|
||||
|
||||
function handleSymbolAccessibilityError(symbolAccessibilityResult: SymbolAccessibilityResult) {
|
||||
if (symbolAccessibilityResult.accessibility === SymbolAccessibility.Accessible) {
|
||||
// Add aliases back onto the possible imports list if they're not there so we can try them again with updated visibility info
|
||||
@@ -197,13 +205,13 @@ namespace ts {
|
||||
lateMarkedStatements = undefined;
|
||||
lateStatementReplacementMap = createMap();
|
||||
necessaryTypeRefernces = undefined;
|
||||
const refs = collectReferences(currentSourceFile, createMap());
|
||||
refs = collectReferences(currentSourceFile, createMap());
|
||||
const references: FileReference[] = [];
|
||||
const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath));
|
||||
const referenceVisitor = mapReferencesIntoArray(references, outputFilePath);
|
||||
refs.forEach(referenceVisitor);
|
||||
const statements = visitNodes(node.statements, visitDeclarationStatements);
|
||||
let combinedStatements = setTextRange(createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements);
|
||||
refs.forEach(referenceVisitor);
|
||||
const emittedImports = filter(combinedStatements, isAnyImportSyntax);
|
||||
if (isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) {
|
||||
combinedStatements = setTextRange(createNodeArray([...combinedStatements, createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([]), /*moduleSpecifier*/ undefined)]), combinedStatements);
|
||||
@@ -217,16 +225,18 @@ namespace ts {
|
||||
|
||||
function getFileReferenceForTypeName(typeName: string): FileReference | undefined {
|
||||
// Elide type references for which we have imports
|
||||
for (const importStatement of emittedImports) {
|
||||
if (isImportEqualsDeclaration(importStatement) && isExternalModuleReference(importStatement.moduleReference)) {
|
||||
const expr = importStatement.moduleReference.expression;
|
||||
if (isStringLiteralLike(expr) && expr.text === typeName) {
|
||||
if (emittedImports) {
|
||||
for (const importStatement of emittedImports) {
|
||||
if (isImportEqualsDeclaration(importStatement) && isExternalModuleReference(importStatement.moduleReference)) {
|
||||
const expr = importStatement.moduleReference.expression;
|
||||
if (isStringLiteralLike(expr) && expr.text === typeName) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
else if (isImportDeclaration(importStatement) && isStringLiteral(importStatement.moduleSpecifier) && importStatement.moduleSpecifier.text === typeName) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
else if (isImportDeclaration(importStatement) && isStringLiteral(importStatement.moduleSpecifier) && importStatement.moduleSpecifier.text === typeName) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return { fileName: typeName, pos: -1, end: -1 };
|
||||
}
|
||||
@@ -1325,4 +1335,4 @@ namespace ts {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+35
-3
@@ -413,9 +413,11 @@ namespace ts {
|
||||
JSDocVariadicType,
|
||||
JSDocComment,
|
||||
JSDocTypeLiteral,
|
||||
JSDocSignature,
|
||||
JSDocTag,
|
||||
JSDocAugmentsTag,
|
||||
JSDocClassTag,
|
||||
JSDocCallbackTag,
|
||||
JSDocParameterTag,
|
||||
JSDocReturnTag,
|
||||
JSDocTypeTag,
|
||||
@@ -2053,7 +2055,7 @@ namespace ts {
|
||||
|
||||
export type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode;
|
||||
|
||||
export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature;
|
||||
|
||||
export interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression;
|
||||
@@ -2387,6 +2389,21 @@ namespace ts {
|
||||
typeExpression?: JSDocTypeExpression | JSDocTypeLiteral;
|
||||
}
|
||||
|
||||
export interface JSDocCallbackTag extends JSDocTag, NamedDeclaration {
|
||||
parent: JSDoc;
|
||||
kind: SyntaxKind.JSDocCallbackTag;
|
||||
fullName?: JSDocNamespaceDeclaration | Identifier;
|
||||
name?: Identifier;
|
||||
typeExpression: JSDocSignature;
|
||||
}
|
||||
|
||||
export interface JSDocSignature extends JSDocType, Declaration {
|
||||
kind: SyntaxKind.JSDocSignature;
|
||||
typeParameters?: ReadonlyArray<JSDocTemplateTag>;
|
||||
parameters: ReadonlyArray<JSDocParameterTag>;
|
||||
type: JSDocReturnTag | undefined;
|
||||
}
|
||||
|
||||
export interface JSDocPropertyLikeTag extends JSDocTag, Declaration {
|
||||
parent: JSDoc;
|
||||
name: EntityName;
|
||||
@@ -3076,7 +3093,7 @@ namespace ts {
|
||||
WriteArrayAsGenericType = 1 << 1, // Write Array<T> instead T[]
|
||||
GenerateNamesForShadowedTypeParams = 1 << 2, // When a type parameter T is shadowing another T, generate a name for it so it can still be referenced
|
||||
UseStructuralFallback = 1 << 3, // When an alias cannot be named by its symbol, rather than report an error, fallback to a structural printout if possible
|
||||
// empty space
|
||||
ForbidIndexedAccessSymbolReferences = 1 << 4, // Forbid references like `I["a"]["b"]` - print `typeof I.a<x>.b<y>` instead
|
||||
WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature
|
||||
UseFullyQualifiedType = 1 << 6, // Write out the fully qualified type name (eg. Module.Type, instead of Type)
|
||||
UseOnlyExternalAliasing = 1 << 7, // Only use external aliases for a symbol
|
||||
@@ -3675,6 +3692,8 @@ namespace ts {
|
||||
ContainsAnyFunctionType = 1 << 26, // Type is or contains the anyFunctionType
|
||||
NonPrimitive = 1 << 27, // intrinsic object type
|
||||
/* @internal */
|
||||
UnionOfUnitTypes = 1 << 28, // Type is union of unit types
|
||||
/* @internal */
|
||||
GenericMappedType = 1 << 29, // Flag used by maybeTypeOfKind
|
||||
|
||||
/* @internal */
|
||||
@@ -3712,6 +3731,8 @@ namespace ts {
|
||||
Narrowable = Any | StructuredOrInstantiable | StringLike | NumberLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
|
||||
NotUnionOrUnit = Any | ESSymbol | Object | NonPrimitive,
|
||||
/* @internal */
|
||||
NotUnit = Any | String | Number | Boolean | Enum | ESSymbol | Void | Never | StructuredOrInstantiable,
|
||||
/* @internal */
|
||||
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
|
||||
/* @internal */
|
||||
PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType,
|
||||
@@ -4032,7 +4053,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface Signature {
|
||||
declaration?: SignatureDeclaration; // Originating declaration
|
||||
declaration?: SignatureDeclaration | JSDocSignature; // Originating declaration
|
||||
typeParameters?: TypeParameter[]; // Type parameters (undefined if non-generic)
|
||||
parameters: Symbol[]; // Parameters
|
||||
/* @internal */
|
||||
@@ -5241,6 +5262,13 @@ namespace ts {
|
||||
isAtStartOfLine(): boolean;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface ModuleNameResolverHost {
|
||||
getCanonicalFileName(f: string): string;
|
||||
getCommonSourceDirectory(): string;
|
||||
getCurrentDirectory(): string;
|
||||
}
|
||||
|
||||
/** @deprecated See comment on SymbolWriter */
|
||||
// Note: this has non-deprecated internal uses.
|
||||
export interface SymbolTracker {
|
||||
@@ -5251,6 +5279,10 @@ namespace ts {
|
||||
reportInaccessibleThisError?(): void;
|
||||
reportPrivateInBaseOfClassExpression?(propertyName: string): void;
|
||||
reportInaccessibleUniqueSymbolError?(): void;
|
||||
/* @internal */
|
||||
moduleResolverHost?: ModuleNameResolverHost;
|
||||
/* @internal */
|
||||
trackReferencedAmbientModule?(decl: ModuleDeclaration): void;
|
||||
}
|
||||
|
||||
export interface TextSpan {
|
||||
|
||||
+79
-44
@@ -520,6 +520,9 @@ namespace ts {
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
case SyntaxKind.JSDocSignature:
|
||||
return true;
|
||||
default:
|
||||
assertTypeIsNever(node);
|
||||
@@ -561,14 +564,7 @@ namespace ts {
|
||||
// Gets the nearest enclosing block scope container that has the provided node
|
||||
// as a descendant, that is not the provided node.
|
||||
export function getEnclosingBlockScopeContainer(node: Node): Node {
|
||||
let current = node.parent;
|
||||
while (current) {
|
||||
if (isBlockScope(current, current.parent)) {
|
||||
return current;
|
||||
}
|
||||
|
||||
current = current.parent;
|
||||
}
|
||||
return findAncestor(node.parent, current => isBlockScope(current, current.parent));
|
||||
}
|
||||
|
||||
// Return display name of an identifier
|
||||
@@ -1803,6 +1799,14 @@ namespace ts {
|
||||
((node as JSDocFunctionType).parameters[0].name as Identifier).escapedText === "new";
|
||||
}
|
||||
|
||||
export function isJSDocTypeAlias(node: Node): node is JSDocTypedefTag | JSDocCallbackTag {
|
||||
return node.kind === SyntaxKind.JSDocTypedefTag || node.kind === SyntaxKind.JSDocCallbackTag;
|
||||
}
|
||||
|
||||
export function isTypeAlias(node: Node): node is JSDocTypedefTag | JSDocCallbackTag | TypeAliasDeclaration {
|
||||
return isJSDocTypeAlias(node) || isTypeAliasDeclaration(node);
|
||||
}
|
||||
|
||||
function getSourceOfAssignment(node: Node): Node {
|
||||
return isExpressionStatement(node) &&
|
||||
node.expression && isBinaryExpression(node.expression) &&
|
||||
@@ -1826,6 +1830,8 @@ namespace ts {
|
||||
return v && v.initializer;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
return (node as PropertyDeclaration).initializer;
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return (node as PropertyAssignment).initializer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1859,8 +1865,7 @@ namespace ts {
|
||||
// * @returns {number}
|
||||
// */
|
||||
// var x = function(name) { return name.length; }
|
||||
if (parent.parent &&
|
||||
(getSingleVariableOfVariableStatement(parent.parent) === node)) {
|
||||
if (parent.parent && (getSingleVariableOfVariableStatement(parent.parent) === node)) {
|
||||
getJSDocCommentsAndTagsWorker(parent.parent);
|
||||
}
|
||||
if (parent.parent && parent.parent.parent &&
|
||||
@@ -1907,8 +1912,11 @@ namespace ts {
|
||||
return parameter && parameter.symbol;
|
||||
}
|
||||
|
||||
export function getHostSignatureFromJSDoc(node: JSDocParameterTag): SignatureDeclaration | undefined {
|
||||
const host = getJSDocHost(node);
|
||||
export function getHostSignatureFromJSDoc(node: Node): SignatureDeclaration | undefined {
|
||||
return getHostSignatureFromJSDocHost(getJSDocHost(node));
|
||||
}
|
||||
|
||||
export function getHostSignatureFromJSDocHost(host: HasJSDoc): SignatureDeclaration | undefined {
|
||||
const decl = getSourceOfDefaultedAssignment(host) ||
|
||||
getSourceOfAssignment(host) ||
|
||||
getSingleInitializerOfVariableStatementOrPropertyDeclaration(host) ||
|
||||
@@ -1918,18 +1926,12 @@ namespace ts {
|
||||
return decl && isFunctionLike(decl) ? decl : undefined;
|
||||
}
|
||||
|
||||
export function getJSDocHost(node: JSDocTag): HasJSDoc {
|
||||
while (node.parent.kind === SyntaxKind.JSDocTypeLiteral) {
|
||||
if (node.parent.parent.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
node = node.parent.parent as JSDocTypedefTag;
|
||||
}
|
||||
else {
|
||||
// node.parent.parent is a type expression, child of a parameter type
|
||||
node = node.parent.parent.parent as JSDocParameterTag;
|
||||
}
|
||||
export function getJSDocHost(node: Node): HasJSDoc {
|
||||
const comment = findAncestor(node.parent,
|
||||
node => !(isJSDocNode(node) || node.flags & NodeFlags.JSDoc) ? "quit" : node.kind === SyntaxKind.JSDocComment);
|
||||
if (comment) {
|
||||
return (comment as JSDoc).parent;
|
||||
}
|
||||
Debug.assert(node.parent!.kind === SyntaxKind.JSDocComment);
|
||||
return node.parent!.parent!;
|
||||
}
|
||||
|
||||
export function getTypeParameterFromJsDoc(node: TypeParameterDeclaration & { parent: JSDocTemplateTag }): TypeParameterDeclaration | undefined {
|
||||
@@ -1938,13 +1940,14 @@ namespace ts {
|
||||
return find(typeParameters, p => p.name.escapedText === name);
|
||||
}
|
||||
|
||||
export function hasRestParameter(s: SignatureDeclaration): boolean {
|
||||
const last = lastOrUndefined(s.parameters);
|
||||
export function hasRestParameter(s: SignatureDeclaration | JSDocSignature): boolean {
|
||||
const last = lastOrUndefined<ParameterDeclaration | JSDocParameterTag>(s.parameters);
|
||||
return last && isRestParameter(last);
|
||||
}
|
||||
|
||||
export function isRestParameter(node: ParameterDeclaration): boolean {
|
||||
return node.dotDotDotToken !== undefined || node.type && node.type.kind === SyntaxKind.JSDocVariadicType;
|
||||
export function isRestParameter(node: ParameterDeclaration | JSDocParameterTag): boolean {
|
||||
const type = isJSDocParameterTag(node) ? (node.typeExpression && node.typeExpression.type) : node.type;
|
||||
return (node as ParameterDeclaration).dotDotDotToken !== undefined || type && type.kind === SyntaxKind.JSDocVariadicType;
|
||||
}
|
||||
|
||||
export const enum AssignmentKind {
|
||||
@@ -2875,11 +2878,11 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function getResolvedExternalModuleName(host: EmitHost, file: SourceFile): string {
|
||||
return file.moduleName || getExternalModuleNameFromPath(host, file.fileName);
|
||||
export function getResolvedExternalModuleName(host: ModuleNameResolverHost, file: SourceFile, referenceFile?: SourceFile): string {
|
||||
return file.moduleName || getExternalModuleNameFromPath(host, file.fileName, referenceFile && referenceFile.fileName);
|
||||
}
|
||||
|
||||
export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode): string {
|
||||
export function getExternalModuleNameFromDeclaration(host: ModuleNameResolverHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode): string {
|
||||
const file = resolver.getExternalModuleFileFromDeclaration(declaration);
|
||||
if (!file || file.isDeclarationFile) {
|
||||
return undefined;
|
||||
@@ -2890,12 +2893,13 @@ namespace ts {
|
||||
/**
|
||||
* Resolves a local path to a path which is absolute to the base of the emit
|
||||
*/
|
||||
export function getExternalModuleNameFromPath(host: EmitHost, fileName: string): string {
|
||||
export function getExternalModuleNameFromPath(host: ModuleNameResolverHost, fileName: string, referencePath?: string): string {
|
||||
const getCanonicalFileName = (f: string) => host.getCanonicalFileName(f);
|
||||
const dir = toPath(host.getCommonSourceDirectory(), host.getCurrentDirectory(), getCanonicalFileName);
|
||||
const dir = toPath(referencePath ? getDirectoryPath(referencePath) : host.getCommonSourceDirectory(), host.getCurrentDirectory(), getCanonicalFileName);
|
||||
const filePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
|
||||
const relativePath = getRelativePathToDirectoryOrUrl(dir, filePath, dir, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
|
||||
return removeFileExtension(relativePath);
|
||||
const extensionless = removeFileExtension(relativePath);
|
||||
return referencePath ? ensurePathIsNonModuleName(extensionless) : extensionless;
|
||||
}
|
||||
|
||||
export function getOwnEmitOutputFilePath(sourceFile: SourceFile, host: EmitHost, extension: string) {
|
||||
@@ -2998,8 +3002,9 @@ namespace ts {
|
||||
return parameter && parameter.type;
|
||||
}
|
||||
|
||||
export function getThisParameter(signature: SignatureDeclaration): ParameterDeclaration | undefined {
|
||||
if (signature.parameters.length) {
|
||||
export function getThisParameter(signature: SignatureDeclaration | JSDocSignature): ParameterDeclaration | undefined {
|
||||
// callback tags do not currently support this parameters
|
||||
if (signature.parameters.length && !isJSDocSignature(signature)) {
|
||||
const thisParameter = signature.parameters[0];
|
||||
if (parameterIsThisKeyword(thisParameter)) {
|
||||
return thisParameter;
|
||||
@@ -3085,7 +3090,10 @@ namespace ts {
|
||||
* Gets the effective return type annotation of a signature. If the node was parsed in a
|
||||
* JavaScript file, gets the return type annotation from JSDoc.
|
||||
*/
|
||||
export function getEffectiveReturnTypeNode(node: SignatureDeclaration): TypeNode | undefined {
|
||||
export function getEffectiveReturnTypeNode(node: SignatureDeclaration | JSDocSignature): TypeNode | undefined {
|
||||
if (isJSDocSignature(node)) {
|
||||
return node.type && node.type.typeExpression && node.type.typeExpression.type;
|
||||
}
|
||||
return node.type || (isInJavaScriptFile(node) ? getJSDocReturnType(node) : undefined);
|
||||
}
|
||||
|
||||
@@ -3093,15 +3101,30 @@ namespace ts {
|
||||
* Gets the effective type parameters. If the node was parsed in a
|
||||
* JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
|
||||
*/
|
||||
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters | JSDocTypedefTag) {
|
||||
return isJSDocTypedefTag(node)
|
||||
? getJSDocTypeParameterDeclarations(node)
|
||||
: node.typeParameters || (isInJavaScriptFile(node) ? getJSDocTypeParameterDeclarations(node) : undefined);
|
||||
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters) {
|
||||
if (isJSDocSignature(node)) {
|
||||
return undefined;
|
||||
}
|
||||
if (isJSDocTypeAlias(node)) {
|
||||
Debug.assert(node.parent.kind === SyntaxKind.JSDocComment);
|
||||
const templateTags = flatMap(filter(node.parent.tags, isJSDocTemplateTag), tag => tag.typeParameters) as ReadonlyArray<TypeParameterDeclaration>;
|
||||
const templateTagNodes = templateTags as NodeArray<TypeParameterDeclaration>;
|
||||
templateTagNodes.pos = templateTagNodes.length > 0 ? first(templateTagNodes).pos : node.pos;
|
||||
templateTagNodes.end = templateTagNodes.length > 0 ? last(templateTagNodes).end : node.end;
|
||||
templateTagNodes.hasTrailingComma = false;
|
||||
return templateTagNodes;
|
||||
}
|
||||
return node.typeParameters || (isInJavaScriptFile(node) ? getJSDocTypeParameterDeclarations(node) : undefined);
|
||||
}
|
||||
|
||||
export function getJSDocTypeParameterDeclarations(node: DeclarationWithTypeParameters | JSDocTypedefTag) {
|
||||
const templateTag = getJSDocTemplateTag(node);
|
||||
return templateTag && templateTag.typeParameters;
|
||||
export function getJSDocTypeParameterDeclarations(node: DeclarationWithTypeParameters) {
|
||||
const tags = filter(getJSDocTags(node), isJSDocTemplateTag);
|
||||
for (const tag of tags) {
|
||||
if (!(tag.parent.kind === SyntaxKind.JSDocComment && find(tag.parent.tags, isJSDocTypeAlias))) {
|
||||
// template tags are only available when a typedef isn't already using them
|
||||
return tag.typeParameters;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4638,6 +4661,8 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
return (declaration as JSDocCallbackTag).name;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return getNameOfJSDocTypedef(declaration as JSDocTypedefTag);
|
||||
case SyntaxKind.ExportAssignment: {
|
||||
@@ -5475,6 +5500,14 @@ namespace ts {
|
||||
export function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral {
|
||||
return node.kind === SyntaxKind.JSDocTypeLiteral;
|
||||
}
|
||||
|
||||
export function isJSDocCallbackTag(node: Node): node is JSDocCallbackTag {
|
||||
return node.kind === SyntaxKind.JSDocCallbackTag;
|
||||
}
|
||||
|
||||
export function isJSDocSignature(node: Node): node is JSDocSignature {
|
||||
return node.kind === SyntaxKind.JSDocSignature;
|
||||
}
|
||||
}
|
||||
|
||||
// Node tests
|
||||
@@ -5636,6 +5669,7 @@ namespace ts {
|
||||
switch (kind) {
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.JSDocSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.FunctionType:
|
||||
@@ -6104,6 +6138,7 @@ namespace ts {
|
||||
|| kind === SyntaxKind.TypeParameter
|
||||
|| kind === SyntaxKind.VariableDeclaration
|
||||
|| kind === SyntaxKind.JSDocTypedefTag
|
||||
|| kind === SyntaxKind.JSDocCallbackTag
|
||||
|| kind === SyntaxKind.JSDocPropertyTag;
|
||||
}
|
||||
|
||||
@@ -6254,7 +6289,7 @@ namespace ts {
|
||||
|
||||
/** True if node is of a kind that may contain comment text. */
|
||||
export function isJSDocCommentContainingNode(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.JSDocComment || isJSDocTag(node) || isJSDocTypeLiteral(node);
|
||||
return node.kind === SyntaxKind.JSDocComment || isJSDocTag(node) || isJSDocTypeLiteral(node) || isJSDocSignature(node);
|
||||
}
|
||||
|
||||
// TODO: determine what this does before making it public.
|
||||
|
||||
@@ -31,32 +31,9 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
const cls = this;
|
||||
describe(`${this.kind()} code samples`, function(this: Mocha.ISuiteCallbackContext) {
|
||||
this.timeout(600_000); // 10 minutes
|
||||
const cwd = path.join(Harness.IO.getWorkspaceRoot(), cls.testDir);
|
||||
const placeholderName = ".node_modules";
|
||||
const moduleDirName = "node_modules";
|
||||
before(() => {
|
||||
ts.forEachAncestorDirectory(cwd, dir => {
|
||||
try {
|
||||
fs.renameSync(path.join(dir, moduleDirName), path.join(dir, placeholderName));
|
||||
}
|
||||
catch {
|
||||
// empty
|
||||
}
|
||||
});
|
||||
});
|
||||
for (const test of testList) {
|
||||
cls.runTest(typeof test === "string" ? test : test.file);
|
||||
}
|
||||
after(() => {
|
||||
ts.forEachAncestorDirectory(cwd, dir => {
|
||||
try {
|
||||
fs.renameSync(path.join(dir, placeholderName), path.join(dir, moduleDirName));
|
||||
}
|
||||
catch {
|
||||
// empty
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
private runTest(directoryName: string) {
|
||||
@@ -137,14 +114,16 @@ ${stripAbsoluteImportPaths(result.stderr.toString().replace(/\r\n/g, "\n"))}`;
|
||||
function stripAbsoluteImportPaths(result: string) {
|
||||
return result
|
||||
.replace(/import\(".*?\/tests\/cases\/user\//g, `import("/`)
|
||||
.replace(/Module '".*?\/tests\/cases\/user\//g, `Module '"/`);
|
||||
.replace(/Module '".*?\/tests\/cases\/user\//g, `Module '"/`)
|
||||
.replace(/import\(".*?\/TypeScript\/node_modules\//g, `import("../../../node_modules`)
|
||||
.replace(/Module '".*?\/TypeScript\/node_modules\//g, `Module '"../../../node_modules`);
|
||||
}
|
||||
|
||||
function sortErrors(result: string) {
|
||||
return ts.flatten(splitBy(result.split("\n"), s => /^\S+/.test(s)).sort(compareErrorStrings)).join("\n");
|
||||
}
|
||||
|
||||
const errorRegexp = /^(.+\.[tj]sx?)\((\d+),(\d+)\): error TS/;
|
||||
const errorRegexp = /^(.+\.[tj]sx?)\((\d+),(\d+)\)(: error TS.*)/;
|
||||
function compareErrorStrings(a: string[], b: string[]) {
|
||||
ts.Debug.assertGreaterThanOrEqual(a.length, 1);
|
||||
ts.Debug.assertGreaterThanOrEqual(b.length, 1);
|
||||
@@ -156,11 +135,12 @@ function compareErrorStrings(a: string[], b: string[]) {
|
||||
if (!matchB) {
|
||||
return 1;
|
||||
}
|
||||
const [, errorFileA, lineNumberStringA, columnNumberStringA] = matchA;
|
||||
const [, errorFileB, lineNumberStringB, columnNumberStringB] = matchB;
|
||||
const [, errorFileA, lineNumberStringA, columnNumberStringA, remainderA] = matchA;
|
||||
const [, errorFileB, lineNumberStringB, columnNumberStringB, remainderB] = matchB;
|
||||
return ts.comparePathsCaseSensitive(errorFileA, errorFileB) ||
|
||||
ts.compareValues(parseInt(lineNumberStringA), parseInt(lineNumberStringB)) ||
|
||||
ts.compareValues(parseInt(columnNumberStringA), parseInt(columnNumberStringB));
|
||||
ts.compareValues(parseInt(columnNumberStringA), parseInt(columnNumberStringB)) ||
|
||||
ts.compareStringsCaseSensitive(remainderA, remainderB);
|
||||
}
|
||||
|
||||
class DefinitelyTypedRunner extends ExternalCompileRunnerBase {
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
"../services/codefixes/moduleSpecifiers.ts",
|
||||
"../services/codefixes/requireInTs.ts",
|
||||
"../services/codefixes/useDefaultImport.ts",
|
||||
"../services/codefixes/fixAddModuleReferTypeMissingTypeof.ts",
|
||||
"../services/refactors/extractSymbol.ts",
|
||||
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
|
||||
"../services/refactors/moveToNewFile.ts",
|
||||
|
||||
@@ -3090,6 +3090,9 @@
|
||||
<Item ItemId=";Dynamic_import_is_only_supported_when_module_flag_is_commonjs_or_esNext_1323" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import is only supported when '--module' flag is 'commonjs' or 'esNext'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Der dynamische Import wird nur unterstützt, wenn das Flag "--module" auf "commonjs" oder "esNext" festgelegt ist.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -5277,6 +5280,9 @@
|
||||
<Item ItemId=";Move_to_a_new_file_95049" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Move to a new file]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[In neue Datei verschieben]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6546,6 +6552,9 @@
|
||||
<Item ItemId=";Remove_all_unreachable_code_95051" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove all unreachable code]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Gesamten nicht erreichbaren Code entfernen]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6582,6 +6591,9 @@
|
||||
<Item ItemId=";Remove_unreachable_code_95050" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove unreachable code]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Nicht erreichbaren Code entfernen]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -3102,6 +3102,9 @@
|
||||
<Item ItemId=";Dynamic_import_is_only_supported_when_module_flag_is_commonjs_or_esNext_1323" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import is only supported when '--module' flag is 'commonjs' or 'esNext'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[La importación dinámica solo se admite cuando la marca "--module" es "commonjs" o "esNext".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -5286,6 +5289,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Move_to_a_new_file_95049" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Move to a new file]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Mover a un nuevo archivo]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Multiple_consecutive_numeric_separators_are_not_permitted_6189" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Multiple consecutive numeric separators are not permitted.]]></Val>
|
||||
@@ -6552,6 +6564,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_all_unreachable_code_95051" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove all unreachable code]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Quitar todo el código inaccesible]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_declaration_for_Colon_0_90004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove declaration for: '{0}']]></Val>
|
||||
@@ -6582,6 +6603,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_unreachable_code_95050" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove unreachable code]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Quitar el código inaccesible]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Replace_import_with_0_95015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Replace import with '{0}'.]]></Val>
|
||||
|
||||
@@ -3086,6 +3086,9 @@
|
||||
<Item ItemId=";Dynamic_import_is_only_supported_when_module_flag_is_commonjs_or_esNext_1323" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import is only supported when '--module' flag is 'commonjs' or 'esNext'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Dinamik içeri aktarma yalnızca '--module' bayrağı 'commonjs' veya 'esNext' olduğunda desteklenir.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -5270,6 +5273,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Move_to_a_new_file_95049" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Move to a new file]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Yeni bir dosyaya taşı]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Multiple_consecutive_numeric_separators_are_not_permitted_6189" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Multiple consecutive numeric separators are not permitted.]]></Val>
|
||||
@@ -6536,6 +6548,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_all_unreachable_code_95051" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove all unreachable code]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Tüm erişilemeyen kodları kaldır]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_declaration_for_Colon_0_90004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove declaration for: '{0}']]></Val>
|
||||
@@ -6566,6 +6587,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_unreachable_code_95050" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove unreachable code]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Erişilemeyen kodları kaldır]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Replace_import_with_0_95015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Replace import with '{0}'.]]></Val>
|
||||
|
||||
@@ -112,6 +112,7 @@
|
||||
"../services/codefixes/moduleSpecifiers.ts",
|
||||
"../services/codefixes/requireInTs.ts",
|
||||
"../services/codefixes/useDefaultImport.ts",
|
||||
"../services/codefixes/fixAddModuleReferTypeMissingTypeof.ts",
|
||||
"../services/refactors/extractSymbol.ts",
|
||||
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
|
||||
"../services/refactors/moveToNewFile.ts",
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
"../services/codefixes/moduleSpecifiers.ts",
|
||||
"../services/codefixes/requireInTs.ts",
|
||||
"../services/codefixes/useDefaultImport.ts",
|
||||
"../services/codefixes/fixAddModuleReferTypeMissingTypeof.ts",
|
||||
"../services/refactors/extractSymbol.ts",
|
||||
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
|
||||
"../services/refactors/moveToNewFile.ts",
|
||||
|
||||
@@ -706,16 +706,17 @@ namespace ts {
|
||||
break;
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
processJSDocTemplateTag(<JSDocTemplateTag>tag);
|
||||
pos = tag.end;
|
||||
break;
|
||||
case SyntaxKind.JSDocTypeTag:
|
||||
processElement((<JSDocTypeTag>tag).typeExpression);
|
||||
pos = tag.end;
|
||||
break;
|
||||
case SyntaxKind.JSDocReturnTag:
|
||||
processElement((<JSDocReturnTag>tag).typeExpression);
|
||||
pos = tag.end;
|
||||
break;
|
||||
}
|
||||
|
||||
pos = tag.end;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
const fixIdAddMissingTypeof = "fixAddModuleReferTypeMissingTypeof";
|
||||
const fixId = fixIdAddMissingTypeof;
|
||||
const errorCodes = [Diagnostics.Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here.code];
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
getCodeActions: context => {
|
||||
const { sourceFile, span } = context;
|
||||
const typeContainer = getImportTypeNode(sourceFile, span.start);
|
||||
if (!typeContainer) return undefined;
|
||||
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, typeContainer));
|
||||
return [createCodeFixAction(fixId, changes, Diagnostics.Add_missing_typeof, fixId, Diagnostics.Add_missing_typeof)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) =>
|
||||
doChange(changes, context.sourceFile, getImportTypeNode(diag.file, diag.start!))),
|
||||
});
|
||||
|
||||
function getImportTypeNode(sourceFile: SourceFile, pos: number): ImportTypeNode | undefined {
|
||||
const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
Debug.assert(token.kind === SyntaxKind.ImportKeyword);
|
||||
Debug.assert(token.parent.kind === SyntaxKind.ImportType);
|
||||
return <ImportTypeNode>token.parent;
|
||||
}
|
||||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, typeContainer: ImportTypeNode) {
|
||||
const newTypeNode = updateImportTypeNode(typeContainer, typeContainer.argument, typeContainer.qualifier, typeContainer.typeArguments, /* isTypeOf */ true);
|
||||
changes.replaceNode(sourceFile, typeContainer, newTypeNode);
|
||||
}
|
||||
}
|
||||
@@ -71,19 +71,6 @@ namespace ts.codefix {
|
||||
|
||||
// Calls 'cb' with the start and end of each range where 'pred' is true.
|
||||
function split<T>(arr: ReadonlyArray<T>, pred: (t: T) => boolean, cb: (start: T, end: T) => void): void {
|
||||
let start: T | undefined;
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const value = arr[i];
|
||||
if (pred(value)) {
|
||||
start = start || value;
|
||||
}
|
||||
else {
|
||||
if (start) {
|
||||
cb(start, arr[i - 1]);
|
||||
start = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (start) cb(start, arr[arr.length - 1]);
|
||||
getRangesWhere(arr, pred, (start, afterEnd) => cb(arr[start], arr[afterEnd - 1]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace ts.codefix {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => t.deleteNode(sourceFile, importDecl));
|
||||
return [createCodeFixAction(fixName, changes, [Diagnostics.Remove_import_from_0, showModuleSpecifier(importDecl)], fixIdDelete, Diagnostics.Delete_all_unused_declarations)];
|
||||
}
|
||||
const delDestructure = textChanges.ChangeTracker.with(context, t => tryDeleteFullDestructure(t, sourceFile, context.span.start));
|
||||
const delDestructure = textChanges.ChangeTracker.with(context, t => tryDeleteFullDestructure(t, sourceFile, context.span.start, /*deleted*/ undefined));
|
||||
if (delDestructure.length) {
|
||||
return [createCodeFixAction(fixName, delDestructure, Diagnostics.Remove_destructuring, fixIdDelete, Diagnostics.Delete_all_unused_declarations)];
|
||||
}
|
||||
@@ -27,7 +27,7 @@ namespace ts.codefix {
|
||||
const token = getToken(sourceFile, textSpanEnd(context.span));
|
||||
const result: CodeFixAction[] = [];
|
||||
|
||||
const deletion = textChanges.ChangeTracker.with(context, t => tryDeleteDeclaration(t, sourceFile, token));
|
||||
const deletion = textChanges.ChangeTracker.with(context, t => tryDeleteDeclaration(t, sourceFile, token, /*deleted*/ undefined));
|
||||
if (deletion.length) {
|
||||
result.push(createCodeFixAction(fixName, deletion, [Diagnostics.Remove_declaration_for_Colon_0, token.getText(sourceFile)], fixIdDelete, Diagnostics.Delete_all_unused_declarations));
|
||||
}
|
||||
@@ -40,30 +40,37 @@ namespace ts.codefix {
|
||||
return result;
|
||||
},
|
||||
fixIds: [fixIdPrefix, fixIdDelete],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
const { sourceFile } = context;
|
||||
const token = findPrecedingToken(textSpanEnd(diag), diag.file!);
|
||||
switch (context.fixId) {
|
||||
case fixIdPrefix:
|
||||
if (isIdentifier(token) && canPrefix(token)) {
|
||||
tryPrefixDeclaration(changes, diag.code, sourceFile, token);
|
||||
}
|
||||
break;
|
||||
case fixIdDelete:
|
||||
const importDecl = tryGetFullImport(diag.file!, diag.start!);
|
||||
if (importDecl) {
|
||||
changes.deleteNode(sourceFile, importDecl);
|
||||
}
|
||||
else {
|
||||
if (!tryDeleteFullDestructure(changes, sourceFile, diag.start!)) {
|
||||
tryDeleteDeclaration(changes, sourceFile, token);
|
||||
getAllCodeActions: context => {
|
||||
// Track a set of deleted nodes that may be ancestors of other marked for deletion -- only delete the ancestors.
|
||||
const deleted = new NodeSet();
|
||||
return codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
const { sourceFile } = context;
|
||||
const token = findPrecedingToken(textSpanEnd(diag), diag.file!);
|
||||
switch (context.fixId) {
|
||||
case fixIdPrefix:
|
||||
if (isIdentifier(token) && canPrefix(token)) {
|
||||
tryPrefixDeclaration(changes, diag.code, sourceFile, token);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Debug.fail(JSON.stringify(context.fixId));
|
||||
}
|
||||
}),
|
||||
break;
|
||||
case fixIdDelete:
|
||||
// Ignore if this range was already deleted.
|
||||
if (deleted.some(d => rangeContainsPosition(d, diag.start!))) break;
|
||||
|
||||
const importDecl = tryGetFullImport(diag.file!, diag.start!);
|
||||
if (importDecl) {
|
||||
changes.deleteNode(sourceFile, importDecl);
|
||||
}
|
||||
else {
|
||||
if (!tryDeleteFullDestructure(changes, sourceFile, diag.start!, deleted)) {
|
||||
tryDeleteDeclaration(changes, sourceFile, token, deleted);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Debug.fail(JSON.stringify(context.fixId));
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Sometimes the diagnostic span is an entire ImportDeclaration, so we should remove the whole thing.
|
||||
@@ -72,18 +79,20 @@ namespace ts.codefix {
|
||||
return startToken.kind === SyntaxKind.ImportKeyword ? tryCast(startToken.parent, isImportDeclaration) : undefined;
|
||||
}
|
||||
|
||||
function tryDeleteFullDestructure(changes: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number): boolean {
|
||||
function tryDeleteFullDestructure(changes: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, deletedAncestors: NodeSet | undefined): boolean {
|
||||
const startToken = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
if (startToken.kind !== SyntaxKind.OpenBraceToken || !isObjectBindingPattern(startToken.parent)) return false;
|
||||
const decl = startToken.parent.parent;
|
||||
switch (decl.kind) {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
tryDeleteVariableDeclaration(changes, sourceFile, decl);
|
||||
tryDeleteVariableDeclaration(changes, sourceFile, decl, deletedAncestors);
|
||||
break;
|
||||
case SyntaxKind.Parameter:
|
||||
if (deletedAncestors) deletedAncestors.add(decl);
|
||||
changes.deleteNodeInList(sourceFile, decl);
|
||||
break;
|
||||
case SyntaxKind.BindingElement:
|
||||
if (deletedAncestors) deletedAncestors.add(decl);
|
||||
changes.deleteNode(sourceFile, decl);
|
||||
break;
|
||||
default:
|
||||
@@ -93,7 +102,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function getToken(sourceFile: SourceFile, pos: number): Node {
|
||||
const token = findPrecedingToken(pos, sourceFile);
|
||||
const token = findPrecedingToken(pos, sourceFile, /*startNode*/ undefined, /*includeJsDoc*/ true);
|
||||
// this handles var ["computed"] = 12;
|
||||
return token.kind === SyntaxKind.CloseBracketToken ? findPrecedingToken(pos - 1, sourceFile) : token;
|
||||
}
|
||||
@@ -121,38 +130,41 @@ namespace ts.codefix {
|
||||
return false;
|
||||
}
|
||||
|
||||
function tryDeleteDeclaration(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node): void {
|
||||
function tryDeleteDeclaration(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node, deletedAncestors: NodeSet | undefined): void {
|
||||
switch (token.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
tryDeleteIdentifier(changes, sourceFile, <Identifier>token);
|
||||
tryDeleteIdentifier(changes, sourceFile, <Identifier>token, deletedAncestors);
|
||||
break;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
if (deletedAncestors) deletedAncestors.add(token.parent);
|
||||
changes.deleteNode(sourceFile, token.parent);
|
||||
break;
|
||||
default:
|
||||
tryDeleteDefault(changes, sourceFile, token);
|
||||
tryDeleteDefault(changes, sourceFile, token, deletedAncestors);
|
||||
}
|
||||
}
|
||||
|
||||
function tryDeleteDefault(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node): void {
|
||||
function tryDeleteDefault(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node, deletedAncestors: NodeSet | undefined): void {
|
||||
if (isDeclarationName(token)) {
|
||||
if (deletedAncestors) deletedAncestors.add(token.parent);
|
||||
changes.deleteNode(sourceFile, token.parent);
|
||||
}
|
||||
else if (isLiteralComputedPropertyDeclarationName(token)) {
|
||||
if (deletedAncestors) deletedAncestors.add(token.parent.parent);
|
||||
changes.deleteNode(sourceFile, token.parent.parent);
|
||||
}
|
||||
}
|
||||
|
||||
function tryDeleteIdentifier(changes: textChanges.ChangeTracker, sourceFile: SourceFile, identifier: Identifier): void {
|
||||
function tryDeleteIdentifier(changes: textChanges.ChangeTracker, sourceFile: SourceFile, identifier: Identifier, deletedAncestors: NodeSet | undefined): void {
|
||||
const parent = identifier.parent;
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
tryDeleteVariableDeclaration(changes, sourceFile, <VariableDeclaration>parent);
|
||||
tryDeleteVariableDeclaration(changes, sourceFile, <VariableDeclaration>parent, deletedAncestors);
|
||||
break;
|
||||
|
||||
case SyntaxKind.TypeParameter:
|
||||
const typeParameters = (<DeclarationWithTypeParameters>parent.parent).typeParameters;
|
||||
const typeParameters = getEffectiveTypeParameterDeclarations(<DeclarationWithTypeParameters>parent.parent);
|
||||
if (typeParameters.length === 1) {
|
||||
const previousToken = getTokenAtPosition(sourceFile, typeParameters.pos - 1, /*includeJsDocComment*/ false);
|
||||
const nextToken = getTokenAtPosition(sourceFile, typeParameters.end, /*includeJsDocComment*/ false);
|
||||
@@ -255,7 +267,7 @@ namespace ts.codefix {
|
||||
break;
|
||||
|
||||
default:
|
||||
tryDeleteDefault(changes, sourceFile, identifier);
|
||||
tryDeleteDefault(changes, sourceFile, identifier, deletedAncestors);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -280,15 +292,17 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
// token.parent is a variableDeclaration
|
||||
function tryDeleteVariableDeclaration(changes: textChanges.ChangeTracker, sourceFile: SourceFile, varDecl: VariableDeclaration): void {
|
||||
function tryDeleteVariableDeclaration(changes: textChanges.ChangeTracker, sourceFile: SourceFile, varDecl: VariableDeclaration, deletedAncestors: NodeSet | undefined): void {
|
||||
switch (varDecl.parent.parent.kind) {
|
||||
case SyntaxKind.ForStatement: {
|
||||
const forStatement = varDecl.parent.parent;
|
||||
const forInitializer = <VariableDeclarationList>forStatement.initializer;
|
||||
if (forInitializer.declarations.length === 1) {
|
||||
if (deletedAncestors) deletedAncestors.add(forInitializer);
|
||||
changes.deleteNode(sourceFile, forInitializer);
|
||||
}
|
||||
else {
|
||||
if (deletedAncestors) deletedAncestors.add(varDecl);
|
||||
changes.deleteNodeInList(sourceFile, varDecl);
|
||||
}
|
||||
break;
|
||||
@@ -298,6 +312,7 @@ namespace ts.codefix {
|
||||
const forOfStatement = varDecl.parent.parent;
|
||||
Debug.assert(forOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList);
|
||||
const forOfInitializer = <VariableDeclarationList>forOfStatement.initializer;
|
||||
if (deletedAncestors) deletedAncestors.add(forOfInitializer.declarations[0]);
|
||||
changes.replaceNode(sourceFile, forOfInitializer.declarations[0], createObjectLiteral());
|
||||
break;
|
||||
|
||||
@@ -308,11 +323,25 @@ namespace ts.codefix {
|
||||
default:
|
||||
const variableStatement = varDecl.parent.parent;
|
||||
if (variableStatement.declarationList.declarations.length === 1) {
|
||||
if (deletedAncestors) deletedAncestors.add(variableStatement);
|
||||
changes.deleteNode(sourceFile, variableStatement);
|
||||
}
|
||||
else {
|
||||
if (deletedAncestors) deletedAncestors.add(varDecl);
|
||||
changes.deleteNodeInList(sourceFile, varDecl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NodeSet {
|
||||
private map = createMap<Node>();
|
||||
|
||||
add(node: Node): void {
|
||||
this.map.set(String(getNodeId(node)), node);
|
||||
}
|
||||
|
||||
some(pred: (node: Node) => boolean): boolean {
|
||||
return forEachEntry(this.map, pred) || false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace ts.JsDoc {
|
||||
"author",
|
||||
"argument",
|
||||
"borrows",
|
||||
"callback",
|
||||
"class",
|
||||
"constant",
|
||||
"constructor",
|
||||
@@ -68,10 +69,12 @@ namespace ts.JsDoc {
|
||||
|
||||
function getCommentHavingNodes(declaration: Declaration): ReadonlyArray<JSDoc | JSDocTag> {
|
||||
switch (declaration.kind) {
|
||||
case SyntaxKind.JSDocParameterTag:
|
||||
case SyntaxKind.JSDocPropertyTag:
|
||||
return [declaration as JSDocPropertyTag];
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return [(declaration as JSDocTypedefTag).parent];
|
||||
return [(declaration as JSDocTypedefTag), (declaration as JSDocTypedefTag).parent];
|
||||
default:
|
||||
return getJSDocCommentsAndTags(declaration);
|
||||
}
|
||||
@@ -98,6 +101,7 @@ namespace ts.JsDoc {
|
||||
case SyntaxKind.JSDocTypeTag:
|
||||
return withNode((tag as JSDocTypeTag).typeExpression);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
case SyntaxKind.JSDocPropertyTag:
|
||||
case SyntaxKind.JSDocParameterTag:
|
||||
const { name } = tag as JSDocTypedefTag | JSDocPropertyTag | JSDocParameterTag;
|
||||
|
||||
@@ -290,7 +290,7 @@ namespace ts.NavigationBar {
|
||||
if (hasJSDocNodes(node)) {
|
||||
forEach(node.jsDoc, jsDoc => {
|
||||
forEach(jsDoc.tags, tag => {
|
||||
if (tag.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
if (isJSDocTypeAlias(tag)) {
|
||||
addLeafNode(tag);
|
||||
}
|
||||
});
|
||||
@@ -414,8 +414,6 @@ namespace ts.NavigationBar {
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.ClassExpression:
|
||||
return getFunctionOrClassName(<FunctionExpression | ArrowFunction | ClassExpression>node);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return getJSDocTypedefTagName(<JSDocTypedefTag>node);
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
@@ -460,31 +458,11 @@ namespace ts.NavigationBar {
|
||||
return "()";
|
||||
case SyntaxKind.IndexSignature:
|
||||
return "[]";
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return getJSDocTypedefTagName(<JSDocTypedefTag>node);
|
||||
default:
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
function getJSDocTypedefTagName(node: JSDocTypedefTag): string {
|
||||
if (node.name) {
|
||||
return node.name.text;
|
||||
}
|
||||
else {
|
||||
const parentNode = node.parent && node.parent.parent;
|
||||
if (parentNode && parentNode.kind === SyntaxKind.VariableStatement) {
|
||||
if (parentNode.declarationList.declarations.length > 0) {
|
||||
const nameIdentifier = parentNode.declarationList.declarations[0].name;
|
||||
if (nameIdentifier.kind === SyntaxKind.Identifier) {
|
||||
return nameIdentifier.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "<typedef>";
|
||||
}
|
||||
}
|
||||
|
||||
/** Flattens the NavNode tree to a list, keeping only the top-level items. */
|
||||
function topLevelItems(root: NavigationBarNode): NavigationBarNode[] {
|
||||
const topLevel: NavigationBarNode[] = [];
|
||||
@@ -511,6 +489,7 @@ namespace ts.NavigationBar {
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
return true;
|
||||
|
||||
case SyntaxKind.Constructor:
|
||||
|
||||
@@ -1464,8 +1464,8 @@ namespace ts.refactor.extractSymbol {
|
||||
}
|
||||
|
||||
// Note that we add the current node's type parameters *after* updating the corresponding scope.
|
||||
if (isDeclarationWithTypeParameters(curr) && curr.typeParameters) {
|
||||
for (const typeParameterDecl of curr.typeParameters) {
|
||||
if (isDeclarationWithTypeParameters(curr) && getEffectiveTypeParameterDeclarations(curr)) {
|
||||
for (const typeParameterDecl of getEffectiveTypeParameterDeclarations(curr)) {
|
||||
const typeParameter = checker.getTypeAtLocation(typeParameterDecl) as TypeParameter;
|
||||
if (allTypeParameterUsages.has(typeParameter.id.toString())) {
|
||||
seenTypeParameterUsages.set(typeParameter.id.toString(), typeParameter);
|
||||
@@ -1536,8 +1536,8 @@ namespace ts.refactor.extractSymbol {
|
||||
|
||||
function hasTypeParameters(node: Node) {
|
||||
return isDeclarationWithTypeParameters(node) &&
|
||||
node.typeParameters !== undefined &&
|
||||
node.typeParameters.length > 0;
|
||||
getEffectiveTypeParameterDeclarations(node) &&
|
||||
getEffectiveTypeParameterDeclarations(node).length > 0;
|
||||
}
|
||||
|
||||
function isInGenericContext(node: Node) {
|
||||
|
||||
@@ -3,7 +3,7 @@ namespace ts.refactor {
|
||||
const refactorName = "Move to a new file";
|
||||
registerRefactor(refactorName, {
|
||||
getAvailableActions(context): ApplicableRefactorInfo[] {
|
||||
if (!context.preferences.allowTextChangesInNewFiles || getStatementsToMove(context) === undefined) return undefined;
|
||||
if (!context.preferences.allowTextChangesInNewFiles || getFirstAndLastStatementToMove(context) === undefined) return undefined;
|
||||
const description = getLocaleSpecificMessage(Diagnostics.Move_to_a_new_file);
|
||||
return [{ name: refactorName, description, actions: [{ name: refactorName, description }] }];
|
||||
},
|
||||
@@ -15,7 +15,7 @@ namespace ts.refactor {
|
||||
}
|
||||
});
|
||||
|
||||
function getStatementsToMove(context: RefactorContext): ReadonlyArray<Statement> | undefined {
|
||||
function getFirstAndLastStatementToMove(context: RefactorContext): { readonly first: number, readonly afterLast: number } | undefined {
|
||||
const { file } = context;
|
||||
const range = createTextRangeFromSpan(getRefactorContextSpan(context));
|
||||
const { statements } = file;
|
||||
@@ -28,12 +28,12 @@ namespace ts.refactor {
|
||||
// Can't be partially into the next node
|
||||
if (afterEndNodeIndex !== -1 && (afterEndNodeIndex === 0 || statements[afterEndNodeIndex].getStart(file) < range.end)) return undefined;
|
||||
|
||||
return statements.slice(startNodeIndex, afterEndNodeIndex === -1 ? statements.length : afterEndNodeIndex);
|
||||
return { first: startNodeIndex, afterLast: afterEndNodeIndex === -1 ? statements.length : afterEndNodeIndex };
|
||||
}
|
||||
|
||||
function doChange(oldFile: SourceFile, program: Program, toMove: ReadonlyArray<Statement>, changes: textChanges.ChangeTracker, host: LanguageServiceHost): void {
|
||||
function doChange(oldFile: SourceFile, program: Program, toMove: ToMove, changes: textChanges.ChangeTracker, host: LanguageServiceHost): void {
|
||||
const checker = program.getTypeChecker();
|
||||
const usage = getUsageInfo(oldFile, toMove, checker);
|
||||
const usage = getUsageInfo(oldFile, toMove.all, checker);
|
||||
|
||||
const currentDirectory = getDirectoryPath(oldFile.fileName);
|
||||
const extension = extensionFromPath(oldFile.fileName);
|
||||
@@ -46,6 +46,42 @@ namespace ts.refactor {
|
||||
addNewFileToTsconfig(program, changes, oldFile.fileName, newFileNameWithExtension, hostGetCanonicalFileName(host));
|
||||
}
|
||||
|
||||
interface StatementRange {
|
||||
readonly first: Statement;
|
||||
readonly last: Statement;
|
||||
}
|
||||
interface ToMove {
|
||||
readonly all: ReadonlyArray<Statement>;
|
||||
readonly ranges: ReadonlyArray<StatementRange>;
|
||||
}
|
||||
|
||||
// Filters imports out of the range of statements to move. Imports will be copied to the new file anyway, and may still be needed in the old file.
|
||||
function getStatementsToMove(context: RefactorContext): ToMove | undefined {
|
||||
const { statements } = context.file;
|
||||
const { first, afterLast } = getFirstAndLastStatementToMove(context)!;
|
||||
const all: Statement[] = [];
|
||||
const ranges: StatementRange[] = [];
|
||||
const rangeToMove = statements.slice(first, afterLast);
|
||||
getRangesWhere(rangeToMove, s => !isPureImport(s), (start, afterEnd) => {
|
||||
for (let i = start; i < afterEnd; i++) all.push(rangeToMove[i]);
|
||||
ranges.push({ first: rangeToMove[start], last: rangeToMove[afterEnd - 1] });
|
||||
});
|
||||
return { all, ranges };
|
||||
}
|
||||
|
||||
function isPureImport(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return true;
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return !hasModifier(node, ModifierFlags.Export);
|
||||
case SyntaxKind.VariableStatement:
|
||||
return (node as VariableStatement).declarationList.declarations.every(d => isRequireCall(d.initializer, /*checkArgumentIsStringLiteralLike*/ true));
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function addNewFileToTsconfig(program: Program, changes: textChanges.ChangeTracker, oldFileName: string, newFileNameWithExtension: string, getCanonicalFileName: GetCanonicalFileName): void {
|
||||
const cfg = program.getCompilerOptions().configFile;
|
||||
if (!cfg) return;
|
||||
@@ -62,13 +98,13 @@ namespace ts.refactor {
|
||||
}
|
||||
|
||||
function getNewStatements(
|
||||
oldFile: SourceFile, usage: UsageInfo, changes: textChanges.ChangeTracker, toMove: ReadonlyArray<Statement>, program: Program, newModuleName: string,
|
||||
oldFile: SourceFile, usage: UsageInfo, changes: textChanges.ChangeTracker, toMove: ToMove, program: Program, newModuleName: string,
|
||||
): ReadonlyArray<Statement> {
|
||||
const checker = program.getTypeChecker();
|
||||
|
||||
if (!oldFile.externalModuleIndicator && !oldFile.commonJsModuleIndicator) {
|
||||
changes.deleteNodeRange(oldFile, first(toMove), last(toMove));
|
||||
return toMove;
|
||||
deleteMovedStatements(oldFile, toMove.ranges, changes);
|
||||
return toMove.all;
|
||||
}
|
||||
|
||||
const useEs6ModuleSyntax = !!oldFile.externalModuleIndicator;
|
||||
@@ -77,17 +113,23 @@ namespace ts.refactor {
|
||||
changes.insertNodeBefore(oldFile, oldFile.statements[0], importsFromNewFile, /*blankLineBetween*/ true);
|
||||
}
|
||||
|
||||
deleteUnusedOldImports(oldFile, toMove, changes, usage.unusedImportsFromOldFile, checker);
|
||||
changes.deleteNodeRange(oldFile, first(toMove), last(toMove));
|
||||
deleteUnusedOldImports(oldFile, toMove.all, changes, usage.unusedImportsFromOldFile, checker);
|
||||
deleteMovedStatements(oldFile, toMove.ranges, changes);
|
||||
|
||||
updateImportsInOtherFiles(changes, program, oldFile, usage.movedSymbols, newModuleName);
|
||||
|
||||
return [
|
||||
...getNewFileImportsAndAddExportInOldFile(oldFile, usage.oldImportsNeededByNewFile, usage.newFileImportsFromOldFile, changes, checker, useEs6ModuleSyntax),
|
||||
...addExports(oldFile, toMove, usage.oldFileImportsFromNewFile, useEs6ModuleSyntax),
|
||||
...addExports(oldFile, toMove.all, usage.oldFileImportsFromNewFile, useEs6ModuleSyntax),
|
||||
];
|
||||
}
|
||||
|
||||
function deleteMovedStatements(sourceFile: SourceFile, moved: ReadonlyArray<StatementRange>, changes: textChanges.ChangeTracker) {
|
||||
for (const { first, last } of moved) {
|
||||
changes.deleteNodeRange(sourceFile, first, last);
|
||||
}
|
||||
}
|
||||
|
||||
function deleteUnusedOldImports(oldFile: SourceFile, toMove: ReadonlyArray<Statement>, changes: textChanges.ChangeTracker, toDelete: ReadonlySymbolSet, checker: TypeChecker) {
|
||||
for (const statement of oldFile.statements) {
|
||||
if (contains(toMove, statement)) continue;
|
||||
@@ -391,13 +433,14 @@ namespace ts.refactor {
|
||||
}
|
||||
function isVariableDeclarationInImport(decl: VariableDeclaration) {
|
||||
return isSourceFile(decl.parent.parent.parent) &&
|
||||
isRequireCall(decl.initializer, /*checkArgumentIsStringLiteralLike*/ true);
|
||||
decl.initializer && isRequireCall(decl.initializer, /*checkArgumentIsStringLiteralLike*/ true);
|
||||
}
|
||||
|
||||
function filterImport(i: SupportedImport, moduleSpecifier: StringLiteralLike, keep: (name: Identifier) => boolean): SupportedImportStatement | undefined {
|
||||
switch (i.kind) {
|
||||
case SyntaxKind.ImportDeclaration: {
|
||||
const clause = i.importClause;
|
||||
if (!clause) return undefined;
|
||||
const defaultImport = clause.name && keep(clause.name) ? clause.name : undefined;
|
||||
const namedBindings = clause.namedBindings && filterNamedBindings(clause.namedBindings, keep);
|
||||
return defaultImport || namedBindings
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return diags.concat(checker.getSuggestionDiagnostics(sourceFile));
|
||||
return diags.concat(checker.getSuggestionDiagnostics(sourceFile)).sort((d1, d2) => d1.start - d2.start);
|
||||
}
|
||||
|
||||
// convertToEs6Module only works on top-level, so don't trigger it if commonjs code only appears in nested scopes.
|
||||
|
||||
+29
-30
@@ -212,7 +212,7 @@ namespace ts.textChanges {
|
||||
export class ChangeTracker {
|
||||
private readonly changes: Change[] = [];
|
||||
private readonly newFiles: { readonly oldFile: SourceFile, readonly fileName: string, readonly statements: ReadonlyArray<Statement> }[] = [];
|
||||
private readonly deletedNodesInLists: true[] = []; // Stores ids of nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`.
|
||||
private readonly deletedNodesInLists = new NodeSet(); // Stores ids of nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`.
|
||||
private readonly classesWithNodesInsertedAtStart = createMap<ClassDeclaration>(); // Set<ClassDeclaration> implemented as Map<node id, ClassDeclaration>
|
||||
|
||||
public static fromContext(context: TextChangesContext): ChangeTracker {
|
||||
@@ -262,35 +262,15 @@ namespace ts.textChanges {
|
||||
this.deleteNode(sourceFile, node);
|
||||
return this;
|
||||
}
|
||||
const id = getNodeId(node);
|
||||
Debug.assert(!this.deletedNodesInLists[id], "Deleting a node twice");
|
||||
this.deletedNodesInLists[id] = true;
|
||||
if (index !== containingList.length - 1) {
|
||||
const nextToken = getTokenAtPosition(sourceFile, node.end, /*includeJsDocComment*/ false);
|
||||
if (nextToken && isSeparator(node, nextToken)) {
|
||||
// find first non-whitespace position in the leading trivia of the node
|
||||
const startPosition = skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
|
||||
const nextElement = containingList[index + 1];
|
||||
/// find first non-whitespace position in the leading trivia of the next node
|
||||
const endPosition = skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, nextElement, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
|
||||
// shift next node so its first non-whitespace position will be moved to the first non-whitespace position of the deleted node
|
||||
this.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
|
||||
}
|
||||
}
|
||||
else {
|
||||
const prev = containingList[index - 1];
|
||||
if (this.deletedNodesInLists[getNodeId(prev)]) {
|
||||
const pos = skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
|
||||
const end = getAdjustedEndPosition(sourceFile, node, {});
|
||||
this.deleteRange(sourceFile, { pos, end });
|
||||
}
|
||||
else {
|
||||
const previousToken = getTokenAtPosition(sourceFile, containingList[index - 1].end, /*includeJsDocComment*/ false);
|
||||
if (previousToken && isSeparator(node, previousToken)) {
|
||||
this.deleteNodeRange(sourceFile, previousToken, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note: We will only delete a comma *after* a node. This will leave a trailing comma if we delete the last node.
|
||||
// That's handled in the end by `finishTrailingCommaAfterDeletingNodesInList`.
|
||||
Debug.assert(!this.deletedNodesInLists.has(node), "Deleting a node twice");
|
||||
this.deletedNodesInLists.add(node);
|
||||
this.deleteRange(sourceFile, {
|
||||
pos: startPositionToDeleteNodeInList(sourceFile, node),
|
||||
end: index === containingList.length - 1 ? getAdjustedEndPosition(sourceFile, node, {}) : startPositionToDeleteNodeInList(sourceFile, containingList[index + 1]),
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -683,6 +663,19 @@ namespace ts.textChanges {
|
||||
});
|
||||
}
|
||||
|
||||
private finishTrailingCommaAfterDeletingNodesInList() {
|
||||
this.deletedNodesInLists.forEach(node => {
|
||||
const sourceFile = node.getSourceFile();
|
||||
const list = formatting.SmartIndenter.getContainingList(node, sourceFile);
|
||||
if (node !== last(list)) return;
|
||||
|
||||
const lastNonDeletedIndex = findLastIndex(list, n => !this.deletedNodesInLists.has(n), list.length - 2);
|
||||
if (lastNonDeletedIndex !== -1) {
|
||||
this.deleteRange(sourceFile, { pos: list[lastNonDeletedIndex].end, end: startPositionToDeleteNodeInList(sourceFile, list[lastNonDeletedIndex + 1]) });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: after calling this, the TextChanges object must be discarded!
|
||||
* @param validate only for tests
|
||||
@@ -691,6 +684,7 @@ namespace ts.textChanges {
|
||||
*/
|
||||
public getChanges(validate?: ValidateNonFormattedText): FileTextChanges[] {
|
||||
this.finishClassesWithNodesInsertedAtStart();
|
||||
this.finishTrailingCommaAfterDeletingNodesInList();
|
||||
const changes = changesToText.getTextChangesFromChanges(this.changes, this.newLineCharacter, this.formatContext, validate);
|
||||
for (const { oldFile, fileName, statements } of this.newFiles) {
|
||||
changes.push(changesToText.newFileChanges(oldFile, fileName, statements, this.newLineCharacter));
|
||||
@@ -703,6 +697,11 @@ namespace ts.textChanges {
|
||||
}
|
||||
}
|
||||
|
||||
// find first non-whitespace position in the leading trivia of the node
|
||||
function startPositionToDeleteNodeInList(sourceFile: SourceFile, node: Node): number {
|
||||
return skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
|
||||
}
|
||||
|
||||
function getClassBraceEnds(cls: ClassLikeDeclaration, sourceFile: SourceFile): [number, number] {
|
||||
return [findChildOfKind(cls, SyntaxKind.OpenBraceToken, sourceFile).end, findChildOfKind(cls, SyntaxKind.CloseBraceToken, sourceFile).end];
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
"codefixes/moduleSpecifiers.ts",
|
||||
"codefixes/requireInTs.ts",
|
||||
"codefixes/useDefaultImport.ts",
|
||||
"codefixes/fixAddModuleReferTypeMissingTypeof.ts",
|
||||
"refactors/extractSymbol.ts",
|
||||
"refactors/generateGetAccessorAndSetAccessor.ts",
|
||||
"refactors/moveToNewFile.ts",
|
||||
|
||||
@@ -276,7 +276,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getContainerNode(node: Node): Declaration {
|
||||
if (node.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
if (isJSDocTypeAlias(node)) {
|
||||
// This doesn't just apply to the node immediately under the comment, but to everything in its parent's scope.
|
||||
// node.parent = the JSDoc comment, node.parent.parent = the node having the comment.
|
||||
// Then we get parent again in the loop.
|
||||
@@ -315,7 +315,10 @@ namespace ts {
|
||||
case SyntaxKind.ClassExpression:
|
||||
return ScriptElementKind.classElement;
|
||||
case SyntaxKind.InterfaceDeclaration: return ScriptElementKind.interfaceElement;
|
||||
case SyntaxKind.TypeAliasDeclaration: return ScriptElementKind.typeElement;
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return ScriptElementKind.typeElement;
|
||||
case SyntaxKind.EnumDeclaration: return ScriptElementKind.enumElement;
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return getKindOfVariableDeclaration(<VariableDeclaration>node);
|
||||
@@ -346,8 +349,6 @@ namespace ts {
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
return ScriptElementKind.alias;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return ScriptElementKind.typeElement;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
const kind = getSpecialPropertyAssignmentKind(node as BinaryExpression);
|
||||
const { right } = node as BinaryExpression;
|
||||
@@ -416,6 +417,10 @@ namespace ts {
|
||||
return startEndContainsRange(r1.pos, r1.end, r2);
|
||||
}
|
||||
|
||||
export function rangeContainsPosition(r: TextRange, pos: number): boolean {
|
||||
return r.pos <= pos && pos <= r.end;
|
||||
}
|
||||
|
||||
export function startEndContainsRange(start: number, end: number, range: TextRange): boolean {
|
||||
return start <= range.pos && end >= range.end;
|
||||
}
|
||||
@@ -1275,6 +1280,23 @@ namespace ts {
|
||||
}
|
||||
return propSymbol;
|
||||
}
|
||||
|
||||
export class NodeSet {
|
||||
private map = createMap<Node>();
|
||||
|
||||
add(node: Node): void {
|
||||
this.map.set(String(getNodeId(node)), node);
|
||||
}
|
||||
has(node: Node): boolean {
|
||||
return this.map.has(String(getNodeId(node)));
|
||||
}
|
||||
forEach(cb: (node: Node) => void): void {
|
||||
this.map.forEach(cb);
|
||||
}
|
||||
some(pred: (node: Node) => boolean): boolean {
|
||||
return forEachEntry(this.map, pred) || false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Display-part writer helpers
|
||||
|
||||
+4
-4
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocParameterTag",
|
||||
"pos": 6,
|
||||
"end": 63,
|
||||
"end": 64,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 6,
|
||||
@@ -21,11 +21,11 @@
|
||||
"typeExpression": {
|
||||
"kind": "JSDocTypeExpression",
|
||||
"pos": 34,
|
||||
"end": 63,
|
||||
"end": 64,
|
||||
"type": {
|
||||
"kind": "JSDocTypeLiteral",
|
||||
"pos": 34,
|
||||
"end": 63,
|
||||
"end": 64,
|
||||
"jsDocPropertyTags": [
|
||||
{
|
||||
"kind": "JSDocParameterTag",
|
||||
@@ -88,6 +88,6 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 6,
|
||||
"end": 63
|
||||
"end": 64
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocParameterTag",
|
||||
"pos": 8,
|
||||
"end": 40,
|
||||
"end": 42,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -40,6 +40,6 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 40
|
||||
"end": 42
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocParameterTag",
|
||||
"pos": 8,
|
||||
"end": 45,
|
||||
"end": 47,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -40,6 +40,6 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 45
|
||||
"end": 47
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocParameterTag",
|
||||
"pos": 7,
|
||||
"end": 58,
|
||||
"end": 59,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 7,
|
||||
@@ -30,6 +30,6 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 7,
|
||||
"end": 58
|
||||
"end": 59
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocReturnTag",
|
||||
"pos": 8,
|
||||
"end": 16,
|
||||
"end": 15,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -21,6 +21,6 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 16
|
||||
"end": 15
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocParameterTag",
|
||||
"pos": 8,
|
||||
"end": 30,
|
||||
"end": 32,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -39,6 +39,6 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 30
|
||||
"end": 32
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocParameterTag",
|
||||
"pos": 8,
|
||||
"end": 55,
|
||||
"end": 57,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -40,6 +40,6 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 55
|
||||
"end": 57
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocParameterTag",
|
||||
"pos": 8,
|
||||
"end": 57,
|
||||
"end": 59,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -40,6 +40,6 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 57
|
||||
"end": 59
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocParameterTag",
|
||||
"pos": 8,
|
||||
"end": 62,
|
||||
"end": 64,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -40,6 +40,6 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 62
|
||||
"end": 64
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocParameterTag",
|
||||
"pos": 8,
|
||||
"end": 42,
|
||||
"end": 44,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -40,6 +40,6 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 42
|
||||
"end": 44
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocParameterTag",
|
||||
"pos": 8,
|
||||
"end": 19,
|
||||
"end": 21,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -29,6 +29,6 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 19
|
||||
"end": 21
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocTemplateTag",
|
||||
"pos": 8,
|
||||
"end": 20,
|
||||
"end": 19,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -22,7 +22,7 @@
|
||||
"0": {
|
||||
"kind": "TypeParameter",
|
||||
"pos": 18,
|
||||
"end": 20,
|
||||
"end": 19,
|
||||
"name": {
|
||||
"kind": "Identifier",
|
||||
"pos": 18,
|
||||
@@ -32,11 +32,11 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 18,
|
||||
"end": 20
|
||||
"end": 19
|
||||
}
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 20
|
||||
"end": 19
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocTemplateTag",
|
||||
"pos": 8,
|
||||
"end": 22,
|
||||
"end": 21,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -33,7 +33,7 @@
|
||||
"1": {
|
||||
"kind": "TypeParameter",
|
||||
"pos": 20,
|
||||
"end": 22,
|
||||
"end": 21,
|
||||
"name": {
|
||||
"kind": "Identifier",
|
||||
"pos": 20,
|
||||
@@ -43,11 +43,11 @@
|
||||
},
|
||||
"length": 2,
|
||||
"pos": 18,
|
||||
"end": 22
|
||||
"end": 21
|
||||
}
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 22
|
||||
"end": 21
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocTemplateTag",
|
||||
"pos": 8,
|
||||
"end": 23,
|
||||
"end": 22,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -33,7 +33,7 @@
|
||||
"1": {
|
||||
"kind": "TypeParameter",
|
||||
"pos": 21,
|
||||
"end": 23,
|
||||
"end": 22,
|
||||
"name": {
|
||||
"kind": "Identifier",
|
||||
"pos": 21,
|
||||
@@ -43,11 +43,11 @@
|
||||
},
|
||||
"length": 2,
|
||||
"pos": 18,
|
||||
"end": 23
|
||||
"end": 22
|
||||
}
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 23
|
||||
"end": 22
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocTemplateTag",
|
||||
"pos": 8,
|
||||
"end": 23,
|
||||
"end": 22,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -33,7 +33,7 @@
|
||||
"1": {
|
||||
"kind": "TypeParameter",
|
||||
"pos": 21,
|
||||
"end": 23,
|
||||
"end": 22,
|
||||
"name": {
|
||||
"kind": "Identifier",
|
||||
"pos": 21,
|
||||
@@ -43,11 +43,11 @@
|
||||
},
|
||||
"length": 2,
|
||||
"pos": 18,
|
||||
"end": 23
|
||||
"end": 22
|
||||
}
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 23
|
||||
"end": 22
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocTemplateTag",
|
||||
"pos": 8,
|
||||
"end": 24,
|
||||
"end": 23,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -33,7 +33,7 @@
|
||||
"1": {
|
||||
"kind": "TypeParameter",
|
||||
"pos": 22,
|
||||
"end": 24,
|
||||
"end": 23,
|
||||
"name": {
|
||||
"kind": "Identifier",
|
||||
"pos": 22,
|
||||
@@ -43,11 +43,11 @@
|
||||
},
|
||||
"length": 2,
|
||||
"pos": 18,
|
||||
"end": 24
|
||||
"end": 23
|
||||
}
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 24
|
||||
"end": 23
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -40,7 +40,7 @@
|
||||
"1": {
|
||||
"kind": "JSDocParameterTag",
|
||||
"pos": 34,
|
||||
"end": 56,
|
||||
"end": 58,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 34,
|
||||
@@ -73,6 +73,6 @@
|
||||
},
|
||||
"length": 2,
|
||||
"pos": 8,
|
||||
"end": 56
|
||||
"end": 58
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -40,7 +40,7 @@
|
||||
"1": {
|
||||
"kind": "JSDocParameterTag",
|
||||
"pos": 30,
|
||||
"end": 52,
|
||||
"end": 54,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 30,
|
||||
@@ -73,6 +73,6 @@
|
||||
},
|
||||
"length": 2,
|
||||
"pos": 8,
|
||||
"end": 52
|
||||
"end": 54
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -6,7 +6,7 @@
|
||||
"0": {
|
||||
"kind": "JSDocTypedefTag",
|
||||
"pos": 8,
|
||||
"end": 98,
|
||||
"end": 100,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 8,
|
||||
@@ -32,8 +32,8 @@
|
||||
},
|
||||
"typeExpression": {
|
||||
"kind": "JSDocTypeLiteral",
|
||||
"pos": 26,
|
||||
"end": 98,
|
||||
"pos": 28,
|
||||
"end": 100,
|
||||
"jsDocPropertyTags": [
|
||||
{
|
||||
"kind": "JSDocPropertyTag",
|
||||
@@ -72,7 +72,7 @@
|
||||
{
|
||||
"kind": "JSDocPropertyTag",
|
||||
"pos": 74,
|
||||
"end": 98,
|
||||
"end": 97,
|
||||
"atToken": {
|
||||
"kind": "AtToken",
|
||||
"pos": 74,
|
||||
@@ -108,6 +108,6 @@
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 8,
|
||||
"end": 98
|
||||
"end": 100
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
=== tests/cases/compiler/Class.ts ===
|
||||
import { Configurable } from "./Configurable"
|
||||
>Configurable : <T extends new (...args: any[]) => {}>(base: T) => T
|
||||
>Configurable : <T extends import("tests/cases/compiler/Configurable").Constructor<{}>>(base: T) => T
|
||||
|
||||
export class HiddenClass {}
|
||||
>HiddenClass : HiddenClass
|
||||
@@ -8,7 +8,7 @@ export class HiddenClass {}
|
||||
export class ActualClass extends Configurable(HiddenClass) {}
|
||||
>ActualClass : ActualClass
|
||||
>Configurable(HiddenClass) : HiddenClass
|
||||
>Configurable : <T extends new (...args: any[]) => {}>(base: T) => T
|
||||
>Configurable : <T extends import("tests/cases/compiler/Configurable").Constructor<{}>>(base: T) => T
|
||||
>HiddenClass : typeof HiddenClass
|
||||
|
||||
=== tests/cases/compiler/Configurable.ts ===
|
||||
|
||||
+39
-21
@@ -349,22 +349,24 @@ declare namespace ts {
|
||||
JSDocVariadicType = 284,
|
||||
JSDocComment = 285,
|
||||
JSDocTypeLiteral = 286,
|
||||
JSDocTag = 287,
|
||||
JSDocAugmentsTag = 288,
|
||||
JSDocClassTag = 289,
|
||||
JSDocParameterTag = 290,
|
||||
JSDocReturnTag = 291,
|
||||
JSDocTypeTag = 292,
|
||||
JSDocTemplateTag = 293,
|
||||
JSDocTypedefTag = 294,
|
||||
JSDocPropertyTag = 295,
|
||||
SyntaxList = 296,
|
||||
NotEmittedStatement = 297,
|
||||
PartiallyEmittedExpression = 298,
|
||||
CommaListExpression = 299,
|
||||
MergeDeclarationMarker = 300,
|
||||
EndOfDeclarationMarker = 301,
|
||||
Count = 302,
|
||||
JSDocSignature = 287,
|
||||
JSDocTag = 288,
|
||||
JSDocAugmentsTag = 289,
|
||||
JSDocClassTag = 290,
|
||||
JSDocCallbackTag = 291,
|
||||
JSDocParameterTag = 292,
|
||||
JSDocReturnTag = 293,
|
||||
JSDocTypeTag = 294,
|
||||
JSDocTemplateTag = 295,
|
||||
JSDocTypedefTag = 296,
|
||||
JSDocPropertyTag = 297,
|
||||
SyntaxList = 298,
|
||||
NotEmittedStatement = 299,
|
||||
PartiallyEmittedExpression = 300,
|
||||
CommaListExpression = 301,
|
||||
MergeDeclarationMarker = 302,
|
||||
EndOfDeclarationMarker = 303,
|
||||
Count = 304,
|
||||
FirstAssignment = 58,
|
||||
LastAssignment = 70,
|
||||
FirstCompoundAssignment = 59,
|
||||
@@ -391,9 +393,9 @@ declare namespace ts {
|
||||
LastBinaryOperator = 70,
|
||||
FirstNode = 145,
|
||||
FirstJSDocNode = 277,
|
||||
LastJSDocNode = 295,
|
||||
FirstJSDocTagNode = 287,
|
||||
LastJSDocTagNode = 295
|
||||
LastJSDocNode = 297,
|
||||
FirstJSDocTagNode = 288,
|
||||
LastJSDocTagNode = 297
|
||||
}
|
||||
enum NodeFlags {
|
||||
None = 0,
|
||||
@@ -1280,7 +1282,7 @@ declare namespace ts {
|
||||
block: Block;
|
||||
}
|
||||
type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode;
|
||||
type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature;
|
||||
interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression;
|
||||
name?: Identifier;
|
||||
@@ -1537,6 +1539,19 @@ declare namespace ts {
|
||||
name?: Identifier;
|
||||
typeExpression?: JSDocTypeExpression | JSDocTypeLiteral;
|
||||
}
|
||||
interface JSDocCallbackTag extends JSDocTag, NamedDeclaration {
|
||||
parent: JSDoc;
|
||||
kind: SyntaxKind.JSDocCallbackTag;
|
||||
fullName?: JSDocNamespaceDeclaration | Identifier;
|
||||
name?: Identifier;
|
||||
typeExpression: JSDocSignature;
|
||||
}
|
||||
interface JSDocSignature extends JSDocType, Declaration {
|
||||
kind: SyntaxKind.JSDocSignature;
|
||||
typeParameters?: ReadonlyArray<JSDocTemplateTag>;
|
||||
parameters: ReadonlyArray<JSDocParameterTag>;
|
||||
type: JSDocReturnTag | undefined;
|
||||
}
|
||||
interface JSDocPropertyLikeTag extends JSDocTag, Declaration {
|
||||
parent: JSDoc;
|
||||
name: EntityName;
|
||||
@@ -1885,6 +1900,7 @@ declare namespace ts {
|
||||
WriteArrayAsGenericType = 2,
|
||||
GenerateNamesForShadowedTypeParams = 4,
|
||||
UseStructuralFallback = 8,
|
||||
ForbidIndexedAccessSymbolReferences = 16,
|
||||
WriteTypeArgumentsOfSignature = 32,
|
||||
UseFullyQualifiedType = 64,
|
||||
UseOnlyExternalAliasing = 128,
|
||||
@@ -2283,7 +2299,7 @@ declare namespace ts {
|
||||
Construct = 1
|
||||
}
|
||||
interface Signature {
|
||||
declaration?: SignatureDeclaration;
|
||||
declaration?: SignatureDeclaration | JSDocSignature;
|
||||
typeParameters?: TypeParameter[];
|
||||
parameters: Symbol[];
|
||||
}
|
||||
@@ -3362,6 +3378,8 @@ declare namespace ts {
|
||||
function isJSDocPropertyTag(node: Node): node is JSDocPropertyTag;
|
||||
function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag;
|
||||
function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral;
|
||||
function isJSDocCallbackTag(node: Node): node is JSDocCallbackTag;
|
||||
function isJSDocSignature(node: Node): node is JSDocSignature;
|
||||
}
|
||||
declare namespace ts {
|
||||
/**
|
||||
|
||||
+39
-21
@@ -349,22 +349,24 @@ declare namespace ts {
|
||||
JSDocVariadicType = 284,
|
||||
JSDocComment = 285,
|
||||
JSDocTypeLiteral = 286,
|
||||
JSDocTag = 287,
|
||||
JSDocAugmentsTag = 288,
|
||||
JSDocClassTag = 289,
|
||||
JSDocParameterTag = 290,
|
||||
JSDocReturnTag = 291,
|
||||
JSDocTypeTag = 292,
|
||||
JSDocTemplateTag = 293,
|
||||
JSDocTypedefTag = 294,
|
||||
JSDocPropertyTag = 295,
|
||||
SyntaxList = 296,
|
||||
NotEmittedStatement = 297,
|
||||
PartiallyEmittedExpression = 298,
|
||||
CommaListExpression = 299,
|
||||
MergeDeclarationMarker = 300,
|
||||
EndOfDeclarationMarker = 301,
|
||||
Count = 302,
|
||||
JSDocSignature = 287,
|
||||
JSDocTag = 288,
|
||||
JSDocAugmentsTag = 289,
|
||||
JSDocClassTag = 290,
|
||||
JSDocCallbackTag = 291,
|
||||
JSDocParameterTag = 292,
|
||||
JSDocReturnTag = 293,
|
||||
JSDocTypeTag = 294,
|
||||
JSDocTemplateTag = 295,
|
||||
JSDocTypedefTag = 296,
|
||||
JSDocPropertyTag = 297,
|
||||
SyntaxList = 298,
|
||||
NotEmittedStatement = 299,
|
||||
PartiallyEmittedExpression = 300,
|
||||
CommaListExpression = 301,
|
||||
MergeDeclarationMarker = 302,
|
||||
EndOfDeclarationMarker = 303,
|
||||
Count = 304,
|
||||
FirstAssignment = 58,
|
||||
LastAssignment = 70,
|
||||
FirstCompoundAssignment = 59,
|
||||
@@ -391,9 +393,9 @@ declare namespace ts {
|
||||
LastBinaryOperator = 70,
|
||||
FirstNode = 145,
|
||||
FirstJSDocNode = 277,
|
||||
LastJSDocNode = 295,
|
||||
FirstJSDocTagNode = 287,
|
||||
LastJSDocTagNode = 295
|
||||
LastJSDocNode = 297,
|
||||
FirstJSDocTagNode = 288,
|
||||
LastJSDocTagNode = 297
|
||||
}
|
||||
enum NodeFlags {
|
||||
None = 0,
|
||||
@@ -1280,7 +1282,7 @@ declare namespace ts {
|
||||
block: Block;
|
||||
}
|
||||
type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode;
|
||||
type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature;
|
||||
interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression;
|
||||
name?: Identifier;
|
||||
@@ -1537,6 +1539,19 @@ declare namespace ts {
|
||||
name?: Identifier;
|
||||
typeExpression?: JSDocTypeExpression | JSDocTypeLiteral;
|
||||
}
|
||||
interface JSDocCallbackTag extends JSDocTag, NamedDeclaration {
|
||||
parent: JSDoc;
|
||||
kind: SyntaxKind.JSDocCallbackTag;
|
||||
fullName?: JSDocNamespaceDeclaration | Identifier;
|
||||
name?: Identifier;
|
||||
typeExpression: JSDocSignature;
|
||||
}
|
||||
interface JSDocSignature extends JSDocType, Declaration {
|
||||
kind: SyntaxKind.JSDocSignature;
|
||||
typeParameters?: ReadonlyArray<JSDocTemplateTag>;
|
||||
parameters: ReadonlyArray<JSDocParameterTag>;
|
||||
type: JSDocReturnTag | undefined;
|
||||
}
|
||||
interface JSDocPropertyLikeTag extends JSDocTag, Declaration {
|
||||
parent: JSDoc;
|
||||
name: EntityName;
|
||||
@@ -1885,6 +1900,7 @@ declare namespace ts {
|
||||
WriteArrayAsGenericType = 2,
|
||||
GenerateNamesForShadowedTypeParams = 4,
|
||||
UseStructuralFallback = 8,
|
||||
ForbidIndexedAccessSymbolReferences = 16,
|
||||
WriteTypeArgumentsOfSignature = 32,
|
||||
UseFullyQualifiedType = 64,
|
||||
UseOnlyExternalAliasing = 128,
|
||||
@@ -2283,7 +2299,7 @@ declare namespace ts {
|
||||
Construct = 1
|
||||
}
|
||||
interface Signature {
|
||||
declaration?: SignatureDeclaration;
|
||||
declaration?: SignatureDeclaration | JSDocSignature;
|
||||
typeParameters?: TypeParameter[];
|
||||
parameters: Symbol[];
|
||||
}
|
||||
@@ -3362,6 +3378,8 @@ declare namespace ts {
|
||||
function isJSDocPropertyTag(node: Node): node is JSDocPropertyTag;
|
||||
function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag;
|
||||
function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral;
|
||||
function isJSDocCallbackTag(node: Node): node is JSDocCallbackTag;
|
||||
function isJSDocSignature(node: Node): node is JSDocSignature;
|
||||
}
|
||||
declare namespace ts {
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ declare module "express" {
|
||||
function e(): e.Express;
|
||||
>e : typeof e
|
||||
>e : any
|
||||
>Express : Express
|
||||
>Express : e.Express
|
||||
|
||||
namespace e {
|
||||
>e : typeof e
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
=== tests/cases/conformance/jsdoc/mod1.js ===
|
||||
/** @callback Con - some kind of continuation
|
||||
* @param {object | undefined} error
|
||||
* @return {any} I don't even know what this should return
|
||||
*/
|
||||
module.exports = C
|
||||
>module : Symbol(export=, Decl(mod1.js, 0, 0))
|
||||
>exports : Symbol(export=, Decl(mod1.js, 0, 0))
|
||||
>C : Symbol(C, Decl(mod1.js, 4, 18))
|
||||
|
||||
function C() {
|
||||
>C : Symbol(C, Decl(mod1.js, 4, 18))
|
||||
|
||||
this.p = 1
|
||||
>p : Symbol(C.p, Decl(mod1.js, 5, 14))
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/jsdoc/use.js ===
|
||||
/** @param {import('./mod1').Con} k */
|
||||
function f(k) {
|
||||
>f : Symbol(f, Decl(use.js, 0, 0))
|
||||
>k : Symbol(k, Decl(use.js, 1, 11))
|
||||
|
||||
if (1 === 2 - 1) {
|
||||
// I guess basic math works!
|
||||
}
|
||||
return k({ ok: true})
|
||||
>k : Symbol(k, Decl(use.js, 1, 11))
|
||||
>ok : Symbol(ok, Decl(use.js, 5, 14))
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
=== tests/cases/conformance/jsdoc/mod1.js ===
|
||||
/** @callback Con - some kind of continuation
|
||||
* @param {object | undefined} error
|
||||
* @return {any} I don't even know what this should return
|
||||
*/
|
||||
module.exports = C
|
||||
>module.exports = C : typeof C
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>C : typeof C
|
||||
|
||||
function C() {
|
||||
>C : typeof C
|
||||
|
||||
this.p = 1
|
||||
>this.p = 1 : 1
|
||||
>this.p : any
|
||||
>this : any
|
||||
>p : any
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/jsdoc/use.js ===
|
||||
/** @param {import('./mod1').Con} k */
|
||||
function f(k) {
|
||||
>f : (k: import("tests/cases/conformance/jsdoc/mod1").Con) => any
|
||||
>k : import("tests/cases/conformance/jsdoc/mod1").Con
|
||||
|
||||
if (1 === 2 - 1) {
|
||||
>1 === 2 - 1 : boolean
|
||||
>1 : 1
|
||||
>2 - 1 : number
|
||||
>2 : 2
|
||||
>1 : 1
|
||||
|
||||
// I guess basic math works!
|
||||
}
|
||||
return k({ ok: true})
|
||||
>k({ ok: true}) : any
|
||||
>k : import("tests/cases/conformance/jsdoc/mod1").Con
|
||||
>{ ok: true} : { ok: boolean; }
|
||||
>ok : boolean
|
||||
>true : true
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
=== tests/cases/conformance/jsdoc/cb.js ===
|
||||
/** @callback Sid
|
||||
* @param {string} s
|
||||
* @returns {string} What were you expecting
|
||||
*/
|
||||
var x = 1
|
||||
>x : Symbol(x, Decl(cb.js, 4, 3))
|
||||
|
||||
/** @type {Sid} smallId */
|
||||
var sid = s => s + "!";
|
||||
>sid : Symbol(sid, Decl(cb.js, 7, 3))
|
||||
>s : Symbol(s, Decl(cb.js, 7, 9))
|
||||
>s : Symbol(s, Decl(cb.js, 7, 9))
|
||||
|
||||
|
||||
/** @type {NoReturn} */
|
||||
var noreturn = obj => void obj.title
|
||||
>noreturn : Symbol(noreturn, Decl(cb.js, 11, 3))
|
||||
>obj : Symbol(obj, Decl(cb.js, 11, 14))
|
||||
>obj.title : Symbol(title, Decl(cb.js, 15, 34))
|
||||
>obj : Symbol(obj, Decl(cb.js, 11, 14))
|
||||
>title : Symbol(title, Decl(cb.js, 15, 34))
|
||||
|
||||
/**
|
||||
* @callback NoReturn
|
||||
* @param {{ e: number, m: number, title: string }} s - Knee deep, shores, etc
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
=== tests/cases/conformance/jsdoc/cb.js ===
|
||||
/** @callback Sid
|
||||
* @param {string} s
|
||||
* @returns {string} What were you expecting
|
||||
*/
|
||||
var x = 1
|
||||
>x : number
|
||||
>1 : 1
|
||||
|
||||
/** @type {Sid} smallId */
|
||||
var sid = s => s + "!";
|
||||
>sid : Sid
|
||||
>s => s + "!" : (s: string) => string
|
||||
>s : string
|
||||
>s + "!" : string
|
||||
>s : string
|
||||
>"!" : "!"
|
||||
|
||||
|
||||
/** @type {NoReturn} */
|
||||
var noreturn = obj => void obj.title
|
||||
>noreturn : (s: { e: number; m: number; title: string; }) => any
|
||||
>obj => void obj.title : (obj: { e: number; m: number; title: string; }) => any
|
||||
>obj : { e: number; m: number; title: string; }
|
||||
>void obj.title : undefined
|
||||
>obj.title : string
|
||||
>obj : { e: number; m: number; title: string; }
|
||||
>title : string
|
||||
|
||||
/**
|
||||
* @callback NoReturn
|
||||
* @param {{ e: number, m: number, title: string }} s - Knee deep, shores, etc
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
tests/cases/conformance/jsdoc/cb.js(18,29): error TS2304: Cannot find name 'S'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/cb.js (1 errors) ====
|
||||
/** @template T
|
||||
* @callback Id
|
||||
* @param {T} t
|
||||
* @returns {T} Maybe just return 120 and cast it?
|
||||
*/
|
||||
var x = 1
|
||||
|
||||
/** @type {Id<string>} I actually wanted to write `const "120"` */
|
||||
var one_twenty = s => "120";
|
||||
|
||||
/** @template S
|
||||
* @callback SharedId
|
||||
* @param {S} ego
|
||||
* @return {S}
|
||||
*/
|
||||
class SharedClass {
|
||||
constructor() {
|
||||
/** @type {SharedId<S>} */
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'S'.
|
||||
this.id;
|
||||
}
|
||||
}
|
||||
/** @type {SharedId<number>} */
|
||||
var outside = n => n + 1;
|
||||
|
||||
/** @type {Final<{ fantasy }, { heroes }>} */
|
||||
var noreturn = (barts, tidus, noctis) => "cecil"
|
||||
|
||||
/**
|
||||
* @template V,X
|
||||
* @callback Final
|
||||
* @param {V} barts - "Barts"
|
||||
* @param {X} tidus - Titus
|
||||
* @param {X & V} noctis - "Prince Noctis Lucius Caelum"
|
||||
* @return {"cecil" | "zidane"}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
=== tests/cases/conformance/jsdoc/cb.js ===
|
||||
/** @template T
|
||||
* @callback Id
|
||||
* @param {T} t
|
||||
* @returns {T} Maybe just return 120 and cast it?
|
||||
*/
|
||||
var x = 1
|
||||
>x : Symbol(x, Decl(cb.js, 5, 3))
|
||||
|
||||
/** @type {Id<string>} I actually wanted to write `const "120"` */
|
||||
var one_twenty = s => "120";
|
||||
>one_twenty : Symbol(one_twenty, Decl(cb.js, 8, 3))
|
||||
>s : Symbol(s, Decl(cb.js, 8, 16))
|
||||
|
||||
/** @template S
|
||||
* @callback SharedId
|
||||
* @param {S} ego
|
||||
* @return {S}
|
||||
*/
|
||||
class SharedClass {
|
||||
>SharedClass : Symbol(SharedClass, Decl(cb.js, 8, 28))
|
||||
|
||||
constructor() {
|
||||
/** @type {SharedId<S>} */
|
||||
this.id;
|
||||
>this.id : Symbol(SharedClass.id, Decl(cb.js, 16, 19))
|
||||
>this : Symbol(SharedClass, Decl(cb.js, 8, 28))
|
||||
>id : Symbol(SharedClass.id, Decl(cb.js, 16, 19))
|
||||
}
|
||||
}
|
||||
/** @type {SharedId<number>} */
|
||||
var outside = n => n + 1;
|
||||
>outside : Symbol(outside, Decl(cb.js, 22, 3))
|
||||
>n : Symbol(n, Decl(cb.js, 22, 13))
|
||||
>n : Symbol(n, Decl(cb.js, 22, 13))
|
||||
|
||||
/** @type {Final<{ fantasy }, { heroes }>} */
|
||||
var noreturn = (barts, tidus, noctis) => "cecil"
|
||||
>noreturn : Symbol(noreturn, Decl(cb.js, 25, 3))
|
||||
>barts : Symbol(barts, Decl(cb.js, 25, 16))
|
||||
>tidus : Symbol(tidus, Decl(cb.js, 25, 22))
|
||||
>noctis : Symbol(noctis, Decl(cb.js, 25, 29))
|
||||
|
||||
/**
|
||||
* @template V,X
|
||||
* @callback Final
|
||||
* @param {V} barts - "Barts"
|
||||
* @param {X} tidus - Titus
|
||||
* @param {X & V} noctis - "Prince Noctis Lucius Caelum"
|
||||
* @return {"cecil" | "zidane"}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
=== tests/cases/conformance/jsdoc/cb.js ===
|
||||
/** @template T
|
||||
* @callback Id
|
||||
* @param {T} t
|
||||
* @returns {T} Maybe just return 120 and cast it?
|
||||
*/
|
||||
var x = 1
|
||||
>x : number
|
||||
>1 : 1
|
||||
|
||||
/** @type {Id<string>} I actually wanted to write `const "120"` */
|
||||
var one_twenty = s => "120";
|
||||
>one_twenty : Id<string>
|
||||
>s => "120" : (s: string) => string
|
||||
>s : string
|
||||
>"120" : "120"
|
||||
|
||||
/** @template S
|
||||
* @callback SharedId
|
||||
* @param {S} ego
|
||||
* @return {S}
|
||||
*/
|
||||
class SharedClass {
|
||||
>SharedClass : SharedClass
|
||||
|
||||
constructor() {
|
||||
/** @type {SharedId<S>} */
|
||||
this.id;
|
||||
>this.id : SharedId<any>
|
||||
>this : this
|
||||
>id : SharedId<any>
|
||||
}
|
||||
}
|
||||
/** @type {SharedId<number>} */
|
||||
var outside = n => n + 1;
|
||||
>outside : SharedId<number>
|
||||
>n => n + 1 : (n: number) => number
|
||||
>n : number
|
||||
>n + 1 : number
|
||||
>n : number
|
||||
>1 : 1
|
||||
|
||||
/** @type {Final<{ fantasy }, { heroes }>} */
|
||||
var noreturn = (barts, tidus, noctis) => "cecil"
|
||||
>noreturn : (barts: { fantasy: any; }, tidus: { heroes: any; }, noctis: { heroes: any; } & { fantasy: any; }) => "cecil" | "zidane"
|
||||
>(barts, tidus, noctis) => "cecil" : (barts: { fantasy: any; }, tidus: { heroes: any; }, noctis: { heroes: any; } & { fantasy: any; }) => "cecil"
|
||||
>barts : { fantasy: any; }
|
||||
>tidus : { heroes: any; }
|
||||
>noctis : { heroes: any; } & { fantasy: any; }
|
||||
>"cecil" : "cecil"
|
||||
|
||||
/**
|
||||
* @template V,X
|
||||
* @callback Final
|
||||
* @param {V} barts - "Barts"
|
||||
* @param {X} tidus - Titus
|
||||
* @param {X & V} noctis - "Prince Noctis Lucius Caelum"
|
||||
* @return {"cecil" | "zidane"}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
=== tests/cases/conformance/jsdoc/cb.js ===
|
||||
/** @callback Miracle
|
||||
* @returns {string} What were you expecting
|
||||
*/
|
||||
/** @type {Miracle} smallId */
|
||||
var sid = () => "!";
|
||||
>sid : Symbol(sid, Decl(cb.js, 4, 3))
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
=== tests/cases/conformance/jsdoc/cb.js ===
|
||||
/** @callback Miracle
|
||||
* @returns {string} What were you expecting
|
||||
*/
|
||||
/** @type {Miracle} smallId */
|
||||
var sid = () => "!";
|
||||
>sid : Miracle
|
||||
>() => "!" : () => string
|
||||
>"!" : "!"
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
=== tests/cases/conformance/jsdoc/namespaced.js ===
|
||||
/**
|
||||
* @callback NS.Nested.Inner
|
||||
* @param {string} space - spaaaaaaaaace
|
||||
* @param {string} peace - peaaaaaaaaace
|
||||
* @return {string | number}
|
||||
*/
|
||||
var x = 1;
|
||||
>x : Symbol(x, Decl(namespaced.js, 6, 3))
|
||||
|
||||
/** @type {NS.Nested.Inner} */
|
||||
function f(space, peace) {
|
||||
>f : Symbol(f, Decl(namespaced.js, 6, 10))
|
||||
>space : Symbol(space, Decl(namespaced.js, 8, 11))
|
||||
>peace : Symbol(peace, Decl(namespaced.js, 8, 17))
|
||||
|
||||
return '1'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
=== tests/cases/conformance/jsdoc/namespaced.js ===
|
||||
/**
|
||||
* @callback NS.Nested.Inner
|
||||
* @param {string} space - spaaaaaaaaace
|
||||
* @param {string} peace - peaaaaaaaaace
|
||||
* @return {string | number}
|
||||
*/
|
||||
var x = 1;
|
||||
>x : number
|
||||
>1 : 1
|
||||
|
||||
/** @type {NS.Nested.Inner} */
|
||||
function f(space, peace) {
|
||||
>f : (space: string, peace: string) => string
|
||||
>space : string
|
||||
>peace : string
|
||||
|
||||
return '1'
|
||||
>'1' : "1"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
//// [classExpressionInClassStaticDeclarations.ts]
|
||||
class C {
|
||||
static D = class extends C {};
|
||||
}
|
||||
|
||||
//// [classExpressionInClassStaticDeclarations.js]
|
||||
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 __());
|
||||
};
|
||||
})();
|
||||
var C = /** @class */ (function () {
|
||||
function C() {
|
||||
}
|
||||
C.D = /** @class */ (function (_super) {
|
||||
__extends(class_1, _super);
|
||||
function class_1() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return class_1;
|
||||
}(C));
|
||||
return C;
|
||||
}());
|
||||
|
||||
|
||||
//// [classExpressionInClassStaticDeclarations.d.ts]
|
||||
declare class C {
|
||||
static D: {
|
||||
new (): {};
|
||||
D: any;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
=== tests/cases/compiler/classExpressionInClassStaticDeclarations.ts ===
|
||||
class C {
|
||||
>C : Symbol(C, Decl(classExpressionInClassStaticDeclarations.ts, 0, 0))
|
||||
|
||||
static D = class extends C {};
|
||||
>D : Symbol(C.D, Decl(classExpressionInClassStaticDeclarations.ts, 0, 9))
|
||||
>C : Symbol(C, Decl(classExpressionInClassStaticDeclarations.ts, 0, 0))
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
=== tests/cases/compiler/classExpressionInClassStaticDeclarations.ts ===
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
static D = class extends C {};
|
||||
>D : typeof (Anonymous class)
|
||||
>class extends C {} : typeof (Anonymous class)
|
||||
>C : C
|
||||
}
|
||||
@@ -36,24 +36,9 @@ exports["default"] = fp.l10ns;
|
||||
|
||||
//// [app.d.ts]
|
||||
declare const _default: {
|
||||
ar?: {
|
||||
weekdays: {
|
||||
shorthand: [string, string, string, string, string, string, string];
|
||||
longhand: [string, string, string, string, string, string, string];
|
||||
};
|
||||
};
|
||||
bg?: {
|
||||
weekdays: {
|
||||
shorthand: [string, string, string, string, string, string, string];
|
||||
longhand: [string, string, string, string, string, string, string];
|
||||
};
|
||||
};
|
||||
ar?: import("./locale").CustomLocale;
|
||||
bg?: import("./locale").CustomLocale;
|
||||
} & {
|
||||
default: {
|
||||
weekdays: {
|
||||
shorthand: [string, string, string, string, string, string, string];
|
||||
longhand: [string, string, string, string, string, string, string];
|
||||
};
|
||||
};
|
||||
default: import("./locale").Locale;
|
||||
};
|
||||
export default _default;
|
||||
|
||||
@@ -62,7 +62,7 @@ const fp = { l10ns: {} } as FlatpickrFn;
|
||||
>FlatpickrFn : FlatpickrFn
|
||||
|
||||
export default fp.l10ns;
|
||||
>fp.l10ns : { ar?: { weekdays: { shorthand: [string, string, string, string, string, string, string]; longhand: [string, string, string, string, string, string, string]; }; }; bg?: { weekdays: { shorthand: [string, string, string, string, string, string, string]; longhand: [string, string, string, string, string, string, string]; }; }; } & { default: { weekdays: { shorthand: [string, string, string, string, string, string, string]; longhand: [string, string, string, string, string, string, string]; }; }; }
|
||||
>fp.l10ns : { ar?: import("tests/cases/compiler/locale").CustomLocale; bg?: import("tests/cases/compiler/locale").CustomLocale; } & { default: import("tests/cases/compiler/locale").Locale; }
|
||||
>fp : FlatpickrFn
|
||||
>l10ns : { ar?: { weekdays: { shorthand: [string, string, string, string, string, string, string]; longhand: [string, string, string, string, string, string, string]; }; }; bg?: { weekdays: { shorthand: [string, string, string, string, string, string, string]; longhand: [string, string, string, string, string, string, string]; }; }; } & { default: { weekdays: { shorthand: [string, string, string, string, string, string, string]; longhand: [string, string, string, string, string, string, string]; }; }; }
|
||||
>l10ns : { ar?: import("tests/cases/compiler/locale").CustomLocale; bg?: import("tests/cases/compiler/locale").CustomLocale; } & { default: import("tests/cases/compiler/locale").Locale; }
|
||||
|
||||
|
||||
@@ -22,5 +22,5 @@ exports.v = v;
|
||||
//// [0.d.ts]
|
||||
export declare type Data = string | boolean;
|
||||
//// [1.d.ts]
|
||||
declare let v: string | boolean;
|
||||
declare let v: import("./0").Data;
|
||||
export { v };
|
||||
|
||||
@@ -9,11 +9,11 @@ let obj: Data = true;
|
||||
|
||||
=== tests/cases/compiler/1.ts ===
|
||||
let v = "str" || true;
|
||||
>v : string | boolean
|
||||
>v : import("tests/cases/compiler/0").Data
|
||||
>"str" || true : true | "str"
|
||||
>"str" : "str"
|
||||
>true : true
|
||||
|
||||
export { v }
|
||||
>v : string | boolean
|
||||
>v : import("tests/cases/compiler/0").Data
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
//// [tests/cases/compiler/declarationFilesGeneratingTypeReferences.ts] ////
|
||||
|
||||
//// [index.d.ts]
|
||||
interface JQuery {
|
||||
|
||||
}
|
||||
|
||||
//// [app.ts]
|
||||
/// <reference types="jquery"/>
|
||||
namespace Test {
|
||||
export var x: JQuery;
|
||||
}
|
||||
|
||||
//// [out.js]
|
||||
/// <reference types="jquery"/>
|
||||
var Test;
|
||||
(function (Test) {
|
||||
})(Test || (Test = {}));
|
||||
|
||||
|
||||
//// [out.d.ts]
|
||||
/// <reference types="jquery" />
|
||||
declare namespace Test {
|
||||
var x: JQuery;
|
||||
}
|
||||
|
||||
|
||||
//// [DtsFileErrors]
|
||||
|
||||
|
||||
out.d.ts(1,23): error TS2688: Cannot find type definition file for 'jquery'.
|
||||
|
||||
|
||||
==== /a/node_modules/@types/jquery/index.d.ts (0 errors) ====
|
||||
interface JQuery {
|
||||
|
||||
}
|
||||
|
||||
==== out.d.ts (1 errors) ====
|
||||
/// <reference types="jquery" />
|
||||
~~~~~~
|
||||
!!! error TS2688: Cannot find type definition file for 'jquery'.
|
||||
declare namespace Test {
|
||||
var x: JQuery;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
=== /a/node_modules/@types/jquery/index.d.ts ===
|
||||
interface JQuery {
|
||||
>JQuery : Symbol(JQuery, Decl(index.d.ts, 0, 0))
|
||||
|
||||
}
|
||||
|
||||
=== /a/app.ts ===
|
||||
/// <reference types="jquery"/>
|
||||
namespace Test {
|
||||
>Test : Symbol(Test, Decl(app.ts, 0, 0))
|
||||
|
||||
export var x: JQuery;
|
||||
>x : Symbol(x, Decl(app.ts, 2, 14))
|
||||
>JQuery : Symbol(JQuery, Decl(index.d.ts, 0, 0))
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
=== /a/node_modules/@types/jquery/index.d.ts ===
|
||||
interface JQuery {
|
||||
>JQuery : JQuery
|
||||
|
||||
}
|
||||
|
||||
=== /a/app.ts ===
|
||||
/// <reference types="jquery"/>
|
||||
namespace Test {
|
||||
>Test : typeof Test
|
||||
|
||||
export var x: JQuery;
|
||||
>x : JQuery
|
||||
>JQuery : JQuery
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
//// [tests/cases/compiler/declarationsForInferredTypeFromOtherFile.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
export class Foo {}
|
||||
//// [file2.ts]
|
||||
export function foo(): import("./file1").Foo {
|
||||
return null as any;
|
||||
}
|
||||
//// [file3.ts]
|
||||
import {foo} from "./file2";
|
||||
export function bar() {
|
||||
return foo();
|
||||
}
|
||||
|
||||
|
||||
//// [file1.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var Foo = /** @class */ (function () {
|
||||
function Foo() {
|
||||
}
|
||||
return Foo;
|
||||
}());
|
||||
exports.Foo = Foo;
|
||||
//// [file2.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function foo() {
|
||||
return null;
|
||||
}
|
||||
exports.foo = foo;
|
||||
//// [file3.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var file2_1 = require("./file2");
|
||||
function bar() {
|
||||
return file2_1.foo();
|
||||
}
|
||||
exports.bar = bar;
|
||||
|
||||
|
||||
//// [file1.d.ts]
|
||||
export declare class Foo {
|
||||
}
|
||||
//// [file2.d.ts]
|
||||
export declare function foo(): import("./file1").Foo;
|
||||
//// [file3.d.ts]
|
||||
export declare function bar(): import("./file1").Foo;
|
||||
@@ -0,0 +1,22 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
export class Foo {}
|
||||
>Foo : Symbol(Foo, Decl(file1.ts, 0, 0))
|
||||
|
||||
=== tests/cases/compiler/file2.ts ===
|
||||
export function foo(): import("./file1").Foo {
|
||||
>foo : Symbol(foo, Decl(file2.ts, 0, 0))
|
||||
>Foo : Symbol(Foo, Decl(file1.ts, 0, 0))
|
||||
|
||||
return null as any;
|
||||
}
|
||||
=== tests/cases/compiler/file3.ts ===
|
||||
import {foo} from "./file2";
|
||||
>foo : Symbol(foo, Decl(file3.ts, 0, 8))
|
||||
|
||||
export function bar() {
|
||||
>bar : Symbol(bar, Decl(file3.ts, 0, 28))
|
||||
|
||||
return foo();
|
||||
>foo : Symbol(foo, Decl(file3.ts, 0, 8))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
export class Foo {}
|
||||
>Foo : Foo
|
||||
|
||||
=== tests/cases/compiler/file2.ts ===
|
||||
export function foo(): import("./file1").Foo {
|
||||
>foo : () => import("tests/cases/compiler/file1").Foo
|
||||
>Foo : import("tests/cases/compiler/file1").Foo
|
||||
|
||||
return null as any;
|
||||
>null as any : any
|
||||
>null : null
|
||||
}
|
||||
=== tests/cases/compiler/file3.ts ===
|
||||
import {foo} from "./file2";
|
||||
>foo : () => import("tests/cases/compiler/file1").Foo
|
||||
|
||||
export function bar() {
|
||||
>bar : () => import("tests/cases/compiler/file1").Foo
|
||||
|
||||
return foo();
|
||||
>foo() : import("tests/cases/compiler/file1").Foo
|
||||
>foo : () => import("tests/cases/compiler/file1").Foo
|
||||
}
|
||||
|
||||
@@ -4,39 +4,39 @@ type Constructor = new (...args: any[]) => {};
|
||||
>args : any[]
|
||||
|
||||
const Mixin1 = <C extends Constructor>(Base: C) => class extends Base { private _fooPrivate: {}; }
|
||||
>Mixin1 : <C extends Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
|
||||
><C extends Constructor>(Base: C) => class extends Base { private _fooPrivate: {}; } : <C extends Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
|
||||
>Mixin1 : <C extends Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: Mixin1<any>.(Anonymous class); } & C
|
||||
><C extends Constructor>(Base: C) => class extends Base { private _fooPrivate: {}; } : <C extends Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: Mixin1<any>.(Anonymous class); } & C
|
||||
>C : C
|
||||
>Constructor : Constructor
|
||||
>Base : C
|
||||
>C : C
|
||||
>class extends Base { private _fooPrivate: {}; } : { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
|
||||
>class extends Base { private _fooPrivate: {}; } : { new (...args: any[]): (Anonymous class); prototype: Mixin1<any>.(Anonymous class); } & C
|
||||
>Base : {}
|
||||
>_fooPrivate : {}
|
||||
|
||||
type FooConstructor = typeof Mixin1 extends (a: Constructor) => infer Cls ? Cls : never;
|
||||
>FooConstructor : { new (...args: any[]): <Constructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & Constructor
|
||||
>Mixin1 : <C extends Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
|
||||
>FooConstructor : { new (...args: any[]): Mixin1<Constructor>.(Anonymous class); prototype: Mixin1<any>.(Anonymous class); } & Constructor
|
||||
>Mixin1 : <C extends Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: Mixin1<any>.(Anonymous class); } & C
|
||||
>a : Constructor
|
||||
>Constructor : Constructor
|
||||
>Cls : Cls
|
||||
>Cls : Cls
|
||||
|
||||
const Mixin2 = <C extends FooConstructor>(Base: C) => class extends Base {};
|
||||
>Mixin2 : <C extends { new (...args: any[]): <Constructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
|
||||
><C extends FooConstructor>(Base: C) => class extends Base {} : <C extends { new (...args: any[]): <Constructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
|
||||
>Mixin2 : <C extends { new (...args: any[]): Mixin1<Constructor>.(Anonymous class); prototype: Mixin1<any>.(Anonymous class); } & Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: Mixin2<any>.(Anonymous class); } & C
|
||||
><C extends FooConstructor>(Base: C) => class extends Base {} : <C extends { new (...args: any[]): Mixin1<Constructor>.(Anonymous class); prototype: Mixin1<any>.(Anonymous class); } & Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: Mixin2<any>.(Anonymous class); } & C
|
||||
>C : C
|
||||
>FooConstructor : { new (...args: any[]): <Constructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & Constructor
|
||||
>FooConstructor : { new (...args: any[]): Mixin1<Constructor>.(Anonymous class); prototype: Mixin1<any>.(Anonymous class); } & Constructor
|
||||
>Base : C
|
||||
>C : C
|
||||
>class extends Base {} : { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
|
||||
>Base : <Constructor>.(Anonymous class)
|
||||
>class extends Base {} : { new (...args: any[]): (Anonymous class); prototype: Mixin2<any>.(Anonymous class); } & C
|
||||
>Base : Mixin1<Constructor>.(Anonymous class)
|
||||
|
||||
class C extends Mixin2(Mixin1(Object)) {}
|
||||
>C : C
|
||||
>Mixin2(Mixin1(Object)) : <{ new (...args: any[]): <ObjectConstructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & ObjectConstructor>.(Anonymous class) & <ObjectConstructor>.(Anonymous class) & Object
|
||||
>Mixin2 : <C extends { new (...args: any[]): <Constructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
|
||||
>Mixin1(Object) : { new (...args: any[]): <ObjectConstructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & ObjectConstructor
|
||||
>Mixin1 : <C extends Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
|
||||
>Mixin2(Mixin1(Object)) : Mixin2<{ new (...args: any[]): Mixin1<ObjectConstructor>.(Anonymous class); prototype: Mixin1<any>.(Anonymous class); } & ObjectConstructor>.(Anonymous class) & Mixin1<ObjectConstructor>.(Anonymous class) & Object
|
||||
>Mixin2 : <C extends { new (...args: any[]): Mixin1<Constructor>.(Anonymous class); prototype: Mixin1<any>.(Anonymous class); } & Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: Mixin2<any>.(Anonymous class); } & C
|
||||
>Mixin1(Object) : { new (...args: any[]): Mixin1<ObjectConstructor>.(Anonymous class); prototype: Mixin1<any>.(Anonymous class); } & ObjectConstructor
|
||||
>Mixin1 : <C extends Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: Mixin1<any>.(Anonymous class); } & C
|
||||
>Object : ObjectConstructor
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/src/a.ts(5,3): error TS2345: Argument of type 'X' is not assignable to parameter of type 'X'.
|
||||
/src/a.ts(5,3): error TS2345: Argument of type 'import("/node_modules/c/node_modules/x/index").default' is not assignable to parameter of type 'import("/node_modules/a/node_modules/x/index").default'.
|
||||
Types have separate declarations of a private property 'x'.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
a(b); // Works
|
||||
a(c); // Error, these are from different versions of the library.
|
||||
~
|
||||
!!! error TS2345: Argument of type 'X' is not assignable to parameter of type 'X'.
|
||||
!!! error TS2345: Argument of type 'import("/node_modules/c/node_modules/x/index").default' is not assignable to parameter of type 'import("/node_modules/a/node_modules/x/index").default'.
|
||||
!!! error TS2345: Types have separate declarations of a private property 'x'.
|
||||
|
||||
==== /node_modules/a/index.d.ts (0 errors) ====
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
=== /src/a.ts ===
|
||||
import { a } from "a";
|
||||
>a : (x: default) => void
|
||||
>a : (x: import("/node_modules/a/node_modules/x/index").default) => void
|
||||
|
||||
import { b } from "b";
|
||||
>b : default
|
||||
>b : import("/node_modules/a/node_modules/x/index").default
|
||||
|
||||
import { c } from "c";
|
||||
>c : default
|
||||
>c : import("/node_modules/c/node_modules/x/index").default
|
||||
|
||||
a(b); // Works
|
||||
>a(b) : void
|
||||
>a : (x: default) => void
|
||||
>b : default
|
||||
>a : (x: import("/node_modules/a/node_modules/x/index").default) => void
|
||||
>b : import("/node_modules/a/node_modules/x/index").default
|
||||
|
||||
a(c); // Error, these are from different versions of the library.
|
||||
>a(c) : void
|
||||
>a : (x: default) => void
|
||||
>c : default
|
||||
>a : (x: import("/node_modules/a/node_modules/x/index").default) => void
|
||||
>c : import("/node_modules/c/node_modules/x/index").default
|
||||
|
||||
=== /node_modules/a/index.d.ts ===
|
||||
import X from "x";
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
=== /index.ts ===
|
||||
import { use } from "foo/use";
|
||||
>use : (o: C) => void
|
||||
>use : (o: import("/node_modules/foo/index").C) => void
|
||||
|
||||
import { o } from "a";
|
||||
>o : C
|
||||
>o : import("/node_modules/foo/index").C
|
||||
|
||||
use(o);
|
||||
>use(o) : void
|
||||
>use : (o: C) => void
|
||||
>o : C
|
||||
>use : (o: import("/node_modules/foo/index").C) => void
|
||||
>o : import("/node_modules/foo/index").C
|
||||
|
||||
=== /node_modules/a/node_modules/foo/index.d.ts ===
|
||||
export class C {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
=== /index.ts ===
|
||||
import { use } from "@foo/bar/use";
|
||||
>use : (o: C) => void
|
||||
>use : (o: import("/node_modules/@foo/bar/index").C) => void
|
||||
|
||||
import { o } from "a";
|
||||
>o : C
|
||||
>o : import("/node_modules/@foo/bar/index").C
|
||||
|
||||
use(o);
|
||||
>use(o) : void
|
||||
>use : (o: C) => void
|
||||
>o : C
|
||||
>use : (o: import("/node_modules/@foo/bar/index").C) => void
|
||||
>o : import("/node_modules/@foo/bar/index").C
|
||||
|
||||
=== /node_modules/a/node_modules/@foo/bar/index.d.ts ===
|
||||
export class C {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
=== tests/cases/compiler/es5ExportEquals.ts ===
|
||||
export function f() { }
|
||||
>f : typeof f
|
||||
>f : typeof import("tests/cases/compiler/es5ExportEquals").f
|
||||
|
||||
export = f;
|
||||
>f : () => void
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
=== tests/cases/compiler/es6ExportEquals.ts ===
|
||||
export function f() { }
|
||||
>f : typeof f
|
||||
>f : typeof import("tests/cases/compiler/es6ExportEquals").f
|
||||
|
||||
export = f;
|
||||
>f : () => void
|
||||
|
||||
@@ -114,7 +114,7 @@ export declare function MyMixin<T extends Constructor<MyBaseClass<any>>>(base: T
|
||||
//// [FinalClass.d.ts]
|
||||
import { MyBaseClass } from './BaseClass';
|
||||
import { MyMixin } from './MixinClass';
|
||||
declare const MyExtendedClass_base: typeof MyBaseClass & (new (...args: any[]) => MyMixin);
|
||||
declare const MyExtendedClass_base: typeof MyBaseClass & import("./BaseClass").Constructor<MyMixin>;
|
||||
export declare class MyExtendedClass extends MyExtendedClass_base<string> {
|
||||
extendedClassProperty: number;
|
||||
}
|
||||
|
||||
@@ -52,12 +52,12 @@ import { MyBaseClass } from './BaseClass';
|
||||
>MyBaseClass : typeof MyBaseClass
|
||||
|
||||
import { MyMixin } from './MixinClass';
|
||||
>MyMixin : <T extends new (...args: any[]) => MyBaseClass<any>>(base: T) => T & (new (...args: any[]) => MyMixin)
|
||||
>MyMixin : <T extends import("tests/cases/compiler/BaseClass").Constructor<MyBaseClass<any>>>(base: T) => T & import("tests/cases/compiler/BaseClass").Constructor<MyMixin>
|
||||
|
||||
export class MyExtendedClass extends MyMixin(MyBaseClass)<string> {
|
||||
>MyExtendedClass : MyExtendedClass
|
||||
>MyMixin(MyBaseClass) : MyBaseClass<string> & MyMixin
|
||||
>MyMixin : <T extends new (...args: any[]) => MyBaseClass<any>>(base: T) => T & (new (...args: any[]) => MyMixin)
|
||||
>MyMixin : <T extends import("tests/cases/compiler/BaseClass").Constructor<MyBaseClass<any>>>(base: T) => T & import("tests/cases/compiler/BaseClass").Constructor<MyMixin>
|
||||
>MyBaseClass : typeof MyBaseClass
|
||||
|
||||
extendedClassProperty: number;
|
||||
@@ -68,7 +68,7 @@ import { MyExtendedClass } from './FinalClass';
|
||||
>MyExtendedClass : typeof MyExtendedClass
|
||||
|
||||
import { MyMixin } from './MixinClass';
|
||||
>MyMixin : <T extends new (...args: any[]) => MyBaseClass<any>>(base: T) => T & (new (...args: any[]) => MyMixin)
|
||||
>MyMixin : <T extends import("tests/cases/compiler/BaseClass").Constructor<import("tests/cases/compiler/BaseClass").MyBaseClass<any>>>(base: T) => T & import("tests/cases/compiler/BaseClass").Constructor<MyMixin>
|
||||
|
||||
const myExtendedClass = new MyExtendedClass('string');
|
||||
>myExtendedClass : MyExtendedClass
|
||||
@@ -77,8 +77,8 @@ const myExtendedClass = new MyExtendedClass('string');
|
||||
>'string' : "string"
|
||||
|
||||
const AnotherMixedClass = MyMixin(MyExtendedClass);
|
||||
>AnotherMixedClass : typeof MyExtendedClass & (new (...args: any[]) => MyMixin)
|
||||
>MyMixin(MyExtendedClass) : typeof MyExtendedClass & (new (...args: any[]) => MyMixin)
|
||||
>MyMixin : <T extends new (...args: any[]) => MyBaseClass<any>>(base: T) => T & (new (...args: any[]) => MyMixin)
|
||||
>AnotherMixedClass : typeof MyExtendedClass & import("tests/cases/compiler/BaseClass").Constructor<MyMixin>
|
||||
>MyMixin(MyExtendedClass) : typeof MyExtendedClass & import("tests/cases/compiler/BaseClass").Constructor<MyMixin>
|
||||
>MyMixin : <T extends import("tests/cases/compiler/BaseClass").Constructor<import("tests/cases/compiler/BaseClass").MyBaseClass<any>>>(base: T) => T & import("tests/cases/compiler/BaseClass").Constructor<MyMixin>
|
||||
>MyExtendedClass : typeof MyExtendedClass
|
||||
|
||||
|
||||
@@ -870,7 +870,7 @@ export interface eI {
|
||||
>pa2 : any
|
||||
}
|
||||
export module eM {
|
||||
>eM : typeof eM
|
||||
>eM : typeof import("tests/cases/compiler/giant").eM
|
||||
|
||||
var V;
|
||||
>V : any
|
||||
|
||||
@@ -13,12 +13,12 @@ async function foo() {
|
||||
|
||||
class C extends (await import("./0")).B {}
|
||||
>C : C
|
||||
>(await import("./0")).B : B
|
||||
>(await import("./0")).B : import("tests/cases/conformance/dynamicImport/0").B
|
||||
>(await import("./0")) : typeof import("tests/cases/conformance/dynamicImport/0")
|
||||
>await import("./0") : typeof import("tests/cases/conformance/dynamicImport/0")
|
||||
>import("./0") : Promise<typeof import("tests/cases/conformance/dynamicImport/0")>
|
||||
>"./0" : "./0"
|
||||
>B : typeof B
|
||||
>B : typeof import("tests/cases/conformance/dynamicImport/0").B
|
||||
|
||||
var c = new C();
|
||||
>c : C
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
tests/cases/conformance/dynamicImport/1.ts(1,5): error TS4023: Exported variable 'p1' has or is using name '"tests/cases/conformance/dynamicImport/0"' from external module "tests/cases/conformance/dynamicImport/0" but cannot be named.
|
||||
|
||||
|
||||
==== tests/cases/conformance/dynamicImport/0.ts (0 errors) ====
|
||||
export function foo() { return "foo"; }
|
||||
|
||||
==== tests/cases/conformance/dynamicImport/1.ts (1 errors) ====
|
||||
var p1 = import("./0");
|
||||
~~
|
||||
!!! error TS4023: Exported variable 'p1' has or is using name '"tests/cases/conformance/dynamicImport/0"' from external module "tests/cases/conformance/dynamicImport/0" but cannot be named.
|
||||
@@ -14,3 +14,5 @@ var p1 = import("./0");
|
||||
|
||||
//// [0.d.ts]
|
||||
export declare function foo(): string;
|
||||
//// [1.d.ts]
|
||||
declare var p1: Promise<typeof import("./0")>;
|
||||
|
||||
@@ -13,12 +13,12 @@ async function foo() {
|
||||
|
||||
class C extends (await import("./0")).B {}
|
||||
>C : C
|
||||
>(await import("./0")).B : B
|
||||
>(await import("./0")).B : import("tests/cases/conformance/dynamicImport/0").B
|
||||
>(await import("./0")) : typeof import("tests/cases/conformance/dynamicImport/0")
|
||||
>await import("./0") : typeof import("tests/cases/conformance/dynamicImport/0")
|
||||
>import("./0") : Promise<typeof import("tests/cases/conformance/dynamicImport/0")>
|
||||
>"./0" : "./0"
|
||||
>B : typeof B
|
||||
>B : typeof import("tests/cases/conformance/dynamicImport/0").B
|
||||
|
||||
var c = new C();
|
||||
>c : C
|
||||
|
||||
@@ -13,12 +13,12 @@ async function foo() {
|
||||
|
||||
class C extends (await import("./0")).B {}
|
||||
>C : C
|
||||
>(await import("./0")).B : B
|
||||
>(await import("./0")).B : import("tests/cases/conformance/dynamicImport/0").B
|
||||
>(await import("./0")) : typeof import("tests/cases/conformance/dynamicImport/0")
|
||||
>await import("./0") : typeof import("tests/cases/conformance/dynamicImport/0")
|
||||
>import("./0") : Promise<typeof import("tests/cases/conformance/dynamicImport/0")>
|
||||
>"./0" : "./0"
|
||||
>B : typeof B
|
||||
>B : typeof import("tests/cases/conformance/dynamicImport/0").B
|
||||
|
||||
var c = new C();
|
||||
>c : C
|
||||
|
||||
@@ -13,12 +13,12 @@ async function foo() {
|
||||
|
||||
class C extends (await import("./0")).B {}
|
||||
>C : C
|
||||
>(await import("./0")).B : B
|
||||
>(await import("./0")).B : import("tests/cases/conformance/dynamicImport/0").B
|
||||
>(await import("./0")) : typeof import("tests/cases/conformance/dynamicImport/0")
|
||||
>await import("./0") : typeof import("tests/cases/conformance/dynamicImport/0")
|
||||
>import("./0") : Promise<typeof import("tests/cases/conformance/dynamicImport/0")>
|
||||
>"./0" : "./0"
|
||||
>B : typeof B
|
||||
>B : typeof import("tests/cases/conformance/dynamicImport/0").B
|
||||
|
||||
var c = new C();
|
||||
>c : C
|
||||
|
||||
@@ -13,12 +13,12 @@ async function foo() {
|
||||
|
||||
class C extends (await import("./0")).B {}
|
||||
>C : C
|
||||
>(await import("./0")).B : B
|
||||
>(await import("./0")).B : import("tests/cases/conformance/dynamicImport/0").B
|
||||
>(await import("./0")) : typeof import("tests/cases/conformance/dynamicImport/0")
|
||||
>await import("./0") : typeof import("tests/cases/conformance/dynamicImport/0")
|
||||
>import("./0") : Promise<typeof import("tests/cases/conformance/dynamicImport/0")>
|
||||
>"./0" : "./0"
|
||||
>B : typeof B
|
||||
>B : typeof import("tests/cases/conformance/dynamicImport/0").B
|
||||
|
||||
var c = new C();
|
||||
>c : C
|
||||
|
||||
@@ -21,6 +21,4 @@ exports.thing = umd_1.makeThing();
|
||||
|
||||
|
||||
//// [index.d.ts]
|
||||
export declare const thing: {
|
||||
a: number;
|
||||
};
|
||||
export declare const thing: import("./node_modules/umd").Thing;
|
||||
|
||||
@@ -15,10 +15,10 @@ export declare function makeThing(): Thing;
|
||||
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import { makeThing } from "umd";
|
||||
>makeThing : () => { a: number; }
|
||||
>makeThing : () => import("tests/cases/compiler/node_modules/umd").Thing
|
||||
|
||||
export const thing = makeThing();
|
||||
>thing : { a: number; }
|
||||
>makeThing() : { a: number; }
|
||||
>makeThing : () => { a: number; }
|
||||
>thing : import("tests/cases/compiler/node_modules/umd").Thing
|
||||
>makeThing() : import("tests/cases/compiler/node_modules/umd").Thing
|
||||
>makeThing : () => import("tests/cases/compiler/node_modules/umd").Thing
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
tests/cases/compiler/intersectionsOfLargeUnions.ts(21,15): error TS2536: Type 'T' cannot be used to index type 'HTMLElementTagNameMap'.
|
||||
tests/cases/compiler/intersectionsOfLargeUnions.ts(21,15): error TS2536: Type 'P' cannot be used to index type 'HTMLElementTagNameMap[T]'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/intersectionsOfLargeUnions.ts (2 errors) ====
|
||||
// Repro from #23977
|
||||
|
||||
export function assertIsElement(node: Node | null): node is Element {
|
||||
let nodeType = node === null ? null : node.nodeType;
|
||||
return nodeType === 1;
|
||||
}
|
||||
|
||||
export function assertNodeTagName<
|
||||
T extends keyof ElementTagNameMap,
|
||||
U extends ElementTagNameMap[T]>(node: Node | null, tagName: T): node is U {
|
||||
if (assertIsElement(node)) {
|
||||
const nodeTagName = node.tagName.toLowerCase();
|
||||
return nodeTagName === tagName;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function assertNodeProperty<
|
||||
T extends keyof ElementTagNameMap,
|
||||
P extends keyof ElementTagNameMap[T],
|
||||
V extends HTMLElementTagNameMap[T][P]>(node: Node | null, tagName: T, prop: P, value: V) {
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2536: Type 'T' cannot be used to index type 'HTMLElementTagNameMap'.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2536: Type 'P' cannot be used to index type 'HTMLElementTagNameMap[T]'.
|
||||
if (assertNodeTagName(node, tagName)) {
|
||||
node[prop];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
//// [intersectionsOfLargeUnions.ts]
|
||||
// Repro from #23977
|
||||
|
||||
export function assertIsElement(node: Node | null): node is Element {
|
||||
let nodeType = node === null ? null : node.nodeType;
|
||||
return nodeType === 1;
|
||||
}
|
||||
|
||||
export function assertNodeTagName<
|
||||
T extends keyof ElementTagNameMap,
|
||||
U extends ElementTagNameMap[T]>(node: Node | null, tagName: T): node is U {
|
||||
if (assertIsElement(node)) {
|
||||
const nodeTagName = node.tagName.toLowerCase();
|
||||
return nodeTagName === tagName;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function assertNodeProperty<
|
||||
T extends keyof ElementTagNameMap,
|
||||
P extends keyof ElementTagNameMap[T],
|
||||
V extends HTMLElementTagNameMap[T][P]>(node: Node | null, tagName: T, prop: P, value: V) {
|
||||
if (assertNodeTagName(node, tagName)) {
|
||||
node[prop];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [intersectionsOfLargeUnions.js]
|
||||
"use strict";
|
||||
// Repro from #23977
|
||||
exports.__esModule = true;
|
||||
function assertIsElement(node) {
|
||||
var nodeType = node === null ? null : node.nodeType;
|
||||
return nodeType === 1;
|
||||
}
|
||||
exports.assertIsElement = assertIsElement;
|
||||
function assertNodeTagName(node, tagName) {
|
||||
if (assertIsElement(node)) {
|
||||
var nodeTagName = node.tagName.toLowerCase();
|
||||
return nodeTagName === tagName;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
exports.assertNodeTagName = assertNodeTagName;
|
||||
function assertNodeProperty(node, tagName, prop, value) {
|
||||
if (assertNodeTagName(node, tagName)) {
|
||||
node[prop];
|
||||
}
|
||||
}
|
||||
exports.assertNodeProperty = assertNodeProperty;
|
||||
@@ -0,0 +1,95 @@
|
||||
=== tests/cases/compiler/intersectionsOfLargeUnions.ts ===
|
||||
// Repro from #23977
|
||||
|
||||
export function assertIsElement(node: Node | null): node is Element {
|
||||
>assertIsElement : Symbol(assertIsElement, Decl(intersectionsOfLargeUnions.ts, 0, 0))
|
||||
>node : Symbol(node, Decl(intersectionsOfLargeUnions.ts, 2, 32))
|
||||
>Node : Symbol(Node, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>node : Symbol(node, Decl(intersectionsOfLargeUnions.ts, 2, 32))
|
||||
>Element : Symbol(Element, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
let nodeType = node === null ? null : node.nodeType;
|
||||
>nodeType : Symbol(nodeType, Decl(intersectionsOfLargeUnions.ts, 3, 7))
|
||||
>node : Symbol(node, Decl(intersectionsOfLargeUnions.ts, 2, 32))
|
||||
>node.nodeType : Symbol(Node.nodeType, Decl(lib.d.ts, --, --))
|
||||
>node : Symbol(node, Decl(intersectionsOfLargeUnions.ts, 2, 32))
|
||||
>nodeType : Symbol(Node.nodeType, Decl(lib.d.ts, --, --))
|
||||
|
||||
return nodeType === 1;
|
||||
>nodeType : Symbol(nodeType, Decl(intersectionsOfLargeUnions.ts, 3, 7))
|
||||
}
|
||||
|
||||
export function assertNodeTagName<
|
||||
>assertNodeTagName : Symbol(assertNodeTagName, Decl(intersectionsOfLargeUnions.ts, 5, 1))
|
||||
|
||||
T extends keyof ElementTagNameMap,
|
||||
>T : Symbol(T, Decl(intersectionsOfLargeUnions.ts, 7, 34))
|
||||
>ElementTagNameMap : Symbol(ElementTagNameMap, Decl(lib.d.ts, --, --))
|
||||
|
||||
U extends ElementTagNameMap[T]>(node: Node | null, tagName: T): node is U {
|
||||
>U : Symbol(U, Decl(intersectionsOfLargeUnions.ts, 8, 38))
|
||||
>ElementTagNameMap : Symbol(ElementTagNameMap, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(intersectionsOfLargeUnions.ts, 7, 34))
|
||||
>node : Symbol(node, Decl(intersectionsOfLargeUnions.ts, 9, 36))
|
||||
>Node : Symbol(Node, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>tagName : Symbol(tagName, Decl(intersectionsOfLargeUnions.ts, 9, 54))
|
||||
>T : Symbol(T, Decl(intersectionsOfLargeUnions.ts, 7, 34))
|
||||
>node : Symbol(node, Decl(intersectionsOfLargeUnions.ts, 9, 36))
|
||||
>U : Symbol(U, Decl(intersectionsOfLargeUnions.ts, 8, 38))
|
||||
|
||||
if (assertIsElement(node)) {
|
||||
>assertIsElement : Symbol(assertIsElement, Decl(intersectionsOfLargeUnions.ts, 0, 0))
|
||||
>node : Symbol(node, Decl(intersectionsOfLargeUnions.ts, 9, 36))
|
||||
|
||||
const nodeTagName = node.tagName.toLowerCase();
|
||||
>nodeTagName : Symbol(nodeTagName, Decl(intersectionsOfLargeUnions.ts, 11, 13))
|
||||
>node.tagName.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --))
|
||||
>node.tagName : Symbol(Element.tagName, Decl(lib.d.ts, --, --))
|
||||
>node : Symbol(node, Decl(intersectionsOfLargeUnions.ts, 9, 36))
|
||||
>tagName : Symbol(Element.tagName, Decl(lib.d.ts, --, --))
|
||||
>toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --))
|
||||
|
||||
return nodeTagName === tagName;
|
||||
>nodeTagName : Symbol(nodeTagName, Decl(intersectionsOfLargeUnions.ts, 11, 13))
|
||||
>tagName : Symbol(tagName, Decl(intersectionsOfLargeUnions.ts, 9, 54))
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function assertNodeProperty<
|
||||
>assertNodeProperty : Symbol(assertNodeProperty, Decl(intersectionsOfLargeUnions.ts, 15, 1))
|
||||
|
||||
T extends keyof ElementTagNameMap,
|
||||
>T : Symbol(T, Decl(intersectionsOfLargeUnions.ts, 17, 35))
|
||||
>ElementTagNameMap : Symbol(ElementTagNameMap, Decl(lib.d.ts, --, --))
|
||||
|
||||
P extends keyof ElementTagNameMap[T],
|
||||
>P : Symbol(P, Decl(intersectionsOfLargeUnions.ts, 18, 38))
|
||||
>ElementTagNameMap : Symbol(ElementTagNameMap, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(intersectionsOfLargeUnions.ts, 17, 35))
|
||||
|
||||
V extends HTMLElementTagNameMap[T][P]>(node: Node | null, tagName: T, prop: P, value: V) {
|
||||
>V : Symbol(V, Decl(intersectionsOfLargeUnions.ts, 19, 41))
|
||||
>HTMLElementTagNameMap : Symbol(HTMLElementTagNameMap, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(intersectionsOfLargeUnions.ts, 17, 35))
|
||||
>P : Symbol(P, Decl(intersectionsOfLargeUnions.ts, 18, 38))
|
||||
>node : Symbol(node, Decl(intersectionsOfLargeUnions.ts, 20, 43))
|
||||
>Node : Symbol(Node, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>tagName : Symbol(tagName, Decl(intersectionsOfLargeUnions.ts, 20, 61))
|
||||
>T : Symbol(T, Decl(intersectionsOfLargeUnions.ts, 17, 35))
|
||||
>prop : Symbol(prop, Decl(intersectionsOfLargeUnions.ts, 20, 73))
|
||||
>P : Symbol(P, Decl(intersectionsOfLargeUnions.ts, 18, 38))
|
||||
>value : Symbol(value, Decl(intersectionsOfLargeUnions.ts, 20, 82))
|
||||
>V : Symbol(V, Decl(intersectionsOfLargeUnions.ts, 19, 41))
|
||||
|
||||
if (assertNodeTagName(node, tagName)) {
|
||||
>assertNodeTagName : Symbol(assertNodeTagName, Decl(intersectionsOfLargeUnions.ts, 5, 1))
|
||||
>node : Symbol(node, Decl(intersectionsOfLargeUnions.ts, 20, 43))
|
||||
>tagName : Symbol(tagName, Decl(intersectionsOfLargeUnions.ts, 20, 61))
|
||||
|
||||
node[prop];
|
||||
>node : Symbol(node, Decl(intersectionsOfLargeUnions.ts, 20, 43))
|
||||
>prop : Symbol(prop, Decl(intersectionsOfLargeUnions.ts, 20, 73))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
=== tests/cases/compiler/intersectionsOfLargeUnions.ts ===
|
||||
// Repro from #23977
|
||||
|
||||
export function assertIsElement(node: Node | null): node is Element {
|
||||
>assertIsElement : (node: Node | null) => node is Element
|
||||
>node : Node | null
|
||||
>Node : Node
|
||||
>null : null
|
||||
>node : any
|
||||
>Element : Element
|
||||
|
||||
let nodeType = node === null ? null : node.nodeType;
|
||||
>nodeType : number | null
|
||||
>node === null ? null : node.nodeType : number | null
|
||||
>node === null : boolean
|
||||
>node : Node | null
|
||||
>null : null
|
||||
>null : null
|
||||
>node.nodeType : number
|
||||
>node : Node
|
||||
>nodeType : number
|
||||
|
||||
return nodeType === 1;
|
||||
>nodeType === 1 : boolean
|
||||
>nodeType : number | null
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
export function assertNodeTagName<
|
||||
>assertNodeTagName : <T extends "symbol" | "object" | "a" | "abbr" | "acronym" | "address" | "applet" | "area" | "article" | "aside" | "audio" | "b" | "base" | "basefont" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | "caption" | "center" | "cite" | "code" | "col" | "colgroup" | "data" | "datalist" | "dd" | "del" | "dfn" | "dir" | "div" | "dl" | "dt" | "em" | "embed" | "fieldset" | "figcaption" | "figure" | "font" | "footer" | "form" | "frame" | "frameset" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "head" | "header" | "hgroup" | "hr" | "html" | "i" | "iframe" | "img" | "input" | "ins" | "isindex" | "kbd" | "keygen" | "label" | "legend" | "li" | "link" | "listing" | "map" | "mark" | "marquee" | "menu" | "meta" | "meter" | "nav" | "nextid" | "nobr" | "noframes" | "noscript" | "ol" | "optgroup" | "option" | "output" | "p" | "param" | "picture" | "plaintext" | "pre" | "progress" | "q" | "rt" | "ruby" | "s" | "samp" | "script" | "section" | "select" | "slot" | "small" | "source" | "span" | "strike" | "strong" | "style" | "sub" | "sup" | "table" | "tbody" | "td" | "template" | "textarea" | "tfoot" | "th" | "thead" | "time" | "title" | "tr" | "track" | "tt" | "u" | "ul" | "var" | "video" | "wbr" | "xmp" | "circle" | "clippath" | "defs" | "desc" | "ellipse" | "feblend" | "fecolormatrix" | "fecomponenttransfer" | "fecomposite" | "feconvolvematrix" | "fediffuselighting" | "fedisplacementmap" | "fedistantlight" | "feflood" | "fefunca" | "fefuncb" | "fefuncg" | "fefuncr" | "fegaussianblur" | "feimage" | "femerge" | "femergenode" | "femorphology" | "feoffset" | "fepointlight" | "fespecularlighting" | "fespotlight" | "fetile" | "feturbulence" | "filter" | "foreignobject" | "g" | "image" | "line" | "lineargradient" | "marker" | "mask" | "metadata" | "path" | "pattern" | "polygon" | "polyline" | "radialgradient" | "rect" | "stop" | "svg" | "switch" | "text" | "textpath" | "tspan" | "use" | "view", U extends ElementTagNameMap[T]>(node: Node | null, tagName: T) => node is U
|
||||
|
||||
T extends keyof ElementTagNameMap,
|
||||
>T : T
|
||||
>ElementTagNameMap : ElementTagNameMap
|
||||
|
||||
U extends ElementTagNameMap[T]>(node: Node | null, tagName: T): node is U {
|
||||
>U : U
|
||||
>ElementTagNameMap : ElementTagNameMap
|
||||
>T : T
|
||||
>node : Node | null
|
||||
>Node : Node
|
||||
>null : null
|
||||
>tagName : T
|
||||
>T : T
|
||||
>node : any
|
||||
>U : U
|
||||
|
||||
if (assertIsElement(node)) {
|
||||
>assertIsElement(node) : boolean
|
||||
>assertIsElement : (node: Node | null) => node is Element
|
||||
>node : Node | null
|
||||
|
||||
const nodeTagName = node.tagName.toLowerCase();
|
||||
>nodeTagName : string
|
||||
>node.tagName.toLowerCase() : string
|
||||
>node.tagName.toLowerCase : () => string
|
||||
>node.tagName : string
|
||||
>node : Element
|
||||
>tagName : string
|
||||
>toLowerCase : () => string
|
||||
|
||||
return nodeTagName === tagName;
|
||||
>nodeTagName === tagName : boolean
|
||||
>nodeTagName : string
|
||||
>tagName : T
|
||||
}
|
||||
return false;
|
||||
>false : false
|
||||
}
|
||||
|
||||
export function assertNodeProperty<
|
||||
>assertNodeProperty : <T extends "symbol" | "object" | "a" | "abbr" | "acronym" | "address" | "applet" | "area" | "article" | "aside" | "audio" | "b" | "base" | "basefont" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | "caption" | "center" | "cite" | "code" | "col" | "colgroup" | "data" | "datalist" | "dd" | "del" | "dfn" | "dir" | "div" | "dl" | "dt" | "em" | "embed" | "fieldset" | "figcaption" | "figure" | "font" | "footer" | "form" | "frame" | "frameset" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "head" | "header" | "hgroup" | "hr" | "html" | "i" | "iframe" | "img" | "input" | "ins" | "isindex" | "kbd" | "keygen" | "label" | "legend" | "li" | "link" | "listing" | "map" | "mark" | "marquee" | "menu" | "meta" | "meter" | "nav" | "nextid" | "nobr" | "noframes" | "noscript" | "ol" | "optgroup" | "option" | "output" | "p" | "param" | "picture" | "plaintext" | "pre" | "progress" | "q" | "rt" | "ruby" | "s" | "samp" | "script" | "section" | "select" | "slot" | "small" | "source" | "span" | "strike" | "strong" | "style" | "sub" | "sup" | "table" | "tbody" | "td" | "template" | "textarea" | "tfoot" | "th" | "thead" | "time" | "title" | "tr" | "track" | "tt" | "u" | "ul" | "var" | "video" | "wbr" | "xmp" | "circle" | "clippath" | "defs" | "desc" | "ellipse" | "feblend" | "fecolormatrix" | "fecomponenttransfer" | "fecomposite" | "feconvolvematrix" | "fediffuselighting" | "fedisplacementmap" | "fedistantlight" | "feflood" | "fefunca" | "fefuncb" | "fefuncg" | "fefuncr" | "fegaussianblur" | "feimage" | "femerge" | "femergenode" | "femorphology" | "feoffset" | "fepointlight" | "fespecularlighting" | "fespotlight" | "fetile" | "feturbulence" | "filter" | "foreignobject" | "g" | "image" | "line" | "lineargradient" | "marker" | "mask" | "metadata" | "path" | "pattern" | "polygon" | "polyline" | "radialgradient" | "rect" | "stop" | "svg" | "switch" | "text" | "textpath" | "tspan" | "use" | "view", P extends keyof ElementTagNameMap[T], V extends HTMLElementTagNameMap[T][P]>(node: Node | null, tagName: T, prop: P, value: V) => void
|
||||
|
||||
T extends keyof ElementTagNameMap,
|
||||
>T : T
|
||||
>ElementTagNameMap : ElementTagNameMap
|
||||
|
||||
P extends keyof ElementTagNameMap[T],
|
||||
>P : P
|
||||
>ElementTagNameMap : ElementTagNameMap
|
||||
>T : T
|
||||
|
||||
V extends HTMLElementTagNameMap[T][P]>(node: Node | null, tagName: T, prop: P, value: V) {
|
||||
>V : V
|
||||
>HTMLElementTagNameMap : HTMLElementTagNameMap
|
||||
>T : T
|
||||
>P : P
|
||||
>node : Node | null
|
||||
>Node : Node
|
||||
>null : null
|
||||
>tagName : T
|
||||
>T : T
|
||||
>prop : P
|
||||
>P : P
|
||||
>value : V
|
||||
>V : V
|
||||
|
||||
if (assertNodeTagName(node, tagName)) {
|
||||
>assertNodeTagName(node, tagName) : boolean
|
||||
>assertNodeTagName : <T extends "symbol" | "object" | "a" | "abbr" | "acronym" | "address" | "applet" | "area" | "article" | "aside" | "audio" | "b" | "base" | "basefont" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | "caption" | "center" | "cite" | "code" | "col" | "colgroup" | "data" | "datalist" | "dd" | "del" | "dfn" | "dir" | "div" | "dl" | "dt" | "em" | "embed" | "fieldset" | "figcaption" | "figure" | "font" | "footer" | "form" | "frame" | "frameset" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "head" | "header" | "hgroup" | "hr" | "html" | "i" | "iframe" | "img" | "input" | "ins" | "isindex" | "kbd" | "keygen" | "label" | "legend" | "li" | "link" | "listing" | "map" | "mark" | "marquee" | "menu" | "meta" | "meter" | "nav" | "nextid" | "nobr" | "noframes" | "noscript" | "ol" | "optgroup" | "option" | "output" | "p" | "param" | "picture" | "plaintext" | "pre" | "progress" | "q" | "rt" | "ruby" | "s" | "samp" | "script" | "section" | "select" | "slot" | "small" | "source" | "span" | "strike" | "strong" | "style" | "sub" | "sup" | "table" | "tbody" | "td" | "template" | "textarea" | "tfoot" | "th" | "thead" | "time" | "title" | "tr" | "track" | "tt" | "u" | "ul" | "var" | "video" | "wbr" | "xmp" | "circle" | "clippath" | "defs" | "desc" | "ellipse" | "feblend" | "fecolormatrix" | "fecomponenttransfer" | "fecomposite" | "feconvolvematrix" | "fediffuselighting" | "fedisplacementmap" | "fedistantlight" | "feflood" | "fefunca" | "fefuncb" | "fefuncg" | "fefuncr" | "fegaussianblur" | "feimage" | "femerge" | "femergenode" | "femorphology" | "feoffset" | "fepointlight" | "fespecularlighting" | "fespotlight" | "fetile" | "feturbulence" | "filter" | "foreignobject" | "g" | "image" | "line" | "lineargradient" | "marker" | "mask" | "metadata" | "path" | "pattern" | "polygon" | "polyline" | "radialgradient" | "rect" | "stop" | "svg" | "switch" | "text" | "textpath" | "tspan" | "use" | "view", U extends ElementTagNameMap[T]>(node: Node | null, tagName: T) => node is U
|
||||
>node : Node | null
|
||||
>tagName : T
|
||||
|
||||
node[prop];
|
||||
>node[prop] : ElementTagNameMap[T][P]
|
||||
>node : ElementTagNameMap[T]
|
||||
>prop : P
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/conformance/jsdoc/templateTagOnClasses.js(24,1): error TS2322: Type 'boolean' is not assignable to type 'number'.
|
||||
tests/cases/conformance/jsdoc/templateTagOnClasses.js(25,1): error TS2322: Type 'boolean' is not assignable to type 'number'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/templateTagOnClasses.js (1 errors) ====
|
||||
@@ -6,6 +6,7 @@ tests/cases/conformance/jsdoc/templateTagOnClasses.js(24,1): error TS2322: Type
|
||||
* @template {T}
|
||||
* @typedef {(t: T) => T} Id
|
||||
*/
|
||||
/** @template T */
|
||||
class Foo {
|
||||
/** @typedef {(t: T) => T} Id2 */
|
||||
/** @param {T} x */
|
||||
@@ -15,7 +16,7 @@ tests/cases/conformance/jsdoc/templateTagOnClasses.js(24,1): error TS2322: Type
|
||||
/**
|
||||
*
|
||||
* @param {T} x
|
||||
* @param {Id} y
|
||||
* @param {Id<T>} y
|
||||
* @param {Id2} alpha
|
||||
* @return {T}
|
||||
*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user