Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Batkovich
2016-06-30 10:44:04 +03:00
155 changed files with 3585 additions and 3639 deletions
@@ -18,6 +18,7 @@ package com.intellij.psi.stubsHierarchy.impl;
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
import com.intellij.util.BitUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.HashSet;
@@ -69,7 +70,7 @@ public class StubResolver {
private void findType(Symbol startScope, int name, Set<Symbol> symbols) throws IncompleteHierarchyException {
// looking up
for (Symbol s = startScope; s != null; s = s.myOwner)
findMemberType(s, name, symbols, new HashSet<Symbol>());
findMemberType(s, name, symbols);
// type from current package
findIdentInPackage(startScope.pkg(), name, IndexTree.CLASS, symbols);
}
@@ -79,7 +80,7 @@ public class StubResolver {
if (receiver.isPackage())
findIdentInPackage((Symbol.PackageSymbol)receiver, name, kind, symbols);
else
findMemberType(receiver, name, symbols, new HashSet<Symbol>());
findMemberType(receiver, name, symbols);
}
private void findIdentInPackage(Symbol.PackageSymbol pck, int name, int kind, Set<Symbol> symbols) {
@@ -97,19 +98,34 @@ public class StubResolver {
}
}
private void findMemberType(Symbol s, int name, Set<Symbol> symbols, Set<Symbol> processed) throws IncompleteHierarchyException {
if (!processed.add(s)) {
return;
private void findMemberType(Symbol s, int name, Set<Symbol> symbols) throws IncompleteHierarchyException {
if (s.isClass()) {
processInheritedMembers((Symbol.ClassSymbol)s, name, false, symbols, null);
} else {
processMembers(s.getMembers(), name, symbols, false);
}
processMembers(s.getMembers(), name, symbols, false);
if (s.isClass())
findInheritedMemberType((Symbol.ClassSymbol)s, name, symbols, processed);
}
private void findInheritedMemberType(Symbol.ClassSymbol c, int name, Set<Symbol> symbols, Set<Symbol> processed)
throws IncompleteHierarchyException {
for (Symbol.ClassSymbol st : c.getSuperClasses(myConnector))
findMemberType(st, name, symbols, processed);
private void processInheritedMembers(Symbol.ClassSymbol s,
int name,
boolean requireStatic,
Set<Symbol> symbols,
@Nullable Set<Symbol> processed) throws IncompleteHierarchyException {
processMembers(s.getMembers(), name, symbols, requireStatic);
@CompactArray(Symbol.ClassSymbol.class) Object supers = s.getSuperClasses(myConnector);
if (supers == null) return;
if (processed == null) processed = new HashSet<>();
if (!processed.add(s)) return;
if (supers instanceof Symbol.ClassSymbol) {
processInheritedMembers((Symbol.ClassSymbol)supers, name, requireStatic, symbols, processed);
} else if (supers instanceof Symbol.ClassSymbol[]) {
for (Symbol.ClassSymbol st : (Symbol.ClassSymbol[])supers) {
processInheritedMembers(st, name, requireStatic, symbols, processed);
}
}
}
private Symbol.ClassSymbol[] loadClass(@NotNull QualifiedName fqn) {
@@ -171,16 +187,7 @@ public class StubResolver {
// handling of import static `tsym.name` as
private void importNamedStatic(final Symbol.ClassSymbol tsym, final int name, final Set<Symbol> symbols) throws IncompleteHierarchyException {
new Object() {
Set<Symbol> processed = new HashSet<Symbol>();
void importFrom(Symbol.ClassSymbol cs) throws IncompleteHierarchyException {
if (cs == null || !processed.add(cs))
return;
for (Symbol.ClassSymbol c : cs.getSuperClasses(myConnector))
importFrom(c);
processMembers(cs.getMembers(), name, symbols, true);
}
}.importFrom(tsym);
processInheritedMembers(tsym, name, true, symbols, null);
}
private static void processMembers(Symbol.ClassSymbol[] members, int name, Set<Symbol> symbols, boolean requireStatic) {
@@ -19,6 +19,7 @@ import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
import com.intellij.util.BitUtil;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.Comparator;
@@ -125,13 +126,14 @@ public abstract class Symbol {
return BitUtil.isSet(myFlags, CONNECT_STARTED);
}
@NotNull
ClassSymbol[] getSuperClasses(StubHierarchyConnector connector) throws IncompleteHierarchyException {
@Nullable
@CompactArray(ClassSymbol.class)
Object getSuperClasses(StubHierarchyConnector connector) throws IncompleteHierarchyException {
connect(connector);
if (isHierarchyIncomplete()) {
throw IncompleteHierarchyException.INSTANCE;
}
return rawSuperClasses();
return mySuperClasses;
}
@NotNull
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.codeInsight.intention.QuickFixFactory;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
@@ -27,6 +28,7 @@ import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.wm.WindowManager;
@@ -77,38 +79,43 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
final String localName = local.getName();
final Query<PsiReference> query = ReferencesSearch.search(local, local.getUseScope());
if (query.findFirst() == null){
LOG.assertTrue(refExpr == null);
String message = RefactoringBundle.message("variable.is.never.used", localName);
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INLINE_VARIABLE);
return;
}
final PsiClass containingClass = PsiTreeUtil.getParentOfType(local, PsiClass.class);
final List<PsiElement> innerClassesWithUsages = Collections.synchronizedList(new ArrayList<PsiElement>());
final List<PsiElement> innerClassUsages = Collections.synchronizedList(new ArrayList<PsiElement>());
query.forEach(psiReference -> {
final PsiElement element = psiReference.getElement();
PsiElement innerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, PsiLambdaExpression.class);
while (innerClass != containingClass && innerClass != null) {
final PsiClass parentPsiClass = PsiTreeUtil.getParentOfType(innerClass, PsiClass.class, true);
if (parentPsiClass == containingClass) {
if (innerClass instanceof PsiLambdaExpression) {
if (PsiTreeUtil.isAncestor(innerClass, local, false)) {
innerClassesWithUsages.add(element);
innerClass = parentPsiClass;
continue;
}
}
innerClassesWithUsages.add(innerClass);
innerClassUsages.add(element);
}
innerClass = parentPsiClass;
final PsiClass containingClass = PsiTreeUtil.getParentOfType(local, PsiClass.class);
final Query<PsiReference> query = ReferencesSearch.search(local, local.getUseScope());
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
if (query.findFirst() == null){
LOG.assertTrue(refExpr == null);
ApplicationManager.getApplication().invokeLater(() -> {
String message = RefactoringBundle.message("variable.is.never.used", localName);
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INLINE_VARIABLE);
}, ModalityState.NON_MODAL);
return;
}
return true;
});
query.forEach(psiReference -> {
final PsiElement element = psiReference.getElement();
PsiElement innerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, PsiLambdaExpression.class);
while (innerClass != containingClass && innerClass != null) {
final PsiClass parentPsiClass = PsiTreeUtil.getParentOfType(innerClass, PsiClass.class, true);
if (parentPsiClass == containingClass) {
if (innerClass instanceof PsiLambdaExpression) {
if (PsiTreeUtil.isAncestor(innerClass, local, false)) {
innerClassesWithUsages.add(element);
innerClass = parentPsiClass;
continue;
}
}
innerClassesWithUsages.add(innerClass);
innerClassUsages.add(element);
}
innerClass = parentPsiClass;
}
return true;
});
}, "Find Usages", true, project)) {
return;
}
final PsiCodeBlock containerBlock = PsiTreeUtil.getParentOfType(local, PsiCodeBlock.class);
if (containerBlock == null) {
final String message = RefactoringBundle.getCannotRefactorMessage("Variable is declared outside a code block");
@@ -116,9 +123,7 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
return;
}
final PsiExpression defToInline = innerClassesWithUsages.isEmpty()
? getDefToInline(local, refExpr, containerBlock)
: getDefToInline(local, innerClassesWithUsages.get(0), containerBlock);
final PsiExpression defToInline = getDefToInline(local, innerClassesWithUsages.isEmpty() ? refExpr : innerClassesWithUsages.get(0), containerBlock);
if (defToInline == null){
final String key = refExpr == null ? "variable.has.no.initializer" : "variable.has.no.dominating.definition";
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message(key, localName));
@@ -150,7 +155,7 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
}
if (refExpr != null && inlineLocalDialog.isInlineThis()) {
refsToInlineList = Collections.<PsiElement>singletonList(refExpr);
refsToInlineList = Collections.singletonList(refExpr);
inlineAll.set(false);
}
}