Beef icon indicating copy to clipboard operation
Beef copied to clipboard

[Bug] Various formatting issues

Open marsej opened this issue 4 years ago • 8 comments

See diff screenshot: SourceEditWidgetContent.bf 0.43.0 138 KB initially, after FoS it's 120 KB. In addition to this it also remove "delete:myAllocator" the :myAllocator part was gone after Format on Save.

beef Format on Save bug EDIT: haxFIX (assuming beef source code is in beefsrc folder, this stops those files getting from formatted and thus preserves delete/destructor related code. If folder name contains Tests then allow reformat.)

0.43.0 SourceViewPanel.bf l 4480

        public void ReformatDocument(bool ignoreSelection = false)
        {
			if (mFilePath != null && !mFilePath.Contains("Tests") && mFilePath.Contains("beefsrc") )
				return;

marsej avatar Apr 09 '21 14:04 marsej

Minimal repro of the other case:

using System;
using System.Collections;
namespace Issue6
{
	class Program
	{
		BumpAllocator mBumpAllocator = CreateAllocator() ~ delete _;

		List<int32> mNextKeys ~ delete:mBumpAllocator _;

//		protected virtual BumpAllocator CreateAllocator()
//		{
//			var bumpAlloc = new BumpAllocator();
//			bumpAlloc.DestructorHandling = .Ignore;
//			return bumpAlloc;
//		}

//		public static void Main()
//		{
//		}
	}
}

The // lines aren't needed for repro, the ":mBumpAllocator"; is gone when Format on Save triggers.

EDIT: I tried tracing the calls in bfPrinter.cpp but it's like 1140 lines of output and the differing lines between no deletion and deletion don't say much - both call DeleteStatement once.

marsej avatar Apr 11 '21 17:04 marsej

EDIT: The change below seems to work but only by stopping edits when the problematic spot is encountered,.. (* or this)

                else if (oldIdx == -1)

... ie.when above line gets hit.

haxFIX:

        public void ReformatInto(SourceEditWidget editWidget, int formatStart, int formatEnd, uint8 orFlags = 0)
        {
            var editWidgetContent = (SourceEditWidgetContent)editWidget.Content;

			let oldText = scope String();
			editWidget.GetText(oldText);
			/*File.WriteAllText(@"c:\temp\orig.txt", origText);*/

            int32[] char8Mapping;
            String newText = scope String();
            Reformat(formatStart, formatEnd, out char8Mapping, newText);
			defer delete char8Mapping;

			//File.WriteAllText(@"c:\temp\new.txt", newText);

            SourceEditBatchHelper sourceEditBatchHelper = scope SourceEditBatchHelper(editWidget, "format");

            int32 insertCount = 0;
            int32 deleteCount = 0;

            int32 insertChars = 0;
            int32 deleteChars = 0;

            int32 insertStartIdx = -1;
            int32 expectedOldIdx = 0;
+	    bool ColonOrTildeIssue=false;
            for (int32 i = 0; i < char8Mapping.Count; i++)
            {

                int32 oldIdx = (int32)char8Mapping[i];

                if ((oldIdx != -1) && (insertStartIdx != -1))
                {
  	            //if (ColonOrTildeIssue) continue;

                    // Finish inserting
                    editWidgetContent.CursorTextPos = insertStartIdx;

                    String insertString = scope String();
                    //newText.Substring(insertStartIdx, i - insertStartIdx, insertString);
+		    if (ColonOrTildeIssue) insertString.Append(""); //change "" to "¤" or some other rare character to get indication of when oldIdx = -1 (formatting fails)
c		    else insertString.Append(newText, insertStartIdx, i - insertStartIdx);

                    var insertTextAction = new EditWidgetContent.InsertTextAction(editWidgetContent, insertString, .None);
                    insertTextAction.mMoveCursor = false;
                    editWidgetContent.mData.mUndoManager.Add(insertTextAction);
                    
                    editWidgetContent.PhysInsertAtCursor(insertString, false);

                    if (orFlags != 0)
                    {
                        for (int32 idx = insertStartIdx; idx < i; idx++)
                            editWidgetContent.mData.mText[idx].mDisplayFlags |= orFlags;
                    }

                    insertStartIdx = -1;
                    insertCount++;
                    insertChars += (int32)insertString.Length;                    
                }

                if (oldIdx == expectedOldIdx)
                {
                    expectedOldIdx++;
                    continue;
                }
                else if (oldIdx == -1)
                {
+		    ColonOrTildeIssue=true;
                    if (insertStartIdx == -1)
                        insertStartIdx = i;
                }
                else
                {
+		        if (ColonOrTildeIssue) continue;
			// This fails if we have the same ID occur multiple times, or we reorder nodes
			if (oldIdx <= expectedOldIdx)
			{
#if DEBUG
				Utils.WriteTextFile(@"c:\temp\old.txt", oldText).IgnoreError();
				Utils.WriteTextFile(@"c:\temp\new.txt", newText).IgnoreError();
				Debug.FatalError("Reformat failed");
#endif
				break; // Error - abort
			}
                    
                    int32 charsToDelete = oldIdx - expectedOldIdx;
                    editWidgetContent.CursorTextPos = i;
                    var deleteCharAction = new EditWidgetContent.DeleteCharAction(editWidgetContent, 0, charsToDelete);
                    deleteCharAction.mMoveCursor = false;
                    editWidgetContent.mData.mUndoManager.Add(deleteCharAction);
                    editWidgetContent.PhysDeleteChars(0, charsToDelete);
                    expectedOldIdx = oldIdx + 1;
                    deleteCount++;
                    deleteChars += charsToDelete;                    
                }
            }

            editWidgetContent.ContentChanged();
            Debug.WriteLine("Reformat {0} inserts, total of {1} chars. {2} deletes, total of {3} chars.", insertCount, insertChars, deleteCount, deleteChars);

            sourceEditBatchHelper.Finish();
        }

(* this also triggers that:

		public static uint32[] sTextColors = new uint32[]
			(
			0xFFFFFFFF, // Normal
...

!!!			0xFF9090C0, // VisibleWhiteSpace   !!! the , triggers the oldIdx = -1
			) ~ delete _;

)

marsej avatar Apr 13 '21 12:04 marsej

int32 oldIdx = (int32)char8Mapping[i];

this gets set to -1 when ":" is hit and weird things going here:

			for (int32 i = 0; i < char8Mapping.Count; i++)
			{
				int32 oldIdx = (int32)char8Mapping[i];
+				var zs= scope String();
+				editWidgetContent.ExtractString(oldIdx,1,zs);
				Debug.Write(zs);
				if ((oldIdx != -1) && (insertStartIdx != -1))
				{

prints out:

List<int32> mNextKeys ~ deleteힽ�ed virtual BumpAllocator CreateAllocator()

The garbage characters just happen to be where : is and that's where the deletion occurs. (changes to

List<int32> mNextKeys ~ delete _;

)

marsej avatar Apr 13 '21 16:04 marsej

Much better thank you. The destructor in this case is still deleted though so can't close this yet:

SourceEditWidgetContent.bf line 3696: (todays build), 
        public bool DoSpellingPopup(Menu menu)
        {
...
                item.mOnMenuItemSelected.Add(new (evt) =>
                    {
                        ReplaceWord(leftIdx, rightIdx, word, replaceStr);
                    }
                    ~
                    {
						delete replaceStr;
                    });
...
        }

marsej avatar Dec 08 '21 15:12 marsej

This also gets wrapped. I'd like to fix this but I don't know how to pass options from the settings.bf to the brprinter.cpp!

SourceEditWidgetContent.bf line 3240:
					else if ((keyChar == '}') && (!HasSelection())) // Jump down to block close, as long as it's just whitespace between us and there

gets turned to

					else if ((keyChar == '}') && (!HasSelection()))// Jump down to block close, as long as it's just
					// whitespace between us and there

All I know is changing the following from 120 to 0 stops the comment wrapping: bfprinter line 47: mMaxCol = 0; //gApp.mSettings.mUISettings.mWrapCommentsAt; //was 120, but prefer 0 so created option under Editor

mWrapCommentsAt is a new setting I made in Settings.bf but I can't access it from bfprinter.cpp. Bummer.

marsej avatar Dec 08 '21 15:12 marsej

Here's a test file that covers these bfprinter issues: formatOnSaveTests2.txt

marsej avatar Dec 09 '21 03:12 marsej

I believe this are all addressed here d57e790a9aea0faf9fe1da5b763a9845987f2140

bfiete avatar Dec 11 '21 18:12 bfiete

Thanks for addressing these. I still found a couple cases that may warrant review:

Notably: #elif gets indent while #else does not //long comment chop to below (would prefer above or no chop) removeNum = (int32)-lineText.Length - 1; // becomes (int32) - lineText.Length - 1 case '<', '>', '(', ')', '[', ']', '{', '}': //spaces removed

formatOnSaveTests3.txt

marsej avatar Dec 14 '21 00:12 marsej