Пример #1
0
        /// <summary>
        /// Indents the switch body by the same indent the whole snippet has and adds one TAB.
        /// </summary>
        string GetBodyIndent(IDocument document, int offset)
        {
            int    lineStart = document.GetLineForOffset(offset).Offset;
            string indent    = DocumentUtilitites.GetWhitespaceAfter(document, lineStart);

            return(indent);
        }
            void EditorKeyPress(object sender, KeyEventArgs e)
            {
                if (e.Key == Key.Tab || e.Key == Key.Enter || e.Key == Key.Return)
                {
                    using (editor.Document.OpenUndoGroup())
                    {
                        // is there a better way to calculate the optimal insertion point?
                        DomRegion region = resolveResult.CallingMember.BodyRegion;
                        editor.Caret.Line   = region.EndLine;
                        editor.Caret.Column = region.EndColumn;

                        editor.Document.Insert(editor.Caret.Offset, this.newHandlerCode);

                        editor.Language.FormattingStrategy.IndentLines(editor, region.EndLine, editor.Caret.Line);

                        IDocumentLine line = editor.Document.GetLine(editor.Caret.Line - 1);
                        int           indentationLength = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset).Length;

                        editor.Select(line.Offset + indentationLength, line.Length - indentationLength);
                    }
                    e.Handled = true;
                }
                // detatch our keydown filter to return to the normal processing state
                RemoveEventHandlers();
            }
        static void ApplyToRange(ITextEditor editor, Stack <string> indentation, List <int> eols, int blockStart, int blockEnd, int selectionStart, int selectionEnd)
        {
            LoggingService.InfoFormatted("indenting line {0} to {1} with {2}", blockStart, blockEnd, (indentation.PeekOrDefault() ?? "").Length);

            int  nextEol      = -1;
            bool wasMultiLine = false;

            for (int i = blockStart; i <= blockEnd; i++)
            {
                IDocumentLine curLine    = editor.Document.GetLine(i);
                string        lineText   = curLine.Text.TrimStart();
                string        noComments = lineText.TrimComments().TrimEnd();

                // adjust indentation if the current line is not selected
                // lines between the selection will be aligned to the selected level
                if (i < selectionStart || i > selectionEnd)
                {
                    indentation.PopOrDefault();
                    indentation.Push(DocumentUtilitites.GetWhitespaceAfter(editor.Document, curLine.Offset));
                }

                // look for next eol if line is not empty
                // (the lexer does not produce eols for empty lines)
                if (!string.IsNullOrEmpty(noComments) && i >= nextEol)
                {
                    int search = eols.BinarySearch(i);
                    if (search < 0)
                    {
                        search = ~search;
                    }
                    nextEol = search < eols.Count ? eols[search] : i;
                }

                // remove indentation in last line of multiline array(, collection, object) initializers
                if (i == nextEol && wasMultiLine && noComments == "}")
                {
                    wasMultiLine = false;
                    Unindent(indentation);
                }

                // apply the indentation
                editor.Document.SmartReplaceLine(curLine, (indentation.PeekOrDefault() ?? "") + lineText);

                // indent line if it is ended by (implicit) line continuation
                if (i < nextEol && !wasMultiLine)
                {
                    wasMultiLine = true;
                    Indent(editor, indentation);
                }

                // unindent if this is the last line of a multiline statement
                if (i == nextEol && wasMultiLine)
                {
                    wasMultiLine = false;
                    Unindent(indentation);
                }
            }
        }
        void DoInsertionOnLine(string terminator, IDocumentLine currentLine, IDocumentLine lineAbove, string textToReplace, ITextEditor editor, int lineNr)
        {
            string curLineText = currentLine.Text;

            if (Regex.IsMatch(textToReplace.Trim(), "^If .*[^_]$", RegexOptions.IgnoreCase))
            {
                if (!Regex.IsMatch(textToReplace, "\\bthen\\b", RegexOptions.IgnoreCase))
                {
                    string specialThen = "Then";                     // do special check in cases like If t = True' comment
                    if (editor.Document.GetCharAt(lineAbove.Offset + textToReplace.Length) == '\'')
                    {
                        specialThen += " ";
                    }
                    if (editor.Document.GetCharAt(lineAbove.Offset + textToReplace.Length - 1) != ' ')
                    {
                        specialThen = " " + specialThen;
                    }
                    editor.Document.Insert(lineAbove.Offset + textToReplace.Length, specialThen);
                    textToReplace += specialThen;
                }
            }

            // check #Region statements
            if (Regex.IsMatch(textToReplace.Trim(), "^#Region", RegexOptions.IgnoreCase) && LookForEndRegion(editor))
            {
                string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, lineAbove.Offset);
                textToReplace += indentation + "\r\n" + indentation + "#End Region";
                editor.Document.Replace(currentLine.Offset, currentLine.Length, textToReplace);
            }

            foreach (VBStatement statement_ in statements)
            {
                VBStatement statement = statement_;                     // allow passing statement byref
                if (Regex.IsMatch(textToReplace.Trim(), statement.StartRegex, RegexOptions.IgnoreCase))
                {
                    string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, lineAbove.Offset);
                    if (IsEndStatementNeeded(editor, ref statement, lineNr))
                    {
                        editor.Document.Replace(currentLine.Offset, currentLine.Length, terminator + indentation + statement.EndStatement);
                    }
                    if (!IsInsideInterface(editor, lineNr) || statement == interfaceStatement)
                    {
                        for (int i = 0; i < statement.IndentPlus; i++)
                        {
                            indentation += editor.Options.IndentationString;
                        }
                    }
                    editor.Document.Replace(currentLine.Offset, currentLine.Length, indentation + curLineText.Trim());
                    editor.Caret.Line   = currentLine.LineNumber;
                    editor.Caret.Column = indentation.Length;
                    return;
                }
            }
        }
        static void InsertDocumentationComments(ITextEditor editor, int lineNr, int cursorOffset)
        {
            string terminator = DocumentUtilitites.GetLineTerminator(editor.Document, lineNr);

            IDocumentLine currentLine  = editor.Document.GetLine(lineNr);
            IDocumentLine previousLine = (lineNr > 1) ? editor.Document.GetLine(lineNr - 1) : null;

            string curLineText   = currentLine.Text;
            string lineAboveText = previousLine == null ? null : previousLine.Text;

            if (curLineText != null && curLineText.EndsWith("'''", StringComparison.OrdinalIgnoreCase) && (lineAboveText == null || !lineAboveText.Trim().StartsWith("'''", StringComparison.OrdinalIgnoreCase)))
            {
                string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, currentLine.Offset);
                object member      = GetMemberAfter(editor, lineNr);
                if (member != null)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.Append(" <summary>");
                    sb.Append(terminator);
                    sb.Append(indentation);
                    sb.Append("''' ");
                    sb.Append(terminator);
                    sb.Append(indentation);
                    sb.Append("''' </summary>");
                    if (member is IMethod)
                    {
                        IMethod method = (IMethod)member;
                        if (method.Parameters != null && method.Parameters.Count > 0)
                        {
                            for (int i = 0; i < method.Parameters.Count; ++i)
                            {
                                sb.Append(terminator);
                                sb.Append(indentation);
                                sb.Append("''' <param name=\"");
                                sb.Append(method.Parameters[i].Name);
                                sb.Append("\"></param>");
                            }
                        }
                        if (method.ReturnType != null && !method.IsConstructor && method.ReturnType.FullyQualifiedName != "System.Void")
                        {
                            sb.Append(terminator);
                            sb.Append(indentation);
                            sb.Append("''' <returns></returns>");
                        }
                    }
                    editor.Document.Insert(cursorOffset, sb.ToString());
                    editor.Caret.Position = editor.Document.OffsetToPosition(cursorOffset + indentation.Length + "/// ".Length + " <summary>".Length + terminator.Length);
                }
            }
        }
