public IToolTip GetToolTip(SqlDocumentRepository sqlDocumentRepository, int cursorPosition)
        {
            if (sqlDocumentRepository == null)
            {
                throw new ArgumentNullException(nameof(sqlDocumentRepository));
            }

            var node = sqlDocumentRepository.Statements.GetNodeAtPosition(cursorPosition);

            if (node == null)
            {
                var statement = sqlDocumentRepository.Statements.GetStatementAtPosition(cursorPosition);
                if (statement?.FirstUnparsedToken == null)
                {
                    return(null);
                }

                if (cursorPosition < statement.FirstUnparsedToken.Index || cursorPosition > statement.FirstUnparsedToken.Index + statement.FirstUnparsedToken.Value.Length)
                {
                    return(null);
                }

                return(BuildExpectedTokenListToolTip(statement.LastTerminalNode));
            }

            var tip = node.Type == NodeType.Terminal && !node.Id.IsIdentifier() ? node.Id : null;

            var validationModel = (OracleValidationModel)sqlDocumentRepository.ValidationModels[node.Statement];

            var nodeSemanticError = validationModel.SemanticErrors
                                    .Concat(validationModel.Suggestions)
                                    .FirstOrDefault(v => node.HasAncestor(v.Node, true));

            if (nodeSemanticError != null)
            {
                tip = nodeSemanticError.ToolTipText;
            }
            else
            {
                var semanticModel = validationModel.SemanticModel;
                var queryBlock    = semanticModel.GetQueryBlock(node);

                var toolTipBuilderVisitor = new OracleToolTipBuilderVisitor(node);

                switch (node.Id)
                {
                case Terminals.Asterisk:
                    return(BuildAsteriskToolTip(queryBlock, node));

                case Terminals.Min:
                case Terminals.Max:
                case Terminals.Sum:
                case Terminals.Avg:
                case Terminals.FirstValue:
                case Terminals.Count:
                case Terminals.Cast:
                case Terminals.Trim:
                case Terminals.CharacterCode:
                case Terminals.Variance:
                case Terminals.StandardDeviation:
                case Terminals.LastValue:
                case Terminals.Lead:
                case Terminals.Lag:
                case Terminals.ListAggregation:
                case Terminals.CumulativeDistribution:
                case Terminals.Rank:
                case Terminals.DenseRank:
                case Terminals.PercentileDiscreteDistribution:
                case Terminals.PercentileContinuousDistribution:
                case Terminals.NegationOrNull:
                case Terminals.RowIdPseudocolumn:
                case Terminals.RowNumberPseudocolumn:
                case Terminals.User:
                case Terminals.Level:
                case Terminals.Extract:
                case Terminals.JsonQuery:
                case Terminals.JsonExists:
                case Terminals.JsonValue:
                case Terminals.XmlCast:
                case Terminals.XmlElement:
                case Terminals.XmlSerialize:
                case Terminals.XmlParse:
                case Terminals.XmlQuery:
                case Terminals.XmlRoot:
                case Terminals.XmlForest:
                case Terminals.PlSqlIdentifier:
                case Terminals.ExceptionIdentifier:
                case Terminals.CursorIdentifier:
                case Terminals.DataTypeIdentifier:
                case Terminals.ObjectIdentifier:
                case Terminals.SchemaIdentifier:
                case Terminals.Identifier:
                    var reference = semanticModel.GetReference <OracleReference>(node);
                    reference?.Accept(toolTipBuilderVisitor);
                    if (toolTipBuilderVisitor.ToolTip != null)
                    {
                        return(toolTipBuilderVisitor.ToolTip);
                    }

                    goto default;

                case Terminals.DatabaseLinkIdentifier:
                case Terminals.Dot:
                case Terminals.AtCharacter:
                    var databaseLink = semanticModel.GetReference <OracleReference>(node)?.DatabaseLink;
                    if (databaseLink == null)
                    {
                        return(null);
                    }

                    return
                        (new ToolTipDatabaseLink(databaseLink)
                    {
                        ScriptExtractor = semanticModel.DatabaseModel.ObjectScriptExtractor,
                    });

                case Terminals.ParameterIdentifier:
                    return(BuildParameterToolTip(semanticModel, node));

                default:
                    var missingTokenLookupTerminal = GetTerminalForCandidateLookup(node, node.LastTerminalNode);
                    if (missingTokenLookupTerminal != null)
                    {
                        return(BuildExpectedTokenListToolTip(node));
                    }

                    break;
                }
            }

            return(String.IsNullOrEmpty(tip) ? null : new ToolTipObject {
                DataContext = tip
            });
        }
