summaryrefslogtreecommitdiff
path: root/jps/jps-builders
diff options
context:
space:
mode:
Diffstat (limited to 'jps/jps-builders')
-rw-r--r--jps/jps-builders/jps-builders.iml1
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Callbacks.java1
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectMultiMaplet.java15
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectPersistentMultiMaplet.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectTransientMultiMaplet.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java283
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java2
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/jps/builders/JavacFileEncodingTest.kt (renamed from jps/jps-builders/testSrc/org/jetbrains/jps/builders/JavacFileEncodingTest.groovy)7
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java6
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/jps/builders/ModuleClasspathTest.kt98
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ArtifactRebuildTest.kt (renamed from jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ArtifactRebuildTest.groovy)70
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.groovy98
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.kt86
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ModuleRebuildTest.kt (renamed from jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ModuleRebuildTest.groovy)14
15 files changed, 370 insertions, 317 deletions
diff --git a/jps/jps-builders/jps-builders.iml b/jps/jps-builders/jps-builders.iml
index 565691fb134e..993bfad6f750 100644
--- a/jps/jps-builders/jps-builders.iml
+++ b/jps/jps-builders/jps-builders.iml
@@ -35,7 +35,6 @@
<orderEntry type="module" module-name="jps-model-api" />
<orderEntry type="module" module-name="jps-model-serialization" />
<orderEntry type="module" module-name="jps-model-impl" />
- <orderEntry type="library" scope="TEST" name="Groovy" level="project" />
<orderEntry type="module" module-name="jps-serialization-tests" scope="TEST" />
<orderEntry type="library" scope="TEST" name="KotlinJavaRuntime" level="project" />
</component>
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Callbacks.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Callbacks.java
index 16a3da40fca1..18419a39f50c 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Callbacks.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Callbacks.java
@@ -29,6 +29,7 @@ public class Callbacks {
public interface Backend {
void associate(String classFileName, String sourceFileName, ClassReader cr);
+ void associate(String classFileName, Collection<String> sources, ClassReader cr);
void registerImports(String className, Collection<String> imports, Collection<String> staticImports);
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectMultiMaplet.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectMultiMaplet.java
index b5415cebaf84..7699e2043670 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectMultiMaplet.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectMultiMaplet.java
@@ -28,7 +28,7 @@ import java.util.List;
* @author: db
* Date: 03.11.11
*/
-abstract class IntObjectMultiMaplet<V extends Streamable> implements Streamable {
+abstract class IntObjectMultiMaplet<V> implements Streamable {
abstract boolean containsKey(final int key);
abstract Collection<V> get(final int key);
@@ -78,12 +78,17 @@ abstract class IntObjectMultiMaplet<V extends Streamable> implements Streamable
final List<String> list = new LinkedList<String>();
for (final V value : b) {
- final ByteArrayOutputStream baos = new ByteArrayOutputStream();
- final PrintStream s = new PrintStream(baos);
+ if (value instanceof Streamable) {
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final PrintStream s = new PrintStream(baos);
- value.toStream(context, s);
+ ((Streamable)value).toStream(context, s);
- list.add(baos.toString());
+ list.add(baos.toString());
+ }
+ else {
+ list.add(value.toString());
+ }
}
Collections.sort(list);
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectPersistentMultiMaplet.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectPersistentMultiMaplet.java
index 3dd4d446c99a..39fbd5b91e42 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectPersistentMultiMaplet.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectPersistentMultiMaplet.java
@@ -32,7 +32,7 @@ import java.util.Collections;
* @author: db
* Date: 08.03.11
*/
-class IntObjectPersistentMultiMaplet<V extends Streamable> extends IntObjectMultiMaplet<V> {
+class IntObjectPersistentMultiMaplet<V> extends IntObjectMultiMaplet<V> {
private static final Collection NULL_COLLECTION = Collections.emptySet();
private static final int CACHE_SIZE = 128;
private final PersistentHashMap<Integer, Collection<V>> myMap;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectTransientMultiMaplet.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectTransientMultiMaplet.java
index 2f581805a678..f19bcfdf72a3 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectTransientMultiMaplet.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntObjectTransientMultiMaplet.java
@@ -24,7 +24,7 @@ import java.util.Collection;
* @author: db
* Date: 08.03.11
*/
-class IntObjectTransientMultiMaplet<V extends Streamable> extends IntObjectMultiMaplet<V> {
+class IntObjectTransientMultiMaplet<V> extends IntObjectMultiMaplet<V> {
private final TIntObjectHashMap<Collection<V>> myMap = new TIntObjectHashMap<Collection<V>>();
private final CollectionFactory<V> myCollectionFactory;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
index a397d4b87a55..3e3a4793cbb6 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
@@ -85,7 +85,7 @@ public class Mappings {
*/
private IntIntMultiMaplet myClassToClassDependency;
private ObjectObjectMultiMaplet<File, ClassRepr> mySourceFileToClasses;
- private IntObjectMaplet<File> myClassToSourceFile;
+ private IntObjectMultiMaplet<File> myClassToSourceFile;
/**
* [short className] -> list of FQ names
*/
@@ -138,12 +138,17 @@ public class Mappings {
myRemovedSuperClasses = myIsDelta ? new IntIntTransientMultiMaplet() : null;
myAddedSuperClasses = myIsDelta ? new IntIntTransientMultiMaplet() : null;
+ final CollectionFactory<File> fileCollectionFactory = new CollectionFactory<File>() {
+ public Collection<File> create() {
+ return new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY); // todo: do we really need set and not a list here?
+ }
+ };
if (myIsDelta && myDeltaIsTransient) {
myClassToSubclasses = new IntIntTransientMultiMaplet();
myClassToClassDependency = new IntIntTransientMultiMaplet();
myShortClassNameIndex = null;
mySourceFileToClasses = new ObjectObjectTransientMultiMaplet<File, ClassRepr>(FileUtil.FILE_HASHING_STRATEGY, ourClassSetConstructor);
- myClassToSourceFile = new IntObjectTransientMaplet<File>();
+ myClassToSourceFile = new IntObjectTransientMultiMaplet<File>(fileCollectionFactory);
}
else {
if (myIsDelta) {
@@ -156,7 +161,7 @@ public class Mappings {
DependencyContext.getTableFile(myRootDir, SOURCE_TO_CLASS), new FileKeyDescriptor(), ClassRepr.externalizer(myContext),
ourClassSetConstructor
);
- myClassToSourceFile = new IntObjectPersistentMaplet<File>(DependencyContext.getTableFile(myRootDir, CLASS_TO_SOURCE), new FileKeyDescriptor());
+ myClassToSourceFile = new IntObjectPersistentMultiMaplet<File>(DependencyContext.getTableFile(myRootDir, CLASS_TO_SOURCE), INT_KEY_DESCRIPTOR, new FileKeyDescriptor(), fileCollectionFactory);
}
}
@@ -190,17 +195,17 @@ public class Mappings {
}
@Nullable
- private ClassRepr getReprByName(@Nullable File source, final int name) {
- if (source == null) {
- source = myClassToSourceFile.get(name);
- }
- if (source != null) {
- final Collection<ClassRepr> reprs = mySourceFileToClasses.get(source);
-
- if (reprs != null) {
- for (ClassRepr repr : reprs) {
- if (repr.name == name) {
- return repr;
+ private ClassRepr getReprByName(final @Nullable File source, final int qName) {
+ final Collection<File> sources = source != null? Collections.singleton(source) : myClassToSourceFile.get(qName);
+ if (sources != null) {
+ for (File src : sources) {
+ final Collection<ClassRepr> reprs = mySourceFileToClasses.get(src);
+
+ if (reprs != null) {
+ for (ClassRepr repr : reprs) {
+ if (repr.name == qName) {
+ return repr;
+ }
}
}
}
@@ -556,14 +561,19 @@ public class Mappings {
void affectSubclasses(final int className, final Collection<File> affectedFiles, final Collection<UsageRepr.Usage> affectedUsages, final TIntHashSet dependants, final boolean usages, final Collection<File> alreadyCompiledFiles) {
debug("Affecting subclasses of class: ", className);
- final File fileName = myClassToSourceFile.get(className);
- if (fileName == null) {
+ final Collection<File> allSources = myClassToSourceFile.get(className);
+ if (allSources == null || allSources.isEmpty()) {
debug("No source file detected for class ", className);
debug("End of affectSubclasses");
return;
}
- debug("Source file name: ", fileName);
+ for (File fName : allSources) {
+ debug("Source file name: ", fName);
+ if (!alreadyCompiledFiles.contains(fName)) {
+ affectedFiles.add(fName);
+ }
+ }
if (usages) {
debug("Class usages affection requested");
@@ -579,9 +589,6 @@ public class Mappings {
if (depClasses != null) {
addAll(dependants, depClasses);
}
- if (!alreadyCompiledFiles.contains(fileName)) {
- affectedFiles.add(fileName);
- }
final TIntHashSet directSubclasses = myClassToSubclasses.get(className);
if (directSubclasses != null) {
@@ -701,10 +708,14 @@ public class Mappings {
dependants.forEach(new TIntProcedure() {
@Override
public boolean execute(int depClass) {
- final File depFile = myClassToSourceFile.get(depClass);
- if (depFile != null && !FileUtil.filesEqual(depFile, sourceFile)) {
- if (filter == null || filter.accept(depFile)) {
- affectedFiles.add(depFile);
+ final Collection<File> allSources = myClassToSourceFile.get(depClass);
+ if (allSources != null) {
+ for (File depFile : allSources) {
+ if (!FileUtil.filesEqual(depFile, sourceFile)) {
+ if (filter == null || filter.accept(depFile)) {
+ affectedFiles.add(depFile);
+ }
+ }
}
}
return true;
@@ -757,6 +768,8 @@ public class Mappings {
return false;
}
+ final THashSet<File> toRecompile = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
+
// Protected branch
if (member.isProtected()) {
debug("Protected access, softening non-incremental decision: adding all relevant subclasses for a recompilation");
@@ -766,10 +779,12 @@ public class Mappings {
propagated.forEach(new TIntProcedure() {
@Override
public boolean execute(int className) {
- final File fileName = myClassToSourceFile.get(className);
- if (fileName != null && !currentlyCompiled.contains(fileName)) {
- debug("Adding ", fileName);
- affectedFiles.add(fileName);
+ final Collection<File> fileNames = myClassToSourceFile.get(className);
+ if (fileNames != null) {
+ for (File fileName : fileNames) {
+ debug("Adding ", fileName);
+ }
+ toRecompile.addAll(fileNames);
}
return true;
}
@@ -782,19 +797,32 @@ public class Mappings {
debug("Package name: ", packageName);
// Package-local branch
- myClassToSourceFile.forEachEntry(new TIntObjectProcedure<File>() {
+ myClassToSourceFile.forEachEntry(new TIntObjectProcedure<Collection<File>>() {
@Override
- public boolean execute(int className, File fileName) {
+ public boolean execute(int className, Collection<File> fileNames) {
if (ClassRepr.getPackageName(myContext.getValue(className)).equals(packageName)) {
- if ((filter == null || filter.accept(fileName)) && !currentlyCompiled.contains(fileName)) {
- debug("Adding: ", fileName);
- affectedFiles.add(fileName);
+ for (File fileName : fileNames) {
+ if (filter == null || filter.accept(fileName)) {
+ debug("Adding: ", fileName);
+ toRecompile.add(fileName);
+ }
}
}
return true;
}
});
+ // filtering already compiled and non-existing paths
+ toRecompile.removeAll(currentlyCompiled);
+ for (Iterator<File> it = toRecompile.iterator(); it.hasNext(); ) {
+ final File file = it.next();
+ if (!file.exists()) {
+ it.remove();
+ }
+ }
+
+ affectedFiles.addAll(toRecompile);
+
return true;
}
@@ -1094,12 +1122,14 @@ public class Mappings {
if (overrides.satisfy(method) && isInheritor) {
debug("Current method overrides that found");
- final File file = myClassToSourceFile.get(methodClass.name);
-
- if (file != null) {
- myAffectedFiles.add(file);
- debug("Affecting file ", file);
+ final Collection<File> files = myClassToSourceFile.get(methodClass.name);
+ if (files != null) {
+ myAffectedFiles.addAll(files);
+ for (File file : files) {
+ debug("Affecting file ", file);
+ }
}
+
}
else {
debug("Current method does not override that found");
@@ -1128,12 +1158,15 @@ public class Mappings {
@Override
public boolean execute(int subClass) {
final ClassRepr r = myFuture.reprByName(subClass);
- if (r != null) {
- final File sourceFileName = myClassToSourceFile.get(subClass);
- if (sourceFileName != null && !myCompiledFiles.contains(sourceFileName)) {
- final int outerClass = r.getOuterClassName();
- if (!isEmpty(outerClass) && myFuture.isMethodVisible(outerClass, m)) {
- myAffectedFiles.add(sourceFileName);
+ if (r == null) {
+ return true;
+ }
+ final Collection<File> sourceFileNames = myClassToSourceFile.get(subClass);
+ if (sourceFileNames != null && !myCompiledFiles.containsAll(sourceFileNames)) {
+ final int outerClass = r.getOuterClassName();
+ if (!isEmpty(outerClass) && myFuture.isMethodVisible(outerClass, m)) {
+ myAffectedFiles.addAll(sourceFileNames);
+ for (File sourceFileName : sourceFileNames) {
debug("Affecting file due to local overriding: ", sourceFileName);
}
}
@@ -1186,10 +1219,12 @@ public class Mappings {
myFuture.addOverridingMethods(m, it, MethodRepr.equalByJavaRules(m), overridingMethods);
for (final Pair<MethodRepr, ClassRepr> p : overridingMethods) {
- final File fName = myClassToSourceFile.get(p.second.name);
- if (fName != null) {
- myAffectedFiles.add(fName);
- debug("Affecting file by overriding: ", fName);
+ final Collection<File> fNames = myClassToSourceFile.get(p.second.name);
+ if (fNames != null) {
+ myAffectedFiles.addAll(fNames);
+ for (File fName : fNames) {
+ debug("Affecting file by overriding: ", fName);
+ }
}
}
@@ -1229,12 +1264,14 @@ public class Mappings {
}
if (allAbstract && visited) {
- final File source = myClassToSourceFile.get(p);
+ final Collection<File> sources = myClassToSourceFile.get(p);
- if (source != null && !myCompiledFiles.contains(source)) {
- myAffectedFiles.add(source);
+ if (sources != null && !myCompiledFiles.containsAll(sources)) {
+ myAffectedFiles.addAll(sources);
debug("Removed method is not abstract & overrides some abstract method which is not then over-overridden in subclass ", p);
- debug("Affecting subclass source file ", source);
+ for (File source : sources) {
+ debug("Affecting subclass source file ", source);
+ }
}
}
}
@@ -1304,9 +1341,9 @@ public class Mappings {
final ClassRepr aClass = p.getSecond();
if (aClass != MOCK_CLASS) {
- final File fileName = myClassToSourceFile.get(aClass.name);
- if (fileName != null) {
- myAffectedFiles.add(fileName);
+ final Collection<File> fileNames = myClassToSourceFile.get(aClass.name);
+ if (fileNames != null) {
+ myAffectedFiles.addAll(fileNames);
}
}
}
@@ -1374,17 +1411,21 @@ public class Mappings {
public boolean execute(int subClass) {
final ClassRepr r = myFuture.reprByName(subClass);
if (r != null) {
- final File sourceFileName = myClassToSourceFile.get(subClass);
- if (sourceFileName != null && !myCompiledFiles.contains(sourceFileName)) {
+ final Collection<File> sourceFileNames = myClassToSourceFile.get(subClass);
+ if (sourceFileNames != null && !myCompiledFiles.containsAll(sourceFileNames)) {
if (r.isLocal()) {
- debug("Affecting local subclass (introduced field can potentially hide surrounding method parameters/local variables): ", sourceFileName);
- myAffectedFiles.add(sourceFileName);
+ for (File sourceFileName : sourceFileNames) {
+ debug("Affecting local subclass (introduced field can potentially hide surrounding method parameters/local variables): ", sourceFileName);
+ }
+ myAffectedFiles.addAll(sourceFileNames);
}
else {
final int outerClass = r.getOuterClassName();
if (!isEmpty(outerClass) && myFuture.isFieldVisible(outerClass, f)) {
- debug("Affecting inner subclass (introduced field can potentially hide surrounding class fields): ", sourceFileName);
- myAffectedFiles.add(sourceFileName);
+ for (File sourceFileName : sourceFileNames) {
+ debug("Affecting inner subclass (introduced field can potentially hide surrounding class fields): ", sourceFileName);
+ }
+ myAffectedFiles.addAll(sourceFileNames);
}
}
}
@@ -1783,7 +1824,9 @@ public class Mappings {
// checking if this newly added class duplicates already existing one
for (ClassRepr c : addedClasses) {
if (!c.isLocal() && !c.isAnonymous() && isEmpty(c.getOuterClassName())) {
- final File currentlyMappedTo = myClassToSourceFile.get(c.name);
+ final Collection<File> currentSources = myClassToSourceFile.get(c.name);
+ final File currentlyMappedTo = currentSources != null && currentSources.size() == 1? currentSources.iterator().next() : null;
+ // only check, if exactly one file is mapped
if (currentlyMappedTo != null && !FileUtil.filesEqual(currentlyMappedTo, srcFile) && currentlyMappedTo.exists() && myFilter.belongsToCurrentTargetChunk(currentlyMappedTo)) {
// Same classes from different source files.
// Schedule for recompilation both to make possible 'duplicate sources' error evident
@@ -1832,11 +1875,13 @@ public class Mappings {
toAffect.forEach(new TIntProcedure() {
@Override
public boolean execute(int depClass) {
- final File fName = myClassToSourceFile.get(depClass);
- if (fName != null) {
- if (myFilter == null || myFilter.accept(fName)) {
- debug("Adding dependent file ", fName);
- myAffectedFiles.add(fName);
+ final Collection<File> fNames = myClassToSourceFile.get(depClass);
+ if (fNames != null) {
+ for (File fName : fNames) {
+ if (myFilter == null || myFilter.accept(fName)) {
+ debug("Adding dependent file ", fName);
+ myAffectedFiles.add(fName);
+ }
}
}
return true;
@@ -1850,24 +1895,30 @@ public class Mappings {
state.myDependants.forEach(new TIntProcedure() {
@Override
public boolean execute(final int depClass) {
- final File depFile = myClassToSourceFile.get(depClass);
+ final Collection<File> depFiles = myClassToSourceFile.get(depClass);
+ if (depFiles != null) {
+ for (File depFile : depFiles) {
+ processDependentFile(depClass, depFile);
+ }
+ }
+ return true;
+ }
- if (depFile == null || myAffectedFiles.contains(depFile) || myCompiledFiles.contains(depFile)) {
- return true;
+ private void processDependentFile(int depClass, @NotNull File depFile) {
+ if (myAffectedFiles.contains(depFile) || myCompiledFiles.contains(depFile)) {
+ return;
}
debug("Dependent class: ", depClass);
final ClassRepr classRepr = getReprByName(depFile, depClass);
-
if (classRepr == null) {
- return true;
+ return;
}
final Set<UsageRepr.Usage> depUsages = classRepr.getUsages();
-
if (depUsages == null || depUsages.isEmpty()) {
- return true;
+ return;
}
for (UsageRepr.Usage usage : depUsages) {
@@ -1876,32 +1927,24 @@ public class Mappings {
if (query.satisfies(usage)) {
debug("Added file due to annotation query");
myAffectedFiles.add(depFile);
-
- return true;
+ return;
}
}
}
else if (state.myAffectedUsages.contains(usage)) {
final Util.UsageConstraint constraint = state.myUsageConstraints.get(usage);
-
if (constraint == null) {
debug("Added file with no constraints");
myAffectedFiles.add(depFile);
-
- return true;
+ return;
}
- else {
- if (constraint.checkResidence(depClass)) {
- debug("Added file with satisfied constraint");
- myAffectedFiles.add(depFile);
-
- return true;
- }
+ if (constraint.checkResidence(depClass)) {
+ debug("Added file with satisfied constraint");
+ myAffectedFiles.add(depFile);
+ return;
}
}
}
-
- return true;
}
});
}
@@ -2007,11 +2050,27 @@ public class Mappings {
private void cleanupRemovedClass(final Mappings delta, @NotNull final ClassRepr cr, File sourceFile, final Set<UsageRepr.Usage> usages, final IntIntMultiMaplet dependenciesTrashBin) {
final int className = cr.name;
- if (!FileUtil.filesEqual(sourceFile, myClassToSourceFile.get(className))) {
- // if classname is already mapped to a different source, the class with such FQ name exists elsewhere, so
- // we cannot destroy all these links
+
+ // it is safe to cleanup class information if it is mapped to non-existing files only
+ final Collection<File> currentlyMapped = myClassToSourceFile.get(className);
+ if (currentlyMapped == null || currentlyMapped.isEmpty()) {
return;
}
+ if (currentlyMapped.size() == 1) {
+ if (!FileUtil.filesEqual(sourceFile, currentlyMapped.iterator().next())) {
+ // if classname is already mapped to a different source, the class with such FQ name exists elsewhere, so
+ // we cannot destroy all these links
+ return;
+ }
+ }
+ else {
+ // many files
+ for (File file : currentlyMapped) {
+ if (!FileUtil.filesEqual(sourceFile, file) && file.exists()) {
+ return;
+ }
+ }
+ }
for (final int superSomething : cr.getSupers()) {
delta.registerRemovedSuperClass(className, superSomething);
@@ -2113,13 +2172,8 @@ public class Mappings {
delta.getChangedClasses().forEach(new TIntProcedure() {
@Override
public boolean execute(final int className) {
- final File sourceFile = delta.myClassToSourceFile.get(className);
- if (sourceFile != null) {
- myClassToSourceFile.put(className, sourceFile);
- }
- else {
- myClassToSourceFile.remove(className);
- }
+ final Collection<File> sourceFiles = delta.myClassToSourceFile.get(className);
+ myClassToSourceFile.replace(className, sourceFiles);
cleanupBackDependency(className, null, dependenciesTrashBin);
@@ -2138,7 +2192,7 @@ public class Mappings {
}
else {
myClassToSubclasses.putAll(delta.myClassToSubclasses);
- myClassToSourceFile.putAll(delta.myClassToSourceFile);
+ myClassToSourceFile.replaceAll(delta.myClassToSourceFile);
mySourceFileToClasses.replaceAll(delta.mySourceFileToClasses);
delta.mySourceFileToClasses.forEachEntry(new TObjectObjectProcedure<File, Collection<ClassRepr>>() {
public boolean execute(File src, Collection<ClassRepr> classes) {
@@ -2203,18 +2257,21 @@ public class Mappings {
public Callbacks.Backend getCallback() {
return new Callbacks.Backend() {
- public void associate(final String classFileName, final String sourceFileName, final ClassReader cr) {
+
+ public void associate(String classFileName, Collection<String> sources, ClassReader cr) {
synchronized (myLock) {
final int classFileNameS = myContext.get(classFileName);
final Pair<ClassRepr, Set<UsageRepr.Usage>> result = new ClassfileAnalyzer(myContext).analyze(classFileNameS, cr);
final ClassRepr repr = result.first;
if (repr != null) {
final Set<UsageRepr.Usage> localUsages = result.second;
- final File sourceFile = new File(sourceFileName);
final int className = repr.name;
- myClassToSourceFile.put(className, sourceFile);
- mySourceFileToClasses.put(sourceFile, repr);
+ for (String sourceFileName : sources) {
+ final File sourceFile = new File(sourceFileName);
+ myClassToSourceFile.put(className, sourceFile);
+ mySourceFileToClasses.put(sourceFile, repr);
+ }
for (final int s : repr.getSupers()) {
myClassToSubclasses.put(s, className);
@@ -2231,6 +2288,10 @@ public class Mappings {
}
}
+ public void associate(final String classFileName, final String sourceFileName, final ClassReader cr) {
+ associate(classFileName, Collections.singleton(sourceFileName), cr);
+ }
+
@Override
public void registerImports(final String className, final Collection<String> imports, Collection<String> staticImports) {
final List<String> allImports = new ArrayList<String>();
@@ -2252,14 +2313,16 @@ public class Mappings {
myPostPasses.offer(new Runnable() {
public void run() {
final int rootClassName = myContext.get(className.replace(".", "/"));
- final File fileName = myClassToSourceFile.get(rootClassName);
- final ClassRepr repr = fileName != null? getReprByName(fileName, rootClassName) : null;
+ final Collection<File> fileNames = myClassToSourceFile.get(rootClassName);
+ final ClassRepr repr = fileNames != null && !fileNames.isEmpty()? getReprByName(fileNames.iterator().next(), rootClassName) : null;
for (final String i : allImports) {
- final int iname = myContext.get(i.replace(".", "/"));
+ final int iname = myContext.get(i.replace('.', '/'));
myClassToClassDependency.put(iname, rootClassName);
if (repr != null && repr.addUsage(UsageRepr.createClassUsage(myContext, iname))) {
- mySourceFileToClasses.put(fileName, repr);
+ for (File fileName : fileNames) {
+ mySourceFileToClasses.put(fileName, repr);
+ }
}
}
}
@@ -2386,10 +2449,10 @@ public class Mappings {
assert (myChangedClasses != null && myChangedFiles != null);
myChangedClasses.add(it);
- final File file = myClassToSourceFile.get(it);
+ final Collection<File> files = myClassToSourceFile.get(it);
- if (file != null) {
- myChangedFiles.add(file);
+ if (files != null) {
+ myChangedFiles.addAll(files);
}
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java
index 551c3ce2f308..bc353aa4b144 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java
@@ -144,7 +144,7 @@ public abstract class ClassProcessingBuilder extends ModuleLevelBuilder {
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
result.set(version);
}
- }, 0);
+ }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
return result.get();
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java
index 823fe088d0cc..a6ed636e8d11 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java
@@ -42,7 +42,7 @@ import java.util.concurrent.ConcurrentMap;
* Date: 10/7/11
*/
public class BuildDataManager implements StorageOwner {
- private static final int VERSION = 24;
+ private static final int VERSION = 25;
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager");
private static final String SRC_TO_FORM_STORAGE = "src-form";
private static final String OUT_TARGET_STORAGE = "out-target";
diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JavacFileEncodingTest.groovy b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JavacFileEncodingTest.kt
index 80770ee36359..a3017b2bc2dd 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JavacFileEncodingTest.groovy
+++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JavacFileEncodingTest.kt
@@ -16,13 +16,14 @@
package org.jetbrains.jps.builders
import org.jetbrains.jps.builders.rebuild.JpsRebuildTestCase
+import org.jetbrains.jps.builders.rebuild.fs
/**
* @author nik
*/
-class JavacFileEncodingTest extends JpsRebuildTestCase {
- public void test() {
- doTest("javacFileEncoding/javacFileEncoding.ipr", {
+class JavacFileEncodingTest: JpsRebuildTestCase() {
+ fun test() {
+ doTest("javacFileEncoding/javacFileEncoding.ipr", fs {
dir("production") {
dir("javacFileEncoding") {
file("MyClass.class")
diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java
index 2c3fca029cd9..eb9b42a3904d 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java
+++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java
@@ -225,7 +225,7 @@ public abstract class JpsBuildTestCase extends UsefulTestCase {
Map<String, String> allPathVariables = new HashMap<String, String>(pathVariables.size() + 1);
allPathVariables.putAll(pathVariables);
allPathVariables.put(PathMacroUtil.APPLICATION_HOME_DIR, PathManager.getHomePath());
- addPathVariables(allPathVariables);
+ allPathVariables.putAll(getAdditionalPathVariables());
JpsProjectLoader.loadProject(myProject, allPathVariables, fullProjectPath);
}
catch (IOException e) {
@@ -233,7 +233,9 @@ public abstract class JpsBuildTestCase extends UsefulTestCase {
}
}
- protected void addPathVariables(Map<String, String> pathVariables) {
+ @NotNull
+ protected Map<String, String> getAdditionalPathVariables() {
+ return Collections.emptyMap();
}
@Nullable
diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/ModuleClasspathTest.kt b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/ModuleClasspathTest.kt
index b76196eba947..cabb841db7f4 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/ModuleClasspathTest.kt
+++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/ModuleClasspathTest.kt
@@ -30,68 +30,68 @@ import org.junit.Assert
* @author nik
*/
public class ModuleClasspathTest(): JpsBuildTestCase() {
- override fun setUp() {
- super.setUp()
- addJdk("1.6", "/jdk.jar")
- addJdk("1.5", "/jdk15.jar")
- loadProject("moduleClasspath/moduleClasspath.ipr")
- }
+ override fun setUp() {
+ super.setUp()
+ addJdk("1.6", "/jdk.jar")
+ addJdk("1.5", "/jdk15.jar")
+ loadProject("moduleClasspath/moduleClasspath.ipr")
+ }
- private fun getProjectPath(): String {
- return FileUtil.toSystemIndependentName(getTestDataRootPath()) + "/moduleClasspath/moduleClasspath.ipr"
- }
+ private fun getProjectPath(): String {
+ return FileUtil.toSystemIndependentName(getTestDataRootPath()) + "/moduleClasspath/moduleClasspath.ipr"
+ }
- override fun getTestDataRootPath(): String {
- return FileUtil.toCanonicalPath(PathManagerEx.findFileUnderCommunityHome("jps/jps-builders/testData/output")!!.getAbsolutePath(), '/')!!
- }
+ override fun getTestDataRootPath(): String {
+ return FileUtil.toCanonicalPath(PathManagerEx.findFileUnderCommunityHome("jps/jps-builders/testData/output")!!.getAbsolutePath(), '/')!!
+ }
- public fun testSimpleClasspath() {
- assertClasspath("util", false, listOf("util/lib/exported.jar", "/jdk15.jar"))
- }
+ public fun testSimpleClasspath() {
+ assertClasspath("util", false, listOf("util/lib/exported.jar", "/jdk15.jar"))
+ }
- public fun testScopes() {
- assertClasspath("test-util", false, listOf("/jdk.jar", "test-util/lib/provided.jar"))
- assertClasspath("test-util", true, listOf("/jdk.jar", "test-util/lib/provided.jar", "test-util/lib/test.jar", "out/production/test-util"))
- }
+ public fun testScopes() {
+ assertClasspath("test-util", false, listOf("/jdk.jar", "test-util/lib/provided.jar"))
+ assertClasspath("test-util", true, listOf("/jdk.jar", "test-util/lib/provided.jar", "test-util/lib/test.jar", "out/production/test-util"))
+ }
- public fun testDepModules() {
- assertClasspath("main", false, listOf("util/lib/exported.jar", "out/production/util", "/jdk.jar", "main/lib/service.jar"))
- assertClasspath("main", true, listOf("out/production/main", "util/lib/exported.jar", "out/test/util", "out/production/util", "/jdk.jar", "out/test/test-util", "out/production/test-util", "main/lib/service.jar"))
- }
+ public fun testDepModules() {
+ assertClasspath("main", false, listOf("util/lib/exported.jar", "out/production/util", "/jdk.jar", "main/lib/service.jar"))
+ assertClasspath("main", true, listOf("out/production/main", "util/lib/exported.jar", "out/test/util", "out/production/util", "/jdk.jar", "out/test/test-util", "out/production/test-util", "main/lib/service.jar"))
+ }
- public fun testCompilationClasspath() {
- val chunk = createChunk("main")
- assertClasspath(listOf("util/lib/exported.jar", "out/production/util", "/jdk.jar"), getPathsList(ProjectPaths.getPlatformCompilationClasspath(chunk, true)))
- assertClasspath(listOf("main/lib/service.jar"), getPathsList(ProjectPaths.getCompilationClasspath(chunk, true)))
- }
+ public fun testCompilationClasspath() {
+ val chunk = createChunk("main")
+ assertClasspath(listOf("util/lib/exported.jar", "out/production/util", "/jdk.jar"), getPathsList(ProjectPaths.getPlatformCompilationClasspath(chunk, true)))
+ assertClasspath(listOf("main/lib/service.jar"), getPathsList(ProjectPaths.getCompilationClasspath(chunk, true)))
+ }
- private fun assertClasspath(moduleName: String, includeTests: Boolean, expected: List<String>) {
- val classpath = getPathsList(ProjectPaths.getCompilationClasspathFiles(createChunk(moduleName), includeTests, true, true))
- assertClasspath(expected, toSystemIndependentPaths(classpath))
- }
+ private fun assertClasspath(moduleName: String, includeTests: Boolean, expected: List<String>) {
+ val classpath = getPathsList(ProjectPaths.getCompilationClasspathFiles(createChunk(moduleName), includeTests, true, true))
+ assertClasspath(expected, toSystemIndependentPaths(classpath))
+ }
- private fun createChunk(moduleName: String): ModuleChunk {
- val module = myProject.getModules().firstOrNull { it.getName() == moduleName }
- return ModuleChunk(setOf(ModuleBuildTarget(module!!, JavaModuleBuildTargetType.PRODUCTION)))
- }
+ private fun createChunk(moduleName: String): ModuleChunk {
+ val module = myProject.getModules().first { it.getName() == moduleName }
+ return ModuleChunk(setOf(ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION)))
+ }
- private fun assertClasspath(expected: List<String>, classpath: List<String>) {
- val basePath = FileUtil.toSystemIndependentName(File(getProjectPath()).getParentFile()!!.getAbsolutePath()) + "/"
- val actual = toSystemIndependentPaths(classpath).map { StringUtil.trimStart(it, basePath) }
- Assert.assertEquals(expected.join("\n"), actual.join("\n"))
- }
+ private fun assertClasspath(expected: List<String>, classpath: List<String>) {
+ val basePath = FileUtil.toSystemIndependentName(File(getProjectPath()).getParentFile()!!.getAbsolutePath()) + "/"
+ val actual = toSystemIndependentPaths(classpath).map { StringUtil.trimStart(it, basePath) }
+ Assert.assertEquals(expected.join("\n"), actual.join("\n"))
+ }
- private fun toSystemIndependentPaths(classpath: List<String>): List<String> {
- return classpath.map(FileUtil::toSystemIndependentName)
- }
+ private fun toSystemIndependentPaths(classpath: List<String>): List<String> {
+ return classpath.map(FileUtil::toSystemIndependentName)
+ }
- public fun getPathsList(files: Collection<File>): List<String> {
- return files.map(::getCanonicalPath)
- }
+ public fun getPathsList(files: Collection<File>): List<String> {
+ return files.map(::getCanonicalPath)
+ }
}
private fun getCanonicalPath(file: File): String {
- val path = file.getPath()
- return if (path.contains(".")) FileUtil.toCanonicalPath(path)!! else FileUtil.toSystemIndependentName(path)
+ val path = file.getPath()
+ return if (path.contains(".")) FileUtil.toCanonicalPath(path)!! else FileUtil.toSystemIndependentName(path)
}
diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ArtifactRebuildTest.groovy b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ArtifactRebuildTest.kt
index 5f4de621d724..0a3a49d559e4 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ArtifactRebuildTest.groovy
+++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ArtifactRebuildTest.kt
@@ -20,14 +20,19 @@ import com.intellij.util.io.ZipUtil
import java.util.jar.Attributes
import java.util.jar.Manifest
+import java.io.File
+import java.io.FileInputStream
+import kotlin.test.assertTrue
+import kotlin.test.assertEquals
+
/**
* @author nik
*/
-class ArtifactRebuildTest extends JpsRebuildTestCase {
- public void testArtifactIncludesArchiveArtifact() {
- def name = "artifactIncludesArchiveArtifact"
+class ArtifactRebuildTest: JpsRebuildTestCase() {
+ fun testArtifactIncludesArchiveArtifact() {
+ val name = "artifactIncludesArchiveArtifact"
try {
- doTest("$name/${name}.ipr", {
+ doTest("$name/${name}.ipr", fs {
dir("artifacts") {
dir("data") {
archive("a.jar") {
@@ -38,16 +43,16 @@ class ArtifactRebuildTest extends JpsRebuildTestCase {
})
}
finally {
- FileUtil.delete(new File(FileUtil.toSystemDependentName(getTestDataRootPath() + "/$name/data/a.jar")))
+ FileUtil.delete(File(FileUtil.toSystemDependentName(getTestDataRootPath() + "/$name/data/a.jar")))
}
}
- public void testArtifactWithoutOutput() {
- def outDir = FileUtil.createTempDirectory("output", "").absolutePath
- loadProject("artifactWithoutOutput/artifactWithoutOutput.ipr", ["OUTPUT_DIR":outDir])
+ fun testArtifactWithoutOutput() {
+ val outDir = FileUtil.createTempDirectory("output", "").getAbsolutePath()
+ loadProject("artifactWithoutOutput/artifactWithoutOutput.ipr", mapOf("OUTPUT_DIR" to outDir))
rebuild()
- assertOutput(outDir, {
+ assertOutput(outDir, fs {
dir("artifacts") {
dir("main") {
file("data.txt")
@@ -57,8 +62,8 @@ class ArtifactRebuildTest extends JpsRebuildTestCase {
})
}
- public void testExtractDir() {
- doTest("extractDirTest/extractDirTest.ipr", {
+ fun testExtractDir() {
+ doTest("extractDirTest/extractDirTest.ipr", fs {
dir("artifacts") {
dir("extractDir") {
file("b.txt", "b")
@@ -88,20 +93,20 @@ class ArtifactRebuildTest extends JpsRebuildTestCase {
})
}
- public void testManifestInArtifact() {
- loadAndRebuild("manifestInArtifact/manifest.ipr", [:])
- File jarFile = new File(myOutputDirectory, "artifacts/simple/simple.jar")
- junit.framework.Assert.assertTrue(jarFile.exists())
- File extracted = FileUtil.createTempDirectory("build-manifest", "")
+ fun testManifestInArtifact() {
+ loadAndRebuild("manifestInArtifact/manifest.ipr", mapOf())
+ val jarFile = File(myOutputDirectory, "artifacts/simple/simple.jar")
+ assertTrue(jarFile.exists())
+ val extracted = FileUtil.createTempDirectory("build-manifest", "")
ZipUtil.extract(jarFile, extracted, null)
- File manifestFile = new File(extracted, "META-INF/MANIFEST.MF")
- junit.framework.Assert.assertTrue(manifestFile.exists())
- Manifest manifest = new Manifest(new FileInputStream(manifestFile))
- junit.framework.Assert.assertEquals("MyClass", manifest.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS))
+ val manifestFile = File(extracted, "META-INF/MANIFEST.MF")
+ assertTrue(manifestFile.exists())
+ val manifest = Manifest(FileInputStream(manifestFile))
+ assertEquals("MyClass", manifest.getMainAttributes()!!.getValue(Attributes.Name.MAIN_CLASS))
}
- public void testOverwriteArtifacts() {
- doTest("overwriteTest/overwriteTest.ipr", {
+ fun testOverwriteArtifacts() {
+ doTest("overwriteTest/overwriteTest.ipr", fs {
dir("artifacts") {
dir("classes") {
file("a.xml", "<root2/>")
@@ -128,9 +133,9 @@ class ArtifactRebuildTest extends JpsRebuildTestCase {
})
}
- public void testPathVariablesInArtifact() {
- String externalDir = "${getTestDataRootPath()}/pathVariables/external"
- doTest("pathVariables/pathVariables.ipr", ["EXTERNAL_DIR": externalDir], {
+ fun testPathVariablesInArtifact() {
+ val externalDir = "${getTestDataRootPath()}/pathVariables/external"
+ doTest("pathVariables/pathVariables.ipr", mapOf("EXTERNAL_DIR" to externalDir), fs {
dir("artifacts") {
dir("fileCopy") {
dir("dir") {
@@ -141,8 +146,8 @@ class ArtifactRebuildTest extends JpsRebuildTestCase {
})
}
- public void testModuleTestOutputElement() {
- doTest("moduleTestOutput/moduleTestOutput.ipr", {
+ fun testModuleTestOutputElement() {
+ doTest("moduleTestOutput/moduleTestOutput.ipr", fs {
dir("artifacts") {
dir("tests") {
file("MyTest.class")
@@ -160,15 +165,4 @@ class ArtifactRebuildTest extends JpsRebuildTestCase {
}
})
}
-
- //todo[nik] fix
- public void _testSourceRootUnderOutput() throws Exception {
- loadProject("sourceFolderUnderOutput/sourceFolderUnderOutput.ipr", [:])
- try {
- rebuild()
- junit.framework.Assert.fail("Cleaning should fail")
- }
- catch (Exception ignored) {
- }
- }
}
diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.groovy b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.groovy
deleted file mode 100644
index 7c102399e989..000000000000
--- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.groovy
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2000-2012 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.jps.builders.rebuild
-import com.intellij.openapi.application.ex.PathManagerEx
-import com.intellij.openapi.util.io.FileUtil
-import com.intellij.util.io.TestFileSystemBuilder
-import org.jetbrains.annotations.NotNull
-import org.jetbrains.jps.util.JpsPathUtil
-import org.jetbrains.jps.builders.JpsBuildTestCase
-import org.jetbrains.jps.model.java.JpsJavaExtensionService
-/**
- * @author nik
- */
-abstract class JpsRebuildTestCase extends JpsBuildTestCase {
- protected File myOutputDirectory;
-
- @Override
- protected void setUp() {
- super.setUp()
- addJdk("1.6")
- }
-
- def doTest(String projectPath, Closure expectedOutput) {
- doTest(projectPath, [:], expectedOutput)
- }
-
- def doTest(String projectPath, Map<String, String> pathVariables, Closure expectedOutput) {
- loadAndRebuild(projectPath, pathVariables)
- assertOutput(getOrCreateOutputDirectory().getAbsolutePath(), expectedOutput);
- }
-
- def protected assertOutput(@NotNull String targetFolder, Closure expectedOutput) {
- def root = TestFileSystemBuilder.fs()
- initFileSystemItem(root, expectedOutput)
- root.build().assertDirectoryEqual(new File(FileUtil.toSystemDependentName(targetFolder)))
- }
-
- protected void loadAndRebuild(String projectPath, Map<String, String> pathVariables) {
- loadProject(projectPath, pathVariables)
- rebuild()
- }
-
- protected void rebuild() {
- JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(myProject).outputUrl = JpsPathUtil.pathToUrl(FileUtil.toSystemIndependentName(getOrCreateOutputDirectory().getAbsolutePath()))
- rebuildAll()
- }
-
- private File getOrCreateOutputDirectory() {
- if (myOutputDirectory == null) {
- myOutputDirectory = FileUtil.createTempDirectory("jps-build-output", "")
- }
- myOutputDirectory
- }
-
- @Override
- protected void addPathVariables(Map<String, String> pathVariables) {
- pathVariables.put("ARTIFACTS_OUT", FileUtil.toSystemIndependentName(getOrCreateOutputDirectory().absolutePath) + "/artifacts")
- }
-
- @Override
- protected String getTestDataRootPath() {
- return PathManagerEx.findFileUnderCommunityHome("jps/jps-builders/testData/output").absolutePath
- }
-
- def initFileSystemItem(TestFileSystemBuilder item, Closure initializer) {
- def meta = new Expando()
- meta.dir = {String name, Closure content ->
- initFileSystemItem(item.dir(name), content)
- }
- meta.archive = {String name, Closure content ->
- initFileSystemItem(item.archive(name), content)
- }
- meta.file = {Object[] args ->
- item.file((String)args[0], (String)args.length > 1 ? args[1] : null)
- }
-
- initializer.delegate = meta
- initializer.setResolveStrategy Closure.DELEGATE_FIRST
- initializer()
- }
-
- def File createTempFile() {
- return FileUtil.createTempFile("jps-build-file", "");
- }
-}
diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.kt b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.kt
new file mode 100644
index 000000000000..dae4cb005e1d
--- /dev/null
+++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.kt
@@ -0,0 +1,86 @@
+package org.jetbrains.jps.builders.rebuild;
+
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.io.TestFileSystemBuilder;
+import org.jetbrains.jps.builders.JpsBuildTestCase;
+import org.jetbrains.jps.model.java.JpsJavaExtensionService;
+import org.jetbrains.jps.util.JpsPathUtil;
+
+import java.io.File;
+import java.util.LinkedHashMap;
+import kotlin.properties.Delegates
+import com.intellij.util.io.TestFileSystemItem
+
+/**
+ * @author nik
+ */
+public abstract class JpsRebuildTestCase: JpsBuildTestCase() {
+ protected val myOutputDirectory: File by Delegates.lazy {
+ FileUtil.createTempDirectory("jps-build-output", "")
+ }
+
+ override fun setUp() {
+ super.setUp()
+ addJdk("1.6");
+ }
+
+ fun doTest(projectPath: String, expectedOutput: TestFileSystemItem) {
+ doTest(projectPath, LinkedHashMap<String, String>(), expectedOutput);
+ }
+
+ fun doTest(projectPath: String, pathVariables: Map<String, String>, expectedOutput: TestFileSystemItem) {
+ loadAndRebuild(projectPath, pathVariables);
+ assertOutput(myOutputDirectory.getAbsolutePath(), expectedOutput);
+ }
+
+ fun assertOutput(targetFolder: String, expectedOutput: TestFileSystemItem) {
+ expectedOutput.assertDirectoryEqual(File(FileUtil.toSystemDependentName(targetFolder)));
+ }
+
+ fun loadAndRebuild(projectPath: String, pathVariables: Map<String, String>) {
+ loadProject(projectPath, pathVariables);
+ rebuild();
+ }
+
+ fun rebuild() {
+ JpsJavaExtensionService.getInstance()!!.getOrCreateProjectExtension(myProject)
+ .setOutputUrl(JpsPathUtil.pathToUrl(FileUtil.toSystemIndependentName(myOutputDirectory.getAbsolutePath())));
+ rebuildAll();
+ }
+
+ override fun getAdditionalPathVariables(): MutableMap<String, String> =
+ hashMapOf("ARTIFACTS_OUT" to FileUtil.toSystemIndependentName(myOutputDirectory.getAbsolutePath()) + "/artifacts")
+
+ protected override fun getTestDataRootPath(): String {
+ return PathManagerEx.findFileUnderCommunityHome("jps/jps-builders/testData/output")!!.getAbsolutePath();
+ }
+}
+
+fun fs(init: TestFileSystemBuilderBuilder.() -> Unit): TestFileSystemItem {
+ val builder = TestFileSystemBuilder.fs()
+ TestFileSystemBuilderBuilder(builder).init()
+ return builder.build()
+}
+
+class TestFileSystemBuilderBuilder(private val current: TestFileSystemBuilder) {
+ fun file(name: String) {
+ current.file(name)
+ }
+
+ fun file(name: String, content: String) {
+ current.file(name, content)
+ }
+
+ fun dir(name: String, init: TestFileSystemBuilderBuilder.() -> Unit) {
+ val dir = current.dir(name)
+ TestFileSystemBuilderBuilder(dir).init()
+ dir.end()
+ }
+
+ fun archive(name: String, init: TestFileSystemBuilderBuilder.() -> Unit) {
+ val dir = current.archive(name)
+ TestFileSystemBuilderBuilder(dir).init()
+ dir.end()
+ }
+} \ No newline at end of file
diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ModuleRebuildTest.groovy b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ModuleRebuildTest.kt
index 36e03eb0890b..09e72b77cf2a 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ModuleRebuildTest.groovy
+++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ModuleRebuildTest.kt
@@ -17,9 +17,9 @@ package org.jetbrains.jps.builders.rebuild
/**
* @author nik
*/
-public class ModuleRebuildTest extends JpsRebuildTestCase {
- public void testModuleCycle() {
- doTest("moduleCycle/moduleCycle.ipr", {
+public class ModuleRebuildTest: JpsRebuildTestCase() {
+ fun testModuleCycle() {
+ doTest("moduleCycle/moduleCycle.ipr", fs {
dir("production") {
dir("module1") {
file("Bar1.class")
@@ -34,8 +34,8 @@ public class ModuleRebuildTest extends JpsRebuildTestCase {
})
}
- public void testOverlappingSourceRoots() {
- doTest("overlappingSourceRoots/overlappingSourceRoots.ipr", {
+ fun testOverlappingSourceRoots() {
+ doTest("overlappingSourceRoots/overlappingSourceRoots.ipr", fs {
dir("production") {
dir("inner") {
dir("y") {
@@ -52,8 +52,8 @@ public class ModuleRebuildTest extends JpsRebuildTestCase {
})
}
- public void testResourceCopying() {
- doTest("resourceCopying/resourceCopying.ipr", {
+ fun testResourceCopying() {
+ doTest("resourceCopying/resourceCopying.ipr", fs {
dir("production") {
dir("resourceCopying") {
dir("copy") {