Пример #1
0
 public ActionExecutionContext(string statementText, int caretOffset, int selectionStart, int selectionLength, SqlDocumentRepository documentRepository)
 {
     StatementText      = statementText;
     SelectedSegments   = new[] { SourcePosition.Create(selectionStart, selectionLength) };
     SelectionStart     = selectionStart;
     SelectionLength    = selectionLength;
     CaretOffset        = caretOffset;
     DocumentRepository = documentRepository;
 }
Пример #2
0
 public static ActionExecutionContext Create(TextEditor editor, SqlDocumentRepository documentRepository)
 {
     return
         (new ActionExecutionContext(editor.Text, editor.CaretOffset, editor.SelectionStart, editor.SelectionLength, documentRepository)
     {
         SelectedSegments = editor.TextArea.Selection.Segments
                            .Select(s => SourcePosition.Create(s.StartOffset, s.EndOffset - 1))
                            .ToArray()
     });
 }
Пример #3
0
        public IEnumerable <ICodeSnippet> GetSnippets(SqlDocumentRepository sqlDocumentRepository, string statementText, int cursorPosition)
        {
            if (sqlDocumentRepository?.Statements == null)
            {
                return(EmptyCollection);
            }

            var statement = sqlDocumentRepository.Statements.TakeWhile(s => s.SourcePosition.IndexStart <= cursorPosition - 1).LastOrDefault();

            StatementGrammarNode currentNode = null;

            if (statement != null)
            {
                currentNode =
                    statement.GetTerminalAtPosition(cursorPosition)
                    ?? statement.GetNearestTerminalToPosition(cursorPosition);
            }

            if (currentNode != null &&
                String.Equals(currentNode.Id, OracleGrammarDescription.Terminals.RightParenthesis) &&
                !String.Equals(currentNode.ParentNode.Id, OracleGrammarDescription.NonTerminals.CommonTableExpression) &&
                currentNode.PrecedingTerminal?.PrecedingTerminal != null)
            {
                currentNode = currentNode.PrecedingTerminal.PrecedingTerminal;
            }

            var textToReplace = new String(statementText.Substring(0, cursorPosition).Reverse().TakeWhile(c => !c.In(' ', '\n', '\t', '(', '\r', ';')).Reverse().ToArray());

            if (String.IsNullOrWhiteSpace(textToReplace))
            {
                return(EmptyCollection);
            }

            var candidates = OracleSqlParser.Instance.GetTerminalCandidates(currentNode).Select(c => c.Id);

            return(Snippets.SnippetCollection.Where(s => s.Name.ToUpperInvariant().Contains(textToReplace.ToUpperInvariant()) &&
                                                    (s.AllowedTerminals == null || s.AllowedTerminals.Length == 0 || s.AllowedTerminals.Select(t => t.Id).Intersect(candidates).Any()))
                   .Select(s => BuildCodeSnippet(s, SourcePosition.Create(cursorPosition - textToReplace.Length, cursorPosition))).ToArray());
        }
Пример #4
0
        private static IEnumerable <SourcePosition> FindCorrespondingStringQuotation(StatementGrammarNode terminal, int cursorPosition)
        {
            if (!String.Equals(terminal.Id, Terminals.StringLiteral))
            {
                yield break;
            }

            var value     = terminal.Token.Value;
            var trimIndex = OracleExtensions.GetTrimIndex(value, out var isQuotedString, out var quoteInitializer);

            if (!isQuotedString)
            {
                yield break;
            }

            var startPosition = terminal.SourcePosition.IndexStart;

            yield return(SourcePosition.Create(startPosition, startPosition + trimIndex - 1));

            if (value[value.Length - 1] == '\'')
            {
                yield return(SourcePosition.Create(startPosition + value.Length - 2, startPosition + value.Length - 1));
            }
        }
