mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git@git.labs.intellij.net:idea/community
This commit is contained in:
+43
-29
@@ -27,6 +27,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.*;
|
||||
@@ -88,7 +89,7 @@ class ChangedConstantsDependencyProcessor {
|
||||
}
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
_ex[0] = e;
|
||||
_ex[0] = e;
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
// supressed deliberately
|
||||
@@ -100,7 +101,7 @@ class ChangedConstantsDependencyProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private void processFieldRemoved(FieldInfo info, PsiClass aClass) throws CacheCorruptedException {
|
||||
private void processFieldRemoved(FieldInfo info, final PsiClass aClass) throws CacheCorruptedException {
|
||||
if (info.isPrivate()) {
|
||||
return; // optimization: don't need to search, cause may be used only in this class
|
||||
}
|
||||
@@ -118,41 +119,54 @@ class ChangedConstantsDependencyProcessor {
|
||||
}
|
||||
final PsiSearchHelper psiSearchHelper = PsiManager.getInstance(myProject).getSearchHelper();
|
||||
|
||||
final Ref<CacheCorruptedException> exRef = new Ref<CacheCorruptedException>(null);
|
||||
final long analysisStart = System.currentTimeMillis();
|
||||
boolean skipResolve = mySkipExpressionResolve;
|
||||
|
||||
PsiIdentifier[] identifiers = findIdentifiers(psiSearchHelper, myDependencyCache.resolve(info.getName()), searchScope, UsageSearchContext.IN_CODE);
|
||||
for (PsiIdentifier identifier : identifiers) {
|
||||
PsiElement parent = identifier.getParent();
|
||||
if (parent instanceof PsiReferenceExpression) {
|
||||
PsiReferenceExpression refExpr = (PsiReferenceExpression)parent;
|
||||
PsiReference reference = refExpr.getReference();
|
||||
skipResolve = skipResolve || (System.currentTimeMillis() - analysisStart) > ANALYSIS_DURATION_THRESHOLD_MILLIS;
|
||||
if (skipResolve || reference == null || reference.resolve() == null) {
|
||||
PsiClass ownerClass = getOwnerClass(refExpr);
|
||||
if (ownerClass != null && !ownerClass.equals(aClass)) {
|
||||
int qualifiedName = myDependencyCache.getSymbolTable().getId(ownerClass.getQualifiedName());
|
||||
// should force marking of the class no matter was it compiled or not
|
||||
// This will ensure the class was recompiled _after_ all the constants get their new values
|
||||
if (myDependencyCache.markClass(qualifiedName, true)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Mark dependent class " + myDependencyCache.resolve(qualifiedName) +
|
||||
"; reason: some constants were removed from " + myDependencyCache.resolve(myQName));
|
||||
|
||||
processIdentifiers(psiSearchHelper, new PsiElementProcessor<PsiIdentifier>() {
|
||||
private boolean skipResolve = mySkipExpressionResolve;
|
||||
@Override
|
||||
public boolean execute(PsiIdentifier identifier) {
|
||||
try {
|
||||
final PsiElement parent = identifier.getParent();
|
||||
if (parent instanceof PsiReferenceExpression) {
|
||||
PsiReferenceExpression refExpr = (PsiReferenceExpression)parent;
|
||||
PsiReference reference = refExpr.getReference();
|
||||
skipResolve = skipResolve || (System.currentTimeMillis() - analysisStart) > ANALYSIS_DURATION_THRESHOLD_MILLIS;
|
||||
if (skipResolve || reference == null || reference.resolve() == null) {
|
||||
final PsiClass ownerClass = getOwnerClass(refExpr);
|
||||
if (ownerClass != null && !ownerClass.equals(aClass)) {
|
||||
final String _qName = ownerClass.getQualifiedName();
|
||||
if (_qName != null) {
|
||||
int qualifiedName = myDependencyCache.getSymbolTable().getId(_qName);
|
||||
// should force marking of the class no matter was it compiled or not
|
||||
// This will ensure the class was recompiled _after_ all the constants get their new values
|
||||
if (myDependencyCache.markClass(qualifiedName, true)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Mark dependent class " + myDependencyCache.resolve(qualifiedName) + "; reason: some constants were removed from " + myDependencyCache.resolve(myQName));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.warn("Class with null qualified name was not expected here: " + ownerClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
exRef.set(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}, myDependencyCache.resolve(info.getName()), searchScope, UsageSearchContext.IN_CODE);
|
||||
|
||||
final CacheCorruptedException cacheCorruptedException = exRef.get();
|
||||
if (cacheCorruptedException != null) {
|
||||
throw cacheCorruptedException;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiIdentifier[] findIdentifiers(PsiSearchHelper helper, @NotNull String identifier, @NotNull SearchScope searchScope, short searchContext) {
|
||||
PsiElementProcessor.CollectElements<PsiIdentifier> processor = new PsiElementProcessor.CollectElements<PsiIdentifier>();
|
||||
processIdentifiers(helper, processor, identifier, searchScope, searchContext);
|
||||
return processor.toArray(PsiIdentifier.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
private static boolean processIdentifiers(PsiSearchHelper helper,
|
||||
@NotNull final PsiElementProcessor<PsiIdentifier> processor,
|
||||
@NotNull final String identifier,
|
||||
@@ -196,7 +210,7 @@ class ChangedConstantsDependencyProcessor {
|
||||
if (myDependencyCache.markClass(qualifiedName, true)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Marked dependent class " + myDependencyCache.resolve(qualifiedName) + "; reason: constants changed in " +
|
||||
myDependencyCache.resolve(myQName));
|
||||
myDependencyCache.resolve(myQName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -17,6 +17,7 @@ package com.intellij.packaging.impl.artifacts;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ui.configuration.ModulesAlphaComparator;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
@@ -32,6 +33,7 @@ import javax.swing.event.DocumentEvent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
@@ -74,7 +76,8 @@ public class JarArtifactFromModulesDialog extends DialogWrapper {
|
||||
updateManifestDirField();
|
||||
myManifestDirField.addBrowseFolderListener(null, null, project, ManifestFileUtil.createDescriptorForManifestDirectory());
|
||||
|
||||
final Module[] modules = context.getModulesProvider().getModules();
|
||||
final Module[] modules = context.getModulesProvider().getModules().clone();
|
||||
Arrays.sort(modules, ModulesAlphaComparator.INSTANCE);
|
||||
if (modules.length > 1) {
|
||||
myModuleComboBox.addItem(null);
|
||||
}
|
||||
|
||||
+2
@@ -25,6 +25,8 @@ import java.util.Comparator;
|
||||
* @author 2003
|
||||
*/
|
||||
public class ModulesAlphaComparator implements Comparator<Module>{
|
||||
public static ModulesAlphaComparator INSTANCE = new ModulesAlphaComparator();
|
||||
|
||||
public int compare(Module module1, Module module2) {
|
||||
final String name1 = module1.getName();
|
||||
final String name2 = module2.getName();
|
||||
|
||||
+1
-3
@@ -73,10 +73,8 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change
|
||||
private final ProjectConfigurable myProjectConfigurable;
|
||||
private final List<ModuleEditor> myModuleEditors = new ArrayList<ModuleEditor>();
|
||||
private final Comparator<ModuleEditor> myModuleEditorComparator = new Comparator<ModuleEditor>() {
|
||||
final ModulesAlphaComparator myModulesComparator = new ModulesAlphaComparator();
|
||||
|
||||
public int compare(ModuleEditor editor1, ModuleEditor editor2) {
|
||||
return myModulesComparator.compare(editor1.getModule(), editor2.getModule());
|
||||
return ModulesAlphaComparator.INSTANCE.compare(editor1.getModule(), editor2.getModule());
|
||||
}
|
||||
|
||||
@SuppressWarnings({"EqualsWhichDoesntCheckParameterClass"})
|
||||
|
||||
+4
-3
@@ -489,7 +489,8 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel {
|
||||
Messages.showMessageDialog(ClasspathPanelImpl.this, ProjectBundle.message("message.no.module.dependency.candidates"), getTitle(), Messages.getInformationIcon());
|
||||
return null;
|
||||
}
|
||||
return new ModuleChooser(chooseItems, ProjectBundle.message("classpath.chooser.title.add.module.dependency"));
|
||||
return new ModuleChooser(chooseItems, ProjectBundle.message("classpath.chooser.title.add.module.dependency"),
|
||||
ProjectBundle.message("classpath.chooser.description.add.module.dependency"));
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -669,8 +670,8 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel {
|
||||
}
|
||||
|
||||
private class ModuleChooser extends ChooseModulesDialog implements ClasspathElementChooser<Module> {
|
||||
public ModuleChooser(final List<Module> items, final String title) {
|
||||
super(ClasspathPanelImpl.this, items, title);
|
||||
public ModuleChooser(final List<Module> items, final String title, String description) {
|
||||
super(ClasspathPanelImpl.this, items, title, description);
|
||||
}
|
||||
|
||||
public void doChoose() {
|
||||
|
||||
+5
@@ -25,6 +25,7 @@ package com.intellij.openapi.roots.ui.configuration.libraryEditor;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.ide.util.ChooseElementsDialog;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -36,6 +37,10 @@ public class ChooseModulesDialog extends ChooseElementsDialog<Module> {
|
||||
super(parent, items, title, null, true);
|
||||
}
|
||||
|
||||
public ChooseModulesDialog(Component parent, List<Module> items, String title, @Nullable String description) {
|
||||
super(parent, items, title, description, true);
|
||||
}
|
||||
|
||||
public ChooseModulesDialog(final Project project, final List<? extends Module> items, final String title, final String description) {
|
||||
super(project, items, title, description, true);
|
||||
}
|
||||
|
||||
@@ -210,7 +210,6 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
|
||||
case '<':
|
||||
case '>':
|
||||
case '\"':
|
||||
case '[': return TailType.createSimpleTailType(completionChar);
|
||||
}
|
||||
final TailType attr = item.getTailType();
|
||||
return attr == TailType.UNKNOWN ? TailType.NONE : attr;
|
||||
|
||||
@@ -87,13 +87,15 @@ public class JavaAwareCompletionData extends CompletionData{
|
||||
ret.setInsertHandler(new InsertHandler<LookupElement>() {
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context, LookupElement item) {
|
||||
if (context.shouldAddCompletionChar()) {
|
||||
return;
|
||||
}
|
||||
TailType type = analyzeItem(item.getObject(), context.getFile().findElementAt(context.getStartOffset()));
|
||||
if (type == TailType.NONE) {
|
||||
type = tailType;
|
||||
}
|
||||
//new DefaultInsertHandler().handleInsert(context, item);
|
||||
if (type != TailType.NONE) {
|
||||
context.setAddCompletionChar(false);
|
||||
type.processTail(context.getEditor(), context.getTailOffset());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,28 +41,31 @@ public class JavaCharFilter extends CharFilter {
|
||||
public Result acceptChar(char c, final int prefixLength, final Lookup lookup) {
|
||||
if (!lookup.isCompletion()) return null;
|
||||
|
||||
if (!(lookup.getPsiFile() instanceof PsiJavaFile)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
LookupElement item = lookup.getCurrentItem();
|
||||
if (item == null) return null;
|
||||
|
||||
if (c == '!') {
|
||||
if (lookup.getPsiFile() instanceof PsiJavaFile) {
|
||||
final LookupElement item = lookup.getCurrentItem();
|
||||
if (item == null) return null;
|
||||
|
||||
final Object o = item.getObject();
|
||||
if (o instanceof PsiVariable) {
|
||||
if (PsiType.BOOLEAN.isAssignableFrom(((PsiVariable)o).getType())) return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
|
||||
}
|
||||
if (o instanceof PsiMethod) {
|
||||
final PsiType type = ((PsiMethod)o).getReturnType();
|
||||
if (type != null && PsiType.BOOLEAN.isAssignableFrom(type)) return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
|
||||
}
|
||||
|
||||
return null;
|
||||
final Object o = item.getObject();
|
||||
if (o instanceof PsiVariable) {
|
||||
if (PsiType.BOOLEAN.isAssignableFrom(((PsiVariable)o).getType())) return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
|
||||
}
|
||||
if (o instanceof PsiMethod) {
|
||||
final PsiType type = ((PsiMethod)o).getReturnType();
|
||||
if (type != null && PsiType.BOOLEAN.isAssignableFrom(type)) return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
if (c == '.' && isWithinLiteral(lookup)) return Result.ADD_TO_PREFIX;
|
||||
if (c == '[') return CharFilter.Result.SELECT_ITEM_AND_FINISH_LOOKUP;
|
||||
if (c == '<' && item.getObject() instanceof PsiClass) return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
|
||||
|
||||
if (c == '#' && PsiTreeUtil.getParentOfType(lookup.getPsiElement(), PsiDocComment.class) != null) {
|
||||
final LookupElement item = lookup.getCurrentItem();
|
||||
if (item != null && item.getObject() instanceof PsiClass) {
|
||||
if (item.getObject() instanceof PsiClass) {
|
||||
return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
|
||||
}
|
||||
}
|
||||
|
||||
+49
-38
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.ExpectedTypesProvider;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.lang.LangBundle;
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
@@ -58,45 +59,10 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
|
||||
final CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result);
|
||||
|
||||
final PsiElement insertedElement = parameters.getPosition();
|
||||
|
||||
final ElementFilter filter =
|
||||
or(JavaSmartCompletionContributor.AFTER_THROW_NEW,
|
||||
JavaCompletionContributor.INSIDE_METHOD_THROWS_CLAUSE,
|
||||
JavaCompletionContributor.IN_CATCH_TYPE).accepts(insertedElement) ? new AssignableFromFilter(CommonClassNames.JAVA_LANG_THROWABLE) :
|
||||
IN_TYPE_PARAMETER.accepts(insertedElement) ? new ExcludeDeclaredFilter(new ClassFilter(PsiTypeParameter.class)) :
|
||||
TrueFilter.INSTANCE;
|
||||
|
||||
|
||||
final boolean inJavaContext = parameters.getPosition() instanceof PsiIdentifier;
|
||||
if (AFTER_NEW.accepts(insertedElement)) {
|
||||
final PsiExpression expr = PsiTreeUtil.getContextOfType(insertedElement, PsiExpression.class, true);
|
||||
for (final ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes(expr, true)) {
|
||||
final PsiType type = info.getType();
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass != null) {
|
||||
result.addElement(createClassLookupItem(psiClass, inJavaContext));
|
||||
}
|
||||
final PsiType defaultType = info.getDefaultType();
|
||||
if (!defaultType.equals(type)) {
|
||||
final PsiClass defClass = PsiUtil.resolveClassInType(defaultType);
|
||||
if (defClass != null) {
|
||||
result.addElement(createClassLookupItem(defClass, inJavaContext));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final boolean lookingForAnnotations = PsiJavaPatterns.psiElement().afterLeaf("@").accepts(insertedElement);
|
||||
|
||||
AllClassesGetter.processJavaClasses(parameters, result.getPrefixMatcher(), parameters.getInvocationCount() <= 1, new Consumer<PsiClass>() {
|
||||
addAllClasses(parameters, result, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(PsiClass psiClass) {
|
||||
if (lookingForAnnotations && !psiClass.isAnnotationType()) return;
|
||||
|
||||
if (filter.isAcceptable(psiClass, insertedElement)) {
|
||||
result.addElement(createClassLookupItem(psiClass, inJavaContext));
|
||||
}
|
||||
public void consume(LookupElement element) {
|
||||
_result.addElement(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -104,6 +70,51 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
|
||||
}
|
||||
|
||||
public static void addAllClasses(CompletionParameters parameters, final CompletionResultSet result, @NotNull final Consumer<LookupElement> consumer) {
|
||||
final PsiElement insertedElement = parameters.getPosition();
|
||||
|
||||
final ElementFilter filter =
|
||||
or(JavaSmartCompletionContributor.AFTER_THROW_NEW,
|
||||
JavaCompletionContributor.INSIDE_METHOD_THROWS_CLAUSE,
|
||||
JavaCompletionContributor.IN_CATCH_TYPE).accepts(insertedElement) ? new AssignableFromFilter(CommonClassNames.JAVA_LANG_THROWABLE) :
|
||||
IN_TYPE_PARAMETER.accepts(insertedElement) ? new ExcludeDeclaredFilter(new ClassFilter(PsiTypeParameter.class)) :
|
||||
TrueFilter.INSTANCE;
|
||||
|
||||
|
||||
final boolean inJavaContext = parameters.getPosition() instanceof PsiIdentifier;
|
||||
if (AFTER_NEW.accepts(insertedElement)) {
|
||||
final PsiExpression expr = PsiTreeUtil.getContextOfType(insertedElement, PsiExpression.class, true);
|
||||
for (final ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes(expr, true)) {
|
||||
final PsiType type = info.getType();
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass != null) {
|
||||
consumer.consume(createClassLookupItem(psiClass, inJavaContext));
|
||||
}
|
||||
final PsiType defaultType = info.getDefaultType();
|
||||
if (!defaultType.equals(type)) {
|
||||
final PsiClass defClass = PsiUtil.resolveClassInType(defaultType);
|
||||
if (defClass != null) {
|
||||
consumer.consume(createClassLookupItem(defClass, inJavaContext));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final boolean lookingForAnnotations = PsiJavaPatterns.psiElement().afterLeaf("@").accepts(insertedElement);
|
||||
|
||||
AllClassesGetter
|
||||
.processJavaClasses(parameters, result.getPrefixMatcher(), parameters.getInvocationCount() <= 1, new Consumer<PsiClass>() {
|
||||
@Override
|
||||
public void consume(PsiClass psiClass) {
|
||||
if (lookingForAnnotations && !psiClass.isAnnotationType()) return;
|
||||
|
||||
if (filter.isAcceptable(psiClass, insertedElement)) {
|
||||
consumer.consume(createClassLookupItem(psiClass, inJavaContext));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static JavaPsiClassReferenceElement createClassLookupItem(final PsiClass psiClass, final boolean inJavaContext) {
|
||||
return AllClassesGetter.createLookupItem(psiClass, inJavaContext ? JavaClassNameInsertHandler.JAVA_CLASS_INSERT_HANDLER : AllClassesGetter.TRY_SHORTENING);
|
||||
}
|
||||
|
||||
@@ -44,10 +44,6 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
|
||||
public void handleInsert(final InsertionContext context, final JavaPsiClassReferenceElement item) {
|
||||
final char c = context.getCompletionChar();
|
||||
|
||||
if (c != '.' && c != ' ' && c != '#') {
|
||||
context.setAddCompletionChar(false);
|
||||
}
|
||||
|
||||
int offset = context.getTailOffset() - 1;
|
||||
final PsiFile file = context.getFile();
|
||||
if (PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiImportStatementBase.class, false) != null) {
|
||||
|
||||
+14
-9
@@ -30,8 +30,12 @@ import com.intellij.openapi.editor.highlighter.HighlighterIterator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.patterns.*;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PatternCondition;
|
||||
import com.intellij.patterns.PsiJavaElementPattern;
|
||||
import com.intellij.patterns.PsiNameValuePairPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.NameUtil;
|
||||
import com.intellij.psi.filters.*;
|
||||
import com.intellij.psi.filters.classes.AssignableFromContextFilter;
|
||||
import com.intellij.psi.filters.element.ExcludeDeclaredFilter;
|
||||
@@ -211,15 +215,14 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
PsiElement position,
|
||||
final InheritorsHolder inheritors) {
|
||||
if (shouldRunClassNameCompletion(result, position)) {
|
||||
result.runRemainingContributors(parameters.withType(CompletionType.CLASS_NAME),
|
||||
new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement lookupElement) {
|
||||
if (!inheritors.alreadyProcessed(lookupElement)) {
|
||||
result.addElement(lookupElement);
|
||||
}
|
||||
JavaClassNameCompletionContributor.addAllClasses(parameters, result, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
if (!inheritors.alreadyProcessed(element)) {
|
||||
result.addElement(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,6 +318,8 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NameUtil.useMinusculeHumpMatcher) return true;
|
||||
|
||||
final String s = result.getPrefixMatcher().getPrefix();
|
||||
if (StringUtil.isEmpty(s) || !Character.isUpperCase(s.charAt(0))) return false;
|
||||
return true;
|
||||
|
||||
@@ -116,6 +116,7 @@ public class JavaCompletionSorting {
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement element) {
|
||||
final Object o = element.getObject();
|
||||
if (o instanceof PsiKeyword) return -3;
|
||||
if (!(o instanceof PsiMember)) return 0;
|
||||
|
||||
if (((PsiMember)o).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
|
||||
@@ -842,8 +842,9 @@ public class JavaCompletionUtil {
|
||||
final boolean hasTail = tailType != TailType.NONE && tailType != TailType.UNKNOWN;
|
||||
final boolean smart = completionChar == Lookup.COMPLETE_STATEMENT_SELECT_CHAR;
|
||||
|
||||
final boolean addCompletionChar = context.shouldAddCompletionChar();
|
||||
context.setAddCompletionChar(false);
|
||||
if (completionChar == '(' || completionChar == '.' || completionChar == ',' || completionChar == ';') {
|
||||
context.setAddCompletionChar(false);
|
||||
}
|
||||
|
||||
final boolean needRightParenth = forceClosingParenthesis || !smart && (CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET || hasTail);
|
||||
if (hasTail) {
|
||||
@@ -863,7 +864,7 @@ public class JavaCompletionUtil {
|
||||
AutoPopupController.getInstance(file.getProject()).autoPopupParameterInfo(editor, overloadsMatter ? null : (PsiElement)item.getObject());
|
||||
}
|
||||
|
||||
if (smart || needRightParenth && addCompletionChar) {
|
||||
if (smart || needRightParenth) {
|
||||
TailType toInsert = tailType;
|
||||
LookupItem lookupItem = item.as(LookupItem.CLASS_CONDITION_KEY);
|
||||
if (lookupItem == null || lookupItem.getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) {
|
||||
@@ -877,7 +878,7 @@ public class JavaCompletionUtil {
|
||||
}
|
||||
toInsert.processTail(editor, context.getTailOffset());
|
||||
|
||||
if (context.getCompletionChar() == '.') {
|
||||
if (completionChar == '.') {
|
||||
AutoPopupController.getInstance(file.getProject()).autoPopupMemberLookup(context.getEditor(), null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
|
||||
|
||||
final PsiType type = method.getReturnType();
|
||||
if (context.getCompletionChar() == '!' && type != null && PsiType.BOOLEAN.isAssignableFrom(type)) {
|
||||
context.setAddCompletionChar(false);
|
||||
context.commitDocument();
|
||||
final int offset = context.getOffset(refStart);
|
||||
final PsiMethodCallExpression methodCall = PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiMethodCallExpression.class, false);
|
||||
|
||||
+7
-4
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.lookup.Lookup;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.codeInsight.lookup.TailTypeDecorator;
|
||||
@@ -52,10 +53,12 @@ public class SmartCompletionDecorator extends TailTypeDecorator<LookupElement> {
|
||||
}
|
||||
|
||||
protected TailType computeTailType(InsertionContext context) {
|
||||
final TailType defType = LookupItem.getDefaultTailType(context.getCompletionChar());
|
||||
if (defType != null) {
|
||||
context.setAddCompletionChar(false);
|
||||
return defType;
|
||||
if (context.getCompletionChar() == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) {
|
||||
return TailType.SMART_COMPLETION;
|
||||
}
|
||||
|
||||
if (LookupItem.getDefaultTailType(context.getCompletionChar()) != null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
LookupElement delegate = getDelegate();
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.codeInsight.daemon.impl;
|
||||
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
|
||||
import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.editor.SyntaxHighlighterColors;
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors;
|
||||
|
||||
/**
|
||||
* @author anna
|
||||
* Date: 01-Feb-2008
|
||||
*/
|
||||
public interface JavaHighlightInfoTypes extends HighlightInfoType {
|
||||
HighlightInfoType UNUSED_IMPORT = new HighlightInfoType.HighlightInfoTypeSeverityByKey(
|
||||
HighlightDisplayKey.findOrRegister(UnusedImportLocalInspection.SHORT_NAME, UnusedImportLocalInspection.DISPLAY_NAME),
|
||||
CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES);
|
||||
|
||||
HighlightInfoType JAVA_KEYWORD = new HighlightInfoType.HighlightInfoTypeImpl(
|
||||
HighlightSeverity.INFORMATION, SyntaxHighlighterColors.KEYWORD);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* User: anna
|
||||
* Date: 01-Feb-2008
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon.impl;
|
||||
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
|
||||
import com.intellij.codeInspection.javaDoc.JavaDocReferenceInspection;
|
||||
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
|
||||
import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection;
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors;
|
||||
|
||||
public class JavaHightlightInfoTypes {
|
||||
|
||||
public static final HighlightInfoType UNUSED_IMPORT = new HighlightInfoType.HighlightInfoTypeSeverityByKey(
|
||||
HighlightDisplayKey.find(UnusedImportLocalInspection.SHORT_NAME) == null ?
|
||||
HighlightDisplayKey.register(UnusedImportLocalInspection.SHORT_NAME, UnusedImportLocalInspection.DISPLAY_NAME) : HighlightDisplayKey.find(UnusedImportLocalInspection.SHORT_NAME), CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES);
|
||||
public static final HighlightInfoType JAVADOC_WRONG_REF = new HighlightInfoType.HighlightInfoTypeSeverityByKey(HighlightDisplayKey.find(
|
||||
JavaDocReferenceInspection.SHORT_NAME) == null ?
|
||||
HighlightDisplayKey.register(JavaDocReferenceInspection.SHORT_NAME, JavaDocReferenceInspection.DISPLAY_NAME) : HighlightDisplayKey.find(JavaDocReferenceInspection.SHORT_NAME), CodeInsightColors.WRONG_REFERENCES_ATTRIBUTES);
|
||||
public static final HighlightInfoType UNCHECKED_WARNING = new HighlightInfoType.HighlightInfoTypeSeverityByKeyAttrBySeverity(HighlightDisplayKey.find(
|
||||
UncheckedWarningLocalInspection.SHORT_NAME) == null ?
|
||||
HighlightDisplayKey.register(UncheckedWarningLocalInspection.SHORT_NAME, UncheckedWarningLocalInspection.DISPLAY_NAME, UncheckedWarningLocalInspection.ID) : HighlightDisplayKey.find(UncheckedWarningLocalInspection.SHORT_NAME));
|
||||
|
||||
private JavaHightlightInfoTypes() {
|
||||
}
|
||||
}
|
||||
@@ -674,7 +674,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
|
||||
}
|
||||
|
||||
private HighlightInfo registerRedundantImport(PsiImportStatementBase importStatement, HighlightDisplayKey unusedImportKey) {
|
||||
HighlightInfo info = HighlightInfo.createHighlightInfo(JavaHightlightInfoTypes.UNUSED_IMPORT, importStatement, InspectionsBundle.message("unused.import.statement"));
|
||||
HighlightInfo info = HighlightInfo.createHighlightInfo(JavaHighlightInfoTypes.UNUSED_IMPORT, importStatement, InspectionsBundle.message("unused.import.statement"));
|
||||
|
||||
QuickFixAction.registerQuickFixAction(info, new OptimizeImportsFix(), unusedImportKey);
|
||||
QuickFixAction.registerQuickFixAction(info, new EnableOptimizeImportsOnTheFlyFix(), unusedImportKey);
|
||||
|
||||
+43
-3
@@ -33,6 +33,7 @@ import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.search.searches.SuperMethodsSearch;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import gnu.trove.THashMap;
|
||||
@@ -115,11 +116,14 @@ public class GenericsHighlightUtil {
|
||||
if (!typeParameterListOwner.hasTypeParameters()) {
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, referenceElements[0], "Diamond operator is not applicable for non-parameterized types");
|
||||
}
|
||||
inferenceResult = ((PsiDiamondType)referenceElements[0].getType()).resolveInferredTypes();
|
||||
final String errorMessage = inferenceResult.getErrorMessage();
|
||||
final PsiType expectedType = detectExpectedType(referenceParameterList);
|
||||
if (!(expectedType instanceof PsiClassType && ((PsiClassType)expectedType).isRaw())) {
|
||||
inferenceResult = ((PsiDiamondType)referenceElements[0].getType()).resolveInferredTypes();
|
||||
final String errorMessage = inferenceResult.getErrorMessage();
|
||||
if (errorMessage != null) {
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, referenceElements[0], errorMessage);
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, referenceElements[0], errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +179,42 @@ public class GenericsHighlightUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PsiType detectExpectedType(PsiReferenceParameterList referenceParameterList) {
|
||||
final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(referenceParameterList, PsiNewExpression.class);
|
||||
LOG.assertTrue(newExpression != null);
|
||||
final PsiElement parent = newExpression.getParent();
|
||||
PsiType expectedType = null;
|
||||
if (parent instanceof PsiVariable && newExpression.equals(((PsiVariable)parent).getInitializer())) {
|
||||
expectedType = ((PsiVariable)parent).getType();
|
||||
}
|
||||
else if (parent instanceof PsiAssignmentExpression && newExpression.equals(((PsiAssignmentExpression)parent).getRExpression())) {
|
||||
expectedType = ((PsiAssignmentExpression)parent).getLExpression().getType();
|
||||
}
|
||||
else if (parent instanceof PsiReturnStatement) {
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
|
||||
if (method != null) {
|
||||
expectedType = method.getReturnType();
|
||||
}
|
||||
}
|
||||
else if (parent instanceof PsiExpressionList) {
|
||||
final PsiElement pParent = parent.getParent();
|
||||
if (pParent instanceof PsiCallExpression && parent.equals(((PsiCallExpression)pParent).getArgumentList())) {
|
||||
final PsiMethod method = ((PsiCallExpression)pParent).resolveMethod();
|
||||
if (method != null) {
|
||||
final PsiExpression[] expressions = ((PsiCallExpression)pParent).getArgumentList().getExpressions();
|
||||
final int idx = ArrayUtil.find(expressions, newExpression);
|
||||
if (idx > -1) {
|
||||
final PsiParameterList parameterList = method.getParameterList();
|
||||
if (idx < parameterList.getParametersCount()) {
|
||||
expectedType = parameterList.getParameters()[idx].getType();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return expectedType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static HighlightInfo checkTypeParameterWithinItsBound(final PsiTypeParameter classParameter,
|
||||
final PsiSubstitutor substitutor,
|
||||
|
||||
+1
-1
@@ -533,7 +533,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalVoidType(keyword));
|
||||
|
||||
if (PsiTreeUtil.getParentOfType(keyword, PsiDocTagValue.class) != null) {
|
||||
myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.JAVA_KEYWORD, keyword, null));
|
||||
myHolder.add(HighlightInfo.createHighlightInfo(JavaHighlightInfoTypes.JAVA_KEYWORD, keyword, null));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -91,6 +91,7 @@ public class ChangeMethodSignatureFromUsageFix implements IntentionAction {
|
||||
}
|
||||
|
||||
private static String formatTypesList(ParameterInfoImpl[] infos, PsiElement context) {
|
||||
if (infos == null) return null;
|
||||
String result = "";
|
||||
try {
|
||||
for (ParameterInfoImpl info : infos) {
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ public class GeneralizeCatchFix implements IntentionAction {
|
||||
@NotNull
|
||||
public String getText() {
|
||||
return QuickFixBundle.message("generalize.catch.text",
|
||||
HighlightUtil.formatType(myCatchParameter.getType()),
|
||||
HighlightUtil.formatType(myCatchParameter == null ? null : myCatchParameter.getType()),
|
||||
HighlightUtil.formatType(myUnhandledException));
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.psi.search.PsiElementProcessor;
|
||||
import com.intellij.psi.search.PsiElementProcessorAdapter;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
import com.intellij.psi.util.PsiFormatUtilBase;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -54,6 +55,7 @@ public class ModifierFix extends IntentionAndQuickFixAction {
|
||||
myShouldHave = shouldHave;
|
||||
myShowContainingClass = showContainingClass;
|
||||
}
|
||||
|
||||
public ModifierFix(@NotNull PsiModifierListOwner owner, @Modifier @NotNull String modifier, boolean shouldHave, boolean showContainingClass) {
|
||||
this(owner.getModifierList(), modifier, shouldHave, showContainingClass);
|
||||
if (owner instanceof PsiVariable) {
|
||||
@@ -64,12 +66,12 @@ public class ModifierFix extends IntentionAndQuickFixAction {
|
||||
@NotNull
|
||||
public String getName() {
|
||||
String name = null;
|
||||
PsiElement parent = myVariable == null ? myModifierList.getParent() : myVariable;
|
||||
PsiElement parent = myVariable == null ? myModifierList == null ? null : myModifierList.getParent() : myVariable;
|
||||
if (parent instanceof PsiClass) {
|
||||
name = ((PsiClass)parent).getName();
|
||||
}
|
||||
else {
|
||||
int options = PsiFormatUtil.SHOW_NAME | (myShowContainingClass ? PsiFormatUtil.SHOW_CONTAINING_CLASS : 0);
|
||||
int options = PsiFormatUtilBase.SHOW_NAME | (myShowContainingClass ? PsiFormatUtilBase.SHOW_CONTAINING_CLASS : 0);
|
||||
if (parent instanceof PsiMethod) {
|
||||
name = PsiFormatUtil.formatMethod((PsiMethod)parent, PsiSubstitutor.EMPTY, options, 0);
|
||||
}
|
||||
@@ -79,8 +81,9 @@ public class ModifierFix extends IntentionAndQuickFixAction {
|
||||
else if (parent instanceof PsiClassInitializer) {
|
||||
PsiClass containingClass = ((PsiClassInitializer)parent).getContainingClass();
|
||||
String className = containingClass instanceof PsiAnonymousClass
|
||||
? QuickFixBundle.message("anonymous.class.presentation", ((PsiAnonymousClass)containingClass).getBaseClassType().getPresentableText())
|
||||
: containingClass.getName();
|
||||
? QuickFixBundle.message("anonymous.class.presentation",
|
||||
((PsiAnonymousClass)containingClass).getBaseClassType().getPresentableText())
|
||||
: containingClass != null ? containingClass.getName() : "unknown";
|
||||
name = QuickFixBundle.message("class.initializer.presentation", className);
|
||||
}
|
||||
}
|
||||
@@ -99,7 +102,7 @@ public class ModifierFix extends IntentionAndQuickFixAction {
|
||||
return myModifierList != null &&
|
||||
myModifierList.isValid() &&
|
||||
myModifierList.getManager().isInProject(myModifierList) &&
|
||||
myModifierList.hasModifierProperty(myModifier) != myShouldHave &&
|
||||
myModifierList.hasExplicitModifier(myModifier) != myShouldHave &&
|
||||
(myVariable == null || myVariable.isValid());
|
||||
}
|
||||
|
||||
|
||||
+3
-5
@@ -101,15 +101,13 @@ public class ReplaceAddAllArrayToCollectionFix implements IntentionAction {
|
||||
@NonNls
|
||||
private String getCollectionsMethodCall() {
|
||||
final PsiExpression qualifierExpression = myMethodCall.getMethodExpression().getQualifierExpression();
|
||||
PsiExpression[] expressions = myMethodCall.getArgumentList().getExpressions();
|
||||
return "java.util.Collections.addAll(" +
|
||||
(qualifierExpression != null ? qualifierExpression.getText() : "this") +
|
||||
", " +
|
||||
myMethodCall.getArgumentList().getExpressions()[0]
|
||||
.getText() +
|
||||
")";
|
||||
", " + (expressions.length == 0 ? "" : expressions[0].getText()) + ")";
|
||||
}
|
||||
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -35,6 +35,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiShortNamesCache;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
import com.intellij.psi.util.PsiFormatUtilBase;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.proximity.PsiProximityComparator;
|
||||
import com.intellij.ui.popup.list.ListPopupImpl;
|
||||
@@ -62,8 +63,10 @@ public class StaticImportMethodFix implements IntentionAction {
|
||||
@NotNull
|
||||
public String getText() {
|
||||
String text = QuickFixBundle.message("static.import.method.text");
|
||||
if (candidates.size() == 1) {
|
||||
text += " '" + PsiFormatUtil.formatMethod(candidates.get(0), PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_CONTAINING_CLASS | PsiFormatUtil.SHOW_FQ_NAME, 0)+"'";
|
||||
if (candidates != null && candidates.size() == 1) {
|
||||
text += " '" + PsiFormatUtil.formatMethod(candidates.get(0), PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_NAME |
|
||||
PsiFormatUtilBase.SHOW_CONTAINING_CLASS |
|
||||
PsiFormatUtilBase.SHOW_FQ_NAME, 0)+"'";
|
||||
}
|
||||
else {
|
||||
text += "...";
|
||||
@@ -243,7 +246,7 @@ public class StaticImportMethodFix implements IntentionAction {
|
||||
final PopupListElementRenderer rightArrow = new PopupListElementRenderer(this);
|
||||
@Override
|
||||
protected ListCellRenderer getListElementRenderer() {
|
||||
return new MethodCellRenderer(true, PsiFormatUtil.SHOW_NAME){
|
||||
return new MethodCellRenderer(true, PsiFormatUtilBase.SHOW_NAME){
|
||||
@Override
|
||||
protected DefaultListCellRenderer getRightCellRenderer() {
|
||||
final DefaultListCellRenderer moduleRenderer = super.getRightCellRenderer();
|
||||
|
||||
-1
@@ -70,7 +70,6 @@ public class VariableAccessFromInnerClassFix implements IntentionAction {
|
||||
case COPY_TO_FINAL:
|
||||
return QuickFixBundle.message("make.final.copy.to.temp", myVariable.getName());
|
||||
default:
|
||||
LOG.error("invalid type "+myFixType);
|
||||
return "";
|
||||
}
|
||||
Collection<PsiVariable> vars = getVariablesToFix();
|
||||
|
||||
+3
-3
@@ -56,13 +56,13 @@ public class WrapExpressionFix implements IntentionAction {
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
final PsiMethod wrapper = myExpression.isValid() ? findWrapper(myExpression.getType(), myExpectedType, myPrimitiveExpected) : null;
|
||||
final String methodPresentation = wrapper != null ? (wrapper.getContainingClass().getName() + "." + wrapper.getName()) : "";
|
||||
final PsiMethod wrapper = myExpression.isValid() && myExpectedType != null ? findWrapper(myExpression.getType(), myExpectedType, myPrimitiveExpected) : null;
|
||||
final String methodPresentation = wrapper != null ? wrapper.getContainingClass().getName() + "." + wrapper.getName() : "";
|
||||
return QuickFixBundle.message("wrap.expression.using.static.accessor.text", methodPresentation);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiMethod findWrapper(PsiType type, PsiClassType expectedType, boolean primitiveExpected) {
|
||||
private static PsiMethod findWrapper(PsiType type, @NotNull PsiClassType expectedType, boolean primitiveExpected) {
|
||||
PsiClass aClass = expectedType.resolve();
|
||||
if (aClass != null) {
|
||||
PsiType expectedReturnType = expectedType;
|
||||
|
||||
+11
-7
@@ -22,6 +22,7 @@ import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiJavaFile;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
|
||||
public class JavaBackspaceHandler extends BackspaceHandlerDelegate {
|
||||
@@ -43,30 +44,33 @@ public class JavaBackspaceHandler extends BackspaceHandlerDelegate {
|
||||
char c1 = chars.charAt(offset);
|
||||
if (c == '<' && myToDeleteGt) {
|
||||
if (c1 != '>') return true;
|
||||
handleLTDeletion(editor, offset);
|
||||
handleLTDeletion(editor, offset, JavaTokenType.LT, JavaTokenType.GT, JavaTypedHandler.INVALID_INSIDE_REFERENCE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void handleLTDeletion(final Editor editor, final int offset) {
|
||||
public static void handleLTDeletion(final Editor editor,
|
||||
final int offset,
|
||||
final IElementType lt,
|
||||
final IElementType gt, final TokenSet invalidInsideReference) {
|
||||
HighlighterIterator iterator = ((EditorEx)editor).getHighlighter().createIterator(offset);
|
||||
while (iterator.getStart() > 0 && !JavaTypedHandlerUtil.isTokenInvalidInsideReference(iterator.getTokenType())) {
|
||||
while (iterator.getStart() > 0 && !invalidInsideReference.contains(iterator.getTokenType())) {
|
||||
iterator.retreat();
|
||||
}
|
||||
|
||||
if (JavaTypedHandlerUtil.isTokenInvalidInsideReference(iterator.getTokenType())) iterator.advance();
|
||||
if (invalidInsideReference.contains(iterator.getTokenType())) iterator.advance();
|
||||
|
||||
int balance = 0;
|
||||
while (!iterator.atEnd() && balance >= 0) {
|
||||
final IElementType tokenType = iterator.getTokenType();
|
||||
if (tokenType == JavaTokenType.LT) {
|
||||
if (tokenType == lt) {
|
||||
balance++;
|
||||
}
|
||||
else if (tokenType == JavaTokenType.GT) {
|
||||
else if (tokenType == gt) {
|
||||
balance--;
|
||||
}
|
||||
else if (JavaTypedHandlerUtil.isTokenInvalidInsideReference(tokenType)) {
|
||||
else if (invalidInsideReference.contains(tokenType)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.intellij.psi.filters.position.SuperParentFilter;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.jsp.JspFile;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -42,6 +43,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @author yole
|
||||
*/
|
||||
public class JavaTypedHandler extends TypedHandlerDelegate {
|
||||
static final TokenSet INVALID_INSIDE_REFERENCE = TokenSet.create(JavaTokenType.SEMICOLON, JavaTokenType.LBRACE, JavaTokenType.RBRACE);
|
||||
private boolean myJavaLTTyped;
|
||||
|
||||
public Result checkAutoPopup(final char charTyped, final Project project, final Editor editor, final PsiFile file) {
|
||||
@@ -106,7 +108,7 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
|
||||
if (file instanceof PsiJavaFile && !(file instanceof JspFile) &&
|
||||
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET &&
|
||||
PsiUtil.isLanguageLevel5OrHigher(file)) {
|
||||
if (handleJavaGT(editor)) return Result.STOP;
|
||||
if (handleJavaGT(editor, JavaTokenType.LT, JavaTokenType.GT, INVALID_INSIDE_REFERENCE)) return Result.STOP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +146,7 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
|
||||
public Result charTyped(final char c, final Project project, final Editor editor, final PsiFile file) {
|
||||
if (myJavaLTTyped) {
|
||||
myJavaLTTyped = false;
|
||||
handleAfterJavaLT(editor);
|
||||
handleAfterJavaLT(editor, JavaTokenType.LT, JavaTokenType.GT, INVALID_INSIDE_REFERENCE);
|
||||
return Result.STOP;
|
||||
}
|
||||
return Result.CONTINUE;
|
||||
@@ -170,7 +172,10 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
|
||||
}
|
||||
|
||||
//need custom handler, since brace matcher cannot be used
|
||||
private static boolean handleJavaGT(final Editor editor) {
|
||||
public static boolean handleJavaGT(final Editor editor,
|
||||
final IElementType lt,
|
||||
final IElementType gt,
|
||||
final TokenSet invalidInsideReference) {
|
||||
if (!CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET) return false;
|
||||
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
@@ -178,24 +183,23 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
|
||||
if (offset == editor.getDocument().getTextLength()) return false;
|
||||
|
||||
HighlighterIterator iterator = ((EditorEx) editor).getHighlighter().createIterator(offset);
|
||||
if (iterator.getTokenType() != JavaTokenType.GT) return false;
|
||||
while (!iterator.atEnd() && !JavaTypedHandlerUtil.isTokenInvalidInsideReference(iterator.getTokenType())) {
|
||||
if (iterator.getTokenType() != gt) return false;
|
||||
while (!iterator.atEnd() && !invalidInsideReference.contains(iterator.getTokenType())) {
|
||||
iterator.advance();
|
||||
}
|
||||
|
||||
if (iterator.atEnd()) return false;
|
||||
if (JavaTypedHandlerUtil.isTokenInvalidInsideReference(iterator.getTokenType())) iterator.retreat();
|
||||
if (!iterator.atEnd() && invalidInsideReference.contains(iterator.getTokenType())) iterator.retreat();
|
||||
|
||||
int balance = 0;
|
||||
while (!iterator.atEnd() && balance >= 0) {
|
||||
final IElementType tokenType = iterator.getTokenType();
|
||||
if (tokenType == JavaTokenType.LT) {
|
||||
if (tokenType == lt) {
|
||||
balance--;
|
||||
}
|
||||
else if (tokenType == JavaTokenType.GT) {
|
||||
else if (tokenType == gt) {
|
||||
balance++;
|
||||
}
|
||||
else if (JavaTypedHandlerUtil.isTokenInvalidInsideReference(tokenType)) {
|
||||
else if (invalidInsideReference.contains(tokenType)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -212,27 +216,30 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
|
||||
}
|
||||
|
||||
//need custom handler, since brace matcher cannot be used
|
||||
private static void handleAfterJavaLT(final Editor editor) {
|
||||
public static void handleAfterJavaLT(final Editor editor,
|
||||
final IElementType lt,
|
||||
final IElementType gt,
|
||||
final TokenSet invalidInsideReference) {
|
||||
if (!CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET) return;
|
||||
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
HighlighterIterator iterator = ((EditorEx) editor).getHighlighter().createIterator(offset);
|
||||
while (iterator.getStart() > 0 && !JavaTypedHandlerUtil.isTokenInvalidInsideReference(iterator.getTokenType())) {
|
||||
while (iterator.getStart() > 0 && !invalidInsideReference.contains(iterator.getTokenType())) {
|
||||
iterator.retreat();
|
||||
}
|
||||
|
||||
if (JavaTypedHandlerUtil.isTokenInvalidInsideReference(iterator.getTokenType())) iterator.advance();
|
||||
if (invalidInsideReference.contains(iterator.getTokenType())) iterator.advance();
|
||||
|
||||
int balance = 0;
|
||||
while (!iterator.atEnd() && balance >= 0) {
|
||||
final IElementType tokenType = iterator.getTokenType();
|
||||
if (tokenType == JavaTokenType.LT) {
|
||||
if (tokenType == lt) {
|
||||
balance++;
|
||||
}
|
||||
else if (tokenType == JavaTokenType.GT) {
|
||||
else if (tokenType == gt) {
|
||||
balance--;
|
||||
}
|
||||
else if (JavaTypedHandlerUtil.isTokenInvalidInsideReference(tokenType)) {
|
||||
else if (invalidInsideReference.contains(tokenType)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -262,7 +269,11 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
|
||||
if (iterator.getStart() > 0) iterator.retreat();
|
||||
final IElementType tokenType = iterator.getTokenType();
|
||||
if (tokenType == JavaTokenType.DOT) return true;
|
||||
if (tokenType == JavaTokenType.IDENTIFIER && iterator.getEnd() == offset) {
|
||||
return isClassLikeIdentifier(offset, editor, iterator, JavaTokenType.IDENTIFIER);
|
||||
}
|
||||
|
||||
public static boolean isClassLikeIdentifier(int offset, Editor editor, HighlighterIterator iterator, final IElementType idType) {
|
||||
if (iterator.getTokenType() == idType && iterator.getEnd() == offset) {
|
||||
final CharSequence chars = editor.getDocument().getCharsSequence();
|
||||
final char startChar = chars.charAt(iterator.getStart());
|
||||
if (!Character.isUpperCase(startChar)) return false;
|
||||
|
||||
+16
-7
@@ -18,6 +18,7 @@ package com.intellij.codeInspection;
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
@@ -26,6 +27,8 @@ import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 1/28/11
|
||||
@@ -76,13 +79,13 @@ public class ExplicitTypeCanBeDiamondInspection extends BaseJavaLocalInspectionT
|
||||
if (typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) return;
|
||||
final PsiDiamondType.DiamondInferenceResult inferenceResult = PsiDiamondType.resolveInferredTypes(expression);
|
||||
if (inferenceResult.getErrorMessage() == null) {
|
||||
final PsiType[] types = inferenceResult.getTypes();
|
||||
final List<PsiType> types = inferenceResult.getInferredTypes();
|
||||
final PsiType[] typeArguments = parameterList.getTypeArguments();
|
||||
if (types.length == typeArguments.length) {
|
||||
if (types.size() == typeArguments.length) {
|
||||
for (int i = 0, typeArgumentsLength = typeArguments.length; i < typeArgumentsLength; i++) {
|
||||
PsiType typeArgument = typeArguments[i];
|
||||
if (types[i] instanceof PsiWildcardType) {
|
||||
final PsiWildcardType wildcardType = (PsiWildcardType)types[i];
|
||||
if (types.get(i) instanceof PsiWildcardType) {
|
||||
final PsiWildcardType wildcardType = (PsiWildcardType)types.get(i);
|
||||
final PsiType bound = wildcardType.getBound();
|
||||
if (bound != null) {
|
||||
if (wildcardType.isExtends()) {
|
||||
@@ -92,7 +95,7 @@ public class ExplicitTypeCanBeDiamondInspection extends BaseJavaLocalInspectionT
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!typeArgument.equals(types[i])) {
|
||||
if (!typeArgument.equals(types.get(i))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -109,6 +112,7 @@ public class ExplicitTypeCanBeDiamondInspection extends BaseJavaLocalInspectionT
|
||||
}
|
||||
|
||||
private static class ReplaceWithDiamondFix implements LocalQuickFix, HighPriorityAction {
|
||||
public static final Logger LOG = Logger.getInstance("#" + ReplaceWithDiamondFix.class.getName());
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
@@ -126,8 +130,13 @@ public class ExplicitTypeCanBeDiamondInspection extends BaseJavaLocalInspectionT
|
||||
final PsiElement psiElement = descriptor.getPsiElement();
|
||||
if (psiElement instanceof PsiReferenceParameterList) {
|
||||
if (!CodeInsightUtilBase.prepareFileForWrite(psiElement.getContainingFile())) return;
|
||||
final PsiTypeElement[] parameterElements = ((PsiReferenceParameterList)psiElement).getTypeParameterElements();
|
||||
psiElement.deleteChildRange(parameterElements[0], parameterElements[parameterElements.length - 1]);
|
||||
final PsiNewExpression expression =
|
||||
(PsiNewExpression)JavaPsiFacade.getElementFactory(project).createExpressionFromText("new a<>()", psiElement);
|
||||
final PsiJavaCodeReferenceElement classReference = expression.getClassReference();
|
||||
LOG.assertTrue(classReference != null);
|
||||
final PsiReferenceParameterList parameterList = classReference.getParameterList();
|
||||
LOG.assertTrue(parameterList != null);
|
||||
psiElement.replace(parameterList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+52
-57
@@ -48,12 +48,10 @@ import java.util.*;
|
||||
|
||||
public class JavaDocReferenceInspection extends BaseLocalInspectionTool {
|
||||
@NonNls public static final String SHORT_NAME = "JavadocReference";
|
||||
public static final String DISPLAY_NAME = InspectionsBundle.message("inspection.javadoc.ref.display.name");
|
||||
|
||||
|
||||
private static ProblemDescriptor createDescriptor(@NotNull PsiElement element, String template, InspectionManager manager,
|
||||
boolean onTheFly) {
|
||||
return manager.createProblemDescriptor(element, template, onTheFly, (LocalQuickFix [])null, ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
||||
return manager.createProblemDescriptor(element, template, onTheFly, null, ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -66,9 +64,14 @@ public class JavaDocReferenceInspection extends BaseLocalInspectionTool {
|
||||
return checkMember(field, manager, isOnTheFly);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ProblemDescriptor[] checkClass(@NotNull PsiClass aClass, @NotNull InspectionManager manager, boolean isOnTheFly) {
|
||||
return checkMember(aClass, manager, isOnTheFly);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ProblemDescriptor[] checkMember(final PsiDocCommentOwner docCommentOwner, final InspectionManager manager, final boolean isOnTheFly) {
|
||||
ArrayList<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>();
|
||||
final ArrayList<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>();
|
||||
final PsiDocComment docComment = docCommentOwner.getDocComment();
|
||||
if (docComment == null) return null;
|
||||
|
||||
@@ -77,26 +80,20 @@ public class JavaDocReferenceInspection extends BaseLocalInspectionTool {
|
||||
for (PsiJavaCodeReferenceElement reference : references) {
|
||||
final List<PsiClass> classesToImport = new ImportClassFix(reference).getClassesToImport();
|
||||
final PsiElement referenceNameElement = reference.getReferenceNameElement();
|
||||
problems.add(manager.createProblemDescriptor(referenceNameElement != null ? referenceNameElement : reference, cannotResolveSymbolMessage("<code>" + reference.getText() + "</code>"),
|
||||
!isOnTheFly || classesToImport.isEmpty() ? null : new AddImportFix(classesToImport), ProblemHighlightType.LIKE_UNKNOWN_SYMBOL,
|
||||
isOnTheFly));
|
||||
problems.add(manager.createProblemDescriptor(referenceNameElement != null ? referenceNameElement : reference,
|
||||
cannotResolveSymbolMessage("<code>" + reference.getText() + "</code>"),
|
||||
!isOnTheFly || classesToImport.isEmpty() ? null : new AddImportFix(classesToImport),
|
||||
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL, isOnTheFly));
|
||||
}
|
||||
|
||||
return problems.isEmpty()
|
||||
? null
|
||||
: problems.toArray(new ProblemDescriptor[problems.size()]);
|
||||
return problems.isEmpty() ? null : problems.toArray(new ProblemDescriptor[problems.size()]);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ProblemDescriptor[] checkClass(@NotNull PsiClass aClass, @NotNull InspectionManager manager, boolean isOnTheFly) {
|
||||
return checkMember(aClass, manager, isOnTheFly);
|
||||
}
|
||||
|
||||
|
||||
private PsiElementVisitor getVisitor(final Set<PsiJavaCodeReferenceElement> references,
|
||||
final PsiElement context,
|
||||
final ArrayList<ProblemDescriptor> problems,
|
||||
final InspectionManager manager, final boolean onTheFly) {
|
||||
final InspectionManager manager,
|
||||
final boolean onTheFly) {
|
||||
return new JavaElementVisitor() {
|
||||
@Override public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
visitElement(expression);
|
||||
@@ -137,58 +134,56 @@ public class JavaDocReferenceInspection extends BaseLocalInspectionTool {
|
||||
};
|
||||
}
|
||||
|
||||
public static void visitRefInDocTag(final PsiDocTag tag, final JavadocManager manager, final PsiElement context, ArrayList<ProblemDescriptor> problems,
|
||||
InspectionManager inspectionManager,
|
||||
boolean onTheFly) {
|
||||
public static void visitRefInDocTag(final PsiDocTag tag,
|
||||
final JavadocManager manager,
|
||||
final PsiElement context,
|
||||
final ArrayList<ProblemDescriptor> problems,
|
||||
final InspectionManager inspectionManager,
|
||||
final boolean onTheFly) {
|
||||
final String tagName = tag.getName();
|
||||
PsiDocTagValue value = tag.getValueElement();
|
||||
final PsiDocTagValue value = tag.getValueElement();
|
||||
if (value == null) return;
|
||||
final JavadocTagInfo info = manager.getTagInfo(tagName);
|
||||
if (info != null && !info.isValidInContext(context)) return;
|
||||
String message = info == null || !info.isInline() ? null : info.checkTagValue(value);
|
||||
final String message = info == null || !info.isInline() ? null : info.checkTagValue(value);
|
||||
if (message != null){
|
||||
problems.add(createDescriptor(value, message, inspectionManager, onTheFly));
|
||||
}
|
||||
|
||||
final PsiReference reference = value.getReference();
|
||||
if (reference != null) {
|
||||
PsiElement element = reference.resolve();
|
||||
if (element == null) {
|
||||
final int textOffset = value.getTextOffset();
|
||||
if (reference == null) return;
|
||||
final PsiElement element = reference.resolve();
|
||||
if (element != null) return;
|
||||
final int textOffset = value.getTextOffset();
|
||||
if (textOffset == value.getTextRange().getEndOffset()) return;
|
||||
final PsiDocTagValue valueElement = tag.getValueElement();
|
||||
if (valueElement == null) return;
|
||||
|
||||
if (textOffset != value.getTextRange().getEndOffset()) {
|
||||
final PsiDocTagValue valueElement = tag.getValueElement();
|
||||
if (valueElement != null) {
|
||||
final CharSequence paramName =
|
||||
value.getContainingFile().getViewProvider().getContents().subSequence(textOffset, value.getTextRange().getEndOffset());
|
||||
@NonNls String params = "<code>" + paramName + "</code>";
|
||||
|
||||
final List<LocalQuickFix> fixes = new ArrayList<LocalQuickFix>();
|
||||
if (onTheFly && "param".equals(tagName)) {
|
||||
final PsiDocCommentOwner commentOwner = PsiTreeUtil.getParentOfType(tag, PsiDocCommentOwner.class);
|
||||
if (commentOwner instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)commentOwner;
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
final PsiDocTag[] tags = tag.getContainingComment().getTags();
|
||||
final Set<String> unboundParams = new HashSet<String>();
|
||||
for (PsiParameter parameter : parameters) {
|
||||
if (!JavaDocLocalInspection.isFound(tags, parameter)) {
|
||||
unboundParams.add(parameter.getName());
|
||||
}
|
||||
}
|
||||
if (!unboundParams.isEmpty()) {
|
||||
fixes.add(new RenameReferenceQuickFix(unboundParams));
|
||||
}
|
||||
}
|
||||
}
|
||||
fixes.add(new RemoveTagFix(tagName, paramName, tag));
|
||||
|
||||
problems.add(inspectionManager.createProblemDescriptor(valueElement, reference.getRangeInElement(), cannotResolveSymbolMessage(params),
|
||||
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL, onTheFly,
|
||||
fixes.toArray(new LocalQuickFix[fixes.size()])));
|
||||
final CharSequence paramName = value.getContainingFile().getViewProvider().getContents().subSequence(textOffset, value.getTextRange().getEndOffset());
|
||||
final String params = "<code>" + paramName + "</code>";
|
||||
final List<LocalQuickFix> fixes = new ArrayList<LocalQuickFix>();
|
||||
if (onTheFly && "param".equals(tagName)) {
|
||||
final PsiDocCommentOwner commentOwner = PsiTreeUtil.getParentOfType(tag, PsiDocCommentOwner.class);
|
||||
if (commentOwner instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)commentOwner;
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
final PsiDocTag[] tags = tag.getContainingComment().getTags();
|
||||
final Set<String> unboundParams = new HashSet<String>();
|
||||
for (PsiParameter parameter : parameters) {
|
||||
if (!JavaDocLocalInspection.isFound(tags, parameter)) {
|
||||
unboundParams.add(parameter.getName());
|
||||
}
|
||||
}
|
||||
if (!unboundParams.isEmpty()) {
|
||||
fixes.add(new RenameReferenceQuickFix(unboundParams));
|
||||
}
|
||||
}
|
||||
}
|
||||
fixes.add(new RemoveTagFix(tagName, paramName, tag));
|
||||
|
||||
problems.add(inspectionManager.createProblemDescriptor(valueElement, reference.getRangeInElement(), cannotResolveSymbolMessage(params),
|
||||
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL, onTheFly,
|
||||
fixes.toArray(new LocalQuickFix[fixes.size()])));
|
||||
}
|
||||
|
||||
private static String cannotResolveSymbolMessage(String params) {
|
||||
@@ -197,7 +192,7 @@ public class JavaDocReferenceInspection extends BaseLocalInspectionTool {
|
||||
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return DISPLAY_NAME;
|
||||
return InspectionsBundle.message("inspection.javadoc.ref.display.name");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.psi.controlFlow;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class LocalsControlFlowPolicy implements ControlFlowPolicy {
|
||||
private final PsiElement myCodeFragment;
|
||||
@@ -36,6 +37,7 @@ public class LocalsControlFlowPolicy implements ControlFlowPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiVariable checkCodeFragment(PsiElement refElement) {
|
||||
PsiElement codeFragement;
|
||||
if (refElement instanceof PsiParameter
|
||||
@@ -45,6 +47,7 @@ public class LocalsControlFlowPolicy implements ControlFlowPolicy {
|
||||
else{
|
||||
codeFragement = ControlFlowUtil.findCodeFragment(refElement);
|
||||
}
|
||||
if (codeFragement == null) return null;
|
||||
if (myCodeFragment.getContainingFile() == codeFragement.getContainingFile() && //In order for jsp includes to work
|
||||
!myCodeFragment.equals(codeFragement)) return null;
|
||||
return (PsiVariable)refElement;
|
||||
|
||||
+83
-85
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source.javadoc;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.Constants;
|
||||
@@ -29,9 +29,9 @@ import com.intellij.psi.javadoc.PsiDocTagValue;
|
||||
import com.intellij.psi.scope.ElementClassFilter;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.scope.processor.FilterScopeProcessor;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.CharTable;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -85,8 +85,6 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
@Nullable
|
||||
private PsiReference getReferenceInScope(PsiElement scope, PsiElement element) {
|
||||
final String name = element.getText();
|
||||
|
||||
|
||||
final String[] signature = getSignature();
|
||||
|
||||
if (signature == null) {
|
||||
@@ -97,49 +95,44 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
}
|
||||
}
|
||||
|
||||
final PsiMethod[] methods = getAllMethods(scope, this);
|
||||
|
||||
nextMethod:
|
||||
for (PsiMethod method : methods) {
|
||||
if (!method.getName().equals(name)) continue;
|
||||
|
||||
if (signature == null) {
|
||||
return new MyReference(method);
|
||||
}
|
||||
else {
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
if (parameters.length != signature.length) continue;
|
||||
for (int j = 0; j < parameters.length; j++) {
|
||||
PsiParameter parameter = parameters[j];
|
||||
PsiType type1 = TypeConversionUtil.erasure(parameter.getType());
|
||||
String type2 = signature[j];
|
||||
if (!Comparing.strEqual(type1.getPresentableText(), type2) && !Comparing.strEqual(type1.getCanonicalText(), type2)) {
|
||||
String shortName = "";
|
||||
PsiClass psiClass = PsiUtil.resolveClassInType(type1);
|
||||
while (psiClass != null) {
|
||||
shortName = psiClass.getName() + (shortName.length() > 0 ? "." + shortName : "");
|
||||
psiClass = PsiTreeUtil.getParentOfType(psiClass, PsiClass.class);
|
||||
}
|
||||
if (!Comparing.strEqual(shortName, type2)) {
|
||||
continue nextMethod;
|
||||
}
|
||||
}
|
||||
final MethodSignature methodSignature;
|
||||
if (signature != null) {
|
||||
final List<PsiType> types = Lists.newArrayListWithCapacity(signature.length);
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(element.getProject()).getElementFactory();
|
||||
for (String s : signature) {
|
||||
try {
|
||||
types.add(elementFactory.createTypeFromText(s, scope));
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
types.add(PsiType.NULL);
|
||||
}
|
||||
|
||||
return new MyReference(method) {
|
||||
@NotNull
|
||||
public PsiElement[] getVariants() {
|
||||
final List<PsiMethod> lst = new ArrayList<PsiMethod>();
|
||||
for (PsiMethod method : methods) {
|
||||
if (name.equals(method.getName())) {
|
||||
lst.add(method);
|
||||
}
|
||||
}
|
||||
return lst.toArray(new PsiMethod[lst.size()]);
|
||||
}
|
||||
};
|
||||
}
|
||||
methodSignature = MethodSignatureUtil.createMethodSignature(name, types.toArray(new PsiType[types.size()]),
|
||||
PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
|
||||
}
|
||||
else {
|
||||
methodSignature = MethodSignatureUtil.createMethodSignature(name, PsiType.EMPTY_ARRAY,
|
||||
PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
|
||||
}
|
||||
|
||||
final PsiMethod[] methods = getAllMethods(scope, this);
|
||||
for (PsiMethod method : methods) {
|
||||
if (!method.getName().equals(name) ||
|
||||
!MethodSignatureUtil.areSignaturesErasureEqual(methodSignature, method.getSignature(PsiSubstitutor.EMPTY))) continue;
|
||||
return new MyReference(method) {
|
||||
@NotNull
|
||||
public PsiElement[] getVariants() {
|
||||
final List<PsiMethod> lst = new ArrayList<PsiMethod>();
|
||||
for (PsiMethod method : methods) {
|
||||
if (name.equals(method.getName())) {
|
||||
lst.add(method);
|
||||
}
|
||||
}
|
||||
return lst.toArray(new PsiMethod[lst.size()]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -157,34 +150,30 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
|
||||
public int getTextOffset() {
|
||||
final PsiElement element = getNameElement();
|
||||
|
||||
if (element != null) {
|
||||
return element.getTextRange().getStartOffset();
|
||||
}
|
||||
|
||||
return getTextRange().getEndOffset();
|
||||
return element != null ? element.getTextRange().getStartOffset() : getTextRange().getEndOffset();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getNameElement() {
|
||||
final ASTNode sharp = findChildByType(DOC_TAG_VALUE_SHARP_TOKEN);
|
||||
if (sharp == null) return null;
|
||||
return SourceTreeToPsiMap.treeElementToPsi(sharp).getNextSibling();
|
||||
return sharp != null ? SourceTreeToPsiMap.treeToPsiNotNull(sharp).getNextSibling() : null;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public String[] getSignature() {
|
||||
PsiElement element = getNameElement().getNextSibling();
|
||||
PsiElement element = getNameElement();
|
||||
if (element == null) return null;
|
||||
|
||||
element = element.getNextSibling();
|
||||
while (element != null && !(element instanceof PsiDocTagValue)) {
|
||||
element = element.getNextSibling();
|
||||
}
|
||||
|
||||
if (element == null) return null;
|
||||
|
||||
List<String> types = new ArrayList<String>();
|
||||
for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
|
||||
if (child.getNode().getElementType() == DOC_TYPE_HOLDER) {
|
||||
final String[] typeStrings = child.getText().split("[, ]"); //avoid param types list parsing hmm mathod(paramType1, paramType2, ...) -> typeElement1, identifier2, ...
|
||||
final String[] typeStrings = child.getText().split("[, ]"); //avoid param types list parsing hmm method(paramType1, paramType2, ...) -> typeElement1, identifier2, ...
|
||||
if (typeStrings != null) {
|
||||
for (String type : typeStrings) {
|
||||
if (type.length() > 0) {
|
||||
@@ -224,14 +213,14 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
}
|
||||
|
||||
public class MyReference implements PsiJavaReference {
|
||||
private final PsiElement myReferencee;
|
||||
private final PsiElement myReferredElement;
|
||||
|
||||
public MyReference(PsiElement referencee) {
|
||||
myReferencee = referencee;
|
||||
public MyReference(PsiElement referredElement) {
|
||||
myReferredElement = referredElement;
|
||||
}
|
||||
|
||||
public PsiElement resolve() {
|
||||
return myReferencee;
|
||||
return myReferredElement;
|
||||
}
|
||||
|
||||
public void processVariants(PsiScopeProcessor processor) {
|
||||
@@ -244,12 +233,14 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
|
||||
@NotNull
|
||||
public JavaResolveResult advancedResolve(boolean incompleteCode) {
|
||||
return myReferencee == null ? JavaResolveResult.EMPTY : new CandidateInfo(myReferencee, PsiSubstitutor.EMPTY);
|
||||
return myReferredElement == null ? JavaResolveResult.EMPTY
|
||||
: new CandidateInfo(myReferredElement, PsiSubstitutor.EMPTY);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JavaResolveResult[] multiResolve(boolean incompleteCode) {
|
||||
return myReferencee == null ? JavaResolveResult.EMPTY_ARRAY : new JavaResolveResult[]{new CandidateInfo(myReferencee, PsiSubstitutor.EMPTY)};
|
||||
return myReferredElement == null ? JavaResolveResult.EMPTY_ARRAY
|
||||
: new JavaResolveResult[]{new CandidateInfo(myReferredElement, PsiSubstitutor.EMPTY)};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -269,21 +260,26 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
|
||||
@NotNull
|
||||
public String getCanonicalText() {
|
||||
return getNameElement().getText();
|
||||
final PsiElement nameElement = getNameElement();
|
||||
assert nameElement != null;
|
||||
return nameElement.getText();
|
||||
}
|
||||
|
||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
final PsiElement element = getNameElement();
|
||||
final ASTNode treeElement = SourceTreeToPsiMap.psiElementToTree(element);
|
||||
final PsiElement nameElement = getNameElement();
|
||||
assert nameElement != null;
|
||||
final ASTNode treeElement = SourceTreeToPsiMap.psiToTreeNotNull(nameElement);
|
||||
final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(treeElement);
|
||||
LeafElement newToken = Factory.createSingleLeafElement(DOC_TAG_VALUE_TOKEN, newElementName, charTableByTree, getManager());
|
||||
((CompositeElement)treeElement.getTreeParent()).replaceChildInternal(SourceTreeToPsiMap.psiElementToTree(element), newToken);
|
||||
return SourceTreeToPsiMap.treeElementToPsi(newToken);
|
||||
final LeafElement newToken = Factory.createSingleLeafElement(DOC_TAG_VALUE_TOKEN, newElementName, charTableByTree, getManager());
|
||||
((CompositeElement)treeElement.getTreeParent()).replaceChildInternal(SourceTreeToPsiMap.psiToTreeNotNull(nameElement), newToken);
|
||||
return SourceTreeToPsiMap.treeToPsiNotNull(newToken);
|
||||
}
|
||||
|
||||
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
if (isReferenceTo(element)) return PsiDocMethodOrFieldRef.this;
|
||||
final String name = getNameElement().getText();
|
||||
final PsiElement nameElement = getNameElement();
|
||||
assert nameElement != null;
|
||||
final String name = nameElement.getText();
|
||||
final String newName;
|
||||
|
||||
final PsiMethod method;
|
||||
@@ -305,15 +301,16 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
|
||||
if (getFirstChild().getNode().getElementType() == ElementType.DOC_REFERENCE_HOLDER) {
|
||||
PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement) getFirstChild().getFirstChild();
|
||||
final PsiElement child = getFirstChild();
|
||||
if (containingClass != null && child != null && child.getNode().getElementType() == ElementType.DOC_REFERENCE_HOLDER) {
|
||||
final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement) child.getFirstChild();
|
||||
assert referenceElement != null;
|
||||
referenceElement.bindToElement(containingClass);
|
||||
}
|
||||
else {
|
||||
if (!PsiTreeUtil.isAncestor(containingClass, PsiDocMethodOrFieldRef.this, true)) {
|
||||
final PsiReferenceExpression ref =
|
||||
JavaPsiFacade.getInstance(containingClass.getProject()).getElementFactory().createReferenceExpression(containingClass);
|
||||
if (containingClass != null && !PsiTreeUtil.isAncestor(containingClass, PsiDocMethodOrFieldRef.this, true)) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(containingClass.getProject()).getElementFactory();
|
||||
final PsiReferenceExpression ref = elementFactory.createReferenceExpression(containingClass);
|
||||
addAfter(ref, null);
|
||||
}
|
||||
}
|
||||
@@ -352,10 +349,11 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
}
|
||||
|
||||
public PsiElement bindToText(PsiClass containingClass, StringBuffer newText) {
|
||||
PsiComment comment =
|
||||
JavaPsiFacade.getInstance(containingClass.getProject()).getElementFactory().createCommentFromText(newText.toString(), null);
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getInstance(containingClass.getProject()).getElementFactory();
|
||||
PsiComment comment = elementFactory.createCommentFromText(newText.toString(), null);
|
||||
PsiElement tag = PsiTreeUtil.getChildOfType(comment, PsiDocTag.class);
|
||||
PsiElement ref = PsiTreeUtil.getChildOfType(tag, PsiDocMethodOrFieldRef.class);
|
||||
assert ref != null : newText;
|
||||
return replace(ref);
|
||||
}
|
||||
|
||||
@@ -366,20 +364,20 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
public TextRange getRangeInElement() {
|
||||
final ASTNode sharp = findChildByType(DOC_TAG_VALUE_SHARP_TOKEN);
|
||||
if (sharp == null) return new TextRange(0, getTextLength());
|
||||
final PsiElement nextSibling = SourceTreeToPsiMap.treeElementToPsi(sharp).getNextSibling();
|
||||
if(nextSibling != null){
|
||||
final PsiElement nextSibling = SourceTreeToPsiMap.treeToPsiNotNull(sharp).getNextSibling();
|
||||
if (nextSibling != null) {
|
||||
final int startOffset = nextSibling.getTextRange().getStartOffset() - getTextRange().getStartOffset();
|
||||
int endOffset = nextSibling.getTextRange().getEndOffset() - getTextRange().getStartOffset();
|
||||
final PsiElement nextParSibling = nextSibling.getNextSibling();
|
||||
if(nextParSibling != null && "(".equals(nextParSibling.getText())){
|
||||
endOffset ++;
|
||||
if (nextParSibling != null && "(".equals(nextParSibling.getText())) {
|
||||
endOffset++;
|
||||
PsiElement nextElement = nextParSibling.getNextSibling();
|
||||
if(nextElement != null && SourceTreeToPsiMap.psiElementToTree(nextElement).getElementType() == DOC_TAG_VALUE_TOKEN){
|
||||
if (nextElement != null && SourceTreeToPsiMap.psiToTreeNotNull(nextElement).getElementType() == DOC_TAG_VALUE_TOKEN) {
|
||||
endOffset += nextElement.getTextLength();
|
||||
nextElement = nextElement.getNextSibling();
|
||||
}
|
||||
if(nextElement != null && ")".equals(nextElement.getText())){
|
||||
endOffset ++;
|
||||
if (nextElement != null && ")".equals(nextElement.getText())) {
|
||||
endOffset++;
|
||||
}
|
||||
}
|
||||
return new TextRange(startOffset, endOffset);
|
||||
|
||||
@@ -373,8 +373,11 @@ public class ExtractMethodDialog extends AbstractExtractDialog {
|
||||
buffer.append("static ");
|
||||
}
|
||||
if (myTypeParameterList != null) {
|
||||
buffer.append(myTypeParameterList.getText());
|
||||
buffer.append(" ");
|
||||
final String typeParamsText = myTypeParameterList.getText();
|
||||
if (!typeParamsText.isEmpty()) {
|
||||
buffer.append(typeParamsText);
|
||||
buffer.append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
if (isChainedConstructor()) {
|
||||
|
||||
+7
-3
@@ -28,6 +28,7 @@ import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.ChangeContextUtil;
|
||||
import com.intellij.codeInsight.TestUtil;
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager;
|
||||
import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.ide.util.DirectoryChooserUtil;
|
||||
import com.intellij.ide.util.PackageUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -552,15 +553,18 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
public void pass(final ElementToWorkOn elementToWorkOn) {
|
||||
if (elementToWorkOn == null) return;
|
||||
|
||||
final boolean hasRunTemplate = LookupManager.getActiveLookup(editor) == null;
|
||||
if (elementToWorkOn.getExpression() == null) {
|
||||
final PsiLocalVariable localVariable = elementToWorkOn.getLocalVariable();
|
||||
final boolean result = invokeImpl(project, localVariable, editor);
|
||||
final boolean result = invokeImpl(project, localVariable, editor) && hasRunTemplate;
|
||||
if (result) {
|
||||
editor.getSelectionModel().removeSelection();
|
||||
}
|
||||
}
|
||||
else if (invokeImpl(project, elementToWorkOn.getExpression(), editor)) {
|
||||
editor.getSelectionModel().removeSelection();
|
||||
else {
|
||||
if (invokeImpl(project, elementToWorkOn.getExpression(), editor) && hasRunTemplate) {
|
||||
editor.getSelectionModel().removeSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
+1
-1
@@ -397,7 +397,7 @@ class IntroduceConstantDialog extends DialogWrapper {
|
||||
errorString = RefactoringBundle.message("no.field.name.specified");
|
||||
} else if (!JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(fieldName)) {
|
||||
errorString = RefactoringMessageUtil.getIncorrectIdentifierMessage(fieldName);
|
||||
} else if (!myParentClass.getLanguage().equals(newClass.getLanguage())) {
|
||||
} else if (newClass != null && !myParentClass.getLanguage().equals(newClass.getLanguage())) {
|
||||
errorString = RefactoringBundle.message("move.to.different.language", UsageViewUtil.getType(myParentClass),
|
||||
myParentClass.getQualifiedName(), newClass.getQualifiedName());
|
||||
}
|
||||
|
||||
+160
-109
@@ -17,6 +17,8 @@ package com.intellij.refactoring.introduceParameter;
|
||||
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager;
|
||||
import com.intellij.codeInsight.intention.impl.TypeExpression;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.ide.IdeTooltipManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
@@ -33,17 +35,17 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.introduceVariable.OccurrencesChooser;
|
||||
import com.intellij.refactoring.introduceVariable.VariableInplaceIntroducer;
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
|
||||
import com.intellij.refactoring.ui.NameSuggestionsGenerator;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManager;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.ui.NonFocusableCheckBox;
|
||||
import com.intellij.ui.TitlePanel;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import gnu.trove.TIntArrayList;
|
||||
@@ -61,30 +63,30 @@ import java.util.List;
|
||||
* Date: 2/25/11
|
||||
*/
|
||||
class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
private JCheckBox myDelegateCb;
|
||||
|
||||
private Balloon myBalloon;
|
||||
private final Project myProject;
|
||||
private final Editor myEditor;
|
||||
private final TypeSelectorManagerImpl myTypeSelectorManager;
|
||||
private final NameSuggestionsGenerator myNameSuggestionsGenerator;
|
||||
private final PsiExpression myExpr;
|
||||
private PsiExpression myExpr;
|
||||
private final PsiLocalVariable myLocalVar;
|
||||
private final PsiMethod myMethod;
|
||||
private final PsiMethod myMethodToSearchFor;
|
||||
private final PsiExpression[] myOccurrences;
|
||||
private final boolean myMustBeFinal;
|
||||
private final RangeMarker myExprMarker;
|
||||
private final List<RangeMarker> myOccurrenceMarkers;
|
||||
private RangeMarker myExprMarker;
|
||||
private List<RangeMarker> myOccurrenceMarkers;
|
||||
|
||||
private final JPanel myWholePanel;
|
||||
private int myParameterIndex = -1;
|
||||
private String myParameterName;
|
||||
private final String myExprText;
|
||||
|
||||
|
||||
InplaceIntroduceParameterPopup(final Project project,
|
||||
final Editor editor,
|
||||
final List<UsageInfo> classMemberRefs,
|
||||
final TypeSelectorManagerImpl typeSelectorManager,
|
||||
final NameSuggestionsGenerator nameSuggestionsGenerator,
|
||||
final PsiExpression expr,
|
||||
final PsiLocalVariable localVar,
|
||||
final PsiMethod method,
|
||||
@@ -96,7 +98,6 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
myProject = project;
|
||||
myEditor = editor;
|
||||
myTypeSelectorManager = typeSelectorManager;
|
||||
myNameSuggestionsGenerator = nameSuggestionsGenerator;
|
||||
myExpr = expr;
|
||||
myLocalVar = localVar;
|
||||
myMethod = method;
|
||||
@@ -104,14 +105,23 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
myOccurrences = occurrences;
|
||||
myMustBeFinal = mustBeFinal;
|
||||
myExprMarker = expr != null ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null;
|
||||
myOccurrenceMarkers = new ArrayList<RangeMarker>();
|
||||
myExprText = myExpr != null ? myExpr.getText() : null;
|
||||
|
||||
myWholePanel = new JPanel(new GridBagLayout());
|
||||
myWholePanel.setBorder(BorderFactory.createTitledBorder(IntroduceParameterHandler.REFACTORING_NAME));
|
||||
myDelegateCb = new NonFocusableCheckBox(RefactoringBundle.message("delegation.panel.delegate.via.overloading.method"));
|
||||
myWholePanel.setBorder(null);
|
||||
final GridBagConstraints gc =
|
||||
new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 0), 0, 0);
|
||||
myWholePanel.add(myDelegateCb, gc);
|
||||
new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0);
|
||||
|
||||
final TitlePanel titlePanel = new TitlePanel();
|
||||
titlePanel.setBorder(null);
|
||||
titlePanel.setText(IntroduceParameterHandler.REFACTORING_NAME);
|
||||
myWholePanel.add(titlePanel, gc);
|
||||
|
||||
gc.insets = new Insets(5, 5, 5, 0);
|
||||
if (myOccurrences.length > 1 && !myIsInvokedOnDeclaration) {
|
||||
gc.gridy++;
|
||||
createOccurrencesCb(gc, myWholePanel, myOccurrences.length);
|
||||
}
|
||||
final JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance();
|
||||
createLocalVariablePanel(gc, myWholePanel, settings);
|
||||
createRemoveParamsPanel(gc, myWholePanel);
|
||||
@@ -119,52 +129,75 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
gc.gridy++;
|
||||
myWholePanel.add(createReplaceFieldsWithGettersPanel(), gc);
|
||||
}
|
||||
gc.gridy++;
|
||||
createDelegateCb(gc, myWholePanel);
|
||||
}
|
||||
|
||||
|
||||
void inplaceIntroduceParameter() {
|
||||
final LinkedHashMap<OccurrencesChooser.ReplaceChoice, PsiExpression[]> occurrencesMap =
|
||||
new LinkedHashMap<OccurrencesChooser.ReplaceChoice, PsiExpression[]>();
|
||||
startIntroduceTemplate(false);
|
||||
}
|
||||
|
||||
for (PsiExpression occurrence : myOccurrences) {
|
||||
myOccurrenceMarkers.add(myEditor.getDocument().createRangeMarker(occurrence.getTextRange()));
|
||||
}
|
||||
|
||||
OccurrencesChooser.fillChoices(myExpr, myOccurrences, occurrencesMap);
|
||||
new OccurrencesChooser(myEditor).showChooser(new IntroduceParameterPass(), occurrencesMap);
|
||||
private void startIntroduceTemplate(final boolean replaceAllOccurrences) {
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
myTypeSelectorManager.setAllOccurences(replaceAllOccurrences);
|
||||
final PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
final String propName = myLocalVar != null ? JavaCodeStyleManager
|
||||
.getInstance(myProject).variableNameToPropertyName(myLocalVar.getName(), VariableKind.LOCAL_VARIABLE) : null;
|
||||
final String[] names = IntroduceParameterHandler.createNameSuggestionGenerator(myExpr, propName, myProject)
|
||||
.getSuggestedNameInfo(defaultType).names;
|
||||
final PsiParameter parameter = createParameterToStartTemplateOn(names, defaultType);
|
||||
if (parameter != null) {
|
||||
myParameterIndex = myMethod.getParameterList().getParameterIndex(parameter);
|
||||
myEditor.getCaretModel().moveToOffset(parameter.getTextOffset());
|
||||
showBalloon();
|
||||
final LinkedHashSet<String> nameSuggestions = new LinkedHashSet<String>();
|
||||
nameSuggestions.add(parameter.getName());
|
||||
nameSuggestions.addAll(Arrays.asList(names));
|
||||
final VariableInplaceRenamer renamer = new ParameterInplaceIntroducer(parameter);
|
||||
renamer.performInplaceRename(false, nameSuggestions);
|
||||
}
|
||||
}
|
||||
}, IntroduceParameterHandler.REFACTORING_NAME, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateControls(JCheckBox[] removeParamsCb) {
|
||||
protected TypeSelectorManager getTypeSelectionManager() {
|
||||
return myTypeSelectorManager;
|
||||
}
|
||||
|
||||
private PsiParameter getParameter() {
|
||||
return myMethod.getParameterList().getParameters()[myParameterIndex];
|
||||
}
|
||||
|
||||
public List<RangeMarker> getOccurrenceMarkers() {
|
||||
if (myOccurrenceMarkers == null) {
|
||||
myOccurrenceMarkers = new ArrayList<RangeMarker>();
|
||||
for (PsiExpression occurrence : myOccurrences) {
|
||||
myOccurrenceMarkers.add(myEditor.getDocument().createRangeMarker(occurrence.getTextRange()));
|
||||
}
|
||||
}
|
||||
return myOccurrenceMarkers;
|
||||
}
|
||||
|
||||
private class ParameterInplaceIntroducer extends VariableInplaceIntroducer {
|
||||
private String myParameterName;
|
||||
|
||||
private SmartTypePointer myParameterTypePointer;
|
||||
private SmartTypePointer myDefaultParameterTypePointer;
|
||||
private final PsiParameter myParameter;
|
||||
private int myParameterIndex;
|
||||
|
||||
private PsiExpression myExpression;
|
||||
private final OccurrencesChooser.ReplaceChoice myReplaceChoice;
|
||||
private boolean myFinal;
|
||||
private final String myExprText;
|
||||
|
||||
public ParameterInplaceIntroducer(PsiParameter parameter,
|
||||
OccurrencesChooser.ReplaceChoice replaceChoice) {
|
||||
public ParameterInplaceIntroducer(PsiParameter parameter) {
|
||||
super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()),
|
||||
myEditor, parameter, myMustBeFinal,
|
||||
myTypeSelectorManager.getTypesForAll().length > 1, myExprMarker, myOccurrenceMarkers);
|
||||
myParameter = parameter;
|
||||
myReplaceChoice = replaceChoice;
|
||||
myExprText = myExpr != null ? myExpr.getText() : null;
|
||||
myParameterIndex = myMethod.getParameterList().getParameterIndex(myParameter);
|
||||
myTypeSelectorManager.getTypesForAll().length > 1, myExprMarker, getOccurrenceMarkers());
|
||||
myDefaultParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(parameter.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiVariable getVariable() {
|
||||
return myMethod.getParameterList().getParameters()[myParameterIndex];
|
||||
return getParameter();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -184,8 +217,13 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
|
||||
@Override
|
||||
protected void collectAdditionalElementsToRename(boolean processTextOccurrences, List<Pair<PsiElement, TextRange>> stringUsages) {
|
||||
for (PsiExpression expression : myOccurrences) {
|
||||
stringUsages.add(Pair.<PsiElement, TextRange>create(expression, new TextRange(0, expression.getTextLength())));
|
||||
if (isReplaceAllOccurences()) {
|
||||
for (PsiExpression expression : myOccurrences) {
|
||||
stringUsages.add(Pair.<PsiElement, TextRange>create(expression, new TextRange(0, expression.getTextLength())));
|
||||
}
|
||||
}
|
||||
else if (myExpr != null) {
|
||||
stringUsages.add(Pair.<PsiElement, TextRange>create(myExpr, new TextRange(0, myExpr.getTextLength())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,9 +240,16 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
@NotNull HighlightManager highlightManager) {
|
||||
final TextAttributes attributes =
|
||||
EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
|
||||
for (RangeMarker marker : myOccurrenceMarkers) {
|
||||
final int startOffset = marker.getStartOffset();
|
||||
highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + myParameter.getName().length(), attributes, 0, highlighters, null);
|
||||
final int variableNameLength = getVariable().getName().length();
|
||||
if (isReplaceAllOccurences()) {
|
||||
for (RangeMarker marker : getOccurrenceMarkers()) {
|
||||
final int startOffset = marker.getStartOffset();
|
||||
highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + variableNameLength, attributes, 0, highlighters, null);
|
||||
}
|
||||
}
|
||||
else if (myExpr != null) {
|
||||
final int startOffset = myExprMarker.getStartOffset();
|
||||
highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + variableNameLength, attributes, 0, highlighters, null);
|
||||
}
|
||||
super.addHighlights(ranges, editor, highlighters, highlightManager);
|
||||
}
|
||||
@@ -222,7 +267,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
if (success) {
|
||||
boolean isDeleteLocalVariable = false;
|
||||
|
||||
PsiExpression parameterInitializer = myExpression;
|
||||
PsiExpression parameterInitializer = myExpr;
|
||||
if (myLocalVar != null) {
|
||||
if (isUseInitializer()) {
|
||||
parameterInitializer = myLocalVar.getInitializer();
|
||||
@@ -233,10 +278,10 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
|
||||
final IntroduceParameterProcessor processor =
|
||||
new IntroduceParameterProcessor(myProject, myMethod,
|
||||
myMethodToSearchFor, parameterInitializer, myExpression,
|
||||
myMethodToSearchFor, parameterInitializer, myExpr,
|
||||
myLocalVar, isDeleteLocalVariable, myParameterName,
|
||||
myReplaceChoice == OccurrencesChooser.ReplaceChoice.ALL,
|
||||
getReplaceFieldsWithGetters(), myMustBeFinal || myFinal, myDelegateCb.isSelected(),
|
||||
isReplaceAllOccurences(),
|
||||
getReplaceFieldsWithGetters(), myMustBeFinal || myFinal, isGenerateDelegate(),
|
||||
myParameterTypePointer.getType(),
|
||||
parametersToRemove);
|
||||
processor.setPrepareSuccessfulSwingThreadCallback(new Runnable() {
|
||||
@@ -263,40 +308,54 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
myBalloon.hide();
|
||||
final PsiParameter psiParameter = myMethod.getParameterList().getParameters()[myParameterIndex];
|
||||
myParameterName = psiParameter.getName();
|
||||
final PsiParameter psiParameter = (PsiParameter)getVariable();
|
||||
LOG.assertTrue(psiParameter != null);
|
||||
myFinal = psiParameter.hasModifierProperty(PsiModifier.FINAL);
|
||||
myParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(psiParameter.getType());
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
myParameterName = psiParameter.getName();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
final PsiFile containingFile = myMethod.getContainingFile();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
|
||||
myExpression = restoreExpression(containingFile, elementFactory, myExprMarker);
|
||||
for (RangeMarker marker : myOccurrenceMarkers) {
|
||||
if (myExprMarker != null && marker.getStartOffset() == myExprMarker.getStartOffset()) continue;
|
||||
restoreExpression(containingFile, elementFactory, marker);
|
||||
myExpr = restoreExpression(containingFile, psiParameter, elementFactory, myExprMarker);
|
||||
if (myExpr != null) {
|
||||
myExprMarker = myEditor.getDocument().createRangeMarker(myExpr.getTextRange());
|
||||
}
|
||||
final List<RangeMarker> occurrenceMarkers = getOccurrenceMarkers();
|
||||
for (int i = 0, occurrenceMarkersSize = occurrenceMarkers.size(); i < occurrenceMarkersSize; i++) {
|
||||
RangeMarker marker = occurrenceMarkers.get(i);
|
||||
if (myExprMarker != null && marker.getStartOffset() == myExprMarker.getStartOffset()) {
|
||||
myOccurrences[i] = myExpr;
|
||||
continue;
|
||||
}
|
||||
final PsiExpression psiExpression = restoreExpression(containingFile, psiParameter, elementFactory, marker);
|
||||
if (psiExpression != null) {
|
||||
myOccurrences[i] = psiExpression;
|
||||
}
|
||||
}
|
||||
myOccurrenceMarkers = null;
|
||||
if (psiParameter.isValid()) {
|
||||
psiParameter.delete();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiExpression restoreExpression(PsiFile containingFile, PsiElementFactory elementFactory, RangeMarker marker) {
|
||||
private PsiExpression restoreExpression(PsiFile containingFile,
|
||||
PsiParameter psiParameter,
|
||||
PsiElementFactory elementFactory,
|
||||
RangeMarker marker) {
|
||||
if (myExprText == null) return null;
|
||||
if (myParameter == null || !myParameter.isValid()) return null;
|
||||
if (psiParameter == null || !psiParameter.isValid()) return null;
|
||||
final PsiElement refVariableElement = containingFile.findElementAt(marker.getStartOffset());
|
||||
final PsiExpression expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class);
|
||||
if (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression)expression).resolve() == myParameter) {
|
||||
if (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression)expression).resolve() == psiParameter) {
|
||||
return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(myExprText, myMethod));
|
||||
}
|
||||
return null;
|
||||
@@ -313,56 +372,48 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
return createFinals == null ? CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS : createFinals.booleanValue();
|
||||
}
|
||||
|
||||
private class IntroduceParameterPass extends Pass<OccurrencesChooser.ReplaceChoice> {
|
||||
|
||||
@Override
|
||||
public void pass(final OccurrencesChooser.ReplaceChoice replaceChoice) {
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
myTypeSelectorManager.setAllOccurences(replaceChoice != OccurrencesChooser.ReplaceChoice.NO);
|
||||
final PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
final String[] names = myNameSuggestionsGenerator.getSuggestedNameInfo(defaultType).names;
|
||||
final PsiParameter parameter = createParameterToStartTemplateOn(names, defaultType);
|
||||
if (parameter != null) {
|
||||
myEditor.getCaretModel().moveToOffset(parameter.getTextOffset());
|
||||
showSettingsPopup();
|
||||
final VariableInplaceRenamer renamer =
|
||||
new ParameterInplaceIntroducer(parameter, replaceChoice);
|
||||
renamer.performInplaceRename(false, new LinkedHashSet<String>(Arrays.asList(names)));
|
||||
}
|
||||
}
|
||||
}, IntroduceParameterHandler.REFACTORING_NAME, null);
|
||||
}
|
||||
|
||||
private PsiParameter createParameterToStartTemplateOn(final String[] names,
|
||||
final PsiType defaultType) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myMethod.getProject());
|
||||
return ApplicationManager.getApplication().runWriteAction(new Computable<PsiParameter>() {
|
||||
@Override
|
||||
public PsiParameter compute() {
|
||||
final PsiParameter psiParameter = (PsiParameter)myMethod.getParameterList()
|
||||
.addAfter(elementFactory.createParameter(names[0], defaultType),
|
||||
JavaIntroduceParameterMethodUsagesProcessor.getAnchorParameter(myMethod));
|
||||
PsiUtil.setModifierProperty(psiParameter, PsiModifier.FINAL, hasFinalModifier());
|
||||
return psiParameter;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showSettingsPopup() {
|
||||
BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createBalloonBuilder(myWholePanel);
|
||||
balloonBuilder.setFadeoutTime(0);
|
||||
balloonBuilder.setFillColor(IdeTooltipManager.GRAPHITE_COLOR);
|
||||
balloonBuilder.setAnimationCycle(0);
|
||||
balloonBuilder.setHideOnClickOutside(false);
|
||||
balloonBuilder.setHideOnKeyOutside(false);
|
||||
balloonBuilder.setHideOnAction(false);
|
||||
balloonBuilder.setCloseButtonEnabled(true);
|
||||
final RelativePoint target = JBPopupFactory.getInstance().guessBestPopupLocation(myEditor);
|
||||
final Point screenPoint = target.getScreenPoint();
|
||||
myBalloon = balloonBuilder.createBalloon();
|
||||
myBalloon
|
||||
.show(new RelativePoint(new Point(screenPoint.x, screenPoint.y - myEditor.getLineHeight())), Balloon.Position.above);
|
||||
@Override
|
||||
protected void updateControls(JCheckBox[] removeParamsCb) {
|
||||
super.updateControls(removeParamsCb);
|
||||
if (myParameterIndex < 0) return;
|
||||
final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
|
||||
if (templateState != null) {
|
||||
templateState.gotoEnd(true);
|
||||
startIntroduceTemplate(isReplaceAllOccurences());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private PsiParameter createParameterToStartTemplateOn(final String[] names,
|
||||
final PsiType defaultType) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myMethod.getProject());
|
||||
return ApplicationManager.getApplication().runWriteAction(new Computable<PsiParameter>() {
|
||||
@Override
|
||||
public PsiParameter compute() {
|
||||
final String name = myParameterName != null ? myParameterName : names[0];
|
||||
final PsiParameter anchor = JavaIntroduceParameterMethodUsagesProcessor.getAnchorParameter(myMethod);
|
||||
final PsiParameter psiParameter = (PsiParameter)myMethod.getParameterList()
|
||||
.addAfter(elementFactory.createParameter(name, defaultType), anchor);
|
||||
PsiUtil.setModifierProperty(psiParameter, PsiModifier.FINAL, hasFinalModifier());
|
||||
return psiParameter;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showBalloon() {
|
||||
final BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createBalloonBuilder(myWholePanel);
|
||||
balloonBuilder.setFadeoutTime(0)
|
||||
.setFillColor(IdeTooltipManager.GRAPHITE_COLOR)
|
||||
.setAnimationCycle(0)
|
||||
.setHideOnClickOutside(false)
|
||||
.setHideOnKeyOutside(false)
|
||||
.setHideOnAction(false)
|
||||
.setCloseButtonEnabled(true);
|
||||
|
||||
final RelativePoint target = JBPopupFactory.getInstance().guessBestPopupLocation(myEditor);
|
||||
final Point screenPoint = target.getScreenPoint();
|
||||
myBalloon = balloonBuilder.createBalloon();
|
||||
myBalloon
|
||||
.show(new RelativePoint(new Point(screenPoint.x, screenPoint.y - myEditor.getLineHeight())), Balloon.Position.above);
|
||||
}
|
||||
}
|
||||
|
||||
+10
-54
@@ -40,8 +40,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.util.List;
|
||||
|
||||
public class IntroduceParameterDialog extends RefactoringDialog {
|
||||
@@ -60,8 +58,7 @@ public class IntroduceParameterDialog extends RefactoringDialog {
|
||||
|
||||
// private JComponent myParameterNameField = null;
|
||||
private NameSuggestionsField myParameterNameField;
|
||||
private JCheckBox myCbReplaceAllOccurences = null;
|
||||
private JCheckBox myCbGenerateDelegate = null;
|
||||
|
||||
|
||||
private final NameSuggestionsGenerator myNameSuggestionsGenerator;
|
||||
private final TypeSelectorManager myTypeSelectorManager;
|
||||
@@ -106,13 +103,7 @@ public class IntroduceParameterDialog extends RefactoringDialog {
|
||||
return myCbDeclareFinal != null && myCbDeclareFinal.isSelected();
|
||||
}
|
||||
|
||||
private boolean isReplaceAllOccurences() {
|
||||
return myPanel.myIsInvokedOnDeclaration || myCbReplaceAllOccurences != null && myCbReplaceAllOccurences.isSelected();
|
||||
}
|
||||
|
||||
private boolean isGenerateDelegate() {
|
||||
return myCbGenerateDelegate != null && myCbGenerateDelegate.isSelected();
|
||||
}
|
||||
|
||||
private String getParameterName() {
|
||||
return myParameterNameField.getEnteredName().trim();
|
||||
@@ -196,11 +187,7 @@ public class IntroduceParameterDialog extends RefactoringDialog {
|
||||
gbConstraints.gridwidth = 2;
|
||||
if (myOccurenceNumber > 1 && !myPanel.myIsInvokedOnDeclaration) {
|
||||
gbConstraints.gridy++;
|
||||
myCbReplaceAllOccurences = new NonFocusableCheckBox();
|
||||
myCbReplaceAllOccurences.setText(RefactoringBundle.message("replace.all.occurences", myOccurenceNumber));
|
||||
|
||||
panel.add(myCbReplaceAllOccurences, gbConstraints);
|
||||
myCbReplaceAllOccurences.setSelected(false);
|
||||
myPanel.createOccurrencesCb(gbConstraints, panel, myOccurenceNumber);
|
||||
}
|
||||
|
||||
JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance();
|
||||
@@ -218,31 +205,19 @@ public class IntroduceParameterDialog extends RefactoringDialog {
|
||||
myCbDeclareFinal.setEnabled(false);
|
||||
}
|
||||
|
||||
if(myCbReplaceAllOccurences != null) {
|
||||
if(myPanel.myCbReplaceAllOccurences != null) {
|
||||
gbConstraints.insets = new Insets(0, 16, 4, 8);
|
||||
}
|
||||
myPanel.createLocalVariablePanel(gbConstraints, panel, settings);
|
||||
|
||||
myPanel.createRemoveParamsPanel(gbConstraints, panel);
|
||||
gbConstraints.insets = new Insets(4, 0, 4, 8);
|
||||
gbConstraints.gridy++;
|
||||
myCbGenerateDelegate = new NonFocusableCheckBox(RefactoringBundle.message("delegation.panel.delegate.via.overloading.method"));
|
||||
panel.add(myCbGenerateDelegate, gbConstraints);
|
||||
myPanel.createDelegateCb(gbConstraints, panel);
|
||||
|
||||
final JCheckBox[] removeParamsCb = myPanel.createRemoveParamsPanel(gbConstraints, panel);
|
||||
if (myCbReplaceAllOccurences != null) {
|
||||
myCbReplaceAllOccurences.addItemListener(
|
||||
new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
myPanel.updateControls(removeParamsCb);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
if(Util.anyFieldsWithGettersPresent(myClassMembersList)) {
|
||||
return myPanel.createReplaceFieldsWithGettersPanel();
|
||||
@@ -276,8 +251,8 @@ public class IntroduceParameterDialog extends RefactoringDialog {
|
||||
myProject, myMethodToReplaceIn, myMethodToSearchFor,
|
||||
parameterInitializer, myExpression,
|
||||
myLocalVar, isDeleteLocalVariable,
|
||||
getParameterName(), isReplaceAllOccurences(),
|
||||
myPanel.getReplaceFieldsWithGetters(), isDeclareFinal(), isGenerateDelegate(), getSelectedType(), myPanel.getParametersToRemove());
|
||||
getParameterName(), myPanel.isReplaceAllOccurences(),
|
||||
myPanel.getReplaceFieldsWithGetters(), isDeclareFinal(), myPanel.isGenerateDelegate(), getSelectedType(), myPanel.getParametersToRemove());
|
||||
invokeRefactoring(processor);
|
||||
myParameterNameField.requestFocusInWindow();
|
||||
}
|
||||
@@ -299,29 +274,10 @@ public class IntroduceParameterDialog extends RefactoringDialog {
|
||||
super(project, onLocalVariable, onExpression, methodToReplaceIn, parametersToRemove);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void updateControls(JCheckBox[] removeParamsCb) {
|
||||
if (myCbReplaceAllOccurences != null) {
|
||||
for (JCheckBox box : removeParamsCb) {
|
||||
if (box != null) {
|
||||
box.setEnabled(myCbReplaceAllOccurences.isSelected());
|
||||
}
|
||||
}
|
||||
myTypeSelectorManager.setAllOccurences(myCbReplaceAllOccurences.isSelected());
|
||||
if (myCbReplaceAllOccurences.isSelected()) {
|
||||
if (myCbDeleteLocalVariable != null) {
|
||||
myCbDeleteLocalVariable.makeSelectable();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (myCbDeleteLocalVariable != null) {
|
||||
myCbDeleteLocalVariable.makeUnselectable(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
myTypeSelectorManager.setAllOccurences(myIsInvokedOnDeclaration);
|
||||
}
|
||||
protected TypeSelectorManager getTypeSelectionManager() {
|
||||
return myTypeSelectorManager;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+237
-92
@@ -26,14 +26,20 @@ package com.intellij.refactoring.introduceParameter;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtil;
|
||||
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
||||
import com.intellij.ide.util.SuperMethodWarningUtil;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.editor.colors.EditorColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.markup.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.*;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Pass;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo;
|
||||
@@ -41,17 +47,28 @@ import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.*;
|
||||
import com.intellij.refactoring.introduceField.ElementToWorkOn;
|
||||
import com.intellij.refactoring.ui.MethodCellRenderer;
|
||||
import com.intellij.refactoring.ui.NameSuggestionsGenerator;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.refactoring.util.occurences.ExpressionOccurenceManager;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
@@ -60,6 +77,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceParameter.IntroduceParameterHandler");
|
||||
static final String REFACTORING_NAME = RefactoringBundle.message("introduce.parameter.title");
|
||||
private Project myProject;
|
||||
private JBPopup myEnclosingMethodsPopup;
|
||||
|
||||
public void invoke(@NotNull final Project project, final Editor editor, PsiFile file, DataContext dataContext) {
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
@@ -86,7 +104,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
|
||||
return invoke(editor, project, null, localVariable, true);
|
||||
}
|
||||
|
||||
private boolean invoke(Editor editor, Project project, final PsiExpression expr,
|
||||
private boolean invoke(final Editor editor, final Project project, final PsiExpression expr,
|
||||
PsiLocalVariable localVar, boolean invokedOnDeclaration) {
|
||||
LOG.assertTrue(!PsiDocumentManager.getInstance(project).hasUncommitedDocuments());
|
||||
PsiMethod method;
|
||||
@@ -131,103 +149,124 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
|
||||
return false;
|
||||
}
|
||||
|
||||
method = chooseEnclosingMethod(method);
|
||||
if (method == null) return false;
|
||||
|
||||
final PsiMethod methodToSearchFor = SuperMethodWarningUtil.checkSuperMethod(method, RefactoringBundle.message("to.refactor"));
|
||||
if (methodToSearchFor == null) return false;
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, methodToSearchFor)) return false;
|
||||
|
||||
PsiExpression[] occurences;
|
||||
if (expr != null) {
|
||||
occurences = new ExpressionOccurenceManager(expr, method, null).findExpressionOccurrences();
|
||||
final List<PsiMethod> validEnclosingMethods = getEnclosingMethods(method);
|
||||
if (validEnclosingMethods.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
else { // local variable
|
||||
occurences = CodeInsightUtil.findReferenceExpressions(method, localVar);
|
||||
}
|
||||
PsiExpression expressionToRemoveParamFrom = expr;
|
||||
if (expr == null) {
|
||||
expressionToRemoveParamFrom = localVar.getInitializer();
|
||||
}
|
||||
TIntArrayList parametersToRemove = expressionToRemoveParamFrom == null ? new TIntArrayList() : Util.findParametersToRemove(method, expressionToRemoveParamFrom, occurences);
|
||||
|
||||
boolean mustBeFinal = false;
|
||||
if (localVar != null) {
|
||||
for(PsiExpression occurrence: occurences) {
|
||||
if (PsiTreeUtil.getParentOfType(occurrence, PsiClass.class, PsiMethod.class) != method) {
|
||||
mustBeFinal = true;
|
||||
break;
|
||||
}
|
||||
final Introducer introducer = new Introducer(project, expr, localVar, editor);
|
||||
final boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode();
|
||||
if (validEnclosingMethods.size() == 1 || unitTestMode) {
|
||||
if (validEnclosingMethods.get(0).findDeepestSuperMethod() == null || unitTestMode) {
|
||||
introducer.introduceParameter(method, method);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
List<UsageInfo> localVars = new ArrayList<UsageInfo>();
|
||||
List<UsageInfo> classMemberRefs = new ArrayList<UsageInfo>();
|
||||
List<UsageInfo> params = new ArrayList<UsageInfo>();
|
||||
chooseMethodToIntroduceParameter(editor, validEnclosingMethods, introducer);
|
||||
|
||||
|
||||
if (expr != null) {
|
||||
Util.analyzeExpression(expr, localVars, classMemberRefs, params);
|
||||
}
|
||||
|
||||
if (expr instanceof PsiReferenceExpression) {
|
||||
PsiElement resolved = ((PsiReferenceExpression) expr).resolve();
|
||||
if (resolved instanceof PsiLocalVariable) {
|
||||
localVar = (PsiLocalVariable) resolved;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
@NonNls String parameterName = "anObject";
|
||||
boolean replaceAllOccurences = true;
|
||||
boolean isDeleteLocalVariable = true;
|
||||
PsiExpression initializer = localVar != null && expr == null ? localVar.getInitializer() : expr;
|
||||
new IntroduceParameterProcessor(myProject, method, methodToSearchFor, initializer, expr, localVar, isDeleteLocalVariable, parameterName,
|
||||
replaceAllOccurences, IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, mustBeFinal,
|
||||
false, null,
|
||||
parametersToRemove).run();
|
||||
}
|
||||
else {
|
||||
final String propName = localVar != null ? JavaCodeStyleManager.getInstance(myProject).variableNameToPropertyName(localVar.getName(), VariableKind.LOCAL_VARIABLE) : null;
|
||||
final PsiType initializerType = IntroduceParameterProcessor.getInitializerType(null, expr, localVar);
|
||||
|
||||
TypeSelectorManagerImpl typeSelectorManager = expr != null
|
||||
? new TypeSelectorManagerImpl(project, initializerType, expr, occurences)
|
||||
: new TypeSelectorManagerImpl(project, initializerType, occurences);
|
||||
|
||||
NameSuggestionsGenerator nameSuggestionsGenerator = new NameSuggestionsGenerator() {
|
||||
public SuggestedNameInfo getSuggestedNameInfo(PsiType type) {
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(myProject);
|
||||
final SuggestedNameInfo info = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, propName, expr, type);
|
||||
final String[] strings = JavaCompletionUtil.completeVariableNameForRefactoring(codeStyleManager, type, VariableKind.LOCAL_VARIABLE, info);
|
||||
return new SuggestedNameInfo.Delegate(strings, info);
|
||||
}
|
||||
|
||||
};
|
||||
boolean isInplaceAvailableOnDataContext = editor != null && editor.getSettings().isVariableInplaceRenameEnabled()
|
||||
&& method == methodToSearchFor
|
||||
&& method.hasModifierProperty(PsiModifier.PRIVATE);
|
||||
|
||||
if (!isInplaceAvailableOnDataContext) {
|
||||
if (editor != null) {
|
||||
RefactoringUtil.highlightAllOccurences(myProject, occurences, editor);
|
||||
}
|
||||
new IntroduceParameterDialog(myProject, classMemberRefs, occurences.length, localVar, expr, nameSuggestionsGenerator,
|
||||
typeSelectorManager, methodToSearchFor, method, parametersToRemove, mustBeFinal).show();
|
||||
if (editor != null) {
|
||||
editor.getSelectionModel().removeSelection();
|
||||
}
|
||||
} else {
|
||||
new InplaceIntroduceParameterPopup(project, editor, classMemberRefs,
|
||||
typeSelectorManager, nameSuggestionsGenerator,
|
||||
expr, localVar, method, methodToSearchFor, occurences, parametersToRemove,
|
||||
mustBeFinal).inplaceIntroduceParameter();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void chooseMethodToIntroduceParameter(final Editor editor,
|
||||
final List<PsiMethod> validEnclosingMethods,
|
||||
final Introducer introducer) {
|
||||
final JPanel panel = new JPanel(new BorderLayout());
|
||||
final JCheckBox superMethod = new JCheckBox("Choose base method", true);
|
||||
superMethod.setMnemonic('b');
|
||||
panel.add(superMethod, BorderLayout.SOUTH);
|
||||
final JBList list = new JBList(validEnclosingMethods.toArray());
|
||||
list.setCellRenderer(new MethodCellRenderer());
|
||||
list.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
list.setSelectedIndex(0);
|
||||
final List<RangeHighlighter> highlighters = new ArrayList<RangeHighlighter>();
|
||||
final TextAttributes attributes =
|
||||
EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
|
||||
list.addListSelectionListener(new ListSelectionListener() {
|
||||
public void valueChanged(final ListSelectionEvent e) {
|
||||
final PsiMethod selectedMethod = (PsiMethod)list.getSelectedValue();
|
||||
if (selectedMethod == null) return;
|
||||
dropHighlighters(highlighters);
|
||||
updateView(selectedMethod, editor, attributes, highlighters, superMethod);
|
||||
}
|
||||
});
|
||||
updateView(validEnclosingMethods.get(0), editor, attributes, highlighters, superMethod);
|
||||
final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(list);
|
||||
scrollPane.setBorder(null);
|
||||
panel.add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
final List<Pair<ActionListener, KeyStroke>>
|
||||
keyboardActions = Collections.singletonList(Pair.<ActionListener, KeyStroke>create(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final PsiMethod methodToSearchIn = (PsiMethod)list.getSelectedValue();
|
||||
if (myEnclosingMethodsPopup != null && myEnclosingMethodsPopup.isVisible()) {
|
||||
myEnclosingMethodsPopup.cancel();
|
||||
}
|
||||
|
||||
final PsiMethod methodToSearchFor = superMethod.isEnabled() && superMethod.isSelected()
|
||||
? methodToSearchIn.findDeepestSuperMethod() : methodToSearchIn;
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
introducer.introduceParameter(methodToSearchIn, methodToSearchFor);
|
||||
}
|
||||
};
|
||||
IdeFocusManager.findInstance().doWhenFocusSettlesDown(runnable);
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)));
|
||||
myEnclosingMethodsPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, list)
|
||||
.setTitle("Introduce parameter to method")
|
||||
.setMovable(false)
|
||||
.setResizable(false)
|
||||
.setRequestFocus(true)
|
||||
.setKeyboardActions(keyboardActions).addListener(new JBPopupAdapter() {
|
||||
@Override
|
||||
public void onClosed(LightweightWindowEvent event) {
|
||||
dropHighlighters(highlighters);
|
||||
}
|
||||
}).createPopup();
|
||||
myEnclosingMethodsPopup.showInBestPositionFor(editor);
|
||||
}
|
||||
|
||||
private static void updateView(PsiMethod selectedMethod,
|
||||
Editor editor,
|
||||
TextAttributes attributes,
|
||||
List<RangeHighlighter> highlighters,
|
||||
JCheckBox superMethod) {
|
||||
final MarkupModel markupModel = editor.getMarkupModel();
|
||||
final PsiIdentifier nameIdentifier = selectedMethod.getNameIdentifier();
|
||||
if (nameIdentifier != null) {
|
||||
final TextRange textRange = nameIdentifier.getTextRange();
|
||||
final RangeHighlighter rangeHighlighter = markupModel.addRangeHighlighter(
|
||||
textRange.getStartOffset(), textRange.getEndOffset(), HighlighterLayer.SELECTION - 1,
|
||||
attributes,
|
||||
HighlighterTargetArea.EXACT_RANGE);
|
||||
highlighters.add(rangeHighlighter);
|
||||
}
|
||||
superMethod.setEnabled(selectedMethod.findDeepestSuperMethod() != null);
|
||||
}
|
||||
|
||||
private static void dropHighlighters(List<RangeHighlighter> highlighters) {
|
||||
for (RangeHighlighter highlighter : highlighters) {
|
||||
highlighter.dispose();
|
||||
}
|
||||
highlighters.clear();
|
||||
}
|
||||
|
||||
protected static NameSuggestionsGenerator createNameSuggestionGenerator(final PsiExpression expr,
|
||||
final String propName,
|
||||
final Project project) {
|
||||
return new NameSuggestionsGenerator() {
|
||||
public SuggestedNameInfo getSuggestedNameInfo(PsiType type) {
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
final SuggestedNameInfo info = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, propName, expr, type);
|
||||
final String[] strings = JavaCompletionUtil
|
||||
.completeVariableNameForRefactoring(codeStyleManager, type, VariableKind.LOCAL_VARIABLE, info);
|
||||
return new SuggestedNameInfo.Delegate(strings, info);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private static void showErrorMessage(Project project, String message, Editor editor) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INTRODUCE_PARAMETER);
|
||||
}
|
||||
@@ -238,7 +277,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
private static List<PsiMethod> getEnclosingMethods(PsiMethod nearest) {
|
||||
public static List<PsiMethod> getEnclosingMethods(PsiMethod nearest) {
|
||||
List<PsiMethod> enclosingMethods = new ArrayList<PsiMethod>();
|
||||
enclosingMethods.add(nearest);
|
||||
PsiMethod method = nearest;
|
||||
@@ -285,4 +324,110 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
|
||||
private static boolean isLibraryInterfaceMethod(final PsiMethod method) {
|
||||
return method.hasModifierProperty(PsiModifier.ABSTRACT) && !method.getManager().isInProject(method);
|
||||
}
|
||||
|
||||
private static class Introducer {
|
||||
|
||||
private final Project myProject;
|
||||
|
||||
private final PsiExpression myExpr;
|
||||
private PsiLocalVariable myLocalVar;
|
||||
private final Editor myEditor;
|
||||
|
||||
public Introducer(Project project,
|
||||
PsiExpression expr,
|
||||
PsiLocalVariable localVar,
|
||||
Editor editor) {
|
||||
myProject = project;
|
||||
myExpr = expr;
|
||||
myLocalVar = localVar;
|
||||
myEditor = editor;
|
||||
}
|
||||
|
||||
public void introduceParameter(PsiMethod method, PsiMethod methodToSearchFor) {
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, methodToSearchFor)) return;
|
||||
|
||||
PsiExpression[] occurences;
|
||||
if (myExpr != null) {
|
||||
occurences = new ExpressionOccurenceManager(myExpr, method, null).findExpressionOccurrences();
|
||||
}
|
||||
else { // local variable
|
||||
occurences = CodeInsightUtil.findReferenceExpressions(method, myLocalVar);
|
||||
}
|
||||
PsiExpression expressionToRemoveParamFrom = myExpr;
|
||||
if (myExpr == null) {
|
||||
expressionToRemoveParamFrom = myLocalVar.getInitializer();
|
||||
}
|
||||
TIntArrayList parametersToRemove = expressionToRemoveParamFrom == null ? new TIntArrayList() : Util
|
||||
.findParametersToRemove(method, expressionToRemoveParamFrom, occurences);
|
||||
|
||||
boolean mustBeFinal = false;
|
||||
if (myLocalVar != null) {
|
||||
for(PsiExpression occurrence: occurences) {
|
||||
if (PsiTreeUtil.getParentOfType(occurrence, PsiClass.class, PsiMethod.class) != method) {
|
||||
mustBeFinal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<UsageInfo> localVars = new ArrayList<UsageInfo>();
|
||||
List<UsageInfo> classMemberRefs = new ArrayList<UsageInfo>();
|
||||
List<UsageInfo> params = new ArrayList<UsageInfo>();
|
||||
|
||||
|
||||
if (myExpr != null) {
|
||||
Util.analyzeExpression(myExpr, localVars, classMemberRefs, params);
|
||||
}
|
||||
|
||||
if (myExpr instanceof PsiReferenceExpression) {
|
||||
PsiElement resolved = ((PsiReferenceExpression)myExpr).resolve();
|
||||
if (resolved instanceof PsiLocalVariable) {
|
||||
myLocalVar = (PsiLocalVariable) resolved;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
@NonNls String parameterName = "anObject";
|
||||
boolean replaceAllOccurences = true;
|
||||
boolean isDeleteLocalVariable = true;
|
||||
PsiExpression initializer = myLocalVar != null && myExpr == null ? myLocalVar.getInitializer() : myExpr;
|
||||
new IntroduceParameterProcessor(myProject, method, methodToSearchFor, initializer, myExpr, myLocalVar, isDeleteLocalVariable, parameterName,
|
||||
replaceAllOccurences, IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, mustBeFinal,
|
||||
false, null,
|
||||
parametersToRemove).run();
|
||||
}
|
||||
else {
|
||||
final String propName = myLocalVar != null ? JavaCodeStyleManager
|
||||
.getInstance(myProject).variableNameToPropertyName(myLocalVar.getName(), VariableKind.LOCAL_VARIABLE) : null;
|
||||
final PsiType initializerType = IntroduceParameterProcessor.getInitializerType(null, myExpr, myLocalVar);
|
||||
|
||||
TypeSelectorManagerImpl typeSelectorManager = myExpr != null
|
||||
? new TypeSelectorManagerImpl(myProject, initializerType, myExpr, occurences)
|
||||
: new TypeSelectorManagerImpl(myProject, initializerType, occurences);
|
||||
|
||||
NameSuggestionsGenerator nameSuggestionsGenerator = createNameSuggestionGenerator(myExpr, propName, myProject);
|
||||
boolean isInplaceAvailableOnDataContext = myEditor != null && myEditor.getSettings().isVariableInplaceRenameEnabled();
|
||||
|
||||
if (!isInplaceAvailableOnDataContext) {
|
||||
if (myEditor != null) {
|
||||
RefactoringUtil.highlightAllOccurences(myProject, occurences, myEditor);
|
||||
}
|
||||
new IntroduceParameterDialog(myProject, classMemberRefs, occurences.length, myLocalVar, myExpr, nameSuggestionsGenerator,
|
||||
typeSelectorManager, methodToSearchFor, method, parametersToRemove, mustBeFinal).show();
|
||||
if (myEditor != null) {
|
||||
myEditor.getSelectionModel().removeSelection();
|
||||
}
|
||||
}
|
||||
else {
|
||||
new InplaceIntroduceParameterPopup(myProject, myEditor, classMemberRefs,
|
||||
typeSelectorManager,
|
||||
myExpr, myLocalVar, method, methodToSearchFor, occurences, parametersToRemove,
|
||||
mustBeFinal).inplaceIntroduceParameter();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+63
-3
@@ -24,6 +24,7 @@ import com.intellij.refactoring.IntroduceParameterRefactoring;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.ui.RefactoringDialog;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManager;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.NonFocusableCheckBox;
|
||||
import com.intellij.ui.StateRestoringCheckBox;
|
||||
@@ -34,6 +35,8 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
@@ -53,6 +56,9 @@ public abstract class IntroduceParameterSettingsUI {
|
||||
protected final boolean[] myParametersToRemoveChecked;
|
||||
protected final boolean myIsLocalVariable;
|
||||
|
||||
protected JCheckBox myCbReplaceAllOccurences = null;
|
||||
private JCheckBox myCbGenerateDelegate = null;
|
||||
|
||||
public IntroduceParameterSettingsUI(Project project,
|
||||
PsiLocalVariable onLocalVariable,
|
||||
PsiExpression onExpression,
|
||||
@@ -97,6 +103,14 @@ public abstract class IntroduceParameterSettingsUI {
|
||||
return IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE;
|
||||
}
|
||||
|
||||
public boolean isReplaceAllOccurences() {
|
||||
return myIsInvokedOnDeclaration || myCbReplaceAllOccurences != null && myCbReplaceAllOccurences.isSelected();
|
||||
}
|
||||
|
||||
public boolean isGenerateDelegate() {
|
||||
return myCbGenerateDelegate != null && myCbGenerateDelegate.isSelected();
|
||||
}
|
||||
|
||||
protected JPanel createReplaceFieldsWithGettersPanel() {
|
||||
JPanel radioButtonPanel = new JPanel(new GridBagLayout());
|
||||
|
||||
@@ -169,9 +183,33 @@ public abstract class IntroduceParameterSettingsUI {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
protected abstract void updateControls(JCheckBox[] removeParamsCb);
|
||||
protected void updateControls(JCheckBox[] removeParamsCb) {
|
||||
if (myCbReplaceAllOccurences != null) {
|
||||
for (JCheckBox box : removeParamsCb) {
|
||||
if (box != null) {
|
||||
box.setEnabled(myCbReplaceAllOccurences.isSelected());
|
||||
}
|
||||
}
|
||||
getTypeSelectionManager().setAllOccurences(myCbReplaceAllOccurences.isSelected());
|
||||
if (myCbReplaceAllOccurences.isSelected()) {
|
||||
if (myCbDeleteLocalVariable != null) {
|
||||
myCbDeleteLocalVariable.makeSelectable();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (myCbDeleteLocalVariable != null) {
|
||||
myCbDeleteLocalVariable.makeUnselectable(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
getTypeSelectionManager().setAllOccurences(myIsInvokedOnDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
protected JCheckBox[] createRemoveParamsPanel(GridBagConstraints gbConstraints, JPanel panel) {
|
||||
protected abstract TypeSelectorManager getTypeSelectionManager();
|
||||
|
||||
protected void createRemoveParamsPanel(GridBagConstraints gbConstraints, JPanel panel) {
|
||||
final JCheckBox[] removeParamsCb = new JCheckBox[myParametersToRemove.length];
|
||||
for (int i = 0; i < myParametersToRemove.length; i++) {
|
||||
PsiParameter parameter = myParametersToRemove[i];
|
||||
@@ -192,7 +230,15 @@ public abstract class IntroduceParameterSettingsUI {
|
||||
}
|
||||
|
||||
updateControls(removeParamsCb);
|
||||
return removeParamsCb;
|
||||
if (myCbReplaceAllOccurences != null) {
|
||||
myCbReplaceAllOccurences.addItemListener(
|
||||
new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
updateControls(removeParamsCb);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected void createLocalVariablePanel(GridBagConstraints gbConstraints, JPanel panel, JavaRefactoringSettings settings) {
|
||||
@@ -216,4 +262,18 @@ public abstract class IntroduceParameterSettingsUI {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void createDelegateCb(GridBagConstraints gbConstraints, JPanel panel) {
|
||||
myCbGenerateDelegate = new NonFocusableCheckBox(RefactoringBundle.message("delegation.panel.delegate.via.overloading.method"));
|
||||
panel.add(myCbGenerateDelegate, gbConstraints);
|
||||
}
|
||||
|
||||
protected void createOccurrencesCb(GridBagConstraints gbConstraints, JPanel panel, final int occurenceNumber) {
|
||||
myCbReplaceAllOccurences = new NonFocusableCheckBox();
|
||||
myCbReplaceAllOccurences.setText(RefactoringBundle.message("replace.all.occurences", occurenceNumber));
|
||||
|
||||
panel.add(myCbReplaceAllOccurences, gbConstraints);
|
||||
myCbReplaceAllOccurences.setSelected(false);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -110,7 +110,7 @@ public class OldReferenceResolver {
|
||||
final JavaResolveResult adv = oldRef.advancedResolve(false);
|
||||
final PsiElement scope = getClassContainingResolve(adv);
|
||||
final PsiClass clss = PsiTreeUtil.getParentOfType(oldExpr, PsiClass.class);
|
||||
if (clss != null && scope != null && PsiTreeUtil.isAncestor(clss, scope, false)) {
|
||||
if (clss != null && scope != null ) {
|
||||
|
||||
final PsiElement subj = adv.getElement();
|
||||
|
||||
@@ -118,7 +118,6 @@ public class OldReferenceResolver {
|
||||
// Parameters
|
||||
if (subj instanceof PsiParameter) {
|
||||
PsiParameterList parameterList = myMethodToReplaceIn.getParameterList();
|
||||
PsiParameter[] parameters = parameterList.getParameters();
|
||||
|
||||
if (subj.getParent() != parameterList) return;
|
||||
int index = parameterList.getParameterIndex((PsiParameter)subj);
|
||||
@@ -133,7 +132,7 @@ public class OldReferenceResolver {
|
||||
}
|
||||
}
|
||||
// "naked" field and methods (should become qualified)
|
||||
else if ((subj instanceof PsiField || subj instanceof PsiMethod) && oldRef.getQualifierExpression() == null) {
|
||||
else if ((subj instanceof PsiField || subj instanceof PsiMethod) && oldRef.getQualifierExpression() == null && PsiTreeUtil.isAncestor(clss, scope, false)) {
|
||||
|
||||
boolean isStatic = subj instanceof PsiField && ((PsiField)subj).hasModifierProperty(PsiModifier.STATIC) ||
|
||||
subj instanceof PsiMethod && ((PsiMethod)subj).hasModifierProperty(PsiModifier.STATIC);
|
||||
@@ -151,7 +150,7 @@ public class OldReferenceResolver {
|
||||
}
|
||||
}
|
||||
|
||||
if (subj instanceof PsiField) {
|
||||
if (subj instanceof PsiField && PsiTreeUtil.isAncestor(clss, scope, false)) {
|
||||
// probably replacing field with a getter
|
||||
if (myReplaceFieldsWithGetters != IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE) {
|
||||
if (myReplaceFieldsWithGetters == IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL ||
|
||||
|
||||
+4
@@ -28,6 +28,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
public interface MoveClassHandler {
|
||||
ExtensionPointName<MoveClassHandler> EP_NAME = new ExtensionPointName<MoveClassHandler>("com.intellij.refactoring.moveClassHandler");
|
||||
|
||||
void prepareMove(@NotNull PsiClass aClass);
|
||||
|
||||
void finishMoveClass(@NotNull PsiClass aClass);
|
||||
|
||||
/**
|
||||
* @return null if it cannot move aClass
|
||||
*/
|
||||
|
||||
+9
-10
@@ -22,6 +22,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -31,10 +32,9 @@ import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.move.MoveHandlerDelegate;
|
||||
import com.intellij.refactoring.move.MoveCallback;
|
||||
import com.intellij.refactoring.move.MoveHandlerDelegate;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.refactoring.util.RadioUpDownListener;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -70,8 +70,8 @@ public class MoveClassesOrPackagesHandlerBase extends MoveHandlerDelegate {
|
||||
|
||||
public static boolean invalid4Move(PsiElement element) {
|
||||
PsiFile parentFile;
|
||||
if (element instanceof PsiJavaFile) {
|
||||
final PsiClass[] classes = ((PsiJavaFile)element).getClasses();
|
||||
if (element instanceof PsiClassOwner) {
|
||||
final PsiClass[] classes = ((PsiClassOwner)element).getClasses();
|
||||
if (classes.length == 0) return true;
|
||||
for (PsiClass aClass : classes) {
|
||||
if (aClass instanceof JspClass) return true;
|
||||
@@ -81,8 +81,9 @@ public class MoveClassesOrPackagesHandlerBase extends MoveHandlerDelegate {
|
||||
else {
|
||||
if (element instanceof JspClass) return true;
|
||||
if (!(element instanceof PsiClass)) return true;
|
||||
if (!(element.getParent() instanceof PsiFile)) return true;
|
||||
parentFile = (PsiFile)element.getParent();
|
||||
if (element instanceof PsiAnonymousClass) return true;
|
||||
if (((PsiClass)element).getContainingClass() != null) return true;
|
||||
parentFile = element.getContainingFile();
|
||||
}
|
||||
if (CollectHighlightsUtil.isOutsideSourceRootJavaFile(parentFile)) return true;
|
||||
return false;
|
||||
@@ -313,12 +314,10 @@ public class MoveClassesOrPackagesHandlerBase extends MoveHandlerDelegate {
|
||||
public boolean tryToMove(final PsiElement element, final Project project, final DataContext dataContext, final PsiReference reference,
|
||||
final Editor editor) {
|
||||
if (isPackageOrDirectory(element)) return false;
|
||||
if (CollectHighlightsUtil.isOutsideSourceRootJavaFile(element.getContainingFile())) return false;
|
||||
if (isReferenceInAnonymousClass(reference)) return false;
|
||||
|
||||
if (element instanceof PsiClass && !(element instanceof PsiAnonymousClass) && element.getParent() instanceof PsiFile) {
|
||||
MoveClassesOrPackagesImpl.doMove(project, new PsiElement[]{element},
|
||||
LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext), null);
|
||||
if (!invalid4Move(element)) {
|
||||
MoveClassesOrPackagesImpl.doMove(project, new PsiElement[]{element}, LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext), null);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
+4
-5
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.refactoring.move.moveClassesOrPackages;
|
||||
|
||||
import com.intellij.codeInsight.ChangeContextUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
@@ -80,8 +79,8 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor {
|
||||
super(project);
|
||||
final Set<PsiElement> toMove = new LinkedHashSet<PsiElement>();
|
||||
for (PsiElement element : elements) {
|
||||
if (element instanceof PsiJavaFile) {
|
||||
Collections.addAll(toMove, ((PsiJavaFile)element).getClasses());
|
||||
if (element instanceof PsiClassOwner) {
|
||||
Collections.addAll(toMove, ((PsiClassOwner)element).getClasses());
|
||||
} else {
|
||||
toMove.add(element);
|
||||
}
|
||||
@@ -448,7 +447,7 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor {
|
||||
element = newElement;
|
||||
}
|
||||
else if (element instanceof PsiClass) {
|
||||
ChangeContextUtil.encodeContextInfo(element, true);
|
||||
MoveClassesOrPackagesUtil.prepareMoveClass((PsiClass)element);
|
||||
final PsiClass newElement = MoveClassesOrPackagesUtil.doMoveClass((PsiClass)element, myMoveDestination.getTargetDirectory(element.getContainingFile()));
|
||||
oldToNewElementsMapping.put(element, newElement);
|
||||
element = newElement;
|
||||
@@ -461,7 +460,7 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor {
|
||||
|
||||
for (PsiElement element : myElementsToMove) {
|
||||
if (element instanceof PsiClass) {
|
||||
ChangeContextUtil.decodeContextInfo(element, null, null);
|
||||
MoveClassesOrPackagesUtil.finishMoveClass((PsiClass)element);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -207,6 +207,18 @@ public class MoveClassesOrPackagesUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void prepareMoveClass(PsiClass aClass) {
|
||||
for (MoveClassHandler handler : MoveClassHandler.EP_NAME.getExtensions()) {
|
||||
handler.prepareMove(aClass);
|
||||
}
|
||||
}
|
||||
|
||||
public static void finishMoveClass(PsiClass aClass) {
|
||||
for (MoveClassHandler handler : MoveClassHandler.EP_NAME.getExtensions()) {
|
||||
handler.finishMoveClass(aClass);
|
||||
}
|
||||
}
|
||||
|
||||
// Does not process non-code usages!
|
||||
public static PsiClass doMoveClass(PsiClass aClass, PsiDirectory moveDestination) throws IncorrectOperationException {
|
||||
PsiClass newClass;
|
||||
|
||||
+15
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.refactoring.move.moveClassesOrPackages;
|
||||
|
||||
import com.intellij.codeInsight.ChangeContextUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.psi.*;
|
||||
@@ -32,6 +33,20 @@ import java.util.Set;
|
||||
public class MoveJavaClassHandler implements MoveClassHandler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.moveClassesOrPackages.MoveJavaClassHandler");
|
||||
|
||||
@Override
|
||||
public void finishMoveClass(@NotNull PsiClass aClass) {
|
||||
if (aClass.getContainingFile() instanceof PsiJavaFile) {
|
||||
ChangeContextUtil.decodeContextInfo(aClass, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareMove(@NotNull PsiClass aClass) {
|
||||
if (aClass.getContainingFile() instanceof PsiJavaFile) {
|
||||
ChangeContextUtil.encodeContextInfo(aClass, true);
|
||||
}
|
||||
}
|
||||
|
||||
public PsiClass doMoveClass(@NotNull final PsiClass aClass, @NotNull PsiDirectory moveDestination) throws IncorrectOperationException {
|
||||
PsiFile file = aClass.getContainingFile();
|
||||
final PsiPackage newPackage = JavaDirectoryService.getInstance().getPackage(moveDestination);
|
||||
|
||||
+11
-8
@@ -203,8 +203,10 @@ public class BindingFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
b3.myBindings.put(i, type);
|
||||
b3.myCyclic = type instanceof PsiTypeVariable;
|
||||
if (type != PsiType.NULL) {
|
||||
b3.myBindings.put(i, type);
|
||||
b3.myCyclic = type instanceof PsiTypeVariable;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -216,8 +218,10 @@ public class BindingFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
b3.myBindings.put(i, type);
|
||||
b3.myCyclic = type instanceof PsiTypeVariable;
|
||||
if (type != PsiType.NULL) {
|
||||
b3.myBindings.put(i, type);
|
||||
b3.myCyclic = type instanceof PsiTypeVariable;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -234,12 +238,11 @@ public class BindingFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
return null;
|
||||
if (type != PsiType.NULL) {
|
||||
b3.myBindings.put(i, type);
|
||||
b3.myCyclic = type instanceof PsiTypeVariable;
|
||||
}
|
||||
|
||||
b3.myBindings.put(i, type);
|
||||
b3.myCyclic = type instanceof PsiTypeVariable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class InlineUtil {
|
||||
initializer = RefactoringUtil.convertInitializerToNormalExpression(initializer, varType);
|
||||
|
||||
ChangeContextUtil.encodeContextInfo(initializer, false);
|
||||
PsiExpression expr = (PsiExpression)ref.replace(initializer);
|
||||
PsiExpression expr = (PsiExpression)replaceDiamondWithInferredTypesIfNeeded(initializer, ref);
|
||||
PsiType exprType = expr.getType();
|
||||
if (exprType != null && (!varType.equals(exprType) && varType instanceof PsiPrimitiveType
|
||||
|| !TypeConversionUtil.isAssignable(varType, exprType))) {
|
||||
@@ -315,6 +315,46 @@ public class InlineUtil {
|
||||
});
|
||||
}
|
||||
|
||||
private static PsiElement replaceDiamondWithInferredTypesIfNeeded(PsiExpression initializer, PsiElement ref) {
|
||||
if (initializer instanceof PsiNewExpression) {
|
||||
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)initializer).getClassOrAnonymousClassReference();
|
||||
if (classReference != null) {
|
||||
final PsiReferenceParameterList parameterList = classReference.getParameterList();
|
||||
if (parameterList != null) {
|
||||
final PsiTypeElement[] typeParameterElements = parameterList.getTypeParameterElements();
|
||||
if (typeParameterElements.length == 1) {
|
||||
final PsiType type = typeParameterElements[0].getType();
|
||||
if (type instanceof PsiDiamondType) {
|
||||
final PsiDiamondType.DiamondInferenceResult inferenceResult = ((PsiDiamondType)type).resolveInferredTypes();
|
||||
if (inferenceResult.getErrorMessage() == null) {
|
||||
final PsiElement copy = ref.copy();
|
||||
final PsiElement parent = ref.replace(initializer);
|
||||
final PsiDiamondType.DiamondInferenceResult result = PsiDiamondType.resolveInferredTypes((PsiNewExpression)initializer, parent);
|
||||
ref = parent.replace(copy);
|
||||
if (!result.equals(inferenceResult)) {
|
||||
final String inferredTypeText = StringUtil.join(inferenceResult.getTypes(),
|
||||
new Function<PsiType, String>() {
|
||||
@Override
|
||||
public String fun(PsiType psiType) {
|
||||
return psiType.getCanonicalText();
|
||||
}
|
||||
}, ", ");
|
||||
final PsiExpressionList argumentList = ((PsiNewExpression)initializer).getArgumentList();
|
||||
if (argumentList != null) {
|
||||
final PsiExpression expression = JavaPsiFacade.getElementFactory(initializer.getProject())
|
||||
.createExpressionFromText("new " + classReference.getReferenceName() + "<" + inferredTypeText + ">" + argumentList.getText(), initializer);
|
||||
return ref.replace(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ref.replace(initializer);
|
||||
}
|
||||
|
||||
public enum TailCallType {
|
||||
None, Simple, Return
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class AbcdClass {}
|
||||
class AbcdeClass {}
|
||||
|
||||
class Foo {
|
||||
Abcd<caret>
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class AbcdClass {}
|
||||
class AbcdeClass {}
|
||||
|
||||
class Foo {
|
||||
AbcdClass<<caret>>
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class AbcdClass {}
|
||||
class AbcdeClass {}
|
||||
|
||||
class Foo {
|
||||
Abcd<caret>
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class AbcdClass {}
|
||||
class AbcdeClass {}
|
||||
|
||||
class Foo {
|
||||
AbcdClass[<caret>]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
int[] aaaa(int x){}
|
||||
int[] aaab(){}
|
||||
|
||||
|
||||
{
|
||||
aaa<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
int[] aaaa(int x){}
|
||||
int[] aaab(){}
|
||||
|
||||
|
||||
{
|
||||
aaaa()[<caret>]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class Foo {
|
||||
d<caret>
|
||||
|
||||
class doz {}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Foo {
|
||||
double[<caret>]
|
||||
|
||||
class doz {}
|
||||
}
|
||||
+1
-1
@@ -3,7 +3,7 @@ class Foo {
|
||||
{
|
||||
String abc;
|
||||
String abcdef;
|
||||
abc <caret>d
|
||||
abc <caret> d
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class Foo {
|
||||
{
|
||||
int[] aaaa;
|
||||
int[] aaab;
|
||||
aa<caret>
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Foo {
|
||||
{
|
||||
int[] aaaa;
|
||||
int[] aaab;
|
||||
aaaa[<caret>]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
public class Test {
|
||||
|
||||
p<caret>
|
||||
|
||||
class paaa {}
|
||||
|
||||
static class paab {}
|
||||
|
||||
}
|
||||
+22
@@ -3,6 +3,7 @@ import java.util.List;
|
||||
|
||||
class Test {
|
||||
List<String> queue = new ArrayList<>();
|
||||
ArrayList l = new ArrayList<>(8);
|
||||
}
|
||||
|
||||
class DD {
|
||||
@@ -73,3 +74,24 @@ class NonParameterized {
|
||||
new NonParameterized<<error descr="Diamond operator is not applicable for non-parameterized types"></error>>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface I<T> {
|
||||
T m();
|
||||
}
|
||||
|
||||
class FI1 {
|
||||
I<? extends String> i1 = new I<>() {
|
||||
@Override
|
||||
public String m() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
I<?> i2 = new I<>() {
|
||||
@Override
|
||||
public Object m() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package pkg;
|
||||
|
||||
/**
|
||||
* @see #method(pkg.B0.C[])
|
||||
* @see #method(B0.C[])
|
||||
* @see #method(B0.C...)
|
||||
*/
|
||||
class A0 {
|
||||
public void method(B0.C[] c) { }
|
||||
}
|
||||
|
||||
class B0 {
|
||||
class C {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package pkg;
|
||||
|
||||
/**
|
||||
* @see #<error descr="Cannot resolve symbol 'method(B1.C)'">method(B1.C)</error>
|
||||
* @see #<error descr="Cannot resolve symbol 'method(B1.C[][])'">method(B1.C[][])</error>
|
||||
* @see #<error descr="Cannot resolve symbol 'method(B1.C..)'">method(<error descr="Cannot resolve symbol 'B1.C.'">B1.C.</error>.)</error>
|
||||
* @see #<error descr="Cannot resolve symbol 'method(B1.C[)'">method(B1.C[)</error>
|
||||
*/
|
||||
class A1 {
|
||||
public void method(B1.C[] c) { }
|
||||
}
|
||||
|
||||
class B1 {
|
||||
class C {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package pkg;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @see #method(java.util.List)
|
||||
* @see #method(java.util.List<String>)
|
||||
* @see #method(java.util.List<T>)
|
||||
* @see #method(java.util.List<Number>)
|
||||
*/
|
||||
class A2<T> {
|
||||
public void method(List<String> list) { }
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Make 'e' not final" "false"
|
||||
|
||||
class C {
|
||||
static {
|
||||
try {
|
||||
throw new Exception();
|
||||
}
|
||||
catch (RuntimeException | IOException e) {
|
||||
<caret>e = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Make 'r' not final" "false"
|
||||
|
||||
class C {
|
||||
void m() throws Exception {
|
||||
try (AutoCloseable r = null) {
|
||||
<caret>r = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Make 'e' final" "false"
|
||||
|
||||
class C {
|
||||
static {
|
||||
try {
|
||||
throw new Exception();
|
||||
}
|
||||
catch (RuntimeException | IOException e) {
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
System.out.println(<caret>e);
|
||||
}
|
||||
}.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Make 'r' final" "false"
|
||||
|
||||
class C {
|
||||
void m() throws Exception {
|
||||
try (AutoCloseable r = null) {
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
System.out.println(<caret>r);
|
||||
}
|
||||
}.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
|
||||
void foo(){
|
||||
Map<Integer, String> m<caret>ap = new HashMap<>();
|
||||
System.out.println(map);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
|
||||
void foo(){
|
||||
System.out.println(new HashMap<Integer, String>());
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
|
||||
void foo(){
|
||||
Map<Integer, String> m<caret>ap = new HashMap<>();
|
||||
Map<Integer, String> map1 = map;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
|
||||
void foo(){
|
||||
Map<Integer, String> map1 = new HashMap<>();
|
||||
}
|
||||
}
|
||||
+10
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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,18 +13,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.editorActions;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
|
||||
public class JavaTypedHandlerUtil {
|
||||
private JavaTypedHandlerUtil() {
|
||||
class AAAA {
|
||||
void foo() {
|
||||
sampleEnclosing("A" + "");
|
||||
}
|
||||
|
||||
public static boolean isTokenInvalidInsideReference(final IElementType tokenType) {
|
||||
return tokenType == JavaTokenType.SEMICOLON ||
|
||||
tokenType == JavaTokenType.LBRACE ||
|
||||
tokenType == JavaTokenType.RBRACE;
|
||||
private void sampleEnclosing(final String anObject) {
|
||||
new AAAA() {
|
||||
void bar() {
|
||||
System.out.println(anObject);
|
||||
}
|
||||
}.bar();
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
*/
|
||||
class AAAA {
|
||||
void foo() {
|
||||
sampleEnclosing("A");
|
||||
}
|
||||
|
||||
private void sampleEnclosing(final String s) {
|
||||
new AAAA() {
|
||||
void bar() {
|
||||
System.out.println(<selection>s + ""</selection>);
|
||||
}
|
||||
}.bar();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
java.util.ArrayList\nPsiField:l
|
||||
java.util.ArrayList\nnew
|
||||
@@ -0,0 +1,2 @@
|
||||
java.util.ArrayList\nPsiField:l
|
||||
java.util.ArrayList\nnew
|
||||
@@ -0,0 +1,6 @@
|
||||
import java.util.ArrayList;
|
||||
|
||||
class Test
|
||||
{
|
||||
ArrayList l = new ArrayList<>(8);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import java.util.ArrayList;
|
||||
|
||||
class Test
|
||||
{
|
||||
ArrayList l = new ArrayList<>(8);
|
||||
}
|
||||
+43
-1
@@ -17,14 +17,20 @@ package com.intellij.codeInsight.completion
|
||||
|
||||
import com.intellij.codeInsight.lookup.Lookup
|
||||
import com.intellij.codeInsight.lookup.LookupManager
|
||||
import com.intellij.ide.DataManager
|
||||
import com.intellij.ide.ui.UISettings
|
||||
import com.intellij.openapi.actionSystem.IdeActions
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.EditorFactory
|
||||
import com.intellij.openapi.editor.actionSystem.EditorActionManager
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.extensions.LoadingOrder
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.psi.PsiFile
|
||||
|
||||
/**
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class JavaAutoPopupTest extends CompletionAutoPopupTestCase {
|
||||
@@ -572,4 +578,40 @@ public interface Test {
|
||||
assert !lookup
|
||||
}
|
||||
|
||||
public void testTypingInAnotherEditor() {
|
||||
myFixture.configureByText("a.java", "")
|
||||
type 'c'
|
||||
assert lookup
|
||||
|
||||
Editor another = null
|
||||
def wca = new WriteCommandAction.Simple(getProject(), new PsiFile[0]) {
|
||||
@Override
|
||||
protected void run() {
|
||||
EditorActionManager.instance.getTypedAction().handler.execute(another, (char) 'x', DataManager.instance.dataContext)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
edt {
|
||||
lookup.hide()
|
||||
def file = myFixture.addFileToProject("b.java", "")
|
||||
another = EditorFactory.instance.createEditor(file.viewProvider.document, project)
|
||||
wca.execute()
|
||||
assert 'x' == another.document.text
|
||||
}
|
||||
joinAlarm()
|
||||
joinCompletion()
|
||||
def l1 = LookupManager.getActiveLookup(another)
|
||||
if (l1) {
|
||||
assert false : l1.items
|
||||
}
|
||||
type 'l'
|
||||
assert lookup
|
||||
}
|
||||
finally {
|
||||
edt { EditorFactory.instance.releaseEditor(another) }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-2
@@ -95,11 +95,11 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase {
|
||||
}
|
||||
|
||||
public void testClassStaticMembersInVoidContext() throws Throwable {
|
||||
checkPreferredItems(0, "booleanMethod", "voidMethod", "AN_OBJECT", "BOOLEAN", "Inner");
|
||||
checkPreferredItems(0, "booleanMethod", "voidMethod", "AN_OBJECT", "BOOLEAN", "class");
|
||||
}
|
||||
|
||||
public void testClassStaticMembersInBooleanContext() throws Throwable {
|
||||
checkPreferredItems(0, "booleanMethod", "voidMethod", "BOOLEAN", "AN_OBJECT", "Inner");
|
||||
checkPreferredItems(0, "booleanMethod", "voidMethod", "BOOLEAN", "AN_OBJECT", "class");
|
||||
}
|
||||
|
||||
public void testDispreferDeclared() throws Throwable {
|
||||
@@ -213,4 +213,8 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase {
|
||||
checkPreferredItems(0, "return", "rLocal", "rParam", "rMethod");
|
||||
}
|
||||
|
||||
public void testPreferModifiers() {
|
||||
checkPreferredItems(0, "private", "protected", "public", "paaa", "paab");
|
||||
}
|
||||
|
||||
}
|
||||
+8
-7
@@ -569,13 +569,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
final int parametersCount = ((PsiMethod)getLookup().getCurrentItem().getObject()).getParameterList().getParametersCount();
|
||||
assertEquals(0, parametersCount);
|
||||
new WriteCommandAction.Simple(getProject(), new PsiFile[0]) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
getLookup().finishLookup(Lookup.NORMAL_SELECT_CHAR);
|
||||
}
|
||||
}.execute().throwException();
|
||||
|
||||
type '\n'
|
||||
checkResult()
|
||||
}
|
||||
|
||||
@@ -834,6 +828,13 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
|
||||
public void testCommaAfterVariable() throws Throwable { doTest(',') }
|
||||
|
||||
public void testClassAngleBracket() throws Throwable { doTest('<') }
|
||||
|
||||
public void testClassSquareBracket() throws Throwable { doTest('[') }
|
||||
public void testPrimitiveSquareBracket() throws Throwable { doTest('[') }
|
||||
public void testVariableSquareBracket() throws Throwable { doTest('[') }
|
||||
public void testMethodSquareBracket() throws Throwable { doTest('[') }
|
||||
|
||||
public void testSuperProtectedMethod() throws Throwable {
|
||||
myFixture.addClass """package foo;
|
||||
public class Bar {
|
||||
|
||||
@@ -79,21 +79,21 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase {
|
||||
public void testImportDefaultPackage2() throws Exception { doTest(BASE_PATH+"/importDefaultPackage/x/ImportOnDemandUsage.java", BASE_PATH+"/importDefaultPackage", false, false); }
|
||||
|
||||
public void testScopeBased() throws Exception {
|
||||
NamedScope xscope = new NamedScope("xxx", new PatternPackageSet("x..*", PatternPackageSet.SCOPE_SOURCE, null));
|
||||
NamedScope utilscope = new NamedScope("util", new PatternPackageSet("java.util.*", PatternPackageSet.SCOPE_LIBRARY, null));
|
||||
NamedScope xScope = new NamedScope("xxx", new PatternPackageSet("x..*", PatternPackageSet.SCOPE_SOURCE, null));
|
||||
NamedScope utilScope = new NamedScope("util", new PatternPackageSet("java.util.*", PatternPackageSet.SCOPE_LIBRARY, null));
|
||||
NamedScopeManager scopeManager = NamedScopeManager.getInstance(getProject());
|
||||
scopeManager.addScope(xscope);
|
||||
scopeManager.addScope(utilscope);
|
||||
scopeManager.addScope(xScope);
|
||||
scopeManager.addScope(utilScope);
|
||||
|
||||
EditorColorsManager manager = EditorColorsManager.getInstance();
|
||||
EditorColorsScheme scheme = (EditorColorsScheme)manager.getGlobalScheme().clone();
|
||||
manager.addColorsScheme(scheme);
|
||||
EditorColorsManager.getInstance().setGlobalScheme(scheme);
|
||||
TextAttributesKey xKey = ColorAndFontOptions.getScopeTextAttributeKey(xscope.getName());
|
||||
TextAttributesKey xKey = ColorAndFontOptions.getScopeTextAttributeKey(xScope.getName());
|
||||
TextAttributes xAttributes = new TextAttributes(Color.cyan, Color.darkGray, Color.blue, EffectType.BOXED, Font.ITALIC);
|
||||
scheme.setAttributes(xKey, xAttributes);
|
||||
|
||||
TextAttributesKey utilKey = ColorAndFontOptions.getScopeTextAttributeKey(utilscope.getName());
|
||||
TextAttributesKey utilKey = ColorAndFontOptions.getScopeTextAttributeKey(utilScope.getName());
|
||||
TextAttributes utilAttributes = new TextAttributes(Color.gray, Color.magenta, Color.orange, EffectType.STRIKEOUT, Font.BOLD);
|
||||
scheme.setAttributes(utilKey, utilAttributes);
|
||||
|
||||
@@ -105,21 +105,21 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase {
|
||||
}
|
||||
}
|
||||
public void testSharedScopeBased() throws Exception {
|
||||
NamedScope xscope = new NamedScope("xxx", new PatternPackageSet("x..*", PatternPackageSet.SCOPE_ANY, null));
|
||||
NamedScope utilscope = new NamedScope("util", new PatternPackageSet("java.util.*", PatternPackageSet.SCOPE_LIBRARY, null));
|
||||
NamedScope xScope = new NamedScope("xxx", new PatternPackageSet("x..*", PatternPackageSet.SCOPE_ANY, null));
|
||||
NamedScope utilScope = new NamedScope("util", new PatternPackageSet("java.util.*", PatternPackageSet.SCOPE_LIBRARY, null));
|
||||
NamedScopesHolder scopeManager = DependencyValidationManager.getInstance(getProject());
|
||||
scopeManager.addScope(xscope);
|
||||
scopeManager.addScope(utilscope);
|
||||
scopeManager.addScope(xScope);
|
||||
scopeManager.addScope(utilScope);
|
||||
|
||||
EditorColorsManager manager = EditorColorsManager.getInstance();
|
||||
EditorColorsScheme scheme = (EditorColorsScheme)manager.getGlobalScheme().clone();
|
||||
manager.addColorsScheme(scheme);
|
||||
EditorColorsManager.getInstance().setGlobalScheme(scheme);
|
||||
TextAttributesKey xKey = ColorAndFontOptions.getScopeTextAttributeKey(xscope.getName());
|
||||
TextAttributesKey xKey = ColorAndFontOptions.getScopeTextAttributeKey(xScope.getName());
|
||||
TextAttributes xAttributes = new TextAttributes(Color.cyan, Color.darkGray, Color.blue, null, Font.ITALIC);
|
||||
scheme.setAttributes(xKey, xAttributes);
|
||||
|
||||
TextAttributesKey utilKey = ColorAndFontOptions.getScopeTextAttributeKey(utilscope.getName());
|
||||
TextAttributesKey utilKey = ColorAndFontOptions.getScopeTextAttributeKey(utilScope.getName());
|
||||
TextAttributes utilAttributes = new TextAttributes(Color.gray, Color.magenta, Color.orange, EffectType.STRIKEOUT, Font.BOLD);
|
||||
scheme.setAttributes(utilKey, utilAttributes);
|
||||
|
||||
@@ -158,6 +158,7 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase {
|
||||
}
|
||||
});
|
||||
|
||||
assert root != null;
|
||||
configureByExistingFile(root.findFileByRelativePath("moduleJava5/com/Java5.java"));
|
||||
Collection<HighlightInfo> infos = highlightErrors();
|
||||
assertEmpty(infos);
|
||||
@@ -168,6 +169,7 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase {
|
||||
VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(new File(path));
|
||||
loadAllModulesUnder(root);
|
||||
|
||||
assert root != null;
|
||||
configureByExistingFile(root.findFileByRelativePath("client/src/BugTest.java"));
|
||||
Collection<HighlightInfo> infos = highlightErrors();
|
||||
assertEmpty(infos);
|
||||
@@ -178,12 +180,18 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase {
|
||||
VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(new File(path));
|
||||
loadAllModulesUnder(root);
|
||||
|
||||
assert root != null;
|
||||
configureByExistingFile(root.findFileByRelativePath("src/ppp/SomeClass.java"));
|
||||
PsiField field = ((PsiJavaFile)myFile).getClasses()[0].findFieldByName("f", false);
|
||||
assert field != null;
|
||||
PsiClass aClass = ((PsiClassType)field.getType()).resolve();
|
||||
assert aClass != null;
|
||||
assertEquals("ppp.BadClass", aClass.getQualifiedName());
|
||||
//lies in source
|
||||
assertEquals(myFile.getVirtualFile().getParent(), aClass.getContainingFile().getVirtualFile().getParent());
|
||||
final VirtualFile vFile1 = myFile.getVirtualFile();
|
||||
final VirtualFile vFile2 = aClass.getContainingFile().getVirtualFile();
|
||||
assert vFile1 != null;
|
||||
assert vFile2 != null;
|
||||
assertEquals(vFile1.getParent(), vFile2.getParent());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-17
@@ -4,8 +4,6 @@ import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.javaDoc.JavaDocLocalInspection;
|
||||
import com.intellij.codeInspection.javaDoc.JavaDocReferenceInspection;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
|
||||
@@ -47,9 +45,7 @@ public class JavadocHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInlineTagAsDescription() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
public void testInlineTagAsDescription() throws Exception { doTest(); }
|
||||
|
||||
public void testParam0() throws Exception { doTestWithLangLevel(LanguageLevel.HIGHEST); }
|
||||
public void testParam1() throws Exception { doTest(); }
|
||||
@@ -62,8 +58,8 @@ public class JavadocHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testSee3() throws Exception { doTest(); }
|
||||
public void testSee4() throws Exception { doTest(); }
|
||||
public void testSee5() throws Exception { doTest(); }
|
||||
public void testSee6() throws Exception {doTest();}
|
||||
public void testSeeConstants() throws Exception { doTest();}
|
||||
public void testSee6() throws Exception { doTest(); }
|
||||
public void testSeeConstants() throws Exception { doTest(); }
|
||||
public void testReturn0() throws Exception { doTest(); }
|
||||
public void testException0() throws Exception { doTest(); }
|
||||
public void testException1() throws Exception { doTest(); }
|
||||
@@ -73,7 +69,7 @@ public class JavadocHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testMultipleThrows() throws Exception { doTest(); }
|
||||
public void testInheritJavaDoc() throws Exception {doTestWithLangLevel(LanguageLevel.JDK_1_3);}
|
||||
public void testLink0() throws Exception { doTest(); }
|
||||
public void testLinkFromInnerClassToSelfMethod() throws Exception {doTest();}
|
||||
public void testLinkFromInnerClassToSelfMethod() throws Exception { doTest(); }
|
||||
|
||||
public void testValueBadReference() throws Exception { doTestWithLangLevel(LanguageLevel.HIGHEST); }
|
||||
public void testValueGoodReference() throws Exception { doTestWithLangLevel(LanguageLevel.HIGHEST); }
|
||||
@@ -83,20 +79,18 @@ public class JavadocHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testValueNotOnStaticField() throws Exception { doTestWithLangLevel(LanguageLevel.HIGHEST); }
|
||||
public void testValueOnNotInitializedField() throws Exception { doTestWithLangLevel(LanguageLevel.HIGHEST); }
|
||||
|
||||
public void testUnknownInlineTag() throws Exception {doTest();}
|
||||
public void testUnknownTags() throws Exception {doTest();}
|
||||
public void testUnknownInlineTag() throws Exception { doTest(); }
|
||||
public void testUnknownTags() throws Exception { doTest(); }
|
||||
|
||||
public void testBadCharacters() throws Exception {doTest();}
|
||||
public void testBadCharacters() throws Exception { doTest(); }
|
||||
|
||||
public void testVararg() throws Exception {doTest();}
|
||||
public void testVararg() throws Exception { doTest(); }
|
||||
|
||||
public void testInnerClassReferenceInSignature() throws Exception {doTest();}
|
||||
public void testInnerClassReferenceInSignature() throws Exception { doTest(); }
|
||||
|
||||
public void testBadReference() throws Exception{
|
||||
doTest();
|
||||
}
|
||||
public void testBadReference() throws Exception { doTest(); }
|
||||
|
||||
public void testMissingReturnDescription() throws Exception {doTest();}
|
||||
public void testMissingReturnDescription() throws Exception { doTest(); }
|
||||
|
||||
private void doTestWithLangLevel(final LanguageLevel langLevel) throws Exception {
|
||||
LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(langLevel);
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.codeInsight.daemon;
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.javaDoc.JavaDocLocalInspection;
|
||||
import com.intellij.codeInspection.javaDoc.JavaDocReferenceInspection;
|
||||
|
||||
public class JavadocResolveTest extends DaemonAnalyzerTestCase {
|
||||
private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/javaDoc/resolve";
|
||||
|
||||
@Override
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{new JavaDocLocalInspection(), new JavaDocReferenceInspection()};
|
||||
}
|
||||
|
||||
public void testSee0() throws Exception { doTest(); }
|
||||
public void testSee1() throws Exception { doTest(); }
|
||||
public void testSee2() throws Exception { doTest(); }
|
||||
|
||||
private void doTest() throws Exception {
|
||||
doTest(BASE_PATH + "/pkg/" + getTestName(false) + ".java", BASE_PATH, false, false);
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,3 @@ public class ModifierTest extends LightQuickFixTestCase {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/modifier";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-11
@@ -17,17 +17,6 @@ package com.intellij.codeInsight.daemon.quickFix;
|
||||
|
||||
import com.intellij.codeInspection.ExplicitTypeCanBeDiamondInspection;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.accessStaticViaInstance.AccessStaticViaInstance;
|
||||
import com.intellij.codeInspection.deprecation.DeprecationInspection;
|
||||
import com.intellij.codeInspection.ex.GlobalInspectionToolWrapper;
|
||||
import com.intellij.codeInspection.javaDoc.JavaDocReferenceInspection;
|
||||
import com.intellij.codeInspection.sillyAssignment.SillyAssignmentInspection;
|
||||
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
|
||||
import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclaration;
|
||||
import com.intellij.codeInspection.unusedParameters.UnusedParametersInspection;
|
||||
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
|
||||
|
||||
|
||||
//todo test3 should be checked if it compiles - as now javac infers Object instead of String?!
|
||||
|
||||
@@ -28,6 +28,8 @@ import gnu.trove.TIntArrayList;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@TestDataPath("$CONTENT_ROOT/testData")
|
||||
public class IntroduceParameterTest extends LightCodeInsightTestCase {
|
||||
@Override
|
||||
@@ -270,6 +272,12 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase {
|
||||
checkResultByFile("/refactoring/introduceParameter/after" + getTestName(false) + ".java");
|
||||
}
|
||||
|
||||
public void testEnclosingWithParamDeletion() throws Exception {
|
||||
configureByFile("/refactoring/introduceParameter/before" + getTestName(false) + ".java");
|
||||
perform(true, 0, "anObject", false, true, true, false, 1);
|
||||
checkResultByFile("/refactoring/introduceParameter/after" + getTestName(false) + ".java");
|
||||
}
|
||||
|
||||
private static boolean perform(boolean replaceAllOccurences,
|
||||
int replaceFieldsWithGetters,
|
||||
@NonNls String parameterName,
|
||||
@@ -277,6 +285,18 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase {
|
||||
boolean declareFinal,
|
||||
final boolean removeUnusedParameters,
|
||||
final boolean generateDelegate) {
|
||||
return perform(replaceAllOccurences, replaceFieldsWithGetters, parameterName, searchForSuper, declareFinal, removeUnusedParameters,
|
||||
generateDelegate, 0);
|
||||
}
|
||||
|
||||
private static boolean perform(boolean replaceAllOccurences,
|
||||
int replaceFieldsWithGetters,
|
||||
@NonNls String parameterName,
|
||||
boolean searchForSuper,
|
||||
boolean declareFinal,
|
||||
final boolean removeUnusedParameters,
|
||||
final boolean generateDelegate,
|
||||
int enclosingLevel) {
|
||||
int startOffset = myEditor.getSelectionModel().getSelectionStart();
|
||||
int endOffset = myEditor.getSelectionModel().getSelectionEnd();
|
||||
|
||||
@@ -294,6 +314,10 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase {
|
||||
PsiMethod method = Util.getContainingMethod(context);
|
||||
if (method == null) return false;
|
||||
|
||||
final List<PsiMethod> methods = IntroduceParameterHandler.getEnclosingMethods(method);
|
||||
assertTrue(methods.size() > enclosingLevel);
|
||||
method = methods.get(enclosingLevel);
|
||||
|
||||
final PsiMethod methodToSearchFor;
|
||||
if (searchForSuper) {
|
||||
methodToSearchFor = method.findDeepestSuperMethod();
|
||||
|
||||
@@ -648,6 +648,10 @@ public class TypeCookTest extends MultiFileTestCase {
|
||||
start();
|
||||
}
|
||||
|
||||
public void testT152() throws Exception {
|
||||
start();
|
||||
}
|
||||
|
||||
public void start() throws Exception {
|
||||
start(false);
|
||||
}
|
||||
|
||||
@@ -70,6 +70,14 @@ public class InlineLocalTest extends LightCodeInsightTestCase {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void testNewExpressionWithDiamond() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void testNewExpressionWithPreservedDiamond() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void testAugmentedAssignment() throws Exception {
|
||||
String exception = null;
|
||||
try {
|
||||
|
||||
@@ -18,11 +18,13 @@ package com.intellij.psi;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -97,6 +99,11 @@ public class PsiDiamondType extends PsiType {
|
||||
}
|
||||
|
||||
public static DiamondInferenceResult resolveInferredTypes(PsiNewExpression newExpression) {
|
||||
return resolveInferredTypes(newExpression, newExpression);
|
||||
}
|
||||
|
||||
public static DiamondInferenceResult resolveInferredTypes(PsiNewExpression newExpression,
|
||||
PsiElement context) {
|
||||
final PsiClass psiClass = findClass(newExpression);
|
||||
if (psiClass == null) return DiamondInferenceResult.NULL_RESULT;
|
||||
final PsiExpressionList argumentList = newExpression.getArgumentList();
|
||||
@@ -107,12 +114,12 @@ public class PsiDiamondType extends PsiType {
|
||||
if (staticFactory == null) {
|
||||
return DiamondInferenceResult.NULL_RESULT;
|
||||
}
|
||||
final PsiSubstitutor inferredSubstitutor = inferTypeParametersForStaticFactory(staticFactory, newExpression);
|
||||
final PsiSubstitutor inferredSubstitutor = inferTypeParametersForStaticFactory(staticFactory, newExpression, context);
|
||||
final PsiTypeParameter[] parameters = staticFactory.getTypeParameters();
|
||||
final PsiTypeParameter[] classParameters = psiClass.getTypeParameters();
|
||||
final PsiJavaCodeReferenceElement classOrAnonymousClassReference = newExpression.getClassOrAnonymousClassReference();
|
||||
LOG.assertTrue(classOrAnonymousClassReference != null);
|
||||
final DiamondInferenceResult result = new DiamondInferenceResult(classOrAnonymousClassReference.getReferenceName() + "<>");
|
||||
final DiamondInferenceResult result = new DiamondInferenceResult(classOrAnonymousClassReference.getReferenceName() + "<>", newExpression.getProject());
|
||||
for (PsiTypeParameter parameter : parameters) {
|
||||
for (PsiTypeParameter classParameter : classParameters) {
|
||||
if (Comparing.strEqual(classParameter.getName(), parameter.getName())) {
|
||||
@@ -187,9 +194,10 @@ public class PsiDiamondType extends PsiType {
|
||||
}
|
||||
else {
|
||||
buf.append("(").append(StringUtil.join(constructor.getParameterList().getParameters(), new Function<PsiParameter, String>() {
|
||||
int myIdx = 0;
|
||||
@Override
|
||||
public String fun(PsiParameter psiParameter) {
|
||||
return psiParameter.getType().getCanonicalText() + " " + psiParameter.getName();
|
||||
return psiParameter.getType().getCanonicalText() + " p" + myIdx++;
|
||||
}
|
||||
}, ",")).append(")");
|
||||
}
|
||||
@@ -209,14 +217,15 @@ public class PsiDiamondType extends PsiType {
|
||||
|
||||
|
||||
private static PsiSubstitutor inferTypeParametersForStaticFactory(@NotNull PsiMethod staticFactoryMethod,
|
||||
PsiNewExpression expression) {
|
||||
PsiNewExpression expression,
|
||||
PsiElement parent) {
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(staticFactoryMethod.getProject());
|
||||
final PsiResolveHelper resolveHelper = facade.getResolveHelper();
|
||||
final PsiParameter[] parameters = staticFactoryMethod.getParameterList().getParameters();
|
||||
final PsiExpressionList argumentList = expression.getArgumentList();
|
||||
final PsiExpression[] expressions = argumentList.getExpressions();
|
||||
return resolveHelper
|
||||
.inferTypeArguments(staticFactoryMethod.getTypeParameters(), parameters, expressions, PsiSubstitutor.EMPTY, expression, false);
|
||||
.inferTypeArguments(staticFactoryMethod.getTypeParameters(), parameters, expressions, PsiSubstitutor.EMPTY, parent, false);
|
||||
}
|
||||
|
||||
public static class DiamondInferenceResult {
|
||||
@@ -236,19 +245,36 @@ public class PsiDiamondType extends PsiType {
|
||||
private String myErrorMessage;
|
||||
|
||||
private String myNewExpressionPresentableText;
|
||||
private Project myProject;
|
||||
|
||||
public DiamondInferenceResult() {
|
||||
}
|
||||
|
||||
public DiamondInferenceResult(String expressionPresentableText) {
|
||||
public DiamondInferenceResult(String expressionPresentableText, Project project) {
|
||||
myNewExpressionPresentableText = expressionPresentableText;
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public PsiType[] getTypes() {
|
||||
if (myErrorMessage != null) {
|
||||
return NULL_TYPES;
|
||||
}
|
||||
return myInferredTypes.toArray(new PsiType[myInferredTypes.size()]);
|
||||
final PsiType[] result = new PsiType[myInferredTypes.size()];
|
||||
for (int i = 0, myInferredTypesSize = myInferredTypes.size(); i < myInferredTypesSize; i++) {
|
||||
PsiType inferredType = myInferredTypes.get(i);
|
||||
if (inferredType instanceof PsiWildcardType) {
|
||||
final PsiType bound = ((PsiWildcardType)inferredType).getBound();
|
||||
result[i] = bound != null ? bound : PsiType.getJavaLangObject(PsiManager.getInstance(myProject), GlobalSearchScope.allScope(myProject));
|
||||
}
|
||||
else {
|
||||
result[i] = inferredType;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<PsiType> getInferredTypes() {
|
||||
return myInferredTypes;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
@@ -300,6 +326,26 @@ public class PsiDiamondType extends PsiType {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
DiamondInferenceResult that = (DiamondInferenceResult)o;
|
||||
|
||||
if (myErrorMessage != null ? !myErrorMessage.equals(that.myErrorMessage) : that.myErrorMessage != null) return false;
|
||||
if (!myInferredTypes.equals(that.myInferredTypes)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = myInferredTypes.hashCode();
|
||||
result = 31 * result + (myErrorMessage != null ? myErrorMessage.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasDefaultConstructor(@NotNull final PsiClass psiClass) {
|
||||
|
||||
@@ -23,16 +23,23 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
|
||||
public interface MethodSignature {
|
||||
MethodSignature[] EMPTY_ARRAY = new MethodSignature[0];
|
||||
@NotNull PsiSubstitutor getSubstitutor();
|
||||
@NotNull String getName();
|
||||
/**
|
||||
* already substituted
|
||||
*/
|
||||
@NotNull PsiType[] getParameterTypes();
|
||||
@NotNull PsiTypeParameter[] getTypeParameters();
|
||||
boolean isRaw();
|
||||
|
||||
@NotNull
|
||||
PsiSubstitutor getSubstitutor();
|
||||
|
||||
@NotNull
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* @return array of parameter types (already substituted)
|
||||
*/
|
||||
@NotNull
|
||||
PsiType[] getParameterTypes();
|
||||
|
||||
@NotNull
|
||||
PsiTypeParameter[] getTypeParameters();
|
||||
|
||||
boolean isRaw();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ import java.util.Set;
|
||||
|
||||
|
||||
public class MethodSignatureUtil {
|
||||
private MethodSignatureUtil() { }
|
||||
|
||||
public static final TObjectHashingStrategy<MethodSignatureBackedByPsiMethod> METHOD_BASED_HASHING_STRATEGY =
|
||||
new TObjectHashingStrategy<MethodSignatureBackedByPsiMethod>() {
|
||||
public int computeHashCode(final MethodSignatureBackedByPsiMethod signature) {
|
||||
@@ -40,9 +42,6 @@ public class MethodSignatureUtil {
|
||||
}
|
||||
};
|
||||
|
||||
private MethodSignatureUtil() {
|
||||
}
|
||||
|
||||
public static MethodSignature createMethodSignature(@NonNls @NotNull String name,
|
||||
@Nullable PsiParameterList parameterTypes,
|
||||
@Nullable PsiTypeParameterList typeParameterList,
|
||||
@@ -154,10 +153,12 @@ public class MethodSignatureUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiMethod findMethodBySignature(final PsiClass aClass, PsiMethod pattenMethod, boolean checkBases) {
|
||||
return findMethodBySignature(aClass, pattenMethod.getSignature(PsiSubstitutor.EMPTY), checkBases);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiMethod findMethodBySignature(final PsiClass aClass, MethodSignature methodSignature, boolean checkBases) {
|
||||
List<Pair<PsiMethod, PsiSubstitutor>> pairs = aClass.findMethodsAndTheirSubstitutorsByName(methodSignature.getName(), checkBases);
|
||||
for (Pair<PsiMethod, PsiSubstitutor> pair : pairs) {
|
||||
@@ -181,13 +182,17 @@ public class MethodSignatureUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiMethod findMethodBySuperMethod(final PsiClass aClass, PsiMethod method, final boolean checkBases) {
|
||||
List<Pair<PsiMethod, PsiSubstitutor>> pairs = aClass.findMethodsAndTheirSubstitutorsByName(method.getName(), checkBases);
|
||||
for (Pair<PsiMethod, PsiSubstitutor> pair : pairs) {
|
||||
PsiMethod candidate = pair.first;
|
||||
PsiSubstitutor substitutor = pair.second;
|
||||
MethodSignature candidateSignature = candidate.getSignature(substitutor);
|
||||
PsiSubstitutor superSubstitutor = TypeConversionUtil.getClassSubstitutor(method.getContainingClass(), candidate.getContainingClass(), substitutor);
|
||||
final PsiClass methodClass = method.getContainingClass();
|
||||
final PsiClass candidateClass = candidate.getContainingClass();
|
||||
if (methodClass == null || candidateClass == null) continue;
|
||||
PsiSubstitutor superSubstitutor = TypeConversionUtil.getClassSubstitutor(methodClass, candidateClass, substitutor);
|
||||
if (superSubstitutor == null) continue;
|
||||
MethodSignature superSignature = method.getSignature(superSubstitutor);
|
||||
if (isSubsignature(superSignature, candidateSignature)) return candidate;
|
||||
@@ -206,41 +211,47 @@ public class MethodSignatureUtil {
|
||||
}
|
||||
|
||||
public static boolean areParametersErasureEqual(PsiMethod method1, PsiMethod method2) {
|
||||
return METHOD_PARAMETERS_ERASURE_EQUALITY.equals(method1.getSignature(PsiSubstitutor.EMPTY),
|
||||
method2.getSignature(PsiSubstitutor.EMPTY));
|
||||
return areSignaturesErasureEqual(method1.getSignature(PsiSubstitutor.EMPTY), method2.getSignature(PsiSubstitutor.EMPTY));
|
||||
}
|
||||
|
||||
public static boolean areSignaturesErasureEqual(MethodSignature signature1, MethodSignature signature2) {
|
||||
return METHOD_PARAMETERS_ERASURE_EQUALITY.equals(signature1, signature2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param methodSignature
|
||||
* @param superMethodSignature
|
||||
* @param methodSignature method signature
|
||||
* @param superMethodSignature super method signature
|
||||
* @return null if signatures do not match
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiSubstitutor getSuperMethodSignatureSubstitutor(MethodSignature methodSignature, MethodSignature superMethodSignature) {
|
||||
PsiSubstitutor result = getSuperMethodSignatureSubstitutorImpl(methodSignature, superMethodSignature);
|
||||
if (result == null) return null;
|
||||
|
||||
PsiTypeParameter[] methoTypeParameters = methodSignature.getTypeParameters();
|
||||
PsiTypeParameter[] methodTypeParameters = methodSignature.getTypeParameters();
|
||||
PsiTypeParameter[] superTypeParameters = superMethodSignature.getTypeParameters();
|
||||
PsiSubstitutor methodSubstitutor = methodSignature.getSubstitutor();
|
||||
|
||||
//check bounds
|
||||
for (int i = 0; i < methoTypeParameters.length; i++) {
|
||||
PsiTypeParameter methoTypeParameter = methoTypeParameters[i];
|
||||
for (int i = 0; i < methodTypeParameters.length; i++) {
|
||||
PsiTypeParameter methodTypeParameter = methodTypeParameters[i];
|
||||
PsiTypeParameter superTypeParameter = superTypeParameters[i];
|
||||
final Set<PsiType> methoSupers = new HashSet<PsiType>();
|
||||
for (PsiClassType methoSuper : methoTypeParameter.getSuperTypes()) {
|
||||
methoSupers.add(methodSubstitutor.substitute(methoSuper));
|
||||
final Set<PsiType> methodSupers = new HashSet<PsiType>();
|
||||
for (PsiClassType methodSuper : methodTypeParameter.getSuperTypes()) {
|
||||
methodSupers.add(methodSubstitutor.substitute(methodSuper));
|
||||
}
|
||||
|
||||
final Set<PsiType> superSupers = new HashSet<PsiType>();
|
||||
for (PsiClassType superSuper : superTypeParameter.getSuperTypes()) {
|
||||
superSupers.add(methodSubstitutor.substitute(PsiUtil.captureToplevelWildcards(result.substitute(superSuper), methoTypeParameter)));
|
||||
superSupers.add(methodSubstitutor.substitute(PsiUtil.captureToplevelWildcards(result.substitute(superSuper), methodTypeParameter)));
|
||||
}
|
||||
if (!methoSupers.equals(superSupers)) return null;
|
||||
if (!methodSupers.equals(superSupers)) return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiSubstitutor getSuperMethodSignatureSubstitutorImpl(MethodSignature methodSignature, MethodSignature superSignature) {
|
||||
// normalize generic method declarations: correlate type parameters
|
||||
// todo: correlate type params by name?
|
||||
@@ -336,5 +347,4 @@ public class MethodSignatureUtil {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
@@ -65,6 +65,7 @@ abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCa
|
||||
}
|
||||
Thread.sleep(10)
|
||||
}
|
||||
printThreadDump()
|
||||
fail("Too long completion")
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -133,12 +133,12 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
|
||||
texts.add(intentionAction.getText());
|
||||
}
|
||||
Collection<HighlightInfo> infos = quickFix.doHighlighting();
|
||||
fail("Action with text '" + text + "' is not available in test " + testFullPath+"\nAvailable actions: "+texts+"\n"+actions+"\nErrors:"+infos);
|
||||
fail("Action with text '" + text + "' is not available in test " + testFullPath+"\nAvailable actions ("+texts.size()+"): "+texts+"\n"+actions+"\nInfos:"+infos);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!actionShouldBeAvailable) {
|
||||
fail("Action '" + text + "' is available in test " + testFullPath);
|
||||
fail("Action '" + text + "' is available (but must not) in test " + testFullPath);
|
||||
}
|
||||
quickFix.invoke(action);
|
||||
UIUtil.dispatchAllInvocationEvents();
|
||||
|
||||
@@ -36,17 +36,18 @@ public class InsertionContext {
|
||||
private final PsiFile myFile;
|
||||
private final Editor myEditor;
|
||||
private Runnable myLaterRunnable;
|
||||
private boolean myAddCompletionChar = true;
|
||||
private boolean myAddCompletionChar;
|
||||
|
||||
public InsertionContext(final OffsetMap offsetMap, final char completionChar, final LookupElement[] elements,
|
||||
@NotNull final PsiFile file,
|
||||
@NotNull final Editor editor) {
|
||||
@NotNull final Editor editor, final boolean addCompletionChar) {
|
||||
myOffsetMap = offsetMap;
|
||||
myCompletionChar = completionChar;
|
||||
myElements = elements;
|
||||
myFile = file;
|
||||
myEditor = editor;
|
||||
setTailOffset(editor.getCaretModel().getOffset());
|
||||
myAddCompletionChar = addCompletionChar;
|
||||
}
|
||||
|
||||
public void setTailOffset(final int offset) {
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.intellij.codeInsight.daemon;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -36,11 +35,12 @@ public class HighlightDisplayKey {
|
||||
private final String myName;
|
||||
private final String myID;
|
||||
|
||||
public static HighlightDisplayKey find(@NonNls @NotNull String name){
|
||||
public static HighlightDisplayKey find(@NonNls @NotNull final String name) {
|
||||
return ourNameToKeyMap.get(name);
|
||||
}
|
||||
|
||||
public static HighlightDisplayKey findById(@NonNls @NotNull String id){
|
||||
@Nullable
|
||||
public static HighlightDisplayKey findById(@NonNls @NotNull final String id) {
|
||||
HighlightDisplayKey key = ourIdToKeyMap.get(id);
|
||||
if (key != null) return key;
|
||||
key = ourNameToKeyMap.get(id);
|
||||
@@ -49,7 +49,7 @@ public class HighlightDisplayKey {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightDisplayKey register(@NonNls @NotNull String name) {
|
||||
public static HighlightDisplayKey register(@NonNls @NotNull final String name) {
|
||||
if (find(name) != null) {
|
||||
LOG.info("Key with name \'" + name + "\' already registered");
|
||||
return null;
|
||||
@@ -58,7 +58,14 @@ public class HighlightDisplayKey {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightDisplayKey register(@NonNls @NotNull String name, @NotNull String displayName, @NotNull @NonNls String id){
|
||||
public static HighlightDisplayKey register(@NonNls @NotNull final String name, @NotNull final String displayName) {
|
||||
return register(name, displayName, name);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightDisplayKey register(@NonNls @NotNull final String name,
|
||||
@NotNull final String displayName,
|
||||
@NotNull @NonNls final String id) {
|
||||
if (find(name) != null) {
|
||||
LOG.info("Key with name \'" + name + "\' already registered");
|
||||
return null;
|
||||
@@ -69,19 +76,49 @@ public class HighlightDisplayKey {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightDisplayKey register(@NonNls @NotNull String name, @NotNull String displayName) {
|
||||
return register(name, displayName, name);
|
||||
public static HighlightDisplayKey register(@NonNls @NotNull final String name,
|
||||
@NonNls @NotNull final String displayName,
|
||||
@NonNls @NotNull final String id,
|
||||
@NonNls @Nullable final String alternativeID) {
|
||||
final HighlightDisplayKey key = register(name, displayName, id);
|
||||
if (alternativeID != null) {
|
||||
ourKeyToAlternativeIDMap.put(key, alternativeID);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public static String getDisplayNameByKey(@Nullable HighlightDisplayKey key){
|
||||
@NotNull
|
||||
public static HighlightDisplayKey findOrRegister(@NonNls @NotNull String name, @NotNull final String displayName) {
|
||||
return findOrRegister(name, displayName, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HighlightDisplayKey findOrRegister(@NonNls @NotNull final String name,
|
||||
@NotNull final String displayName,
|
||||
@NonNls @Nullable final String id) {
|
||||
HighlightDisplayKey key = find(name);
|
||||
if (key == null) {
|
||||
key = register(name, displayName, id != null ? id : name);
|
||||
assert key != null : name;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getDisplayNameByKey(@Nullable HighlightDisplayKey key) {
|
||||
return key == null ? null : ourKeyToDisplayNameMap.get(key);
|
||||
}
|
||||
|
||||
private HighlightDisplayKey(@NotNull String name) {
|
||||
public static String getAlternativeID(@NotNull HighlightDisplayKey key) {
|
||||
return ourKeyToAlternativeIDMap.get(key);
|
||||
}
|
||||
|
||||
|
||||
private HighlightDisplayKey(@NonNls @NotNull final String name) {
|
||||
this(name, name);
|
||||
}
|
||||
|
||||
public HighlightDisplayKey(@NonNls @NotNull final String name, @NotNull @NonNls final String ID) {
|
||||
public HighlightDisplayKey(@NonNls @NotNull final String name, @NonNls @NotNull final String ID) {
|
||||
myName = name;
|
||||
myID = ID;
|
||||
ourNameToKeyMap.put(myName, this);
|
||||
@@ -97,16 +134,4 @@ public class HighlightDisplayKey {
|
||||
public String getID(){
|
||||
return myID;
|
||||
}
|
||||
|
||||
public static HighlightDisplayKey register(@NotNull String shortName, @NotNull String displayName, @NotNull String id, String alternativeID) {
|
||||
final HighlightDisplayKey key = register(shortName, displayName, id);
|
||||
if (alternativeID != null) {
|
||||
ourKeyToAlternativeIDMap.put(key, alternativeID);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public static String getAlternativeID(@NotNull HighlightDisplayKey key) {
|
||||
return ourKeyToAlternativeIDMap.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,4 +37,9 @@ public abstract class BaseIntentionAction implements IntentionAction {
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getText();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-6
@@ -131,13 +131,12 @@ public class CommonCodeStyleSettingsManager implements JDOMExternalizable {
|
||||
final String languageId = commonSettingsElement.getAttributeValue(LANGUAGE_ATTR);
|
||||
if (languageId != null && languageId.length() > 0) {
|
||||
Language target = Language.findLanguageByID(languageId);
|
||||
if (target == null) {
|
||||
target = new Language(languageId) {};
|
||||
if (target != null) {
|
||||
final CommonCodeStyleSettings defaultSettings = LanguageCodeStyleSettingsProvider.getDefaultCommonSettings(target);
|
||||
final CommonCodeStyleSettings settings = defaultSettings != null ? defaultSettings : new CommonCodeStyleSettings(target);
|
||||
settings.readExternal(commonSettingsElement);
|
||||
registerCommonSettings(target, settings);
|
||||
}
|
||||
final CommonCodeStyleSettings defaultSettings = LanguageCodeStyleSettingsProvider.getDefaultCommonSettings(target);
|
||||
final CommonCodeStyleSettings settings = defaultSettings != null ? defaultSettings : new CommonCodeStyleSettings(target);
|
||||
settings.readExternal(commonSettingsElement);
|
||||
registerCommonSettings(target, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.diagnostic.LogUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.ShutDownTracker;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IStubFileElementType;
|
||||
@@ -51,6 +52,7 @@ public class SerializationManagerImpl extends SerializationManager implements Ap
|
||||
private final AtomicBoolean myNameStorageCrashed = new AtomicBoolean(false);
|
||||
private final File myFile = new File(PathManager.getIndexRoot(), "rep.names");
|
||||
private boolean mySerializersLoaded = false;
|
||||
private final AtomicBoolean myShutdownPerformed = new AtomicBoolean(false);
|
||||
|
||||
public SerializationManagerImpl() {
|
||||
myFile.getParentFile().mkdirs();
|
||||
@@ -63,7 +65,14 @@ public class SerializationManagerImpl extends SerializationManager implements Ap
|
||||
repairNameStorage(); // need this in order for myNameStorage not to be null
|
||||
myNameStorageCrashed.set(true);
|
||||
}
|
||||
registerSerializer(PsiFileStubImpl.TYPE);
|
||||
finally {
|
||||
registerSerializer(PsiFileStubImpl.TYPE);
|
||||
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
|
||||
public void run() {
|
||||
performShutdown();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNameStorageCorrupted() {
|
||||
@@ -230,8 +239,17 @@ public class SerializationManagerImpl extends SerializationManager implements Ap
|
||||
}
|
||||
|
||||
public void disposeComponent() {
|
||||
performShutdown();
|
||||
}
|
||||
|
||||
private void performShutdown() {
|
||||
if (!myShutdownPerformed.compareAndSet(false, true)) {
|
||||
return; // already shut down
|
||||
}
|
||||
LOG.info("START StubSerializationManager SHUTDOWN");
|
||||
try {
|
||||
myNameStorage.close();
|
||||
LOG.info("END StubSerializationManager SHUTDOWN");
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user