diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/JavaBraceMatcher.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/JavaBraceMatcher.java index 471198e146ba..ffb589a07873 100644 --- a/java/java-impl/src/com/intellij/codeInsight/highlighting/JavaBraceMatcher.java +++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/JavaBraceMatcher.java @@ -32,6 +32,7 @@ public class JavaBraceMatcher implements PairedBraceMatcher { new BracePair(JavaTokenType.LBRACE, JavaTokenType.RBRACE, true), new BracePair(JavaTokenType.LBRACKET, JavaTokenType.RBRACKET, false), new BracePair(JavaDocTokenType.DOC_INLINE_TAG_START, JavaDocTokenType.DOC_INLINE_TAG_END, false), + new BracePair(JavaTokenType.LT, JavaTokenType.GT, false) }; @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/JavaPairedBraceMatcher.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/JavaPairedBraceMatcher.java new file mode 100644 index 000000000000..f11c40ff4bfc --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/JavaPairedBraceMatcher.java @@ -0,0 +1,98 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.highlighting; + +import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.lang.BracePair; +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.editor.highlighter.HighlighterIterator; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.impl.source.tree.StdTokenSets; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.ArrayUtil; + +public class JavaPairedBraceMatcher extends PairedBraceMatcherAdapter { + public JavaPairedBraceMatcher() { + super(new JavaBraceMatcher(), JavaLanguage.INSTANCE); + } + + @Override + public boolean isLBraceToken(HighlighterIterator iterator, CharSequence fileText, FileType fileType) { + return isBrace(iterator, fileText, fileType, true); + } + + @Override + public boolean isRBraceToken(HighlighterIterator iterator, CharSequence fileText, FileType fileType) { + return isBrace(iterator, fileText, fileType, false); + } + + private boolean isBrace(HighlighterIterator iterator, + CharSequence fileText, + FileType fileType, + boolean left) { + final BracePair pair = findPair(left, iterator, fileText, fileType); + if (pair == null) return false; + + final IElementType opposite = left ? JavaTokenType.GT : JavaTokenType.LT; + if ((left ? pair.getRightBraceType() : pair.getLeftBraceType()) != opposite) return true; + + if (fileType != JavaFileType.INSTANCE) return false; + + final IElementType braceElementType = left ? JavaTokenType.LT : JavaTokenType.GT; + int paired = 1; + int count = 0; + try { + while (true) { + count++; + if (iterator.atEnd()) break; + if (left) { + iterator.advance(); + } else { + iterator.retreat(); + } + final IElementType tokenType = iterator.getTokenType(); + if (tokenType == opposite) { + paired--; + if (paired == 0) return true; + continue; + } + + if (tokenType == braceElementType) { + paired++; + continue; + } + + if (!StdTokenSets.WHITE_SPACE_OR_COMMENT_BIT_SET.contains(tokenType) && + tokenType != JavaTokenType.IDENTIFIER && + tokenType != JavaTokenType.COMMA) { + return false; + } + } + return false; + } + finally { + while (count-- > 0) { + if (left) { + iterator.retreat(); + } else { + iterator.advance(); + } + } + } + } +} + diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/highlighting/JavaBraceMatcherTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/highlighting/JavaBraceMatcherTest.java new file mode 100644 index 000000000000..97f59458f676 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/highlighting/JavaBraceMatcherTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.highlighting; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.highlighter.EditorHighlighter; +import com.intellij.openapi.editor.highlighter.HighlighterIterator; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; + +public class JavaBraceMatcherTest extends LightCodeInsightFixtureTestCase { + public void testGenerics() { + myFixture.configureByText("a.java", "import java.util.ArrayList;" + + "class A {" + + " ArrayList f;" + + "}"); + final int offset = BraceMatchingUtil.getMatchedBraceOffset(myFixture.getEditor(), true, myFixture.getFile()); + assertTrue(offset == 54); + } + + public void testBinaryStatement() { + myFixture.configureByText("a.java", "import java.util.ArrayList;" + + "class A {" + + " int i = 3 < 4 ? 5 > 6 : 1 : 1 : 1;" + + "}"); + final Editor editor = myFixture.getEditor(); + final EditorHighlighter editorHighlighter = ((EditorEx)editor).getHighlighter(); + final HighlighterIterator iterator = editorHighlighter.createIterator(editor.getCaretModel().getOffset()); + boolean matched = BraceMatchingUtil.matchBrace(editor.getDocument().getCharsSequence(), myFixture.getFile().getFileType(), iterator, true); + assertFalse(matched); + } + + + +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceMatchingUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceMatchingUtil.java index c3fc814181b3..2eceba6e82e6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceMatchingUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceMatchingUtil.java @@ -391,6 +391,9 @@ public class BraceMatchingUtil { if (matcher instanceof XmlAwareBraceMatcher) { return (XmlAwareBraceMatcher)matcher; } + else if (matcher instanceof PairedBraceMatcherAdapter) { + return (BraceMatcher)matcher; + } else { return new PairedBraceMatcherAdapter(matcher, lang); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/PairedBraceMatcherAdapter.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/PairedBraceMatcherAdapter.java index 8880ad3a6ad3..4078fe41fd24 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/PairedBraceMatcherAdapter.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/PairedBraceMatcherAdapter.java @@ -30,7 +30,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -public class PairedBraceMatcherAdapter implements NontrivialBraceMatcher { +public class PairedBraceMatcherAdapter implements NontrivialBraceMatcher, PairedBraceMatcher { private final PairedBraceMatcher myMatcher; private final Language myLanguage; @@ -39,6 +39,11 @@ public class PairedBraceMatcherAdapter implements NontrivialBraceMatcher { myLanguage = language; } + @Override + public BracePair[] getPairs() { + return myMatcher.getPairs(); + } + @Override public int getBraceTokenGroupId(IElementType tokenType) { final BracePair[] pairs = myMatcher.getPairs(); diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 6b889d90a370..c06866b0a63d 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -970,7 +970,7 @@ - +