Пример #6
0
        public virtual void IndentLine(ITextEditor editor, IDocumentLine line)
        {
            IDocument document   = editor.Document;
            int       lineNumber = line.LineNumber;

            if (lineNumber > 1)
            {
                IDocumentLine previousLine = document.GetLine(lineNumber - 1);
                string        indentation  = DocumentUtilitites.GetWhitespaceAfter(document, previousLine.Offset);
                // copy indentation to line
                string newIndentation = DocumentUtilitites.GetWhitespaceAfter(document, line.Offset);
                document.Replace(line.Offset, newIndentation.Length, indentation);
            }
        }
        public override void IndentLine(ITextEditor editor, IDocumentLine line)
        {
            if (line.LineNumber > 1)
            {
                IDocumentLine above = editor.Document.GetLine(line.LineNumber - 1);
                string        up    = above.Text.Trim();
                if (up.StartsWith("--") == false)
                {
                    // above line is an indent statement
                    if (up.EndsWith("do") ||
                        up.EndsWith("then") ||
                        (up.StartsWith("function") && up.EndsWith(")")) ||
                        (up.Contains("function") && up.EndsWith(")")))    // e.g. aTable.x = function([...])
                    {
                        string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, above.Offset);
                        string newLine     = line.Text.TrimStart();
                        newLine = indentation + editor.Options.IndentationString + newLine;
                        editor.Document.SmartReplaceLine(line, newLine);
                    }
                    else // above line is not an indent statement
                    {
                        string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, above.Offset);
                        string newLine     = line.Text.TrimStart();
                        newLine = indentation + newLine;
                        editor.Document.SmartReplaceLine(line, newLine);
                    }
                }

                if (line.Text.StartsWith("end"))
                {
                    string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, above.Offset);
                    string newLine     = line.Text.TrimStart();
                    string newIndent   = "";

                    if (indentation.Length >= editor.Options.IndentationSize)
                    {
                        newIndent = indentation.Substring(0, indentation.Length - editor.Options.IndentationSize);
                    }

                    newLine = newIndent + newLine;
                    editor.Document.SmartReplaceLine(line, newLine);
                }
            }
            else
            {
            }
            //base.IndentLine(editor, line);
        }
Пример #8
0
        public static void ToggleBookmark(ITextEditor editor, int line,
                                          Predicate <SDBookmark> canToggle,
                                          Func <Location, SDBookmark> bookmarkFactory)
        {
            foreach (SDBookmark bookmark in GetBookmarks(new FileName(editor.FileName)))
            {
                if (canToggle(bookmark) && bookmark.LineNumber == line)
                {
                    BookmarkManager.RemoveMark(bookmark);
                    return;
                }
            }
            // no bookmark at that line: create a new bookmark
            int lineStartOffset = editor.Document.GetLine(line).Offset;
            int column          = 1 + DocumentUtilitites.GetWhitespaceAfter(editor.Document, lineStartOffset).Length;

            BookmarkManager.AddMark(bookmarkFactory(new Location(column, line)));
        }
        public override void IndentLine(ITextEditor editor, IDocumentLine line)
        {
            IDocument document   = editor.Document;
            int       lineNumber = line.LineNumber;

            if (lineNumber > 1)
            {
                IDocumentLine previousLine = document.GetLine(line.LineNumber - 1);

                if (previousLine.Text.EndsWith(":", StringComparison.Ordinal))
                {
                    string indentation = DocumentUtilitites.GetWhitespaceAfter(document, previousLine.Offset);
                    indentation += editor.Options.IndentationString;
                    string newIndentation = DocumentUtilitites.GetWhitespaceAfter(document, line.Offset);
                    document.Replace(line.Offset, newIndentation.Length, indentation);
                    return;
                }
            }
            base.IndentLine(editor, line);
        }
