]> O.S.I.I.S - jp/crowedit.git/commitdiff
async compile SourceDocument
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 9 Mar 2025 22:19:24 +0000 (23:19 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 9 Mar 2025 22:19:24 +0000 (23:19 +0100)
12 files changed:
CrowEditBase/src/Compiler/SourceDocument.cs
CrowEditBase/src/Compiler/SyntaxAnalyser.cs
CrowEditBase/src/Compiler/SyntaxNode.cs
CrowEditBase/src/Editor.cs
CrowEditBase/src/SourceEditor.cs
CrowEditBase/ui/sourceEditor.itmp
plugins/CECrowPlugin/src/Parsing/IML/ImlSyntaxAnalyser.cs
plugins/CECrowPlugin/src/Parsing/Styling/StyleSyntaxAnalyser.cs
plugins/CEEbnfPlugin/src/Parsing/EbnfSyntaxAnalyser.cs
plugins/CERoslynPlugin/src/CSDocument.cs
plugins/CERoslynPlugin/src/CSSyntaxAnalyser.cs
plugins/CEXmlPlugin/src/Parsing/XmlSyntaxAnalyser.cs

index b4f220b6bfd9b3c8dbd89dcdc056b9d3a4f672ff..5db2e43e99ca332411ede2f80e0eeeda9d306055 100644 (file)
@@ -10,6 +10,8 @@ using System.Collections;
 using System.Collections.Generic;
 using Drawing2D;
 using System.Security;
+using System.Threading;
+using System.Threading.Tasks;
 
 namespace CrowEditBase
 {
@@ -141,20 +143,33 @@ namespace CrowEditBase
                //protected abstract Tokenizer CreateTokenizer ();
                protected abstract SyntaxAnalyser CreateSyntaxAnalyser ();
                public abstract IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode currentNode, CharLocation loc);
-
+               CancellationTokenSource cancelSource;
+               Task backgroundCompilationTask;
                protected virtual async void parse () {
-                       SyntaxAnalyser syntaxAnalyser = CreateSyntaxAnalyser ();
-                       root = await syntaxAnalyser.Process ();
+                       if (backgroundCompilationTask != null && !backgroundCompilationTask.IsCompleted) {
+                               cancelSource.Cancel();
+                               await backgroundCompilationTask;
+                       }
 
-                       NotifyValueChanged("Exceptions", syntaxAnalyser?.Exceptions);
-                       NotifyValueChanged ("SyntaxRootChildNodes", (object)null);
-                       NotifyValueChanged ("SyntaxRootChildNodes", SyntaxRootChildNodes);
+                       cancelSource = new CancellationTokenSource();
+                       backgroundCompilationTask = Task.Run(()=>parseAssync(cancelSource.Token));
                        
                        //CurrentNode?.ExpandToTheTop();
                        
                        //CrowEditBase.App.Log (LogType.Low, $"Syntax Analysis done in {sw.ElapsedMilliseconds}(ms) {sw.ElapsedTicks}(ticks)");
                }
 
+               async void parseAssync(CancellationToken cancel) {
+                       SyntaxAnalyser syntaxAnalyser = CreateSyntaxAnalyser ();
+                       root = await syntaxAnalyser.Process (cancel);
+                       if (cancel.IsCancellationRequested)
+                               return;
+
+                       NotifyValueChanged("Exceptions", syntaxAnalyser?.Exceptions);
+                       NotifyValueChanged ("SyntaxRootChildNodes", (object)null);
+                       NotifyValueChanged ("SyntaxRootChildNodes", SyntaxRootChildNodes);
+               }
+
                public SyntaxException CurrentException {
                        get => CrowEditBase.App.CurrentException;
                        set {
index 9273fe19e5970e7e36a9181d31354220e306ecd7..3f95d491927eaa92b2039567feb25080e076eb62 100644 (file)
@@ -4,6 +4,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading;
 using System.Threading.Tasks;
 using Crow.Text;
 
@@ -16,7 +17,7 @@ namespace CrowEditBase
                public SyntaxAnalyser (SourceDocument document) {
                        this.document = document;
                }
-               public abstract Task<SyntaxRootNode> Process ();
+               public abstract Task<SyntaxRootNode> Process (CancellationToken cancel = default);
                
                #region Token handling
                protected Token curTok => tokIdx < 0 ? default : tokens[tokIdx];
index 69c73cbc2e74e1cf4bd08582e560ea757717eb62..31f70b5b7f563a9813ed06937ca0fe920ba0ab3a 100644 (file)
@@ -102,6 +102,7 @@ namespace CrowEditBase
                                }
                        }
                }
