From: Jean-Philippe Bruyère Date: Tue, 25 Feb 2025 12:36:58 +0000 (+0100) Subject: exceptions dockwin, rename document RW Mutex, syntaxRootNode X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=211214309beb67386a8c689251ec6f36d2eb612f;p=jp%2Fcrowedit.git exceptions dockwin, rename document RW Mutex, syntaxRootNode --- diff --git a/CrowEditBase/src/Compiler/SourceDocument.cs b/CrowEditBase/src/Compiler/SourceDocument.cs index c2ffdb5..741db82 100644 --- a/CrowEditBase/src/Compiler/SourceDocument.cs +++ b/CrowEditBase/src/Compiler/SourceDocument.cs @@ -17,7 +17,10 @@ namespace CrowEditBase : base (fullPath, editorPath) { } protected Token[] tokens; - protected SyntaxNode RootNode; + protected SyntaxRootNode root; + protected int currentTokenIndex; + SyntaxNode currentNode; + protected Token currentToken => currentTokenIndex < 0 ? default : tokens[currentTokenIndex]; protected Token? previousToken { get { @@ -26,7 +29,6 @@ namespace CrowEditBase return tokens[currentTokenIndex-1]; } } - SyntaxNode currentNode; public SyntaxNode CurrentNode { get => currentNode; set { @@ -36,16 +38,15 @@ namespace CrowEditBase NotifyValueChanged ("CurrentNode", currentNode); } } - public string CurrentTokenString => RootNode?.Root.GetTokenStringByIndex (currentTokenIndex); + public string CurrentTokenString => root?.GetTokenStringByIndex (currentTokenIndex); public Token CurrentToken => currentToken; - public bool IsParsed => tokens.Length > 0 && RootNode != null; + public bool IsParsed => tokens.Length > 0 && root != null; + public SyntaxRootNode Root => root; //public SyntaxNode EditedNode { get; protected set; } - protected int currentTokenIndex; public Token[] Tokens => tokens; - public SyntaxNode SyntaxRootNode => RootNode; - public IEnumerable SyntaxRootChildNodes => RootNode?.children; + public IEnumerable SyntaxRootChildNodes => root?.children; public LineCollection Lines => lines; public Token FindTokenIncludingPosition (int pos) { if (pos == 0 || tokens == null || tokens.Length == 0) @@ -65,30 +66,30 @@ namespace CrowEditBase /// if outermost is true, return oldest ancestor exept root node, useful for folding. /// public SyntaxNode FindNodeIncludingPosition (int pos, bool outerMost = false) { - if (RootNode == null) + if (root == null) return null; - if (!RootNode.Contains (pos)) + if (!root.Contains (pos)) return null; - SyntaxNode sn = RootNode.FindNodeIncludingPosition (pos); + SyntaxNode sn = root.FindNodeIncludingPosition (pos); if (outerMost) { - while (sn.Parent != RootNode && sn.Span.Start == sn.Parent.Span.Start) + while (sn.Parent != root && sn.Span.Start == sn.Parent.Span.Start) sn = sn.Parent; } return sn; } public T FindNodeIncludingPosition (int pos) { - if (RootNode == null) + if (root == null) return default; - if (!RootNode.Contains (pos)) + if (!root.Contains (pos)) return default; - return RootNode.FindNodeIncludingPosition (pos); + return root.FindNodeIncludingPosition (pos); } public SyntaxNode FindNodeIncludingSpan (TextSpan span) { - if (RootNode == null) + if (root == null) return null; - if (!RootNode.Contains (span)) + if (!root.Contains (span)) return null; - return RootNode.FindNodeIncludingSpan (span); + return root.FindNodeIncludingSpan (span); } protected override void reloadFromFile () { base.reloadFromFile (); @@ -104,24 +105,23 @@ namespace CrowEditBase SyntaxAnalyser syntaxAnalyser = CreateSyntaxAnalyser (); if (syntaxAnalyser == null) { - RootNode = null; + root = null; return; } - SyntaxNode changedNode = RootNode.FindNodeIncludingSpan (TextSpan.FromStartAndLength (change.Start, change.ChangedText.Length)); - + //SyntaxNode changedNode = root.FindNodeIncludingSpan (TextSpan.FromStartAndLength (change.Start, change.ChangedText.Length)); tokens = tokenizer.Tokenize (buffer.Span); - - syntaxAnalyser.Process (); - NotifyValueChanged("Exceptions", syntaxAnalyser.Exceptions); + root = syntaxAnalyser.Root; + NotifyValueChanged("Exceptions", syntaxAnalyser.Exceptions); + /* SyntaxNode newNode = syntaxAnalyser.Root.FindNodeIncludingSpan (TextSpan.FromStartAndLength (change.Start, change.ChangedText.Length)); if (editedNode == null) { //System.Diagnostics.Debugger.Break (); - RootNode = syntaxAnalyser.Root; + root = syntaxAnalyser.Root; } else if (newNode.IsSimilar (editedNode)) { if (!tryReplaceNode (editedNode, newNode)) RootNode = syntaxAnalyser.Root; @@ -138,6 +138,7 @@ namespace CrowEditBase //System.Diagnostics.Debugger.Break (); RootNode = syntaxAnalyser.Root; } + */ //updateCurrentTokAndNode (change.End2); //EditedNode = editedNode; @@ -197,16 +198,11 @@ namespace CrowEditBase Stopwatch sw = Stopwatch.StartNew (); syntaxAnalyser?.Process (); sw.Stop(); - RootNode = syntaxAnalyser?.Root; + root = syntaxAnalyser?.Root; //CrowEditBase.App.Log (LogType.Low, $"Syntax Analysis done in {sw.ElapsedMilliseconds}(ms) {sw.ElapsedTicks}(ticks)"); if (syntaxAnalyser == null) return; - LogItem log = CrowEditBase.App.GetLog(this.FileName); - log.ResetLog(); - foreach (SyntaxException ex in syntaxAnalyser.Exceptions) - log.Add(LogType.Error, $"{ex}"); - /*foreach (Token t in Tokens) Console.WriteLine ($"{t,-40} {Source.AsSpan(t.Start, t.Length).ToString()}"); syntaxAnalyser.Root.Dump();*/ diff --git a/CrowEditBase/src/Compiler/SyntaxAnalyser.cs b/CrowEditBase/src/Compiler/SyntaxAnalyser.cs index ab2df67..cad6fe1 100644 --- a/CrowEditBase/src/Compiler/SyntaxAnalyser.cs +++ b/CrowEditBase/src/Compiler/SyntaxAnalyser.cs @@ -10,7 +10,7 @@ namespace CrowEditBase public abstract class SyntaxAnalyser { //protected abstract void Parse(SyntaxNode node); protected SourceDocument source; - public abstract SyntaxNode Root { get; } + public SyntaxRootNode Root { get; protected set; } public IEnumerable Exceptions => Root?.GetAllExceptions(); public SyntaxAnalyser (SourceDocument source) { this.source = source; diff --git a/CrowEditBase/src/Compiler/SyntaxException.cs b/CrowEditBase/src/Compiler/SyntaxException.cs index d889cc3..3031acb 100644 --- a/CrowEditBase/src/Compiler/SyntaxException.cs +++ b/CrowEditBase/src/Compiler/SyntaxException.cs @@ -7,10 +7,13 @@ namespace CrowEditBase { public class SyntaxException : Exception { public readonly Token Token; - public SyntaxException(string message, Token token = default, Exception innerException = null) + public readonly SyntaxAnalyser SyntaxAnalyser; + public SyntaxException(string message, Token token = default, SyntaxAnalyser syntaxAnalyser = null, Exception innerException = null) : base (message, innerException) { Token = token; + SyntaxAnalyser = syntaxAnalyser; } - public override string ToString() => $"{Message}, {Token}"; + public string TokenString => SyntaxAnalyser.Root.GetTokenString(Token); + public override string ToString() => $"{Message}: {TokenString}"; } } \ No newline at end of file diff --git a/CrowEditBase/src/CrowEditBase.cs b/CrowEditBase/src/CrowEditBase.cs index 985c14b..9ca4749 100644 --- a/CrowEditBase/src/CrowEditBase.cs +++ b/CrowEditBase/src/CrowEditBase.cs @@ -23,6 +23,18 @@ namespace CrowEditBase Log(LogType.Normal,"Crow edit started"); } + protected DockStack mainDock; + protected const string _defaultFileName = "unnamed.txt"; + Document currentDocument; + Editor currentEditor; + Project currentProject; + public CommandGroup CommandsRoot, FileCommands, EditCommands, ViewCommands; + public ObservableList OpenedDocuments = new ObservableList (); + public ObservableList Services = new ObservableList (); + public ObservableList Plugins = new ObservableList (); + public ObservableList Projects = new ObservableList (); + + #region logging LogItem currentLog; public LogItem CurrentLog { @@ -116,16 +128,7 @@ namespace CrowEditBase #endregion - protected const string _defaultFileName = "unnamed.txt"; - Document currentDocument; - Editor currentEditor; - Project currentProject; - public CommandGroup CommandsRoot, FileCommands, EditCommands, ViewCommands; - public ObservableList OpenedDocuments = new ObservableList (); - public ObservableList Services = new ObservableList (); - public ObservableList Plugins = new ObservableList (); - public ObservableList Projects = new ObservableList (); public T GetService () where T : Service { T service = Services.OfType().FirstOrDefault (); if (service == null) { @@ -375,7 +378,6 @@ namespace CrowEditBase Configuration.Global.Save (); } - protected DockStack mainDock; protected void reloadWinConfigs() { if (Configuration.Global.TryGet("WinConfigs", out string conf) && !string.IsNullOrEmpty(conf)) diff --git a/CrowEditBase/src/Document.cs b/CrowEditBase/src/Document.cs index 56ef878..03db4e5 100644 --- a/CrowEditBase/src/Document.cs +++ b/CrowEditBase/src/Document.cs @@ -28,11 +28,11 @@ namespace CrowEditBase public string EditorPath { get; private set; }//the ressource path is used as an id for editor template selection. public event EventHandler CloseEvent; - protected ReaderWriterLockSlim editorRWLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); - public void EnterReadLock () => editorRWLock.EnterReadLock (); - public void ExitReadLock () => editorRWLock.ExitReadLock (); - public void EnterWriteLock () => editorRWLock.EnterWriteLock (); - public void ExitWriteLock () => editorRWLock.ExitWriteLock (); + protected ReaderWriterLockSlim documentRWLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + public void EnterReadLock () => documentRWLock.EnterReadLock (); + public void ExitReadLock () => documentRWLock.ExitReadLock (); + public void EnterWriteLock () => documentRWLock.EnterWriteLock (); + public void ExitWriteLock () => documentRWLock.ExitWriteLock (); public abstract bool TryGetState (object client, out T state); public abstract void RegisterClient (object client); @@ -98,14 +98,14 @@ namespace CrowEditBase protected abstract void readFromDisk (); protected abstract void initNewFile (); protected virtual void reloadFromFile () { - editorRWLock.EnterWriteLock (); + documentRWLock.EnterWriteLock (); try { if (File.Exists (FullPath)) readFromDisk (); else initNewFile (); } finally { - editorRWLock.ExitWriteLock (); + documentRWLock.ExitWriteLock (); } } public abstract bool IsDirty { get; } diff --git a/CrowEditBase/src/Editor.cs b/CrowEditBase/src/Editor.cs index dc9613f..f447ad5 100644 --- a/CrowEditBase/src/Editor.cs +++ b/CrowEditBase/src/Editor.cs @@ -805,9 +805,12 @@ namespace Crow public override void onKeyPress (object sender, KeyPressEventArgs e) { base.onKeyPress (sender, e); - TextSpan selection = Selection; - update (new TextChange (selection.Start, selection.Length, e.KeyChar.ToString ())); + if (!e.Handled) { + TextSpan selection = Selection; + update (new TextChange (selection.Start, selection.Length, e.KeyChar.ToString ())); + e.Handled = true; + } /*Insert (e.KeyChar.ToString()); SelRelease = -1; diff --git a/CrowEditBase/src/SourceEditor.cs b/CrowEditBase/src/SourceEditor.cs index 7a77750..9535d9e 100644 --- a/CrowEditBase/src/SourceEditor.cs +++ b/CrowEditBase/src/SourceEditor.cs @@ -331,7 +331,7 @@ namespace Crow if (Document is SourceDocument doc) { switch (e.Key) { case Key.F3: - doc.SyntaxRootNode?.Dump(); + doc.Root?.Dump(); break; case Key.Enter: case Key.KeypadEnter: @@ -355,7 +355,7 @@ namespace Crow SyntaxNode getFoldStartingAt (int line) { if (!(Document is SourceDocument doc)) return null; - IEnumerable folds = doc.SyntaxRootNode.FoldableNodes; + IEnumerable folds = doc.Root.FoldableNodes; if (folds == null) return null; return folds.FirstOrDefault (n => n.StartLine == line); @@ -365,7 +365,7 @@ namespace Crow return null; doc.EnterReadLock(); try { - IEnumerable folds = doc.SyntaxRootNode.FoldableNodes; + IEnumerable folds = doc.Root.FoldableNodes; if (folds == null) return null; return folds.LastOrDefault (n => n.StartLine <= line && n.EndLine >= line); @@ -380,7 +380,7 @@ namespace Crow doc.EnterReadLock(); try { int foldedLines = 0; - IEnumerator foldsEnum = doc.SyntaxRootNode.FoldableNodes.GetEnumerator(); + IEnumerator foldsEnum = doc.Root.FoldableNodes.GetEnumerator(); bool notEndOfFolds = foldsEnum.MoveNext(); while (notEndOfFolds && foldsEnum.Current.StartLine < absoluteLine) { if (foldsEnum.Current.isFolded) { @@ -405,7 +405,7 @@ namespace Crow doc.EnterReadLock(); try { int foldedLines = 0; - IEnumerator nodeEnum = doc.SyntaxRootNode.FoldableNodes.GetEnumerator (); + IEnumerator nodeEnum = doc.Root.FoldableNodes.GetEnumerator (); if (!nodeEnum.MoveNext()) return 0; @@ -615,7 +615,7 @@ namespace Crow SyntaxNode curNode = null; - IEnumerator nodeEnum = doc.SyntaxRootNode.FoldableNodes.GetEnumerator (); + IEnumerator nodeEnum = doc.Root.FoldableNodes.GetEnumerator (); bool notEndOfNodes = nodeEnum.MoveNext(); gr.LineWidth = 1; diff --git a/CrowEditBase/src/TextDocument.cs b/CrowEditBase/src/TextDocument.cs index d64ce27..9242e5b 100644 --- a/CrowEditBase/src/TextDocument.cs +++ b/CrowEditBase/src/TextDocument.cs @@ -79,28 +79,28 @@ namespace CrowEditBase Dictionary> registeredClients = new Dictionary>(); public override bool TryGetState(object client, out T state) { state = default; - if (editorRWLock.TryEnterReadLock (10)) { + if (documentRWLock.TryEnterReadLock (10)) { try { state = (T)(object)registeredClients[client]; registeredClients[client] = null; } finally { - editorRWLock.ExitReadLock (); + documentRWLock.ExitReadLock (); } } return state != null; } public override void RegisterClient(object client) { - editorRWLock.EnterWriteLock (); + documentRWLock.EnterWriteLock (); registeredClients.Add (client, null); //notifyClient (client, new TextChange (0, 0, source)); - editorRWLock.ExitWriteLock (); + documentRWLock.ExitWriteLock (); } public override void UnregisterClient(object client) { - editorRWLock.EnterWriteLock (); + documentRWLock.EnterWriteLock (); registeredClients.Remove (client); - editorRWLock.ExitWriteLock (); + documentRWLock.ExitWriteLock (); } void notifyClients (TextChange tc, object triggeringClient = null) { object[] clients = registeredClients.Keys.ToArray (); @@ -140,7 +140,7 @@ namespace CrowEditBase buffer = new TextBuffer(""); } protected override void reloadFromFile () { - editorRWLock.EnterWriteLock (); + documentRWLock.EnterWriteLock (); try { if (File.Exists (FullPath)) readFromDisk (); @@ -148,7 +148,7 @@ namespace CrowEditBase initNewFile (); resetUndoRedo (); } finally { - editorRWLock.ExitWriteLock (); + documentRWLock.ExitWriteLock (); } } protected Stack undoStack = new Stack (); @@ -173,7 +173,7 @@ namespace CrowEditBase } protected override void undo () { - editorRWLock.EnterWriteLock (); + documentRWLock.EnterWriteLock (); try { if (undoStack.TryPop (out TextChange tc)) { redoStack.Push (tc.Inverse (source)); @@ -185,11 +185,11 @@ namespace CrowEditBase if (undoStack.Count == 0) CMDUndo.CanExecute = false; } finally { - editorRWLock.ExitWriteLock (); + documentRWLock.ExitWriteLock (); } } protected override void redo () { - editorRWLock.EnterWriteLock (); + documentRWLock.EnterWriteLock (); try { if (redoStack.TryPop (out TextChange tc)) { undoStack.Push (tc.Inverse (source)); @@ -200,7 +200,7 @@ namespace CrowEditBase if (redoStack.Count == 0) CMDRedo.CanExecute = false; } finally { - editorRWLock.ExitWriteLock (); + documentRWLock.ExitWriteLock (); } } @@ -220,7 +220,7 @@ namespace CrowEditBase CMDSave.CanExecute = IsDirty; } protected void applyTextChange (TextChange change, object triggeringEditor = null) { - editorRWLock.EnterWriteLock (); + documentRWLock.EnterWriteLock (); try { undoStack.Push (change.Inverse (source)); redoStack.Clear (); @@ -229,15 +229,14 @@ namespace CrowEditBase apply (change); notifyClients (change, triggeringEditor); } finally { - editorRWLock.ExitWriteLock (); + documentRWLock.ExitWriteLock (); } - } protected void onTextChanged (object sender, TextChangeEventArgs e) { applyTextChange (e.Change, sender); } protected void getLines () { - editorRWLock.EnterWriteLock (); + documentRWLock.EnterWriteLock (); if (lines == null) lines = new LineCollection (10); else @@ -247,10 +246,10 @@ namespace CrowEditBase lines.Add (new TextLine (0, 0, 0)); else lines.Update (source); - editorRWLock.ExitWriteLock (); + documentRWLock.ExitWriteLock (); } public string GetLineBreak () { - editorRWLock.EnterReadLock (); + documentRWLock.EnterReadLock (); try { if (string.IsNullOrEmpty (lineBreak)) { mixedLineBreak = false; @@ -271,32 +270,32 @@ namespace CrowEditBase } return lineBreak; } finally { - editorRWLock.ExitReadLock(); + documentRWLock.ExitReadLock(); } } public CharLocation GetLocation (int absolutePosition) { - editorRWLock.EnterReadLock (); + documentRWLock.EnterReadLock (); try { return lines.GetLocation (absolutePosition); } finally { - editorRWLock.ExitReadLock(); + documentRWLock.ExitReadLock(); } } public int GetAbsolutePosition (CharLocation loc) { - editorRWLock.EnterReadLock (); + documentRWLock.EnterReadLock (); try { return lines.GetAbsolutePosition (loc); } finally { - editorRWLock.ExitReadLock(); + documentRWLock.ExitReadLock(); } } public CharLocation EndLocation { get { - editorRWLock.EnterReadLock (); + documentRWLock.EnterReadLock (); try { return new CharLocation (lines.Count - 1, lines[lines.Count - 1].Length); } finally { - editorRWLock.ExitReadLock(); + documentRWLock.ExitReadLock(); } } } @@ -304,59 +303,59 @@ namespace CrowEditBase get { if (lines == null) getLines(); - editorRWLock.EnterReadLock (); + documentRWLock.EnterReadLock (); try { return lines.Count; } finally { - editorRWLock.ExitReadLock(); + documentRWLock.ExitReadLock(); } } } public int Lenght { get { - editorRWLock.EnterReadLock (); + documentRWLock.EnterReadLock (); try { return source.Length; } finally { - editorRWLock.ExitReadLock(); + documentRWLock.ExitReadLock(); } } } public TextLine GetLine (int index) { - editorRWLock.EnterReadLock (); + documentRWLock.EnterReadLock (); try { return lines[index]; } finally { - editorRWLock.ExitReadLock(); + documentRWLock.ExitReadLock(); } } public ReadOnlySpan GetText (TextLine line) { - editorRWLock.EnterReadLock (); + documentRWLock.EnterReadLock (); try { return source.GetLine (line); } finally { - editorRWLock.ExitReadLock(); + documentRWLock.ExitReadLock(); } } public ReadOnlySpan GetText (TextSpan span) { - editorRWLock.EnterReadLock (); + documentRWLock.EnterReadLock (); try { return source.Slice (span.Start, span.Length); } finally { - editorRWLock.ExitReadLock(); + documentRWLock.ExitReadLock(); } } public char GetChar (int pos){ - editorRWLock.EnterReadLock (); + documentRWLock.EnterReadLock (); try { return source[pos]; } finally { - editorRWLock.ExitReadLock(); + documentRWLock.ExitReadLock(); } } public virtual CharLocation GetWordStart (CharLocation loc) { - editorRWLock.EnterReadLock (); + documentRWLock.EnterReadLock (); try { int pos = lines.GetAbsolutePosition (loc); //skip white spaces @@ -366,11 +365,11 @@ namespace CrowEditBase pos--; return lines.GetLocation (pos); } finally { - editorRWLock.ExitReadLock(); + documentRWLock.ExitReadLock(); } } public virtual CharLocation GetWordEnd (CharLocation loc) { - editorRWLock.EnterReadLock (); + documentRWLock.EnterReadLock (); try { int pos = lines.GetAbsolutePosition (loc); //skip white spaces @@ -380,7 +379,7 @@ namespace CrowEditBase pos++; return lines.GetLocation (pos); } finally { - editorRWLock.ExitReadLock(); + documentRWLock.ExitReadLock(); } } } diff --git a/CrowEditBase/ui/sourceEditor.itmp b/CrowEditBase/ui/sourceEditor.itmp index ffeb398..54967ac 100644 --- a/CrowEditBase/ui/sourceEditor.itmp +++ b/CrowEditBase/ui/sourceEditor.itmp @@ -36,7 +36,5 @@