Пример #10
0
        public static void InsertCode(this ITextEditor editor, AbstractNode target, AbstractNode insert, int insertOffset, bool updateCaretPos)
        {
            if (insertOffset < 0)
            {
                return;
            }

            var regionCorrectVisitor = new SetRegionInclusionVisitor();

            insert.AcceptVisitor(regionCorrectVisitor, null);

            var doc     = editor.Document;
            var codeGen = editor.Language.Properties.CodeGenerator;

            string indent = DocumentUtilitites.GetWhitespaceAfter(doc, doc.GetLineStartOffset(target.StartLocation));
            string code   = codeGen.GenerateCode(insert, indent);

            doc.Insert(insertOffset, code);
            if (updateCaretPos)
            {
                editor.Caret.Offset = insertOffset + code.Length - 1;
            }
        }
        void FormatLineInternal(ITextEditor textArea, int lineNr, int cursorOffset, char ch)
        {
            IDocumentLine curLine    = textArea.Document.GetLine(lineNr);
            IDocumentLine lineAbove  = lineNr > 1 ? textArea.Document.GetLine(lineNr - 1) : null;
            string        terminator = DocumentUtilitites.GetLineTerminator(textArea.Document, lineNr);

            string curLineText;

            //// local string for curLine segment
            if (ch == '/')
            {
                curLineText = curLine.Text;
                string lineAboveText = lineAbove == null ? "" : lineAbove.Text;
                if (curLineText != null && curLineText.EndsWith("///") && (lineAboveText == null || !lineAboveText.Trim().StartsWith("///")))
                {
                    string indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset);
                    object member      = GetMemberAfter(textArea, lineNr);
                    if (member != null)
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.Append(" <summary>");
                        sb.Append(terminator);
                        sb.Append(indentation);
                        sb.Append("/// ");
                        sb.Append(terminator);
                        sb.Append(indentation);
                        sb.Append("/// </summary>");

                        if (member is IMethod)
                        {
                            IMethod method = (IMethod)member;
                            if (method.Parameters != null && method.Parameters.Count > 0)
                            {
                                for (int i = 0; i < method.Parameters.Count; ++i)
                                {
                                    sb.Append(terminator);
                                    sb.Append(indentation);
                                    sb.Append("/// <param name=\"");
                                    sb.Append(method.Parameters[i].Name);
                                    sb.Append("\"></param>");
                                }
                            }
                            if (method.ReturnType != null && !method.IsConstructor && method.ReturnType.FullyQualifiedName != "System.Void")
                            {
                                sb.Append(terminator);
                                sb.Append(indentation);
                                sb.Append("/// <returns></returns>");
                            }
                        }
                        textArea.Document.Insert(cursorOffset, sb.ToString());

                        textArea.Caret.Offset = cursorOffset + indentation.Length + "/// ".Length + " <summary>".Length + terminator.Length;
                    }
                }
                return;
            }

            if (ch != '\n' && ch != '>')
            {
                if (IsInsideStringOrComment(textArea, curLine, cursorOffset))
                {
                    return;
                }
            }
            switch (ch)
            {
            case '>':
                if (IsInsideDocumentationComment(textArea, curLine, cursorOffset))
                {
                    curLineText = curLine.Text;
                    int column = cursorOffset - curLine.Offset;
                    int index  = Math.Min(column - 1, curLineText.Length - 1);

                    while (index >= 0 && curLineText[index] != '<')
                    {
                        --index;
                        if (curLineText[index] == '/')
                        {
                            return;                                     // the tag was an end tag or already
                        }
                    }

                    if (index > 0)
                    {
                        StringBuilder commentBuilder = new StringBuilder("");
                        for (int i = index; i < curLineText.Length && i < column && !Char.IsWhiteSpace(curLineText[i]); ++i)
                        {
                            commentBuilder.Append(curLineText[i]);
                        }
                        string tag = commentBuilder.ToString().Trim();
                        if (!tag.EndsWith(">"))
                        {
                            tag += ">";
                        }
                        if (!tag.StartsWith("/"))
                        {
                            textArea.Document.Insert(cursorOffset, "</" + tag.Substring(1), AnchorMovementType.BeforeInsertion);
                        }
                    }
                }
                break;

            case ':':
            case ')':
            case ']':
            case '}':
            case '{':
                //if (textArea.Document.TextEditorProperties.IndentStyle == IndentStyle.Smart) {
                IndentLine(textArea, curLine);
                //}
                break;

            case '\n':
                string lineAboveText = lineAbove == null ? "" : lineAbove.Text;
                //// curLine might have some text which should be added to indentation
                curLineText = curLine.Text;

                if (lineAbove != null && lineAbove.Text.Trim().StartsWith("#region") &&
                    NeedEndregion(textArea.Document))
                {
                    textArea.Document.Insert(cursorOffset, "#endregion");
                    return;
                }

                ISyntaxHighlighter highlighter = textArea.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter;
                bool isInMultilineComment      = false;
                bool isInMultilineString       = false;
                if (highlighter != null && lineAbove != null)
                {
                    var spanStack = highlighter.GetSpanColorNamesFromLineStart(lineNr);
                    isInMultilineComment = spanStack.Contains(SyntaxHighligherKnownSpanNames.Comment);
                    isInMultilineString  = spanStack.Contains(SyntaxHighligherKnownSpanNames.String);
                }
                bool isInNormalCode = !(isInMultilineComment || isInMultilineString);

                if (lineAbove != null && isInMultilineComment)
                {
                    string lineAboveTextTrimmed = lineAboveText.TrimStart();
                    if (lineAboveTextTrimmed.StartsWith("/*", StringComparison.Ordinal))
                    {
                        textArea.Document.Insert(cursorOffset, " * ");
                        return;
                    }

                    if (lineAboveTextTrimmed.StartsWith("*", StringComparison.Ordinal))
                    {
                        textArea.Document.Insert(cursorOffset, "* ");
                        return;
                    }
                }

                if (lineAbove != null && isInNormalCode)
                {
                    IDocumentLine nextLine     = lineNr + 1 <= textArea.Document.TotalNumberOfLines ? textArea.Document.GetLine(lineNr + 1) : null;
                    string        nextLineText = (nextLine != null) ? nextLine.Text : "";

                    int indexAbove = lineAboveText.IndexOf("///");
                    int indexNext  = nextLineText.IndexOf("///");
                    if (indexAbove > 0 && (indexNext != -1 || indexAbove + 4 < lineAbove.Length))
                    {
                        textArea.Document.Insert(cursorOffset, "/// ");
                        return;
                    }

                    if (IsInNonVerbatimString(lineAboveText, curLineText))
                    {
                        textArea.Document.Insert(cursorOffset, "\"");
                        textArea.Document.Insert(lineAbove.Offset + lineAbove.Length,
                                                 "\" +");
                    }
                }
                if (textArea.Options.AutoInsertBlockEnd && lineAbove != null && isInNormalCode)
                {
                    string oldLineText = lineAbove.Text;
                    if (oldLineText.EndsWith("{"))
                    {
                        if (NeedCurlyBracket(textArea.Document.Text))
                        {
                            int insertionPoint = curLine.Offset + curLine.Length;
                            textArea.Document.Insert(insertionPoint, terminator + "}");
                            IndentLine(textArea, textArea.Document.GetLine(lineNr + 1));
                            textArea.Caret.Offset = insertionPoint;
                        }
                    }
                }
                return;
            }
        }
        void FormatLineInternal(ITextEditor textArea, int lineNr, int cursorOffset, char ch)
        {
            IDocumentLine curLine    = textArea.Document.GetLine(lineNr);
            IDocumentLine lineAbove  = lineNr > 1 ? textArea.Document.GetLine(lineNr - 1) : null;
            string        terminator = DocumentUtilitites.GetLineTerminator(textArea.Document, lineNr);

            string curLineText;

            //// local string for curLine segment
            if (ch == '-')
            {
                curLineText = curLine.Text;
                string lineAboveText = lineAbove == null ? "" : lineAbove.Text;
                if (curLineText != null && curLineText.EndsWith("---") && (lineAboveText == null || !lineAboveText.Trim().StartsWith("---")))
                {
                    string        indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset);
                    StringBuilder sb          = new StringBuilder();
                    sb.Append(" <summary>");
                    sb.Append(terminator);
                    sb.Append(indentation);
                    sb.Append("--- ");
                    sb.Append(terminator);
                    sb.Append(indentation);
                    sb.Append("--- </summary>");

                    //sb.Append(terminator);
                    //sb.Append(indentation);
                    //sb.Append("--- <returns></returns>");
                    textArea.Document.Insert(cursorOffset, sb.ToString());

                    textArea.Caret.Offset = cursorOffset + indentation.Length + "--- ".Length + " <summary>".Length + terminator.Length;
                }
                else if (curLineText != null && curLineText.Trim() == "-" && (lineAboveText != null && lineAboveText.Trim().StartsWith("---")))
                {
                    StringBuilder sb = new StringBuilder();
                    sb.Append("-- ");

                    //sb.Append(terminator);
                    //sb.Append(indentation);
                    //sb.Append("--- <returns></returns>");
                    textArea.Document.Insert(cursorOffset, sb.ToString());

                    textArea.Caret.Offset = cursorOffset + "-- ".Length;
                }
                return;
            }

            if (ch != '\n' && ch != '>')
            {
                if (IsInsideStringOrComment(textArea, curLine, cursorOffset))
                {
                    return;
                }
            }

            if (IsInsideStringOrComment(textArea, curLine, cursorOffset) == false &&
                textArea.Caret.Offset == curLine.EndOffset && // end of line, not editing something inside the line
                (curLine.Text.TrimEnd().EndsWith("then") ||
                 curLine.Text.TrimEnd().EndsWith("do")))
            {
                string        indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset);
                StringBuilder sb          = new StringBuilder();
                sb.Append(terminator);
                sb.Append(indentation + textArea.Options.IndentationString);
                sb.Append(terminator);
                sb.Append(indentation);
                sb.Append("end");
                textArea.Document.Insert(cursorOffset, sb.ToString());
                textArea.Caret.Offset =
                    cursorOffset
                    + terminator.Length  // end of line
                    + indentation.Length // indentation
                    + textArea.Options.IndentationString.Length
                ;
            }

            if (IsInsideStringOrComment(textArea, curLine, cursorOffset) == false &&
                textArea.Caret.Offset == curLine.EndOffset && // end of line, not editing something inside the line
                curLine.Text.TrimStart().StartsWith("repeat"))
            {
                string        indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset);
                StringBuilder sb          = new StringBuilder();
                sb.Append(terminator);
                sb.Append(indentation + textArea.Options.IndentationString);
                sb.Append(terminator);
                sb.Append(indentation);
                sb.Append("until ");
                textArea.Document.Insert(cursorOffset, sb.ToString());

                textArea.Caret.Offset =
                    cursorOffset
                    + indentation.Length
                    + terminator.Length // line 1
                    + indentation.Length
                    + textArea.Options.IndentationString.Length
                    + terminator.Length // line 2
                    + "until ".Length
                ;
            }

            switch (ch)
            {
            case '>':
                if (IsInsideDocumentationComment(textArea, curLine, cursorOffset))
                {
                    curLineText = curLine.Text;
                    int column = cursorOffset - curLine.Offset;
                    int index  = Math.Min(column - 1, curLineText.Length - 1);

                    while (index >= 0 && curLineText[index] != '<')
                    {
                        --index;
                        if (curLineText[index] == '/')
                        {
                            return;     // the tag was an end tag or already
                        }
                    }

                    if (index > 0)
                    {
                        StringBuilder commentBuilder = new StringBuilder("");
                        for (int i = index; i < curLineText.Length && i < column && !Char.IsWhiteSpace(curLineText[i]); ++i)
                        {
                            commentBuilder.Append(curLineText[i]);
                        }
                        string tag = commentBuilder.ToString().Trim();
                        if (!tag.EndsWith(">"))
                        {
                            tag += ">";
                        }
                        if (!tag.StartsWith("/"))
                        {
                            textArea.Document.Insert(cursorOffset, "</" + tag.Substring(1), AnchorMovementType.BeforeInsertion);
                        }
                    }
                }
                break;

            case ')':
                if (curLine.Text.TrimStart().StartsWith("function"))
                {
                    string        indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset);
                    StringBuilder sb          = new StringBuilder();
                    sb.Append(terminator);
                    sb.Append(indentation + textArea.Options.IndentationString);
                    sb.Append(terminator);
                    sb.Append(indentation);
                    sb.Append("end");
                    textArea.Document.Insert(cursorOffset, sb.ToString());
                    textArea.Caret.Offset =
                        cursorOffset
                        + terminator.Length     // end of line
                        + indentation.Length    // indentation
                        + textArea.Options.IndentationString.Length
                    ;
                }
                else
                {
                    IndentLine(textArea, curLine);
                }
                break;

            case ':':
            case ']':
            case '}':
            case '{':
                IndentLine(textArea, curLine);
                break;

            case '\n':
                string lineAboveText = lineAbove == null ? "" : lineAbove.Text;
                //// curLine might have some text which should be added to indentation
                curLineText = curLine.Text;


                ISyntaxHighlighter highlighter = textArea.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter;
                bool isInMultilineComment      = false;
                bool isInMultilineString       = false;
                if (highlighter != null && lineAbove != null)
                {
                    var spanStack = highlighter.GetSpanColorNamesFromLineStart(lineNr);
                    isInMultilineComment = spanStack.Contains(SyntaxHighligherKnownSpanNames.Comment);
                    isInMultilineString  = spanStack.Contains(SyntaxHighligherKnownSpanNames.String);
                }
                bool isInNormalCode = !(isInMultilineComment || isInMultilineString);

                if (lineAbove != null && isInMultilineComment)
                {
                    string lineAboveTextTrimmed = lineAboveText.TrimStart();
                    if (lineAboveTextTrimmed.StartsWith("--[[", StringComparison.Ordinal))
                    {
                        textArea.Document.Insert(cursorOffset, " - ");
                        return;
                    }

                    if (lineAboveTextTrimmed.StartsWith("-", StringComparison.Ordinal))
                    {
                        textArea.Document.Insert(cursorOffset, "- ");
                        return;
                    }
                }

                if (lineAbove != null && isInNormalCode)
                {
                    IDocumentLine nextLine     = lineNr + 1 <= textArea.Document.TotalNumberOfLines ? textArea.Document.GetLine(lineNr + 1) : null;
                    string        nextLineText = (nextLine != null) ? nextLine.Text : "";

                    int indexAbove = lineAboveText.IndexOf("---");
                    int indexNext  = nextLineText.IndexOf("---");
                    if (indexAbove > 0 && (indexNext != -1 || indexAbove + 4 < lineAbove.Length))
                    {
                        textArea.Document.Insert(cursorOffset, "--- ");
                        return;
                    }

                    if (IsInNonVerbatimString(lineAboveText, curLineText))
                    {
                        textArea.Document.Insert(cursorOffset, "\"");
                        textArea.Document.Insert(lineAbove.Offset + lineAbove.Length,
                                                 "\" +");
                    }
                }
                return;
            }
        }
        static int SmartIndentInternal(ITextEditor editor, int begin, int end)
        {
            ILexer lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, new StringReader(editor.Document.Text));

            Stack <string> indentation = new Stack <string>();

            indentation.Push(string.Empty);

            List <int> eols = new List <int>();

            bool inInterface    = false;
            bool isMustOverride = false;
            bool isDeclare      = false;
            bool isDelegate     = false;

            Token currentToken = null;
            Token prevToken    = null;

            int blockStart    = 1;
            int lambdaNesting = 0;

            while ((currentToken = lexer.NextToken()).Kind != Tokens.EOF)
            {
                if (prevToken == null)
                {
                    prevToken = currentToken;
                }

                if (currentToken.Kind == Tokens.MustOverride)
                {
                    isMustOverride = true;
                }

                if (currentToken.Kind == Tokens.Delegate)
                {
                    isDelegate = true;
                }

                if (currentToken.Kind == Tokens.Declare)
                {
                    isDeclare = true;
                }

                if (currentToken.Kind == Tokens.EOL)
                {
                    isDelegate = isDeclare = isMustOverride = false;
                    eols.Add(currentToken.Location.Line);
                }

                if (IsBlockEnd(currentToken, prevToken))
                {
                    // indent the lines inside the block
                    // this is an End-statement
                    // hence we indent from blockStart to the previous line
                    int blockEnd = currentToken.Location.Line - 1;

                    // if this is a lambda end include End-Statement in block
//					if (lambdaNesting > 0 && (currentToken.Kind == Tokens.Function || currentToken.Kind == Tokens.Sub)) {
//						blockEnd++;
//					}

                    ApplyToRange(editor, indentation, eols, blockStart, blockEnd, begin, end);

                    if (lambdaNesting > 0 && (currentToken.Kind == Tokens.Function || currentToken.Kind == Tokens.Sub))
                    {
                        Unindent(indentation);

                        ApplyToRange(editor, indentation, eols, currentToken.Location.Line, currentToken.Location.Line, begin, end);
                    }

                    if (currentToken.Kind == Tokens.Interface)
                    {
                        inInterface = false;
                    }

                    if (!inInterface && !isMustOverride && !isDeclare && !isDelegate)
                    {
                        Unindent(indentation);

                        if (currentToken.Kind == Tokens.Select)
                        {
                            Unindent(indentation);
                        }
                    }

                    // block start is this line (for the lines between two blocks)
                    blockStart = currentToken.Location.Line;

                    if (lambdaNesting > 0 && (currentToken.Kind == Tokens.Function || currentToken.Kind == Tokens.Sub))
                    {
                        blockStart++;
                        lambdaNesting--;
                    }
                }

                bool isMultiLineLambda;
                if (IsBlockStart(lexer, currentToken, prevToken, out isMultiLineLambda))
                {
                    // indent the lines between the last and this block
                    // this is a Begin-statement
                    // hence we indent from blockStart to the this line
                    int lastVisualLine = FindNextEol(lexer);
                    eols.Add(lastVisualLine);
                    ApplyToRange(editor, indentation, eols, blockStart, lastVisualLine, begin, end);

                    if (isMultiLineLambda && (currentToken.Kind == Tokens.Function || currentToken.Kind == Tokens.Sub))
                    {
                        lambdaNesting++;
                        int endColumn   = currentToken.Location.Column;
                        int startColumn = DocumentUtilitites.GetWhitespaceAfter(editor.Document, editor.Document.GetLine(lastVisualLine).Offset).Length;
                        if (startColumn < endColumn)
                        {
                            Indent(editor, indentation, new string(' ', endColumn - startColumn - 1));
                        }
                    }

                    if (!inInterface && !isMustOverride && !isDeclare && !isDelegate)
                    {
                        Indent(editor, indentation);

                        if (currentToken.Kind == Tokens.Select)
                        {
                            Indent(editor, indentation);
                        }
                    }

                    if (currentToken.Kind == Tokens.Interface)
                    {
                        inInterface = true;
                    }

                    // block start is the following line (for the lines inside a block)
                    blockStart = lastVisualLine + 1;
                }

                prevToken = currentToken;
            }

            ApplyToRange(editor, indentation, eols, blockStart, editor.Document.TotalNumberOfLines, begin, end);

            return((indentation.PeekOrDefault() ?? string.Empty).Length);
        }
        void FormatLineInternal(ITextEditor editor, int lineNr, int cursorOffset, char ch)
        {
            string terminator = DocumentUtilitites.GetLineTerminator(editor.Document, lineNr);

            doCasing    = PropertyService.Get("VBBinding.TextEditor.EnableCasing", true);
            doInsertion = PropertyService.Get("VBBinding.TextEditor.EnableEndConstructs", true);

            IDocumentLine currentLine = editor.Document.GetLine(lineNr);
            IDocumentLine lineAbove   = lineNr > 1 ? editor.Document.GetLine(lineNr - 1) : null;

            string curLineText   = currentLine == null ? "" : currentLine.Text;
            string lineAboveText = lineAbove == null ? "" : lineAbove.Text;

            if (ch == '\'')
            {
                InsertDocumentationComments(editor, lineNr, cursorOffset);
            }

            if (ch == '\n' && lineAboveText != null)
            {
                if (LanguageUtils.IsInsideDocumentationComment(editor, lineAbove, lineAbove.EndOffset))
                {
                    editor.Document.Insert(cursorOffset, "''' ");
                    return;
                }

                string textToReplace = lineAboveText.TrimLine();

                if (doCasing)
                {
                    DoCasingOnLine(lineAbove, textToReplace, editor);
                }

                if (doInsertion)
                {
                    DoInsertionOnLine(terminator, currentLine, lineAbove, textToReplace, editor, lineNr);
                }

                if (IsInString(lineAboveText))
                {
                    if (IsFinishedString(curLineText))
                    {
                        editor.Document.Insert(lineAbove.EndOffset, "\" & _");
                        editor.Document.Insert(currentLine.Offset, "\"");
                    }
                    else
                    {
                        editor.Document.Insert(lineAbove.EndOffset, "\"");
                    }
                }
                else
                {
                    string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, lineAbove.Offset);
                    if (indent.Length > 0)
                    {
                        string newLineText = indent + currentLine.Text.Trim();
                        editor.Document.Replace(currentLine.Offset, currentLine.Length, newLineText);
                    }
                    editor.Caret.Column = indent.Length + 1;
                }

                IndentLines(editor, lineNr - 1, lineNr);
            }
            else if (ch == '>')
            {
                if (LanguageUtils.IsInsideDocumentationComment(editor, currentLine, cursorOffset))
                {
                    int column = editor.Caret.Offset - currentLine.Offset;
                    int index  = Math.Min(column - 1, curLineText.Length - 1);

                    while (index > 0 && curLineText[index] != '<')
                    {
                        --index;
                        if (curLineText[index] == '/')
                        {
                            return;                             // the tag was an end tag or already
                        }
                    }

                    if (index > 0)
                    {
                        StringBuilder commentBuilder = new StringBuilder("");
                        for (int i = index; i < curLineText.Length && i < column && !Char.IsWhiteSpace(curLineText[i]); ++i)
                        {
                            commentBuilder.Append(curLineText[i]);
                        }
                        string tag = commentBuilder.ToString().Trim();
                        if (!tag.EndsWith(">", StringComparison.OrdinalIgnoreCase))
                        {
                            tag += ">";
                        }
                        if (!tag.StartsWith("/", StringComparison.OrdinalIgnoreCase))
                        {
                            string endTag = "</" + tag.Substring(1);
                            editor.Document.Insert(editor.Caret.Offset, endTag);
                            editor.Caret.Offset -= endTag.Length;
                        }
                    }
                }
            }
        }