Beispiel #2
0
		public IToolTip GetToolTip(SqlDocumentRepository sqlDocumentRepository, int cursorPosition)
		{
			if (sqlDocumentRepository == null)
			{
				throw new ArgumentNullException(nameof(sqlDocumentRepository));
			}

			var node = sqlDocumentRepository.Statements.GetNodeAtPosition(cursorPosition);
			if (node == null)
			{
				var statement = sqlDocumentRepository.Statements.GetStatementAtPosition(cursorPosition);
				if (statement?.FirstUnparsedToken == null)
				{
					return null;
				}

				if (cursorPosition < statement.FirstUnparsedToken.Index || cursorPosition > statement.FirstUnparsedToken.Index + statement.FirstUnparsedToken.Value.Length)
				{
					return null;
				}

				return BuildExpectedTokenListToolTip(statement.LastTerminalNode);
			}

			var tip = node.Type == NodeType.Terminal && !node.Id.IsIdentifier() ? node.Id : null;

			var validationModel = (OracleValidationModel)sqlDocumentRepository.ValidationModels[node.Statement];

			var nodeSemanticError = validationModel.SemanticErrors
				.Concat(validationModel.Suggestions)
				.FirstOrDefault(v => node.HasAncestor(v.Node, true));

			if (nodeSemanticError != null)
			{
				tip = nodeSemanticError.ToolTipText;
			}
			else
			{
				var semanticModel = validationModel.SemanticModel;
				var queryBlock = semanticModel.GetQueryBlock(node);

				var toolTipBuilderVisitor = new OracleToolTipBuilderVisitor(node);

				switch (node.Id)
				{
					case Terminals.Asterisk:
						return BuildAsteriskToolTip(queryBlock, node);
					case Terminals.Min:
					case Terminals.Max:
					case Terminals.Sum:
					case Terminals.Avg:
					case Terminals.FirstValue:
					case Terminals.Count:
					case Terminals.Cast:
					case Terminals.Trim:
					case Terminals.CharacterCode:
					case Terminals.Variance:
					case Terminals.StandardDeviation:
					case Terminals.LastValue:
					case Terminals.Lead:
					case Terminals.Lag:
					case Terminals.ListAggregation:
					case Terminals.CumulativeDistribution:
					case Terminals.Rank:
					case Terminals.DenseRank:
					case Terminals.PercentileDiscreteDistribution:
					case Terminals.PercentileContinuousDistribution:
					case Terminals.NegationOrNull:
					case Terminals.RowIdPseudocolumn:
					case Terminals.RowNumberPseudocolumn:
					case Terminals.User:
					case Terminals.Level:
					case Terminals.Extract:
					case Terminals.JsonQuery:
					case Terminals.JsonExists:
					case Terminals.JsonValue:
					case Terminals.XmlCast:
					case Terminals.XmlElement:
					case Terminals.XmlSerialize:
					case Terminals.XmlParse:
					case Terminals.XmlQuery:
					case Terminals.XmlRoot:
					case Terminals.XmlForest:
					case Terminals.PlSqlIdentifier:
					case Terminals.ExceptionIdentifier:
					case Terminals.CursorIdentifier:
					case Terminals.DataTypeIdentifier:
					case Terminals.ObjectIdentifier:
					case Terminals.SchemaIdentifier:
					case Terminals.Identifier:
						var reference = semanticModel.GetReference<OracleReference>(node);
						reference?.Accept(toolTipBuilderVisitor);
						if (toolTipBuilderVisitor.ToolTip != null)
						{
							return toolTipBuilderVisitor.ToolTip;
						}

						goto default;
					case Terminals.DatabaseLinkIdentifier:
					case Terminals.Dot:
					case Terminals.AtCharacter:
						var databaseLink = semanticModel.GetReference<OracleReference>(node)?.DatabaseLink;
						if (databaseLink == null)
						{
							return null;
						}

						return
							new ToolTipDatabaseLink(databaseLink)
							{
								ScriptExtractor = semanticModel.DatabaseModel.ObjectScriptExtractor,
							};

					case Terminals.ParameterIdentifier:
						return BuildParameterToolTip(semanticModel, node);

					default:
						var missingTokenLookupTerminal = GetTerminalForCandidateLookup(node, node.LastTerminalNode);
						if (missingTokenLookupTerminal != null)
						{
							return BuildExpectedTokenListToolTip(node);
						}

						break;
				}
			}

			return String.IsNullOrEmpty(tip) ? null : new ToolTipObject { DataContext = tip };
		}