From 72eb77b4bc2c5f61a32e19064aa755c778474545 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 6 Dec 2012 17:41:19 +0400 Subject: [PATCH 1/9] IDEA-96743 Gradle: Avoid unnecessary refresh on initial project import 1. Project entities import is performed in a way that 'auto-refresh on project roots change' is not triggered; 2. Legacy code is removed; --- .../manage/GradleContentRootManager.java | 93 ++- .../manage/GradleDependencyManager.java | 191 +++--- .../gradle/manage/GradleLibraryManager.java | 61 +- .../gradle/manage/GradleModuleManager.java | 62 +- .../gradle/manage/GradleModulesImporter.java | 564 ------------------ .../manage/GradleProjectImportBuilder.java | 170 ++++-- .../GradleAdjustImportSettingsStep.java | 7 +- .../remote/impl/GradleApiFacadeImpl.java | 2 +- .../sync/GradleProjectStructureHelper.java | 32 +- .../gradle/task/AbstractGradleTask.java | 4 +- .../plugins/gradle/util/GradleUtil.java | 35 +- 11 files changed, 360 insertions(+), 861 deletions(-) delete mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModulesImporter.java diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleContentRootManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleContentRootManager.java index 1d40834f1a14..d062f821f762 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleContentRootManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleContentRootManager.java @@ -1,18 +1,18 @@ package org.jetbrains.plugins.gradle.manage; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.model.gradle.GradleContentRoot; import org.jetbrains.plugins.gradle.model.gradle.SourceType; import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot; import org.jetbrains.plugins.gradle.util.GradleUtil; +import java.util.Collection; import java.util.Collections; /** @@ -28,76 +28,59 @@ public class GradleContentRootManager { } @SuppressWarnings("MethodMayBeStatic") - public void importContentRoots(@NotNull final Iterable contentRoots, @NotNull final Module module) { - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - doImportContentRoots(contentRoots, module); - } - }); - } - - private static void doImportContentRoots(@NotNull final Iterable contentRoots, @NotNull final Module module) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void importContentRoots(@NotNull final Collection contentRoots, @NotNull final Module module) { + if (contentRoots.isEmpty()) { + return; + } + GradleUtil.executeProjectChangeAction(module.getProject(), contentRoots, new Runnable() { @Override public void run() { final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); final ModifiableRootModel model = moduleRootManager.getModifiableModel(); - GradleUtil.executeProjectChangeAction(module.getProject(), contentRoots, new Runnable() { - @Override - public void run() { - try { - for (GradleContentRoot contentRoot : contentRoots) { - ContentEntry contentEntry = model.addContentEntry(toVfsUrl(contentRoot.getRootPath())); - for (String path : contentRoot.getPaths(SourceType.SOURCE)) { - contentEntry.addSourceFolder(toVfsUrl(path), false); - } - for (String path : contentRoot.getPaths(SourceType.TEST)) { - contentEntry.addSourceFolder(toVfsUrl(path), true); - } - for (String path : contentRoot.getPaths(SourceType.EXCLUDED)) { - contentEntry.addExcludeFolder(toVfsUrl(path)); - } - } + try { + for (GradleContentRoot contentRoot : contentRoots) { + ContentEntry contentEntry = model.addContentEntry(toVfsUrl(contentRoot.getRootPath())); + for (String path : contentRoot.getPaths(SourceType.SOURCE)) { + contentEntry.addSourceFolder(toVfsUrl(path), false); + } + for (String path : contentRoot.getPaths(SourceType.TEST)) { + contentEntry.addSourceFolder(toVfsUrl(path), true); + } + for (String path : contentRoot.getPaths(SourceType.EXCLUDED)) { + contentEntry.addExcludeFolder(toVfsUrl(path)); } - finally { - model.commit(); - } } - }); + } + finally { + model.commit(); + } } }); } - + private static String toVfsUrl(@NotNull String path) { return LocalFileSystem.PROTOCOL_PREFIX + path; } @SuppressWarnings("MethodMayBeStatic") - public void removeContentRoots(@NotNull final Iterable contentRoots) { - UIUtil.invokeLaterIfNeeded(new Runnable() { + public void removeContentRoots(@NotNull final Collection contentRoots) { + if (contentRoots.isEmpty()) { + return; + } + Project project = contentRoots.iterator().next().getModule().getProject(); + GradleUtil.executeProjectChangeAction(project, contentRoots, new Runnable() { @Override public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - for (final ModuleAwareContentRoot contentRoot : contentRoots) { - GradleUtil.executeProjectChangeAction(contentRoot.getModule().getProject(), contentRoot, new Runnable() { - @Override - public void run() { - final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(contentRoot.getModule()); - ModifiableRootModel model = moduleRootManager.getModifiableModel(); - try { - model.removeContentEntry(contentRoot); - } - finally { - model.commit(); - } - } - }); - } + for (ModuleAwareContentRoot contentRoot : contentRoots) { + final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(contentRoot.getModule()); + ModifiableRootModel model = moduleRootManager.getModifiableModel(); + try { + model.removeContentEntry(contentRoot); } - }); + finally { + model.commit(); + } + } } }); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleDependencyManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleDependencyManager.java index 4fa493f1c634..f8ec9ac9121b 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleDependencyManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleDependencyManager.java @@ -1,20 +1,16 @@ package org.jetbrains.plugins.gradle.manage; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.config.PlatformFacade; import org.jetbrains.plugins.gradle.model.gradle.*; import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper; import org.jetbrains.plugins.gradle.util.GradleUtil; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; /** * Thread-safe. @@ -23,17 +19,19 @@ import java.util.List; * @since 2/7/12 3:23 PM */ public class GradleDependencyManager { - - @NotNull private final PlatformFacade myPlatformFacade; - public GradleDependencyManager(@NotNull PlatformFacade platformFacade) { + @NotNull private final PlatformFacade myPlatformFacade; + @NotNull private final GradleLibraryManager myLibraryManager; + + public GradleDependencyManager(@NotNull PlatformFacade platformFacade, @NotNull GradleLibraryManager manager) { myPlatformFacade = platformFacade; + myLibraryManager = manager; } public void importDependency(@NotNull GradleDependency dependency, @NotNull Module module) { importDependencies(Collections.singleton(dependency), module); } - + public void importDependencies(@NotNull Iterable dependencies, @NotNull Module module) { final List moduleDependencies = new ArrayList(); final List libraryDependencies = new ArrayList(); @@ -56,19 +54,12 @@ public class GradleDependencyManager { } @SuppressWarnings("MethodMayBeStatic") - public void importModuleDependencies(@NotNull final Iterable dependencies, @NotNull final Module module) { - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - doImportModuleDependencies(dependencies, module); - } - }); - } - - private static void doImportModuleDependencies(@NotNull final Iterable dependencies, - @NotNull final Module module) - { - ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void importModuleDependencies(@NotNull final Collection dependencies, @NotNull final Module module) { + if (dependencies.isEmpty()) { + return; + } + + GradleUtil.executeProjectChangeAction(module.getProject(), dependencies, new Runnable() { @Override public void run() { ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); @@ -77,12 +68,20 @@ public class GradleDependencyManager { final GradleProjectStructureHelper projectStructureHelper = module.getProject().getComponent(GradleProjectStructureHelper.class); for (GradleModuleDependency dependency : dependencies) { final String moduleName = dependency.getName(); - final Module intellijModuleDependency = projectStructureHelper.findIntellijModule(moduleName); - if (intellijModuleDependency == null) { + final Module intellijModule = projectStructureHelper.findIntellijModule(moduleName); + if (intellijModule == null) { assert false; continue; } - final ModuleOrderEntry orderEntry = moduleRootModel.addModuleOrderEntry(intellijModuleDependency); + else if (intellijModule.equals(module)) { + // Gradle api returns recursive module dependencies (a module depends on itself) for 'gradle' project. + continue; + } + + ModuleOrderEntry orderEntry = projectStructureHelper.findIntellijModuleDependency(dependency, moduleRootModel); + if (orderEntry == null) { + orderEntry = moduleRootModel.addModuleOrderEntry(intellijModule); + } orderEntry.setScope(dependency.getScope()); orderEntry.setExported(dependency.isExported()); } @@ -93,97 +92,79 @@ public class GradleDependencyManager { } }); } - + public void importLibraryDependencies(@NotNull final Iterable dependencies, @NotNull final Module module) { - final List infos = new ArrayList(); - final LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject()); - for (GradleLibraryDependency dependency : dependencies) { - final Library library = libraryTable.getLibraryByName(dependency.getName()); - if (library != null) { - infos.add(new LibraryDependencyInfo(library, dependency.getScope(), dependency.isExported())); - } - } - doImportLibraryDependencies(infos, module); - } - - private static void doImportLibraryDependencies(@NotNull final Iterable infos, @NotNull final Module module) { - UIUtil.invokeLaterIfNeeded(new Runnable() { + GradleUtil.executeProjectChangeAction(module.getProject(), dependencies, new Runnable() { @Override public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - GradleUtil.executeProjectChangeAction(module.getProject(), infos, new Runnable() { - @Override - public void run() { - ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); - final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); - try { - for (LibraryDependencyInfo info : infos) { - LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(info.library); - orderEntry.setExported(info.exported); - orderEntry.setScope(info.scope); - } - } - finally { - moduleRootModel.commit(); - } - } - }); + LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject()); + Set librariesToImport = new HashSet(); + for (GradleLibraryDependency dependency : dependencies) { + final Library library = libraryTable.getLibraryByName(dependency.getName()); + if (library == null) { + librariesToImport.add(dependency.getTarget()); } - }); + } + if (!librariesToImport.isEmpty()) { + myLibraryManager.importLibraries(librariesToImport, module.getProject()); + } + + for (GradleLibraryDependency dependency : dependencies) { + GradleProjectStructureHelper helper = module.getProject().getComponent(GradleProjectStructureHelper.class); + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); + try { + libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject()); + final Library library = libraryTable.getLibraryByName(dependency.getName()); + if (library == null) { + assert false; + continue; + } + LibraryOrderEntry orderEntry = helper.findIntellijLibraryDependency(dependency.getName(), moduleRootModel); + if (orderEntry == null) { + // We need to get the most up-to-date Library object due to our project model restrictions. + orderEntry = moduleRootModel.addLibraryEntry(library); + } + orderEntry.setExported(dependency.isExported()); + orderEntry.setScope(dependency.getScope()); + } + finally { + moduleRootModel.commit(); + } + } } }); } @SuppressWarnings("MethodMayBeStatic") - public void removeDependencies(@NotNull final Iterable dependencies) { - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - for (final ExportableOrderEntry dependency : dependencies) { - final Module module = dependency.getOwnerModule(); - GradleUtil.executeProjectChangeAction(module.getProject(), dependency, new Runnable() { - @Override - public void run() { - ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); - final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); - try { - // The thing is that intellij created order entry objects every time new modifiable model is created, - // that's why we can't use target dependency object as is but need to get a reference to the current - // entry object from the model instead. - for (OrderEntry entry : moduleRootModel.getOrderEntries()) { - if (entry.getPresentableName().equals(dependency.getPresentableName())) { - moduleRootModel.removeOrderEntry(entry); - break; - } - } - } - finally { - moduleRootModel.commit(); - } - } - }); + public void removeDependencies(@NotNull final Collection dependencies) { + if (dependencies.isEmpty()) { + return; + } + + for (final ExportableOrderEntry dependency : dependencies) { + final Module module = dependency.getOwnerModule(); + GradleUtil.executeProjectChangeAction(module.getProject(), dependency, new Runnable() { + @Override + public void run() { + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); + try { + // The thing is that intellij created order entry objects every time new modifiable model is created, + // that's why we can't use target dependency object as is but need to get a reference to the current + // entry object from the model instead. + for (OrderEntry entry : moduleRootModel.getOrderEntries()) { + if (entry.getPresentableName().equals(dependency.getPresentableName())) { + moduleRootModel.removeOrderEntry(entry); + break; + } } } - }); - } - }); - } - - private static class LibraryDependencyInfo { - - @NotNull public final Library library; - @NotNull public final DependencyScope scope; - public final boolean exported; - - LibraryDependencyInfo(@NotNull Library library, @NotNull DependencyScope scope, boolean exported) { - this.library = library; - this.scope = scope; - this.exported = exported; + finally { + moduleRootModel.commit(); + } + } + }); } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleLibraryManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleLibraryManager.java index b749ebebb165..c0b38fae255e 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleLibraryManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleLibraryManager.java @@ -1,23 +1,21 @@ package org.jetbrains.plugins.gradle.manage; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.JavadocOrderRootType; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; -import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.NotNullFunction; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.config.PlatformFacade; import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary; import org.jetbrains.plugins.gradle.model.gradle.LibraryPathType; import org.jetbrains.plugins.gradle.util.GradleLog; +import org.jetbrains.plugins.gradle.util.GradleUtil; import java.io.File; import java.util.*; @@ -34,8 +32,13 @@ public class GradleLibraryManager { myPlatformFacade = platformFacade; } - @NotNull - public Library importLibrary(@NotNull final GradleLibrary library, @NotNull final Project project) { + public void importLibraries(@NotNull Collection libraries, @NotNull Project project) { + for (GradleLibrary library : libraries) { + importLibrary(library, project); + } + } + + public void importLibrary(@NotNull final GradleLibrary library, @NotNull final Project project) { Map> libraryFiles = new HashMap>(); for (LibraryPathType pathType : LibraryPathType.values()) { final Set paths = library.getPaths(pathType); @@ -50,47 +53,22 @@ public class GradleLibraryManager { } })); } - return importLibrary(library.getName(), libraryFiles, project); + importLibrary(library.getName(), libraryFiles, project); } - @NotNull - public Library importLibrary(@NotNull final String libraryName, - @NotNull final Map> libraryFiles, - @NotNull final Project project) + public void importLibrary(@NotNull final String libraryName, + @NotNull final Map> libraryFiles, + @NotNull final Project project) { - final Ref result = new Ref(); - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - final GradleProjectEntityChangeListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC); - publisher.onChangeStart(libraryName); - try { - result.set(doImportLibrary(libraryName, libraryFiles, project)); - } - finally { - publisher.onChangeEnd(libraryName); - } - } - }); - return result.get(); - } - - @NotNull - private Library doImportLibrary(@NotNull final String libraryName, - @NotNull final Map> libraryFiles, - @NotNull Project project) - { - // Is assumed to be called from the EDT. - final LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(project); - final Ref result = new Ref(); - ApplicationManager.getApplication().runWriteAction(new Runnable() { + GradleUtil.executeProjectChangeAction(project, libraryName, new Runnable() { @Override public void run() { + // Is assumed to be called from the EDT. + final LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(project); final LibraryTable.ModifiableModel projectLibraryModel = libraryTable.getModifiableModel(); final Library intellijLibrary; try { intellijLibrary = projectLibraryModel.createLibrary(libraryName); - result.set(intellijLibrary); } finally { projectLibraryModel.commit(); @@ -104,7 +82,6 @@ public class GradleLibraryManager { } } }); - return result.get(); } private static void registerPaths(@NotNull final Map> libraryFiles, @@ -115,9 +92,9 @@ public class GradleLibraryManager { for (File file : entry.getValue()) { VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(file); if (virtualFile == null) { - GradleLog.LOG.warn( - String.format("Can't find %s of the library '%s' at path '%s'", entry.getKey(), libraryName, file.getAbsolutePath()) - ); + //GradleLog.LOG.warn( + // String.format("Can't find %s of the library '%s' at path '%s'", entry.getKey(), libraryName, file.getAbsolutePath()) + //); continue; } if (virtualFile.isDirectory()) { @@ -137,7 +114,7 @@ public class GradleLibraryManager { } } - public void removeLibraries(@NotNull List libraries) { + public void removeLibraries(@NotNull List libraries) { // TODO den implement //LibraryTable table = library.getTable(); //table.removeLibrary(library); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModuleManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModuleManager.java index 0ffc42f734cb..916ee0057597 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModuleManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModuleManager.java @@ -16,6 +16,7 @@ import org.jetbrains.plugins.gradle.util.GradleLog; import org.jetbrains.plugins.gradle.util.GradleUtil; import java.io.File; +import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -50,7 +51,13 @@ public class GradleModuleManager { importModules(Collections.singleton(module), project, false); } - public void importModules(@NotNull final Iterable modules, @NotNull final Project project, final boolean recursive) { + public void importModules(@NotNull final Collection modules, + @NotNull final Project project, + final boolean recursive) + { + if (modules.isEmpty()) { + return; + } if (!project.isInitialized()) { myAlarm.addRequest(new ImportModulesTask(project, modules, recursive), PROJECT_INITIALISATION_DELAY_MS); return; @@ -65,7 +72,7 @@ public class GradleModuleManager { @Override public void run() { final ModuleManager moduleManager = ModuleManager.getInstance(project); - final GradleProjectEntityChangeListener publisher + final GradleProjectEntityChangeListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC); for (GradleModule module : modules) { publisher.onChangeStart(module); @@ -121,7 +128,7 @@ public class GradleModuleManager { }); } - private static void removeExistingModulesConfigs(@NotNull Iterable modules) { + private static void removeExistingModulesConfigs(@NotNull Collection modules) { for (GradleModule module : modules) { // Remove existing '*.iml' file if necessary. final String moduleFilePath = module.getModuleFilePath(); @@ -136,43 +143,37 @@ public class GradleModuleManager { } @SuppressWarnings("MethodMayBeStatic") - public void removeModules(@NotNull final Iterable modules) { - UIUtil.invokeLaterIfNeeded(new Runnable() { + public void removeModules(@NotNull final Collection modules) { + if (modules.isEmpty()) { + return; + } + Project project = modules.iterator().next().getProject(); + GradleUtil.executeProjectChangeAction(project, modules, new Runnable() { @Override public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - for (final Module module : modules) { - GradleUtil.executeProjectChangeAction(module.getProject(), module, new Runnable() { - @Override - public void run() { - ModuleManager moduleManager = ModuleManager.getInstance(module.getProject()); - String path = module.getModuleFilePath(); - moduleManager.disposeModule(module); - File file = new File(path); - if (file.isFile()) { - boolean success = file.delete(); - if (!success) { - GradleLog.LOG.warn("Can't remove module file at '" + path + "'"); - } - } - } - }); - } + for (Module module : modules) { + ModuleManager moduleManager = ModuleManager.getInstance(module.getProject()); + String path = module.getModuleFilePath(); + moduleManager.disposeModule(module); + File file = new File(path); + if (file.isFile()) { + boolean success = file.delete(); + if (!success) { + GradleLog.LOG.warn("Can't remove module file at '" + path + "'"); + } } - }); + } } }); } private class ImportModulesTask implements Runnable { - private final Project myProject; - private final Iterable myModules; - private final boolean myRecursive; + private final Project myProject; + private final Collection myModules; + private final boolean myRecursive; - ImportModulesTask(@NotNull Project project, @NotNull Iterable modules, boolean recursive) { + ImportModulesTask(@NotNull Project project, @NotNull Collection modules, boolean recursive) { myProject = project; myModules = modules; myRecursive = recursive; @@ -192,5 +193,4 @@ public class GradleModuleManager { importModules(myModules, myProject, myRecursive); } } - } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModulesImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModulesImporter.java deleted file mode 100644 index f55af6110203..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleModulesImporter.java +++ /dev/null @@ -1,564 +0,0 @@ -package org.jetbrains.plugins.gradle.manage; - -import com.intellij.openapi.application.*; -import com.intellij.openapi.module.ModifiableModuleModel; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.module.StdModuleTypes; -import com.intellij.openapi.roots.impl.ModifiableModelCommitter; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.Task; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.*; -import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; -import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.roots.libraries.LibraryTable; -import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.Alarm; -import com.intellij.util.containers.hash.HashMap; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.gradle.model.gradle.*; -import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesModel; -import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask; -import org.jetbrains.plugins.gradle.util.GradleBundle; -import org.jetbrains.plugins.gradle.util.GradleLog; - -import java.io.File; -import java.util.*; -import java.util.concurrent.TimeUnit; - -/** - * Encapsulates functionality of creating IntelliJ IDEA modules on the basis of {@link GradleModule gradle modules}. - *

- * Not thread-safe. - * - * @author Denis Zhdanov - * @since 8/26/11 10:01 AM - */ -// TODO den remove -public class GradleModulesImporter { - - private static final Map LIBRARY_ROOT_MAPPINGS - = new EnumMap(LibraryPathType.class); - static { - LIBRARY_ROOT_MAPPINGS.put(LibraryPathType.BINARY, OrderRootType.CLASSES); - LIBRARY_ROOT_MAPPINGS.put(LibraryPathType.SOURCE, OrderRootType.SOURCES); - LIBRARY_ROOT_MAPPINGS.put(LibraryPathType.DOC, JavadocOrderRootType.getInstance()); - assert LibraryPathType.values().length == LIBRARY_ROOT_MAPPINGS.size(); - } - - /** - * We can't modify project modules (add/remove) until it's initialised, so, we delay that activity. Current constant - * holds number of milliseconds to wait between 'after project initialisation' processing attempts. - */ - private static final int PROJECT_INITIALISATION_DELAY_MS = (int)TimeUnit.SECONDS.toMillis(1); - - private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); - - /** - * Entry point for the whole 'import modules' procedure. - * - * @param modules module info containers received from the gradle api - * @param project project that should host the modules - * @param model modules model - * @param gradleProjectPath file system path to the gradle project file being imported - * @return mappings between the given gradle modules and newly created intellij modules - */ - @NotNull - public Map importModules(@NotNull final Iterable modules, @Nullable final Project project, - @Nullable final ModifiableModuleModel model, @NotNull String gradleProjectPath) - { - if (project == null) { - return Collections.emptyMap(); - } - removeExistingModulesSettings(modules); - if (!project.isInitialized()) { - myAlarm.addRequest(new ImportModulesTask(project, modules, gradleProjectPath), PROJECT_INITIALISATION_DELAY_MS); - return Collections.emptyMap(); - } - if (model == null) { - return Collections.emptyMap(); - } - return importModules(modules, model, project, gradleProjectPath); - } - - private static void removeExistingModulesSettings(@NotNull Iterable modules) { - for (GradleModule module : modules) { - // Remove existing '*.iml' file if necessary. - final String moduleFilePath = module.getModuleFilePath(); - File file = new File(moduleFilePath); - if (file.isFile()) { - boolean success = file.delete(); - if (!success) { - GradleLog.LOG.warn("Can't remove existing module file at '" + moduleFilePath + "'"); - } - } - } - } - - public Map importModules(@NotNull final Iterable modules, - @NotNull final ModifiableModuleModel model, - @NotNull final Project intellijProject, - @NotNull final String gradleProjectPath) - { - final Map result = new HashMap(); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - Application application = ApplicationManager.getApplication(); - AccessToken writeLock = application.acquireWriteActionLock(getClass()); - try { - final List rootModels = new ArrayList(); - final GradleProjectEntityChangeListener publisher = - intellijProject.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC); - for (GradleModule module : modules) { - publisher.onChangeStart(module); - } - try { - Map moduleMappings = doImportModules(modules, model, rootModels); - result.putAll(moduleMappings); - myAlarm.cancelAllRequests(); - myAlarm.addRequest( - new SetupExternalLibrariesTask(moduleMappings, gradleProjectPath, intellijProject), - PROJECT_INITIALISATION_DELAY_MS - ); - } - finally { - ModifiableRootModel[] modelsAsArray = rootModels.toArray(new ModifiableRootModel[rootModels.size()]); - ModifiableModelCommitter.multiCommit(modelsAsArray, model); - for (GradleModule module : modules) { - publisher.onChangeEnd(module); - } - } - } - finally { - writeLock.finish(); - } - } - }); - return result; - } - - /** - * Actual implementation of {@link #importModules(Iterable, Project, ModifiableModuleModel, String)}. - * Insists on all arguments to be ready to use. - * - * @param modules modules to import - * @param model modules model - * @param rootModels holder for the module root modules. Is expected to be populated during the current method processing - * @return mappings between the given gradle modules and corresponding intellij modules - */ - @NotNull - @SuppressWarnings("MethodMayBeStatic") - private Map doImportModules(@NotNull Iterable modules, - @NotNull ModifiableModuleModel model, - @NotNull List rootModels) - { - Map result = new HashMap(); - for (GradleModule moduleToImport : modules) { - Module createdModule = createModule(moduleToImport, model); - result.put(moduleToImport, createdModule); - } - for (GradleModule moduleToImport : modules) { - ModifiableRootModel rootModel = configureModule(moduleToImport, result); - rootModels.add(rootModel); - } - return result; - } - - /** - * We need to create module objects for all modules at first and then configure them. That is necessary for setting up - * module dependencies. - * - * @param module gradle module to import - * @param model module model - * @return newly created IJ module - */ - @NotNull - private static Module createModule(@NotNull GradleModule module, @NotNull ModifiableModuleModel model) { - Application application = ApplicationManager.getApplication(); - application.assertWriteAccessAllowed(); - final String moduleFilePath = module.getModuleFilePath(); - return model.newModule(moduleFilePath, StdModuleTypes.JAVA.getId()); - } - - /** - * Applies module settings received from the gradle api (encapsulate at the given {@link GradleModule} object) to the - * target intellij module (retrieved from the given module mappings). - * - * @param module target gradle module which corresponding intellij module should be configured - * @param modules gradle module to intellij modules mappings. Is assumed to have a value for the given gradle modules used as a key - * @return module roots model used during configuration - */ - @NotNull - private static ModifiableRootModel configureModule(@NotNull GradleModule module, @NotNull Map modules) { - Application application = ApplicationManager.getApplication(); - application.assertWriteAccessAllowed(); - - ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(modules.get(module)); - ModifiableRootModel rootModel = moduleRootManager.getModifiableModel(); - configureModule(module, rootModel, modules); - return rootModel; - } - - /** - * Contains actual logic of {@link #configureModule(GradleModule, Map)}. - * - * @param module target module settings holder - * @param model intellij module setting manager - * @param modules modules mappings - */ - private static void configureModule(@NotNull GradleModule module, @NotNull final ModifiableRootModel model, - @NotNull final Map modules) - { - // Ensure that dependencies are clear. - final Object key = new Object(); - final Object dummy = new Object(); - RootPolicy policy = new RootPolicy() { - @Override - public Object visitModuleSourceOrderEntry(ModuleSourceOrderEntry moduleSourceOrderEntry, Object value) { - return key; - } - }; - for (OrderEntry orderEntry : model.getOrderEntries()) { - // Don't remove 'module source' order entry (configured automatically on module creation). - if (key != orderEntry.accept(policy, dummy)) { - model.removeOrderEntry(orderEntry); - } - } - - // Configure SDK. - model.inheritSdk(); - - // Compile output. - CompilerModuleExtension compilerExtension = model.getModuleExtension(CompilerModuleExtension.class); - compilerExtension.inheritCompilerOutputPath(module.isInheritProjectCompileOutputPath()); - if (!module.isInheritProjectCompileOutputPath()) { - String compileOutputPath = module.getCompileOutputPath(SourceType.SOURCE); - String testCompileOutputPath = module.getCompileOutputPath(SourceType.TEST); - if (StringUtil.isEmpty(compileOutputPath) || StringUtil.isEmpty(testCompileOutputPath)) { - GradleLog.LOG.warn(String.format( - "Module '%s' doesn't inherit project compile output path but has incomplete local setup. Falling back to the project " - + "compile output path. Local compile output path: '%s', local test compile output path: '%s'", - module.getName(), compileOutputPath, testCompileOutputPath - )); - compilerExtension.inheritCompilerOutputPath(true); - } - else { - compilerExtension.setCompilerOutputPath(compileOutputPath); - compilerExtension.setCompilerOutputPathForTests(testCompileOutputPath); - } - } - - // Content roots. - for (GradleContentRoot contentRoot : module.getContentRoots()) { - ContentEntry contentEntry = model.addContentEntry(toVfsUrl(contentRoot.getRootPath())); - for (String path : contentRoot.getPaths(SourceType.SOURCE)) { - contentEntry.addSourceFolder(toVfsUrl(path), false); - } - for (String path : contentRoot.getPaths(SourceType.TEST)) { - contentEntry.addSourceFolder(toVfsUrl(path), true); - } - for (String path : contentRoot.getPaths(SourceType.EXCLUDED)) { - contentEntry.addExcludeFolder(toVfsUrl(path)); - } - } - - // Module dependencies. - for (GradleDependency dependency : module.getDependencies()) { - dependency.invite(new GradleEntityVisitorAdapter() { - @Override - public void visit(@NotNull GradleModuleDependency dependency) { - ModuleOrderEntry orderEntry = model.addModuleOrderEntry(modules.get(dependency.getTarget())); - orderEntry.setExported(dependency.isExported()); - orderEntry.setScope(dependency.getScope()); - } - }); - } - } - - /** - * Resolves (downloads if necessary) external libraries necessary for the gradle project located at the given path and configures - * them for the corresponding intellij project. - *

- * Note: is assumed to be executed under write action. - * - * @param moduleMappings gradle-intellij module mappings - * @param intellijProject intellij project for the target gradle project - * @param gradleProjectPath file system path to the target gradle project - */ - private static void setupLibraries(@NotNull final Map moduleMappings, - @NotNull final Project intellijProject, - @NotNull final String gradleProjectPath) - { - final Ref gradleProjectRef = new Ref(); - final Ref libraryToPreserve = new Ref(); - - final Runnable setupExternalDependenciesTask = new Runnable() { - @Override - public void run() { - final GradleProject gradleProject = gradleProjectRef.get(); - if (gradleProject == null) { - return; - } - - Application application = ApplicationManager.getApplication(); - AccessToken writeLock = application.acquireWriteActionLock(getClass()); - try { - doSetupLibraries(moduleMappings, gradleProject, intellijProject, libraryToPreserve.get()); - } - finally { - writeLock.finish(); - } - - if (intellijProject.isDisposed()) { - return; - } - - // Force refresh the infrastructure in order to apply newly introduce intellij project structure changes - final GradleProjectStructureChangesModel changesModel = intellijProject.getComponent(GradleProjectStructureChangesModel.class); - if (changesModel != null) { - final GradleProject project = changesModel.getGradleProject(); - if (project != null) { - changesModel.update(project); - } - } - } - }; - - final Runnable resolveDependenciesTask = new Runnable() { - @Override - public void run() { - ProgressManager.getInstance().run( - new Task.Backgroundable(intellijProject, GradleBundle.message("gradle.library.resolve.progress.text"), false) { - @Override - public void run(@NotNull final ProgressIndicator indicator) { - GradleResolveProjectTask task = new GradleResolveProjectTask(intellijProject, gradleProjectPath, true); - task.execute(indicator); - GradleProject projectWithResolvedLibraries = task.getGradleProject(); - gradleProjectRef.set(projectWithResolvedLibraries); - ApplicationManager.getApplication().invokeLater(setupExternalDependenciesTask, ModalityState.NON_MODAL); - } - }); - } - }; - - UIUtil.invokeLaterIfNeeded(resolveDependenciesTask); - } - - private static void doSetupLibraries(@NotNull Map moduleMappings, - @NotNull GradleProject gradleProject, - @NotNull Project intellijProject, - @Nullable Library libraryToPreserve) { - if (intellijProject.isDisposed()) { - return; - } - Application application = ApplicationManager.getApplication(); - application.assertWriteAccessAllowed(); - - LibraryTable projectLibraryTable = ProjectLibraryTable.getInstance(intellijProject); - if (projectLibraryTable == null) { - GradleLog.LOG.warn( - "Can't resolve external dependencies of the target gradle project (" + intellijProject + "). Reason: project " - + "library table is undefined" - ); - return; - } - LibraryTable.ModifiableModel model = projectLibraryTable.getModifiableModel(); - // Clean existing libraries (if any). - try { - for (Library library : model.getLibraries()) { - if (libraryToPreserve != library) { - model.removeLibrary(library); - } - } - } - finally { - model.commit(); - } - - model = projectLibraryTable.getModifiableModel(); - List modelsToCommit = new ArrayList(); - Map libraryMappings = registerProjectLibraries(gradleProject, model); - final GradleProjectEntityChangeListener publisher - = intellijProject.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC); - try { - if (libraryMappings == null) { - return; - } - for (GradleLibrary library : libraryMappings.keySet()) { - publisher.onChangeStart(library); - } - modelsToCommit.addAll(configureModulesLibraryDependencies(moduleMappings, libraryMappings, gradleProject)); - } - finally { - model.commit(); - ProjectRootManager projectRootManager = ProjectRootManager.getInstance(intellijProject); - ModifiableRootModel[] modelsAsArray = modelsToCommit.toArray(new ModifiableRootModel[modelsToCommit.size()]); - if (modelsAsArray.length > 0) { - ModifiableModelCommitter.multiCommit(modelsAsArray, ModuleManager.getInstance(modelsAsArray[0].getProject()).getModifiableModel()); - } - if (libraryMappings != null) { - for (GradleLibrary library : libraryMappings.keySet()) { - publisher.onChangeEnd(library); - } - } - } - } - - /** - * Registers {@link GradleProject#getLibraries() libraries} of the given gradle project at the intellij project. - * - * @param gradleProject target gradle project being imported - * @param librariesModel model that manages project libraries - * @return mapping between libraries of the given gradle and intellij projects - */ - @Nullable - private static Map registerProjectLibraries(@NotNull GradleProject gradleProject, - @NotNull LibraryTable.ModifiableModel librariesModel) - { - Map libraryMappings = new HashMap(); - for (GradleLibrary gradleLibrary : gradleProject.getLibraries()) { - Library intellijLibrary = librariesModel.createLibrary(gradleLibrary.getName()); - libraryMappings.put(gradleLibrary, intellijLibrary); - Library.ModifiableModel model = intellijLibrary.getModifiableModel(); - try { - registerPath(gradleLibrary, model); - } - finally { - model.commit(); - } - } - return libraryMappings; - } - - private static Collection configureModulesLibraryDependencies( - @NotNull Map moduleMappings, - @NotNull final Map libraryMappings, - @NotNull GradleProject gradleProject) - { - List result = new ArrayList(); - for (GradleModule gradleModule : gradleProject.getModules()) { - Module intellijModule = moduleMappings.get(gradleModule); - if (intellijModule == null) { - GradleLog.LOG.warn(String.format( - "Can't find intellij module for the gradle module '%s'. Registered mappings: %s", gradleModule, moduleMappings - )); - continue; - } - ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(intellijModule); - final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); - result.add(moduleRootModel); - GradleEntityVisitor visitor = new GradleEntityVisitorAdapter() { - @Override - public void visit(@NotNull GradleLibraryDependency dependency) { - GradleLibrary gradleLibrary = dependency.getTarget(); - Library intellijLibrary = libraryMappings.get(gradleLibrary); - if (intellijLibrary == null) { - GradleLog.LOG.warn(String.format( - "Can't find registered intellij library for gradle library '%s'. Registered mappings: %s", gradleLibrary, libraryMappings - )); - return; - } - LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(intellijLibrary); - orderEntry.setExported(dependency.isExported()); - orderEntry.setScope(dependency.getScope()); - } - }; - for (GradleDependency dependency : gradleModule.getDependencies()) { - dependency.invite(visitor); - } - } - return result; - } - - private static void registerPath(@NotNull GradleLibrary gradleLibrary, @NotNull Library.ModifiableModel model) { - for (LibraryPathType pathType : LibraryPathType.values()) { - for (String path : gradleLibrary.getPaths(pathType)) { - VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(new File(path)); - if (virtualFile == null) { - GradleLog.LOG.warn(String.format("Can't find %s of the library '%s' at path '%s'", pathType, gradleLibrary.getName(), path)); - continue; - } - if (virtualFile.isDirectory()) { - model.addRoot(virtualFile, LIBRARY_ROOT_MAPPINGS.get(pathType)); - } - else { - VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(virtualFile); - if (jarRoot == null) { - GradleLog.LOG.warn(String.format( - "Can't parse contents of the jar file at path '%s' for the library '%s''", path, gradleLibrary.getName() - )); - continue; - } - model.addRoot(jarRoot, LIBRARY_ROOT_MAPPINGS.get(pathType)); - } - } - } - } - - private static String toVfsUrl(@NotNull String path) { - return LocalFileSystem.PROTOCOL_PREFIX + path; - } - - private class ImportModulesTask implements Runnable { - - private final Project myProject; - private final Iterable myModules; - private final String myGradleProjectPath; - - ImportModulesTask(@NotNull Project project, @NotNull Iterable modules, @NotNull String gradleProjectPath) { - myProject = project; - myModules = modules; - myGradleProjectPath = gradleProjectPath; - } - - @Override - public void run() { - myAlarm.cancelAllRequests(); - if (!myProject.isInitialized()) { - myAlarm.addRequest( - new ImportModulesTask(myProject, myModules, myGradleProjectPath), - PROJECT_INITIALISATION_DELAY_MS - ); - return; - } - - final ModifiableModuleModel model = new ReadAction() { - protected void run(Result result) throws Throwable { - result.setResult(ModuleManager.getInstance(myProject).getModifiableModel()); - } - }.execute().getResultObject(); - - importModules(myModules, model, myProject, myGradleProjectPath); - } - } - - private static class SetupExternalLibrariesTask implements Runnable { - - private final Map myModules; - private final String myGradleProjectPath; - private final Project myIntellijProject; - - SetupExternalLibrariesTask(@NotNull Map modules, - @NotNull String gradleProjectPath, - @NotNull Project intellijProject) - { - myModules = modules; - myGradleProjectPath = gradleProjectPath; - myIntellijProject = intellijProject; - } - - @Override - public void run() { - setupLibraries(myModules, myIntellijProject, myGradleProjectPath); - } - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleProjectImportBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleProjectImportBuilder.java index 1dc7cbe3fed5..33edefceeefa 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleProjectImportBuilder.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/GradleProjectImportBuilder.java @@ -4,11 +4,18 @@ import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.projectRoots.JavaSdk; import com.intellij.openapi.projectRoots.SdkTypeId; import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Ref; @@ -16,14 +23,17 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.packaging.artifacts.ModifiableArtifactModel; import com.intellij.pom.java.LanguageLevel; import com.intellij.projectImport.ProjectImportBuilder; +import com.intellij.util.ui.UIUtil; import icons.GradleIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.config.GradleConfigurable; import org.jetbrains.plugins.gradle.config.GradleSettings; -import org.jetbrains.plugins.gradle.model.gradle.GradleEntity; +import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary; import org.jetbrains.plugins.gradle.model.gradle.GradleModule; import org.jetbrains.plugins.gradle.model.gradle.GradleProject; +import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper; +import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask; import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleConstants; import org.jetbrains.plugins.gradle.util.GradleLog; @@ -31,7 +41,10 @@ import org.jetbrains.plugins.gradle.util.GradleUtil; import javax.swing.*; import java.io.File; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; /** * GoF builder for gradle-backed projects. @@ -42,12 +55,22 @@ import java.util.*; @SuppressWarnings("MethodMayBeStatic") public class GradleProjectImportBuilder extends ProjectImportBuilder { - /** @see #setModuleMappings(Map) */ - private final Map myModuleMappings = new HashMap(); - - private GradleProject myGradleProject; + @NotNull private final GradleModuleManager myModuleManager; + @NotNull private final GradleLibraryManager myLibraryManager; + @NotNull private final GradleDependencyManager myDependencyManager; + + private GradleProject myGradleProject; private GradleConfigurable myConfigurable; + public GradleProjectImportBuilder(@NotNull GradleModuleManager moduleManager, + @NotNull GradleLibraryManager libraryManager, + @NotNull GradleDependencyManager manager) + { + myModuleManager = moduleManager; + myLibraryManager = libraryManager; + myDependencyManager = manager; + } + @NotNull @Override public String getName() { @@ -93,12 +116,13 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder commit(final Project project, ModifiableModuleModel model, ModulesProvider modulesProvider, - ModifiableArtifactModel artifactModel) { + ModifiableArtifactModel artifactModel) + { System.setProperty(GradleConstants.NEWLY_IMPORTED_PROJECT, Boolean.TRUE.toString()); final GradleProject gradleProject = getGradleProject(); if (gradleProject != null) { @@ -114,15 +138,107 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder mappings = - importer.importModules(myModuleMappings.values(), project, model, projectFile.getAbsolutePath()); - return new ArrayList(mappings.values()); + /** + * The whole import sequence looks like below: + *

+ *

+   * 
    + *
  1. Get project view from the gradle tooling api without resolving dependencies (downloading libraries);
  2. + *
  3. Allow to adjust project settings before importing;
  4. + *
  5. Create IJ project and modules;
  6. + *
  7. Ask gradle tooling api to resolve library dependencies (download the if necessary);
  8. + *
  9. Configure libraries used by the gradle project at intellij;
  10. + *
  11. Configure library dependencies;
  12. + *
+ *
+ *

+ * + * @param projectWithResolvedLibraries gradle project with resolved libraries (libraries have already been downloaded and + * are available at file system under gradle service directory) + * @param project current intellij project which should be configured by libraries and module library + * dependencies information available at the given gradle project + */ + private void setupLibraries(final GradleProject projectWithResolvedLibraries, final Project project) { + final Set libraries = projectWithResolvedLibraries.getLibraries(); + GradleUtil.executeProjectChangeAction(project, libraries, new Runnable() { + @Override + public void run() { + ProjectRootManagerEx.getInstanceEx(project).mergeRootsChangesDuring(new Runnable() { + @Override + public void run() { + // Clean existing libraries (if any). + LibraryTable projectLibraryTable = ProjectLibraryTable.getInstance(project); + if (projectLibraryTable == null) { + GradleLog.LOG.warn( + "Can't resolve external dependencies of the target gradle project (" + project + "). Reason: project " + + "library table is undefined" + ); + return; + } + LibraryTable.ModifiableModel model = projectLibraryTable.getModifiableModel(); + try { + for (Library library : model.getLibraries()) { + model.removeLibrary(library); + } + } + finally { + model.commit(); + } + + // Register libraries. + myLibraryManager.importLibraries(projectWithResolvedLibraries.getLibraries(), project); + GradleProjectStructureHelper helper = project.getComponent(GradleProjectStructureHelper.class); + for (GradleModule module : projectWithResolvedLibraries.getModules()) { + Module intellijModule = helper.findIntellijModule(module); + assert intellijModule != null; + myDependencyManager.importDependencies(module.getDependencies(), intellijModule); + } + } + }); + } + }); } @Nullable @@ -206,32 +322,6 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder - *

-   * 
    - *
  1. Get project view from the gradle tooling api without resolving dependencies (downloading libraries);
  2. - *
  3. Allow to adjust project settings before importing;
  4. - *
  5. Create IJ project and modules;
  6. - *
  7. Ask gradle tooling api to resolve library dependencies (download the if necessary);
  8. - *
  9. Configure modules dependencies;
  10. - *
- *
- *

- * {@link GradleEntity} guarantees correct {@link #equals(Object)}/{@link #hashCode()} implementation, so, we expect - * to get {@link GradleModule modules} that are the same in terms of {@link #equals(Object)} on subsequent calls. However, - * end-user is allowed to change their settings before the importing (e.g. module name), so, we need to map modules with - * resolved libraries to the modules from project 'view'. That's why end-user adjusts settings of the cloned modules. - * Given collection holds mappings between them. - * - * @param mappings origin-adjusted modules mappings - */ - public void setModuleMappings(@NotNull Map mappings) { - myModuleMappings.clear(); - myModuleMappings.putAll(mappings); - } - /** * Allows to get {@link Project} instance to use. Basically, there are two alternatives - * {@link WizardContext#getProject() project from the current wizard context} and diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleAdjustImportSettingsStep.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleAdjustImportSettingsStep.java index 44c3da214b88..39dc8f4b7400 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleAdjustImportSettingsStep.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/manage/wizard/adjust/GradleAdjustImportSettingsStep.java @@ -188,15 +188,11 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza List modules = new ArrayList(project.getModules()); Collections.sort(modules, Named.COMPARATOR); List moduleNodes = new ArrayList(); - Map moduleMappings = new HashMap(); - GradleEntityCloneContext cloneContext = new GradleEntityCloneContext(); for (GradleModule module : modules) { - GradleModule moduleCopy = module.clone(cloneContext); - moduleMappings.put(module, moduleCopy); GradleProjectStructureNode moduleNode = buildNode(module, entity2nodes, counter++); moduleNodes.add(moduleNode); - for (GradleContentRoot contentRoot : moduleCopy.getContentRoots()) { + for (GradleContentRoot contentRoot : module.getContentRoots()) { moduleNode.add(buildNode(contentRoot, entity2nodes, counter++)); } Collection dependencies = module.getDependencies(); @@ -263,7 +259,6 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza } myTree.expandPath(new TreePath(root.getPath())); - builder.setModuleMappings(moduleMappings); } private GradleProjectStructureNode buildNode( diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleApiFacadeImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleApiFacadeImpl.java index 74ed43dd9c74..e753764fbc9a 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleApiFacadeImpl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleApiFacadeImpl.java @@ -113,7 +113,7 @@ public class GradleApiFacadeImpl extends RemoteServer implements GradleApiFacade try { I stub = (I)UnicastRemoteObject.exportObject(proxy, 0); I stored = (I)myRemotes.putIfAbsent(implClass, stub); - return stored == null ? result : stored; + return stored == null ? stub : stored; } catch (RemoteException e) { Object raceResult = myRemotes.get(implClass); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureHelper.java index df0e73be81c5..8a0b05240b37 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureHelper.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureHelper.java @@ -3,10 +3,7 @@ package org.jetbrains.plugins.gradle.sync; import com.intellij.openapi.components.AbstractProjectComponent; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.LibraryOrderEntry; -import com.intellij.openapi.roots.ModuleOrderEntry; -import com.intellij.openapi.roots.OrderEntry; -import com.intellij.openapi.roots.RootPolicy; +import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.util.Ref; @@ -177,6 +174,21 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent { return null; } + @Nullable + public LibraryOrderEntry findIntellijLibraryDependency(@NotNull final String libraryName, + @NotNull ModifiableRootModel model) + { + for (OrderEntry entry : model.getOrderEntries()) { + if (entry instanceof LibraryOrderEntry) { + LibraryOrderEntry candidate = (LibraryOrderEntry)entry; + if (libraryName.equals(candidate.getLibraryName())) { + return candidate; + } + } + } + return null; + } + @Nullable public GradleLibrary findGradleLibrary(@NotNull final String libraryName) { final GradleProject project = myModel.getGradleProject(); @@ -268,6 +280,18 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent { } } return null; + } + @Nullable + public ModuleOrderEntry findIntellijModuleDependency(@NotNull GradleModuleDependency dependency, @NotNull ModifiableRootModel model) { + for (OrderEntry entry : model.getOrderEntries()) { + if (entry instanceof ModuleOrderEntry) { + ModuleOrderEntry candidate = (ModuleOrderEntry)entry; + if (dependency.getName().equals(candidate.getModuleName())) { + return candidate; + } + } + } + return null; } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/task/AbstractGradleTask.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/task/AbstractGradleTask.java index d39d0e20d981..6be6f4448fc2 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/task/AbstractGradleTask.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/task/AbstractGradleTask.java @@ -74,7 +74,9 @@ public abstract class AbstractGradleTask implements GradleTask { catch (Throwable e) { setState(GradleTaskState.FAILED); myError.set(e); - LOG.warn(e); + if (myIntellijProject == null || !myIntellijProject.isDisposed()) { + LOG.warn(e); + } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java index 69b0ef1b7fcb..11e91135ec4f 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java @@ -503,23 +503,34 @@ public class GradleUtil { return INSTALLATION_MANAGER.getValue().getGradleHome(project) != null; } + public static void executeProjectChangeAction(@NotNull Project project, @NotNull Object entityToChange, @NotNull Runnable task) { executeProjectChangeAction(project, Collections.singleton(entityToChange), task); } - public static void executeProjectChangeAction(@NotNull Project project, @NotNull Iterable entitiesToChange, @NotNull Runnable task) { - final GradleProjectEntityChangeListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC); - for (Object e : entitiesToChange) { - publisher.onChangeStart(e); - } - try { - task.run(); - } - finally { - for (Object e : entitiesToChange) { - publisher.onChangeEnd(e); + public static void executeProjectChangeAction(@NotNull final Project project, @NotNull final Iterable entitiesToChange, @NotNull final Runnable task) { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + final GradleProjectEntityChangeListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC); + for (Object e : entitiesToChange) { + publisher.onChangeStart(e); + } + try { + task.run(); + } + finally { + for (Object e : entitiesToChange) { + publisher.onChangeEnd(e); + } + } + } + }); } - } + }); } private interface TaskUnderProgress { From 5bcfdd589a90ba6e5eaa11f1b243960c0f473f10 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 6 Dec 2012 17:53:17 +0400 Subject: [PATCH 2/9] for IDEA-96501 Exception at opening project - correct assertion --- .../vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java index f371d376ddec..c5dc9c1472a4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java @@ -88,7 +88,7 @@ public class FilePathImpl implements FilePath { } private FilePathImpl(@NotNull File file, final boolean isDirectory, boolean local) { myFile = file; - assert myFile.isAbsolute(); + assert myFile.isAbsolute() || ! local; myName = file.getName(); myIsDirectory = isDirectory; myLocal = local; From 369da1daefeedad8223cd9fbc55851707d909255 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Thu, 6 Dec 2012 17:47:55 +0400 Subject: [PATCH 3/9] RUBY-11747 Color names overwrites to hex version if choose in completion #RUBY-11747 fixed --- .../xml/util/ColorSampleLookupValue.java | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/xml/impl/src/com/intellij/xml/util/ColorSampleLookupValue.java b/xml/impl/src/com/intellij/xml/util/ColorSampleLookupValue.java index 2b129714da06..6f0cfe5e6530 100644 --- a/xml/impl/src/com/intellij/xml/util/ColorSampleLookupValue.java +++ b/xml/impl/src/com/intellij/xml/util/ColorSampleLookupValue.java @@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Iconable; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; +import com.intellij.ui.ColorUtil; import com.intellij.xml.XmlBundle; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -451,22 +452,7 @@ public class ColorSampleLookupValue implements LookupValueWithUIHint, DeferredUs } String hexValue = text.charAt(0) == '#' ? text : getHexCodeForColorName(text.toLowerCase()); if (hexValue != null) { - String hexValue2 = hexValue.substring(1); - if (hexValue2.length() == 3) { - StringBuilder buf = new StringBuilder(6); - buf.append(hexValue2.charAt(0)).append(hexValue2.charAt(0)); - buf.append(hexValue2.charAt(1)).append(hexValue2.charAt(1)); - buf.append(hexValue2.charAt(2)).append(hexValue2.charAt(2)); - - hexValue2 = buf.toString(); - } - - try { - return Color.decode("0x" + hexValue2); - } - catch (NumberFormatException e) { - //ignore - } + return ColorUtil.fromHex(hexValue, null); } return null; } From d26c4791926bfdee8adce835d3e31380798473bd Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 6 Dec 2012 15:02:02 +0100 Subject: [PATCH 4/9] IDEA-96755 ("Module with too few classes": Not if only one module) --- .../ModuleWithTooFewClassesInspection.java | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/modularization/ModuleWithTooFewClassesInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/modularization/ModuleWithTooFewClassesInspection.java index 65e53924eb9a..1893ff6e5add 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/modularization/ModuleWithTooFewClassesInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/modularization/ModuleWithTooFewClassesInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2006-2012 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. @@ -23,6 +23,9 @@ import com.intellij.codeInspection.reference.RefClass; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.reference.RefModule; import com.intellij.codeInspection.ui.SingleIntegerFieldOptionsPanel; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseGlobalInspection; import org.jetbrains.annotations.NotNull; @@ -39,17 +42,13 @@ public class ModuleWithTooFewClassesInspection extends BaseGlobalInspection { @NotNull @Override public String getDisplayName() { - return InspectionGadgetsBundle.message( - "module.with.too.few.classes.display.name"); + return InspectionGadgetsBundle.message("module.with.too.few.classes.display.name"); } @Override @Nullable - public CommonProblemDescriptor[] checkElement( - RefEntity refEntity, - AnalysisScope analysisScope, - InspectionManager inspectionManager, - GlobalInspectionContext globalInspectionContext) { + public CommonProblemDescriptor[] checkElement(RefEntity refEntity, AnalysisScope analysisScope, InspectionManager inspectionManager, + GlobalInspectionContext globalInspectionContext) { if (!(refEntity instanceof RefModule)) { return null; } @@ -67,10 +66,13 @@ public class ModuleWithTooFewClassesInspection extends BaseGlobalInspection { if (numClasses >= limit || numClasses == 0) { return null; } - final String errorString = InspectionGadgetsBundle.message( - "module.with.too.few.classes.problem.descriptor", - refModule.getName(), Integer.valueOf(numClasses), - Integer.valueOf(limit)); + final Project project = globalInspectionContext.getProject(); + final Module[] modules = ModuleManager.getInstance(project).getModules(); + if (modules.length == 1) { + return null; + } + final String errorString = InspectionGadgetsBundle.message("module.with.too.few.classes.problem.descriptor", + refModule.getName(), Integer.valueOf(numClasses), Integer.valueOf(limit)); return new CommonProblemDescriptor[]{ inspectionManager.createProblemDescriptor(errorString) }; @@ -78,9 +80,6 @@ public class ModuleWithTooFewClassesInspection extends BaseGlobalInspection { @Override public JComponent createOptionsPanel() { - return new SingleIntegerFieldOptionsPanel( - InspectionGadgetsBundle.message( - "module.with.too.few.classes.min.option"), - this, "limit"); + return new SingleIntegerFieldOptionsPanel(InspectionGadgetsBundle.message("module.with.too.few.classes.min.option"), this, "limit"); } } \ No newline at end of file From 1e3d6848a2a692585946d795eb456223461bf441 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 6 Dec 2012 15:30:44 +0100 Subject: [PATCH 5/9] IDEA-96753 ('public' constructor Inspection reports Interfaces) --- .../com/siyeh/ig/classlayout/PublicConstructorInspection.java | 2 +- .../igtest/classlayout/public_constructor/PublicInterface.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/public_constructor/PublicInterface.java diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/PublicConstructorInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/PublicConstructorInspection.java index 1a9874338ba1..ffdddabcd865 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/PublicConstructorInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/PublicConstructorInspection.java @@ -115,7 +115,7 @@ public class PublicConstructorInspection extends BaseInspection { @Override public void visitClass(PsiClass aClass) { super.visitClass(aClass); - if (!aClass.hasModifierProperty(PsiModifier.PUBLIC)) { + if (aClass.isInterface() || !aClass.hasModifierProperty(PsiModifier.PUBLIC)) { return; } final PsiMethod[] constructors = aClass.getConstructors(); diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/public_constructor/PublicInterface.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/public_constructor/PublicInterface.java new file mode 100644 index 000000000000..7eafa56b735c --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/public_constructor/PublicInterface.java @@ -0,0 +1,3 @@ +package com.siyeh.igtest.classlayout.public_constructor; + +public interface PublicInterface {} \ No newline at end of file From 07fa429a94188595b13ffed384b735b72a673f01 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 6 Dec 2012 18:38:54 +0400 Subject: [PATCH 6/9] fix IDEA-96501 Exception at opening project [^kirill.l] --- .../svn/annotate/SvnAnnotationProvider.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java index a104087e10f3..53582d00fc69 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java @@ -54,23 +54,26 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn } public FileAnnotation annotate(final VirtualFile file) throws VcsException { - final VcsRevisionDescription currentRevision = ((SvnDiffProvider) myVcs.getDiffProvider()).getCurrentRevisionDescription(file); - if (currentRevision == null) { + final SvnDiffProvider provider = (SvnDiffProvider)myVcs.getDiffProvider(); + final SVNRevision currentRevision = ((SvnRevisionNumber)provider.getCurrentRevision(file)).getRevision(); + final VcsRevisionDescription lastChangedRevision = provider.getCurrentRevisionDescription(file); + if (lastChangedRevision == null) { throw new VcsException("Can not get current revision for file " + file.getPath()); } - final SvnRevisionNumber lastChangedRevision = (SvnRevisionNumber)currentRevision.getRevisionNumber(); - if (! lastChangedRevision.getRevision().isValid()) { + final SVNRevision svnRevision = ((SvnRevisionNumber)lastChangedRevision.getRevisionNumber()).getRevision(); + if (! svnRevision.isValid()) { throw new VcsException("Can not get last changed revision for file: " + file.getPath() + "\nPlease run svn info for this file and file an issue."); } - final SVNRevision svnRevision = lastChangedRevision.getRevision(); - return annotate(file, new SvnFileRevision(myVcs, svnRevision, svnRevision, null, null, null, null, null, file.getCharset()), true); + return annotate(file, new SvnFileRevision(myVcs, currentRevision, currentRevision, null, null, null, null, null, file.getCharset()), + lastChangedRevision.getRevisionNumber(), true); } public FileAnnotation annotate(final VirtualFile file, final VcsFileRevision revision) throws VcsException { - return annotate(file, revision, false); + return annotate(file, revision, revision.getRevisionNumber(), false); } - private FileAnnotation annotate(final VirtualFile file, final VcsFileRevision revision, final boolean loadExternally) throws VcsException { + private FileAnnotation annotate(final VirtualFile file, final VcsFileRevision revision, final VcsRevisionNumber lastChangedRevision, + final boolean loadExternally) throws VcsException { if (file.isDirectory()) { throw new VcsException(SvnBundle.message("exception.text.cannot.annotate.directory")); } @@ -94,7 +97,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn contents = LoadTextUtil.getTextByBinaryPresentation(bytes, file, false).toString(); } - final SvnFileAnnotation result = new SvnFileAnnotation(myVcs, file, contents, revision.getRevisionNumber()); + final SvnFileAnnotation result = new SvnFileAnnotation(myVcs, file, contents, lastChangedRevision); SVNWCClient wcClient = myVcs.createWCClient(); info = wcClient.doInfo(ioFile, SVNRevision.UNDEFINED); @@ -229,7 +232,8 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn charset == null ? CharsetToolkit.UTF8_CHARSET : charset).toString(); SVNLogClient client = myVcs.createLogClient(); setLogClientOptions(client); - final SvnRemoteFileAnnotation result = new SvnRemoteFileAnnotation(myVcs, contents, revision.getRevisionNumber(), pair.getFirst(), pair.getSecond().getPath(), current); + final SvnRemoteFileAnnotation result = new SvnRemoteFileAnnotation(myVcs, contents, revision.getRevisionNumber(), pair.getFirst(), + pair.getSecond().getPath(), current); final ISVNAnnotateHandler annotateHandler = createAnnotationHandler(ProgressManager.getInstance().getProgressIndicator(), result); final boolean calculateMergeinfo = SvnConfiguration.getInstance(myVcs.getProject()).SHOW_MERGE_SOURCES_IN_ANNOTATE && From a0cb161d7a566ca7f398f23f62e8ca06a36593fe Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 6 Dec 2012 15:51:11 +0100 Subject: [PATCH 7/9] IDEA-96447 ("Add clarifying parentheses" incorrectly marks an area and does nothing on accepting the intention) --- .../UnclearBinaryExpressionInspection.java | 20 ++++++++++--------- .../UnclearBinaryExpression.java | 5 +++++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnclearBinaryExpressionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnclearBinaryExpressionInspection.java index c6917f576831..9f6d5156c8a3 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnclearBinaryExpressionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnclearBinaryExpressionInspection.java @@ -26,6 +26,7 @@ import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -145,7 +146,7 @@ public class UnclearBinaryExpressionInspection extends BaseInspection { } } - private static void appendText(PsiInstanceOfExpression instanceofExpression, boolean parentheses, StringBuilder out) { + private static void appendText(PsiInstanceOfExpression instanceofExpression, boolean parentheses, @NonNls StringBuilder out) { if (parentheses) { out.append('('); } @@ -287,16 +288,17 @@ public class UnclearBinaryExpressionInspection extends BaseInspection { return; } final PsiExpression rhs = expression.getRExpression(); - if (!(mightBeConfusingExpression(rhs))) { + if (!mightBeConfusingExpression(rhs)) { return; } - if (rhs instanceof PsiAssignmentExpression) { - final PsiAssignmentExpression nestedAssignment = (PsiAssignmentExpression)rhs; - final IElementType nestedTokenType = nestedAssignment.getOperationTokenType(); - final IElementType tokenType = expression.getOperationTokenType(); - if (nestedTokenType.equals(tokenType)) { - return; - } + if (!(rhs instanceof PsiAssignmentExpression)) { + return; + } + final PsiAssignmentExpression nestedAssignment = (PsiAssignmentExpression)rhs; + final IElementType nestedTokenType = nestedAssignment.getOperationTokenType(); + final IElementType tokenType = expression.getOperationTokenType(); + if (nestedTokenType.equals(tokenType)) { + return; } registerError(expression); } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unclear_binary_expression/UnclearBinaryExpression.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unclear_binary_expression/UnclearBinaryExpression.java index a893eee720e5..9c126070eb81 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unclear_binary_expression/UnclearBinaryExpression.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unclear_binary_expression/UnclearBinaryExpression.java @@ -50,4 +50,9 @@ public class UnclearBinaryExpression { void more(int i) { i = i += i = 1; } + + void noMore() { + String s; + s = ":asdf" + "5s"; + } } From 8b07fb336a84987dbeb839c81cee9d6278070f78 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 6 Dec 2012 18:56:18 +0400 Subject: [PATCH 8/9] Hide file path assertions, sorry for tests --- .../vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java index c5dc9c1472a4..aa7aaf08dfdf 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java @@ -46,6 +46,7 @@ public class FilePathImpl implements FilePath { private boolean myIsDirectory; private final boolean myLocal; + //private FilePathImpl(@NotNull VirtualFile virtualParent, private FilePathImpl(@NotNull VirtualFile virtualParent, @NotNull String name, final boolean isDirectory, @@ -88,7 +89,7 @@ public class FilePathImpl implements FilePath { } private FilePathImpl(@NotNull File file, final boolean isDirectory, boolean local) { myFile = file; - assert myFile.isAbsolute() || ! local; + //assert myFile.isAbsolute() || ! local; myName = file.getName(); myIsDirectory = isDirectory; myLocal = local; From 73d330fd4f237e27f1db804d2ef4deb638bceabd Mon Sep 17 00:00:00 2001 From: Alexander Doroshko Date: Wed, 5 Dec 2012 17:46:41 +0400 Subject: [PATCH 9/9] [nik] getEncoding(File file) method introduced --- .../JpsEncodingProjectConfiguration.java | 3 +- .../JpsEncodingProjectConfigurationImpl.java | 35 +++++++++++++++++-- .../JpsProjectSerializationTest.java | 4 ++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsEncodingProjectConfiguration.java b/jps/model-api/src/org/jetbrains/jps/model/JpsEncodingProjectConfiguration.java index 5b918fe0f6d0..a41fbf891897 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsEncodingProjectConfiguration.java +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsEncodingProjectConfiguration.java @@ -3,6 +3,7 @@ package org.jetbrains.jps.model; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.File; import java.util.Map; /** @@ -10,7 +11,7 @@ import java.util.Map; */ public interface JpsEncodingProjectConfiguration extends JpsElement { @Nullable - String getEncoding(@NotNull String url); + String getEncoding(@NotNull File file); @Nullable String getProjectEncoding(); diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsEncodingProjectConfigurationImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsEncodingProjectConfigurationImpl.java index 5fe77c852ed9..a929662bdbcc 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsEncodingProjectConfigurationImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsEncodingProjectConfigurationImpl.java @@ -1,11 +1,17 @@ package org.jetbrains.jps.model.impl; +import com.intellij.openapi.util.io.FileUtilRt; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsElementChildRole; +import org.jetbrains.jps.model.JpsEncodingConfigurationService; import org.jetbrains.jps.model.JpsEncodingProjectConfiguration; +import org.jetbrains.jps.model.JpsModel; import org.jetbrains.jps.model.ex.JpsElementBase; import org.jetbrains.jps.model.ex.JpsElementChildRoleBase; +import org.jetbrains.jps.util.JpsPathUtil; +import java.io.File; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -13,7 +19,8 @@ import java.util.Map; /** * @author nik */ -public class JpsEncodingProjectConfigurationImpl extends JpsElementBase implements JpsEncodingProjectConfiguration { +public class JpsEncodingProjectConfigurationImpl extends JpsElementBase + implements JpsEncodingProjectConfiguration { public static final JpsElementChildRole ROLE = JpsElementChildRoleBase.create("encoding configuration"); private final Map myUrlToEncoding = new HashMap(); private final String myProjectEncoding; @@ -23,9 +30,30 @@ public class JpsEncodingProjectConfigurationImpl extends JpsElementBase