Add helper functions for adding an item to an array only if it's not already contained (#17833)
* Add helper functions for adding an item to an array only if it's not already contained * One more use of appendIfUnique
This commit is contained in:
parent
cd2ea9a12f
commit
2fede097f3
|
@ -1881,10 +1881,9 @@ namespace ts {
|
|||
// The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example,
|
||||
// module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error.
|
||||
function visit(symbol: Symbol): SymbolTable {
|
||||
if (!(symbol && symbol.flags & SymbolFlags.HasExports && !contains(visitedSymbols, symbol))) {
|
||||
if (!(symbol && symbol.flags & SymbolFlags.HasExports && pushIfUnique(visitedSymbols, symbol))) {
|
||||
return;
|
||||
}
|
||||
visitedSymbols.push(symbol);
|
||||
const symbols = cloneMap(symbol.exports);
|
||||
// All export * declarations are collected in an __export symbol by the binder
|
||||
const exportStars = symbol.exports.get(InternalSymbolName.ExportStar);
|
||||
|
@ -2060,10 +2059,10 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getAccessibleSymbolChainFromSymbolTableWorker(symbols: SymbolTable, visitedSymbolTables: SymbolTable[]): Symbol[] {
|
||||
if (contains<SymbolTable>(visitedSymbolTables, symbols)) {
|
||||
if (!pushIfUnique(visitedSymbolTables, symbols)) {
|
||||
return undefined;
|
||||
}
|
||||
visitedSymbolTables.push(symbols);
|
||||
|
||||
const result = trySymbolTable(symbols);
|
||||
visitedSymbolTables.pop();
|
||||
return result;
|
||||
|
@ -2276,14 +2275,7 @@ namespace ts {
|
|||
// since we will do the emitting later in trackSymbol.
|
||||
if (shouldComputeAliasToMakeVisible) {
|
||||
getNodeLinks(declaration).isVisible = true;
|
||||
if (aliasesToMakeVisible) {
|
||||
if (!contains(aliasesToMakeVisible, anyImportSyntax)) {
|
||||
aliasesToMakeVisible.push(anyImportSyntax);
|
||||
}
|
||||
}
|
||||
else {
|
||||
aliasesToMakeVisible = [anyImportSyntax];
|
||||
}
|
||||
aliasesToMakeVisible = appendIfUnique(aliasesToMakeVisible, anyImportSyntax);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -3981,9 +3973,7 @@ namespace ts {
|
|||
forEach(declarations, declaration => {
|
||||
getNodeLinks(declaration).isVisible = true;
|
||||
const resultNode = getAnyImportSyntax(declaration) || declaration;
|
||||
if (!contains(result, resultNode)) {
|
||||
result.push(resultNode);
|
||||
}
|
||||
pushIfUnique(result, resultNode);
|
||||
|
||||
if (isInternalModuleImportEqualsDeclaration(declaration)) {
|
||||
// Add the referenced top container visible
|
||||
|
@ -4793,12 +4783,7 @@ namespace ts {
|
|||
function appendTypeParameters(typeParameters: TypeParameter[], declarations: ReadonlyArray<TypeParameterDeclaration>): TypeParameter[] {
|
||||
for (const declaration of declarations) {
|
||||
const tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration));
|
||||
if (!typeParameters) {
|
||||
typeParameters = [tp];
|
||||
}
|
||||
else if (!contains(typeParameters, tp)) {
|
||||
typeParameters.push(tp);
|
||||
}
|
||||
typeParameters = appendIfUnique(typeParameters, tp);
|
||||
}
|
||||
return typeParameters;
|
||||
}
|
||||
|
@ -5521,9 +5506,7 @@ namespace ts {
|
|||
if (!match) {
|
||||
return undefined;
|
||||
}
|
||||
if (!contains(result, match)) {
|
||||
(result || (result = [])).push(match);
|
||||
}
|
||||
result = appendIfUnique(result, match);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -6073,12 +6056,7 @@ namespace ts {
|
|||
const modifiers = prop ? getDeclarationModifierFlagsFromSymbol(prop) : 0;
|
||||
if (prop && !(modifiers & excludeModifiers)) {
|
||||
commonFlags &= prop.flags;
|
||||
if (!props) {
|
||||
props = [prop];
|
||||
}
|
||||
else if (!contains(props, prop)) {
|
||||
props.push(prop);
|
||||
}
|
||||
props = appendIfUnique(props, prop);
|
||||
checkFlags |= (isReadonlySymbol(prop) ? CheckFlags.Readonly : 0) |
|
||||
(!(modifiers & ModifierFlags.NonPublicAccessibilityModifier) ? CheckFlags.ContainsPublic : 0) |
|
||||
(modifiers & ModifierFlags.Protected ? CheckFlags.ContainsProtected : 0) |
|
||||
|
@ -6237,12 +6215,7 @@ namespace ts {
|
|||
let result: TypeParameter[];
|
||||
forEach(getEffectiveTypeParameterDeclarations(declaration), node => {
|
||||
const tp = getDeclaredTypeOfTypeParameter(node.symbol);
|
||||
if (!contains(result, tp)) {
|
||||
if (!result) {
|
||||
result = [];
|
||||
}
|
||||
result.push(tp);
|
||||
}
|
||||
result = appendIfUnique(result, tp);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
@ -11715,9 +11688,7 @@ namespace ts {
|
|||
if (type === declaredType && declaredType === initialType) {
|
||||
return type;
|
||||
}
|
||||
if (!contains(antecedentTypes, type)) {
|
||||
antecedentTypes.push(type);
|
||||
}
|
||||
pushIfUnique(antecedentTypes, type);
|
||||
// If an antecedent type is not a subset of the declared type, we need to perform
|
||||
// subtype reduction. This happens when a "foreign" type is injected into the control
|
||||
// flow using the instanceof operator or a user defined type predicate.
|
||||
|
@ -11783,9 +11754,7 @@ namespace ts {
|
|||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
if (!contains(antecedentTypes, type)) {
|
||||
antecedentTypes.push(type);
|
||||
}
|
||||
pushIfUnique(antecedentTypes, type);
|
||||
// If an antecedent type is not a subset of the declared type, we need to perform
|
||||
// subtype reduction. This happens when a "foreign" type is injected into the control
|
||||
// flow using the instanceof operator or a user defined type predicate.
|
||||
|
@ -16826,9 +16795,7 @@ namespace ts {
|
|||
? Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member
|
||||
: Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
|
||||
}
|
||||
if (!contains(aggregatedTypes, type)) {
|
||||
aggregatedTypes.push(type);
|
||||
}
|
||||
pushIfUnique(aggregatedTypes, type);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -16880,9 +16847,7 @@ namespace ts {
|
|||
if (type.flags & TypeFlags.Never) {
|
||||
hasReturnOfTypeNever = true;
|
||||
}
|
||||
else if (!contains(aggregatedTypes, type)) {
|
||||
aggregatedTypes.push(type);
|
||||
}
|
||||
pushIfUnique(aggregatedTypes, type);
|
||||
}
|
||||
else {
|
||||
hasReturnWithNoExpression = true;
|
||||
|
@ -16893,9 +16858,7 @@ namespace ts {
|
|||
return undefined;
|
||||
}
|
||||
if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) {
|
||||
if (!contains(aggregatedTypes, undefinedType)) {
|
||||
aggregatedTypes.push(undefinedType);
|
||||
}
|
||||
pushIfUnique(aggregatedTypes, undefinedType);
|
||||
}
|
||||
return aggregatedTypes;
|
||||
}
|
||||
|
|
|
@ -771,6 +771,32 @@ namespace ts {
|
|||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the value was added.
|
||||
*/
|
||||
export function pushIfUnique<T>(array: T[], toAdd: T): boolean {
|
||||
if (contains(array, toAdd)) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
array.push(toAdd);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlike `pushIfUnique`, this can take `undefined` as an input, and returns a new array.
|
||||
*/
|
||||
export function appendIfUnique<T>(array: T[] | undefined, toAdd: T): T[] {
|
||||
if (array) {
|
||||
pushIfUnique(array, toAdd);
|
||||
return array;
|
||||
}
|
||||
else {
|
||||
return [toAdd];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stable sort of an array. Elements equal to each other maintain their relative position in the array.
|
||||
*/
|
||||
|
|
|
@ -2636,9 +2636,7 @@ namespace ts {
|
|||
if (some(helpers)) {
|
||||
const emitNode = getOrCreateEmitNode(node);
|
||||
for (const helper of helpers) {
|
||||
if (!contains(emitNode.helpers, helper)) {
|
||||
emitNode.helpers = append(emitNode.helpers, helper);
|
||||
}
|
||||
emitNode.helpers = appendIfUnique(emitNode.helpers, helper);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
|
@ -2680,9 +2678,7 @@ namespace ts {
|
|||
const helper = sourceEmitHelpers[i];
|
||||
if (predicate(helper)) {
|
||||
helpersRemoved++;
|
||||
if (!contains(targetEmitNode.helpers, helper)) {
|
||||
targetEmitNode.helpers = append(targetEmitNode.helpers, helper);
|
||||
}
|
||||
targetEmitNode.helpers = appendIfUnique(targetEmitNode.helpers, helper);
|
||||
}
|
||||
else if (helpersRemoved > 0) {
|
||||
sourceEmitHelpers[i - helpersRemoved] = helper;
|
||||
|
|
Loading…
Reference in a new issue