From 39ec0f922adab0df84c2ef336c24285d9aa00849 Mon Sep 17 00:00:00 2001 From: fm-117 <51322634+fm-117@users.noreply.github.com> Date: Tue, 26 Mar 2024 12:21:43 +0100 Subject: [PATCH] WI #2619 Optimize the StartPosition property (#2620) --- TypeCobol/Compiler/Nodes/Data.cs | 76 +++++++++++++++----------------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/TypeCobol/Compiler/Nodes/Data.cs b/TypeCobol/Compiler/Nodes/Data.cs index c2a31a7ef..13c980d24 100644 --- a/TypeCobol/Compiler/Nodes/Data.cs +++ b/TypeCobol/Compiler/Nodes/Data.cs @@ -528,61 +528,57 @@ public virtual long StartPosition { get { - if (_startPosition.HasValue) + if (!_startPosition.HasValue) { - return _startPosition.Value; + ComputeStartPosition(); } - if (this is DataRedefines node) + System.Diagnostics.Debug.Assert(_startPosition.HasValue); + return _startPosition.Value; + + void ComputeStartPosition() { - //Get the start position from the node it redefines. - var result = node.RedefinedVariable; - if (result != null) + if (this is DataRedefines node) { - _startPosition = result.StartPosition + SlackBytes; - return _startPosition.Value; + //Get the start position from the node it redefines. + var result = node.RedefinedVariable; + if (result != null) + { + _startPosition = result.StartPosition + SlackBytes; + return; + } + + // Redefined variable does not exist -> handle node as a DataDescription } - // Redefined variable does not exist -> handle node as a DataDescription - } + if (Parent is DataSection) + { + _startPosition = 1; + return; + } - if (Parent is DataSection) - { - _startPosition = 1; - } - else - { - //Searching for the first sibling with specified physical position, preceeding the current node. - for (int i = 0; i < Parent.Children.Count; i++) + //Searching for the first sibling with specified physical position, preceding the current node. + int siblingIndex = Parent.ChildIndex(this) - 1; + if (siblingIndex >= 0) { - Node sibling = Parent.Children[i]; + Node sibling = Parent.Children[siblingIndex]; - if (i == Parent.ChildIndex(this) - 1) + //Looks further up if the first position encountered is from a DataRedefines node with an existing redefined variable. + while (sibling is DataRedefines dataRedefines && dataRedefines.RedefinedVariable != null) { - int siblingIndex = i; - //Looks further up if the first position encountered is from a DataRedefines node with an existing redefined variable. - while (sibling is DataRedefines dataRedefines && dataRedefines.RedefinedVariable != null) - { - sibling = Parent.Children[siblingIndex - 1]; - - siblingIndex--; - - } - - DataDefinition siblingDefinition = (DataDefinition)sibling; - //Add 1 for the next free Byte in memory - _startPosition = Math.Max(siblingDefinition.GetBiggestRedefines()?.PhysicalPosition ?? 0, siblingDefinition.PhysicalPosition) + 1 + SlackBytes; - + sibling = Parent.Children[--siblingIndex]; } + DataDefinition siblingDefinition = (DataDefinition)sibling; + //Add 1 for the next free Byte in memory + _startPosition = Math.Max(siblingDefinition.GetBiggestRedefines()?.PhysicalPosition ?? 0, siblingDefinition.PhysicalPosition) + 1 + SlackBytes; + return; } - if (_startPosition == null) - { - _startPosition = (Parent as DataDefinition)?.StartPosition; - } - } - return _startPosition ?? 0; + // No previous data at same level, use position of parent + // Default to 0, but it means we could not compute the actual start position + _startPosition = (Parent as DataDefinition)?.StartPosition ?? 0; + } } }