diff --git a/bin/scripts/win/idea.bat b/bin/scripts/win/idea.bat index 483f10f10a804..f5059ff959215 100644 --- a/bin/scripts/win/idea.bat +++ b/bin/scripts/win/idea.bat @@ -15,34 +15,33 @@ SET IDE_HOME=%IDE_BIN_DIR%\.. :: Try (in order): @@product_uc@@_JDK, @@vm_options@@.jdk, ..\jre, JDK_HOME, JAVA_HOME. :: --------------------------------------------------------------------- SET JDK= -IF EXIST "%@@product_uc@@_JDK%" ( - SET JDK=%@@product_uc@@_JDK% -) -IF "%JDK%" == "" ( - SET BITS=64 - SET USER_JDK64_FILE=%USERPROFILE%\.@@system_selector@@\config\@@vm_options@@.jdk - SET BITS= - SET USER_JDK_FILE=%USERPROFILE%\.@@system_selector@@\config\@@vm_options@@.jdk - IF EXIST "%USER_JDK64_FILE%" ( - SET /P JDK=<%USER_JDK64_FILE% - IF NOT EXIST "%JDK%" SET JDK=%IDE_HOME%\%JDK% - ) ELSE ( - IF EXIST "%USER_JDK_FILE%" ( - SET /P JDK=<%USER_JDK_FILE% - IF NOT EXIST "%JDK%" SET JDK=%IDE_HOME%\%JDK% - ) - ) -) -IF "%JDK%" == "" ( - IF EXIST "%IDE_HOME%\jre" SET JDK=%IDE_HOME%\jre -) -IF "%JDK%" == "" ( - IF EXIST "%JDK_HOME%" SET JDK=%JDK_HOME% + +IF EXIST "%@@product_uc@@_JDK%" SET JDK=%@@product_uc@@_JDK% +IF NOT "%JDK%" == "" GOTO check + +SET BITS=64 +SET USER_JDK64_FILE=%USERPROFILE%\.@@system_selector@@\config\@@vm_options@@.jdk +SET BITS= +SET USER_JDK_FILE=%USERPROFILE%\.@@system_selector@@\config\@@vm_options@@.jdk +IF EXIST "%USER_JDK64_FILE%" ( + SET /P JDK=<%USER_JDK64_FILE% +) ELSE ( + IF EXIST "%USER_JDK_FILE%" SET /P JDK=<%USER_JDK_FILE% ) -IF "%JDK%" == "" ( - IF EXIST "%JAVA_HOME%" SET JDK=%JAVA_HOME% +IF NOT "%JDK%" == "" ( + IF NOT EXIST "%JDK%" SET JDK=%IDE_HOME%\%JDK% + GOTO check ) +IF EXIST "%IDE_HOME%\jre" SET JDK=%IDE_HOME%\jre +IF NOT "%JDK%" == "" GOTO check + +IF EXIST "%JDK_HOME%" SET JDK=%JDK_HOME% +IF NOT "%JDK%" == "" GOTO check + +IF EXIST "%JAVA_HOME%" SET JDK=%JAVA_HOME% + +:check SET JAVA_EXE=%JDK%\bin\java.exe IF NOT EXIST "%JAVA_EXE%" SET JAVA_EXE=%JDK%\jre\bin\java.exe IF NOT EXIST "%JAVA_EXE%" ( diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BoxingEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BoxingEvaluator.java index 1bcd93ef432f2..c5eb7951615e6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BoxingEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BoxingEvaluator.java @@ -19,9 +19,9 @@ import com.intellij.debugger.engine.JVMNameUtil; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; -import com.intellij.psi.CommonClassNames; +import com.intellij.psi.PsiPrimitiveType; +import com.intellij.psi.impl.PsiJavaParserFacadeImpl; import com.sun.jdi.*; -import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; @@ -43,29 +43,12 @@ public Object evaluate(EvaluationContextImpl context) throws EvaluateException { return result; } - if (result instanceof BooleanValue) { - return convertToWrapper(context, (BooleanValue)result, CommonClassNames.JAVA_LANG_BOOLEAN); - } - if (result instanceof ByteValue) { - return convertToWrapper(context, (ByteValue)result, CommonClassNames.JAVA_LANG_BYTE); - } - if (result instanceof CharValue) { - return convertToWrapper(context, (CharValue)result, CommonClassNames.JAVA_LANG_CHARACTER); - } - if (result instanceof ShortValue) { - return convertToWrapper(context, (ShortValue)result, CommonClassNames.JAVA_LANG_SHORT); - } - if (result instanceof IntegerValue) { - return convertToWrapper(context, (IntegerValue)result, CommonClassNames.JAVA_LANG_INTEGER); - } - if (result instanceof LongValue) { - return convertToWrapper(context, (LongValue)result, CommonClassNames.JAVA_LANG_LONG); - } - if (result instanceof FloatValue) { - return convertToWrapper(context, (FloatValue)result, CommonClassNames.JAVA_LANG_FLOAT); - } - if (result instanceof DoubleValue) { - return convertToWrapper(context, (DoubleValue)result, CommonClassNames.JAVA_LANG_DOUBLE); + if (result instanceof PrimitiveValue) { + PrimitiveValue primitiveValue = (PrimitiveValue)result; + PsiPrimitiveType primitiveType = PsiJavaParserFacadeImpl.getPrimitiveType(primitiveValue.type().name()); + if (primitiveType != null) { + return convertToWrapper(context, primitiveValue, primitiveType.getBoxedTypeName()); + } } throw new EvaluateException("Cannot perform boxing conversion for a value of type " + ((Value)result).type().name()); } diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/MethodBytecodeUtil.java b/java/debugger/impl/src/com/intellij/debugger/jdi/MethodBytecodeUtil.java index c994079ed0d3b..d84212cfb0639 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/MethodBytecodeUtil.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/MethodBytecodeUtil.java @@ -15,6 +15,7 @@ */ package com.intellij.debugger.jdi; +import com.intellij.util.ReflectionUtil; import com.intellij.util.ThrowableConsumer; import com.sun.jdi.*; import org.jetbrains.annotations.NotNull; @@ -52,13 +53,23 @@ public static void visit(ReferenceType classType, Method method, long maxOffset, visit(classType, method, bytecodes, methodVisitor); } + public static byte[] getConstantPool(ReferenceType type) { + try { + return type.constantPool(); + } + catch (NullPointerException e) { // workaround for JDK bug 6822627 + ReflectionUtil.resetField(type, "constantPoolInfoGotten"); + return type.constantPool(); + } + } + private static void visit(ReferenceType type, Method method, byte[] bytecodes, MethodVisitor methodVisitor) { try { try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos)) { dos.writeInt(0xCAFEBABE); // magic dos.writeInt(Opcodes.V1_8); // version dos.writeShort(type.constantPoolCount()); // constant_pool_count - dos.write(type.constantPool()); // constant_pool + dos.write(getConstantPool(type)); // constant_pool dos.writeShort(0); // access_flags; dos.writeShort(0); // this_class; dos.writeShort(0); // super_class; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CachedEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CachedEvaluator.java index c878a356dc012..224e78431161a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CachedEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CachedEvaluator.java @@ -20,6 +20,7 @@ import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.impl.PsiJavaParserFacadeImpl; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.reference.SoftReference; import org.jetbrains.annotations.Nullable; @@ -65,14 +66,24 @@ public void clear() { protected Cache initEvaluatorAndChildrenExpression(final Project project) { final Cache cache = new Cache(); try { - PsiClass contextClass = DebuggerUtils.findClass(getClassName(), project, GlobalSearchScope.allScope(project)); - if (contextClass instanceof PsiCompiledElement) { - contextClass = (PsiClass)((PsiCompiledElement)contextClass).getMirror(); + String className = getClassName(); + PsiClass contextClass; + PsiType contextType; + PsiPrimitiveType primitiveType = PsiJavaParserFacadeImpl.getPrimitiveType(className); + if (primitiveType != null) { + contextClass = JavaPsiFacade.getInstance(project).findClass(primitiveType.getBoxedTypeName(), GlobalSearchScope.allScope(project)); + contextType = primitiveType; } - if(contextClass == null) { - throw EvaluateExceptionUtil.CANNOT_FIND_SOURCE_CLASS; + else { + contextClass = DebuggerUtils.findClass(className, project, GlobalSearchScope.allScope(project)); + if (contextClass instanceof PsiCompiledElement) { + contextClass = (PsiClass)((PsiCompiledElement)contextClass).getMirror(); + } + if (contextClass == null) { + throw EvaluateExceptionUtil.CANNOT_FIND_SOURCE_CLASS; + } + contextType = DebuggerUtils.getType(className, project); } - final PsiType contextType = DebuggerUtils.getType(getClassName(), project); cache.myPsiChildrenExpression = null; JavaCodeFragment codeFragment = myDefaultFragmentFactory.createCodeFragment(myReferenceExpression, contextClass, project); codeFragment.forceResolveScope(GlobalSearchScope.allScope(project)); diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java b/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java index 9f3b1229aac83..2f382f0ca80fd 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java @@ -40,6 +40,7 @@ import com.intellij.psi.util.ClassUtil; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiTypesUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.StringBuilderSpinAllocator; import com.intellij.util.containers.ContainerUtil; @@ -266,10 +267,14 @@ else if (nodeClass.dims > rendererClass.dims) { } public static boolean instanceOf(@Nullable Type subType, @NotNull String superType) { - if (subType == null || subType instanceof PrimitiveType || subType instanceof VoidType) { + if (subType == null || subType instanceof VoidType) { return false; } + if (subType instanceof PrimitiveType) { + return superType.equals(subType.name()); + } + if (CommonClassNames.JAVA_LANG_OBJECT.equals(superType)) { return true; } @@ -389,18 +394,16 @@ public static PsiClass findClass(@NotNull final String className, @NotNull Proje public static PsiType getType(@NotNull String className, @NotNull Project project) { ApplicationManager.getApplication().assertReadAccessAllowed(); - final PsiManager psiManager = PsiManager.getInstance(project); try { if (getArrayClass(className) != null) { - return JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory().createTypeFromText(className, null); + return JavaPsiFacade.getInstance(project).getElementFactory().createTypeFromText(className, null); } - if(project.isDefault()) { + if (project.isDefault()) { return null; } - final PsiClass aClass = - JavaPsiFacade.getInstance(psiManager.getProject()).findClass(className.replace('$', '.'), GlobalSearchScope.allScope(project)); + PsiClass aClass = findClass(className, project, GlobalSearchScope.allScope(project)); if (aClass != null) { - return JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory().createType(aClass); + return PsiTypesUtil.getClassType(aClass); } } catch (IncorrectOperationException e) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java index 13faebfeb7990..6d699ea589fc1 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java @@ -24,6 +24,7 @@ import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction; import com.intellij.codeInsight.intention.QuickFixFactory; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.module.impl.scopes.ModulesScope; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; @@ -75,21 +76,18 @@ static HighlightInfo checkModuleDuplicates(@NotNull PsiJavaModule element, @NotN @Nullable static HighlightInfo checkFileDuplicates(@NotNull PsiJavaModule element, @NotNull PsiFile file) { - VirtualFile vFile = file.getVirtualFile(); - if (vFile != null) { + Module module = ModuleUtilCore.findModuleForPsiElement(element); + if (module != null) { Project project = file.getProject(); - Module module = ProjectFileIndex.SERVICE.getInstance(project).getModuleForFile(vFile); - if (module != null) { - Collection others = - FilenameIndex.getVirtualFilesByName(project, MODULE_INFO_FILE, new ModulesScope(Collections.singleton(module), project)); - if (others.size() > 1) { - String message = JavaErrorMessages.message("module.file.duplicate"); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(element)).description(message).create(); - others.stream().map(f -> PsiManager.getInstance(project).findFile(f)).filter(f -> f != file).findFirst().ifPresent( - duplicate -> QuickFixAction.registerQuickFixAction(info, new GoToSymbolFix(duplicate, JavaErrorMessages.message("module.open.duplicate.text"))) - ); - return info; - } + Collection others = + FilenameIndex.getVirtualFilesByName(project, MODULE_INFO_FILE, new ModulesScope(Collections.singleton(module), project)); + if (others.size() > 1) { + String message = JavaErrorMessages.message("module.file.duplicate"); + HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(element)).description(message).create(); + others.stream().map(f -> PsiManager.getInstance(project).findFile(f)).filter(f -> f != file).findFirst().ifPresent( + duplicate -> QuickFixAction.registerQuickFixAction(info, new GoToSymbolFix(duplicate, JavaErrorMessages.message("module.open.duplicate.text"))) + ); + return info; } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java index f9525dc0a2683..f9f0e5e88008e 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java @@ -32,6 +32,7 @@ public class UnusedSymbolLocalInspectionBase extends BaseJavaLocalInspectionTool @NonNls public static final String SHORT_NAME = HighlightInfoType.UNUSED_SYMBOL_SHORT_NAME; @NonNls public static final String DISPLAY_NAME = HighlightInfoType.UNUSED_SYMBOL_DISPLAY_NAME; @NonNls public static final String UNUSED_PARAMETERS_SHORT_NAME = "UnusedParameters"; + @NonNls public static final String UNUSED_ID = "unused"; public boolean LOCAL_VARIABLE = true; public boolean FIELD = true; @@ -126,7 +127,7 @@ public String getShortName() { @NotNull @NonNls public String getID() { - return "unused"; + return UNUSED_ID; } @Override diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionMerger.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionMerger.java index 5092410f419e5..75be9546415be 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionMerger.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionMerger.java @@ -15,12 +15,12 @@ */ package com.intellij.codeInspection.deadCode; -import com.intellij.codeInspection.ex.InspectionElementsMerger; +import com.intellij.codeInspection.ex.InspectionElementsMergerBase; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; import com.intellij.openapi.util.WriteExternalException; import org.jdom.Element; -public class UnusedDeclarationInspectionMerger extends InspectionElementsMerger { +public class UnusedDeclarationInspectionMerger extends InspectionElementsMergerBase { private static final String UNUSED_SYMBOL = "UNUSED_SYMBOL"; private static final String UNUSED_DECLARATION = "UnusedDeclaration"; diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java b/java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java index 6abd0970c83ab..9ef81a9729040 100644 --- a/java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/unusedParameters/UnusedParametersInspection.java @@ -193,7 +193,7 @@ public static ArrayList getUnusedParameters(RefMethod refMethod) { clearUsedParameters(refMethod, result, checkDeep); for (RefParameter parameter : result) { - if (parameter != null && !((RefElementImpl)parameter).isSuppressed(UnusedSymbolLocalInspectionBase.UNUSED_PARAMETERS_SHORT_NAME)) { + if (parameter != null && !((RefElementImpl)parameter).isSuppressed(UnusedSymbolLocalInspectionBase.UNUSED_PARAMETERS_SHORT_NAME, UnusedSymbolLocalInspectionBase.UNUSED_ID)) { res.add(parameter); } } @@ -315,6 +315,6 @@ private static void removeUnusedParameterViaChangeSignature(final PsiMethod psiM @Nullable @Override public String getAlternativeID() { - return "unused"; + return UnusedSymbolLocalInspectionBase.UNUSED_ID; } } diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java index 372aa1f881a32..a3f0c17d764ed 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java @@ -301,9 +301,9 @@ private static Indent getDefaultSubtreeIndent(@NotNull ASTNode child, @NotNull C if (parent != null) { final Indent defaultChildIndent = getChildIndent(parent, indentOptions); if (defaultChildIndent != null) return defaultChildIndent; - } - if (child.getTreeParent() instanceof PsiLambdaExpression && child instanceof PsiCodeBlock) { - return Indent.getNoneIndent(); + if (parent.getPsi() instanceof PsiLambdaExpression && child instanceof PsiCodeBlock) { + return Indent.getNoneIndent(); + } } return null; diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Imports.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Imports.java index 639a8ea07db8f..67210ee46d7a1 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Imports.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Imports.java @@ -49,40 +49,28 @@ Import[] readImports(UnitInputStream in) throws IOException { } private static void writeImport(@NotNull DataOutput out, IndexTree.Import anImport) throws IOException { - SerializedUnit.writeQualifiedName(out, anImport.myFullname); - boolean hasAlias = anImport.myAlias != 0; + out.writeInt(NameEnvironment.fromString(anImport.myQualifier)); + boolean hasAlias = anImport.myAlias != null; int flags = 0; flags = BitUtil.set(flags, IS_STATIC, anImport.myStaticImport); flags = BitUtil.set(flags, IS_ON_DEMAND, anImport.myOnDemand); flags = BitUtil.set(flags, HAS_ALIAS, hasAlias); out.writeByte(flags); + if (anImport.myImportedName != null) { + out.writeInt(NameEnvironment.hashIdentifier(anImport.myImportedName)); + } if (hasAlias) { - out.writeInt(anImport.myAlias); + out.writeInt(NameEnvironment.hashIdentifier(anImport.myAlias)); } } private Import readImport(UnitInputStream in) throws IOException { - int qualifier = 0; - int len = DataInputOutputUtil.readINT(in); - for (int i = 0; i < len - 1; i++) { - qualifier = in.names.qualifiedName(qualifier, in.readInt()); - } - int lastId = in.readInt(); + int qualifier = in.readInt(); int flags = in.readByte(); + int shortName = BitUtil.isSet(flags, IS_ON_DEMAND) ? 0 : in.readInt(); int alias = BitUtil.isSet(flags, HAS_ALIAS) ? in.readInt() : 0; - boolean onDemand = BitUtil.isSet(flags, IS_ON_DEMAND); - boolean isStatic = BitUtil.isSet(flags, IS_STATIC); - - int shortName; - if (onDemand) { - shortName = 0; - qualifier = in.names.qualifiedName(qualifier, lastId); - } else { - shortName = lastId; - } - - return obtainImport(qualifier, shortName, alias, isStatic); + return obtainImport(qualifier, shortName, alias, BitUtil.isSet(flags, IS_STATIC)); } private Import obtainImport(int qualifier, int shortName, int alias, boolean isStatic) { diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/NameEnvironment.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/NameEnvironment.java index ab943317b08d9..e64a6d74f88ca 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/NameEnvironment.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/NameEnvironment.java @@ -16,52 +16,59 @@ package com.intellij.psi.stubsHierarchy.impl; import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.CommonClassNames; -import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree; -import com.intellij.util.io.DataInputOutputUtil; +import com.intellij.psi.PsiNameHelper; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; +import java.util.List; class NameEnvironment extends UserDataHolderBase { - public static final int OBJECT_NAME = IndexTree.hashIdentifier("Object"); - public static final int NO_NAME = 0; - @QNameHash final int java_lang; - public final QualifiedName java_lang_Enum; - public final QualifiedName java_lang_annotation_Annotation; + static final int OBJECT_NAME = hashIdentifier("Object"); + static final int NO_NAME = 0; + @QNameHash final static int java_lang = fromString("java.lang"); + static final QualifiedName java_lang_Enum = new QualifiedName.Interned(fromString(CommonClassNames.JAVA_LANG_ENUM)); + static final QualifiedName java_lang_annotation_Annotation = + new QualifiedName.Interned(fromString(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION)); - NameEnvironment() { - java_lang = fromString("java.lang"); - java_lang_Enum = new QualifiedName.Interned(fromString(CommonClassNames.JAVA_LANG_ENUM)); - java_lang_annotation_Annotation = new QualifiedName.Interned(fromString(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION)); - } - - @QNameHash int fromString(String s) { + static @QNameHash int fromString(String s) { int id = 0; - for (int shortName : IndexTree.hashQualifiedName(s)) { + for (int shortName : hashQualifiedName(s)) { id = qualifiedName(id, shortName); } return id; } - /** - * @see SerializedUnit#writeQualifiedName(DataOutput, int[]) - */ - @QNameHash int readQualifiedName(DataInput in) throws IOException { - int id = 0; - int len = DataInputOutputUtil.readINT(in); - for (int i = 0; i < len; i++) { - id = qualifiedName(id, in.readInt()); + static int hashIdentifier(@Nullable String s) { + if (StringUtil.isEmpty(s)) return 0; + + // not using String.hashCode because this way there's less collisions for short package names like 'com' + int hash = 0; + for (int i = 0; i < s.length(); i++) { + hash = hash * 239 + s.charAt(i); } - return id; + return hash == 0 ? 1 : hash; + } + + static int[] hashQualifiedName(@NotNull String qName) { + qName = PsiNameHelper.getQualifiedClassName(qName, true); + if (qName.isEmpty()) return ArrayUtil.EMPTY_INT_ARRAY; + + List components = StringUtil.split(qName, "."); + int[] result = new int[components.size()]; + for (int i = 0; i < components.size(); i++) { + result[i] = hashIdentifier(components.get(i)); + } + return result; } - int memberQualifiedName(@QNameHash int ownerName, @ShortName int name) { + static int memberQualifiedName(@QNameHash int ownerName, @ShortName int name) { return name == NO_NAME || ownerName == 0 ? 0 : qualifiedName(ownerName, name); } - @QNameHash int qualifiedName(@QNameHash int prefix, @ShortName int shortName) { + static @QNameHash int qualifiedName(@QNameHash int prefix, @ShortName int shortName) { int hash = prefix * 31 + shortName; return hash == 0 ? 1 : hash; } diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/SerializedUnit.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/SerializedUnit.java index db9a6353f8b9d..ef5067fc6e4ef 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/SerializedUnit.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/SerializedUnit.java @@ -66,10 +66,8 @@ void readUnit(StubEnter stubEnter, int fileId) { } } - /** - * @see NameEnvironment#readQualifiedName(DataInput) - */ - static void writeQualifiedName(DataOutput out, @QNameHash int[] array) throws IOException { + private static void writeNameComponents(DataOutput out, String qName) throws IOException { + int[] array = NameEnvironment.hashQualifiedName(qName); DataInputOutputUtil.writeINT(out, array.length); for (int i : array) { out.writeInt(i); @@ -90,15 +88,16 @@ static QualifiedName readNameComponents(DataInput in) throws IOException { // unit private static void writeUnit(@NotNull DataOutput out, IndexTree.Unit value) throws IOException { - writeQualifiedName(out, value.myPackageName); + writeNameComponents(out, value.myPackageName); out.writeByte(value.myUnitType); - if (value.myUnitType != IndexTree.BYTECODE) { + boolean compiled = value.myUnitType == IndexTree.BYTECODE; + if (!compiled) { Imports.writeImports(out, value); } // class Declaration DataInputOutputUtil.writeINT(out, value.myDecls.length); for (IndexTree.ClassDecl def : value.myDecls) { - saveClassDecl(out, def); + saveClassDecl(out, def, compiled); } } @@ -116,12 +115,12 @@ private static void enterUnit(UnitInputStream in) throws IOException { // class - private static void saveClassDecl(@NotNull DataOutput out, IndexTree.ClassDecl value) throws IOException { + private static void saveClassDecl(@NotNull DataOutput out, IndexTree.ClassDecl value, boolean compiled) throws IOException { DataInputOutputUtil.writeINT(out, value.myStubId); DataInputOutputUtil.writeINT(out, value.myMods); - out.writeInt(value.myName); - writeSupers(out, value); - writeMembers(out, value.myDecls); + out.writeInt(NameEnvironment.hashIdentifier(value.myName)); + writeSupers(out, value, compiled); + writeMembers(out, value.myDecls, compiled); } private static ClassSymbol readClassDecl(UnitInputStream in, UnitInfo info, Symbol owner, @QNameHash int ownerName) throws IOException { @@ -130,7 +129,7 @@ private static ClassSymbol readClassDecl(UnitInputStream in, UnitInfo info, Symb @ShortName int name = in.readInt(); @CompactArray(QualifiedName.class) Object superNames = readSupers(in, info.isCompiled()); - @QNameHash int qname = in.names.memberQualifiedName(ownerName, name); + @QNameHash int qname = NameEnvironment.memberQualifiedName(ownerName, name); ClassSymbol symbol = in.stubEnter.classEnter(info, owner, stubId, mods, name, superNames, qname, in.fileId); readMembers(in, info, qname, symbol); @@ -139,10 +138,10 @@ private static ClassSymbol readClassDecl(UnitInputStream in, UnitInfo info, Symb // supers - private static void writeSupers(@NotNull DataOutput out, IndexTree.ClassDecl value) throws IOException { + private static void writeSupers(@NotNull DataOutput out, IndexTree.ClassDecl value, boolean interned) throws IOException { DataInputOutputUtil.writeINT(out, value.mySupers.length); - for (int[] aSuper : value.mySupers) { - writeQualifiedName(out, aSuper); + for (String aSuper : value.mySupers) { + writeSuperName(out, interned, aSuper); } } @@ -158,16 +157,24 @@ private static void writeSupers(@NotNull DataOutput out, IndexTree.ClassDecl val return superNames; } + private static void writeSuperName(@NotNull DataOutput out, boolean interned, String aSuper) throws IOException { + if (interned) { + out.writeInt(NameEnvironment.fromString(aSuper)); + } else { + writeNameComponents(out, aSuper); + } + } + private static QualifiedName readSuperName(UnitInputStream in, boolean intern) throws IOException { - return intern ? new QualifiedName.Interned(in.names.readQualifiedName(in)) : readNameComponents(in); + return intern ? new QualifiedName.Interned(in.readInt()) : readNameComponents(in); } // members - private static void writeMembers(@NotNull DataOutput out, IndexTree.Decl[] decls) throws IOException { + private static void writeMembers(@NotNull DataOutput out, IndexTree.Decl[] decls, boolean compiled) throws IOException { DataInputOutputUtil.writeINT(out, decls.length); for (IndexTree.Decl def : decls) { - saveDecl(out, def); + saveDecl(out, def, compiled); } } @@ -187,13 +194,13 @@ private static void readMembers(UnitInputStream in, // decl: class or member - private static void saveDecl(@NotNull DataOutput out, IndexTree.Decl value) throws IOException { + private static void saveDecl(@NotNull DataOutput out, IndexTree.Decl value, boolean compiled) throws IOException { if (value instanceof IndexTree.ClassDecl) { out.writeBoolean(true); - saveClassDecl(out, (IndexTree.ClassDecl)value); + saveClassDecl(out, (IndexTree.ClassDecl)value, compiled); } else if (value instanceof IndexTree.MemberDecl) { out.writeBoolean(false); - writeMembers(out, ((IndexTree.MemberDecl)value).myDecls); + writeMembers(out, ((IndexTree.MemberDecl)value).myDecls, compiled); } } @@ -225,12 +232,10 @@ public int hashCode() { class UnitInputStream extends DataInputStream { final int fileId; final StubEnter stubEnter; - final NameEnvironment names; UnitInputStream(InputStream in, int fileId, StubEnter stubEnter) { super(in); this.fileId = fileId; this.stubEnter = stubEnter; - this.names = stubEnter.myNameEnvironment; } } diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubEnter.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubEnter.java index cc4cc55a2d7cb..2bd07184d4b81 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubEnter.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubEnter.java @@ -29,7 +29,6 @@ import static com.intellij.psi.stubsHierarchy.impl.Symbol.PackageSymbol; public class StubEnter { - final NameEnvironment myNameEnvironment; final Imports imports = new Imports(); private final Symbols mySymbols; private final StubHierarchyConnector myStubHierarchyConnector; @@ -37,9 +36,8 @@ public class StubEnter { private ArrayList uncompleted = new ArrayList(); StubEnter(Symbols symbols) { - myNameEnvironment = symbols.myNameEnvironment; mySymbols = symbols; - myStubHierarchyConnector = new StubHierarchyConnector(myNameEnvironment, symbols); + myStubHierarchyConnector = new StubHierarchyConnector(symbols); } PackageSymbol readPackageName(DataInput in) throws IOException { @@ -48,7 +46,7 @@ PackageSymbol readPackageName(DataInput in) throws IOException { int len = DataInputOutputUtil.readINT(in); for (int i = 0; i < len; i++) { int shortName = in.readInt(); - qname = myNameEnvironment.qualifiedName(qname, shortName); + qname = NameEnvironment.qualifiedName(qname, shortName); pkg = mySymbols.enterPackage(qname, shortName, pkg); } return pkg; @@ -75,13 +73,13 @@ ClassSymbol classEnter(UnitInfo info, @CompactArray(QualifiedName.class) Object handleSpecialSupers(int flags, @CompactArray(QualifiedName.class) Object superNames) { if (BitUtil.isSet(flags, IndexTree.ANNOTATION)) { - return myNameEnvironment.java_lang_annotation_Annotation; + return NameEnvironment.java_lang_annotation_Annotation; } if (BitUtil.isSet(flags, IndexTree.ENUM)) { - if (superNames == null) return myNameEnvironment.java_lang_Enum; - if (superNames instanceof QualifiedName) return new QualifiedName[]{(QualifiedName)superNames, myNameEnvironment.java_lang_Enum}; - return ArrayUtil.append((QualifiedName[])superNames, myNameEnvironment.java_lang_Enum); + if (superNames == null) return NameEnvironment.java_lang_Enum; + if (superNames instanceof QualifiedName) return new QualifiedName[]{(QualifiedName)superNames, NameEnvironment.java_lang_Enum}; + return ArrayUtil.append((QualifiedName[])superNames, NameEnvironment.java_lang_Enum); } return superNames; diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubHierarchyConnector.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubHierarchyConnector.java index 8d8112ddec82f..5a3c1f58c85a4 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubHierarchyConnector.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubHierarchyConnector.java @@ -21,11 +21,9 @@ import java.util.Set; public class StubHierarchyConnector { - private final NameEnvironment myNameEnvironment; private final StubResolver myResolve; - protected StubHierarchyConnector(NameEnvironment nameEnvironment, Symbols symbols) { - this.myNameEnvironment = nameEnvironment; + protected StubHierarchyConnector(Symbols symbols) { myResolve = new StubResolver(symbols, this); } @@ -67,9 +65,9 @@ void connect(Symbol sym) { c.setSupers(supertypes); } - private boolean isJavaLangObject(Symbol s) { + private static boolean isJavaLangObject(Symbol s) { return s.myShortName == NameEnvironment.OBJECT_NAME && s.myOwner instanceof Symbol.PackageSymbol && - ((Symbol.PackageSymbol)s.myOwner).myQualifiedName == myNameEnvironment.java_lang; + ((Symbol.PackageSymbol)s.myOwner).myQualifiedName == NameEnvironment.java_lang; } } diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubHierarchyIndex.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubHierarchyIndex.java index 1e94cad878a35..e6019223e13ba 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubHierarchyIndex.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubHierarchyIndex.java @@ -96,7 +96,7 @@ public SerializedUnit read(@NotNull DataInput in) throws IOException { @Override public int getVersion() { - return IndexTree.STUB_HIERARCHY_ENABLED ? 7 + Arrays.stream(ourIndexers).mapToInt(StubHierarchyIndexer::getVersion).sum() : 0; + return IndexTree.STUB_HIERARCHY_ENABLED ? 8 + Arrays.stream(ourIndexers).mapToInt(StubHierarchyIndexer::getVersion).sum() : 0; } @NotNull diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubResolver.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubResolver.java index 9e3c7520d0320..0375ce909ff63 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubResolver.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubResolver.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.stubsHierarchy.impl; +import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,16 +25,35 @@ import java.util.Set; public class StubResolver { + private static final Import[] DEFAULT_JAVA_IMPORTS = {importPackage("java.lang")}; + private static final Import[] DEFAULT_GROOVY_IMPORTS = { + importPackage("java.lang"), + importPackage("java.util"), + importPackage("java.io"), + importPackage("java.net"), + importPackage("groovy.lang"), + importPackage("groovy.util"), + new Import(NameEnvironment.fromString("java.math"), NameEnvironment.hashIdentifier("BigInteger"), false), + new Import(NameEnvironment.fromString("java.math"), NameEnvironment.hashIdentifier("BigDecimal"), false), + }; private final Symbols mySymbols; - private final NameEnvironment myNameEnvironment; private final StubHierarchyConnector myConnector; public StubResolver(Symbols symbols, StubHierarchyConnector connector) { this.mySymbols = symbols; - this.myNameEnvironment = symbols.myNameEnvironment; myConnector = connector; } + private static Import importPackage(String qname) { + return new Import(NameEnvironment.fromString(qname), 0, false); + } + + private static Import[] getDefaultImports(byte type) { + if (type == IndexTree.JAVA) return DEFAULT_JAVA_IMPORTS; + if (type == IndexTree.GROOVY) return DEFAULT_GROOVY_IMPORTS; + return Imports.EMPTY_ARRAY; + } + // resolve class `sym` extends/implements `baseId` Set resolveBase(Symbol.ClassSymbol sym, @ShortName int[] qname) throws IncompleteHierarchyException { Set result = resolveUnqualified(sym, qname[0], qname.length > 1); @@ -91,7 +111,7 @@ private void selectSym(Symbol receiver, @ShortName int name, boolean processPack } private void findIdentInPackage(Symbol.PackageSymbol pck, @ShortName int name, boolean processPackages, Set symbols) { - @QNameHash int fullname = mySymbols.myNameEnvironment.qualifiedName(pck.myQualifiedName, name); + @QNameHash int fullname = NameEnvironment.qualifiedName(pck.myQualifiedName, name); if (processPackages) { ContainerUtil.addIfNotNull(symbols, mySymbols.getPackage(fullname)); } @@ -132,7 +152,7 @@ public Symbol.ClassSymbol[] findGlobalType(@QNameHash int nameId) { } private void findGlobalType(UnitInfo info, @ShortName int name, Set symbols) throws IncompleteHierarchyException { - for (Import anImport : Translator.getDefaultImports(info.type, myNameEnvironment)) + for (Import anImport : getDefaultImports(info.type)) handleImport(anImport, name, symbols); for (Import anImport : info.imports) handleImport(anImport, name, symbols); @@ -157,14 +177,14 @@ public void handleImport(Import anImport, @ShortName int name, Set symbo importNamedStatic(s, anImport.importedName, symbols); } else { - Collections.addAll(symbols, findGlobalType(myNameEnvironment.qualifiedName(anImport.qualifier, anImport.importedName))); + Collections.addAll(symbols, findGlobalType(NameEnvironment.qualifiedName(anImport.qualifier, anImport.importedName))); } } } // handling of `import prefix.*` private void importAll(@QNameHash int prefix, @ShortName int suffix, final Set symbols) { - Collections.addAll(symbols, findGlobalType(myNameEnvironment.qualifiedName(prefix, suffix))); + Collections.addAll(symbols, findGlobalType(NameEnvironment.qualifiedName(prefix, suffix))); } // handling of import static `tsym.name` as diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Symbols.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Symbols.java index f74d19c06a142..beb8cd346a6ed 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Symbols.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Symbols.java @@ -12,7 +12,6 @@ public class Symbols { public final PackageSymbol myRootPackage = new PackageSymbol(null, 0, NameEnvironment.NO_NAME); - protected final NameEnvironment myNameEnvironment = new NameEnvironment(); private final AnchorRepository myClassAnchors = new AnchorRepository(); private List myClassSymbols = new ArrayList<>(0x8000); diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Translator.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Translator.java deleted file mode 100644 index 107ec71ded999..0000000000000 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Translator.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2000-2016 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.psi.stubsHierarchy.impl; - -import com.intellij.openapi.util.Key; -import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree; - -public class Translator { - private static final Key DEFAULT_JAVA_IMPORTS_KEY = Key.create("java_imports"); - private static final Key DEFAULT_GROOVY_IMPORTS_KEY = Key.create("groovy_imports"); - - private static Import[] getDefaultJavaImports(NameEnvironment nameEnvironment) { - Import[] imports = nameEnvironment.getUserData(DEFAULT_JAVA_IMPORTS_KEY); - if (imports == null) { - imports = createDefaultJavaImports(nameEnvironment); - nameEnvironment.putUserData(DEFAULT_JAVA_IMPORTS_KEY, imports); - } - return imports; - } - - private static Import[] createDefaultJavaImports(NameEnvironment nameEnvironment) { - return new Import[]{ - importPackage(nameEnvironment, "java.lang") - }; - } - - private static Import[] getDefaultGroovyImports(NameEnvironment nameEnvironment) { - Import[] imports = nameEnvironment.getUserData(DEFAULT_GROOVY_IMPORTS_KEY); - if (imports == null) { - imports = createDefaultGroovyImports(nameEnvironment); - nameEnvironment.putUserData(DEFAULT_GROOVY_IMPORTS_KEY, imports); - } - return imports; - } - - private static Import[] createDefaultGroovyImports(NameEnvironment nameEnvironment) { - return new Import[] { - importPackage(nameEnvironment, "java.lang"), - importPackage(nameEnvironment, "java.util"), - importPackage(nameEnvironment, "java.io"), - importPackage(nameEnvironment, "java.net"), - importPackage(nameEnvironment, "groovy.lang"), - importPackage(nameEnvironment, "groovy.util"), - new Import(nameEnvironment.fromString("java.math"), IndexTree.hashIdentifier("BigInteger"), false), - new Import(nameEnvironment.fromString("java.math"), IndexTree.hashIdentifier("BigDecimal"), false), - }; - } - - private static Import importPackage(NameEnvironment nameEnvironment, String qname) { - return new Import(nameEnvironment.fromString(qname), 0, false); - } - - public static Import[] getDefaultImports(byte type, NameEnvironment nameEnvironment) { - if (type == IndexTree.JAVA) - return getDefaultJavaImports(nameEnvironment); - if (type == IndexTree.GROOVY) - return getDefaultGroovyImports(nameEnvironment); - return Imports.EMPTY_ARRAY; - } - -} diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/annotations.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/annotations.java index 9727110a24115..f2c613e57a78c 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/annotations.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/annotations.java @@ -15,8 +15,6 @@ */ package com.intellij.psi.stubsHierarchy.impl; -import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -43,7 +41,7 @@ @interface QNameHash { } /** - * int hash of a qualified name part, produced by {@link IndexTree#hashIdentifier(String)} + * int hash of a qualified name part, produced by {@link NameEnvironment#hashIdentifier(String)} */ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE_USE) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MisspelledCompareToInspection.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/FunctionalExpressionStub.java similarity index 52% rename from plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MisspelledCompareToInspection.java rename to java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/FunctionalExpressionStub.java index d56c8d46959a9..b926e4631d3f6 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MisspelledCompareToInspection.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/FunctionalExpressionStub.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2000-2016 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,16 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.siyeh.ig.bugs; +package com.intellij.psi.impl.java.stubs; -import com.siyeh.HardcodedMethodConstants; -import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.fixes.RenameFix; +import com.intellij.psi.PsiFunctionalExpression; +import com.intellij.psi.stubs.IStubElementType; +import com.intellij.psi.stubs.StubBase; +import com.intellij.psi.stubs.StubElement; -public class MisspelledCompareToInspection extends MisspelledCompareToInspectionBase { - - @Override - protected InspectionGadgetsFix buildFix(Object... infos) { - return new RenameFix(HardcodedMethodConstants.COMPARE_TO); +public class FunctionalExpressionStub extends StubBase { + protected FunctionalExpressionStub(StubElement parent, + IStubElementType elementType) { + super(parent, elementType); } } \ No newline at end of file diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaStubElementTypes.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaStubElementTypes.java index 03591f90e27e7..981e99112707c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaStubElementTypes.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaStubElementTypes.java @@ -30,6 +30,8 @@ public interface JavaStubElementTypes { JavaAnnotationParameterListType ANNOTATION_PARAMETER_LIST = new JavaAnnotationParameterListType(); JavaNameValuePairType NAME_VALUE_PAIR = new JavaNameValuePairType(); JavaLiteralExpressionElementType LITERAL_EXPRESSION = new JavaLiteralExpressionElementType(); + LambdaExpressionElementType LAMBDA_EXPRESSION = new LambdaExpressionElementType(); + MethodReferenceElementType METHOD_REFERENCE = new MethodReferenceElementType(); JavaParameterListElementType PARAMETER_LIST = new JavaParameterListElementType(); JavaParameterElementType PARAMETER = new JavaParameterElementType(); JavaTypeParameterElementType TYPE_PARAMETER = new JavaTypeParameterElementType(); @@ -135,4 +137,4 @@ public ASTNode createCompositeNode() { }; IStubFileElementType JAVA_FILE = new JavaFileElementType(); -} \ No newline at end of file +} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/LambdaExpressionElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/LambdaExpressionElementType.java new file mode 100644 index 0000000000000..8cab424d6e5d9 --- /dev/null +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/LambdaExpressionElementType.java @@ -0,0 +1,97 @@ +/* + * Copyright 2000-2016 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.psi.impl.java.stubs; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.LighterAST; +import com.intellij.lang.LighterASTNode; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiLambdaExpression; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.impl.source.tree.java.PsiLambdaExpressionImpl; +import com.intellij.psi.impl.source.tree.java.ReplaceExpressionUtil; +import com.intellij.psi.stubs.*; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +public class LambdaExpressionElementType extends JavaStubElementType,PsiLambdaExpression> { + public LambdaExpressionElementType() { + super("LAMBDA_EXPRESSION"); + } + + @Override + public PsiLambdaExpression createPsi(@NotNull ASTNode node) { + return new PsiLambdaExpressionImpl(node); + } + + @Override + public FunctionalExpressionStub createStub(LighterAST tree, LighterASTNode node, StubElement parentStub) { + return new FunctionalExpressionStub(parentStub, this); + } + + @Override + public PsiLambdaExpression createPsi(@NotNull FunctionalExpressionStub stub) { + return new PsiLambdaExpressionImpl(stub); + } + + @Override + public void serialize(@NotNull FunctionalExpressionStub stub, @NotNull StubOutputStream dataStream) throws IOException { + } + + @NotNull + @Override + public FunctionalExpressionStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException { + return new FunctionalExpressionStub(parentStub, this); + } + + @Override + public void indexStub(@NotNull FunctionalExpressionStub stub, @NotNull IndexSink sink) { + } + + @NotNull + @Override + public ASTNode createCompositeNode() { + return new CompositeElement(this) { + @Override + public void replaceChildInternal(@NotNull ASTNode child, @NotNull TreeElement newElement) { + if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType()) && + ElementType.EXPRESSION_BIT_SET.contains(newElement.getElementType())) { + boolean needParenth = ReplaceExpressionUtil.isNeedParenthesis(child, newElement); + if (needParenth) { + newElement = JavaSourceUtil.addParenthToReplacedChild(JavaElementType.PARENTH_EXPRESSION, newElement, getManager()); + } + } + super.replaceChildInternal(child, newElement); + } + + @Override + public int getChildRole(ASTNode child) { + final IElementType elType = child.getElementType(); + if (elType == JavaTokenType.ARROW) { + return ChildRole.ARROW; + } else if (elType == JavaElementType.PARAMETER_LIST) { + return ChildRole.PARAMETER_LIST; + } else if (elType == JavaElementType.CODE_BLOCK) { + return ChildRole.LBRACE; + } else { + return ChildRole.EXPRESSION; + } + } + }; + } +} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/MethodReferenceElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/MethodReferenceElementType.java new file mode 100644 index 0000000000000..41cb46f0236cf --- /dev/null +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/MethodReferenceElementType.java @@ -0,0 +1,99 @@ +/* + * Copyright 2000-2016 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.psi.impl.java.stubs; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.LighterAST; +import com.intellij.lang.LighterASTNode; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiMethodReferenceExpression; +import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.impl.source.tree.java.PsiMethodReferenceExpressionImpl; +import com.intellij.psi.impl.source.tree.java.ReplaceExpressionUtil; +import com.intellij.psi.stubs.*; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +public class MethodReferenceElementType extends + JavaStubElementType, PsiMethodReferenceExpression> { + public MethodReferenceElementType() { + super("METHOD_REF_EXPRESSION"); + } + + @Override + public PsiMethodReferenceExpression createPsi(@NotNull ASTNode node) { + return new PsiMethodReferenceExpressionImpl(node); + } + + @Override + public FunctionalExpressionStub createStub(LighterAST tree, LighterASTNode node, StubElement parentStub) { + return new FunctionalExpressionStub(parentStub, this); + } + + @Override + public PsiMethodReferenceExpression createPsi(@NotNull FunctionalExpressionStub stub) { + return new PsiMethodReferenceExpressionImpl(stub); + } + + @Override + public void serialize(@NotNull FunctionalExpressionStub stub, @NotNull StubOutputStream dataStream) throws IOException { + } + + @NotNull + @Override + public FunctionalExpressionStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException { + return new FunctionalExpressionStub(parentStub, this); + } + + @Override + public void indexStub(@NotNull FunctionalExpressionStub stub, @NotNull IndexSink sink) { + } + + @NotNull + @Override + public ASTNode createCompositeNode() { + return new CompositeElement(this) { + @Override + public void replaceChildInternal(@NotNull ASTNode child, @NotNull TreeElement newElement) { + if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType()) && + ElementType.EXPRESSION_BIT_SET.contains(newElement.getElementType())) { + boolean needParenth = ReplaceExpressionUtil.isNeedParenthesis(child, newElement); + if (needParenth) { + newElement = JavaSourceUtil.addParenthToReplacedChild(JavaElementType.PARENTH_EXPRESSION, newElement, getManager()); + } + } + super.replaceChildInternal(child, newElement); + } + + + @Override + public int getChildRole(ASTNode child) { + final IElementType elType = child.getElementType(); + if (elType == JavaTokenType.DOUBLE_COLON) { + return ChildRole.DOUBLE_COLON; + } else if (elType == JavaTokenType.IDENTIFIER) { + return ChildRole.REFERENCE_NAME; + } else if (elType == JavaElementType.REFERENCE_EXPRESSION) { + return ChildRole.CLASS_REFERENCE; + } + return ChildRole.EXPRESSION; + } + + }; + } +} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/hierarchy/IndexTree.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/hierarchy/IndexTree.java index 2ac4457938822..708b7e609b874 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/hierarchy/IndexTree.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/hierarchy/IndexTree.java @@ -18,14 +18,9 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiNameHelper; -import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; -import java.util.List; - public class IndexTree { public static final boolean STUB_HIERARCHY_ENABLED = Registry.is("java.hierarchy.service"); @@ -41,123 +36,37 @@ public class IndexTree { public static final byte JAVA = 1; public static final byte GROOVY = 2; - public static int hashIdentifier(@Nullable String s) { - if (StringUtil.isEmpty(s)) return 0; - - // not using String.hashCode because this way there's less collisions for short package names like 'com' - int hash = 0; - for (int i = 0; i < s.length(); i++) { - hash = hash * 239 + s.charAt(i); - } - return hash == 0 ? 1 : hash; - } - - public static int[] hashQualifiedName(@NotNull String qName) { - qName = PsiNameHelper.getQualifiedClassName(qName, true); - if (qName.isEmpty()) return ArrayUtil.EMPTY_INT_ARRAY; - - List components = StringUtil.split(qName, "."); - int[] result = new int[components.size()]; - for (int i = 0; i < components.size(); i++) { - result[i] = hashIdentifier(components.get(i)); - } - return result; - } - - private static int[][] hashQualifiedNameArray(String[] supers) { - int[][] superHashes = new int[supers.length][]; - for (int i = 0; i < supers.length; i++) { - superHashes[i] = hashQualifiedName(supers[i]); - } - return superHashes; - } - public static class Unit { - @NotNull public final int[] myPackageName; + @NotNull public final String myPackageName; public final byte myUnitType; public final Import[] imports; public final ClassDecl[] myDecls; public Unit(@Nullable String packageName, byte unitType, Import[] imports, ClassDecl[] decls) { - this(hashQualifiedName(StringUtil.notNullize(packageName)), unitType, imports, decls); - } - - public Unit(@NotNull int[] packageName, byte unitType, Import[] imports, ClassDecl[] decls) { - myPackageName = packageName; + myPackageName = StringUtil.notNullize(packageName); myUnitType = unitType; this.imports = imports; myDecls = decls; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Unit unit = (Unit)o; - - if (myUnitType != unit.myUnitType) return false; - if (!Arrays.equals(myPackageName, unit.myPackageName)) return false; - if (!Arrays.equals(imports, unit.imports)) return false; - if (!Arrays.equals(myDecls, unit.myDecls)) return false; - - return true; - } - - @Override - public int hashCode() { - int hash = myUnitType * 31 + Arrays.hashCode(myPackageName); - for (ClassDecl decl : myDecls) { - int name = decl.myName; - if (name != 0) { - return hash * 31 + name; - } - } - return hash; - } } public static class Import { public static final Import[] EMPTY_ARRAY = new Import[0]; - public final int[] myFullname; + @NotNull public final String myQualifier; + @Nullable public final String myImportedName; public final boolean myStaticImport; public final boolean myOnDemand; - public final int myAlias; + @Nullable public final String myAlias; public Import(String fullname, boolean staticImport, boolean onDemand, @Nullable String alias) { - this(hashQualifiedName(fullname), staticImport, onDemand, hashIdentifier(alias)); - } - - public Import(int[] fullname, boolean staticImport, boolean onDemand, int alias) { - myFullname = fullname; + myQualifier = onDemand ? fullname : StringUtil.getPackageName(fullname); + myImportedName = onDemand ? null : StringUtil.getShortName(fullname); myStaticImport = staticImport; myOnDemand = onDemand; myAlias = alias; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Import anImport = (Import)o; - - if (myStaticImport != anImport.myStaticImport) return false; - if (myOnDemand != anImport.myOnDemand) return false; - if (!Arrays.equals(myFullname, anImport.myFullname)) return false; - if (myAlias != anImport.myAlias) return false; - - return true; - } - - @Override - public int hashCode() { - int result = Arrays.hashCode(myFullname); - result = 31 * result + (myStaticImport ? 1 : 0); - result = 31 * result + (myOnDemand ? 1 : 0); - result = 31 * result + myAlias; - return result; - } } public static abstract class Decl { @@ -173,14 +82,10 @@ public static class ClassDecl extends Decl { public static final ClassDecl[] EMPTY_ARRAY = new ClassDecl[0]; public final int myStubId; public final int myMods; - public final int myName; - public final int[][] mySupers; + public final String myName; + public final String[] mySupers; public ClassDecl(int stubId, int mods, @Nullable String name, String[] supers, Decl[] decls) { - this(stubId, mods, hashIdentifier(name), hashQualifiedNameArray(supers), decls); - } - - public ClassDecl(int stubId, int mods, int name, int[][] supers, Decl[] decls) { super(decls); assert stubId > 0; myStubId = stubId; @@ -189,27 +94,6 @@ public ClassDecl(int stubId, int mods, int name, int[][] supers, Decl[] decls) { mySupers = supers; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ClassDecl classDecl = (ClassDecl)o; - if (myStubId != classDecl.myStubId) return false; - if (myMods != classDecl.myMods) return false; - if (myName != classDecl.myName) return false; - if (!Arrays.deepEquals(mySupers, classDecl.mySupers)) return false; - if (!Arrays.equals(myDecls, classDecl.myDecls)) return false; - return true; - } - - @Override - public int hashCode() { - int result = myStubId; - result = 31 * result + myMods; - result = 31 * result + myName; - return result; - } } public static class MemberDecl extends Decl { @@ -218,19 +102,6 @@ public MemberDecl(Decl[] decls) { super(decls); } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - MemberDecl that = (MemberDecl)o; - if (!Arrays.equals(myDecls, that.myDecls)) return false; - return true; - } - - @Override - public int hashCode() { - return Arrays.hashCode(myDecls); - } } } 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 324c86edf580f..85fbce060fb70 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 @@ -38,7 +38,7 @@ * @author max */ public class JavaFileElementType extends ILightStubFileElementType { - public static final int STUB_VERSION = 26; + public static final int STUB_VERSION = 27; public JavaFileElementType() { super("java.FILE", JavaLanguage.INSTANCE); @@ -111,4 +111,4 @@ public PsiJavaFileStub deserialize(@NotNull StubInputStream dataStream, StubElem @Override @SuppressWarnings("LambdaUnfriendlyMethodOverload") public void indexStub(@NotNull PsiJavaFileStub stub, @NotNull IndexSink sink) { } -} \ No newline at end of file +} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaLightStubBuilder.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaLightStubBuilder.java index 3f6b9309f86c1..b13629f0ac2c1 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaLightStubBuilder.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaLightStubBuilder.java @@ -103,7 +103,8 @@ private static boolean checkByTypes(IElementType parentType, IElementType nodeTy private static class CodeBlockVisitor extends RecursiveTreeElementWalkingVisitor implements LighterLazyParseableNode.Visitor { private static final TokenSet BLOCK_ELEMENTS = TokenSet.create( - JavaElementType.ANNOTATION, JavaElementType.CLASS, JavaElementType.ANONYMOUS_CLASS); + JavaElementType.ANNOTATION, JavaElementType.CLASS, JavaElementType.ANONYMOUS_CLASS, + JavaElementType.LAMBDA_EXPRESSION, JavaElementType.METHOD_REF_EXPRESSION); private boolean result = true; @@ -127,8 +128,8 @@ public boolean visit(IElementType type) { return true; } - // annotations - if (type == JavaTokenType.AT) { + // annotations, method refs & lambdas + if (type == JavaTokenType.AT || type == JavaTokenType.ARROW || type == JavaTokenType.DOUBLE_COLON) { return (result = false); } // anonymous classes @@ -150,4 +151,4 @@ else if (type == JavaTokenType.CLASS_KEYWORD && last != JavaTokenType.DOT) { return true; } } -} \ No newline at end of file +} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java index cb33d967c737c..8b090449e12fc 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java @@ -557,23 +557,23 @@ private static boolean isAnonymousOrLocal(PsiClass aClass) { } @Nullable - private static PsiElement calcBasesResolveContext(PsiClass aClass, - String className, + private static PsiElement calcBasesResolveContext(PsiElement scope, + String baseClassName, boolean isInitialClass, final PsiElement defaultResolveContext) { - final PsiClassStub stub = ((PsiClassImpl)aClass).getStub(); - if (stub == null || stub.isAnonymousInQualifiedNew()) { - return aClass.getParent(); + final StubElement stub = ((StubBasedPsiElementBase)scope).getStub(); + if (stub == null || stub instanceof PsiClassStub && ((PsiClassStub)stub).isAnonymousInQualifiedNew()) { + return scope.getParent(); } - boolean isAnonOrLocal = isAnonymousOrLocal(aClass); - - if (!isAnonOrLocal) { - return isInitialClass ? defaultResolveContext : aClass; - } + if (scope instanceof PsiClass) { + if (!isAnonymousOrLocal((PsiClass)scope)) { + return isInitialClass ? defaultResolveContext : scope; + } - if (!isInitialClass) { - if (aClass.findInnerClassByName(className, true) != null) return aClass; + if (!isInitialClass) { + if (((PsiClass)scope).findInnerClassByName(baseClassName, true) != null) return scope; + } } final StubElement parentStub = stub.getParentStub(); @@ -582,43 +582,38 @@ private static PsiElement calcBasesResolveContext(PsiClass aClass, LOG.error(stub + " parent is " + parentStub); return null; } - final StubBasedPsiElementBase context = (StubBasedPsiElementBase)psi; - @SuppressWarnings("unchecked") - PsiClass[] classesInScope = (PsiClass[])parentStub.getChildrenByType(Constants.CLASS_BIT_SET, PsiClass.ARRAY_FACTORY); - boolean needPreciseContext = false; - if (classesInScope.length > 1) { - for (PsiClass scopeClass : classesInScope) { - if (scopeClass == aClass) continue; - String className1 = scopeClass.getName(); - if (className.equals(className1)) { - needPreciseContext = true; - break; - } - } - } - else { - if (classesInScope.length != 1) { - LOG.error("Parent stub: " + parentStub.getStubType() + "; children: " + parentStub.getChildrenStubs() + "; \ntext:" + context.getText()); - } - LOG.assertTrue(classesInScope[0] == aClass); + if (hasChildClassStub(parentStub, baseClassName, scope)) { + return scope.getParent(); } - if (needPreciseContext) { - return aClass.getParent(); + if (psi instanceof PsiClass || psi instanceof PsiLambdaExpression) { + return calcBasesResolveContext(psi, baseClassName, false, defaultResolveContext); } - else { - if (context instanceof PsiClass) { - return calcBasesResolveContext((PsiClass)context, className, false, defaultResolveContext); - } - else if (context instanceof PsiMember) { - return calcBasesResolveContext(((PsiMember)context).getContainingClass(), className, false, defaultResolveContext); + if (psi instanceof PsiMember) { + return calcBasesResolveContext(((PsiMember)psi).getContainingClass(), baseClassName, false, defaultResolveContext); + } + LOG.error(parentStub); + return psi; + } + + private static boolean hasChildClassStub(StubElement parentStub, String className, PsiElement place) { + PsiClass[] classesInScope = (PsiClass[])parentStub.getChildrenByType(Constants.CLASS_BIT_SET, PsiClass.ARRAY_FACTORY); + + for (PsiClass scopeClass : classesInScope) { + if (scopeClass == place) continue; + if (className.equals(scopeClass.getName())) { + return true; } - else { - LOG.assertTrue(false); - return context; + } + + if (place instanceof PsiClass) { + if (classesInScope.length == 0) { + LOG.error("Parent stub: " + parentStub.getStubType() + "; children: " + parentStub.getChildrenStubs() + "; \ntext:" + parentStub.getPsi().getText()); } + LOG.assertTrue(Arrays.asList(classesInScope).contains(place)); } + return false; } @Override diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java index f1e0f2e083ca8..89497290f92db 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java @@ -84,6 +84,8 @@ public ASTNode createCompositeNode() { IElementType EXTENDS_BOUND_LIST = JavaStubElementTypes.EXTENDS_BOUND_LIST; IElementType THROWS_LIST = JavaStubElementTypes.THROWS_LIST; IElementType MODULE = JavaStubElementTypes.MODULE; + IElementType LAMBDA_EXPRESSION = JavaStubElementTypes.LAMBDA_EXPRESSION; + IElementType METHOD_REF_EXPRESSION = JavaStubElementTypes.METHOD_REFERENCE; IElementType IMPORT_STATIC_REFERENCE = new JavaCompositeElementType("IMPORT_STATIC_REFERENCE", PsiImportStaticReferenceElementImpl.class); IElementType TYPE = new JavaCompositeElementType("TYPE", PsiTypeElementImpl.class); @@ -110,8 +112,6 @@ public ASTNode createCompositeNode() { IElementType INSTANCE_OF_EXPRESSION = new JavaCompositeElementType("INSTANCE_OF_EXPRESSION", PsiInstanceOfExpressionImpl.class); IElementType CLASS_OBJECT_ACCESS_EXPRESSION = new JavaCompositeElementType("CLASS_OBJECT_ACCESS_EXPRESSION", PsiClassObjectAccessExpressionImpl.class); IElementType EMPTY_EXPRESSION = new JavaCompositeElementType("EMPTY_EXPRESSION", PsiEmptyExpressionImpl.class, true); - IElementType METHOD_REF_EXPRESSION = new JavaCompositeElementType("METHOD_REF_EXPRESSION", PsiMethodReferenceExpressionImpl.class); - IElementType LAMBDA_EXPRESSION = new JavaCompositeElementType("LAMBDA_EXPRESSION", PsiLambdaExpressionImpl.class); IElementType EXPRESSION_LIST = new JavaCompositeElementType("EXPRESSION_LIST", PsiExpressionListImpl.class, true); IElementType EMPTY_STATEMENT = new JavaCompositeElementType("EMPTY_STATEMENT", PsiEmptyStatementImpl.class); IElementType BLOCK_STATEMENT = new JavaCompositeElementType("BLOCK_STATEMENT", PsiBlockStatementImpl.class); @@ -294,4 +294,4 @@ public ASTNode parseContents(final ASTNode chameleon) { } } IElementType DUMMY_ELEMENT = new JavaDummyElementType(); -} \ No newline at end of file +} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java index cdb71a7419e2f..649a0a63f05da 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java @@ -21,13 +21,13 @@ import com.intellij.psi.*; import com.intellij.psi.controlFlow.*; import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.java.stubs.FunctionalExpressionStub; +import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; +import com.intellij.psi.impl.source.JavaStubPsiElement; import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil; import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession; -import com.intellij.psi.impl.source.tree.ChildRole; -import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.scope.PsiScopeProcessor; -import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; @@ -36,7 +36,8 @@ import javax.swing.*; import java.util.Map; -public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements PsiLambdaExpression { +public class PsiLambdaExpressionImpl extends JavaStubPsiElement> + implements PsiLambdaExpression { private static final ControlFlowPolicy ourPolicy = new ControlFlowPolicy() { @Nullable @@ -56,8 +57,12 @@ public boolean isLocalVariableAccepted(@NotNull PsiLocalVariable psiVariable) { } }; - public PsiLambdaExpressionImpl() { - super(JavaElementType.LAMBDA_EXPRESSION); + public PsiLambdaExpressionImpl(@NotNull FunctionalExpressionStub stub) { + super(stub, JavaStubElementTypes.LAMBDA_EXPRESSION); + } + + public PsiLambdaExpressionImpl(@NotNull ASTNode node) { + super(node); } @NotNull @@ -67,17 +72,8 @@ public PsiParameterList getParameterList() { } @Override - public int getChildRole(ASTNode child) { - final IElementType elType = child.getElementType(); - if (elType == JavaTokenType.ARROW) { - return ChildRole.ARROW; - } else if (elType == JavaElementType.PARAMETER_LIST) { - return ChildRole.PARAMETER_LIST; - } else if (elType == JavaElementType.CODE_BLOCK) { - return ChildRole.LBRACE; - } else { - return ChildRole.EXPRESSION; - } + public PsiElement getParent() { + return getParentByTree(); } @Override diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java index fe910bde5fb6b..1967a50f68ff4 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java @@ -24,6 +24,7 @@ import com.intellij.psi.impl.ResolveScopeManager; import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; import com.intellij.psi.impl.java.stubs.impl.PsiLiteralStub; +import com.intellij.psi.impl.source.JavaStubPsiElement; import com.intellij.psi.impl.source.tree.CompositeElement; import com.intellij.psi.impl.source.tree.LeafElement; import com.intellij.psi.impl.source.tree.injected.StringLiteralEscaper; @@ -38,7 +39,7 @@ import java.util.Locale; public class PsiLiteralExpressionImpl - extends StubBasedPsiElementBase + extends JavaStubPsiElement implements PsiLiteralExpression, PsiLanguageInjectionHost, ContributedReferenceHost { @NonNls private static final String QUOT = """; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java index ce572483c1998..1ab3723edb458 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java @@ -23,10 +23,12 @@ import com.intellij.psi.*; import com.intellij.psi.impl.CheckUtil; import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.java.stubs.FunctionalExpressionStub; +import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; +import com.intellij.psi.impl.source.JavaStubPsiElement; import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil; import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession; import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil; -import com.intellij.psi.impl.source.tree.ChildRole; import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.scope.ElementClassFilter; @@ -35,8 +37,8 @@ import com.intellij.psi.scope.conflictResolvers.DuplicateConflictResolver; import com.intellij.psi.scope.processor.FilterScopeProcessor; import com.intellij.psi.scope.util.PsiScopesUtil; -import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.*; +import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -45,15 +47,25 @@ import javax.swing.*; import java.util.*; -public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase implements PsiMethodReferenceExpression { +public class PsiMethodReferenceExpressionImpl extends JavaStubPsiElement> + implements PsiMethodReferenceExpression { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiMethodReferenceExpressionImpl"); private static final MethodReferenceResolver RESOLVER = new MethodReferenceResolver(); - public PsiMethodReferenceExpressionImpl() { - super(JavaElementType.METHOD_REF_EXPRESSION); + public PsiMethodReferenceExpressionImpl(@NotNull FunctionalExpressionStub stub) { + super(stub, JavaStubElementTypes.METHOD_REFERENCE); + } + + public PsiMethodReferenceExpressionImpl(@NotNull ASTNode node) { + super(node); } + @Override + public PsiElement getParent() { + return getParentByTree(); + } + @Override public PsiTypeElement getQualifierType() { final PsiElement qualifier = getQualifier(); @@ -284,19 +296,6 @@ public void setQualifierExpression(@Nullable PsiExpression newQualifier) throws } } - @Override - public int getChildRole(ASTNode child) { - final IElementType elType = child.getElementType(); - if (elType == JavaTokenType.DOUBLE_COLON) { - return ChildRole.DOUBLE_COLON; - } else if (elType == JavaTokenType.IDENTIFIER) { - return ChildRole.REFERENCE_NAME; - } else if (elType == JavaElementType.REFERENCE_EXPRESSION) { - return ChildRole.CLASS_REFERENCE; - } - return ChildRole.EXPRESSION; - } - @NotNull @Override public JavaResolveResult[] multiResolve(boolean incompleteCode) { @@ -316,7 +315,7 @@ public TextRange getRangeInElement() { final int offsetInParent = element.getStartOffsetInParent(); return new TextRange(offsetInParent, offsetInParent + element.getTextLength()); } - final PsiElement colons = findPsiChildByType(JavaTokenType.DOUBLE_COLON); + final PsiElement colons = findChildByType(JavaTokenType.DOUBLE_COLON); if (colons != null) { final int offsetInParent = colons.getStartOffsetInParent(); return new TextRange(offsetInParent, offsetInParent + colons.getTextLength()); @@ -375,9 +374,9 @@ else if (element instanceof PsiClass) { @Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { - PsiElement oldIdentifier = findChildByRoleAsPsiElement(ChildRole.REFERENCE_NAME); + PsiElement oldIdentifier = findChildByType(JavaTokenType.IDENTIFIER); if (oldIdentifier == null) { - oldIdentifier = findChildByRoleAsPsiElement(ChildRole.CLASS_REFERENCE); + oldIdentifier = findChildByType(JavaElementType.REFERENCE_EXPRESSION); } if (oldIdentifier == null) { throw new IncorrectOperationException(); @@ -478,4 +477,72 @@ public boolean isAcceptable(PsiType left) { public Icon getIcon(int flags) { return AllIcons.Nodes.MethodReference; } + + @Override + public PsiElement bindToElementViaStaticImport(@NotNull final PsiClass qualifierClass) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + @Override + public PsiElement getElement() { + return this; + } + + @Override + public PsiElement resolve() { + return advancedResolve(false).getElement(); + } + + @NotNull + @Override + public Object[] getVariants() { + // this reference's variants are rather obtained with processVariants() + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + + @Override + public boolean isSoft() { + return false; + } + + @Override + public PsiReference getReference() { + return this; + } + + @NotNull + @Override + public JavaResolveResult advancedResolve(boolean incompleteCode) { + final JavaResolveResult[] results = multiResolve(incompleteCode); + return results.length == 1 ? results[0] : JavaResolveResult.EMPTY; + } + + @Override + public String getReferenceName() { + final PsiElement element = getReferenceNameElement(); + return element != null ? element.getText() : null; + } + + @Override + public PsiReferenceParameterList getParameterList() { + return PsiTreeUtil.getChildOfType(this, PsiReferenceParameterList.class); + } + + @NotNull + @Override + public PsiType[] getTypeParameters() { + final PsiReferenceParameterList parameterList = getParameterList(); + return parameterList != null ? parameterList.getTypeArguments() : PsiType.EMPTY_ARRAY; + } + + @Override + public boolean isQualified() { + return getQualifier() != null; + } + + @Override + public String getQualifiedName() { + return getCanonicalText(); + } + } diff --git a/java/java-tests/testData/inspection/unusedMethodParameter/suppressedParameter/src/Test.java b/java/java-tests/testData/inspection/unusedMethodParameter/suppressedParameter/src/Test.java index f2b5752b9eef7..1897fa90b9206 100644 --- a/java/java-tests/testData/inspection/unusedMethodParameter/suppressedParameter/src/Test.java +++ b/java/java-tests/testData/inspection/unusedMethodParameter/suppressedParameter/src/Test.java @@ -2,4 +2,8 @@ public class Test { public void foo(@SuppressWarnings("UnusedParameters") boolean b) { } + + public void foo(@SuppressWarnings("unused") boolean b) { + + } } diff --git a/java/java-tests/testData/refactoring/inlineLocal/ParenthesisAroundCast.java b/java/java-tests/testData/refactoring/inlineLocal/ParenthesisAroundCast.java new file mode 100644 index 0000000000000..5b581ce4ce425 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineLocal/ParenthesisAroundCast.java @@ -0,0 +1,6 @@ +class Test { + { + Double d = 1.0; + d.byteValue(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineLocal/ParenthesisAroundCast.java.after b/java/java-tests/testData/refactoring/inlineLocal/ParenthesisAroundCast.java.after new file mode 100644 index 0000000000000..d210d8aa1c1aa --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineLocal/ParenthesisAroundCast.java.after @@ -0,0 +1,5 @@ +class Test { + { + ((Double) 1.0).byteValue(); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/ex/InspectionProfileTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/ex/InspectionProfileTest.java index 91a9bfa8556b2..6b049b7d6ee56 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/ex/InspectionProfileTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/ex/InspectionProfileTest.java @@ -357,6 +357,22 @@ public void testDisabledUnusedDeclarationWithoutChanges() throws Exception { ""); } + public void testMergedMisspelledInspections() throws Exception { + checkMergedNoChanges("\n" + + " "); + checkMergedNoChanges("\n" + + " "); + } + public void testDisabledUnusedDeclarationWithChanges() throws Exception { checkMergedNoChanges("\n" + "