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

This commit is contained in:
Dmitry Avdeev
2010-02-09 12:19:09 +03:00
59 changed files with 788 additions and 316 deletions
@@ -55,8 +55,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.impl.WindowManagerImpl;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.content.AlertIcon;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManagerAdapter;
@@ -424,7 +423,7 @@ public class DebuggerSessionTab extends DebuggerLogConsoleManagerBase implements
protected void toFront() {
if (!ApplicationManager.getApplication().isUnitTestMode()) {
ExecutionManager.getInstance(getProject()).getContentManager().toFrontRunContent(DefaultDebugExecutor.getDebugExecutorInstance(), myRunContentDescriptor);
ProjectUtil.focusProjectWindow(getProject());
ProjectUtil.focusProjectWindow(getProject(), Registry.is("debugger.mayBringFrameToFrontOnBreakpoint"));
}
}
@@ -20,7 +20,6 @@ import com.intellij.execution.JavaExecutionUtil;
import com.intellij.execution.configuration.BrowseModuleValueActionListener;
import com.intellij.execution.configurations.ConfigurationUtil;
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserDialog;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
@@ -51,7 +50,7 @@ public abstract class ClassBrowser extends BrowseModuleValueActionListener {
info.showNow();
return null;
}
final TreeClassChooser dialog = TreeClassChooserFactory.getInstance(getProject()).createWithInnerClassesScopeChooser(myTitle, classFilter.getScope(), classFilter, null);
final TreeClassChooser dialog = createClassChooser(classFilter);
configureDialog(dialog);
dialog.showDialog();
final PsiClass psiClass = dialog.getSelectedClass();
@@ -60,6 +59,10 @@ public abstract class ClassBrowser extends BrowseModuleValueActionListener {
return JavaExecutionUtil.getRuntimeQualifiedName(psiClass);
}
protected TreeClassChooser createClassChooser(TreeClassChooser.ClassFilterWithScope classFilter) {
return TreeClassChooserFactory.getInstance(getProject()).createWithInnerClassesScopeChooser(myTitle, classFilter.getScope(), classFilter, null);
}
protected abstract TreeClassChooser.ClassFilterWithScope getFilter() throws NoFilterException;
protected void onClassChoosen(final PsiClass psiClass) { }
@@ -91,12 +94,16 @@ public abstract class ClassBrowser extends BrowseModuleValueActionListener {
public static ClassBrowser createAppletClassBrowser(final Project project,
final ConfigurationModuleSelector moduleSelector) {
return new MainClassBrowser(project, moduleSelector, ExecutionBundle.message("choose.applet.class.dialog.title")) {
protected TreeClassChooser.ClassFilter createFilter(final Module module) {
final String title = ExecutionBundle.message("choose.applet.class.dialog.title");
return new MainClassBrowser(project, moduleSelector, title) {
@Override
protected TreeClassChooser createClassChooser(TreeClassChooser.ClassFilterWithScope classFilter) {
final Module module = moduleSelector.getModule();
final GlobalSearchScope scope =
module == null ? GlobalSearchScope.allScope(myProject) : GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module);
final PsiClass appletClass = JavaPsiFacade.getInstance(project).findClass("java.applet.Applet", scope);
return new TreeClassChooserDialog.InheritanceClassFilterImpl(appletClass, false, false, ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS);
final PsiClass appletClass = JavaPsiFacade.getInstance(project).findClass("java.applet.Applet", scope);
return TreeClassChooserFactory.getInstance(getProject()).createInheritanceClassChooser(title, classFilter.getScope(), appletClass, false, false, ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS);
}
};
}
@@ -30,7 +30,7 @@ import com.intellij.codeInsight.daemon.impl.quickfix.*;
import com.intellij.codeInsight.intention.EmptyIntentionAction;
import com.intellij.codeInspection.InspectionProfile;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.deadCode.DeadCodeInspection;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.ex.InspectionManagerEx;
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection;
@@ -97,7 +97,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
private int myCurentEntryIndex;
private boolean myHasMissortedImports;
private final ImplicitUsageProvider[] myImplicitUsageProviders;
private DeadCodeInspection myDeadCodeInspection;
private UnusedDeclarationInspection myDeadCodeInspection;
private UnusedSymbolLocalInspection myUnusedSymbolInspection;
private HighlightDisplayKey myUnusedSymbolKey;
private boolean myDeadCodeEnabled;
@@ -220,8 +220,8 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
myUnusedSymbolInspection = unusedSymbolTool == null ? null : (UnusedSymbolLocalInspection)unusedSymbolTool.getTool();
LOG.assertTrue(ApplicationManager.getApplication().isUnitTestMode() || myUnusedSymbolInspection != null);
myDeadCodeKey = HighlightDisplayKey.find(DeadCodeInspection.SHORT_NAME);
myDeadCodeInspection = (DeadCodeInspection)profile.getInspectionTool(DeadCodeInspection.SHORT_NAME, myFile);
myDeadCodeKey = HighlightDisplayKey.find(UnusedDeclarationInspection.SHORT_NAME);
myDeadCodeInspection = (UnusedDeclarationInspection)profile.getInspectionTool(UnusedDeclarationInspection.SHORT_NAME, myFile);
myDeadCodeEnabled = profile.isToolEnabled(myDeadCodeKey, myFile);
if (unusedImportEnabled && JspPsiUtil.isInJspFile(myFile)) {
final JspFile jspFile = JspPsiUtil.getJspFile(myFile);
@@ -542,7 +542,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
if (count[0] == 0 && !canbeReferencedViaWeirdNames(member)) return true;
Query<PsiReference> query = member instanceof PsiMethod
? MethodReferencesSearch.search((PsiMethod)member, scope, false)
? MethodReferencesSearch.search((PsiMethod)member, scope, true)
: ReferencesSearch.search(member, scope, true);
return query.findFirst() == null;
}
@@ -30,10 +30,10 @@ import org.jetbrains.annotations.NotNull;
*/
public class DummyEntryPointsTool extends FilteringInspectionTool {
private RefEntryPointFilter myFilter;
private final DeadCodeInspection myOwner;
private final UnusedDeclarationInspection myOwner;
private QuickFixAction[] myQuickFixActions;
public DummyEntryPointsTool(DeadCodeInspection owner) {
public DummyEntryPointsTool(UnusedDeclarationInspection owner) {
myOwner = owner;
}
@@ -75,7 +75,7 @@ import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
public class DeadCodeInspection extends FilteringInspectionTool {
public class UnusedDeclarationInspection extends FilteringInspectionTool {
public boolean ADD_MAINS_TO_ENTRIES = true;
public boolean ADD_APPLET_TO_ENTRIES = true;
@@ -83,7 +83,7 @@ public class DeadCodeInspection extends FilteringInspectionTool {
public boolean ADD_NONJAVA_TO_ENTRIES = true;
public JDOMExternalizableStringList ADDITIONAL_ANNOTATIONS = new JDOMExternalizableStringList();
private static final String[] ADDITIONAL_ANNOS = {
@NonNls private static final String[] ADDITIONAL_ANNOS = {
"javax.ws.rs.*"
};
@@ -104,7 +104,7 @@ public class DeadCodeInspection extends FilteringInspectionTool {
public final UnusedCodeExtension[] myExtensions;
public DeadCodeInspection() {
public UnusedDeclarationInspection() {
ADDITIONAL_ANNOTATIONS.addAll(Arrays.asList(ADDITIONAL_ANNOS));
myQuickFixActions = new QuickFixAction[]{new PermanentDeleteAction(), new CommentOutBin(), new MoveToEntries()};
ExtensionPoint<UnusedCodeExtension> point = Extensions.getRootArea().getExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL);
@@ -317,8 +317,8 @@ public class DeadCodeInspection extends FilteringInspectionTool {
final RefElementImpl refElement = (RefElementImpl)refEntity;
final PsiElement element = refElement.getElement();
if (element == null) return;
final boolean isSuppressed = ((RefElementImpl)refElement).isSuppressed(getShortName());
if (!getContext().isToCheckMember(element, DeadCodeInspection.this) || isSuppressed) {
final boolean isSuppressed = refElement.isSuppressed(getShortName());
if (!getContext().isToCheckMember(element, UnusedDeclarationInspection.this) || isSuppressed) {
if (isSuppressed || !scope.contains(element)) {
getEntryPointsManager().addEntryPoint(refElement, false);
}
@@ -370,7 +370,7 @@ public class DeadCodeInspection extends FilteringInspectionTool {
checkForReachables();
ProgressManager.getInstance().runProcess(new Runnable() {
public void run() {
final RefFilter filter = new StrictUnreferencedFilter(DeadCodeInspection.this);
final RefFilter filter = new StrictUnreferencedFilter(UnusedDeclarationInspection.this);
final PsiSearchHelper helper = PsiManager.getInstance(getRefManager().getProject()).getSearchHelper();
getRefManager().iterate(new RefJavaVisitor() {
@Override public void visitElement(final RefEntity refEntity) {
@@ -529,7 +529,7 @@ public class DeadCodeInspection extends FilteringInspectionTool {
if (isSerializablePatternMethod(psiMethod)) {
getEntryPointsManager().addEntryPoint(refMethod, false);
}
else if (!refMethod.isExternalOverride() && refMethod.getAccessModifier() != PsiModifier.PRIVATE) {
else if (!refMethod.isExternalOverride() && !PsiModifier.PRIVATE.equals(refMethod.getAccessModifier())) {
for (final RefMethod derivedMethod : refMethod.getDerivedMethods()) {
myProcessedSuspicious.add(derivedMethod);
}
@@ -721,7 +721,7 @@ public class DeadCodeInspection extends FilteringInspectionTool {
private class PermanentDeleteAction extends QuickFixAction {
private PermanentDeleteAction() {
super(DELETE_QUICK_FIX, IconLoader.getIcon("/actions/cancel.png"), KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), DeadCodeInspection.this);
super(DELETE_QUICK_FIX, IconLoader.getIcon("/actions/cancel.png"), KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), UnusedDeclarationInspection.this);
}
protected boolean applyFix(final RefElement[] refElements) {
@@ -739,7 +739,7 @@ public class DeadCodeInspection extends FilteringInspectionTool {
final Project project = getContext().getProject();
SafeDeleteHandler.invoke(project, psiElements.toArray(new PsiElement[psiElements.size()]), false, new Runnable(){
public void run() {
removeElements(refElements, project, DeadCodeInspection.this);
removeElements(refElements, project, UnusedDeclarationInspection.this);
}
});
}
@@ -789,7 +789,7 @@ public class DeadCodeInspection extends FilteringInspectionTool {
private class CommentOutBin extends QuickFixAction {
private CommentOutBin() {
super(COMMENT_OUT_QUICK_FIX, null, KeyStroke.getKeyStroke(KeyEvent.VK_SLASH, SystemInfo.isMac ? InputEvent.META_MASK : InputEvent.CTRL_MASK),
DeadCodeInspection.this);
UnusedDeclarationInspection.this);
}
protected boolean applyFix(RefElement[] refElements) {
@@ -846,7 +846,7 @@ public class DeadCodeInspection extends FilteringInspectionTool {
private class MoveToEntries extends QuickFixAction {
private MoveToEntries() {
super(InspectionsBundle.message("inspection.dead.code.entry.point.quickfix"), null, KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), DeadCodeInspection.this);
super(InspectionsBundle.message("inspection.dead.code.entry.point.quickfix"), null, KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), UnusedDeclarationInspection.this);
}
protected boolean applyFix(RefElement[] refElements) {
@@ -871,7 +871,7 @@ public class DeadCodeInspection extends FilteringInspectionTool {
final RefJavaElementImpl refElement = (RefJavaElementImpl)refEntity;
final PsiElement element = refElement.getElement();
if (element == null) return;
if (!getContext().isToCheckMember(refElement, DeadCodeInspection.this)) return;
if (!getContext().isToCheckMember(refElement, UnusedDeclarationInspection.this)) return;
refElement.setReachable(false);
}
}
@@ -26,7 +26,7 @@ import com.intellij.codeInspection.GlobalInspectionContext;
import com.intellij.codeInspection.GlobalJavaInspectionContext;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.deadCode.DeadCodeInspection;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.reference.*;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.application.ApplicationManager;
@@ -393,8 +393,8 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext
getEntryPointsManager(context.getRefManager()).resolveEntryPoints(context.getRefManager());
ContainerUtil.quickSort(globalTools, new Comparator<Tools>() {
public int compare(Tools o1, Tools o2) {
if (o1.getTool() instanceof DeadCodeInspection) return -1;
if (o2.getTool() instanceof DeadCodeInspection) return 1;
if (o1.getTool() instanceof UnusedDeclarationInspection) return -1;
if (o2.getTool() instanceof UnusedDeclarationInspection) return 1;
return 0;
}
});
@@ -23,7 +23,7 @@ import com.intellij.codeInspection.accessStaticViaInstance.AccessStaticViaInstan
import com.intellij.codeInspection.canBeFinal.CanBeFinalInspection;
import com.intellij.codeInspection.concurrencyAnnotations.*;
import com.intellij.codeInspection.dataFlow.DataFlowInspection;
import com.intellij.codeInspection.deadCode.DeadCodeInspection;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.defUse.DefUseInspection;
import com.intellij.codeInspection.defaultFileTemplateUsage.DefaultFileTemplateUsageInspection;
import com.intellij.codeInspection.dependencyViolation.DependencyInspection;
@@ -66,7 +66,7 @@ public class StandardInspectionToolsProvider implements InspectionToolProvider {
public Class[] getInspectionClasses() {
return new Class[] {
DeadCodeInspection.class,
UnusedDeclarationInspection.class,
UnusedLibrariesInspection.class,
InconsistentLanguageLevelInspection.class,
VisibilityInspection.class,
@@ -15,7 +15,7 @@
*/
package com.intellij.codeInspection.ui;
import com.intellij.codeInspection.deadCode.DeadCodeInspection;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.deadCode.DummyEntryPointsTool;
import com.intellij.openapi.util.IconLoader;
@@ -26,7 +26,7 @@ import javax.swing.*;
*/
public class EntryPointsNode extends InspectionNode {
private static final Icon ENTRY_POINTS = IconLoader.getIcon("/nodes/entryPoints.png");
public EntryPointsNode(DeadCodeInspection tool) {
public EntryPointsNode(UnusedDeclarationInspection tool) {
super(new DummyEntryPointsTool(tool));
getTool().updateContent();
}
@@ -20,9 +20,11 @@ import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.ide.util.projectWizard.ProjectWizardStepFactory;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.IconLoader;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.JavaPsiFacade;
@@ -67,7 +69,12 @@ public class JavaModuleType extends ModuleType<JavaModuleBuilder> {
final ProjectWizardStepFactory wizardFactory = ProjectWizardStepFactory.getInstance();
ArrayList<ModuleWizardStep> steps = new ArrayList<ModuleWizardStep>();
steps.add(wizardFactory.createSourcePathsStep(wizardContext, moduleBuilder, getWizardIcon(), "reference.dialogs.new.project.fromScratch.source"));
steps.add(wizardFactory.createProjectJdkStep(wizardContext));
steps.add(wizardFactory.createProjectJdkStep(wizardContext, JavaSdk.getInstance(), moduleBuilder, new Computable<Boolean>() {
public Boolean compute() {
final Sdk projectJdk = wizardContext.getProjectJdk();
return projectJdk == null || projectJdk.getSdkType() != JavaSdk.getInstance() ? Boolean.TRUE : Boolean.FALSE;
}
}, getWizardIcon(), "reference.dialogs.new.project.fromScratch.sdk"));
final ModuleWizardStep supportForFrameworksStep = wizardFactory.createSupportForFrameworksStep(wizardContext, moduleBuilder);
if (supportForFrameworksStep != null) {
steps.add(supportForFrameworksStep);
@@ -121,4 +128,4 @@ public class JavaModuleType extends ModuleType<JavaModuleBuilder> {
return JavaPsiFacade.getInstance(module.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT,
module.getModuleWithLibrariesScope()) != null;
}
}
}
@@ -20,19 +20,20 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.ui.NameSuggestionsField;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.ParameterTablePanel;
import com.intellij.refactoring.util.RefactoringMessageUtil;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.NonFocusableCheckBox;
import com.intellij.util.Function;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
import java.awt.*;
@@ -45,7 +46,7 @@ class AnonymousToInnerDialog extends DialogWrapper{
private final PsiAnonymousClass myAnonClass;
private final boolean myNeedsThis;
private EditorTextField myNameField;
private NameSuggestionsField myNameField;
private final ParameterTablePanel.VariableData[] myVariableData;
private final Map<PsiVariable,VariableInfo> myVariableToInfoMap = new HashMap<PsiVariable, VariableInfo>();
private JCheckBox myCbMakeStatic;
@@ -79,11 +80,20 @@ class AnonymousToInnerDialog extends DialogWrapper{
init();
final String[] names;
String name = myAnonClass.getBaseClassReference().getReferenceName();
@NonNls final String prefix = "My";
name = prefix + name; //?
myNameField.setText(name);
myNameField.selectAll();
PsiType[] typeParameters = myAnonClass.getBaseClassReference().getTypeParameters();
if (typeParameters.length > 0) {
names = new String[]{StringUtil.join(typeParameters, new Function<PsiType, String>() {
public String fun(PsiType psiType) {
return psiType.getPresentableText();
}
}, "") + name, "My" + name};
} else {
names = new String[]{"My" + name};
}
myNameField.setSuggestions(names);
myNameField.selectNameWithoutExtension();
}
protected Action[] createActions(){
@@ -104,7 +114,7 @@ class AnonymousToInnerDialog extends DialogWrapper{
}
public String getClassName() {
return myNameField.getText().trim();
return myNameField.getEnteredName();
}
public VariableInfo[] getVariableInfos() {
@@ -183,7 +193,7 @@ class AnonymousToInnerDialog extends DialogWrapper{
JLabel namePrompt = new JLabel(RefactoringBundle.message("anonymousToInner.class.name.label.text"));
panel.add(namePrompt, gbConstraints);
myNameField = new EditorTextField("");
myNameField = new NameSuggestionsField(myProject);
gbConstraints.gridwidth = 1;
gbConstraints.weightx = 1;
gbConstraints.gridx = 1;
@@ -52,10 +52,10 @@ public class CopyClassesHandler implements CopyHandlerDelegate {
FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.copyClass");
PsiClass aClass = convertToTopLevelClass(elements);
assert aClass != null;
Project project = aClass.getProject();
if (defaultTargetDirectory == null) {
defaultTargetDirectory = aClass.getContainingFile().getContainingDirectory();
}
Project project = defaultTargetDirectory.getProject();
CopyClassDialog dialog = new CopyClassDialog(aClass, defaultTargetDirectory, project, false);
dialog.setTitle(RefactoringBundle.message("copy.handler.copy.class"));
dialog.show();
@@ -33,8 +33,10 @@ import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.MethodReferencesSearch;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.IntroduceParameterRefactoring;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
@@ -253,7 +255,15 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
for (final UsageInfo usageInfo : usageArray) {
if (usageInfo instanceof ExternalUsageInfo && isMethodUsage(usageInfo)) {
final PsiElement place = usageInfo.getElement();
for (final PsiElement element : result) {
for (PsiElement element : result) {
if (element instanceof PsiField && myReplaceFieldsWithGetters != IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE) { //check getter access instead
final PsiClass psiClass = ((PsiField)element).getContainingClass();
LOG.assertTrue(psiClass != null);
final PsiMethod method = psiClass.findMethodBySignature(PropertyUtil.generateGetterPrototype((PsiField)element), true);
if (method != null){
element = method;
}
}
if (element instanceof PsiMember &&
!JavaPsiFacade.getInstance(myProject).getResolveHelper().isAccessible((PsiMember)element, place, null)) {
String message =
@@ -227,10 +227,9 @@ public class OldReferenceResolver {
if (JavaPsiFacade.getInstance(psiField.getProject()).getResolveHelper().isAccessible(getter, newExpr, null)) {
PsiElementFactory factory = JavaPsiFacade.getInstance(newExpr.getProject()).getElementFactory();
String id = getter.getName();
final PsiElement parent = newExpr.getParent();
String qualifier = null;
if (parent instanceof PsiReferenceExpression) {
final PsiExpression qualifierExpression = ((PsiReferenceExpression)parent).getQualifierExpression();
if (newExpr instanceof PsiReferenceExpression) {
final PsiExpression qualifierExpression = ((PsiReferenceExpression)newExpr).getQualifierExpression();
if (qualifierExpression != null) {
qualifier = qualifierExpression.getText();
}
@@ -238,8 +237,8 @@ public class OldReferenceResolver {
PsiMethodCallExpression getterCall =
(PsiMethodCallExpression)factory.createExpressionFromText((qualifier != null ? qualifier + "." : "") + id + "()", null);
getterCall = (PsiMethodCallExpression)CodeStyleManager.getInstance(myProject).reformat(getterCall);
if (parent != null) {
newExpr = parent.replace(getterCall);
if (newExpr.getParent() != null) {
newExpr = newExpr.replace(getterCall);
}
else {
newExpr = getterCall;
@@ -577,6 +577,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
}
declaration = (PsiDeclarationStatement) putStatementInLoopBody(declaration, container, finalAnchorStatement);
declaration = (PsiDeclarationStatement)JavaCodeStyleManager.getInstance(project).shortenClassReferences(declaration);
PsiVariable var = (PsiVariable) declaration.getDeclaredElements()[0];
PsiUtil.setModifierProperty(var, PsiModifier.FINAL, declareFinal);
@@ -39,6 +39,7 @@ import com.intellij.refactoring.rename.RenameUtil;
import com.intellij.refactoring.util.*;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import com.intellij.util.VisibilityUtil;
@@ -142,7 +143,12 @@ public class MoveClassToInnerProcessor extends BaseRefactoringProcessor {
for (PsiClass classToMove : myClassesToMove) {
ChangeContextUtil.encodeContextInfo(classToMove, true);
PsiClass newClass = (PsiClass)myTargetClass.addBefore(classToMove, myTargetClass.getRBrace());
PsiUtil.setModifierProperty(newClass, PsiModifier.STATIC, true);
if (myTargetClass.isInterface()) {
PsiUtil.setModifierProperty(newClass, PsiModifier.PACKAGE_LOCAL, true);
}
else {
PsiUtil.setModifierProperty(newClass, PsiModifier.STATIC, true);
}
newClass = (PsiClass)ChangeContextUtil.decodeContextInfo(newClass, null, null);
oldToNewElementsMapping.put(classToMove, newClass);
}
@@ -290,7 +296,11 @@ public class MoveClassToInnerProcessor extends BaseRefactoringProcessor {
protected String getCommandName() {
return RefactoringBundle.message("move.class.to.inner.command.name",
myClassesToMove[0].getQualifiedName(),
(myClassesToMove.length > 1 ? "classes " : "class ") + StringUtil.join(myClassesToMove, new Function<PsiClass, String>() {
public String fun(PsiClass psiClass) {
return psiClass.getName();
}
}, ", "),
myTargetClass.getQualifiedName());
}
@@ -80,7 +80,7 @@ public class JavaNameSuggestionProvider implements NameSuggestionProvider {
}
final String[] strings = info != null ? info.names : ArrayUtil.EMPTY_STRING_ARRAY;
ArrayList<String> list = new ArrayList<String>(Arrays.asList(strings));
final String properlyCased = suggestProperlyCasedName(element);
final String[] properlyCased = suggestProperlyCasedName(element);
if (!list.contains(initialName)) {
list.add(0, initialName);
}
@@ -89,8 +89,10 @@ public class JavaNameSuggestionProvider implements NameSuggestionProvider {
list.remove(i);
list.add(0, initialName);
}
if (properlyCased != null && !properlyCased.equals(initialName)) {
list.add(1, properlyCased);
if (properlyCased != null) {
for (String properlyCasedSuggestion : properlyCased) {
list.add(1, properlyCasedSuggestion);
}
}
if (parameterName != null && !list.contains(parameterName)) {
list.add(parameterName);
@@ -137,7 +139,7 @@ public class JavaNameSuggestionProvider implements NameSuggestionProvider {
}
@Nullable
private static String suggestProperlyCasedName(PsiElement psiElement) {
private static String[] suggestProperlyCasedName(PsiElement psiElement) {
if (!(psiElement instanceof PsiNamedElement)) return null;
String name = ((PsiNamedElement)psiElement).getName();
if (name == null) return null;
@@ -156,25 +158,29 @@ public class JavaNameSuggestionProvider implements NameSuggestionProvider {
if (i > 0) buffer.append('_');
buffer.append(word.toUpperCase());
}
return buffer.toString();
return new String[] {buffer.toString()};
}
else {
StringBuilder buffer = new StringBuilder(prefix);
for (int i = 0; i < words.length; i++) {
String word = words[i];
final boolean prefixRequiresCapitalization = prefix.length() > 0 && !StringUtil.endsWithChar(prefix, '_');
if (i > 0 || prefixRequiresCapitalization) {
buffer.append(StringUtil.capitalize(word));
}
else {
buffer.append(StringUtil.decapitalize(word));
}
}
return buffer.toString();
return new String[]{suggestProperlyCasedName(prefix, words), suggestProperlyCasedName(prefix, NameUtil.splitNameIntoWords(name.toLowerCase()))};
}
}
return name;
return new String[]{name};
}
private static String suggestProperlyCasedName(String prefix, String[] words) {
StringBuilder buffer = new StringBuilder(prefix);
for (int i = 0; i < words.length; i++) {
String word = words[i];
final boolean prefixRequiresCapitalization = prefix.length() > 0 && !StringUtil.endsWithChar(prefix, '_');
if (i > 0 || prefixRequiresCapitalization) {
buffer.append(StringUtil.capitalize(word));
}
else {
buffer.append(StringUtil.decapitalize(word));
}
}
return buffer.toString();
}
@Nullable
@@ -23,7 +23,7 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.HelpID;
@@ -36,7 +36,7 @@ import com.intellij.refactoring.util.RefactoringMessageUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashSet;
import com.intellij.util.Processor;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
@@ -192,11 +192,11 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
}
if (getter != null) {
addOverriddenAndImplemented(aClass, getter, newGetterName, allRenames);
addOverriddenAndImplemented(getter, newGetterName, allRenames);
}
if (setter != null) {
addOverriddenAndImplemented(aClass, setter, newSetterName, allRenames);
addOverriddenAndImplemented(setter, newSetterName, allRenames);
}
if (shouldRenameSetterParameter) {
@@ -211,18 +211,16 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
return Messages.showYesNoDialog(project, text, RefactoringBundle.message("rename.title"), Messages.getQuestionIcon()) != 0;
}
private static void addOverriddenAndImplemented(PsiClass aClass, PsiMethod methodPrototype, String newName,
final Map<PsiElement, String> allRenames) {
final HashSet<PsiClass> superClasses = new HashSet<PsiClass>();
InheritanceUtil.getSuperClasses(aClass, superClasses, true);
superClasses.add(aClass);
for (PsiClass superClass : superClasses) {
PsiMethod method = superClass.findMethodBySignature(methodPrototype, false);
if (method != null) {
allRenames.put(method, newName);
}
private static void addOverriddenAndImplemented(PsiMethod methodPrototype, final String newName, final Map<PsiElement, String> allRenames) {
allRenames.put(methodPrototype, newName);
for (PsiMethod method : methodPrototype.findDeepestSuperMethods()) {
OverridingMethodsSearch.search(method).forEach(new Processor<PsiMethod>() {
public boolean process(PsiMethod psiMethod) {
allRenames.put(psiMethod, newName);
return true;
}
});
allRenames.put(method, newName);
}
}
@@ -15,9 +15,12 @@
*/
package com.intellij.refactoring.safeDelete;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Disposer;
import com.intellij.psi.PsiSubstitutor;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.refactoring.HelpID;
@@ -25,20 +28,23 @@ import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteOverridingMethodUsageInfo;
import com.intellij.ui.BooleanTableCellRenderer;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.util.ui.Table;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.impl.UsagePreviewPanel;
import com.intellij.util.ui.Table;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumnModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jetbrains.annotations.NonNls;
/**
* @author dsl
*/
@@ -49,6 +55,7 @@ class OverridingMethodsDialog extends DialogWrapper {
private static final int CHECK_COLUMN = 0;
private Table myTable;
private final UsagePreviewPanel myUsagePreviewPanel;
public OverridingMethodsDialog(Project project, List<UsageInfo> overridingMethods) {
super(project, true);
@@ -67,7 +74,7 @@ class OverridingMethodsDialog extends DialogWrapper {
PsiFormatUtil.SHOW_TYPE
);
}
myUsagePreviewPanel = new UsagePreviewPanel(project);
setTitle(RefactoringBundle.message("unused.overriding.methods.title"));
init();
}
@@ -106,6 +113,12 @@ class OverridingMethodsDialog extends DialogWrapper {
return myTable;
}
@Override
protected void dispose() {
Disposer.dispose(myUsagePreviewPanel);
super.dispose();
}
protected JComponent createCenterPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(8, 0, 4, 0));
@@ -157,7 +170,35 @@ class OverridingMethodsDialog extends DialogWrapper {
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable);
panel.add(scrollPane, BorderLayout.CENTER);
return panel;
ListSelectionListener selectionListener = new ListSelectionListener() {
public void valueChanged(final ListSelectionEvent e) {
int index = myTable.getSelectionModel().getLeadSelectionIndex();
if (index != -1) {
UsageInfo usageInfo = myOverridingMethods.get(index);
myUsagePreviewPanel.updateLayout(Collections.singletonList(usageInfo));
}
else {
myUsagePreviewPanel.updateLayout(null);
}
}
};
myTable.getSelectionModel().addListSelectionListener(selectionListener);
final Splitter splitter = new Splitter(true, 0.3f);
splitter.setFirstComponent(panel);
splitter.setSecondComponent(myUsagePreviewPanel);
myUsagePreviewPanel.updateLayout(null);
Disposer.register(myDisposable, new Disposable(){
public void dispose() {
splitter.dispose();
}
});
if (tableModel.getRowCount() != 0) {
myTable.getSelectionModel().addSelectionInterval(0,0);
}
return splitter;
}
class MyTableModel extends AbstractTableModel {
@@ -294,6 +294,9 @@ public abstract class TurnRefsToSuperProcessorBase extends BaseRefactoringProces
processUsage(variable);
return;
}
} else if (classReference.getParent() instanceof PsiAnonymousClass) {
processUsage(classReference);
return;
}
}
markNode(ref); //???
@@ -635,10 +638,17 @@ public abstract class TurnRefsToSuperProcessorBase extends BaseRefactoringProces
final PsiType type = ((PsiParameter)element).getType();
final PsiClass aClass = PsiUtil.resolveClassInType(type);
if (aClass != null) {
if (!myManager.isInProject(element) || !myManager.areElementsEquivalent(aClass, myClass)) {
if (!isSuperInheritor(aClass)) {
markNode(element);
if (aClass instanceof PsiTypeParameter) {
for (Node node : myElementToNode.get(element).mySuccessors) {
final PsiResolveHelper psiResolveHelper = JavaPsiFacade.getInstance(myProject).getResolveHelper();
final PsiType psiType = psiResolveHelper
.inferTypeForMethodTypeParameter((PsiTypeParameter)aClass, new PsiParameter[]{(PsiParameter)element},
new PsiExpression[]{(PsiExpression)node.myMark.myElement}, PsiSubstitutor.EMPTY, null,
false);
if (checkNode(element, PsiUtil.resolveClassInType(psiType))) break;
}
} else {
checkNode(element, aClass);
}
}
else { // unresolvable class
@@ -648,6 +658,16 @@ public abstract class TurnRefsToSuperProcessorBase extends BaseRefactoringProces
}
}
private boolean checkNode(PsiElement element, PsiClass psiClass) {
if (!myManager.isInProject(element) || !myManager.areElementsEquivalent(psiClass, myClass)) {
if (!isSuperInheritor(psiClass)) {
markNode(element);
return true;
}
}
return false;
}
protected abstract boolean isSuperInheritor(PsiClass aClass);
protected abstract boolean isInSuper(PsiElement member);
@@ -0,0 +1,17 @@
public class R {
private static int ourInt;
public static int getOurInt() {
return ourInt;
}
public static void doSmth(final int anObject) {
System.out.println(anObject);
}
}
class Usage {
void foo() {
R.doSmth(R.getOurInt());
}
}
@@ -0,0 +1,17 @@
public class R {
private static int ourInt;
public static int getOurInt() {
return ourInt;
}
public static void doSmth() {
System.out.println(<selection>ourInt</selection>);
}
}
class Usage {
void foo() {
R.doSmth();
}
}
@@ -1,6 +1,6 @@
package pack2;
public interface A {
static class Class1 {
class Class1 {
}
}
@@ -0,0 +1,20 @@
interface Intf {
}
interface Factory<E extends Intf> {
E create();
void save(E obj);
static class helper {
static Factory<Intf> get2() {
return (Factory)new Factory<Intf>() {
public Intf create() { return null; }
public void save(Intf obj) { }
};
}
}
}
public class Clazz implements Intf {
}
@@ -0,0 +1,20 @@
interface Intf {
}
interface Factory<E extends Intf> {
E create();
void save(E obj);
static class helper {
static Factory<Intf> get2() {
return (Factory)new Factory<Clazz>() {
public Clazz create() { return null; }
public void save(Clazz obj) { }
};
}
}
}
public class Clazz implements Intf {
}
@@ -0,0 +1,22 @@
interface Intf {
}
interface Factory<E extends Intf> {
E create();
void save(E obj);
static class helper {
static Factory<Intf> get() {
return null;
}
}
}
public class Clazz implements Intf {
void bar() {
Intf y = Factory.helper.get().create();
Factory.helper.get().save(y);
}
}
@@ -0,0 +1,22 @@
interface Intf {
}
interface Factory<E extends Intf> {
E create();
void save(E obj);
static class helper {
static Factory<Intf> get() {
return null;
}
}
}
public class Clazz implements Intf {
void bar() {
Clazz y = Factory.helper.get().create();
Factory.helper.get().save(y);
}
}
@@ -1,7 +1,7 @@
package com.intellij.codeInspection;
import com.intellij.JavaTestUtil;
import com.intellij.codeInspection.deadCode.DeadCodeInspection;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaPsiFacade;
@@ -10,8 +10,8 @@ import com.intellij.testFramework.InspectionTestCase;
/**
* @author max
*/
public class DeadCodeTest extends InspectionTestCase {
private DeadCodeInspection myTool;
public class UnusedDeclarationTest extends InspectionTestCase {
private UnusedDeclarationInspection myTool;
@Override
protected String getTestDataPath() {
@@ -20,7 +20,7 @@ public class DeadCodeTest extends InspectionTestCase {
protected void setUp() throws Exception {
super.setUp();
myTool = new DeadCodeInspection();
myTool = new UnusedDeclarationInspection();
LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_3);
}
@@ -40,11 +40,11 @@ public class ChangeSignatureTargetTest extends LightCodeInsightTestCase {
}
private void doTest(String expectedMemberName) throws Exception {
String basePath = "/refactoring/changeSignatureTarget/" + getTestName(false);
String basePath = "/refactoring/changeSignatureTarget/" + getTestName(true);
@NonNls final String filePath = basePath + ".java";
configureByFile(filePath);
final PsiMember member = ChangeSignatureTargetUtil.findTargetMember(getFile(), getEditor());
assertNotNull(member);
assertEquals(expectedMemberName, member.getName());
}
}
}
@@ -8,12 +8,14 @@ import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.PsiLocalVariable;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.LightCodeInsightTestCase;
import com.intellij.testFramework.TestDataPath;
import junit.framework.Assert;
import org.jetbrains.annotations.NonNls;
/**
* @author ven
*/
@TestDataPath("$CONTENT_ROOT/testData")
public class IntroduceConstantTest extends LightCodeInsightTestCase {
@NonNls private static final String BASE_PATH = "/refactoring/introduceConstant/";
@@ -22,10 +22,12 @@ import com.intellij.refactoring.introduceParameter.IntroduceParameterHandler;
import com.intellij.refactoring.introduceParameter.IntroduceParameterProcessor;
import com.intellij.refactoring.introduceParameter.Util;
import com.intellij.testFramework.LightCodeInsightTestCase;
import com.intellij.testFramework.TestDataPath;
import gnu.trove.TIntArrayList;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
@TestDataPath("$CONTENT_ROOT/testData")
public class IntroduceParameterTest extends LightCodeInsightTestCase {
@Override
protected String getTestDataPath() {
@@ -234,6 +236,10 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase {
"Incomplete call(Root()): expected to delete the 1 parameter but only 0 parameters found");
}
public void testStaticFieldWithGetterReplacement() throws Exception {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, true, false, true, false);
}
private void doTestThroughHandler() throws Exception {
configureByFile("/refactoring/introduceParameter/before" + getTestName(false) + ".java");
new IntroduceParameterHandler().invoke(getProject(), myEditor, myFile, new DataContext() {
@@ -126,6 +126,14 @@ public class TurnRefsToSuperTest extends MultiFileTestCase {
doTest("IImpl", "I", false);
}
public void testAnonymousWithTypeArguments() throws Exception {
doTest("Clazz", "Intf", false);
}
public void testTypeArgumentsParam() throws Exception {
doTest("Clazz", "Intf", false);
}
private void doTest(@NonNls final String className, @NonNls final String superClassName, final boolean replaceInstanceOf) throws Exception {
doTest(new PerformAction() {
public void performAction(VirtualFile rootDir, VirtualFile rootAfter) throws Exception {
@@ -28,7 +28,7 @@ import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInspection.GlobalInspectionTool;
import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.deadCode.DeadCodeInspection;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.ex.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.PathManagerEx;
@@ -114,7 +114,7 @@ public abstract class InspectionTestCase extends PsiTestCase {
globalContext.setCurrentScope(scope);
if (runDeadCodeFirst) {
runTool(new DeadCodeInspection(), scope, globalContext, inspectionManager);
runTool(new UnusedDeclarationInspection(), scope, globalContext, inspectionManager);
}
runTool(tool, scope, globalContext, inspectionManager);
}
@@ -27,6 +27,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
@@ -231,6 +232,9 @@ public class Browser extends JPanel {
String fileURL = url.toExternalForm();
fileURL = fileURL.substring(0, fileURL.indexOf('#'));
VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(fileURL);
if (vFile == null) {
vFile = VfsUtil.findFileByURL(url);
}
if (vFile != null) {
fireClickEvent(vFile, offset, offset);
}
@@ -220,7 +220,10 @@ public class BookmarkManager implements PersistentStateComponent<Element> {
}
private void writeExternal(Element element) {
for (Bookmark bookmark : myBookmarks) {
List<Bookmark> reversed = new ArrayList<Bookmark>(myBookmarks);
Collections.reverse(reversed);
for (Bookmark bookmark : reversed) {
Element bookmarkElement = new Element("bookmark");
bookmarkElement.setAttribute("url", bookmark.getFile().getUrl());
@@ -1188,11 +1188,14 @@ public abstract class ChooseByNameBase{
}
private List<String> split(String s) {
for (String separator : myModel.getSeparators()) {
final List<String> result = StringUtil.split(s, separator);
if (!result.isEmpty()) return result;
List<String> answer = new ArrayList<String>();
for (String token : StringUtil.tokenize(s, StringUtil.join(myModel.getSeparators(), ""))) {
if (token.length() > 0) {
answer.add(token);
}
}
return Collections.singletonList(s);
return answer.isEmpty() ? Collections.singletonList(s) : answer;
}
private boolean matchesQualifier(final Object element, final String qualifierPattern) {
@@ -474,6 +474,10 @@ public class EditorWindow implements EditorEx, UserDataHolderEx {
return myDelegate.setCaretVisible(b);
}
public boolean setCaretEnabled(boolean enabled) {
return myDelegate.setCaretEnabled(enabled);
}
public void addFocusListener(final FocusChangeListener listener) {
myDelegate.addFocusListener(listener);
}
@@ -16,11 +16,14 @@
package com.intellij.refactoring.rename;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.psi.PsiNamedElement;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.rename.naming.AutomaticRenamer;
@@ -211,7 +214,7 @@ public class AutomaticRenamingDialog extends DialogWrapper {
}
protected void dispose() {
myUsagePreviewPanel.dispose();
Disposer.dispose(myUsagePreviewPanel);
super.dispose();
}
@@ -241,7 +244,15 @@ public class AutomaticRenamingDialog extends DialogWrapper {
case CHECK_COLUMN:
return Boolean.valueOf(myShouldRename[rowIndex]);
case OLD_NAME_COLUMN:
return myRenames[rowIndex].getName();
final PsiNamedElement namedElement = myRenames[rowIndex];
String location = null;
if (namedElement instanceof NavigationItem) {
final ItemPresentation presentation = ((NavigationItem)namedElement).getPresentation();
if (presentation != null) {
location = presentation.getLocationString();
}
}
return namedElement.getName() + (location != null ? " " + location : "");
case NEW_NAME_COLUMN:
return myNewNames[rowIndex];
default:
@@ -398,7 +398,13 @@ public class PluginManager {
}
public static boolean isIncompatible(final IdeaPluginDescriptor descriptor) {
BuildNumber buildNumber = getBuildNumber();
BuildNumber buildNumber = null;
try {
buildNumber = getBuildNumber();
}
catch (RuntimeException e) {
return false;
}
if (!StringUtil.isEmpty(descriptor.getSinceBuild())) {
BuildNumber sinceBuild = BuildNumber.fromString(descriptor.getSinceBuild());
@@ -31,6 +31,8 @@ public abstract class FocusCommand extends ActiveRunnable implements Expirable {
private Component myDominationComponent;
private Throwable myAllocation;
private ActionCallback myCallback;
protected FocusCommand() {
}
@@ -56,6 +58,14 @@ public abstract class FocusCommand extends ActiveRunnable implements Expirable {
myDominationComponent = dominationComp;
}
public final ActionCallback getCallback() {
return myCallback;
}
public final void setCallback(ActionCallback callback) {
myCallback = callback;
}
public boolean isExpired() {
return false;
}
@@ -17,6 +17,7 @@ package com.intellij.openapi.wm;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ActionCallback;
@@ -131,8 +132,17 @@ public abstract class IdeFocusManager {
public abstract Expirable getTimestamp(boolean trackOnlyForcedCommands);
@NotNull
public static IdeFocusManager getGlobalInstance() {
return ApplicationManager.getApplication().getComponent(IdeFocusManager.class);
Application app = ApplicationManager.getApplication();
IdeFocusManager fm = app != null ? app.getComponent(IdeFocusManager.class) : PassThroughtIdeFocusManager.getInstance();
// It happens when IDEA server dialog is shown, app != null but it's semi-initialized
if (fm == null) {
fm = PassThroughtIdeFocusManager.getInstance();
}
return fm;
}
}
@@ -145,7 +145,7 @@ public class ProjectUtil {
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
for (Project project : openProjects) {
if (isSameProject(path, project)) {
focusProjectWindow(project);
focusProjectWindow(project, false);
return project;
}
}
@@ -206,18 +206,24 @@ public class ProjectUtil {
return FileUtil.pathsEqual(toOpen, existing);
}
public static void focusProjectWindow(final Project p) {
IdeFocusManager.getInstance(p).requestFocus(new FocusCommand() {
public static void focusProjectWindow(final Project p, boolean executeIfAppInactive) {
FocusCommand cmd = new FocusCommand() {
@Override
public ActionCallback run() {
JFrame f = WindowManager.getInstance().getFrame(p);
if (f != null) {
f.toFront();
f.requestFocus();
//f.requestFocus();
}
return new ActionCallback.Done();
}
}, false);
};
if (executeIfAppInactive) {
cmd.run();
} else {
IdeFocusManager.getInstance(p).requestFocus(cmd, false);
}
}
public static boolean isProjectOrWorkspaceFile(final VirtualFile file) {
@@ -328,6 +328,9 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
try {
action.run();
}
catch (ProcessCanceledException e) {
// ignore
}
catch (Throwable t) {
LOG.error(t);
}
@@ -87,6 +87,8 @@ public interface EditorEx extends Editor {
boolean setCaretVisible(boolean b);
boolean setCaretEnabled(boolean enabled);
void addFocusListener(FocusChangeListener listener);
void setOneLineMode(boolean b);
@@ -549,7 +549,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myEditorComponent.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
myCaretCursor.activate(false);
myCaretCursor.activate();
int caretLine = getCaretModel().getLogicalPosition().line;
repaintLines(caretLine, caretLine);
fireFocusGained();
@@ -2669,10 +2669,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
public boolean setCaretVisible(boolean b) {
myCaretCursor.setVisible(b);
boolean old = myCaretCursor.isActive();
if (b) {
myCaretCursor.activate(true);
myCaretCursor.activate();
}
else {
myCaretCursor.passivate();
@@ -2680,6 +2679,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
return old;
}
public boolean setCaretEnabled(boolean enabled) {
boolean old = myCaretCursor.isEnabled();
myCaretCursor.setEnabled(enabled);
return old;
}
public void addFocusListener(FocusChangeListener listener) {
myFocusListeners.add(listener);
}
@@ -2722,7 +2727,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
private class CaretCursor {
private Point myLocation;
private int myWidth;
private boolean myIsVisible;
private boolean myEnabled;
@SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"})
private boolean myIsShown = false;
@@ -2730,23 +2735,18 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
private CaretCursor() {
myLocation = new Point(0, 0);
myIsVisible = true;
setEnabled(true);
}
public boolean isVisible() {
return myIsVisible;
public boolean isEnabled() {
return myEnabled;
}
public void setVisible(boolean visible) {
myIsVisible = visible;
public void setEnabled(boolean enabled) {
myEnabled = enabled;
}
private void activate(boolean enforceVisible) {
if (enforceVisible) {
setVisible(true);
}
if (!myIsVisible) return;
private void activate() {
final boolean blink = mySettings.isBlinkCaret();
final int blinkPeriod = mySettings.getCaretBlinkPeriod();
synchronized (ourCaretBlinkingCommand) {
@@ -2772,7 +2772,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
private void setPosition(Point location, int width) {
myStartTime = System.currentTimeMillis();
myLocation = location;
myIsShown = myIsVisible;
myWidth = Math.max(width, 2);
repaint();
}
@@ -2782,7 +2781,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
private void paint(Graphics g) {
if (!myIsShown || !IJSwingUtilities.hasFocus(getContentComponent()) || isRendererMode()) return;
if (!isEnabled() || !myIsShown || !IJSwingUtilities.hasFocus(getContentComponent()) || isRendererMode()) return;
int x = myLocation.x;
int lineHeight = getLineHeight();
@@ -102,10 +102,12 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
private boolean myFilterFocumentWasChanged;
//[back/forward] private ActionToolbar myToolbar;
private Window myWindow;
private PropertiesComponent myProperties;
public OptionsEditor(Project project, ConfigurableGroup[] groups, Configurable preselectedConfigurable) {
myProject = project;
myGroups = groups;
myProperties = PropertiesComponent.getInstance(project);
myFilter = new Filter();
myContext = new OptionsEditorContext(myFilter);
@@ -244,7 +246,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
private float readPropertion(final float defaultValue, final String propertyName) {
float proportion = defaultValue;
try {
final String p = PropertiesComponent.getInstance(myProject).getValue(propertyName);
final String p = myProperties.getValue(propertyName);
if (p != null) {
proportion = Float.valueOf(p);
}
@@ -829,10 +831,9 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
}
public void dispose() {
final PropertiesComponent props = PropertiesComponent.getInstance(myProject);
props.setValue(MAIN_SPLITTER_PROPORTION, String.valueOf(myMainSplitter.getProportion()));
props.setValue(DETAILS_SPLITTER_PROPORTION, String.valueOf(myContentWrapper.myLastSplitterProproprtion));
props.setValue(SEARCH_VISIBLE, Boolean.valueOf(isFilterFieldVisible()).toString());
myProperties.setValue(MAIN_SPLITTER_PROPORTION, String.valueOf(myMainSplitter.getProportion()));
myProperties.setValue(DETAILS_SPLITTER_PROPORTION, String.valueOf(myContentWrapper.myLastSplitterProproprtion));
myProperties.setValue(SEARCH_VISIBLE, Boolean.valueOf(isFilterFieldVisible()).toString());
Toolkit.getDefaultToolkit().removeAWTEventListener(this);
@@ -15,7 +15,6 @@
*/
package com.intellij.openapi.wm.impl;
import com.intellij.Patches;
import com.intellij.ide.IdeEventQueue;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
@@ -41,6 +40,7 @@ import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -151,6 +151,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
if (checkForRejectOrByPass(command, forced, result)) return;
setCommand(command);
command.setCallback(result);
if (forced) {
myForcedFocusRequestsAlarm.cancelAllRequests();
@@ -190,7 +191,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
}
}).doWhenProcessed(new Runnable() {
public void run() {
resetCommand(command);
resetCommand(command, true);
if (forced) {
myForcedFocusRequestsAlarm.addRequest(new EdtRunnable() {
@@ -258,7 +259,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
}
}
private void resetCommand(FocusCommand cmd) {
private void resetCommand(FocusCommand cmd, boolean reject) {
if (cmd == myRequestFocusCmd) {
myRequestFocusCmd = null;
}
@@ -269,6 +270,13 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
}
myFocusRequests.remove(cmd);
if (reject) {
ActionCallback cb = cmd.getCallback();
if (cb != null && !cb.isProcessed()) {
cmd.getCallback().setRejected();
}
}
}
private void resetUnforcedCommand(FocusCommand cmd) {
@@ -381,12 +389,31 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
}
public boolean isFocusTransferReady() {
invalidateFocusRequestsQueue();
if (!myFocusRequests.isEmpty()) return false;
if (myQueue == null) return true;
return !myQueue.isSuspendMode() && !myQueue.hasFocusEventsPending();
}
private void invalidateFocusRequestsQueue() {
if (myFocusRequests.size() == 0) return;
FocusCommand[] requests = myFocusRequests.toArray(new FocusCommand[myFocusRequests.size()]);
boolean wasChanged = false;
for (FocusCommand each : requests) {
if (each.isExpired()) {
resetCommand(each, true);
wasChanged = true;
}
}
if (wasChanged && myFocusRequests.size() == 0) {
restartIdleAlarm();
}
}
private boolean isIdleQueueEmpty() {
return isPendingKeyEventsRedispatched() && myIdleRequests.isEmpty();
}
@@ -461,7 +488,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
private void rejectCommand(FocusCommand cmd, ActionCallback callback) {
resetCommand(cmd);
resetCommand(cmd, true);
resetUnforcedCommand(cmd);
callback.setRejected();
@@ -691,7 +691,7 @@ inline.to.anonymous.no.abstract=Abstract classes cannot be inlined
inline.to.anonymous.no.inheritors=Classes which have subclasses cannot be inlined
inline.to.anonymous.no.multiple.interfaces=Classes which implement multiple interfaces cannot be inlined
inline.to.anonymous.no.superclass.and.interface=Classes which have a superclass and implement an interface cannot be inlined
move.class.to.inner.command.name=Move class {0} to {1}
move.class.to.inner.command.name=Move {0} to {1}
move.classes.destination.to.package=To packa&ge
move.classes.destination.make.inner=&Make inner class of
move.to.inner.duplicate.inner.class=Class {0} already contains an inner class named {1}
@@ -41,6 +41,7 @@ ide.tabbedPane.bufferedPaint=true
debugger.valueTooltipAutoShow=true
debugger.valueTooltipAutoShow.description=Auto show tooltip on mouse over
debugger.mayBringFrameToFrontOnBreakpoint=true
filesystem.useNative=true
@@ -95,7 +95,7 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
* @param filePath - relative path from %IDEA_INSTALLATION_HOME%/testData/
* @throws Exception
*/
protected void configureByFile(@NonNls String filePath) throws Exception {
protected void configureByFile(@TestDataFile @NonNls String filePath) throws Exception {
String fullPath = getTestDataPath() + filePath;
final File ioFile = new File(fullPath);
@@ -1236,7 +1236,7 @@ public class StringUtil {
@NonNls StringBuilder result = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
final char c = text.charAt(i);
if (c == ' ' || Character.isLetter(c) || Character.isDigit(c)) {
if (c == ' ' || Character.isLetter(c) || Character.isDigit(c) || c == '_') {
result.append(c);
}
else if (c == '\n') {
@@ -97,7 +97,7 @@ public class ChangeListViewerDialog extends DialogWrapper implements DataProvide
private void initCommitMessageArea(final Project project, final CommittedChangeList changeList) {
myCommitMessageArea = new JEditorPane(UIUtil.HTML_MIME, "");
myCommitMessageArea.setEditable(false);
@NonNls final String text = IssueLinkHtmlRenderer.formatTextIntoHtml(project, changeList.getComment());
@NonNls final String text = IssueLinkHtmlRenderer.formatTextIntoHtml(project, changeList.getComment().trim());
myCommitMessageArea.setBackground(UIUtil.getComboBoxDisabledBackground());
myCommitMessageArea.addHyperlinkListener(new BrowserHyperlinkListener());
commitMessageScroll = new JScrollPane(myCommitMessageArea);
@@ -37,7 +37,7 @@ import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.tabs.PinToolwindowTabAction;
import com.intellij.xdebugger.XDebugProcess;
@@ -259,7 +259,7 @@ public class XDebugSessionTab extends DebuggerLogConsoleManagerBase {
public void toFront() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
ProjectUtil.focusProjectWindow(getProject());
ProjectUtil.focusProjectWindow(getProject(), Registry.is("debugger.mayBringFrameToFrontOnBreakpoint"));
ExecutionManager.getInstance(getProject()).getContentManager().toFrontRunContent(DefaultDebugExecutor.getDebugExecutorInstance(), myRunContentDescriptor);
}
});
@@ -5,6 +5,14 @@
<version>1.0.0</version>
<vendor url="http://www.jetbrains.com" logo="/general/ijLogo.png">JetBrains</vendor>
<actions>
<action id="TestData.Navigate"
class="com.intellij.testAssistant.NavigateToTestDataAction"
text="Navigate to testdata">
<keyboard-shortcut first-keystroke="control shift D" keymap="$default"/>
</action>
</actions>
<extensions defaultExtensionNs="com.intellij">
<codeInsight.lineMarkerProvider language="JAVA" implementationClass="com.intellij.testAssistant.TestDataLineMarkerProvider"/>
<fileEditorProvider implementation="com.intellij.testAssistant.TestDataGroupEditorProvider"/>
@@ -0,0 +1,87 @@
/*
* Copyright 2000-2010 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.testAssistant;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* @author yole
*/
public class NavigateToTestDataAction extends AnAction {
@Override
public void actionPerformed(AnActionEvent e) {
final PsiMethod method = findTargetMethod(e);
final Editor editor = e.getData(PlatformDataKeys.EDITOR);
if (method == null || editor == null) {
return;
}
final String name = method.getName();
if (name.startsWith("test")) {
final String testDataPath = TestDataLineMarkerProvider.getTestDataBasePath(method.getContainingClass());
if (testDataPath == null) {
final Notification notification =
new Notification("testdata", "No testdata path", "Cannot find testdata path for class", NotificationType.INFORMATION);
Notifications.Bus.notify(notification, method.getProject());
}
else {
final TestDataReferenceCollector collector = new TestDataReferenceCollector(testDataPath, name.substring(4));
List<String> fileNames = collector.collectTestDataReferences(method);
if (fileNames.size() == 0) {
String message = collector.getLog();
if (message == null) {
message = "Cannot find testdata files for class";
}
final Notification notification = new Notification("testdata", "Found no testdata files", message, NotificationType.INFORMATION);
Notifications.Bus.notify(notification, method.getProject());
}
else {
new TestDataNavigationHandler(fileNames).navigate(method, JBPopupFactory.getInstance().guessBestPopupLocation(editor));
}
}
}
}
@Override
public void update(AnActionEvent e) {
e.getPresentation().setEnabled(findTargetMethod(e) != null);
}
@Nullable
private static PsiMethod findTargetMethod(AnActionEvent e) {
final Editor editor = e.getData(PlatformDataKeys.EDITOR);
final PsiFile file = e.getData(LangDataKeys.PSI_FILE);
if (file != null && editor != null) {
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
return PsiTreeUtil.getParentOfType(element, PsiMethod.class);
}
return null;
}
}
@@ -2,35 +2,15 @@ package com.intellij.testAssistant;
import com.intellij.codeHighlighting.Pass;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.LineMarkerProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Icons;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -63,7 +43,7 @@ public class TestDataLineMarkerProvider implements LineMarkerProvider {
}
@Nullable
private static String getTestDataBasePath(PsiClass psiClass) {
public static String getTestDataBasePath(PsiClass psiClass) {
final PsiAnnotation annotation = AnnotationUtil.findAnnotationInHierarchy(psiClass, Collections.singleton("com.intellij.testFramework.TestDataPath"));
if (annotation != null) {
final PsiAnnotationMemberValue value = annotation.findAttributeValue(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME);
@@ -85,127 +65,4 @@ public class TestDataLineMarkerProvider implements LineMarkerProvider {
return null;
}
private static class TestDataNavigationHandler implements GutterIconNavigationHandler<PsiMethod> {
private List<String> myFileNames;
public TestDataNavigationHandler(List<String> fileNames) {
myFileNames = fileNames;
}
public void navigate(MouseEvent e, final PsiMethod elt) {
if (myFileNames.size() == 1) {
openFileByIndex(elt.getProject(), 0);
}
else {
TestDataGroupVirtualFile groupFile = getTestDataGroup();
if (groupFile != null) {
new OpenFileDescriptor(elt.getProject(), groupFile).navigate(true);
}
else {
showNavigationPopup(elt.getProject(), e);
}
}
}
@Nullable
private TestDataGroupVirtualFile getTestDataGroup() {
if (myFileNames.size() != 2) {
return null;
}
VirtualFile file1 = LocalFileSystem.getInstance().refreshAndFindFileByPath(myFileNames.get(0));
VirtualFile file2 = LocalFileSystem.getInstance().refreshAndFindFileByPath(myFileNames.get(1));
if (file1 == null || file2 == null) {
return null;
}
final int commonPrefixLength = StringUtil.commonPrefixLength(file1.getName(), file2.getName());
if (file1.getName().substring(commonPrefixLength).toLowerCase().contains("after")) {
return new TestDataGroupVirtualFile(file2, file1);
}
if (file2.getName().substring(commonPrefixLength).toLowerCase().contains("after")) {
return new TestDataGroupVirtualFile(file1, file2);
}
return null;
}
private void showNavigationPopup(final Project project, MouseEvent e) {
List<String> shortNames = new ArrayList<String>();
for (String fileName : myFileNames) {
shortNames.add(new File(fileName).getName());
}
final String CREATE_MISSING_OPTION = "Create Missing Files";
if (myFileNames.size() == 2) {
shortNames.add(CREATE_MISSING_OPTION);
}
final JList list = new JList(shortNames.toArray(new String[shortNames.size()]));
list.setCellRenderer(new ColoredListCellRenderer() {
@Override
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
String fileName = (String)value;
if (!fileName.equals(CREATE_MISSING_OPTION)) {
final FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(fileName);
setIcon(fileType.getIcon());
}
append(fileName);
}
});
PopupChooserBuilder builder = new PopupChooserBuilder(list);
builder.setItemChoosenCallback(new Runnable() {
public void run() {
final int[] indices = list.getSelectedIndices();
if (ArrayUtil.indexOf(indices, myFileNames.size()) >= 0) {
createMissingFiles(project);
}
else {
for (int index : indices) {
openFileByIndex(project, index);
}
}
}
}).createPopup().show(new RelativePoint(e));
}
private void createMissingFiles(Project project) {
for (String name : myFileNames) {
if (LocalFileSystem.getInstance().refreshAndFindFileByPath(name) == null) {
createFileByName(project, name);
}
}
final TestDataGroupVirtualFile testDataGroup = getTestDataGroup();
if (testDataGroup != null) {
new OpenFileDescriptor(project, testDataGroup).navigate(true);
}
}
private void openFileByIndex(final Project project, final int index) {
final String path = myFileNames.get(index);
final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
if (file != null) {
new OpenFileDescriptor(project, file).navigate(true);
}
else {
int rc = Messages.showYesNoDialog(project, "The referenced testdata file " + path + " does not exist. Would you like to create it?",
"Create Testdata File", Messages.getQuestionIcon());
if (rc == 0) {
VirtualFile vFile = createFileByName(project, path);
new OpenFileDescriptor(project, vFile).navigate(true);
}
}
}
private VirtualFile createFileByName(final Project project, final String path) {
return ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
public VirtualFile compute() {
try {
final File file = new File(path);
final VirtualFile parent = VfsUtil.createDirectories(file.getParent());
return parent.createChildData(this, file.getName());
}
catch (IOException e) {
Messages.showErrorDialog(project, e.getMessage(), "Create Testdata File");
return null;
}
}
});
}
}
}
@@ -0,0 +1,173 @@
/*
* Copyright 2000-2010 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.testAssistant;
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiMethod;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author yole
*/
public class TestDataNavigationHandler implements GutterIconNavigationHandler<PsiMethod> {
private List<String> myFileNames;
public TestDataNavigationHandler(List<String> fileNames) {
myFileNames = fileNames;
}
public void navigate(MouseEvent e, final PsiMethod elt) {
navigate(elt, new RelativePoint(e));
}
public void navigate(PsiMethod elt, final RelativePoint point) {
if (myFileNames.size() == 1) {
openFileByIndex(elt.getProject(), 0);
}
else {
TestDataGroupVirtualFile groupFile = getTestDataGroup();
if (groupFile != null) {
new OpenFileDescriptor(elt.getProject(), groupFile).navigate(true);
}
else {
showNavigationPopup(elt.getProject(), point);
}
}
}
@Nullable
private TestDataGroupVirtualFile getTestDataGroup() {
if (myFileNames.size() != 2) {
return null;
}
VirtualFile file1 = LocalFileSystem.getInstance().refreshAndFindFileByPath(myFileNames.get(0));
VirtualFile file2 = LocalFileSystem.getInstance().refreshAndFindFileByPath(myFileNames.get(1));
if (file1 == null || file2 == null) {
return null;
}
final int commonPrefixLength = StringUtil.commonPrefixLength(file1.getName(), file2.getName());
if (file1.getName().substring(commonPrefixLength).toLowerCase().contains("after")) {
return new TestDataGroupVirtualFile(file2, file1);
}
if (file2.getName().substring(commonPrefixLength).toLowerCase().contains("after")) {
return new TestDataGroupVirtualFile(file1, file2);
}
return null;
}
private void showNavigationPopup(final Project project, final RelativePoint point) {
List<String> shortNames = new ArrayList<String>();
for (String fileName : myFileNames) {
shortNames.add(new File(fileName).getName());
}
final String CREATE_MISSING_OPTION = "Create Missing Files";
if (myFileNames.size() == 2) {
shortNames.add(CREATE_MISSING_OPTION);
}
final JList list = new JList(shortNames.toArray(new String[shortNames.size()]));
list.setCellRenderer(new ColoredListCellRenderer() {
@Override
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
String fileName = (String)value;
if (!fileName.equals(CREATE_MISSING_OPTION)) {
final FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(fileName);
setIcon(fileType.getIcon());
}
append(fileName);
}
});
PopupChooserBuilder builder = new PopupChooserBuilder(list);
builder.setItemChoosenCallback(new Runnable() {
public void run() {
final int[] indices = list.getSelectedIndices();
if (ArrayUtil.indexOf(indices, myFileNames.size()) >= 0) {
createMissingFiles(project);
}
else {
for (int index : indices) {
openFileByIndex(project, index);
}
}
}
}).createPopup().show(point);
}
private void createMissingFiles(Project project) {
for (String name : myFileNames) {
if (LocalFileSystem.getInstance().refreshAndFindFileByPath(name) == null) {
createFileByName(project, name);
}
}
final TestDataGroupVirtualFile testDataGroup = getTestDataGroup();
if (testDataGroup != null) {
new OpenFileDescriptor(project, testDataGroup).navigate(true);
}
}
private void openFileByIndex(final Project project, final int index) {
final String path = myFileNames.get(index);
final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
if (file != null) {
new OpenFileDescriptor(project, file).navigate(true);
}
else {
int rc = Messages.showYesNoDialog(project, "The referenced testdata file " + path + " does not exist. Would you like to create it?",
"Create Testdata File", Messages.getQuestionIcon());
if (rc == 0) {
VirtualFile vFile = createFileByName(project, path);
new OpenFileDescriptor(project, vFile).navigate(true);
}
}
}
private VirtualFile createFileByName(final Project project, final String path) {
return ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
public VirtualFile compute() {
try {
final File file = new File(path);
final VirtualFile parent = VfsUtil.createDirectories(file.getParent());
return parent.createChildData(this, file.getName());
}
catch (IOException e) {
Messages.showErrorDialog(project, e.getMessage(), "Create Testdata File");
return null;
}
}
});
}
}
@@ -15,6 +15,8 @@
*/
package com.intellij.testAssistant;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.testFramework.UsefulTestCase;
import org.jetbrains.annotations.Nullable;
@@ -27,6 +29,8 @@ import java.util.*;
public class TestDataReferenceCollector {
private final String myTestDataPath;
private final String myTestName;
private final List<String> myLogMessages = new ArrayList<String>();
private boolean myFoundTestDataParameters = false;
public TestDataReferenceCollector(String testDataPath, String testName) {
myTestDataPath = testDataPath;
@@ -34,10 +38,14 @@ public class TestDataReferenceCollector {
}
List<String> collectTestDataReferences(final PsiMethod method) {
return collectTestDataReferences(method, new HashMap<String, String>());
final List<String> result = collectTestDataReferences(method, new HashMap<String, Computable<String>>());
if (!myFoundTestDataParameters) {
myLogMessages.add("Found no parameters annotated with @TestDataFile");
}
return result;
}
private List<String> collectTestDataReferences(final PsiMethod method, final Map<String, String> argumentMap) {
private List<String> collectTestDataReferences(final PsiMethod method, final Map<String, Computable<String>> argumentMap) {
final List<String> result = new ArrayList<String>();
method.accept(new JavaRecursiveElementVisitor() {
@Override
@@ -52,6 +60,7 @@ public class TestDataReferenceCollector {
PsiParameter psiParameter = psiParameters[i];
final PsiModifierList modifierList = psiParameter.getModifierList();
if (modifierList != null && modifierList.findAnnotation("com.intellij.testFramework.TestDataFile") != null) {
myFoundTestDataParameters = true;
processCallArgument(expression, argumentMap, result, i);
haveAnnotatedParameters = true;
}
@@ -65,7 +74,7 @@ public class TestDataReferenceCollector {
return result;
}
private void processCallArgument(PsiMethodCallExpression expression, Map<String, String> argumentMap, List<String> result, final int index) {
private void processCallArgument(PsiMethodCallExpression expression, Map<String, Computable<String>> argumentMap, List<String> result, final int index) {
final PsiExpression[] arguments = expression.getArgumentList().getExpressions();
if (arguments.length > index) {
String testDataFile = evaluate(arguments [index], argumentMap);
@@ -75,21 +84,23 @@ public class TestDataReferenceCollector {
}
}
private Map<String, String> buildArgumentMap(PsiMethodCallExpression expression, PsiMethod method) {
Map<String, String> result = new HashMap<String, String>();
private Map<String, Computable<String>> buildArgumentMap(PsiMethodCallExpression expression, PsiMethod method) {
Map<String, Computable<String>> result = new HashMap<String, Computable<String>>();
final PsiParameter[] parameters = method.getParameterList().getParameters();
final PsiExpression[] arguments = expression.getArgumentList().getExpressions();
for (int i = 0; i < arguments.length && i < parameters.length; i++) {
String value = evaluate(arguments [i], Collections.<String, String>emptyMap());
if (value != null) {
result.put(parameters [i].getName(), value);
}
final int finalI = i;
result.put(parameters [i].getName(), new Computable<String>() {
public String compute() {
return evaluate(arguments [finalI], Collections.<String, Computable<String>>emptyMap());
}
});
}
return result;
}
@Nullable
private String evaluate(PsiExpression expression, Map<String, String> arguments) {
private String evaluate(PsiExpression expression, Map<String, Computable<String>> arguments) {
if (expression instanceof PsiBinaryExpression) {
PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression;
if (binaryExpression.getOperationTokenType() == JavaTokenType.PLUS) {
@@ -110,7 +121,7 @@ public class TestDataReferenceCollector {
final PsiElement result = ((PsiReferenceExpression)expression).resolve();
if (result instanceof PsiParameter) {
final String name = ((PsiParameter)result).getName();
return arguments.get(name);
return arguments.get(name).compute();
}
if (result instanceof PsiVariable) {
final PsiExpression initializer = ((PsiVariable)result).getInitializer();
@@ -133,6 +144,11 @@ public class TestDataReferenceCollector {
}
}
}
myLogMessages.add("Failed to evaluate " + expression.getText());
return null;
}
public String getLog() {
return StringUtil.join(myLogMessages, "\n");
}
}
@@ -20,7 +20,6 @@ import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.command.undo.DocumentReference;
import com.intellij.openapi.command.undo.UndoManager;
import com.intellij.openapi.command.undo.UndoableAction;
import com.intellij.openapi.command.undo.UnexpectedUndoException;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
@@ -277,7 +276,7 @@ public final class Configuration implements PersistentStateComponent<Element> {
}
@Nullable
public static Configuration load(final InputStream is) throws IOException, JDOMException, InvalidDataException {
public static Configuration load(final InputStream is) throws IOException, JDOMException {
try {
final Document document = JDOMUtil.loadDocument(is);
final ArrayList<Element> elements = new ArrayList<Element>();
@@ -465,11 +464,11 @@ public final class Configuration implements PersistentStateComponent<Element> {
final List<? extends PsiElement> psiElementsToRemove,
final PairProcessor<T, T> actualProcessor) {
final UndoableAction action = new UndoableAction() {
public void undo() throws UnexpectedUndoException {
public void undo() {
actualProcessor.process(remove, add);
}
public void redo() throws UnexpectedUndoException {
public void redo() {
actualProcessor.process(add, remove);
}
@@ -425,11 +425,11 @@ public class I18nInspection extends BaseLocalInspectionTool {
fixes.add(createIntroduceConstantFix(expression));
}
final PsiManager manager = expression.getManager();
if (PsiUtil.getLanguageLevel(expression).hasEnumKeywordAndAutoboxing() &&
JavaPsiFacade.getInstance(manager.getProject()).findClass(AnnotationUtil.NON_NLS, expression.getResolveScope()) != null) {
for(PsiModifierListOwner element: nonNlsTargets) {
if (!AnnotationUtil.isAnnotated(element, AnnotationUtil.NLS, true)) {
final JavaPsiFacade facade = JavaPsiFacade.getInstance(expression.getManager().getProject());
if (PsiUtil.getLanguageLevel(expression).hasEnumKeywordAndAutoboxing()) {
for (PsiModifierListOwner element : nonNlsTargets) {
if (!AnnotationUtil.isAnnotated(element, AnnotationUtil.NLS, true) &&
facade.findClass(AnnotationUtil.NON_NLS, element.getResolveScope()) != null) {
fixes.add(new AddAnnotationFix(AnnotationUtil.NON_NLS, element));
}
}