Skip to content

Commit 235ff05

Browse files
authored
Centralize ExcludeProperty filter application in ViewGenerator base class (#26574)
1 parent 2a49561 commit 235ff05

5 files changed

Lines changed: 146 additions & 142 deletions

File tree

src/System.Management.Automation/FormatAndOutput/common/FormatViewGenerator.cs

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -348,19 +348,49 @@ protected class DataBaseInfo
348348

349349
protected DataBaseInfo dataBaseInfo = new DataBaseInfo();
350350

351-
protected List<MshResolvedExpressionParameterAssociation> activeAssociationList = null;
352351
/// <summary>
353-
/// Apply ExcludeProperty filter to activeAssociationList if specified.
354-
/// This method filters and updates "activeAssociationList" instance property.
352+
/// Builds the raw association list for the given object.
353+
/// Subclasses override this to provide cmdlet-specific property expansion logic.
355354
/// </summary>
356-
protected void ApplyExcludePropertyFilter()
355+
/// <param name="so">The object to build the association list for.</param>
356+
/// <param name="propertyList">The list of properties specified by the user, or null if not specified.</param>
357+
/// <returns>The raw association list, or null if not applicable.</returns>
358+
protected virtual List<MshResolvedExpressionParameterAssociation> BuildRawAssociationList(PSObject so, List<MshParameter> propertyList)
357359
{
358-
if (this.parameters is not null && this.parameters.excludePropertyFilter is not null)
360+
return null;
361+
}
362+
363+
/// <summary>
364+
/// Builds the active association list for the given object, with ExcludeProperty filter applied.
365+
/// </summary>
366+
/// <param name="so">The object to build the association list for.</param>
367+
/// <returns>The filtered association list.</returns>
368+
protected List<MshResolvedExpressionParameterAssociation> BuildActiveAssociationList(PSObject so)
369+
{
370+
var propertyList = parameters?.mshParameterList;
371+
var excludeFilter = parameters?.excludePropertyFilter;
372+
var rawList = BuildRawAssociationList(so, propertyList);
373+
return ApplyExcludeFilter(rawList, excludeFilter);
374+
}
375+
376+
/// <summary>
377+
/// Applies the ExcludeProperty filter to the given association list.
378+
/// </summary>
379+
/// <param name="associationList">The list to filter.</param>
380+
/// <param name="excludeFilter">The exclude filter to apply.</param>
381+
/// <returns>The filtered list, or the original list if no filter is specified.</returns>
382+
internal static List<MshResolvedExpressionParameterAssociation> ApplyExcludeFilter(
383+
List<MshResolvedExpressionParameterAssociation> associationList,
384+
PSPropertyExpressionFilter excludeFilter)
385+
{
386+
if (associationList is null || excludeFilter is null)
359387
{
360-
this.activeAssociationList = this.activeAssociationList
361-
.Where(item => !this.parameters.excludePropertyFilter.IsMatch(item.ResolvedExpression))
362-
.ToList();
388+
return associationList;
363389
}
390+
391+
return associationList
392+
.Where(item => !excludeFilter.IsMatch(item.ResolvedExpression))
393+
.ToList();
364394
}
365395

366396
protected string GetExpressionDisplayValue(PSObject so, int enumerationLimit, PSPropertyExpression ex,

src/System.Management.Automation/FormatAndOutput/common/FormatViewGenerator_Complex.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
using System.Collections;
55
using System.Collections.Generic;
6-
using System.Linq;
76
using System.Collections.ObjectModel;
87
using System.Management.Automation;
98
using System.Management.Automation.Internal;
@@ -514,13 +513,8 @@ private void DisplayObject(PSObject so, TraversalInfo currentLevel, List<MshPara
514513
List<MshResolvedExpressionParameterAssociation> activeAssociationList =
515514
AssociationManager.SetupActiveProperties(parameterList, so, _expressionFactory);
516515

517-
// Apply ExcludeProperty filter if specified
518-
if (_parameters != null && _parameters.excludePropertyFilter != null)
519-
{
520-
activeAssociationList = activeAssociationList
521-
.Where(item => !_parameters.excludePropertyFilter.IsMatch(item.ResolvedExpression))
522-
.ToList();
523-
}
516+
// Apply ExcludeProperty filter using the centralized method
517+
activeAssociationList = ViewGenerator.ApplyExcludeFilter(activeAssociationList, _parameters?.excludePropertyFilter);
524518

525519
// create a format entry
526520
FormatEntry fe = new FormatEntry();

src/System.Management.Automation/FormatAndOutput/common/FormatViewGenerator_List.cs

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,14 @@ internal override void Initialize(TerminatingErrorContext errorContext, PSProper
3030
{
3131
_listBody = (ListControlBody)this.dataBaseInfo.view.mainControl;
3232
}
33+
}
3334

34-
this.parameters = parameters;
35-
SetUpActiveProperties(so);
35+
/// <summary>
36+
/// Builds the raw association list for list formatting.
37+
/// </summary>
38+
protected override List<MshResolvedExpressionParameterAssociation> BuildRawAssociationList(PSObject so, List<MshParameter> propertyList)
39+
{
40+
return AssociationManager.SetupActiveProperties(propertyList, so, this.expressionFactory);
3641
}
3742

3843
/// <summary>
@@ -178,17 +183,14 @@ private ListControlEntryDefinition GetActiveListControlEntryDefinition(ListContr
178183

179184
private ListViewEntry GenerateListViewEntryFromProperties(PSObject so, int enumerationLimit)
180185
{
181-
// compute active properties every time
182-
if (this.activeAssociationList == null)
183-
{
184-
SetUpActiveProperties(so);
185-
}
186+
// Build active association list (with ExcludeProperty filter applied)
187+
var associationList = BuildActiveAssociationList(so);
186188

187189
ListViewEntry lve = new ListViewEntry();
188190

189-
for (int k = 0; k < this.activeAssociationList.Count; k++)
191+
for (int k = 0; k < associationList.Count; k++)
190192
{
191-
MshResolvedExpressionParameterAssociation a = this.activeAssociationList[k];
193+
MshResolvedExpressionParameterAssociation a = associationList[k];
192194
ListViewField lvf = new ListViewField();
193195

194196
if (a.OriginatingParameter != null)
@@ -218,21 +220,7 @@ private ListViewEntry GenerateListViewEntryFromProperties(PSObject so, int enume
218220
lvf.formatPropertyField.propertyValue = this.GetExpressionDisplayValue(so, enumerationLimit, a.ResolvedExpression, directive);
219221
lve.listViewFieldList.Add(lvf);
220222
}
221-
222-
this.activeAssociationList = null;
223223
return lve;
224224
}
225-
226-
private void SetUpActiveProperties(PSObject so)
227-
{
228-
List<MshParameter> mshParameterList = null;
229-
230-
if (this.parameters != null)
231-
mshParameterList = this.parameters.mshParameterList;
232-
233-
this.activeAssociationList = AssociationManager.SetupActiveProperties(mshParameterList, so, this.expressionFactory);
234-
235-
ApplyExcludePropertyFilter();
236-
}
237225
}
238226
}

src/System.Management.Automation/FormatAndOutput/common/FormatViewGenerator_Table.cs

Lines changed: 57 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ internal sealed class TableViewGenerator : ViewGenerator
1414
// tableBody to use for this instance of the ViewGenerator;
1515
private TableControlBody _tableBody;
1616

17+
private List<MshResolvedExpressionParameterAssociation> _activeAssociationList;
18+
1719
internal override void Initialize(TerminatingErrorContext terminatingErrorContext, PSPropertyExpressionFactory mshExpressionFactory, TypeInfoDataBase db, ViewDefinition view, FormattingCommandLineParameters formatParameters)
1820
{
1921
base.Initialize(terminatingErrorContext, mshExpressionFactory, db, view, formatParameters);
@@ -34,51 +36,48 @@ internal override void Initialize(TerminatingErrorContext errorContext, PSProper
3436
_tableBody = (TableControlBody)this.dataBaseInfo.view.mainControl;
3537
}
3638

37-
List<MshParameter> rawMshParameterList = null;
38-
39-
if (parameters != null)
40-
rawMshParameterList = parameters.mshParameterList;
39+
// Build the active association list (with ExcludeProperty filter applied)
40+
_activeAssociationList = BuildActiveAssociationList(so);
41+
}
4142

43+
/// <summary>
44+
/// Builds the raw association list for table formatting.
45+
/// </summary>
46+
protected override List<MshResolvedExpressionParameterAssociation> BuildRawAssociationList(PSObject so, List<MshParameter> propertyList)
47+
{
4248
// check if we received properties from the command line
43-
if (rawMshParameterList is not null && rawMshParameterList.Count > 0)
49+
if (propertyList is not null && propertyList.Count > 0)
4450
{
45-
this.activeAssociationList = AssociationManager.ExpandTableParameters(rawMshParameterList, so);
51+
return AssociationManager.ExpandTableParameters(propertyList, so);
4652
}
47-
else
53+
54+
// we did not get any properties:
55+
// try to get properties from the default property set of the object
56+
var list = AssociationManager.ExpandDefaultPropertySet(so, this.expressionFactory);
57+
if (list.Count > 0)
4858
{
49-
// we did not get any properties:
50-
// try to get properties from the default property set of the object
51-
this.activeAssociationList = AssociationManager.ExpandDefaultPropertySet(so, this.expressionFactory);
52-
if (this.activeAssociationList.Count > 0)
53-
{
54-
// we got a valid set of properties from the default property set..add computername for
55-
// remoteobjects (if available)
56-
if (PSObjectHelper.ShouldShowComputerNameProperty(so))
57-
{
58-
activeAssociationList.Add(new MshResolvedExpressionParameterAssociation(null,
59-
new PSPropertyExpression(RemotingConstants.ComputerNameNoteProperty)));
60-
}
61-
}
62-
else
59+
// we got a valid set of properties from the default property set..add computername for
60+
// remoteobjects (if available)
61+
if (PSObjectHelper.ShouldShowComputerNameProperty(so))
6362
{
64-
// we failed to get anything from the default property set
65-
this.activeAssociationList = AssociationManager.ExpandAll(so);
66-
if (this.activeAssociationList.Count > 0)
67-
{
68-
// Remove PSComputerName and PSShowComputerName from the display as needed.
69-
AssociationManager.HandleComputerNameProperties(so, activeAssociationList);
70-
FilterActiveAssociationList();
71-
}
72-
else
73-
{
74-
// we were unable to retrieve any properties, so we leave an empty list
75-
this.activeAssociationList = new List<MshResolvedExpressionParameterAssociation>();
76-
return;
77-
}
63+
list.Add(new MshResolvedExpressionParameterAssociation(null,
64+
new PSPropertyExpression(RemotingConstants.ComputerNameNoteProperty)));
7865
}
66+
67+
return list;
7968
}
8069

81-
ApplyExcludePropertyFilter();
70+
// we failed to get anything from the default property set
71+
list = AssociationManager.ExpandAll(so);
72+
if (list.Count > 0)
73+
{
74+
// Remove PSComputerName and PSShowComputerName from the display as needed.
75+
AssociationManager.HandleComputerNameProperties(so, list);
76+
return LimitAssociationListSize(list);
77+
}
78+
79+
// we were unable to retrieve any properties, so we leave an empty list
80+
return new List<MshResolvedExpressionParameterAssociation>();
8281
}
8382

8483
/// <summary>
@@ -129,30 +128,29 @@ internal override FormatStartData GenerateStartData(PSObject so)
129128
}
130129

131130
/// <summary>
132-
/// Method to filter resolved expressions as per table view needs.
131+
/// Limits the association list size for table view.
133132
/// For v1.0, table view supports only 10 properties.
134-
///
135-
/// This method filters and updates "activeAssociationList" instance property.
136133
/// </summary>
137-
/// <returns>None.</returns>
138-
/// <remarks>This method updates "activeAssociationList" instance property.</remarks>
139-
private void FilterActiveAssociationList()
134+
/// <param name="list">The list to limit.</param>
135+
/// <returns>The limited list.</returns>
136+
private static List<MshResolvedExpressionParameterAssociation> LimitAssociationListSize(
137+
List<MshResolvedExpressionParameterAssociation> list)
140138
{
141-
// we got a valid set of properties from the default property set
142-
// make sure we do not have too many properties
143-
144139
// NOTE: this is an arbitrary number, chosen to be a sensitive default
145-
const int nMax = 10;
140+
const int maxCount = 10;
141+
142+
if (list.Count <= maxCount)
143+
{
144+
return list;
145+
}
146146

147-
if (activeAssociationList.Count > nMax)
147+
var result = new List<MshResolvedExpressionParameterAssociation>(maxCount);
148+
for (int k = 0; k < maxCount; k++)
148149
{
149-
List<MshResolvedExpressionParameterAssociation> tmp = this.activeAssociationList;
150-
this.activeAssociationList = new List<MshResolvedExpressionParameterAssociation>();
151-
for (int k = 0; k < nMax; k++)
152-
this.activeAssociationList.Add(tmp[k]);
150+
result.Add(list[k]);
153151
}
154152

155-
return;
153+
return result;
156154
}
157155

158156
private TableHeaderInfo GenerateTableHeaderInfoFromDataBaseInfo(PSObject so)
@@ -228,9 +226,9 @@ private TableHeaderInfo GenerateTableHeaderInfoFromProperties(PSObject so)
228226
thi.hideHeader = this.HideHeaders;
229227
thi.repeatHeader = this.RepeatHeader;
230228

231-
for (int k = 0; k < this.activeAssociationList.Count; k++)
229+
for (int k = 0; k < _activeAssociationList.Count; k++)
232230
{
233-
MshResolvedExpressionParameterAssociation a = this.activeAssociationList[k];
231+
MshResolvedExpressionParameterAssociation a = _activeAssociationList[k];
234232
TableColumnInfo ci = new TableColumnInfo();
235233

236234
// set the label of the column
@@ -241,7 +239,7 @@ private TableHeaderInfo GenerateTableHeaderInfoFromProperties(PSObject so)
241239
ci.propertyName = (string)key;
242240
}
243241

244-
ci.propertyName ??= this.activeAssociationList[k].ResolvedExpression.ToString();
242+
ci.propertyName ??= _activeAssociationList[k].ResolvedExpression.ToString();
245243

246244
// set the width of the table
247245
if (a.OriginatingParameter != null)
@@ -473,13 +471,13 @@ private TableRowEntry GenerateTableRowEntryFromDataBaseInfo(PSObject so, int enu
473471
private TableRowEntry GenerateTableRowEntryFromFromProperties(PSObject so, int enumerationLimit)
474472
{
475473
TableRowEntry tre = new TableRowEntry();
476-
for (int k = 0; k < this.activeAssociationList.Count; k++)
474+
for (int k = 0; k < _activeAssociationList.Count; k++)
477475
{
478476
FormatPropertyField fpf = new FormatPropertyField();
479477
FieldFormattingDirective directive = null;
480-
if (activeAssociationList[k].OriginatingParameter != null)
478+
if (_activeAssociationList[k].OriginatingParameter != null)
481479
{
482-
directive = activeAssociationList[k].OriginatingParameter.GetEntry(FormatParameterDefinitionKeys.FormatStringEntryKey) as FieldFormattingDirective;
480+
directive = _activeAssociationList[k].OriginatingParameter.GetEntry(FormatParameterDefinitionKeys.FormatStringEntryKey) as FieldFormattingDirective;
483481
}
484482

485483
if (directive is null)
@@ -488,7 +486,7 @@ private TableRowEntry GenerateTableRowEntryFromFromProperties(PSObject so, int e
488486
directive.isTable = true;
489487
}
490488

491-
fpf.propertyValue = this.GetExpressionDisplayValue(so, enumerationLimit, this.activeAssociationList[k].ResolvedExpression, directive);
489+
fpf.propertyValue = this.GetExpressionDisplayValue(so, enumerationLimit, _activeAssociationList[k].ResolvedExpression, directive);
492490
tre.formatPropertyFieldList.Add(fpf);
493491
}
494492

0 commit comments

Comments
 (0)