Пример #15
0
        internal void ExecuteIntroduceMethod(UnknownMethodResolveResult rr, Ast.Expression invocationExpr, ITextEditor editor, bool isNew, object result)
        {
            IClass targetClass = IsEqualClass(rr.CallingClass, rr.Target.GetUnderlyingClass()) ? rr.CallingClass
                                : rr.Target.GetUnderlyingClass();

            CodeGenerator gen      = targetClass.ProjectContent.Language.CodeGenerator;
            IAmbience     ambience = targetClass.ProjectContent.Language.GetAmbience();

            ClassFinder finder = new ClassFinder(rr.CallingMember);

            ModifierEnum modifiers = ModifierEnum.None;

            bool isExtension = !targetClass.IsUserCode();

            if (IsEqualClass(rr.CallingClass, targetClass))
            {
                if (rr.CallingMember != null)
                {
                    modifiers |= (rr.CallingMember.Modifiers & ModifierEnum.Static);
                }
            }
            else
            {
                if (isExtension)
                {
                    if (isNew)
                    {
                        targetClass = rr.CallingClass;
                    }
                    else
                    {
                        targetClass = result as IClass;
                    }
                }
                // exclude in Unit Test mode
                if (WorkbenchSingleton.Workbench != null)
                {
                    editor = (FileService.OpenFile(targetClass.CompilationUnit.FileName) as ITextEditorProvider).TextEditor;
                }
                if (targetClass.ClassType != ClassType.Interface)
                {
                    modifiers |= ModifierEnum.Public;
                }
                if (rr.IsStaticContext)
                {
                    modifiers |= ModifierEnum.Static;
                }
            }

            NRefactoryResolver resolver = Extensions.CreateResolverForContext(targetClass.ProjectContent.Language, editor);

            IReturnType type = resolver.GetExpectedTypeFromContext(invocationExpr);

            Ast.TypeReference typeRef = CodeGenerator.ConvertType(type, finder);

            if (typeRef.IsNull)
            {
                if (invocationExpr.Parent is Ast.ExpressionStatement)
                {
                    typeRef = new Ast.TypeReference("void", true);
                }
                else
                {
                    typeRef = new Ast.TypeReference("object", true);
                }
            }

            Ast.MethodDeclaration method = new Ast.MethodDeclaration {
                Name          = rr.CallName,
                Modifier      = CodeGenerator.ConvertModifier(modifiers, finder),
                TypeReference = typeRef,
                Parameters    = CreateParameters(rr, finder, invocationExpr as Ast.InvocationExpression).ToList(),
            };

            if (targetClass.ClassType != ClassType.Interface)
            {
                method.Body = CodeGenerator.CreateNotImplementedBlock();
            }

            RefactoringDocumentAdapter documentWrapper = new RefactoringDocumentAdapter(editor.Document);

            if (isExtension)
            {
                method.Parameters.Insert(0, new Ast.ParameterDeclarationExpression(CodeGenerator.ConvertType(rr.Target, finder), "thisInstance"));
                method.IsExtensionMethod = true;
                method.Modifier         |= Ast.Modifiers.Static;
            }

            if (isNew)
            {
                Ast.TypeDeclaration newType = new Ast.TypeDeclaration(isExtension ? Ast.Modifiers.Static : Ast.Modifiers.None, null);
                newType.Name = result as string;
                newType.AddChild(method);
                gen.InsertCodeAfter(targetClass, documentWrapper, newType);
            }
            else
            {
                if (IsEqualClass(rr.CallingClass, targetClass))
                {
                    gen.InsertCodeAfter(rr.CallingMember, documentWrapper, method);
                }
                else
                {
                    gen.InsertCodeAtEnd(targetClass.BodyRegion, documentWrapper, method);
                }
            }

            if (targetClass.ClassType == ClassType.Interface)
            {
                return;
            }

            ParseInformation info = ParserService.ParseFile(targetClass.CompilationUnit.FileName);

            if (info != null)
            {
                IMember newMember;

                if (isNew)
                {
                    targetClass = info.CompilationUnit.Classes.FirstOrDefault(c => c.DotNetName == c.Namespace + "." + (result as string));
                }
                else
                {
                    targetClass = info.CompilationUnit.Classes.Flatten(c => c.InnerClasses).FirstOrDefault(c => c.DotNetName == targetClass.DotNetName);
                }

                if (targetClass == null)
                {
                    return;
                }

                if (IsEqualClass(rr.CallingClass, targetClass))
                {
                    newMember = targetClass.GetInnermostMember(editor.Caret.Line, editor.Caret.Column);
                    newMember = targetClass.AllMembers
                                .OrderBy(m => m.BodyRegion.BeginLine)
                                .ThenBy(m2 => m2.BodyRegion.BeginColumn)
                                .First(m3 => m3.BodyRegion.BeginLine > newMember.BodyRegion.BeginLine);
                }
                else
                {
                    newMember = targetClass.Methods.Last();
                }

                IDocumentLine line         = editor.Document.GetLine(newMember.BodyRegion.BeginLine + 2);
                int           indentLength = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset).Length;
                editor.Select(line.Offset + indentLength, "throw new NotImplementedException();".Length);
            }
        }
