private static bool NeedAutoinsertCloseBracket(CachingLexer lexer)
        {
            using (LexerStateCookie.Create(lexer))
            {
                TokenNodeType typedToken = lexer.TokenType;

                // find the leftmost non-closed bracket (including typed) of typed class so that there are no opened brackets of other type
                var           bracketMatcher = new PsiBracketMatcher();
                TokenNodeType tokenType      = typedToken;

                int leftParenthPos = lexer.CurrentPosition;
                do
                {
                    if (tokenType == typedToken && bracketMatcher.IsStackEmpty())
                    {
                        leftParenthPos = lexer.CurrentPosition;
                    }
                    else if (!bracketMatcher.ProceedStack(tokenType))
                    {
                        break;
                    }
                    lexer.Advance(-1);
                } while ((tokenType = lexer.TokenType) != null);

                // Try to find the matched pair bracket
                lexer.CurrentPosition = leftParenthPos;

                return(!bracketMatcher.FindMatchingBracket(lexer));
            }
        }
Esempio n. 2
0
        public virtual IChameleonNode ReSync(CachingLexer cachingLexer, TreeTextRange changedRange, int insertedTextLen)
        {
            TreeTextRange oldRange = this.GetTreeTextRange();

            Logger.Assert(changedRange.ContainedIn(oldRange), "The condition “changedRange.ContainedIn(oldRange)” is false.");

            int newLength = oldRange.Length - changedRange.Length + insertedTextLen;

            // Find starting comment
            if (!cachingLexer.FindTokenAt(oldRange.StartOffset.Offset) ||
                cachingLexer.TokenType != this.GetTokenType() ||
                cachingLexer.TokenStart != oldRange.StartOffset.Offset ||
                cachingLexer.TokenEnd != oldRange.StartOffset.Offset + newLength)
            {
                return(null);
            }

            var element = TreeElementFactory.CreateLeafElement(
                cachingLexer.TokenType,
                new ProjectedBuffer(
                    cachingLexer.Buffer, new TextRange(cachingLexer.TokenStart, cachingLexer.TokenStart + newLength)),
                0,
                newLength);
            var comment = element as Comment;

            if (comment == null || this.CommentType != comment.CommentType)
            {
                return(null);
            }
            return(comment);
        }
Esempio n. 3
0
        public IChameleonNode ReSync(CachingLexer cachingLexer, TreeTextRange changedRange, int insertedTextLen)
        {
            TreeOffset currStartOffset = GetTreeStartOffset();
            int        currLength      = GetTextLength();

            Logger.Assert(changedRange.StartOffset >= currStartOffset && changedRange.EndOffset <= (currStartOffset + currLength),
                          "changedRange.StartOffset >= currStartOffset && changedRange.EndOffset <= (currStartOffset+currLength)");

            int newLength = currLength - changedRange.Length + insertedTextLen;

            LanguageService languageService = Language.LanguageService();

            if (languageService != null)
            {
                var         parser     = (IPsiParser)languageService.CreateParser(new ProjectedLexer(cachingLexer, new TextRange(currStartOffset.Offset, currStartOffset.Offset + newLength)), GetPsiModule(), GetSourceFile());
                TreeElement newElement = parser.ParseStatement();
                if (newElement.GetTextLength() == 0)
                {
                    return(null);
                }
                if ((newElement.GetTextLength() == newLength) && (";".Equals(newElement.GetText().Substring(newElement.GetTextLength() - 1))))
                {
                    var psiFile = GetContainingNode <PsiFile>();
                    if (psiFile != null)
                    {
                        psiFile.ClearTables();
                    }
                    return(newElement as IRuleDeclaration);
                }
            }
            return(null);
        }
        private bool HandleLeftBraceTyped(ITypingContext typingContext)
        {
            ITextControl textControl = typingContext.TextControl;

            using (CommandProcessor.UsingCommand("Smart LBRACE"))
            {
                typingContext.CallNext();

                // check if typed char is a token
                int          charPos = TextControlToLexer(textControl, textControl.Caret.Offset() - 1);
                CachingLexer lexer   = GetCachingLexer(textControl);
                if (charPos < 0 || !lexer.FindTokenAt(charPos) || lexer.TokenStart != charPos)
                {
                    return(true);
                }

                if (NeedAutoinsertCloseBracket(lexer))
                {
                    if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS)
                    {
                        return(true);
                    }

                    AutoinsertRBrace(textControl, lexer);
                    int position = charPos + 1;
                    if (position >= 0)
                    {
                        textControl.Caret.MoveTo(position, CaretVisualPlacement.DontScrollIfVisible);
                    }
                }
            }
            return(true);
        }
