public void DisplayBindVariableUsages(ActionExecutionContext executionContext) { var terminal = executionContext.DocumentRepository.Statements.GetTerminalAtPosition(executionContext.CaretOffset); if (terminal == null || !String.Equals(terminal.Id, Terminals.BindVariableIdentifier)) { return; } var nodes = executionContext.DocumentRepository.ValidationModels.Values .Select(v => FindUsagesCommand.GetBindVariable((OracleStatementSemanticModel)v.SemanticModel, terminal.Token.Value)) .Where(v => v != null) .SelectMany(v => v.Nodes); executionContext.SegmentsToReplace.AddRange( nodes.Select(n => new TextSegment { IndextStart = n.SourcePosition.IndexStart, Length = n.SourcePosition.Length, DisplayOptions = DisplayOptions.Usage })); }
public MultiNodeEditorData GetMultiNodeEditorData(ActionExecutionContext executionContext) { var multiNodeData = new MultiNodeEditorData { SynchronizedSegments = new SourcePosition[0] }; var terminal = executionContext.DocumentRepository.Statements.GetTerminalAtPosition(executionContext.CaretOffset, n => !String.Equals(n.Id, Terminals.Comma) && !String.Equals(n.Id, Terminals.Dot) && !String.Equals(n.Id, Terminals.RightParenthesis)); if (executionContext.SelectionLength > 0 || terminal?.Id.IsIdentifierOrAlias() != true) { return(multiNodeData); } multiNodeData.CurrentNode = terminal; var semanticModel = (OracleStatementSemanticModel)executionContext.DocumentRepository.ValidationModels[terminal.Statement].SemanticModel; OracleColumnReference columnReference; OracleQueryBlock cteQueryBlock; switch (terminal.Id) { case Terminals.ObjectAlias: var objectReference = semanticModel.AllReferenceContainers .SelectMany(c => c.ObjectReferences) .SingleOrDefault(o => o.AliasNode == terminal); var synchronizedSegments = new List <SourcePosition>(); cteQueryBlock = semanticModel.QueryBlocks.SingleOrDefault(qb => qb.AliasNode == terminal); if (objectReference == null && cteQueryBlock != null) { synchronizedSegments.AddRange(GetDataObjectReferences(cteQueryBlock).Select(o => o.ObjectNode.SourcePosition)); } var objectQualifiedColumnSynchronizedSegments = semanticModel.AllReferenceContainers .SelectMany(c => c.ColumnReferences) .Where(c => c.ObjectNode != null && c.ValidObjectReference != null && (c.ValidObjectReference == objectReference || IsCommonTableExpressionColumnReference(cteQueryBlock, c))) .Concat(GetCommonTableExpressionObjectPrefixedColumnReferences(cteQueryBlock)) .Select(c => c.ObjectNode.SourcePosition); synchronizedSegments.AddRange(objectQualifiedColumnSynchronizedSegments); multiNodeData.SynchronizedSegments = synchronizedSegments.AsReadOnly(); break; case Terminals.ObjectIdentifier: var editNodes = new List <SourcePosition>(); columnReference = semanticModel.GetReference <OracleColumnReference>(terminal); var objectReferences = new HashSet <OracleDataObjectReference>(); var dataObjectReferenceCandidate = columnReference?.ValidObjectReference as OracleDataObjectReference; if (dataObjectReferenceCandidate != null) { objectReferences.Add(dataObjectReferenceCandidate); } else { dataObjectReferenceCandidate = semanticModel.GetReference <OracleDataObjectReference>(terminal); } if (dataObjectReferenceCandidate?.Type == ReferenceType.CommonTableExpression) { objectReferences.Add(dataObjectReferenceCandidate); if (dataObjectReferenceCandidate.QueryBlocks.Count == 1) { cteQueryBlock = dataObjectReferenceCandidate.QueryBlocks.First(); var cteColumnReferences = GetCommonTableExpressionObjectPrefixedColumnReferences(cteQueryBlock); editNodes.AddRange(cteColumnReferences.Select(c => c.ObjectNode.SourcePosition)); editNodes.AddRange(GetDataObjectReferences(cteQueryBlock).Where(o => o != dataObjectReferenceCandidate).Select(o => o.ObjectNode.SourcePosition)); StatementGrammarNode cteAliasNode; if (cteQueryBlock.AliasNode == null) { cteQueryBlock = cteQueryBlock.AllPrecedingConcatenatedQueryBlocks.Last(); cteAliasNode = cteQueryBlock.AliasNode; var referencesToCte = semanticModel.AllReferenceContainers.SelectMany(c => c.ObjectReferences).Where(o => o.QueryBlocks.Count == 1 && o.QueryBlocks.First() == cteQueryBlock); objectReferences.UnionWith(referencesToCte); } else { cteAliasNode = cteQueryBlock.AliasNode; } editNodes.Add(cteAliasNode.SourcePosition); } } foreach (var dataObjectReference in objectReferences) { if (dataObjectReference.AliasNode != null && columnReference != null) { editNodes.Add(dataObjectReference.AliasNode.SourcePosition); } else if (dataObjectReference.Type == ReferenceType.CommonTableExpression && dataObjectReference.ObjectNode != terminal) { editNodes.Add(dataObjectReference.ObjectNode.SourcePosition); } if (dataObjectReference.AliasNode == null || columnReference != null) { var editNodesSource = semanticModel.AllReferenceContainers .SelectMany(c => c.ColumnReferences) .Where(r => r.ObjectNode != null && r != columnReference && r.ValidObjectReference == dataObjectReference) .Select(r => r.ObjectNode.SourcePosition); editNodes.AddRange(editNodesSource); } } multiNodeData.SynchronizedSegments = editNodes.AsReadOnly(); break; case Terminals.BindVariableIdentifier: var bindVariable = FindUsagesCommand.GetBindVariable(semanticModel, terminal.Token.Value); multiNodeData.SynchronizedSegments = bindVariable.Nodes.Where(n => n != terminal).Select(t => t.SourcePosition).ToArray(); break; case Terminals.ColumnAlias: var selectListColumn = semanticModel.AllReferenceContainers .OfType <OracleSelectListColumn>() .SingleOrDefault(c => c.AliasNode == terminal); if (selectListColumn != null) { multiNodeData.SynchronizedSegments = FindUsagesCommand.GetParentQueryBlockColumnUsages(selectListColumn) .TakeWhile(t => String.Equals(t.Token.Value.ToQuotedIdentifier(), selectListColumn.NormalizedName)) .Select(t => t.SourcePosition) .ToArray(); } else { goto case Terminals.Identifier; } break; case Terminals.Identifier: multiNodeData.SynchronizedSegments = FindUsagesCommand.GetColumnUsages(semanticModel, terminal, true) .Where(t => t != terminal) .Select(t => t.SourcePosition) .ToArray(); break; } return(multiNodeData); }