public void HandleClosedFile(SkriptFile file)
 {
     if (Current.Files.ContainsKey(file.Url))
     {
         Current.Files.TryRemove(file.Url, out _);
     }
 }
Exemplo n.º 2
0
 protected sealed override void Inspect(SkriptFile file, int line, AbstractFileNode node)
 {
     if (node.MatchedSyntax != null)
     {
         Inspect(file, line, node, node.MatchedSyntax);
     }
 }
 public void HandleOpenedFile(SkriptFile file)
 {
     if (!Current.Files.ContainsKey(file.Url))
     {
         Current.Files[file.Url] = file;
     }
 }
        public sealed override void Inspect(SkriptFile file, int line)
        {
            var node = file.Nodes[line];

            if (node != null)
            {
                Inspect(file, line, node);
            }
        }
Exemplo n.º 5
0
        public void AssertResource(string name)
        {
            var parser = new AnnotationParser();

            parser.RegisterAnnotation <AssertInspectionAnnotation>();
            SkriptFile file = null;

            var host = new InspectionDelegatingHost((uri, list) =>
            {
                foreach (var diagnostic in list)
                {
                    // ReSharper disable AccessToModifiedClosure
                    Debug.Assert(file != null, nameof(file) + " != null");

                    var node = file.Nodes[diagnostic.Range.Start.Line];

                    //TODO: Allow multiple annotations to a single node by parsing the comments directly above.
                    var comment = node.RawComment.TrimStart('#').Trim();
                    if (!comment.StartsWith("@"))
                    {
                        continue;
                    }

                    var annotation = parser.TryParse(comment);

                    switch (annotation)
                    {
                    case AssertInspectionAnnotation assertInspectionAnnotation:
                        Assert.Equal(assertInspectionAnnotation.InspectionType, diagnostic.Code);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(nameof(annotation));
                    }


                    // ReSharper restore AccessToModifiedClosure
                }
            });

            WorkspaceManager.CurrentHost = host;
            var current = WorkspaceManager.CurrentWorkspace;

            var code = ReadResource(name);

            file = new SkriptFile(new Uri($"memory://{name}"));

            file.HandleChange(new TextDocumentContentChangeEvent
            {
                Text = code
            });

            file.PrepareNodes();

            parser.UnregisterAnnotation <AssertInspectionAnnotation>();
        }
        public override void DoWork(SkriptFile file, int lineNumber, string rawContent, FileParseContext context)
        {
            var node = file.Nodes[lineNumber];

            //Only attempt to parse already matched syntax if the user is changing the contents of the file
            if (!context.File.IsDoingNodesChange && node.MatchedSyntax != null)
            {
                return;
            }

            var workDone = false;

            foreach (var elements in WorkspaceManager.Instance.Current.AddonDocumentations.Select(addon =>
                                                                                                  node.IsSectionNode
                    ? addon.Events
                    : addon.Expressions.Cast <AbstractSyntaxElement>().Concat(addon.Effects)))
            {
                foreach (var effect in elements)
                {
                    for (var index = 0; index < effect.PatternNodes.Length; index++)
                    {
                        var effectPattern = effect.PatternNodes[index];

                        context.Matches     = new List <ParseMatch>();
                        context.CurrentLine = lineNumber;
                        var result = effectPattern.Parse(context);
                        if (result.IsSuccess)
                        {
                            result.Context     = context.Clone();
                            result.Matches     = result.Context.Matches;
                            node.MatchedSyntax = new SyntaxMatch(effect, result)
                            {
                                PatternIndex = index
                            };
                            workDone = true;
                        }

                        if (workDone)
                        {
                            break;
                        }
                    }

                    if (workDone)
                    {
                        break;
                    }
                }

                if (workDone)
                {
                    break;
                }
            }
        }
Exemplo n.º 7
0
        public sealed override void DoWork(SkriptFile file, int lineNumber, string rawContent, FileParseContext context)
        {
            if (!CanInspect(file, lineNumber))
            {
                return;
            }

            StaticProblemsHolder.Value = file.ProblemsHolder;
            Inspect(file, lineNumber);
            StaticProblemsHolder.Value = null;
        }
