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; }
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() }); }
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()); }
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)); } }
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)); }
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); }
private static SourcePosition CreateNodePosition(StatementNode movedNode, StatementGrammarNode nodeToExchange) { return(nodeToExchange == null ? SourcePosition.Empty : SourcePosition.Create(nodeToExchange.SourcePosition.IndexStart, GetLastNonChainingNodePosition(nodeToExchange, movedNode.ParentNode.Id))); }