Esempio n. 5
0
        private bool IsAtValidStartToken(CachingLexer cachingLexer)
        {
            // Make sure the current token is one we can start resyncing from. A body node can start with practically anything
            // so the best we can do is make sure there are no significant tokens before us - i.e. the only preceding tokens
            // should be whitespace, new lines, comment and document or directive end
            var tokenBuffer = cachingLexer.TokenBuffer;

            for (var i = cachingLexer.CurrentPosition - 1; i >= 0; i--)
            {
                var token = tokenBuffer[i];

                // Start of buffer, start of document, end of previous document
                if (token.Type == null || token.Type == YamlTokenType.DIRECTIVES_END || token.Type == YamlTokenType.DOCUMENT_END)
                {
                    return(true);
                }

                if (!token.Type.IsComment && !token.Type.IsWhitespace)
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 6
0
        public IChameleonNode ReSync(CachingLexer cachingLexer, TreeTextRange changedRange, int insertedTextLen)
        {
            var currentStartOffset = GetTreeStartOffset();
            var currentLength      = GetTextLength();

            Assertion.Assert(
                changedRange.StartOffset >= currentStartOffset && changedRange.EndOffset <= currentStartOffset + currentLength,
                "changedRange.StartOffset >= currentStartOffset && changedRange.EndOffset <= (currentStartOffset+currentLength)");

            var newLength = currentLength - changedRange.Length + insertedTextLen;

            // Can we resync from the start point?
            if (!cachingLexer.FindTokenAt(currentStartOffset.Offset) ||
                cachingLexer.TokenStart != currentStartOffset.Offset ||
                !IsAtValidStartToken(cachingLexer))
            {
                return(null);
            }

            // Try to find a valid end point
            TokenNodeType tokenType;
            var           calculatedNewLength = 0;

            while ((tokenType = cachingLexer.TokenType) != null &&
                   (calculatedNewLength += cachingLexer.TokenEnd - cachingLexer.TokenStart) < newLength)
            {
                // We shouldn't encounter these until the end of the changed range
                if (tokenType == YamlTokenType.DOCUMENT_END || tokenType == YamlTokenType.DIRECTIVES_END)
                {
                    return(null);
                }

                cachingLexer.Advance();
            }

            if (calculatedNewLength != newLength || !IsAtValidEndToken(cachingLexer))
            {
                return(null);
            }

            // TODO: Should this be synchronised?
            // The C# implementation isn't...
            if (!myOpened)
            {
                var buffer = ProjectedBuffer.Create(cachingLexer.Buffer,
                                                    new TextRange(currentStartOffset.Offset, currentStartOffset.Offset + newLength));
                var closedChameleon = new ClosedChameleonElement(YamlTokenType.CHAMELEON, buffer, TreeOffset.Zero,
                                                                 new TreeOffset(buffer.Length));
                return(new ChameleonDocumentBody(closedChameleon));
            }

            var projectedLexer = new ProjectedLexer(cachingLexer, new TextRange(currentStartOffset.Offset, currentStartOffset.Offset + newLength));
            var parser         =
                (IYamlParser)Language.LanguageService().CreateParser(projectedLexer, GetPsiModule(), GetSourceFile());

            var openedChameleon = parser.ParseDocumentBody();

            return(new ChameleonDocumentBody(openedChameleon));
        }
Esempio n. 7
0
        /// <summary>
        /// When a " is typed, insert another ".
        /// </summary>
        private bool OnQuoteTyped(ITypingContext context)
        {
            ITextControl textControl = context.TextControl;

            // the " character should be skipped to avoid double insertions
            if (_skippingTypingAssist.ShouldSkip(textControl.Document, context.Char))
            {
                _skippingTypingAssist.SkipIfNeeded(textControl.Document, context.Char);
                return(true);
            }

            // get the token type after "
            CachingLexer cachingLexer = GetCachingLexer(textControl);
            int          offset       = textControl.Selection.OneDocRangeWithCaret().GetMinOffset();

            if (cachingLexer == null || offset <= 0 || !cachingLexer.FindTokenAt(offset))
            {
                return(false);
            }

            // there is already another quote after the ", swallow the typing
            TokenNodeType tokenType = cachingLexer.TokenType;

            if (tokenType == T4TokenNodeTypes.Quote)
            {
                textControl.Caret.MoveTo(offset + 1, CaretVisualPlacement.DontScrollIfVisible);
                return(true);
            }

            // we're inside or after an attribute value, simply do nothing and let the " be typed
            if (tokenType == T4TokenNodeTypes.Value)
            {
                return(false);
            }

            // insert the first "
            TextControlUtil.DeleteSelection(textControl);
            textControl.FillVirtualSpaceUntilCaret();
            textControl.Document.InsertText(offset, "\"");

            // insert the second "
            context.QueueCommand(() => {
                using (CommandProcessor.UsingCommand("Inserting \"")) {
                    textControl.Document.InsertText(offset + 1, "\"");
                    textControl.Caret.MoveTo(offset + 1, CaretVisualPlacement.DontScrollIfVisible);
                }

                // ignore if a subsequent " is typed by the user
                _skippingTypingAssist.SetCharsToSkip(textControl.Document, "\"");

                // popup auto completion
                _codeCompletionSessionManager.ExecuteAutoCompletion <T4AutopopupSettingsKey>(textControl, Solution, key => key.InDirectives);
            });

            return(true);
        }
        private bool HandleColonTyped(ITypingContext typingContext)
        {
            ITextControl textControl = typingContext.TextControl;

            if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS)
            {
                return(false);
            }

            using (CommandProcessor.UsingCommand("Smart :"))
            {
                TextControlUtil.DeleteSelection(textControl);

                textControl.FillVirtualSpaceUntilCaret();
                int          charPos = TextControlToLexer(textControl, textControl.Caret.Offset());
                CachingLexer lexer   = GetCachingLexer(textControl);

                if (charPos < 0 || !lexer.FindTokenAt(charPos) || lexer.TokenStart != charPos ||
                    lexer.TokenType != PsiTokenType.COLON)
                {
                    typingContext.CallNext();
                }
                else
                {
                    int position = charPos + 1;
                    if (position < 0)
                    {
                        return(true);
                    }
                    textControl.Caret.MoveTo(position, CaretVisualPlacement.DontScrollIfVisible);
                }

                if (NeedAutoinsertSemicolon(textControl))
                {
                    if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS)
                    {
                        return(true);
                    }

                    char c         = typingContext.Char;
                    int  insertPos = charPos;
                    if (insertPos >= 0)
                    {
                        textControl.Document.InsertText(insertPos + 1, ";");
                        textControl.Caret.MoveTo(insertPos + 1, CaretVisualPlacement.DontScrollIfVisible);
                    }

                    // format statement
                    if (GetTypingAssistOption(textControl, TypingAssistOptions.FormatStatementOnSemicolonExpression))
                    {
                        DoFormatStatementOnColon(textControl);
                    }
                }
                return(true);
            }
        }
 // smart backspaces expecteed that GetExtraStub return not null value, "foo " is typical value
 protected override string GetExtraStub(CachingLexer lexer, int offset)
 {
     using (LexerStateCookie.Create(lexer))
     {
         lexer.FindTokenAt(offset);
         if (!(lexer.TokenType is CppTokenNodeType))
         {
             return("foo ");
         }
     }
     return(base.GetExtraStub(lexer, offset));
 }
        private bool FindCgContent(ITextControl textControl, out CachingLexer lexer)
        {
            var offset = textControl.Caret.DocumentOffset().Offset;

            // base is important here!
            lexer = base.GetCachingLexer(textControl);

            if (lexer == null || !lexer.FindTokenAt(offset))
            {
                return(false);
            }
            return(true);
        }
        private bool HandleLeftBracketOrParenthTyped(ITypingContext typingContext)
        {
            ITextControl textControl = typingContext.TextControl;

            using (CommandProcessor.UsingCommand("Smart " + typingContext.Char))
            {
                typingContext.CallNext();
                using (WriteLockCookie.Create())
                {
                    // check if typed char is a token
                    CachingLexer lexer   = GetCachingLexer(textControl);
                    int          charPos = TextControlToLexer(textControl, textControl.Caret.Offset() - 1);
                    if (charPos < 0 || !lexer.FindTokenAt(charPos) || lexer.TokenStart != charPos)
                    {
                        return(true);
                    }
                    if (lexer.TokenType != PsiTokenType.LBRACKET && lexer.TokenType != PsiTokenType.LPARENTH)
                    {
                        return(true);
                    }

                    // check that next token is good one
                    TokenNodeType nextTokenType = lexer.LookaheadToken(1);
                    if (nextTokenType != null && nextTokenType != PsiTokenType.WHITE_SPACE &&
                        nextTokenType != PsiTokenType.NEW_LINE && nextTokenType != PsiTokenType.C_STYLE_COMMENT &&
                        nextTokenType != PsiTokenType.END_OF_LINE_COMMENT && nextTokenType != PsiTokenType.SEMICOLON &&
                        nextTokenType != PsiTokenType.RBRACKET && nextTokenType != PsiTokenType.RBRACE &&
                        nextTokenType != PsiTokenType.RPARENTH)
                    {
                        return(true);
                    }

                    if (NeedAutoinsertCloseBracket(lexer))
                    {
                        if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS)
                        {
                            return(true);
                        }

                        char c         = typingContext.Char;
                        int  insertPos = charPos;
                        if (insertPos >= 0)
                        {
                            textControl.Document.InsertText(insertPos + 1, c == '(' ? ")" : c == '[' ? "]" : "}");
                            textControl.Caret.MoveTo(insertPos + 1, CaretVisualPlacement.DontScrollIfVisible);
                        }
                    }
                }
            }
            return(true);
        }
        private bool ShouldIgnoreCaretPosition(ITextControl textControl, out CachingLexer lexer)
        {
            var offset = textControl.Caret.DocumentOffset().Offset;

            // base is important here!
            lexer = base.GetCachingLexer(textControl);

            if (lexer == null || !lexer.FindTokenAt(offset))
            {
                return(true);
            }

            // inside HLSL program
            return(lexer.TokenType is CppTokenNodeType);
        }
