Compare commits

...

37 commits

Author SHA1 Message Date
Nathan Shively-Sanders 032fbc85af octokit back to latest 2020-06-15 10:18:00 -07:00
Nathan Shively-Sanders c89ee760e4 try pinning octokit again 2020-06-15 09:38:15 -07:00
kingwl b1eb8e0eaf Add more tests 2020-06-15 10:20:48 +08:00
kingwl 22410c18a0 Accept baseline 2020-06-15 10:14:52 +08:00
kingwl 7e18beb674 Add cached utils function 2020-06-15 10:13:17 +08:00
kingwl dc97c6651f Merge branch 'master' into deprecated_support 2020-06-13 22:00:06 +08:00
kingwl a30a430025 fix crash 2020-06-13 21:38:16 +08:00
kingwl 8fdceabae1 Fix crash 2020-06-13 21:37:42 +08:00
kingwl 69ddd5f41f Make lint happy 2020-06-13 20:59:12 +08:00
kingwl ed18e4a861 Fix modifier flag resolve 2020-06-13 20:56:59 +08:00
kingwl 8b2f1f84a4 Use modifier flags insted of symbol props 2020-06-13 20:44:31 +08:00
kingwl 182ed1c785 Revolve alias symbol 2020-06-12 20:05:24 +08:00
kingwl b0311e304f Adjust deprecated mark on qualifed name 2020-06-12 17:00:46 +08:00
kingwl 3c75d8e8a3 Merge branch 'deprecated_support' of github.com:Kingwl/TypeScript into deprecated_support 2020-06-12 16:23:55 +08:00
kingwl 0022d54402 Merge branch 'master' into deprecated_support 2020-06-12 16:22:44 +08:00
kingwl 8d5bcc00a7 fix public api 2020-05-28 22:33:27 +08:00
kingwl 70b0445af0 fix perf 2020-05-28 21:06:13 +08:00
kingwl 7fcd23f900 Merge branch 'master' into deprecated_support 2020-05-26 11:07:04 +08:00
kingwl e796f20cf2 Add tests 2020-05-26 11:02:20 +08:00
kingwl e7be90959f Accept baseline 2020-05-20 10:09:00 +08:00
kingwl 8abcf7e938 Avoid useless changes 2020-05-20 10:07:01 +08:00
kingwl 9c577e2aad fix incorrect fix 2020-05-20 10:07:00 +08:00
kingwl d856ad50e4 fix jsdoc cache 2020-05-20 10:07:00 +08:00
kingwl 1f151361aa fix baseline 2020-05-20 10:06:59 +08:00
kingwl 6df251f405 Check deprecated in binder 2020-05-20 10:06:58 +08:00
kingwl 36f4226d85 accept baseline 2020-05-20 10:06:58 +08:00
kingwl 9d27ab3f66 avoid tags 2020-05-20 10:06:57 +08:00
kingwl f794e11861 avoid new tag 2020-05-20 10:06:57 +08:00
kingwl 1b3e477d08 improve diagnostic 2020-05-20 10:06:57 +08:00
kingwl 13bdb75863 fix crash 2020-05-20 10:06:56 +08:00
kingwl 30cea12902 fix more crash 2020-05-20 10:06:56 +08:00
kingwl 03d1ffe479 fix crash 2020-05-20 10:06:55 +08:00
kingwl 06c8d22b78 Add more deprecated 2020-05-20 10:06:54 +08:00
kingwl 9847ffb8cb Add identifier check 2020-05-20 10:06:54 +08:00
kingwl 2deadaa1d3 fix navtree 2020-05-20 10:06:53 +08:00
kingwl 5a8da1694f Add more support 2020-05-20 10:06:53 +08:00
kingwl bb09d38645 Add deprecated related feature 2020-05-20 10:06:49 +08:00
34 changed files with 812 additions and 101 deletions

View file

@ -5,6 +5,7 @@ interface DiagnosticDetails {
category: string;
code: number;
reportsUnnecessary?: {};
reportsDeprecated?: {};
isEarly?: boolean;
elidedInCompatabilityPyramid?: boolean;
}
@ -64,15 +65,17 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, inputFil
"// generated from '" + inputFilePathRel + "' by '" + thisFilePathRel.replace(/\\/g, "/") + "'\r\n" +
"/* @internal */\r\n" +
"namespace ts {\r\n" +
" function diag(code: number, category: DiagnosticCategory, key: string, message: string, reportsUnnecessary?: {}, elidedInCompatabilityPyramid?: boolean): DiagnosticMessage {\r\n" +
" return { code, category, key, message, reportsUnnecessary, elidedInCompatabilityPyramid };\r\n" +
" function diag(code: number, category: DiagnosticCategory, key: string, message: string, reportsUnnecessary?: {}, elidedInCompatabilityPyramid?: boolean, reportsDeprecated?: {}): DiagnosticMessage {\r\n" +
" return { code, category, key, message, reportsUnnecessary, elidedInCompatabilityPyramid, reportsDeprecated };\r\n" +
" }\r\n" +
" export const Diagnostics = {\r\n";
messageTable.forEach(({ code, category, reportsUnnecessary, elidedInCompatabilityPyramid }, name) => {
messageTable.forEach(({ code, category, reportsUnnecessary, elidedInCompatabilityPyramid, reportsDeprecated }, name) => {
const propName = convertPropertyName(name);
const argReportsUnnecessary = reportsUnnecessary ? `, /*reportsUnnecessary*/ ${reportsUnnecessary}` : "";
const argElidedInCompatabilityPyramid = elidedInCompatabilityPyramid ? `${!reportsUnnecessary ? ", /*reportsUnnecessary*/ undefined" : ""}, /*elidedInCompatabilityPyramid*/ ${elidedInCompatabilityPyramid}` : "";
result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}${argReportsUnnecessary}${argElidedInCompatabilityPyramid}),\r\n`;
const argReportsDeprecated = reportsDeprecated ? `${!argElidedInCompatabilityPyramid ? ", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ undefined" : ""}, /*reportsDeprecated*/ ${reportsDeprecated}` : "";
result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}${argReportsUnnecessary}${argElidedInCompatabilityPyramid}${argReportsDeprecated}),\r\n`;
});
result += " };\r\n}";

View file

