Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Eugene Kudelevsky
2011-03-09 14:41:48 +03:00
280 changed files with 4470 additions and 2374 deletions
@@ -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));
}
}
}
@@ -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);
}
@@ -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();
@@ -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"})
@@ -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() {
@@ -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;
}
}
@@ -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) {
@@ -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);
@@ -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);
@@ -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,
@@ -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));
}
}
@@ -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) {
@@ -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());
}
@@ -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;
}
}
}
@@ -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();
@@ -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();
@@ -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;
@@ -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;
@@ -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);
}
}
}
@@ -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;
@@ -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()) {
@@ -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();
}
}
}
};
@@ -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());
}
@@ -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);
}
}
@@ -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;
}
}
}
@@ -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();
}
}
}
}
}
@@ -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);
}
}
@@ -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 ||
@@ -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
*/
@@ -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;
@@ -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);
}
}
@@ -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,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);
@@ -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 {}
}
@@ -0,0 +1,5 @@
class Foo {
double[<caret>]
class doz {}
}
@@ -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>
}
}
@@ -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 {}
}
@@ -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) { }
}
@@ -0,0 +1,12 @@
// "Make 'e' not final" "false"
class C {
static {
try {
throw new Exception();
}
catch (RuntimeException | IOException e) {
<caret>e = null;
}
}
}
@@ -0,0 +1,9 @@
// "Make 'r' not final" "false"
class C {
void m() throws Exception {
try (AutoCloseable r = null) {
<caret>r = null;
}
}
}
@@ -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();
}
}
}
@@ -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>());
}
}
@@ -0,0 +1,9 @@
import java.util.*;
class Test {
void foo(){
Map<Integer, String> m<caret>ap = new HashMap<>();
Map<Integer, String> map1 = map;
}
}
@@ -0,0 +1,8 @@
import java.util.*;
class Test {
void foo(){
Map<Integer, String> map1 = new HashMap<>();
}
}
@@ -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();
}
}
@@ -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);
}
@@ -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) }
}
}
}
@@ -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");
}
}
@@ -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());
}
}
@@ -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";
}
}
@@ -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;
}
}
@@ -65,6 +65,7 @@ abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCa
}
Thread.sleep(10)
}
printThreadDump()
fail("Too long completion")
}
@@ -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();
}
}
@@ -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