mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-76142: Gradle support - cannot update IDEA projects once one of build.gradle files changes
1. Added support for importing module dependencies; 2. Corresponding tests are added;
This commit is contained in:
@@ -55,6 +55,7 @@ gradle.sync.change.type.conflict=Settings conflict
|
||||
gradle.sync.change.type.unchanged=Unchanged setting
|
||||
gradle.sync.change.type.confirmed=Confirmed settings diff
|
||||
gradle.sync.change.entity.type.module=module
|
||||
gradle.sync.change.entity.type.module.dependency=module dependency
|
||||
gradle.sync.change.entity.type.library.dependency=library dependency
|
||||
gradle.sync.change.library.path=library ''{0}'' binary path
|
||||
gradle.sync.change.project.name.text=project name
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
<applicationService serviceInterface="org.jetbrains.plugins.gradle.diff.GradleStructureChangesCalculator"
|
||||
serviceImplementation="org.jetbrains.plugins.gradle.diff.GradleProjectStructureChangesCalculator"/>
|
||||
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.diff.GradleModuleStructureChangesCalculator"/>
|
||||
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.diff.GradleModuleDependencyStructureChangesCalculator"/>
|
||||
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.diff.GradleLibraryStructureChangesCalculator"/>
|
||||
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.diff.GradleLibraryDependencyStructureChangesCalculator"/>
|
||||
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package org.jetbrains.plugins.gradle.diff;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleEntity;
|
||||
|
||||
/**
|
||||
* Manages common dependency properties like 'scope', 'exported'.
|
||||
* <p/>
|
||||
* Thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 2/20/12 11:17 AM
|
||||
*/
|
||||
public abstract class GradleAbstractDependencyStructureChangesCalculator<G extends GradleEntity, I>
|
||||
implements GradleStructureChangesCalculator<G, I>
|
||||
{
|
||||
@Override
|
||||
public void calculate(@NotNull G gradleEntity, @NotNull I intellijEntity, @NotNull GradleChangesCalculationContext context)
|
||||
{
|
||||
// TODO den process common dependency properties here.
|
||||
doCalculate(gradleEntity, intellijEntity, context);
|
||||
}
|
||||
|
||||
protected abstract void doCalculate(@NotNull G gradleEntity, @NotNull I intellijEntity, @NotNull GradleChangesCalculationContext context);
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package org.jetbrains.plugins.gradle.diff;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <code>'Parameter object'</code> to use during project structure changes calculations.
|
||||
* <p/>
|
||||
* Thread-safe.
|
||||
*/
|
||||
public class GradleChangesCalculationContext {
|
||||
|
||||
@NotNull private final Set<GradleProjectStructureChange> myKnownChanges = new HashSet<GradleProjectStructureChange>();
|
||||
@NotNull private final Set<GradleProjectStructureChange> myCurrentChanges = new HashSet<GradleProjectStructureChange>();
|
||||
|
||||
@NotNull private final PlatformFacade myPlatformFacade;
|
||||
|
||||
/**
|
||||
* @param knownChanges changes between the gradle and intellij project structure that has been known up until now
|
||||
* @param platformFacade platform facade to use during the calculations
|
||||
*/
|
||||
public GradleChangesCalculationContext(@NotNull Set<GradleProjectStructureChange> knownChanges,
|
||||
@NotNull PlatformFacade platformFacade)
|
||||
{
|
||||
myKnownChanges.addAll(knownChanges);
|
||||
myPlatformFacade = platformFacade;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<GradleProjectStructureChange> getKnownChanges() {
|
||||
return myKnownChanges;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<GradleProjectStructureChange> getCurrentChanges() {
|
||||
return myCurrentChanges;
|
||||
}
|
||||
|
||||
public void register(@NotNull GradleProjectStructureChange change) {
|
||||
myCurrentChanges.add(change);
|
||||
}
|
||||
|
||||
public boolean hasNewChanges() {
|
||||
return !myKnownChanges.equals(myCurrentChanges);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PlatformFacade getPlatformFacade() {
|
||||
return myPlatformFacade;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
package org.jetbrains.plugins.gradle.diff;
|
||||
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.*;
|
||||
import org.jetbrains.plugins.gradle.model.intellij.IntellijEntityVisitor;
|
||||
import org.jetbrains.plugins.gradle.util.GradleUtil;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Contains various utility methods for building changes between the gradle and intellij project structures.
|
||||
@@ -25,10 +31,10 @@ public class GradleDiffUtil {
|
||||
* Example: particular module has been added at the gradle side. We want to mark that module, its content root(s), dependencies etc
|
||||
* as gradle-local changes.
|
||||
*
|
||||
* @param entity target gradle-local entity
|
||||
* @param currentChanges holder for the changes built during the current call
|
||||
* @param entity target gradle-local entity
|
||||
* @param context changes calculation context to use
|
||||
*/
|
||||
public static void buildLocalChanges(@NotNull GradleEntity entity, @NotNull final Set<GradleProjectStructureChange> currentChanges) {
|
||||
public static void buildLocalChanges(@NotNull GradleEntity entity, @NotNull final GradleChangesCalculationContext context) {
|
||||
entity.invite(new GradleEntityVisitor() {
|
||||
@Override
|
||||
public void visit(@NotNull GradleProject project) {
|
||||
@@ -37,7 +43,7 @@ public class GradleDiffUtil {
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleModule module) {
|
||||
currentChanges.add(new GradleModulePresenceChange(module, null));
|
||||
context.register(new GradleModulePresenceChange(module, null));
|
||||
for (GradleDependency dependency : module.getDependencies()) {
|
||||
dependency.invite(this);
|
||||
}
|
||||
@@ -55,59 +61,56 @@ public class GradleDiffUtil {
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleModuleDependency dependency) {
|
||||
// TODO den implement
|
||||
context.register(new GradleModuleDependencyPresenceChange(dependency, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleLibraryDependency dependency) {
|
||||
currentChanges.add(new GradleLibraryDependencyPresenceChange(dependency, null));
|
||||
context.register(new GradleLibraryDependencyPresenceChange(dependency, null));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Analogues to {@link #buildLocalChanges} but targets intellij entity.
|
||||
*
|
||||
* @param module target intellij-local module that doesn't present at the gradle side
|
||||
* @param currentChanges holder for the changes built during the current call
|
||||
*/
|
||||
public static void buildLocalChanges(@NotNull Module module,
|
||||
@NotNull Set<GradleProjectStructureChange> currentChanges)
|
||||
{
|
||||
currentChanges.add(new GradleModulePresenceChange(null, module));
|
||||
// TODO den process module sub-entities here (content roots and dependencies).
|
||||
}
|
||||
|
||||
/**
|
||||
* Analogues to {@link #buildLocalChanges} but targets intellij entity.
|
||||
*
|
||||
* @param libraryDependency target intellij-local library dependency that doesn't present at the gradle side
|
||||
* @param currentChanges holder for the changes built during the current call
|
||||
*/
|
||||
public static void buildLocalChanges(@NotNull LibraryOrderEntry libraryDependency,
|
||||
@NotNull Set<GradleProjectStructureChange> currentChanges)
|
||||
{
|
||||
final String libraryName = libraryDependency.getLibraryName();
|
||||
if (libraryName != null) {
|
||||
currentChanges.add(new GradleLibraryDependencyPresenceChange(null, libraryDependency));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs argument type-based dispatch and delegates to one of strongly typed <code>'buildLocalChanges()'</code> methods.
|
||||
*
|
||||
* @param entity target intellij-local entity that doesn't present at the gradle side
|
||||
* @param currentChanges holder for the changes built during the current call
|
||||
* @param entity target intellij-local entity that doesn't present at the gradle side
|
||||
* @param context changes calculation context to use
|
||||
*/
|
||||
public static void buildLocalChanges(@NotNull Object entity, @NotNull Set<GradleProjectStructureChange> currentChanges) {
|
||||
public static void buildLocalChanges(@NotNull Object entity, @NotNull final GradleChangesCalculationContext context) {
|
||||
if (entity instanceof GradleEntity) {
|
||||
buildLocalChanges((GradleEntity)entity, currentChanges);
|
||||
buildLocalChanges((GradleEntity)entity, context);
|
||||
}
|
||||
else if (entity instanceof Module) {
|
||||
buildLocalChanges((Module)entity, currentChanges);
|
||||
}
|
||||
else if (entity instanceof LibraryOrderEntry) {
|
||||
buildLocalChanges((LibraryOrderEntry)entity, currentChanges);
|
||||
else {
|
||||
GradleUtil.dispatch(entity, new IntellijEntityVisitor() {
|
||||
@Override
|
||||
public void visit(@NotNull Project project) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull Module module) {
|
||||
context.register(new GradleModulePresenceChange(null, module));
|
||||
for (OrderEntry entry : context.getPlatformFacade().getOrderEntries(module)) {
|
||||
GradleUtil.dispatch(entry, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull LibraryOrderEntry libraryDependency) {
|
||||
final String libraryName = libraryDependency.getLibraryName();
|
||||
if (libraryName != null) {
|
||||
context.register(new GradleLibraryDependencyPresenceChange(null, libraryDependency));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull ModuleOrderEntry moduleDependency) {
|
||||
final Module module = moduleDependency.getModule();
|
||||
if (module != null) {
|
||||
context.register(new GradleModuleDependencyPresenceChange(null, moduleDependency));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,8 +123,7 @@ public class GradleDiffUtil {
|
||||
* @param calculator comparison strategy that works with the single entities (not collection of entities)
|
||||
* @param gradleEntities entities available at the gradle side
|
||||
* @param intellijEntities entities available at the intellij side
|
||||
* @param knownChanges collection that contains known changes about the entities
|
||||
* @param currentChanges holder for the changes discovered during the current call
|
||||
* @param context changes calculation context
|
||||
* @param <I> target intellij entity type
|
||||
* @param <G> target gradle entity type
|
||||
*/
|
||||
@@ -129,8 +131,7 @@ public class GradleDiffUtil {
|
||||
@NotNull GradleStructureChangesCalculator<G, I> calculator,
|
||||
@NotNull Iterable<? extends G> gradleEntities,
|
||||
@NotNull Iterable<? extends I> intellijEntities,
|
||||
@NotNull Set<GradleProjectStructureChange> knownChanges,
|
||||
@NotNull Set<GradleProjectStructureChange> currentChanges)
|
||||
@NotNull GradleChangesCalculationContext context)
|
||||
{
|
||||
Map<Object, I> intellijEntitiesByKeys = new HashMap<Object, I>();
|
||||
for (I entity : intellijEntities) {
|
||||
@@ -138,17 +139,17 @@ public class GradleDiffUtil {
|
||||
assert previous == null;
|
||||
}
|
||||
for (G gradleEntity: gradleEntities) {
|
||||
I intellijEntity = intellijEntitiesByKeys.remove(calculator.getGradleKey(gradleEntity, knownChanges));
|
||||
I intellijEntity = intellijEntitiesByKeys.remove(calculator.getGradleKey(gradleEntity, context));
|
||||
if (intellijEntity == null) {
|
||||
buildLocalChanges(gradleEntity, currentChanges);
|
||||
buildLocalChanges(gradleEntity, context);
|
||||
}
|
||||
else {
|
||||
calculator.calculate(gradleEntity, intellijEntity, knownChanges, currentChanges);
|
||||
calculator.calculate(gradleEntity, intellijEntity, context);
|
||||
}
|
||||
}
|
||||
|
||||
for (I entity : intellijEntitiesByKeys.values()) {
|
||||
buildLocalChanges(entity, currentChanges);
|
||||
buildLocalChanges(entity, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -5,14 +5,12 @@ import com.intellij.openapi.roots.libraries.Library;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleLibraryDependency;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 1/24/12 1:37 PM
|
||||
*/
|
||||
public class GradleLibraryDependencyStructureChangesCalculator
|
||||
implements GradleStructureChangesCalculator<GradleLibraryDependency, LibraryOrderEntry>
|
||||
extends GradleAbstractDependencyStructureChangesCalculator<GradleLibraryDependency, LibraryOrderEntry>
|
||||
{
|
||||
|
||||
private final GradleLibraryStructureChangesCalculator myLibraryCalculator;
|
||||
@@ -22,28 +20,30 @@ public class GradleLibraryDependencyStructureChangesCalculator
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate(@NotNull GradleLibraryDependency gradleEntity,
|
||||
@NotNull LibraryOrderEntry intellijEntity,
|
||||
@NotNull Set<GradleProjectStructureChange> knownChanges,
|
||||
@NotNull Set<GradleProjectStructureChange> currentChanges)
|
||||
public void doCalculate(@NotNull GradleLibraryDependency gradleEntity,
|
||||
@NotNull LibraryOrderEntry intellijEntity,
|
||||
@NotNull GradleChangesCalculationContext context)
|
||||
{
|
||||
final Library library = intellijEntity.getLibrary();
|
||||
if (library == null) {
|
||||
return;
|
||||
}
|
||||
myLibraryCalculator.calculate(gradleEntity.getTarget(), library, knownChanges, currentChanges);
|
||||
myLibraryCalculator.calculate(gradleEntity.getTarget(), library, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object getIntellijKey(@NotNull LibraryOrderEntry entity) {
|
||||
final String result = entity.getLibraryName();
|
||||
return result == null ? "" : result;
|
||||
final Library library = entity.getLibrary();
|
||||
if (library == null) {
|
||||
return "";
|
||||
}
|
||||
return myLibraryCalculator.getIntellijKey(library);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object getGradleKey(@NotNull GradleLibraryDependency entity, @NotNull Set<GradleProjectStructureChange> knownChanges) {
|
||||
return myLibraryCalculator.getGradleKey(entity.getTarget(), knownChanges);
|
||||
public Object getGradleKey(@NotNull GradleLibraryDependency entity, @NotNull GradleChangesCalculationContext context) {
|
||||
return myLibraryCalculator.getGradleKey(entity.getTarget(), context);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -25,8 +25,7 @@ public class GradleLibraryStructureChangesCalculator implements GradleStructureC
|
||||
@Override
|
||||
public void calculate(@NotNull GradleLibrary gradleEntity,
|
||||
@NotNull Library intellijEntity,
|
||||
@NotNull Set<GradleProjectStructureChange> knownChanges,
|
||||
@NotNull Set<GradleProjectStructureChange> currentChanges)
|
||||
@NotNull GradleChangesCalculationContext context)
|
||||
{
|
||||
final Set<String> gradleBinaryPaths = new HashSet<String>(gradleEntity.getPaths(LibraryPathType.BINARY));
|
||||
final Set<String> intellijBinaryPaths = new HashSet<String>();
|
||||
@@ -38,7 +37,7 @@ public class GradleLibraryStructureChangesCalculator implements GradleStructureC
|
||||
}
|
||||
|
||||
if (!gradleBinaryPaths.equals(intellijBinaryPaths)) {
|
||||
currentChanges.add(new GradleMismatchedLibraryPathChange(intellijEntity, gradleBinaryPaths, intellijBinaryPaths));
|
||||
context.register(new GradleMismatchedLibraryPathChange(intellijEntity, gradleBinaryPaths, intellijBinaryPaths));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +49,7 @@ public class GradleLibraryStructureChangesCalculator implements GradleStructureC
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object getGradleKey(@NotNull GradleLibrary entity, @NotNull Set<GradleProjectStructureChange> knownChanges) {
|
||||
public Object getGradleKey(@NotNull GradleLibrary entity, @NotNull GradleChangesCalculationContext context) {
|
||||
// TODO den consider the known changes
|
||||
return entity.getName();
|
||||
}
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package org.jetbrains.plugins.gradle.diff;
|
||||
|
||||
import com.intellij.openapi.roots.ModuleOrderEntry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleModuleDependency;
|
||||
import org.jetbrains.plugins.gradle.model.id.GradleEntityIdMapper;
|
||||
import org.jetbrains.plugins.gradle.model.id.GradleModuleDependencyId;
|
||||
import org.jetbrains.plugins.gradle.util.GradleBundle;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 2/17/12 3:14 PM
|
||||
*/
|
||||
public class GradleModuleDependencyPresenceChange extends GradleEntityPresenceChange<GradleModuleDependencyId> {
|
||||
|
||||
public GradleModuleDependencyPresenceChange(@Nullable GradleModuleDependency gradle,
|
||||
@Nullable ModuleOrderEntry intellij)
|
||||
{
|
||||
super(GradleBundle.message("gradle.sync.change.entity.type.module.dependency"), of(gradle), of(intellij));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invite(@NotNull GradleProjectStructureChangeVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static GradleModuleDependencyId of(@Nullable GradleModuleDependency dependency) {
|
||||
if (dependency == null) {
|
||||
return null;
|
||||
}
|
||||
return GradleEntityIdMapper.mapEntityToId(dependency);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static GradleModuleDependencyId of(@Nullable ModuleOrderEntry dependency) {
|
||||
if (dependency == null) {
|
||||
return null;
|
||||
}
|
||||
return GradleEntityIdMapper.mapEntityToId(dependency);
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package org.jetbrains.plugins.gradle.diff;
|
||||
|
||||
import com.intellij.openapi.roots.ModuleOrderEntry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleModuleDependency;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 2/20/12 11:10 AM
|
||||
*/
|
||||
public class GradleModuleDependencyStructureChangesCalculator
|
||||
extends GradleAbstractDependencyStructureChangesCalculator<GradleModuleDependency, ModuleOrderEntry>
|
||||
{
|
||||
|
||||
@Override
|
||||
public void doCalculate(@NotNull GradleModuleDependency gradleEntity,
|
||||
@NotNull ModuleOrderEntry intellijEntity,
|
||||
@NotNull GradleChangesCalculationContext context)
|
||||
{
|
||||
// Assuming that the modules referenced by the given dependencies are compared independently.
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object getIntellijKey(@NotNull ModuleOrderEntry entity) {
|
||||
final String intellijModuleName = entity.getModuleName();
|
||||
if (intellijModuleName == null) {
|
||||
return "";
|
||||
}
|
||||
return intellijModuleName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object getGradleKey(@NotNull GradleModuleDependency entity, @NotNull GradleChangesCalculationContext context) {
|
||||
// TODO den consider known changes here.
|
||||
return entity.getTarget().getName();
|
||||
}
|
||||
}
|
||||
+15
-16
@@ -16,13 +16,15 @@
|
||||
package org.jetbrains.plugins.gradle.diff;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.*;
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Encapsulates functionality of calculating changes between Gradle and IntelliJ IDEA module hierarchies.
|
||||
@@ -34,25 +36,24 @@ import java.util.Set;
|
||||
*/
|
||||
public class GradleModuleStructureChangesCalculator implements GradleStructureChangesCalculator<GradleModule, Module> {
|
||||
|
||||
private final GradleLibraryDependencyStructureChangesCalculator myLibraryDependencyCalculator;
|
||||
private final PlatformFacade myStructureHelper;
|
||||
@NotNull private final GradleLibraryDependencyStructureChangesCalculator myLibraryDependencyCalculator;
|
||||
@NotNull private final GradleModuleDependencyStructureChangesCalculator myModuleDependencyCalculator;
|
||||
|
||||
public GradleModuleStructureChangesCalculator(@NotNull GradleLibraryDependencyStructureChangesCalculator libraryDependencyCalculator,
|
||||
@NotNull PlatformFacade structureHelper)
|
||||
@NotNull GradleModuleDependencyStructureChangesCalculator moduleDependencyCalculator)
|
||||
{
|
||||
myLibraryDependencyCalculator = libraryDependencyCalculator;
|
||||
myStructureHelper = structureHelper;
|
||||
myModuleDependencyCalculator = moduleDependencyCalculator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate(@NotNull GradleModule gradleEntity,
|
||||
@NotNull Module intellijEntity,
|
||||
@NotNull Set<GradleProjectStructureChange> knownChanges,
|
||||
@NotNull Set<GradleProjectStructureChange> currentChanges)
|
||||
@NotNull GradleChangesCalculationContext context)
|
||||
{
|
||||
//TODO den process module-local settings
|
||||
//TODO den process content roots
|
||||
checkDependencies(gradleEntity, intellijEntity, knownChanges, currentChanges);
|
||||
checkDependencies(gradleEntity, intellijEntity, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -63,15 +64,14 @@ public class GradleModuleStructureChangesCalculator implements GradleStructureCh
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object getGradleKey(@NotNull GradleModule entity, @NotNull Set<GradleProjectStructureChange> knownChanges) {
|
||||
public Object getGradleKey(@NotNull GradleModule entity, @NotNull GradleChangesCalculationContext context) {
|
||||
// TODO den consider the known changes
|
||||
return entity.getName();
|
||||
}
|
||||
|
||||
private void checkDependencies(@NotNull GradleModule gradleModule,
|
||||
@NotNull Module intellijModule,
|
||||
@NotNull Set<GradleProjectStructureChange> knownChanges,
|
||||
@NotNull Set<GradleProjectStructureChange> currentChanges)
|
||||
@NotNull GradleChangesCalculationContext context)
|
||||
{
|
||||
// Prepare intellij part.
|
||||
final List<ModuleOrderEntry> intellijModuleDependencies = new ArrayList<ModuleOrderEntry>();
|
||||
@@ -89,7 +89,7 @@ public class GradleModuleStructureChangesCalculator implements GradleStructureCh
|
||||
return libraryOrderEntry;
|
||||
}
|
||||
};
|
||||
for (OrderEntry orderEntry : myStructureHelper.getOrderEntries(intellijModule)) {
|
||||
for (OrderEntry orderEntry : context.getPlatformFacade().getOrderEntries(intellijModule)) {
|
||||
orderEntry.accept(policy, null);
|
||||
}
|
||||
|
||||
@@ -112,8 +112,7 @@ public class GradleModuleStructureChangesCalculator implements GradleStructureCh
|
||||
}
|
||||
|
||||
// Calculate changes.
|
||||
// TODO den process module dependencies here as well.
|
||||
GradleDiffUtil.calculate(myLibraryDependencyCalculator, gradleLibraryDependencies, intellijLibraryDependencies,
|
||||
knownChanges, currentChanges);
|
||||
GradleDiffUtil.calculate(myLibraryDependencyCalculator, gradleLibraryDependencies, intellijLibraryDependencies, context);
|
||||
GradleDiffUtil.calculate(myModuleDependencyCalculator, gradleModuleDependencies, intellijModuleDependencies, context);
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -28,5 +28,6 @@ public interface GradleProjectStructureChangeVisitor {
|
||||
void visit(@NotNull GradleLanguageLevelChange change);
|
||||
void visit(@NotNull GradleModulePresenceChange change);
|
||||
void visit(@NotNull GradleLibraryDependencyPresenceChange change);
|
||||
void visit(@NotNull GradleModuleDependencyPresenceChange change);
|
||||
void visit(@NotNull GradleMismatchedLibraryPathChange change);
|
||||
}
|
||||
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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 org.jetbrains.plugins.gradle.diff;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 11/16/11 8:49 PM
|
||||
*/
|
||||
public class GradleProjectStructureChangeVisitorAdapter implements GradleProjectStructureChangeVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleProjectRenameChange change) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleLanguageLevelChange change) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleModulePresenceChange change) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleLibraryDependencyPresenceChange change) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleMismatchedLibraryPathChange change) {
|
||||
}
|
||||
}
|
||||
+9
-10
@@ -21,25 +21,24 @@ import java.util.Set;
|
||||
public class GradleProjectStructureChangesCalculator implements GradleStructureChangesCalculator<GradleProject, Project> {
|
||||
|
||||
private final GradleModuleStructureChangesCalculator myModuleChangesCalculator;
|
||||
private final PlatformFacade myStructureHelper;
|
||||
private final PlatformFacade myPlatformFacade;
|
||||
|
||||
public GradleProjectStructureChangesCalculator(@NotNull GradleModuleStructureChangesCalculator moduleCalculator,
|
||||
@NotNull PlatformFacade structureHelper) {
|
||||
@NotNull PlatformFacade platformFacade) {
|
||||
myModuleChangesCalculator = moduleCalculator;
|
||||
myStructureHelper = structureHelper;
|
||||
myPlatformFacade = platformFacade;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate(@NotNull GradleProject gradleEntity,
|
||||
@NotNull Project intellijEntity,
|
||||
@NotNull Set<GradleProjectStructureChange> knownChanges,
|
||||
@NotNull Set<GradleProjectStructureChange> currentChanges)
|
||||
@NotNull GradleChangesCalculationContext context)
|
||||
{
|
||||
calculateProjectChanges(gradleEntity, intellijEntity, currentChanges);
|
||||
calculateProjectChanges(gradleEntity, intellijEntity, context.getCurrentChanges());
|
||||
|
||||
final Set<? extends GradleModule> gradleSubEntities = gradleEntity.getModules();
|
||||
final Collection<Module> intellijSubEntities = myStructureHelper.getModules(intellijEntity);
|
||||
GradleDiffUtil.calculate(myModuleChangesCalculator, gradleSubEntities, intellijSubEntities, knownChanges, currentChanges);
|
||||
final Collection<Module> intellijSubEntities = myPlatformFacade.getModules(intellijEntity);
|
||||
GradleDiffUtil.calculate(myModuleChangesCalculator, gradleSubEntities, intellijSubEntities, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -50,7 +49,7 @@ public class GradleProjectStructureChangesCalculator implements GradleStructureC
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object getGradleKey(@NotNull GradleProject entity, @NotNull Set<GradleProjectStructureChange> knownChanges) {
|
||||
public Object getGradleKey(@NotNull GradleProject entity, @NotNull GradleChangesCalculationContext context) {
|
||||
// TODO den consider the known changes
|
||||
return entity.getName();
|
||||
}
|
||||
@@ -79,7 +78,7 @@ public class GradleProjectStructureChangesCalculator implements GradleStructureC
|
||||
@NotNull Set<GradleProjectStructureChange> currentChanges)
|
||||
{
|
||||
LanguageLevel gradleLevel = gradleProject.getLanguageLevel();
|
||||
LanguageLevel intellijLevel = myStructureHelper.getLanguageLevel(intellijProject);
|
||||
LanguageLevel intellijLevel = myPlatformFacade.getLanguageLevel(intellijProject);
|
||||
if (gradleLevel != intellijLevel) {
|
||||
currentChanges.add(new GradleLanguageLevelChange(gradleLevel, intellijLevel));
|
||||
}
|
||||
|
||||
+9
-17
@@ -3,8 +3,6 @@ package org.jetbrains.plugins.gradle.diff;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleEntity;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Defines common interface to the strategy that calculates difference between the corresponding gradle and intellij entities
|
||||
* (e.g. between the gradle and intellij module).
|
||||
@@ -20,18 +18,12 @@ public interface GradleStructureChangesCalculator<G extends GradleEntity, I> {
|
||||
|
||||
/**
|
||||
* Calculates changes between the given entities.
|
||||
*
|
||||
*
|
||||
* @param gradleEntity target gradle entity
|
||||
* @param intellijEntity target intellij entity
|
||||
* @param knownChanges changes between the gradle and intellij project structure that has been known up until now
|
||||
* @param currentChanges holder for the changes between the given entities discovered by the current call. Note that
|
||||
* it must contain the change objects that have been known (contained at the <code>'knownChanges'</code>)
|
||||
* but are still in place
|
||||
* @param context target diff calculation context
|
||||
*/
|
||||
void calculate(@NotNull G gradleEntity,
|
||||
@NotNull I intellijEntity,
|
||||
@NotNull Set<GradleProjectStructureChange> knownChanges,
|
||||
@NotNull Set<GradleProjectStructureChange> currentChanges);
|
||||
void calculate(@NotNull G gradleEntity, @NotNull I intellijEntity, @NotNull GradleChangesCalculationContext context);
|
||||
|
||||
/**
|
||||
* There are three possible situations when we compare a set of gradle entities with a set of intellij entities:
|
||||
@@ -43,16 +35,16 @@ public interface GradleStructureChangesCalculator<G extends GradleEntity, I> {
|
||||
* </ul>
|
||||
* </pre>
|
||||
* <p/>
|
||||
* The general idea is to map evey item at the given sets of gradle and intellij entities to particular key (both gradle and
|
||||
* The general idea is to map every item at the given sets of gradle and intellij entities to particular key (both gradle and
|
||||
* intellij keys are expected to belong to the same class) and then compare them. Matched keys shows that corresponding
|
||||
* entities should be {@link #calculate(GradleEntity, Object, Set, Set)} compared to each other}; non-matched indicate that corresponding
|
||||
* entities are gradle- or intellij-local.
|
||||
* entities should be {@link #calculate(GradleEntity, Object, GradleChangesCalculationContext) compared to each other};
|
||||
* non-matched indicate that corresponding entities are gradle- or intellij-local.
|
||||
* <p/>
|
||||
* This method allows to match intellij entity to the target key.
|
||||
*
|
||||
* @param entity intellij entity to match
|
||||
* @return key for the given entity
|
||||
* @see #getGradleKey(GradleEntity, Set)
|
||||
* @see #getGradleKey(GradleEntity, GradleChangesCalculationContext)
|
||||
*/
|
||||
@NotNull
|
||||
Object getIntellijKey(@NotNull I entity);
|
||||
@@ -68,10 +60,10 @@ public interface GradleStructureChangesCalculator<G extends GradleEntity, I> {
|
||||
* So, we take into consideration the known changes only during {@code gradle-entity -> key} processing.
|
||||
*
|
||||
* @param entity target gradle entity that should be mapped to a key
|
||||
* @param knownChanges known changes between the gradle and intellij structures
|
||||
* @param context changes calculation context
|
||||
* @return key for the given entity
|
||||
* @see #getIntellijKey(Object)
|
||||
*/
|
||||
@NotNull
|
||||
Object getGradleKey(@NotNull G entity, @NotNull Set<GradleProjectStructureChange> knownChanges);
|
||||
Object getGradleKey(@NotNull G entity, @NotNull GradleChangesCalculationContext context);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import javax.swing.*;
|
||||
*/
|
||||
public enum GradleEntityType {
|
||||
PROJECT(GradleIcons.PROJECT_ICON), MODULE(GradleIcons.MODULE_ICON), MODULE_DEPENDENCY(GradleIcons.MODULE_ICON),
|
||||
LIBRARY_DEPENDENCY(GradleIcons.LIB_ICON), CONTENT_ROOT(GradleIcons.CONTENT_ROOT_ICON), SYNTHETIC(null);
|
||||
LIBRARY(GradleIcons.LIB_ICON), LIBRARY_DEPENDENCY(GradleIcons.LIB_ICON), CONTENT_ROOT(GradleIcons.CONTENT_ROOT_ICON), SYNTHETIC(null);
|
||||
|
||||
@Nullable private final Icon myIcon;
|
||||
|
||||
|
||||
@@ -89,6 +89,10 @@ public class GradleModule extends AbstractNamedGradleEntity implements Named {
|
||||
myDependencies.add(dependency);
|
||||
}
|
||||
|
||||
public void clearDependencies() {
|
||||
myDependencies.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invite(@NotNull GradleEntityVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package org.jetbrains.plugins.gradle.model.id;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
|
||||
import org.jetbrains.plugins.gradle.model.GradleEntityType;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 2/20/12 12:01 PM
|
||||
*/
|
||||
public abstract class GradleAbstractDependencyId extends GradleAbstractEntityId {
|
||||
|
||||
@NotNull private final String myOwnerModuleName;
|
||||
@NotNull private final String myDependencyName;
|
||||
|
||||
public GradleAbstractDependencyId(@NotNull GradleEntityType type,
|
||||
@NotNull GradleEntityOwner owner,
|
||||
@NotNull String ownerModuleName,
|
||||
@NotNull String dependencyName)
|
||||
{
|
||||
super(type, owner);
|
||||
myOwnerModuleName = ownerModuleName;
|
||||
myDependencyName = dependencyName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getOwnerModuleName() {
|
||||
return myOwnerModuleName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDependencyName() {
|
||||
return myDependencyName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public GradleModuleId getOwnerModuleId() {
|
||||
return new GradleModuleId(getOwner(), myOwnerModuleName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 31 * super.hashCode() + myOwnerModuleName.hashCode();
|
||||
return 31 * result + myDependencyName.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
GradleAbstractDependencyId that = (GradleAbstractDependencyId)o;
|
||||
return myOwnerModuleName.equals(that.myOwnerModuleName) && myDependencyName.equals(that.myDependencyName);
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public class GradleEntityIdMapper {
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleModuleDependency dependency) {
|
||||
result.set(new GradleLibraryDependencyId(GradleEntityOwner.GRADLE, dependency.getOwnerModule().getName(), dependency.getName()));
|
||||
result.set(new GradleModuleDependencyId(GradleEntityOwner.GRADLE, dependency.getOwnerModule().getName(), dependency.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,7 +74,7 @@ public class GradleEntityIdMapper {
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleLibrary library) {
|
||||
// TODO den implement
|
||||
result.set(new GradleLibraryId(GradleEntityOwner.GRADLE, library.getName()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+7
-41
@@ -8,60 +8,26 @@ import org.jetbrains.plugins.gradle.model.GradleEntityType;
|
||||
* @author Denis Zhdanov
|
||||
* @since 2/14/12 1:59 PM
|
||||
*/
|
||||
public class GradleLibraryDependencyId extends GradleAbstractEntityId {
|
||||
public class GradleLibraryDependencyId extends GradleAbstractDependencyId {
|
||||
|
||||
@NotNull private final String myModuleName;
|
||||
@NotNull private final String myLibraryName;
|
||||
|
||||
public GradleLibraryDependencyId(@NotNull GradleEntityOwner owner, @NotNull String moduleName, @NotNull String libraryName) {
|
||||
super(GradleEntityType.LIBRARY_DEPENDENCY, owner);
|
||||
myModuleName = moduleName;
|
||||
myLibraryName = libraryName;
|
||||
super(GradleEntityType.LIBRARY_DEPENDENCY, owner, moduleName, libraryName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getModuleName() {
|
||||
return myModuleName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getLibraryName() {
|
||||
return myLibraryName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public GradleModuleId getModuleId() {
|
||||
return new GradleModuleId(getOwner(), myModuleName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object mapToEntity(@NotNull GradleEntityMappingContext context) {
|
||||
switch (getOwner()) {
|
||||
case GRADLE: return context.getProjectStructureHelper().findGradleLibraryDependency(myModuleName, myLibraryName);
|
||||
case INTELLIJ: return context.getProjectStructureHelper().findIntellijLibraryDependency(myModuleName, myLibraryName);
|
||||
case GRADLE: return context.getProjectStructureHelper().findGradleLibraryDependency(getOwnerModuleName(), getDependencyName());
|
||||
case INTELLIJ: return context.getProjectStructureHelper().findIntellijLibraryDependency(getOwnerModuleName(), getDependencyName());
|
||||
}
|
||||
throw new IllegalStateException(String.format(
|
||||
"Can't map id to the target library dependency. Owner: %s, module: '%s', library: '%s'", getOwner(), myModuleName, myLibraryName
|
||||
"Can't map id to the target library dependency. Owner: %s, module: '%s', library: '%s'",
|
||||
getOwner(), getOwnerModuleName(), getDependencyName()
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 31 * super.hashCode() + myModuleName.hashCode();
|
||||
return 31 * result + myLibraryName.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
GradleLibraryDependencyId that = (GradleLibraryDependencyId)o;
|
||||
return myModuleName.equals(that.myModuleName) && myLibraryName.equals(that.myLibraryName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("library dependency:owner module='%s'|library='%s'", myModuleName, myLibraryName);
|
||||
return String.format("library dependency:owner module='%s'|library='%s'", getOwnerModuleName(), getDependencyName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.jetbrains.plugins.gradle.model.id;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
|
||||
import org.jetbrains.plugins.gradle.model.GradleEntityType;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 2/20/12 7:12 PM
|
||||
*/
|
||||
public class GradleLibraryId extends GradleAbstractEntityId {
|
||||
|
||||
@NotNull private final String myLibraryName;
|
||||
|
||||
public GradleLibraryId(@NotNull GradleEntityOwner owner, @NotNull String libraryName) {
|
||||
super(GradleEntityType.LIBRARY, owner);
|
||||
myLibraryName = libraryName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object mapToEntity(@NotNull GradleEntityMappingContext context) {
|
||||
switch (getOwner()) {
|
||||
case GRADLE: return context.getProjectStructureHelper().findGradleLibrary(myLibraryName);
|
||||
case INTELLIJ: return context.getProjectStructureHelper().findIntellijLibrary(myLibraryName);
|
||||
}
|
||||
throw new IllegalStateException(String.format(
|
||||
"Can't map library id to the target library. Id owner: %s, name: '%s'", getOwner(), myLibraryName
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * super.hashCode() + myLibraryName.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
GradleLibraryId that = (GradleLibraryId)o;
|
||||
return myLibraryName.equals(that.myLibraryName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "library '" + myLibraryName + "'";
|
||||
}
|
||||
}
|
||||
+6
-26
@@ -8,46 +8,26 @@ import org.jetbrains.plugins.gradle.model.GradleEntityType;
|
||||
* @author Denis Zhdanov
|
||||
* @since 2/14/12 2:06 PM
|
||||
*/
|
||||
public class GradleModuleDependencyId extends GradleAbstractEntityId {
|
||||
public class GradleModuleDependencyId extends GradleAbstractDependencyId {
|
||||
|
||||
@NotNull private final String myOwnerModuleName;
|
||||
@NotNull private final String myDependencyModuleName;
|
||||
|
||||
public GradleModuleDependencyId(@NotNull GradleEntityOwner owner, @NotNull String ownerModuleName, @NotNull String dependencyModuleName) {
|
||||
super(GradleEntityType.MODULE, owner);
|
||||
myOwnerModuleName = ownerModuleName;
|
||||
myDependencyModuleName = dependencyModuleName;
|
||||
super(GradleEntityType.MODULE_DEPENDENCY, owner, ownerModuleName, dependencyModuleName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object mapToEntity(@NotNull GradleEntityMappingContext context) {
|
||||
switch (getOwner()) {
|
||||
case GRADLE: return context.getProjectStructureHelper().findGradleModuleDependency(myOwnerModuleName, myDependencyModuleName);
|
||||
case INTELLIJ: return context.getProjectStructureHelper().findIntellijModuleDependency(myOwnerModuleName, myDependencyModuleName);
|
||||
case GRADLE: return context.getProjectStructureHelper().findGradleModuleDependency(getOwnerModuleName(), getDependencyName());
|
||||
case INTELLIJ: return context.getProjectStructureHelper().findIntellijModuleDependency(getOwnerModuleName(), getDependencyName());
|
||||
}
|
||||
throw new IllegalStateException(String.format(
|
||||
"Can't map id to the target module dependency. Owner: %s, owner module: '%s', dependency module: '%s'",
|
||||
getOwner(), myOwnerModuleName, myDependencyModuleName
|
||||
getOwner(), getOwnerModuleName(), getDependencyName()
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 31 * super.hashCode() + myOwnerModuleName.hashCode();
|
||||
return 31 * result + myDependencyModuleName.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
GradleModuleDependencyId that = (GradleModuleDependencyId)o;
|
||||
return myOwnerModuleName.equals(that.myOwnerModuleName) && myDependencyModuleName.equals(that.myDependencyModuleName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("module dependency:owner module='%s'|dependency module='%s'", myOwnerModuleName, myDependencyModuleName);
|
||||
return String.format("module dependency:owner module='%s'|dependency module='%s'", getOwnerModuleName(), getDependencyName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,4 +46,9 @@ public class GradleModuleId extends GradleAbstractEntityId {
|
||||
GradleModuleId that = (GradleModuleId)o;
|
||||
return myModuleName.equals(that.myModuleName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "module '" + myModuleName + "'";
|
||||
}
|
||||
}
|
||||
|
||||
+13
-9
@@ -4,8 +4,10 @@ import com.intellij.openapi.components.AbstractProjectComponent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.gradle.diff.GradleChangesCalculationContext;
|
||||
import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChange;
|
||||
import org.jetbrains.plugins.gradle.diff.GradleStructureChangesCalculator;
|
||||
import org.jetbrains.plugins.gradle.diff.PlatformFacade;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleProject;
|
||||
|
||||
import java.util.HashSet;
|
||||
@@ -28,14 +30,17 @@ public class GradleProjectStructureChangesModel extends AbstractProjectComponent
|
||||
= new AtomicReference<Set<GradleProjectStructureChange>>(new HashSet<GradleProjectStructureChange>());
|
||||
|
||||
private final AtomicReference<GradleProject> myGradleProject = new AtomicReference<GradleProject>();
|
||||
|
||||
private final GradleStructureChangesCalculator<GradleProject, Project> myChangesCalculator;
|
||||
|
||||
@NotNull private final GradleStructureChangesCalculator<GradleProject, Project> myChangesCalculator;
|
||||
@NotNull private final PlatformFacade myPlatformFacade;
|
||||
|
||||
public GradleProjectStructureChangesModel(@NotNull Project project,
|
||||
@NotNull GradleStructureChangesCalculator<GradleProject, Project> changesCalculator)
|
||||
@NotNull GradleStructureChangesCalculator<GradleProject, Project> changesCalculator,
|
||||
@NotNull PlatformFacade platformFacade)
|
||||
{
|
||||
super(project);
|
||||
myChangesCalculator = changesCalculator;
|
||||
myPlatformFacade = platformFacade;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,15 +63,14 @@ public class GradleProjectStructureChangesModel extends AbstractProjectComponent
|
||||
*/
|
||||
public void update(@NotNull GradleProject gradleProject) {
|
||||
myGradleProject.set(gradleProject);
|
||||
Set<GradleProjectStructureChange> knownChanges = new HashSet<GradleProjectStructureChange>(myChanges.get());
|
||||
Set<GradleProjectStructureChange> currentChanges = new HashSet<GradleProjectStructureChange>();
|
||||
myChangesCalculator.calculate(gradleProject, myProject, knownChanges, currentChanges);
|
||||
if (currentChanges.equals(knownChanges)) {
|
||||
GradleChangesCalculationContext context = new GradleChangesCalculationContext(myChanges.get(), myPlatformFacade);
|
||||
myChangesCalculator.calculate(gradleProject, myProject, context);
|
||||
if (!context.hasNewChanges()) {
|
||||
return;
|
||||
}
|
||||
myChanges.set(currentChanges);
|
||||
myChanges.set(context.getCurrentChanges());
|
||||
for (GradleProjectStructureChangeListener listener : myListeners) {
|
||||
listener.onChanges(knownChanges, currentChanges);
|
||||
listener.onChanges(context.getKnownChanges(), context.getCurrentChanges());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+31
-19
@@ -15,6 +15,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.gradle.diff.PlatformFacade;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.*;
|
||||
import org.jetbrains.plugins.gradle.model.id.GradleLibraryDependencyId;
|
||||
import org.jetbrains.plugins.gradle.model.id.GradleModuleDependencyId;
|
||||
|
||||
/**
|
||||
* Thread-safe.
|
||||
@@ -49,23 +50,7 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent {
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public boolean isIntellijLibraryDependencyExist(@NotNull final GradleLibraryDependencyId id) {
|
||||
final Module module = findIntellijModule(id.getModuleName());
|
||||
if (module == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RootPolicy<Boolean> visitor = new RootPolicy<Boolean>() {
|
||||
@Override
|
||||
public Boolean visitLibraryOrderEntry(LibraryOrderEntry libraryOrderEntry, Boolean value) {
|
||||
return id.getLibraryName().equals(libraryOrderEntry.getLibraryName());
|
||||
}
|
||||
};
|
||||
for (OrderEntry entry : myFacade.getOrderEntries(module)) {
|
||||
if (entry.accept(visitor, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return findIntellijLibraryDependency(id.getOwnerModuleName(), id.getDependencyName()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +61,15 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent {
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public boolean isGradleLibraryDependencyExist(@NotNull final GradleLibraryDependencyId id) {
|
||||
return findGradleLibraryDependency(id.getModuleName(), id.getLibraryName()) != null;
|
||||
return findGradleLibraryDependency(id.getOwnerModuleName(), id.getDependencyName()) != null;
|
||||
}
|
||||
|
||||
public boolean isIntellijModuleDependencyExist(@NotNull final GradleModuleDependencyId id) {
|
||||
return findIntellijModuleDependency(id.getOwnerModuleName(), id.getDependencyName()) != null;
|
||||
}
|
||||
|
||||
public boolean isGradleModuleDependencyExist(@NotNull final GradleModuleDependencyId id) {
|
||||
return findIntellijModuleDependency(id.getOwnerModuleName(), id.getDependencyName()) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -111,10 +104,15 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent {
|
||||
|
||||
@Nullable
|
||||
public Library findIntellijLibrary(@NotNull final GradleLibrary library) {
|
||||
return findIntellijLibrary(library.getName());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Library findIntellijLibrary(@NotNull String libraryName) {
|
||||
final LibraryTable libraryTable = myFacade.getProjectLibraryTable(myProject);
|
||||
for (Library intellijLibrary : libraryTable.getLibraries()) {
|
||||
// TODO den consider 'merged libraries' at the registered project structure changes here.
|
||||
if (library.getName().equals(intellijLibrary.getName())) {
|
||||
if (libraryName.equals(intellijLibrary.getName())) {
|
||||
return intellijLibrary;
|
||||
}
|
||||
}
|
||||
@@ -145,6 +143,20 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GradleLibrary findGradleLibrary(@NotNull final String libraryName) {
|
||||
final GradleProject project = myModel.getGradleProject();
|
||||
if (project == null) {
|
||||
return null;
|
||||
}
|
||||
for (GradleLibrary library : project.getLibraries()) {
|
||||
if (libraryName.equals(library.getName())) {
|
||||
return library;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GradleLibraryDependency findGradleLibraryDependency(@NotNull final String moduleName, @NotNull final String libraryName) {
|
||||
|
||||
+73
-21
@@ -92,7 +92,7 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
|
||||
return value;
|
||||
}
|
||||
GradleLibraryDependencyId id = GradleEntityIdMapper.mapEntityToId(libraryOrderEntry);
|
||||
dependencies.add(buildNode(id, id.getLibraryName()));
|
||||
dependencies.add(buildNode(id, id.getDependencyName()));
|
||||
return value;
|
||||
}
|
||||
};
|
||||
@@ -137,6 +137,7 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
|
||||
GradleProjectStructureNode<GradleModuleId> moduleNode = getModuleNode(id);
|
||||
GradleProjectStructureNode<GradleSyntheticId> result
|
||||
= new GradleProjectStructureNode<GradleSyntheticId>(GradleConstants.DEPENDENCIES_NODE_DESCRIPTOR);
|
||||
result.addListener(myNodeListener);
|
||||
moduleNode.add(result);
|
||||
myModuleDependencies.put(id.getModuleName(), result);
|
||||
|
||||
@@ -196,7 +197,7 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
|
||||
for (GradleProjectStructureNode<GradleSyntheticId> holder : myModuleDependencies.values()) {
|
||||
for (GradleProjectStructureNode<GradleLibraryDependencyId> dependencyNode : holder.getChildren(GradleLibraryDependencyId.class)) {
|
||||
final GradleLibraryDependencyId id = dependencyNode.getDescriptor().getElement();
|
||||
if (change.getLibraryName().equals(id.getLibraryName())) {
|
||||
if (change.getLibraryName().equals(id.getDependencyName())) {
|
||||
dependencyNode.addConflictChange(change);
|
||||
break;
|
||||
}
|
||||
@@ -205,25 +206,31 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
|
||||
}
|
||||
|
||||
private void processNewLibraryDependencyPresenceChange(@NotNull GradleLibraryDependencyPresenceChange change) {
|
||||
GradleLibraryDependencyId id = change.getGradleEntity();
|
||||
processNewDependencyPresenceChange(change);
|
||||
}
|
||||
|
||||
private void processNewModuleDependencyPresenceChange(@NotNull GradleModuleDependencyPresenceChange change) {
|
||||
processNewDependencyPresenceChange(change);
|
||||
}
|
||||
|
||||
private <I extends GradleAbstractDependencyId> void processNewDependencyPresenceChange(@NotNull GradleEntityPresenceChange<I> change) {
|
||||
I id = change.getGradleEntity();
|
||||
TextAttributesKey attributes = GradleTextAttributes.GRADLE_LOCAL_CHANGE;
|
||||
if (id == null) {
|
||||
id = change.getIntellijEntity();
|
||||
attributes = GradleTextAttributes.INTELLIJ_LOCAL_CHANGE;
|
||||
}
|
||||
assert id != null;
|
||||
final GradleProjectStructureNode<GradleSyntheticId> dependenciesNode = getDependenciesNode(id.getModuleId());
|
||||
for (GradleProjectStructureNode<GradleLibraryDependencyId> node : dependenciesNode.getChildren(GradleLibraryDependencyId.class)) {
|
||||
GradleProjectStructureNodeDescriptor<GradleLibraryDependencyId> d = node.getDescriptor();
|
||||
if (id.equals(d.getElement())) {
|
||||
d.setAttributes(attributes);
|
||||
nodeStructureChanged(node);
|
||||
final GradleProjectStructureNode<GradleSyntheticId> dependenciesNode = getDependenciesNode(id.getOwnerModuleId());
|
||||
for (GradleProjectStructureNode<? extends GradleAbstractDependencyId> node : dependenciesNode.getChildren(id.getClass())) {
|
||||
if (id.equals(node.getDescriptor().getElement())) {
|
||||
node.setAttributes(attributes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
GradleProjectStructureNode<GradleLibraryDependencyId> newNode = buildNode(id, id.getLibraryName());
|
||||
newNode.setAttributes(attributes);
|
||||
GradleProjectStructureNode<I> newNode = buildNode(id, id.getDependencyName());
|
||||
dependenciesNode.add(newNode);
|
||||
newNode.setAttributes(attributes);
|
||||
}
|
||||
|
||||
private void processNewModulePresenceChange(@NotNull GradleModulePresenceChange change) {
|
||||
@@ -254,7 +261,7 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
|
||||
for (GradleProjectStructureNode<GradleSyntheticId> holder : myModuleDependencies.values()) {
|
||||
for (GradleProjectStructureNode<GradleLibraryDependencyId> node : holder.getChildren(GradleLibraryDependencyId.class)) {
|
||||
final GradleLibraryDependencyId id = node.getDescriptor().getElement();
|
||||
if (id.getLibraryName().equals(change.getLibraryName())) {
|
||||
if (id.getDependencyName().equals(change.getLibraryName())) {
|
||||
node.removeConflictChange(change);
|
||||
break;
|
||||
}
|
||||
@@ -274,7 +281,25 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
|
||||
else {
|
||||
removeNode = !myProjectStructureHelper.isGradleLibraryDependencyExist(id);
|
||||
}
|
||||
final GradleProjectStructureNode<GradleSyntheticId> holder = myModuleDependencies.get(id.getModuleName());
|
||||
processObsoleteDependencyPresenceChange(id, removeNode);
|
||||
}
|
||||
|
||||
private void processObsoleteModuleDependencyPresenceChange(@NotNull GradleModuleDependencyPresenceChange change) {
|
||||
GradleModuleDependencyId id = change.getGradleEntity();
|
||||
boolean removeNode;
|
||||
if (id == null) {
|
||||
id = change.getIntellijEntity();
|
||||
assert id != null;
|
||||
removeNode = !myProjectStructureHelper.isIntellijModuleDependencyExist(id);
|
||||
}
|
||||
else {
|
||||
removeNode = !myProjectStructureHelper.isGradleModuleDependencyExist(id);
|
||||
}
|
||||
processObsoleteDependencyPresenceChange(id, removeNode);
|
||||
}
|
||||
|
||||
private void processObsoleteDependencyPresenceChange(@NotNull GradleAbstractDependencyId id, boolean removeNode) {
|
||||
final GradleProjectStructureNode<GradleSyntheticId> holder = myModuleDependencies.get(id.getOwnerModuleName());
|
||||
if (holder == null) {
|
||||
return;
|
||||
}
|
||||
@@ -285,8 +310,8 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
|
||||
// We should distinguish between those situations because we need to mark the node as 'synced' at one case and
|
||||
// completely removed at another one.
|
||||
|
||||
for (GradleProjectStructureNode<GradleLibraryDependencyId> node : holder.getChildren(GradleLibraryDependencyId.class)) {
|
||||
GradleProjectStructureNodeDescriptor<GradleLibraryDependencyId> descriptor = node.getDescriptor();
|
||||
for (GradleProjectStructureNode<? extends GradleAbstractDependencyId> node : holder.getChildren(id.getClass())) {
|
||||
GradleProjectStructureNodeDescriptor<? extends GradleAbstractDependencyId> descriptor = node.getDescriptor();
|
||||
if (!id.equals(descriptor.getElement())) {
|
||||
continue;
|
||||
}
|
||||
@@ -303,12 +328,31 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
|
||||
|
||||
private void processObsoleteModulePresenceChange(@NotNull GradleModulePresenceChange change) {
|
||||
GradleModuleId id = change.getGradleEntity();
|
||||
boolean removeNode;
|
||||
if (id == null) {
|
||||
id = change.getIntellijEntity();
|
||||
assert id != null;
|
||||
removeNode = myProjectStructureHelper.findIntellijModule(id.getModuleName()) == null;
|
||||
}
|
||||
assert id != null;
|
||||
else {
|
||||
removeNode = myProjectStructureHelper.findGradleModule(id.getModuleName()) == null;
|
||||
}
|
||||
|
||||
|
||||
// There are two possible cases why 'module presence' change is obsolete:
|
||||
// 1. Corresponding module has been added at the counterparty;
|
||||
// 2. The 'local module' has been removed;
|
||||
// We should distinguish between those situations because we need to mark the node as 'synced' at one case and
|
||||
// completely removed at another one.
|
||||
|
||||
final GradleProjectStructureNode<GradleModuleId> moduleNode = myModules.get(id.getModuleName());
|
||||
if (moduleNode != null) {
|
||||
if (moduleNode == null) {
|
||||
return;
|
||||
}
|
||||
if (removeNode) {
|
||||
moduleNode.removeFromParent();
|
||||
}
|
||||
else {
|
||||
moduleNode.getDescriptor().setAttributes(GradleTextAttributes.GRADLE_NO_CHANGE);
|
||||
}
|
||||
}
|
||||
@@ -322,10 +366,13 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNodeRemoved(@NotNull GradleProjectStructureNode<?> node, int index) {
|
||||
myIndexHolder[0] = index;
|
||||
myNodeHolder[0] = node;
|
||||
nodesWereRemoved(node.getParent(), myIndexHolder, myNodeHolder);
|
||||
public void onNodeRemoved(@NotNull GradleProjectStructureNode<?> parent,
|
||||
@NotNull GradleProjectStructureNode<?> removedChild,
|
||||
int removedChildIndex)
|
||||
{
|
||||
myIndexHolder[0] = removedChildIndex;
|
||||
myNodeHolder[0] = removedChild;
|
||||
nodesWereRemoved(parent, myIndexHolder, myNodeHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -339,6 +386,8 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
|
||||
@Override public void visit(@NotNull GradleLanguageLevelChange change) { processNewLanguageLevelChange(change); }
|
||||
@Override public void visit(@NotNull GradleModulePresenceChange change) { processNewModulePresenceChange(change); }
|
||||
@Override public void visit(@NotNull GradleLibraryDependencyPresenceChange change) { processNewLibraryDependencyPresenceChange(change); }
|
||||
@Override public void visit(@NotNull GradleModuleDependencyPresenceChange change) { processNewModuleDependencyPresenceChange(change); }
|
||||
|
||||
@Override public void visit(@NotNull GradleMismatchedLibraryPathChange change) { processNewMismatchedLibraryPathChange(change); }
|
||||
}
|
||||
|
||||
@@ -349,6 +398,9 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
|
||||
@Override public void visit(@NotNull GradleLibraryDependencyPresenceChange change) {
|
||||
processObsoleteLibraryDependencyPresenceChange(change);
|
||||
}
|
||||
@Override public void visit(@NotNull GradleModuleDependencyPresenceChange change) {
|
||||
processObsoleteModuleDependencyPresenceChange(change);
|
||||
}
|
||||
@Override public void visit(@NotNull GradleMismatchedLibraryPathChange change) { processObsoleteMismatchedLibraryPathChange(change); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class GradleResolveProjectTask extends AbstractGradleTask {
|
||||
final GradleProject project = resolver.resolveProjectInfo(getId(), myProjectPath, myResolveLibraries);
|
||||
myGradleProject.set(project);
|
||||
setState(GradleTaskState.FINISHED);
|
||||
if (myIntellijProject == null) {
|
||||
if (myIntellijProject == null || myIntellijProject.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
final GradleProjectStructureChangesModel model = myIntellijProject.getComponent(GradleProjectStructureChangesModel.class);
|
||||
|
||||
@@ -70,13 +70,11 @@ public class GradleProjectStructureNode<T extends GradleEntityId> extends Defaul
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
GradleProjectStructureNode<?> node = getChildAt(i);
|
||||
if (NODE_COMPARATOR.compare((GradleProjectStructureNode<?>)newChild, node) <= 0) {
|
||||
insert(newChild, i);
|
||||
onNodeAdded((GradleProjectStructureNode<?>)newChild, i);
|
||||
insert(newChild, i); // Assuming that the node listeners are notified during the nested call.
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.add(newChild);
|
||||
onNodeAdded((GradleProjectStructureNode<?>)newChild, getChildCount() - 1);
|
||||
super.add(newChild); // Assuming that the node listeners are notified during the nested call to 'insert()'.
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,7 +106,7 @@ public class GradleProjectStructureNode<T extends GradleEntityId> extends Defaul
|
||||
*/
|
||||
public void correctChildPositionIfNecessary(@NotNull GradleProjectStructureNode<?> child) {
|
||||
int currentPosition = -1;
|
||||
int desiredPosition = getChildCount() - 1;
|
||||
int desiredPosition = getChildCount();
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
GradleProjectStructureNode<?> node = getChildAt(i);
|
||||
if (node == child) {
|
||||
@@ -117,12 +115,21 @@ public class GradleProjectStructureNode<T extends GradleEntityId> extends Defaul
|
||||
}
|
||||
if (NODE_COMPARATOR.compare(child, node) <= 0) {
|
||||
desiredPosition = i;
|
||||
if (currentPosition >= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentPosition < 0) {
|
||||
// Given node is not a child of the current node.
|
||||
return;
|
||||
}
|
||||
if (currentPosition < desiredPosition) {
|
||||
desiredPosition--;
|
||||
}
|
||||
if (currentPosition == desiredPosition) {
|
||||
return;
|
||||
}
|
||||
remove(currentPosition);
|
||||
insert(child, desiredPosition);
|
||||
}
|
||||
@@ -237,9 +244,9 @@ public class GradleProjectStructureNode<T extends GradleEntityId> extends Defaul
|
||||
}
|
||||
}
|
||||
|
||||
private void onNodeRemoved(@NotNull GradleProjectStructureNode<?> node, int index) {
|
||||
private void onNodeRemoved(@NotNull GradleProjectStructureNode<?> node, int removedChildIndex) {
|
||||
for (Listener listener : myListeners) {
|
||||
listener.onNodeRemoved(node, index);
|
||||
listener.onNodeRemoved(this, node, removedChildIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +258,9 @@ public class GradleProjectStructureNode<T extends GradleEntityId> extends Defaul
|
||||
|
||||
public interface Listener {
|
||||
void onNodeAdded(@NotNull GradleProjectStructureNode<?> node, int index);
|
||||
void onNodeRemoved(@NotNull GradleProjectStructureNode<?> node, int index);
|
||||
void onNodeRemoved(@NotNull GradleProjectStructureNode<?> parent,
|
||||
@NotNull GradleProjectStructureNode<?> removedChild,
|
||||
int removedChildIndex);
|
||||
void onNodeChanged(@NotNull GradleProjectStructureNode<?> node);
|
||||
}
|
||||
}
|
||||
|
||||
+186
-9
@@ -40,8 +40,8 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest {
|
||||
// Check that the initial projects state is correctly parsed.
|
||||
checkChanges {
|
||||
presence {
|
||||
library(gradle: gradle.modules.dependencies.flatten().findAll { it.name == "lib2" })
|
||||
library(gradle: gradle.modules.dependencies.flatten().findAll { it.name == "lib3" })
|
||||
library(gradle: gradle.libraryDependencies.values().flatten().findAll { it.name == "lib2" })
|
||||
library(gradle: gradle.libraryDependencies.values().flatten().findAll { it.name == "lib3" })
|
||||
} }
|
||||
checkTree {
|
||||
project {
|
||||
@@ -63,7 +63,7 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest {
|
||||
|
||||
checkChanges {
|
||||
presence {
|
||||
library(gradle: gradle.modules.dependencies.flatten().findAll { it.name == "lib3" })
|
||||
library(gradle: gradle.libraryDependencies.values().flatten().findAll { it.name == "lib3" })
|
||||
} }
|
||||
checkTree {
|
||||
project {
|
||||
@@ -144,7 +144,7 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest {
|
||||
} } } }
|
||||
)
|
||||
checkChanges {
|
||||
libraryConflict(entity: intellij.dependencies.values().flatten().find {it.library.name == 'lib2' }.library) {
|
||||
libraryConflict(entity: intellij.libraryDependencies.values().flatten().find {it.library.name == 'lib2' }.library) {
|
||||
binaryPath(gradle: null, intellij: '3')
|
||||
} }
|
||||
checkTree {
|
||||
@@ -209,8 +209,8 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest {
|
||||
} } )
|
||||
checkChanges {
|
||||
presence {
|
||||
module(gradle: gradle.modules.find { it.name == 'module2'})
|
||||
libraryDependency(gradle: gradle.modules.dependencies.flatten())
|
||||
module(gradle: gradle.modules['module2'])
|
||||
libraryDependency(gradle: gradle.modules['module2'].dependencies)
|
||||
} }
|
||||
checkTree {
|
||||
project {
|
||||
@@ -237,7 +237,7 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest {
|
||||
)
|
||||
checkChanges {
|
||||
presence {
|
||||
module(gradle: gradle.modules.find { it.name == 'module2' })
|
||||
module(gradle: gradle.modules['module2'])
|
||||
} }
|
||||
checkTree {
|
||||
project {
|
||||
@@ -286,8 +286,8 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest {
|
||||
|
||||
checkChanges {
|
||||
presence {
|
||||
module(gradle: gradle.modules.find { it.name == 'module2' })
|
||||
libraryDependency(gradle: gradle.dependencies[gradle.modules.find { it.name == 'module2' }].first())
|
||||
module(gradle: gradle.modules['module2'])
|
||||
libraryDependency(gradle: gradle.libraryDependencies[gradle.modules['module2']].first())
|
||||
}
|
||||
libraryConflict(entity: intellij.libraries['lib1']) {
|
||||
binaryPath(gradle: ['1'], intellij: ['2'])
|
||||
@@ -303,4 +303,181 @@ public class GradleProjectStructureChangesModelTest extends AbstractGradleTest {
|
||||
lib1('gradle') // This is the point of the test. We don't expect to see 'conflict' here.
|
||||
} } } }
|
||||
}
|
||||
|
||||
@Test
|
||||
public void "mismatched module dependency import"() {
|
||||
init(
|
||||
gradle: {
|
||||
project {
|
||||
module('module1')
|
||||
module('module2')
|
||||
module('module3') {
|
||||
dependencies {
|
||||
module('module1')
|
||||
module('module2')
|
||||
} } } },
|
||||
intellij: {
|
||||
project {
|
||||
module('module2')
|
||||
module('module4')
|
||||
module('module3') {
|
||||
dependencies {
|
||||
module('module2')
|
||||
module('module4')
|
||||
} } } }
|
||||
)
|
||||
checkChanges {
|
||||
presence {
|
||||
module(gradle: gradle.modules['module1'])
|
||||
module(intellij: intellij.modules['module4'])
|
||||
moduleDependency(gradle: gradle.moduleDependencies[gradle.modules['module3']].find { it.target == gradle.modules['module1']})
|
||||
moduleDependency(intellij: intellij.moduleDependencies[intellij.modules['module3']].find { it.moduleName == 'module4'})
|
||||
} }
|
||||
checkTree {
|
||||
project {
|
||||
module1('gradle')
|
||||
module2()
|
||||
module3() {
|
||||
dependencies {
|
||||
module1('gradle')
|
||||
module2()
|
||||
module4('intellij')
|
||||
} }
|
||||
module4('intellij')
|
||||
} }
|
||||
|
||||
Closure newProjectState = {
|
||||
project {
|
||||
module('module1')
|
||||
module('module2')
|
||||
module('module4')
|
||||
module('module3') {
|
||||
dependencies {
|
||||
module('module1')
|
||||
module('module2')
|
||||
module('module4')
|
||||
} } } }
|
||||
setState(gradle: newProjectState, intellij: newProjectState)
|
||||
checkChanges { } // No changes
|
||||
checkTree {
|
||||
project {
|
||||
module1()
|
||||
module2()
|
||||
module3 {
|
||||
dependencies {
|
||||
module1()
|
||||
module2()
|
||||
module4()
|
||||
} }
|
||||
module4()
|
||||
} }
|
||||
}
|
||||
|
||||
@Test
|
||||
public void "mismatched module dependency removal"() {
|
||||
init(
|
||||
gradle: {
|
||||
project {
|
||||
module('module1')
|
||||
module('module2')
|
||||
module('module3') {
|
||||
dependencies {
|
||||
module('module1')
|
||||
module('module2')
|
||||
} } } },
|
||||
intellij: {
|
||||
project {
|
||||
module('module2')
|
||||
module('module4')
|
||||
module('module3') {
|
||||
dependencies {
|
||||
module('module2')
|
||||
module('module4')
|
||||
} } } }
|
||||
)
|
||||
checkChanges {
|
||||
presence {
|
||||
module(gradle: gradle.modules['module1'])
|
||||
module(intellij: intellij.modules['module4'])
|
||||
moduleDependency(gradle: gradle.moduleDependencies[gradle.modules['module3']].find { it.target == gradle.modules['module1']})
|
||||
moduleDependency(intellij: intellij.moduleDependencies[intellij.modules['module3']].find { it.moduleName == 'module4'})
|
||||
} }
|
||||
checkTree {
|
||||
project {
|
||||
module1('gradle')
|
||||
module2()
|
||||
module3() {
|
||||
dependencies {
|
||||
module1('gradle')
|
||||
module2()
|
||||
module4('intellij')
|
||||
} }
|
||||
module4('intellij')
|
||||
} }
|
||||
|
||||
Closure newProjectState = {
|
||||
project {
|
||||
module('module2')
|
||||
module('module3') {
|
||||
dependencies {
|
||||
module('module2')
|
||||
} } } }
|
||||
setState(gradle: newProjectState, intellij: newProjectState)
|
||||
checkChanges { } // No changes
|
||||
checkTree {
|
||||
project {
|
||||
module2()
|
||||
module3 {
|
||||
dependencies {
|
||||
module2()
|
||||
} } } }
|
||||
}
|
||||
|
||||
@Test
|
||||
public void "cycled module dependencies"() {
|
||||
init(
|
||||
gradle: {
|
||||
project {
|
||||
module('module1') {
|
||||
dependencies {
|
||||
module('module2')
|
||||
} }
|
||||
module('module2') {
|
||||
dependencies {
|
||||
module('module1')
|
||||
} } } },
|
||||
intellij: {
|
||||
project {
|
||||
module('module2') {
|
||||
dependencies {
|
||||
module('module3')
|
||||
} }
|
||||
module('module3') {
|
||||
dependencies {
|
||||
module('module2')
|
||||
} } } }
|
||||
)
|
||||
checkChanges {
|
||||
presence {
|
||||
module(gradle: gradle.modules['module1'])
|
||||
module(intellij: intellij.modules['module3'])
|
||||
moduleDependency(gradle: gradle.moduleDependencies.values().flatten())
|
||||
moduleDependency(intellij: intellij.moduleDependencies.values().flatten())
|
||||
} }
|
||||
checkTree {
|
||||
project {
|
||||
module1('gradle') {
|
||||
dependencies {
|
||||
module2('gradle')
|
||||
} }
|
||||
module2() {
|
||||
dependencies {
|
||||
module1('gradle')
|
||||
module3('intellij')
|
||||
} }
|
||||
module3('intellij') {
|
||||
dependencies {
|
||||
module2('intellij')
|
||||
} } } }
|
||||
}
|
||||
}
|
||||
|
||||
+26
-15
@@ -1,23 +1,18 @@
|
||||
package org.jetbrains.plugins.gradle.testutil
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.plugins.gradle.model.id.GradleEntityIdMapper
|
||||
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangeListener
|
||||
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesModel
|
||||
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper
|
||||
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureTreeModel
|
||||
import org.junit.Before
|
||||
import org.picocontainer.defaults.DefaultPicoContainer
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.plugins.gradle.diff.PlatformFacade
|
||||
import org.jetbrains.plugins.gradle.diff.GradleStructureChangesCalculator
|
||||
import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChangesCalculator
|
||||
import org.jetbrains.plugins.gradle.diff.GradleModuleStructureChangesCalculator
|
||||
import org.jetbrains.plugins.gradle.diff.GradleLibraryDependencyStructureChangesCalculator
|
||||
import org.jetbrains.plugins.gradle.diff.GradleLibraryStructureChangesCalculator
|
||||
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangeListener
|
||||
|
||||
import static org.junit.Assert.assertEquals
|
||||
import org.picocontainer.MutablePicoContainer
|
||||
import org.jetbrains.plugins.gradle.model.id.GradleEntityIdMapper;
|
||||
import org.picocontainer.defaults.DefaultPicoContainer
|
||||
import org.jetbrains.plugins.gradle.diff.*
|
||||
|
||||
import static org.junit.Assert.fail
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -48,6 +43,7 @@ public abstract class AbstractGradleTest {
|
||||
container.registerComponentImplementation(GradleProjectStructureHelper)
|
||||
container.registerComponentImplementation(GradleStructureChangesCalculator, GradleProjectStructureChangesCalculator)
|
||||
container.registerComponentImplementation(GradleModuleStructureChangesCalculator)
|
||||
container.registerComponentImplementation(GradleModuleDependencyStructureChangesCalculator)
|
||||
container.registerComponentImplementation(GradleLibraryDependencyStructureChangesCalculator)
|
||||
container.registerComponentImplementation(GradleLibraryStructureChangesCalculator)
|
||||
container.registerComponentImplementation(GradleEntityIdMapper)
|
||||
@@ -96,7 +92,22 @@ public abstract class AbstractGradleTest {
|
||||
if (!expected) {
|
||||
expected = [].toSet()
|
||||
}
|
||||
assertEquals(expected, changesModel.changes)
|
||||
def actual = new HashSet(changesModel.changes)
|
||||
if (expected == actual) {
|
||||
return
|
||||
}
|
||||
actual.removeAll(expected)
|
||||
expected.removeAll(changesModel.changes)
|
||||
def message = "Project structure changes are mismatched."
|
||||
if (expected) {
|
||||
message += "\n Expected but not matched:"
|
||||
expected.each { message += "\n * $it"}
|
||||
}
|
||||
if (actual) {
|
||||
message += "\n Unexpected:"
|
||||
actual.each { message += "\n * $it"}
|
||||
}
|
||||
fail(message)
|
||||
}
|
||||
|
||||
protected def checkTree(c) {
|
||||
|
||||
+48
-17
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.plugins.gradle.testutil
|
||||
|
||||
import com.intellij.pom.java.LanguageLevel
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -12,16 +13,28 @@ public abstract class AbstractProjectBuilder extends BuilderSupport {
|
||||
private static int COUNTER
|
||||
|
||||
def project
|
||||
def modules = []
|
||||
|
||||
/** [module name; module] */
|
||||
def modules = [:]
|
||||
|
||||
/** Holds (library name; library) pairs for the active configuration. */
|
||||
def libraries = [:]
|
||||
|
||||
/** [module; dependency list] */
|
||||
def libraryDependencies = [:].withDefault {[]}
|
||||
|
||||
/** [module; dependency list] */
|
||||
def moduleDependencies = [:].withDefault {[]}
|
||||
|
||||
/**
|
||||
* Holds (library name; library) pairs for the whole test. I.e. there is a possible case that we define particular configuration
|
||||
* initially and the adjust it. We need to use the same library instance then in order to pass hashCode()/equals() checks then.
|
||||
* This map works as a test-wide storage.
|
||||
*/
|
||||
def librariesCache = [:]
|
||||
def dependencies = [:].withDefault {[]}
|
||||
|
||||
/** [module name; module] */
|
||||
def modulesCache = [:]
|
||||
|
||||
@Override
|
||||
protected void setParent(Object parent, Object child) {
|
||||
@@ -43,37 +56,54 @@ public abstract class AbstractProjectBuilder extends BuilderSupport {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object createNode(Object name, Map attributes) {
|
||||
protected Object createNode(name, Map attributes) {
|
||||
switch (name) {
|
||||
case "dependencies": return current // Assuming that 'current' is a module object
|
||||
case "project":
|
||||
reset()
|
||||
clear()
|
||||
return project = createProject(attributes.name?: same, attributes.langLevel?: LanguageLevel.JDK_1_6)
|
||||
case "module": def module = createModule(attributes.name?: same); modules << module; return module
|
||||
case "module":
|
||||
case "library":
|
||||
def n = StringUtil.capitalize(name)
|
||||
if (current == project) {
|
||||
// Library.
|
||||
return getLibrary(attributes)
|
||||
}
|
||||
else {
|
||||
// Library dependency.
|
||||
def module = current
|
||||
def dep = createLibraryDependency(module, getLibrary(attributes))
|
||||
dependencies[module] << dep
|
||||
return dep
|
||||
// Not a dependency.
|
||||
return "get$n"(attributes)
|
||||
}
|
||||
def ownerModule = current
|
||||
def dep = "create${n}Dependency"(ownerModule, "get$n"(attributes))
|
||||
"get${n}Dependencies"()[ownerModule] << dep
|
||||
return dep
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract def createProject(String name, LanguageLevel languageLevel)
|
||||
protected abstract def createModule(String name)
|
||||
protected abstract def registerModule(module)
|
||||
protected abstract def createLibrary(String name, Map paths)
|
||||
protected abstract def applyLibraryPaths(library, Map paths)
|
||||
protected abstract def createLibraryDependency(module, library)
|
||||
protected abstract def createModuleDependency(ownerModule, targetModule)
|
||||
protected abstract def reset();
|
||||
|
||||
protected String getUnique() { "./${COUNTER++}" }
|
||||
protected String getSame() { SAME_TOKEN }
|
||||
|
||||
private def getModule(Map attributes) {
|
||||
def name = attributes.name?: same
|
||||
def result = modules[name]
|
||||
if (result) return result
|
||||
result = modulesCache[name]
|
||||
if (result) {
|
||||
registerModule(result)
|
||||
}
|
||||
else {
|
||||
result = createModule(name)
|
||||
modulesCache[name] = result
|
||||
}
|
||||
modules[name] = result
|
||||
result
|
||||
}
|
||||
|
||||
private def getLibrary(Map attributes) {
|
||||
def name = attributes.name?: same
|
||||
def result = libraries[name]
|
||||
@@ -89,8 +119,9 @@ public abstract class AbstractProjectBuilder extends BuilderSupport {
|
||||
libraries[name] = result
|
||||
result
|
||||
}
|
||||
|
||||
private def reset() {
|
||||
[modules, dependencies, libraries]*.clear()
|
||||
|
||||
private def clear() {
|
||||
reset()
|
||||
[modules, libraryDependencies, libraries, moduleDependencies]*.clear()
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -6,6 +6,7 @@ import org.jetbrains.plugins.gradle.diff.GradleMismatchedLibraryPathChange
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import org.jetbrains.plugins.gradle.util.GradleUtil
|
||||
import org.jetbrains.plugins.gradle.diff.GradleModulePresenceChange
|
||||
import org.jetbrains.plugins.gradle.diff.GradleModuleDependencyPresenceChange
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -34,6 +35,10 @@ public class ChangeBuilder extends BuilderSupport {
|
||||
changes.addAll attributes.gradle.collect { new GradleModulePresenceChange(it, null)}
|
||||
changes.addAll attributes.intellij.collect { new GradleModulePresenceChange(null, it)}
|
||||
return changes
|
||||
case "moduleDependency":
|
||||
changes.addAll attributes.gradle.collect { new GradleModuleDependencyPresenceChange(it, null) }
|
||||
changes.addAll attributes.intellij.collect { new GradleModuleDependencyPresenceChange(null, it) }
|
||||
return changes
|
||||
case "library":
|
||||
changes.addAll attributes.gradle.collect { new GradleLibraryDependencyPresenceChange(it, null)}
|
||||
changes.addAll attributes.intellij.collect { new GradleLibraryDependencyPresenceChange(null, it)}
|
||||
@@ -52,7 +57,7 @@ public class ChangeBuilder extends BuilderSupport {
|
||||
// Assuming that we're processing library binary path conflict here
|
||||
register(new GradleMismatchedLibraryPathChange(
|
||||
current as Library, collectPaths(attributes.gradle), collectPaths(attributes.intellij)
|
||||
))
|
||||
))
|
||||
}
|
||||
changes
|
||||
}
|
||||
|
||||
+19
-2
@@ -6,6 +6,7 @@ import org.jetbrains.plugins.gradle.model.gradle.GradleLibraryDependency
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary
|
||||
import org.jetbrains.plugins.gradle.model.gradle.LibraryPathType
|
||||
import com.intellij.pom.java.LanguageLevel
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleModuleDependency
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -23,8 +24,19 @@ class GradleProjectBuilder extends AbstractProjectBuilder {
|
||||
|
||||
@Override
|
||||
protected createModule(String name) {
|
||||
def result = new GradleModule(name, unique)
|
||||
project.addModule(result)
|
||||
registerModule(new GradleModule(name, unique))
|
||||
}
|
||||
|
||||
@Override
|
||||
protected registerModule(module) {
|
||||
project.addModule(module)
|
||||
module
|
||||
}
|
||||
|
||||
@Override
|
||||
protected createModuleDependency(ownerModule, targetModule) {
|
||||
def result = new GradleModuleDependency(ownerModule, targetModule)
|
||||
ownerModule.addDependency(result)
|
||||
result
|
||||
}
|
||||
|
||||
@@ -49,4 +61,9 @@ class GradleProjectBuilder extends AbstractProjectBuilder {
|
||||
key, type -> paths[key]?.each { library.addPath(type, it) }
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected reset() {
|
||||
modulesCache.values().each { it.clearDependencies() }
|
||||
}
|
||||
}
|
||||
|
||||
+21
-3
@@ -13,6 +13,7 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import org.jetbrains.plugins.gradle.util.GradleUtil
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable
|
||||
import com.intellij.openapi.roots.ModuleOrderEntry
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -30,8 +31,8 @@ class IntellijProjectBuilder extends AbstractProjectBuilder {
|
||||
def projectLibraryTable = projectLibraryTableStub as LibraryTable
|
||||
|
||||
def platformFacade = [
|
||||
getModules: { modules },
|
||||
getOrderEntries: { dependencies[it] },
|
||||
getModules: { modules.values() },
|
||||
getOrderEntries: { libraryDependencies[it] + moduleDependencies[it] },
|
||||
getProjectIcon: { IconLoader.getIcon("/nodes/ideaProject.png") },
|
||||
getLocalFileSystemPath: { it.path },
|
||||
getProjectLibraryTable: { projectLibraryTable }
|
||||
@@ -42,7 +43,7 @@ class IntellijProjectBuilder extends AbstractProjectBuilder {
|
||||
@Override
|
||||
protected createProject(String name, LanguageLevel languageLevel) {
|
||||
projectStub.getName = { name }
|
||||
platformFacade.getLanguageLevel = { languageLevel }
|
||||
platformFacade.getLanguageLevel = { languageLevel } as Closure
|
||||
project
|
||||
}
|
||||
|
||||
@@ -51,6 +52,20 @@ class IntellijProjectBuilder extends AbstractProjectBuilder {
|
||||
[ getName: { name } ] as Module
|
||||
}
|
||||
|
||||
@Override
|
||||
protected registerModule(Object module) { }
|
||||
|
||||
@Override
|
||||
protected createModuleDependency(ownerModule, targetModule) {
|
||||
def stub = [:]
|
||||
def result = stub as ModuleOrderEntry
|
||||
stub.accept = { policy, defaultValue -> policy.visitModuleOrderEntry(result, defaultValue) }
|
||||
stub.getModule = { targetModule }
|
||||
stub.getOwnerModule = { ownerModule }
|
||||
stub.getModuleName = { targetModule.name }
|
||||
result
|
||||
}
|
||||
|
||||
@Override
|
||||
protected createLibrary(String name, Map paths) {
|
||||
libraryPaths[name] = paths
|
||||
@@ -81,4 +96,7 @@ class IntellijProjectBuilder extends AbstractProjectBuilder {
|
||||
protected applyLibraryPaths(library, Map paths) {
|
||||
libraryPaths[library.name] = paths
|
||||
}
|
||||
|
||||
@Override
|
||||
protected reset() { }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user