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

This commit is contained in:
nik
2009-11-26 09:25:11 +03:00
74 changed files with 1097 additions and 242 deletions
Binary file not shown.
Binary file not shown.
-1
View File
@@ -13,7 +13,6 @@
<orderEntry type="library" name="OroMatcher" level="project" />
<orderEntry type="library" name="commons-collections" level="project" />
<orderEntry type="module" module-name="xml" />
<orderEntry type="library" name="Groovy" level="project" />
<orderEntry type="module" module-name="java-runtime" />
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="module" module-name="compiler-openapi" />
@@ -44,6 +44,9 @@ public class CopyPasteReferenceProcessor implements CopyPastePostProcessor {
if (file instanceof PsiCompiledElement) {
file = (PsiFile) ((PsiCompiledElement) file).getMirror();
}
if (!(file instanceof PsiClassOwner)) {
return new ReferenceTransferableData(new ReferenceTransferableData.ReferenceData[0]);
}
final ArrayList<ReferenceTransferableData.ReferenceData> array = new ArrayList<ReferenceTransferableData.ReferenceData>();
for (int j = 0; j < startOffsets.length; j++) {
@@ -104,10 +107,13 @@ public class CopyPasteReferenceProcessor implements CopyPastePostProcessor {
if (DumbService.getInstance(project).isDumb()) {
return;
}
final Document document = editor.getDocument();
final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (!(file instanceof PsiClassOwner)) {
return;
}
PsiDocumentManager.getInstance(project).commitAllDocuments();
final ReferenceTransferableData.ReferenceData[] referenceData = ((ReferenceTransferableData)value).getData();
final PsiJavaCodeReferenceElement[] refs = findReferencesToRestore(file, bounds, referenceData);
@@ -18,14 +18,15 @@ package com.intellij.ide.projectView.impl.nodes;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collection;
import org.jetbrains.annotations.NotNull;
public class PackageViewModuleNode extends AbstractModuleNode{
public PackageViewModuleNode(Project project, Module value, ViewSettings viewSettings) {
super(project, value, viewSettings);
@@ -45,4 +46,9 @@ public class PackageViewModuleNode extends AbstractModuleNode{
}
public boolean contains(@NotNull VirtualFile file) {
Module module = getValue();
return module != null && !module.isDisposed() &&
(ModuleUtil.moduleContainsFile(module, file, false) || ModuleUtil.moduleContainsFile(module, file, true));
}
}
@@ -1,28 +1,27 @@
/*
* 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.
*/
* 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.refactoring.actions;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.*;
import com.intellij.refactoring.RefactoringActionHandler;
import com.intellij.refactoring.changeSignature.ChangeSignatureHandler;
import com.intellij.refactoring.changeSignature.ChangeSignatureTargetUtil;
public class ChangeSignatureAction extends BaseRefactoringAction {
public boolean isAvailableInEditorOnly() {
@@ -34,10 +33,15 @@ public class ChangeSignatureAction extends BaseRefactoringAction {
}
protected boolean isAvailableOnElementInEditor(final PsiElement element, final Editor editor) {
final Document document = editor.getDocument();
final PsiFile file = PsiDocumentManager.getInstance(element.getProject()).getPsiFile(document);
if (file != null && ChangeSignatureTargetUtil.findTargetMember(file, editor) != null) {
return true;
}
return element instanceof PsiMethod || element instanceof PsiClass;
}
public RefactoringActionHandler getHandler(DataContext dataContext) {
return new ChangeSignatureHandler();
}
}
}
@@ -37,7 +37,10 @@ public class ChangeSignatureHandler implements RefactoringActionHandler {
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
PsiElement element = ChangeSignatureTargetUtil.findTargetMember(file, editor);
if (element == null) {
element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
}
invokeOnElement(project, editor, element);
}
@@ -93,4 +96,4 @@ public class ChangeSignatureHandler implements RefactoringActionHandler {
ChangeClassSignatureDialog dialog = new ChangeClassSignatureDialog(aClass);
dialog.show();
}
}
}
@@ -0,0 +1,77 @@
/*
* 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: 24-Nov-2009
*/
package com.intellij.refactoring.changeSignature;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
public class ChangeSignatureTargetUtil {
private ChangeSignatureTargetUtil() {}
@Nullable
public static PsiMember findTargetMember(PsiFile file, Editor editor) {
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
if (PsiTreeUtil.getParentOfType(element, PsiParameterList.class) != null) {
return PsiTreeUtil.getParentOfType(element, PsiMethod.class);
}
final PsiMethodCallExpression expression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (expression != null) {
assert element != null;
final PsiExpression qualifierExpression = expression.getMethodExpression().getQualifierExpression();
if (PsiTreeUtil.isAncestor(qualifierExpression, element, false)) {
final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(qualifierExpression, PsiExpressionList.class);
if (expressionList != null) {
final PsiElement parent = expressionList.getParent();
if (parent instanceof PsiMethodCallExpression) {
return ((PsiMethodCallExpression)parent).resolveMethod();
}
}
} else {
return expression.resolveMethod();
}
}
final PsiTypeParameterList typeParameterList = PsiTreeUtil.getParentOfType(element, PsiTypeParameterList.class);
if (typeParameterList != null) {
return PsiTreeUtil.getParentOfType(typeParameterList, PsiMember.class);
}
final PsiReferenceParameterList referenceParameterList = PsiTreeUtil.getParentOfType(element, PsiReferenceParameterList.class);
if (referenceParameterList != null) {
final PsiJavaCodeReferenceElement referenceElement =
PsiTreeUtil.getParentOfType(referenceParameterList, PsiJavaCodeReferenceElement.class);
if (referenceElement != null) {
final PsiElement resolved = referenceElement.resolve();
if (resolved instanceof PsiClass) {
return (PsiMember)resolved;
}
else if (resolved instanceof PsiMethod) {
return (PsiMember)resolved;
}
}
}
return null;
}
}
@@ -53,6 +53,7 @@ class CopyClassDialog extends DialogWrapper{
public CopyClassDialog(PsiClass aClass, PsiDirectory defaultTargetDirectory, Project project, boolean doClone) {
super(project, true);
myProject = project;
myDefaultTargetDirectory = defaultTargetDirectory;
init();
myDoClone = doClone;
String text = myDoClone ? RefactoringBundle.message("copy.class.clone.0.1", UsageViewUtil.getType(aClass), UsageViewUtil.getLongName(aClass)) :
@@ -60,13 +61,6 @@ class CopyClassDialog extends DialogWrapper{
myInformationLabel.setText(text);
myNameField.setText(UsageViewUtil.getShortName(aClass));
myNameLabel.setText(RefactoringBundle.message("name.prompt"));
myDefaultTargetDirectory = defaultTargetDirectory;
if (myDefaultTargetDirectory != null) {
PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(myDefaultTargetDirectory);
if (aPackage != null) {
myTfPackage.prependItem(aPackage.getQualifiedName());
}
}
if (myDoClone) {
myTfPackage.setVisible(false);
myPackageLabel.setVisible(false);
@@ -116,7 +110,18 @@ class CopyClassDialog extends DialogWrapper{
gbConstraints.gridx = 1;
gbConstraints.weightx = 1;
myTfPackage = new PackageNameReferenceEditorCombo("", myProject, RECENTS_KEY, RefactoringBundle.message("choose.destination.package"));
String qualifiedName = "";
if (myDefaultTargetDirectory != null) {
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(myDefaultTargetDirectory);
if (aPackage != null) {
qualifiedName = aPackage.getQualifiedName();
}
}
myTfPackage = new PackageNameReferenceEditorCombo(qualifiedName, myProject, RECENTS_KEY, RefactoringBundle.message("choose.destination.package"));
if (qualifiedName.length() > 0) {
myTfPackage.setTextFieldPreferredWidth(qualifiedName.length() + 5);
}
myPackageLabel.setText(RefactoringBundle.message("destination.package"));
@@ -89,19 +89,9 @@ public class ExtractMethodDialog extends AbstractExtractDialog {
myStaticFlag = isStatic;
myCanBeStatic = canBeStatic;
myElementsToExtract = elementsToExtract;
boolean canBeVarargs = false;
for (ParameterTablePanel.VariableData data : inputVariables.getInputVariables()) {
canBeVarargs |= data.type instanceof PsiArrayType;
}
myVariableData = inputVariables;
if (inputVariables.isFoldable()) {
canBeVarargs |= inputVariables.isFoldingSelectedByDefault();
}
setTitle(title);
myHelpId = helpId;
setTitle(title);
// Create UI components
@@ -118,9 +108,6 @@ public class ExtractMethodDialog extends AbstractExtractDialog {
if (canBeChainedConstructor) {
myCbChainedConstructor = new NonFocusableCheckBox(RefactoringBundle.message("extract.chained.constructor.checkbox"));
}
if (canBeVarargs) {
myCbMakeVarargs = new NonFocusableCheckBox(RefactoringBundle.message("declare.varargs.checkbox"));
}
// Initialize UI
@@ -232,7 +219,15 @@ public class ExtractMethodDialog extends AbstractExtractDialog {
});
panel.add(myFoldCb);
if (myCbMakeVarargs != null) {
boolean canBeVarargs = false;
for (ParameterTablePanel.VariableData data : myInputVariables) {
canBeVarargs |= data.type instanceof PsiArrayType;
}
if (myVariableData.isFoldable()) {
canBeVarargs |= myVariableData.isFoldingSelectedByDefault();
}
if (canBeVarargs) {
myCbMakeVarargs = new NonFocusableCheckBox(RefactoringBundle.message("declare.varargs.checkbox"));
updateVarargsEnabled();
myCbMakeVarargs.setSelected(false);
panel.add(myCbMakeVarargs);
@@ -39,9 +39,14 @@ public class AppMain {
final String osName = System.getProperty("os.name").toLowerCase();
String libPath = null;
if (osName.startsWith("windows")) {
libPath = binPath + "breakgen.dll";
if (System.getProperty("os.arch").equals("amd64")) {
libPath = binPath + "breakgen64.dll";
}
else {
libPath = binPath + "breakgen.dll";
}
} else if (osName.startsWith("linux")) {
if (System.getProperty("os.name").toLowerCase().equals("amd64")) {
if (System.getProperty("os.arch").toLowerCase().equals("amd64")) {
libPath = binPath + "libbreakgen64.so";
} else {
libPath = binPath + "libbreakgen.so";
@@ -0,0 +1,3 @@
import java.util.*;
class A1<<caret>T> {
}
@@ -0,0 +1,12 @@
import java.util.*;
class B{
public static void main(String[] args) {
B b = null;
b.bar(b.<Str<caret>ing>foo("", ""));
}
<T> String foo(T t, String s){return null;}
String bar(String s) {return null;}
}
@@ -0,0 +1,4 @@
import java.util.*;
class B {
<T> String foo(T t, St<caret>ring s){return null;}
}
@@ -0,0 +1,23 @@
import java.util.*;
class A1<T> {
public static void main(String[] args) {
Callable<Object> callable = new Callable<Object>() {
public Object call() throws Exception {
return new A1<Str<caret>ing>().toString();
}
};
B b = null;
b.bar(b.<String>foo("", ""));
}
<T> String foo(T t, String s) {
return null;
}
String bar(String s) {
return null;
}
}
@@ -0,0 +1,50 @@
/*
* User: anna
* Date: 25-Nov-2009
*/
package com.intellij.refactoring;
import com.intellij.JavaTestUtil;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
import com.intellij.psi.PsiMember;
import com.intellij.refactoring.changeSignature.ChangeSignatureTargetUtil;
import com.intellij.testFramework.LightCodeInsightTestCase;
import org.jetbrains.annotations.NonNls;
public class ChangeSignatureTargetTest extends LightCodeInsightTestCase {
@Override
protected String getTestDataPath() {
return JavaTestUtil.getJavaTestDataPath();
}
public void testInMethodParameters() throws Exception {
doTest("foo");
}
public void testInMethodArguments() throws Exception {
doTest("foo");
}
public void testInClassTypeParameters() throws Exception {
doTest("A1");
}
public void testInTypeArguments() throws Exception {
doTest("A1");
}
@Override
protected Sdk getProjectJDK() {
return JavaSdkImpl.getMockJdk15("java 1.5");
}
private void doTest(String expectedMemberName) throws Exception {
String basePath = "/refactoring/changeSignatureTarget/" + getTestName(false);
@NonNls final String filePath = basePath + ".java";
configureByFile(filePath);
final PsiMember member = ChangeSignatureTargetUtil.findTargetMember(getFile(), getEditor());
assertNotNull(member);
assertEquals(expectedMemberName, member.getName());
}
}
+1 -1
View File
@@ -14,10 +14,10 @@
* limitations under the License.
*/
#include <jni.h>
#if defined(WIN32)
#include <windows.h>
#else
#include <jni.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
+1
View File
@@ -0,0 +1 @@
gcc -I/opt/jdk1.6.0_16_x64/include/ -I/opt/jdk1.6.0_16_x64/include/linux/ AppMain.c -shared -fPIC -o libbreakgen64.so
@@ -125,11 +125,13 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager
if (projectProfile != null) {
final Element profileElement = new Element(PROFILE);
projectProfile.writeExternal(profileElement);
boolean hasSmthToSave = sortedProfiles.size() > 1;
for (Object child : profileElement.getChildren()) {
if (!((Element)child).getName().equals("option")) {
hasSmthToSave = true;
break;
boolean hasSmthToSave = sortedProfiles.size() > 1 || !Comparing.strEqual(PROJECT_PROFILE, PROJECT_DEFAULT_PROFILE_NAME);
if (!hasSmthToSave) {
for (Object child : profileElement.getChildren()) {
if (!((Element)child).getName().equals("option")) {
hasSmthToSave = true;
break;
}
}
}
if (!hasSmthToSave) continue;
@@ -143,7 +145,7 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager
}
}
if (profiles != null || !Comparing.strEqual(PROJECT_PROFILE, PROJECT_DEFAULT_PROFILE_NAME)) {
if (profiles != null) {
DefaultJDOMExternalizer.writeExternal(this, element);
final Element version = new Element("version");
version.setAttribute("value", VERSION);
+1
View File
@@ -19,6 +19,7 @@
<orderEntry type="module" module-name="platform-impl" exported="" />
<orderEntry type="module" module-name="usageView" exported="" />
<orderEntry type="module" module-name="testFramework" scope="TEST" />
<orderEntry type="library" name="Groovy" level="project" />
</component>
</module>
@@ -1077,6 +1077,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
public void disposeUIResources() {
if (mySubPanel != null) {
mySubPanel.disposeUIResources();
mySubPanel = null;
}
}
@@ -23,6 +23,7 @@ import com.intellij.codeInspection.InspectionProfile;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.ModifiableModel;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
@@ -249,6 +250,17 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
}
}
public Set<HighlightSeverity> getUsedSeverities() {
LOG.assertTrue(myInitialized.get());
final Set<HighlightSeverity> result = new HashSet<HighlightSeverity>();
for (ToolsImpl tools : myTools.values()) {
for (ScopeToolState state : tools.getTools()) {
result.add(state.getLevel().getSeverity());
}
}
return result;
}
public void writeExternal(Element element) throws WriteExternalException {
super.writeExternal(element);
@@ -168,8 +168,10 @@ public class ToolsImpl implements Tools {
final InspectionProfileEntry copyTool =
((InspectionProfileImpl)profile).myRegistrar.createInspectionTool(myShortName, tool);
copyTool.readSettings(scopeElement);
final HighlightDisplayLevel scopeLevel = errorLevel != null ? HighlightDisplayLevel
.find(((SeverityProvider)profileManager).getOwnSeverityRegistrar().getSeverity(errorLevel)) : level;
HighlightDisplayLevel scopeLevel = level;
if (errorLevel != null){
scopeLevel = HighlightDisplayLevel.find(((SeverityProvider)profileManager).getOwnSeverityRegistrar().getSeverity(errorLevel));
}
if (namedScope != null) {
addTool(namedScope, copyTool, enabledInScope != null && Boolean.parseBoolean(enabledInScope), scopeLevel);
} else {
@@ -303,7 +303,7 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo
List<FileTemplate> existingTemplates = new ArrayList<FileTemplate>();
// Read user-defined templates
for (File file : files) {
if (file.isDirectory()) {
if (file.isDirectory() || FileTypeManagerEx.getInstance().isFileIgnored(file.getName())) {
continue;
}
String name = file.getName();
@@ -332,6 +332,7 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo
LOG.debug("FileTemplateManagerImpl.loadTemplates() reading default templates...");
// Read default templates
for (VirtualFile file : defaultTemplates) {
if(FileTypeManagerEx.getInstance().isFileIgnored(file.getName())) continue;
String name = file.getName(); //name.extension.ft , e.g. "NewClass.java.ft"
@NonNls String extension = myTypeManager.getExtension(name);
name = name.substring(0, name.length() - extension.length() - 1); //name="NewClass.java" extension="ft"
@@ -20,20 +20,27 @@
package com.intellij.ide.impl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NonNls;
public class ModuleStructureComponent extends SimpleToolWindowPanel implements Disposable, DataProvider {
private final ModuleStructurePane myStructurePane;
public class ModuleStructureComponent extends SimpleToolWindowPanel implements Disposable {
public ModuleStructureComponent(Module module) {
super(true, true);
final ModuleStructurePane structurePane = new ModuleStructurePane(module);
Disposer.register(this, structurePane);
myStructurePane = new ModuleStructurePane(module);
Disposer.register(this, myStructurePane);
setContent(structurePane.createComponent());
setContent(myStructurePane.createComponent());
}
public Object getData(@NonNls String dataId) {
return myStructurePane.getData(dataId);
}
public void dispose() {
@@ -52,7 +52,7 @@ public class StructureViewSelectInTarget implements SelectInTarget {
StructureViewFactoryEx.getInstanceEx(myProject).runWhenInitialized(new Runnable() {
public void run() {
final StructureViewWrapper structureView = getStructureViewWrapper();
structureView.selectCurrentElement(fileEditor,requestFocus);
structureView.selectCurrentElement(fileEditor, context.getVirtualFile(), requestFocus);
}
});
}
@@ -18,31 +18,40 @@ package com.intellij.ide.impl;
import com.intellij.ide.DataManager;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.projectView.impl.ProjectRootsUtil;
import com.intellij.ide.structureView.StructureView;
import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.ide.structureView.StructureViewWrapper;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.actionSystem.TimerListener;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorProvider;
import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.util.Alarm;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.util.Arrays;
/**
* @author Eugene Belyaev
@@ -50,13 +59,13 @@ import java.util.Arrays;
public class StructureViewWrapperImpl implements StructureViewWrapper, Disposable {
private final Project myProject;
private FileEditor myFileEditor;
private Module myModule;
private VirtualFile myFile;
private StructureView myStructureView;
private ModuleStructureComponent myModuleStructureComponent;
private final JPanel myPanel;
private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
// -------------------------------------------------------------------------
// Constructor
@@ -69,7 +78,7 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
ActionManager.getInstance().addTimerListener(500, new TimerListener() {
public ModalityState getModalityState() {
return ModalityState.NON_MODAL;
return ModalityState.stateForComponent(myPanel);
}
public void run() {
@@ -80,7 +89,7 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
getComponent().addHierarchyListener(new HierarchyListener() {
public void hierarchyChanged(HierarchyEvent e) {
if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {
rebuild();
scheduleRebuild();
}
}
});
@@ -100,18 +109,23 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
if (owner == null || SwingUtilities.isDescendingFrom(owner, myPanel)) return;
final DataContext dataContext = DataManager.getInstance().getDataContext(owner);
final FileEditor fileEditor = PlatformDataKeys.FILE_EDITOR.getData(dataContext);
if (fileEditor != null) {
if (Arrays.asList(FileEditorManager.getInstance(myProject).getSelectedEditors()).contains(fileEditor)) {
setFileEditor(fileEditor);
}
final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
if (files != null && files.length == 1) {
setFile(files[0]);
}
else {
setModule(LangDataKeys.MODULE_CONTEXT.getData(dataContext));
setFile(null);
}
}
}
private void setFile(VirtualFile file) {
if (!Comparing.equal(file, myFile)) {
myFile = file;
scheduleRebuild();
}
}
// -------------------------------------------------------------------------
// StructureView interface implementation
@@ -122,14 +136,13 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
}
public void dispose() {
myFileEditor = null;
rebuild();
}
public boolean selectCurrentElement(FileEditor fileEditor, boolean requestFocus) {
public boolean selectCurrentElement(FileEditor fileEditor, VirtualFile file, boolean requestFocus) {
if (myStructureView != null) {
if (!Comparing.equal(myStructureView.getFileEditor(), fileEditor)) {
setFileEditor(fileEditor);
myFile = file;
rebuild();
}
return myStructureView.navigateToSelectedElement(requestFocus);
@@ -139,30 +152,13 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
}
}
private void setModule(Module module) {
if (module != myModule) {
myModule = module;
rebuild();
}
}
public void setFileEditor(FileEditor fileEditor) {
if (myModule != null) {
myModule = null;
rebuild();
}
else {
if (!Comparing.equal(myFileEditor, fileEditor)) {
myFileEditor = fileEditor;
rebuild();
return;
}
if (isStructureViewShowing() && myPanel.getComponentCount() == 0 && myFileEditor != null) {
private void scheduleRebuild() {
myUpdateAlarm.cancelAllRequests();
myUpdateAlarm.addRequest(new Runnable() {
public void run() {
rebuild();
}
}
}, 300, ModalityState.stateForComponent(myPanel));
}
public void rebuild() {
@@ -188,29 +184,48 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
return;
}
if (myModule != null) {
myModuleStructureComponent = new ModuleStructureComponent(myModule);
myPanel.add(myModuleStructureComponent, BorderLayout.CENTER);
if (hadFocus) {
JComponent focusedComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myModuleStructureComponent);
if (focusedComponent != null) {
focusedComponent.requestFocus();
}
VirtualFile file = myFile;
if (file == null) {
final VirtualFile[] selectedFiles = FileEditorManager.getInstance(myProject).getSelectedFiles();
if (selectedFiles.length > 0) {
file = selectedFiles[0];
}
}
else if (myFileEditor != null && myFileEditor.isValid()) {
final StructureViewBuilder structureViewBuilder = myFileEditor.getStructureViewBuilder();
if (structureViewBuilder != null) {
myStructureView = structureViewBuilder.createStructureView(myFileEditor, myProject);
myPanel.add(myStructureView.getComponent(), BorderLayout.CENTER);
if (hadFocus) {
JComponent focusedComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myStructureView.getComponent());
if (focusedComponent != null) {
focusedComponent.requestFocus();
if (file != null) {
if (file.isDirectory()) {
if (ProjectRootsUtil.isModuleContentRoot(file, myProject)) {
Module module = ModuleUtil.findModuleForFile(file, myProject);
if (module != null) {
myModuleStructureComponent = new ModuleStructureComponent(module);
myPanel.add(myModuleStructureComponent, BorderLayout.CENTER);
if (hadFocus) {
JComponent focusedComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myModuleStructureComponent);
if (focusedComponent != null) {
focusedComponent.requestFocus();
}
}
}
}
}
else {
FileEditor editor = FileEditorManager.getInstance(myProject).getSelectedEditor(file);
if (editor == null) editor = crteateTempFileEditor(file);
if (editor != null && editor.isValid()) {
final StructureViewBuilder structureViewBuilder = editor.getStructureViewBuilder();
if (structureViewBuilder != null) {
myStructureView = structureViewBuilder.createStructureView(editor, myProject);
myPanel.add(myStructureView.getComponent(), BorderLayout.CENTER);
if (hadFocus) {
JComponent focusedComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myStructureView.getComponent());
if (focusedComponent != null) {
focusedComponent.requestFocus();
}
}
myStructureView.restoreState();
myStructureView.centerSelectedRow();
}
}
myStructureView.restoreState();
myStructureView.centerSelectedRow();
}
}
@@ -222,6 +237,16 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
myPanel.repaint();
}
@Nullable
private FileEditor crteateTempFileEditor(VirtualFile file) {
FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance();
final FileEditorProvider[] providers = editorProviderManager.getProviders(myProject, file);
for (FileEditorProvider provider : providers) {
return provider.createEditor(myProject, file);
}
return null;
}
protected boolean isStructureViewShowing() {
ToolWindowManager windowManager = ToolWindowManager.getInstance(myProject);
@@ -19,10 +19,12 @@ import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.projectView.ProjectViewNode;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.SimpleTextAttributes;
import org.jetbrains.annotations.NotNull;
public abstract class AbstractModuleNode extends ProjectViewNode<Module> {
@@ -36,6 +38,8 @@ public abstract class AbstractModuleNode extends ProjectViewNode<Module> {
return;
}
presentation.setPresentableText(getValue().getName());
presentation.addText(getValue().getName(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
presentation.setOpenIcon(getValue().getModuleType().getNodeIcon(true));
presentation.setClosedIcon(getValue().getModuleType().getNodeIcon(false));
}
@@ -45,10 +49,12 @@ public abstract class AbstractModuleNode extends ProjectViewNode<Module> {
return "Module";
}
@Override
public boolean contains(@NotNull VirtualFile file) {
Module module = getValue();
return module != null && !module.isDisposed() &&
(ModuleUtil.moduleContainsFile(module, file, false) || ModuleUtil.moduleContainsFile(module, file, true));
for (VirtualFile root : ModuleRootManager.getInstance(getValue()).getContentRoots()) {
if (VfsUtil.isAncestor(root, file, false)) return true;
}
return false;
}
public String getToolTip() {
@@ -62,9 +62,12 @@ public class ProjectViewModuleNode extends AbstractModuleNode {
PsiDirectoryNode directoryNode = new PsiDirectoryNode(getProject(), psiDirectory, getSettings());
children.add(directoryNode);
}
/*
if (getSettings().isShowLibraryContents()) {
children.add(new LibraryGroupNode(getProject(), new LibraryGroupElement(getValue()), getSettings()));
}
*/
return children;
}
@@ -45,11 +45,22 @@ public class ProjectViewProjectNode extends AbstractProjectNode {
public Collection<AbstractTreeNode> getChildren() {
List<VirtualFile> topLevelContentRoots = ProjectViewDirectoryHelper.getInstance(myProject).getTopLevelRoots();
Set<Module> modules = new LinkedHashSet<Module>(topLevelContentRoots.size());
for (VirtualFile root : topLevelContentRoots) {
modules.add(ModuleUtil.findModuleForFile(root, myProject));
}
ArrayList<AbstractTreeNode> nodes = new ArrayList<AbstractTreeNode>();
final PsiManager psiManager = PsiManager.getInstance(getProject());
/*
for (VirtualFile root : reduceRoots(topLevelContentRoots)) {
nodes.add(new PsiDirectoryNode(getProject(), psiManager.findDirectory(root), getSettings()));
}
*/
nodes.addAll(modulesAndGroups(modules.toArray(new Module[modules.size()])));
final VirtualFile baseDir = getProject().getBaseDir();
if (baseDir == null) return nodes;
@@ -57,21 +57,27 @@ public class PsiDirectoryNode extends BasePsiNode<PsiDirectory> {
final PsiDirectory psiDirectory = getValue();
final VirtualFile directoryFile = psiDirectory.getVirtualFile();
final Object parentValue = getParentValue();
if (ProjectRootsUtil.isModuleContentRoot(directoryFile, project)) {
ProjectFileIndex fi = ProjectRootManager.getInstance(project).getFileIndex();
Module module = fi.getModuleForFile(directoryFile);
data.setPresentableText(directoryFile.getName());
if (module != null) {
if (Comparing.equal(module.getName(), directoryFile.getName())) {
data.addText(directoryFile.getName(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
if (!(parentValue instanceof Module )) {
if (Comparing.equal(module.getName(), directoryFile.getName())) {
data.addText(directoryFile.getName(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
}
else {
data.addText(directoryFile.getName() + " ", SimpleTextAttributes.REGULAR_ATTRIBUTES);
data.addText("[" + module.getName() + "]", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
}
}
else {
data.addText(directoryFile.getName() + " ", SimpleTextAttributes.REGULAR_ATTRIBUTES);
data.addText("[" + module.getName() + "]", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
data.addText(directoryFile.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
if (getParentValue() instanceof Project) {
if (parentValue instanceof Project || parentValue instanceof Module) {
data.addText(" (" + directoryFile.getPresentableUrl() + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
}
else if (ProjectRootsUtil.isSourceOrTestRoot(directoryFile, project)) {
@@ -89,9 +95,9 @@ public class PsiDirectoryNode extends BasePsiNode<PsiDirectory> {
}
}
final String name = getParentValue() instanceof Project
final String name = parentValue instanceof Project
? psiDirectory.getVirtualFile().getPresentableUrl()
: ProjectViewDirectoryHelper.getInstance(psiDirectory.getProject()).getNodeName(getSettings(), getParentValue(), psiDirectory);
: ProjectViewDirectoryHelper.getInstance(psiDirectory.getProject()).getNodeName(getSettings(), parentValue, psiDirectory);
if (name == null) {
setValue(null);
return;
@@ -21,6 +21,7 @@ import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -48,4 +49,9 @@ public class StructureViewModuleNode extends AbstractModuleNode {
public int getTypeSortWeight(final boolean sortByType) {
return 2;
}
@Override
public boolean contains(@NotNull VirtualFile file) {
return false;
}
}
@@ -17,6 +17,7 @@
package com.intellij.ide.structureView;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.vfs.VirtualFile;
/**
* Created by IntelliJ IDEA.
@@ -26,5 +27,5 @@ import com.intellij.openapi.fileEditor.FileEditor;
* To change this template use File | Settings | File Templates.
*/
public interface StructureViewWrapper {
boolean selectCurrentElement(FileEditor fileEditor, boolean requestFocus);
boolean selectCurrentElement(FileEditor fileEditor, VirtualFile file, boolean requestFocus);
}
@@ -23,7 +23,6 @@ import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.MultiValuesMap;
@@ -87,10 +86,7 @@ public final class StructureViewFactoryImpl extends StructureViewFactoryEx imple
final Content content = ContentFactory.SERVICE.getInstance().createContent(myStructureViewWrapperImpl.getComponent(), "", false);
Disposer.register(content, myStructureViewWrapperImpl);
toolWindow.getContentManager().addContent(content);
final FileEditor[] fileEditors = FileEditorManager.getInstance(myProject).getSelectedEditors();
if (fileEditors.length > 0) {
myStructureViewWrapperImpl.setFileEditor(fileEditors [0]);
}
if (myRunWhenInitialized != null) {
myRunWhenInitialized.run();
myRunWhenInitialized = null;
@@ -22,10 +22,16 @@
*/
package com.intellij.profile.codeInspection.ui;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
import com.intellij.codeInspection.ModifiableModel;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.codeInspection.ex.InspectionToolRegistrar;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
@@ -36,6 +42,7 @@ import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.profile.Profile;
@@ -53,9 +60,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.*;
public abstract class InspectionToolsConfigurable extends BaseConfigurable implements ErrorsConfigurable {
private CardLayout myLayout = new CardLayout();
@@ -116,7 +121,37 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
InspectionProfileImpl profile =
new InspectionProfileImpl("TempProfile", InspectionToolRegistrar.getInstance(), myProfileManager);
try {
profile.readExternal(JDOMUtil.loadDocument(VfsUtil.virtualToIoFile(files[0])).getRootElement());
final Element rootElement = JDOMUtil.loadDocument(VfsUtil.virtualToIoFile(files[0])).getRootElement();
final Set<String> levels = new HashSet<String>();
for (Object o : rootElement.getChildren("inspection_tool")) {
final Element inspectElement = (Element)o;
levels.add(inspectElement.getAttributeValue("level"));
for (Object s : inspectElement.getChildren("scope")) {
levels.add(((Element)s).getAttributeValue("level"));
}
}
for (Iterator<String> iterator = levels.iterator(); iterator.hasNext();) {
String level = iterator.next();
if (myProfileManager.getOwnSeverityRegistrar().getSeverity(level) != null) {
iterator.remove();
}
}
if (!levels.isEmpty()) {
if (Messages.showOkCancelDialog(myWholePanel, "Undefined severities detected: " +
StringUtil.join(levels, ", ") +
". Do you want to create them?", "Warning", Messages.getWarningIcon()) ==
DialogWrapper.OK_EXIT_CODE) {
for (String level : levels) {
final TextAttributes textAttributes = CodeInsightColors.WARNINGS_ATTRIBUTES.getDefaultAttributes();
HighlightInfoType.HighlightInfoTypeImpl info
= new HighlightInfoType.HighlightInfoTypeImpl(new HighlightSeverity(level, 50), TextAttributesKey.createTextAttributesKey(level));
myProfileManager.getOwnSeverityRegistrar()
.registerSeverity(new SeverityRegistrar.SeverityBasedTextAttributes(textAttributes.clone(), info),
textAttributes.getErrorStripeColor());
}
}
}
profile.readExternal(rootElement);
profile.initInspectionTools();
if (myProfileManager.getProfile(profile.getName(), false) != null) {
if (Messages.showOkCancelDialog(myWholePanel, "Profile with name \'" + profile.getName() + "\' already exists. Do you want to overwrite it?", "Warning", Messages.getInformationIcon()) != DialogWrapper.OK_EXIT_CODE) return;
@@ -19,6 +19,7 @@ package com.intellij.profile.codeInspection.ui;
import com.intellij.CommonBundle;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
import com.intellij.codeInspection.InspectionProfile;
import com.intellij.codeInspection.InspectionProfileEntry;
@@ -36,6 +37,8 @@ import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.Splitter;
@@ -926,6 +929,7 @@ public class SingleInspectionProfilePanel extends JPanel {
if (selectedProfile.getProfileManager().getProfile(selectedProfile.getName(), false) != null) {
selectedProfile.getProfileManager().deleteProfile(selectedProfile.getName());
}
copyUsedSeveritiesIfUndefined(selectedProfile, profileManager);
selectedProfile.setProfileManager(profileManager);
}
final InspectionProfile parentProfile = selectedProfile.getParentProfile();
@@ -948,6 +952,29 @@ public class SingleInspectionProfilePanel extends JPanel {
myModified = false;
}
private static void copyUsedSeveritiesIfUndefined(final ModifiableModel selectedProfile, final ProfileManager profileManager) {
final SeverityRegistrar registrar = ((SeverityProvider)profileManager).getSeverityRegistrar();
final Set<HighlightSeverity> severities = ((InspectionProfileImpl)selectedProfile).getUsedSeverities();
for (Iterator<HighlightSeverity> iterator = severities.iterator(); iterator.hasNext();) {
HighlightSeverity severity = iterator.next();
if (registrar.isSeverityValid(severity.toString())) {
iterator.remove();
}
}
if (!severities.isEmpty()) {
final SeverityRegistrar oppositeRegister = ((SeverityProvider)selectedProfile.getProfileManager()).getSeverityRegistrar();
for (HighlightSeverity severity : severities) {
final TextAttributesKey attributesKey = TextAttributesKey.find(severity.toString());
final TextAttributes textAttributes = oppositeRegister.getTextAttributesBySeverity(severity);
LOG.assertTrue(textAttributes != null);
HighlightInfoType.HighlightInfoTypeImpl info = new HighlightInfoType.HighlightInfoTypeImpl(severity, attributesKey);
registrar.registerSeverity(new SeverityRegistrar.SeverityBasedTextAttributes(textAttributes.clone(), info),
textAttributes.getErrorStripeColor());
}
}
}
private boolean descriptorsAreChanged() {
for (Descriptor defaultDescriptor : myDescriptors.keySet()) {
if (mySelectedProfile.isToolEnabled(defaultDescriptor.getKey(), (NamedScope)null) != defaultDescriptor.isEnabled()){
@@ -87,7 +87,7 @@ public class CopyHandler {
else if (ToolWindowId.STRUCTURE_VIEW.equals(id)) {
VirtualFile virtualFile = newElement.getContainingFile().getVirtualFile();
FileEditor editor = FileEditorManager.getInstance(newElement.getProject()).getSelectedEditor(virtualFile);
StructureViewFactoryEx.getInstanceEx(project).getStructureViewWrapper().selectCurrentElement(editor, true);
StructureViewFactoryEx.getInstanceEx(project).getStructureViewWrapper().selectCurrentElement(editor, virtualFile, true);
}
}
}
@@ -74,6 +74,8 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
FontMetrics fontMetrics = comp.getFontMetrics(comp.getFont());
size.width = fontMetrics.charWidth('a') * charCount;
comp.setPreferredSize(size);
final Dimension preferredSize = myBrowseButton.getPreferredSize();
setPreferredSize(new Dimension(size.width + preferredSize.width + 2, preferredSize.height + 2));
}
public void setEnabled(boolean enabled) {
@@ -0,0 +1,24 @@
/*
* 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.openapi.ui;
import com.intellij.openapi.util.ActionCallback;
public interface TypingTarget {
ActionCallback type(String text);
}
@@ -20,14 +20,14 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
import com.intellij.openapi.editor.actionSystem.TypedAction;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.ui.playback.commands.KeyCodeTypeCommand;
import com.intellij.openapi.ui.playback.commands.TypeCommand;
import com.intellij.openapi.util.*;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
@@ -50,6 +50,8 @@ public class ActionMacro implements JDOMExternalizable {
@NonNls
private static final String ATTRIBUTE_TEXT = "text";
@NonNls
private static final String ATTRIBUTE_KEY_CODES = "text-keycode";
@NonNls
private static final String ELEMENT_ACTION = "action";
@NonNls
private static final String ATTRIBUTE_ID = "id";
@@ -80,7 +82,8 @@ public class ActionMacro implements JDOMExternalizable {
for (Iterator iterator = actions.iterator(); iterator.hasNext();) {
Element action = (Element)iterator.next();
if (ELEMENT_TYPING.equals(action.getName())) {
myActions.add(new TypedDescriptor(action.getAttributeValue(ATTRIBUTE_TEXT)));
Pair<List<Integer>, List<Integer>> codes = parseKeyCodes(action.getAttributeValue(ATTRIBUTE_KEY_CODES));
myActions.add(new TypedDescriptor(action.getAttributeValue(ATTRIBUTE_TEXT), codes.getFirst(), codes.getSecond()));
}
else if (ELEMENT_ACTION.equals(action.getName())) {
myActions.add(new IdActionDescriptor(action.getAttributeValue(ATTRIBUTE_ID)));
@@ -90,6 +93,14 @@ public class ActionMacro implements JDOMExternalizable {
}
}
private Pair<List<Integer>, List<Integer>> parseKeyCodes(String keyCodesText) {
return KeyCodeTypeCommand.parseKeyCodes(keyCodesText);
}
public String unparseKeyCodes(Pair<List<Integer>, List<Integer>> keyCodes) {
return KeyCodeTypeCommand.unparseKeyCodes(keyCodes);
}
public void writeExternal(Element macro) throws WriteExternalException {
macro.setAttribute(ATTRIBUTE_NAME, myName);
final ActionDescriptor[] actions = getActions();
@@ -98,8 +109,10 @@ public class ActionMacro implements JDOMExternalizable {
Element actionNode = null;
if (action instanceof TypedDescriptor) {
actionNode = new Element(ELEMENT_TYPING);
final String t = ((TypedDescriptor)action).getText();
TypedDescriptor typedDescriptor = (TypedDescriptor)action;
final String t = typedDescriptor.getText();
actionNode.setAttribute(ATTRIBUTE_TEXT, JDOMUtil.escapeText(t));
actionNode.setAttribute(ATTRIBUTE_KEY_CODES, unparseKeyCodes(new Pair<List<Integer>, List<Integer>>(typedDescriptor.getKeyCodes(), typedDescriptor.getKeyModifiers())));
}
else if (action instanceof IdActionDescriptor) {
actionNode = new Element(ELEMENT_ACTION);
@@ -161,13 +174,13 @@ public class ActionMacro implements JDOMExternalizable {
myActions.add(new ShortcutActionDesciption(text));
}
public void appendKeytyped(char c) {
public void appendKeytyped(char c, int keyCode, int modifiers) {
ActionDescriptor lastAction = myActions.size() > 0 ? myActions.get(myActions.size() - 1) : null;
if (lastAction instanceof TypedDescriptor) {
((TypedDescriptor)lastAction).addChar(c);
((TypedDescriptor)lastAction).addChar(c, keyCode, modifiers);
}
else {
myActions.add(new TypedDescriptor(c));
myActions.add(new TypedDescriptor(c, keyCode, modifiers));
}
}
@@ -184,18 +197,30 @@ public class ActionMacro implements JDOMExternalizable {
}
public static class TypedDescriptor implements ActionDescriptor {
private String myText;
public TypedDescriptor(String text) {
private List<Integer> myKeyCodes = new ArrayList<Integer>();
private List<Integer> myModifiers = new ArrayList<Integer>();
public TypedDescriptor(String text, List<Integer> keyCodes, List<Integer> modifiers) {
myText = text;
myKeyCodes.addAll(keyCodes);
myModifiers.addAll(modifiers);
assert myKeyCodes.size() == myModifiers.size() : "codes=" + myKeyCodes.toString() + " modifiers=" + myModifiers.toString();
}
public TypedDescriptor(char c) {
public TypedDescriptor(char c, int keyCode, int modifiers) {
myText = String.valueOf(c);
myKeyCodes.add(keyCode);
myModifiers.add(modifiers);
}
public void addChar(char c) {
public void addChar(char c, int keyCode, int modifier) {
myText = myText + c;
myKeyCodes.add(keyCode);
myModifiers.add(modifier);
}
public String getText() {
@@ -203,7 +228,7 @@ public class ActionMacro implements JDOMExternalizable {
}
public Object clone() {
return new TypedDescriptor(myText);
return new TypedDescriptor(myText, myKeyCodes, myModifiers);
}
public boolean equals(Object o) {
@@ -217,8 +242,23 @@ public class ActionMacro implements JDOMExternalizable {
}
public void generateTo(StringBuffer script) {
script.append(myText);
script.append("\n");
if (TypeCommand.containsUnicode(myText)) {
script.append(KeyCodeTypeCommand.PREFIX).append(" ");
for (int i = 0; i < myKeyCodes.size(); i++) {
Integer each = myKeyCodes.get(i);
script.append(each.toString());
script.append(KeyCodeTypeCommand.MODIFIER_DELIMITER);
script.append(myModifiers.get(i));
if (i < myKeyCodes.size() - 1) {
script.append(KeyCodeTypeCommand.CODE_DELIMITER);
}
}
script.append(" ").append(myText).append("\n");
} else {
script.append(myText);
script.append("\n");
}
}
public String toString() {
@@ -233,6 +273,14 @@ public class ActionMacro implements JDOMExternalizable {
typedAction.actionPerformed(editor, chars[i], context);
}
}
public List<Integer> getKeyCodes() {
return myKeyCodes;
}
public List<Integer> getKeyModifiers() {
return myModifiers;
}
}
public static class ShortcutActionDesciption implements ActionDescriptor {
@@ -360,11 +360,11 @@ public class ActionMacroManager implements ExportableApplicationComponent, Named
&& e.getKeyCode() != KeyEvent.VK_META
&& e.getKeyCode() != KeyEvent.VK_SHIFT;
if (e.getID() == KeyEvent.KEY_TYPED && plainType && !isEnter) {
myRecordingMacro.appendKeytyped(e.getKeyChar());
if (e.getID() == KeyEvent.KEY_PRESSED && plainType && !isEnter) {
myRecordingMacro.appendKeytyped(e.getKeyChar(), e.getKeyCode(), e.getModifiers());
} else if (e.getID() == KeyEvent.KEY_PRESSED && noModifierKeyIsPressed && (!plainType || isEnter)) {
final boolean waiting = IdeEventQueue.getInstance().getKeyEventDispatcher().isWaitingForSecondKeyStroke();
if (!e.equals(myLastActionInputEvent) && !waiting) {
if ((!e.equals(myLastActionInputEvent) && !waiting) || isEnter) {
final String stroke = KeyStroke.getKeyStrokeForEvent(e).toString();
final int pressed = stroke.indexOf("pressed");
@@ -374,7 +374,9 @@ public class ActionMacroManager implements ExportableApplicationComponent, Named
String ready = (modifiers.replaceAll("ctrl", "control").trim() + " " + key.trim()).trim();
myRecordingMacro.appendShortuct(ready);
myLastActionInputEvent = null;
if (!isEnter) {
myLastActionInputEvent = null;
}
}
}
}
@@ -28,8 +28,11 @@ import com.intellij.openapi.project.DumbAware;
*/
public class StartStopMacroRecordingAction extends AnAction implements DumbAware {
public void update(AnActionEvent e) {
e.getPresentation().setEnabled(e.getDataContext().getData(DataConstants.EDITOR) != null);
e.getPresentation().setText(ActionMacroManager.getInstance().isRecording()
boolean editorAvailable = e.getDataContext().getData(DataConstants.EDITOR) != null;
boolean isRecording = ActionMacroManager.getInstance().isRecording();
e.getPresentation().setEnabled(editorAvailable || isRecording);
e.getPresentation().setText(isRecording
? IdeBundle.message("action.stop.macro.recording")
: IdeBundle.message("action.start.macro.recording"));
}
@@ -22,6 +22,8 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.ui.TestableUi;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.ui.TypingTarget;
import com.intellij.openapi.util.ActionCallback;
import javax.swing.*;
import java.awt.*;
@@ -33,7 +35,7 @@ import java.util.Map;
/**
*
*/
public class EditorComponentImpl extends JComponent implements Scrollable, DataProvider, TestableUi {
public class EditorComponentImpl extends JComponent implements Scrollable, DataProvider, TestableUi, TypingTarget {
private final EditorImpl myEditor;
public EditorComponentImpl(EditorImpl editor) {
@@ -96,6 +98,10 @@ public class EditorComponentImpl extends JComponent implements Scrollable, DataP
}
}
public ActionCallback type(String text) {
return myEditor.type(text);
}
public InputMethodRequests getInputMethodRequests() {
return myEditor.getInputMethodRequests();
}
@@ -24,6 +24,7 @@ import com.intellij.ide.*;
import com.intellij.ide.dnd.DnDManager;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
@@ -593,17 +594,43 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myPropertyChangeSupport.firePropertyChange(PROP_FONT_SIZE, oldFontSize, fontSize);
}
private void processKeyTyped(char c) {
public ActionCallback type(final String text) {
final ActionCallback result = new ActionCallback();
Application app = ApplicationManager.getApplication();
if (!app.isWriteAccessAllowed()) {
result.setRejected();
} else {
app.runWriteAction(new Runnable() {
public void run() {
for (int i = 0; i < text.length(); i++) {
if (!processKeyTyped(text.charAt(i))) {
result.setRejected();
return;
}
}
result.setDone();
}
});
}
return result;
}
private boolean processKeyTyped(char c) {
// [vova] This is patch for Mac OS X. Under Mac "input methods"
// is handled before our EventQueue consume upcoming KeyEvents.
IdeEventQueue queue = IdeEventQueue.getInstance();
if (queue.shouldNotTypeInEditor() || ProgressManager.getInstance().hasModalProgressIndicator()) {
return;
return false;
}
ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
DataContext dataContext = getDataContext();
actionManager.fireBeforeEditorTyping(c, dataContext);
EditorActionManager.getInstance().getTypedAction().actionPerformed(this, c, dataContext);
return true;
}
private void fireFocusLost() {
@@ -126,6 +126,10 @@ public class PlaybackRunner {
return new EmptyCommand(line);
}
if (actualString.startsWith(KeyCodeTypeCommand.PREFIX)) {
return new KeyCodeTypeCommand(string, line);
}
if (actualString.startsWith(DelayCommand.PREFIX)) {
return new DelayCommand(string, line);
}
@@ -229,7 +233,7 @@ public class PlaybackRunner {
}
});
new PlaybackRunner("%[comma]", new StatusCallback() {
new PlaybackRunner("%type", new StatusCallback() {
public void error(String text, int currentLine) {
System.out.println("Error: " + currentLine + " " + text);
}
@@ -15,8 +15,11 @@
*/
package com.intellij.openapi.ui.playback.commands;
import com.intellij.openapi.ui.TypingTarget;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.ui.playback.PlaybackRunner;
import com.intellij.openapi.util.registry.Registry;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.awt.event.KeyEvent;
@@ -28,7 +31,31 @@ public class AlphaNumericTypeCommand extends TypeCommand {
}
public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall) {
final String text = getText();
return type(robot, getText());
}
protected ActionCallback type(final Robot robot, final String text) {
final ActionCallback result = new ActionCallback();
TypingTarget typingTarget = findTarget();
if (typingTarget != null) {
typingTarget.type(text).doWhenDone(new Runnable() {
public void run() {
result.setDone();
}
}).doWhenRejected(new Runnable() {
public void run() {
typeByRobot(robot, text).notify(result);
}
});
} else {
typeByRobot(robot, text).notify(result);
}
return result;
}
private ActionCallback typeByRobot(Robot robot, String text) {
for (int i = 0; i < text.length(); i++) {
final char each = text.charAt(i);
if ('\\' == each && i + 1 < text.length()) {
@@ -57,4 +84,23 @@ public class AlphaNumericTypeCommand extends TypeCommand {
}
return new ActionCallback.Done();
}
@Nullable
public static TypingTarget findTarget() {
if (!Registry.is("actionSystem.playback.useTypingTargets")) return null;
Component each = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
while (each != null) {
if (each instanceof TypingTarget) {
return (TypingTarget)each;
}
each = each.getParent();
}
return null;
}
}
@@ -0,0 +1,135 @@
/*
* 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.openapi.ui.playback.commands;
import com.intellij.openapi.ui.TypingTarget;
import com.intellij.openapi.ui.playback.PlaybackRunner;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.awt.List;
import java.util.*;
public class KeyCodeTypeCommand extends AlphaNumericTypeCommand {
public static final String PREFIX = CMD_PREFIX + "type";
public static final String CODE_DELIMITER = ";";
public static final String MODIFIER_DELIMITER = ":";
public KeyCodeTypeCommand(String text, int line) {
super(text, line);
}
@Override
public ActionCallback _execute(final PlaybackRunner.StatusCallback cb, final Robot robot, boolean directActionCall) {
String text = getText().substring(PREFIX.length()).trim();
int textDelim = text.indexOf(" ");
final String codes;
if (textDelim >= 0) {
codes = text.substring(0, textDelim);
} else {
codes = text;
}
String unicode;
if (codes.length() + 1 < text.length()) {
unicode = text.substring(textDelim + 1);
} else {
unicode = "";
}
final ActionCallback result = new ActionCallback();
TypingTarget typingTarget = findTarget();
if (typingTarget != null) {
typingTarget.type(unicode).doWhenDone(new Runnable() {
public void run() {
result.setDone();
}
}).doWhenRejected(new Runnable() {
public void run() {
typeCodes(cb, robot, codes).notify(result);
}
});
} else {
typeCodes(cb, robot, codes).notify(result);
}
return result;
}
private ActionCallback typeCodes(PlaybackRunner.StatusCallback cb, Robot robot, String codes) {
String[] pairs = codes.split(CODE_DELIMITER);
for (String eachPair : pairs) {
try {
String[] splits = eachPair.split(MODIFIER_DELIMITER);
Integer code = Integer.valueOf(splits[0]);
Integer modifier = Integer.valueOf(splits[1]);
type(robot, code.intValue(), modifier.intValue());
}
catch (NumberFormatException e) {
dumpError(cb, "Invalid code: " + eachPair);
return new ActionCallback.Rejected();
}
}
return new ActionCallback.Done();
}
public static Pair<java.util.List<Integer>, java.util.List<Integer>> parseKeyCodes(String keyCodesText) {
ArrayList<Integer> codes = new ArrayList<Integer>();
ArrayList<Integer> modifiers = new ArrayList<Integer>();
if (keyCodesText != null) {
String[] pairs = keyCodesText.split(CODE_DELIMITER);
for (String each : pairs) {
String[] strings = each.split(MODIFIER_DELIMITER);
if (strings.length == 2) {
codes.add(Integer.valueOf(strings[0]));
modifiers.add(Integer.valueOf(strings[1]));
}
}
}
return new Pair<java.util.List<Integer>, java.util.List<Integer>>(codes, modifiers);
}
public static String unparseKeyCodes(Pair<java.util.List<Integer>, java.util.List<Integer>> pairs) {
StringBuffer result = new StringBuffer();
java.util.List<Integer> codes = pairs.getFirst();
java.util.List<Integer> modifiers = pairs.getSecond();
for (int i = 0; i < codes.size(); i++) {
Integer each = codes.get(i);
result.append(each.toString());
result.append(MODIFIER_DELIMITER);
result.append(modifiers.get(i));
if (i < codes.size() - 1) {
result.append(CODE_DELIMITER);
}
}
return result.toString();
}
}
@@ -23,7 +23,7 @@ import java.awt.*;
public class KeyShortcutCommand extends TypeCommand {
public static String PREFIX = CMD_PREFIX + "[";
public static String POSTFIX = CMD_PREFIX + "]";
public static String POSTFIX = "]";
public KeyShortcutCommand(String text, int line) {
super(text, line);
@@ -31,7 +31,7 @@ public class KeyShortcutCommand extends TypeCommand {
public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall) {
final String one = getText().substring(PREFIX.length());
if (!one.endsWith("]")) {
if (!one.endsWith(POSTFIX)) {
dumpError(cb, "Expected " + "]");
return new ActionCallback.Rejected();
}
@@ -22,7 +22,6 @@ import javax.swing.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class KeyStokeMap {
@@ -32,11 +31,17 @@ public class KeyStokeMap {
private Map<Character, KeyStroke> myMap;
public KeyStroke get(char c) {
if (myMap == null) {
myMap = generateKeyStrokeMappings();
}
Character mappedChar = new Character(c);
return myMap.get(new Character(c));
if (getMap().containsKey(mappedChar)) {
return getMap().get(mappedChar);
} else {
return KeyStroke.getKeyStroke(c);
}
}
public boolean containsChar(char c) {
return getMap().containsKey(c);
}
public KeyStroke get(String strokeText) {
@@ -136,13 +141,13 @@ public class KeyStokeMap {
map.put(new Character((char)entry[0]), stroke);
}
// If the locale is not en_US/GB, provide only a very basic map and
// rely on key_typed events instead
Locale locale = Locale.getDefault();
if (!Locale.US.equals(locale) && !Locale.UK.equals(locale)) {
LOG.debug("Not US: " + locale);
return map;
}
//// If the locale is not en_US/GB, provide only a very basic map and
//// rely on key_typed events instead
//Locale locale = Locale.getDefault();
//if (!Locale.US.equals(locale) && !Locale.UK.equals(locale)) {
// LOG.debug("Not US: " + locale);
// return map;
//}
// Basic symbol/punctuation mappings
for (int i = 0; i < mappings.length; i++) {
@@ -175,4 +180,11 @@ public class KeyStokeMap {
return map;
}
private Map<Character, KeyStroke> getMap() {
if (myMap == null) {
myMap = generateKeyStrokeMappings();
}
return myMap;
}
}
@@ -24,7 +24,7 @@ import java.awt.event.KeyEvent;
public abstract class TypeCommand extends AbstractCommand {
private KeyStokeMap myMap = new KeyStokeMap();
private static KeyStokeMap ourMap = new KeyStokeMap();
public TypeCommand(String text, int line) {
super(text, line);
@@ -56,9 +56,16 @@ public abstract class TypeCommand extends AbstractCommand {
robot.keyPress(KeyEvent.VK_META);
}
robot.keyPress(keyStroke.getKeyCode());
robot.delay(Registry.intValue("actionSystem.playback.autodelay"));
robot.keyRelease(keyStroke.getKeyCode());
if (keyStroke.getKeyCode() > 0) {
robot.keyPress(keyStroke.getKeyCode());
robot.delay(Registry.intValue("actionSystem.playback.autodelay"));
robot.keyRelease(keyStroke.getKeyCode());
} else {
robot.keyPress(keyStroke.getKeyChar());
robot.delay(Registry.intValue("actionSystem.playback.autodelay"));
robot.keyRelease(keyStroke.getKeyChar());
}
if (shift) {
robot.keyRelease(KeyEvent.VK_SHIFT);
@@ -78,10 +85,18 @@ public abstract class TypeCommand extends AbstractCommand {
}
protected KeyStroke get(char c) {
return myMap.get(c);
return ourMap.get(c);
}
protected KeyStroke getFromShortcut(String sc) {
return myMap.get(sc);
return ourMap.get(sc);
}
public static boolean containsUnicode(String s) {
for (int i = 0; i < s.length(); i++) {
if (!ourMap.containsChar(s.charAt(i))) return true;
}
return false;
}
}
@@ -17,6 +17,7 @@ actionSystem.typeAheadTimeBeforeDialog.description=If dialog shown as a result o
actionSystem.playback.autodelay=20
actionSystem.playback.autodelay.description=Delay between events generated by the playback runner
actionSystem.playback.useDirectActionCall=true
actionSystem.playback.useTypingTargets=true
actionSystem.focusIdleTimeout=20
actionSystem.mac.screenMenuNotUpdatedFix=false
actionSystem.keyGestures.enabled=false
@@ -286,6 +286,7 @@
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.CurrentTimeMacro"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.CurrentUserMacro"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.CapitalizeMacro"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.GroovyScriptMacro"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.DecapitalizeMacro"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.FirstWordMacro"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.ReplaceUnderscoresWithSpacesMacro"/>
@@ -27,6 +27,7 @@ import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.*;
@@ -561,7 +562,11 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme
}
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() {
public void run() {
myMappings.setDirectoryMappings(mappingsList);
DumbService.getInstance(myProject).runWhenSmart(new Runnable() {
public void run() {
myMappings.setDirectoryMappings(mappingsList);
}
});
}
});
}
@@ -1312,7 +1312,8 @@ unnecessarily.qualified.static.usage.problem.descriptor1=Unnecessarily qualified
unnecessarily.qualified.static.usage.ignore.field.option=Ignore unnecessarily qualified field accesses
unnecessarily.qualified.static.usage.ignore.method.option=Ignore unnecessarily qualified method calls
unnecessary.interface.modifier.problem.descriptor=Modifier <code>#ref</code> is redundant for interfaces #loc
unnecessary.interface.modifier.problem.descriptor1=Modifier <code>#ref</code> is redundant for inner interfaces of interfaces #loc
unnecessary.interface.modifier.inner.interface.of.interface.problem.descriptor=Modifier <code>#ref</code> is redundant for inner interfaces of interfaces #loc
unnecessary.interface.modifier.inner.interface.of.class.problem.descriptor=Modifier <code>#ref</code> is redundant for inner interfaces of classes #loc
unnecessary.interface.modifier.problem.descriptor2=Modifier <code>#ref</code> is redundant for interface methods #loc
unnecessary.interface.modifier.problem.descriptor3=Modifier <code>#ref</code> is redundant for inner classes of interfaces #loc
unnecessary.interface.modifier.problem.descriptor4=Modifier <code>#ref</code> is redundant for interface fields #loc
@@ -1754,4 +1755,4 @@ unnecessary.javadoc.link.display.name=Unnecessary JavaDoc link
unnecessary.javadoc.link.problem.descriptor=<code>#ref</code> is unnecessary
unnecessary.javadoc.link.quickfix=Remove unnecessary {0}
thread.local.not.static.final.display.name=ThreadLocal field not declared static final
thread.local.not.static.final.problem.descriptor=ThreadLocal <code>#ref</code> is not declared 'static final'
thread.local.not.static.final.problem.descriptor=ThreadLocal <code>#ref</code> is not declared 'static final'
@@ -108,15 +108,17 @@ public class InstanceOfUtils {
expression.getOperationSign();
final IElementType tokenType = sign.getTokenType();
if (tokenType == JavaTokenType.ANDAND) {
inElse = false;
final PsiExpression lhs = expression.getLOperand();
checkExpression(lhs);
final PsiExpression rhs = expression.getROperand();
checkExpression(rhs);
checkExpression(expression.getLOperand());
checkExpression(expression.getROperand());
if (!inElse && conflictingInstanceof != null) {
agreeingInstanceof = false;
}
} else if (tokenType == JavaTokenType.OROR) {
inElse = true;
final PsiExpression lhs = expression.getLOperand();
checkExpression(lhs);
checkExpression(expression.getLOperand());
checkExpression(expression.getROperand());
if (inElse && conflictingInstanceof != null) {
agreeingInstanceof = false;
}
}
}
@@ -259,4 +261,4 @@ public class InstanceOfUtils {
return conflictingInstanceof;
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2008 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2009 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -65,8 +65,13 @@ public class UnnecessaryInterfaceModifierInspection extends BaseInspection {
final PsiClass containingClass = aClass.getContainingClass();
if (containingClass != null) {
if (aClass.isInterface()) {
return InspectionGadgetsBundle.message(
"unnecessary.interface.modifier.problem.descriptor1");
if (containingClass.isInterface()) {
return InspectionGadgetsBundle.message(
"unnecessary.interface.modifier.inner.interface.of.interface.problem.descriptor");
} else {
return InspectionGadgetsBundle.message(
"unnecessary.interface.modifier.inner.interface.of.class.problem.descriptor");
}
} else {
return InspectionGadgetsBundle.message(
"unnecessary.interface.modifier.problem.descriptor3");
@@ -91,15 +96,15 @@ public class UnnecessaryInterfaceModifierInspection extends BaseInspection {
@Override
public InspectionGadgetsFix buildFix(Object... infos) {
return new UnnecessaryInterfaceModifersFix((String) infos[0]);
return new UnnecessaryInterfaceModifiersFix((String) infos[0]);
}
private static class UnnecessaryInterfaceModifersFix
private static class UnnecessaryInterfaceModifiersFix
extends InspectionGadgetsFix {
private final String modifiersText;
private UnnecessaryInterfaceModifersFix(String modifiersText) {
private UnnecessaryInterfaceModifiersFix(String modifiersText) {
this.modifiersText = modifiersText;
}
@@ -217,4 +222,4 @@ public class UnnecessaryInterfaceModifierInspection extends BaseInspection {
}
}
}
}
}
@@ -0,0 +1,32 @@
/*
* 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.
*/
public interface I {}
class A implements I {}
class B implements I {}
class U {
void foo(Object o, boolean b) {
if (o instanceof I && b) {
} else {
if (o instanceof A) {
} else {
B bb = (B)o;
}
}
}
}
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
</problems>
@@ -0,0 +1,32 @@
/*
* 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.
*/
public interface I {}
class A implements I {}
class B implements I {}
class U {
void foo(Object o, boolean b) {
if (o instanceof I || b) {
} else {
if (o instanceof A) {
} else {
B bb = (B)o;
}
}
}
}
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
</problems>
@@ -0,0 +1,31 @@
/*
* 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.
*/
public interface I {}
class A implements I {}
class B implements I {}
class U {
void foo(Object o, boolean b) {
if (o instanceof I && b) {
} else {
if (o instanceof A) {
B bb = (B)o;
} else {
}
}
}
}
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>ElseElse.java</file>
<line>26</line>
<description>Cast to &lt;code&gt;(B)o&lt;/code&gt; conflicts with surrounding 'instanceof' check #loc</description>
</problem>
</problems>
@@ -0,0 +1,37 @@
/*
* 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.siyeh.ig.bugs;
import com.IGInspectionTestCase;
public class CastConflictsWithInstanceofInspectionTest extends IGInspectionTestCase {
public void testElseElse() throws Exception {
doTest();
}
public void testSimple() throws Exception {
doTest();
}
public void testElseElseOrOr() throws Exception {
doTest();
}
private void doTest() throws Exception {
doTest("com/siyeh/igtest/bugs/castConflictingInstanceof/" + getTestName(false), new CastConflictsWithInstanceofInspection());
}
}
@@ -241,9 +241,10 @@ public class AnnotationUtilEx {
if (listOwner instanceof PsiParameter) {
PsiParameter parameter = (PsiParameter)listOwner;
PsiElement declarationScope = parameter.getDeclarationScope();
if (declarationScope instanceof PsiMethod && parameter.getParent() == ((PsiMethod)declarationScope).getParameterList()) {
PsiParameterList parameterList;
if (declarationScope instanceof PsiMethod && parameter.getParent() == (parameterList = ((PsiMethod)declarationScope).getParameterList())) {
PsiMethod method = (PsiMethod)declarationScope;
final int parameterIndex = method.getParameterList().getParameterIndex(parameter);
final int parameterIndex = parameterList.getParameterIndex(parameter);
all.addAll(Arrays.asList(modifierList.getAnnotations()));
SuperMethodsSearch.search(method, null, true, true).forEach(new Processor<MethodSignatureBackedByPsiMethod>() {
public boolean process(final MethodSignatureBackedByPsiMethod superMethod) {
@@ -425,7 +425,7 @@ public class GroovyAnnotator implements Annotator {
for (List<GrNamedArgument> args : map.values()) {
for (int i = 1; i < args.size(); i++) {
GrNamedArgument namedArgument = args.get(i);
holder.createErrorAnnotation(namedArgument, GroovyBundle.message("duplicate.element.in.the.map"));
holder.createWarningAnnotation(namedArgument, GroovyBundle.message("duplicate.element.in.the.map"));
}
}
}
@@ -141,7 +141,13 @@ public class GroovycStubGenerator extends GroovyCompilerBase {
deleteChildrenRecursively(child);
}
TranslatingCompilerFilesMonitor.removeSourceInfo(child);
child.delete(this);
try {
child.delete(this);
}
catch (IOException ignored) {
//may be a leaked handle from some non-completely terminated compiler process, or compiler caches, or something else
//not a big deal, we'll delete it next time
}
}
}
}.execute();
@@ -22,11 +22,12 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
import com.intellij.psi.impl.source.tree.LeafElement;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpressionImpl;
@@ -36,6 +37,8 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*;
/**
* @author ilyas
*/
@@ -120,6 +123,16 @@ public class GrLiteralImpl extends GrExpressionImpl implements GrLiteral, PsiLan
return ReferenceProvidersRegistry.getReferencesFromProviders(this, GrLiteral.class);
}
@Nullable
@Override
public PsiReference getReference() {
final PsiReference[] references = getReferences();
if (references.length > 0) {
return new PsiMultiReference(references, this);
}
return null;
}
public List<Pair<PsiElement, TextRange>> getInjectedPsi() {
if (!(getValue() instanceof String)) return null;
return InjectedLanguageUtil.getInjectedPsiFiles(this);
@@ -46,8 +46,8 @@ import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.rt.execution.junit.JUnitStarter;
import com.intellij.rt.execution.junit.IDEAJUnitListener;
import com.intellij.rt.execution.junit.JUnitStarter;
import com.intellij.util.Function;
import com.intellij.util.PathUtil;
import org.jetbrains.annotations.NotNull;
@@ -57,7 +57,10 @@ import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public abstract class TestObject implements JavaCommandLine {
protected static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit.TestObject");
@@ -296,13 +299,18 @@ public abstract class TestObject implements JavaCommandLine {
try {
writer.println(junit4 ? JUnitStarter.JUNIT4_PARAMETER : "-junit3");
writer.println(packageName);
final List<String> testNames = new ArrayList<String>();
for (final PsiElement element : elements) {
final String name = nameFunction.fun(element);
if (name == null) {
LOG.error("invalid element " + element);
return;
}
writer.println(name);
testNames.add(name);
}
Collections.sort(testNames); //sort tests in FQN order
for (String testName : testNames) {
writer.println(testName);
}
}
finally {
@@ -242,16 +242,6 @@ public class MavenProjectsStructure extends SimpleTreeStructure {
ALWAYS, NEVER, NORMAL
}
private DisplayKind getDisplayKind(CustomNode node) {
Class[] visibles = getVisibleNodesClasses();
if (visibles == null) return DisplayKind.NORMAL;
for (Class each : visibles) {
if (each.isInstance(node)) return DisplayKind.ALWAYS;
}
return DisplayKind.NORMAL;
}
protected Class<? extends CustomNode>[] getVisibleNodesClasses() {
return null;
}
@@ -353,7 +343,13 @@ public class MavenProjectsStructure extends SimpleTreeStructure {
}
public DisplayKind getDisplayKind() {
return MavenProjectsStructure.this.getDisplayKind(this);
Class[] visibles = getVisibleNodesClasses();
if (visibles == null) return DisplayKind.NORMAL;
for (Class each : visibles) {
if (each.isInstance(this)) return DisplayKind.ALWAYS;
}
return DisplayKind.NEVER;
}
public CustomNode[] getChildren() {
@@ -1094,11 +1090,6 @@ public class MavenProjectsStructure extends SimpleTreeStructure {
setNodeErrorLevel(myArtifact.isResolved() ? ErrorLevel.NONE : ErrorLevel.ERROR);
}
@Override
public boolean isVisible() {
return true;
}
@Override
public Navigatable getNavigatable() {
final Module m = myProjectsManager.findModule(myMavenProject);
@@ -1119,5 +1110,10 @@ public class MavenProjectsStructure extends SimpleTreeStructure {
}
};
}
@Override
public boolean isVisible() {
return getDisplayKind() != DisplayKind.NEVER;
}
}
}
+1 -1
View File
@@ -828,7 +828,7 @@
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.SuggestIndexNameMacro"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.GuessElementTypeMacro"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.ExpectedTypeMacro"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.GroovyScriptMacro"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.AnnotatedMacro"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.MethodNameMacro"/>
<liveTemplateMacro implementation="com.intellij.codeInsight.template.macro.MethodReturnTypeMacro"/>
@@ -12,6 +12,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Key;
@@ -320,7 +321,7 @@ public final class DomManagerImpl extends DomManager {
}
final InvocationHandler handler = AdvancedProxy.getInvocationHandler(proxy);
if (handler instanceof StableInvocationHandler) {
final DomElement element = ((StableInvocationHandler)handler).getWrappedElement();
final DomElement element = ((StableInvocationHandler<DomElement>)handler).getWrappedElement();
return element == null ? null : getDomInvocationHandler(element);
}
if (handler instanceof DomInvocationHandler) {
@@ -493,9 +494,17 @@ public final class DomManagerImpl extends DomManager {
}
public final <T extends DomElement> T createStableValue(final Factory<T> provider) {
return createStableValue(provider, new Condition<T>() {
public boolean value(T t) {
return t.isValid();
}
});
}
public final <T> T createStableValue(final Factory<T> provider, final Condition<T> validator) {
final T initial = provider.create();
assert initial != null;
final StableInvocationHandler handler = new StableInvocationHandler<T>(initial, provider);
final StableInvocationHandler handler = new StableInvocationHandler<T>(initial, provider, validator);
final Set<Class> intf = new HashSet<Class>();
intf.addAll(Arrays.asList(initial.getClass().getInterfaces()));
@@ -16,6 +16,7 @@
package com.intellij.util.xml.impl;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Factory;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xml.DomElement;
@@ -33,16 +34,18 @@ import java.util.Set;
/**
* @author peter
*/
class StableInvocationHandler<T extends DomElement> implements InvocationHandler, StableElement {
class StableInvocationHandler<T> implements InvocationHandler, StableElement {
private T myOldValue;
private T myCachedValue;
private final Set<Class> myClasses;
private final Factory<T> myProvider;
private final Condition<T> myValidator;
public StableInvocationHandler(final T initial, final Factory<T> provider) {
public StableInvocationHandler(final T initial, final Factory<T> provider, Condition<T> validator) {
myProvider = provider;
myCachedValue = initial;
myOldValue = initial;
myValidator = validator;
final Class superClass = initial.getClass().getSuperclass();
final Set<Class> classes = new HashSet<Class>();
classes.addAll(Arrays.asList(initial.getClass().getInterfaces()));
@@ -125,7 +128,7 @@ class StableInvocationHandler<T extends DomElement> implements InvocationHandler
}
}
public final DomElement getWrappedElement() {
public final T getWrappedElement() {
if (isNotValid(myCachedValue)) {
myCachedValue = myProvider.create();
}
@@ -137,7 +140,7 @@ class StableInvocationHandler<T extends DomElement> implements InvocationHandler
}
private boolean isNotValid(final T t) {
if (t == null || !t.isValid()) return true;
if (t == null || !myValidator.value(t)) return true;
for (final Class aClass : myClasses) {
if (!aClass.isInstance(t)) return true;
}
@@ -19,10 +19,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.util.NotNullLazyKey;
import com.intellij.openapi.util.*;
import com.intellij.psi.PsiReferenceFactory;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlFile;
@@ -121,6 +118,8 @@ public abstract class DomManager implements ModificationTracker {
*/
public abstract <T extends DomElement> T createStableValue(Factory<T> provider);
public abstract <T> T createStableValue(final Factory<T> provider, final Condition<T> validator);
/**
* Registers a new {@link com.intellij.util.xml.DomFileDescription} within the manager. The description parameter describes some DOM
* parameters and restrictions to the particular XML files, that need DOM support. Should be called on