@ -3,6 +3,7 @@ namespace ts {
export interface ReusableDiagnostic extends ReusableDiagnosticRelatedInformation {
/** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */
reportsUnnecessary?: {};
reportDeprecated?: {}
source?: string;
relatedInformation?: ReusableDiagnosticRelatedInformation[];
}
@ -267,6 +268,7 @@ namespace ts {
return diagnostics.map(diagnostic => {
const result: Diagnostic = convertToDiagnosticRelatedInformation(diagnostic, newProgram, toPath);
result.reportsUnnecessary = diagnostic.reportsUnnecessary;
result.reportsDeprecated = diagnostic.reportDeprecated;
result.source = diagnostic.source;
const { relatedInformation } = diagnostic;
result.relatedInformation = relatedInformation ?
@ -815,6 +817,7 @@ namespace ts {
return diagnostics.map(diagnostic => {
const result: ReusableDiagnostic = convertToReusableDiagnosticRelatedInformation(diagnostic, relativeToBuildInfo);
result.reportsUnnecessary = diagnostic.reportsUnnecessary;
result.reportDeprecated = diagnostic.reportsDeprecated;
result.source = diagnostic.source;
const { relatedInformation } = diagnostic;
result.relatedInformation = relatedInformation ?

View file

@ -13031,6 +13031,10 @@ namespace ts {
if (propName !== undefined) {
const prop = getPropertyOfType(objectType, propName);
if (prop) {
if (accessNode && hasEffectiveModifierFlagsFromSymbol(prop, ModifierFlags.Deprecated)) {
const deprecatedNode = accessExpression?.argumentExpression ?? (isIndexedAccessTypeNode(accessNode) ? accessNode.indexType : accessNode);
errorOrSuggestion(/* isError */ false, deprecatedNode, Diagnostics._0_is_deprecated, propName as string);
}
if (accessExpression) {
markPropertyAsReferenced(prop, accessExpression, /*isThisAccess*/ accessExpression.expression.kind === SyntaxKind.ThisKeyword);
if (isAssignmentToReadonlyEntity(accessExpression, prop, getAssignmentTargetKind(accessExpression))) {
@ -21554,6 +21558,10 @@ namespace ts {
const localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
let declaration: Declaration | undefined = localOrExportSymbol.valueDeclaration;
const target = (symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol);
if (hasEffectiveModifierFlagsFromSymbol(target, ModifierFlags.Deprecated)) {
errorOrSuggestion(/* isError */ false, node, Diagnostics._0_is_deprecated, node.escapedText as string);
}
if (localOrExportSymbol.flags & SymbolFlags.Class) {
// Due to the emit for class decorators, any reference to the class from inside of the class body
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
@ -24524,6 +24532,10 @@ namespace ts {
propType = indexInfo.type;
}
else {
if (hasEffectiveModifierFlagsFromSymbol(prop, ModifierFlags.Deprecated)) {
errorOrSuggestion(/* isError */ false, right, Diagnostics._0_is_deprecated, right.escapedText as string);
}
checkPropertyNotUsedBeforeDeclaration(prop, node, right);
markPropertyAsReferenced(prop, node, left.kind === SyntaxKind.ThisKeyword);
getNodeLinks(node).resolvedSymbol = prop;
@ -30345,8 +30357,15 @@ namespace ts {
checkTypeArgumentConstraints(node, typeParameters);
}
}
if (type.flags & TypeFlags.Enum && getNodeLinks(node).resolvedSymbol!.flags & SymbolFlags.EnumMember) {
error(node, Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type));
const symbol = getNodeLinks(node).resolvedSymbol;
if (symbol) {
if (hasEffectiveModifierFlagsFromSymbol(symbol, ModifierFlags.Deprecated)) {
const diagLocation = isTypeReferenceNode(node) && isQualifiedName(node.typeName) ? node.typeName.right : node;
errorOrSuggestion(/* isError */ false, diagLocation, Diagnostics._0_is_deprecated, symbol.escapedName as string);
}
if (type.flags & TypeFlags.Enum && symbol.flags & SymbolFlags.EnumMember) {
error(node, Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type));
}
}
}
}
@ -31490,6 +31509,7 @@ namespace ts {
error(classLike, Diagnostics.JSDoc_0_is_not_attached_to_a_class, idText(node.tagName));
}
}
function checkJSDocAugmentsTag(node: JSDocAugmentsTag): void {
const classLike = getEffectiveJSDocHost(node);
if (!classLike || !isClassDeclaration(classLike) && !isClassExpression(classLike)) {
@ -34649,33 +34669,39 @@ namespace ts {
let symbol = getSymbolOfNode(node);
const target = resolveAlias(symbol);
const shouldSkipWithJSExpandoTargets = symbol.flags & SymbolFlags.Assignment;
if (!shouldSkipWithJSExpandoTargets && target !== unknownSymbol) {
// For external modules symbol represents local symbol for an alias.
// This local symbol will merge any other local declarations (excluding other aliases)
// and symbol.flags will contains combined representation for all merged declaration.
// Based on symbol.flags we can compute a set of excluded meanings (meaning that resolved alias should not have,
// otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export*
// in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names).
symbol = getMergedSymbol(symbol.exportSymbol || symbol);
const excludedMeanings =
(symbol.flags & (SymbolFlags.Value | SymbolFlags.ExportValue) ? SymbolFlags.Value : 0) |
(symbol.flags & SymbolFlags.Type ? SymbolFlags.Type : 0) |
(symbol.flags & SymbolFlags.Namespace ? SymbolFlags.Namespace : 0);
if (target.flags & excludedMeanings) {
const message = node.kind === SyntaxKind.ExportSpecifier ?
Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 :
Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0;
error(node, message, symbolToString(symbol));
if (target !== unknownSymbol) {
const shouldSkipWithJSExpandoTargets = symbol.flags & SymbolFlags.Assignment;
if (!shouldSkipWithJSExpandoTargets) {
// For external modules symbol represents local symbol for an alias.
// This local symbol will merge any other local declarations (excluding other aliases)
// and symbol.flags will contains combined representation for all merged declaration.
// Based on symbol.flags we can compute a set of excluded meanings (meaning that resolved alias should not have,
// otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export*
// in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names).
symbol = getMergedSymbol(symbol.exportSymbol || symbol);
const excludedMeanings =
(symbol.flags & (SymbolFlags.Value | SymbolFlags.ExportValue) ? SymbolFlags.Value : 0) |
(symbol.flags & SymbolFlags.Type ? SymbolFlags.Type : 0) |
(symbol.flags & SymbolFlags.Namespace ? SymbolFlags.Namespace : 0);
if (target.flags & excludedMeanings) {
const message = node.kind === SyntaxKind.ExportSpecifier ?
Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 :
Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0;
error(node, message, symbolToString(symbol));
}
// Don't allow to re-export something with no value side when `--isolatedModules` is set.
if (compilerOptions.isolatedModules
&& node.kind === SyntaxKind.ExportSpecifier
&& !node.parent.parent.isTypeOnly
&& !(target.flags & SymbolFlags.Value)
&& !(node.flags & NodeFlags.Ambient)) {
error(node, Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type);
}
}
// Don't allow to re-export something with no value side when `--isolatedModules` is set.
if (compilerOptions.isolatedModules
&& node.kind === SyntaxKind.ExportSpecifier
&& !node.parent.parent.isTypeOnly
&& !(target.flags & SymbolFlags.Value)
&& !(node.flags & NodeFlags.Ambient)) {
error(node, Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type);
if (isImportSpecifier(node) && hasEffectiveModifierFlagsFromSymbol(target, ModifierFlags.Deprecated)) {
errorOrSuggestion(/* isError */ false, node.name, Diagnostics._0_is_deprecated, symbol.escapedName as string);
}
}
}

View file

@ -4594,6 +4594,11 @@
"category": "Message",
"code": 6384
},
"'{0}' is deprecated": {
"category": "Suggestion",
"code": 6385,
"reportsDeprecated": true
},
"The expected type comes from property '{0}' which is declared here on type '{1}'": {
"category": "Message",

View file

@ -2613,6 +2613,10 @@ namespace ts {
return createJSDocTag<JSDocAuthorTag>(SyntaxKind.JSDocAuthorTag, "author", comment);
}
export function createJSDocDeprecatedTag(comment?: string) {
return createJSDocTag(SyntaxKind.JSDocDeprecatedTag, "deprecated", comment);
}
export function createJSDocPublicTag() {
return createJSDocTag<JSDocPublicTag>(SyntaxKind.JSDocPublicTag, "public");
}

View file

@ -7095,6 +7095,9 @@ namespace ts {
case "readonly":
tag = parseSimpleTag(start, SyntaxKind.JSDocReadonlyTag, tagName);
break;
case "deprecated":
tag = parseSimpleTag(start, SyntaxKind.JSDocDeprecatedTag, tagName);
break;
case "this":
tag = parseThisTag(start, tagName);
break;

View file

@ -477,6 +477,7 @@ namespace ts {
JSDocAugmentsTag,
JSDocImplementsTag,
JSDocAuthorTag,
JSDocDeprecatedTag,
JSDocClassTag,
JSDocPublicTag,
JSDocPrivateTag,
@ -614,6 +615,8 @@ namespace ts {
Default = 1 << 9, // Function/Class (export default declaration)
Const = 1 << 11, // Const enum
HasComputedJSDocModifiers = 1 << 12, // Indicates the computed modifier flags include modifiers from JSDoc.
Deprecated = 1 << 13, // Deprecated tag.
HasComputedFlags = 1 << 29, // Modifier flags have been computed
AccessibilityModifier = Public | Private | Protected,
@ -623,7 +626,7 @@ namespace ts {
TypeScriptModifier = Ambient | Public | Private | Protected | Readonly | Abstract | Const,
ExportDefault = Export | Default,
All = Export | Ambient | Public | Private | Protected | Static | Readonly | Abstract | Async | Default | Const
All = Export | Ambient | Public | Private | Protected | Static | Readonly | Abstract | Async | Default | Const | Deprecated
}
export const enum JsxFlags {
@ -2700,6 +2703,10 @@ namespace ts {
kind: SyntaxKind.JSDocAuthorTag;
}
export interface JSDocDeprecatedTag extends JSDocTag {
kind: SyntaxKind.JSDocDeprecatedTag;
}
export interface JSDocClassTag extends JSDocTag {
kind: SyntaxKind.JSDocClassTag;
}
@ -5051,6 +5058,7 @@ namespace ts {
code: number;
message: string;
reportsUnnecessary?: {};
reportsDeprecated?: {};
/* @internal */
elidedInCompatabilityPyramid?: boolean;
}
@ -5071,6 +5079,8 @@ namespace ts {
export interface Diagnostic extends DiagnosticRelatedInformation {
/** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */
reportsUnnecessary?: {};
reportsDeprecated?: {}
source?: string;
relatedInformation?: DiagnosticRelatedInformation[];
}

View file

@ -4360,6 +4360,10 @@ namespace ts {
return getSyntacticModifierFlags(node) & flags;
}
export function hasEffectiveModifierFlagsFromSymbol(symbol: Symbol, flags: ModifierFlags): boolean {
return !!symbol.declarations?.some(decl => !!getSelectedEffectiveModifierFlags(decl, flags));
}
function getModifierFlagsWorker(node: Node, includeJSDoc: boolean): ModifierFlags {
if (node.kind >= SyntaxKind.FirstToken && node.kind <= SyntaxKind.LastToken) {
return ModifierFlags.None;
@ -4369,7 +4373,7 @@ namespace ts {
node.modifierFlagsCache = getSyntacticModifierFlagsNoCache(node) | ModifierFlags.HasComputedFlags;
}
if (includeJSDoc && !(node.modifierFlagsCache & ModifierFlags.HasComputedJSDocModifiers) && isInJSFile(node) && node.parent) {
if (includeJSDoc && !(node.modifierFlagsCache & ModifierFlags.HasComputedJSDocModifiers) && node.parent) {
node.modifierFlagsCache |= getJSDocModifierFlagsNoCache(node) | ModifierFlags.HasComputedJSDocModifiers;
}
@ -4396,12 +4400,16 @@ namespace ts {
function getJSDocModifierFlagsNoCache(node: Node): ModifierFlags {
let flags = ModifierFlags.None;
if (isInJSFile(node) && !!node.parent && !isParameter(node)) {
if (getJSDocPublicTagNoCache(node)) flags |= ModifierFlags.Public;
if (getJSDocPrivateTagNoCache(node)) flags |= ModifierFlags.Private;
if (getJSDocProtectedTagNoCache(node)) flags |= ModifierFlags.Protected;
if (getJSDocReadonlyTagNoCache(node)) flags |= ModifierFlags.Readonly;
if (!!node.parent && !isParameter(node)) {
if (isInJSFile(node)) {
if (getJSDocPublicTagNoCache(node)) flags |= ModifierFlags.Public;
if (getJSDocPrivateTagNoCache(node)) flags |= ModifierFlags.Private;
if (getJSDocProtectedTagNoCache(node)) flags |= ModifierFlags.Protected;
if (getJSDocReadonlyTagNoCache(node)) flags |= ModifierFlags.Readonly;
}
if (getJSDocDeprecatedTagNoCache(node)) flags |= ModifierFlags.Deprecated;
}
return flags;
}
@ -5379,6 +5387,7 @@ namespace ts {
category: message.category,
code: message.code,
reportsUnnecessary: message.reportsUnnecessary,
reportsDeprecated: message.reportsDeprecated
};
}
@ -5410,6 +5419,7 @@ namespace ts {
category: message.category,
code: message.code,
reportsUnnecessary: message.reportsUnnecessary,
reportsDeprecated: message.reportsDeprecated
};
}

View file

@ -740,6 +740,16 @@ namespace ts {
return getFirstJSDocTag(node, isJSDocReadonlyTag, /*noCache*/ true);
}
/** Gets the JSDoc deprecated tag for the node if present */
export function getJSDocDeprecatedTag(node: Node): JSDocDeprecatedTag | undefined {
return getFirstJSDocTag(node, isJSDocDeprecatedTag);
}
/*@internal */
export function getJSDocDeprecatedTagNoCache(node: Node): JSDocDeprecatedTag | undefined {
return getFirstJSDocTag(node, isJSDocDeprecatedTag, /*noCache*/ true);
}
/** Gets the JSDoc enum tag for the node if present */
export function getJSDocEnumTag(node: Node): JSDocEnumTag | undefined {
return getFirstJSDocTag(node, isJSDocEnumTag);
@ -1693,6 +1703,10 @@ namespace ts {
return node.kind === SyntaxKind.JSDocTemplateTag;
}
export function isJSDocDeprecatedTag(node: Node): node is JSDocDeprecatedTag {
return node.kind === SyntaxKind.JSDocDeprecatedTag;
}
export function isJSDocTypedefTag(node: Node): node is JSDocTypedefTag {
return node.kind === SyntaxKind.JSDocTypedefTag;
}

View file

@ -388,6 +388,7 @@ namespace ts.server {
category: Debug.checkDefined(category, "convertDiagnostic: category should not be undefined"),
code: entry.code,
reportsUnnecessary: entry.reportsUnnecessary,
reportsDeprecated: entry.reportsDeprecated,
};
});
}
@ -748,6 +749,7 @@ namespace ts.server {
file: item.file,
name: item.name,
kind: item.kind,
kindModifiers: item.kindModifiers,
span: this.decodeSpan(item.span, item.file),
selectionSpan: this.decodeSpan(item.selectionSpan, item.file)
};

View file

@ -1218,6 +1218,7 @@ namespace FourSlash {
code: e.code,
...ts.createTextSpanFromRange(range),
reportsUnnecessary: e.reportsUnnecessary,
reportsDeprecated: e.reportsDeprecated
};
}));
}

View file

@ -1612,6 +1612,7 @@ namespace FourSlashInterface {
range?: FourSlash.Range;
code: number;
reportsUnnecessary?: true;
reportsDeprecated?: true;
}
export interface GetEditsForFileRenameOptions {

View file

@ -498,6 +498,7 @@ namespace ts.server.protocol {
code: number;
/** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */
reportsUnnecessary?: {};
reportsDeprecated?: {};
relatedInformation?: DiagnosticRelatedInformation[];
}
@ -2535,6 +2536,8 @@ namespace ts.server.protocol {
reportsUnnecessary?: {};
reportsDeprecated?: {};
/**
* Any related spans the diagnostic may have, such as other locations relevant to an error, such as declarartion sites
*/
@ -3066,6 +3069,7 @@ namespace ts.server.protocol {
export interface CallHierarchyItem {
name: string;
kind: ScriptElementKind;
kindModifiers?: string
file: string;
span: TextSpan;
selectionSpan: TextSpan;

View file

@ -56,6 +56,7 @@ namespace ts.server {
code: diag.code,
category: diagnosticCategoryName(diag),
reportsUnnecessary: diag.reportsUnnecessary,
reportsDeprecated: diag.reportsDeprecated,
source: diag.source,
relatedInformation: map(diag.relatedInformation, formatRelatedInformation),
};
@ -100,6 +101,7 @@ namespace ts.server {
code,
category,
reportsUnnecessary: diag.reportsUnnecessary,
reportsDeprecated: diag.reportsDeprecated,
source,
relatedInformation: map(diag.relatedInformation, formatRelatedInformation),
};
@ -1018,6 +1020,7 @@ namespace ts.server {
startLocation: (d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start!)))!, // TODO: GH#18217
endLocation: (d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start! + d.length!)))!, // TODO: GH#18217
reportsUnnecessary: d.reportsUnnecessary,
reportsDeprecated: d.reportsDeprecated,
relatedInformation: map(d.relatedInformation, formatRelatedInformation)
}));
}
@ -1047,6 +1050,7 @@ namespace ts.server {
startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start!), // TODO: GH#18217
endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start! + d.length!),
reportsUnnecessary: d.reportsUnnecessary,
reportsDeprecated: d.reportsDeprecated,
relatedInformation: map(d.relatedInformation, formatRelatedInformation),
});
}
@ -1882,6 +1886,7 @@ namespace ts.server {
const bakedItem: protocol.NavtoItem = {
name: navItem.name,
kind: navItem.kind,
kindModifiers: navItem.kindModifiers,
isCaseSensitive: navItem.isCaseSensitive,
matchKind: navItem.matchKind,
file: navItem.fileName,
@ -2221,6 +2226,7 @@ namespace ts.server {
return {
name: item.name,
kind: item.kind,
kindModifiers: item.kindModifiers,
file: item.file,
span: toProtocolTextSpan(item.span, scriptInfo),
selectionSpan: toProtocolTextSpan(item.selectionSpan, scriptInfo)

View file

@ -272,9 +272,10 @@ namespace ts.CallHierarchy {
const name = getCallHierarchyItemName(program, node);
const containerName = getCallHierarchItemContainerName(node);
const kind = getNodeKind(node);
const kindModifiers = getNodeModifiers(node);
const span = createTextSpanFromBounds(skipTrivia(sourceFile.text, node.getFullStart(), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true), node.getEnd());
const selectionSpan = createTextSpanFromBounds(name.pos, name.end);
return { file: sourceFile.fileName, kind, name: name.text, containerName, span, selectionSpan };
return { file: sourceFile.fileName, kind, kindModifiers, name: name.text, containerName, span, selectionSpan };
}
function isDefined<T>(x: T): x is NonNullable<T> {

View file

@ -601,6 +601,7 @@ namespace ts {
category: string;
code: number;
reportsUnnecessary?: {};
reportsDeprecated?: {};
}
export function realizeDiagnostics(diagnostics: readonly Diagnostic[], newLine: string): RealizedDiagnostic[] {
return diagnostics.map(d => realizeDiagnostic(d, newLine));
@ -614,6 +615,7 @@ namespace ts {
category: diagnosticCategoryName(diagnostic),
code: diagnostic.code,
reportsUnnecessary: diagnostic.reportsUnnecessary,
reportsDeprecated: diagnostic.reportsDeprecated
};
}

View file

@ -612,6 +612,7 @@ namespace ts {
export interface CallHierarchyItem {
name: string;
kind: ScriptElementKind;
kindModifiers?: string;
file: string;
span: TextSpan;
selectionSpan: TextSpan;
@ -1298,6 +1299,8 @@ namespace ts {
abstractModifier = "abstract",
optionalModifier = "optional",
deprecatedModifier = "deprecated",
dtsModifier = ".d.ts",
tsModifier = ".ts",
tsxModifier = ".tsx",

View file

@ -1504,6 +1504,7 @@ namespace ts {
if (flags & ModifierFlags.Static) result.push(ScriptElementKindModifier.staticModifier);
if (flags & ModifierFlags.Abstract) result.push(ScriptElementKindModifier.abstractModifier);
if (flags & ModifierFlags.Export) result.push(ScriptElementKindModifier.exportedModifier);
if (flags & ModifierFlags.Deprecated) result.push(ScriptElementKindModifier.deprecatedModifier);
if (node.flags & NodeFlags.Ambient) result.push(ScriptElementKindModifier.ambientModifier);
if (node.kind === SyntaxKind.ExportAssignment) result.push(ScriptElementKindModifier.exportedModifier);

View file

@ -128,6 +128,7 @@ namespace ts {
messageText: error.messageText,
start: undefined,
reportsUnnecessary: undefined,
reportsDeprecated: undefined
}));
assertParsed(actual, expected);
}

View file

@ -615,7 +615,8 @@ export = C;
"D.ts",
"d.ts",
),
reportsUnnecessary: undefined
reportsUnnecessary: undefined,
reportsDeprecated: undefined
}]
);
});
@ -641,7 +642,8 @@ export = C;
"/a/b/D.ts",
"d.ts",
),
reportsUnnecessary: undefined
reportsUnnecessary: undefined,
reportsDeprecated: undefined
}]
);
});
@ -667,7 +669,8 @@ export = C;
"ModuleB.ts",
"moduleB.ts",
),
reportsUnnecessary: undefined
reportsUnnecessary: undefined,
reportsDeprecated: undefined
}]
);
});
@ -694,7 +697,8 @@ export = C;
"/a/b/D.ts",
"d.ts",
),
reportsUnnecessary: undefined
reportsUnnecessary: undefined,
reportsDeprecated: undefined
}]
);
});
@ -722,7 +726,8 @@ export = C;
"ModuleC.ts",
"moduleC.ts",
),
reportsUnnecessary: undefined
reportsUnnecessary: undefined,
reportsDeprecated: undefined
},
{
...tscWatch.getDiagnosticOfFileFromProgram(
@ -734,7 +739,8 @@ export = C;
"moduleC.ts",
"ModuleC.ts"
),
reportsUnnecessary: undefined
reportsUnnecessary: undefined,
reportsDeprecated: undefined
}
]
);
@ -766,7 +772,8 @@ import b = require("./moduleB");
"/a/B/c/moduleC.ts",
"/a/B/c/ModuleC.ts"
),
reportsUnnecessary: undefined
reportsUnnecessary: undefined,
reportsDeprecated: undefined
}]
);
});