Exemplo n.º 8
0
        protected override void Inspect(SkriptFile file, int line, AbstractFileNode node)
        {
            var signatureRequiresSection = node.GetType().GetCustomAttribute <SectionNodeAttribute>() != null;
            var isSectionMismatch        = node.IsSectionNode !=
                                           signatureRequiresSection;

            if (isSectionMismatch)
            {
                AddProblem(DiagnosticSeverity.Error,
                           $"{(signatureRequiresSection ? "E" : "Une")}xpected section at the end of this line", node);
            }
        }
Exemplo n.º 9
0
        protected override void Inspect(SkriptFile file, int line, AbstractFileNode node, SyntaxMatch match)
        {
            var cancelEvent = node.GetSyntaxNode <EffCancelEvent>();

            if (cancelEvent == null)
            {
                return;
            }

            if (node.RootParentSyntax?.Element is SkriptEvent @event && [email protected])
            {
                AddProblem(DiagnosticSeverity.Error,
                           $"This event can't be {(!cancelEvent.ToCancel ? "un" : "")}cancelled.", node);
            }
        }
        public void MatchesMessagePlayer(string code, int expectedMatches)
        {
            var file = new SkriptFile(new Uri("memory://file"))
            {
                RawContents = ("on chat:\n" +
                               "    " + code).SplitOnNewLines()
            };

            WorkspaceManager.Instance.HandleOpenedFile(file);
            file.PrepareNodes();
            var effMessageNode = file.Nodes[1];

            Assert.NotNull(effMessageNode);
            Assert.NotNull(effMessageNode.MatchedSyntax);
            Assert.True(effMessageNode.MatchedSyntax.Result.IsSuccess);
            Assert.Equal(expectedMatches, effMessageNode.MatchedSyntax.Result.Matches.Count);
        }
Exemplo n.º 11
0
        public void FileKnowsHowToSwitchLinesOnTheContext(int count)
        {
            const string selector    = "abcd";
            var          fileContent = string.Join("\n", Enumerable.Range(0, count).Select(_ => selector));

            var file = new SkriptFile(MemoryFile)
            {
                RawContents = fileContent.SplitOnNewLines()
            };

            for (var i = 0; i < count; i++)
            {
                Assert.Equal(selector, file.ParseContext.ReadNext(selector.Length));
            }

            Assert.True(file.ParseContext.HasReachedEndOfFile);
        }
        public void EmptyUnitTest()
        {
            Debugger.Break();
            var code = "{_test}.hello().world().bruh()";

            var file = new SkriptFile(new Uri("memory://file"))
            {
                RawContents = ("on chat:\n" +
                               "    " + code).SplitOnNewLines()
            };

            WorkspaceManager.Instance.HandleOpenedFile(file);
            file.PrepareNodes();

            var node = file.Nodes[1];

            Debugger.Break();
            _testOutputHelper.WriteLine(node.ToJson());
        }
Exemplo n.º 13
0
        public void BasicNodeInformationIsCorrect()
        {
            AbstractFileNode resultNode  = new BaseFileNode();
            const string     content     = "this is a##test";
            const string     rawContent  = @"    " + content + " #comment";
            const int        lineNumber  = 0;
            var expectedContentRange     = RangeExtensions.From(lineNumber, 4, 19);
            var expectedCommentRange     = RangeExtensions.From(lineNumber, 19, 28);
            var expectedIndentationRange = RangeExtensions.From(lineNumber, 0, 4);

            var file = new SkriptFile(new Uri("memory://tests"));

            NodeContentHelper.ApplyBasicNodeInfoToNode(rawContent, lineNumber, file, ref resultNode);

            Assert.Equal(content, resultNode.NodeContent);
            Assert.Equal(expectedContentRange, resultNode.ContentRange);
            Assert.Equal(expectedCommentRange, resultNode.CommentRange);
            Assert.Equal(expectedIndentationRange, resultNode.IndentationRange);
            Assert.Equal(new[] { new NodeIndentation(IndentType.Space, 4) }, resultNode.Indentations);
            Assert.Single(resultNode.Indentations);
        }
        public static void ApplyBasicNodeInfoToNode(string content, int line, SkriptFile file,
                                                    ref AbstractFileNode node)
        {
            ExtractBasicNodeInformationFrom(content, line, out var indentations, out var indentRange,
                                            out var contentRange, out var nodeRange, out var commentRange, out var commentContent,
                                            out var nodeContent);

            node.RawText          = content;
            node.LineNumber       = line;
            node.Indentations     = indentations;
            node.IndentationRange = indentRange;
            node.Range            = nodeRange;
            node.CommentRange     = commentRange;
            node.RawComment       = commentContent;
            node.ContentRange     = contentRange;
            node.NodeContent      = nodeContent;
            node.File             = file;

            if (nodeContent.EndsWith(":"))
            {
                node.IsSectionNode = true;
            }
        }
