Beispiel #1
0
        internal static void FormatSql()
        {
            Gateway.SetCurrentLanguage(LangType.L_SQL);

            var text = GetCurrentText();

            var options = new TSqlStandardFormatterOptions
            {
                BreakJoinOnSections      = _settings.BreakJoinOnSections,
                ExpandBetweenConditions  = _settings.ExpandBetweenConditions,
                ExpandBooleanExpressions = _settings.ExpandBooleanExpressions,
                ExpandCaseStatements     = _settings.ExpandCaseStatements,
                ExpandCommaLists         = _settings.ExpandCommaList,
                ExpandInLists            = false,
                HTMLColoring             = false,
                IndentString             = _settings.IndentString,
                KeywordStandardization   = _settings.KeywordStandardization,
                MaxLineWidth             = _settings.MaxLineWidth,
                NewClauseLineBreaks      = 0,
                NewStatementLineBreaks   = 0,
                SpaceAfterExpandedComma  = _settings.SpaceAfterExpandedComma,
                SpacesPerTab             = _settings.SpacesPerTab,
                TrailingCommas           = _settings.TrailingCommas,
                UppercaseKeywords        = _settings.UppercaseKeywords
            };

            var innerFormatter = new TSqlStandardFormatter(options);
            var tokenizer      = new TSqlStandardTokenizer();
            var parser         = new TSqlStandardParser();


            var parsedSql = parser.ParseSQL(tokenizer.TokenizeSQL(text));

            Editor.SetText(innerFormatter.FormatSQLTree(parsedSql));
        }
        public string PrettyPrint(string sql)
        {
            var tokenizer = new TSqlStandardTokenizer();
            var tokenized = tokenizer.TokenizeSQL(sql);
            var parser    = new TSqlStandardParser();
            var parsedSql = parser.ParseSQL(tokenized);

            return(_formatter.FormatSQLTree(parsedSql)?.TrimEnd());
        }
        public IList <ClassificationSpan> GetClassificationSpans(SnapshotSpan span)
        {
            List <ClassificationSpan> classifiedSpans = new List <ClassificationSpan>();

            // Note: best would be to avoid recalulating the output everytime on multiline SQL.
            // I am not sure how to achive this while avoiding chaching potentially huge documents.

            var tagSpans = tagger.GetTags(span);

            foreach (var tagSpan in tagSpans)
            {
                var snapshotSpan = tagSpan.Span.GetSpans(span.Snapshot).First();

                var text = snapshotSpan.GetText();

                if (!IsKnownStartOfSql(text))
                {
                    break;
                }

                // TODO: think about what is the best way to handle '{ }', both in normal
                //       as well as in interpolated strings. most futureproof might be to
                //       actually use the roslyn code analyzer.

                List <Span> stringInterpolations     = new List <Span>();
                int         stringInterpolationIndex = 0;

                if (tagSpan.Tag.Interpolations != null)
                {
                    // replace interpolations with "xxxx", to avoid confusing PoorMansTSqlFormatter

                    StringBuilder b = new StringBuilder(text);
                    foreach (var interpolation in tagSpan.Tag.Interpolations)
                    {
                        int relStart  = interpolation.Start.Position - snapshotSpan.Start.Position;
                        int relLength = interpolation.Length;
                        for (int i = 0; i < relLength; ++i)
                        {
                            b[i + relStart] = 'x';
                        }

                        stringInterpolations.Add(interpolation.Span);
                    }

                    text = b.ToString();
                    stringInterpolations.OrderBy(i => i.Start).ThenBy(i => i.Length).ToList();
                }

                var index = 0;

                var tokens = tokenizer.TokenizeSQL(text);
                var doc    = parser.ParseSQL(tokens).ToXmlDoc();

                // no need to be too strict
                //if (doc.DocumentElement.HasAttribute("errorFound") && doc.DocumentElement.GetAttribute("errorFound").Equals("1", StringComparison.InvariantCultureIgnoreCase))
                //    continue;
                if (doc.DocumentElement == null)
                {
                    continue;
                }

                //$"SELECT { --index } FROM x";

                var sqlWithType = formatter.FormatSQLTree(doc);

                foreach (var pair in sqlWithType)
                {
                    int           length = pair.Value.Length;
                    SnapshotPoint start  = snapshotSpan.Start + index;

                    index += length;

                    string classification = pair.Key;
                    if (classification == null)
                    {
                        continue;
                    }

                    Span cutOutinterpolation = default(Span);
                    // cut out string interpolations, if any.
                    while (stringInterpolationIndex < stringInterpolations.Count)
                    {
                        Span cutOut = stringInterpolations[stringInterpolationIndex];
                        if (cutOut.Start > start.Position + length)
                        {
                            break;
                        }

                        if (cutOut.Start + cutOut.Length < start.Position)
                        {
                            ++stringInterpolationIndex;
                            continue;
                        }

                        // there is some overlap.
                        cutOutinterpolation = cutOut;
                        break;
                    }

                    if (cutOutinterpolation.IsEmpty)
                    {
                        AddClassification(classifiedSpans, classification, new SnapshotSpan(start, length));
                    }
                    else
                    {
                        if (cutOutinterpolation.Start > start.Position)
                        {
                            AddClassification(classifiedSpans, classification, new SnapshotSpan(start, cutOutinterpolation.Start - start.Position));
                        }
                        if (cutOutinterpolation.Start + cutOutinterpolation.Length < start.Position + length)
                        {
                            int keepStart  = cutOutinterpolation.Start + cutOutinterpolation.Length;
                            int keepLength = start.Position + length - keepStart;
                            AddClassification(classifiedSpans, classification, new SnapshotSpan(new SnapshotPoint(start.Snapshot, keepStart), keepLength));
                        }
                    }
                }
            }

            return(classifiedSpans);
        }