diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java index e41b55b61655..9ccd8c29e377 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -48,7 +48,6 @@ import com.intellij.util.VisibilityUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.text.UniqueNameGenerator; import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.java.generate.GenerationUtil; @@ -134,7 +133,7 @@ public class GenerateMembersUtil { } /** - * @see GenerationInfo#positionCaret(com.intellij.openapi.editor.Editor, boolean) + * @see GenerationInfo#positionCaret(Editor, boolean) */ public static void positionCaret(@NotNull Editor editor, @NotNull PsiElement firstMember, boolean toEditMethodBody) { LOG.assertTrue(firstMember.isValid()); @@ -195,7 +194,9 @@ public class GenerateMembersUtil { offset = method.getTextRange().getStartOffset(); } else { - offset = body.getLBrace().getTextRange().getEndOffset(); + PsiJavaToken lBrace = body.getLBrace(); + assert lBrace != null : firstMember.getText(); + offset = lBrace.getTextRange().getEndOffset(); } } else { @@ -265,7 +266,7 @@ public class GenerateMembersUtil { @NotNull PsiSubstitutor substitutor, @Nullable PsiElement target) { final Project project = sourceMethod.getProject(); - final JVMElementFactory factory = getFactory(sourceMethod, target); + final JVMElementFactory factory = getFactory(sourceMethod.getProject(), target); final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project); try { @@ -284,7 +285,8 @@ public class GenerateMembersUtil { for (PsiClass aSuper : supers) { final PsiMethod psiMethod = aSuper.findMethodBySignature(sourceMethod, true); if (psiMethod != null && psiMethod != sourceMethod) { - ExceptionUtil.retainExceptions(thrownTypes, ExceptionUtil.collectSubstituted(TypeConversionUtil.getSuperClassSubstitutor(aSuper, (PsiClass)target, PsiSubstitutor.EMPTY), psiMethod.getThrowsList().getReferencedTypes(), scope)); + PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(aSuper, (PsiClass)target, PsiSubstitutor.EMPTY); + ExceptionUtil.retainExceptions(thrownTypes, ExceptionUtil.collectSubstituted(superClassSubstitutor, psiMethod.getThrowsList().getReferencedTypes(), scope)); } } } @@ -345,7 +347,7 @@ public class GenerateMembersUtil { } @NotNull - private static String suggestUniqueTypeParameterName(@NonNls String baseName, @NotNull PsiTypeParameterList typeParameterList, @Nullable PsiClass targetClass) { + private static String suggestUniqueTypeParameterName(String baseName, @NotNull PsiTypeParameterList typeParameterList, @Nullable PsiClass targetClass) { int i = 0; while (true) { final String newName = baseName + ++i; @@ -356,7 +358,7 @@ public class GenerateMembersUtil { } - private static boolean checkUniqueTypeParameterName(@NonNls @NotNull String baseName, @Nullable PsiTypeParameterList typeParameterList) { + private static boolean checkUniqueTypeParameterName(@NotNull String baseName, @Nullable PsiTypeParameterList typeParameterList) { if (typeParameterList == null) return true; for (PsiTypeParameter typeParameter : typeParameterList.getTypeParameters()) { @@ -415,7 +417,7 @@ public class GenerateMembersUtil { PsiParameter parameter = parameters[i]; final PsiType parameterType = parameter.getType(); final PsiType substituted = substituteType(substitutor, parameterType, (PsiMethod)parameter.getDeclarationScope()); - @NonNls String paramName = parameter.getName(); + String paramName = parameter.getName(); boolean isBaseNameGenerated = true; final boolean isSubstituted = substituted.equals(parameterType); if (!isSubstituted && isBaseNameGenerated(codeStyleManager, TypeConversionUtil.erasure(parameterType), paramName)) { @@ -497,12 +499,8 @@ public class GenerateMembersUtil { } @NotNull - private static JVMElementFactory getFactory(@NotNull PsiMethod method, @Nullable PsiElement target) { - if (target == null) { - return JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); - } - - return JVMElementFactories.getFactory(target.getLanguage(), method.getProject()); + private static JVMElementFactory getFactory(@NotNull Project p, @Nullable PsiElement target) { + return target == null ? JavaPsiFacade.getInstance(p).getElementFactory() : JVMElementFactories.requireFactory(target.getLanguage(), p); } private static boolean isBaseNameGenerated(JavaCodeStyleManager csManager, PsiType parameterType, String paramName) { @@ -534,21 +532,23 @@ public class GenerateMembersUtil { } public static void setupGeneratedMethod(PsiMethod method) { - PsiClass base = method.getContainingClass().getSuperClass(); + PsiClass containingClass = method.getContainingClass(); + PsiClass base = containingClass == null ? null : containingClass.getSuperClass(); PsiMethod overridden = base == null ? null : base.findMethodBySignature(method, true); if (overridden == null) { - CreateFromUsageUtils.setupMethodBody(method, method.getContainingClass()); + CreateFromUsageUtils.setupMethodBody(method, containingClass); return; } - OverrideImplementUtil.setupMethodBody(method, overridden, method.getContainingClass()); + OverrideImplementUtil.setupMethodBody(method, overridden, containingClass); OverrideImplementUtil.annotateOnOverrideImplement(method, base, overridden); } public static void copyOrReplaceModifierList(@NotNull PsiModifierListOwner sourceParam, @NotNull PsiModifierListOwner targetParam) { PsiModifierList sourceModifierList = sourceParam.getModifierList(); PsiModifierList targetModifierList = targetParam.getModifierList(); + if (sourceModifierList != null && targetModifierList != null) { if (sourceParam.getLanguage() == targetParam.getLanguage()) { targetModifierList = (PsiModifierList)targetModifierList.replace(sourceModifierList); @@ -562,11 +562,12 @@ public class GenerateMembersUtil { targetModifierList.setModifierProperty(m, sourceParam.hasModifierProperty(m)); } } - processAnnotations(sourceModifierList.getProject(), targetModifierList, targetModifierList.getResolveScope()); + + filterAnnotations(sourceModifierList.getProject(), targetModifierList, targetModifierList.getResolveScope()); } } - private static void processAnnotations(Project project, PsiModifierList modifierList, GlobalSearchScope moduleScope) { + private static void filterAnnotations(Project project, PsiModifierList modifierList, GlobalSearchScope moduleScope) { final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); final Set toRemove = new HashSet(); for (PsiAnnotation annotation : modifierList.getAnnotations()) { @@ -644,13 +645,14 @@ public class GenerateMembersUtil { private static PsiMethod generatePrototype(@NotNull PsiField field, PsiClass psiClass, - boolean ignoreInvalidTemplate, TemplatesManager templatesManager) { + boolean ignoreInvalidTemplate, + TemplatesManager templatesManager) { Project project = field.getProject(); PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); - final String methodText = GenerationUtil.velocityGenerateCode(psiClass, Collections.singletonList(field), - new HashMap(), - templatesManager.getDefaultTemplate().getTemplate(), 0, false); + String template = templatesManager.getDefaultTemplate().getTemplate(); + String methodText = GenerationUtil.velocityGenerateCode(psiClass, Collections.singletonList(field), new HashMap(), template, 0, false); + boolean isGetter = templatesManager instanceof GetterTemplatesManager; PsiMethod result; try { result = factory.createMethodFromText(methodText, psiClass); @@ -658,8 +660,8 @@ public class GenerateMembersUtil { catch (IncorrectOperationException e) { if (ignoreInvalidTemplate) { LOG.info(e); - result = templatesManager instanceof GetterTemplatesManager ? PropertyUtil.generateGetterPrototype(field) - : PropertyUtil.generateSetterPrototype(field); + result = isGetter ? PropertyUtil.generateGetterPrototype(field) : PropertyUtil.generateSetterPrototype(field); + assert result != null : field.getText(); } else { throw new GenerateCodeException(e); @@ -668,7 +670,7 @@ public class GenerateMembersUtil { result = (PsiMethod)CodeStyleManager.getInstance(project).reformat(result); PsiModifierListOwner listOwner = null; - if (templatesManager instanceof GetterTemplatesManager) { + if (isGetter) { listOwner = result; } else { @@ -691,12 +693,20 @@ public class GenerateMembersUtil { @Contract("_, null -> null") public static PsiMethod setVisibility(PsiMember member, PsiMethod prototype) { if (prototype == null) return null; - final String visibility = CodeStyleSettingsManager.getSettings(member.getProject()).VISIBILITY; - final PsiModifierList modifierList = prototype.getModifierList(); - final String newVisibility = VisibilityUtil.ESCALATE_VISIBILITY.equals(visibility) - ? PsiUtil.getMaximumModifierForMember(member instanceof PsiClass ? (PsiClass)member : member.getContainingClass(), false) - : visibility; - VisibilityUtil.setVisibility(modifierList, newVisibility); + + String visibility = CodeStyleSettingsManager.getSettings(member.getProject()).VISIBILITY; + + @PsiModifier.ModifierConstant String newVisibility; + if (VisibilityUtil.ESCALATE_VISIBILITY.equals(visibility)) { + PsiClass aClass = member instanceof PsiClass ? (PsiClass)member : member.getContainingClass(); + newVisibility = PsiUtil.getMaximumModifierForMember(aClass, false); + } + else { + //noinspection MagicConstant + newVisibility = visibility; + } + VisibilityUtil.setVisibility(prototype.getModifierList(), newVisibility); + return prototype; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java index 3508873df641..f7f7045af78c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -31,7 +31,6 @@ import java.util.List; * @author max */ public class PsiClassReferenceType extends PsiClassType.Stub { - @NotNull private final PsiJavaCodeReferenceElement myReference; public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel level) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java index 1eb3a4efe70c..1a859c709da0 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java @@ -266,7 +266,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme case CLASS_OR_PACKAGE_NAME_KIND: case CLASS_IN_QUALIFIED_NEW_KIND: JavaResolveResult[] results = PsiImplUtil.multiResolveImpl(containingFile.getProject(), containingFile, this, false, OurGenericsResolver.INSTANCE); - final PsiElement target = results.length == 1 ? results[0].getElement() : null; + PsiElement target = results.length == 1 ? results[0].getElement() : null; if (target instanceof PsiClass) { PsiClass aClass = (PsiClass)target; StringBuilder buffer = new StringBuilder(); @@ -626,7 +626,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme switch (getKind(containingFile)) { case CLASS_OR_PACKAGE_NAME_KIND: if (resolve() instanceof PsiPackage) return true; - //noinspection fallthrough + break; case CLASS_NAME_KIND: break; @@ -687,7 +687,6 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme } case CLASS_OR_PACKAGE_NAME_KIND: - // if (lastChild.type != IDENTIFIER) return false; if (element instanceof PsiPackage) { final String qName = ((PsiPackage)element).getQualifiedName(); return qName.equals(getCanonicalText(false, null, containingFile)); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.groovy index 0cf316faa639..67c89fc5cc48 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -13,60 +13,51 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.codeInsight; +package com.intellij.codeInsight -import com.intellij.JavaTestUtil; +import com.intellij.JavaTestUtil import com.intellij.codeInsight.generation.OverrideImplementUtil import com.intellij.idea.ActionsBundle import com.intellij.openapi.actionSystem.Presentation -import com.intellij.openapi.command.CommandProcessor; -import com.intellij.psi.PsiClass; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import com.intellij.openapi.command.CommandProcessor +import com.intellij.psi.PsiClass +import com.intellij.psi.util.PsiTreeUtil +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase /** * @author ven */ -public class OverrideImplementTest extends LightCodeInsightFixtureTestCase { - private static final String BASE_DIR = "/codeInsight/overrideImplement/"; - +class OverrideImplementTest extends LightCodeInsightFixtureTestCase { @Override protected String getBasePath() { - return JavaTestUtil.getRelativeJavaTestDataPath(); + JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/overrideImplement" } - public void testImplementExtensionMethods() { doTest(true); } - public void testOverrideExtensionMethods() { doTest(false); } - public void testDoNotImplementExtensionMethods() { doTest(true); } - public void testSkipUnknownAnnotations() { doTest(true); } + public void testImplementExtensionMethods() { doTest(true) } + public void testOverrideExtensionMethods() { doTest(false) } + public void testDoNotImplementExtensionMethods() { doTest(true) } + public void testSkipUnknownAnnotations() { doTest(true) } + public void testMultipleInheritedThrows() { doTest(false) } + public void testOverrideInInterface() { doTest(false) } - public void testOverrideInInterface() { doTest(false); } public void testImplementInInterface() { - myFixture.addClass """ + myFixture.addClass """\ interface A { void foo(); } """ - def file = myFixture.addClass(""" + def file = myFixture.addClass("""\ interface B extends A { } """).containingFile.virtualFile myFixture.configureFromExistingVirtualFile(file) - def implementMethodsName = ActionsBundle.message("action.ImplementMethods.text") - final Presentation presentation = new Presentation(); - presentation.setText(implementMethodsName); + def Presentation presentation = new Presentation() + presentation.setText(ActionsBundle.message("action.ImplementMethods.text")) + CommandProcessor.instance.executeCommand(project, { invokeAction(true) }, presentation.text, null) - CommandProcessor.instance.executeCommand(project, new Runnable() { - @Override - void run() { - invokeAction(true) - } - }, presentation.getText(), null) - - - myFixture.checkResult """ + myFixture.checkResult """\ interface B extends A { @Override default void foo() { @@ -74,12 +65,11 @@ interface B extends A { } } """ - } - public void testMultipleInheritedThrows() {doTest(false);} public void "test overriding overloaded method"() { - myFixture.addClass """package bar; + myFixture.addClass """\ +package bar; interface A { void foo(Foo2 f); void foo(Foo1 f); @@ -87,7 +77,8 @@ interface A { """ myFixture.addClass "package bar; class Foo1 {}" myFixture.addClass "package bar; class Foo2 {}" - def file = myFixture.addClass("""package bar; + def file = myFixture.addClass("""\ +package bar; class Test implements A { public void foo(Foo1 f) {} @@ -97,7 +88,8 @@ class Test implements A { invokeAction(true) - myFixture.checkResult """package bar; + myFixture.checkResult """\ +package bar; class Test implements A { public void foo(Foo1 f) {} @@ -110,16 +102,16 @@ class Test implements A { } private void doTest(boolean toImplement) { - String name = getTestName(false); - myFixture.configureByFile(BASE_DIR + "before" + name + ".java"); + String name = getTestName(false) + myFixture.configureByFile("before${name}.java") invokeAction(toImplement) - myFixture.checkResultByFile(BASE_DIR + "after" + name + ".java"); + myFixture.checkResultByFile("after${name}.java") } private void invokeAction(boolean toImplement) { - int offset = myFixture.getEditor().getCaretModel().getOffset(); - PsiClass psiClass = PsiTreeUtil.findElementOfClassAtOffset(myFixture.getFile(), offset, PsiClass.class, false); - assert psiClass != null; - OverrideImplementUtil.chooseAndOverrideOrImplementMethods(getProject(), myFixture.getEditor(), psiClass, toImplement); + int offset = myFixture.getEditor().getCaretModel().getOffset() + PsiClass psiClass = PsiTreeUtil.findElementOfClassAtOffset(myFixture.getFile(), offset, PsiClass.class, false) + assert psiClass != null + OverrideImplementUtil.chooseAndOverrideOrImplementMethods(getProject(), myFixture.getEditor(), psiClass, toImplement) } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy index 6373bc3ce307..db8d4ad35867 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/psi/AnnotatedTypeTest.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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,28 +18,26 @@ package com.intellij.codeInsight.psi import com.intellij.pom.java.LanguageLevel import com.intellij.psi.* import com.intellij.psi.impl.source.PsiImmediateClassType -import com.intellij.testFramework.LightIdeaTestCase +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase -@SuppressWarnings("GroovyAssignabilityCheck") -class AnnotatedTypeTest extends LightIdeaTestCase { - private PsiFile context +class AnnotatedTypeTest extends LightCodeInsightFixtureTestCase { private PsiElementFactory factory + private PsiElement context public void setUp() throws Exception { super.setUp() - factory = javaFacade.elementFactory - context = createFile("typeCompositionTest.java", """ -package pkg; -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.*; + factory = myFixture.javaFacade.elementFactory + context = myFixture.addClass("""\ + package pkg; -@interface A { } -@Target({TYPE_USE}) @interface TA { int value() default 42; } + import java.lang.annotation.*; -class E1 extends Exception { } -class E2 extends Exception { } -""") + @interface A { } + @Target(ElementType.TYPE_USE) @interface TA { int value() default 42; } + + class E1 extends Exception { } + class E2 extends Exception { }""".stripIndent()) } public void testPrimitiveArrayType() { @@ -47,12 +45,14 @@ class E2 extends Exception { } } public void testEllipsisType() { - def psi = factory.createParameterFromText("@TA int @TA ... p", context) - assertTypeText(psi.type, "@pkg.TA int @pkg.TA ...", "int...") + doTest("@TA int @TA ... p", "@pkg.TA int @pkg.TA ...", "int...") } public void testClassReferenceType() { doTest("@A @TA(1) String s", "java.lang.@pkg.TA(1) String", "java.lang.String") + } + + public void testQualifiedClassReferenceType() { doTest("@A java.lang.@TA(1) String s", "java.lang.@pkg.TA(1) String", "java.lang.String") } @@ -65,26 +65,25 @@ class E2 extends Exception { } } public void testDisjunctionType() { - def psi = factory.createStatementFromText("try { } catch (@A @TA(1) E1 | @TA(2) E2 e) { }", context) + def psi = factory.createStatementFromText("try { } catch (@A @TA(1) E1 | @TA(2) E2 e) { }", context) as PsiTryStatement assertTypeText(psi.catchBlockParameters[0].type, "pkg.@pkg.TA(1) E1 | pkg.@pkg.TA(2) E2", "pkg.E1 | pkg.E2") } public void testDiamondType() { - def psi = factory.createStatementFromText("Class<@TA String> cs = new Class<>()", context) - assertTypeText(psi.declaredElements[0].initializer.type, "java.lang.Class", "java.lang.Class") + def psi = factory.createStatementFromText("Class<@TA String> cs = new Class<>()", context) as PsiDeclarationStatement + def var = psi.declaredElements[0] as PsiVariable + assertTypeText(var.initializer.type, "java.lang.Class", "java.lang.Class") } public void testImmediateClassType() { - def aClass = javaFacade.findClass(CommonClassNames.JAVA_LANG_OBJECT) - def statement = factory.createStatementFromText("@TA int x", context) - def annotations = statement.declaredElements[0].modifierList.annotations + def aClass = myFixture.javaFacade.findClass(CommonClassNames.JAVA_LANG_OBJECT) + def annotations = factory.createParameterFromText("@TA int x", context).modifierList.annotations def type = new PsiImmediateClassType(aClass, PsiSubstitutor.EMPTY, LanguageLevel.JDK_1_8, annotations) assertTypeText(type, "java.lang.@pkg.TA Object", CommonClassNames.JAVA_LANG_OBJECT) } private void doTest(String text, String annotated, String canonical) { - def psi = factory.createStatementFromText(text, context) - assertTypeText(psi.declaredElements[0].type, annotated, canonical) + assertTypeText(factory.createParameterFromText(text, context).type, annotated, canonical) } private static void assertTypeText(PsiType type, String annotated, String canonical) {