diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index aad54bdea60f..00b601bf69bf 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -66,7 +66,6 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.openapi.vfs.newvfs.RefreshQueue; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; @@ -420,8 +419,6 @@ public class CompileDriver { } finally { compileContext.commitZipFiles(); - CompilerUtil.logDuration("Refreshing VFS in total", CompilerUtil.ourRefreshTime); - CompilerUtil.ourRefreshTime = 0L; final long finish = System.currentTimeMillis(); CompilerUtil.logDuration( "\tCOMPILATION FINISHED; Errors: " + @@ -704,7 +701,6 @@ public class CompileDriver { final long initialRefreshTime = System.currentTimeMillis() - refreshStart; CompilerUtil.logDuration("Initial VFS refresh", initialRefreshTime); - CompilerUtil.ourRefreshTime += initialRefreshTime; } //DumbService.getInstance(myProject).waitForSmartMode(); @@ -789,13 +785,6 @@ public class CompileDriver { }); } - if (!context.getProgressIndicator().isCanceled() && context.getMessageCount(CompilerMessageCategory.ERROR) == 0) { - RefreshQueue.getInstance().refresh(true, true, new Runnable() { - public void run() { - CompilerDirectoryTimestamp.updateTimestamp(Arrays.asList(allOutputDirs)); - } - }, allOutputDirs); - } } if (!onlyCheckStatus) { diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerDirectoryTimestamp.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerDirectoryTimestamp.java deleted file mode 100644 index 818423731436..000000000000 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerDirectoryTimestamp.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2000-2009 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 com.intellij.compiler.impl; - -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.newvfs.FileAttribute; -import com.intellij.openapi.vfs.newvfs.ManagingFS; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Collection; - -/** - * @author Eugene Zhuravlev - * Date: Jun 15, 2007 - */ -public class CompilerDirectoryTimestamp extends FileAttribute { - private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompilerDirectoryTimestamp"); - - private static final CompilerDirectoryTimestamp INSTANCE = new CompilerDirectoryTimestamp(); - - private CompilerDirectoryTimestamp() { - super("_compiler_stamp_", 2); - } - - public static boolean isUpToDate(Collection files) { - try { - final ManagingFS managingFS = ManagingFS.getInstance(); - for (VirtualFile file : files) { - if (!file.isValid()) { - return false; - } - final DataInputStream stream = INSTANCE.readAttribute(file); - if (stream == null) { - return false; - } - try { - final int savedStamp = stream.readInt(); - if (savedStamp != managingFS.getModificationCount(file)) { - return false; - } - } - finally { - stream.close(); - } - } - } - catch (IOException e) { - LOG.info(e); - return false; - } - return true; - } - - public static void updateTimestamp(Collection files) { - try { - final ManagingFS managingFS = ManagingFS.getInstance(); - for (VirtualFile file : files) { - if (!file.isValid()) { - continue; - } - final DataOutputStream stream = INSTANCE.writeAttribute(file); - try { - stream.writeInt(managingFS.getModificationCount(file)); - } - finally { - stream.close(); - } - } - } - catch (IOException e) { - LOG.info(e); - } - } -} diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java index 8a55cdac0d7b..6124a0850b0f 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java @@ -43,7 +43,6 @@ import java.util.*; public class CompilerUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompilerUtil"); - public static volatile long ourRefreshTime = 0L; public static String quotePath(String path) { if(path != null && path.indexOf(' ') != -1) { @@ -103,43 +102,25 @@ public class CompilerUtil { * @param files */ public static void refreshIOFiles(@NotNull final Collection files) { - final long start = System.currentTimeMillis(); - try { - LocalFileSystem.getInstance().refreshIoFiles(files); - } - finally { - ourRefreshTime += (System.currentTimeMillis() - start); - } + LocalFileSystem.getInstance().refreshIoFiles(files); } public static void refreshIODirectories(@NotNull final Collection files) { - final long start = System.currentTimeMillis(); - try { - final LocalFileSystem lfs = LocalFileSystem.getInstance(); - final List filesToRefresh = new ArrayList(); - for (File file : files) { - final VirtualFile virtualFile = lfs.refreshAndFindFileByIoFile(file); - if (virtualFile != null) { - filesToRefresh.add(virtualFile); - } + final LocalFileSystem lfs = LocalFileSystem.getInstance(); + final List filesToRefresh = new ArrayList(); + for (File file : files) { + final VirtualFile virtualFile = lfs.refreshAndFindFileByIoFile(file); + if (virtualFile != null) { + filesToRefresh.add(virtualFile); } - RefreshQueue.getInstance().refresh(false, true, null, VfsUtil.toVirtualFileArray(filesToRefresh)); - } - finally { - ourRefreshTime += (System.currentTimeMillis() - start); } + RefreshQueue.getInstance().refresh(false, true, null, VfsUtil.toVirtualFileArray(filesToRefresh)); } public static void refreshIOFile(final File file) { - final long start = System.currentTimeMillis(); - try { - final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file); - if (vFile != null) { - vFile.refresh(false, false); - } - } - finally { - ourRefreshTime += (System.currentTimeMillis() - start); + final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file); + if (vFile != null) { + vFile.refresh(false, false); } } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessorsRunner.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessorsRunner.java deleted file mode 100644 index 6c5baa95caa4..000000000000 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessorsRunner.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright 2000-2009 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. - */ - -/* - * @author: Eugene Zhuravlev - * Date: Jan 24, 2003 - * Time: 4:25:47 PM - */ -package com.intellij.compiler.impl.javaCompiler; - -import com.intellij.compiler.CompilerException; -import com.intellij.compiler.OutputParser; -import com.intellij.compiler.impl.CompilerUtil; -import com.intellij.compiler.make.CacheCorruptedException; -import com.intellij.ide.util.projectWizard.JavaModuleBuilder; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.compiler.CompileContext; -import com.intellij.openapi.compiler.CompilerBundle; -import com.intellij.openapi.compiler.CompilerMessageCategory; -import com.intellij.openapi.compiler.TranslatingCompiler; -import com.intellij.openapi.compiler.ex.CompileContextEx; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.module.JavaModuleType; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleType; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.JavaSdkType; -import com.intellij.openapi.roots.ProjectFileIndex; -import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.Chunk; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.io.IOException; -import java.util.*; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - -public class AnnotationProcessorsRunner { - private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.BackendCompilerWrapper"); - - private final BackendCompiler myCompiler; - private final Set mySuccesfullyCompiledJavaFiles; // VirtualFile - - private final CompileContextEx myCompileContext; - private final List myFilesToCompile; - private final TranslatingCompiler.OutputSink mySink; - private final Chunk myChunk; - private final Project myProject; - private final Set myFilesToRecompile; - private final ProjectFileIndex myProjectFileIndex; - private long myCompilationDuration = 0L; - - - public AnnotationProcessorsRunner(Chunk chunk, @NotNull final Project project, - @NotNull List filesToCompile, - @NotNull CompileContextEx compileContext, - @NotNull BackendCompiler compiler, TranslatingCompiler.OutputSink sink) { - myChunk = chunk; - myProject = project; - myCompiler = compiler; - myCompileContext = compileContext; - myFilesToCompile = filesToCompile; - myFilesToRecompile = new HashSet(filesToCompile); - mySink = sink; - myProjectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); - mySuccesfullyCompiledJavaFiles = new HashSet(filesToCompile.size()); - } - - public void compile() throws CompilerException, CacheCorruptedException { - try { - if (!myFilesToCompile.isEmpty()) { - final Map> moduleToFilesMap = buildModuleToFilesMap(myFilesToCompile); - myProcessedFilesCount = 0; - try { - // todo: need special ModuleChunk to be able to filter sources - final ModuleChunk chunk = new ModuleChunk(myCompileContext, myChunk, moduleToFilesMap); - // TODO: do we really need this for annot. processors? - //runTransformingCompilers(chunk); - - setPresentableNameFor(chunk); - - // assuming output dir pointing to source-generated output dir - final List outs = getOutputDirsToCompileTo(chunk); - - for (final OutputDir outputDir : outs) { - // todo: proper filtering - chunk.setSourcesFilter(outputDir.getKind()); - doCompile(chunk, outputDir.getPath()); - } - } - catch (IOException e) { - throw new CompilerException(e.getMessage(), e); - } - } - } - catch (SecurityException e) { - throw new CompilerException(CompilerBundle.message("error.compiler.process.not.started", e.getMessage()), e); - } - catch (IllegalArgumentException e) { - throw new CompilerException(e.getMessage(), e); - } - finally { - CompilerUtil.logDuration(myCompiler.getId() + " running", myCompilationDuration); - } - - // do not update caches if cancelled because there is a chance that they will be incomplete - - myFilesToRecompile.removeAll(mySuccesfullyCompiledJavaFiles); - if (myFilesToRecompile.size() > 0) { - mySink.add(null, Collections.emptyList(), myFilesToRecompile.toArray(new VirtualFile[myFilesToRecompile.size()])); - } - } - - private Map> buildModuleToFilesMap(final List filesToCompile) { - if (myChunk.getNodes().size() == 1) { - return Collections.singletonMap(myChunk.getNodes().iterator().next(), Collections.unmodifiableList(filesToCompile)); - } - return CompilerUtil.buildModuleToFilesMap(myCompileContext, filesToCompile); - } - - - private void setPresentableNameFor(final ModuleChunk chunk) { - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - final Module[] modules = chunk.getModules(); - StringBuilder moduleName = new StringBuilder(Math.min(128, modules.length * 8)); - for (int idx = 0; idx < modules.length; idx++) { - final Module module = modules[idx]; - if (idx > 0) { - moduleName.append(", "); - } - moduleName.append(module.getName()); - if (moduleName.length() > 128 && idx + 1 < modules.length /*name is already too long and seems to grow longer*/) { - moduleName.append("..."); - break; - } - } - myModuleName = moduleName.toString(); - } - }); - } - - private List getOutputDirsToCompileTo(ModuleChunk chunk) throws IOException { - // todo - return Collections.emptyList(); - } - - private final Object lock = new Object(); - - private class SynchedCompilerParsing extends CompilerParsingThread { - - private SynchedCompilerParsing(Process process, final CompileContext context, OutputParser outputParser, boolean readErrorStream, - boolean trimLines) { - super(process, outputParser, readErrorStream, trimLines,context); - } - - public void setProgressText(String text) { - synchronized (lock) { - super.setProgressText(text); - } - } - - public void message(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum) { - synchronized (lock) { - super.message(category, message, url, lineNum, columnNum); - } - } - - public void fileProcessed(String path) { - synchronized (lock) { - sourceFileProcessed(); - } - } - } - - private void doCompile(@NotNull final ModuleChunk chunk, @NotNull String outputDir) throws IOException { - myCompileContext.getProgressIndicator().checkCanceled(); - - if (ApplicationManager.getApplication().runReadAction(new Computable() { - public Boolean compute() { - return chunk.getFilesToCompile().isEmpty() ? Boolean.TRUE : Boolean.FALSE; - } - }).booleanValue()) { - return; // should not invoke javac with empty sources list - } - - ModuleType moduleType = chunk.getModules()[0].getModuleType(); - if (!(chunk.getJdk().getSdkType() instanceof JavaSdkType) && - !(moduleType instanceof JavaModuleType || moduleType.createModuleBuilder() instanceof JavaModuleBuilder)) { - // TODO - // don't try to compile non-java type module - return; - } - - int exitValue = 0; - try { - Process process = myCompiler.launchProcess(chunk, outputDir, myCompileContext); - final long compilationStart = System.currentTimeMillis(); - - OutputParser errorParser = myCompiler.createErrorParser(outputDir, process); - CompilerParsingThread errorParsingThread = errorParser == null - ? null - : new SynchedCompilerParsing(process, myCompileContext, errorParser, true, errorParser.isTrimLines()); - Future errorParsingThreadFuture = null; - if (errorParsingThread != null) { - errorParsingThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(errorParsingThread); - } - - OutputParser outputParser = myCompiler.createOutputParser(outputDir); - CompilerParsingThread outputParsingThread = outputParser == null - ? null - : new SynchedCompilerParsing(process, myCompileContext, outputParser, false, outputParser.isTrimLines()); - Future outputParsingThreadFuture = null; - if (outputParsingThread != null) { - outputParsingThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(outputParsingThread); - } - - try { - exitValue = process.waitFor(); - } - catch (InterruptedException e) { - process.destroy(); - exitValue = process.exitValue(); - } - finally { - myCompilationDuration += (System.currentTimeMillis() - compilationStart); - if (errorParsingThread != null) { - errorParsingThread.setProcessTerminated(true); - } - if (outputParsingThread != null) { - outputParsingThread.setProcessTerminated(true); - } - joinThread(errorParsingThreadFuture); - joinThread(outputParsingThreadFuture); - - registerParsingException(outputParsingThread); - registerParsingException(errorParsingThread); - assert outputParsingThread == null || !outputParsingThread.processing; - assert errorParsingThread == null || !errorParsingThread.processing; - } - } - finally { - compileFinished(exitValue, chunk, outputDir); - myModuleName = null; - } - } - - private static void joinThread(final Future threadFuture) { - if (threadFuture != null) { - try { - threadFuture.get(); - } - catch (InterruptedException ignored) { - } - catch(ExecutionException ignored) { - } - } - } - - private void registerParsingException(final CompilerParsingThread outputParsingThread) { - Throwable error = outputParsingThread == null ? null : outputParsingThread.getError(); - if (error != null) { - String message = error.getMessage(); - if (error instanceof CacheCorruptedException) { - myCompileContext.requestRebuildNextTime(message); - } - else { - myCompileContext.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1); - } - } - } - - private void compileFinished(int exitValue, final ModuleChunk chunk, final String outputDir) { - if (exitValue != 0 && !myCompileContext.getProgressIndicator().isCanceled() && - myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) { - myCompileContext.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("error.compiler.internal.error", exitValue), null, -1, -1); - } - - myCompiler.compileFinished(); - - try { - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - final String outputDirPath = outputDir.replace(File.separatorChar, '/'); - for (final Module module : chunk.getModules()) { - for (final VirtualFile root : chunk.getSourceRoots(module)) { - final String packagePrefix = myProjectFileIndex.getPackageNameByDirectory(root); - if (LOG.isDebugEnabled()) { - LOG.debug("Building output items for " + root.getPresentableUrl() + "; output dir = " + outputDirPath + "; packagePrefix = \"" + packagePrefix + "\""); - } - } - } - } - }); - } - finally { - // todo: refresh dirs her - } - } - - private volatile int myProcessedFilesCount = 0; - private volatile int myClassesCount = 0; - private volatile String myModuleName = null; - - private void sourceFileProcessed() { - myProcessedFilesCount++; - updateStatistics(); - } - - private void updateStatistics() { - final String msg; - String moduleName = myModuleName; - if (moduleName != null) { - msg = CompilerBundle.message("statistics.files.classes.module", myProcessedFilesCount, myClassesCount, moduleName); - } - else { - msg = CompilerBundle.message("statistics.files.classes", myProcessedFilesCount, myClassesCount); - } - myCompileContext.getProgressIndicator().setText2(msg); - } - - /* - private void runTransformingCompilers(final ModuleChunk chunk) { - final JavaSourceTransformingCompiler[] transformers = - CompilerManager.getInstance(myProject).getCompilers(JavaSourceTransformingCompiler.class); - if (transformers.length == 0) { - return; - } - if (LOG.isDebugEnabled()) { - LOG.debug("Running transforming compilers..."); - } - final Module[] modules = chunk.getModules(); - for (final JavaSourceTransformingCompiler transformer : transformers) { - final Map originalToCopyFileMap = new HashMap(); - final Application application = ApplicationManager.getApplication(); - application.invokeAndWait(new Runnable() { - public void run() { - for (final Module module : modules) { - List filesToCompile = chunk.getFilesToCompile(module); - for (final VirtualFile file : filesToCompile) { - if (transformer.isTransformable(file)) { - application.runWriteAction(new Runnable() { - public void run() { - try { - VirtualFile fileCopy = createFileCopy(getTempDir(module), file); - originalToCopyFileMap.put(file, fileCopy); - } - catch (IOException e) { - // skip it - } - } - }); - } - } - } - } - }, myCompileContext.getProgressIndicator().getModalityState()); - - // do actual transform - for (final Module module : modules) { - final List filesToCompile = chunk.getFilesToCompile(module); - for (int j = 0; j < filesToCompile.size(); j++) { - final VirtualFile file = filesToCompile.get(j); - VirtualFile fileCopy = originalToCopyFileMap.get(file); - if (fileCopy != null) { - final boolean ok = transformer.transform(myCompileContext, fileCopy, file); - if (ok) { - chunk.substituteWithTransformedVersion(module, j, fileCopy); - } - } - } - } - } - } - - private VirtualFile createFileCopy(VirtualFile tempDir, final VirtualFile file) throws IOException { - final String fileName = file.getName(); - if (tempDir.findChild(fileName) != null) { - int idx = 0; - while (true) { - //noinspection HardCodedStringLiteral - final String dirName = "dir" + idx++; - final VirtualFile dir = tempDir.findChild(dirName); - if (dir == null) { - tempDir = tempDir.createChildDirectory(this, dirName); - break; - } - if (dir.findChild(fileName) == null) { - tempDir = dir; - break; - } - } - } - return VfsUtil.copyFile(this, file, tempDir); - } - */ - -} \ No newline at end of file diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java index b92fc0ea2d54..ff0ee19259cb 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java @@ -86,7 +86,6 @@ public class BackendCompilerWrapper { private final ProjectFileIndex myProjectFileIndex; @NonNls private static final String PACKAGE_ANNOTATION_FILE_NAME = "package-info.java"; private static final FileObject myStopThreadToken = new FileObject(new File(""), new byte[0]); - private long myCompilationDuration = 0L; public final Map> myFileNameToSourceMap= new THashMap>(); @@ -145,7 +144,6 @@ public class BackendCompilerWrapper { throw new CompilerException(e.getMessage(), e); } finally { - CompilerUtil.logDuration(myCompiler.getId() + " running", myCompilationDuration); for (final VirtualFile file : myModuleToTempDirMap.values()) { if (file != null) { final File ioFile = new File(file.getPath()); @@ -458,7 +456,6 @@ public class BackendCompilerWrapper { exitValue = process.exitValue(); } finally { - myCompilationDuration += System.currentTimeMillis() - compilationStart; if (errorParsingThread != null) { errorParsingThread.setProcessTerminated(true); } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java index 468618c3b296..9a46164f86b5 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java @@ -78,7 +78,6 @@ public class ResourceCompiler implements TranslatingCompiler { final Map> processed = new HashMap>(); final LinkedList copyCommands = new LinkedList(); final Module singleChunkModule = moduleChunk.getNodes().size() == 1? moduleChunk.getNodes().iterator().next() : null; - final long start = System.currentTimeMillis(); ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); @@ -123,9 +122,6 @@ public class ResourceCompiler implements TranslatingCompiler { final Set rootsToRefresh = new HashSet(); // do actual copy outside of read action to reduce the time the application is locked on it - int idx = 0; - final int total = copyCommands.size(); - CopyCommand.ourCopyingTime = 0L; while (!copyCommands.isEmpty()) { final CopyCommand command = copyCommands.removeFirst(); if (context.getProgressIndicator().isCanceled()) { @@ -146,10 +142,6 @@ public class ResourceCompiler implements TranslatingCompiler { ); } } - final long stop = System.currentTimeMillis(); - - CompilerUtil.logDuration("Copying resources TOTAL", stop - start); - CompilerUtil.logDuration("\tCopying resources (actual copying)", CopyCommand.ourCopyingTime); if (!rootsToRefresh.isEmpty()) { final List dirs = new ArrayList(); @@ -182,7 +174,6 @@ public class ResourceCompiler implements TranslatingCompiler { private final String myFromPath; private final String myToPath; private final VirtualFile mySourceFile; - public static long ourCopyingTime = 0L; private CopyCommand(String outputPath, String fromPath, String toPath, VirtualFile sourceFile) { myOutputPath = outputPath; @@ -196,9 +187,7 @@ public class ResourceCompiler implements TranslatingCompiler { LOG.debug("Copying " + myFromPath + " to " + myToPath); } final File targetFile = new File(myToPath); - final long start = System.currentTimeMillis(); FileUtil.copyContent(new File(myFromPath), targetFile); - ourCopyingTime += (System.currentTimeMillis() - start); return new MyOutputItem(myToPath, mySourceFile); } diff --git a/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java b/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java index f0faf4e19683..1514175abc88 100644 --- a/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java +++ b/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java @@ -19,7 +19,6 @@ import com.intellij.compiler.CompilerConfiguration; import com.intellij.compiler.CompilerManagerImpl; import com.intellij.compiler.SymbolTable; import com.intellij.compiler.classParsing.MethodInfo; -import com.intellij.compiler.impl.CompilerUtil; import com.intellij.compiler.impl.javaCompiler.DependencyProcessor; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompilerBundle; @@ -137,8 +136,6 @@ public class CacheUtils { final DependencyCache dependencyCache = context.getDependencyCache(); - final long start = System.currentTimeMillis(); - final Pair> deps = dependencyCache.findDependentClasses(context, context.getProject(), succesfullyCompiledJavaFiles, additionalDependencyProcessor); final Pair> filteredDeps = filter != null? filter.fun(deps) : deps; @@ -188,7 +185,6 @@ public class CacheUtils { } context.getProgressIndicator().setText(CompilerBundle.message("progress.found.dependent.files", dependentFiles.size())); - CompilerUtil.logDuration("Finding dependencies", System.currentTimeMillis() - start); return dependentFiles; } } diff --git a/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java b/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java index ad4610fa9ce8..bb9082cc6742 100644 --- a/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java +++ b/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java @@ -22,7 +22,6 @@ package com.intellij.compiler.make; import com.intellij.compiler.SymbolTable; import com.intellij.compiler.classParsing.*; -import com.intellij.compiler.impl.CompilerUtil; import com.intellij.compiler.impl.javaCompiler.DependencyProcessor; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompileContext; @@ -158,7 +157,6 @@ public class DependencyCache { return; // optimization } - final long updateStart = System.currentTimeMillis(); //pause(); final int[] namesToUpdate = myToUpdate.toArray(); @@ -230,7 +228,6 @@ public class DependencyCache { } myToUpdate = new TIntHashSet(); - CompilerUtil.logDuration("Dependency cache update", System.currentTimeMillis() - updateStart); //pause(); } @@ -577,40 +574,33 @@ public class DependencyCache { } public void resetState() { - final long start = System.currentTimeMillis(); - + myClassesWithSourceRemoved.clear(); + myMarkedFiles.clear(); + myMarkedInfos.clear(); + myToUpdate.clear(); + myTraverseRoots.clear(); + if (myNewClassesCache != null) { + myNewClassesCache.wipe(); + myNewClassesCache = null; + } + myCacheNavigator = null; try { - myClassesWithSourceRemoved.clear(); - myMarkedFiles.clear(); - myMarkedInfos.clear(); - myToUpdate.clear(); - myTraverseRoots.clear(); - if (myNewClassesCache != null) { - myNewClassesCache.wipe(); - myNewClassesCache = null; - } - myCacheNavigator = null; - try { - if (myCache != null) { - myCache.dispose(); - myCache = null; - } - } - catch (CacheCorruptedException e) { - LOG.info(e); - } - try { - if (mySymbolTable != null) { - mySymbolTable.dispose(); - mySymbolTable = null; - } - } - catch (CacheCorruptedException e) { - LOG.info(e); + if (myCache != null) { + myCache.dispose(); + myCache = null; } } - finally { - CompilerUtil.logDuration("Dependency cache disposal", System.currentTimeMillis() - start); + catch (CacheCorruptedException e) { + LOG.info(e); + } + try { + if (mySymbolTable != null) { + mySymbolTable.dispose(); + mySymbolTable = null; + } + } + catch (CacheCorruptedException e) { + LOG.info(e); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/ArrayRendererConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/ArrayRendererConfigurable.java index 609b2ba47d79..bd872b0879b5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/ArrayRendererConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/ArrayRendererConfigurable.java @@ -50,10 +50,10 @@ public class ArrayRendererConfigurable implements UnnamedConfigurable{ } public void apply() { - applyTo(myRenderer); + applyTo(myRenderer, true); } - private void applyTo(ArrayRenderer renderer) { + private void applyTo(ArrayRenderer renderer, boolean showBigRangeWarning) { int newStartIndex = getInt(myStartIndex); int newEndIndex = getInt(myEndIndex); int newLimit = getInt(myEntriesLimit); @@ -69,7 +69,7 @@ public class ArrayRendererConfigurable implements UnnamedConfigurable{ newLimit = 1; } - if(newEndIndex - newStartIndex > 10000) { + if(showBigRangeWarning && (newEndIndex - newStartIndex > 10000)) { final int answer = Messages.showOkCancelDialog( myPanel.getRootPane(), DebuggerBundle.message("warning.range.too.big", ApplicationNamesInfo.getInstance().getProductName()), @@ -151,7 +151,7 @@ public class ArrayRendererConfigurable implements UnnamedConfigurable{ public boolean isModified() { ArrayRenderer cloneRenderer = myRenderer.clone(); - applyTo(cloneRenderer); + applyTo(cloneRenderer, false); final boolean valuesEqual = (myRenderer.END_INDEX == cloneRenderer.END_INDEX) && (myRenderer.START_INDEX == cloneRenderer.START_INDEX) && diff --git a/platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java b/platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java index c1fbeafc746a..684e2fc5fb0c 100644 --- a/platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java +++ b/platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java @@ -576,7 +576,8 @@ public class PsiTreeUtil { return filteredElements.toArray(new PsiElement[filteredElements.size()]); } - public static boolean treeWalkUp(@NotNull final PsiScopeProcessor processor, @NotNull final PsiElement entrance, + public static boolean treeWalkUp(@NotNull final PsiScopeProcessor processor, + @NotNull final PsiElement entrance, @Nullable final PsiElement maxScope, @NotNull final ResolveState state) { PsiElement prevParent = entrance; diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ExtractMethodDecorator.java b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ExtractMethodDecorator.java new file mode 100644 index 000000000000..7c28399cf9fd --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ExtractMethodDecorator.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2010 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 com.intellij.refactoring.extractmethod; + +/** + * @author oleg + */ +public interface ExtractMethodDecorator { + String createMethodPreview(String methodName, VariableData[] variableDatas); +} diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ExtractMethodDialog.java b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ExtractMethodDialog.java new file mode 100644 index 000000000000..c0547b43ff59 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ExtractMethodDialog.java @@ -0,0 +1,196 @@ +/* + * Copyright 2000-2010 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 com.intellij.refactoring.extractmethod; + +import com.intellij.codeInsight.codeFragment.CodeFragment; +import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.ui.DocumentAdapter; +import com.intellij.util.containers.HashMap; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class ExtractMethodDialog extends DialogWrapper implements ExtractMethodSettings { + private JPanel myContentPane; + private ParameterTablePanel myParametersPanel; + private JTextField myMethodNameTextField; + private JTextArea mySignaturePreviewTextArea; + private JTextArea myOutputVariablesTextArea; + private final String myDefaultName; + private final ExtractMethodValidator myValidator; + private final ExtractMethodDecorator myDecorator; + + private VariableData[] myVariableData; + private Map myVariablesMap; + + private final List myArguments; + private final ArrayList myOutputVariables; + + public ExtractMethodDialog(final Project project, + final String defaultName, + final CodeFragment fragment, + final ExtractMethodValidator validator, + final ExtractMethodDecorator decorator) { + super(project, true); + myDefaultName = defaultName; + CodeFragment fragment1 = fragment; + myValidator = validator; + myDecorator = decorator; + myArguments = new ArrayList(fragment1.getInputVariables()); + Collections.sort(myArguments); + myOutputVariables = new ArrayList(fragment1.getOutputVariables()); + Collections.sort(myOutputVariables); + setModal(true); + setTitle(RefactoringBundle.message("extract.method.title")); + init(); + } + + @Override + protected void init() { + super.init(); + // Set default name and select it + myMethodNameTextField.setText(myDefaultName); + myMethodNameTextField.setSelectionStart(0); + myMethodNameTextField.setSelectionStart(myDefaultName.length()); + myMethodNameTextField.getDocument().addDocumentListener(new DocumentAdapter() { + @Override + protected void textChanged(DocumentEvent e) { + updateOutputVariables(); + updateSignature(); + updateOkStatus(); + } + }); + + + myVariableData = createVariableData(myArguments); + myVariablesMap = createVariableMap(myVariableData); + myParametersPanel.setVariableData(myVariableData); + myParametersPanel.init(); + + updateOutputVariables(); + updateSignature(); + updateOkStatus(); + } + + public JComponent getPreferredFocusedComponent() { + return myMethodNameTextField; + } + + public static VariableData[] createVariableData(final List args) { + final VariableData[] datas = new VariableData[args.size()]; + for (int i = 0; i < args.size(); i++) { + final VariableData data = new VariableData(); + final String name = args.get(i); + data.originalName = name; + data.name = name; + data.passAsParameter = true; + datas[i] = data; + } + return datas; + } + + public static Map createVariableMap(final VariableData[] data) { + final HashMap map = new HashMap(); + for (VariableData variableData : data) { + map.put(variableData.getOriginalName(), variableData); + } + return map; + } + + @Override + protected Action[] createActions() { + return new Action[]{getOKAction(), getCancelAction(), getHelpAction()}; + } + + @Override + protected void doOKAction() { + final String error = myValidator.check(getMethodName()); + if (error!=null){ + Messages.showInfoMessage(error, RefactoringBundle.message("error.title")); + return; + } + super.doOKAction(); + } + + @Override + protected void doHelpAction() { + HelpManager.getInstance().invokeHelp("refactoring.extractMethod"); + } + + protected JComponent createCenterPanel() { + return myContentPane; + } + + private void createUIComponents() { + myParametersPanel = new ParameterTablePanel(myValidator){ + protected void doCancelAction() { + ExtractMethodDialog.this.doCancelAction(); + } + + protected void doEnterAction() { + doOKAction(); + } + + protected void updateSignature() { + updateOutputVariables(); + ExtractMethodDialog.this.updateSignature(); + } + }; + } + + private void updateOutputVariables() { + final StringBuilder builder = new StringBuilder(); + boolean first = true; + for (String variable : myOutputVariables) { + if (myVariablesMap!=null){ + final VariableData data = myVariablesMap.get(variable); + final String outputName = data != null ? data.getName() : variable; + if (first){ + first = false; + } else { + builder.append(", "); + } + builder.append(outputName); + } + } + myOutputVariablesTextArea.setText(builder.length() > 0 ? builder.toString() : "None"); + } + + private void updateSignature() { + mySignaturePreviewTextArea.setText(myDecorator.createMethodPreview(getMethodName(), myVariableData)); + } + + private void updateOkStatus() { + setOKActionEnabled(myValidator.isValidName(getMethodName())); + } + + public String getMethodName() { + return myMethodNameTextField.getText().trim(); + } + + public VariableData[] getVariableData() { + return myVariableData; + } + +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ExtractMethodSettings.java b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ExtractMethodSettings.java new file mode 100644 index 000000000000..5916d5af675a --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ExtractMethodSettings.java @@ -0,0 +1,24 @@ +/* + * Copyright 2000-2010 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 com.intellij.refactoring.extractmethod; + +/** + * @author oleg + */ +public interface ExtractMethodSettings { + String getMethodName(); + VariableData[] getVariableData(); +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ExtractMethodValidator.java b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ExtractMethodValidator.java new file mode 100644 index 000000000000..dcc221b2ab4d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ExtractMethodValidator.java @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2010 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 com.intellij.refactoring.extractmethod; + +import org.jetbrains.annotations.Nullable; + +/** + * @author oleg + * This validator should check if name will clash with existing methods + */ +public interface ExtractMethodValidator { + @Nullable + String check(String name); + + boolean isValidName(String name); +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ParameterTablePanel.java b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ParameterTablePanel.java new file mode 100644 index 000000000000..4a73ce9fadc8 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/ParameterTablePanel.java @@ -0,0 +1,318 @@ +/* + * Copyright 2000-2010 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 com.intellij.refactoring.extractmethod; + +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TableUtil; +import com.intellij.ui.UIBundle; +import com.intellij.util.ui.Table; +import org.jetbrains.annotations.NonNls; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellEditor; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; + +/** + * @author oleg + * It`s a modified copy of com.intellij.refactoring.util.ParameterTablePanel + */ +public abstract class ParameterTablePanel extends JPanel { + private VariableData[] myVariableData; + + private Table myTable; + private MyTableModel myTableModel; + private JButton myUpButton; + private JButton myDownButton; + private final ExtractMethodValidator myValidator; + + protected abstract void updateSignature(); + + protected abstract void doEnterAction(); + + protected abstract void doCancelAction(); + + public void setVariableData(VariableData[] variableData) { + myVariableData = variableData; + } + + public ParameterTablePanel(final ExtractMethodValidator validator) { + super(new BorderLayout()); + myValidator = validator; + } + + public void init() { + myTableModel = new MyTableModel(); + myTable = new Table(myTableModel); + DefaultCellEditor defaultEditor = (DefaultCellEditor)myTable.getDefaultEditor(Object.class); + defaultEditor.setClickCountToStart(1); + + myTable.setTableHeader(null); + myTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myTable.getColumnModel().getColumn(MyTableModel.CHECKMARK_COLUMN).setMaxWidth(new JCheckBox().getPreferredSize().width); + myTable.getColumnModel().getColumn(MyTableModel.PARAMETER_NAME_COLUMN).setCellRenderer(new DefaultTableCellRenderer() { + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + VariableData data = myVariableData[row]; + setText(data.name); + return this; + } + }); + + + myTable.setPreferredScrollableViewportSize(new Dimension(250, myTable.getRowHeight() * 5)); + myTable.setShowGrid(false); + myTable.setIntercellSpacing(new Dimension(0, 0)); + @NonNls final InputMap inputMap = myTable.getInputMap(); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "enable_disable"); + @NonNls final ActionMap actionMap = myTable.getActionMap(); + actionMap.put("enable_disable", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if (myTable.isEditing()) return; + int[] rows = myTable.getSelectedRows(); + if (rows.length > 0) { + boolean valueToBeSet = false; + for (int row : rows) { + if (!myVariableData[row].passAsParameter) { + valueToBeSet = true; + break; + } + } + for (int row : rows) { + myVariableData[row].passAsParameter = valueToBeSet; + } + myTableModel.fireTableRowsUpdated(rows[0], rows[rows.length - 1]); + TableUtil.selectRows(myTable, rows); + } + } + }); + // F2 should edit the name + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), "edit_parameter_name"); + actionMap.put("edit_parameter_name", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if (!myTable.isEditing()) { + int row = myTable.getSelectedRow(); + if (row >= 0 && row < myTableModel.getRowCount()) { + TableUtil.editCellAt(myTable, row, MyTableModel.PARAMETER_NAME_COLUMN); + } + } + } + }); + + // make ENTER work when the table has focus + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "invokeImpl"); + actionMap.put("invokeImpl", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } + else { + doEnterAction(); + } + } + }); + + // make ESCAPE work when the table has focus + actionMap.put("doCancel", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } + else { + doCancelAction(); + } + } + }); + + JPanel listPanel = new JPanel(new BorderLayout()); + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable); + listPanel.add(scrollPane, BorderLayout.CENTER); + listPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); + add(listPanel, BorderLayout.CENTER); + + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); + add(buttonsPanel, BorderLayout.EAST); + + buttonsPanel.setLayout(new GridBagLayout()); + GridBagConstraints gbConstraints = new GridBagConstraints(); + gbConstraints.gridwidth = GridBagConstraints.REMAINDER; + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.insets = new Insets(2, 4, 2, 4); + + myUpButton = new JButton(); + myUpButton.setText(UIBundle.message("row.move.up")); + myUpButton.setDefaultCapable(false); + buttonsPanel.add(myUpButton, gbConstraints); + + myDownButton = new JButton(); + myDownButton.setText(UIBundle.message("row.move.down")); + myDownButton.setDefaultCapable(false); + buttonsPanel.add(myDownButton, gbConstraints); + + gbConstraints.weighty = 1; + buttonsPanel.add(new JPanel(), gbConstraints); + + myUpButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (myTable.isEditing()) { + final boolean isStopped = myTable.getCellEditor().stopCellEditing(); + if (!isStopped) return; + } + moveSelectedItem(-1); + updateSignature(); + myTable.requestFocus(); + } + }); + + myDownButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (myTable.isEditing()) { + final boolean isStopped = myTable.getCellEditor().stopCellEditing(); + if (!isStopped) return; + } + moveSelectedItem(+1); + updateSignature(); + myTable.requestFocus(); + } + }); + + myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + updateMoveButtons(); + } + }); + if (myVariableData.length <= 1) { + myUpButton.setEnabled(false); + myDownButton.setEnabled(false); + } + else { + myTable.getSelectionModel().setSelectionInterval(0, 0); + } + updateMoveButtons(); + } + + private void updateMoveButtons() { + int row = myTable.getSelectedRow(); + if (0 <= row && row < myVariableData.length) { + myUpButton.setEnabled(row > 0); + myDownButton.setEnabled(row < myVariableData.length - 1); + } + else { + myUpButton.setEnabled(false); + myDownButton.setEnabled(false); + } + } + + private void moveSelectedItem(int moveIncrement) { + int row = myTable.getSelectedRow(); + if (row < 0 || row >= myVariableData.length) return; + int targetRow = row + moveIncrement; + if (targetRow < 0 || targetRow >= myVariableData.length) return; + + VariableData currentItem = myVariableData[row]; + myVariableData[row] = myVariableData[targetRow]; + myVariableData[targetRow] = currentItem; + + myTableModel.fireTableRowsUpdated(Math.min(targetRow, row), Math.max(targetRow, row)); + myTable.getSelectionModel().setSelectionInterval(targetRow, targetRow); + } + + public void setEnabled(boolean enabled) { + myTable.setEnabled(enabled); + if (!enabled) { + myUpButton.setEnabled(false); + myDownButton.setEnabled(false); + } + else { + updateMoveButtons(); + } + super.setEnabled(enabled); + } + + private class MyTableModel extends AbstractTableModel { + public static final int CHECKMARK_COLUMN = 0; + public static final int PARAMETER_NAME_COLUMN = 1; + + public int getRowCount() { + return myVariableData.length; + } + + public int getColumnCount() { + return 2; + } + + public Object getValueAt(int rowIndex, int columnIndex) { + switch (columnIndex) { + case CHECKMARK_COLUMN: { + return myVariableData[rowIndex].passAsParameter ? Boolean.TRUE : Boolean.FALSE; + } + case PARAMETER_NAME_COLUMN: { + return myVariableData[rowIndex].name; + } + } + assert false; + return null; + } + + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + switch (columnIndex) { + case CHECKMARK_COLUMN: { + myVariableData[rowIndex].passAsParameter = ((Boolean)aValue).booleanValue(); + fireTableRowsUpdated(rowIndex, rowIndex); + myTable.getSelectionModel().setSelectionInterval(rowIndex, rowIndex); + updateSignature(); + break; + } + case PARAMETER_NAME_COLUMN: { + VariableData data = myVariableData[rowIndex]; + String name = (String)aValue; + if (myValidator.isValidName(name)) { + data.name = name; + } + updateSignature(); + break; + } + } + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + switch (columnIndex) { + case CHECKMARK_COLUMN: + return isEnabled(); + case PARAMETER_NAME_COLUMN: + return isEnabled() && myVariableData[rowIndex].passAsParameter; + default: + return false; + } + } + + public Class getColumnClass(int columnIndex) { + if (columnIndex == CHECKMARK_COLUMN) { + return Boolean.class; + } + return super.getColumnClass(columnIndex); + } + } +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractmethod/PyExtractMethodDialog.form b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/PyExtractMethodDialog.form new file mode 100644 index 000000000000..c27b42145137 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/PyExtractMethodDialog.form @@ -0,0 +1,107 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractmethod/VariableData.java b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/VariableData.java new file mode 100644 index 000000000000..00b9a4343787 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/extractmethod/VariableData.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2010 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 com.intellij.refactoring.extractmethod; + +/** +* @author oleg +*/ +public class VariableData { + public String originalName; + public String name; + public boolean passAsParameter; + + public String getName() { + return name; + } + + public String getOriginalName() { + return originalName; + } + + public boolean isPassAsParameter() { + return passAsParameter; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompiler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompiler.java index 1346be937ad8..8a669b0ff836 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompiler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompiler.java @@ -16,36 +16,45 @@ package org.jetbrains.plugins.groovy.compiler; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompileScope; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.JavaModuleType; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.JavaSdkType; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.ContentIterator; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.ui.configuration.ClasspathEditor; import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.util.containers.FactoryMap; +import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.GroovyFileTypeLoader; import org.jetbrains.plugins.groovy.config.GroovyConfigUtils; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; +import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass; import org.jetbrains.plugins.groovy.util.LibrariesUtil; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @author Dmitry.Krasilschikov */ public class GroovyCompiler extends GroovyCompilerBase { - private static final String GROOVY_COMPILER = "groovy compiler"; + private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.compiler.GroovyCompiler"); public GroovyCompiler(Project project) { super(project); @@ -53,12 +62,118 @@ public class GroovyCompiler extends GroovyCompilerBase { @NotNull public String getDescription() { - return GROOVY_COMPILER; + return "groovy compiler"; } @Override - protected void compileFiles(CompileContext compileContext, Module module, List toCompile, OutputSink sink, boolean tests) { - runGroovycCompiler(compileContext, module, toCompile, false, getMainOutput(compileContext, module, tests), sink, tests); + protected void compileFiles(final CompileContext context, final Module module, List toCompile, OutputSink sink, boolean tests) { + final Set allToCompile = new LinkedHashSet(toCompile); + + // groovyc may fail if we don't also recompile files like B such that A depends on B and B depends on C, where A & C \in toCompile + // see http://jira.codehaus.org/browse/GROOVY-4024 + // this is important only if >1 files have been changed + if (toCompile.size() > 1 && !"false".equals(System.getProperty("compile.groovy.dependencies", "true"))) { + context.getProgressIndicator().checkCanceled(); + context.getProgressIndicator().setText("Enumerating Groovy classes..."); + + Set groovyFiles = enumerateGroovyFiles(module); + + if (toCompile.size() < groovyFiles.size()) { + context.getProgressIndicator().checkCanceled(); + context.getProgressIndicator().setText("Processing Groovy dependencies..."); + + addIntermediateGroovyClasses(allToCompile, groovyFiles); + } + } + + context.getProgressIndicator().checkCanceled(); + context.getProgressIndicator().setText(GroovycOSProcessHandler.GROOVY_COMPILER_IN_OPERATION); + + runGroovycCompiler(context, module, new ArrayList(allToCompile), false, getMainOutput(context, module, tests), sink, tests); + } + + private void addIntermediateGroovyClasses(Set allToCompile, final Set groovyFiles) { + final Set initialFiles = new THashSet(allToCompile); + + final THashSet visited = new THashSet(); + for (VirtualFile aClass : initialFiles) { + if (visited.add(aClass)) { + goForIntermediateFiles(aClass, allToCompile, new FactoryMap>() { + @Override + protected Set create(final VirtualFile key) { + return ApplicationManager.getApplication().runReadAction(new Computable>() { + public Set compute() { + return calcCodeReferenceDependencies(key, groovyFiles); + } + }); + } + }, visited); + } + } + } + + private Set enumerateGroovyFiles(final Module module) { + final Set moduleClasses = new THashSet(); + ModuleRootManager.getInstance(module).getFileIndex().iterateContent(new ContentIterator() { + public boolean processFile(final VirtualFile vfile) { + if (!vfile.isDirectory() && + GroovyFileType.GROOVY_FILE_TYPE.equals(vfile.getFileType())) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + if (PsiManager.getInstance(myProject).findFile(vfile) instanceof GroovyFile) { + moduleClasses.add(vfile); + } + } + }); + + } + return true; + } + }); + return moduleClasses; + } + + private static void goForIntermediateFiles(VirtualFile from, Set dirty, FactoryMap> deps, Set visited) { + final Set set = deps.get(from); + for (VirtualFile psiClass : set) { + if (visited.add(psiClass)) { + goForIntermediateFiles(psiClass, dirty, deps, visited); + } + if (dirty.contains(psiClass)) { + dirty.add(from); + } + } + } + + private Set calcCodeReferenceDependencies(VirtualFile vfile, final Set moduleFiles) { + final PsiFile psi = PsiManager.getInstance(myProject).findFile(vfile); + if (!(psi instanceof GroovyFile)) return Collections.emptySet(); + + final Set deps = new THashSet(); + psi.acceptChildren(new PsiElementVisitor() { + @Override + public void visitElement(PsiElement element) { + if (element instanceof GrCodeReferenceElement) { + GrCodeReferenceElement referenceElement = (GrCodeReferenceElement)element; + try { + final PsiElement target = referenceElement.resolve(); + if (target instanceof GrTypeDefinition || target instanceof GroovyScriptClass) { + final VirtualFile targetFile = target.getContainingFile().getViewProvider().getVirtualFile(); + if (moduleFiles.contains(targetFile)) { + deps.add(targetFile); + } + } + } + catch (Exception e) { + LOG.error(e); + //prevent our PSI errors from failing the entire compilation + } + } + + element.acceptChildren(this); + } + }); + return deps; } public boolean validateConfiguration(CompileScope compileScope) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java index 577c06dee595..0d6585f66a3f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java @@ -130,7 +130,7 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler { } //debug - //commandLine.addParameter("-Xdebug"); commandLine.addParameter("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5239"); + //parameters.getVMParametersList().add("-Xdebug"); parameters.getVMParametersList().add("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5239"); // Setting up process encoding according to locale final ArrayList list = new ArrayList(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovycOSProcessHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovycOSProcessHandler.java index 64ad41c847b1..b1d75ce67cef 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovycOSProcessHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovycOSProcessHandler.java @@ -44,6 +44,7 @@ public class GroovycOSProcessHandler extends OSProcessHandler { private final CompileContext myContext; private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.compiler.GroovycOSProcessHandler"); + public static final String GROOVY_COMPILER_IN_OPERATION = "Groovy compiler in operation..."; public GroovycOSProcessHandler(CompileContext context, Process process, String s) { super(process, s); @@ -73,7 +74,7 @@ public class GroovycOSProcessHandler extends OSProcessHandler { } if (GroovycRunner.CLEAR_PRESENTABLE.equals(text)) { - myContext.getProgressIndicator().setText("Groovy compiler in operation..."); + myContext.getProgressIndicator().setText(GROOVY_COMPILER_IN_OPERATION); return; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java index e0ab7650578e..d24e5dcfe238 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java @@ -574,8 +574,13 @@ public class GroovyToJavaGenerator { final GroovyResolveResult[] results = constructorInvocation.multiResolveConstructor(); if (results.length > 0) { int i = 0; - if (results[i].getElement() == constructor && results.length > 1) { - i = 1; + while (results.length > i+1) { + final PsiMethod candidate = (PsiMethod)results[i].getElement(); + final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(constructor.getProject()).getResolveHelper(); + if (candidate != null && candidate != constructor && resolveHelper.isAccessible(candidate, constructorInvocation, null)) { + break; + } + i++; } chainedConstructor = (PsiMethod) results[i].getElement(); substitutor = results[i].getSubstitutor(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java index 878e6caeb0ae..bd756a33c690 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClosureType.java @@ -37,13 +37,6 @@ public class GrClosureType extends PsiClassType { private final boolean[] myOptionals; private final PsiManager myManager; - private GrClosureType(GlobalSearchScope scope, - @Nullable PsiType returnType, - PsiType[] parameters, - boolean[] optionals, - PsiManager manager) { - this(scope, returnType, parameters, optionals, manager,LanguageLevel.JDK_1_5); - } private GrClosureType(GlobalSearchScope scope, @Nullable PsiType returnType, PsiType[] parameters, @@ -62,6 +55,7 @@ public class GrClosureType extends PsiClassType { return JavaPsiFacade.getInstance(myManager.getProject()).findClass(GrClosableBlock.GROOVY_LANG_CLOSURE, getResolveScope()); } + @Nullable public PsiType getClosureReturnType() { return myReturnType; } @@ -189,8 +183,7 @@ public class GrClosureType extends PsiClassType { } public PsiClassType setLanguageLevel(final LanguageLevel languageLevel) { - GrClosureType copy = create(myReturnType, myParameterTypes, myOptionals, myManager, myScope, languageLevel); - return copy; + return create(myReturnType, myParameterTypes, myOptionals, myManager, myScope, languageLevel); } public static GrClosureType create(GrClosableBlock closure) { @@ -222,6 +215,7 @@ public class GrClosureType extends PsiClassType { return new GrClosureType(scope, returnType, parameterTypes, optionals, manager,languageLevel); } + @Nullable public PsiType curry(int num) { if (num > myParameterTypes.length) return null; PsiType[] newParameterTypes = new PsiType[myParameterTypes.length - num]; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java index 3c40bac3dd73..20f4c6918d9d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java @@ -427,7 +427,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements } } - private void processQualifierForSpreadDot(GrReferenceExpressionImpl refExpr, ResolverProcessor processor, GrExpression qualifier) { + private static void processQualifierForSpreadDot(GrReferenceExpressionImpl refExpr, ResolverProcessor processor, GrExpression qualifier) { PsiType qualifierType = qualifier.getType(); if (qualifierType instanceof PsiClassType) { PsiClassType.ClassResolveResult result = ((PsiClassType) qualifierType).resolveGenerics(); @@ -449,13 +449,19 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements } } - private void processQualifier(GrReferenceExpressionImpl refExpr, ResolverProcessor processor, GrExpression qualifier) { + private static void processQualifier(GrReferenceExpressionImpl refExpr, ResolverProcessor processor, GrExpression qualifier) { PsiType qualifierType = qualifier.getType(); if (qualifierType == null) { if (qualifier instanceof GrReferenceExpression) { PsiElement resolved = ((GrReferenceExpression) qualifier).resolve(); if (resolved instanceof PsiPackage) { - if (!resolved.processDeclarations(processor, ResolveState.initial(), null, refExpr)) return; + if (!resolved.processDeclarations(processor, ResolveState.initial(), null, refExpr)) //noinspection UnnecessaryReturnStatement + return; + } + else { + qualifierType = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory() + .createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, refExpr.getResolveScope()); + processClassQualifierType(refExpr, processor, qualifierType); } } } else { @@ -556,6 +562,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements return Kind.TYPE_OR_PROPERTY; } + @Nullable public String getCanonicalText() { return null; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java index e4d6fa8b2ff9..6e474a66363d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java @@ -25,6 +25,7 @@ import com.intellij.util.containers.HashMap; import gnu.trove.TIntObjectHashMap; import gnu.trove.TObjectIntHashMap; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; @@ -199,7 +200,9 @@ public class TypesUtil { if (rType instanceof GrTupleType) { final GrTupleType tuple = (GrTupleType)rType; if (tuple.getComponentTypes().length == 0) { - if (lType instanceof PsiArrayType || InheritanceUtil.isInheritor(lType, JAVA_UTIL_LIST)) { + if (lType instanceof PsiArrayType || + InheritanceUtil.isInheritor(lType, JAVA_UTIL_LIST) || + InheritanceUtil.isInheritor(lType, JAVA_UTIL_SET)) { return true; } } @@ -216,6 +219,17 @@ public class TypesUtil { public static boolean isAssignableByMethodCallConversion(PsiType lType, PsiType rType, PsiManager manager, GlobalSearchScope scope) { if (lType == null || rType == null) return false; + if (rType instanceof GrTupleType) { + final GrTupleType tuple = (GrTupleType)rType; + if (tuple.getComponentTypes().length == 0) { + if (lType instanceof PsiArrayType || + InheritanceUtil.isInheritor(lType, JAVA_UTIL_LIST) || + InheritanceUtil.isInheritor(lType, JAVA_UTIL_SET)) { + return true; + } + } + } + if (rType.equalsToText(GrStringUtil.GROOVY_LANG_GSTRING)) { final PsiClass javaLangString = JavaPsiFacade.getInstance(manager.getProject()).findClass(JAVA_LANG_STRING, scope); if (javaLangString != null && @@ -259,18 +273,6 @@ public class TypesUtil { return type; } - public static PsiType boxPrimitiveTypeAndEraseGenerics(PsiType result, PsiManager manager, GlobalSearchScope resolveScope) { - if (result instanceof PsiPrimitiveType) { - PsiPrimitiveType primitive = (PsiPrimitiveType)result; - String boxedTypeName = primitive.getBoxedTypeName(); - if (boxedTypeName != null) { - return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(boxedTypeName, resolveScope); - } - } - - return TypeConversionUtil.erasure(result); - } - public static PsiType boxPrimitiveType(PsiType result, PsiManager manager, GlobalSearchScope resolveScope) { if (result instanceof PsiPrimitiveType && result != PsiType.VOID) { PsiPrimitiveType primitive = (PsiPrimitiveType)result; @@ -312,7 +314,7 @@ public class TypesUtil { } @Nullable - public static PsiType getLeastUpperBound(PsiType type1, PsiType type2, PsiManager manager) { + public static PsiType getLeastUpperBound(@NotNull PsiType type1, @NotNull PsiType type2, PsiManager manager) { if (type1 instanceof GrTupleType && type2 instanceof GrTupleType) { GrTupleType tuple1 = (GrTupleType)type1; GrTupleType tuple2 = (GrTupleType)type2; @@ -344,7 +346,9 @@ public class TypesUtil { paramTypes[i] = GenericsUtil.getGreatestLowerBound(parameterTypes1[i], parameterTypes2[i]); opts[i] = clType1.isOptionalParameter(i) && clType2.isOptionalParameter(i); } - PsiType returnType = getLeastUpperBound(clType1.getClosureReturnType(), clType2.getClosureReturnType(), manager); + final PsiType ret1 = clType1.getClosureReturnType(); + final PsiType ret2 = clType2.getClosureReturnType(); + PsiType returnType = ret1 == null ? ret2 : ret2 == null ? ret1 : getLeastUpperBound(ret1, ret2, manager); GlobalSearchScope scope = clType1.getResolveScope().intersectWith(clType2.getResolveScope()); return GrClosureType.create(returnType, paramTypes, opts, manager, scope, LanguageLevel.JDK_1_5); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java index 7f6fa68c773a..39c1f33bf59d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java @@ -22,6 +22,7 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; @@ -91,6 +92,7 @@ public class GrMethodCallExpressionImpl extends GrCallExpressionImpl implements } }; + @Nullable private static PsiType getClosureCallOrCurryReturnType(GrMethodCallExpressionImpl callExpression, GrReferenceExpression refExpr, PsiMethod resolved) { PsiClass clazz = resolved.getContainingClass(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.java index bb5787809bf9..b64c58e97147 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.java @@ -65,6 +65,9 @@ public class GrClassImplUtil { } }; + private GrClassImplUtil() { + } + @Nullable public static PsiClass getSuperClass(GrTypeDefinition grType) { @@ -74,6 +77,7 @@ public class GrClassImplUtil { return superClass != null ? superClass : getBaseClass(grType); } + @Nullable public static PsiClass getBaseClass(GrTypeDefinition grType) { if (grType.isEnum()) { return JavaPsiFacade.getInstance(grType.getProject()).findClass(CommonClassNames.JAVA_LANG_ENUM, grType.getResolveScope()); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/generator/GeneratorTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java similarity index 97% rename from plugins/groovy/test/org/jetbrains/plugins/groovy/lang/generator/GeneratorTest.java rename to plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java index 4d0a379bc786..d4cec2cf5564 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/generator/GeneratorTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java @@ -1,4 +1,4 @@ -package org.jetbrains.plugins.groovy.lang.generator; +package org.jetbrains.plugins.groovy.compiler; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.module.Module; @@ -59,6 +59,7 @@ public void testArrayType1() throws Throwable { doTest(); } public void testToGenerate() throws Throwable { doTest(); } public void testToGenerate1() throws Throwable { doTest(); } public void testVararg1() throws Throwable { doTest(); } + public void testInaccessibleConstructor() throws Throwable { doTest(); } @Override protected void tuneFixture(JavaModuleFixtureBuilder moduleBuilder) { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy similarity index 92% rename from plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.groovy rename to plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy index fff8d04f1871..5cb388cad796 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.jetbrains.plugins.groovy.lang; +package org.jetbrains.plugins.groovy.compiler; import com.intellij.compiler.CompilerConfiguration; -import com.intellij.openapi.application.Result; -import com.intellij.openapi.command.WriteCommandAction; + + import com.intellij.openapi.module.Module; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; @@ -287,5 +287,47 @@ class Foo { assertEmpty make() } + public void testRecompileDependentClass() throws Exception { + def cloud = myFixture.addFileToProject("Cloud.groovy", """ +class Cloud { + def accessFooProperty(Foo c) { + c.prop = 2 + } +} +""") + myFixture.addFileToProject "Foo.groovy", """ +class Foo { + def withGooParameter(Goo x) {} +}""" + def goo = myFixture.addFileToProject("Goo.groovy", "class Goo {}") + + assertEmpty make() + + touch(cloud.virtualFile) + touch(goo.virtualFile) + assertEmpty make() + } + + public void testRecompileImportedClass() throws Exception { + def bar = myFixture.addFileToProject("pack/Bar.groovy", """ +package pack +import pack.Foo +class Bar {} +""") + myFixture.addFileToProject "pack/Foo.groovy", """ +package pack +class Foo extends Goo { +}""" + def goo = myFixture.addFileToProject("Goo.groovy", """ +package pack +class Goo {}""") + + assertEmpty make() + + touch(bar.virtualFile) + touch(goo.virtualFile) + assertEmpty make() + } + } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTestCase.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java similarity index 99% rename from plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTestCase.java rename to plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java index 8e06fa9b6bf5..32e7386840ff 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTestCase.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java @@ -1,4 +1,4 @@ -package org.jetbrains.plugins.groovy.lang; +package org.jetbrains.plugins.groovy.compiler; import com.intellij.compiler.CompilerManagerImpl; import com.intellij.execution.ExecutionException; diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java index 4a4ced60ae66..51de8c847d56 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java @@ -205,4 +205,8 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase { public void testWithMethod() throws Exception {doTest();} public void testArrayLikeAccess() throws Exception {doTest();} + + public void testSetInitializing() throws Exception {doTest();} + + public void testEmptyTupleAssignability() throws Exception {doTest();} } \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.java index e66d0336db5e..146af08a9ae4 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.java @@ -540,4 +540,10 @@ public class ResolveMethodTest extends GroovyResolveTestCase { final PsiElement resolved = ref.resolve(); assertInstanceOf(resolved, PsiMethod.class); } + + public void testNotInitializedVariable() throws Exception { + PsiReference ref = configureByFile("notInitializedVariable/A.groovy"); + final PsiElement resolved = ref.resolve(); + assertInstanceOf(resolved, PsiMethod.class); + } } diff --git a/plugins/groovy/testdata/groovy/stubGenerator/inaccessibleConstructor.test b/plugins/groovy/testdata/groovy/stubGenerator/inaccessibleConstructor.test new file mode 100644 index 000000000000..d0b75c5606f5 --- /dev/null +++ b/plugins/groovy/testdata/groovy/stubGenerator/inaccessibleConstructor.test @@ -0,0 +1,72 @@ +class Foo { + private Foo(Void v, Foo p) {} + protected Foo(Foo p) {} + protected Foo() {} +} + +class ExtensionLoader extends Foo { + ExtensionLoader(parent) { + super(parent); + } +} +----- +public class Foo implements groovy.lang.GroovyObject { + public Foo(java.lang.Void v, Foo p) { + + } + + public Foo(Foo p) { + + } + + public Foo() { + + } + + public groovy.lang.MetaClass getMetaClass() { + return null; + } + + public void setMetaClass(groovy.lang.MetaClass mc) { + return ; + } + + public java.lang.Object invokeMethod(java.lang.String name, java.lang.Object args) { + return null; + } + + public java.lang.Object getProperty(java.lang.String propertyName) { + return null; + } + + public void setProperty(java.lang.String propertyName, java.lang.Object newValue) { + return ; + } +} +--- +public class ExtensionLoader extends Foo implements groovy.lang.GroovyObject { + public ExtensionLoader(java.lang.Object parent) { + super((Foo)null); + } + + public groovy.lang.MetaClass getMetaClass() { + return null; + } + + public void setMetaClass(groovy.lang.MetaClass mc) { + return ; + } + + public java.lang.Object invokeMethod(java.lang.String name, java.lang.Object args) { + return null; + } + + public java.lang.Object getProperty(java.lang.String propertyName) { + return null; + } + + public void setProperty(java.lang.String propertyName, java.lang.Object newValue) { + return ; + } +} +--- \ No newline at end of file diff --git a/plugins/groovy/testdata/highlighting/EmptyTupleAssignability.groovy b/plugins/groovy/testdata/highlighting/EmptyTupleAssignability.groovy new file mode 100644 index 000000000000..f3aa4ba3f87c --- /dev/null +++ b/plugins/groovy/testdata/highlighting/EmptyTupleAssignability.groovy @@ -0,0 +1,11 @@ +class Foo { + Foo(List l) { + + } +} + +class Bar extends Foo { + def Bar() { + super([]) + } +} \ No newline at end of file diff --git a/plugins/groovy/testdata/highlighting/SetInitializing.groovy b/plugins/groovy/testdata/highlighting/SetInitializing.groovy new file mode 100644 index 000000000000..0c729c415915 --- /dev/null +++ b/plugins/groovy/testdata/highlighting/SetInitializing.groovy @@ -0,0 +1 @@ +Set set = [1, 2, 3] \ No newline at end of file diff --git a/plugins/groovy/testdata/resolve/method/notInitializedVariable/A.groovy b/plugins/groovy/testdata/resolve/method/notInitializedVariable/A.groovy new file mode 100644 index 000000000000..02476e7b5b8a --- /dev/null +++ b/plugins/groovy/testdata/resolve/method/notInitializedVariable/A.groovy @@ -0,0 +1,2 @@ +def foo +foo.hashCode() \ No newline at end of file diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java b/plugins/ui-designer/src/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java index 3b2165b16c56..4cd472bc52dc 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java @@ -16,7 +16,6 @@ package com.intellij.uiDesigner.make; import com.intellij.compiler.PsiClassWriter; -import com.intellij.compiler.impl.CompilerUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.*; import com.intellij.openapi.diagnostic.Logger; @@ -263,8 +262,6 @@ public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { context.getProgressIndicator().pushState(); context.getProgressIndicator().setText(UIDesignerBundle.message("progress.compiling.ui.forms")); - final long start = System.currentTimeMillis(); - final Project project = context.getProject(); final HashMap> module2itemsList = sortByModules(project, items); @@ -347,7 +344,6 @@ public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { } } } - CompilerUtil.logDuration("Forms compilation", System.currentTimeMillis() - start); context.getProgressIndicator().popState(); return compiledItems.toArray(new ProcessingItem[compiledItems.size()]);