Exemplo n.º 15
0
        public void KnowsHowToParseSimpleSendEffect()
        {
            var url      = new Uri("memory://file1");
            var contents = "on chat\n    send \"hi\"".SplitOnNewLines();
            var file     = new SkriptFile(url)
            {
                RawContents = contents
            };

            WorkspaceManager.Instance.HandleOpenedFile(file);
            file.PrepareNodes();

            file.HandleChange(new TextDocumentContentChangeEvent
            {
                Range       = RangeExtensions.From(0, 7, 7),
                RangeLength = 1,
                Text        = ":"
            });

            Assert.Equal(2, file.Nodes.Count);

            //Basic node match just to be sure
            for (var i = 0; i < file.Nodes.Count; i++)
            {
                Assert.Equal(contents[i], file.Nodes[i].ToString());
            }


            var results = new[] { "org.bukkit.event.player.AsyncPlayerChatEvent", "ch.njol.skript.effects.EffMessage" };

            for (var i = 0; i < results.Length; i++)
            {
                Assert.True(file.Nodes[i].IsMatchOfType(results[i]),
                            $"{i}: {file.Nodes[i].NodeContent} supposed to be {results[i]}");
            }
        }
 protected abstract void Inspect(SkriptFile file, int line, AbstractFileNode node);
 protected virtual bool CanInspect(SkriptFile file, int line, AbstractFileNode node)
 {
     return(true);
 }
Exemplo n.º 18
0
 public abstract void DoWork(SkriptFile file, int lineNumber, string rawContent, FileParseContext context);
Exemplo n.º 19
0
        public void KnowsHowToHandleParentsAndChildren()
        {
            var url      = new Uri("memory://file1");
            var contents = (
                "on chat\n" +
                "    if message contains \"h\"\n" +
                "        if message contains \"i\"\n" +
                "            send \"hi\""
                ).SplitOnNewLines();
            var file = new SkriptFile(url)
            {
                RawContents = contents
            };

            WorkspaceManager.Instance.HandleOpenedFile(file);
            file.PrepareNodes();

            file.HandleChange(new TextDocumentContentChangeEvent
            {
                Range       = RangeExtensions.From(2, 31, 31),
                RangeLength = 1,
                Text        = ":"
            });

            file.HandleChange(new TextDocumentContentChangeEvent
            {
                Range       = RangeExtensions.From(1, 27, 27),
                RangeLength = 1,
                Text        = ":"
            });

            file.HandleChange(new TextDocumentContentChangeEvent
            {
                Range       = RangeExtensions.From(0, 7, 7),
                RangeLength = 1,
                Text        = ":"
            });

            Assert.Equal(4, file.Nodes.Count);

            //Basic node match just to be sure
            for (var i = 0; i < file.Nodes.Count; i++)
            {
                Assert.Equal(contents[i], file.Nodes[i].ToString());
            }


            var results = new[]
            { "org.bukkit.event.player.AsyncPlayerChatEvent", "", "", "ch.njol.skript.effects.EffMessage" };

            for (var i = 0; i < results.Length; i++)
            {
                if (!string.IsNullOrEmpty(results[i]))
                {
                    Assert.True(file.Nodes[i].IsMatchOfType(results[i]),
                                $"{i}: {file.Nodes[i].NodeContent} supposed to be {results[i]}");
                }
            }


            Assert.Equal(file.Nodes[0], file.Nodes[1].Parent);
            Assert.Equal(file.Nodes[1], file.Nodes[2].Parent);
            Assert.Equal(file.Nodes[2], file.Nodes[3].Parent);
        }