Пример #16
0
 protected string GetIndentation(IDocument document, int line)
 {
     return(DocumentUtilitites.GetWhitespaceAfter(document, document.GetLine(line).Offset));
 }
Пример #17
0
        protected override string GenerateCode(LanguageProperties language, IClass currentClass)
        {
            IDocumentLine line   = editor.Document.GetLineForOffset(anchor.Offset);
            string        indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset);

            List <PropertyOrFieldWrapper> filtered = this.varList.SelectedItems.OfType <PropertyOrFieldWrapper>()
                                                     .OrderBy(p => p.Index)
                                                     .ToList();

            BlockStatement block = new BlockStatement();

            foreach (PropertyOrFieldWrapper w in filtered)
            {
                if (w.AddCheckForNull)
                {
                    // true = reference, null = generic or unknown
                    if (w.Type.IsReferenceType != false)
                    {
                        block.AddChild(
                            new IfElseStatement(
                                new BinaryOperatorExpression(new IdentifierExpression(w.ParameterName), BinaryOperatorType.Equality, new PrimitiveExpression(null)),
                                new ThrowStatement(new ObjectCreateExpression(new TypeReference("ArgumentNullException"), new List <Expression>()
                        {
                            new PrimitiveExpression(w.ParameterName, '"' + w.ParameterName + '"')
                        }))
                                )
                            );
                    }
                    else
                    {
                        block.AddChild(
                            new IfElseStatement(
                                new UnaryOperatorExpression(new MemberReferenceExpression(new IdentifierExpression(w.MemberName), "HasValue"), UnaryOperatorType.Not),
                                new ThrowStatement(new ObjectCreateExpression(new TypeReference("ArgumentNullException"), new List <Expression>()
                        {
                            new PrimitiveExpression(w.ParameterName, '"' + w.ParameterName + '"')
                        }))
                                )
                            );
                    }
                }
                if (w.AddRangeCheck)
                {
                    block.AddChild(
                        new IfElseStatement(
                            new BinaryOperatorExpression(
                                new BinaryOperatorExpression(new IdentifierExpression(w.ParameterName), BinaryOperatorType.LessThan, new IdentifierExpression("lower")),
                                BinaryOperatorType.LogicalOr,
                                new BinaryOperatorExpression(new IdentifierExpression(w.ParameterName), BinaryOperatorType.GreaterThan, new IdentifierExpression("upper"))
                                ),
                            new ThrowStatement(
                                new ObjectCreateExpression(
                                    new TypeReference("ArgumentOutOfRangeException"),
                                    new List <Expression>()
                    {
                        new PrimitiveExpression(w.ParameterName, '"' + w.ParameterName + '"'), new IdentifierExpression(w.ParameterName), new BinaryOperatorExpression(new PrimitiveExpression("Value must be between "), BinaryOperatorType.Concat, new BinaryOperatorExpression(new IdentifierExpression("lower"), BinaryOperatorType.Concat, new BinaryOperatorExpression(new PrimitiveExpression(" and "), BinaryOperatorType.Concat, new IdentifierExpression("upper"))))
                    }
                                    )
                                )
                            )
                        );
                }
            }

            foreach (PropertyOrFieldWrapper w in filtered)
            {
                block.AddChild(new ExpressionStatement(new AssignmentExpression(new MemberReferenceExpression(new ThisReferenceExpression(), w.MemberName), AssignmentOperatorType.Assign, new IdentifierExpression(w.ParameterName))));
            }

            AnchorElement parameterListElement = context.ActiveElements
                                                 .OfType <AnchorElement>()
                                                 .FirstOrDefault(item => item.Name.Equals("parameterList", StringComparison.OrdinalIgnoreCase));

            if (parameterListElement != null)
            {
                StringBuilder pList = new StringBuilder();

                var parameters = filtered
                                 .Select(p => new ParameterDeclarationExpression(ConvertType(p.Type), p.ParameterName))
                                 .ToList();

                for (int i = 0; i < parameters.Count; i++)
                {
                    if (i > 0)
                    {
                        pList.Append(", ");
                    }
                    pList.Append(language.CodeGenerator.GenerateCode(parameters[i], ""));
                }

                parameterListElement.Text = pList.ToString();
            }

            StringBuilder builder = new StringBuilder();

            foreach (var element in block.Children.OfType <AbstractNode>())
            {
                builder.Append(language.CodeGenerator.GenerateCode(element, indent));
            }

            return(builder.ToString().Trim());
        }
        protected override string GenerateCode(LanguageProperties language, IClass currentClass)
        {
            StringBuilder builder              = new StringBuilder();
            IDocumentLine line                 = editor.Document.GetLineForOffset(anchor.Offset);
            string        indent               = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset);
            bool          implementInterface   = this.implementInterface.IsChecked == true;
            bool          hasOnPropertyChanged = HasOnPropertyChanged(currentClass);
            bool          useEventArgs         = false;

            if (implementInterface && !currentClass.IsStatic)
            {
                if (!hasOnPropertyChanged)
                {
                    var nodes = new List <AbstractNode>();
                    var rt    = new GetClassReturnType(currentClass.ProjectContent, "System.ComponentModel.INotifyPropertyChanged", 0);
                    if (!currentClass.ClassInheritanceTree.Any(bt => bt.FullyQualifiedName == "System.ComponentModel.INotifyPropertyChanged"))
                    {
                        int insertion = editor.Document.PositionToOffset(currentClass.BodyRegion.BeginLine, currentClass.BodyRegion.BeginColumn);
                        if (currentClass.BaseTypes.Count > 0)
                        {
                            editor.Document.Insert(insertion, ", INotifyPropertyChanged");
                        }
                        else
                        {
                            editor.Document.Insert(insertion, " : INotifyPropertyChanged");
                        }
                    }
                    language.CodeGenerator.ImplementInterface(nodes, rt, false, currentClass);
                    var ev = rt.GetEvents().First(e => e.Name == "PropertyChanged");
                    MethodDeclaration onEvent = language.CodeGenerator.CreateOnEventMethod(new DefaultEvent(ev.Name, ev.ReturnType, ev.Modifiers, ev.Region, ev.BodyRegion, currentClass));
                    nodes.Add(onEvent);
                    onEvent.Parameters[0].TypeReference = new TypeReference("string", true);
                    onEvent.Parameters[0].ParameterName = "propertyName";
                    ((RaiseEventStatement)onEvent.Body.Children[0]).Arguments[1] = new ObjectCreateExpression(new TypeReference("PropertyChangedEventArgs"), new List <Expression> {
                        new IdentifierExpression("propertyName")
                    });
                    foreach (var node in nodes)
                    {
                        builder.AppendLine(language.CodeGenerator.GenerateCode(node, indent));
                    }
                    useEventArgs = false;
                }
                else
                {
                    useEventArgs = currentClass.DefaultReturnType.GetMethods().First(m => m.Name == "OnPropertyChanged").Parameters[0].ReturnType.FullyQualifiedName != "System.String";
                }
            }

            foreach (FieldWrapper field in listBox.SelectedItems)
            {
                var prop = language.CodeGenerator.CreateProperty(field.Field, true, field.AddSetter);
                if (!field.Field.IsStatic && !currentClass.IsStatic && field.AddSetter && implementInterface)
                {
                    var invocation = new ExpressionStatement(CreateInvocation(field.PropertyName, useEventArgs));
                    var assignment = prop.SetRegion.Block.Children[0];
                    prop.SetRegion.Block.Children.Clear();
                    prop.SetRegion.Block.AddChild(
                        new IfElseStatement(
                            new BinaryOperatorExpression(new IdentifierExpression(field.MemberName), BinaryOperatorType.InEquality, new IdentifierExpression("value")),
                            new BlockStatement {
                        Children = { assignment, invocation }
                    }
                            )
                        );
                }
                builder.AppendLine(language.CodeGenerator.GenerateCode(prop, indent));
            }

            return(builder.ToString().Trim());
        }
