diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaMethodParameterTypesIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaMethodParameterTypesIndex.java new file mode 100644 index 000000000000..eea3d1c1f46e --- /dev/null +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaMethodParameterTypesIndex.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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. + */ + +/* + * @author max + */ +package com.intellij.psi.impl.java.stubs.index; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.impl.search.JavaSourceFilterScope; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.stubs.StringStubIndexExtension; +import com.intellij.psi.stubs.StubIndex; +import com.intellij.psi.stubs.StubIndexKey; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public class JavaMethodParameterTypesIndex extends StringStubIndexExtension { + + private static final JavaMethodParameterTypesIndex ourInstance = new JavaMethodParameterTypesIndex(); + public static JavaMethodParameterTypesIndex getInstance() { + return ourInstance; + } + + @NotNull + @Override + public StubIndexKey getKey() { + return JavaStubIndexKeys.METHOD_TYPES; + } + + @Override + public Collection get(@NotNull final String s, @NotNull final Project project, @NotNull final GlobalSearchScope scope) { + return StubIndex.getElements(getKey(), s, project, new JavaSourceFilterScope(scope), PsiMethod.class); + } +} \ No newline at end of file diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionIndex.java new file mode 100644 index 000000000000..bff63da0e482 --- /dev/null +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionIndex.java @@ -0,0 +1,223 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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.search; + +import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.indexing.*; +import com.intellij.util.io.DataExternalizer; +import com.intellij.util.io.DataInputOutputUtil; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import org.jetbrains.annotations.NotNull; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.*; + +public class JavaFunctionalExpressionIndex extends FileBasedIndexExtension> implements PsiDependentIndex { + public static final ID> JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID = ID.create("java.functional.expression"); + private static final String THIS_REF_NAME = "this"; + private static final String SUPER_REF_NAME = "super"; + + @NotNull + @Override + public ID> getName() { + return JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID; + } + + @NotNull + @Override + public DataIndexer, FileContent> getIndexer() { + return new DataIndexer, FileContent>() { + @NotNull + @Override + public Map> map(@NotNull FileContent inputData) { + final CharSequence contentAsText = inputData.getContentAsText(); + if (!StringUtil.contains(contentAsText, "::") && !StringUtil.contains(contentAsText, "->")) { + return Collections.emptyMap(); + } + + final PsiFile file = ((FileContentImpl)inputData).getPsiFileForPsiDependentIndex(); + if (!(file instanceof PsiJavaFile) || !JavaStubElementTypes.JAVA_FILE.shouldBuildStubFor(inputData.getFile())) { + return Collections.emptyMap(); + } + + final HashMap> methodsMap = ContainerUtil.newHashMap(); + for (PsiFunctionalExpression expression : SyntaxTraverser.psiTraverser().withRoot(file).filter(PsiFunctionalExpression.class)) { + final PsiExpressionList expressionList = + PsiTreeUtil.getParentOfType(expression, PsiExpressionList.class, true, PsiStatement.class, PsiModifierListOwner.class); + if (expressionList != null) { + final PsiElement parent = expressionList.getParent(); + String methodName = null; + if (parent instanceof PsiMethodCallExpression) { + methodName = ((PsiMethodCallExpression)parent).getMethodExpression().getReferenceName(); + if (methodName != null) { + final boolean thisRef = methodName.equals(THIS_REF_NAME); + if (thisRef || methodName.equals(SUPER_REF_NAME)) { + methodName = null; + final PsiClass containingClass = PsiTreeUtil.getParentOfType(parent, PsiClass.class); + if (containingClass != null) { + if (thisRef) { + methodName = containingClass.getName(); + } else { + final PsiReferenceList extendsList = containingClass.getExtendsList(); + if (extendsList != null) { + final PsiJavaCodeReferenceElement[] referenceElements = extendsList.getReferenceElements(); + if (referenceElements.length > 0) { + methodName = referenceElements[0].getReferenceName(); + } + } + } + } + } + } + } + else if (parent instanceof PsiNewExpression) { + final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)parent).getClassOrAnonymousClassReference(); + if (classReference != null) { + methodName = classReference.getReferenceName(); + } + } + else if (parent instanceof PsiEnumConstant) { + final PsiClass containingClass = ((PsiEnumConstant)parent).getContainingClass(); + if (containingClass != null) { + final String shortEnumName = containingClass.getName(); + if (shortEnumName != null) { //should be always true as enums can't be local + methodName = shortEnumName; + } + } + } + + if (methodName != null) { + Collection holders = methodsMap.get(methodName); + if (holders == null) { + holders = new HashSet(); + methodsMap.put(methodName, holders); + } + holders.add(new IndexHolder(expression instanceof PsiLambdaExpression ? ((PsiLambdaExpression)expression).getParameterList().getParametersCount() : -1, + expressionList.getExpressions().length, + LambdaUtil.getLambdaIdx(expressionList, expression))); + } + } + } + + return methodsMap; + } + }; + } + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return EnumeratorStringDescriptor.INSTANCE; + } + + @NotNull + @Override + public DataExternalizer> getValueExternalizer() { + return new DataExternalizer>() { + @Override + public void save(@NotNull DataOutput out, Collection holders) throws IOException { + DataInputOutputUtil.writeINT(out, holders.size()); + for (IndexHolder holder : holders) { + DataInputOutputUtil.writeINT(out, holder.getLambdaParamsNumber()); + DataInputOutputUtil.writeINT(out, holder.getMethodArgsLength()); + DataInputOutputUtil.writeINT(out, holder.getFunctionExpressionIndex()); + } + } + + @Override + public Collection read(@NotNull DataInput in) throws IOException { + int l = DataInputOutputUtil.readINT(in); + final Collection holders = new HashSet(l); + while (l-- > 0) { + holders.add(new IndexHolder(DataInputOutputUtil.readINT(in), + DataInputOutputUtil.readINT(in), + DataInputOutputUtil.readINT(in))); + } + return holders; + } + }; + } + + @NotNull + @Override + public FileBasedIndex.InputFilter getInputFilter() { + return new DefaultFileTypeSpecificInputFilter(JavaFileType.INSTANCE); + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 0; + } + + public static class IndexHolder { + private final int myLambdaParamsNumber; + private final int myMethodArgsLength; + private final int myFunctionExpressionIndex; + + public IndexHolder(int lambdaParamsNumber, int methodArgsLength, int functionExpressionIndex) { + myLambdaParamsNumber = lambdaParamsNumber; + myMethodArgsLength = methodArgsLength; + myFunctionExpressionIndex = functionExpressionIndex; + } + + public int getLambdaParamsNumber() { + return myLambdaParamsNumber; + } + + public int getMethodArgsLength() { + return myMethodArgsLength; + } + + public int getFunctionExpressionIndex() { + return myFunctionExpressionIndex; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IndexHolder holder = (IndexHolder)o; + + if (myLambdaParamsNumber != holder.myLambdaParamsNumber) return false; + if (myMethodArgsLength != holder.myMethodArgsLength) return false; + if (myFunctionExpressionIndex != holder.myFunctionExpressionIndex) return false; + + return true; + } + + @Override + public int hashCode() { + int result = myLambdaParamsNumber; + result = 31 * result + myMethodArgsLength; + result = 31 * result + myFunctionExpressionIndex; + return result; + } + } +} diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java index 78be4b3d6ca4..1fdd4a44391d 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java @@ -15,8 +15,8 @@ */ package com.intellij.psi.impl.search; -import com.intellij.ide.highlighter.JavaFileType; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadActionProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; @@ -24,26 +24,28 @@ import com.intellij.openapi.module.impl.scopes.ModulesScope; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.LanguageLevelModuleExtension; import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.ProjectFileIndex; -import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; +import com.intellij.psi.impl.java.stubs.JavaMethodElementType; +import com.intellij.psi.impl.java.stubs.index.JavaMethodParameterTypesIndex; import com.intellij.psi.search.*; import com.intellij.psi.search.searches.FunctionalExpressionSearch; -import com.intellij.psi.util.InheritanceUtil; -import com.intellij.psi.util.PsiUtil; -import com.intellij.psi.util.PsiUtilCore; +import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.*; import com.intellij.util.CommonProcessors; import com.intellij.util.Function; import com.intellij.util.Processor; import com.intellij.util.QueryExecutor; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; +import com.intellij.util.indexing.FileBasedIndex; import org.jetbrains.annotations.NotNull; +import java.util.Collection; +import java.util.LinkedHashSet; import java.util.Set; public class JavaFunctionalExpressionSearcher implements QueryExecutor { @@ -86,50 +88,8 @@ public class JavaFunctionalExpressionSearcher implements QueryExecutor consumer, - final Set highLevelModules) { - final Project project = PsiUtilCore.getProjectInReadAction(aClass); - final GlobalSearchScope scope = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public GlobalSearchScope compute() { - return prepareScopeToProcessFiles(highLevelModules, aClass, searchScope, project); - } - }); - final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex(); - final HashSet files = new HashSet(); - CommonProcessors.CollectProcessor processor = new CommonProcessors.CollectProcessor(files) { - @Override - protected boolean accept(VirtualFile virtualFile) { - return scope.contains(virtualFile) && virtualFile.getFileType() == JavaFileType.INSTANCE && index.isInSource(virtualFile); - } - }; - - final PsiSearchHelperImpl helper = (PsiSearchHelperImpl)PsiSearchHelper.SERVICE.getInstance(project); - helper.processFilesWithText(scope, UsageSearchContext.IN_CODE, true, "::", processor); - helper.processFilesWithText(scope, UsageSearchContext.IN_CODE, true, "->", processor); - LOG.info("#files: " + files.size()); - - final PsiManager psiManager = PsiManager.getInstance(project); - for (final VirtualFile file : files) { - if (!ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - return processFileWithFunctionalInterfaces(aClass, consumer, psiManager, file); - } - })) return false; - } - return true; - } - @NotNull - protected static GlobalSearchScope prepareScopeToProcessFiles(final Set highLevelModules, - final PsiClass aClass, - final SearchScope searchScope, - final Project project) { - final SearchScope useScope = searchScope.intersectWith(aClass.getUseScope()); - + private static GlobalSearchScope convertToGlobalScope(Project project, SearchScope useScope) { final GlobalSearchScope scope; if (useScope instanceof GlobalSearchScope) { scope = (GlobalSearchScope)useScope; @@ -145,16 +105,162 @@ public class JavaFunctionalExpressionSearcher implements QueryExecutor consumer, + final Set highLevelModules) { + final Project project = PsiUtilCore.getProjectInReadAction(aClass); + final ModulesScope modulesScope = new ModulesScope(highLevelModules, project); + final GlobalSearchScope useScope = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public GlobalSearchScope compute() { + return modulesScope.intersectWith(convertToGlobalScope(project, searchScope.intersectWith(aClass.getUseScope()))); + } + }); + + final PsiSearchHelperImpl helper = (PsiSearchHelperImpl)PsiSearchHelper.SERVICE.getInstance(project); + final HashSet files = new HashSet(); + final CommonProcessors.CollectProcessor processor = new CommonProcessors.CollectProcessor(files); + helper.processFilesWithText(useScope, UsageSearchContext.IN_CODE, true, "::", processor); + helper.processFilesWithText(useScope, UsageSearchContext.IN_CODE, true, "->", processor); + + final GlobalSearchScope filesScope = GlobalSearchScope.filesScope(project, files); + + final Collection lambdaCandidates = ApplicationManager.getApplication().runReadAction(new Computable>() { + @Override + public Collection compute() { + final String functionalInterfaceName = aClass.getName(); + JavaMethodParameterTypesIndex parameterTypesIndex = JavaMethodParameterTypesIndex.getInstance(); + + LinkedHashSet methods = new LinkedHashSet(parameterTypesIndex.get(functionalInterfaceName, project, useScope)); + + methods.addAll(parameterTypesIndex.get(JavaMethodElementType.TYPE_PARAMETER_PSEUDO_NAME, project, + GlobalSearchScope.allScope(project))); + return methods; + } + }); + + final LinkedHashSet usageFiles = new LinkedHashSet(); + final MethodSignature functionalInterfaceMethod = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public MethodSignature compute() { + return LambdaUtil.getFunction(aClass); + } + }); + LOG.assertTrue(functionalInterfaceMethod != null); + final int expectedFunExprParamsCount = functionalInterfaceMethod.getParameterTypes().length; + final FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance(); + for (final PsiMethod psiMethod : lambdaCandidates) { + final int parametersCount = psiMethod.getParameterList().getParametersCount(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final boolean varArgs = psiMethod.isVarArgs(); + final PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); + final GlobalSearchScope methodUseScope = modulesScope.intersectWith(convertToGlobalScope(project, psiMethod.getUseScope())); + fileBasedIndex.processValues(JavaFunctionalExpressionIndex.JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID, psiMethod.getName(), null, + new FileBasedIndex.ValueProcessor>() { + @Override + public boolean process(VirtualFile file, Collection holders) { + for (JavaFunctionalExpressionIndex.IndexHolder holder : holders) { + if (holder.getLambdaParamsNumber() == expectedFunExprParamsCount && + (varArgs ? holder.getMethodArgsLength() >= parametersCount - 1 : holder.getMethodArgsLength() == parametersCount) && + canBeFunctional(holder) + ) { + usageFiles.add(file); + break; + } + } + return true; + } + + private boolean canBeFunctional(JavaFunctionalExpressionIndex.IndexHolder holder) { + final int paramIdx = holder.getFunctionExpressionIndex(); + final PsiClass functionalCandidate = PsiUtil.resolveClassInClassTypeOnly(parameters[paramIdx].getType()); + return functionalCandidate instanceof PsiTypeParameter || + LambdaUtil.isFunctionalClass(functionalCandidate); + } + }, useScope.intersectWith(methodUseScope)); + } + }); } - return new ModulesScope(highLevelModules, project).intersectWith(scope); + collectFilesWithAssignments(aClass, filesScope, usageFiles); + + LOG.info("#usage files: " + usageFiles.size()); + return ContainerUtil.process(usageFiles, new ReadActionProcessor() { + @Override + public boolean processInReadAction(VirtualFile file) { + return processFileWithFunctionalInterfaces(aClass, expectedFunExprParamsCount, consumer, file); + } + }); + } + + /** + * Collect files where: + * aClass is used, e.g. in type declaration or method return type; + * fields with type aClass are used on the left side of assignments. Should find Bar of the following example +
+    class Foo {
+        Runnable myRunnable;
+    }
+    
+    class Bar {
+      void foo(Foo foo){
+        foo.myRunnable = () -> {};
+      }
+    }
+    
+ */ + private static void collectFilesWithAssignments(PsiClass aClass, + GlobalSearchScope filesScope, + final LinkedHashSet usageFiles) { + final Set fields = new LinkedHashSet(); + for (final PsiReference reference : ReferencesSearch.search(aClass, filesScope)) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + final PsiElement element = reference.getElement(); + if (element != null) { + ContainerUtil.addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(element)); + final PsiElement parent = element.getParent(); + if (parent instanceof PsiTypeElement) { + final PsiElement gParent = parent.getParent(); + if (gParent instanceof PsiField && + !((PsiField)gParent).hasModifierProperty(PsiModifier.PRIVATE) && + !((PsiField)gParent).hasModifierProperty(PsiModifier.FINAL)) { + fields.add((PsiField)gParent); + } + } + } + } + }); + } + + for (PsiField field : fields) { + ReferencesSearch.search(field, filesScope).forEach(new ReadActionProcessor() { + @Override + public boolean processInReadAction(PsiReference fieldRef) { + final PsiElement fieldElement = fieldRef.getElement(); + final PsiAssignmentExpression varElementParent = PsiTreeUtil.getParentOfType(fieldElement, PsiAssignmentExpression.class); + if (varElementParent != null && PsiTreeUtil.isAncestor(varElementParent.getLExpression(), fieldElement, false)) { + ContainerUtil.addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(fieldElement)); + } + return true; + } + }); + } } private static boolean processFileWithFunctionalInterfaces(final PsiClass aClass, + final int expectedParamCount, final Processor consumer, - final PsiManager psiManager, VirtualFile file) { - final PsiFile psiFile = psiManager.findFile(file); + VirtualFile file) { + final PsiFile psiFile = aClass.getManager().findFile(file); if (psiFile != null) { final Ref ref = new Ref(true); psiFile.accept(new JavaRecursiveElementWalkingVisitor() { @@ -178,7 +284,9 @@ public class JavaFunctionalExpressionSearcher implements QueryExecutor { + public static final String TYPE_PARAMETER_PSEUDO_NAME = "$TYPE_PARAMETER$"; public JavaMethodElementType(@NonNls final String name) { super(name); } @@ -149,5 +150,35 @@ public abstract class JavaMethodElementType extends JavaStubElementType methodTypeParams = null; + for (StubElement stubElement : stub.getChildrenStubs()) { + if (stubElement instanceof PsiTypeParameterListStub) { + for (Object tStub : stubElement.getChildrenStubs()) { + if (tStub instanceof PsiTypeParameterStub) { + if (methodTypeParams == null) { + methodTypeParams = new HashSet(); + } + methodTypeParams.add(((PsiTypeParameterStub)tStub).getName()); + } + } + } + else if (stubElement instanceof PsiParameterListStub) { + for (StubElement paramStub : ((PsiParameterListStub)stubElement).getChildrenStubs()) { + if (paramStub instanceof PsiParameterStub) { + TypeInfo type = ((PsiParameterStub)paramStub).getType(false); + if (type.arrayCount > 0) continue; + String typeName = type.getShortTypeText(); + if (TypeConversionUtil.isPrimitive(typeName) || TypeConversionUtil.isPrimitiveWrapper(typeName)) continue; + sink.occurrence(JavaStubIndexKeys.METHOD_TYPES, typeName); + if (methodTypeParams != null && methodTypeParams.contains(typeName)) { + sink.occurrence(JavaStubIndexKeys.METHOD_TYPES, TYPE_PARAMETER_PSEUDO_NAME); + methodTypeParams = null; + } + } + } + break; + } + } } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStubIndexKeys.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStubIndexKeys.java index e8760f5f95fa..a3e247f73de8 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStubIndexKeys.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStubIndexKeys.java @@ -29,6 +29,7 @@ public class JavaStubIndexKeys { public static final StubIndexKey JVM_STATIC_MEMBERS_NAMES = StubIndexKey.createIndexKey("jvm.static.member.name"); public static final StubIndexKey JVM_STATIC_MEMBERS_TYPES = StubIndexKey.createIndexKey("jvm.static.member.type"); public static final StubIndexKey ANONYMOUS_BASEREF = StubIndexKey.createIndexKey("java.anonymous.baseref"); + public static final StubIndexKey METHOD_TYPES = StubIndexKey.createIndexKey("java.method.parameter.types"); public static final StubIndexKey CLASS_SHORT_NAMES = StubIndexKey.createIndexKey("java.class.shortname"); public static final StubIndexKey CLASS_FQN = StubIndexKey.createIndexKey("java.class.fqn"); 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 cec30eb3c8af..b09649c6d4a0 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 @@ import java.io.IOException; * @author max */ public class JavaFileElementType extends ILightStubFileElementType { - public static final int STUB_VERSION = 19; + public static final int STUB_VERSION = 20; public JavaFileElementType() { super("java.FILE", JavaLanguage.INSTANCE); diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java index 617bbaa02ef7..7d8c4be4efd9 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java @@ -91,7 +91,7 @@ public class IdIndex extends FileBasedIndexExtension { @Override public int getVersion() { - return 15 + (ourSnapshotMappingsEnabled ? 0xFF:0); // TODO: version should enumerate all word scanner versions and build version upon that set + return 16 + (ourSnapshotMappingsEnabled ? 0xFF:0); // TODO: version should enumerate all word scanner versions and build version upon that set } @Override diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 7ac69fa8d991..71ee1d40597c 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -345,6 +345,7 @@ + @@ -1461,6 +1462,7 @@ +