/
githubmirror
/
PowerShell
Обзор
Документация
Войти
/
githubmirror
/
PowerShell
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/System.Management.Automation/FormatAndOutput/common/DisplayDatabase/displayDescriptionData_Table.cs
614 строк
20 KB
Dmitry Volodin
Apply the `InlineAsTypeCheck` in the engine code - 2nd pass (#19694)
11 июл 2023, 03:17
Не верифицирован
11 июл 2023, 03:17
a26b09d
Код
Авторство
О чём код?
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. // this file contains the data structures for the in memory database // containing display and formatting information using System.Collections.Generic; using Microsoft.PowerShell.Commands; using Microsoft.PowerShell.Commands.Internal.Format; namespace Microsoft.PowerShell.Commands.Internal.Format { #region Table View Definitions /// <summary> /// Alignment values /// NOTE: we do not use an enum because this will have to be /// serialized and ERS/serialization do not support enumerations. /// </summary> internal static class TextAlignment { internal const int Undefined = 0; internal const int Left = 1; internal const int Center = 2; internal const int Right = 3; } /// <summary> /// Definition of a table control. /// </summary> internal sealed class TableControlBody : ControlBody { /// <summary> /// Optional, if not present, use data off the default table row definition. /// </summary> internal TableHeaderDefinition header = new TableHeaderDefinition(); /// <summary> /// Default row definition /// It's mandatory. /// </summary> internal TableRowDefinition defaultDefinition; /// <summary> /// Optional list of row definition overrides. It can be empty if there are no overrides. /// </summary> internal List<TableRowDefinition> optionalDefinitionList = new List<TableRowDefinition>(); internal override ControlBase Copy() { TableControlBody result = new TableControlBody { autosize = this.autosize, header = this.header.Copy() }; if (defaultDefinition != null) { result.defaultDefinition = this.defaultDefinition.Copy(); } foreach (TableRowDefinition trd in this.optionalDefinitionList) { result.optionalDefinitionList.Add(trd); } return result; } } /// <summary> /// Information about the table header /// NOTE: if an instance of this class is present, the list must not be empty. /// </summary> internal sealed class TableHeaderDefinition { /// <summary> /// If true, direct the outputter to suppress table header printing. /// </summary> internal bool hideHeader; /// <summary> /// Mandatory list of column header definitions. /// </summary> internal List<TableColumnHeaderDefinition> columnHeaderDefinitionList = new List<TableColumnHeaderDefinition>(); /// <summary> /// Returns a Shallow Copy of the current object. /// </summary> /// <returns></returns> internal TableHeaderDefinition Copy() { TableHeaderDefinition result = new TableHeaderDefinition { hideHeader = this.hideHeader }; foreach (TableColumnHeaderDefinition tchd in this.columnHeaderDefinitionList) { result.columnHeaderDefinitionList.Add(tchd); } return result; } } internal sealed class TableColumnHeaderDefinition { /// <summary> /// Optional label /// If not present, use the name of the property from the matching /// mandatory row description. /// </summary> internal TextToken label = null; /// <summary> /// General alignment for the column /// If not present, either use the one from the row definition /// or the data driven heuristics. /// </summary> internal int alignment = TextAlignment.Undefined; /// <summary> /// Width of the column. /// </summary> internal int width = 0; // undefined } /// <summary> /// Definition of the data to be displayed in a table row. /// </summary> internal sealed class TableRowDefinition { /// <summary> /// Applicability clause /// Only valid if not the default definition. /// </summary> internal AppliesTo appliesTo; /// <summary> /// If true, the current table row should be allowed /// to wrap to multiple lines, else truncated. /// </summary> internal bool multiLine; /// <summary> /// Mandatory list of column items. /// It cannot be empty. /// </summary> internal List<TableRowItemDefinition> rowItemDefinitionList = new List<TableRowItemDefinition>(); /// <summary> /// Returns a Shallow Copy of the current object. /// </summary> /// <returns></returns> internal TableRowDefinition Copy() { TableRowDefinition result = new TableRowDefinition { appliesTo = this.appliesTo, multiLine = this.multiLine }; foreach (TableRowItemDefinition trid in this.rowItemDefinitionList) { result.rowItemDefinitionList.Add(trid); } return result; } } /// <summary> /// Cell definition inside a row. /// </summary> internal sealed class TableRowItemDefinition { /// <summary> /// Optional alignment to override the default one at the header level. /// </summary> internal int alignment = TextAlignment.Undefined; /// <summary> /// Format directive body telling how to format the cell /// RULE: the body can only contain /// * TextToken /// * PropertyToken /// * NOTHING (provide an empty cell) /// </summary> internal List<FormatToken> formatTokenList = new List<FormatToken>(); } #endregion } namespace System.Management.Automation { /// <summary> /// Defines a table control. /// </summary> public sealed class TableControl : PSControl { /// <summary>Collection of column header definitions for this table control</summary> public List<TableControlColumnHeader> Headers { get; set; } /// <summary>Collection of row definitions for this table control</summary> public List<TableControlRow> Rows { get; set; } /// <summary>When true, column widths are calculated based on more than the first object.</summary> public bool AutoSize { get; set; } /// <summary>When true, table headers are not displayed</summary> public bool HideTableHeaders { get; set; } /// <summary>Create a default TableControl</summary> public static TableControlBuilder Create(bool outOfBand = false, bool autoSize = false, bool hideTableHeaders = false) { var table = new TableControl { OutOfBand = outOfBand, AutoSize = autoSize, HideTableHeaders = hideTableHeaders }; return new TableControlBuilder(table); } /// <summary>Public default constructor for TableControl</summary> public TableControl() { Headers = new List<TableControlColumnHeader>(); Rows = new List<TableControlRow>(); } internal override void WriteToXml(FormatXmlWriter writer) { writer.WriteTableControl(this); } /// <summary> /// Determines if this object is safe to be written. /// </summary> /// <returns>True if safe, false otherwise.</returns> internal override bool SafeForExport() { if (!base.SafeForExport()) return false; foreach (var row in Rows) { if (!row.SafeForExport()) return false; } return true; } internal override bool CompatibleWithOldPowerShell() { if (!base.CompatibleWithOldPowerShell()) return false; foreach (var row in Rows) { if (!row.CompatibleWithOldPowerShell()) return false; } return true; } internal TableControl(TableControlBody tcb, ViewDefinition viewDefinition) : this() { this.OutOfBand = viewDefinition.outOfBand; this.GroupBy = PSControlGroupBy.Get(viewDefinition.groupBy); this.AutoSize = tcb.autosize.GetValueOrDefault(); this.HideTableHeaders = tcb.header.hideHeader; TableControlRow row = new TableControlRow(tcb.defaultDefinition); Rows.Add(row); foreach (TableRowDefinition rd in tcb.optionalDefinitionList) { row = new TableControlRow(rd); Rows.Add(row); } foreach (TableColumnHeaderDefinition hd in tcb.header.columnHeaderDefinitionList) { TableControlColumnHeader header = new TableControlColumnHeader(hd); Headers.Add(header); } } /// <summary> /// Public constructor for TableControl that only takes 'tableControlRows'. /// </summary> /// <param name="tableControlRow"></param> public TableControl(TableControlRow tableControlRow) : this() { if (tableControlRow == null) throw PSTraceSource.NewArgumentNullException("tableControlRows"); this.Rows.Add(tableControlRow); } /// <summary> /// Public constructor for TableControl that takes both 'tableControlRows' and 'tableControlColumnHeaders'. /// </summary> /// <param name="tableControlRow"></param> /// <param name="tableControlColumnHeaders"></param> public TableControl(TableControlRow tableControlRow, IEnumerable<TableControlColumnHeader> tableControlColumnHeaders) : this() { if (tableControlRow == null) throw PSTraceSource.NewArgumentNullException("tableControlRows"); if (tableControlColumnHeaders == null) throw PSTraceSource.NewArgumentNullException(nameof(tableControlColumnHeaders)); this.Rows.Add(tableControlRow); foreach (TableControlColumnHeader header in tableControlColumnHeaders) { this.Headers.Add(header); } } } /// <summary> /// Defines the header for a particular column in a table control. /// </summary> public sealed class TableControlColumnHeader { /// <summary>Label for the column</summary> public string Label { get; set; } /// <summary>Alignment of the string within the column</summary> public Alignment Alignment { get; set; } /// <summary>Width of the column - in number of display cells</summary> public int Width { get; set; } internal TableControlColumnHeader(TableColumnHeaderDefinition colheaderdefinition) { if (colheaderdefinition.label != null) { Label = colheaderdefinition.label.text; } Alignment = (Alignment)colheaderdefinition.alignment; Width = colheaderdefinition.width; } /// <summary>Default constructor</summary> public TableControlColumnHeader() { } /// <summary> /// Public constructor for TableControlColumnHeader. /// </summary> /// <param name="label">Could be null if no label to specify.</param> /// <param name="width">The Value should be non-negative.</param> /// <param name="alignment">The default value is Alignment.Undefined.</param> public TableControlColumnHeader(string label, int width, Alignment alignment) { if (width < 0) throw PSTraceSource.NewArgumentOutOfRangeException(nameof(width), width); this.Label = label; this.Width = width; this.Alignment = alignment; } } /// <summary> /// Defines a particular column within a row /// in a table control. /// </summary> public sealed class TableControlColumn { /// <summary>Alignment of the particular column</summary> public Alignment Alignment { get; set; } /// <summary>Display Entry</summary> public DisplayEntry DisplayEntry { get; set; } /// <summary>Format string to apply</summary> public string FormatString { get; internal set; } /// <summary> /// Returns the value of the entry. /// </summary> /// <returns></returns> public override string ToString() { return DisplayEntry.Value; } /// <summary>Default constructor</summary> public TableControlColumn() { } internal TableControlColumn(string text, int alignment, bool isscriptblock, string formatString) { Alignment = (Alignment)alignment; DisplayEntry = new DisplayEntry(text, isscriptblock ? DisplayEntryValueType.ScriptBlock : DisplayEntryValueType.Property); FormatString = formatString; } /// <summary> /// Public constructor for TableControlColumn. /// </summary> /// <param name="alignment"></param> /// <param name="entry"></param> public TableControlColumn(Alignment alignment, DisplayEntry entry) { this.Alignment = alignment; this.DisplayEntry = entry; } internal bool SafeForExport() { return DisplayEntry.SafeForExport(); } } /// <summary> /// Defines a single row in a table control. /// </summary> public sealed class TableControlRow { /// <summary>Collection of column definitions for this row</summary> public List<TableControlColumn> Columns { get; set; } /// <summary>List of typenames which select this entry</summary> public EntrySelectedBy SelectedBy { get; internal set; } /// <summary>When true, instead of truncating to the column width, use multiple lines.</summary> public bool Wrap { get; set; } /// <summary>Public constructor for TableControlRow</summary> public TableControlRow() { Columns = new List<TableControlColumn>(); } internal TableControlRow(TableRowDefinition rowdefinition) : this() { Wrap = rowdefinition.multiLine; if (rowdefinition.appliesTo != null) { SelectedBy = EntrySelectedBy.Get(rowdefinition.appliesTo.referenceList); } foreach (TableRowItemDefinition itemdef in rowdefinition.rowItemDefinitionList) { TableControlColumn column; if (itemdef.formatTokenList[0] is FieldPropertyToken fpt) { column = new TableControlColumn(fpt.expression.expressionValue, itemdef.alignment, fpt.expression.isScriptBlock, fpt.fieldFormattingDirective.formatString); } else { column = new TableControlColumn(); } Columns.Add(column); } } /// <summary>Public constructor for TableControlRow.</summary> public TableControlRow(IEnumerable<TableControlColumn> columns) : this() { if (columns == null) throw PSTraceSource.NewArgumentNullException(nameof(columns)); foreach (TableControlColumn column in columns) { Columns.Add(column); } } internal bool SafeForExport() { foreach (var column in Columns) { if (!column.SafeForExport()) return false; } return SelectedBy != null && SelectedBy.SafeForExport(); } internal bool CompatibleWithOldPowerShell() { // Old versions of PowerShell don't support multiple row definitions. return SelectedBy == null; } } /// <summary>A helper class for defining table controls</summary> public sealed class TableRowDefinitionBuilder { internal readonly TableControlBuilder _tcb; internal readonly TableControlRow _tcr; internal TableRowDefinitionBuilder(TableControlBuilder tcb, TableControlRow tcr) { _tcb = tcb; _tcr = tcr; } private TableRowDefinitionBuilder AddItem(string value, DisplayEntryValueType entryType, Alignment alignment, string format) { if (string.IsNullOrEmpty(value)) throw PSTraceSource.NewArgumentException(nameof(value)); var tableControlColumn = new TableControlColumn(alignment, new DisplayEntry(value, entryType)) { FormatString = format }; _tcr.Columns.Add(tableControlColumn); return this; } /// <summary> /// Add a column to the current row definition that calls a script block. /// </summary> public TableRowDefinitionBuilder AddScriptBlockColumn(string scriptBlock, Alignment alignment = Alignment.Undefined, string format = null) { return AddItem(scriptBlock, DisplayEntryValueType.ScriptBlock, alignment, format); } /// <summary> /// Add a column to the current row definition that references a property. /// </summary> public TableRowDefinitionBuilder AddPropertyColumn(string propertyName, Alignment alignment = Alignment.Undefined, string format = null) { return AddItem(propertyName, DisplayEntryValueType.Property, alignment, format); } /// <summary> /// Complete a row definition. /// </summary> public TableControlBuilder EndRowDefinition() { return _tcb; } } /// <summary>A helper class for defining table controls</summary> public sealed class TableControlBuilder { internal readonly TableControl _table; internal TableControlBuilder(TableControl table) { _table = table; } /// <summary>Group instances by the property name with an optional label.</summary> public TableControlBuilder GroupByProperty(string property, CustomControl customControl = null, string label = null) { _table.GroupBy = new PSControlGroupBy { Expression = new DisplayEntry(property, DisplayEntryValueType.Property), CustomControl = customControl, Label = label }; return this; } /// <summary>Group instances by the script block expression with an optional label.</summary> public TableControlBuilder GroupByScriptBlock(string scriptBlock, CustomControl customControl = null, string label = null) { _table.GroupBy = new PSControlGroupBy { Expression = new DisplayEntry(scriptBlock, DisplayEntryValueType.ScriptBlock), CustomControl = customControl, Label = label }; return this; } /// <summary>Add a header</summary> public TableControlBuilder AddHeader(Alignment alignment = Alignment.Undefined, int width = 0, string label = null) { _table.Headers.Add(new TableControlColumnHeader(label, width, alignment)); return this; } /// <summary>Add a header</summary> public TableRowDefinitionBuilder StartRowDefinition(bool wrap = false, IEnumerable<string> entrySelectedByType = null, IEnumerable<DisplayEntry> entrySelectedByCondition = null) { var row = new TableControlRow { Wrap = wrap }; if (entrySelectedByType != null || entrySelectedByCondition != null) { row.SelectedBy = new EntrySelectedBy(); if (entrySelectedByType != null) { row.SelectedBy.TypeNames = new List<string>(entrySelectedByType); } if (entrySelectedByCondition != null) { row.SelectedBy.SelectionCondition = new List<DisplayEntry>(entrySelectedByCondition); } } _table.Rows.Add(row); return new TableRowDefinitionBuilder(this, row); } /// <summary>Complete a table definition</summary> public TableControl EndTable() { return _table; } } }