Esempio n. 13
0
        /// <summary>When = is typed, insert "".</summary>
        private bool OnEqualTyped(ITypingContext context)
        {
            ITextControl textControl = context.TextControl;

            // get the token type before =
            CachingLexer cachingLexer = GetCachingLexer(textControl);
            int          offset       = textControl.Selection.OneDocRangeWithCaret().GetMinOffset();

            if (cachingLexer == null || offset <= 0 || !cachingLexer.FindTokenAt(offset - 1))
            {
                return(false);
            }

            // do nothing if we're not after an attribute name
            TokenNodeType tokenType = cachingLexer.TokenType;

            if (tokenType != T4TokenNodeTypes.TOKEN)
            {
                return(false);
            }

            // insert =
            textControl.Selection.Delete();
            textControl.FillVirtualSpaceUntilCaret();
            textControl.Document.InsertText(offset, "=");
            textControl.Caret.MoveTo(offset + 1, CaretVisualPlacement.DontScrollIfVisible);

            // insert ""
            context.QueueCommand(() =>
            {
                using (CommandProcessor.UsingCommand("Inserting \"\""))
                {
                    textControl.Document.InsertText(offset + 1, "\"\"");
                    textControl.Caret.MoveTo(offset + 2, CaretVisualPlacement.DontScrollIfVisible);
                }

                // ignore if a subsequent " is typed by the user
                SkippingTypingAssist.SetCharsToSkip(textControl.Document, "\"");

                // popup auto completion
                _codeCompletionSessionManager.ExecuteAutoCompletion <T4AutopopupSettingsKey>(textControl, Solution,
                                                                                             key => key.InDirectives);
            });

            return(true);
        }
        private TextRange FixRange(int startOffset, int endOffset, [CanBeNull] string logicalName, IBuffer buffer,
                                   CachingLexer lexer)
        {
            // todo: remove when visualfsharp#3920 is implemented

            // trim foo.``bar`` to ``bar``
            const int minimumEscapedNameLength = 5;

            if (endOffset >= minimumEscapedNameLength && buffer.Length >= minimumEscapedNameLength &&
                buffer[endOffset - 1] == '`' && buffer[endOffset - 2] == '`')
            {
                for (var i = endOffset - 4; i >= startOffset; i--)
                {
                    if (buffer[i] == '`' && buffer[i + 1] == '`')
                    {
                        return(new TextRange(i, endOffset));
                    }
                }
            }

            if (logicalName != null && PrettyNaming.IsMangledOpName(logicalName))
            {
                var sourceName = PrettyNaming.DecompileOpName.Invoke(logicalName);
                if (sourceName.Length == endOffset - startOffset)
                {
                    return(new TextRange(startOffset, endOffset));
                }

                // todo: use lexer buffer
                if (lexer.FindTokenAt(endOffset - 1) && lexer.TokenType is TokenNodeType tokenType)
                {
                    var opText = tokenType == FSharpTokenType.SYMBOLIC_OP ? sourceName : logicalName;
                    return(new TextRange(endOffset - opText.Length, endOffset));
                }
            }

            // trim foo.bar to bar
            for (var i = endOffset - 1; i > startOffset; i--)
            {
                if (buffer[i].Equals('.'))
                {
                    return(new TextRange(i + 1, endOffset));
                }
            }
            return(new TextRange(startOffset, endOffset));
        }
        public override string CalculateInjectionIndent(CachingLexer lexer, ITextControl textControl)
        {
            var offset = textControl.Caret.DocumentOffset();

            using (LexerStateCookie.Create(lexer))
            {
                if (!lexer.FindTokenAt(offset.Offset))
                {
                    return("");
                }

                var tt = lexer.TokenType;
                while (tt != null)
                {
                    lexer.Advance(-1);
                    tt = lexer.TokenType;

                    if (tt == ShaderLabTokenType.CG_PROGRAM || tt == ShaderLabTokenType.CG_INCLUDE ||
                        tt == ShaderLabTokenType.HLSL_PROGRAM || tt == ShaderLabTokenType.HLSL_INCLUDE ||
                        tt == ShaderLabTokenType.GLSL_PROGRAM || tt == ShaderLabTokenType.GLSL_INCLUDE)
                    {
                        break;
                    }
                }

                if (tt != null)
                {
                    var doc       = textControl.Document;
                    var lineStart = doc.GetLineStartOffset(doc.GetCoordsByOffset(lexer.TokenStart).Line);
                    lexer.FindTokenAt(lineStart);
                    tt = lexer.TokenType;

                    Assertion.AssertNotNull(tt, "Lexer.TokenType may not be null");
                    while (tt.IsWhitespace)
                    {
                        lexer.Advance();
                        tt = lexer.TokenType;
                    }

                    var tokenLineStart = doc.GetLineStartOffset(doc.GetCoordsByOffset(lexer.TokenStart).Line);
                    return(doc.GetText(new TextRange(tokenLineStart, lexer.TokenStart)));
                }
            }

            return("");
        }
        private bool NeedSkipCloseBracket(CachingLexer lexer, char charTyped)
        {
            // check if the next token matches the typed char
            TokenNodeType nextToken = lexer.TokenType;

            if ((charTyped == ')' && nextToken != PsiTokenType.RPARENTH) ||
                (charTyped == ']' && nextToken != PsiTokenType.RBRACKET) ||
                (charTyped == '}' && nextToken != PsiTokenType.RBRACE))
            {
                return(false);
            }

            // find the leftmost non-closed bracket (excluding typed) of typed class so that there are no opened brackets of other type
            var           bracketMatcher  = new PsiBracketMatcher();
            TokenNodeType searchTokenType = charTyped == ')'
        ? PsiTokenType.LPARENTH
        : charTyped == ']' ? PsiTokenType.LBRACKET : PsiTokenType.LBRACE;
            int?          leftParenthPos = null;
            TokenNodeType tokenType;

            for (lexer.Advance(-1); (tokenType = lexer.TokenType) != null; lexer.Advance(-1))
            {
                if (tokenType == searchTokenType && bracketMatcher.IsStackEmpty())
                {
                    leftParenthPos = lexer.CurrentPosition;
                }
                else if (!bracketMatcher.ProceedStack(tokenType))
                {
                    break;
                }
            }

            // proceed with search result
            if (leftParenthPos == null)
            {
                return(false);
            }
            lexer.CurrentPosition = leftParenthPos.Value;
            return(bracketMatcher.FindMatchingBracket(lexer));
        }
