From c743997c7bcac7340665d493c3421a6a8734537b Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Mon, 14 May 2012 19:26:12 +0400 Subject: [PATCH 01/11] RelativeLayout --- .../RelativeLayoutResizeOperation.java | 73 +++++++++++++++++++ .../layout/actions/ResizeOperation.java | 34 +++++---- .../layout/relative/RadRelativeLayout.java | 43 ++++++++--- 3 files changed, 127 insertions(+), 23 deletions(-) create mode 100644 plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/RelativeLayoutResizeOperation.java diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/RelativeLayoutResizeOperation.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/RelativeLayoutResizeOperation.java new file mode 100644 index 000000000000..1887a166412e --- /dev/null +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/RelativeLayoutResizeOperation.java @@ -0,0 +1,73 @@ +/* + * Copyright 2000-2012 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.android.designer.designSurface.layout.actions; + +import com.intellij.designer.designSurface.EditOperation; +import com.intellij.designer.designSurface.OperationContext; +import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator; +import com.intellij.designer.model.RadComponent; + +import java.util.List; + +/** + * @author Alexander Lobas + */ +public class RelativeLayoutResizeOperation implements EditOperation { + public static final String TYPE = "relative_resize"; + + public RelativeLayoutResizeOperation(OperationContext context) { + } + + @Override + public void setComponent(RadComponent component) { + // TODO: Auto-generated method stub + } + + @Override + public void setComponents(List components) { + // TODO: Auto-generated method stub + } + + @Override + public void showFeedback() { + // TODO: Auto-generated method stub + } + + @Override + public void eraseFeedback() { + // TODO: Auto-generated method stub + } + + @Override + public boolean canExecute() { + return false; // TODO: Auto-generated method stub + } + + @Override + public void execute() throws Exception { + // TODO: Auto-generated method stub + } + + ////////////////////////////////////////////////////////////////////////////////////////// + // + // ResizePoint + // + ////////////////////////////////////////////////////////////////////////////////////////// + + public static void points(ResizeSelectionDecorator decorator) { + // XXX + } +} \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/ResizeOperation.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/ResizeOperation.java index ff7025ac434c..d6e8b8ebb7c4 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/ResizeOperation.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/ResizeOperation.java @@ -65,20 +65,6 @@ public class ResizeOperation implements EditOperation { myContext = context; } - public static void points(ResizeSelectionDecorator decorator) { - width(decorator); - height(decorator); - decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH_EAST, TYPE, "Change layout:width x layout:height")); - } - - public static void width(ResizeSelectionDecorator decorator) { - decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.EAST, TYPE, "Change layout:width")); - } - - public static void height(ResizeSelectionDecorator decorator) { - decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH, TYPE, "Change layout:height")); - } - @Override public void setComponent(RadComponent component) { myComponent = (RadViewComponent)component; @@ -338,4 +324,24 @@ public class ResizeOperation implements EditOperation { } return Integer.toString(size) + "dp"; } + + ////////////////////////////////////////////////////////////////////////////////////////// + // + // ResizePoint + // + ////////////////////////////////////////////////////////////////////////////////////////// + + public static void points(ResizeSelectionDecorator decorator) { + width(decorator); + height(decorator); + decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH_EAST, TYPE, "Change layout:width x layout:height")); + } + + public static void width(ResizeSelectionDecorator decorator) { + decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.EAST, TYPE, "Change layout:width")); + } + + public static void height(ResizeSelectionDecorator decorator) { + decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH, TYPE, "Change layout:height")); + } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/RadRelativeLayout.java b/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/RadRelativeLayout.java index d24c12f69ce8..c2d573943077 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/RadRelativeLayout.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/RadRelativeLayout.java @@ -17,11 +17,14 @@ package com.intellij.android.designer.model.layout.relative; import com.intellij.android.designer.designSurface.TreeDropToOperation; import com.intellij.android.designer.designSurface.layout.RelativeLayoutOperation; +import com.intellij.android.designer.designSurface.layout.actions.RelativeLayoutResizeOperation; import com.intellij.android.designer.designSurface.layout.relative.RelativeDecorator; import com.intellij.android.designer.model.PropertyParser; import com.intellij.android.designer.model.RadViewLayoutWithData; +import com.intellij.android.designer.model.layout.actions.AllGravityAction; import com.intellij.designer.componentTree.TreeEditOperation; import com.intellij.designer.designSurface.*; +import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator; import com.intellij.designer.model.RadComponent; import com.intellij.designer.propertyTable.Property; import com.intellij.designer.propertyTable.PropertyTable; @@ -29,6 +32,8 @@ import com.intellij.openapi.actionSystem.DefaultActionGroup; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import java.awt.*; +import java.util.Arrays; import java.util.List; /** @@ -38,6 +43,7 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD private static final String[] LAYOUT_PARAMS = {"RelativeLayout_Layout", "ViewGroup_MarginLayout"}; private RelativeDecorator myRelativeDecorator; + private ResizeSelectionDecorator mySelectionDecorator; @NotNull @Override @@ -86,15 +92,12 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD } return new RelativeLayoutOperation(myContainer, context); } - // XXX + if (context.is(RelativeLayoutResizeOperation.TYPE)) { + return new RelativeLayoutResizeOperation(context); + } return null; } - @Override - public void removeComponentFromContainer(RadComponent component) { - // TODO: Auto-generated method stub - } - private RelativeDecorator getRelativeDecorator() { if (myRelativeDecorator == null) { myRelativeDecorator = new RelativeDecorator(myContainer); @@ -117,7 +120,11 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD @Override public ComponentDecorator getChildSelectionDecorator(RadComponent component, List selection) { - return super.getChildSelectionDecorator(component, selection); // TODO: Auto-generated method stub + if (mySelectionDecorator == null) { + mySelectionDecorator = new ResizeSelectionDecorator(Color.red, 1); + RelativeLayoutResizeOperation.points(mySelectionDecorator); + } + return mySelectionDecorator; } ////////////////////////////////////////////////////////////////////////////////////////// @@ -131,7 +138,16 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD DefaultActionGroup actionGroup, JComponent shortcuts, List selection) { - super.addContainerSelectionActions(designer, actionGroup, shortcuts, selection); // TODO: Auto-generated method stub + if (selection.get(selection.size() - 1) != myContainer) { + return; + } + for (RadComponent component : selection) { + if (!(component.getLayout() instanceof RadRelativeLayout)) { + return; + } + } + + actionGroup.add(new AllGravityAction(designer, Arrays.asList(myContainer))); } @Override @@ -139,6 +155,15 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD DefaultActionGroup actionGroup, JComponent shortcuts, List selection) { - super.addSelectionActions(designer, actionGroup, shortcuts, selection); // TODO: Auto-generated method stub + if (selection.get(selection.size() - 1).getParent() != myContainer) { + return; + } + for (RadComponent component : selection) { + if (!(component.getParent() instanceof RadRelativeLayoutComponent)) { + return; + } + } + + actionGroup.add(new AllGravityAction(designer, Arrays.asList(myContainer))); } } \ No newline at end of file From 4fcb275e5523843da1d4b930c26636528a867473 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 14 May 2012 19:35:42 +0400 Subject: [PATCH 02/11] Java 8: parse extension method bodies --- .../lang/java/parser/DeclarationParser.java | 18 +++++---- .../tree/java/AnnotationMethodElement.java | 9 +---- .../impl/source/tree/java/MethodElement.java | 13 ++++--- .../parser-partial/declarations/Extension.txt | 33 +++++++++++++++++ .../parser-partial/declarations/Unclosed6.txt | 25 +++++++++++++ .../parser-partial/declarations/Unclosed7.txt | 37 +++++++++++++++++++ .../parser-partial/declarations/Unclosed8.txt | 23 ++++++++++++ .../parser-partial/declarations/Unclosed9.txt | 25 +++++++++++++ .../parser/partial/DeclarationParserTest.java | 8 +++- 9 files changed, 168 insertions(+), 23 deletions(-) create mode 100644 java/java-tests/testData/psi/parser-partial/declarations/Extension.txt create mode 100644 java/java-tests/testData/psi/parser-partial/declarations/Unclosed6.txt create mode 100644 java/java-tests/testData/psi/parser-partial/declarations/Unclosed7.txt create mode 100644 java/java-tests/testData/psi/parser-partial/declarations/Unclosed8.txt create mode 100644 java/java-tests/testData/psi/parser-partial/declarations/Unclosed9.txt 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 b481daada460..7fa765687740 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 @@ -33,7 +33,6 @@ import static com.intellij.lang.PsiBuilderUtil.expect; import static com.intellij.lang.PsiBuilderUtil.nextTokenType; import static com.intellij.lang.java.parser.JavaParserUtil.*; - public class DeclarationParser { private final ExpressionParser myExpressionParser; private final StatementParser myStatementParser; @@ -417,7 +416,7 @@ public class DeclarationParser { } private PsiBuilder.Marker parseMethodFromLeftParenth(final PsiBuilder builder, final PsiBuilder.Marker declaration, - final boolean anno, final boolean constructor) { + final boolean anno, final boolean constructor) { parseParameterList(builder); eatBrackets(builder, constructor, "expected.semicolon"); @@ -435,12 +434,14 @@ public class DeclarationParser { myReferenceParser.parseReferenceList(builder, JavaTokenType.THROWS_KEYWORD, JavaElementType.THROWS_LIST, JavaTokenType.COMMA); - if (anno && expect(builder, JavaTokenType.DEFAULT_KEYWORD)) { + final boolean hasDefault = expect(builder, JavaTokenType.DEFAULT_KEYWORD); + if (hasDefault && anno) { parseAnnotationValue(builder); } final IElementType tokenType = builder.getTokenType(); - if (tokenType != JavaTokenType.SEMICOLON && tokenType != JavaTokenType.LBRACE) { + final boolean hasError = tokenType != JavaTokenType.SEMICOLON && tokenType != JavaTokenType.LBRACE; + if (hasError) { final PsiBuilder.Marker error = builder.mark(); // heuristic: going to next line obviously means method signature is over, starting new method (actually, another one completion hack) final CharSequence text = builder.getOriginalText(); @@ -456,10 +457,11 @@ public class DeclarationParser { error.error(JavaErrorMessages.message("expected.lbrace.or.semicolon")); } - if (!expect(builder, JavaTokenType.SEMICOLON)) { - if (builder.getTokenType() == JavaTokenType.LBRACE) { - myStatementParser.parseCodeBlock(builder); - } + if (hasDefault && !anno && !hasError && builder.getTokenType() != JavaTokenType.LBRACE) { + error(builder, JavaErrorMessages.message("expected.lbrace")); + } + if (!expect(builder, JavaTokenType.SEMICOLON) && builder.getTokenType() == JavaTokenType.LBRACE) { + myStatementParser.parseCodeBlock(builder); } done(declaration, anno ? JavaElementType.ANNOTATION_METHOD : JavaElementType.METHOD); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationMethodElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationMethodElement.java index 1903ab885e15..972b89e5068e 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationMethodElement.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationMethodElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.tree.java; import com.intellij.psi.impl.source.tree.ChildRole; import com.intellij.lang.ASTNode; - /** * @author ven */ @@ -31,8 +30,6 @@ public class AnnotationMethodElement extends MethodElement { public ASTNode findChildByRole(int role) { if (role == ChildRole.ANNOTATION_DEFAULT_VALUE) { return findChildByType(ANNOTATION_MEMBER_VALUE_BIT_SET); - } else if (role == ChildRole.DEFAULT_KEYWORD) { - return findChildByType(DEFAULT_KEYWORD); } return super.findChildByRole(role); @@ -40,9 +37,7 @@ public class AnnotationMethodElement extends MethodElement { @Override public int getChildRole(ASTNode child) { - if (child.getElementType() == DEFAULT_KEYWORD) { - return ChildRole.DEFAULT_KEYWORD; - } else if (ANNOTATION_MEMBER_VALUE_BIT_SET.contains(child.getElementType())) { + if (ANNOTATION_MEMBER_VALUE_BIT_SET.contains(child.getElementType())) { return ChildRole.ANNOTATION_DEFAULT_VALUE; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodElement.java index 600f4bd3e011..048ae975beb1 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodElement.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -112,6 +112,9 @@ public class MethodElement extends CompositeElement implements Constants { case ChildRole.CLOSING_SEMICOLON: return TreeUtil.findChildBackward(this, SEMICOLON); + + case ChildRole.DEFAULT_KEYWORD: + return findChildByType(DEFAULT_KEYWORD); } } @@ -122,11 +125,6 @@ public class MethodElement extends CompositeElement implements Constants { if (i == JavaDocElementType.DOC_COMMENT) { return getChildRole(child, ChildRole.DOC_COMMENT); } - else if (i == C_STYLE_COMMENT || i == END_OF_LINE_COMMENT) { - { - return ChildRoleBase.NONE; - } - } else if (i == MODIFIER_LIST) { return ChildRole.MODIFIER_LIST; } @@ -151,6 +149,9 @@ public class MethodElement extends CompositeElement implements Constants { else if (i == SEMICOLON) { return getChildRole(child, ChildRole.CLOSING_SEMICOLON); } + else if (i == DEFAULT_KEYWORD) { + return ChildRole.DEFAULT_KEYWORD; + } else { return ChildRoleBase.NONE; } diff --git a/java/java-tests/testData/psi/parser-partial/declarations/Extension.txt b/java/java-tests/testData/psi/parser-partial/declarations/Extension.txt new file mode 100644 index 000000000000..fe4e23c8ec36 --- /dev/null +++ b/java/java-tests/testData/psi/parser-partial/declarations/Extension.txt @@ -0,0 +1,33 @@ +PsiJavaFile:Extension.java + PsiJavaToken:LBRACE('{') + PsiWhiteSpace(' ') + PsiMethod:f + PsiModifierList: + + PsiTypeParameterList + + PsiTypeElement:int + PsiKeyword:int('int') + PsiWhiteSpace(' ') + PsiIdentifier:f('f') + PsiParameterList:() + PsiJavaToken:LPARENTH('(') + PsiJavaToken:RPARENTH(')') + PsiReferenceList + + PsiWhiteSpace(' ') + PsiKeyword:default('default') + PsiWhiteSpace(' ') + PsiCodeBlock + PsiJavaToken:LBRACE('{') + PsiWhiteSpace(' ') + PsiReturnStatement + PsiKeyword:return('return') + PsiWhiteSpace(' ') + PsiLiteralExpression:42 + PsiJavaToken:INTEGER_LITERAL('42') + PsiJavaToken:SEMICOLON(';') + PsiWhiteSpace(' ') + PsiJavaToken:RBRACE('}') + PsiWhiteSpace(' ') + PsiJavaToken:RBRACE('}') diff --git a/java/java-tests/testData/psi/parser-partial/declarations/Unclosed6.txt b/java/java-tests/testData/psi/parser-partial/declarations/Unclosed6.txt new file mode 100644 index 000000000000..e1e1b65dfa04 --- /dev/null +++ b/java/java-tests/testData/psi/parser-partial/declarations/Unclosed6.txt @@ -0,0 +1,25 @@ +PsiJavaFile:Unclosed6.java + PsiJavaToken:LBRACE('{') + PsiWhiteSpace(' ') + PsiAnnotationMethod:f + PsiModifierList: + + PsiTypeParameterList + + PsiTypeElement:void + PsiKeyword:void('void') + PsiWhiteSpace(' ') + PsiIdentifier:f('f') + PsiParameterList:() + PsiJavaToken:LPARENTH('(') + PsiJavaToken:RPARENTH(')') + PsiReferenceList + + PsiWhiteSpace(' ') + PsiKeyword:default('default') + PsiErrorElement:Value expected + + PsiWhiteSpace(' ') + PsiJavaToken:SEMICOLON(';') + PsiWhiteSpace(' ') + PsiJavaToken:RBRACE('}') diff --git a/java/java-tests/testData/psi/parser-partial/declarations/Unclosed7.txt b/java/java-tests/testData/psi/parser-partial/declarations/Unclosed7.txt new file mode 100644 index 000000000000..128c0711cb0b --- /dev/null +++ b/java/java-tests/testData/psi/parser-partial/declarations/Unclosed7.txt @@ -0,0 +1,37 @@ +PsiJavaFile:Unclosed7.java + PsiJavaToken:LBRACE('{') + PsiWhiteSpace(' ') + PsiAnnotationMethod:f + PsiModifierList: + + PsiTypeParameterList + + PsiTypeElement:void + PsiKeyword:void('void') + PsiWhiteSpace(' ') + PsiIdentifier:f('f') + PsiParameterList:() + PsiJavaToken:LPARENTH('(') + PsiJavaToken:RPARENTH(')') + PsiReferenceList + + PsiWhiteSpace(' ') + PsiKeyword:default('default') + PsiWhiteSpace(' ') + PsiArrayInitializerMemberValue:{ + PsiJavaToken:LBRACE('{') + PsiErrorElement:Value expected + + PsiErrorElement:'}' expected + + PsiErrorElement:'{' or ';' expected + + PsiErrorElement:Unexpected token + PsiKeyword:return('return') + PsiWhiteSpace(' ') + PsiJavaToken:INTEGER_LITERAL('42') + PsiJavaToken:SEMICOLON(';') + PsiJavaToken:RBRACE('}') + PsiWhiteSpace(' ') + PsiErrorElement:Unparsed tokens + PsiJavaToken:RBRACE('}') diff --git a/java/java-tests/testData/psi/parser-partial/declarations/Unclosed8.txt b/java/java-tests/testData/psi/parser-partial/declarations/Unclosed8.txt new file mode 100644 index 000000000000..5505b83c9a2c --- /dev/null +++ b/java/java-tests/testData/psi/parser-partial/declarations/Unclosed8.txt @@ -0,0 +1,23 @@ +PsiJavaFile:Unclosed8.java + PsiJavaToken:LBRACE('{') + PsiWhiteSpace(' ') + PsiMethod:f + PsiModifierList: + + PsiTypeParameterList + + PsiTypeElement:void + PsiKeyword:void('void') + PsiWhiteSpace(' ') + PsiIdentifier:f('f') + PsiParameterList:() + PsiJavaToken:LPARENTH('(') + PsiJavaToken:RPARENTH(')') + PsiReferenceList + + PsiWhiteSpace(' ') + PsiKeyword:default('default') + PsiErrorElement:'{' or ';' expected + + PsiWhiteSpace(' ') + PsiJavaToken:RBRACE('}') diff --git a/java/java-tests/testData/psi/parser-partial/declarations/Unclosed9.txt b/java/java-tests/testData/psi/parser-partial/declarations/Unclosed9.txt new file mode 100644 index 000000000000..e1df58f533ae --- /dev/null +++ b/java/java-tests/testData/psi/parser-partial/declarations/Unclosed9.txt @@ -0,0 +1,25 @@ +PsiJavaFile:Unclosed9.java + PsiJavaToken:LBRACE('{') + PsiWhiteSpace(' ') + PsiMethod:f + PsiModifierList: + + PsiTypeParameterList + + PsiTypeElement:void + PsiKeyword:void('void') + PsiWhiteSpace(' ') + PsiIdentifier:f('f') + PsiParameterList:() + PsiJavaToken:LPARENTH('(') + PsiJavaToken:RPARENTH(')') + PsiReferenceList + + PsiWhiteSpace(' ') + PsiKeyword:default('default') + PsiErrorElement:'{' expected + + PsiWhiteSpace(' ') + PsiJavaToken:SEMICOLON(';') + PsiWhiteSpace(' ') + PsiJavaToken:RBRACE('}') diff --git a/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/DeclarationParserTest.java b/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/DeclarationParserTest.java index a35c0298a067..a1b6b4290124 100644 --- a/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/DeclarationParserTest.java +++ b/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/DeclarationParserTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -20,7 +20,6 @@ import com.intellij.lang.java.parser.JavaParsers; import com.intellij.lang.java.parser.JavaParsingTestCase; import com.intellij.pom.java.LanguageLevel; - public class DeclarationParserTest extends JavaParsingTestCase { public DeclarationParserTest() { super("parser-partial/declarations"); @@ -82,11 +81,16 @@ public class DeclarationParserTest extends JavaParsingTestCase { public void testMethodNormal1() { doParserTest("{ void f(); }", false, false); } public void testSemicolons() { doParserTest("{ void f() {}; void g() {}; }", false, false); } public void testUnclosed0() { doParserTest("{ void f() }", false, false); } + public void testExtension() { doParserTest("{ int f() default { return 42; } }", false, false); } public void testUnclosed1() { doParserTest("{ void f( }", false, false); } public void testUnclosed2() { doParserTest("{ void f()\n void g(); }", false, false); } public void testUnclosed3() { doParserTest("{ void f(int a }", false, false); } public void testUnclosed4() { doParserTest("{ void f(int a,, }", false, false); } public void testUnclosed5() { doParserTest("{ void f(int a,); }", false, false); } + public void testUnclosed6() { doParserTest("{ void f() default ; }", true, false); } + public void testUnclosed7() { doParserTest("{ void f() default {return 42;} }", true, false); } + public void testUnclosed8() { doParserTest("{ void f() default }", false, false); } + public void testUnclosed9() { doParserTest("{ void f() default ; }", false, false); } public void testConstructorBrackets() { doParserTest("{ A() [] { } }", false, false); } public void testVarArgBrackets() { doParserTest("{ void foo(int... x[]); }", false, false); } From 2c371a6dcddcaadb9cb337eb66482f24f0f8f727 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 14 May 2012 19:32:46 +0400 Subject: [PATCH 03/11] NPE --- .../move/moveClassesOrPackages/DestinationFolderComboBox.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java index 76f3638cfdbf..ca76ad7ffd00 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java @@ -287,6 +287,8 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton } return true; } + if (oItem == null) return itemWrapper == null; + if (itemWrapper == null) return false; if (oItem.getDirectory() != itemWrapper.getDirectory()) { return false; } From ccba3bf443fc8e8c9020db80cf5d26815c74dc33 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 14 May 2012 19:50:53 +0400 Subject: [PATCH 04/11] inplace introduce parameter: from field with the same name (IDEA-85750) --- .../AbstractJavaInplaceIntroducer.java | 11 +++++++---- .../inplaceIntroduceParameter/replaceAll2.java | 13 +++++++++++++ .../replaceAll2_after.java | 13 +++++++++++++ .../refactoring/InplaceIntroduceParameterTest.java | 9 +++++++++ 4 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll2.java create mode 100644 java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll2_after.java diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java index 30bfd9c48055..546c24722493 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java @@ -125,10 +125,13 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro if (psiVariable == null || !psiVariable.isValid()) return null; final PsiElement refVariableElement = containingFile.findElementAt(marker.getStartOffset()); PsiExpression expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class); - if (expression instanceof PsiReferenceExpression && (((PsiReferenceExpression)expression).resolve() == psiVariable || - Comparing.strEqual(psiVariable.getName(), - ((PsiReferenceExpression)expression).getReferenceName()))) { - return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(exprText, psiVariable)); + if (expression instanceof PsiReferenceExpression) { + final String referenceName = ((PsiReferenceExpression)expression).getReferenceName(); + if (((PsiReferenceExpression)expression).resolve() == psiVariable || + Comparing.strEqual(psiVariable.getName(), referenceName) || + Comparing.strEqual(exprText, referenceName)) { + return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(exprText, psiVariable)); + } } if (expression == null) { expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiExpression.class); diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll2.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll2.java new file mode 100644 index 000000000000..6233f721169e --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll2.java @@ -0,0 +1,13 @@ +public class ATest { + public static final String FOO = "foo"; + public static final String FOO1 = "foo1"; + + String m_interval = ""; + void foo() { + if (FOO.equals(m_interval.substring(1))) { + System.out.println(FOO); + } else if (FOO1.equals(m_interval.substring(1))) { + System.out.println(); + } + } +} diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll2_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll2_after.java new file mode 100644 index 000000000000..ecd91369aead --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll2_after.java @@ -0,0 +1,13 @@ +public class ATest { + public static final String FOO = "foo"; + public static final String FOO1 = "foo1"; + + String m_interval = ""; + void foo(String m_interval1) { + if (FOO.equals(m_interval1.substring(1))) { + System.out.println(FOO); + } else if (FOO1.equals(m_interval1.substring(1))) { + System.out.println(); + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java index 4ee036833c0c..97c475910e9e 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java @@ -50,6 +50,15 @@ public class InplaceIntroduceParameterTest extends AbstractJavaInplaceIntroduceT }); } + public void testReplaceAll2() throws Exception { + doTest(new Pass() { + @Override + public void pass(AbstractInplaceIntroducer inplaceIntroduceFieldPopup) { + inplaceIntroduceFieldPopup.setReplaceAllOccurrences(true); + } + }); + } + public void testReplaceAllMethodCalls() throws Exception { doTest(new Pass() { @Override From 62817522e216e692255755d265820714e8c061e4 Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Mon, 14 May 2012 20:41:14 +0400 Subject: [PATCH 05/11] RelativeLayout --- .../layout/RelativeLayoutOperation.java | 3 ++ .../RelativeLayoutResizeOperation.java | 52 +++++++++++++++++-- .../layout/actions/ResizeOperation.java | 2 +- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/RelativeLayoutOperation.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/RelativeLayoutOperation.java index 227325b5b684..24e70befb986 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/RelativeLayoutOperation.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/RelativeLayoutOperation.java @@ -43,10 +43,13 @@ public class RelativeLayoutOperation extends AbstractEditOperation { private SnapPointFeedbackHost mySnapFeedback; private TextFeedback myHorizontalTextFeedback; private TextFeedback myVerticalTextFeedback; + private Rectangle myContainerBounds; private Rectangle myBounds; + private List myHorizontalPoints; private List myVerticalPoints; + private SnapPoint myHorizontalPoint; private SnapPoint myVerticalPoint; diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/RelativeLayoutResizeOperation.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/RelativeLayoutResizeOperation.java index 1887a166412e..9f04adfd53c4 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/RelativeLayoutResizeOperation.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/RelativeLayoutResizeOperation.java @@ -15,11 +15,19 @@ */ package com.intellij.android.designer.designSurface.layout.actions; +import com.intellij.android.designer.designSurface.layout.relative.SnapPoint; +import com.intellij.android.designer.designSurface.layout.relative.SnapPointFeedbackHost; +import com.intellij.android.designer.model.RadViewComponent; import com.intellij.designer.designSurface.EditOperation; import com.intellij.designer.designSurface.OperationContext; +import com.intellij.designer.designSurface.feedbacks.RectangleFeedback; +import com.intellij.designer.designSurface.feedbacks.TextFeedback; +import com.intellij.designer.designSurface.selection.DirectionResizePoint; import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator; import com.intellij.designer.model.RadComponent; +import com.intellij.designer.utils.Position; +import java.awt.*; import java.util.List; /** @@ -28,21 +36,42 @@ import java.util.List; public class RelativeLayoutResizeOperation implements EditOperation { public static final String TYPE = "relative_resize"; + private final OperationContext myContext; + private RadViewComponent myComponent; + + private RectangleFeedback myFeedback; + private SnapPointFeedbackHost mySnapFeedback; + private TextFeedback myHorizontalTextFeedback; + private TextFeedback myVerticalTextFeedback; + + private Rectangle myContainerBounds; + private Rectangle myBounds; + + private List myHorizontalPoints; + private List myVerticalPoints; + + private SnapPoint myHorizontalPoint; + private SnapPoint myVerticalPoint; + public RelativeLayoutResizeOperation(OperationContext context) { + myContext = context; } @Override public void setComponent(RadComponent component) { - // TODO: Auto-generated method stub + myComponent = (RadViewComponent)component; } @Override public void setComponents(List components) { - // TODO: Auto-generated method stub + } + + private void createFeedback() { } @Override public void showFeedback() { + createFeedback(); // TODO: Auto-generated method stub } @@ -53,7 +82,7 @@ public class RelativeLayoutResizeOperation implements EditOperation { @Override public boolean canExecute() { - return false; // TODO: Auto-generated method stub + return true; } @Override @@ -68,6 +97,21 @@ public class RelativeLayoutResizeOperation implements EditOperation { ////////////////////////////////////////////////////////////////////////////////////////// public static void points(ResizeSelectionDecorator decorator) { - // XXX + decorator.addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.NORTH_WEST, TYPE, + "Change layout:width x layout:height, top x left alignment")); + decorator + .addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.NORTH, TYPE, "Change layout:height, top alignment")); + decorator.addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.NORTH_EAST, TYPE, + "Change layout:width x layout:height, top x right alignment")); + decorator + .addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.EAST, TYPE, "Change layout:width, right alignment")); + decorator.addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.SOUTH_EAST, TYPE, + "Change layout:width x layout:height, bottom x right alignment")); + decorator.addPoint( + new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.SOUTH, TYPE, "Change layout:height, bottom alignment")); + decorator.addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.SOUTH_WEST, TYPE, + "Change layout:width x layout:height, bottom x left alignment")); + decorator + .addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.WEST, TYPE, "Change layout:width, left alignment")); } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/ResizeOperation.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/ResizeOperation.java index d6e8b8ebb7c4..34e2d1fa8125 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/ResizeOperation.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/layout/actions/ResizeOperation.java @@ -41,7 +41,7 @@ import java.util.List; public class ResizeOperation implements EditOperation { public static final String TYPE = "resize_children"; - private final static Color blue = new Color(0, 50, 255); + public final static Color blue = new Color(0, 50, 255); private static final int SNAP_DELTA = 4; private static final int WRAP_CONTENT = 0 << 30; From 52838d389920b731b55887a491a83a027abaf255 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 14 May 2012 22:33:48 +0200 Subject: [PATCH 06/11] IDEA-85807 ('Show as tree' not working in Version Control History window) --- .../history/CvsHistoryProvider.java | 27 +++++-------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/history/CvsHistoryProvider.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/history/CvsHistoryProvider.java index 9467e665d90b..2cb4236c6e88 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/history/CvsHistoryProvider.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/history/CvsHistoryProvider.java @@ -21,8 +21,7 @@ import com.intellij.cvsSupport2.application.CvsEntriesManager; import com.intellij.cvsSupport2.changeBrowser.CvsChangeList; import com.intellij.cvsSupport2.connections.CvsConnectionSettings; import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutor; -import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutorCallback; -import com.intellij.cvsSupport2.cvsExecution.ModalityContext; +import com.intellij.cvsSupport2.cvsExecution.DefaultCvsOperationExecutorCallback; import com.intellij.cvsSupport2.cvshandlers.CommandCvsHandler; import com.intellij.cvsSupport2.cvsoperations.cvsLog.LocalPathIndifferentLogOperation; import com.intellij.cvsSupport2.cvsoperations.cvsTagOrBranch.ui.TagsPanel; @@ -226,13 +225,8 @@ public class CvsHistoryProvider implements VcsHistoryProvider { final CvsOperationExecutor executor = new CvsOperationExecutor(myProject); final ArrayList result = new ArrayList(); executor.performActionSync(new CommandCvsHandler(CvsBundle.message("operation.name.load.file.content"), logOperation), - new CvsOperationExecutorCallback() { - public void executionFinished(boolean successfully) { - } - - public void executeInProgressAfterAction(ModalityContext modalityContext) { - } - + new DefaultCvsOperationExecutorCallback() { + @Override public void executionFinishedSuccessfully() { final CvsConnectionSettings env = CvsEntriesManager.getInstance() .getCvsConnectionSettingsFor(filePath.getVirtualFileParent()); @@ -246,7 +240,7 @@ public class CvsHistoryProvider implements VcsHistoryProvider { } } }); - Collections.sort(result, VcsFileRevisionComparator.INSTANCE); + Collections.sort(result, Collections.reverseOrder(VcsFileRevisionComparator.INSTANCE)); return result; } @@ -266,12 +260,12 @@ public class CvsHistoryProvider implements VcsHistoryProvider { } public List> createTreeOn(List allRevisions) { - final List sortedRevisions = sortRevisions(allRevisions); + Collections.sort(allRevisions, VcsFileRevisionComparator.INSTANCE); final List> result = new ArrayList>(); TreeItem prevRevision = null; - for (final VcsFileRevision sortedRevision : sortedRevisions) { + for (final VcsFileRevision sortedRevision : allRevisions) { final CvsFileRevisionImpl cvsFileRevision = (CvsFileRevisionImpl)sortedRevision; final TreeItem treeItem = new TreeItem(cvsFileRevision); final TreeItem commonParent = getCommonParent(prevRevision, treeItem); @@ -281,12 +275,10 @@ public class CvsHistoryProvider implements VcsHistoryProvider { else { result.add(treeItem); } - prevRevision = treeItem; } return result; - } @Nullable @@ -304,11 +296,6 @@ public class CvsHistoryProvider implements VcsHistoryProvider { final CvsFileRevisionImpl data = (CvsFileRevisionImpl)cvsFileRevision.getData(); return data.getRevisionNumber().asString().startsWith(prevData.getRevisionNumber().asString()); } - - private static List sortRevisions(List revisionsList) { - Collections.sort(revisionsList, VcsFileRevisionComparator.INSTANCE); - return revisionsList; - } } private static class VcsFileRevisionComparator implements Comparator { @@ -318,7 +305,7 @@ public class CvsHistoryProvider implements VcsHistoryProvider { private VcsFileRevisionComparator() {} public int compare(VcsFileRevision rev1, VcsFileRevision rev2) { - return VcsHistoryUtil.compare(rev2, rev1); + return VcsHistoryUtil.compare(rev1, rev2); } } } From 7fa57737e9fd27312e45d05b428dd8da3bebc192 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 14 May 2012 22:40:53 +0200 Subject: [PATCH 07/11] no default selection --- .../com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java index dd921862163e..c01f87d1bb8a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java @@ -579,8 +579,6 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { }); myDualView.requestFocus(); - myDualView.setSelectionInterval(0, 0); - myDualView.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { From 58bcd463489aa4f797bed983b9197f85dfb317b5 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 14 May 2012 22:43:35 +0200 Subject: [PATCH 08/11] scroll selection to visible on switching between tree and list view --- .../platform-api/src/com/intellij/ui/dualView/DualView.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/ui/dualView/DualView.java b/platform/platform-api/src/com/intellij/ui/dualView/DualView.java index f1abf56b08ad..efc1765053eb 100644 --- a/platform/platform-api/src/com/intellij/ui/dualView/DualView.java +++ b/platform/platform-api/src/com/intellij/ui/dualView/DualView.java @@ -190,6 +190,8 @@ public class DualView extends JPanel { if (myCurrentView instanceof JBTable) { ((JBTable)myCurrentView).setStriped(true); } + final int row = myCurrentView.getSelectedRow(); + myCurrentView.scrollRectToVisible(myCurrentView.getCellRect(row, 0, true)); } } @@ -304,7 +306,7 @@ public class DualView extends JPanel { SelectionProvider visibleTable = (SelectionProvider)getVisibleTable(); Collection selection = visibleTable.getSelection(); for (Iterator each = selection.iterator(); each.hasNext();) { - result.add((Object)each.next()); + result.add(each.next()); } return result; } From 6b6e2e19a7731e91d19ac3e82ef6f8bf5c41e2d1 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 15 May 2012 09:32:42 +0400 Subject: [PATCH 09/11] write directly to char array if it is available (cherry picked from commit a664bc8) --- .../intellij/openapi/fileEditor/impl/LoadTextUtil.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java b/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java index 94f527af681f..2ffcba202119 100644 --- a/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java +++ b/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java @@ -63,7 +63,8 @@ public final class LoadTextUtil { char c = bufferArray != null ? bufferArray[src]:buffer.charAt(src); switch (c) { case '\r': - buffer.put(dst++, '\n'); + if(bufferArray != null) bufferArray[dst++] = '\n'; + else buffer.put(dst++, '\n'); crCount++; break; case '\n': @@ -72,12 +73,14 @@ public final class LoadTextUtil { crlfCount++; } else { - buffer.put(dst++, '\n'); + if(bufferArray != null) bufferArray[dst++] = '\n'; + else buffer.put(dst++, '\n'); lfCount++; } break; default: - buffer.put(dst++, c); + if(bufferArray != null) bufferArray[dst++] = c; + else buffer.put(dst++, c); break; } prev = c; From be5278d42e4d99d37313a387f8f38dead925a175 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 15 May 2012 09:36:04 +0400 Subject: [PATCH 10/11] less memory for storing indices (optimize for one pair of ket / value - 80% case) (cherry picked from commit 37a7f7b) --- .../ChangeTrackingValueContainer.java | 121 +++++----- .../intellij/util/indexing/IndexStorage.java | 2 - .../util/indexing/MapIndexStorage.java | 11 - .../util/indexing/MemoryIndexStorage.java | 13 -- .../util/indexing/ValueContainerImpl.java | 214 ++++++++++++------ .../util/indexing/ValueContainerMap.java | 18 +- 6 files changed, 203 insertions(+), 176 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ChangeTrackingValueContainer.java b/platform/lang-impl/src/com/intellij/util/indexing/ChangeTrackingValueContainer.java index f41bc79ec6e3..660d759fcf48 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/ChangeTrackingValueContainer.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/ChangeTrackingValueContainer.java @@ -19,6 +19,7 @@ package com.intellij.util.indexing; import com.intellij.openapi.util.Computable; import gnu.trove.TIntHashSet; import gnu.trove.TIntProcedure; +import org.jetbrains.annotations.Nullable; import java.util.Iterator; import java.util.List; @@ -28,11 +29,11 @@ import java.util.List; * Date: Dec 20, 2007 */ class ChangeTrackingValueContainer extends UpdatableValueContainer{ - private final ValueContainerImpl myAdded; - private final ValueContainerImpl myRemoved; - private final TIntHashSet myInvalidated; + // there is no volatile as we modify under write lock and read under read lock + private ValueContainerImpl myAdded; + private TIntHashSet myInvalidated; + private volatile ValueContainerImpl myMerged; private final Initializer myInitializer; - private volatile ValueContainerImpl myMerged = null; public interface Initializer extends Computable> { Object getLock(); @@ -40,51 +41,48 @@ class ChangeTrackingValueContainer extends UpdatableValueContainer public ChangeTrackingValueContainer(Initializer initializer) { myInitializer = initializer; - myAdded = new ValueContainerImpl(); - myRemoved = new ValueContainerImpl(); - myInvalidated = new TIntHashSet(1); } - //public void log(String op, int id, final Value value) { - // System.out.print("@" + mcount + ": "); - // System.out.print(op); - // System.out.print("(" + id + ")"); - // System.out.print(" value=" + value + " "); - // System.out.print("+[" + myAdded.dumpInputIdMapping() + "], "); - // System.out.print("-[" + myRemoved.dumpInputIdMapping() + "], "); - // System.out.println("*[" + (myMerged != null ? myMerged.dumpInputIdMapping() : "null") + "] "); - //} - @Override public void addValue(int inputId, Value value) { - if (myMerged != null) { - myMerged.addValue(inputId, value); + ValueContainerImpl merged = myMerged; + if (merged != null) { + merged.addValue(inputId, value); } - if (!myRemoved.removeValue(inputId, value)) { - myAdded.addValue(inputId, value); + ValueContainerImpl added = myAdded; + if (added == null) { + myAdded = added = new ValueContainerImpl(); } + added.addValue(inputId, value); // will flush the changes & caller should ensure exclusiveness to avoid intermediate visibility issues } @Override public void removeAssociatedValue(int inputId) { - if (myMerged != null) { - myMerged.removeAssociatedValue(inputId); + ValueContainerImpl merged = myMerged; + if (merged != null) { + merged.removeAssociatedValue(inputId); } - myAdded.removeAssociatedValue(inputId); - myRemoved.removeAssociatedValue(inputId); - myInvalidated.add(inputId); + + ValueContainerImpl added = myAdded; + if (added != null) added.removeAssociatedValue(inputId); + + TIntHashSet invalidated = myInvalidated; + if (invalidated == null) { + invalidated = new TIntHashSet(1); + } + invalidated.add(inputId); + myInvalidated = invalidated; // volatile write } @Override public boolean removeValue(int inputId, Value value) { - if (myMerged != null) { - myMerged.removeValue(inputId, value); - } - if (!myAdded.removeValue(inputId, value)) { - if (!myInvalidated.contains(inputId)) { - myRemoved.addValue(inputId, value); - } + ValueContainerImpl merged = myMerged; + if (merged != null) { + merged.removeValue(inputId, value); } + ValueContainerImpl added = myAdded; + if (added != null) added.removeValue(inputId, value); + return true; } @@ -143,28 +141,29 @@ class ChangeTrackingValueContainer extends UpdatableValueContainer } else { newMerged = ((ChangeTrackingValueContainer)fromDisk).getMergedData().copy(); } - myInvalidated.forEach(new TIntProcedure() { - @Override - public boolean execute(int inputId) { - newMerged.removeAssociatedValue(inputId); - return true; - } - }); - myRemoved.forEach(new ContainerAction() { - @Override - public boolean perform(final int id, final Value value) { - newMerged.removeValue(id, value); - return true; - } - }); - myAdded.forEach(new ContainerAction() { - @Override - public boolean perform(final int id, final Value value) { - newMerged.removeAssociatedValue(id); // enforcing "one-value-per-file for particular key" invariant - newMerged.addValue(id, value); - return true; - } - }); + + TIntHashSet invalidated = myInvalidated; + if (invalidated != null) { + invalidated.forEach(new TIntProcedure() { + @Override + public boolean execute(int inputId) { + newMerged.removeAssociatedValue(inputId); + return true; + } + }); + } + + ValueContainerImpl added = myAdded; + if (added != null) { + added.forEach(new ContainerAction() { + @Override + public boolean perform(final int id, final Value value) { + newMerged.removeAssociatedValue(id); // enforcing "one-value-per-file for particular key" invariant + newMerged.addValue(id, value); + return true; + } + }); + } setNeedsCompacting(fromDisk.needsCompacting()); myMerged = newMerged; @@ -173,18 +172,16 @@ class ChangeTrackingValueContainer extends UpdatableValueContainer } public boolean isDirty() { - return myAdded.size() > 0 || myRemoved.size() > 0 || !myInvalidated.isEmpty() || needsCompacting(); + return (myAdded != null && myAdded.size() > 0) || + (myInvalidated != null && !myInvalidated.isEmpty()) || + needsCompacting(); } - public ValueContainer getAddedDelta() { + public @Nullable ValueContainer getAddedDelta() { return myAdded; } - - public ValueContainer getRemovedDelta() { - return myRemoved; - } - public TIntHashSet getInvalidated() { + public @Nullable TIntHashSet getInvalidated() { return myInvalidated; } } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java index 0eefa0bf5bf1..5b0f2aa3f447 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java @@ -31,8 +31,6 @@ public interface IndexStorage extends Flushable { void addValue(Key key, int inputId, Value value) throws StorageException; - void removeValue(Key key, int inputId, Value value) throws StorageException; - void removeAllValues(Key key, int inputId) throws StorageException; void clear() throws StorageException; diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java index d0c60582c640..9379f64369bf 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java @@ -237,17 +237,6 @@ public final class MapIndexStorage implements IndexStorage implements IndexStorage myBackendStorage.addValue(key, inputId, value); } - @Override - public void removeValue(final Key key, final int inputId, final Value value) throws StorageException { - if (myBufferingEnabled.get()) { - getMemValueContainer(key).removeValue(inputId, value); - return; - } - final ChangeTrackingValueContainer valueContainer = myMap.get(key); - if (valueContainer != null) { - valueContainer.dropMergedData(); - } - myBackendStorage.removeValue(key, inputId, value); - } - @Override public void removeAllValues(Key key, int inputId) throws StorageException { if (myBufferingEnabled.get()) { diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java index 89e2429ff1ae..36ef41459f42 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java @@ -33,27 +33,37 @@ import java.util.*; class ValueContainerImpl extends UpdatableValueContainer implements Cloneable{ private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.ValueContainerImpl"); private final static Object myNullValue = new Object(); - private THashMap myInputIdMapping; - - public ValueContainerImpl() { - // per statistic most maps (80%) has one value - myInputIdMapping = new THashMap(1); - } + // there is no volatile as we modify under write lock and read under read lock + // Most often (80%) we store 0 or one mapping, then we store them in two fields: myInputIdMapping, myInputIdMappingValue + // when there are several value mapped, myInputIdMapping is THashMap, myInputIdMappingValue = null + private Object myInputIdMapping; + private Object myInputIdMappingValue; @Override public void addValue(int inputId, Value value) { - value = maskNull(value); - final Object input = myInputIdMapping.get(value); + final Object input = getInput(value); + if (input == null) { - //idSet = new TIntHashSet(3, 0.98f); - myInputIdMapping.put(value, inputId); + if (myInputIdMapping != null) { + if (!(myInputIdMapping instanceof THashMap)) { + Object oldMapping = myInputIdMapping; + myInputIdMapping = new THashMap(2); + ((THashMap)myInputIdMapping).put((Value)oldMapping, myInputIdMappingValue); + myInputIdMappingValue = null; + } + ((THashMap)myInputIdMapping).put(value, inputId); + } else { + myInputIdMapping = value != null ? value:(Value)myNullValue; + myInputIdMappingValue = inputId; + } } else { final TIntHashSet idSet; if (input instanceof Integer) { idSet = new IdSet(3, 0.98f); idSet.add(((Integer)input).intValue()); - myInputIdMapping.put(value, idSet); + if (!(myInputIdMapping instanceof THashMap)) myInputIdMappingValue = idSet; + else ((THashMap)myInputIdMapping).put(value, idSet); } else { idSet = (TIntHashSet)input; @@ -64,21 +74,19 @@ class ValueContainerImpl extends UpdatableValueContainer implement @Override public int size() { - return myInputIdMapping.size(); + return myInputIdMapping != null ? myInputIdMapping instanceof THashMap ? ((THashMap)myInputIdMapping).size(): 1 : 0; } @Override public void removeAssociatedValue(int inputId) { - if (myInputIdMapping.isEmpty()) return; + if (myInputIdMapping == null) return; List toRemove = null; for (final Iterator valueIterator = getValueIterator(); valueIterator.hasNext();) { final Value value = valueIterator.next(); if (isAssociated(value, inputId)) { - if (toRemove == null) toRemove = new SmartList(value); - else { - LOG.error("Expected only one value per-inputId"); - toRemove.add(value); - } + if (toRemove == null) toRemove = new SmartList(); + else LOG.error("Expected only one value per-inputId"); + toRemove.add(value); } } @@ -91,12 +99,11 @@ class ValueContainerImpl extends UpdatableValueContainer implement @Override public boolean removeValue(int inputId, Value value) { - if (myInputIdMapping.isEmpty()) return false; // skipping hash code for value - value = maskNull(value); - final Object input = myInputIdMapping.get(value); + final Object input = getInput(value); if (input == null) { return false; } + if (input instanceof TIntHashSet) { final TIntHashSet idSet = (TIntHashSet)input; final boolean reallyRemoved = idSet.remove(inputId); @@ -112,57 +119,87 @@ class ValueContainerImpl extends UpdatableValueContainer implement return false; } } - myInputIdMapping.remove(value); - return true; - } - private Value maskNull(Value value) { - if (value == null) { - return (Value)myNullValue; + if (!(myInputIdMapping instanceof THashMap)) { + myInputIdMapping = null; + myInputIdMappingValue = null; + } else { + THashMap mapping = (THashMap)myInputIdMapping; + mapping.remove(value); + if (mapping.size() == 1) { + myInputIdMapping = mapping.keySet().iterator().next(); + myInputIdMappingValue = mapping.get((Value)myInputIdMapping); + } } - return value; + + return true; } @Override public Iterator getValueIterator() { - if (myInputIdMapping.isEmpty()) { + if (myInputIdMapping != null) { + if (!(myInputIdMapping instanceof THashMap)) { + return new Iterator() { + private Value value = (Value)myInputIdMapping; + @Override + public boolean hasNext() { + return value != null; + } + + @Override + public Value next() { + Value next = value; + if (next == myNullValue) next = null; + value = null; + return next; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } else { + return new Iterator() { + final Iterator iterator = ((THashMap)myInputIdMapping).keySet().iterator(); + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public Value next() { + Value next = iterator.next(); + if (next == myNullValue) next = null; + return next; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + } else { return EmptyIterator.getInstance(); } - - return new Iterator() { - final Iterator iterator = myInputIdMapping.keySet().iterator(); - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public Value next() { - Value next = iterator.next(); - if (next == myNullValue) next = null; - return next; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; } @Override public List toValueList() { - if (myInputIdMapping.isEmpty()) { + if (myInputIdMapping == null) { return Collections.emptyList(); + } else if (myInputIdMapping instanceof THashMap) { + return new ArrayList(((THashMap)myInputIdMapping).keySet()); + } else { + return new SmartList((Value)myInputIdMapping); } - return new ArrayList(myInputIdMapping.keySet()); } @Override public boolean isAssociated(Value value, final int inputId) { - value = maskNull(value); - final Object input = myInputIdMapping.get(value); + final Object input = getInput(value); if (input instanceof TIntHashSet) { return ((TIntHashSet)input).contains(inputId); } @@ -174,7 +211,7 @@ class ValueContainerImpl extends UpdatableValueContainer implement @Override public IntPredicate getValueAssociationPredicate(Value value) { - final Object input = myInputIdMapping.get(value); + final Object input = getInput(value); if (input == null) return EMPTY_PREDICATE; if (input instanceof Integer) { return new IntPredicate() { @@ -196,8 +233,7 @@ class ValueContainerImpl extends UpdatableValueContainer implement @Override public IntIterator getInputIdsIterator(Value value) { - value = maskNull(value); - final Object input = myInputIdMapping.get(value); + final Object input = getInput(value); final IntIterator it; if (input instanceof TIntHashSet) { it = new IntSetIterator((TIntHashSet)input); @@ -211,11 +247,30 @@ class ValueContainerImpl extends UpdatableValueContainer implement return it; } + private Object getInput(Value value) { + if (myInputIdMapping == null) return null; + + value = value != null ? value:(Value)myNullValue; + + if (myInputIdMapping == value || // myNullValue is Object + myInputIdMapping.equals(value) + ) { + return myInputIdMappingValue; + } + + if (!(myInputIdMapping instanceof THashMap)) return null; + return ((THashMap)myInputIdMapping).get(value); + } + @Override public ValueContainerImpl clone() { try { final ValueContainerImpl clone = (ValueContainerImpl)super.clone(); - clone.myInputIdMapping = mapCopy(myInputIdMapping); + if (myInputIdMapping instanceof THashMap) { + clone.myInputIdMapping = mapCopy((THashMap)myInputIdMapping); + } else if (myInputIdMappingValue instanceof TIntHashSet) { + clone.myInputIdMappingValue = ((TIntHashSet)myInputIdMappingValue).clone(); + } return clone; } catch (CloneNotSupportedException e) { @@ -241,18 +296,30 @@ class ValueContainerImpl extends UpdatableValueContainer implement }; public ValueContainerImpl copy() { - final ValueContainerImpl container = new ValueContainerImpl(); - myInputIdMapping.forEachEntry(new TObjectObjectProcedure() { - @Override - public boolean execute(Value key, Object val) { - if (val instanceof TIntHashSet) { - container.myInputIdMapping.put(key, ((TIntHashSet)val).clone()); - } else { - container.myInputIdMapping.put(key, val); + ValueContainerImpl container = new ValueContainerImpl(); + + if (myInputIdMapping instanceof THashMap) { + final THashMap mapping = (THashMap)myInputIdMapping; + final THashMap newMapping = new THashMap(mapping.size()); + container.myInputIdMapping = newMapping; + + mapping.forEachEntry(new TObjectObjectProcedure() { + @Override + public boolean execute(Value key, Object val) { + if (val instanceof TIntHashSet) { + newMapping.put(key, ((TIntHashSet)val).clone()); + } + else { + newMapping.put(key, val); + } + return true; } - return true; - } - }); + }); + } else { + container.myInputIdMapping = myInputIdMapping; + container.myInputIdMappingValue = myInputIdMappingValue instanceof TIntHashSet ? + ((TIntHashSet)myInputIdMappingValue).clone():myInputIdMappingValue; + } return container; } @@ -271,12 +338,9 @@ class ValueContainerImpl extends UpdatableValueContainer implement @Override public int next() { - try { - return myValue; - } - finally { - myValueRead = true; - } + int next = myValue; + myValueRead = true; + return next; } @Override diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java index cb26b39d4994..ba3d72501fba 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java @@ -38,18 +38,14 @@ class ValueContainerMap extends PersistentHashMap 0) { + if (set != null && set.size() > 0) { for (int inputId : set.toArray()) { ValueContainerExternalizer.saveInvalidateCommand(_out, inputId); } } - final ValueContainer toRemove = valueContainer.getRemovedDelta(); - if (toRemove.size() > 0) { - myValueContainerExternalizer.saveAsRemoved(_out, toRemove); - } final ValueContainer toAppend = valueContainer.getAddedDelta(); - if (toAppend.size() > 0) { + if (toAppend != null && toAppend.size() > 0) { myValueContainerExternalizer.save(_out, toAppend); } @@ -76,18 +72,14 @@ class ValueContainerMap extends PersistentHashMap container) throws IOException { - saveImpl(out, container, false); - } - - public void saveAsRemoved(final DataOutput out, @NotNull final ValueContainer container) throws IOException { - saveImpl(out, container, true); + saveImpl(out, container); } public static void saveInvalidateCommand(final DataOutput out, int inputId) throws IOException { DataInputOutputUtil.writeSINT(out, -inputId); } - private void saveImpl(final DataOutput out, @NotNull final ValueContainer container, final boolean asRemovedData) throws IOException { + private void saveImpl(final DataOutput out, @NotNull final ValueContainer container) throws IOException { DataInputOutputUtil.writeSINT(out, container.size()); for (final Iterator valueIterator = container.getValueIterator(); valueIterator.hasNext();) { final T value = valueIterator.next(); @@ -98,7 +90,7 @@ class ValueContainerMap extends PersistentHashMap Date: Tue, 15 May 2012 10:31:16 +0400 Subject: [PATCH 11/11] IDEA-85819 AppCode inspections are shown in the view --- .../codeInspection/ui/SingleInspectionProfilePanel.java | 4 ++-- .../intellij/codeHighlighting/HighlightDisplayLevel.java | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index 39efab431bb4..4e3fcbfa03cd 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -229,9 +229,9 @@ public class SingleInspectionProfilePanel extends JPanel { List tools = profile.getDefaultStates(); for (ScopeToolState state : tools) { final ArrayList descriptors = new ArrayList(); - /* if (state.getLevel() == HighlightDisplayLevel.NON_SWITCHABLE_ERROR) { + if (state.getLevel() == HighlightDisplayLevel.NON_SWITCHABLE_ERROR) { continue; - }*/ + } myDescriptors.put(new Descriptor(state, profile), descriptors); final List nonDefaultTools = profile.getNonDefaultTools(state.getTool().getShortName()); if (nonDefaultTools != null) { diff --git a/platform/platform-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java b/platform/platform-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java index d26d37cc65f7..9f58c34dd19d 100644 --- a/platform/platform-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java +++ b/platform/platform-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java @@ -24,6 +24,7 @@ import com.intellij.openapi.util.Comparing; import com.intellij.util.ImageLoader; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -44,11 +45,12 @@ public class HighlightDisplayLevel { public static final HighlightDisplayLevel INFO = new HighlightDisplayLevel(HighlightSeverity.INFO, DO_NOT_SHOW.getIcon()); public static final HighlightDisplayLevel WEAK_WARNING = new HighlightDisplayLevel(HighlightSeverity.WEAK_WARNING, DO_NOT_SHOW.getIcon()); - public static final HighlightDisplayLevel NON_SWITCHABLE_ERROR = new HighlightDisplayLevel(HighlightSeverity.ERROR, createIconByMask(CodeInsightColors.ERRORS_ATTRIBUTES)); + public static final HighlightDisplayLevel NON_SWITCHABLE_ERROR = new HighlightDisplayLevel(HighlightSeverity.ERROR); private Icon myIcon; private final HighlightSeverity mySeverity; + @Nullable public static HighlightDisplayLevel find(String name) { for (Map.Entry entry : ourMap.entrySet()) { HighlightSeverity severity = entry.getKey(); @@ -70,6 +72,11 @@ public class HighlightDisplayLevel { ourMap.put(mySeverity, this); } + public HighlightDisplayLevel(HighlightSeverity severity) { + mySeverity = severity; + } + + public String toString() { return mySeverity.toString(); }