Пример #5
0
        private static StatementCollection ProceedGrammar(IEnumerable <OracleToken> tokens, CancellationToken cancellationToken)
        {
            var allTokens     = new List <IToken>();
            var tokenBuffer   = new List <OracleToken>();
            var commentBuffer = new List <OracleToken>();

            foreach (var token in tokens)
            {
                if (token.CommentType == CommentType.None)
                {
                    tokenBuffer.Add(token);
                }
                else
                {
                    commentBuffer.Add(token);
                }

                allTokens.Add(token);
            }

            var oracleSqlCollection = new List <StatementBase>();

            if (tokenBuffer.Count == 0)
            {
                return(new OracleStatementCollection(oracleSqlCollection, allTokens, commentBuffer.Select(c => new StatementCommentNode(null, c))));
            }

            do
            {
                var result  = new ParseResult();
                var context =
                    new ParseContext
                {
                    CancellationToken = cancellationToken,
                    Statement         = new OracleStatement(),
                    TokenBuffer       = tokenBuffer
                };

                foreach (var nonTerminal in AvailableNonTerminals)
                {
                    var newResult = ProceedNonTerminal(context, nonTerminal, 1, 0, false, nonTerminal.TargetRule.Scope);

                    //if (newResult.Nodes.SelectMany(n => n.AllChildNodes).Any(n => n.Terminals.Count() != n.TerminalCount))
                    //	throw new ApplicationException("StatementGrammarNode TerminalCount value is invalid. ");

                    if (newResult.Status != ParseStatus.Success)
                    {
                        if (result.BestCandidates == null || newResult.BestCandidates.Sum(n => n.TerminalCount) > result.BestCandidates.Sum(n => n.TerminalCount))
                        {
                            result = newResult;
                        }

                        continue;
                    }

                    result = newResult;

                    var lastTerminal = result.Nodes[result.Nodes.Count - 1].LastTerminalNode;
                    if (lastTerminal == null ||
                        !TerminatorIds.Contains(lastTerminal.Id) && tokenBuffer.Count > result.Nodes.Sum(n => n.TerminalCount))
                    {
                        if (lastTerminal != null)
                        {
                            var lastToken           = result.BestCandidates.Last().LastTerminalNode.Token;
                            var parsedTerminalCount = result.BestCandidates.Sum(n => n.TerminalCount);
                            context.Statement.FirstUnparsedToken = tokenBuffer.Count > parsedTerminalCount ? tokenBuffer[parsedTerminalCount] : lastToken;
                        }

                        result.Status = ParseStatus.SequenceNotFound;
                    }

                    break;
                }

                int indexStart;
                int indexEnd;
                if (result.Status != ParseStatus.Success)
                {
                    if (result.BestCandidates.Sum(n => n.TerminalCount) > result.Nodes.Sum(n => n.TerminalCount))
                    {
                        result.Nodes = result.BestCandidates;
                    }

                    indexStart = tokenBuffer.First().Index;

                    var index = tokenBuffer.FindIndex(t => TerminatorValues.Contains(t.Value));
                    if (index == -1)
                    {
                        var lastToken = tokenBuffer[tokenBuffer.Count - 1];
                        indexEnd = lastToken.Index + lastToken.Value.Length - 1;
                        tokenBuffer.Clear();
                    }
                    else
                    {
                        indexEnd = tokenBuffer[index].Index;
                        tokenBuffer.RemoveRange(0, index + 1);
                    }
                }
                else
                {
                    var lastTerminal = result.Nodes[result.Nodes.Count - 1].LastTerminalNode.Token;
                    indexStart = result.Nodes[0].FirstTerminalNode.Token.Index;
                    indexEnd   = lastTerminal.Index + lastTerminal.Value.Length - 1;

                    tokenBuffer.RemoveRange(0, result.Nodes.Sum(n => n.TerminalCount));

                    var hasInvalidGrammarNodes = result.Nodes.Any(HasInvalidGrammarNodes);
                    if (hasInvalidGrammarNodes)
                    {
                        result.Status = ParseStatus.SequenceNotFound;
                    }
                }

                var lastNode = result.Nodes.LastOrDefault();
                if (lastNode?.FirstTerminalNode != null && TerminatorIds.Contains(lastNode.FirstTerminalNode.Id))
                {
                    context.Statement.TerminatorNode = lastNode.FirstTerminalNode;
                    result.Nodes.Remove(lastNode);
                }

                context.Statement.SourcePosition = SourcePosition.Create(indexStart, indexEnd);
                var rootNode =
                    new StatementGrammarNode(NodeType.NonTerminal, context.Statement, null)
                {
                    Id             = result.NodeId,
                    IsGrammarValid = result.Nodes.All(n => n.IsGrammarValid),
                    IsRequired     = true,
                };

                rootNode.AddChildNodes(result.Nodes);

                context.Statement.RootNode    = rootNode;
                context.Statement.ParseStatus = result.Status;

                oracleSqlCollection.Add(context.Statement);
            }while (tokenBuffer.Count > 0);

            var commentNodes = AddCommentNodes(oracleSqlCollection, commentBuffer);

            return(new OracleStatementCollection(oracleSqlCollection, allTokens, commentNodes));
        }
