Have Symbol#isReferenced check the SymbolFlags of the reference (#21996)
This commit is contained in:
parent
ecddf8468f
commit
9ee51fadd9
|
@ -1394,7 +1394,7 @@ namespace ts {
|
|||
// If `result === lastSelfReferenceLocation.symbol`, that means that we are somewhere inside `lastSelfReferenceLocation` looking up a name, and resolving to `lastLocation` itself.
|
||||
// That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used.
|
||||
if (isUse && result && nameNotFoundMessage && noUnusedIdentifiers && (!lastSelfReferenceLocation || result !== lastSelfReferenceLocation.symbol)) {
|
||||
result.isReferenced = true;
|
||||
result.isReferenced |= meaning;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
|
@ -15697,7 +15697,7 @@ namespace ts {
|
|||
if (reactSym) {
|
||||
// Mark local symbol as referenced here because it might not have been marked
|
||||
// if jsx emit was not react as there wont be error being emitted
|
||||
reactSym.isReferenced = true;
|
||||
reactSym.isReferenced = SymbolFlags.All;
|
||||
|
||||
// If react symbol is alias, mark it as refereced
|
||||
if (reactSym.flags & SymbolFlags.Alias && !isConstEnumOrConstEnumOnlyModule(resolveAlias(reactSym))) {
|
||||
|
@ -16267,12 +16267,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
if (getCheckFlags(prop) & CheckFlags.Instantiated) {
|
||||
getSymbolLinks(prop).target.isReferenced = true;
|
||||
}
|
||||
else {
|
||||
prop.isReferenced = true;
|
||||
}
|
||||
(getCheckFlags(prop) & CheckFlags.Instantiated ? getSymbolLinks(prop).target : prop).isReferenced = SymbolFlags.All;
|
||||
}
|
||||
|
||||
function isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: __String): boolean {
|
||||
|
@ -21442,7 +21437,9 @@ namespace ts {
|
|||
function checkUnusedLocalsAndParameters(node: Node): void {
|
||||
if (noUnusedIdentifiers && !(node.flags & NodeFlags.Ambient)) {
|
||||
node.locals.forEach(local => {
|
||||
if (!local.isReferenced) {
|
||||
// If it's purely a type parameter, ignore, will be checked in `checkUnusedTypeParameters`.
|
||||
// If it's a type parameter merged with a parameter, check if the parameter-side is used.
|
||||
if (local.flags & SymbolFlags.TypeParameter ? (local.flags & SymbolFlags.Variable && !(local.isReferenced & SymbolFlags.Variable)) : !local.isReferenced) {
|
||||
if (local.valueDeclaration && getRootDeclaration(local.valueDeclaration).kind === SyntaxKind.Parameter) {
|
||||
const parameter = <ParameterDeclaration>getRootDeclaration(local.valueDeclaration);
|
||||
const name = getNameOfDeclaration(local.valueDeclaration);
|
||||
|
@ -21453,7 +21450,7 @@ namespace ts {
|
|||
error(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local));
|
||||
}
|
||||
}
|
||||
else if (local.flags & SymbolFlags.TypeParameter ? compilerOptions.noUnusedParameters : compilerOptions.noUnusedLocals) {
|
||||
else if (compilerOptions.noUnusedLocals) {
|
||||
forEach(local.declarations, d => errorUnusedLocal(d, symbolName(local)));
|
||||
}
|
||||
}
|
||||
|
@ -21538,7 +21535,7 @@ namespace ts {
|
|||
return;
|
||||
}
|
||||
for (const typeParameter of node.typeParameters) {
|
||||
if (!getMergedSymbol(typeParameter.symbol).isReferenced && !isIdentifierThatStartsWithUnderScore(typeParameter.name)) {
|
||||
if (!(getMergedSymbol(typeParameter.symbol).isReferenced & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderScore(typeParameter.name)) {
|
||||
error(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3307,7 +3307,7 @@ namespace ts {
|
|||
/* @internal */ parent?: Symbol; // Parent symbol
|
||||
/* @internal */ exportSymbol?: Symbol; // Exported symbol associated with this symbol
|
||||
/* @internal */ constEnumOnlyModule?: boolean; // True if module contains only const enums or other modules with only const enums
|
||||
/* @internal */ isReferenced?: boolean; // True if the symbol is referenced elsewhere
|
||||
/* @internal */ isReferenced?: SymbolFlags; // True if the symbol is referenced elsewhere. Keeps track of the meaning of a reference in case a symbol is both a type parameter and parameter.
|
||||
/* @internal */ isReplaceableByMethod?: boolean; // Can this Javascript class property be replaced by a method symbol?
|
||||
/* @internal */ isAssigned?: boolean; // True if the symbol is a parameter with assignments
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts(1,18): error TS6133: 'T' is declared but its value is never read.
|
||||
tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts(1,21): error TS6133: 'T' is declared but its value is never read.
|
||||
tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts(3,19): error TS6133: 'T' is declared but its value is never read.
|
||||
tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts(7,26): error TS6133: 'T' is declared but its value is never read.
|
||||
|
||||
|
||||
==== tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts (4 errors) ====
|
||||
function useNone<T>(T: number) {}
|
||||
~
|
||||
!!! error TS6133: 'T' is declared but its value is never read.
|
||||
~
|
||||
!!! error TS6133: 'T' is declared but its value is never read.
|
||||
|
||||
function useParam<T>(T: number) {
|
||||
~
|
||||
!!! error TS6133: 'T' is declared but its value is never read.
|
||||
return T;
|
||||
}
|
||||
|
||||
function useTypeParam<T>(T: T) {}
|
||||
~
|
||||
!!! error TS6133: 'T' is declared but its value is never read.
|
||||
|
||||
function useBoth<T>(T: T) {
|
||||
return T;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
//// [noUnusedLocals_typeParameterMergedWithParameter.ts]
|
||||
function useNone<T>(T: number) {}
|
||||
|
||||
function useParam<T>(T: number) {
|
||||
return T;
|
||||
}
|
||||
|
||||
function useTypeParam<T>(T: T) {}
|
||||
|
||||
function useBoth<T>(T: T) {
|
||||
return T;
|
||||
}
|
||||
|
||||
|
||||
//// [noUnusedLocals_typeParameterMergedWithParameter.js]
|
||||
function useNone(T) { }
|
||||
function useParam(T) {
|
||||
return T;
|
||||
}
|
||||
function useTypeParam(T) { }
|
||||
function useBoth(T) {
|
||||
return T;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
=== tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts ===
|
||||
function useNone<T>(T: number) {}
|
||||
>useNone : Symbol(useNone, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 20))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 20))
|
||||
|
||||
function useParam<T>(T: number) {
|
||||
>useParam : Symbol(useParam, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 33))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 18), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 21))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 18), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 21))
|
||||
|
||||
return T;
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 18), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 21))
|
||||
}
|
||||
|
||||
function useTypeParam<T>(T: T) {}
|
||||
>useTypeParam : Symbol(useTypeParam, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 4, 1))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 22), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 25))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 22), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 25))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 22), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 25))
|
||||
|
||||
function useBoth<T>(T: T) {
|
||||
>useBoth : Symbol(useBoth, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 33))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 20))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 20))
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 20))
|
||||
|
||||
return T;
|
||||
>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 20))
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
=== tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts ===
|
||||
function useNone<T>(T: number) {}
|
||||
>useNone : <T>(T: number) => void
|
||||
>T : T
|
||||
>T : number
|
||||
|
||||
function useParam<T>(T: number) {
|
||||
>useParam : <T>(T: number) => number
|
||||
>T : T
|
||||
>T : number
|
||||
|
||||
return T;
|
||||
>T : number
|
||||
}
|
||||
|
||||
function useTypeParam<T>(T: T) {}
|
||||
>useTypeParam : <T>(T: T) => void
|
||||
>T : T
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
function useBoth<T>(T: T) {
|
||||
>useBoth : <T>(T: T) => T
|
||||
>T : T
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
return T;
|
||||
>T : T
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// @noUnusedLocals: true
|
||||
// @noUnusedParameters: true
|
||||
|
||||
function useNone<T>(T: number) {}
|
||||
|
||||
function useParam<T>(T: number) {
|
||||
return T;
|
||||
}
|
||||
|
||||
function useTypeParam<T>(T: T) {}
|
||||
|
||||
function useBoth<T>(T: T) {
|
||||
return T;
|
||||
}
|
Loading…
Reference in a new issue