Merge remote-tracking branch 'origin/master'

This commit is contained in:
Andrey Vlasovskikh
2014-11-06 17:38:23 +03:00
12 changed files with 141 additions and 180 deletions
@@ -58,7 +58,9 @@ public class JavaFilterLexer extends BaseFilterLexer {
if (tokenType == JavaTokenType.IDENTIFIER
|| tokenType == JavaTokenType.LONG_LITERAL
|| tokenType == JavaTokenType.INTEGER_LITERAL
|| tokenType == JavaTokenType.CHARACTER_LITERAL) {
|| tokenType == JavaTokenType.CHARACTER_LITERAL
|| tokenType == JavaTokenType.ARROW
|| tokenType == JavaTokenType.DOUBLE_COLON) {
addOccurrenceInToken(UsageSearchContext.IN_CODE);
}
else if (tokenType == JavaTokenType.STRING_LITERAL) {
@@ -1,50 +0,0 @@
/*
* Copyright 2000-2014 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<PsiMethod> {
private static final JavaMethodParameterTypesIndex ourInstance = new JavaMethodParameterTypesIndex();
public static JavaMethodParameterTypesIndex getInstance() {
return ourInstance;
}
@NotNull
@Override
public StubIndexKey<String, PsiMethod> getKey() {
return JavaStubIndexKeys.METHOD_TYPES;
}
@Override
public Collection<PsiMethod> get(@NotNull final String s, @NotNull final Project project, @NotNull final GlobalSearchScope scope) {
return StubIndex.getElements(getKey(), s, project, new JavaSourceFilterScope(scope), PsiMethod.class);
}
}
@@ -15,37 +15,39 @@
*/
package com.intellij.psi.impl.search;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
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.EverythingGlobalScope;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.*;
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
import com.intellij.psi.search.searches.MethodReferencesSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import com.intellij.util.QueryExecutor;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
public class JavaFunctionalExpressionSearcher implements QueryExecutor<PsiFunctionalExpression, FunctionalExpressionSearch.SearchParameters> {
private static final Logger LOG = Logger.getInstance("#" + JavaFunctionalExpressionSearcher.class.getName());
@Override
public boolean execute(@NotNull final FunctionalExpressionSearch.SearchParameters queryParameters,
@NotNull final Processor<PsiFunctionalExpression> consumer) {
@@ -98,102 +100,75 @@ public class JavaFunctionalExpressionSearcher implements QueryExecutor<PsiFuncti
return searchScope.intersectWith(classScope);
}
});
final Project project = PsiUtilCore.getProjectInReadAction(aClass);
final GlobalSearchScope scope = new ModulesScope(highLevelModules, project)
.intersectWith(useScope instanceof GlobalSearchScope ? (GlobalSearchScope)useScope : new EverythingGlobalScope(project));
final Collection<PsiMethod> lambdaCandidates = ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiMethod>>() {
final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
CommonProcessors.CollectProcessor<VirtualFile> processor = new CommonProcessors.CollectProcessor<VirtualFile>() {
@Override
public Collection<PsiMethod> compute() {
final String functionalInterfaceName = aClass.getName();
final GlobalSearchScope useClassScope = classScope instanceof GlobalSearchScope ? (GlobalSearchScope)classScope : scope;
JavaMethodParameterTypesIndex parameterTypesIndex = JavaMethodParameterTypesIndex.getInstance();
LinkedHashSet<PsiMethod> methods = new LinkedHashSet<PsiMethod>(parameterTypesIndex.get(functionalInterfaceName, project, useClassScope));
methods.addAll(parameterTypesIndex.get(JavaMethodElementType.TYPE_PARAMETER_PSEUDO_NAME, project,
GlobalSearchScope.allScope(project)));
return methods;
protected boolean accept(VirtualFile virtualFile) {
return scope.contains(virtualFile) && virtualFile.getFileType() == JavaFileType.INSTANCE && index.isInSource(virtualFile);
}
});
for (PsiMethod psiMethod : lambdaCandidates) {
for (final PsiReference ref : MethodReferencesSearch.search(psiMethod, scope, false)) {
boolean accepted = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
final PsiElement refElement = ref.getElement();
if (refElement != null) {
final PsiElement candidateElement = refElement.getParent();
if (candidateElement instanceof PsiCallExpression) {
final PsiExpressionList argumentList = ((PsiCallExpression)candidateElement).getArgumentList();
if (argumentList != null) {
final PsiExpression[] args = argumentList.getExpressions();
for (PsiExpression arg : args) {
if (arg instanceof PsiFunctionalExpression) {
final PsiFunctionalExpression functionalExpression = (PsiFunctionalExpression)arg;
final PsiType functionalType = functionalExpression.getFunctionalInterfaceType();
if (PsiUtil.resolveClassInType(functionalType) == aClass) {
if (!consumer.process(functionalExpression)) return false;
}
}
}
}
}
}
return true;
}
});
if (!accepted) return false;
}
}
};
for (final PsiReference reference : ReferencesSearch.search(aClass, scope)) {
boolean accepted = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
final PsiSearchHelperImpl helper = (PsiSearchHelperImpl)PsiSearchHelper.SERVICE.getInstance(project);
helper.processFilesWithText(scope, UsageSearchContext.IN_CODE, true, "::", processor);
helper.processFilesWithText(scope, UsageSearchContext.IN_CODE, true, "->", processor);
Collection<VirtualFile> files = processor.getResults();
LOG.info("#files: " + files.size());
final PsiManager psiManager = PsiManager.getInstance(project);
for (final VirtualFile file : files) {
if (!ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
final PsiElement element = reference.getElement();
if (element != null) {
final PsiElement parent = element.getParent();
if (parent instanceof PsiTypeElement) {
final PsiElement gParent = parent.getParent();
if (gParent instanceof PsiVariable) {
final PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(((PsiVariable)gParent).getInitializer());
if (initializer instanceof PsiFunctionalExpression) {
if (!consumer.process((PsiFunctionalExpression)initializer)) return false;
}
for (PsiReference varRef : ReferencesSearch.search(parent, scope)) {
final PsiElement varElement = varRef.getElement();
if (varElement != null) {
final PsiElement varElementParent = varElement.getParent();
if (varElementParent instanceof PsiAssignmentExpression &&
((PsiAssignmentExpression)varElementParent).getLExpression() == varElement) {
final PsiExpression rExpression = PsiUtil.skipParenthesizedExprDown(((PsiAssignmentExpression)varElementParent).getRExpression());
if (rExpression instanceof PsiFunctionalExpression) {
if (!consumer.process((PsiFunctionalExpression)rExpression)) return false;
}
}
}
}
} else if (gParent instanceof PsiMethod) {
final PsiReturnStatement[] returnStatements = ApplicationManager.getApplication().runReadAction(
new Computable<PsiReturnStatement[]>() {
@Override
public PsiReturnStatement[] compute() {
return PsiUtil.findReturnStatements((PsiMethod)gParent);
}
});
for (PsiReturnStatement returnStatement : returnStatements) {
final PsiExpression returnValue = returnStatement.getReturnValue();
if (returnValue instanceof PsiFunctionalExpression) {
if (!consumer.process((PsiFunctionalExpression)returnValue)) return false;
}
}
}
return processFileWithFunctionalInterfaces(aClass, consumer, psiManager, file);
}
})) return false;
}
return true;
}
private static boolean processFileWithFunctionalInterfaces(final PsiClass aClass,
final Processor<PsiFunctionalExpression> consumer,
final PsiManager psiManager, VirtualFile file) {
final PsiFile psiFile = psiManager.findFile(file);
if (psiFile != null) {
final Ref<Boolean> ref = new Ref<Boolean>(true);
psiFile.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitElement(PsiElement element) {
if (!ref.get()) {
return;
}
super.visitElement(element);
}
private void visitFunctionalExpression(PsiFunctionalExpression expression) {
PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
if (psiManager.areElementsEquivalent(PsiUtil.resolveClassInType(functionalInterfaceType), aClass)) {
if (!consumer.process(expression)) {
ref.set(false);
}
}
}
return true;
@Override
public void visitLambdaExpression(PsiLambdaExpression expression) {
super.visitLambdaExpression(expression);
visitFunctionalExpression(expression);
}
@Override
public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
super.visitMethodReferenceExpression(expression);
visitFunctionalExpression(expression);
}
});
if (!accepted) return false;
if (!ref.get()) return false;
}
return true;
}
@@ -50,7 +50,6 @@ import java.util.Set;
* @author max
*/
public abstract class JavaMethodElementType extends JavaStubElementType<PsiMethodStub, PsiMethod> {
public static final String TYPE_PARAMETER_PSEUDO_NAME = "$TYPE_PARAMETER$";
public JavaMethodElementType(@NonNls final String name) {
super(name);
}
@@ -150,35 +149,5 @@ public abstract class JavaMethodElementType extends JavaStubElementType<PsiMetho
sink.occurrence(JavaStubIndexKeys.JVM_STATIC_MEMBERS_TYPES, stub.getReturnTypeText(false).getShortTypeText());
}
}
Set<String> 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<String>();
}
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;
}
}
}
}
@@ -29,7 +29,6 @@ public class JavaStubIndexKeys {
public static final StubIndexKey<String, PsiMember> JVM_STATIC_MEMBERS_NAMES = StubIndexKey.createIndexKey("jvm.static.member.name");
public static final StubIndexKey<String, PsiMember> JVM_STATIC_MEMBERS_TYPES = StubIndexKey.createIndexKey("jvm.static.member.type");
public static final StubIndexKey<String, PsiAnonymousClass> ANONYMOUS_BASEREF = StubIndexKey.createIndexKey("java.anonymous.baseref");
public static final StubIndexKey<String, PsiMethod> METHOD_TYPES = StubIndexKey.createIndexKey("java.method.parameter.types");
public static final StubIndexKey<String, PsiClass> CLASS_SHORT_NAMES = StubIndexKey.createIndexKey("java.class.shortname");
public static final StubIndexKey<Integer,PsiClass> CLASS_FQN = StubIndexKey.createIndexKey("java.class.fqn");
@@ -38,7 +38,7 @@ import java.io.IOException;
* @author max
*/
public class JavaFileElementType extends ILightStubFileElementType<PsiJavaFileStub> {
public static final int STUB_VERSION = 18;
public static final int STUB_VERSION = 19;
public JavaFileElementType() {
super("java.FILE", JavaLanguage.INSTANCE);
@@ -54,7 +54,9 @@ public class JsonStandardComplianceInspection extends LocalInspectionTool {
@Override
public void visitComment(PsiComment comment) {
if (myWarnAboutComments) {
holder.registerProblem(comment, JsonBundle.message("msg.compliance.problem.comments"), ProblemHighlightType.WEAK_WARNING);
if (JsonStandardComplianceProvider.shouldWarnAboutComment(comment)) {
holder.registerProblem(comment, JsonBundle.message("msg.compliance.problem.comments"), ProblemHighlightType.WEAK_WARNING);
}
}
}
@@ -0,0 +1,44 @@
/*
* Copyright 2000-2014 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.json.codeinsight;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiComment;
import org.jetbrains.annotations.NotNull;
/**
* Allows to configure a compliance level for JSON.
* For example, some tools ignore comments in JSON silently when parsing, so there is no need to warn users about it.
*/
public abstract class JsonStandardComplianceProvider {
public static final ExtensionPointName<JsonStandardComplianceProvider> EP_NAME =
ExtensionPointName.create("com.intellij.json.jsonStandardComplianceProvider");
public abstract boolean isCommentAllowed(@NotNull PsiComment comment);
public static boolean shouldWarnAboutComment(@NotNull PsiComment comment) {
JsonStandardComplianceProvider[] providers = EP_NAME.getExtensions();
if (providers.length == 0) {
return true;
}
for (JsonStandardComplianceProvider provider : providers) {
if (provider.isCommentAllowed(comment)) {
return false;
}
}
return true;
}
}
@@ -91,7 +91,7 @@ public class IdIndex extends FileBasedIndexExtension<IdIndexEntry, Integer> {
@Override
public int getVersion() {
return 13 + (ourSnapshotMappingsEnabled ? 0xFF:0); // TODO: version should enumerate all word scanner versions and build version upon that set
return 14 + (ourSnapshotMappingsEnabled ? 0xFF:0); // TODO: version should enumerate all word scanner versions and build version upon that set
}
@Override
@@ -39,6 +39,7 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vcs.FileStatusManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.ListCellRendererWrapper;
@@ -329,12 +330,26 @@ public class ImplementationViewComponent extends JPanel {
if (element instanceof PsiNamedElement) {
names.add(((PsiNamedElement)element).getName());
}
if (names.size() > 1) {
break;
}
}
for (PsiElement element : elements) {
PsiFile file = getContainingFile(element);
if (file == null) continue;
final PsiElement parent = element.getParent();
files.add(new FileDescriptor(file, names.size() > 1 || parent == file ? element : parent));
if (names.size() > 1) {
files.add(new FileDescriptor(file, element));
}
else {
final PsiElement parent = PsiTreeUtil.getStubOrPsiParent(element);
if (parent == file) {
files.add(new FileDescriptor(file, element));
}
else {
files.add(new FileDescriptor(file, parent));
}
}
candidates.add(element);
}
@@ -58,4 +58,10 @@
implementationClass="com.intellij.json.psi.JsonStringLiteralManipulator"/>
</extensions>
<extensionPoints>
<extensionPoint qualifiedName="com.intellij.json.jsonStandardComplianceProvider"
interface="com.intellij.json.codeinsight.JsonStandardComplianceProvider"/>
</extensionPoints>
</idea-plugin>
-1
View File
@@ -1375,7 +1375,6 @@
<stubIndex implementation="com.intellij.psi.impl.java.stubs.index.JavaStaticMemberTypeIndex"/>
<stubIndex implementation="com.intellij.psi.impl.java.stubs.index.JavaShortClassNameIndex"/>
<stubIndex implementation="com.intellij.psi.impl.java.stubs.index.JavaSuperClassNameOccurenceIndex"/>
<stubIndex implementation="com.intellij.psi.impl.java.stubs.index.JavaMethodParameterTypesIndex"/>
<fileBasedIndex implementation="com.intellij.codeInspection.bytecodeAnalysis.BytecodeAnalysisIndex"/>
<fileBasedIndex implementation="com.intellij.psi.RefQueueIndex"/>