Esempio n. 17
0
        private TokenNodeType FindPreviousToken([CanBeNull] CachingLexer lexer, int initialOffset)
        {
            if (lexer == null)
            {
                return(null);
            }
            for (int offset = initialOffset; offset >= 0; offset -= 1)
            {
                if (!lexer.FindTokenAt(offset))
                {
                    continue;
                }
                var tokenType = lexer.TokenType;
                if (tokenType?.IsWhitespace != false)
                {
                    continue;
                }
                return(tokenType);
            }

            return(null);
        }
Esempio n. 18
0
        private bool IsAtValidEndToken(CachingLexer cachingLexer)
        {
            // There is no token marking the exact end of the chameleon body - make sure the next significant token is EOF,
            // directives end or document end
            TokenNodeType tokenType;

            while ((tokenType = cachingLexer.TokenType) != null)
            {
                if (tokenType == YamlTokenType.DOCUMENT_END || tokenType == YamlTokenType.DIRECTIVES_END)
                {
                    return(true);
                }

                if (!tokenType.IsComment && !tokenType.IsWhitespace)
                {
                    return(false);
                }

                cachingLexer.Advance();
            }

            return(true);
        }
        private bool HandleRightBracketTyped(ITypingContext typingContext)
        {
            ITextControl textControl = typingContext.TextControl;

            if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS)
            {
                return(false);
            }

            using (CommandProcessor.UsingCommand("Smart bracket"))
            {
                TextControlUtil.DeleteSelection(textControl);

                int          charPos = TextControlToLexer(textControl, textControl.Caret.Offset());
                CachingLexer lexer   = GetCachingLexer(textControl);
                if (charPos < 0 || !lexer.FindTokenAt(charPos) || lexer.TokenStart != charPos)
                {
                    return(false);
                }

                if (NeedSkipCloseBracket(lexer, typingContext.Char))
                {
                    int position = charPos + 1;
                    if (position >= 0)
                    {
                        textControl.Caret.MoveTo(position, CaretVisualPlacement.DontScrollIfVisible);
                    }
                }
                else
                {
                    typingContext.CallNext();
                }
            }

            return(true);
        }