Exemplo n.º 20
0
 /// <summary>
 /// Inspect the code.
 /// </summary>
 /// <param name="file">The file to get inspected</param>
 /// <param name="line">The line number from the file to inspect</param>
 /// <param name="problemHolder">The instance that holds the problems that are found by this inspection</param>
 public abstract void Inspect(SkriptFile file, int line);
Exemplo n.º 21
0
 /// <summary>
 /// A simple check performed to see if a certain line of a file can be inspected by the current inspection.
 /// </summary>
 /// <param name="file">The file to get inspected</param>
 /// <param name="line">The line number from the file to inspect</param>
 /// <returns></returns>
 public abstract bool CanInspect(SkriptFile file, int line);
Exemplo n.º 22
0
 protected sealed override bool CanInspect(SkriptFile file, int line, AbstractFileNode node)
 {
     return(node.MatchedSyntax != null && node.MatchedSyntax.Result.IsSuccess &&
            CanInspect(file, line, node, node.MatchedSyntax));
 }
Exemplo n.º 23
0
        public override void DoWork(SkriptFile file, int lineNumber, string rawContent, FileParseContext context)
        {
            AbstractFileNode resultNode = new BaseFileNode();

            NodeContentHelper.ApplyBasicNodeInfoToNode(rawContent, lineNumber, file, ref resultNode);

            if (resultNode.NodeContent.IsEmpty() && !resultNode.RawComment.IsEmpty())
            {
                AbstractFileNode commentNode = new CommentLineNode();
                NodeContentHelper.ApplyBasicNodeInfoToOtherNode(resultNode, ref commentNode);
                resultNode = commentNode;
            }
            else if (resultNode.NodeContent.IsEmpty() && resultNode.RawComment.IsEmpty())
            {
                AbstractFileNode emptyLineNode = new EmptyLineNode();
                emptyLineNode.MatchedSyntax =
                    new SyntaxMatch(SignatureElements.EmptyLine, ParseResult.Success(context));
                NodeContentHelper.ApplyBasicNodeInfoToOtherNode(resultNode, ref emptyLineNode);
                resultNode = emptyLineNode;
            }
            else
            {
                if (file.IsNodeVisible(resultNode))
                {
                    var ctx = ParseContext.FromCode(rawContent);

                    var signatureMatches = new List <(bool isSectionMismatch, AbstractFileNode node)>();
                    //Try to match to one of our known signatures
                    foreach (var(signatureNodeType, signatureDelegate) in NodeSignaturesManager.Instance.SignatureTypes
                             )
                    {
                        ctx.Matches.Clear();
                        ctx.CurrentPosition = context.IndentationChars;

                        var isSectionTypeMismatch = resultNode.IsSectionNode !=
                                                    (signatureNodeType.GetCustomAttribute <SectionNodeAttribute>() !=
                                                     null);


                        var tryParseResult = signatureDelegate.DynamicInvoke(ctx);

                        // We matched one signature
                        if (tryParseResult != null && ctx.HasFinishedLine)
                        {
                            var instance = signatureNodeType.NewInstance(tryParseResult);

                            if (instance is AbstractFileNode fileNode)
                            {
                                NodeContentHelper.ApplyBasicNodeInfoToOtherNode(resultNode, ref fileNode);
                                signatureMatches.Add((isSectionTypeMismatch, fileNode));
                            }

                            if (!isSectionTypeMismatch)
                            {
                                break;
                            }
                        }
                    }

                    var resultingNode = signatureMatches.FirstOrDefault(x => !x.isSectionMismatch).node;
                    if (resultingNode != null)
                    {
                        resultNode = resultingNode;
                    }
                }
            }

            file.Nodes[lineNumber] = resultNode;
        }
Exemplo n.º 24
0
 protected override bool CanInspect(SkriptFile file, int line, AbstractFileNode node)
 {
     return(node.MatchedSyntax == null && node.GetType().IsSubclassOfRawGeneric(typeof(SignatureFileNode <>)));
 }
 public sealed override bool CanInspect(SkriptFile file, int line)
 {
     return(file.Nodes[line] != null && CanInspect(file, line, file.Nodes[line]));
 }
Exemplo n.º 26
0
 protected abstract void Inspect(SkriptFile file, int line, AbstractFileNode node, SyntaxMatch match);