Ejemplo n.º 1
0
        Token GetClosestMissing(List <Token> missingEnds, VBStatement statement, TextArea textArea, int lineNr)
        {
            Token closest = null;
            int   diff    = 0;

            foreach (Token t in missingEnds)
            {
                if (!IsSingleLine(t.Location.Line, textArea))
                {
                    if (IsMatchingStatement(t, statement) && ((diff = lineNr - t.Location.Line + 1) > -1))
                    {
                        if (closest == null)
                        {
                            closest = t;
                        }
                        else
                        {
                            if (diff < lineNr - closest.Location.Line + 1)
                            {
                                closest = t;
                            }
                        }
                    }
                }
            }

            return(closest);
        }
Ejemplo n.º 2
0
        bool IsEndStatementNeeded(TextArea textArea, ref VBStatement statement, int lineNr)
        {
            Stack <Token> tokens      = new Stack <Token>();
            List <Token>  missingEnds = new List <Token>();

            ILexer lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, new StringReader(textArea.Document.TextContent));

            Token currentToken = null;
            Token prevToken    = null;

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

                if (IsBlockStart(lexer, currentToken, prevToken))
                {
                    if ((tokens.Count > 0 && tokens.Peek().Kind != Tokens.Interface) || IsDeclaration(currentToken.Kind))
                    {
                        tokens.Push(currentToken);
                    }
                }

                if (IsBlockEnd(currentToken, prevToken))
                {
                    while (tokens.Count > 0 && !IsMatchingEnd(tokens.Peek(), currentToken))
                    {
                        missingEnds.Add(tokens.Pop());
                    }

                    if (tokens.Count > 0)
                    {
                        if (IsMatchingEnd(tokens.Peek(), currentToken))
                        {
                            tokens.Pop();
                        }
                    }
                }

                prevToken = currentToken;
            }

            while (tokens.Count > 0)
            {
                missingEnds.Add(tokens.Pop());
            }

            if (missingEnds.Count > 0)
            {
                return(GetClosestMissing(missingEnds, statement, textArea, lineNr) != null);
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 3
0
        bool IsMatchingStatement(Token token, VBStatement statement)
        {
            if (token.Kind == Tokens.For && statement.EndStatement == "Next")
            {
                return(true);
            }

            if (token.Kind == Tokens.Do && statement.EndStatement.StartsWith("Loop"))
            {
                return(true);
            }

            bool empty = !string.IsNullOrEmpty(token.Value);
            bool match = statement.EndStatement.IndexOf(token.Value, StringComparison.InvariantCultureIgnoreCase) != -1;

            return(empty && match);
        }
Ejemplo n.º 4
0
        public VBFormattingStrategy()
        {
            statements = new List <VBStatement>();
            statements.Add(new VBStatement(@"^if.*?(then|\s+_)$", "^end ?if$", "End If", 1));
            statements.Add(new VBStatement(@"\bclass\s+\w+\s*($|\(\s*Of)", "^end class$", "End Class", 1));
            statements.Add(new VBStatement(@"\bnamespace\s+\w+(\.\w+)*$", "^end namespace$", "End Namespace", 1));
            statements.Add(new VBStatement(@"\bmodule\s+\w+$", "^end module$", "End Module", 1));
            statements.Add(new VBStatement(@"\bstructure\s+\w+\s*($|\(\s*Of)", "^end structure$", "End Structure", 1));
            statements.Add(new VBStatement(@"^while\s+", "^end while$", "End While", 1));
            statements.Add(new VBStatement(@"^select case", "^end select$", "End Select", 1));
            statements.Add(new VBStatement(@"(?<!\b(delegate|mustoverride|declare(\s+(unicode|ansi|auto))?)\s+)\bsub\s+\w+", @"^end\s+sub$", "End Sub", 1));
            statements.Add(new VBStatement(@"(?<!\bmustoverride (readonly |writeonly )?)\bproperty\s+\w+", @"^end\s+property$", "End Property", 1));
            statements.Add(new VBStatement(@"(?<!\b(delegate|mustoverride|declare(\s+(unicode|ansi|auto))?)\s+)\bfunction\s+\w+", @"^end\s+function$", "End Function", 1));
            statements.Add(new VBStatement(@"\boperator(\s*[\+\-\*\/\&\^\>\<\=\\]+\s*|\s+\w+\s*)\(", @"^end\s+operator$", "End Operator", 1));
            statements.Add(new VBStatement(@"\bfor\s+.*?$", "^next( \\w+)?$", "Next", 1));
            statements.Add(new VBStatement(@"^synclock\s+.*?$", "^end synclock$", "End SyncLock", 1));
            statements.Add(new VBStatement(@"^get$", "^end get$", "End Get", 1));
            statements.Add(new VBStatement(@"^with\s+.*?$", "^end with$", "End With", 1));
            statements.Add(new VBStatement(@"^set(\s*\(.*?\))?$", "^end set$", "End Set", 1));
            statements.Add(new VBStatement(@"^try$", "^end try$", "End Try", 1));
            statements.Add(new VBStatement(@"^do\s+.+?$", "^loop$", "Loop", 1));
            statements.Add(new VBStatement(@"^do$", "^loop .+?$", "Loop While ", 1));
            statements.Add(new VBStatement(@"\benum\s+\w+$", "^end enum$", "End Enum", 1));
            interfaceStatement = new VBStatement(@"\binterface\s+\w+\s*($|\(\s*Of)", "^end interface$", "End Interface", 1);
            statements.Add(interfaceStatement);
            statements.Add(new VBStatement(@"\busing\s+", "^end using$", "End Using", 1));
            statements.Add(new VBStatement(@"^#region\s+", "^#end region$", "#End Region", 0));

            keywords = new string[] {
                "AddHandler", "AddressOf", "Alias", "And",
                "AndAlso", "As", "Boolean", "ByRef",
                "Byte", "ByVal", "Call", "Case",
                "Catch", "CBool", "CByte", "CChar",
                "CDate", "CDbl", "CDec", "Char",
                "CInt", "Class", "CLng", "CObj",
                "Const", "Continue", "CSByte", "CShort",
                "CSng", "CStr", "CType", "CUInt",
                "CULng", "CUShort", "Date", "Decimal",
                "Declare", "Default", "Delegate", "Dim",
                "DirectCast", "Do", "Double", "Each",
                "Else", "ElseIf", "End", "EndIf",                 // EndIf special case: converted to "End If"
                "Enum", "Erase", "Error", "Event",
                "Exit", "False", "Finally", "For",
                "Friend", "Function", "Get", "GetType",
                "Global", "GoSub", "GoTo", "Handles",
                "If", "Implements", "Imports", "In",
                "Inherits", "Integer", "Interface", "Is",
                "IsNot", "Let", "Lib", "Like",
                "Long", "Loop", "Me", "Mod",
                "Module", "MustInherit", "MustOverride", "MyBase",
                "MyClass", "Namespace", "Narrowing", "New",
                "Next", "Not", "Nothing", "NotInheritable",
                "NotOverridable", "Object", "Of", "On",
                "Operator", "Option", "Optional", "Or",
                "OrElse", "Overloads", "Overridable", "Overrides",
                "ParamArray", "Partial", "Private", "Property",
                "Protected", "Public", "RaiseEvent", "ReadOnly",
                "ReDim", "REM", "RemoveHandler", "Resume",
                "Return", "SByte", "Select", "Set",
                "Shadows", "Shared", "Short", "Single",
                "Static", "Step", "Stop", "String",
                "Structure", "Sub", "SyncLock", "Then",
                "Throw", "To", "True", "Try",
                "TryCast", "TypeOf", "UInteger", "ULong",
                "UShort", "Using", "Variant", "Wend",
                "When", "While", "Widening", "With",
                "WithEvents", "WriteOnly", "Xor",
                // these are not keywords, but context dependend
                "Until", "Ansi", "Unicode", "Region", "Preserve"
            };
        }
Ejemplo n.º 5
0
        void FormatLineInternal(TextArea textArea, int lineNr, int cursorOffset, char ch)
        {
            string terminator = textArea.TextEditorProperties.LineTerminator;

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

            if (lineNr > 0)
            {
                LineSegment curLine   = textArea.Document.GetLineSegment(lineNr);
                LineSegment lineAbove = lineNr > 0 ? textArea.Document.GetLineSegment(lineNr - 1) : null;

                string curLineText   = textArea.Document.GetText(curLine.Offset, curLine.Length);
                string lineAboveText = lineAbove == null ? "" : textArea.Document.GetText(lineAbove);

                if (ch == '\'')
                {
                    curLineText = textArea.Document.GetText(curLine);

                    if (curLineText != null && curLineText.EndsWith("'''") && (lineAboveText == null || !lineAboveText.Trim().StartsWith("'''")))
                    {
                        string indentation = base.GetIndentation(textArea, lineNr);
                        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.Refresh();
                            textArea.Caret.Position = textArea.Document.OffsetToPosition(cursorOffset + indentation.Length + "/// ".Length + " <summary>".Length + terminator.Length);
                        }
                    }
                    return;
                }

                if (ch == '\n' && lineAboveText != null)
                {
                    string texttoreplace = lineAboveText;
                    // remove string content
                    MatchCollection strmatches = Regex.Matches(texttoreplace, "\"[^\"]*?\"", RegexOptions.Singleline);
                    foreach (Match match in strmatches)
                    {
                        texttoreplace = texttoreplace.Remove(match.Index, match.Length).Insert(match.Index, new String('-', match.Length));
                    }
                    // remove comments
                    texttoreplace = Regex.Replace(texttoreplace, "'.*$", "", RegexOptions.Singleline);

                    if (doCasing)
                    {
                        foreach (string keyword in keywords)
                        {
                            string          regex   = "\\b" + keyword + "\\b";                  // \b = word border
                            MatchCollection matches = Regex.Matches(texttoreplace, regex, RegexOptions.IgnoreCase | RegexOptions.Singleline);
                            foreach (Match match in matches)
                            {
                                if (keyword == "EndIf")                                 // special case
                                {
                                    textArea.Document.Replace(lineAbove.Offset + match.Index, match.Length, "End If");
                                }
                                else
                                {
                                    textArea.Document.Replace(lineAbove.Offset + match.Index, match.Length, keyword);
                                }
                            }
                        }
                    }

                    if (doInsertion)
                    {
                        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 (textArea.Document.GetCharAt(lineAbove.Offset + texttoreplace.Length) == '\'')
                                {
                                    specialThen += " ";
                                }
                                if (textArea.Document.GetCharAt(lineAbove.Offset + texttoreplace.Length - 1) != ' ')
                                {
                                    specialThen = " " + specialThen;
                                }

                                textArea.Document.Insert(lineAbove.Offset + texttoreplace.Length, specialThen);
                                texttoreplace += specialThen;
                            }
                        }
                        // check #Region statements
                        if (Regex.IsMatch(texttoreplace.Trim(), @"^#Region", RegexOptions.IgnoreCase) && LookForEndRegion(textArea))
                        {
                            string indentation = GetIndentation(textArea, lineNr - 1);
                            texttoreplace += indentation + "\r\n" + indentation + "#End Region";
                            textArea.Document.Replace(curLine.Offset, curLine.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 = GetIndentation(textArea, lineNr - 1);
                                if (IsEndStatementNeeded(textArea, ref statement, lineNr))
                                {
                                    textArea.Document.Replace(curLine.Offset, curLine.Length, terminator + indentation + statement.EndStatement);
                                }
                                if (!IsInsideInterface(textArea, lineNr) || statement == interfaceStatement)
                                {
                                    for (int i = 0; i < statement.IndentPlus; i++)
                                    {
                                        indentation += Tab.GetIndentationString(textArea.Document);
                                    }
                                }

                                textArea.Document.Replace(curLine.Offset, curLine.Length, indentation + curLineText.Trim());
                                textArea.Caret.Column = indentation.Length;
                                return;
                            }
                        }
                    }

                    if (IsInString(lineAboveText))
                    {
                        if (IsFinishedString(curLineText))
                        {
                            textArea.Document.Insert(lineAbove.Offset + lineAbove.Length,
                                                     "\" & _");
                            curLine = textArea.Document.GetLineSegment(lineNr);
                            textArea.Document.Insert(curLine.Offset, "\"");

                            if (IsElseConstruct(lineAboveText))
                            {
                                SmartIndentLine(textArea, lineNr - 1);
                            }
                            textArea.Caret.Column = SmartIndentLine(textArea, lineNr) + 1;
                        }
                        else
                        {
                            textArea.Document.Insert(lineAbove.Offset + lineAbove.Length,
                                                     "\"");
                            if (IsElseConstruct(lineAboveText))
                            {
                                SmartIndentLine(textArea, lineNr - 1);
                            }
                            textArea.Caret.Column = SmartIndentLine(textArea, lineNr);
                        }
                    }
                    else
                    {
                        string indent = GetIndentation(textArea, lineNr - 1);
                        if (indent.Length > 0)
                        {
                            string newLineText = indent + TextUtilities.GetLineAsString(textArea.Document, lineNr).Trim();
                            curLine = textArea.Document.GetLineSegment(lineNr);
                            textArea.Document.Replace(curLine.Offset, curLine.Length, newLineText);
                        }
                        if (IsElseConstruct(lineAboveText))
                        {
                            SmartIndentInternal(textArea, lineNr - 1, lineNr);
                        }
                        textArea.Caret.Column = GetIndentation(textArea, lineNr).Length;
                    }
                }
                else if (ch == '>')
                {
                    if (IsInsideDocumentationComment(textArea, curLine, cursorOffset))
                    {
                        curLineText = textArea.Document.GetText(curLine);
                        int column = textArea.Caret.Offset - 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(textArea.Caret.Offset, "</" + tag.Substring(1));
                            }
                        }
                    }
                }
            }
        }