From 22122761476a3cd9be342b63848c620966cffa32 Mon Sep 17 00:00:00 2001 From: "Svetlana.Zemlyanskay" Date: Wed, 17 Dec 2014 18:47:23 +0300 Subject: [PATCH 1/8] IDEA-129802 Rearranger UI: fix colors for Darcula --- .../arrangement/match/ArrangementMatchingRulesControl.java | 2 ++ .../arrangement/util/ArrangementRuleIndexControl.java | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRulesControl.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRulesControl.java index f1091a5bbce9..2d902488266a 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRulesControl.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRulesControl.java @@ -27,6 +27,7 @@ import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchConditio import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsManager; import com.intellij.psi.codeStyle.arrangement.std.ArrangementUiComponent; import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens; +import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.table.JBTable; import com.intellij.util.ui.AbstractTableCellEditor; @@ -79,6 +80,7 @@ public class ArrangementMatchingRulesControl extends JBTable { setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); setShowColumns(false); setShowGrid(false); + setBorder(IdeBorderFactory.createBorder()); setSurrendersFocusOnKeystroke(true); putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/util/ArrangementRuleIndexControl.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/util/ArrangementRuleIndexControl.java index 606ca5c5f615..39bfaae8e6ae 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/util/ArrangementRuleIndexControl.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/util/ArrangementRuleIndexControl.java @@ -77,12 +77,15 @@ public class ArrangementRuleIndexControl extends JPanel { return; } - g.setColor(myIsError ? JBColor.red : UIUtil.getBorderColor()); + g.setColor(myIsError ? JBColor.red : JBColor.border()); Rectangle bounds = getBounds(); ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int y = Math.max(0, myBaseLine - myHeight - (myDiameter - myHeight) / 2); g.drawOval(0, y, myDiameter, myDiameter); - + + if (UIUtil.isUnderDarcula()) { + g.setColor(UIUtil.getLabelForeground()); + } g.drawChars(myChars, 0, myChars.length, (bounds.width - myIndexWidth) / 2, myBaseLine); } From e6194911f3f58a42aaf054033f49cdbfb7a20bf4 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Wed, 17 Dec 2014 18:54:10 +0300 Subject: [PATCH 2/8] increased PyCharm Edu versions --- python/edu/course-creator/resources/META-INF/plugin.xml | 2 +- python/edu/learn-python/resources/META-INF/plugin.xml | 2 +- python/edu/resources/idea/PyCharmEduApplicationInfo.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/edu/course-creator/resources/META-INF/plugin.xml b/python/edu/course-creator/resources/META-INF/plugin.xml index 636927381260..4defe81f2931 100644 --- a/python/edu/course-creator/resources/META-INF/plugin.xml +++ b/python/edu/course-creator/resources/META-INF/plugin.xml @@ -1,7 +1,7 @@ org.jetbrains.plugins.coursecreator Course Creator for PyCharm Educational - 1.1 + 1.2 com.jetbrains.python.edu.learn-python Educational plugin for PyCharm - 1.1 + 1.2 - + From be9338022f8e1ad91c4d5f16c332522ae7ddeb21 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 17 Dec 2014 17:13:30 +0100 Subject: [PATCH 3/8] platform: avoid returning corrupted plugin descriptor --- .../malformed/META-INF/plugin.xml | 1 + .../ide/plugins/PluginManagerCore.java | 23 +++++----- .../ide/plugins/PluginDescriptorTest.java | 43 ++++++++++++++++--- 3 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 java/java-tests/testData/ide/plugins/pluginDescriptor/malformed/META-INF/plugin.xml diff --git a/java/java-tests/testData/ide/plugins/pluginDescriptor/malformed/META-INF/plugin.xml b/java/java-tests/testData/ide/plugins/pluginDescriptor/malformed/META-INF/plugin.xml new file mode 100644 index 000000000000..17843c7c94da --- /dev/null +++ b/java/java-tests/testData/ide/plugins/pluginDescriptor/malformed/META-INF/plugin.xml @@ -0,0 +1 @@ +oops \ No newline at end of file diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java index 842478c2d8cc..1922fb6cfcbb 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java +++ b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java @@ -556,23 +556,27 @@ public class PluginManagerCore { @Nullable static IdeaPluginDescriptorImpl loadDescriptorFromDir(@NotNull File file, @NotNull String fileName) { - IdeaPluginDescriptorImpl descriptor = null; File descriptorFile = new File(file, META_INF + File.separator + fileName); if (descriptorFile.exists()) { - descriptor = new IdeaPluginDescriptorImpl(file); try { + IdeaPluginDescriptorImpl descriptor = new IdeaPluginDescriptorImpl(file); descriptor.readExternal(descriptorFile.toURI().toURL()); + return descriptor; } - catch (Exception e) { - System.err.println("Cannot load: " + descriptorFile.getAbsolutePath()); - e.printStackTrace(); + catch (XmlSerializationException e) { + getLogger().info("Cannot load " + file, e); + prepareLoadingPluginsErrorMessage("File '" + file.getName() + "' contains invalid plugin descriptor."); + } + catch (Throwable e) { + getLogger().info("Cannot load " + file, e); } } - return descriptor; + + return null; } @Nullable - static IdeaPluginDescriptorImpl loadDescriptorFromJar(@NotNull File file, @NotNull @NonNls String fileName) { + static IdeaPluginDescriptorImpl loadDescriptorFromJar(@NotNull File file, @NotNull String fileName) { try { String fileURL = StringUtil.replace(file.toURI().toASCIIString(), "!", "%21"); URL jarURL = new URL("jar:" + fileURL + "!/META-INF/" + fileName); @@ -593,7 +597,7 @@ public class PluginManagerCore { } catch (XmlSerializationException e) { getLogger().info("Cannot load " + file, e); - prepareLoadingPluginsErrorMessage("Plugin file " + file.getName() + " contains invalid plugin descriptor file."); + prepareLoadingPluginsErrorMessage("File '" + file.getName() + "' contains invalid plugin descriptor."); } catch (Throwable e) { getLogger().info("Cannot load " + file, e); @@ -607,9 +611,8 @@ public class PluginManagerCore { return loadDescriptorFromJar(file, PLUGIN_XML); } - @SuppressWarnings({"HardCodedStringLiteral"}) @Nullable - public static IdeaPluginDescriptorImpl loadDescriptor(final File file, @NonNls final String fileName) { + public static IdeaPluginDescriptorImpl loadDescriptor(@NotNull final File file, @NotNull String fileName) { IdeaPluginDescriptorImpl descriptor = null; if (file.isDirectory()) { diff --git a/platform/platform-tests/testSrc/com/intellij/ide/plugins/PluginDescriptorTest.java b/platform/platform-tests/testSrc/com/intellij/ide/plugins/PluginDescriptorTest.java index fd4a052a8933..72dbbb82e6e5 100644 --- a/platform/platform-tests/testSrc/com/intellij/ide/plugins/PluginDescriptorTest.java +++ b/platform/platform-tests/testSrc/com/intellij/ide/plugins/PluginDescriptorTest.java @@ -1,21 +1,50 @@ +/* + * Copyright 2000-2014 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.ide.plugins; import com.intellij.openapi.application.ex.PathManagerEx; -import junit.framework.TestCase; +import org.junit.Test; import java.io.File; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + /** * @author Dmitry Avdeev - * Date: 7/14/11 */ -public class PluginDescriptorTest extends TestCase { +public class PluginDescriptorTest { + private static String getTestDataPath() { + return PathManagerEx.getTestDataPath() + "/ide/plugins/pluginDescriptor"; + } - public void testDescriptorLoading() throws Exception { - String path = PathManagerEx.getTestDataPath().replace(File.separatorChar, '/') + "/ide/plugins/pluginDescriptor"; - File file = new File(path + "/asp.jar"); + @Test + public void testDescriptorLoading() { + File file = new File(getTestDataPath(), "asp.jar"); assertTrue(file + " not exist", file.exists()); - IdeaPluginDescriptorImpl descriptor = PluginManager.loadDescriptorFromJar(file); + IdeaPluginDescriptorImpl descriptor = PluginManagerCore.loadDescriptorFromJar(file); assertNotNull(descriptor); } + + @Test + public void testInvalidFileDescriptor() { + File file = new File(getTestDataPath(), "malformed"); + assertTrue(file + " not exist", file.exists()); + IdeaPluginDescriptorImpl descriptor = PluginManagerCore.loadDescriptorFromDir(file, PluginManagerCore.PLUGIN_XML); + assertNull(descriptor); + } } From ae06d36a7382c58f8b5b775efd9e58559cbfe7bb Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 17 Dec 2014 17:14:28 +0100 Subject: [PATCH 4/8] Cleanup (formatting) --- .../ide/plugins/PluginManagerCore.java | 88 ++++++++++--------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java index 1922fb6cfcbb..e2711874aff7 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java +++ b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java @@ -619,56 +619,57 @@ public class PluginManagerCore { descriptor = loadDescriptorFromDir(file, fileName); if (descriptor == null) { - File libDir = new File(file, "lib"); - if (!libDir.isDirectory()) { - return null; - } - final File[] files = libDir.listFiles(); - if (files == null || files.length == 0) { - return null; - } - Arrays.sort(files, new Comparator() { - @Override - public int compare(@NotNull File o1, @NotNull File o2) { - if (o2.getName().startsWith(file.getName())) return Integer.MAX_VALUE; - if (o1.getName().startsWith(file.getName())) return -Integer.MAX_VALUE; - if (o2.getName().startsWith("resources")) return -Integer.MAX_VALUE; - if (o1.getName().startsWith("resources")) return Integer.MAX_VALUE; - return 0; - } - }); - for (final File f : files) { - if (FileUtil.isJarOrZip(f)) { - descriptor = loadDescriptorFromJar(f, fileName); - if (descriptor != null) { - descriptor.setPath(file); - break; - } -// getLogger().warn("Cannot load descriptor from " + f.getName() + ""); - } - else if (f.isDirectory()) { - IdeaPluginDescriptorImpl descriptor1 = loadDescriptorFromDir(f, fileName); - if (descriptor1 != null) { - if (descriptor != null) { - getLogger().info("Cannot load " + file + " because two or more plugin.xml's detected"); - return null; - } - descriptor = descriptor1; - descriptor.setPath(file); - } - } - } - } + File libDir = new File(file, "lib"); + if (!libDir.isDirectory()) { + return null; + } + final File[] files = libDir.listFiles(); + if (files == null || files.length == 0) { + return null; + } + Arrays.sort(files, new Comparator() { + @Override + public int compare(@NotNull File o1, @NotNull File o2) { + if (o2.getName().startsWith(file.getName())) return Integer.MAX_VALUE; + if (o1.getName().startsWith(file.getName())) return -Integer.MAX_VALUE; + if (o2.getName().startsWith("resources")) return -Integer.MAX_VALUE; + if (o1.getName().startsWith("resources")) return Integer.MAX_VALUE; + return 0; + } + }); + for (final File f : files) { + if (FileUtil.isJarOrZip(f)) { + descriptor = loadDescriptorFromJar(f, fileName); + if (descriptor != null) { + descriptor.setPath(file); + break; + } + // getLogger().warn("Cannot load descriptor from " + f.getName() + ""); + } + else if (f.isDirectory()) { + IdeaPluginDescriptorImpl descriptor1 = loadDescriptorFromDir(f, fileName); + if (descriptor1 != null) { + if (descriptor != null) { + getLogger().info("Cannot load " + file + " because two or more plugin.xml's detected"); + return null; + } + descriptor = descriptor1; + descriptor.setPath(file); + } + } + } + } } else if (StringUtil.endsWithIgnoreCase(file.getName(), ".jar") && file.exists()) { descriptor = loadDescriptorFromJar(file, fileName); } if (descriptor != null && descriptor.getOptionalConfigs() != null && !descriptor.getOptionalConfigs().isEmpty()) { - final Map descriptors = new THashMap(descriptor.getOptionalConfigs().size()); - for (Map.Entry entry: descriptor.getOptionalConfigs().entrySet()) { + final Map descriptors = + new THashMap(descriptor.getOptionalConfigs().size()); + for (Map.Entry entry : descriptor.getOptionalConfigs().entrySet()) { String optionalDescriptorName = entry.getValue(); - assert !Comparing.equal(fileName, optionalDescriptorName) : "recursive dependency: "+ fileName; + assert !Comparing.equal(fileName, optionalDescriptorName) : "recursive dependency: " + fileName; IdeaPluginDescriptorImpl optionalDescriptor = loadDescriptor(file, optionalDescriptorName); if (optionalDescriptor == null && !FileUtil.isJarOrZip(file)) { @@ -690,6 +691,7 @@ public class PluginManagerCore { } descriptor.setOptionalDescriptors(descriptors); } + return descriptor; } From d7cbc016b8c177dd67812eec8612aa3d45a96cef Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 16 Dec 2014 14:46:50 +0100 Subject: [PATCH 5/8] delete some commented out code, minor cleanup --- .../nodes/ProjectViewDirectoryHelper.java | 67 +++++++------------ 1 file changed, 23 insertions(+), 44 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java index 36c09aff2218..cfdde22d49f1 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java @@ -130,7 +130,7 @@ public class ProjectViewDirectoryHelper { } else { // source directory in "flatten packages" mode final PsiDirectory parentDir = psiDirectory.getParentDirectory(); - if (parentDir == null || skipDirectory(parentDir) /*|| !rootDirectoryFound(parentDir)*/ && withSubDirectories) { + if (parentDir == null || skipDirectory(parentDir) && withSubDirectories) { addAllSubpackages(children, psiDirectory, moduleFileIndex, settings); } PsiDirectory[] subdirs = psiDirectory.getSubdirectories(); @@ -218,20 +218,22 @@ public class ProjectViewDirectoryHelper { } // used only for non-flatten packages mode - public void processPsiDirectoryChildren(final PsiDirectory psiDir, - PsiElement[] children, - List container, - ProjectFileIndex projectFileIndex, - ModuleFileIndex moduleFileIndex, - ViewSettings viewSettings, - boolean withSubDirectories) { + public void processPsiDirectoryChildren(final PsiDirectory psiDir, + PsiElement[] children, + List container, + ProjectFileIndex projectFileIndex, + @Nullable ModuleFileIndex moduleFileIndex, + ViewSettings viewSettings, + boolean withSubDirectories) { for (PsiElement child : children) { LOG.assertTrue(child.isValid()); final VirtualFile vFile; if (child instanceof PsiFile) { vFile = ((PsiFile)child).getVirtualFile(); - addNode(moduleFileIndex, projectFileIndex, psiDir, vFile, container, PsiFileNode.class, child, viewSettings); + if (vFile != null) { + addNode(moduleFileIndex, vFile, container, PsiFileNode.class, child, viewSettings); + } } else if (child instanceof PsiDirectory) { if (withSubDirectories) { @@ -244,7 +246,7 @@ public class ProjectViewDirectoryHelper { continue; } } - addNode(moduleFileIndex, projectFileIndex, psiDir, vFile, container, PsiDirectoryNode.class, child, viewSettings); + addNode(moduleFileIndex, vFile, container, PsiDirectoryNode.class, child, viewSettings); } } else { @@ -254,36 +256,15 @@ public class ProjectViewDirectoryHelper { } public void addNode(ModuleFileIndex moduleFileIndex, - ProjectFileIndex projectFileIndex, - PsiDirectory psiDir, - VirtualFile vFile, - List container, - Class nodeClass, - PsiElement element, - final ViewSettings settings) { - if (vFile == null) { - return; - } + VirtualFile vFile, + List container, + Class nodeClass, + PsiElement element, + final ViewSettings settings) { // this check makes sense for classes not in library content only if (moduleFileIndex != null && !moduleFileIndex.isInContent(vFile)) { return; } - /* - final boolean childInLibraryClasses = projectFileIndex.isInLibraryClasses(vFile); - if (!projectFileIndex.isInSourceContent(vFile)) { - if (childInLibraryClasses) { - final VirtualFile psiDirVFile = psiDir.getVirtualFile(); - final boolean parentInLibraryContent = - projectFileIndex.isInLibraryClasses(psiDirVFile) || projectFileIndex.isInLibrarySource(psiDirVFile); - if (!parentInLibraryContent) { - return; - } - } - } - if (childInLibraryClasses && !projectFileIndex.isInContent(vFile) && !showFileInLibClasses(vFile)) { - return; // skip java sources in classpath - } - */ try { container.add(ProjectViewNode.createTreeNode(nodeClass, element.getProject(), element, settings)); @@ -295,20 +276,18 @@ public class ProjectViewDirectoryHelper { // used only in flatten packages mode public void addAllSubpackages(List container, - PsiDirectory dir, - ModuleFileIndex moduleFileIndex, - ViewSettings viewSettings) { + PsiDirectory dir, + @Nullable ModuleFileIndex moduleFileIndex, + ViewSettings viewSettings) { final Project project = dir.getProject(); PsiDirectory[] subdirs = dir.getSubdirectories(); for (PsiDirectory subdir : subdirs) { if (skipDirectory(subdir)) { continue; } - if (moduleFileIndex != null) { - if (!moduleFileIndex.isInContent(subdir.getVirtualFile())) { - container.add(new PsiDirectoryNode(project, subdir, viewSettings)); - continue; - } + if (moduleFileIndex != null && !moduleFileIndex.isInContent(subdir.getVirtualFile())) { + container.add(new PsiDirectoryNode(project, subdir, viewSettings)); + continue; } if (viewSettings.isHideEmptyMiddlePackages()) { if (!isEmptyMiddleDirectory(subdir, false)) { From a9de0503c444ad526d750f238b21a6f5a52d23b3 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 17 Dec 2014 15:51:21 +0100 Subject: [PATCH 6/8] some javadocs for JPS --- .../impl/BuildTargetScopeProvider.java | 2 + .../jps/builders/BuildRootDescriptor.java | 16 ++++++- .../jetbrains/jps/builders/BuildTarget.java | 48 +++++++++++++++++++ .../jps/builders/BuildTargetRegistry.java | 13 ++++- .../jps/builders/BuildTargetType.java | 8 ++++ .../jps/builders/TargetOutputIndex.java | 9 ++++ .../jps/incremental/BuilderCategory.java | 5 +- .../jps/incremental/BuilderService.java | 10 ++++ .../jps/incremental/ModuleLevelBuilder.java | 19 +++++++- .../jps/incremental/TargetBuilder.java | 15 +++++- .../jps/indices/IgnoredFileIndex.java | 5 ++ .../jps/indices/ModuleExcludeIndex.java | 11 +++++ .../org/jetbrains/jps/model/JpsGlobal.java | 3 ++ .../src/org/jetbrains/jps/model/JpsModel.java | 2 + 14 files changed, 160 insertions(+), 6 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java b/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java index 304957977b13..0fc54f980819 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java @@ -27,6 +27,8 @@ import java.util.List; import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope; /** + * Allows to control the list of build targets which are compiled when the Make action is invoked for a specific scope. + * * @author nik */ public abstract class BuildTargetScopeProvider { diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/BuildRootDescriptor.java b/jps/jps-builders/src/org/jetbrains/jps/builders/BuildRootDescriptor.java index 1c1f9aa31fff..64880314deab 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/BuildRootDescriptor.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/BuildRootDescriptor.java @@ -25,13 +25,24 @@ import java.util.Collections; import java.util.Set; /** + * Describes a source root of a build target. + * * @author nik */ public abstract class BuildRootDescriptor { + /** + * Returns the serializable ID of the root, used for writing caches. May return simply the file path. + */ public abstract String getRootId(); + /** + * Returns the directory of the source root. + */ public abstract File getRootFile(); + /** + * Returns the target to which this source root belongs. + */ public abstract BuildTarget getTarget(); /** @@ -41,13 +52,16 @@ public abstract class BuildRootDescriptor { return null; } + /** + * Creates the file filter specifying which files under the specified root belong to this build target. + */ @NotNull public FileFilter createFileFilter() { return FileUtilRt.ALL_FILES; } /** - * @return the set of excluded directories under this root + * @return the set of excluded directories under this root. */ @NotNull public Set getExcludedRoots() { diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTarget.java b/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTarget.java index 08c452a048ec..cf893816e1b8 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTarget.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTarget.java @@ -30,6 +30,14 @@ import java.util.Collection; import java.util.List; /** + * A single unit of the compilation process of a specific project. Has a number of inputs (individual files or directories with + * filter support). Places its output in a specific set of output roots. Can have dependencies on other build targets. + * E.g. any Java module has two build targets: production output and test output. Custom build targets (not based on a module) + * cannot have cyclic dependencies on each other. + *

+ * When parallel compilation is enabled, build targets that don't have any dependencies on each other may be built at the same + * time in different threads. + * * @author nik */ public abstract class BuildTarget { @@ -45,23 +53,63 @@ public abstract class BuildTarget { return myTargetType; } + /** + * Calculates the dependencies of this build target. + * + * @param targetRegistry the registry of all targets existing in the project. + * @param outputIndex the index of output files by target. + * @return + */ public abstract Collection> computeDependencies(BuildTargetRegistry targetRegistry, TargetOutputIndex outputIndex); + /** + * Allows the build target to tag the current project settings relevant to the build of this target + * (e.g the language level of a Java module) so that the target is fully recompiled when those settings + * change. + * + * @param pd the complete state of a compilation invocation + * @param out the print writer to which the project settings can be written (the settings are compared with the ones + * written during the invocation of the same method in a previous compilation). + */ public void writeConfiguration(ProjectDescriptor pd, PrintWriter out) { } + /** + * Returns the list of source roots for this target. + * + * @param model the JPS project model. + * @param index the index of exclude roots. + * @param ignoredFileIndex the index of ignore patterns. + * @param dataPaths the index of paths that can be used to serialize data related to build targets. + * @return + */ @NotNull public abstract List computeRootDescriptors(JpsModel model, ModuleExcludeIndex index, IgnoredFileIndex ignoredFileIndex, BuildDataPaths dataPaths); + /** + * Finds a source root by its serialized ID. + * + * @param rootId the serialized root ID. + * @param rootIndex the index of build roots. + * @return the build root or null if no root with this ID exists. + */ @Nullable public abstract R findRootDescriptor(String rootId, BuildRootIndex rootIndex); @NotNull public abstract String getPresentableName(); + /** + * Returns the list of output directories in which this target is going to produce its output. (The specific + * files produced need to be reported by {@link org.jetbrains.jps.incremental.TargetBuilder#build} through + * + * {@link org.jetbrains.jps.builders.BuildOutputConsumer#registerOutputFile}.) + * @param context the compilation context. + * @return the collection of output roots. + */ @NotNull public abstract Collection getOutputRoots(CompileContext context); diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTargetRegistry.java b/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTargetRegistry.java index 6560142c21b9..a9d1191934c4 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTargetRegistry.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTargetRegistry.java @@ -22,14 +22,22 @@ import java.util.Collection; import java.util.List; /** + * Allows to enumerate all build targets existing in a project. + * * @author Eugene Zhuravlev - * Date: 10/27/12 + * @since 10/27/12 */ public interface BuildTargetRegistry { + /** + * Returns all build targets of a specified type. + */ @NotNull > List getAllTargets(@NotNull BuildTargetType type); + /** + * Returns all build targets existing in the project. + */ @NotNull List> getAllTargets(); @@ -37,6 +45,9 @@ public interface BuildTargetRegistry { PRODUCTION, TEST, ALL } + /** + * Returns the module-based targets of the specified module that have the specified type. + */ @NotNull Collection> getModuleBasedTargets(@NotNull JpsModule module, @NotNull ModuleTargetSelector selector); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTargetType.java b/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTargetType.java index 496ad4778925..e6c8a4ea5a57 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTargetType.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTargetType.java @@ -21,7 +21,10 @@ import org.jetbrains.jps.model.JpsModel; import java.util.List; /** + * The type of a build target. For example, there is a build target type for Java production and another for Java tests. + * * @author nik + * @see org.jetbrains.jps.incremental.BuilderService#getTargetTypes() */ public abstract class BuildTargetType> { private final String myTypeId; @@ -44,6 +47,11 @@ public abstract class BuildTargetType> { return myTypeId.hashCode(); } + /** + * Finds all targets of the given type that need to be built in the given project. + * @param model the model instance representing a project. + * @return the list of targets. + */ @NotNull public abstract List computeAllTargets(@NotNull JpsModel model); diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/TargetOutputIndex.java b/jps/jps-builders/src/org/jetbrains/jps/builders/TargetOutputIndex.java index 8f3b6497f421..9fa861f90be5 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/TargetOutputIndex.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/TargetOutputIndex.java @@ -21,8 +21,17 @@ import java.io.File; import java.util.Collection; /** + * Indexes the output roots of individual build targets. + * * @author nik */ public interface TargetOutputIndex { + /** + * Returns the list of targets that contain the specified output file in their output roots. + * + * @param file a build output file. + * @return a collection of targets to the output roots of which this file belongs, or an empty collection + * if no such targets exist. + */ Collection> getTargetsByOutputFile(@NotNull File file); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderCategory.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderCategory.java index da5473ea80b3..9983b1330538 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderCategory.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderCategory.java @@ -16,8 +16,11 @@ package org.jetbrains.jps.incremental; /** + * The category of a module-level builder. Determines the order of executing builders when compiling a module. + * * @author Eugene Zhuravlev - * Date: 9/17/11 + * @since 9/17/11 + * @see ModuleLevelBuilder#getCategory() */ public enum BuilderCategory { INITIAL, diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderService.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderService.java index 1036eb3c8278..3cf53433da12 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderService.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderService.java @@ -29,16 +29,26 @@ import java.util.List; * @author nik */ public abstract class BuilderService { + /** + * Returns the list of build target types contributed by this plugin. If it only participates in the compilation + * of regular Java modules, you don't need to return anything here. + */ @NotNull public List> getTargetTypes() { return Collections.emptyList(); } + /** + * Returns the list of Java module builder extensions contributed by this plugin. + */ @NotNull public List createModuleLevelBuilders() { return Collections.emptyList(); } + /** + * Returns the list of non-module target builders contributed by this plugin. + */ @NotNull public List> createBuilders() { return Collections.emptyList(); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleLevelBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleLevelBuilder.java index 394ce12e8042..15cd7a18365a 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleLevelBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleLevelBuilder.java @@ -29,10 +29,14 @@ import java.util.List; import java.util.Map; /** - * Use {@link BuilderService} to register implementations of this class + * Allows to extend the compilation process for Java modules compiled to .class files. Use {@link BuilderService} to register + * implementations of this class. The order of execution of different module-level builders is determined by their category + * (they're executed in the order of constants in the {@code BuilderCategory}; the order of executing different builders of + * the same category is not determined). * * @author Eugene Zhuravlev - * Date: 9/17/11 + * @since 9/17/11 + * @see BuilderService#createModuleLevelBuilders() */ public abstract class ModuleLevelBuilder extends Builder { private final BuilderCategory myCategory; @@ -59,6 +63,17 @@ public abstract class ModuleLevelBuilder extends Builder { BinaryContent lookupClassBytes(String className); } + /** + * Performs the compilation actions for a single module or a chunk of cyclically dependent modules. + * + * @param context compilation context (can be used to report compiler errors/warnings and to check whether the build + * has been cancelled and needs to be stopped). + * @param chunk target to build. + * @param dirtyFilesHolder can be used to enumerate the source files from the inputs of this target that have been modified + * or deleted since the previous compilation run. + * @param outputConsumer receives the output files and classes produced by the build. (All output files produced by the build + * need to be reported here.) + */ public abstract ExitCode build(CompileContext context, ModuleChunk chunk, DirtyFilesHolder dirtyFilesHolder, diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/TargetBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/TargetBuilder.java index 27609d7a5f88..5e01c8d3d8c7 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/TargetBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/TargetBuilder.java @@ -22,8 +22,10 @@ import java.io.IOException; import java.util.Collection; /** - * Use {@link BuilderService} to register implementations of this class + * Produced the output of a single build target. Use {@link BuilderService} to register implementations of this class. + * * @author nik + * @see BuilderService#createBuilders() */ public abstract class TargetBuilder> extends Builder { private final Collection> myTargetTypes; @@ -36,6 +38,17 @@ public abstract class TargetBuilder holder, @NotNull BuildOutputConsumer outputConsumer, @NotNull CompileContext context) throws ProjectBuildException, IOException; diff --git a/jps/jps-builders/src/org/jetbrains/jps/indices/IgnoredFileIndex.java b/jps/jps-builders/src/org/jetbrains/jps/indices/IgnoredFileIndex.java index cddd4a4e9852..660101445f15 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/indices/IgnoredFileIndex.java +++ b/jps/jps-builders/src/org/jetbrains/jps/indices/IgnoredFileIndex.java @@ -16,8 +16,13 @@ package org.jetbrains.jps.indices; /** + * Indexes the ignored files in a project. + * * @author nik */ public interface IgnoredFileIndex { + /** + * Checks if the specified filename is ignored (listed under Settings | File Types | Files and folders to ignore). + */ boolean isIgnored(String fileName); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/indices/ModuleExcludeIndex.java b/jps/jps-builders/src/org/jetbrains/jps/indices/ModuleExcludeIndex.java index c0d1b5401d8f..5c7930fb562b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/indices/ModuleExcludeIndex.java +++ b/jps/jps-builders/src/org/jetbrains/jps/indices/ModuleExcludeIndex.java @@ -21,12 +21,23 @@ import java.io.File; import java.util.Collection; /** + * Allows to check whether a particular file is in the content or under an exclude root of a module. + * * @author nik */ public interface ModuleExcludeIndex { + /** + * Checks if the specified file is under an exclude root of a module. + */ boolean isExcluded(File file); + /** + * Returns the list of exclude roots for a specified module. + */ Collection getModuleExcludes(JpsModule module); + /** + * Checks if the specified file is under the content of any module in the project and not under an exclude root. + */ boolean isInContent(File file); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java b/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java index 2b92580e862f..3598e07ee927 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java @@ -22,7 +22,10 @@ import org.jetbrains.jps.model.library.sdk.JpsSdk; import org.jetbrains.jps.model.library.sdk.JpsSdkType; /** + * Represents the application-level settings (JDKs and global libraries) required for an external build. + * * @author nik + * @see org.jetbrains.jps.model.JpsModel#getGlobal() */ public interface JpsGlobal extends JpsCompositeElement, JpsReferenceableElement { @NotNull diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsModel.java b/jps/model-api/src/org/jetbrains/jps/model/JpsModel.java index 469bab8e865e..2efda57ef880 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsModel.java +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsModel.java @@ -18,6 +18,8 @@ package org.jetbrains.jps.model; import org.jetbrains.annotations.NotNull; /** + * Represents an IntelliJ IDEA project and a set of relevant application-level settings (e.g. the JDK configuration) in JPS. + * * @author nik */ public interface JpsModel { From bd98adae86a5bc386a0e4757a823d260d9a57503 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 17 Dec 2014 17:19:03 +0100 Subject: [PATCH 7/8] extract common base class from ClassCoverageInfo and PackageCoverageInfo --- .../coverage/JavaCoverageAnnotator.java | 51 +++++----------- .../intellij/coverage/PackageAnnotator.java | 42 +++++++++----- .../view/JavaCoverageViewExtension.java | 58 +++++++------------ 3 files changed, 63 insertions(+), 88 deletions(-) diff --git a/plugins/coverage/src/com/intellij/coverage/JavaCoverageAnnotator.java b/plugins/coverage/src/com/intellij/coverage/JavaCoverageAnnotator.java index 6c9be40eb590..0fad443ceb23 100644 --- a/plugins/coverage/src/com/intellij/coverage/JavaCoverageAnnotator.java +++ b/plugins/coverage/src/com/intellij/coverage/JavaCoverageAnnotator.java @@ -144,14 +144,14 @@ public class JavaCoverageAnnotator extends BaseCoverageAnnotator { } @Nullable - public static String getCoverageInformationString(PackageAnnotator.PackageCoverageInfo info, boolean subCoverageActive) { + public static String getCoverageInformationString(PackageAnnotator.SummaryCoverageInfo info, boolean subCoverageActive) { if (info == null) return null; if (info.totalClassCount == 0 || info.totalLineCount == 0) return null; if (subCoverageActive) { - return info.coveredClassCount + info.coveredLineCount > 0 ? "covered" : null; + return info.coveredClassCount + info.getCoveredLineCount() > 0 ? "covered" : null; } return (int)((double)info.coveredClassCount / info.totalClassCount * 100) + "% classes, " + - (int)((double)info.coveredLineCount / info.totalLineCount * 100) + "% lines covered"; + (int)((double)info.getCoveredLineCount() / info.totalLineCount * 100) + "% lines covered"; } /** @@ -184,10 +184,9 @@ public class JavaCoverageAnnotator extends BaseCoverageAnnotator { boolean flatten) { if (psiPackage == null) return null; final boolean subCoverageActive = coverageDataManager.isSubCoverageActive(); - PackageAnnotator.PackageCoverageInfo info; if (module != null) { final PsiDirectory[] directories = psiPackage.getDirectories(GlobalSearchScope.moduleScope(module)); - PackageAnnotator.PackageCoverageInfo result = null; + PackageAnnotator.SummaryCoverageInfo result = null; for (PsiDirectory directory : directories) { final VirtualFile virtualFile = directory.getVirtualFile(); result = merge(result, myDirCoverageInfos.get(virtualFile)); @@ -196,49 +195,27 @@ public class JavaCoverageAnnotator extends BaseCoverageAnnotator { return getCoverageInformationString(result, subCoverageActive); } else { - info = getPackageCoverageInfo(psiPackage, flatten); + PackageAnnotator.PackageCoverageInfo info = getPackageCoverageInfo(psiPackage, flatten); + return getCoverageInformationString(info, subCoverageActive); } - return getCoverageInformationString(info, subCoverageActive); } public PackageAnnotator.PackageCoverageInfo getPackageCoverageInfo(@NotNull PsiPackage psiPackage, boolean flattenPackages) { final String qualifiedName = psiPackage.getQualifiedName(); return flattenPackages ? myFlattenPackageCoverageInfos.get(qualifiedName) : myPackageCoverageInfos.get(qualifiedName); } - - public String getPackageClassPercentage(@NotNull final PsiPackage psiPackage, boolean flatten) { - final PackageAnnotator.PackageCoverageInfo packageCoverageInfo = getPackageCoverageInfo(psiPackage, flatten); - if (packageCoverageInfo == null) return null; - return getPercentage(packageCoverageInfo.coveredClassCount, packageCoverageInfo.totalClassCount); - } - - public String getPackageMethodPercentage(PsiPackage psiPackage, boolean flatten) { - final PackageAnnotator.PackageCoverageInfo packageCoverageInfo = getPackageCoverageInfo(psiPackage, flatten); - if (packageCoverageInfo == null) return null; - return getPercentage(packageCoverageInfo.coveredMethodCount, packageCoverageInfo.totalMethodCount); - } - public String getPackageLinePercentage(final PsiPackage psiPackage, boolean flatten) { - final PackageAnnotator.PackageCoverageInfo packageCoverageInfo = getPackageCoverageInfo(psiPackage, flatten); - if (packageCoverageInfo == null) return null; - return getPercentage(packageCoverageInfo.coveredLineCount, packageCoverageInfo.totalLineCount); - } - - public String getClassLinePercentage(String classFQName) { - final PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName); + public String getLineCoveredPercentage(@Nullable PackageAnnotator.SummaryCoverageInfo info) { if (info == null) return null; - final int coveredLines = info.fullyCoveredLineCount + info.partiallyCoveredLineCount; - return getPercentage(coveredLines, info.totalLineCount); + return getPercentage(info.getCoveredLineCount(), info.totalLineCount); } - - public String getClassMethodPercentage(String classFQName) { - final PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName); + + public String getMethodCoveredPercentage(@Nullable PackageAnnotator.SummaryCoverageInfo info) { if (info == null) return null; return getPercentage(info.coveredMethodCount, info.totalMethodCount); } - public String getClassCoveredPercentage(String classFQName) { - final PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName); + public String getClassCoveredPercentage(@Nullable PackageAnnotator.SummaryCoverageInfo info) { if (info == null) return null; return getPercentage(info.coveredClassCount, info.totalClassCount); } @@ -247,8 +224,8 @@ public class JavaCoverageAnnotator extends BaseCoverageAnnotator { return (int)((double)covered /total * 100) +"% (" + covered + "/" + total + ")"; } - public static PackageAnnotator.PackageCoverageInfo merge(final PackageAnnotator.PackageCoverageInfo info, - final PackageAnnotator.PackageCoverageInfo testInfo) { + public static PackageAnnotator.SummaryCoverageInfo merge(@Nullable final PackageAnnotator.SummaryCoverageInfo info, + @Nullable final PackageAnnotator.SummaryCoverageInfo testInfo) { if (info == null) return testInfo; if (testInfo == null) return info; final PackageAnnotator.PackageCoverageInfo coverageInfo = new PackageAnnotator.PackageCoverageInfo(); @@ -256,7 +233,7 @@ public class JavaCoverageAnnotator extends BaseCoverageAnnotator { coverageInfo.coveredClassCount = info.coveredClassCount + testInfo.coveredClassCount; coverageInfo.totalLineCount = info.totalLineCount + testInfo.totalLineCount; - coverageInfo.coveredLineCount = info.coveredLineCount + testInfo.coveredLineCount; + coverageInfo.coveredLineCount = info.getCoveredLineCount() + testInfo.getCoveredLineCount(); return coverageInfo; } diff --git a/plugins/coverage/src/com/intellij/coverage/PackageAnnotator.java b/plugins/coverage/src/com/intellij/coverage/PackageAnnotator.java index f300d5be4776..b4a935fc1ee3 100644 --- a/plugins/coverage/src/com/intellij/coverage/PackageAnnotator.java +++ b/plugins/coverage/src/com/intellij/coverage/PackageAnnotator.java @@ -64,25 +64,39 @@ public class PackageAnnotator { void annotateClass(String classQualifiedName, ClassCoverageInfo classCoverageInfo); } - public static class ClassCoverageInfo { - public int totalLineCount; - public int fullyCoveredLineCount; - public int partiallyCoveredLineCount; - public int totalMethodCount; - public int coveredMethodCount; - - public int totalClassCount = 1; - public int coveredClassCount; - } - - public static class PackageCoverageInfo { + public static abstract class SummaryCoverageInfo { public int totalClassCount; public int coveredClassCount; + + public int totalMethodCount; + public int coveredMethodCount; + public int totalLineCount; + + public abstract int getCoveredLineCount(); + } + + public static class ClassCoverageInfo extends SummaryCoverageInfo { + public int fullyCoveredLineCount; + public int partiallyCoveredLineCount; + + public ClassCoverageInfo() { + totalClassCount = 1; + } + + @Override + public int getCoveredLineCount() { + return fullyCoveredLineCount + partiallyCoveredLineCount; + } + } + + public static class PackageCoverageInfo extends SummaryCoverageInfo { public int coveredLineCount; - public int coveredMethodCount; - public int totalMethodCount; + @Override + public int getCoveredLineCount() { + return coveredLineCount; + } } public static class DirCoverageInfo extends PackageCoverageInfo { diff --git a/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java b/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java index 808f330ea3e0..81abc84bde0e 100644 --- a/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java +++ b/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java @@ -44,28 +44,12 @@ public class JavaCoverageViewExtension extends CoverageViewExtension { myCoverageDataManager); if (coverageInformationString == null) { if (!myCoverageViewManager.isReady()) return "Loading..."; - PackageAnnotator.PackageCoverageInfo info = new PackageAnnotator.PackageCoverageInfo(); + PackageAnnotator.SummaryCoverageInfo info = new PackageAnnotator.PackageCoverageInfo(); final Collection children = childNode.getChildren(); for (Object child : children) { final Object childValue = ((CoverageListNode)child).getValue(); - if (childValue instanceof PsiPackage) { - final PackageAnnotator.PackageCoverageInfo coverageInfo = myAnnotator.getPackageCoverageInfo((PsiPackage)childValue, myStateBean.myFlattenPackages); - if (coverageInfo != null) { - info = JavaCoverageAnnotator.merge(info, coverageInfo); - } - } else { - final PackageAnnotator.ClassCoverageInfo classCoverageInfo = getClassCoverageInfo(((PsiClass)childValue)); - if (classCoverageInfo != null) { - info.coveredClassCount += classCoverageInfo.coveredMethodCount > 0 ? 1 : 0; - info.totalClassCount ++; - - info.coveredMethodCount += classCoverageInfo.coveredMethodCount; - info.totalMethodCount += classCoverageInfo.totalMethodCount; - - info.coveredLineCount += classCoverageInfo.partiallyCoveredLineCount + classCoverageInfo.fullyCoveredLineCount; - info.totalLineCount += classCoverageInfo.totalLineCount; - } - } + PackageAnnotator.SummaryCoverageInfo childInfo = getSummaryCoverageForNodeValue(childValue); + info = JavaCoverageAnnotator.merge(info, childInfo); } coverageInformationString = JavaCoverageAnnotator.getCoverageInformationString(info, false); } @@ -82,30 +66,30 @@ public class JavaCoverageViewExtension extends CoverageViewExtension { @Override public String getPercentage(int columnIndex, AbstractTreeNode node) { final Object value = node.getValue(); + PackageAnnotator.SummaryCoverageInfo info = getSummaryCoverageForNodeValue(value); + + if (columnIndex == 1) { + return myAnnotator.getClassCoveredPercentage(info); + } else if (columnIndex == 2){ + return myAnnotator.getMethodCoveredPercentage(info); + } + + return myAnnotator.getLineCoveredPercentage(info); + } + + public PackageAnnotator.SummaryCoverageInfo getSummaryCoverageForNodeValue(Object value) { + PackageAnnotator.SummaryCoverageInfo info = null; if (value instanceof PsiClass) { - //no coverage gathered - if (((PsiClass)value).isInterface()) return null; - - final String qualifiedName = ((PsiClass)value).getQualifiedName(); - if (columnIndex == 1) { - return myAnnotator.getClassCoveredPercentage(qualifiedName); - } else if (columnIndex == 2){ - return myAnnotator.getClassMethodPercentage(qualifiedName); + if (!((PsiClass)value).isInterface()) { + final String qualifiedName = ((PsiClass)value).getQualifiedName(); + info = myAnnotator.getClassCoverageInfo(qualifiedName); } - - return myAnnotator.getClassLinePercentage(qualifiedName); } if (value instanceof PsiPackage) { - final boolean flatten = myStateBean.myFlattenPackages; - if (columnIndex == 1) { - return myAnnotator.getPackageClassPercentage((PsiPackage)value, flatten); - } else if (columnIndex == 2) { - return myAnnotator.getPackageMethodPercentage((PsiPackage)value, flatten); - } - return myAnnotator.getPackageLinePercentage((PsiPackage)value, flatten); + info = myAnnotator.getPackageCoverageInfo((PsiPackage)value, myStateBean.myFlattenPackages); } - return null; + return info; } @Override From d343ff4ac6b6edcfb2fe7f8f0bf18bc96c646c96 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 17 Dec 2014 17:23:05 +0100 Subject: [PATCH 8/8] if the data hasn't been loaded, show "Loading..." as summary for any node, not just root node --- .../com/intellij/coverage/view/JavaCoverageViewExtension.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java b/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java index 81abc84bde0e..e7f780a99967 100644 --- a/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java +++ b/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java @@ -32,6 +32,7 @@ public class JavaCoverageViewExtension extends CoverageViewExtension { @Override public String getSummaryForNode(AbstractTreeNode node) { + if (!myCoverageViewManager.isReady()) return "Loading..."; final String coverageInformationString = myAnnotator .getPackageCoverageInformationString((PsiPackage)node.getValue(), null, myCoverageDataManager, myStateBean.myFlattenPackages); return getNotCoveredMessage(coverageInformationString) + " in package \'" + node.toString() + "\'";