Пример #6
0
        private static List <SourcePosition> FindCorrespondingBeginIfAndCaseTerminals(StatementGrammarNode terminal)
        {
            var correlatedSegments = new List <SourcePosition>();

            if (!terminal.Id.In(Terminals.Case, Terminals.End, Terminals.If, Terminals.Loop, Terminals.Begin) ||
                !terminal.ParentNode.Id.In(NonTerminals.CaseExpression, NonTerminals.PlSqlBasicLoopStatement, NonTerminals.PlSqlIfStatement, NonTerminals.PlSqlCaseStatement, NonTerminals.ProgramEnd, NonTerminals.PackageBodyInitializeSection, NonTerminals.ProgramBody))
            {
                return(correlatedSegments);
            }

            var includePreviousChild = false;

            foreach (var child in terminal.ParentNode.ChildNodes)
            {
                if (child.Id.In(Terminals.Case, Terminals.End, Terminals.If, Terminals.Loop))
                {
                    if (includePreviousChild)
                    {
                        var index = correlatedSegments.Count - 1;
                        correlatedSegments[index] = SourcePosition.Create(correlatedSegments[index].IndexStart, child.SourcePosition.IndexEnd);
                    }
                    else
                    {
                        correlatedSegments.Add(child.SourcePosition);
                    }

                    if (String.Equals(terminal.ParentNode.Id, NonTerminals.ProgramEnd))
                    {
                        var begin = terminal.ParentNode.ParentNode[Terminals.Begin];
                        if (begin != null)
                        {
                            correlatedSegments.Add(begin.SourcePosition);
                        }
                    }

                    includePreviousChild = true;
                }
                else if (String.Equals(child.Id, Terminals.Begin))
                {
                    var endTerminal = terminal.ParentNode[NonTerminals.ProgramEnd, Terminals.End];
                    if (endTerminal != null)
                    {
                        correlatedSegments.Add(child.SourcePosition);
                        correlatedSegments.Add(endTerminal.SourcePosition);
                    }

                    break;
                }
                else
                {
                    includePreviousChild = false;
                }
            }

            if (correlatedSegments.Count == 1)
            {
                correlatedSegments.Clear();
            }

            return(correlatedSegments);
        }
Пример #7
0
 private static SourcePosition CreateNodePosition(StatementNode movedNode, StatementGrammarNode nodeToExchange)
 {
     return(nodeToExchange == null
                         ? SourcePosition.Empty
                         : SourcePosition.Create(nodeToExchange.SourcePosition.IndexStart, GetLastNonChainingNodePosition(nodeToExchange, movedNode.ParentNode.Id)));
 }