/
githubmirror
/
PowerShell
Обзор
Документация
Войти
/
githubmirror
/
PowerShell
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/System.Management.Automation/FormatAndOutput/common/DisplayDatabase/displayDescriptionData_Complex.cs
512 строк
16 KB
Steve Lee
Fix `Get-FormatData` to not cast a type incorrectly (#21157)
26 авг 2024, 23:32
Не верифицирован
26 авг 2024, 23:32
59bce18
Код
Авторство
О чём код?
// 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 Complex View Definitions /// <summary> /// In line definition of a complex control. /// </summary> internal sealed class ComplexControlBody : ControlBody { /// <summary> /// Default list entry definition /// It's mandatory. /// </summary> internal ComplexControlEntryDefinition defaultEntry; /// <summary> /// Optional list of list entry definition overrides. It can be empty if there are no overrides. /// </summary> internal List<ComplexControlEntryDefinition> optionalEntryList = new List<ComplexControlEntryDefinition>(); } internal sealed class ComplexControlEntryDefinition { /// <summary> /// Applicability clause /// Only valid if not the default definition. /// </summary> internal AppliesTo appliesTo = null; /// <summary> /// Item associated with this entry definition. /// </summary> internal ComplexControlItemDefinition itemDefinition = new ComplexControlItemDefinition(); } internal sealed class ComplexControlItemDefinition { /// <summary> /// List of tokens the item can contain. /// </summary> internal List<FormatToken> formatTokenList = new List<FormatToken>(); } #endregion } namespace System.Management.Automation { /// <summary/> public sealed class CustomControl : PSControl { /// <summary/> public List<CustomControlEntry> Entries { get; set; } internal ComplexControlBody _cachedBody; internal CustomControl() { Entries = new List<CustomControlEntry>(); } internal CustomControl(ComplexControlBody body, ViewDefinition viewDefinition) { // viewDefinition can be null for nested controls if (viewDefinition != null) { OutOfBand = viewDefinition.outOfBand; GroupBy = PSControlGroupBy.Get(viewDefinition.groupBy); } Entries = new List<CustomControlEntry>(); // Default entry var cce = new CustomControlEntry(body.defaultEntry); Entries.Add(cce); foreach (var entry in body.optionalEntryList) { cce = new CustomControlEntry(entry); Entries.Add(cce); } } /// <summary/> public static CustomControlBuilder Create(bool outOfBand = false) { var customControl = new CustomControl { OutOfBand = outOfBand }; return new CustomControlBuilder(customControl); } internal override void WriteToXml(FormatXmlWriter writer) { writer.WriteCustomControl(this); } internal override bool SafeForExport() { if (!base.SafeForExport()) return false; foreach (var entry in Entries) { if (!entry.SafeForExport()) return false; } return true; } internal override bool CompatibleWithOldPowerShell() { // Old versions of PowerShell know nothing about CustomControl. return false; } } /// <summary/> public sealed class CustomControlEntry { internal CustomControlEntry() { CustomItems = new List<CustomItemBase>(); } internal CustomControlEntry(ComplexControlEntryDefinition entry) { if (entry.appliesTo != null) { SelectedBy = EntrySelectedBy.Get(entry.appliesTo.referenceList); } CustomItems = new List<CustomItemBase>(); foreach (var tok in entry.itemDefinition.formatTokenList) { CustomItems.Add(CustomItemBase.Create(tok)); } } /// <summary/> public EntrySelectedBy SelectedBy { get; set; } /// <summary/> public List<CustomItemBase> CustomItems { get; set; } internal bool SafeForExport() { foreach (var item in CustomItems) { if (!item.SafeForExport()) return false; } return SelectedBy == null || SelectedBy.SafeForExport(); } } /// <summary/> public abstract class CustomItemBase { internal virtual bool SafeForExport() { return true; } internal static CustomItemBase Create(FormatToken token) { if (token is NewLineToken) { return new CustomItemNewline(); } if (token is TextToken textToken) { return new CustomItemText { Text = textToken.text }; } if (token is FrameToken frameToken) { var frame = new CustomItemFrame { RightIndent = (uint)frameToken.frameInfoDefinition.rightIndentation, LeftIndent = (uint)frameToken.frameInfoDefinition.leftIndentation }; var firstLine = frameToken.frameInfoDefinition.firstLine; if (firstLine > 0) { frame.FirstLineIndent = (uint)firstLine; } else if (firstLine < 0) { frame.FirstLineHanging = (uint)-firstLine; } foreach (var frameItemToken in frameToken.itemDefinition.formatTokenList) { frame.CustomItems.Add(CustomItemBase.Create(frameItemToken)); } return frame; } if (token is CompoundPropertyToken cpt) { var cie = new CustomItemExpression { EnumerateCollection = cpt.enumerateCollection }; if (cpt.conditionToken != null) { cie.ItemSelectionCondition = new DisplayEntry(cpt.conditionToken); } if (cpt.expression.expressionValue != null) { cie.Expression = new DisplayEntry(cpt.expression); } if (cpt.control is ComplexControlBody complexControlBody) { cie.CustomControl = new CustomControl(complexControlBody, null); } return cie; } Diagnostics.Assert(false, "Unexpected formatting token kind"); return null; } } /// <summary/> public sealed class CustomItemExpression : CustomItemBase { internal CustomItemExpression() { } /// <summary/> public DisplayEntry ItemSelectionCondition { get; set; } /// <summary/> public DisplayEntry Expression { get; set; } /// <summary/> public bool EnumerateCollection { get; set; } /// <summary/> public CustomControl CustomControl { get; set; } internal override bool SafeForExport() { return (ItemSelectionCondition == null || ItemSelectionCondition.SafeForExport()) && (Expression == null || Expression.SafeForExport()) && (CustomControl == null || CustomControl.SafeForExport()); } } /// <summary/> public sealed class CustomItemFrame : CustomItemBase { /// <summary/> public uint LeftIndent { get; set; } /// <summary/> public uint RightIndent { get; set; } /// <summary/> public uint FirstLineHanging { get; set; } /// <summary/> public uint FirstLineIndent { get; set; } internal CustomItemFrame() { CustomItems = new List<CustomItemBase>(); } /// <summary/> public List<CustomItemBase> CustomItems { get; set; } internal override bool SafeForExport() { foreach (var frameItem in CustomItems) { if (!frameItem.SafeForExport()) return false; } return true; } } /// <summary/> public sealed class CustomItemNewline : CustomItemBase { /// <summary/> public CustomItemNewline() { this.Count = 1; } /// <summary/> public int Count { get; set; } } /// <summary/> public sealed class CustomItemText : CustomItemBase { /// <summary/> public string Text { get; set; } } /// <summary/> public sealed class CustomEntryBuilder { private readonly Stack<List<CustomItemBase>> _entryStack; private readonly CustomControlBuilder _controlBuilder; internal CustomEntryBuilder(CustomControlBuilder controlBuilder, CustomControlEntry entry) { _entryStack = new Stack<List<CustomItemBase>>(); _entryStack.Push(entry.CustomItems); _controlBuilder = controlBuilder; } /// <summary/> public CustomEntryBuilder AddNewline(int count = 1) { _entryStack.Peek().Add(new CustomItemNewline { Count = count }); return this; } /// <summary/> public CustomEntryBuilder AddText(string text) { _entryStack.Peek().Add(new CustomItemText { Text = text }); return this; } private void AddDisplayExpressionBinding( string value, DisplayEntryValueType valueType, bool enumerateCollection = false, string selectedByType = null, string selectedByScript = null, CustomControl customControl = null) { _entryStack.Peek().Add(new CustomItemExpression() { ItemSelectionCondition = selectedByScript != null ? new DisplayEntry(selectedByScript, DisplayEntryValueType.ScriptBlock) : selectedByType != null ? new DisplayEntry(selectedByType, DisplayEntryValueType.Property) : null, EnumerateCollection = enumerateCollection, Expression = new DisplayEntry(value, valueType), CustomControl = customControl }); } /// <summary/> public CustomEntryBuilder AddPropertyExpressionBinding( string property, bool enumerateCollection = false, string selectedByType = null, string selectedByScript = null, CustomControl customControl = null) { AddDisplayExpressionBinding(property, DisplayEntryValueType.Property, enumerateCollection, selectedByType, selectedByScript, customControl); return this; } /// <summary/> public CustomEntryBuilder AddScriptBlockExpressionBinding( string scriptBlock, bool enumerateCollection = false, string selectedByType = null, string selectedByScript = null, CustomControl customControl = null) { AddDisplayExpressionBinding(scriptBlock, DisplayEntryValueType.ScriptBlock, enumerateCollection, selectedByType, selectedByScript, customControl); return this; } /// <summary/> public CustomEntryBuilder AddCustomControlExpressionBinding( CustomControl customControl, bool enumerateCollection = false, string selectedByType = null, string selectedByScript = null) { _entryStack.Peek().Add(new CustomItemExpression() { ItemSelectionCondition = selectedByScript != null ? new DisplayEntry(selectedByScript, DisplayEntryValueType.ScriptBlock) : selectedByType != null ? new DisplayEntry(selectedByType, DisplayEntryValueType.Property) : null, EnumerateCollection = enumerateCollection, CustomControl = customControl }); return this; } /// <summary/> public CustomEntryBuilder StartFrame(uint leftIndent = 0, uint rightIndent = 0, uint firstLineHanging = 0, uint firstLineIndent = 0) { // Mutually exclusive if (leftIndent != 0 && rightIndent != 0) { throw PSTraceSource.NewArgumentException(nameof(leftIndent)); } // Mutually exclusive if (firstLineHanging != 0 && firstLineIndent != 0) { throw PSTraceSource.NewArgumentException(nameof(firstLineHanging)); } var frame = new CustomItemFrame { LeftIndent = leftIndent, RightIndent = rightIndent, FirstLineHanging = firstLineHanging, FirstLineIndent = firstLineIndent }; _entryStack.Peek().Add(frame); _entryStack.Push(frame.CustomItems); return this; } /// <summary/> public CustomEntryBuilder EndFrame() { if (_entryStack.Count < 2) { throw PSTraceSource.NewInvalidOperationException(); } _entryStack.Pop(); return this; } /// <summary/> public CustomControlBuilder EndEntry() { if (_entryStack.Count != 1) { throw PSTraceSource.NewInvalidOperationException(); } _entryStack.Pop(); return _controlBuilder; } } /// <summary/> public sealed class CustomControlBuilder { internal CustomControl _control; internal CustomControlBuilder(CustomControl control) { _control = control; } /// <summary>Group instances by the property name with an optional label.</summary> public CustomControlBuilder GroupByProperty(string property, CustomControl customControl = null, string label = null) { _control.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 CustomControlBuilder GroupByScriptBlock(string scriptBlock, CustomControl customControl = null, string label = null) { _control.GroupBy = new PSControlGroupBy { Expression = new DisplayEntry(scriptBlock, DisplayEntryValueType.ScriptBlock), CustomControl = customControl, Label = label }; return this; } /// <summary/> public CustomEntryBuilder StartEntry(IEnumerable<string> entrySelectedByType = null, IEnumerable<DisplayEntry> entrySelectedByCondition = null) { var entry = new CustomControlEntry { SelectedBy = EntrySelectedBy.Get(entrySelectedByType, entrySelectedByCondition) }; _control.Entries.Add(entry); return new CustomEntryBuilder(this, entry); } /// <summary/> public CustomControl EndControl() { return _control; } } }