diff options
author | Tor Norbye <tnorbye@google.com> | 2014-08-19 22:27:03 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-08-19 21:25:05 +0000 |
commit | 4ca751c002784c4bfd349cc5240b045b62277c80 (patch) | |
tree | dfc17b31990e2429535609b85f6d080c4fa0d9fe /jps | |
parent | 890d9a2952301682ffecaed4495f5f65c84c3642 (diff) | |
parent | 060e58b3afea3ea39f5ba1cb5a443ca3ebda28c8 (diff) | |
download | idea-4ca751c002784c4bfd349cc5240b045b62277c80.tar.gz |
Merge "Merge remote-tracking branch 'aosp/upstream-master' into merge"
Diffstat (limited to 'jps')
18 files changed, 417 insertions, 373 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") { diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/PathMacroUtil.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/PathMacroUtil.java index 6214412c4a52..cf87eb5744b3 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/PathMacroUtil.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/PathMacroUtil.java @@ -16,16 +16,19 @@ package org.jetbrains.jps.model.serialization; import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.ObjectUtils; import com.intellij.util.SystemProperties; -import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.Map; +import static com.intellij.openapi.util.io.FileUtil.toSystemIndependentName; + /** * @author nik */ @@ -34,9 +37,16 @@ public class PathMacroUtil { @NonNls public static final String MODULE_DIR_MACRO_NAME = "MODULE_DIR"; @NonNls public static final String DIRECTORY_STORE_NAME = ".idea"; @NonNls public static final String APPLICATION_HOME_DIR = "APPLICATION_HOME_DIR"; + @NonNls public static final String APPLICATION_CONFIG_DIR = "APPLICATION_CONFIG_DIR"; @NonNls public static final String APPLICATION_PLUGINS_DIR = "APPLICATION_PLUGINS_DIR"; @NonNls public static final String USER_HOME_NAME = "USER_HOME"; + private static final Map<String, String> ourGlobalMacros = ContainerUtil.<String, String>immutableMapBuilder() + .put(APPLICATION_HOME_DIR, toSystemIndependentName(PathManager.getHomePath())) + .put(APPLICATION_CONFIG_DIR, toSystemIndependentName(PathManager.getConfigPath())) + .put(APPLICATION_PLUGINS_DIR, toSystemIndependentName(PathManager.getPluginsPath())) + .put(USER_HOME_NAME, StringUtil.trimEnd(toSystemIndependentName(SystemProperties.getUserHome()), "/")).build(); + @Nullable public static String getModuleDir(String moduleFilePath) { File moduleDirFile = new File(moduleFilePath).getParentFile(); @@ -57,31 +67,18 @@ public class PathMacroUtil { return moduleDir; } + @NotNull public static String getUserHomePath() { - return StringUtil.trimEnd(FileUtil.toSystemIndependentName(SystemProperties.getUserHome()), "/"); + return ObjectUtils.assertNotNull(getGlobalSystemMacroValue(USER_HOME_NAME)); } + @NotNull public static Map<String, String> getGlobalSystemMacros() { - final Map<String, String> map = new HashMap<String, String>(); - map.put(APPLICATION_HOME_DIR, getApplicationHomeDirPath()); - map.put(APPLICATION_PLUGINS_DIR, getApplicationPluginsDirPath()); - map.put(USER_HOME_NAME, getUserHomePath()); - return map; - } - - private static String getApplicationHomeDirPath() { - return FileUtil.toSystemIndependentName(PathManager.getHomePath()); - } - - private static String getApplicationPluginsDirPath() { - return FileUtil.toSystemIndependentName(PathManager.getPluginsPath()); + return ourGlobalMacros; } @Nullable public static String getGlobalSystemMacroValue(String name) { - if (APPLICATION_HOME_DIR.equals(name)) return getApplicationHomeDirPath(); - if (APPLICATION_PLUGINS_DIR.equals(name)) return getApplicationPluginsDirPath(); - if (USER_HOME_NAME.equals(name)) return getUserHomePath(); - return null; + return ourGlobalMacros.get(name); } } diff --git a/jps/standalone-builder/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy b/jps/standalone-builder/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy deleted file mode 100644 index d7e52c6d061f..000000000000 --- a/jps/standalone-builder/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.jps.idea - -/** - * @author max - */ -public class IdeaProjectLoader { - public static String guessHome(Script script) { - String uri = script["gant.file"] - File home = new File(new URI(uri).getSchemeSpecificPart()) - - while (home != null) { - if (home.isDirectory() && new File(home, ".idea").exists()) { - return home.getCanonicalPath() - } - - home = home.getParentFile() - } - - throw new IllegalArgumentException("Cannot guess project home from '" + uri + "'") - } -} diff --git a/jps/standalone-builder/src/org/jetbrains/jps/idea/IdeaProjectLoader.java b/jps/standalone-builder/src/org/jetbrains/jps/idea/IdeaProjectLoader.java new file mode 100644 index 000000000000..b392dcf15081 --- /dev/null +++ b/jps/standalone-builder/src/org/jetbrains/jps/idea/IdeaProjectLoader.java @@ -0,0 +1,30 @@ +package org.jetbrains.jps.idea; + +import groovy.lang.Script; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * @author max + */ +public class IdeaProjectLoader { + public static String guessHome(Script script) throws IOException, URISyntaxException { + String uri = (String)script.getProperty("gant.file"); + File home = new File(new URI(uri).getSchemeSpecificPart()); + + while (home != null) { + if (home.isDirectory() && new File(home, ".idea").exists()) { + return home.getCanonicalPath(); + } + + + home = home.getParentFile(); + } + + + throw new IllegalArgumentException("Cannot guess project home from '" + uri + "'"); + } +} |