View file

@ -194,6 +194,7 @@ namespace ts.tscWatch {
messageText: "Type 'number' is not assignable to type 'string'.",
relatedInformation: undefined,
reportsUnnecessary: undefined,
reportsDeprecated: undefined,
source: undefined
}]);
});

View file

@ -868,6 +868,7 @@ namespace ts.projectSystem {
code: Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file.code,
category: diagnosticCategoryName(Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file),
reportsUnnecessary: undefined,
reportsDeprecated: undefined,
relatedInformation: undefined,
source: undefined
}]

View file

@ -204,6 +204,7 @@ namespace ts.projectSystem {
category: DiagnosticCategory;
code: number;
reportsUnnecessary?: {};
reportsDeprecated?: {};
source?: string;
relatedInformation?: DiagnosticRelatedInformation[];
}
@ -699,8 +700,8 @@ namespace ts.projectSystem {
checkNthEvent(session, server.toEvent(eventName, diagnostics), 0, isMostRecent);
}
export function createDiagnostic(start: protocol.Location, end: protocol.Location, message: DiagnosticMessage, args: readonly string[] = [], category = diagnosticCategoryName(message), reportsUnnecessary?: {}, relatedInformation?: protocol.DiagnosticRelatedInformation[]): protocol.Diagnostic {
return { start, end, text: formatStringFromArgs(message.message, args), code: message.code, category, reportsUnnecessary, relatedInformation, source: undefined };
export function createDiagnostic(start: protocol.Location, end: protocol.Location, message: DiagnosticMessage, args: readonly string[] = [], category = diagnosticCategoryName(message), reportsUnnecessary?: {}, relatedInformation?: protocol.DiagnosticRelatedInformation[], reportsDeprecated?: {}): protocol.Diagnostic {
return { start, end, text: formatStringFromArgs(message.message, args), code: message.code, category, reportsUnnecessary, reportsDeprecated, relatedInformation, source: undefined };
}
export function checkCompleteEvent(session: TestSession, numberOfCurrentEvents: number, expectedSequenceId: number, isMostRecent = true): void {

View file

@ -1,7 +1,11 @@
namespace ts.projectSystem {
describe("unittests:: tsserver:: navigate-to for javascript project", () => {
function findNavToItem(items: protocol.NavtoItem[], itemName: string, itemKind: string) {
return find(items, item => item.name === itemName && item.kind === itemKind);
}
function containsNavToItem(items: protocol.NavtoItem[], itemName: string, itemKind: string) {
return find(items, item => item.name === itemName && item.kind === itemKind) !== undefined;
return findNavToItem(items, itemName, itemKind) !== undefined;
}
it("should not include type symbols", () => {
@ -67,5 +71,26 @@ export const ghijkl = a.abcdef;`
assert.strictEqual(item.name, "abcdef");
assert.strictEqual(item.file, file1.path);
});
it("should work with Deprecated", () => {
const file1: File = {
path: "/a/b/file1.js",
content: "/** @deprecated */\nfunction foo () {}"
};
const configFile: File = {
path: "/a/b/jsconfig.json",
content: "{}"
};
const host = createServerHost([file1, configFile, libFile]);
const session = createSession(host);
openFilesForSession([file1], session);
// Try to find some interface type defined in lib.d.ts
const libTypeNavToRequest = makeSessionRequest<protocol.NavtoRequestArgs>(CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path });
const items = session.executeCommand(libTypeNavToRequest).response as protocol.NavtoItem[];
const fooItem = findNavToItem(items, "foo", "function");
assert.isNotNull(fooItem, `Cannot find function symbol "foo".`);
assert.isTrue(fooItem?.kindModifiers?.includes("deprecated"));
});
});
}

View file

@ -534,7 +534,8 @@ declare module '@custom/plugin' {
messageText: formatStringFromArgs(d.message, didYouMean ? [prop, didYouMean] : [prop]),
category: d.category,
code: d.code,
reportsUnnecessary: undefined
reportsUnnecessary: undefined,
reportsDeprecated: undefined
};
}
@ -549,7 +550,8 @@ declare module '@custom/plugin' {
messageText: formatStringFromArgs(d.message, [`${getDirectoryPath(configFile.path)}/${relativeFileName}`]),
category: d.category,
code: d.code,
reportsUnnecessary: undefined
reportsUnnecessary: undefined,
reportsDeprecated: undefined
};
}
@ -908,6 +910,7 @@ declare module '@custom/plugin' {
code: Diagnostics.Unused_label.code,
relatedInformation: undefined,
reportsUnnecessary: true,
reportsDeprecated: undefined,
source: undefined,
},
]);

View file

@ -389,28 +389,29 @@ declare namespace ts {
JSDocAugmentsTag = 311,
JSDocImplementsTag = 312,
JSDocAuthorTag = 313,
JSDocClassTag = 314,
JSDocPublicTag = 315,
JSDocPrivateTag = 316,
JSDocProtectedTag = 317,
JSDocReadonlyTag = 318,
JSDocCallbackTag = 319,
JSDocEnumTag = 320,
JSDocParameterTag = 321,
JSDocReturnTag = 322,
JSDocThisTag = 323,
JSDocTypeTag = 324,
JSDocTemplateTag = 325,
JSDocTypedefTag = 326,
JSDocPropertyTag = 327,
SyntaxList = 328,
NotEmittedStatement = 329,
PartiallyEmittedExpression = 330,
CommaListExpression = 331,
MergeDeclarationMarker = 332,
EndOfDeclarationMarker = 333,
SyntheticReferenceExpression = 334,
Count = 335,
JSDocDeprecatedTag = 314,
JSDocClassTag = 315,
JSDocPublicTag = 316,
JSDocPrivateTag = 317,
JSDocProtectedTag = 318,
JSDocReadonlyTag = 319,
JSDocCallbackTag = 320,
JSDocEnumTag = 321,
JSDocParameterTag = 322,
JSDocReturnTag = 323,
JSDocThisTag = 324,
JSDocTypeTag = 325,
JSDocTemplateTag = 326,
JSDocTypedefTag = 327,
JSDocPropertyTag = 328,
SyntaxList = 329,
NotEmittedStatement = 330,
PartiallyEmittedExpression = 331,
CommaListExpression = 332,
MergeDeclarationMarker = 333,
EndOfDeclarationMarker = 334,
SyntheticReferenceExpression = 335,
Count = 336,
FirstAssignment = 62,
LastAssignment = 77,
FirstCompoundAssignment = 63,
@ -439,9 +440,9 @@ declare namespace ts {
LastStatement = 245,
FirstNode = 156,
FirstJSDocNode = 298,
LastJSDocNode = 327,
LastJSDocNode = 328,
FirstJSDocTagNode = 310,
LastJSDocTagNode = 327,
LastJSDocTagNode = 328,
}
export enum NodeFlags {
None = 0,
@ -487,13 +488,14 @@ declare namespace ts {
Default = 512,
Const = 2048,
HasComputedJSDocModifiers = 4096,
Deprecated = 8192,
HasComputedFlags = 536870912,
AccessibilityModifier = 28,
ParameterPropertyModifier = 92,
NonPublicAccessibilityModifier = 24,
TypeScriptModifier = 2270,
ExportDefault = 513,
All = 3071
All = 11263
}
export enum JsxFlags {
None = 0,
@ -1663,6 +1665,9 @@ declare namespace ts {
export interface JSDocAuthorTag extends JSDocTag {
kind: SyntaxKind.JSDocAuthorTag;
}
export interface JSDocDeprecatedTag extends JSDocTag {
kind: SyntaxKind.JSDocDeprecatedTag;
}
export interface JSDocClassTag extends JSDocTag {
kind: SyntaxKind.JSDocClassTag;
}
@ -2581,6 +2586,7 @@ declare namespace ts {
code: number;
message: string;
reportsUnnecessary?: {};
reportsDeprecated?: {};
}
/**
* A linked list of formatted diagnostic messages to be used as part of a multiline message.
@ -2597,6 +2603,7 @@ declare namespace ts {
export interface Diagnostic extends DiagnosticRelatedInformation {
/** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */
reportsUnnecessary?: {};
reportsDeprecated?: {};
source?: string;
relatedInformation?: DiagnosticRelatedInformation[];
}
@ -3543,6 +3550,8 @@ declare namespace ts {
function getJSDocProtectedTag(node: Node): JSDocProtectedTag | undefined;
/** Gets the JSDoc protected tag for the node if present */
function getJSDocReadonlyTag(node: Node): JSDocReadonlyTag | undefined;
/** Gets the JSDoc deprecated tag for the node if present */
function getJSDocDeprecatedTag(node: Node): JSDocDeprecatedTag | undefined;
/** Gets the JSDoc enum tag for the node if present */
function getJSDocEnumTag(node: Node): JSDocEnumTag | undefined;
/** Gets the JSDoc this tag for the node if present */
@ -3765,6 +3774,7 @@ declare namespace ts {
function isJSDocReturnTag(node: Node): node is JSDocReturnTag;
function isJSDocTypeTag(node: Node): node is JSDocTypeTag;
function isJSDocTemplateTag(node: Node): node is JSDocTemplateTag;
function isJSDocDeprecatedTag(node: Node): node is JSDocDeprecatedTag;
function isJSDocTypedefTag(node: Node): node is JSDocTypedefTag;
function isJSDocPropertyTag(node: Node): node is JSDocPropertyTag;
function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag;
@ -4277,6 +4287,7 @@ declare namespace ts {
function createJSDocTypeLiteral(jsDocPropertyTags?: readonly JSDocPropertyLikeTag[], isArrayType?: boolean): JSDocTypeLiteral;
function createJSDocImplementsTag(classExpression: JSDocImplementsTag["class"], comment?: string): JSDocImplementsTag;
function createJSDocAuthorTag(comment?: string): JSDocAuthorTag;
function createJSDocDeprecatedTag(comment?: string): JSDocTag;
function createJSDocPublicTag(): JSDocPublicTag;
function createJSDocPrivateTag(): JSDocPrivateTag;
function createJSDocProtectedTag(): JSDocProtectedTag;
@ -5428,6 +5439,7 @@ declare namespace ts {
interface CallHierarchyItem {
name: string;
kind: ScriptElementKind;
kindModifiers?: string;
file: string;
span: TextSpan;
selectionSpan: TextSpan;
@ -5977,6 +5989,7 @@ declare namespace ts {
staticModifier = "static",
abstractModifier = "abstract",
optionalModifier = "optional",
deprecatedModifier = "deprecated",
dtsModifier = ".d.ts",
tsModifier = ".ts",
tsxModifier = ".tsx",
@ -6599,6 +6612,7 @@ declare namespace ts.server.protocol {
code: number;
/** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */
reportsUnnecessary?: {};
reportsDeprecated?: {};
relatedInformation?: DiagnosticRelatedInformation[];
}
/**
@ -8152,6 +8166,7 @@ declare namespace ts.server.protocol {
*/
category: string;
reportsUnnecessary?: {};
reportsDeprecated?: {};
/**
* Any related spans the diagnostic may have, such as other locations relevant to an error, such as declarartion sites
*/
@ -8588,6 +8603,7 @@ declare namespace ts.server.protocol {
interface CallHierarchyItem {
name: string;
kind: ScriptElementKind;
kindModifiers?: string;
file: string;
span: TextSpan;
selectionSpan: TextSpan;

View file

@ -389,28 +389,29 @@ declare namespace ts {
JSDocAugmentsTag = 311,
JSDocImplementsTag = 312,
JSDocAuthorTag = 313,
JSDocClassTag = 314,
JSDocPublicTag = 315,
JSDocPrivateTag = 316,
JSDocProtectedTag = 317,
JSDocReadonlyTag = 318,
JSDocCallbackTag = 319,
JSDocEnumTag = 320,
JSDocParameterTag = 321,
JSDocReturnTag = 322,
JSDocThisTag = 323,
JSDocTypeTag = 324,
JSDocTemplateTag = 325,
JSDocTypedefTag = 326,
JSDocPropertyTag = 327,
SyntaxList = 328,
NotEmittedStatement = 329,
PartiallyEmittedExpression = 330,
CommaListExpression = 331,
MergeDeclarationMarker = 332,
EndOfDeclarationMarker = 333,
SyntheticReferenceExpression = 334,
Count = 335,
JSDocDeprecatedTag = 314,
JSDocClassTag = 315,
JSDocPublicTag = 316,
JSDocPrivateTag = 317,
JSDocProtectedTag = 318,
JSDocReadonlyTag = 319,
JSDocCallbackTag = 320,
JSDocEnumTag = 321,
JSDocParameterTag = 322,
JSDocReturnTag = 323,
JSDocThisTag = 324,
JSDocTypeTag = 325,
JSDocTemplateTag = 326,
JSDocTypedefTag = 327,
JSDocPropertyTag = 328,
SyntaxList = 329,
NotEmittedStatement = 330,
PartiallyEmittedExpression = 331,
CommaListExpression = 332,
MergeDeclarationMarker = 333,
EndOfDeclarationMarker = 334,
SyntheticReferenceExpression = 335,
Count = 336,
FirstAssignment = 62,
LastAssignment = 77,
FirstCompoundAssignment = 63,
@ -439,9 +440,9 @@ declare namespace ts {
LastStatement = 245,
FirstNode = 156,
FirstJSDocNode = 298,
LastJSDocNode = 327,
LastJSDocNode = 328,
FirstJSDocTagNode = 310,
LastJSDocTagNode = 327,
LastJSDocTagNode = 328,
}
export enum NodeFlags {
None = 0,
@ -487,13 +488,14 @@ declare namespace ts {
Default = 512,
Const = 2048,
HasComputedJSDocModifiers = 4096,
Deprecated = 8192,
HasComputedFlags = 536870912,
AccessibilityModifier = 28,
ParameterPropertyModifier = 92,
NonPublicAccessibilityModifier = 24,
TypeScriptModifier = 2270,
ExportDefault = 513,
All = 3071
All = 11263
}
export enum JsxFlags {
None = 0,
@ -1663,6 +1665,9 @@ declare namespace ts {
export interface JSDocAuthorTag extends JSDocTag {
kind: SyntaxKind.JSDocAuthorTag;
}
export interface JSDocDeprecatedTag extends JSDocTag {
kind: SyntaxKind.JSDocDeprecatedTag;
}
export interface JSDocClassTag extends JSDocTag {
kind: SyntaxKind.JSDocClassTag;
}
@ -2581,6 +2586,7 @@ declare namespace ts {
code: number;
message: string;
reportsUnnecessary?: {};
reportsDeprecated?: {};
}
/**
* A linked list of formatted diagnostic messages to be used as part of a multiline message.
@ -2597,6 +2603,7 @@ declare namespace ts {
export interface Diagnostic extends DiagnosticRelatedInformation {
/** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */
reportsUnnecessary?: {};
reportsDeprecated?: {};
source?: string;
relatedInformation?: DiagnosticRelatedInformation[];
}
@ -3543,6 +3550,8 @@ declare namespace ts {
function getJSDocProtectedTag(node: Node): JSDocProtectedTag | undefined;
/** Gets the JSDoc protected tag for the node if present */
function getJSDocReadonlyTag(node: Node): JSDocReadonlyTag | undefined;
/** Gets the JSDoc deprecated tag for the node if present */
function getJSDocDeprecatedTag(node: Node): JSDocDeprecatedTag | undefined;
/** Gets the JSDoc enum tag for the node if present */
function getJSDocEnumTag(node: Node): JSDocEnumTag | undefined;
/** Gets the JSDoc this tag for the node if present */
@ -3765,6 +3774,7 @@ declare namespace ts {
function isJSDocReturnTag(node: Node): node is JSDocReturnTag;
function isJSDocTypeTag(node: Node): node is JSDocTypeTag;
function isJSDocTemplateTag(node: Node): node is JSDocTemplateTag;
function isJSDocDeprecatedTag(node: Node): node is JSDocDeprecatedTag;
function isJSDocTypedefTag(node: Node): node is JSDocTypedefTag;
function isJSDocPropertyTag(node: Node): node is JSDocPropertyTag;
function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag;
@ -4277,6 +4287,7 @@ declare namespace ts {
function createJSDocTypeLiteral(jsDocPropertyTags?: readonly JSDocPropertyLikeTag[], isArrayType?: boolean): JSDocTypeLiteral;
function createJSDocImplementsTag(classExpression: JSDocImplementsTag["class"], comment?: string): JSDocImplementsTag;
function createJSDocAuthorTag(comment?: string): JSDocAuthorTag;
function createJSDocDeprecatedTag(comment?: string): JSDocTag;
function createJSDocPublicTag(): JSDocPublicTag;
function createJSDocPrivateTag(): JSDocPrivateTag;
function createJSDocProtectedTag(): JSDocProtectedTag;
@ -5428,6 +5439,7 @@ declare namespace ts {
interface CallHierarchyItem {
name: string;
kind: ScriptElementKind;
kindModifiers?: string;
file: string;
span: TextSpan;
selectionSpan: TextSpan;
@ -5977,6 +5989,7 @@ declare namespace ts {
staticModifier = "static",
abstractModifier = "abstract",
optionalModifier = "optional",
deprecatedModifier = "deprecated",
dtsModifier = ".d.ts",
tsModifier = ".ts",
tsxModifier = ".tsx",

View file

@ -0,0 +1,89 @@
//// [tests/cases/conformance/jsdoc/jsdocDeprecatedTag1.ts] ////
//// [a.ts]
export namespace foo {
/** @deprecated */
export function faff () { }
faff()
}
const a = foo.faff()
foo["faff"]
const { faff } = foo
faff()
/** @deprecated */
export function bar () {
foo?.faff()
}
foo?.["faff"]?.()
bar();
/** @deprecated */
export interface Foo {
/** @deprecated */
zzz: number
}
/** @deprecated */
export type QW = Foo["zzz"]
export type WQ = QW
//// [b.ts]
import * as f from './a';
import { bar, QW } from './a';
f.bar();
f.foo.faff();
bar();
type Z = QW;
type A = f.Foo;
type B = f.QW;
type C = f.WQ;
type O = Z | A | B | C;
//// [a.js]
"use strict";
var _a;
exports.__esModule = true;
exports.bar = exports.foo = void 0;
var foo;
(function (foo) {
/** @deprecated */
function faff() { }
foo.faff = faff;
faff();
})(foo = exports.foo || (exports.foo = {}));
var a = foo.faff();
foo["faff"];
var faff = foo.faff;
faff();
/** @deprecated */
function bar() {
foo === null || foo === void 0 ? void 0 : foo.faff();
}
exports.bar = bar;
(_a = foo === null || foo === void 0 ? void 0 : foo["faff"]) === null || _a === void 0 ? void 0 : _a.call(foo);
bar();
//// [b.js]
"use strict";
exports.__esModule = true;
var f = require("./a");
var a_1 = require("./a");
f.bar();
f.foo.faff();
a_1.bar();
//// [a.d.ts]
export declare namespace foo {
/** @deprecated */
function faff(): void;
}
/** @deprecated */
export declare function bar(): void;
/** @deprecated */
export interface Foo {
/** @deprecated */
zzz: number;
}
/** @deprecated */
export declare type QW = Foo["zzz"];
export declare type WQ = QW;
//// [b.d.ts]
export {};

View file

@ -0,0 +1,110 @@
=== tests/cases/conformance/jsdoc/a.ts ===
export namespace foo {
>foo : Symbol(foo, Decl(a.ts, 0, 0))
/** @deprecated */
export function faff () { }
>faff : Symbol(faff, Decl(a.ts, 0, 22))
faff()
>faff : Symbol(faff, Decl(a.ts, 0, 22))
}
const a = foo.faff()
>a : Symbol(a, Decl(a.ts, 5, 5))
>foo.faff : Symbol(foo.faff, Decl(a.ts, 0, 22))
>foo : Symbol(foo, Decl(a.ts, 0, 0))
>faff : Symbol(foo.faff, Decl(a.ts, 0, 22))
foo["faff"]
>foo : Symbol(foo, Decl(a.ts, 0, 0))
>"faff" : Symbol(foo.faff, Decl(a.ts, 0, 22))
const { faff } = foo
>faff : Symbol(faff, Decl(a.ts, 7, 7))
>foo : Symbol(foo, Decl(a.ts, 0, 0))
faff()
>faff : Symbol(faff, Decl(a.ts, 7, 7))
/** @deprecated */
export function bar () {
>bar : Symbol(bar, Decl(a.ts, 8, 6))
foo?.faff()
>foo?.faff : Symbol(foo.faff, Decl(a.ts, 0, 22))
>foo : Symbol(foo, Decl(a.ts, 0, 0))
>faff : Symbol(foo.faff, Decl(a.ts, 0, 22))
}
foo?.["faff"]?.()
>foo : Symbol(foo, Decl(a.ts, 0, 0))
>"faff" : Symbol(foo.faff, Decl(a.ts, 0, 22))
bar();
>bar : Symbol(bar, Decl(a.ts, 8, 6))
/** @deprecated */
export interface Foo {
>Foo : Symbol(Foo, Decl(a.ts, 14, 6))
/** @deprecated */
zzz: number
>zzz : Symbol(Foo.zzz, Decl(a.ts, 16, 22))
}
/** @deprecated */
export type QW = Foo["zzz"]
>QW : Symbol(QW, Decl(a.ts, 19, 1))
>Foo : Symbol(Foo, Decl(a.ts, 14, 6))
export type WQ = QW
>WQ : Symbol(WQ, Decl(a.ts, 21, 27))
>QW : Symbol(QW, Decl(a.ts, 19, 1))
=== tests/cases/conformance/jsdoc/b.ts ===
import * as f from './a';
>f : Symbol(f, Decl(b.ts, 0, 6))
import { bar, QW } from './a';
>bar : Symbol(bar, Decl(b.ts, 1, 8))
>QW : Symbol(QW, Decl(b.ts, 1, 13))
f.bar();
>f.bar : Symbol(f.bar, Decl(a.ts, 8, 6))
>f : Symbol(f, Decl(b.ts, 0, 6))
>bar : Symbol(f.bar, Decl(a.ts, 8, 6))
f.foo.faff();
>f.foo.faff : Symbol(f.foo.faff, Decl(a.ts, 0, 22))
>f.foo : Symbol(f.foo, Decl(a.ts, 0, 0))
>f : Symbol(f, Decl(b.ts, 0, 6))
>foo : Symbol(f.foo, Decl(a.ts, 0, 0))
>faff : Symbol(f.foo.faff, Decl(a.ts, 0, 22))
bar();
>bar : Symbol(bar, Decl(b.ts, 1, 8))
type Z = QW;
>Z : Symbol(Z, Decl(b.ts, 4, 6))
>QW : Symbol(QW, Decl(b.ts, 1, 13))
type A = f.Foo;
>A : Symbol(A, Decl(b.ts, 5, 12))
>f : Symbol(f, Decl(b.ts, 0, 6))
>Foo : Symbol(f.Foo, Decl(a.ts, 14, 6))
type B = f.QW;
>B : Symbol(B, Decl(b.ts, 6, 15))
>f : Symbol(f, Decl(b.ts, 0, 6))
>QW : Symbol(f.QW, Decl(a.ts, 19, 1))
type C = f.WQ;
>C : Symbol(C, Decl(b.ts, 7, 14))
>f : Symbol(f, Decl(b.ts, 0, 6))
>WQ : Symbol(f.WQ, Decl(a.ts, 21, 27))
type O = Z | A | B | C;
>O : Symbol(O, Decl(b.ts, 8, 14))
>Z : Symbol(Z, Decl(b.ts, 4, 6))
>A : Symbol(A, Decl(b.ts, 5, 12))
>B : Symbol(B, Decl(b.ts, 6, 15))
>C : Symbol(C, Decl(b.ts, 7, 14))

View file

@ -0,0 +1,109 @@
=== tests/cases/conformance/jsdoc/a.ts ===
export namespace foo {
>foo : typeof foo
/** @deprecated */
export function faff () { }
>faff : () => void
faff()
>faff() : void
>faff : () => void
}
const a = foo.faff()
>a : void
>foo.faff() : void
>foo.faff : () => void
>foo : typeof foo
>faff : () => void
foo["faff"]
>foo["faff"] : () => void
>foo : typeof foo
>"faff" : "faff"
const { faff } = foo
>faff : () => void
>foo : typeof foo
faff()
>faff() : void
>faff : () => void
/** @deprecated */
export function bar () {
>bar : () => void
foo?.faff()
>foo?.faff() : void
>foo?.faff : () => void
>foo : typeof foo
>faff : () => void
}
foo?.["faff"]?.()
>foo?.["faff"]?.() : void
>foo?.["faff"] : () => void
>foo : typeof foo
>"faff" : "faff"
bar();
>bar() : void
>bar : () => void
/** @deprecated */
export interface Foo {
/** @deprecated */
zzz: number
>zzz : number
}
/** @deprecated */
export type QW = Foo["zzz"]
>QW : number
export type WQ = QW
>WQ : number
=== tests/cases/conformance/jsdoc/b.ts ===
import * as f from './a';
>f : typeof f
import { bar, QW } from './a';
>bar : () => void
>QW : any
f.bar();
>f.bar() : void
>f.bar : () => void
>f : typeof f
>bar : () => void
f.foo.faff();
>f.foo.faff() : void
>f.foo.faff : () => void
>f.foo : typeof f.foo
>f : typeof f
>foo : typeof f.foo
>faff : () => void
bar();
>bar() : void
>bar : () => void
type Z = QW;
>Z : number
type A = f.Foo;
>A : f.Foo
>f : any
type B = f.QW;
>B : number
>f : any
type C = f.WQ;
>C : number
>f : any
type O = Z | A | B | C;
>O : O

View file

@ -0,0 +1,37 @@
// @declaration: true
// @Filename: a.ts
export namespace foo {
/** @deprecated */
export function faff () { }
faff()
}
const a = foo.faff()
foo["faff"]
const { faff } = foo
faff()
/** @deprecated */
export function bar () {
foo?.faff()
}
foo?.["faff"]?.()
bar();
/** @deprecated */
export interface Foo {
/** @deprecated */
zzz: number
}
/** @deprecated */
export type QW = Foo["zzz"]
export type WQ = QW
// @Filename: b.ts
import * as f from './a';
import { bar, QW } from './a';
f.bar();
f.foo.faff();
bar();
type Z = QW;
type A = f.Foo;
type B = f.QW;
type C = f.WQ;
type O = Z | A | B | C;

View file

@ -0,0 +1,32 @@
/// <reference path="fourslash.ts" />
// @strict: true
//// /** @deprecated */
//// interface Foo {
//// /** @deprecated */
//// bar(): void
//// /** @deprecated */
//// prop: number
//// }
//// declare const foo: Foo;
//// declare const foooo: Fo/*1*/;
//// foo.ba/*2*/;
//// foo.pro/*3*/;
verify.completions({
marker: "1",
includes: [
{ name: "Foo", kind: "interface", kindModifiers: "deprecated" }
]
}, {
marker: "2",
includes: [
{ name: "bar", kind: "method", kindModifiers: "deprecated" }
]
}, {
marker: "3",
includes: [
{ name: "prop", kind: "property", kindModifiers: "deprecated" }
]
});

View file

@ -586,6 +586,7 @@ declare namespace FourSlashInterface {
range?: Range;
code: number;
reportsUnnecessary?: true;
reportsDeprecated?: true;
}
interface VerifyDocumentHighlightsOptions {
filesToSearch?: ReadonlyArray<string>;

View file

@ -0,0 +1,166 @@
// @Filename: a.ts
//// export namespace foo {
//// /** @deprecated */
//// export function faff () { }
//// [|faff|]()
//// }
//// const [|a|] = foo.[|faff|]()
//// foo[[|"faff"|]]
//// const { [|faff|] } = foo
//// faff()
//// /** @deprecated */
//// export function bar () {
//// foo?.[|faff|]()
//// }
//// foo?.[[|"faff"|]]?.()
//// [|bar|]();
//// /** @deprecated */
//// export interface Foo {
//// /** @deprecated */
//// zzz: number
//// }
//// /** @deprecated */
//// export type QW = [|Foo|][[|"zzz"|]]
//// export type WQ = [|QW|]
// @Filename: b.ts
//// import * as f from './a';
//// import { [|bar|], [|QW|] } from './a';
//// f.[|bar|]();
//// f.foo.[|faff|]();
//// [|bar|]();
//// type Z = [|QW|];
//// type A = f.[|Foo|];
//// type B = f.[|QW|];
//// type C = f.WQ;
//// type [|O|] = Z | A | B | C;
goTo.file('a.ts')
const ranges = test.ranges();
verify.getSuggestionDiagnostics([
{
message: "'faff' is deprecated",
code: 6385,
range: ranges[0],
reportsDeprecated: true,
},
{
message: "'a' is declared but its value is never read.",
code: 6133,
range: ranges[1],
reportsUnnecessary: true
},
{
message: "'faff' is deprecated",
code: 6385,
range: ranges[2],
reportsDeprecated: true,
},
{
message: "'faff' is deprecated",
code: 6385,
range: ranges[3],
reportsDeprecated: true,
},
{
message: "'faff' is deprecated",
code: 6385,
range: ranges[4],
reportsDeprecated: true,
},
{
message: "'faff' is deprecated",
code: 6385,
range: ranges[5],
reportsDeprecated: true,
},
{
message: "'faff' is deprecated",
code: 6385,
range: ranges[6],
reportsDeprecated: true,
},
{
message: "'bar' is deprecated",
code: 6385,
range: ranges[7],
reportsDeprecated: true,
},
{
message: "'Foo' is deprecated",
code: 6385,
range: ranges[8],
reportsDeprecated: true,
},
{
message: "'zzz' is deprecated",
code: 6385,
range: ranges[9],
reportsDeprecated: true,
},
{
message: "'QW' is deprecated",
code: 6385,
range: ranges[10],
reportsDeprecated: true,
}
])
goTo.file('b.ts')
verify.getSuggestionDiagnostics([
{
message: "'bar' is deprecated",
code: 6385,
range: ranges[11],
reportsDeprecated: true,
},
{
message: "'QW' is deprecated",
code: 6385,
range: ranges[12],
reportsDeprecated: true,
},
{
message: "'bar' is deprecated",
code: 6385,
range: ranges[13],
reportsDeprecated: true,
},
{
message: "'faff' is deprecated",
code: 6385,
range: ranges[14],
reportsDeprecated: true,
},
{
message: "'bar' is deprecated",
code: 6385,
range: ranges[15],
reportsDeprecated: true,
},
{
message: "'QW' is deprecated",
code: 6385,
range: ranges[16],
reportsDeprecated: true,
},
{
message: "'Foo' is deprecated",
code: 6385,
range: ranges[17],
reportsDeprecated: true,
},
{
message: "'QW' is deprecated",
code: 6385,
range: ranges[18],
reportsDeprecated: true,
},
{
message: "'O' is declared but never used.",
code: 6196,
range: ranges[19],
reportsUnnecessary: true
}
])