using System.Collections;
using System.Collections.Generic;
using Drawing2D;
+using System.Security;
namespace CrowEditBase
{
CMDRefreshSyntaxTree = new ActionCommand ("Reparse", parse, "#icons.refresh.svg", true);
}
- public SyntaxRootNode Root => root;
+ public SyntaxRootNode Root {
+ get => root;
+ }
+
public bool IsParsed => root != null && Tokens.Length > 0;
public ReadOnlySpan<Token> Tokens => root.Tokens;
public IEnumerable<SyntaxNode> SyntaxRootChildNodes => root?.children;
protected override void apply(TextChange change)
{
SyntaxNode editedNode = root?.FindNodeIncludingSpan (new TextSpan (change.Start, change.End));
-
base.apply(change);
-
- SyntaxAnalyser syntaxAnalyser = CreateSyntaxAnalyser ();
- root = syntaxAnalyser?.Process ();
-
- NotifyValueChanged("Exceptions", syntaxAnalyser?.Exceptions);
+ parse ();
+
//SyntaxNode changedNode = root.FindNodeIncludingSpan (TextSpan.FromStartAndLength (change.Start, change.ChangedText.Length));
protected abstract SyntaxAnalyser CreateSyntaxAnalyser ();
public abstract IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode currentNode, CharLocation loc);
- void parse () {
+ protected virtual async void parse () {
SyntaxAnalyser syntaxAnalyser = CreateSyntaxAnalyser ();
- root = syntaxAnalyser?.Process ();
+ root = await syntaxAnalyser.Process ();
NotifyValueChanged("Exceptions", syntaxAnalyser?.Exceptions);
NotifyValueChanged ("SyntaxRootChildNodes", (object)null);
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
using Crow.Text;
namespace CrowEditBase
{
public abstract class SyntaxAnalyser {
- //protected abstract void Parse(SyntaxNode node);
- protected ReadOnlyMemory<char> source;
+ protected SourceDocument document;
protected LineCollection lines;
protected SyntaxRootNode Root;
public IEnumerable<SyntaxException> Exceptions => Root?.GetAllExceptions();
public SyntaxAnalyser (SourceDocument document) {
- this.source = document.ImmutableBufferCopy;
+ this.document = document;
this.lines = document.Lines;
}
- public abstract SyntaxRootNode Process ();
+ public abstract Task<SyntaxRootNode> Process ();
#region Token handling
protected Token curTok => tokIdx < 0 ? default : tokens[tokIdx];
- protected ReadOnlySpan<char> curTokString => curTok.AsString(source.Span);
+
protected ReadOnlySpan<Token> tokens => Root.Tokens;
protected bool EOF => tokIdx == tokens.Length;
protected bool tryRead (out Token tok) {
namespace CrowEditBase
{
+ /*public class SingleTokenSyntax {
+ Token token;
+
+ }*/
public class SyntaxNode : CrowEditComponent {
+ #region CTOR
internal SyntaxNode () {}
public SyntaxNode (int startLine, int tokenBase, int? lastTokenIdx = null) {
StartLine = startLine;
if (lastTokenIdx.HasValue)
lastTokenOfset = lastTokenIdx - tokenBase;
}
-
- bool _isExpanded;
+ #endregion
+
+ internal List<SyntaxNode> children = new List<SyntaxNode> ();
+
+
internal int? lastTokenOfset;
- internal bool isFolded;
internal int lineCount;
+ #region Folding and ?expand?
+ bool _isExpanded;
+ internal bool isFolded;
public bool isExpanded {
get => _isExpanded;
NotifyValueChanged (_isExpanded);
}
}
+ public virtual bool IsFoldable => IsComplete && !(Parent != Root && Parent.StartLine == StartLine) && lineCount > 1;
public void ExpandToTheTop () {
isExpanded = true;
Parent?.ExpandToTheTop ();
}
- public SyntaxNode Parent { get; private set; }
- public int StartLine { get; private set; }
- public virtual int LineCount => lineCount;
- public virtual bool IsComplete => lastTokenOfset.HasValue;
- public virtual bool IsFoldable => IsComplete && !(Parent != Root && Parent.StartLine == StartLine) && lineCount > 1;
- public virtual SyntaxRootNode Root => Parent.Root;
public virtual void UnfoldToTheTop () {
isFolded = false;
Parent.UnfoldToTheTop ();
}
- protected Token getTokenByIndex (int idx) => Root.GetTokenByIndex(idx);
- internal List<SyntaxNode> children = new List<SyntaxNode> ();
+ public IEnumerable<SyntaxNode> VisibleFoldableNodes {
+ get {
+ if (IsFoldable) {
+ yield return this;
+ }
+ if (!isFolded) {
+ foreach (SyntaxNode n in Children) {
+ foreach (SyntaxNode folds in n.VisibleFoldableNodes)
+ yield return folds;
+ }
+ }
+ }
+ }
+ public virtual int FoldedLineCount {
+ get {
+ if (isFolded)
+ return lineCount;
+ int tmp = 0;
+ if (HasChilds) {
+ foreach (SyntaxNode n in children.Where (c => c.IsFoldable))
+ tmp += n.FoldedLineCount;
+ }
+ return tmp;
+ }
+ }
+ #endregion
+
+
+
+ public IEnumerable<SyntaxNode> Children => children;
+ public bool HasChilds => children.Count > 0;
+ public SyntaxNode Parent { get; private set; }
+ public virtual bool IsComplete => lastTokenOfset.HasValue;
+
+ public virtual SyntaxRootNode Root => Parent.Root;
+
+
+ public int StartLine { get; private set; }
+ public virtual int LineCount => lineCount;
+
+
List<SyntaxException> exceptions = new List<SyntaxException>();
+ public IEnumerable<SyntaxException> Exceptions => exceptions;
public void AddException(SyntaxException e) => exceptions.Add(e);
public void ResetExceptions(SyntaxException e) => exceptions.Clear();
- public IEnumerable<SyntaxException> Exceptions => exceptions;
public IEnumerable<SyntaxException> GetAllExceptions() {
foreach (SyntaxException e in exceptions)
yield return e;
}
}
- public IEnumerable<SyntaxNode> Children => children;
+
+ protected Token getTokenByIndex (int idx) => Root.GetTokenByIndex(idx);
+
+
//public int IndexOf (SyntaxNode node) => children.IndexOf (node);
- public bool HasChilds => children.Count > 0;
public SyntaxNode NextSibling {
get {
if (Parent != null) {
}
public virtual SyntaxNode NextSiblingOrParentsNextSibling
=> NextSibling ?? Parent.NextSiblingOrParentsNextSibling;
- public IEnumerable<SyntaxNode> VisibleFoldableNodes {
- get {
- if (IsFoldable) {
- yield return this;
- }
- if (!isFolded) {
- foreach (SyntaxNode n in Children) {
- foreach (SyntaxNode folds in n.VisibleFoldableNodes)
- yield return folds;
- }
- }
- }
- }
- public virtual int FoldedLineCount {
- get {
- if (isFolded)
- return lineCount;
- int tmp = 0;
- if (HasChilds) {
- foreach (SyntaxNode n in children.Where (c => c.IsFoldable))
- tmp += n.FoldedLineCount;
- }
- return tmp;
- }
- }
public virtual int TokenIndexBase { get; private set; }
public virtual int TokenCount => lastTokenOfset.HasValue ? lastTokenOfset.Value + 1 : 0;
return new TextSpan (startTok.Start, endTok.End);
}
}
+ public int SpanStart;
+
public SyntaxNode AddChild (SyntaxNode child) {
children.Add (child);
child.Parent = this;
protected int startOfTok;
public Tokenizer () {}
- public abstract Token[] Tokenize (ReadOnlySpan<char> source);
+ public abstract Token[] Tokenize (ReadOnlySpan<char> source = default);
/// <summary>
/// First method to call in tokenizers to init parsing variables
/// </summary>
doc.EnterReadLock();
try {
int foldedLines = 0;
+ if (!doc.IsParsed)
+ return 0;
IEnumerator<SyntaxNode> foldsEnum = doc.Root.VisibleFoldableNodes.GetEnumerator();
bool notEndOfFolds = foldsEnum.MoveNext();
while (notEndOfFolds && foldsEnum.Current.StartLine < absoluteLine) {
doc.EnterReadLock();
try {
int foldedLines = 0;
+ if (!doc.IsParsed)
+ return 0;
IEnumerator<SyntaxNode> nodeEnum = doc.Root.VisibleFoldableNodes.GetEnumerator ();
if (!nodeEnum.MoveNext())
return 0;
using System.Linq;
using CrowEditBase;
using CrowEdit.Xml;
+using System.Threading.Tasks;
namespace CECrowPlugin
{
public ImlSyntaxAnalyser (ImlDocument document) : base (document) {}
- public override SyntaxRootNode Process () {
+ public override async Task<SyntaxRootNode> Process () {
- return base.Process();
+ return await base.Process();
/*
ImlDocument xmlDoc = source as ImlDocument;
--- /dev/null
+// Copyright (c) 2021-2021 Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using CrowEditBase;
+
+namespace CECrowPlugin.Style
+{
+ public static class Extensions {
+ public static StyleTokenType GetTokenType (this Token tok) {
+ return (StyleTokenType)tok.Type;
+ }
+ public static void SetTokenType (this Token tok, StyleTokenType type) {
+ tok.Type = (TokenType)type;
+ }
+ }
+ public class StyleSyntaxAnalyser : SyntaxAnalyser {
+ public StyleSyntaxAnalyser (StyleDocument document) : base (document) {}
+
+ public override async Task<SyntaxRootNode> Process () {
+ Tokenizer tokenizer = new StyleTokenizer();
+ ReadOnlyMemory<char> source = document.ImmutableBufferCopy;
+ Token[] tokens = tokenizer.Tokenize(source.Span);
+ currentNode = Root = new StyleRootSyntax (source, tokens);
+
+ currentLine = 0;
+ tokIdx = 0;
+
+ while (tokIdx < tokens.Length) {
+ if (!skipTrivia(true))
+ break;
+ Token curTok = tokens[tokIdx];
+ if (currentNode is StyleRootSyntax srs) {
+ if (tokens[tokIdx].GetTokenType() != StyleTokenType.Name) {
+ addException ("Unexpected Token");
+ } else {
+ StyleIdentifierSyntax sis = new StyleIdentifierSyntax(currentLine, tokIdx);
+ if (!skipTrivia(true)) {
+ addException ("Unexpected end of file");
+ break;
+ }
+ if (tokens[tokIdx].GetTokenType() == StyleTokenType.EqualSign) {
+ ConstantDefinitionSyntax cds = new ConstantDefinitionSyntax(sis);
+ cds.equal = tokIdx;
+ if (!skipTrivia(true)) {
+ addException ("Unexpected end of file");
+ break;
+ }
+
+
+ }
+
+ }
+ }
+
+ tokIdx++;
+ }
+ while (currentNode.Parent != null) {
+ if (!currentNode.LastTokenIndex.HasValue)
+ finishCurrentNode (-1);
+ else
+ currentNode = currentNode.Parent;
+ }
+ setCurrentNodeEndLine (currentLine);
+
+ return Root;
+ }
+ }
+}
\ No newline at end of file
+++ /dev/null
-// Copyright (c) 2021-2021 Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using CrowEditBase;
-
-namespace CECrowPlugin.Style
-{
- public static class Extensions {
- public static StyleTokenType GetTokenType (this Token tok) {
- return (StyleTokenType)tok.Type;
- }
- public static void SetTokenType (this Token tok, StyleTokenType type) {
- tok.Type = (TokenType)type;
- }
- }
- public class StyleSyntaxAnalyser : SyntaxAnalyser {
- public StyleSyntaxAnalyser (StyleDocument document) : base (document) {}
-
- public override SyntaxRootNode Process () {
- Tokenizer tokenizer = new StyleTokenizer();
- Token[] tokens = tokenizer.Tokenize(source.Span);
-
- currentNode = Root = new StyleRootSyntax (source, tokens);
-
- currentLine = 0;
- tokIdx = 0;
-
- int firstNameIdx = -1;
-
- while (tokIdx < tokens.Length) {
- Token curTok = tokens[tokIdx];
- if (curTok.Type == TokenType.LineBreak)
- currentLine++;
- else if (!curTok.Type.HasFlag (TokenType.Trivia)) {
- /*if (currentNode is StyleRootSyntax root) {
- if (firstNameIdx < 0) {
- if (curTok.GetTokenType() == StyleTokenType.Name) {
- firstNameIdx = tokIdx;
- } else {
- Exceptions.Add (new SyntaxException ("Unexpected Token", curTok));
- }
-
- }
-
- }*/
- }
- tokIdx++;
- }
- while (currentNode.Parent != null) {
- if (!currentNode.LastTokenIndex.HasValue)
- finishCurrentNode (-1);
- else
- currentNode = currentNode.Parent;
- }
- setCurrentNodeEndLine (currentLine);
-
- return Root;
- }
- }
-}
\ No newline at end of file
public StyleRootSyntax (ReadOnlyMemory<char> source, Token[] tokens) : base (source, tokens) { }
}
public class ConstantDefinitionSyntax : SyntaxNode {
- internal int? name, equal, valueOpen, valueClose;
- public override bool IsComplete => base.IsComplete & name.HasValue & equal.HasValue &
+ internal int? equal;
+ public readonly StyleIdentifierSyntax Identifier;
+ public readonly ImlValueSyntax Value;
+ public override bool IsComplete => base.IsComplete & Identifier != null & equal.HasValue;
+ public ConstantDefinitionSyntax (StyleIdentifierSyntax id)
+ : base (id.StartLine, id.TokenIndexBase) {
+ Identifier = id;
+ }
+ }
+ public class StyleIdentifierSyntax : SyntaxNode {
+ public StyleIdentifierSyntax (int startLine, int tokenBase)
+ : base (startLine, tokenBase, tokenBase) {
+ EndLine = startLine;
+ }
+ }
+ public class ImlValueSyntax : SyntaxNode {
+ internal int? valueOpen, value, valueClose;
+ public override bool IsComplete => base.IsComplete & value.HasValue &
valueOpen.HasValue & valueClose.HasValue;
- public ConstantDefinitionSyntax (int startLine, int tokenBase)
+ public ImlValueSyntax (int startLine, int tokenBase)
: base (startLine, tokenBase) {
}
+
}
public class AttributeSyntax : SyntaxNode {
public Token? NameToken { get; internal set; }
using System;
using System.Collections.Generic;
+using System.Threading.Tasks;
using CrowEditBase;
namespace CrowEdit.Ebnf
//NCName | StringLiteral | CharCode | CharClass | '(' Choice ')'
// StringLiteral ::= '"' [^"]* '"' | "'" [^']* "'"
- public override SyntaxRootNode Process()
+ public override async Task<SyntaxRootNode> Process()
{
Tokenizer tokenizer = new EbnfTokenizer();
+ ReadOnlyMemory<char> source = document.ImmutableBufferCopy;
Token[] tokens = tokenizer.Tokenize(source.Span);
-
currentNode = Root = new EbnfRootSyntax (source, tokens);
+
currentLine = 0;
tokIdx = 0;
App.GetService<RoslynService> ()?.Start ();
}
- CSharpSyntaxTree tree;
+ internal CSharpSyntaxTree tree;
public CSDocument (string fullPath, string editorPath) : base (fullPath, editorPath) {
tree = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText (source.ToString(), CSharpParseOptions.Default);
- var root = tree.GetRoot();
}
#region SourceDocument abstract class implementation
return Colors.DarkSlateBlue;
return Colors.Red;
- }
+ }
+
+ protected override void apply(TextChange change)
+ {
+ buffer.Update(change);
+ NotifyValueChanged ("IsDirty", IsDirty);
+ CMDSave.CanExecute = IsDirty;
- }
+ parse();
+ }
+ protected override void parse()
+ {
+ tree = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText (source.ToString(), CSharpParseOptions.Default);
+ base.parse();
+ }
+ }
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
using CrowEditBase;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
{
throw new NotImplementedException();
}*/
+ CSDocument csdoc;
+ public CSSyntaxAnalyser (CSDocument document) : base (document) {
+ csdoc = document;
+ }
- public CSSyntaxAnalyser (CSDocument document) : base (document) {}
-
- public override SyntaxRootNode Process () {
- CSTokenizer tokenizer = new CSTokenizer();
- Token[] tokens = tokenizer.Tokenize(source.Span);
-
-
-
+ public override async Task<SyntaxRootNode> Process () {
+ CSTokenizer tokenizer = new CSTokenizer(csdoc.tree);
+ ReadOnlyMemory<char> source = document.ImmutableBufferCopy;
+ Token[] tokens = tokenizer.Tokenize();
CsharpSyntaxWalkerBridge bridge = new CsharpSyntaxWalkerBridge(new CSRootSyntax (source, tokens));
- bridge.Visit(tokenizer.syntaxTree.GetRoot());
-
- Root = bridge.Root;
-
+ bridge.Visit(await tokenizer.syntaxTree.GetRootAsync());
+ Root = bridge.Root;
return Root;
}
}
{
public class CSTokenizer : Tokenizer
{
- protected List<Token> Toks;
public SyntaxTree syntaxTree;
+ public CSTokenizer(SyntaxTree syntaxTree) {
+ this.syntaxTree = syntaxTree;
+ }
- public override Token[] Tokenize(ReadOnlySpan<char> source)
+ public override Token[] Tokenize(ReadOnlySpan<char> source = default)
{
/*foreach (var e in Enum.GetNames(typeof(SyntaxKind))) {
Console.WriteLine($"case SyntaxKind.{e}:");
Console.WriteLine($"\treturn CSTokenType.Unknown;");
}*/
- syntaxTree = CSharpSyntaxTree.ParseText(source.ToString());
+// syntaxTree = CSharpSyntaxTree.ParseText(source.ToString());
CsharpSyntaxWalkerTokenizer bridge = new CsharpSyntaxWalkerTokenizer();
bridge.Visit(syntaxTree.GetRoot());
Toks = bridge.Toks;
return "#icons.file_type_csharp.svg";
case ".svg":
return "#icons.file_type_svg.svg";
- case ".crow":
case ".xml":
return "#icons.file_type_xml.svg";
+ case ".crow":
+ case ".template":
+ case ".itemp":
+ case ".iml":
+ return "#icons.file_type_xml.svg";
default:
return "#icons.blank-file.svg";
}
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
+using System.Threading.Tasks;
using CrowEditBase;
namespace CrowEdit.Xml
public virtual void ProcessAttributeValueSyntax(AttributeSyntax attrib) {
attrib.valueTok = tokIdx - attrib.TokenIndexBase;
}
- public override SyntaxRootNode Process () {
+ public override async Task<SyntaxRootNode> Process () {
Tokenizer tokenizer = new XmlTokenizer();
+ ReadOnlyMemory<char> source = document.ImmutableBufferCopy;
Token[] tokens = tokenizer.Tokenize(source.Span);
-
currentNode = Root = new XMLRootSyntax (source, tokens);
+
currentLine = 0;
tokIdx = 0;
using System.Linq;
using System.Text;
using Drawing2D;
+using System.Diagnostics;
namespace CrowEdit
{
} catch (Exception ex) {
MessageBox.ShowModal (this, MessageBox.Type.Alert, $"Unable to open {filePath}.\n{ex.Message}");
Log(LogType.Error, $"Unable to open {filePath}.\n{ex.Message}");
+ Debug.WriteLine(ex.Message);
+ Debug.WriteLine(ex.StackTrace);
}
return doc;
}