+               
                public virtual int FoldedLineCount {
                        get {
                                if (isFolded)
index 28175ac886d7d4bf463f3668a35c79c42bdc5a37..48cc23ee72fcb8093122293ff864aca2f2367c0a 100644 (file)
@@ -105,7 +105,7 @@ namespace CrowEditBase
                                CMDCopy.CanExecute = CMDCut.CanExecute = !SelectionIsEmpty;
                        }
                }
-               public int CurrentColumn {
+               public int CurrentColumn {                      
                        get => currentLoc.HasValue ? currentLoc.Value.Column < 0 ? 0 : currentLoc.Value.Column : 0;
                        set {
                                if (CurrentColumn == value)
@@ -483,6 +483,8 @@ namespace CrowEditBase
                }
                protected int getLineIndexFromMousePosition (Point mouseLocalPos) =>
                        (int)Math.Min (Math.Max (0, Math.Floor ((mouseLocalPos.Y + ScrollY)/ lineHeight)), visualLineCount - 1);
+               protected int getLineIndexFromMousePositionUnchecked (Point mouseLocalPos) =>
+                       (int)Math.Max (0, Math.Floor ((mouseLocalPos.Y + ScrollY)/ lineHeight));
                protected int getVisualLineIndex (Point mouseLocalPos) =>
                        (int)Math.Min (Math.Max (0, Math.Floor (mouseLocalPos.Y / lineHeight)), visibleLines - 1);
                protected virtual int visualCurrentLine => CurrentLoc.HasValue ? CurrentLoc.Value.Line : 0;
index 4724f9e92020a0d4d5026a8ba1930903d92f11e6..e4b7762e385d05db0e8d3b91dd090077027fe0ff 100644 (file)
@@ -13,6 +13,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text.Unicode;
 using System.Text;
+using System.Threading.Tasks;
 
 namespace CrowEditBase
 {
@@ -27,7 +28,7 @@ namespace CrowEditBase
                }
         int currentTokenIndex = -1;
                SyntaxNode currentNode;
-#if DEBUG_NODE
+/*#if DEBUG_NODE
                SyntaxNode _hoverNode;
                SyntaxNode hoverNode {
                        get =>_hoverNode;
@@ -38,7 +39,7 @@ namespace CrowEditBase
                                RegisterForRedraw ();
                        }
                }
-#endif
+#endif*/
                public SyntaxNode CurrentNode {
                        get => currentNode;
                        set {
@@ -211,6 +212,8 @@ namespace CrowEditBase
                        }
                }
                
+               //Task<int> taskFirstVisibleLineIndex;
+
                #region Mouse & Keyboard overrides
                public override void onMouseDown (object sender, MouseButtonEventArgs e) {
                        hideOverlay ();
@@ -240,12 +243,41 @@ namespace CrowEditBase
                                mouseIsInMargin = mouseIsInFoldRect = false;
                                IFace.MouseCursor = MouseCursor.ibeam;
                        }
+                       
+                       int hoverVisualLine = getLineIndexFromMousePositionUnchecked (mLoc);
+                       int hoverLine = getAbsoluteLineFromVisualLine (hoverVisualLine);
+
+                       /***************************/
+                               /*hoverLoc = new CharLocation (hoverLine, -1, mLoc.X + ScrollX - leftMargin);
+                               using (IContext gr = IFace.Backend.CreateContext (IFace.MainSurface)) {
+                                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+                                       gr.SetFontSize (Font.Size);
+                                       updateLocation (gr, ref hoverLoc);
+                               }*/
+                       /***************************/
+
+                       NotifyValueChanged("MouseY", mLoc.Y + ScrollY);
+                       NotifyValueChanged("hoverVisualLine", hoverVisualLine);
+                       NotifyValueChanged("hoverLine", hoverLine);
 
-                       updateHoverLocation (mLoc);
+                       
+                       if (mouseIsInMargin) {
+                               if (hoverLoc.HasValue)
+                                       hoverLoc = new CharLocation (hoverLine, hoverLoc.Value.Column, hoverLoc.Value.VisualCharXPosition);
+                               else
+                                       hoverLoc = new CharLocation (hoverLine, 0, 0);
+                       } else {
+                               hoverLoc = new CharLocation (hoverLine, -1, mLoc.X + ScrollX - leftMargin);
+                               using (IContext gr = IFace.Backend.CreateContext (IFace.MainSurface)) {
+                                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+                                       gr.SetFontSize (Font.Size);
+                                       updateLocation (gr, ref hoverLoc);
+                               }
+                       }
 
                        if (mouseIsInMargin) {
                                Rectangle rFold = new Rectangle (leftMargin - foldMargin - leftMarginRightGap,
-                                       (int)(lineHeight * getVisualLine(hoverLoc.Value.Line) + lineHeight / 2.0 - foldSize / 2.0) - ScrollY, foldSize, foldSize);
+                                       (int)(lineHeight * hoverVisualLine + lineHeight / 2.0 - foldSize / 2.0) - ScrollY, foldSize, foldSize);
                                rFold.Inflate(2);
                                mouseIsInFoldRect = rFold.ContainsOrIsEqual (mLoc);
                                RegisterForRedraw();
@@ -261,12 +293,9 @@ namespace CrowEditBase
                        }
                }
                protected override void updateHoverLocation (Point mouseLocalPos) {
-                       int hoverVisualLine = getLineIndexFromMousePosition (mouseLocalPos);
-                       int hoverLine = hoverVisualLine + countFoldedLinesUntil (hoverVisualLine);
-                       NotifyValueChanged("MouseY", mouseLocalPos.Y + ScrollY);
-                       NotifyValueChanged("ScrollY", ScrollY);
-                       NotifyValueChanged("VisibleLines", visibleLines);
-                       NotifyValueChanged("HoverLine", hoverLine);
+                       int hoverVisualLine = getLineIndexFromMousePositionUnchecked (mouseLocalPos);
+                       int hoverLine = getAbsoluteLineFromVisualLine (hoverVisualLine);
+                       
                        if (mouseIsInMargin) {
                                if (hoverLoc.HasValue)
                                        hoverLoc = new CharLocation (hoverLine, hoverLoc.Value.Column, hoverLoc.Value.VisualCharXPosition);
@@ -280,11 +309,11 @@ namespace CrowEditBase
                                gr.SetFontSize (Font.Size);
                                updateLocation (gr, ref hoverLoc);
                        }
-#if DEBUG_NODES
+/*#if DEBUG_NODES
                        if (Document is SourceDocument doc) {
                                hoverNode = doc.FindNodeIncludingPosition (lines.GetAbsolutePosition (hoverLoc.Value));
                        }
-#endif
+#endif*/
                }
                public override void onKeyDown(object sender, KeyEventArgs e)
                {
@@ -415,7 +444,7 @@ namespace CrowEditBase
                        }
                }
 
