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-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; } 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/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/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); } 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