Esempio n. 20
0
    public IChameleonNode ReSync(CachingLexer cachingLexer, TreeTextRange changedRange, int insertedTextLen)
    {
      TreeTextRange oldRange = this.GetTreeTextRange();

      Logger.Assert(changedRange.ContainedIn(oldRange), "The condition “changedRange.ContainedIn(oldRange)” is false.");

      int newLength = oldRange.Length - changedRange.Length + insertedTextLen;
      // Find starting comment
      if (!cachingLexer.FindTokenAt(oldRange.StartOffset.Offset) ||
        cachingLexer.TokenType != GetTokenType() ||
          cachingLexer.TokenStart != oldRange.StartOffset.Offset ||
            cachingLexer.TokenEnd != oldRange.StartOffset.Offset + newLength)
      {
        return null;
      }

      LeafElementBase element = TreeElementFactory.CreateLeafElement(cachingLexer.TokenType, new ProjectedBuffer(cachingLexer.Buffer, new TextRange(cachingLexer.TokenStart, cachingLexer.TokenStart + newLength)), 0, newLength);
      var comment = element as Comment;
      if (comment == null || CommentType != comment.CommentType)
      {
        return null;
      }
      return comment;
    }
    public IChameleonNode ReSync(CachingLexer cachingLexer, TreeTextRange changedRange, int insertedTextLen)
    {
      TreeOffset currStartOffset = GetTreeStartOffset();
      int currLength = GetTextLength();

      Logger.Assert(changedRange.StartOffset >= currStartOffset && changedRange.EndOffset <= (currStartOffset + currLength),
        "changedRange.StartOffset >= currStartOffset && changedRange.EndOffset <= (currStartOffset+currLength)");

      int newLength = currLength - changedRange.Length + insertedTextLen;

      LanguageService languageService = Language.LanguageService();
      if (languageService != null)
      {
        var parser = (IPsiParser)languageService.CreateParser(new ProjectedLexer(cachingLexer, new TextRange(currStartOffset.Offset, currStartOffset.Offset + newLength)), GetPsiModule(), GetSourceFile());
        TreeElement newElement = parser.ParseStatement();
        if (newElement.GetTextLength() == 0)
        {
          return null;
        }
        if ((newElement.GetTextLength() == newLength) && (";".Equals(newElement.GetText().Substring(newElement.GetTextLength() - 1))))
        {
          var psiFile = GetContainingNode<PsiFile>();
          if (psiFile != null)
          {
            psiFile.ClearTables();
          }
          return newElement as IRuleDeclaration;
        }
      }
      return null;
    }