-               int getVisualLine (int absoluteLine) {
+               int getVisualLineFromAboluteLine (int absoluteLine) {
                        if (!(Document is SourceDocument doc))
                                return absoluteLine;
                        doc.EnterReadLock();
@@ -442,47 +471,32 @@ namespace CrowEditBase
                                doc.ExitReadLock ();
                        }
                }
-               int countFoldedLinesUntil (int visualLine) {
+               int getAbsoluteLineFromVisualLine (int visualLine) {
                        if (!(Document is SourceDocument doc))
                                return 0;
                        doc.EnterReadLock();
                        try {
-                               int foldedLines = 0;
                                if (!doc.IsParsed)
                                        return 0;
-                               IEnumerator<MultiNodeSyntax> nodeEnum = doc.Root.VisibleFoldableNodes.GetEnumerator ();
-                               if (!nodeEnum.MoveNext())
-                                       return 0;
 
-                               int l = 0;
-                               while (l < visualLine + foldedLines) {
-                                       if (nodeEnum.Current.StartLocation.Line == l) {
-                                               if (nodeEnum.Current.isFolded) {
-                                                       foldedLines += nodeEnum.Current.LineCount - 1;
-                                                       SyntaxNode nextNode = nodeEnum.Current.NextSiblingOrParentsNextSibling;
-                                                       if (nextNode == null || !nodeEnum.MoveNext())
-                                                               return foldedLines;
-
-                                                       while (nodeEnum.Current.StartLocation.Line < nextNode.StartLocation.Line) {
-                                                               if (!nodeEnum.MoveNext())
-                                                                       return foldedLines;
-                                                       }
+                               int linesToSkip = visualLine;
+                               IEnumerator<MultiNodeSyntax> foldsEnum = doc.Root.VisibleFoldableNodes.GetEnumerator ();
+                               bool notEndOfFolds = foldsEnum.MoveNext();
 
-                                               } else if (!nodeEnum.MoveNext())
-                                                       return foldedLines;
-                                       }
-                                       l ++;
+                               while (notEndOfFolds && foldsEnum.Current.StartLocation.Line < linesToSkip) {
+                                       if (foldsEnum.Current.isFolded)
+                                               linesToSkip += foldsEnum.Current.LineCount-1;
+                                       notEndOfFolds = foldsEnum.MoveNext();
                                }
-                               //Console.WriteLine ($"visualLine: {visualLine} foldedLines: {foldedLines}");
-                               return foldedLines;
+                               return linesToSkip;                                     
                        } finally {
                                doc.ExitReadLock ();
                        }
                }
 
                protected override int getAbsoluteLineIndexFromVisualLineMove (int startLine, int visualLineDiff) {
-                       int newVl = Math.Min (Math.Max (0, getVisualLine (startLine) + visualLineDiff), visualLineCount - 1);
-                       return newVl + countFoldedLinesUntil (newVl);
+                       int newVl = Math.Min (Math.Max (0, getVisualLineFromAboluteLine (startLine) + visualLineDiff), visualLineCount - 1);
+                       return getAbsoluteLineFromVisualLine (newVl);
                }
 
                protected override int visualLineCount
@@ -490,10 +504,11 @@ namespace CrowEditBase
                        get {
                                if (!(Document is SourceDocument doc))
                                        return base.visualLineCount;
-                               return Document.LinesCount - countFoldedLinesUntil (Document.LinesCount);
+                               
+                               return Document.LinesCount - doc.Root.FoldedLineCount;
                        }
                }
-               protected override int visualCurrentLine => CurrentLoc.HasValue ? getVisualLine (CurrentLoc.Value.Line) : 0;
+               protected override int visualCurrentLine => CurrentLoc.HasValue ? getVisualLineFromAboluteLine (CurrentLoc.Value.Line) : 0;
                protected override void updateMaxScrolls (LayoutingType layout) {
                        updateMargin();
                        Rectangle cb = ClientRectangle;
index 5444c2d72a2a7f23eb05000ca9830fd6e3cd1697..a8609d62c881ce03d577256e27e83a57264d9242 100644 (file)
                                <Label Text="{../../tb.ScrollLine}" Margin="3"/>
                                <Label Text="HoverLine:" Foreground="Grey"/>
                                <Label Text="{../../tb.HoverLine}" Margin="3"/>
+                               <Label Text="hoverVisualLine:" Foreground="Grey"/>
+                               <Label Text="{../../tb.hoverVisualLine}" Margin="3"/>
+                               <Label Text="hoverLine:" Foreground="Grey"/>
+                               <Label Text="{../../tb.hoverLine}" Margin="3"/>
                                <Label Text="Line:" Foreground="Grey"/>
                                <Label Text="{../../tb.CurrentLine}" Margin="3"/>
                                <Label Text="Col:" Foreground="Grey"/>
index d8d9816cfd5e6bd1fa83dd8de3e612620d9c838f..196f0bf69e2d95c4d1e7d6045d21182d6a37d702 100644 (file)
@@ -7,6 +7,7 @@ using System.Linq;
 using CrowEditBase;
 using CrowEdit.Xml;
 using System.Threading.Tasks;
+using System.Threading;
 
 namespace CECrowPlugin
 {
@@ -14,7 +15,7 @@ namespace CECrowPlugin
                public ImlSyntaxAnalyser (ImlDocument document) : base (document) {}
 
 
-               public override async Task<SyntaxRootNode> Process () {
+               public override async Task<SyntaxRootNode> Process (CancellationToken cancel = default) {
 
                        return await base.Process();
 
index 97519566555e6930f1d7e425d76e879005d323dd..5f9d03377b20f86d5768ecef28f19d8e823a0ba9 100644 (file)
@@ -5,6 +5,7 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Reflection.Metadata.Ecma335;
+using System.Threading;
 using System.Threading.Tasks;
 using CrowEdit.Xml;
 using CrowEditBase;
@@ -102,6 +103,9 @@ namespace CECrowPlugin.Style
                MemberListSyntax processNode(MemberListSyntax memberList) {
                        memberList.AddChild(new SingleTokenSyntax(Read()));
                        while (skipTriviaAndComments(memberList)) {
+                                       if (cancel.IsCancellationRequested)
+                                               break;
+
                                if (Peek().Is(StyleTokenType.Name)) {
                                        memberList.AddChild(processNode(new MemberSyntax(new MemberIdentifierSyntax(Read()))));
                                        continue;
@@ -123,6 +127,8 @@ namespace CECrowPlugin.Style
                ImlValueSyntax processNode(ImlValueSyntax iml) {
                        if (accept(iml, StyleTokenType.MemberValueOpen)) {
                                while (tryPeek(out Token tok)) {
+                                       if (cancel.IsCancellationRequested)
+                                               break;
                                        if (tok.Is(StyleTokenType.ConstantRefOpen)) {
                                                iml.AddChild(processNode(new ConstanteReferenceSyntax()));
                                        } else if (tok.Is(StyleTokenType.MemberValueClose)) {
@@ -146,15 +152,18 @@ namespace CECrowPlugin.Style
                                        accept(cst, StyleTokenType.ClosingBrace);
                        return cst;
                }
-
-               public override async Task<SyntaxRootNode> Process () {
+               CancellationToken cancel;
+               public override async Task<SyntaxRootNode> Process (CancellationToken cancel = default) {
                        Tokenizer tokenizer = new StyleTokenizer();
                        ReadOnlyTextBuffer buff = document.ImmutableBufferCopy;
                        Token[] tokens = tokenizer.Tokenize(buff.Source.Span);
                        tokIdx = 0;
+                       this.cancel = cancel;
 
                        Root = new StyleRootSyntax (buff, tokens);
                        while (!EOF) {
+                               if (cancel.IsCancellationRequested)
+                                       break;
                                if (!skipTriviaAndComments(Root))
                                        break;
                                if (!Peek().Is(StyleTokenType.Name)) {
index ef2e1c6118beac689b5a43ffe5877b67fcf922ba..28044bd8edd86df23bf963abdd53370e65510929 100644 (file)
@@ -4,6 +4,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Threading;
 using System.Threading.Tasks;
 using CrowEditBase;
 
@@ -22,7 +23,7 @@ namespace CrowEdit.Ebnf
                //NCName | StringLiteral | CharCode | CharClass | '(' Choice ')'
                // StringLiteral ::= '"' [^"]* '"' | "'" [^']* "'"      
                
-        public override async Task<SyntaxRootNode> Process()
+        public override async Task<SyntaxRootNode> Process(CancellationToken cancel = default)
         {
                        Tokenizer tokenizer = new EbnfTokenizer();
                        ReadOnlyTextBuffer buff = document.ImmutableBufferCopy;
index a270b81aba1de9d62d1591b1a91e8a3f537450a9..d38afb9813e93e5ddc33928b7f9024376f2a0ee0 100644 (file)
@@ -19,6 +19,7 @@ using Microsoft.CodeAnalysis.CSharp;
 using Microsoft.CodeAnalysis.CSharp.Syntax;
 
 using static CrowEditBase.CrowEditBase;
+using System.Threading;
 
 
 namespace CERoslynPlugin
@@ -108,8 +109,8 @@ namespace CERoslynPlugin
                        parse();
         }
         protected override void parse()
-        {
-                       tree = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText (source.ToString(), CSharpParseOptions.Default);
+        {      
+                       tree = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText (source.ToString(), CSharpParseOptions.Default, "", null);
             base.parse();
         }
     }
index 0ff1fc3fc9de3b2331f2b963ce1c5d57f778c4fc..12de25f646c0da94f069232246cea7f5aeafec12 100644 (file)
@@ -5,6 +5,7 @@ using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
+using System.Threading;
 using System.Threading.Tasks;
 using Crow.Text;
 using CrowEditBase;
@@ -54,30 +55,36 @@ namespace CERoslynPlugin
                        csdoc = document;
                }
 
-               public override async Task<SyntaxRootNode> Process () {
+               public override async Task<SyntaxRootNode> Process (CancellationToken cancel = default) {
                        ReadOnlyTextBuffer buff = document.ImmutableBufferCopy;
-                       
+                       CsharpSyntaxWalkerBridge bridge = new CsharpSyntaxWalkerBridge(new CSRootSyntax (buff), cancel);
+                       CSharpSyntaxNode csroot = await csdoc.tree.GetRootAsync(cancel);
 
-                       CsharpSyntaxWalkerBridge bridge = new CsharpSyntaxWalkerBridge(new CSRootSyntax (buff));
-                       
-                       bridge.Visit(await csdoc.tree.GetRootAsync());
+                       if (cancel.IsCancellationRequested)
+                               return null;
+
+                       bridge.Visit(csroot);
                        bridge.Root.SetTokens (bridge.Toks.ToArray());
                        Root = bridge.Root;
                        return Root;
                }
        }
-       class CsharpSyntaxWalkerBridge : Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker
+       class CsharpSyntaxWalkerBridge : CSharpSyntaxWalker
        {
                public CSRootSyntax Root;
                public List<Token> Toks;
                MultiNodeSyntax currentNode;
-               public CsharpSyntaxWalkerBridge (CSRootSyntax root) : base (SyntaxWalkerDepth.StructuredTrivia)
+               CancellationToken cancel;
+               public CsharpSyntaxWalkerBridge (CSRootSyntax root, CancellationToken cancel = default) : base (SyntaxWalkerDepth.StructuredTrivia)
                {
+                       this.cancel = cancel;
                        currentNode = Root = root;
                        Toks = new List<Token>(100);
                }
                public override void Visit (Microsoft.CodeAnalysis.SyntaxNode node)
                {
+                       if (cancel.IsCancellationRequested)
+                               return;
                        currentNode = currentNode.AddChild(new CSSyntaxNode(node)) as MultiNodeSyntax;
                        
                        base.Visit (node);
@@ -93,6 +100,9 @@ namespace CERoslynPlugin
 
                public override void VisitToken (SyntaxToken token)
                {
+                       if (cancel.IsCancellationRequested)
+                               return;
+
                        VisitLeadingTrivia (token);
 
                        Microsoft.CodeAnalysis.Text.TextSpan fs = token.Span;
@@ -113,6 +123,9 @@ namespace CERoslynPlugin
                
         public override void VisitTrivia (SyntaxTrivia trivia)
                {
+                       if (cancel.IsCancellationRequested)
+                               return;
+
                        SyntaxKind kind = trivia.Kind ();
                        Microsoft.CodeAnalysis.Text.TextSpan span = trivia.Span;
                        if (kind == SyntaxKind.EndOfLineTrivia) {
@@ -142,6 +155,8 @@ namespace CERoslynPlugin
                        startOfTok = 0;
 
                        while(!reader.EndOfSpan) {
+                               if (cancel.IsCancellationRequested)
+                                       return;
                                switch (reader.Peek) {
                                        case '\x85':
                                        case '\x2028':
index d64454e7193a259647c1cb3045ea7171eee275da..55307de9994679b791aa814b99492d83f5263cc7 100644 (file)
@@ -5,6 +5,7 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Reflection.Metadata.Ecma335;
+using System.Threading;
 using System.Threading.Tasks;
 using CrowEditBase;
 
@@ -15,7 +16,7 @@ namespace CrowEdit.Xml
                public virtual void ProcessAttributeValueSyntax(AttributeSyntax attrib) {
                        //attrib.valueTok = tokIdx - attrib.TokenIndexBase;
                }
-               public override async Task<SyntaxRootNode> Process () {
+               public override async Task<SyntaxRootNode> Process (CancellationToken cancel = default) {
                        Tokenizer tokenizer = new XmlTokenizer();
                        ReadOnlyTextBuffer buff = document.ImmutableBufferCopy;
                        Token[] tokens = tokenizer.Tokenize(buff.Source.Span);