diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.java b/java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.java index 46d734d549bd..342f4bbbdc6c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.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. @@ -20,7 +20,6 @@ package com.intellij.psi.impl.cache; * @author max */ public interface ModifierFlags { -// ---- The group equal to corresponding in ClsUtil.ACC_* int PUBLIC_MASK = 0x0001; int PRIVATE_MASK = 0x0002; int PROTECTED_MASK = 0x0004; @@ -31,9 +30,8 @@ public interface ModifierFlags { int TRANSIENT_MASK = 0x0080; int NATIVE_MASK = 0x0100; int INTERFACE_MASK = 0x0200; + int DEFENDER_MASK = 0x0200; int ABSTRACT_MASK = 0x0400; -// ---- End of the group equal to corresponding in ClsUtil.ACC_* - int STRICTFP_MASK = 0x0800; int PACKAGE_LOCAL_MASK = 0x1000; int DEPRECATED_MASK = 0x2000; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.java index 677c9a002a82..b3f90b70dfd6 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.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. @@ -30,12 +30,8 @@ import com.intellij.psi.tree.IElementType; import com.intellij.util.CharTable; import gnu.trove.TObjectIntHashMap; import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.Nullable; -import java.util.Collections; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Set; /** * @author max @@ -123,7 +119,7 @@ public class RecordUtil { else if (parent instanceof PsiMethodStub) { if (grandParent instanceof PsiClassStub && ((PsiClassStub)grandParent).isInterface()) { alreadyPublic = true; - alreadyAbstract = true; + alreadyAbstract = !((PsiMethodStub)parent).isDefender(); } } else if (parent instanceof PsiFieldStub) { @@ -143,27 +139,37 @@ public class RecordUtil { for (final LighterASTNode child : tree.getChildren(modList)) { final IElementType type = child.getTokenType(); - if(type == JavaTokenType.PUBLIC_KEYWORD) { + if (type == JavaTokenType.PUBLIC_KEYWORD) { alreadyPublic = true; - } else if(type == JavaTokenType.PRIVATE_KEYWORD) { + } + else if (type == JavaTokenType.PRIVATE_KEYWORD) { packed |= ModifierFlags.PRIVATE_MASK; - } else if(type == JavaTokenType.PROTECTED_KEYWORD) { + } + else if (type == JavaTokenType.PROTECTED_KEYWORD) { packed |= ModifierFlags.PROTECTED_MASK; - } else if(type == JavaTokenType.ABSTRACT_KEYWORD) { - alreadyAbstract =true; - } else if (type == JavaTokenType.FINAL_KEYWORD) { + } + else if (type == JavaTokenType.ABSTRACT_KEYWORD) { + alreadyAbstract = true; + } + else if (type == JavaTokenType.FINAL_KEYWORD) { alreadyFinal = true; - } else if (type == JavaTokenType.STATIC_KEYWORD) { + } + else if (type == JavaTokenType.STATIC_KEYWORD) { alreadyStatic = true; - } else if(type == JavaTokenType.NATIVE_KEYWORD) { + } + else if (type == JavaTokenType.NATIVE_KEYWORD) { packed |= ModifierFlags.NATIVE_MASK; - } else if (type == JavaTokenType.SYNCHRONIZED_KEYWORD) { + } + else if (type == JavaTokenType.SYNCHRONIZED_KEYWORD) { packed |= ModifierFlags.SYNCHRONIZED_MASK; - } else if (type == JavaTokenType.TRANSIENT_KEYWORD) { + } + else if (type == JavaTokenType.TRANSIENT_KEYWORD) { packed |= ModifierFlags.TRANSIENT_MASK; - } else if (type == JavaTokenType.VOLATILE_KEYWORD) { + } + else if (type == JavaTokenType.VOLATILE_KEYWORD) { packed |= ModifierFlags.VOLATILE_MASK; - } else if (type == JavaTokenType.STRICTFP_KEYWORD) { + } + else if (type == JavaTokenType.STRICTFP_KEYWORD) { packed |= ModifierFlags.STRICTFP_MASK; } } @@ -175,8 +181,7 @@ public class RecordUtil { if ((packed & ModifierFlags.PRIVATE_MASK) == 0 && (packed & ModifierFlags.PROTECTED_MASK) == 0 && - (packed & ModifierFlags.PUBLIC_MASK) == 0 - ) { + (packed & ModifierFlags.PUBLIC_MASK) == 0) { packed |= ModifierFlags.PACKAGE_LOCAL_MASK; } @@ -217,62 +222,6 @@ public class RecordUtil { return (ourModifierNameToFlagMap.get(psiModifier) & packed) != 0; } - @SuppressWarnings({"unchecked"}) - private static final Set[] SET_INSTANCES = new Set[8 * 4]; - - private static final String[] VISIBILITY_MODIFIERS = {null, PsiModifier.PUBLIC, PsiModifier.PRIVATE, PsiModifier.PROTECTED}; - - private static final int[] MODIFIER_MAP = {0, 1, 2, -1, 3, -1, -1, -1, -1}; - - static { - SET_INSTANCES[0] = Collections.emptySet(); - for (int i = 1; i < 4; i++) { - SET_INSTANCES[i << 3] = Collections.singleton(VISIBILITY_MODIFIERS[i]); - } - - for (int i = 1; i < 8; i++) { - int attr = i << 3; - - Set set = new LinkedHashSet(); - if ((attr & ModifierFlags.STATIC_MASK) != 0) set.add(PsiModifier.STATIC); - if ((attr & ModifierFlags.FINAL_MASK) != 0) set.add(PsiModifier.FINAL); - if ((attr & (4 << 3)) != 0) set.add(PsiModifier.ABSTRACT); - - if (set.size() == 1) set = Collections.singleton(set.iterator().next()); - - SET_INSTANCES[i] = set; - - for (int k = 1; k < 4; k++) { - Set setWithModifier = new LinkedHashSet(); - setWithModifier.add(VISIBILITY_MODIFIERS[k]); - setWithModifier.addAll(set); - assert setWithModifier.size() > 1; - - SET_INSTANCES[(k << 3) + i] = setWithModifier; - } - } - } - - public static Set getModifierSet(int modifiers) { - assert (modifiers & ~(ModifierFlags.PUBLIC_MASK | ModifierFlags.PRIVATE_MASK | ModifierFlags.PROTECTED_MASK | - ModifierFlags.FINAL_MASK | ModifierFlags.ABSTRACT_MASK | ModifierFlags.STATIC_MASK)) == 0; - - int visibilityModifierIndex = MODIFIER_MAP[modifiers & 7]; - int index = ((modifiers >>> 3) & 3) + ((modifiers & ModifierFlags.ABSTRACT_MASK) >>> 8); - if (visibilityModifierIndex != -1) { - return SET_INSTANCES[index + (visibilityModifierIndex << 3)]; - } - - Set res = new LinkedHashSet(); - if ((modifiers & ModifierFlags.PUBLIC_MASK) != 0) res.add(PsiModifier.PUBLIC); - if ((modifiers & ModifierFlags.PRIVATE_MASK) != 0) res.add(PsiModifier.PRIVATE); - if ((modifiers & ModifierFlags.PROTECTED_MASK) != 0) res.add(PsiModifier.PROTECTED); - - res.addAll(SET_INSTANCES[index]); - - return res; - } - public static String intern(final CharTable table, final LighterASTNode node) { assert node instanceof LighterASTTokenNode; return table.intern(((LighterASTTokenNode)node).getText()).toString(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java index 8ba604ac0ba6..1185d9fe9263 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java @@ -58,6 +58,10 @@ public class StubBuildingVisitor extends ClassVisitor { public static final String FLOAT_NEGATIVE_INF = "-1.0f / 0.0"; public static final String FLOAT_NAN = "0.0f / 0.0"; + @NonNls private static final String SYNTHETIC_CLASS_INIT_METHOD = ""; + @NonNls private static final String SYNTHETIC_INIT_METHOD = ""; + + private static final int ACC_DEFENDER = Opcodes.ACC_INTERFACE; // todo[r.sh] use right constant once ASM gets Java 8 support private final InnerClassSourceStrategy myInnersStrategy; private final StubElement myParent; @@ -65,8 +69,6 @@ public class StubBuildingVisitor extends ClassVisitor { private final T mySource; private PsiModifierListStub myModList; private PsiClassStub myResult; - @NonNls private static final String SYNTHETIC_CLINIT_METHOD = ""; - @NonNls private static final String SYNTHETIC_INIT_METHOD = ""; private JavaLexer myLexer; public StubBuildingVisitor(final T classSource, InnerClassSourceStrategy innersStrategy, final StubElement parent, final int access) { @@ -174,20 +176,25 @@ public class StubBuildingVisitor extends ClassVisitor { return convertedSuper; } + // for lexer, so need not to be precise private static LanguageLevel convertFromVersion(final int version) { - if (version == Opcodes.V1_1 || version == Opcodes.V1_2 || version == Opcodes.V1_3) { - return LanguageLevel.JDK_1_3; - } + switch (version) { + case Opcodes.V1_1: + case Opcodes.V1_2: + case Opcodes.V1_3: + return LanguageLevel.JDK_1_3; - if (version == Opcodes.V1_4) { - return LanguageLevel.JDK_1_4; - } + case Opcodes.V1_4: + return LanguageLevel.JDK_1_4; - if (version == Opcodes.V1_5 || version == Opcodes.V1_6) { - return LanguageLevel.JDK_1_5; - } + case Opcodes.V1_5: + case Opcodes.V1_6: + case Opcodes.V1_7: + return LanguageLevel.JDK_1_5; - return LanguageLevel.HIGHEST; + default: + return LanguageLevel.HIGHEST; + } } private static int packCommonFlags(final int access) { @@ -357,16 +364,17 @@ public class StubBuildingVisitor extends ClassVisitor { // However Scala compiler erroneously generates ACC_BRIDGE instead of ACC_SYNTHETIC flag for in-trait implementation delegation. See IDEA-78649 if (isSynthetic) return null; - if (SYNTHETIC_CLINIT_METHOD.equals(name)) return null; + if (SYNTHETIC_CLASS_INIT_METHOD.equals(name)) return null; boolean isDeprecated = (access & Opcodes.ACC_DEPRECATED) != 0; boolean isConstructor = SYNTHETIC_INIT_METHOD.equals(name); boolean isVarargs = (access & Opcodes.ACC_VARARGS) != 0; boolean isAnnotationMethod = myResult.isAnnotationType(); + boolean isDefender = (access & ACC_DEFENDER) != 0; if (!isConstructor && !isCorrectName(name)) return null; - final byte flags = PsiMethodStubImpl.packFlags(isConstructor, isAnnotationMethod, isVarargs, isDeprecated, false); + final byte flags = PsiMethodStubImpl.packFlags(isConstructor, isAnnotationMethod, isVarargs, isDeprecated, false, isDefender); String canonicalMethodName = isConstructor ? myResult.getName() : name; final List args = new ArrayList(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java index 966832d67bf6..562128f464a8 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.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. @@ -73,6 +73,7 @@ public abstract class JavaMethodElementType extends JavaStubElementType { boolean isConstructor(); boolean isVarArgs(); boolean isAnnotationMethod(); + boolean isDefender(); @Nullable String getDefaultValueText(); @NotNull TypeInfo getReturnTypeText(boolean doResolve); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java index 81420296c9dd..f076c8a273e0 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 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. @@ -43,6 +43,7 @@ public class PsiMethodStubImpl extends StubBase implements PsiMethodS private static final int ANNOTATION = 0x04; private static final int DEPRECATED = 0x08; private static final int DEPRECATED_ANNOTATION = 0x10; + private static final int DEFENDER = 0x20; public PsiMethodStubImpl(final StubElement parent, @@ -88,6 +89,11 @@ public class PsiMethodStubImpl extends StubBase implements PsiMethodS return isAnnotationMethod(myFlags); } + @Override + public boolean isDefender() { + return (myFlags & DEFENDER) != 0; + } + public static boolean isAnnotationMethod(final byte flags) { return (flags & ANNOTATION) != 0; } @@ -145,13 +151,19 @@ public class PsiMethodStubImpl extends StubBase implements PsiMethodS myDefaultValueText = StringRef.fromString(defaultValueText); } - public static byte packFlags(boolean isConstructor, boolean isAnnotationMethod, boolean isVarargs, boolean isDeprecated, boolean hasDeprecatedAnnotation) { + public static byte packFlags(boolean isConstructor, + boolean isAnnotationMethod, + boolean isVarargs, + boolean isDeprecated, + boolean hasDeprecatedAnnotation, + boolean isDefender) { byte flags = 0; if (isConstructor) flags |= CONSTRUCTOR; if (isAnnotationMethod) flags |= ANNOTATION; if (isVarargs) flags |= VARARGS; if (isDeprecated) flags |= DEPRECATED; if (hasDeprecatedAnnotation) flags |= DEPRECATED_ANNOTATION; + if (isDefender) flags |= DEFENDER; return flags; } @@ -179,6 +191,10 @@ public class PsiMethodStubImpl extends StubBase implements PsiMethodS builder.append(" default=").append(defaultValue); } + if (isDefender()) { + builder.append(" default {}"); + } + builder.append("]"); return builder.toString(); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java index b20b16b5c7d6..97cc4bed2543 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 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. @@ -37,7 +37,7 @@ import java.io.IOException; * @author max */ public class JavaFileElementType extends ILightStubFileElementType { - public static final int STUB_VERSION = 9; + public static final int STUB_VERSION = 10; public JavaFileElementType() { super("java.FILE", JavaLanguage.INSTANCE); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java index 17b56ed2c050..f2ecc6853e3b 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 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. @@ -31,6 +31,7 @@ import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.impl.source.tree.TreeElement; import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; @@ -151,7 +152,7 @@ public class PsiModifierListImpl extends JavaStubPsiElement return false; } if (type == JavaTokenType.ABSTRACT_KEYWORD) { - return true; + return !PsiUtil.isExtensionMethod((PsiMethod)parent); } } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/ExtensionMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/ExtensionMethods.java index 478b76d6eb8d..909d08a364b9 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/ExtensionMethods.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/ExtensionMethods.java @@ -13,9 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + class C { interface I { - void m1() { } - void m2() default { } + void m() default { } + } + + void test() { + new I(){}.m(); } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/psi/JavaStubBuilderTest.java b/java/java-tests/testSrc/com/intellij/psi/JavaStubBuilderTest.java index 58528d12e401..9bd2f1abd2d4 100644 --- a/java/java-tests/testSrc/com/intellij/psi/JavaStubBuilderTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/JavaStubBuilderTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 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. @@ -32,7 +32,6 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.security.SecureRandom; - public class JavaStubBuilderTest extends LightIdeaTestCase { private static final StubBuilder NEW_BUILDER = new JavaLightStubBuilder(); @@ -40,7 +39,7 @@ public class JavaStubBuilderTest extends LightIdeaTestCase { public void setUp() throws Exception { super.setUp(); doTest("@interface A { int i() default 42; }\n class C { void m(int p) throws E { } }", null); // warm up - LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_7); + LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.HIGHEST); } public void testEmpty() { @@ -112,6 +111,10 @@ public class JavaStubBuilderTest extends LightIdeaTestCase { " public C() throws Exception { }\n" + " public abstract void m(final int i, int[] a1, int a2[], int[] a3[]);\n" + " private static int v2a(int... v) [] { return v; }\n" + + "}\n" + + "interface I {\n" + + " void m1();\n" + + " void m2() default { }\n" + "}", "PsiJavaFileStub []\n" + @@ -160,6 +163,21 @@ public class JavaStubBuilderTest extends LightIdeaTestCase { " PARAMETER_LIST:PsiParameterListStub\n" + " PARAMETER:PsiParameterStub[v:int...]\n" + " MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" + + " THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" + + " CLASS:PsiClassStub[interface name=I fqn=I]\n" + + " MODIFIER_LIST:PsiModifierListStub[mask=5120]\n" + + " TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" + + " EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" + + " IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" + + " METHOD:PsiMethodStub[m1:void]\n" + + " MODIFIER_LIST:PsiModifierListStub[mask=1025]\n" + + " TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" + + " PARAMETER_LIST:PsiParameterListStub\n" + + " THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" + + " METHOD:PsiMethodStub[m2:void default {}]\n" + + " MODIFIER_LIST:PsiModifierListStub[mask=1]\n" + + " TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" + + " PARAMETER_LIST:PsiParameterListStub\n" + " THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n"); } @@ -393,7 +411,7 @@ public class JavaStubBuilderTest extends LightIdeaTestCase { final String lightStr2 = DebugUtil.stubTreeToString(lighterTree2); if (tree != null) { System.out.println("light=" + t1 + "mks, heavy=" + t2 + "mks"); - if (!"".equals(tree)) { + if (!tree.isEmpty()) { assertEquals("light tree differs", tree, lightStr); assertEquals("light tree (2nd) differs", tree, lightStr2); }