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

This commit is contained in:
Dmitry Trofimov
2010-12-23 09:33:09 +03:00
163 changed files with 2227 additions and 1575 deletions
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GantSettings">
<option name="SDK_HOME" value="$PROJECT_DIR$/build/lib/gant" />
</component>
</project>
-13
View File
@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Gant">
<CLASSES>
<root url="file://$PROJECT_DIR$/build/lib/gant/lib" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/build/lib/gant/src.zip!/groovy" />
<root url="jar://$PROJECT_DIR$/build/lib/gant/jps-sources.zip!/" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/build/lib/gant/lib" recursive="false" />
</library>
</component>
+2 -1
View File
@@ -4,8 +4,9 @@
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="library" name="Gant" level="project" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Groovy" level="project" />
<orderEntry type="library" name="Ant" level="project" />
</component>
</module>
+1
View File
@@ -56,6 +56,7 @@ String appInfoFile() {
}
def wire_build_date(String buildNumber) {
ant.tstamp()
ant.replace(token: "__BUILD_NUMBER__", value: buildNumber, file: appInfoFile())
ant.replace(token: "__BUILD_DATE__", value: DSTAMP, file: appInfoFile())
}
@@ -3,12 +3,12 @@
<grid id="3d49c" binding="myPanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="52" y="58" width="686" height="190"/>
<xy x="52" y="58" width="727" height="229"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="770dc" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="770dc" layout-manager="GridLayoutManager" row-count="3" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -18,7 +18,7 @@
<children>
<component id="7d65" class="javax.swing.JRadioButton" binding="myRbGenerateMultipleFilesBuild">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="0" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.generate.multiple.files"/>
@@ -26,7 +26,7 @@
</component>
<component id="f1821" class="javax.swing.JRadioButton" binding="myRbGenerateSingleFileBuild">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.single.file"/>
@@ -34,7 +34,7 @@
</component>
<component id="81381" class="javax.swing.JRadioButton" binding="myRbBackupFiles">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.backup.files"/>
@@ -42,12 +42,28 @@
</component>
<component id="a019e" class="javax.swing.JRadioButton" binding="myRbOverwriteFiles">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.overwrite.files"/>
</properties>
</component>
<component id="cd13a" class="javax.swing.JTextField" binding="myOutputFileNameField">
<constraints>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="3a774" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.filename"/>
</properties>
</component>
</children>
</grid>
<component id="ec5e9" class="javax.swing.JCheckBox" binding="myCbEnableUIFormsCompilation">
@@ -56,7 +56,7 @@ public class GenerateAntBuildAction extends CompileActionBase {
public void run() {
genOptions[0] = new GenerationOptionsImpl(project, dialog.isGenerateSingleFileBuild(), dialog.isFormsCompilationEnabled(),
dialog.isBackupFiles(), dialog.isForceTargetJdk(), dialog.isRuntimeClasspathInlined(),
dialog.isIdeaHomeGenerated(), names);
dialog.isIdeaHomeGenerated(), names, dialog.getOutputFileName());
}
};
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(runnable, "Analyzing project structure...", true, project)) {
@@ -118,8 +118,8 @@ public class GenerateAntBuildAction extends CompileActionBase {
try {
if (genOptions.generateSingleFile) {
final File projectBuildFileDestDir = VfsUtil.virtualToIoFile(project.getBaseDir());
final File destFile = new File(projectBuildFileDestDir, BuildProperties.getProjectBuildFileName(project) + XML_EXTENSION);
final File propertiesFile = new File(projectBuildFileDestDir, BuildProperties.getPropertyFileName(project));
final File destFile = new File(projectBuildFileDestDir, genOptions.getBuildFileName());
final File propertiesFile = new File(projectBuildFileDestDir, genOptions.getPropertiesFileName());
ensureFilesWritable(project, new File[]{destFile, propertiesFile});
}
@@ -127,8 +127,8 @@ public class GenerateAntBuildAction extends CompileActionBase {
final List<File> allFiles = new ArrayList<File>();
final File projectBuildFileDestDir = VfsUtil.virtualToIoFile(project.getBaseDir());
allFiles.add(new File(projectBuildFileDestDir, BuildProperties.getProjectBuildFileName(project) + XML_EXTENSION));
allFiles.add(new File(projectBuildFileDestDir, BuildProperties.getPropertyFileName(project)));
allFiles.add(new File(projectBuildFileDestDir, genOptions.getBuildFileName()));
allFiles.add(new File(projectBuildFileDestDir, genOptions.getPropertiesFileName()));
final ModuleChunk[] chunks = genOptions.getModuleChunks();
for (final ModuleChunk chunk : chunks) {
@@ -218,8 +218,8 @@ public class GenerateAntBuildAction extends CompileActionBase {
private File[] generateSingleFileBuild(Project project, GenerationOptions genOptions, List<File> filesToRefresh) throws IOException {
final File projectBuildFileDestDir = VfsUtil.virtualToIoFile(project.getBaseDir());
projectBuildFileDestDir.mkdirs();
final File destFile = new File(projectBuildFileDestDir, BuildProperties.getProjectBuildFileName(project) + XML_EXTENSION);
final File propertiesFile = new File(projectBuildFileDestDir, BuildProperties.getPropertyFileName(project));
final File destFile = new File(projectBuildFileDestDir, genOptions.getBuildFileName());
final File propertiesFile = new File(projectBuildFileDestDir, genOptions.getPropertiesFileName());
if (!backup(destFile, project, genOptions, filesToRefresh)) {
return null;
@@ -289,8 +289,8 @@ public class GenerateAntBuildAction extends CompileActionBase {
final File projectBuildFileDestDir = VfsUtil.virtualToIoFile(project.getBaseDir());
projectBuildFileDestDir.mkdirs();
final List<File> generated = new ArrayList<File>();
final File projectBuildFile = new File(projectBuildFileDestDir, BuildProperties.getProjectBuildFileName(project) + XML_EXTENSION);
final File propertiesFile = new File(projectBuildFileDestDir, BuildProperties.getPropertyFileName(project));
final File projectBuildFile = new File(projectBuildFileDestDir, genOptions.getBuildFileName());
final File propertiesFile = new File(projectBuildFileDestDir, genOptions.getPropertiesFileName());
final ModuleChunk[] chunks = genOptions.getModuleChunks();
final File[] chunkFiles = new File[chunks.length];
@@ -17,6 +17,7 @@ package com.intellij.compiler.actions;
import com.intellij.compiler.HelpID;
import com.intellij.compiler.ModuleCompilerUtil;
import com.intellij.compiler.ant.BuildProperties;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.help.HelpManager;
@@ -51,178 +52,197 @@ import java.util.List;
* Date: Mar 29, 2004
*/
public class GenerateAntBuildDialog extends DialogWrapper {
private JPanel myPanel;
private JRadioButton myRbGenerateSingleFileBuild;
private JRadioButton myRbGenerateMultipleFilesBuild;
private JCheckBox myCbEnableUIFormsCompilation;
private JRadioButton myRbBackupFiles;
private JRadioButton myRbOverwriteFiles;
private JCheckBox myCbForceTargetJdk;
private JCheckBox myCbInlineRuntimeClasspath;
private JPanel myChunksPanel;
private JCheckBox myGenerateIdeaHomeProperty;
private final Project myProject;
@NonNls private static final String SINGLE_FILE_PROPERTY = "GenerateAntBuildDialog.generateSingleFile";
@NonNls private static final String UI_FORM_PROPERTY = "GenerateAntBuildDialog.enableUiFormCompile";
@NonNls private static final String FORCE_TARGET_JDK_PROPERTY = "GenerateAntBuildDialog.forceTargetJdk";
@NonNls private static final String BACKUP_FILES_PROPERTY = "GenerateAntBuildDialog.backupFiles";
@NonNls private static final String INLINE_RUNTIME_CLASSPATH_PROPERTY = "GenerateAntBuildDialog.inclineRuntiemClasspath";
@NonNls private static final String GENERATE_IDEA_HOME_PROPERTY = "GenerateAntBuildDialog.generateIdeaHomeProperty";
private MyTableModel myTableModel;
private Table myTable;
private JPanel myPanel;
private JRadioButton myRbGenerateSingleFileBuild;
private JRadioButton myRbGenerateMultipleFilesBuild;
private JCheckBox myCbEnableUIFormsCompilation;
private JRadioButton myRbBackupFiles;
private JRadioButton myRbOverwriteFiles;
private JCheckBox myCbForceTargetJdk;
private JCheckBox myCbInlineRuntimeClasspath;
private JPanel myChunksPanel;
private JCheckBox myGenerateIdeaHomeProperty;
private JTextField myOutputFileNameField;
private final Project myProject;
@NonNls private static final String SINGLE_FILE_PROPERTY = "GenerateAntBuildDialog.generateSingleFile";
@NonNls private static final String UI_FORM_PROPERTY = "GenerateAntBuildDialog.enableUiFormCompile";
@NonNls private static final String FORCE_TARGET_JDK_PROPERTY = "GenerateAntBuildDialog.forceTargetJdk";
@NonNls private static final String BACKUP_FILES_PROPERTY = "GenerateAntBuildDialog.backupFiles";
@NonNls private static final String INLINE_RUNTIME_CLASSPATH_PROPERTY = "GenerateAntBuildDialog.inclineRuntiemClasspath";
@NonNls private static final String GENERATE_IDEA_HOME_PROPERTY = "GenerateAntBuildDialog.generateIdeaHomeProperty";
@NonNls private static final String OUTPUT_FILE_NAME_PROPERTY = "GenerateAntBuildDialog.outputFileNameProperty";
private MyTableModel myTableModel;
private Table myTable;
public GenerateAntBuildDialog(Project project) {
super(project, false);
myProject = project;
setTitle(CompilerBundle.message("generate.ant.build.title"));
init();
loadSettings();
}
public GenerateAntBuildDialog(Project project) {
super(project, false);
myProject = project;
setTitle(CompilerBundle.message("generate.ant.build.title"));
init();
loadSettings();
}
private List<Chunk<Module>> getCycleChunks() {
List<Chunk<Module>> chunks =
ModuleCompilerUtil.getSortedModuleChunks(myProject, Arrays.asList(ModuleManager.getInstance(myProject).getModules()));
for (Iterator<Chunk<Module>> it = chunks.iterator(); it.hasNext();) {
final Chunk<Module> chunk = it.next();
if (chunk.getNodes().size() == 1) {
it.remove();
}
private List<Chunk<Module>> getCycleChunks() {
List<Chunk<Module>> chunks =
ModuleCompilerUtil.getSortedModuleChunks(myProject, Arrays.asList(ModuleManager.getInstance(myProject).getModules()));
for (Iterator<Chunk<Module>> it = chunks.iterator(); it.hasNext();) {
final Chunk<Module> chunk = it.next();
if (chunk.getNodes().size() == 1) {
it.remove();
}
return chunks;
}
return chunks;
}
private void loadSettings() {
final PropertiesComponent properties = PropertiesComponent.getInstance(myProject);
if (properties.isValueSet(SINGLE_FILE_PROPERTY)) {
final boolean singleFile = properties.isTrueValue(SINGLE_FILE_PROPERTY);
myRbGenerateSingleFileBuild.setSelected(singleFile);
myRbGenerateMultipleFilesBuild.setSelected(!singleFile);
}
if (properties.isValueSet(UI_FORM_PROPERTY)) {
myCbEnableUIFormsCompilation.setSelected(properties.isTrueValue(UI_FORM_PROPERTY));
}
if (properties.isValueSet(FORCE_TARGET_JDK_PROPERTY)) {
myCbForceTargetJdk.setSelected(properties.isTrueValue(FORCE_TARGET_JDK_PROPERTY));
}
if (properties.isValueSet(BACKUP_FILES_PROPERTY)) {
final boolean backup = properties.isTrueValue(BACKUP_FILES_PROPERTY);
myRbBackupFiles.setSelected(backup);
myRbOverwriteFiles.setSelected(!backup);
}
if (properties.isValueSet(INLINE_RUNTIME_CLASSPATH_PROPERTY)) {
myCbInlineRuntimeClasspath.setSelected(properties.isTrueValue(INLINE_RUNTIME_CLASSPATH_PROPERTY));
}
if (properties.isValueSet(GENERATE_IDEA_HOME_PROPERTY)) {
myGenerateIdeaHomeProperty.setSelected(properties.isTrueValue(GENERATE_IDEA_HOME_PROPERTY));
}
private void loadSettings() {
final PropertiesComponent properties = PropertiesComponent.getInstance(myProject);
if (properties.isValueSet(SINGLE_FILE_PROPERTY)) {
final boolean singleFile = properties.isTrueValue(SINGLE_FILE_PROPERTY);
myRbGenerateSingleFileBuild.setSelected(singleFile);
myRbGenerateMultipleFilesBuild.setSelected(!singleFile);
}
private void saveSettings() {
final PropertiesComponent properties = PropertiesComponent.getInstance(myProject);
properties.setValue(SINGLE_FILE_PROPERTY, Boolean.toString(myRbGenerateSingleFileBuild.isSelected()));
properties.setValue(UI_FORM_PROPERTY, Boolean.toString(myCbEnableUIFormsCompilation.isSelected()));
properties.setValue(FORCE_TARGET_JDK_PROPERTY, Boolean.toString(myCbForceTargetJdk.isSelected()));
properties.setValue(BACKUP_FILES_PROPERTY, Boolean.toString(myRbBackupFiles.isSelected()));
properties.setValue(INLINE_RUNTIME_CLASSPATH_PROPERTY, Boolean.toString(myCbInlineRuntimeClasspath.isSelected()));
properties.setValue(GENERATE_IDEA_HOME_PROPERTY, Boolean.toString(myGenerateIdeaHomeProperty.isSelected()));
if (properties.isValueSet(UI_FORM_PROPERTY)) {
myCbEnableUIFormsCompilation.setSelected(properties.isTrueValue(UI_FORM_PROPERTY));
}
public void dispose() {
saveSettings();
super.dispose();
if (properties.isValueSet(FORCE_TARGET_JDK_PROPERTY)) {
myCbForceTargetJdk.setSelected(properties.isTrueValue(FORCE_TARGET_JDK_PROPERTY));
}
protected JComponent createCenterPanel() {
final ButtonGroup group = new ButtonGroup();
group.add(myRbGenerateMultipleFilesBuild);
group.add(myRbGenerateSingleFileBuild);
final ButtonGroup group1 = new ButtonGroup();
group1.add(myRbBackupFiles);
group1.add(myRbOverwriteFiles);
myRbGenerateMultipleFilesBuild.setSelected(true);
myRbBackupFiles.setSelected(true);
myCbEnableUIFormsCompilation.setSelected(true);
myCbForceTargetJdk.setSelected(true);
myCbInlineRuntimeClasspath.setSelected(false);
initChunksPanel();
return myPanel;
if (properties.isValueSet(BACKUP_FILES_PROPERTY)) {
final boolean backup = properties.isTrueValue(BACKUP_FILES_PROPERTY);
myRbBackupFiles.setSelected(backup);
myRbOverwriteFiles.setSelected(!backup);
}
private void initChunksPanel() {
List<Chunk<Module>> chunks = getCycleChunks();
if (chunks.isEmpty()) {
return;
}
myChunksPanel.setLayout(new BorderLayout());
myChunksPanel.setBorder(
IdeBorderFactory.createTitledBorder(CompilerBundle.message("generate.ant.build.dialog.cyclic.modules.table.title")));
JLabel textLabel = new JLabel(CompilerBundle.message("generate.ant.build.dialog.cyclic.modules.table.description"));
textLabel.setUI(new MultiLineLabelUI());
textLabel.setBorder(IdeBorderFactory.createEmptyBorder(4, 4, 6, 4));
myChunksPanel.add(textLabel, BorderLayout.NORTH);
myTableModel = new MyTableModel(chunks);
myTable = new Table(myTableModel);
final MyTableCellRenderer cellRenderer = new MyTableCellRenderer();
final TableColumn nameColumn = myTable.getColumnModel().getColumn(MyTableModel.NAME_COLUMN);
nameColumn.setCellEditor(ComboBoxTableCellEditor.INSTANCE);
nameColumn.setCellRenderer(cellRenderer);
final TableColumn labelColumn = myTable.getColumnModel().getColumn(MyTableModel.NUMBER_COLUMN);
labelColumn.setCellRenderer(cellRenderer);
final Dimension preferredSize = new Dimension(myTable.getPreferredSize());
preferredSize.height = (myTableModel.getRowCount() + 2) * myTable.getRowHeight() + myTable.getTableHeader().getHeight();
final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable);
scrollPane.setPreferredSize(preferredSize);
myChunksPanel.add(scrollPane, BorderLayout.CENTER);
if (properties.isValueSet(INLINE_RUNTIME_CLASSPATH_PROPERTY)) {
myCbInlineRuntimeClasspath.setSelected(properties.isTrueValue(INLINE_RUNTIME_CLASSPATH_PROPERTY));
}
protected void doOKAction() {
if (myTable != null) {
TableCellEditor cellEditor = myTable.getCellEditor();
if (cellEditor != null) {
cellEditor.stopCellEditing();
}
}
super.doOKAction();
if (properties.isValueSet(GENERATE_IDEA_HOME_PROPERTY)) {
myGenerateIdeaHomeProperty.setSelected(properties.isTrueValue(GENERATE_IDEA_HOME_PROPERTY));
}
public boolean isGenerateSingleFileBuild() {
return myRbGenerateSingleFileBuild.isSelected();
if (properties.isValueSet(OUTPUT_FILE_NAME_PROPERTY)) {
myOutputFileNameField.setText(properties.getValue(OUTPUT_FILE_NAME_PROPERTY));
}
public boolean isFormsCompilationEnabled() {
return myCbEnableUIFormsCompilation.isSelected();
else {
myOutputFileNameField.setText(BuildProperties.getProjectBuildFileName(myProject));
}
}
public boolean isForceTargetJdk() {
return myCbForceTargetJdk.isSelected();
private void saveSettings() {
final PropertiesComponent properties = PropertiesComponent.getInstance(myProject);
properties.setValue(SINGLE_FILE_PROPERTY, Boolean.toString(myRbGenerateSingleFileBuild.isSelected()));
properties.setValue(UI_FORM_PROPERTY, Boolean.toString(myCbEnableUIFormsCompilation.isSelected()));
properties.setValue(FORCE_TARGET_JDK_PROPERTY, Boolean.toString(myCbForceTargetJdk.isSelected()));
properties.setValue(BACKUP_FILES_PROPERTY, Boolean.toString(myRbBackupFiles.isSelected()));
properties.setValue(INLINE_RUNTIME_CLASSPATH_PROPERTY, Boolean.toString(myCbInlineRuntimeClasspath.isSelected()));
properties.setValue(GENERATE_IDEA_HOME_PROPERTY, Boolean.toString(myGenerateIdeaHomeProperty.isSelected()));
final String outputFileName = getOutputFileName();
if (outputFileName.length() > 0) {
properties.setValue(OUTPUT_FILE_NAME_PROPERTY, outputFileName);
}
public boolean isBackupFiles() {
return myRbBackupFiles.isSelected();
else {
properties.unsetValue(OUTPUT_FILE_NAME_PROPERTY);
}
}
public boolean isRuntimeClasspathInlined() {
return myCbInlineRuntimeClasspath.isSelected();
public void dispose() {
saveSettings();
super.dispose();
}
protected JComponent createCenterPanel() {
final ButtonGroup group = new ButtonGroup();
group.add(myRbGenerateMultipleFilesBuild);
group.add(myRbGenerateSingleFileBuild);
final ButtonGroup group1 = new ButtonGroup();
group1.add(myRbBackupFiles);
group1.add(myRbOverwriteFiles);
myRbGenerateMultipleFilesBuild.setSelected(true);
myRbBackupFiles.setSelected(true);
myCbEnableUIFormsCompilation.setSelected(true);
myCbForceTargetJdk.setSelected(true);
myCbInlineRuntimeClasspath.setSelected(false);
initChunksPanel();
return myPanel;
}
private void initChunksPanel() {
List<Chunk<Module>> chunks = getCycleChunks();
if (chunks.isEmpty()) {
return;
}
myChunksPanel.setLayout(new BorderLayout());
myChunksPanel.setBorder(
IdeBorderFactory.createTitledBorder(CompilerBundle.message("generate.ant.build.dialog.cyclic.modules.table.title")));
JLabel textLabel = new JLabel(CompilerBundle.message("generate.ant.build.dialog.cyclic.modules.table.description"));
textLabel.setUI(new MultiLineLabelUI());
textLabel.setBorder(IdeBorderFactory.createEmptyBorder(4, 4, 6, 4));
myChunksPanel.add(textLabel, BorderLayout.NORTH);
public String[] getRepresentativeModuleNames() {
return myTableModel != null ? myTableModel.getModuleRepresentatives() : ArrayUtil.EMPTY_STRING_ARRAY;
myTableModel = new MyTableModel(chunks);
myTable = new Table(myTableModel);
final MyTableCellRenderer cellRenderer = new MyTableCellRenderer();
final TableColumn nameColumn = myTable.getColumnModel().getColumn(MyTableModel.NAME_COLUMN);
nameColumn.setCellEditor(ComboBoxTableCellEditor.INSTANCE);
nameColumn.setCellRenderer(cellRenderer);
final TableColumn labelColumn = myTable.getColumnModel().getColumn(MyTableModel.NUMBER_COLUMN);
labelColumn.setCellRenderer(cellRenderer);
final Dimension preferredSize = new Dimension(myTable.getPreferredSize());
preferredSize.height = (myTableModel.getRowCount() + 2) * myTable.getRowHeight() + myTable.getTableHeader().getHeight();
final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable);
scrollPane.setPreferredSize(preferredSize);
myChunksPanel.add(scrollPane, BorderLayout.CENTER);
}
protected void doOKAction() {
if (myTable != null) {
TableCellEditor cellEditor = myTable.getCellEditor();
if (cellEditor != null) {
cellEditor.stopCellEditing();
}
}
super.doOKAction();
}
/**
* @return true if user has selected to generate IDEA_HOME property
*/
public boolean isIdeaHomeGenerated() {
return myGenerateIdeaHomeProperty.isSelected();
}
public boolean isGenerateSingleFileBuild() {
return myRbGenerateSingleFileBuild.isSelected();
}
public boolean isFormsCompilationEnabled() {
return myCbEnableUIFormsCompilation.isSelected();
}
public boolean isForceTargetJdk() {
return myCbForceTargetJdk.isSelected();
}
public boolean isBackupFiles() {
return myRbBackupFiles.isSelected();
}
public boolean isRuntimeClasspathInlined() {
return myCbInlineRuntimeClasspath.isSelected();
}
public String[] getRepresentativeModuleNames() {
return myTableModel != null ? myTableModel.getModuleRepresentatives() : ArrayUtil.EMPTY_STRING_ARRAY;
}
/**
* @return true if user has selected to generate IDEA_HOME property
*/
public boolean isIdeaHomeGenerated() {
return myGenerateIdeaHomeProperty.isSelected();
}
public String getOutputFileName() {
return myOutputFileNameField.getText().trim();
}
private static class MyTableModel extends AbstractTableModel {
private static final int NUMBER_COLUMN = 0;
private static final int NAME_COLUMN = 1;
@@ -43,7 +43,7 @@ import java.io.IOException;
public class BuildPropertiesImpl extends BuildProperties {
public BuildPropertiesImpl(Project project, final GenerationOptions genOptions) {
add(new Property(getPropertyFileName(project)));
add(new Property(genOptions.getPropertiesFileName()));
//noinspection HardCodedStringLiteral
add(new Comment(CompilerBundle.message("generated.ant.build.disable.tests.property.comment"),
@@ -44,267 +44,286 @@ import java.util.*;
* Date: Mar 25, 2004
*/
public class GenerationOptionsImpl extends GenerationOptions {
/**
* from absolute path to macro substitutions
*/
private final ReplacePathToMacroMap myMacroReplacementMap;
/**
* from absolute path to macro substitutions
*/
private final Map<String, String> myOutputUrlToPropertyRefMap;
/**
* module chunks
*/
private final ModuleChunk[] myModuleChunks;
/**
* the project to be converted
*/
private final Project myProject;
private final boolean myGenerateIdeaHomeProperty;
private Set<String> myJdkUrls;
/**
* Custom compilers used in the ant build.
*/
private final Set<ChunkCustomCompilerExtension> myCustomCompilers = new HashSet<ChunkCustomCompilerExtension>();
/**
* map from modules to chunks
*/
private final Map<Module, ModuleChunk> myModuleToChunkMap = new HashMap<Module, ModuleChunk>();
/**
* A constructor
*
* @param project a project to generate
* @param forceTargetJdk a value of corresponding option
* @param generateSingleFile a value of corresponding option
* @param enableFormCompiler a value of corresponding option
* @param backupPreviouslyGeneratedFiles a value of corresponding option
* @param inlineRuntimeClasspath if true a runtiem classpaths are inlined
* @param representativeModuleNames a module name that represents module chunks.
*/
public GenerationOptionsImpl(Project project,
boolean generateSingleFile,
boolean enableFormCompiler,
boolean backupPreviouslyGeneratedFiles,
boolean forceTargetJdk,
boolean inlineRuntimeClasspath,
boolean generateIdeaHomeProperty,
String[] representativeModuleNames) {
super(forceTargetJdk, generateSingleFile, enableFormCompiler, backupPreviouslyGeneratedFiles, inlineRuntimeClasspath);
myProject = project;
myGenerateIdeaHomeProperty = generateIdeaHomeProperty;
myMacroReplacementMap = createReplacementMap();
myModuleChunks = createModuleChunks(representativeModuleNames);
myOutputUrlToPropertyRefMap = createOutputUrlToPropertyRefMap(myModuleChunks);
/**
* from absolute path to macro substitutions
*/
private final ReplacePathToMacroMap myMacroReplacementMap;
/**
* from absolute path to macro substitutions
*/
private final Map<String, String> myOutputUrlToPropertyRefMap;
/**
* module chunks
*/
private final ModuleChunk[] myModuleChunks;
/**
* the project to be converted
*/
private final Project myProject;
private final boolean myGenerateIdeaHomeProperty;
private final String myOutputFileName;
private Set<String> myJdkUrls;
/**
* Custom compilers used in the ant build.
*/
private final Set<ChunkCustomCompilerExtension> myCustomCompilers = new HashSet<ChunkCustomCompilerExtension>();
/**
* map from modules to chunks
*/
private final Map<Module, ModuleChunk> myModuleToChunkMap = new HashMap<Module, ModuleChunk>();
/**
* A constructor
*
* @param project a project to generate
* @param generateSingleFile a value of corresponding option
* @param enableFormCompiler a value of corresponding option
* @param backupPreviouslyGeneratedFiles a value of corresponding option
* @param forceTargetJdk a value of corresponding option
* @param inlineRuntimeClasspath if true a runtiem classpaths are inlined
* @param representativeModuleNames a module name that represents module chunks.
* @param outputFileName a name for the output file
*/
public GenerationOptionsImpl(Project project,
boolean generateSingleFile,
boolean enableFormCompiler,
boolean backupPreviouslyGeneratedFiles,
boolean forceTargetJdk,
boolean inlineRuntimeClasspath,
boolean generateIdeaHomeProperty,
String[] representativeModuleNames, String outputFileName) {
super(forceTargetJdk, generateSingleFile, enableFormCompiler, backupPreviouslyGeneratedFiles, inlineRuntimeClasspath);
myProject = project;
myGenerateIdeaHomeProperty = generateIdeaHomeProperty;
myOutputFileName = outputFileName;
myMacroReplacementMap = createReplacementMap();
myModuleChunks = createModuleChunks(representativeModuleNames);
myOutputUrlToPropertyRefMap = createOutputUrlToPropertyRefMap(myModuleChunks);
}
/**
* A constructor
*
* @param project a project to generate
* @param forceTargetJdk a value of corresponding option
* @param generateSingleFile a value of corresponding option
* @param enableFormCompiler a value of corresponding option
* @param backupPreviouslyGeneratedFiles a value of corresponding option
* @param representativeModuleNames a module name that represents module chunks.
*/
@Deprecated
public GenerationOptionsImpl(Project project,
boolean generateSingleFile,
boolean enableFormCompiler,
boolean backupPreviouslyGeneratedFiles,
boolean forceTargetJdk,
String[] representativeModuleNames) {
this(project, forceTargetJdk, generateSingleFile, enableFormCompiler, backupPreviouslyGeneratedFiles, false, false,
representativeModuleNames, null);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isIdeaHomeGenerated() {
return myGenerateIdeaHomeProperty;
}
public String getBuildFileName() {
return getOutputFileName() + ".xml";
}
public String getPropertiesFileName() {
return getOutputFileName() + ".properties";
}
private String getOutputFileName() {
if (myOutputFileName == null || myOutputFileName.length() == 0) {
return BuildProperties.getProjectBuildFileName(myProject);
}
return myOutputFileName;
}
/**
* A constructor
*
* @param project a project to generate
* @param forceTargetJdk a value of corresponding option
* @param generateSingleFile a value of corresponding option
* @param enableFormCompiler a value of corresponding option
* @param backupPreviouslyGeneratedFiles a value of corresponding option
* @param representativeModuleNames a module name that represents module chunks.
*/
@Deprecated
public GenerationOptionsImpl(Project project,
boolean generateSingleFile,
boolean enableFormCompiler,
boolean backupPreviouslyGeneratedFiles,
boolean forceTargetJdk,
String[] representativeModuleNames) {
this(project, forceTargetJdk, generateSingleFile, enableFormCompiler, backupPreviouslyGeneratedFiles, false, false,
representativeModuleNames);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isIdeaHomeGenerated() {
return myGenerateIdeaHomeProperty;
}
/**
* {@inheritDoc}
*/
@Override
public ModuleChunk getChunkByModule(final Module module) {
if (myModuleToChunkMap.isEmpty()) {
for (ModuleChunk c : myModuleChunks) {
for (Module m : c.getModules()) {
myModuleToChunkMap.put(m, c);
}
}
/**
* {@inheritDoc}
*/
@Override
public ModuleChunk getChunkByModule(final Module module) {
if (myModuleToChunkMap.isEmpty()) {
for (ModuleChunk c : myModuleChunks) {
for (Module m : c.getModules()) {
myModuleToChunkMap.put(m, c);
}
return myModuleToChunkMap.get(module);
}
}
return myModuleToChunkMap.get(module);
}
@Override
public String subsitutePathWithMacros(String path) {
if (myMacroReplacementMap.size() == 0) {
return path; // optimization
@Override
public String subsitutePathWithMacros(String path) {
if (myMacroReplacementMap.size() == 0) {
return path; // optimization
}
return myMacroReplacementMap.substitute(path, SystemInfo.isFileSystemCaseSensitive);
}
public String getPropertyRefForUrl(String url) {
return myOutputUrlToPropertyRefMap.get(url);
}
private static ReplacePathToMacroMap createReplacementMap() {
final PathMacros pathMacros = PathMacros.getInstance();
final Set<String> macroNames = pathMacros.getUserMacroNames();
final ReplacePathToMacroMap map = new ReplacePathToMacroMap();
for (final String macroName : macroNames) {
map.put(GenerationUtils.normalizePath(pathMacros.getValue(macroName)),
BuildProperties.propertyRef(BuildProperties.getPathMacroProperty(macroName)));
}
map.put(GenerationUtils.normalizePath(PathManager.getHomePath()), BuildProperties.propertyRef(BuildProperties.PROPERTY_IDEA_HOME));
return map;
}
private static Map<String, String> createOutputUrlToPropertyRefMap(ModuleChunk[] chunks) {
final Map<String, String> map = new HashMap<String, String>();
for (final ModuleChunk chunk : chunks) {
final String outputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(chunk.getName()));
final String testsOutputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathForTestsProperty(chunk.getName()));
final Module[] modules = chunk.getModules();
for (final Module module : modules) {
final String outputPathUrl = CompilerModuleExtension.getInstance(module).getCompilerOutputUrl();
if (outputPathUrl != null) {
map.put(outputPathUrl, outputPathRef);
}
return myMacroReplacementMap.substitute(path, SystemInfo.isFileSystemCaseSensitive);
}
public String getPropertyRefForUrl(String url) {
return myOutputUrlToPropertyRefMap.get(url);
}
private static ReplacePathToMacroMap createReplacementMap() {
final PathMacros pathMacros = PathMacros.getInstance();
final Set<String> macroNames = pathMacros.getUserMacroNames();
final ReplacePathToMacroMap map = new ReplacePathToMacroMap();
for (final String macroName : macroNames) {
map.put(GenerationUtils.normalizePath(pathMacros.getValue(macroName)),
BuildProperties.propertyRef(BuildProperties.getPathMacroProperty(macroName)));
}
map.put(GenerationUtils.normalizePath(PathManager.getHomePath()), BuildProperties.propertyRef(BuildProperties.PROPERTY_IDEA_HOME));
return map;
}
private static Map<String, String> createOutputUrlToPropertyRefMap(ModuleChunk[] chunks) {
final Map<String, String> map = new HashMap<String, String>();
for (final ModuleChunk chunk : chunks) {
final String outputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(chunk.getName()));
final String testsOutputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathForTestsProperty(chunk.getName()));
final Module[] modules = chunk.getModules();
for (final Module module : modules) {
final String outputPathUrl = CompilerModuleExtension.getInstance(module).getCompilerOutputUrl();
if (outputPathUrl != null) {
map.put(outputPathUrl, outputPathRef);
}
final String outputPathForTestsUrl = CompilerModuleExtension.getInstance(module).getCompilerOutputUrlForTests();
if (outputPathForTestsUrl != null) {
if (outputPathUrl == null || !outputPathForTestsUrl.equals(outputPathUrl)) {
map.put(outputPathForTestsUrl, testsOutputPathRef);
}
}
}
}
return map;
}
@Override
public ModuleChunk[] getModuleChunks() {
return myModuleChunks;
}
private ModuleChunk[] createModuleChunks(String[] representativeModuleNames) {
final Set<String> mainModuleNames = new HashSet<String>(Arrays.asList(representativeModuleNames));
final Graph<Chunk<Module>> chunkGraph = ModuleCompilerUtil.toChunkGraph(ModuleManager.getInstance(myProject).moduleGraph());
final Map<Chunk<Module>, ModuleChunk> map = new HashMap<Chunk<Module>, ModuleChunk>();
final Map<ModuleChunk, Chunk<Module>> reverseMap = new HashMap<ModuleChunk, Chunk<Module>>();
for (final Chunk<Module> chunk : chunkGraph.getNodes()) {
final Set<Module> modules = chunk.getNodes();
final ModuleChunk moduleChunk = new ModuleChunk(modules.toArray(new Module[modules.size()]));
for (final Module module : modules) {
if (mainModuleNames.contains(module.getName())) {
moduleChunk.setMainModule(module);
break;
}
}
map.put(chunk, moduleChunk);
reverseMap.put(moduleChunk, chunk);
}
final Graph<ModuleChunk> moduleChunkGraph =
GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<ModuleChunk>() {
public Collection<ModuleChunk> getNodes() {
return map.values();
}
public Iterator<ModuleChunk> getIn(ModuleChunk n) {
final Chunk<Module> chunk = reverseMap.get(n);
final Iterator<Chunk<Module>> in = chunkGraph.getIn(chunk);
return new Iterator<ModuleChunk>() {
public boolean hasNext() {
return in.hasNext();
}
public ModuleChunk next() {
return map.get(in.next());
}
public void remove() {
new OperationNotSupportedException();
}
};
}
}));
final Collection<ModuleChunk> nodes = moduleChunkGraph.getNodes();
final ModuleChunk[] moduleChunks = nodes.toArray(new ModuleChunk[nodes.size()]);
for (ModuleChunk moduleChunk : moduleChunks) {
final Iterator<ModuleChunk> depsIterator = moduleChunkGraph.getIn(moduleChunk);
List<ModuleChunk> deps = new ArrayList<ModuleChunk>();
while (depsIterator.hasNext()) {
deps.add(depsIterator.next());
final String outputPathForTestsUrl = CompilerModuleExtension.getInstance(module).getCompilerOutputUrlForTests();
if (outputPathForTestsUrl != null) {
if (outputPathUrl == null || !outputPathForTestsUrl.equals(outputPathUrl)) {
map.put(outputPathForTestsUrl, testsOutputPathRef);
}
moduleChunk.setDependentChunks(deps.toArray(new ModuleChunk[deps.size()]));
ContainerUtil.addAll(myCustomCompilers, moduleChunk.getCustomCompilers());
}
Arrays.sort(moduleChunks, new ChunksComparator());
if (generateSingleFile) {
final File baseDir = BuildProperties.getProjectBaseDir(myProject);
for (ModuleChunk chunk : moduleChunks) {
chunk.setBaseDir(baseDir);
}
}
return map;
}
@Override
public ModuleChunk[] getModuleChunks() {
return myModuleChunks;
}
private ModuleChunk[] createModuleChunks(String[] representativeModuleNames) {
final Set<String> mainModuleNames = new HashSet<String>(Arrays.asList(representativeModuleNames));
final Graph<Chunk<Module>> chunkGraph = ModuleCompilerUtil.toChunkGraph(ModuleManager.getInstance(myProject).moduleGraph());
final Map<Chunk<Module>, ModuleChunk> map = new HashMap<Chunk<Module>, ModuleChunk>();
final Map<ModuleChunk, Chunk<Module>> reverseMap = new HashMap<ModuleChunk, Chunk<Module>>();
for (final Chunk<Module> chunk : chunkGraph.getNodes()) {
final Set<Module> modules = chunk.getNodes();
final ModuleChunk moduleChunk = new ModuleChunk(modules.toArray(new Module[modules.size()]));
for (final Module module : modules) {
if (mainModuleNames.contains(module.getName())) {
moduleChunk.setMainModule(module);
break;
}
}
map.put(chunk, moduleChunk);
reverseMap.put(moduleChunk, chunk);
}
final Graph<ModuleChunk> moduleChunkGraph =
GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<ModuleChunk>() {
public Collection<ModuleChunk> getNodes() {
return map.values();
}
public Iterator<ModuleChunk> getIn(ModuleChunk n) {
final Chunk<Module> chunk = reverseMap.get(n);
final Iterator<Chunk<Module>> in = chunkGraph.getIn(chunk);
return new Iterator<ModuleChunk>() {
public boolean hasNext() {
return in.hasNext();
}
}
return moduleChunks;
}
/**
* {@inheritDoc}
*/
public ChunkCustomCompilerExtension[] getCustomCompilers() {
ChunkCustomCompilerExtension[] sorted = myCustomCompilers.toArray(new ChunkCustomCompilerExtension[myCustomCompilers.size()]);
Arrays.sort(sorted, ChunkCustomCompilerExtension.COMPARATOR);
return sorted;
}
Set<String> getAllJdkUrls() {
if (myJdkUrls != null) {
return myJdkUrls;
}
final Sdk[] projectJdks = ProjectJdkTable.getInstance().getAllJdks();
myJdkUrls = new HashSet<String>();
for (Sdk jdk : projectJdks) {
ContainerUtil.addAll(myJdkUrls, jdk.getRootProvider().getUrls(OrderRootType.CLASSES));
}
return myJdkUrls;
}
private static class ChunksComparator implements Comparator<ModuleChunk> {
final Map<ModuleChunk, Integer> myCachedLevels = new HashMap<ModuleChunk, Integer>();
public int compare(final ModuleChunk o1, final ModuleChunk o2) {
final int level1 = getChunkLevel(o1);
final int level2 = getChunkLevel(o2);
return (level1 == level2) ? o1.getName().compareToIgnoreCase(o2.getName()) : (level1 - level2);
}
private int getChunkLevel(ModuleChunk chunk) {
Integer level = myCachedLevels.get(chunk);
if (level == null) {
final ModuleChunk[] chunks = chunk.getDependentChunks();
if (chunks.length > 0) {
int maxLevel = 0;
for (ModuleChunk dependent : chunks) {
maxLevel = Math.max(maxLevel, getChunkLevel(dependent));
}
level = 1 + maxLevel;
}
else {
level = 0;
}
myCachedLevels.put(chunk, level);
public ModuleChunk next() {
return map.get(in.next());
}
return level.intValue();
public void remove() {
new OperationNotSupportedException();
}
};
}
}));
final Collection<ModuleChunk> nodes = moduleChunkGraph.getNodes();
final ModuleChunk[] moduleChunks = nodes.toArray(new ModuleChunk[nodes.size()]);
for (ModuleChunk moduleChunk : moduleChunks) {
final Iterator<ModuleChunk> depsIterator = moduleChunkGraph.getIn(moduleChunk);
List<ModuleChunk> deps = new ArrayList<ModuleChunk>();
while (depsIterator.hasNext()) {
deps.add(depsIterator.next());
}
moduleChunk.setDependentChunks(deps.toArray(new ModuleChunk[deps.size()]));
ContainerUtil.addAll(myCustomCompilers, moduleChunk.getCustomCompilers());
}
Arrays.sort(moduleChunks, new ChunksComparator());
if (generateSingleFile) {
final File baseDir = BuildProperties.getProjectBaseDir(myProject);
for (ModuleChunk chunk : moduleChunks) {
chunk.setBaseDir(baseDir);
}
}
return moduleChunks;
}
/**
* {@inheritDoc}
*/
public ChunkCustomCompilerExtension[] getCustomCompilers() {
ChunkCustomCompilerExtension[] sorted = myCustomCompilers.toArray(new ChunkCustomCompilerExtension[myCustomCompilers.size()]);
Arrays.sort(sorted, ChunkCustomCompilerExtension.COMPARATOR);
return sorted;
}
Set<String> getAllJdkUrls() {
if (myJdkUrls != null) {
return myJdkUrls;
}
final Sdk[] projectJdks = ProjectJdkTable.getInstance().getAllJdks();
myJdkUrls = new HashSet<String>();
for (Sdk jdk : projectJdks) {
ContainerUtil.addAll(myJdkUrls, jdk.getRootProvider().getUrls(OrderRootType.CLASSES));
}
return myJdkUrls;
}
private static class ChunksComparator implements Comparator<ModuleChunk> {
final Map<ModuleChunk, Integer> myCachedLevels = new HashMap<ModuleChunk, Integer>();
public int compare(final ModuleChunk o1, final ModuleChunk o2) {
final int level1 = getChunkLevel(o1);
final int level2 = getChunkLevel(o2);
return (level1 == level2) ? o1.getName().compareToIgnoreCase(o2.getName()) : (level1 - level2);
}
private int getChunkLevel(ModuleChunk chunk) {
Integer level = myCachedLevels.get(chunk);
if (level == null) {
final ModuleChunk[] chunks = chunk.getDependentChunks();
if (chunks.length > 0) {
int maxLevel = 0;
for (ModuleChunk dependent : chunks) {
maxLevel = Math.max(maxLevel, getChunkLevel(dependent));
}
level = 1 + maxLevel;
}
else {
level = 0;
}
myCachedLevels.put(chunk, level);
}
return level.intValue();
}
}
}
@@ -72,11 +72,6 @@ public abstract class BuildProperties extends CompositeGenerator {
return jdks.toArray(new Sdk[jdks.size()]);
}
@NonNls
public static String getPropertyFileName(Project project) {
return getProjectBuildFileName(project) + ".properties";
}
@NonNls
public static String getJdkPathId(@NonNls final String jdkName) {
return "jdk.classpath." + convertName(jdkName);
@@ -23,7 +23,7 @@ import com.intellij.openapi.module.Module;
* @author anna
*/
public abstract class GenerationOptions {
/**
/**
* This option specifies whether mulitfile or single file ant script is created.
*/
public final boolean generateSingleFile;
@@ -146,4 +146,7 @@ public abstract class GenerationOptions {
public abstract boolean isIdeaHomeGenerated();
public abstract String getBuildFileName();
public abstract String getPropertiesFileName();
}
@@ -374,10 +374,12 @@ public class HighlightUtil {
IElementType opSign = TypeConversionUtil.convertEQtoOperation(eqOpSign);
if (opSign == null) return null;
HighlightInfo errorResult = null;
if (!TypeConversionUtil.isBinaryOperatorApplicable(opSign, assignment.getLExpression(), assignment.getRExpression(), true)) {
final PsiType lType = assignment.getLExpression().getType();
if (!TypeConversionUtil.isBinaryOperatorApplicable(opSign, assignment.getLExpression(), assignment.getRExpression(), true) ||
PsiType.getJavaLangObject(assignment.getManager(), assignment.getResolveScope()).equals(lType)) {
String operatorText = operationSign.getText().substring(0, operationSign.getText().length() - 1);
String message = JavaErrorMessages.message("binary.operator.not.applicable", operatorText,
formatType(assignment.getLExpression().getType()),
formatType(lType),
formatType(assignment.getRExpression().getType()));
errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, assignment, message);
@@ -209,7 +209,7 @@ public class InvertIfConditionAction extends PsiElementBaseIntentionAction {
PsiStatement[] statements = ((PsiBlockStatement) thenBranch).getCodeBlock().getStatements();
int len = statements.length;
if (len > 0) {
if (statements[len - 1] instanceof PsiReturnStatement) len--;
//if (statements[len - 1] instanceof PsiReturnStatement) len--;
if (len > 0) {
PsiElement firstElement = statements [0];
while (firstElement.getPrevSibling() instanceof PsiWhiteSpace || firstElement.getPrevSibling() instanceof PsiComment) {
@@ -334,6 +334,16 @@ public class JavaParserUtil {
return myDelegate.lookAhead(steps);
}
@Override
public IElementType rawLookup(int steps) {
return myDelegate.rawLookup(steps);
}
@Override
public int rawTokenTypeStart(int steps) {
return myDelegate.rawTokenTypeStart(steps);
}
@Nullable @NonNls
public String getTokenText() {
return myDelegate.getTokenText();
@@ -31,18 +31,44 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
/**
* @author peter
*/
public abstract class NonClasspathClassFinder extends PsiElementFinder {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.NonClasspathClassFinder");
private final AtomicLong myLastStamp = new AtomicLong();
protected final Project myProject;
private volatile List<VirtualFile> myCache;
public NonClasspathClassFinder(Project project) {
myProject = project;
}
protected List<VirtualFile> getClassRoots() {
List<VirtualFile> cache = myCache;
long stamp = PsiManager.getInstance(myProject).getModificationTracker().getModificationCount();
if (myLastStamp.get() != stamp) {
cache = null;
}
if (cache != null && !cache.isEmpty()) {
for (VirtualFile file : cache) {
if (!file.isValid()) {
cache = null;
break;
}
}
}
if (cache == null) {
myCache = cache = calcClassRoots();
myLastStamp.set(stamp);
}
return cache;
}
@Override
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
final List<VirtualFile> classRoots = getClassRoots();
@@ -71,7 +97,7 @@ public abstract class NonClasspathClassFinder extends PsiElementFinder {
return null;
}
protected abstract List<VirtualFile> getClassRoots();
protected abstract List<VirtualFile> calcClassRoots();
@NotNull
@Override
@@ -114,7 +114,7 @@ public class ShiftIndentInsideHelper {
}
else {
if (newSpace.length() > 0) {
LeafElement newLeaf = ASTFactory.leaf(TokenType.WHITE_SPACE, newSpace, charTableByTree);
LeafElement newLeaf = ASTFactory.whitespace(newSpace);
next.getTreeParent().addChild(newLeaf, next);
}
text = text.substring(0, offset + 1) + newSpace + text.substring(offset1);
@@ -291,10 +291,13 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
}
else {
List<PsiReferenceExpression> refExprList = new ArrayList<PsiReferenceExpression>();
final List<PsiElement> imports2Delete = new ArrayList<PsiElement>();
for (final UsageInfo usage : usages) {
final PsiElement element = usage.getElement();
if (element instanceof PsiReferenceExpression) {
refExprList.add((PsiReferenceExpression)element);
} else if (element instanceof PsiImportStaticReferenceElement) {
imports2Delete.add(PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class));
}
}
PsiReferenceExpression[] refs = refExprList.toArray(new PsiReferenceExpression[refExprList.size()]);
@@ -302,6 +305,11 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
for (PsiReferenceExpression ref : refs) {
inlineMethodCall(ref);
}
for (PsiElement psiElement : imports2Delete) {
if (psiElement != null && psiElement.isValid()) {
psiElement.delete();
}
}
myMethod.delete();
}
}
@@ -39,6 +39,7 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pass;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.WindowManager;
@@ -134,7 +135,8 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
}
PsiElement tempAnchorElement = RefactoringUtil.getParentExpressionAnchorElement(selectedExpr);
if (IntroduceVariableBase.checkAnchorBeforeThisOrSuper(project, editor, tempAnchorElement, getRefactoringName(), getHelpID())) return false;
if (!Comparing.strEqual(IntroduceConstantHandler.REFACTORING_NAME, getRefactoringName()) &&
IntroduceVariableBase.checkAnchorBeforeThisOrSuper(project, editor, tempAnchorElement, getRefactoringName(), getHelpID())) return false;
final Settings settings =
showRefactoringDialog(project, editor, myParentClass, selectedExpr, tempType,
@@ -300,11 +300,13 @@ public class IntroduceParameterDialog extends RefactoringDialog {
myCbGenerateDelegate = new NonFocusableCheckBox(RefactoringBundle.message("delegation.panel.delegate.via.overloading.method"));
panel.add(myCbGenerateDelegate, gbConstraints);
final JCheckBox[] removeParamsCb = new JCheckBox[myParametersToRemove.length];
for (int i = 0; i < myParametersToRemove.length; i++) {
PsiParameter parameter = myParametersToRemove[i];
if (parameter == null) continue;
final NonFocusableCheckBox cb = new NonFocusableCheckBox(RefactoringBundle.message("remove.parameter.0.no.longer.used",
parameter.getName()));
removeParamsCb[i] = cb;
cb.setSelected(true);
gbConstraints.gridy++;
panel.add(cb, gbConstraints);
@@ -317,12 +319,13 @@ public class IntroduceParameterDialog extends RefactoringDialog {
myParametersToRemoveChecked[i] = true;
}
updateControls();
updateControls(removeParamsCb);
if (myCbReplaceAllOccurences != null) {
myCbReplaceAllOccurences.addItemListener(
new ItemListener() {
public void itemStateChanged(ItemEvent e) {
updateControls();
updateControls(removeParamsCb);
}
}
);
@@ -330,8 +333,13 @@ public class IntroduceParameterDialog extends RefactoringDialog {
return panel;
}
private void updateControls() {
if(myCbReplaceAllOccurences != null) {
private void updateControls(JCheckBox[] removeParamsCb) {
if (myCbReplaceAllOccurences != null) {
for (JCheckBox box : removeParamsCb) {
if (box != null) {
box.setEnabled(myCbReplaceAllOccurences.isSelected());
}
}
myTypeSelectorManager.setAllOccurences(myCbReplaceAllOccurences.isSelected());
if(myCbReplaceAllOccurences.isSelected()) {
if (myCbDeleteLocalVariable != null) {
@@ -141,12 +141,6 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
if (methodToSearchFor == null) return false;
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, methodToSearchFor)) return false;
PsiExpression expressionToRemoveParamFrom = expr;
if (expr == null) {
expressionToRemoveParamFrom = localVar.getInitializer();
}
TIntArrayList parametersToRemove = expressionToRemoveParamFrom == null ? new TIntArrayList() : Util.findParametersToRemove(method, expressionToRemoveParamFrom);
PsiExpression[] occurences;
if (expr != null) {
occurences = new ExpressionOccurenceManager(expr, method, null).findExpressionOccurrences();
@@ -154,6 +148,11 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
else { // local variable
occurences = CodeInsightUtil.findReferenceExpressions(method, localVar);
}
PsiExpression expressionToRemoveParamFrom = expr;
if (expr == null) {
expressionToRemoveParamFrom = localVar.getInitializer();
}
TIntArrayList parametersToRemove = expressionToRemoveParamFrom == null ? new TIntArrayList() : Util.findParametersToRemove(method, expressionToRemoveParamFrom, occurences);
if (editor != null) {
RefactoringUtil.highlightAllOccurences(myProject, occurences, editor);
}
@@ -37,6 +37,7 @@ import gnu.trove.TIntArrayList;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntIterator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -102,7 +103,9 @@ public class Util {
// returns parameters that are used solely in specified expression
@NotNull
public static TIntArrayList findParametersToRemove(@NotNull PsiMethod method, @NotNull final PsiExpression expr) {
public static TIntArrayList findParametersToRemove(@NotNull PsiMethod method,
@NotNull final PsiExpression expr,
@Nullable final PsiExpression[] occurences) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length == 0) return new TIntArrayList();
@@ -133,7 +136,18 @@ public class Util {
if (!ReferencesSearch.search(parameter, parameter.getResolveScope(), false).forEach(new Processor<PsiReference>() {
public boolean process(final PsiReference reference) {
PsiElement element = reference.getElement();
boolean stillCanBeRemoved = element != null && (PsiTreeUtil.isAncestor(expr, element, false) || PsiUtil.isInsideJavadocComment(element));
boolean stillCanBeRemoved = false;
if (element != null) {
stillCanBeRemoved = PsiTreeUtil.isAncestor(expr, element, false) || PsiUtil.isInsideJavadocComment(element);
if (!stillCanBeRemoved && occurences != null) {
for (PsiExpression occurence : occurences) {
if (PsiTreeUtil.isAncestor(occurence, element, false)) {
stillCanBeRemoved = true;
break;
}
}
}
}
if (!stillCanBeRemoved) {
iterator.remove();
return false;
@@ -22,14 +22,14 @@ import com.intellij.pom.references.PomService;
import com.intellij.psi.PsiElement;
import com.intellij.psi.targets.AliasingPsiTarget;
import com.intellij.psi.targets.AliasingPsiTargetMapper;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
public class RenameAliasingPomTargetProcessor extends RenamePsiElementProcessor {
@Override
public boolean canProcessElement(@Nullable PsiElement element) {
public boolean canProcessElement(@NotNull PsiElement element) {
return element instanceof PomTarget || element instanceof PomTargetPsiElement;
}
@@ -50,7 +50,7 @@ import java.util.regex.Pattern;
public class RenameJavaClassProcessor extends RenamePsiElementProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameJavaClassProcessor");
public boolean canProcessElement(final PsiElement element) {
public boolean canProcessElement(@NotNull final PsiElement element) {
return element instanceof PsiClass;
}
@@ -48,7 +48,7 @@ import java.util.*;
public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameJavaMethodProcessor");
public boolean canProcessElement(final PsiElement element) {
public boolean canProcessElement(@NotNull final PsiElement element) {
return element instanceof PsiMethod;
}
@@ -40,6 +40,7 @@ import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -50,7 +51,7 @@ import java.util.Map;
public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameJavaVariableProcessor");
public boolean canProcessElement(final PsiElement element) {
public boolean canProcessElement(@NotNull final PsiElement element) {
return element instanceof PsiVariable;
}
@@ -33,7 +33,7 @@ import java.util.Collection;
* @author yole
*/
public class RenamePsiDirectoryProcessor extends RenamePsiElementProcessor {
public boolean canProcessElement(final PsiElement element) {
public boolean canProcessElement(@NotNull final PsiElement element) {
return element instanceof PsiDirectory;
}
@@ -26,6 +26,7 @@ import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
@@ -36,7 +37,7 @@ import java.util.Map;
public class RenamePsiPackageProcessor extends RenamePsiElementProcessor {
private final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenamePsiPackageProcessor");
public boolean canProcessElement(final PsiElement element) {
public boolean canProcessElement(@NotNull final PsiElement element) {
return element instanceof PsiPackage;
}
@@ -44,7 +44,7 @@ public class a {
ia[~i | (i+=(!b?2:i))] -= i + 3.3;
// Object += String
o += o + "string";
<error descr="Operator '+' cannot be applied to 'java.lang.Object','java.lang.String'">o += o + "string"</error>;
return 0;
}
@@ -475,6 +475,27 @@ public class Test {
}
}
}
//IDEA-63447
void testUnboundWildcardWithArrayTypes() {
class IUWWAT{
private <T> void method1(T[][] matrix) {
final Class<T[]> type = (Class<T[]>) matrix.getClass().getComponentType();
}
private <T> void method2(T[][] matrix) {
final Class<Object> type = (Class<Object>) matrix.getClass().getComponentType();
}
private <T> void method3(T[][] matrix) {
final Class<Object[]> type = (Class<Object[]>) matrix.getClass().getComponentType();
}
private <T> void method4(T[][] matrix) {
final Class<Object[][]> type = (Class<Object[][]>) matrix.getClass().getComponentType();
}
}
}
}
class W<T> {}
@@ -0,0 +1,10 @@
// "Invert If Condition" "true"
class Test {
public static int create() {
if (true) {
return;
}
return "s";
}
}
@@ -0,0 +1,9 @@
// "Invert If Condition" "true"
class Test {
public static int create() {
if (!tr<caret>ue) {
return "s";
}
}
}
@@ -0,0 +1,4 @@
public class Bar {
void bar() {
}
}
@@ -0,0 +1,2 @@
public class Foo {
}
@@ -0,0 +1,6 @@
import static Foo.foo;
public class Bar {
void bar() {
foo();
}
}
@@ -0,0 +1,3 @@
public class Foo {
public static void foo(){}
}
@@ -0,0 +1,8 @@
class Test {
public Test() {
this(<selection>10</selection>);
}
public Test(final int i) {
}
}
@@ -0,0 +1,10 @@
class Test {
public static final int xxx = 10;
public Test() {
this(xxx);
}
public Test(final int i) {
}
}
@@ -0,0 +1,11 @@
public class Parameters {
public void subject(final int anObject) {
System.out.println(anObject);
System.out.println(anObject);
}
public void context() {
subject(1 +1);
subject(2 +1);
}
}
@@ -0,0 +1,11 @@
public class Parameters {
public void subject(int p) {
System.out.println(<selection>p+1</selection>);
System.out.println(p+1);
}
public void context() {
subject(1);
subject(2);
}
}
@@ -73,6 +73,12 @@ public class IntroduceConstantTest extends LightCodeInsightTestCase {
checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
}
public void testIntroduceConstantFromThisCall() throws Exception {
configureByFile(BASE_PATH + getTestName(false) + ".java");
new MockIntroduceConstantHandler(null).invoke(getProject(), getEditor(), getFile(), null);
checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
}
public void testEscalateVisibility() throws Exception {
configureByFile(BASE_PATH + getTestName(false) + ".java");
final PsiClass[] classes = ((PsiJavaFile)getFile()).getClasses();
@@ -21,6 +21,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.introduceParameter.IntroduceParameterHandler;
import com.intellij.refactoring.introduceParameter.IntroduceParameterProcessor;
import com.intellij.refactoring.introduceParameter.Util;
import com.intellij.refactoring.util.occurences.ExpressionOccurenceManager;
import com.intellij.testFramework.LightCodeInsightTestCase;
import com.intellij.testFramework.TestDataPath;
import gnu.trove.TIntArrayList;
@@ -253,6 +254,10 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, true, true, true, true);
}
public void testReplaceAllAndDeleteUnused() 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() {
@@ -296,8 +301,17 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase {
else {
methodToSearchFor = method;
}
PsiExpression initializer = expr == null ? localVariable.getInitializer() : expr;
TIntArrayList parametersToRemove = removeUnusedParameters ? Util.findParametersToRemove(method, initializer) : new TIntArrayList();
PsiExpression[] occurences = null;
PsiExpression initializer;
if (expr == null) {
initializer = localVariable.getInitializer();
occurences = CodeInsightUtil.findReferenceExpressions(method, localVariable);
}
else {
initializer = expr;
occurences = new ExpressionOccurenceManager(expr, method, null).findExpressionOccurrences();
}
TIntArrayList parametersToRemove = removeUnusedParameters ? Util.findParametersToRemove(method, initializer, occurences) : new TIntArrayList();
new IntroduceParameterProcessor(
getProject(), method, methodToSearchFor, initializer, expr, localVariable, true, parameterName, replaceAllOccurences,
replaceFieldsWithGetters,
@@ -325,7 +339,7 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase {
assertNotNull(methodToSearchFor);
final PsiLocalVariable localVariable = (PsiLocalVariable)element;
final PsiExpression parameterInitializer = localVariable.getInitializer();
TIntArrayList parametersToRemove = removeUnusedParameters ? Util.findParametersToRemove(method, parameterInitializer) : new TIntArrayList();
TIntArrayList parametersToRemove = removeUnusedParameters ? Util.findParametersToRemove(method, parameterInitializer, null) : new TIntArrayList();
new IntroduceParameterProcessor(
getProject(), method, methodToSearchFor,
@@ -0,0 +1,67 @@
/*
* 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.refactoring.inline;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.CodeInsightTestCase;
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.search.ProjectScope;
import com.intellij.refactoring.MockInlineMethodOptions;
import com.intellij.refactoring.util.InlineUtil;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.PsiTestUtil;
import java.io.File;
public class InlineMethodMultifileTest extends CodeInsightTestCase {
private String getRoot() {
return JavaTestUtil.getJavaTestDataPath() + "/refactoring/inlineMethod/multifile/" + getTestName(true);
}
public void testRemoveStaticImports() throws Exception {
doTest("Foo", "foo");
}
private void doTest(String className, String methodName) throws Exception {
String rootBefore = getRoot() + "/before";
PsiTestUtil.removeAllRoots(myModule, JavaSdkImpl.getMockJdk17());
final VirtualFile rootDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, rootBefore, myFilesToDelete);
PsiClass aClass = myJavaFacade.findClass(className, ProjectScope.getAllScope(myProject));
assertTrue(aClass != null);
PsiElement element = aClass.findMethodsByName(methodName, false)[0];
assertTrue(element instanceof PsiMethod);
PsiMethod method = (PsiMethod)element;
final boolean condition = InlineMethodProcessor.checkBadReturns(method) && !InlineUtil.allUsagesAreTailCalls(method);
assertFalse("Bad returns found", condition);
InlineOptions options = new MockInlineMethodOptions();
final InlineMethodProcessor processor = new InlineMethodProcessor(getProject(), method, null, myEditor, options.isInlineThisOnly());
processor.run();
String rootAfter = getRoot() + "/after";
VirtualFile rootDir2 = LocalFileSystem.getInstance().findFileByPath(rootAfter.replace(File.separatorChar, '/'));
myProject.getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
IdeaTestUtil.assertDirectoriesEqual(rootDir2, rootDir, IdeaTestUtil.CVS_FILE_FILTER);
}
}
@@ -196,6 +196,9 @@ public class TypesDistinctProver {
else if (bound instanceof PsiClassType) {
return !possibleClasses.contains(((PsiClassType)bound).resolve());
}
else if (bound instanceof PsiWildcardType && !((PsiWildcardType)bound).isBounded()) {
return false;
}
return true;
}
}
@@ -48,23 +48,14 @@ class ClassFilterEditorAddDialog extends DialogWrapper {
}
protected JComponent createCenterPanel() {
Box box = Box.createVerticalBox();
JPanel _panel = new JPanel(new BorderLayout());
myClassName = new TextFieldWithBrowseButton();
_panel.add(new JLabel(UIBundle.message("label.class.filter.editor.add.dialog.filter.pattern")), BorderLayout.NORTH);
_panel.add(myClassName, BorderLayout.CENTER);
box.add(_panel);
box.add(Box.createVerticalBox());
JPanel panel = new JPanel(new BorderLayout());
panel.setPreferredSize(new Dimension(310, -1));
JLabel iconLabel = new JLabel(Messages.getQuestionIcon());
panel.add(iconLabel, BorderLayout.WEST);
panel.add(box, BorderLayout.CENTER);
final JPanel panel = new JPanel(new GridBagLayout());
final JLabel header = new JLabel(UIBundle.message("label.class.filter.editor.add.dialog.filter.pattern"));
myClassName = new TextFieldWithBrowseButton(new JTextField(35));
final JLabel iconLabel = new JLabel(Messages.getQuestionIcon());
panel.add(header, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 10, 0, 0), 0, 0));
panel.add(myClassName, new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 10, 0, 0), 0, 0));
panel.add(iconLabel, new GridBagConstraints(0, 0, 1, 2, 0.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(15, 0, 0, 0), 0, 0));
myClassName.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
@@ -48,6 +48,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Disposer;
@@ -288,7 +289,9 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
//to initialize caches
myPsiManager.getCacheManager().getFilesWithWord("XXX", UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(myProject), true);
if (!DumbService.isDumb(getProject())) {
myPsiManager.getCacheManager().getFilesWithWord("XXX", UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(myProject), true);
}
final JavaPsiFacadeEx facade = getJavaFacade();
if (facade != null) {
facade.setAssertOnFileLoadingFilter(myFileTreeAccessFilter); // check repository work
@@ -28,7 +28,7 @@ public class LibrariesDownloadAssistant {
private LibrariesDownloadAssistant() {
}
@Nullable
@NotNull
public static Artifact[] getVersions(@NotNull String groupId, @NotNull URL... localUrls) {
final Artifact[] versions = getDownloadServiceVersions(groupId);
return versions == null ? getVersions(localUrls) : versions;
@@ -87,6 +87,22 @@ public interface PsiBuilder extends UserDataHolder, UserDataHolderUnprotected {
@Nullable
IElementType lookAhead(int steps);
/**
* See what token type is in <code>steps</code> ahead / behind
* @param steps 0 is current token (i.e. the same {@link PsiBuilder#getTokenType()} returns)
* @return type element ahead or behind, including whitespace / comment tokens
*/
@Nullable
IElementType rawLookup(int steps);
/**
* See what token type is in <code>steps</code> ahead / behind current position
* @param steps 0 is current token (i.e. the same {@link PsiBuilder#getTokenType()} returns)
* @return offset type element ahead or behind, including whitespace / comment tokens, -1 if first token,
* getOriginalText().getLength() at end
*/
int rawTokenTypeStart(int steps);
/**
* Returns the text of the current token from the lexer.
*
@@ -0,0 +1,49 @@
/*
* 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.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.ui.PathEditor;
import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory;
import com.intellij.openapi.util.IconLoader;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* @author Rustam Vishnyakov
*/
public class DocumentationOrderRootTypeUIFactory implements OrderRootTypeUIFactory {
private static final Icon ICON = IconLoader.getIcon("/nodes/javaDocFolder.png");
@Override
@Nullable
public PathEditor createPathEditor(Sdk sdk) {
return null;
}
@Override
public Icon getIcon() {
return ICON;
}
@Override
public String getNodeText() {
return ProjectBundle.message("library.docs.node");
}
}
@@ -0,0 +1,34 @@
package com.intellij.psi.templateLanguages;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import static com.intellij.psi.TokenType.BAD_CHARACTER;
/**
* @author peter
*/
public class TemplateDataHighlighterWrapper implements SyntaxHighlighter {
private final SyntaxHighlighter myHighlighter;
public TemplateDataHighlighterWrapper(SyntaxHighlighter highlighter) {
myHighlighter = highlighter;
}
@NotNull
public Lexer getHighlightingLexer() {
return myHighlighter.getHighlightingLexer();
}
@NotNull
public TextAttributesKey[] getTokenHighlights(final IElementType tokenType) {
if (tokenType == BAD_CHARACTER) {
return new TextAttributesKey[0];
}
return myHighlighter.getTokenHighlights(tokenType);
}
}
@@ -97,7 +97,10 @@ public class CopyPasteIndentProcessor implements CopyPastePostProcessor<IndentTr
try {
final DataFlavor flavor = IndentTransferableData.getDataFlavorStatic();
if (flavor != null) {
indentData = (IndentTransferableData)content.getTransferData(flavor);
final Object transferData = content.getTransferData(flavor);
if (transferData instanceof IndentTransferableData) {
indentData = (IndentTransferableData)transferData;
}
}
}
catch (UnsupportedFlavorException e) {
@@ -25,7 +25,9 @@ import java.awt.*;
/**
* @author Dmitry Avdeev
* Use {@link com.intellij.codeInsight.lookup.LookupElementBuilder}
*/
@Deprecated
public class LookupValueFactory {
private LookupValueFactory() {
@@ -20,7 +20,9 @@ import com.intellij.psi.PsiElement;
/**
* @author Maxim.Mossienko
* Use {@link com.intellij.codeInsight.lookup.LookupElementBuilder}
*/
@Deprecated
public interface LookupValueWithPsiElement {
PsiElement getElement();
}
@@ -60,10 +60,8 @@ public class ChooseItemReplaceAction extends EditorAction {
return true;
}
if (lookup.isCompletion()) {
lookup.refreshUi(); // to bring the list model up to date
return !lookup.getItems().isEmpty();
}
lookup.refreshUi(); // to bring the list model up to date
return !lookup.getItems().isEmpty();
}
return false;
}
@@ -25,4 +25,9 @@ public class ListTemplatesAction extends BaseCodeInsightAction{
protected CodeInsightActionHandler getHandler() {
return new ListTemplatesHandler();
}
@Override
protected boolean isValidForLookup() {
return true;
}
}
@@ -13,10 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @author max
*/
package com.intellij.lang;
import com.intellij.lexer.Lexer;
@@ -31,78 +27,44 @@ import com.intellij.util.CharTable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/*
* @author max
*/
public abstract class ASTFactory {
public static final DefaultFactory DEFAULT = new DefaultFactory();
private static final CharTable WHITSPACES = new CharTableImpl();
private static final CharTable WHITESPACES = new CharTableImpl();
// interface methods
@Nullable
public abstract CompositeElement createComposite(IElementType type);
@Nullable
public LazyParseableElement createLazy(ILazyParseableElementType type, CharSequence text) {
if (type instanceof IFileElementType) {
return new FileElement(type, text);
}
return new LazyParseableElement(type, text);
public LazyParseableElement createLazy(final ILazyParseableElementType type, final CharSequence text) {
return DEFAULT.createLazy(type, text);
}
@Nullable
public abstract LeafElement createLeaf(IElementType type, CharSequence text);
public abstract CompositeElement createComposite(final IElementType type);
@Nullable
public abstract LeafElement createLeaf(final IElementType type, final CharSequence text);
// factory methods
@NotNull
public static LazyParseableElement lazy(ILazyParseableElementType type, CharSequence text) {
ASTNode node = type.createNode(text);
public static LazyParseableElement lazy(final ILazyParseableElementType type, final CharSequence text) {
final ASTNode node = type.createNode(text);
if (node != null) return (LazyParseableElement)node;
if (type == TokenType.CODE_FRAGMENT) {
return new CodeFragmentElement(null);
}
LazyParseableElement psi = factory(type).createLazy(type, text);
return psi != null ? psi : DEFAULT.createLazy(type, text);
}
@Deprecated
@NotNull
public static LeafElement leaf(IElementType type, CharSequence fileText, int start, int end, CharTable table) {
return leaf(type, table.intern(fileText, start, end));
final LazyParseableElement customLazy = factory(type).createLazy(type, text);
return customLazy != null ? customLazy : DEFAULT.createLazy(type, text);
}
@NotNull
public static LeafElement leaf(IElementType type, CharSequence text) {
if (type == TokenType.WHITE_SPACE) {
return new PsiWhiteSpaceImpl(text);
}
if (type instanceof ILeafElementType) {
return (LeafElement)((ILeafElementType)type).createLeafNode(text);
}
final LeafElement customLeaf = factory(type).createLeaf(type, text);
return customLeaf != null ? customLeaf : DEFAULT.createLeaf(type, text);
}
private static ASTFactory factory(IElementType type) {
return LanguageASTFactory.INSTANCE.forLanguage(type.getLanguage());
}
public static LeafElement whitespace(CharSequence text) {
PsiWhiteSpaceImpl w = new PsiWhiteSpaceImpl(WHITSPACES.intern(text));
CodeEditUtil.setNodeGenerated(w, true);
return w;
}
public static LeafElement leaf(IElementType type, CharSequence text, CharTable table) {
return leaf(type, table.intern(text));
}
public static LeafElement leaf(final Lexer lexer, final CharTable charTable) {
return leaf(lexer.getTokenType(), LexerUtil.internToken(lexer, charTable));
}
@NotNull
public static CompositeElement composite(IElementType type) {
public static CompositeElement composite(final IElementType type) {
if (type instanceof ICompositeElementType) {
return (CompositeElement)((ICompositeElementType)type).createCompositeNode();
}
@@ -115,10 +77,71 @@ public abstract class ASTFactory {
return customComposite != null ? customComposite : DEFAULT.createComposite(type);
}
@NotNull
public static LeafElement leaf(final IElementType type, final CharSequence text) {
if (type == TokenType.WHITE_SPACE) {
return new PsiWhiteSpaceImpl(text);
}
if (type instanceof ILeafElementType) {
return (LeafElement)((ILeafElementType)type).createLeafNode(text);
}
final LeafElement customLeaf = factory(type).createLeaf(type, text);
return customLeaf != null ? customLeaf : DEFAULT.createLeaf(type, text);
}
private static ASTFactory factory(final IElementType type) {
return LanguageASTFactory.INSTANCE.forLanguage(type.getLanguage());
}
@NotNull
public static LeafElement whitespace(final CharSequence text) {
final PsiWhiteSpaceImpl w = new PsiWhiteSpaceImpl(WHITESPACES.intern(text));
CodeEditUtil.setNodeGenerated(w, true);
return w;
}
/**
* @deprecated use {@link #leaf(com.intellij.psi.tree.IElementType, CharSequence)} (to remove in IDEA 11).
*/
@NotNull
public static LeafElement leaf(IElementType type, CharSequence fileText, int start, int end, CharTable table) {
return leaf(type, table.intern(fileText, start, end));
}
/**
* @deprecated use {@link #leaf(com.intellij.psi.tree.IElementType, CharSequence)} (to remove in IDEA 11).
*/
@NotNull
public static LeafElement leaf(IElementType type, CharSequence text, CharTable table) {
return leaf(type, table.intern(text));
}
/**
* @deprecated use {@link #leaf(com.intellij.psi.tree.IElementType, CharSequence)} (to remove in IDEA 11).
*/
@NotNull
public static LeafElement leaf(final Lexer lexer, final CharTable charTable) {
return leaf(lexer.getTokenType(), LexerUtil.internToken(lexer, charTable));
}
// default implementation
private static class DefaultFactory extends ASTFactory {
@Override
@NotNull
public CompositeElement createComposite(IElementType type) {
public LazyParseableElement createLazy(final ILazyParseableElementType type, final CharSequence text) {
if (type instanceof IFileElementType) {
return new FileElement(type, text);
}
return new LazyParseableElement(type, text);
}
@Override
@NotNull
public CompositeElement createComposite(final IElementType type) {
if (type instanceof IFileElementType) {
return new FileElement(type, null);
}
@@ -128,7 +151,7 @@ public abstract class ASTFactory {
@Override
@NotNull
public LeafElement createLeaf(IElementType type, CharSequence text) {
public LeafElement createLeaf(final IElementType type, final CharSequence text) {
final Language lang = type.getLanguage();
final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
if (parserDefinition != null) {
@@ -14,15 +14,15 @@
* limitations under the License.
*/
package com.intellij.lang;
/*
* @author max
*/
package com.intellij.lang;
public class LanguageASTFactory extends LanguageExtension<ASTFactory> {
public static final LanguageASTFactory INSTANCE = new LanguageASTFactory();
private LanguageASTFactory() {
super("com.intellij.lang.ast.factory", ASTFactory.DEFAULT);
}
}
}
@@ -623,6 +623,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
int cur = myCurrentLexeme;
while (steps > 0) {
++cur;
while (cur < myLexemeCount && whitespaceOrComment(myLexTypes[cur])) {
cur++;
}
@@ -633,6 +634,20 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
return cur < myLexemeCount ? myLexTypes[cur] : null;
}
@Override
public IElementType rawLookup(int steps) {
int cur = myCurrentLexeme + steps;
return cur < myLexemeCount && cur >= 0 ? myLexTypes[cur] : null;
}
@Override
public int rawTokenTypeStart(int steps) {
int cur = myCurrentLexeme + steps;
if (cur < 0) return -1;
if (cur >= myLexemeCount) return getOriginalText().length();
return myLexStarts[cur];
}
@Override
public void setWhitespaceSkippedCallback(WhitespaceSkippedCallback callback) {
myWhitespaceSkippedCallback = callback;
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.indexing.IndexableSetContributor;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
@@ -34,15 +35,13 @@ import java.util.Set;
*/
public abstract class ScriptingIndexableSetContributor extends IndexableSetContributor {
@NotNull
@Override
public Set<VirtualFile> getAdditionalRootsToIndex(@Nullable Project project) {
final Set<VirtualFile> predefinedFiles = getPredefinedFilesToIndex();
final THashSet<VirtualFile> filesToIndex = new THashSet<VirtualFile>();
filesToIndex.addAll(predefinedFiles);
filesToIndex.addAll(getLibraryFiles(project));
return filesToIndex;
public Set<VirtualFile> getAdditionalProjectRootsToIndex(@Nullable Project project) {
return getLibraryFiles(project);
}
@NotNull
public Set<VirtualFile> getLibraryFiles(Project project) {
final THashSet<VirtualFile> libFiles = new THashSet<VirtualFile>();
LibraryType libType = getLibraryType();
@@ -67,8 +66,8 @@ public abstract class ScriptingIndexableSetContributor extends IndexableSetContr
}
@Override
public Set<VirtualFile> getAdditionalRootsToIndex() {
return getAdditionalRootsToIndex(null);
public final Set<VirtualFile> getAdditionalRootsToIndex() {
return getPredefinedFilesToIndex();
}
public abstract Set<VirtualFile> getPredefinedFilesToIndex();
@@ -849,7 +849,7 @@ public class SingleInspectionProfilePanel extends JPanel {
}
public Dimension getPreferredSize() {
return new Dimension(700, -1);
return new Dimension(700, 500);
}
public void disposeUI() {
@@ -18,11 +18,9 @@ package com.intellij.psi.impl.file.impl;
import com.intellij.AppTopics;
import com.intellij.ProjectTopics;
import com.intellij.extapi.psi.PsiFileBase;
import com.intellij.injected.editor.DocumentWindow;
import com.intellij.injected.editor.VirtualFileWindow;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -1083,12 +1081,8 @@ public class FileManagerImpl implements FileManager {
}
// When file is renamed so that extension changes then language dialect might change and thus psiFile should be invalidated
// We could detect it right now with checks of parser definition equivalence
// The file name under passed psi file is "new" but parser def is from old name
private static boolean languageDialectChanged(final PsiFile newPsiFile, String oldFileName) {
return newPsiFile instanceof PsiFileBase
&& LanguageParserDefinitions.INSTANCE.forLanguage(newPsiFile.getLanguage()).getClass() == ((PsiFileBase)newPsiFile).getParserDefinition().getClass()
&& !FileUtil.getExtension(newPsiFile.getName()).equals(FileUtil.getExtension(oldFileName));
return newPsiFile != null && !FileUtil.getExtension(newPsiFile.getName()).equals(FileUtil.getExtension(oldFileName));
}
private class MyModuleRootListener implements ModuleRootListener {
@@ -87,6 +87,14 @@ public class PsiElementRenameHandler implements RenameHandler {
static boolean canRename(Project project, Editor editor, PsiElement element) {
if (element == null) return false;
if (!(element instanceof PsiFile) && CollectHighlightsUtil.isOutsideSourceRootJavaFile(element.getContainingFile())) return false;
if (!element.isWritable()) {
String message = RefactoringBundle.getCannotRefactorMessage("This element cannot be renamed.");
showErrorMessage(project, editor, message);
return false;
}
boolean hasRenameProcessor = RenamePsiElementProcessor.forElement(element) != RenamePsiElementProcessor.DEFAULT;
boolean hasWritableMetaData = element instanceof PsiMetaOwner && ((PsiMetaOwner)element).getMetaData() instanceof PsiWritableMetaData;
@@ -114,7 +114,7 @@ public class RenameProcessor extends BaseRefactoringProcessor {
super.doRun();
}
public void prepareRenaming(final PsiElement element, final String newName, final LinkedHashMap<PsiElement, String> allRenames) {
public void prepareRenaming(@NotNull final PsiElement element, final String newName, final LinkedHashMap<PsiElement, String> allRenames) {
final List<RenamePsiElementProcessor> processors = RenamePsiElementProcessor.allForElement(element);
myForceShowPreview = false;
for (RenamePsiElementProcessor processor : processors) {
@@ -46,7 +46,7 @@ import java.util.Map;
public abstract class RenamePsiElementProcessor {
private static final ExtensionPointName<RenamePsiElementProcessor> EP_NAME = ExtensionPointName.create("com.intellij.renamePsiElementProcessor");
public abstract boolean canProcessElement(@Nullable PsiElement element);
public abstract boolean canProcessElement(@NotNull PsiElement element);
public RenameDialog createRenameDialog(Project project, PsiElement element, PsiElement nameSuggestionContext, Editor editor) {
return new RenameDialog(project, element, nameSuggestionContext, editor);
@@ -85,7 +85,7 @@ public abstract class RenamePsiElementProcessor {
public void findExistingNameConflicts(final PsiElement element, final String newName, final MultiMap<PsiElement,String> conflicts) {
}
public static List<RenamePsiElementProcessor> allForElement(PsiElement element) {
public static List<RenamePsiElementProcessor> allForElement(@NotNull PsiElement element) {
final List<RenamePsiElementProcessor> result = new ArrayList<RenamePsiElementProcessor>();
for (RenamePsiElementProcessor processor : EP_NAME.getExtensions()) {
if (processor.canProcessElement(element)) {
@@ -96,7 +96,7 @@ public abstract class RenamePsiElementProcessor {
}
@NotNull
public static RenamePsiElementProcessor forElement(PsiElement element) {
public static RenamePsiElementProcessor forElement(@NotNull PsiElement element) {
for(RenamePsiElementProcessor processor: Extensions.getExtensions(EP_NAME)) {
if (processor.canProcessElement(element)) {
return processor;
@@ -161,7 +161,7 @@ public abstract class RenamePsiElementProcessor {
}
public static final RenamePsiElementProcessor DEFAULT = new RenamePsiElementProcessor() {
public boolean canProcessElement(final PsiElement element) {
public boolean canProcessElement(@NotNull final PsiElement element) {
return true;
}
};
@@ -32,7 +32,7 @@ import java.util.Collections;
*/
public class RenamePsiFileProcessor extends RenamePsiElementProcessor {
@Override
public boolean canProcessElement(@Nullable PsiElement element) {
public boolean canProcessElement(@NotNull PsiElement element) {
return element instanceof PsiFile;
}
@@ -1912,7 +1912,12 @@ public class FileBasedIndex implements ApplicationComponent {
if (project.isDisposed()) {
return;
}
for (VirtualFile root : IndexableSetContributor.getRootsToIndex(provider, project)) {
for (VirtualFile root : IndexableSetContributor.getRootsToIndex(provider)) {
if (visitedRoots.add(root)) {
iterateRecursively(root, processor, indicator);
}
}
for (VirtualFile root : IndexableSetContributor.getProjectRootsToIndex(provider, project)) {
if (visitedRoots.add(root)) {
iterateRecursively(root, processor, indicator);
}
@@ -5,9 +5,11 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.NotNullFunction;
import com.intellij.util.containers.ContainerUtil;
import org.apache.commons.collections.SetUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -15,6 +17,9 @@ import java.util.Set;
* @author peter
*/
public abstract class IndexableSetContributor implements IndexedRootsProvider {
protected static final Set<VirtualFile> EMPTY_FILE_SET = Collections.unmodifiableSet(new HashSet<VirtualFile>());
@Override
public final Set<String> getRootsToIndex() {
return ContainerUtil.map2Set(getAdditionalRootsToIndex(), new NotNullFunction<VirtualFile, String>() {
@@ -26,13 +31,17 @@ public abstract class IndexableSetContributor implements IndexedRootsProvider {
});
}
public static Set<VirtualFile> getRootsToIndex(IndexedRootsProvider provider) {
return getRootsToIndex(provider, null);
@NotNull
public static Set<VirtualFile> getProjectRootsToIndex(IndexedRootsProvider provider, Project project) {
if (provider instanceof IndexableSetContributor) {
return ((IndexableSetContributor)provider).getAdditionalProjectRootsToIndex(project);
}
return EMPTY_FILE_SET;
}
public static Set<VirtualFile> getRootsToIndex(IndexedRootsProvider provider, @Nullable Project project) {
public static Set<VirtualFile> getRootsToIndex(IndexedRootsProvider provider) {
if (provider instanceof IndexableSetContributor) {
return ((IndexableSetContributor)provider).getAdditionalRootsToIndex(project);
return ((IndexableSetContributor)provider).getAdditionalRootsToIndex();
}
final HashSet<VirtualFile> result = new HashSet<VirtualFile>();
@@ -43,8 +52,9 @@ public abstract class IndexableSetContributor implements IndexedRootsProvider {
return result;
}
public Set<VirtualFile> getAdditionalRootsToIndex(@Nullable Project project) {
return getAdditionalRootsToIndex();
@NotNull
public Set<VirtualFile> getAdditionalProjectRootsToIndex(@Nullable Project project) {
return EMPTY_FILE_SET;
}
public abstract Set<VirtualFile> getAdditionalRootsToIndex();
@@ -17,6 +17,9 @@ package com.intellij.codeHighlighting;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.util.Comparing;
import com.intellij.util.ImageLoader;
import com.intellij.util.containers.HashMap;
@@ -30,9 +33,9 @@ public class HighlightDisplayLevel {
private static final Map<HighlightSeverity, HighlightDisplayLevel> ourMap = new HashMap<HighlightSeverity, HighlightDisplayLevel>();
public static final HighlightDisplayLevel GENERIC_SERVER_ERROR_OR_WARNING = new HighlightDisplayLevel(HighlightSeverity.GENERIC_SERVER_ERROR_OR_WARNING,
createIconByMask(CodeInsightColors.GENERIC_SERVER_ERROR_OR_WARNING.getDefaultAttributes().getErrorStripeColor()));
public static final HighlightDisplayLevel ERROR = new HighlightDisplayLevel(HighlightSeverity.ERROR, createIconByMask(CodeInsightColors.ERRORS_ATTRIBUTES.getDefaultAttributes().getErrorStripeColor()));
public static final HighlightDisplayLevel WARNING = new HighlightDisplayLevel(HighlightSeverity.WARNING, createIconByMask(CodeInsightColors.WARNINGS_ATTRIBUTES.getDefaultAttributes().getErrorStripeColor()));
createIconByMask(CodeInsightColors.GENERIC_SERVER_ERROR_OR_WARNING));
public static final HighlightDisplayLevel ERROR = new HighlightDisplayLevel(HighlightSeverity.ERROR, createIconByMask(CodeInsightColors.ERRORS_ATTRIBUTES));
public static final HighlightDisplayLevel WARNING = new HighlightDisplayLevel(HighlightSeverity.WARNING, createIconByMask(CodeInsightColors.WARNINGS_ATTRIBUTES));
public static final HighlightDisplayLevel DO_NOT_SHOW = new HighlightDisplayLevel(HighlightSeverity.INFORMATION, createIconByMask(new Color(30, 160, 0)));
public static final HighlightDisplayLevel INFO = new HighlightDisplayLevel(HighlightSeverity.INFO, DO_NOT_SHOW.getIcon());
@@ -89,6 +92,17 @@ public class HighlightDisplayLevel {
}
private static final int EMPTY_ICON_DIM = 12;
public static Icon createIconByMask(TextAttributesKey key) {
final EditorColorsManager manager = EditorColorsManager.getInstance();
if (manager != null) {
final EditorColorsScheme globalScheme = manager.getGlobalScheme();
return createIconByMask(globalScheme.getAttributes(key).getErrorStripeColor());
}
return createIconByMask(key.getDefaultAttributes().getErrorStripeColor());
}
public static Icon createIconByMask(final Color renderColor) {
return new Icon() {
public void paintIcon(Component c, Graphics g, int x, int y) {
@@ -84,7 +84,10 @@ public class BaseTableView extends Table {
}
index = 0;
for (final String columnIndex : columnIndices) {
columnModel.moveColumn(indexbyModelIndex(columnModel, Integer.parseInt(columnIndex)), index);
final int modelColumnIndex = indexbyModelIndex(columnModel, Integer.parseInt(columnIndex));
if (modelColumnIndex > 0 && modelColumnIndex < columnModel.getColumnCount()) {
columnModel.moveColumn(modelColumnIndex, index);
}
index++;
}
for (int i = 0; i < columnIndices.size(); i++) {
@@ -39,7 +39,6 @@ import com.intellij.util.Alarm;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -49,7 +48,6 @@ import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
@@ -131,6 +129,7 @@ public class IdeEventQueue extends EventQueue {
private final Set<Runnable> myReady = new HashSet<Runnable>();
private boolean myKeyboardBusy;
private boolean myDispatchingFocusEvent;
private static class IdeEventQueueHolder {
private static final IdeEventQueue INSTANCE = new IdeEventQueue();
@@ -649,6 +648,7 @@ public class IdeEventQueue extends EventQueue {
private void defaultDispatchEvent(final AWTEvent e) {
try {
myDispatchingFocusEvent = e instanceof FocusEvent;
super.dispatchEvent(e);
}
catch (ProcessCanceledException pce) {
@@ -658,9 +658,15 @@ public class IdeEventQueue extends EventQueue {
if (!myToolkitBugsProcessor.process(exc)) {
LOG.error("Error during dispatching of " + e, exc);
}
} finally {
myDispatchingFocusEvent = false;
}
}
public boolean isDispatchingFocusEvent() {
return myDispatchingFocusEvent;
}
private static boolean typeAheadDispatchToFocusManager(AWTEvent e) {
if (e instanceof KeyEvent) {
final KeyEvent event = (KeyEvent)e;
@@ -787,7 +793,7 @@ public class IdeEventQueue extends EventQueue {
return peekEvent(FocusEvent.FOCUS_GAINED) != null || peekEvent(FocusEvent.FOCUS_LOST) != null;
}
private boolean isReady() {
public boolean isReady() {
return !myKeyboardBusy && myKeyEventDispatcher.isReady();
}
@@ -118,7 +118,7 @@ public class CreateLauncherScriptAction extends AnAction {
String launcherContents = FileUtil.loadTextAndClose(new InputStreamReader(stream));
launcherContents = launcherContents.replace("$CONFIG_PATH$", PathManager.getConfigPath());
String homePath = PathManager.getHomePath().replace(" ", "\\ ");
String homePath = PathManager.getHomePath();
String productName = ApplicationNamesInfo.getInstance().getProductName().toLowerCase();
if (SystemInfo.isMac) {
launcherContents = launcherContents.replace("$RUN_PATH$", homePath + "/Contents/MacOS/" + productName);
@@ -25,6 +25,7 @@ import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -41,6 +42,7 @@ import java.util.List;
*/
public class PluginManagerConfigurable extends BaseConfigurable implements SearchableConfigurable {
@NonNls private static final String POSTPONE = "&Postpone";
public boolean EXPANDED = false;
public String FIND = "";
public boolean TREE_VIEW = false;
@@ -172,15 +174,13 @@ public class PluginManagerConfigurable extends BaseConfigurable implements Searc
private static int showShutDownIDEADialog() {
String message = IdeBundle.message("message.idea.shutdown.required", ApplicationNamesInfo.getInstance().getProductName());
String title = IdeBundle.message("title.plugins.changed");
String cancel = IdeBundle.message("button.cancel");
return Messages.showDialog(message, title, new String[]{"Shut Down", cancel},0,0,Messages.getQuestionIcon());
return Messages.showDialog(message, title, new String[]{"Shut Down", POSTPONE},0,0,Messages.getQuestionIcon());
}
public static int showRestartIDEADialog() {
String message = IdeBundle.message("message.idea.restart.required", ApplicationNamesInfo.getInstance().getProductName());
String title = IdeBundle.message("title.plugins.changed");
String cancel = IdeBundle.message("button.cancel");
return Messages.showDialog(message, title, new String[]{"Restart", cancel},0,0,Messages.getQuestionIcon());
return Messages.showDialog(message, title, new String[]{"Restart", POSTPONE},0,0,Messages.getQuestionIcon());
}
public boolean isModified() {
@@ -39,8 +39,8 @@ import com.intellij.util.io.storage.HeavyProcessLatch;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import java.lang.reflect.InvocationHandler;
@@ -79,6 +79,17 @@ public class DumbServiceImpl extends DumbService {
return myDumb;
}
@TestOnly
public void setDumb(boolean dumb) {
if (dumb) {
myDumb = true;
myPublisher.enteredDumbMode();
}
else {
updateFinished();
}
}
@Override
public void runWhenSmart(Runnable runnable) {
if (!isDumb()) {
@@ -159,7 +170,7 @@ public class DumbServiceImpl extends DumbService {
final IndexUpdateRunnable updateRunnable = new IndexUpdateRunnable(runner);
invokeOnEDT(new DumbAwareRunnable() {
UIUtil.invokeLaterIfNeeded(new DumbAwareRunnable() {
public void run() {
if (myProject.isDisposed()) {
return;
@@ -185,15 +196,6 @@ public class DumbServiceImpl extends DumbService {
});
}
private static void invokeOnEDT(DumbAwareRunnable runnable) {
if (ApplicationManager.getApplication().isDispatchThread()) {
runnable.run();
}
else {
SwingUtilities.invokeLater(runnable);
}
}
private void updateFinished() {
myDumb = false;
myPublisher.exitDumbMode();
@@ -359,7 +361,7 @@ public class DumbServiceImpl extends DumbService {
}
finally {
myProcessedItems += count;
invokeOnEDT(new DumbAwareRunnable() {
UIUtil.invokeLaterIfNeeded(new DumbAwareRunnable() {
public void run() {
if (myUpdatesQueue.isEmpty()) {
// really terminate the task
@@ -11,12 +11,12 @@
<component id="bc72e" class="javax.swing.JEditorPane" binding="myEditorPane">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="2" hsize-policy="2" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="150" height="50"/>
<preferred-size width="250" height="70"/>
</grid>
</constraints>
<properties>
<contentType value="text/html"/>
<text value="&lt;html&gt;&#13;&#10; &lt;head&gt;&#13;&#10; &#13;&#10; &lt;/head&gt;&#13;&#10; &lt;body&gt;&#13;&#10; &lt;/body&gt;&#13;&#10;&lt;/html&gt;&#13;&#10;"/>
<text value="&lt;html&gt;&#13;&#10; &lt;head&gt;&#13;&#10;&#13;&#10; &lt;/head&gt;&#13;&#10; &lt;body&gt;&#13;&#10; &lt;p style=&quot;margin-top: 0&quot;&gt;&#13;&#10; &#13;&#10; &lt;/p&gt;&#13;&#10; &lt;/body&gt;&#13;&#10;&lt;/html&gt;&#13;&#10;"/>
</properties>
</component>
<grid id="71b5" binding="myWholePluginsPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -85,7 +85,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
private boolean myFlushWasDelayedToFixFocus;
private boolean canFlushIdleRequests() {
return isFocusTransferReady() && !isIdleQueueEmpty();
return isFocusTransferReady() && !isIdleQueueEmpty() && !IdeEventQueue.getInstance().isDispatchingFocusEvent();
}
private final Map<IdeFrame, WeakReference<Component>> myLastFocused = new HashMap<IdeFrame, WeakReference<Component>>();
@@ -5,7 +5,7 @@
<td>You can quickly find a setting you need in the Settings dialog, without browsing through the numerous options.
Just type some characters that to your opinion exist in the option description, and the list of settings will reduce to the
matching ones. Select the desired entry, and see the setting that contains the entered characters highlighted:
<p><img hspace="20" src="../../../../resources-en/src/tips/images/search_settings.png"></p>
<p><img hspace="20" src="images/search_settings.png"></p>
</td>
</tr>
</table>
@@ -25,7 +25,10 @@ import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.impl.*;
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass;
import com.intellij.codeInsight.folding.impl.CodeFoldingManagerImpl;
import com.intellij.codeInsight.highlighting.actions.HighlightUsagesAction;
import com.intellij.codeInsight.intention.IntentionAction;
@@ -70,7 +73,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.DumbServiceImpl;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
@@ -1307,9 +1310,10 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
}
public static void ensureIndexesUpToDate(Project project) {
FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, null);
FileBasedIndex.getInstance().ensureUpToDate(TodoIndex.NAME, project, null);
assertTrue(!DumbServiceImpl.getInstance(project).isDumb());
if (!DumbService.isDumb(project)) {
FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, null);
FileBasedIndex.getInstance().ensureUpToDate(TodoIndex.NAME, project, null);
}
}
@Override
@@ -32,6 +32,7 @@ import com.intellij.openapi.vcs.diff.RevisionSelector;
import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vcs.history.VcsHistoryProvider;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.impl.IllegalStateProxy;
import com.intellij.openapi.vcs.merge.MergeProvider;
import com.intellij.openapi.vcs.rollback.RollbackEnvironment;
import com.intellij.openapi.vcs.update.UpdateEnvironment;
@@ -61,6 +62,10 @@ public abstract class AbstractVcs<ComList extends CommittedChangeList> extends S
private VcsShowSettingOption myUpdateOption;
private VcsShowSettingOption myStatusOption;
private CheckinEnvironment myCheckinEnvironment;
private UpdateEnvironment myUpdateEnvironment;
private RollbackEnvironment myRollbackEnvironment;
public AbstractVcs(final Project project, final String name) {
super(project);
@@ -124,23 +129,43 @@ public abstract class AbstractVcs<ComList extends CommittedChangeList> extends S
}
/**
* creates the object for performing checkin / commit / submit operations.
*/
@Nullable
protected CheckinEnvironment createCheckinEnvironment() {
return IllegalStateProxy.create(CheckinEnvironment.class);
}
/**
* !!! concrete VCS should define {@link #createCheckinEnvironment} method
* this method wraps created environment with a listener
*
* Returns the interface for performing checkin / commit / submit operations.
*
* @return the checkin interface, or null if checkins are not supported by the VCS.
*/
@Nullable
public CheckinEnvironment getCheckinEnvironment() {
return null;
return myCheckinEnvironment;
}
/**
* Returns the interface for performing revert / rollback operations.
*/
@Nullable
protected RollbackEnvironment createRollbackEnvironment() {
return IllegalStateProxy.create(RollbackEnvironment.class);
}
/**
* !!! concrete VCS should define {@link #createRollbackEnvironment()} method
* this method wraps created environment with a listener
*
* @return the rollback interface, or null if rollbacks are not supported by the VCS.
*/
@Nullable
public RollbackEnvironment getRollbackEnvironment() {
return null;
return myRollbackEnvironment;
}
@Nullable
@@ -159,12 +184,21 @@ public abstract class AbstractVcs<ComList extends CommittedChangeList> extends S
/**
* Returns the interface for performing update/sync operations.
*/
@Nullable
protected UpdateEnvironment createUpdateEnvironment() {
return IllegalStateProxy.create(UpdateEnvironment.class);
}
/**
* !!! concrete VCS should define {@link #createUpdateEnvironment()} method
* this method wraps created environment with a listener
*
* @return the update interface, or null if the updates are not supported by the VCS.
*/
@Nullable
public UpdateEnvironment getUpdateEnvironment() {
return null;
return myUpdateEnvironment;
}
/**
@@ -494,5 +528,20 @@ public abstract class AbstractVcs<ComList extends CommittedChangeList> extends S
@CalledInAwt
public void generalPreConfigurationStep() {
}
public void setCheckinEnvironment(CheckinEnvironment checkinEnvironment) {
if (myCheckinEnvironment != null) throw new IllegalStateException("Attempt to redefine checkin environment");
myCheckinEnvironment = checkinEnvironment;
}
public void setUpdateEnvironment(UpdateEnvironment updateEnvironment) {
if (myUpdateEnvironment != null) throw new IllegalStateException("Attempt to redefine update environment");
myUpdateEnvironment = updateEnvironment;
}
public void setRollbackEnvironment(RollbackEnvironment rollbackEnvironment) {
if (myRollbackEnvironment != null) throw new IllegalStateException("Attempt to redefine rollback environment");
myRollbackEnvironment = rollbackEnvironment;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
* 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.
@@ -13,9 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.telemetry;
package com.intellij.openapi.vcs;
public interface InspectionRunListener{
void reportRun(String inspectionID, long runTime);
import com.intellij.openapi.util.Pair;
import com.intellij.util.Consumer;
/**
* @author irengrig
* Date: 12/21/10
* Time: 2:15 PM
*/
public class ForwardingListener<T> implements Consumer<Pair<VcsKey, Consumer<T>>> {
private final T myT;
public ForwardingListener(T t) {
myT = t;
}
@Override
public void consume(Pair<VcsKey, Consumer<T>> vcsKeyConsumerPair) {
vcsKeyConsumerPair.getSecond().consume(myT);
}
}
@@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vcs.checkin.CheckinHandlerFactory;
import com.intellij.openapi.vcs.impl.VcsDescriptor;
import com.intellij.openapi.vcs.impl.VcsEnvironmentsProxyCreator;
import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Processor;
@@ -275,4 +276,7 @@ public abstract class ProjectLevelVcsManager {
public abstract CheckoutProvider.Listener getCompositeCheckoutListener();
public static Topic<VcsListener> VCS_CONFIGURATION_CHANGED = Topic.create("VCS configuration changed", VcsListener.class);
public abstract VcsEventsListenerManager getVcsEventsListenerManager();
protected abstract VcsEnvironmentsProxyCreator getProxyCreator();
}
@@ -0,0 +1,57 @@
/*
* 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.openapi.vcs;
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vcs.impl.IllegalStateProxy;
import com.intellij.openapi.vcs.impl.VcsEnvironmentsProxyCreator;
import com.intellij.openapi.vcs.rollback.RollbackEnvironment;
import com.intellij.openapi.vcs.update.UpdateEnvironment;
/**
* @author irengrig
* Date: 12/17/10
* Time: 12:46 PM
*/
public class VcsActiveEnvironmentsProxy {
private VcsActiveEnvironmentsProxy() {
}
public static AbstractVcs proxyVcs(final AbstractVcs vcs) {
final ProjectLevelVcsManager manager = ProjectLevelVcsManager.getInstance(vcs.getProject());
final VcsEnvironmentsProxyCreator proxyCreator = manager.getProxyCreator();
if (proxyCreator == null) return vcs;
final VcsKey key = vcs.getKeyInstanceMethod();
final CheckinEnvironment checkinEnvironment = vcs.createCheckinEnvironment();
final UpdateEnvironment updateEnvironment = vcs.createUpdateEnvironment();
final RollbackEnvironment rollbackEnvironment = vcs.createRollbackEnvironment();
if (checkinEnvironment != null && checkinEnvironment.equals(IllegalStateProxy.IDENTITY) ||
updateEnvironment != null && updateEnvironment.equals(IllegalStateProxy.IDENTITY) ||
rollbackEnvironment != null && rollbackEnvironment.equals(IllegalStateProxy.IDENTITY)) {
return vcs;
} else {
final CheckinEnvironment proxedCheckin = proxyCreator.proxyCheckin(key, checkinEnvironment);
final UpdateEnvironment proxedUpdate = proxyCreator.proxyUpdate(key, updateEnvironment);
final RollbackEnvironment proxedRollback = proxyCreator.proxyRollback(key, rollbackEnvironment);
vcs.setCheckinEnvironment(proxedCheckin);
vcs.setUpdateEnvironment(proxedUpdate);
vcs.setRollbackEnvironment(proxedRollback);
return vcs;
}
}
}
@@ -0,0 +1,37 @@
/*
* 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.openapi.vcs;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vcs.rollback.RollbackEnvironment;
import com.intellij.openapi.vcs.update.UpdateEnvironment;
import com.intellij.util.Consumer;
/**
* @author irengrig
* Date: 12/15/10
* Time: 5:42 PM
*/
public interface VcsEventsListenerManager {
void removeCheckin(final Object key);
void removeUpdate(final Object key);
void removeRollback(final Object key);
Object addCheckin(Consumer<Pair<VcsKey, Consumer<CheckinEnvironment>>> consumer);
Object addUpdate(Consumer<Pair<VcsKey, Consumer<UpdateEnvironment>>> consumer);
Object addRollback(Consumer<Pair<VcsKey, Consumer<RollbackEnvironment>>> consumer);
}
@@ -0,0 +1,46 @@
/*
* 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.openapi.vcs.impl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author irengrig
* Date: 12/17/10
* Time: 2:21 PM
*/
public class IllegalStateProxy {
public static final Object IDENTITY = new Object();
private static final InvocationHandler HANDLER = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("equals".equals(method.getName())) {
return IDENTITY.equals(args[0]);
}
throw new IllegalStateException();
}
};
private IllegalStateProxy() {
}
public static<T> T create(final Class<T> clazz) {
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, HANDLER);
}
}
@@ -0,0 +1,38 @@
/*
* 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.openapi.vcs.impl;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vcs.rollback.RollbackEnvironment;
import com.intellij.openapi.vcs.update.UpdateEnvironment;
import org.jetbrains.annotations.Nullable;
/**
* @author irengrig
* Date: 12/17/10
* Time: 5:34 PM
*/
public interface VcsEnvironmentsProxyCreator {
@Nullable
CheckinEnvironment proxyCheckin(VcsKey key, CheckinEnvironment environment);
@Nullable
UpdateEnvironment proxyUpdate(VcsKey key, UpdateEnvironment environment);
@Nullable
RollbackEnvironment proxyRollback(VcsKey key, RollbackEnvironment environment);
}
@@ -232,7 +232,7 @@ public class ChangeListWorker implements ChangeListsWriteOperations {
}
public boolean addChangeToList(@NotNull final String name, final Change change, final VcsKey vcsKey) {
LOG.debug("[addChangeToList] name: " + name + " change: " + ChangesUtil.getFilePath(change).getPath() + " vcs: " +
LOG.info("[addChangeToList] name: " + name + " change: " + ChangesUtil.getFilePath(change).getPath() + " vcs: " +
(vcsKey == null ? null : vcsKey.getName()));
final LocalChangeList changeList = myMap.get(name);
if (changeList != null) {
@@ -243,16 +243,16 @@ public class ChangeListWorker implements ChangeListsWriteOperations {
}
public void addChangeToCorrespondingList(final Change change, final VcsKey vcsKey) {
final String path = LOG.isDebugEnabled() ? ChangesUtil.getFilePath(change).getPath() : "";
LOG.debug("[addChangeToCorrespondingList] for change " + path + " type: " + change.getType() + " have before revision: " + (change.getBeforeRevision() != null));
final String path = ChangesUtil.getFilePath(change).getPath();
LOG.info("[addChangeToCorrespondingList] for change " + path + " type: " + change.getType() + " have before revision: " + (change.getBeforeRevision() != null));
assert myDefault != null;
for (LocalChangeList list : myMap.values()) {
if (list.isDefault()) {
LOG.debug("[addChangeToCorrespondingList] skip default list: " + list.getName() + " type: " + change.getType() + " have before revision: " + (change.getBeforeRevision() != null));
LOG.info("[addChangeToCorrespondingList] skip default list: " + list.getName() + " type: " + change.getType() + " have before revision: " + (change.getBeforeRevision() != null));
continue;
}
if (((LocalChangeListImpl) list).processChange(change)) {
LOG.debug("[addChangeToCorrespondingList] matched: " + list.getName() + " type: " + change.getType() + " have before revision: " + (change.getBeforeRevision() != null));
LOG.info("[addChangeToCorrespondingList] matched: " + list.getName() + " type: " + change.getType() + " have before revision: " + (change.getBeforeRevision() != null));
myIdx.changeAdded(change, vcsKey);
return;
}
@@ -66,11 +66,11 @@ class UpdatingChangeListBuilder implements ChangelistBuilder {
public void processChangeInList(final Change change, @Nullable final ChangeList changeList, final VcsKey vcsKey) {
checkIfDisposed();
LOG.debug("[processChangeInList-1] entering, cl name: " + ((changeList == null) ? null: changeList.getName()) +
LOG.info("[processChangeInList-1] entering, cl name: " + ((changeList == null) ? null: changeList.getName()) +
" change: " + ChangesUtil.getFilePath(change).getPath());
final String fileName = ChangesUtil.getFilePath(change).getName();
if (FileTypeManager.getInstance().isFileIgnored(fileName)) {
LOG.debug("[processChangeInList-1] file type ignored");
LOG.info("[processChangeInList-1] file type ignored");
return;
}
@@ -78,14 +78,14 @@ class UpdatingChangeListBuilder implements ChangelistBuilder {
public void run() {
if (ChangeListManagerImpl.isUnder(change, myScope)) {
if (changeList != null) {
LOG.debug("[processChangeInList-1] to add change to cl");
LOG.info("[processChangeInList-1] to add change to cl");
myChangeListWorker.addChangeToList(changeList.getName(), change, vcsKey);
} else {
LOG.debug("[processChangeInList-1] to add to corresponding list");
LOG.info("[processChangeInList-1] to add to corresponding list");
myChangeListWorker.addChangeToCorrespondingList(change, vcsKey);
}
} else {
LOG.debug("[processChangeInList-1] not under scope");
LOG.info("[processChangeInList-1] not under scope");
}
}
});
@@ -50,4 +50,4 @@ public abstract class ProjectLevelVcsManagerEx extends ProjectLevelVcsManager {
public abstract void fireDirectoryMappingsChanged();
public abstract String haveDefaultMapping();
}
}
@@ -53,7 +53,6 @@ import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.ui.content.ContentManager;
import com.intellij.util.ContentsUtil;
import com.intellij.util.EventDispatcher;
import com.intellij.util.Icons;
import com.intellij.util.Processor;
import com.intellij.util.containers.Convertor;
@@ -105,6 +104,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme
private final Map<VcsBackgroundableActions, BackgroundableActionEnabledHandler> myBackgroundableActionHandlerMap;
private final List<Pair<String, TextAttributes>> myPendingOutput = new ArrayList<Pair<String, TextAttributes>>();
private VcsEventsListenerManagerImpl myVcsEventListenerManager;
public ProjectLevelVcsManagerImpl(Project project, final FileStatusManager manager, MessageBus messageBus) {
myProject = project;
@@ -118,6 +118,10 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme
myInitialization = new VcsInitialization(myProject);
myMappings = new NewMappings(myProject, myMessageBus, this, manager);
myMappingsToRoots = new MappingsToRoots(myMappings, myProject);
if (! myProject.isDefault()) {
myVcsEventListenerManager = new VcsEventsListenerManagerImpl();
}
}
public void initComponent() {
@@ -660,6 +664,11 @@ public void addMessageToConsoleWindow(final String message, final TextAttributes
return new CompositeCheckoutListener(myProject);
}
@Override
public VcsEventsListenerManager getVcsEventsListenerManager() {
return myVcsEventListenerManager;
}
public void fireDirectoryMappingsChanged() {
if (myProject.isOpen() && (! myProject.isDisposed())) {
myMappings.mappingsChanged();
@@ -670,6 +679,11 @@ public void addMessageToConsoleWindow(final String message, final TextAttributes
return myMappings.haveDefaultMapping();
}
@Override
protected VcsEnvironmentsProxyCreator getProxyCreator() {
return myVcsEventListenerManager;
}
public BackgroundableActionEnabledHandler getBackgroundableActionHandler(final VcsBackgroundableActions action) {
ApplicationManager.getApplication().assertIsDispatchThread();
@@ -23,6 +23,7 @@ import com.intellij.openapi.extensions.AbstractExtensionPointBean;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.VcsActiveEnvironmentsProxy;
import com.intellij.util.xmlb.annotations.Attribute;
/**
@@ -56,7 +57,7 @@ public class VcsEP extends AbstractExtensionPointBean {
return myVcs;
}
}
myVcs = instantiate(vcsClass, project.getPicoContainer());
myVcs = VcsActiveEnvironmentsProxy.proxyVcs((AbstractVcs)instantiate(vcsClass, project.getPicoContainer()));
}
catch(Exception e) {
LOG.error(e);
@@ -69,4 +70,4 @@ public class VcsEP extends AbstractExtensionPointBean {
public VcsDescriptor createDescriptor() {
return new VcsDescriptor(administrativeAreaName, displayName, name);
}
}
}
@@ -0,0 +1,197 @@
/*
* 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.openapi.vcs.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.VcsEventsListenerManager;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vcs.rollback.RollbackEnvironment;
import com.intellij.openapi.vcs.update.UpdateEnvironment;
import com.intellij.util.Consumer;
import com.intellij.util.EventDispatcher;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.EventListener;
import java.util.HashMap;
import java.util.Map;
/**
* @author irengrig
* Date: 12/15/10
* Time: 5:50 PM
*/
public class VcsEventsListenerManagerImpl implements VcsEventsListenerManager, VcsEnvironmentsProxyCreator {
private final Wrapper<CheckinEnvironment> myCheckinWrapper;
private final Wrapper<UpdateEnvironment> myUpdateWrapper;
private final Wrapper<RollbackEnvironment> myRollbackWrapper;
public VcsEventsListenerManagerImpl() {
myCheckinWrapper = new Wrapper<CheckinEnvironment>(CheckinEnvironment.class);
myUpdateWrapper = new Wrapper<UpdateEnvironment>(UpdateEnvironment.class);
myRollbackWrapper = new Wrapper<RollbackEnvironment>(RollbackEnvironment.class);
}
@Override
public Object addCheckin(final Consumer<Pair<VcsKey, Consumer<CheckinEnvironment>>> consumer) {
return myCheckinWrapper.add(consumer);
}
@Override
public Object addUpdate(final Consumer<Pair<VcsKey, Consumer<UpdateEnvironment>>> consumer) {
return myUpdateWrapper.add(consumer);
}
@Override
public Object addRollback(final Consumer<Pair<VcsKey, Consumer<RollbackEnvironment>>> consumer) {
return myRollbackWrapper.add(consumer);
}
@Override
public void removeCheckin(Object key) {
myCheckinWrapper.remove(key);
}
@Override
public void removeUpdate(Object key) {
myUpdateWrapper.remove(key);
}
@Override
public void removeRollback(Object key) {
myRollbackWrapper.remove(key);
}
@Nullable
@Override
public CheckinEnvironment proxyCheckin(final VcsKey key, final CheckinEnvironment environment) {
return myCheckinWrapper.createProxy(key, environment);
}
@Nullable
@Override
public UpdateEnvironment proxyUpdate(final VcsKey key, final UpdateEnvironment environment) {
return myUpdateWrapper.createProxy(key, environment);
}
@Nullable
@Override
public RollbackEnvironment proxyRollback(final VcsKey key, final RollbackEnvironment environment) {
return myRollbackWrapper.createProxy(key, environment);
}
private static class Wrapper<T> {
private final Map<Object, EventListenerWrapperI> myListenersMap;
private final Map<VcsKey, EventDispatcher<EventListenerWrapperI>> myExistingMulticasters;
private final Class<T> myClazz;
private final Object myLock;
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.impl.VcsEventsListenerManagerImpl.Wrapper");
private Wrapper(final Class<T> clazz) {
myClazz = clazz;
myListenersMap = new HashMap<Object, EventListenerWrapperI>();
myExistingMulticasters = Collections.synchronizedMap(new HashMap<VcsKey, EventDispatcher<EventListenerWrapperI>>());
myLock = new Object();
}
@Nullable
public T createProxy(final VcsKey key, @Nullable final T environment) {
if (environment == null) return null;
final EventDispatcher<EventListenerWrapperI> eventDispatcher;
synchronized (myLock) {
assert ! myExistingMulticasters.containsKey(key);
eventDispatcher = EventDispatcher.create(EventListenerWrapperI.class);
myExistingMulticasters.put(key, eventDispatcher);
for (EventListenerWrapperI wrapper : myListenersMap.values()) {
eventDispatcher.addListener(wrapper);
}
}
final T proxy = (T) Proxy.newProxyInstance(myClazz.getClassLoader(),
new Class[]{myClazz},
new InvocationHandler() {
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
method.setAccessible(true);
synchronized (myLock) {
eventDispatcher.getMulticaster().consume(
new Pair<VcsKey, Consumer<T>>(key, new Consumer<T>() {
@Override
public void consume(T t) {
try {
method.invoke(t, args);
}
catch (IllegalAccessException e) {
LOG.info(e);
}
catch (InvocationTargetException e) {
LOG.info(e);
}
}
}));
}
return method.invoke(environment, args);
}
});
return proxy;
}
public Object add(final Consumer<Pair<VcsKey,Consumer<T>>> consumer) {
final Object key = new Object();
synchronized (myLock) {
EventListenerWrapper<T> listenerWrapper = new EventListenerWrapper<T>(consumer);
myListenersMap.put(key, listenerWrapper);
for (EventDispatcher<EventListenerWrapperI> eventDispatcher : myExistingMulticasters.values()) {
eventDispatcher.addListener(listenerWrapper);
}
}
return key;
}
public void remove(Object key) {
synchronized (myLock) {
final EventListenerWrapperI listenerWrapper = myListenersMap.remove(key);
if (listenerWrapper != null) {
for (EventDispatcher<EventListenerWrapperI> dispatcher : myExistingMulticasters.values()) {
dispatcher.removeListener(listenerWrapper);
}
}
}
}
private interface EventListenerWrapperI<T> extends Consumer<Pair<VcsKey, Consumer<T>>>, EventListener {}
private static class EventListenerWrapper<T> implements EventListenerWrapperI<T> {
private final Consumer<Pair<VcsKey, Consumer<T>>> myConsumer;
public EventListenerWrapper(Consumer<Pair<VcsKey, Consumer<T>>> consumer) {
myConsumer = consumer;
}
@Override
public void consume(Pair<VcsKey, Consumer<T>> vcsKeyConsumerPair) {
myConsumer.consume(vcsKeyConsumerPair);
}
}
}
}
@@ -203,10 +203,10 @@ public.method.without.logging.display.name='public' method without logging
public.method.without.logging.problem.descriptor='public' method <code>#ref</code> has no logging statement #loc
action.reset.telemetry.description=Reset telemetry data
telemetry.table.column.inspection.name=Inspection Name
telemetry.table.column.total.time=Total Run Time (msecs)
telemetry.table.column.average.time=Average Run Time (msecs)
telemetry.table.column.run.count=Total Run Count
telemetry.table.column.inspection.name=Inspection
telemetry.table.column.total.time=Total Run Time (ms)
telemetry.table.column.average.time=Average Run Time (ms)
telemetry.table.column.run.count=Run Count
telemetry.toolwindow.title=IG Telemetry
action.telemetry.refresh.description=Refresh telemetry display
finalize.doesnt.call.super.display.name='finalize()' does not call 'super.finalize()'
@@ -535,7 +535,7 @@ public class ImportUtils{
PsiTreeUtil.getParentOfType(context, PsiClass.class);
if (InheritanceUtil.isCorrectDescendant(containingClass, memberClass,
true)) {
return true;
return false;
}
final PsiFile psiFile = context.getContainingFile();
if (!(psiFile instanceof PsiJavaFile)) {
@@ -15,85 +15,39 @@
*/
package com.siyeh.ig.telemetry;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
public class InspectionGadgetsTelemetry implements InspectionRunListener {
public class InspectionGadgetsTelemetry {
private final Map<String, Integer> totalRunCount =
new HashMap<String, Integer>(400);
private final Map<String, Long> totalRunTime =
new HashMap<String, Long>(400);
private final Object lock = new Object();
private final ConcurrentHashMap<String, InspectionRunTime> inspectionRunTimes =
new ConcurrentHashMap();
public List<InspectionRunTime> buildList() {
if (inspectionRunTimes.isEmpty()) {
return Collections.EMPTY_LIST;
}
return new ArrayList(inspectionRunTimes.values());
}
public void reportRun(String inspectionID, long runTime) {
synchronized (lock) {
final Integer count = totalRunCount.get(inspectionID);
if (count == null) {
totalRunCount.put(inspectionID, Integer.valueOf(1));
} else {
totalRunCount.put(inspectionID,
Integer.valueOf(count.intValue() + 1));
}
final Long runTimeSoFar = totalRunTime.get(inspectionID);
if (runTimeSoFar == null) {
totalRunTime.put(inspectionID, Long.valueOf(runTime));
} else {
totalRunTime.put(inspectionID,
Long.valueOf(runTimeSoFar.longValue() + runTime));
InspectionRunTime inspectionRunTime =
inspectionRunTimes.get(inspectionID);
if (inspectionRunTime == null) {
inspectionRunTime = new InspectionRunTime(inspectionID);
final InspectionRunTime oldValue =
inspectionRunTimes.putIfAbsent(inspectionID,
inspectionRunTime);
if (oldValue != null) {
inspectionRunTime = oldValue;
}
}
inspectionRunTime.addRunTime(runTime);
}
public void reset() {
synchronized (lock) {
totalRunCount.clear();
totalRunTime.clear();
}
}
public long getRunTimeForInspection(String inspectionID) {
synchronized (lock) {
final Long runTime = totalRunTime.get(inspectionID);
if (runTime == null) {
return 0L;
}
return runTime.longValue();
}
}
public int getRunCountForInspection(String inspectionID) {
synchronized (lock) {
final Integer runCount = totalRunCount.get(inspectionID);
if (runCount == null) {
return 0;
}
return runCount.intValue();
}
}
public String[] getInspections() {
synchronized (lock) {
final Set<String> inspections = totalRunCount.keySet();
final int numInspections = inspections.size();
final String[] inspectionArray =
inspections.toArray(new String[numInspections]);
Arrays.sort(inspectionArray);
return inspectionArray;
}
}
public double getAverageRunTimeForInspection(String inspectionID) {
synchronized (lock) {
final Integer runCount = totalRunCount.get(inspectionID);
if (runCount == null) {
return 0.0;
}
final Long runTime = totalRunTime.get(inspectionID);
return (double)runTime / (double)runCount;
}
inspectionRunTimes.clear();
}
}
@@ -0,0 +1,57 @@
/*
* Copyright 2010 Bas Leijdekkers
*
* 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.telemetry;
public class InspectionRunTime {
private final String inspectionName;
private long totalRunTime = 0L;
private int runCount = 0;
public InspectionRunTime(String inspectionName) {
this.inspectionName = inspectionName;
}
public void addRunTime(long runTime) {
synchronized (this) {
totalRunTime += runTime;
runCount++;
}
}
public double getAverageRunTime() {
synchronized (this) {
return (double) totalRunTime / (double) runCount;
}
}
public String getInspectionName() {
return inspectionName;
}
public int getRunCount() {
synchronized (this) {
return runCount;
}
}
public long getTotalRunTime() {
synchronized (this) {
return totalRunTime;
}
}
}
@@ -27,7 +27,7 @@ class ResetTelemetryAction extends AnAction{
private final TelemetryDisplay display;
ResetTelemetryAction(InspectionGadgetsTelemetry telemetry,
TelemetryDisplay display){
TelemetryDisplay display){
super(CommonBundle.message("button.reset"),
InspectionGadgetsBundle.message(
"action.reset.telemetry.description"),
@@ -39,6 +39,6 @@ class ResetTelemetryAction extends AnAction{
@Override
public void actionPerformed(AnActionEvent event){
telemetry.reset();
display.update();
display.update(telemetry.buildList());
}
}
@@ -1,485 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.telemetry;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.*;
/**
* TableSorter is a decorator for TableModels; adding sorting
* functionality to a supplied TableModel. TableSorter does
* not store or copy the data in its TableModel; instead it maintains
* a map from the row indexes of the view to the row indexes of the
* model. As requests are made of the sorter (like getValueAt(row, col))
* they are passed to the underlying model after the row numbers
* have been translated via the internal mapping array. This way,
* the TableSorter appears to hold another copy of the table
* with the rows in a different order.
* <p/>
* TableSorter registers itself as a listener to the underlying model,
* just as the JTable itself would. Events recieved from the model
* are examined, sometimes manipulated (typically widened), and then
* passed on to the TableSorter's listeners (typically the JTable).
* If a change to the model has invalidated the order of TableSorter's
* rows, a note of this is made and the sorter will resort the
* rows the next time a value is requested.
* <p/>
* When the tableHeader property is set, either by using the
* setTableHeader() method or the two argument constructor, the
* table header may be used as a complete UI for TableSorter.
* The default renderer of the tableHeader is decorated with a renderer
* that indicates the sorting status of each column. In addition,
* a mouse listener is installed with the following behavior:
* <ul>
* <li>
* Mouse-click: Clears the sorting status of all other columns
* and advances the sorting status of that column through three
* values: {NOT_SORTED, ASCENDING, DESCENDING} (then back to
* NOT_SORTED again).
* <li>
* SHIFT-mouse-click: Clears the sorting status of all other columns
* and cycles the sorting status of the column through the same
* three values, in the opposite order: {NOT_SORTED, DESCENDING, ASCENDING}.
* <li>
* CONTROL-mouse-click and CONTROL-SHIFT-mouse-click: as above except
* that the changes to the column do not cancel the statuses of columns
* that are already sorting - giving a way to initiate a compound
* sort.
* </ul>
* <p/>
* This is a long overdue rewrite of a class of the same name that
* first appeared in the swing table demos in 1997.
*
* @author Philip Milne
* @author Brendon McLean
* @author Dan van Enckevort
* @author Parwinder Sekhon
* @version 2.0 02/27/04
*/
public class TableSorter extends AbstractTableModel {
protected TableModel tableModel = null;
public static final int DESCENDING = -1;
public static final int NOT_SORTED = 0;
public static final int ASCENDING = 1;
private static final Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);
public static final Comparator<Comparable> COMPARABLE_COMPARATOR = new Comparator<Comparable>() {
public int compare(Comparable c1, Comparable c2) {
return c1.compareTo(c2);
}
};
public static final Comparator LEXICAL_COMPARATOR = new Comparator() {
public int compare(Object o1, Object o2) {
return o1.toString().compareTo(o2.toString());
}
};
private Row[] viewToModel = null;
int[] modelToView = null;
private JTableHeader tableHeader = null;
private MouseListener mouseListener;
private TableModelListener tableModelListener;
private final Map<Class, Comparator> columnComparators = new HashMap();
List<Directive> sortingColumns = new ArrayList();
public TableSorter() {
mouseListener = new MouseHandler();
tableModelListener = new TableModelHandler();
}
public TableSorter(TableModel tableModel) {
this();
setTableModel(tableModel);
}
public TableSorter(TableModel tableModel, JTableHeader tableHeader) {
this();
setTableHeader(tableHeader);
setTableModel(tableModel);
}
void clearSortingState() {
viewToModel = null;
modelToView = null;
}
public TableModel getTableModel() {
return tableModel;
}
public void setTableModel(TableModel tableModel) {
if (this.tableModel != null) {
this.tableModel.removeTableModelListener(tableModelListener);
}
this.tableModel = tableModel;
if (this.tableModel != null) {
this.tableModel.addTableModelListener(tableModelListener);
}
clearSortingState();
fireTableStructureChanged();
}
public JTableHeader getTableHeader() {
return tableHeader;
}
public void setTableHeader(JTableHeader tableHeader) {
if (this.tableHeader != null) {
this.tableHeader.removeMouseListener(mouseListener);
final TableCellRenderer defaultRenderer =
this.tableHeader.getDefaultRenderer();
if (defaultRenderer instanceof SortableHeaderRenderer) {
final TableCellRenderer tableCellRenderer =
((SortableHeaderRenderer)defaultRenderer).tableCellRenderer;
this.tableHeader.setDefaultRenderer(tableCellRenderer);
}
}
this.tableHeader = tableHeader;
if (this.tableHeader != null) {
this.tableHeader.addMouseListener(mouseListener);
this.tableHeader.setDefaultRenderer(
new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));
}
}
public boolean isSorting() {
return sortingColumns.size() != 0;
}
private Directive getDirective(int column) {
for (Directive directive : sortingColumns) {
if (directive.column == column) {
return directive;
}
}
return EMPTY_DIRECTIVE;
}
public int getSortingStatus(int column) {
return getDirective(column).direction;
}
private void sortingStatusChanged() {
clearSortingState();
fireTableDataChanged();
if (tableHeader != null) {
tableHeader.repaint();
}
}
public void setSortingStatus(int column, int status) {
final Directive directive = getDirective(column);
if (directive != EMPTY_DIRECTIVE) {
sortingColumns.remove(directive);
}
if (status != NOT_SORTED) {
sortingColumns.add(new Directive(column, status));
}
sortingStatusChanged();
}
protected Icon getHeaderRendererIcon(int column, int size) {
final Directive directive = getDirective(column);
final int index = sortingColumns.indexOf(directive);
if (index >= 0 && index == sortingColumns.size() - 1) {
return new Arrow(directive.direction == DESCENDING, size);
} else {
return null;
}
}
void cancelSorting() {
sortingColumns.clear();
sortingStatusChanged();
}
public void setColumnComparator(Class type, Comparator comparator) {
if (comparator == null) {
columnComparators.remove(type);
} else {
columnComparators.put(type, comparator);
}
}
protected Comparator getComparator(int column) {
final Class columnType = tableModel.getColumnClass(column);
final Comparator comparator = columnComparators.get(columnType);
if (comparator != null) {
return comparator;
}
if (Comparable.class.isAssignableFrom(columnType)) {
return COMPARABLE_COMPARATOR;
}
return LEXICAL_COMPARATOR;
}
private Row[] getViewToModel() {
if (viewToModel == null ||
viewToModel.length != tableModel.getRowCount()) {
final int tableModelRowCount = tableModel.getRowCount();
viewToModel = new Row[tableModelRowCount];
for (int row = 0; row < tableModelRowCount; row++) {
viewToModel[row] = new Row(row);
}
if (isSorting()) {
Arrays.sort(viewToModel);
}
}
return viewToModel;
}
public int modelIndex(int viewIndex) {
return getViewToModel()[viewIndex].modelIndex;
}
int[] getModelToView() {
if (modelToView == null) {
final int n = getViewToModel().length;
modelToView = new int[n];
for (int i = 0; i < n; i++) {
modelToView[modelIndex(i)] = i;
}
}
return modelToView;
}
// TableModel interface methods
public int getRowCount() {
if (tableModel == null) {
return 0;
} else {
return tableModel.getRowCount();
}
}
public int getColumnCount() {
if (tableModel == null) {
return 0;
} else {
return tableModel.getColumnCount();
}
}
public String getColumnName(int column) {
return tableModel.getColumnName(column);
}
public Class getColumnClass(int column) {
return tableModel.getColumnClass(column);
}
public boolean isCellEditable(int row, int column) {
return tableModel.isCellEditable(modelIndex(row), column);
}
public Object getValueAt(int row, int column) {
return tableModel.getValueAt(modelIndex(row), column);
}
public void setValueAt(Object aValue, int row, int column) {
tableModel.setValueAt(aValue, modelIndex(row), column);
}
// Helper classes
private class Row implements Comparable {
int modelIndex;
Row(int index) {
modelIndex = index;
}
public int compareTo(Object o) {
final int row1 = modelIndex;
final int row2 = ((Row) o).modelIndex;
for (Directive directive : sortingColumns) {
final int column = directive.column;
final Object o1 = tableModel.getValueAt(row1, column);
final Object o2 = tableModel.getValueAt(row2, column);
final int comparison;
// Define null less than everything, except null.
if (o1 == null && o2 == null) {
comparison = 0;
} else if (o1 == null) {
comparison = -1;
} else if (o2 == null) {
comparison = 1;
} else {
final Comparator comparator = getComparator(column);
comparison = comparator.compare(o1, o2);
}
if (comparison != 0) {
if (directive.direction == DESCENDING) {
return -comparison;
} else {
return comparison;
}
}
}
return 0;
}
}
private class TableModelHandler implements TableModelListener {
public void tableChanged(TableModelEvent e) {
// If we're not sorting by anything, just pass the event along.
if (!isSorting()) {
clearSortingState();
fireTableChanged(e);
return;
}
// If the table structure has changed, cancel the sorting; the
// sorting columns may have been either moved or deleted from
// the model.
if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
cancelSorting();
fireTableChanged(e);
return;
}
// Something has happened to the data that may have invalidated the row order.
clearSortingState();
fireTableDataChanged();
}
}
private class MouseHandler extends MouseAdapter {
public void mouseClicked(MouseEvent event) {
final JTableHeader header = (JTableHeader) event.getSource();
final TableColumnModel columnModel = header.getColumnModel();
final int viewColumn = columnModel.getColumnIndexAtX(event.getX());
final TableColumn column = columnModel.getColumn(viewColumn);
final int columnIndex = column.getModelIndex();
if (columnIndex != -1) {
int status = getSortingStatus(columnIndex);
// Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or
// {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed.
if (status == ASCENDING) {
status = DESCENDING;
} else {
status = ASCENDING;
}
setSortingStatus(columnIndex, status);
}
}
}
private static class Arrow implements Icon {
private final boolean descending;
private final int size;
Arrow(boolean descending, int size) {
this.descending = descending;
this.size = size;
}
public void paintIcon(Component component, Graphics g, int x, int y) {
final Color color;
if (component == null) {
color = Color.GRAY;
} else {
color = component.getBackground();
}
final int dx = size - 2;
final int dy;
if (descending) {
dy = dx - 2;
} else {
dy = -(dx - 3);
}
// Align icon (roughly) with font baseline.
y += 4 * size / 6;
if (descending) {
y += -dy;
}
g.translate(x, y);
g.setColor(color.darker());
g.fillPolygon(new int[]{dx >> 1, 0, dx}, new int[]{0, dy, dy}, 3);
g.setColor(color);
g.translate(-x, -y);
}
public int getIconWidth() {
return size;
}
public int getIconHeight() {
return size;
}
}
private class SortableHeaderRenderer implements TableCellRenderer {
TableCellRenderer tableCellRenderer;
SortableHeaderRenderer(TableCellRenderer tableCellRenderer) {
this.tableCellRenderer = tableCellRenderer;
}
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
final Component component =
tableCellRenderer.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
if (component instanceof JLabel) {
final JLabel label = (JLabel) component;
label.setHorizontalTextPosition(JLabel.LEADING);
final int modelColumn = table.convertColumnIndexToModel(column);
final Font font = label.getFont();
label.setIcon(getHeaderRendererIcon(modelColumn, font.getSize()));
}
return component;
}
}
private static class Directive {
int column;
int direction;
Directive(int column, int direction) {
this.column = column;
this.direction = direction;
}
}
}
@@ -16,31 +16,153 @@
package com.siyeh.ig.telemetry;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.TableSpeedSearch;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
import com.siyeh.InspectionGadgetsBundle;
import javax.swing.*;
import javax.swing.table.JTableHeader;
import java.text.NumberFormat;
import java.util.Comparator;
import java.util.List;
public class TelemetryDisplay {
private final JTable table;
private final JScrollPane scrollPane;
private final TableSorter model;
private final ListTableModel<InspectionRunTime> tableModel;
public TelemetryDisplay(InspectionGadgetsTelemetry telemetry){
model = new TableSorter(new TelemetryTableModel(telemetry));
table = new JBTable(model);
final JTableHeader tableHeader = table.getTableHeader();
model.setTableHeader(tableHeader);
tableModel = new ListTableModel<InspectionRunTime>(createColumns(),
telemetry.buildList(), 0);
final JTable table = new JBTable(tableModel);
new TableSpeedSearch(table);
scrollPane = ScrollPaneFactory.createScrollPane(table);
}
private static ColumnInfo[] createColumns() {
final Comparator<InspectionRunTime> nameComparator =
new Comparator<InspectionRunTime>() {
public int compare(InspectionRunTime runTime1,
InspectionRunTime runTime2) {
return runTime1.getInspectionName().compareToIgnoreCase(
runTime2.getInspectionName());
}
};
final Comparator<InspectionRunTime> runCountComparator =
new Comparator<InspectionRunTime>() {
public int compare(InspectionRunTime runTime1,
InspectionRunTime runTime2) {
return runTime1.getRunCount() - runTime2.getRunCount();
}
};
final Comparator<InspectionRunTime> totalRunTimeComparator =
new Comparator<InspectionRunTime>() {
public int compare(InspectionRunTime runTime1,
InspectionRunTime runTime2) {
final long totalRunTime1 = runTime1.getTotalRunTime();
final long totalRunTime2 = runTime2.getTotalRunTime();
if (totalRunTime1 < totalRunTime2) {
return -1;
} else if (totalRunTime1 > totalRunTime2) {
return 1;
} else {
return 0;
}
}
};
final Comparator<InspectionRunTime> averageRunTimeComparator =
new Comparator<InspectionRunTime>() {
public int compare(InspectionRunTime runTime1,
InspectionRunTime runTime2) {
final double averageRunTime1 =
runTime1.getAverageRunTime();
final double averageRunTime2 =
runTime2.getAverageRunTime();
if (averageRunTime1 < averageRunTime2) {
return -1;
} else if (averageRunTime1 > averageRunTime2) {
return 1;
} else {
return 0;
}
}
};
return new ColumnInfo[] {
new ColumnInfo<InspectionRunTime, String>(
InspectionGadgetsBundle.message(
"telemetry.table.column.inspection.name")) {
@Override
public String valueOf(InspectionRunTime inspectionRunTime) {
return inspectionRunTime.getInspectionName();
}
@Override
public Comparator<InspectionRunTime> getComparator() {
return nameComparator;
}
},
new ColumnInfo<InspectionRunTime, Integer>(
InspectionGadgetsBundle.message(
"telemetry.table.column.run.count")) {
@Override
public Integer valueOf(
InspectionRunTime inspectionRunTime) {
return Integer.valueOf(inspectionRunTime.getRunCount());
}
@Override
public Comparator<InspectionRunTime> getComparator() {
return runCountComparator;
}
},
new ColumnInfo<InspectionRunTime, Long>(
InspectionGadgetsBundle.message(
"telemetry.table.column.total.time")) {
@Override
public Long valueOf(InspectionRunTime inspectionRunTime) {
return Long.valueOf(
inspectionRunTime.getTotalRunTime());
}
@Override
public Comparator<InspectionRunTime> getComparator() {
return totalRunTimeComparator;
}
},
new ColumnInfo<InspectionRunTime, String>(
InspectionGadgetsBundle.message(
"telemetry.table.column.average.time")) {
private final NumberFormat format =
NumberFormat.getNumberInstance();
{
format.setMaximumFractionDigits(2);
format.setMinimumFractionDigits(2);
}
@Override
public String valueOf(InspectionRunTime inspectionRunTime) {
return format.format(inspectionRunTime.getAverageRunTime());
}
@Override
public Comparator<InspectionRunTime> getComparator() {
return averageRunTimeComparator;
}
}
};
}
public JComponent getContentPane(){
return scrollPane;
}
public void update(){
table.setModel(model);
table.repaint();
public void update(List<InspectionRunTime> inspectionRunTimes){
tableModel.setItems(inspectionRunTimes);
}
}
@@ -1,120 +0,0 @@
/*
* Copyright 2003-2010 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.
* 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.telemetry;
import org.jetbrains.annotations.Nullable;
import javax.swing.table.DefaultTableModel;
import java.text.NumberFormat;
import com.siyeh.InspectionGadgetsBundle;
class TelemetryTableModel extends DefaultTableModel {
private final InspectionGadgetsTelemetry telemetry;
private final NumberFormat format = NumberFormat.getNumberInstance();
TelemetryTableModel(InspectionGadgetsTelemetry telemetry) {
this.telemetry = telemetry;
format.setMaximumFractionDigits(2);
format.setMinimumFractionDigits(2);
}
@Override
public int getColumnCount() {
return 4;
}
@Override
@Nullable
public Class getColumnClass(int column) {
switch (column) {
case 0:
return String.class;
case 1:
return Long.class;
case 2:
return String.class;
case 3:
return Integer.class;
default:
return null;
}
}
@Override
public int getRowCount() {
if (telemetry == null) {
return 0;
}
return telemetry.getInspections().length;
}
@Override
@Nullable
public Object getValueAt(int row, int column) {
if (telemetry == null) {
return null;
}
final String[] inspections = telemetry.getInspections();
final String inspection = inspections[row];
switch (column) {
case 0:
return inspection;
case 1:
final long totalRunTime =
telemetry.getRunTimeForInspection(inspection);
return Long.valueOf(totalRunTime);
case 2:
final double averageRunTime =
telemetry.getAverageRunTimeForInspection(inspection);
return format.format(averageRunTime);
case 3:
final int runCount =
telemetry.getRunCountForInspection(inspection);
return Integer.valueOf(runCount);
default:
return null;
}
}
@Override
public void setValueAt(Object object, int i,
int i1) {
//don't do anything
}
@Override
@Nullable
public String getColumnName(int column) {
switch (column) {
case 0:
return InspectionGadgetsBundle.message(
"telemetry.table.column.inspection.name");
case 1:
return InspectionGadgetsBundle.message(
"telemetry.table.column.total.time");
case 2:
return InspectionGadgetsBundle.message(
"telemetry.table.column.average.time");
case 3:
return InspectionGadgetsBundle.message(
"telemetry.table.column.run.count");
default:
return null;
}
}
}
@@ -42,7 +42,8 @@ public class TelemetryToolWindow {
final TelemetryDisplay telemetryDisplay =
new TelemetryDisplay(telemetry);
final DefaultActionGroup toolbarGroup = new DefaultActionGroup();
toolbarGroup.add(new UpdateTelemetryViewAction(telemetryDisplay));
toolbarGroup.add(
new UpdateTelemetryViewAction(telemetry, telemetryDisplay));
toolbarGroup.add(new ResetTelemetryAction(telemetry, telemetryDisplay));
final ActionManager actionManager = ActionManager.getInstance();
final ActionToolbar toolbar =
@@ -23,18 +23,21 @@ import com.siyeh.InspectionGadgetsBundle;
class UpdateTelemetryViewAction extends AnAction{
private final InspectionGadgetsTelemetry telemetry;
private final TelemetryDisplay telemetryDisplay;
UpdateTelemetryViewAction(TelemetryDisplay telemetryDisplay){
UpdateTelemetryViewAction(InspectionGadgetsTelemetry telemetry,
TelemetryDisplay telemetryDisplay){
super(CommonBundle.message("action.refresh"),
InspectionGadgetsBundle.message(
"action.telemetry.refresh.description"),
IconLoader.getIcon("/actions/sync.png"));
this.telemetry = telemetry;
this.telemetryDisplay = telemetryDisplay;
}
@Override
public void actionPerformed(AnActionEvent event){
telemetryDisplay.update();
telemetryDisplay.update(telemetry.buildList());
}
}
@@ -47,6 +47,7 @@ import org.jetbrains.android.resourceManagers.LocalResourceManager;
import org.jetbrains.android.resourceManagers.ResourceManager;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidResourceUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -62,7 +63,7 @@ public class AndroidRenameResourceProcessor extends RenamePsiElementProcessor {
// for tests
public static volatile boolean ASK = true;
public boolean canProcessElement(final PsiElement element) {
public boolean canProcessElement(@NotNull final PsiElement element) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
public Boolean compute() {
if (element instanceof PsiFile) {

Some files were not shown because too many files have changed in this diff Show More