diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java index 939a0a5b2c1d..0377048d0acb 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java @@ -17,6 +17,7 @@ package com.intellij.lang.java.parser; import com.intellij.codeInsight.daemon.JavaErrorMessages; import com.intellij.lang.PsiBuilder; +import com.intellij.lang.WhitespacesBinders; import com.intellij.openapi.util.Pair; import com.intellij.psi.JavaTokenType; import com.intellij.psi.impl.source.tree.ElementType; @@ -910,7 +911,7 @@ public class DeclarationParser { done(annoArray, JavaElementType.ANNOTATION_ARRAY_INITIALIZER); if (unclosed) { - annoArray.setCustomEdgeTokenBinders(null, GREEDY_RIGHT_EDGE_PROCESSOR); + annoArray.setCustomEdgeTokenBinders(null, WhitespacesBinders.GREEDY_RIGHT_BINDER); } return annoArray; } diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java index 25da01947be8..a8a2ff5006cb 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java @@ -18,6 +18,7 @@ package com.intellij.lang.java.parser; import com.intellij.codeInsight.daemon.JavaErrorMessages; import com.intellij.lang.PsiBuilder; import com.intellij.lang.PsiBuilderUtil; +import com.intellij.lang.WhitespacesBinders; import com.intellij.psi.JavaTokenType; import com.intellij.psi.TokenType; import com.intellij.psi.impl.source.tree.ElementType; @@ -964,7 +965,7 @@ public class ExpressionParser { list.done(JavaElementType.EXPRESSION_LIST); if (!closed) { - list.setCustomEdgeTokenBinders(null, GREEDY_RIGHT_EDGE_PROCESSOR); + list.setCustomEdgeTokenBinders(null, WhitespacesBinders.GREEDY_RIGHT_BINDER); } return list; } diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java index 2b436e78d926..ec6b39106d0b 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java @@ -51,13 +51,6 @@ public class JavaParserUtil { void parse(PsiBuilder builder); } - public static final WhitespacesAndCommentsBinder GREEDY_RIGHT_EDGE_PROCESSOR = new WhitespacesAndCommentsBinder() { - @Override - public int getEdgePosition(final List tokens, final boolean atStreamEdge, final TokenTextGetter getter) { - return tokens.size(); - } - }; - private static class PrecedingWhitespacesAndCommentsBinder implements WhitespacesAndCommentsBinder { private final boolean myAfterEmptyImport; diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/StatementParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/StatementParser.java index a2bce4d119d5..9e0655eba009 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/parser/StatementParser.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/StatementParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -17,6 +17,7 @@ package com.intellij.lang.java.parser; import com.intellij.codeInsight.daemon.JavaErrorMessages; import com.intellij.lang.PsiBuilder; +import com.intellij.lang.WhitespacesBinders; import com.intellij.psi.JavaTokenType; import com.intellij.psi.impl.source.tree.ElementType; import com.intellij.psi.impl.source.tree.JavaElementType; @@ -109,7 +110,7 @@ public class StatementParser { codeBlock.collapse(JavaElementType.CODE_BLOCK); if (greedyBlock) { - codeBlock.setCustomEdgeTokenBinders(null, GREEDY_RIGHT_EDGE_PROCESSOR); + codeBlock.setCustomEdgeTokenBinders(null, WhitespacesBinders.GREEDY_RIGHT_BINDER); } return codeBlock; } @@ -128,7 +129,7 @@ public class StatementParser { done(codeBlock, JavaElementType.CODE_BLOCK); if (greedyBlock) { - codeBlock.setCustomEdgeTokenBinders(null, GREEDY_RIGHT_EDGE_PROCESSOR); + codeBlock.setCustomEdgeTokenBinders(null, WhitespacesBinders.GREEDY_RIGHT_BINDER); } return codeBlock; } diff --git a/platform/core-api/src/com/intellij/lang/WhitespacesBinders.java b/platform/core-api/src/com/intellij/lang/WhitespacesBinders.java new file mode 100644 index 000000000000..4756be61ee07 --- /dev/null +++ b/platform/core-api/src/com/intellij/lang/WhitespacesBinders.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2013 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.lang; + +import com.intellij.openapi.util.Condition; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class WhitespacesBinders { + public static final WhitespacesAndCommentsBinder DEFAULT_RIGHT_BINDER = new WhitespacesAndCommentsBinder() { + public int getEdgePosition(List tokens, boolean atStreamEdge, TokenTextGetter getter) { + return 0; + } + }; + public static final WhitespacesAndCommentsBinder DEFAULT_LEFT_BINDER = new WhitespacesAndCommentsBinder() { + public int getEdgePosition(List tokens, boolean atStreamEdge, TokenTextGetter getter) { + return tokens.size(); + } + }; + + public static final WhitespacesAndCommentsBinder GREEDY_LEFT_BINDER = DEFAULT_RIGHT_BINDER; + public static final WhitespacesAndCommentsBinder GREEDY_RIGHT_BINDER = DEFAULT_LEFT_BINDER; + + public static WhitespacesAndCommentsBinder leadingCommentsBinder(@NotNull Condition isCommentCondition) { + return new LeadingCommentsBinder(isCommentCondition); + } + + public static WhitespacesAndCommentsBinder leadingCommentsBinder(IElementType... commentTypes) { + return leadingCommentsBinder(TokenSet.create(commentTypes)); + } + + public static WhitespacesAndCommentsBinder leadingCommentsBinder(@NotNull final TokenSet commentTypes) { + return leadingCommentsBinder(new Condition() { + @Override + public boolean value(IElementType type) { + return commentTypes.contains(type); + } + }); + } + + private static class LeadingCommentsBinder implements WhitespacesAndCommentsBinder { + @NotNull private final Condition myIsCommentCondition; + + LeadingCommentsBinder(@NotNull Condition isCommentCondition) { + myIsCommentCondition = isCommentCondition; + } + + @Override + public int getEdgePosition(List tokens, boolean atStreamEdge, TokenTextGetter getter) { + int i = 0; + while (i < tokens.size() && !myIsCommentCondition.value(tokens.get(i))) { + i++; + } + return i; + } + } + + private WhitespacesBinders() { + } +} diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java index 48d7c43c105e..dabe29e48617 100644 --- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java +++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java @@ -122,20 +122,6 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { } }); - private static final WhitespacesAndCommentsBinder DEFAULT_LEFT_EDGE_TOKEN_BINDER = new WhitespacesAndCommentsBinder() { - @Override - public int getEdgePosition(final List tokens, final boolean atStreamEdge, final TokenTextGetter getter) { - return tokens.size(); - } - }; - - private static final WhitespacesAndCommentsBinder DEFAULT_RIGHT_EDGE_TOKEN_BINDER = new WhitespacesAndCommentsBinder() { - @Override - public int getEdgePosition(final List tokens, final boolean atStreamEdge, final TokenTextGetter getter) { - return 0; - } - }; - public static void registerWhitespaceToken(IElementType type) { ourAnyLanguageWhitespaceTokens = TokenSet.orSet(ourAnyLanguageWhitespaceTokens, TokenSet.create(type)); } @@ -302,7 +288,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { private int myHC = -1; private StartMarker() { - myEdgeTokenBinder = DEFAULT_LEFT_EDGE_TOKEN_BINDER; + myEdgeTokenBinder = WhitespacesBinders.DEFAULT_LEFT_BINDER; } @Override @@ -314,7 +300,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { myDebugAllocationPosition = null; myFirstChild = myLastChild = null; myHC = -1; - myEdgeTokenBinder = DEFAULT_LEFT_EDGE_TOKEN_BINDER; + myEdgeTokenBinder = WhitespacesBinders.DEFAULT_LEFT_BINDER; } @Override @@ -577,7 +563,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { private boolean myCollapse = false; public DoneMarker() { - myEdgeTokenBinder = DEFAULT_RIGHT_EDGE_TOKEN_BINDER; + myEdgeTokenBinder = WhitespacesBinders.DEFAULT_RIGHT_BINDER; } public DoneMarker(final StartMarker marker, final int currentLexeme) { @@ -590,7 +576,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { public void clean() { super.clean(); myStart = null; - myEdgeTokenBinder = DEFAULT_RIGHT_EDGE_TOKEN_BINDER; + myEdgeTokenBinder = WhitespacesBinders.DEFAULT_RIGHT_BINDER; } @Override @@ -637,7 +623,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { myBuilder = builder; myMessage = message; myLexemeIndex = idx; - myEdgeTokenBinder = DEFAULT_RIGHT_EDGE_TOKEN_BINDER; + myEdgeTokenBinder = WhitespacesBinders.DEFAULT_RIGHT_BINDER; } @Override @@ -883,7 +869,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { DoneWithErrorMarker doneMarker = new DoneWithErrorMarker((StartMarker)marker, myCurrentLexeme, message); boolean tieToTheLeft = isEmpty(((StartMarker)marker).myLexemeIndex, myCurrentLexeme); - if (tieToTheLeft) ((StartMarker)marker).myEdgeTokenBinder = DEFAULT_RIGHT_EDGE_TOKEN_BINDER; + if (tieToTheLeft) ((StartMarker)marker).myEdgeTokenBinder = WhitespacesBinders.DEFAULT_RIGHT_BINDER; ((StartMarker)marker).myDoneMarker = doneMarker; myProduction.add(doneMarker); @@ -897,7 +883,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { DoneWithErrorMarker doneMarker = new DoneWithErrorMarker((StartMarker)marker, ((StartMarker)before).myLexemeIndex, message); boolean tieToTheLeft = isEmpty(((StartMarker)marker).myLexemeIndex, ((StartMarker)before).myLexemeIndex); - if (tieToTheLeft) ((StartMarker)marker).myEdgeTokenBinder = DEFAULT_RIGHT_EDGE_TOKEN_BINDER; + if (tieToTheLeft) ((StartMarker)marker).myEdgeTokenBinder = WhitespacesBinders.DEFAULT_RIGHT_BINDER; ((StartMarker)marker).myDoneMarker = doneMarker; myProduction.add(beforeIndex, doneMarker); @@ -911,7 +897,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { doneMarker.myLexemeIndex = myCurrentLexeme; boolean tieToTheLeft = doneMarker.myStart.myType.isLeftBound() && isEmpty(((StartMarker)marker).myLexemeIndex, myCurrentLexeme); - if (tieToTheLeft) ((StartMarker)marker).myEdgeTokenBinder = DEFAULT_RIGHT_EDGE_TOKEN_BINDER; + if (tieToTheLeft) ((StartMarker)marker).myEdgeTokenBinder = WhitespacesBinders.DEFAULT_RIGHT_BINDER; ((StartMarker)marker).myDoneMarker = doneMarker; myProduction.add(doneMarker); @@ -928,7 +914,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { doneMarker.myStart = (StartMarker)marker; boolean tieToTheLeft = doneMarker.myStart.myType.isLeftBound() && isEmpty(((StartMarker)marker).myLexemeIndex, ((StartMarker)before).myLexemeIndex); - if (tieToTheLeft) ((StartMarker)marker).myEdgeTokenBinder = DEFAULT_RIGHT_EDGE_TOKEN_BINDER; + if (tieToTheLeft) ((StartMarker)marker).myEdgeTokenBinder = WhitespacesBinders.DEFAULT_RIGHT_BINDER; ((StartMarker)marker).myDoneMarker = doneMarker; myProduction.add(beforeIndex, doneMarker); diff --git a/python/src/com/jetbrains/python/parsing/FunctionParsing.java b/python/src/com/jetbrains/python/parsing/FunctionParsing.java index 768fa0a8acff..ec8b528296ad 100644 --- a/python/src/com/jetbrains/python/parsing/FunctionParsing.java +++ b/python/src/com/jetbrains/python/parsing/FunctionParsing.java @@ -16,6 +16,7 @@ package com.jetbrains.python.parsing; import com.intellij.lang.PsiBuilder; +import com.intellij.lang.WhitespacesBinders; import com.intellij.psi.tree.IElementType; import com.jetbrains.python.PyElementTypes; import com.jetbrains.python.PyTokenTypes; @@ -81,7 +82,7 @@ public class FunctionParsing extends Parsing { } else { // empty arglist node, so we always have it PsiBuilder.Marker argListMarker = myBuilder.mark(); - argListMarker.setCustomEdgeTokenBinders(LeftBiasedWhitespaceBinder.INSTANCE, null); + argListMarker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, null); argListMarker.done(PyElementTypes.ARGUMENT_LIST); } if (atToken(PyTokenTypes.STATEMENT_BREAK)) { diff --git a/python/src/com/jetbrains/python/parsing/LeftBiasedWhitespaceBinder.java b/python/src/com/jetbrains/python/parsing/LeftBiasedWhitespaceBinder.java deleted file mode 100644 index 38bd0794f487..000000000000 --- a/python/src/com/jetbrains/python/parsing/LeftBiasedWhitespaceBinder.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2000-2013 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.jetbrains.python.parsing; - -import com.intellij.lang.WhitespacesAndCommentsBinder; -import com.intellij.psi.tree.IElementType; - -import java.util.List; - -/** - * @author yole - */ -public class LeftBiasedWhitespaceBinder implements WhitespacesAndCommentsBinder { - public static LeftBiasedWhitespaceBinder INSTANCE = new LeftBiasedWhitespaceBinder(); - - @Override - public int getEdgePosition(List tokens, boolean atStreamEdge, TokenTextGetter getter) { - return 0; - } -}