Пример #19
0
        protected override string GenerateCode(LanguageProperties language, IClass currentClass)
        {
            StringBuilder code = new StringBuilder();

            var line = editor.Document.GetLineForOffset(startAnchor.Offset);

            string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset);

            CodeGenerator generator = language.CodeGenerator;

            if (Options.AddIEquatableInterface)
            {
                // TODO : add IEquatable<T> to class
//				IAmbience ambience = currentClass.CompilationUnit.Language.GetAmbience();
//
//				IReturnType baseRType = currentClass.CompilationUnit.ProjectContent.GetClass("System.IEquatable", 1).DefaultReturnType;
//
//				IClass newClass = new DefaultClass(currentClass.CompilationUnit, currentClass.FullyQualifiedName, currentClass.Modifiers, currentClass.Region, null);
//
//				foreach (IReturnType type in currentClass.BaseTypes) {
//					newClass.BaseTypes.Add(type);
//				}
//
//
//				newClass.BaseTypes.Add(new ConstructedReturnType(baseRType, new List<IReturnType>() { currentClass.DefaultReturnType }));
//
//				ambience.ConversionFlags = ConversionFlags.IncludeBody;
//
//				string a = ambience.Convert(currentClass);
//
//				int startOffset = editor.Document.PositionToOffset(currentClass.Region.BeginLine, currentClass.Region.BeginColumn);
//				int endOffset = editor.Document.PositionToOffset(currentClass.BodyRegion.EndLine, currentClass.BodyRegion.EndColumn);
//
//				editor.Document.Replace(startOffset, endOffset - startOffset, a);
            }

            if (Options.SurroundWithRegion)
            {
                editor.Document.InsertNormalized(startAnchor.Offset, "#region Equals and GetHashCode implementation\n" + indent);
            }

            string codeForMethodBody;

            if ("Equals".Equals(selectedMethod.Name, StringComparison.Ordinal))
            {
                IList <MethodDeclaration> equalsOverrides = CreateEqualsOverrides(currentClass);
                MethodDeclaration         defaultOverride = equalsOverrides.First();
                equalsOverrides = equalsOverrides.Skip(1).ToList();

                StringBuilder builder = new StringBuilder();

                foreach (AbstractNode element in defaultOverride.Body.Children.OfType <AbstractNode>())
                {
                    builder.Append(language.CodeGenerator.GenerateCode(element, indent + "\t"));
                }

                codeForMethodBody = builder.ToString().Trim();

                if (addOtherMethod.IsChecked == true)
                {
                    if (equalsOverrides.Any())
                    {
                        code.Append(indent + "\n" + string.Join("\n", equalsOverrides.Select(item => generator.GenerateCode(item, indent))));
                    }
                    code.Append(indent + "\n" + generator.GenerateCode(CreateGetHashCodeOverride(currentClass), indent));
                }
            }
            else
            {
                StringBuilder builder = new StringBuilder();

                foreach (AbstractNode element in CreateGetHashCodeOverride(currentClass).Body.Children.OfType <AbstractNode>())
                {
                    builder.Append(language.CodeGenerator.GenerateCode(element, indent + "\t"));
                }

                codeForMethodBody = builder.ToString().Trim();

                if (addOtherMethod.IsChecked == true)
                {
                    code.Append(indent + "\n" + string.Join("\n", CreateEqualsOverrides(currentClass).Select(item => generator.GenerateCode(item, indent))));
                }
            }

            if (Options.AddOperatorOverloads)
            {
                var checkStatements = new[] {
                    new IfElseStatement(
                        new InvocationExpression(
                            new IdentifierExpression("ReferenceEquals"),
                            new List <Expression>()
                    {
                        new IdentifierExpression("lhs"), new IdentifierExpression("rhs")
                    }
                            ),
                        new ReturnStatement(new PrimitiveExpression(true))
                        ),
                    new IfElseStatement(
                        new BinaryOperatorExpression(
                            new InvocationExpression(
                                new IdentifierExpression("ReferenceEquals"),
                                new List <Expression>()
                    {
                        new IdentifierExpression("lhs"), new PrimitiveExpression(null)
                    }
                                ),
                            BinaryOperatorType.LogicalOr,
                            new InvocationExpression(
                                new IdentifierExpression("ReferenceEquals"),
                                new List <Expression>()
                    {
                        new IdentifierExpression("rhs"), new PrimitiveExpression(null)
                    }
                                )
                            ),
                        new ReturnStatement(new PrimitiveExpression(false))
                        )
                };

                BlockStatement equalsOpBody = new BlockStatement()
                {
                    Children =
                    {
                        new ReturnStatement(
                            new InvocationExpression(
                                new MemberReferenceExpression(new IdentifierExpression("lhs"), "Equals"),
                                new List <Expression>()
                        {
                            new IdentifierExpression("rhs")
                        }
                                )
                            )
                    }
                };

                if (currentClass.ClassType == Dom.ClassType.Class)
                {
                    equalsOpBody.Children.InsertRange(0, checkStatements);
                }

                BlockStatement notEqualsOpBody = new BlockStatement()
                {
                    Children =
                    {
                        new ReturnStatement(
                            new UnaryOperatorExpression(
                                new ParenthesizedExpression(
                                    new BinaryOperatorExpression(
                                        new IdentifierExpression("lhs"),
                                        BinaryOperatorType.Equality,
                                        new IdentifierExpression("rhs")
                                        )
                                    ),
                                UnaryOperatorType.Not
                                )
                            )
                    }
                };

                code.Append(indent + "\n" + generator.GenerateCode(CreateOperatorOverload(OverloadableOperatorType.Equality, currentClass, equalsOpBody), indent));
                code.Append(indent + "\n" + generator.GenerateCode(CreateOperatorOverload(OverloadableOperatorType.InEquality, currentClass, notEqualsOpBody), indent));
            }

            if (Options.SurroundWithRegion)
            {
                code.AppendLine(indent + "#endregion");
            }

            editor.Document.InsertNormalized(insertionEndAnchor.Offset, code.ToString());

            return(codeForMethodBody);
        }