Esempio n. 22
0
 public IChameleonNode ReSync(CachingLexer cachingLexer, TreeTextRange changedRange, int insertedTextLen)
 {
     return(null);
 }
Esempio n. 23
0
 public IChameleonNode ReSync(CachingLexer cachingLexer, TreeTextRange changedRange, int insertedTextLen)
 {
     throw new System.NotImplementedException();
 }
Esempio n. 24
0
 private bool IsBlockStart([NotNull] CachingLexer lexer) =>
 lexer.TokenType == T4TokenNodeTypes.STATEMENT_BLOCK_START ||
 lexer.TokenType == T4TokenNodeTypes.EXPRESSION_BLOCK_START ||
 lexer.TokenType == T4TokenNodeTypes.FEATURE_BLOCK_START;
 public FilteringPsiLexer(CachingLexer lexer)
     : base(lexer)
 {
 }
Esempio n. 26
0
 protected override string CalculateBaseIndent(CachingLexer lexer, ITextControl textControl)
 {
     return(myCppDummyFormatter.CalculateInjectionIndent(lexer, textControl));
 }
Esempio n. 27
0
 public override IChameleonNode ReSync(CachingLexer cachingLexer, TreeTextRange changedRange, int insertedTextLen)
 {
     return(base.ReSync(cachingLexer, changedRange, insertedTextLen) as DocComment);
 }
        /*private bool HandleRightBraceTyped(ITypingContext typingContext)
         * {
         * var textControl = typingContext.TextControl;
         * using (CommandProcessor.UsingCommand("Smart LBRACE"))
         * {
         *  typingContext.CallNext();
         *
         *  // check if typed char is a token
         *  int charPos = TextControlToLexer(textControl, textControl.Caret.Offset() - 1);
         *  CachingLexer lexer = GetCachingLexer(textControl);
         *  if (charPos < 0 || !lexer.FindTokenAt(charPos) || lexer.TokenStart != charPos)
         *    return true;
         *
         *  if (NeedAutoinsertCloseBracket(lexer))
         *  {
         *    if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS)
         *      return true;
         *
         *    AutoinsertRBrace(textControl, lexer);
         *    var position = charPos + 1;
         *    if (position >= 0)
         *      textControl.Caret.MoveTo(position, CaretVisualPlacement.DontScrollIfVisible);
         *  }
         * }
         * return true;
         * }*/

        private bool AutoinsertRBrace(ITextControl textControl, CachingLexer lexer)
        {
            int charPos   = lexer.TokenEnd;
            int lBracePos = charPos - 1;

            if (lexer.TokenType != PsiTokenType.LBRACE)
            {
                return(false);
            }

            if (!NeedAutoinsertCloseBracket(lexer))
            {
                return(false);
            }

            // insert RBRACE next to the LBRACE
            IDocument document = textControl.Document;
            int       position = lBracePos;

            if (position < 0)
            {
                return(false);
            }

            document.InsertText(position + 1, "}");

            // Commit PSI
            IFile file = CommitPsi(textControl);

            if (file == null)
            {
                return(false);
            }

            TreeTextRange treeLBraceRange = file.Translate(new DocumentRange(document, new TextRange(lBracePos + 1)));

            if (!treeLBraceRange.IsValid())
            {
                return(false);
            }

            var rBraceToken = file.FindTokenAt(treeLBraceRange.StartOffset) as ITokenNode;

            if (rBraceToken == null || rBraceToken.GetTokenType() != PsiTokenType.RBRACE)
            {
                return(false);
            }
            TreeOffset positionForRBrace = rBraceToken.GetTreeTextRange().EndOffset;


            // move RBRACE to another position, if necessary
            DocumentRange documentRangeForRBrace = file.GetDocumentRange(positionForRBrace);

            if (documentRangeForRBrace.IsValid() && documentRangeForRBrace.TextRange.StartOffset != lBracePos + 1)
            {
                int pos = documentRangeForRBrace.TextRange.StartOffset;
                if (pos >= 0)
                {
                    document.InsertText(pos, "}");
                    document.DeleteText(new TextRange(lBracePos + 1, lBracePos + 2));
                }
            }

            return(true);
        }
 public IChameleonNode ReSync(CachingLexer cachingLexer, TreeTextRange changedRange, int insertedTextLen) =>
 null; // No reparse for now.
        private bool HandleQuoteTyped(ITypingContext typingContext)
        {
            ITextControl textControl = typingContext.TextControl;

            if (typingContext.EnsureWritable() != EnsureWritableResult.SUCCESS)
            {
                return(false);
            }

            using (CommandProcessor.UsingCommand("Smart quote"))
            {
                TextControlUtil.DeleteSelection(textControl);
                textControl.FillVirtualSpaceUntilCaret();

                CachingLexer  lexer   = GetCachingLexer(textControl);
                IBuffer       buffer  = lexer.Buffer;
                int           charPos = TextControlToLexer(textControl, textControl.Caret.Offset());
                TokenNodeType correspondingTokenType = PsiTokenType.STRING_LITERAL;

                if (charPos < 0 || !lexer.FindTokenAt(charPos))
                {
                    return(false);
                }

                TokenNodeType tokenType = lexer.TokenType;


                // check if we should skip the typed char
                if (charPos < buffer.Length && buffer[charPos] == typingContext.Char && tokenType == correspondingTokenType &&
                    lexer.TokenStart != charPos && buffer[lexer.TokenStart] != '@')
                {
                    int position = charPos;
                    if (position >= 0)
                    {
                        textControl.Caret.MoveTo(position + 1, CaretVisualPlacement.DontScrollIfVisible);
                    }
                    return(true);
                }

                // check that next token is a good one
                if (tokenType != null && !IsStopperTokenForStringLiteral(tokenType))
                {
                    return(false);
                }


                // find next not whitespace token
                while (lexer.TokenType == PsiTokenType.WHITE_SPACE)
                {
                    lexer.Advance();
                }

                bool doInsertPairQuote = (lexer.TokenType == correspondingTokenType) &&
                                         ((lexer.TokenEnd > lexer.TokenStart + 1) && (lexer.Buffer[lexer.TokenStart] == typingContext.Char) && (lexer.Buffer[lexer.TokenEnd - 1] == typingContext.Char));

                // do inserting of the requested char and updating of the lexer
                typingContext.CallNext();
                lexer = GetCachingLexer(textControl);
                //        charPos = TextControlToLexer(textControl, textControl.CaretModel.Offset - 1);

                if (!doInsertPairQuote)
                {
                    // check if the typed char is the beginning of the corresponding token
                    if (!lexer.FindTokenAt(charPos))
                    {
                        return(true);
                    }

                    bool isStringWithAt = lexer.TokenType == PsiTokenType.STRING_LITERAL && lexer.TokenStart == charPos - 1 &&
                                          lexer.Buffer[lexer.TokenStart] == '@';
                    if ((lexer.TokenStart != charPos) && !isStringWithAt)
                    {
                        return(true);
                    }

                    // check if there is unclosed token of the corresponding type up to the end of the source line
                    int newPos = charPos;
                    if (newPos < 0)
                    {
                        return(true);
                    }

                    DocumentCoords documentCoords = textControl.Document.GetCoordsByOffset(newPos);
                    int            offset         = textControl.Document.GetLineEndOffsetNoLineBreak(documentCoords.Line) - 1;

                    int lexerOffset = TextControlToLexer(textControl, offset);
                    if (lexerOffset >= 0)
                    {
                        lexer.FindTokenAt(lexerOffset);
                    }
                    if (lexerOffset < 0 || lexer.TokenType == null)
                    {
                        charPos = TextControlToLexer(textControl, textControl.Caret.Offset() - 1);
                        if (charPos >= 0)
                        {
                            lexer.FindTokenAt(charPos);
                        }
                        else
                        {
                            return(true);
                        }
                    }

                    doInsertPairQuote = (lexer.TokenType == correspondingTokenType) &&
                                        ((lexer.TokenEnd == lexer.TokenStart + 1) || (lexer.Buffer[lexer.TokenEnd - 1] != typingContext.Char) ||
                                         (isStringWithAt && (lexer.TokenStart == charPos - 1) && (lexer.TokenEnd != charPos + 1)));
                }

                // insert paired quote
                if (doInsertPairQuote)
                {
                    charPos++;
                    int documentPos = charPos;
                    if (documentPos >= 0)
                    {
                        textControl.Document.InsertText(documentPos, typingContext.Char == '\'' ? "'" : "\"");
                        textControl.Caret.MoveTo(documentPos, CaretVisualPlacement.DontScrollIfVisible);
                    }
                }
            }

            return(true);
        }
