show usages from generated code in separate group (IDEA-97579)

This commit is contained in:
nik
2013-11-11 10:02:52 +04:00
parent 034f42b8dd
commit b8df146aba
14 changed files with 189 additions and 62 deletions
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2013 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;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class JavaGeneratedSourcesFilter extends GeneratedSourcesFilter {
@Override
public boolean isGeneratedSource(@NotNull VirtualFile file, @NotNull Project project) {
return JavaProjectRootsUtil.isInGeneratedCode(file, project);
}
}
@@ -38,8 +38,7 @@ public class JavaProjectRootsUtil {
for (Module module : ModuleManager.getInstance(project).getModules()) {
for (ContentEntry entry : ModuleRootManager.getInstance(module).getContentEntries()) {
for (SourceFolder sourceFolder : entry.getSourceFolders(JavaModuleSourceRootTypes.SOURCES)) {
JavaSourceRootProperties properties = sourceFolder.getJpsElement().getProperties(JavaModuleSourceRootTypes.SOURCES);
if (properties != null && !properties.isForGeneratedSources()) {
if (!isForGeneratedSources(sourceFolder)) {
ContainerUtil.addIfNotNull(roots, sourceFolder.getFile());
}
}
@@ -47,4 +46,27 @@ public class JavaProjectRootsUtil {
}
return roots;
}
private static boolean isForGeneratedSources(SourceFolder sourceFolder) {
JavaSourceRootProperties properties = sourceFolder.getJpsElement().getProperties(JavaModuleSourceRootTypes.SOURCES);
return properties != null && properties.isForGeneratedSources();
}
public static boolean isInGeneratedCode(@NotNull VirtualFile file, @NotNull Project project) {
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
Module module = fileIndex.getModuleForFile(file);
if (module == null) return false;
VirtualFile sourceRoot = fileIndex.getSourceRootForFile(file);
if (sourceRoot == null) return false;
for (ContentEntry entry : ModuleRootManager.getInstance(module).getContentEntries()) {
for (SourceFolder folder : entry.getSourceFolders()) {
if (sourceRoot.equals(folder.getFile())) {
return isForGeneratedSources(folder);
}
}
}
return false;
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2013 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;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public abstract class GeneratedSourcesFilter {
public static final ExtensionPointName<GeneratedSourcesFilter> EP_NAME = ExtensionPointName.create("com.intellij.generatedSourcesFilter");
public abstract boolean isGeneratedSource(@NotNull VirtualFile file, @NotNull Project project);
}
@@ -1651,6 +1651,7 @@ public abstract class ChooseByNameBase {
final String prefixPattern = myFindUsagesTitle + " \'" + myTextField.getText().trim() + "\'";
final String nonPrefixPattern = myFindUsagesTitle + " \'*" + myTextField.getText().trim() + "*\'";
presentation.setCodeUsagesString(prefixPattern);
presentation.setUsagesInGeneratedCodeString(prefixPattern + " in generated code");
presentation.setDynamicUsagesString(nonPrefixPattern);
presentation.setTabName(prefixPattern);
presentation.setTabText(prefixPattern);
@@ -22,7 +22,6 @@ import com.intellij.history.LocalHistoryAction;
import com.intellij.ide.DataManager;
import com.intellij.lang.Language;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.UndoConfirmationPolicy;
@@ -370,6 +369,7 @@ public abstract class BaseRefactoringProcessor implements Runnable {
presentation.setCodeUsagesString(descriptor.getCodeReferencesText(codeUsageCount, codeFiles.size()));
presentation.setNonCodeUsagesString(descriptor.getCommentReferencesText(nonCodeUsageCount, nonCodeFiles.size()));
presentation.setDynamicUsagesString("Dynamic " + StringUtil.decapitalize(descriptor.getCodeReferencesText(dynamicUsagesCount, dynamicUsagesCodeFiles.size())));
presentation.setUsagesInGeneratedCodeString(descriptor.getCodeReferencesText(codeUsageCount, codeFiles.size()) + " in generated code");
return presentation;
}
@@ -244,6 +244,7 @@ public class SafeDeleteProcessor extends BaseRefactoringProcessor {
presentation.setShowReadOnlyStatusAsRed(true);
presentation.setShowCancelButton(true);
presentation.setCodeUsagesString(RefactoringBundle.message("references.found.in.code"));
presentation.setUsagesInGeneratedCodeString(RefactoringBundle.message("references.found.in.generated.code"));
presentation.setNonCodeUsagesString(RefactoringBundle.message("occurrences.found.in.comments.strings.and.non.java.files"));
presentation.setUsagesString(RefactoringBundle.message("usageView.usagesText"));
@@ -368,6 +368,7 @@ references.in.code.to.0.1=References in code to {0} {1}
move.classes.elements.header=Classes to be moved to {0}
move.packages.elements.header=Packages to be moved to {0}
references.found.in.code=References found in code
references.found.in.generated.code=References found in generated code
comments.elements.header=Occurrences found in comments, strings and non-code files {0}
move.files.elements.header=Files to be moved to {0}
move.directories.elements.header=Directories to be moved to {0}
@@ -1,5 +1,6 @@
node.targets=Targets
node.non.code.usages=Non-code usages
node.usages.in.generated.code=Usages in generated code
node.found.usages=Found usages
usage.name=usage
usages.title=Usages
@@ -231,6 +231,8 @@
<extensionPoint name="resolveScopeEnlarger" interface="com.intellij.psi.ResolveScopeEnlarger"/>
<extensionPoint name="resolveScopeProvider" interface="com.intellij.psi.ResolveScopeProvider"/>
<extensionPoint name="generatedSourcesFilter" interface="com.intellij.openapi.roots.GeneratedSourcesFilter"/>
<extensionPoint name="gotoClassContributor"
interface="com.intellij.navigation.ChooseByNameContributor"/>
<extensionPoint name="gotoSymbolContributor"
@@ -32,6 +32,7 @@ public class UsageViewPresentation {
private String myTargetsNodeText = UsageViewBundle.message("node.targets"); // Default value. to be overwritten in most cases.
private String myNonCodeUsagesString = UsageViewBundle.message("node.non.code.usages");
private String myCodeUsagesString = UsageViewBundle.message("node.found.usages");
private String myUsagesInGeneratedCodeString = UsageViewBundle.message("node.usages.in.generated.code");
private boolean myShowReadOnlyStatusAsRed = false;
private boolean myShowCancelButton = false;
private boolean myOpenInNewTab = true;
@@ -176,6 +177,14 @@ public class UsageViewPresentation {
return myDynamicCodeUsagesString;
}
public String getUsagesInGeneratedCodeString() {
return myUsagesInGeneratedCodeString;
}
public void setUsagesInGeneratedCodeString(String usagesInGeneratedCodeString) {
myUsagesInGeneratedCodeString = usagesInGeneratedCodeString;
}
public boolean isMergeDupLinesAvailable() {
return myMergeDupLinesAvailable;
}
@@ -42,7 +42,7 @@ public class UsageGroupingRuleProviderImpl implements UsageGroupingRuleProvider
@NotNull
public UsageGroupingRule[] getActiveRules(Project project) {
List<UsageGroupingRule> rules = new ArrayList<UsageGroupingRule>();
rules.add(new NonCodeUsageGroupingRule());
rules.add(new NonCodeUsageGroupingRule(project));
if (UsageViewSettings.getInstance().GROUP_BY_SCOPE) {
rules.add(new UsageScopeGroupingRule());
}
@@ -15,7 +15,9 @@
*/
package com.intellij.usages.impl.rules;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.roots.GeneratedSourcesFilter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewBundle;
import com.intellij.usages.Usage;
@@ -24,16 +26,23 @@ import com.intellij.usages.UsageInfo2UsageAdapter;
import com.intellij.usages.UsageView;
import com.intellij.usages.rules.PsiElementUsage;
import com.intellij.usages.rules.UsageGroupingRule;
import com.intellij.usages.rules.UsageInFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* @author max
*/
public class NonCodeUsageGroupingRule implements UsageGroupingRule {
private static class CodeUsageGroup implements UsageGroup {
private final GeneratedSourcesFilter[] myGeneratedSourcesFilters;
private final Project myProject;
public NonCodeUsageGroupingRule(Project project) {
myProject = project;
myGeneratedSourcesFilters = GeneratedSourcesFilter.EP_NAME.getExtensions();
}
private static class CodeUsageGroup extends UsageGroupBase {
private static final UsageGroup INSTANCE = new CodeUsageGroup();
@Override
@@ -42,21 +51,11 @@ public class NonCodeUsageGroupingRule implements UsageGroupingRule {
return view == null ? UsageViewBundle.message("node.group.code.usages") : view.getPresentation().getCodeUsagesString();
}
@Override
public void update() {
}
public String toString() {
//noinspection HardCodedStringLiteral
return "CodeUsages";
}
@Override
public Icon getIcon(boolean isOpen) { return null; }
@Override
public FileStatus getFileStatus() { return null; }
@Override
public boolean isValid() { return true; }
@Override
public int compareTo(@NotNull UsageGroup usageGroup) {
if (usageGroup instanceof DynamicUsageGroup) {
@@ -64,18 +63,28 @@ public class NonCodeUsageGroupingRule implements UsageGroupingRule {
}
return usageGroup == this ? 0 : 1;
}
@Override
public void navigate(boolean requestFocus) { }
@Override
public boolean canNavigate() { return false; }
}
private static class UsageInGeneratedCodeGroup extends UsageGroupBase {
public static final UsageGroup INSTANCE = new UsageInGeneratedCodeGroup();
@Override
public boolean canNavigateToSource() {
return canNavigate();
@NotNull
public String getText(UsageView view) {
return view == null ? UsageViewBundle.message("node.usages.in.generated.code") : view.getPresentation().getUsagesInGeneratedCodeString();
}
public String toString() {
return "UsagesInGeneratedCode";
}
@Override
public int compareTo(@NotNull UsageGroup usageGroup) {
return usageGroup == this ? 0 : -1;
}
}
private static class NonCodeUsageGroup implements UsageGroup {
private static class NonCodeUsageGroup extends UsageGroupBase {
public static final UsageGroup INSTANCE = new NonCodeUsageGroup();
@Override
@@ -92,26 +101,10 @@ public class NonCodeUsageGroupingRule implements UsageGroupingRule {
//noinspection HardCodedStringLiteral
return "NonCodeUsages";
}
@Override
public Icon getIcon(boolean isOpen) { return null; }
@Override
public FileStatus getFileStatus() { return null; }
@Override
public boolean isValid() { return true; }
@Override
public int compareTo(@NotNull UsageGroup usageGroup) { return usageGroup == this ? 0 : -1; }
@Override
public void navigate(boolean requestFocus) { }
@Override
public boolean canNavigate() { return false; }
@Override
public boolean canNavigateToSource() {
return canNavigate();
}
}
private static class DynamicUsageGroup implements UsageGroup {
private static class DynamicUsageGroup extends UsageGroupBase {
public static final UsageGroup INSTANCE = new DynamicUsageGroup();
@NonNls private static final String DYNAMIC_CAPTION = "Dynamic usages";
@@ -127,35 +120,25 @@ public class NonCodeUsageGroupingRule implements UsageGroupingRule {
}
}
@Override
public void update() {
}
public String toString() {
//noinspection HardCodedStringLiteral
return "DynamicUsages";
}
@Override
public Icon getIcon(boolean isOpen) { return null; }
@Override
public FileStatus getFileStatus() { return null; }
@Override
public boolean isValid() { return true; }
@Override
public int compareTo(@NotNull UsageGroup usageGroup) { return usageGroup == this ? 0 : 1; }
@Override
public void navigate(boolean requestFocus) { }
@Override
public boolean canNavigate() { return false; }
@Override
public boolean canNavigateToSource() {
return canNavigate();
}
}
@Override
public UsageGroup groupUsage(@NotNull Usage usage) {
if (usage instanceof UsageInFile) {
VirtualFile file = ((UsageInFile)usage).getFile();
if (file != null) {
for (GeneratedSourcesFilter filter : myGeneratedSourcesFilters) {
if (filter.isGeneratedSource(file, myProject)) {
return UsageInGeneratedCodeGroup.INSTANCE;
}
}
}
}
if (usage instanceof PsiElementUsage) {
if (usage instanceof UsageInfo2UsageAdapter) {
final UsageInfo usageInfo = ((UsageInfo2UsageAdapter)usage).getUsageInfo();
@@ -0,0 +1,46 @@
package com.intellij.usages.impl.rules;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.usages.UsageGroup;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* @author nik
*/
public abstract class UsageGroupBase implements UsageGroup {
@Override
public void update() {
}
@Nullable
@Override
public FileStatus getFileStatus() {
return null;
}
@Override
public boolean isValid() {
return true;
}
@Override
public Icon getIcon(boolean isOpen) {
return null;
}
@Override
public void navigate(boolean focus) {
}
@Override
public boolean canNavigate() {
return false;
}
@Override
public boolean canNavigateToSource() {
return false;
}
}
+1
View File
@@ -1487,6 +1487,7 @@
<refactoring.pullUpHelperFactory language="JAVA" implementationClass="com.intellij.refactoring.memberPullUp.JavaPullUpHelperFactory"/>
<hierarchy.referenceProcessor implementation="com.intellij.ide.hierarchy.call.JavaCallReferenceProcessor"/>
<projectTemplate projectType="Java" templatePath="resources/projectTemplates/Java/Command_Line_App.zip"/>
<generatedSourcesFilter implementation="com.intellij.openapi.roots.JavaGeneratedSourcesFilter"/>
</extensions>
<actions>