Пример #20
0
        static void TryIndent(ITextEditor editor, int begin, int end)
        {
            string         currentIndentation = "";
            Stack <string> tagStack           = new Stack <string>();
            IDocument      document           = editor.Document;

            string      tab             = editor.Options.IndentationString;
            int         nextLine        = begin; // in #dev coordinates
            bool        wasEmptyElement = false;
            XmlNodeType lastType        = XmlNodeType.XmlDeclaration;

            using (StringReader stringReader = new StringReader(document.Text)) {
                XmlTextReader r = new XmlTextReader(stringReader);
                r.XmlResolver = null;                 // prevent XmlTextReader from loading external DTDs
                while (r.Read())
                {
                    if (wasEmptyElement)
                    {
                        wasEmptyElement = false;
                        if (tagStack.Count == 0)
                        {
                            currentIndentation = "";
                        }
                        else
                        {
                            currentIndentation = tagStack.Pop();
                        }
                    }
                    if (r.NodeType == XmlNodeType.EndElement)
                    {
                        if (tagStack.Count == 0)
                        {
                            currentIndentation = "";
                        }
                        else
                        {
                            currentIndentation = tagStack.Pop();
                        }
                    }

                    while (r.LineNumber >= nextLine)
                    {
                        if (nextLine > end)
                        {
                            break;
                        }
                        if (lastType == XmlNodeType.CDATA || lastType == XmlNodeType.Comment)
                        {
                            nextLine++;
                            continue;
                        }
                        // set indentation of 'nextLine'
                        IDocumentLine line     = document.GetLine(nextLine);
                        string        lineText = line.Text;

                        string newText;
                        // special case: opening tag has closing bracket on extra line: remove one indentation level
                        if (lineText.Trim() == ">")
                        {
                            newText = tagStack.Peek() + lineText.Trim();
                        }
                        else
                        {
                            newText = currentIndentation + lineText.Trim();
                        }

                        if (newText != lineText)
                        {
                            int extraCharsToBeAddedAtStartedOfLine = newText.Length - lineText.Length;
                            document.Replace(line.Offset, line.Length, newText);
                            Location caretPosition = document.OffsetToPosition(line.Offset + extraCharsToBeAddedAtStartedOfLine);
                            editor.Caret.Position = caretPosition;
                        }
                        nextLine++;
                    }
                    if (r.LineNumber > end)
                    {
                        break;
                    }
                    wasEmptyElement = r.NodeType == XmlNodeType.Element && r.IsEmptyElement;
                    string attribIndent = null;
                    if (r.NodeType == XmlNodeType.Element)
                    {
                        tagStack.Push(currentIndentation);
                        if (r.LineNumber < begin)
                        {
                            currentIndentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, editor.Document.PositionToOffset(r.LineNumber, 1));
                        }
                        if (r.Name.Length < 16)
                        {
                            attribIndent = currentIndentation + new string(' ', 2 + r.Name.Length);
                        }
                        else
                        {
                            attribIndent = currentIndentation + tab;
                        }
                        currentIndentation += tab;
                    }
                    lastType = r.NodeType;
                    if (r.NodeType == XmlNodeType.Element && r.HasAttributes)
                    {
                        int startLine = r.LineNumber;
                        r.MoveToAttribute(0);                         // move to first attribute
                        if (r.LineNumber != startLine)
                        {
                            attribIndent = currentIndentation;                             // change to tab-indentation
                        }
                        r.MoveToAttribute(r.AttributeCount - 1);
                        while (r.LineNumber >= nextLine)
                        {
                            if (nextLine > end)
                            {
                                break;
                            }
                            // set indentation of 'nextLine'
                            IDocumentLine line    = document.GetLine(nextLine);
                            string        newText = attribIndent + line.Text.Trim();
                            document.SmartReplaceLine(line, newText);
                            nextLine++;
                        }
                    }
                }
                r.Close();
            }
        }