Esempio n. 31
0
 public TextRange GetBlockComment(CachingLexer lexer)
 {
     return(lexer.TokenType == ShaderLabTokenType.MULTI_LINE_COMMENT
         ? new TextRange(lexer.TokenStart, lexer.TokenEnd)
         : TextRange.InvalidRange);
 }
        private bool DoHandleEnterAfterLBracePressed(ITextControl textControl)
        {
            int charPos = TextControlToLexer(textControl, textControl.Caret.Offset());

            if (charPos <= 0)
            {
                return(false);
            }

            // Check that token before caret is LBRACE
            CachingLexer lexer = GetCachingLexer(textControl);

            if (!lexer.FindTokenAt(charPos - 1))
            {
                return(false);
            }

            if (lexer.TokenType == PsiTokenType.WHITE_SPACE)
            {
                charPos = lexer.TokenStart;
                lexer.Advance(-1);
            }
            if (lexer.TokenType != PsiTokenType.LBRACE)
            {
                return(false);
            }

            int lBracePos = lexer.TokenStart;

            // If necessary, do RBRACE autoinsert
            bool braceInserted = false;

            if (GetTypingAssistOption(textControl, TypingAssistOptions.BraceInsertTypeExpression) == SmartBraceInsertType.ON_ENTER)
            {
                braceInserted = AutoinsertRBrace(textControl, lexer);

                // Resync with modified text
                lexer = GetCachingLexer(textControl);
                lexer.FindTokenAt(lBracePos);
                Logger.Assert(lexer.TokenType == PsiTokenType.LBRACE, "The condition (lexer.TokenType == CSharpTokenType.LBRACE) is false.");
            }

            // Find the matched RBRACE and check they are on the same line
            int rBracePos;

            if (!new PsiBracketMatcher().FindMatchingBracket(lexer, out rBracePos))
            {
                return(false);
            }

            int textControlLBracePos = lBracePos;
            int textControlRBracePos = rBracePos;

            if (textControlLBracePos < 0 || textControlRBracePos < 0 ||
                (!braceInserted &&
                 textControl.Document.GetCoordsByOffset(textControlLBracePos).Line !=
                 textControl.Document.GetCoordsByOffset(textControlRBracePos).Line))
            {
                return(false);
            }

            // Commit PSI for current document
            IFile file = CommitPsi(textControl);

            if (file == null)
            {
                return(false);
            }

            // Find nodes at the tree for braces
            TreeOffset lBraceTreePos = file.Translate(new DocumentRange(textControl.Document, lBracePos)).StartOffset;
            TreeOffset rBraceTreePos = file.Translate(new DocumentRange(textControl.Document, rBracePos)).StartOffset;

            var lBraceNode = file.FindTokenAt(lBraceTreePos) as ITokenNode;

            if (lBraceNode == null || lBraceNode.GetTokenType() != PsiTokenType.LBRACE)
            {
                return(false);
            }

            var rBraceNode = file.FindTokenAt(rBraceTreePos) as ITokenNode;

            if (rBraceNode == null || rBraceNode.GetTokenType() != PsiTokenType.RBRACE)
            {
                return(false);
            }

            TreeTextRange reparseTreeOffset = file.Translate(new DocumentRange(textControl.Document, charPos));
            const string  dummyText         = "a";

            return(ReformatForSmartEnter(dummyText, textControl, file, reparseTreeOffset, lBraceTreePos, rBraceTreePos));
        }
Esempio n. 33
0
 public override IChameleonNode ReSync(CachingLexer cachingLexer, TreeTextRange changedRange, int insertedTextLen)
 {
     return base.ReSync(cachingLexer, changedRange, insertedTextLen) as DocComment;
 }