diff options
Diffstat (limited to 'jps')
9 files changed, 124 insertions, 74 deletions
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 cb8a777774d7..f652c17448e6 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 @@ -799,7 +799,7 @@ public class Mappings { } private class Differential { - private static final int DESPERATE_MASK = Opcodes.ACC_STATIC | Opcodes.ACC_FINAL; + private static final int DESPERATE_MASK = Opcodes.ACC_FINAL; final Mappings myDelta; final Collection<File> myFilesToCompile; diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java index d8e709b6c622..c6cc1173e0d3 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -27,6 +27,7 @@ import com.intellij.util.SystemProperties; import com.intellij.util.containers.ContainerUtil; import com.jgoodies.forms.layout.CellConstraints; import io.netty.util.NetUtil; +import jsr166e.extra.SequenceLock; import net.n3.nanoxml.IXMLBuilder; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.ClassVisitor; @@ -37,8 +38,11 @@ import org.jetbrains.jps.model.JpsModel; import org.jetbrains.jps.model.impl.JpsModelImpl; import org.jetbrains.jps.model.serialization.JpsProjectLoader; -import javax.tools.*; +import javax.tools.JavaCompiler; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; import java.io.File; +import java.lang.reflect.Method; import java.util.*; /** @@ -52,20 +56,31 @@ public class ClasspathBootstrap { static final String CLASS_NAME = "org.jetbrains.jps.javac.OptimizedFileManager"; @Nullable static final Class<StandardJavaFileManager> managerClass; + static final Method directoryCacheClearMethod; @Nullable static final String initError; static { - Class<StandardJavaFileManager> aClass; + Class<StandardJavaFileManager> aClass = null; + Method cacheClearMethod = null; String error = null; try { - @SuppressWarnings("unchecked") Class<StandardJavaFileManager> c = (Class<StandardJavaFileManager>)Class.forName(CLASS_NAME); + @SuppressWarnings("unchecked") + Class<StandardJavaFileManager> c = (Class<StandardJavaFileManager>)Class.forName(CLASS_NAME); aClass = c; + try { + cacheClearMethod = c.getMethod("fileGenerated", File.class); + cacheClearMethod.setAccessible(true); + } + catch (NoSuchMethodException e) { + LOG.info(e); + } } catch (Throwable ex) { aClass = null; error = ex.getClass().getName() + ": " + ex.getMessage(); } managerClass = aClass; + directoryCacheClearMethod = cacheClearMethod; initError = error; } @@ -77,20 +92,31 @@ public class ClasspathBootstrap { static final String CLASS_NAME = "org.jetbrains.jps.javac.OptimizedFileManager17"; @Nullable static final Class<StandardJavaFileManager> managerClass; + static final Method directoryCacheClearMethod; @Nullable static final String initError; static { Class<StandardJavaFileManager> aClass; + Method cacheClearMethod = null; String error = null; try { - @SuppressWarnings("unchecked") Class<StandardJavaFileManager> c = (Class<StandardJavaFileManager>)Class.forName(CLASS_NAME); + @SuppressWarnings("unchecked") + Class<StandardJavaFileManager> c = (Class<StandardJavaFileManager>)Class.forName(CLASS_NAME); aClass = c; + try { + cacheClearMethod = c.getMethod("fileGenerated", File.class); + cacheClearMethod.setAccessible(true); + } + catch (NoSuchMethodException e) { + LOG.info(e); + } } catch (Throwable ex) { aClass = null; error = ex.getClass().getName() + ": " + ex.getMessage(); } managerClass = aClass; + directoryCacheClearMethod = cacheClearMethod; initError = error; } @@ -119,6 +145,7 @@ public class ClasspathBootstrap { cp.add(getResourcePath(CellConstraints.class)); // jGoodies-forms cp.add(getResourcePath(NotNullVerifyingInstrumenter.class)); // not-null cp.add(getResourcePath(IXMLBuilder.class)); // nano-xml + cp.add(getResourcePath(SequenceLock.class)); // jsr166 if (!isLauncherUsed) { appendJavaCompilerClasspath(cp); @@ -238,6 +265,15 @@ public class ClasspathBootstrap { } @Nullable + public static Method getOptimizedFileManagerCacheClearMethod() { + final Method method = OptimizedFileManagerClassHolder.directoryCacheClearMethod; + if (method != null) { + return method; + } + return OptimizedFileManager17ClassHolder.directoryCacheClearMethod; + } + + @Nullable public static String getOptimizedFileManagerLoadError() { StringBuilder builder = new StringBuilder(); if (OptimizedFileManagerClassHolder.initError != null) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 776c3a800834..3cb21174c862 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -59,7 +59,8 @@ import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.module.JpsModuleType; import org.jetbrains.jps.service.JpsServiceManager; -import javax.tools.*; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; import java.io.*; import java.net.ServerSocket; import java.util.*; @@ -904,19 +905,21 @@ public class JavaBuilder extends ModuleLevelBuilder { } public void save(@NotNull final OutputFileObject fileObject) { - if (JavaFileObject.Kind.CLASS != fileObject.getKind()) { - // generated sources or resources must be saved synchronously, because some compilers (e.g. eclipse) - // may want to read generated text for further compilation - try { - final BinaryContent content = fileObject.getContent(); - if (content != null) { - content.saveToFile(fileObject.getFile()); - } + // generated files must be saved synchronously, because some compilers (e.g. eclipse) + // may want to read them for further compilation + try { + final BinaryContent content = fileObject.getContent(); + final File file = fileObject.getFile(); + if (content != null) { + content.saveToFile(file); } - catch (IOException e) { - myContext.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, e.getMessage())); + else { + myContext.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.WARNING, "Missing content for file " + file.getPath())); } } + catch (IOException e) { + myContext.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, e.getMessage())); + } submitAsyncTask(myContext, new Runnable() { public void run() { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/OutputFilesSink.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/OutputFilesSink.java index 519762b92954..187d7d199a33 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/OutputFilesSink.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/OutputFilesSink.java @@ -29,7 +29,7 @@ import org.jetbrains.jps.incremental.messages.ProgressMessage; import org.jetbrains.jps.javac.OutputFileConsumer; import org.jetbrains.jps.javac.OutputFileObject; -import javax.tools.*; +import javax.tools.JavaFileObject; import java.io.File; import java.io.IOException; import java.util.Collections; @@ -102,12 +102,9 @@ class OutputFilesSink implements OutputFileConsumer { } if (outKind == JavaFileObject.Kind.CLASS) { - // generated sources and resources are handled separately - try { - writeToDisk(fileObject, isTemp); - } - catch (IOException e) { - myContext.processMessage(new CompilerMessage(JavaBuilder.BUILDER_NAME, BuildMessage.Kind.ERROR, e.getMessage())); + myContext.processMessage(new ProgressMessage("Writing classes... " + myChunkName)); + if (!isTemp && srcFile != null) { + mySuccessfullyCompiled.add(srcFile); } } } @@ -116,27 +113,6 @@ class OutputFilesSink implements OutputFileConsumer { return Collections.unmodifiableSet(mySuccessfullyCompiled); } - private void writeToDisk(@NotNull OutputFileObject fileObject, boolean isTemp) throws IOException { - myContext.processMessage(new ProgressMessage("Writing classes... " + myChunkName)); - - final File file = fileObject.getFile(); - final BinaryContent content = fileObject.getContent(); - if (content == null) { - throw new IOException("Missing content for file " + file); - } - - content.saveToFile(file); - - final File source = fileObject.getSourceFile(); - if (!isTemp && source != null) { - mySuccessfullyCompiled.add(source); - //final String className = fileObject.getClassName(); - //if (className != null) { - // myContext.processMessage(new ProgressMessage("Compiled " + className)); - //} - } - } - public void markError(@NotNull final File sourceFile) { mySuccessfullyCompiled.remove(sourceFile); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java index 273f9272638a..d294c19f3f7b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java @@ -19,6 +19,7 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.util.ExceptionUtil; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.api.CanceledStatus; import org.jetbrains.jps.builders.java.JavaSourceTransformer; import org.jetbrains.jps.cmdline.ClasspathBootstrap; @@ -328,6 +329,8 @@ public class JavacMain { private static class ContextImpl implements JavacFileManager.Context { private final StandardJavaFileManager myStdManager; + @Nullable + private final Method myCacheClearMethod; private final DiagnosticOutputConsumer myOutConsumer; private final OutputFileConsumer myOutputFileSink; private final CanceledStatus myCanceledStatus; @@ -339,7 +342,8 @@ public class JavacMain { myOutConsumer = outConsumer; myOutputFileSink = sink; myCanceledStatus = canceledStatus; - StandardJavaFileManager stdManager = null; + StandardJavaFileManager optimizedManager = null; + Method cacheClearMethod = null; if (canUseOptimizedmanager) { final Class<StandardJavaFileManager> optimizedManagerClass = ClasspathBootstrap.getOptimizedFileManagerClass(); if (optimizedManagerClass != null) { @@ -348,7 +352,8 @@ public class JavacMain { // if optimizedManagerClass is loaded by another classloader, cls.newInstance() will not work // that's why we need to call setAccessible() to ensure access constructor.setAccessible(true); - stdManager = constructor.newInstance(); + optimizedManager = constructor.newInstance(); + cacheClearMethod = ClasspathBootstrap.getOptimizedFileManagerCacheClearMethod(); } catch (Throwable e) { if (SystemInfo.isWindows) { @@ -364,8 +369,9 @@ public class JavacMain { outConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.OTHER, "JPS build failed to load optimized file manager for javac:\n" + error)); } } - if (stdManager != null) { - myStdManager = stdManager; + myCacheClearMethod = cacheClearMethod; + if (optimizedManager != null) { + myStdManager = optimizedManager; } else { myStdManager = compiler.getStandardFileManager(outConsumer, Locale.US, null); @@ -385,7 +391,21 @@ public class JavacMain { } public void consumeOutputFile(@NotNull final OutputFileObject cls) { - myOutputFileSink.save(cls); + try { + myOutputFileSink.save(cls); + } + finally { + final Method cacheClearMethod = myCacheClearMethod; + if (cacheClearMethod != null) { + try { + cacheClearMethod.invoke(myStdManager, cls.getFile()); + } + catch (Throwable e) { + //noinspection UseOfSystemOutOrSystemErr + e.printStackTrace(System.err); + } + } + } } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager.java b/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager.java index 0004f5736c3a..2408290a3f4a 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager.java @@ -22,7 +22,8 @@ import com.sun.tools.javac.util.List; import org.jetbrains.jps.incremental.Utils; import javax.lang.model.SourceVersion; -import javax.tools.*; +import javax.tools.FileObject; +import javax.tools.JavaFileObject; import java.io.*; import java.lang.ref.SoftReference; import java.lang.reflect.Field; @@ -115,10 +116,10 @@ class OptimizedFileManager extends DefaultFileManager { else { final File directory = relativePath.length() != 0 ? new File(root, relativePath) : root; if (recurse) { - collectFromDirectoryRecursively(directory, kinds, results, true, !location.isOutputLocation()); + collectFromDirectoryRecursively(directory, kinds, results, true); } else { - collectFromDirectory(directory, kinds, results, !location.isOutputLocation()); + collectFromDirectory(directory, kinds, results); } } } @@ -126,6 +127,14 @@ class OptimizedFileManager extends DefaultFileManager { return results.toList(); } + // important! called via reflection, so avoid renaming or signature changing or rename carefully + public void fileGenerated(File file) { + final File parent = file.getParentFile(); + if (parent != null) { + myDirectoryCache.remove(parent); + } + } + private boolean isFile(File root) { Boolean cachedIsFile = myIsFile.get(root); if (cachedIsFile == null) { @@ -168,8 +177,8 @@ class OptimizedFileManager extends DefaultFileManager { } } - private void collectFromDirectory(File directory, Set<JavaFileObject.Kind> fileKinds, ListBuffer<JavaFileObject> result, boolean canUseCache) { - final File[] children = listChildren(directory, canUseCache); + private void collectFromDirectory(File directory, Set<JavaFileObject.Kind> fileKinds, ListBuffer<JavaFileObject> result) { + final File[] children = listChildren(directory); if (children != null) { final boolean acceptUnknownFiles = fileKinds.contains(JavaFileObject.Kind.OTHER); for (File child : children) { @@ -184,13 +193,13 @@ class OptimizedFileManager extends DefaultFileManager { } } - private void collectFromDirectoryRecursively(File file, Set<JavaFileObject.Kind> fileKinds, ListBuffer<JavaFileObject> result, boolean isRootCall, boolean canUseCache) { - final File[] children = listChildren(file, canUseCache); + private void collectFromDirectoryRecursively(File file, Set<JavaFileObject.Kind> fileKinds, ListBuffer<JavaFileObject> result, boolean isRootCall) { + final File[] children = listChildren(file); final String name = file.getName(); if (children != null) { // is directory if (isRootCall || SourceVersion.isIdentifier(name)) { for (File child : children) { - collectFromDirectoryRecursively(child, fileKinds, result, false, canUseCache); + collectFromDirectoryRecursively(child, fileKinds, result, false); } } } @@ -202,10 +211,7 @@ class OptimizedFileManager extends DefaultFileManager { } } - private File[] listChildren(File file, boolean canUseCache) { - if (!canUseCache) { - return file.listFiles(); - } + private File[] listChildren(File file) { File[] cached = myDirectoryCache.get(file); if (cached == null) { cached = file.listFiles(); diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager17.java b/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager17.java index a9f47ec2f6f6..4e7b99a82e14 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager17.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager17.java @@ -24,7 +24,7 @@ import com.sun.tools.javac.util.ListBuffer; import org.jetbrains.jps.incremental.Utils; import javax.lang.model.SourceVersion; -import javax.tools.*; +import javax.tools.JavaFileObject; import java.io.*; import java.lang.ref.Reference; import java.lang.ref.SoftReference; @@ -112,10 +112,10 @@ class OptimizedFileManager17 extends com.sun.tools.javac.file.JavacFileManager { else { final File dir = subdirectory.getFile(root); if (recurse) { - listDirectoryRecursively(dir, kinds, results, true, !location.isOutputLocation()); + listDirectoryRecursively(dir, kinds, results, true); } else { - listDirectory(dir, kinds, results, !location.isOutputLocation()); + listDirectory(dir, kinds, results); } } @@ -146,8 +146,8 @@ class OptimizedFileManager17 extends com.sun.tools.javac.file.JavacFileManager { } } - private void listDirectory(File directory, Set<JavaFileObject.Kind> fileKinds, ListBuffer<JavaFileObject> resultList, boolean canUseCache) { - final File[] files = listChildren(directory, canUseCache); + private void listDirectory(File directory, Set<JavaFileObject.Kind> fileKinds, ListBuffer<JavaFileObject> resultList) { + final File[] files = listChildren(directory); if (files != null) { if (sortFiles != null) { Arrays.sort(files, sortFiles); @@ -166,8 +166,8 @@ class OptimizedFileManager17 extends com.sun.tools.javac.file.JavacFileManager { } } - private void listDirectoryRecursively(File file, Set<JavaFileObject.Kind> fileKinds, ListBuffer<JavaFileObject> resultList, boolean isRootCall, boolean canUseCache) { - final File[] children = listChildren(file, canUseCache); + private void listDirectoryRecursively(File file, Set<JavaFileObject.Kind> fileKinds, ListBuffer<JavaFileObject> resultList, boolean isRootCall) { + final File[] children = listChildren(file); final String fileName = file.getName(); if (children != null) { // is directory if (isRootCall || SourceVersion.isIdentifier(fileName)) { @@ -175,7 +175,7 @@ class OptimizedFileManager17 extends com.sun.tools.javac.file.JavacFileManager { Arrays.sort(children, sortFiles); } for (File child : children) { - listDirectoryRecursively(child, fileKinds, resultList, false, canUseCache); + listDirectoryRecursively(child, fileKinds, resultList, false); } } } @@ -187,10 +187,7 @@ class OptimizedFileManager17 extends com.sun.tools.javac.file.JavacFileManager { } } - private File[] listChildren(File file, boolean canUseCache) { - if (!canUseCache) { - return file.listFiles(); - } + private File[] listChildren(File file) { File[] cached = myDirectoryCache.get(file); if (cached == null) { cached = file.listFiles(); @@ -199,6 +196,14 @@ class OptimizedFileManager17 extends com.sun.tools.javac.file.JavacFileManager { return cached == NULL_FILE_ARRAY ? null : cached; } + // important! called via reflection, so avoid renaming or signature changing or rename carefully + public void fileGenerated(File file) { + final File parent = file.getParentFile(); + if (parent != null) { + myDirectoryCache.remove(parent); + } + } + private boolean isFile(File root) { Boolean cachedIsFile = myIsFile.get(root); if (cachedIsFile == null) { diff --git a/jps/jps-builders/testSrc/org/jetbrains/ether/FieldPropertyTest.java b/jps/jps-builders/testSrc/org/jetbrains/ether/FieldPropertyTest.java index 918f1213a1ad..aa99a68c8dd0 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/ether/FieldPropertyTest.java +++ b/jps/jps-builders/testSrc/org/jetbrains/ether/FieldPropertyTest.java @@ -60,6 +60,10 @@ public class FieldPropertyTest extends IncrementalTestCase { doTest(); } + public void testIntNonStaticConstantChange() throws Exception { + doTest(); + } + public void testLongConstantChange() throws Exception { doTest(); } diff --git a/jps/lib/optimizedFileManager.jar b/jps/lib/optimizedFileManager.jar Binary files differindex 8a12d502b63b..f7d95998d3c6 100644 --- a/jps/lib/optimizedFileManager.jar +++ b/jps/lib/optimizedFileManager.jar |