mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/community
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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<VirtualFile> 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<VirtualFile> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<File> 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<File> files) {
|
||||
final long start = System.currentTimeMillis();
|
||||
try {
|
||||
final LocalFileSystem lfs = LocalFileSystem.getInstance();
|
||||
final List<VirtualFile> filesToRefresh = new ArrayList<VirtualFile>();
|
||||
for (File file : files) {
|
||||
final VirtualFile virtualFile = lfs.refreshAndFindFileByIoFile(file);
|
||||
if (virtualFile != null) {
|
||||
filesToRefresh.add(virtualFile);
|
||||
}
|
||||
final LocalFileSystem lfs = LocalFileSystem.getInstance();
|
||||
final List<VirtualFile> filesToRefresh = new ArrayList<VirtualFile>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-414
@@ -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<VirtualFile> mySuccesfullyCompiledJavaFiles; // VirtualFile
|
||||
|
||||
private final CompileContextEx myCompileContext;
|
||||
private final List<VirtualFile> myFilesToCompile;
|
||||
private final TranslatingCompiler.OutputSink mySink;
|
||||
private final Chunk<Module> myChunk;
|
||||
private final Project myProject;
|
||||
private final Set<VirtualFile> myFilesToRecompile;
|
||||
private final ProjectFileIndex myProjectFileIndex;
|
||||
private long myCompilationDuration = 0L;
|
||||
|
||||
|
||||
public AnnotationProcessorsRunner(Chunk<Module> chunk, @NotNull final Project project,
|
||||
@NotNull List<VirtualFile> filesToCompile,
|
||||
@NotNull CompileContextEx compileContext,
|
||||
@NotNull BackendCompiler compiler, TranslatingCompiler.OutputSink sink) {
|
||||
myChunk = chunk;
|
||||
myProject = project;
|
||||
myCompiler = compiler;
|
||||
myCompileContext = compileContext;
|
||||
myFilesToCompile = filesToCompile;
|
||||
myFilesToRecompile = new HashSet<VirtualFile>(filesToCompile);
|
||||
mySink = sink;
|
||||
myProjectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
|
||||
mySuccesfullyCompiledJavaFiles = new HashSet<VirtualFile>(filesToCompile.size());
|
||||
}
|
||||
|
||||
public void compile() throws CompilerException, CacheCorruptedException {
|
||||
try {
|
||||
if (!myFilesToCompile.isEmpty()) {
|
||||
final Map<Module, List<VirtualFile>> 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<OutputDir> 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.<TranslatingCompiler.OutputItem>emptyList(), myFilesToRecompile.toArray(new VirtualFile[myFilesToRecompile.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Module, List<VirtualFile>> buildModuleToFilesMap(final List<VirtualFile> 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<OutputDir> 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<Boolean>() {
|
||||
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<VirtualFile, VirtualFile> originalToCopyFileMap = new HashMap<VirtualFile, VirtualFile>();
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
application.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
for (final Module module : modules) {
|
||||
List<VirtualFile> 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<VirtualFile> 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);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
-3
@@ -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<String, Set<CompiledClass>> myFileNameToSourceMap= new THashMap<String, Set<CompiledClass>>();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
-11
@@ -78,7 +78,6 @@ public class ResourceCompiler implements TranslatingCompiler {
|
||||
final Map<String, Collection<OutputItem>> processed = new HashMap<String, Collection<OutputItem>>();
|
||||
final LinkedList<CopyCommand> copyCommands = new LinkedList<CopyCommand>();
|
||||
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<String> rootsToRefresh = new HashSet<String>();
|
||||
// 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<File> dirs = new ArrayList<File>();
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<int[], Set<VirtualFile>> deps =
|
||||
dependencyCache.findDependentClasses(context, context.getProject(), succesfullyCompiledJavaFiles, additionalDependencyProcessor);
|
||||
final Pair<int[], Set<VirtualFile>> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -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) &&
|
||||
|
||||
@@ -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;
|
||||
|
||||
+23
@@ -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);
|
||||
}
|
||||
+196
@@ -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<String, VariableData> myVariablesMap;
|
||||
|
||||
private final List<String> myArguments;
|
||||
private final ArrayList<String> 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<String>(fragment1.getInputVariables());
|
||||
Collections.sort(myArguments);
|
||||
myOutputVariables = new ArrayList<String>(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<String> 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<String, VariableData> createVariableMap(final VariableData[] data) {
|
||||
final HashMap<String, VariableData> map = new HashMap<String, VariableData>();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
+24
@@ -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();
|
||||
}
|
||||
+29
@@ -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);
|
||||
}
|
||||
+318
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.refactoring.extractmethod.ExtractMethodDialog">
|
||||
<grid id="cbd77" binding="myContentPane" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="48" y="54" width="436" height="297"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="e3588" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="1" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="462a8" class="javax.swing.JTextField" binding="myMethodNameTextField">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<columns value="10"/>
|
||||
<horizontalAlignment value="2"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="e8f16" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="org/jetbrains/plugins/ruby/RBundle" key="refactoring.extract.method.dialog.method.name"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="865ab" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="1" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="etched" title-resource-bundle="org/jetbrains/plugins/ruby/RBundle" title-key="refactoring.extract.method.dialog.parameters"/>
|
||||
<children>
|
||||
<component id="d4ee9" class="com.intellij.refactoring.extractmethod.ParameterTablePanel" binding="myParametersPanel" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="1" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<scrollpane id="b0a7b">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="1" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="6b27f" class="javax.swing.JTextArea" binding="mySignaturePreviewTextArea">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<columns value="10"/>
|
||||
<editable value="false"/>
|
||||
<enabled value="true"/>
|
||||
<rows value="0"/>
|
||||
<text value="def foo()"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<component id="d94f6" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="org/jetbrains/plugins/ruby/RBundle" key="refactoring.extract.method.dialog.signature.preview"/>
|
||||
</properties>
|
||||
</component>
|
||||
<scrollpane id="ca3f5">
|
||||
<constraints>
|
||||
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="1" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="ccc83" class="javax.swing.JTextArea" binding="myOutputVariablesTextArea">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<editable value="false"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<component id="4bbe1" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="org/jetbrains/plugins/ruby/RBundle" key="refactoring.extract.method.dialog.output.variables"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<VirtualFile> 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<VirtualFile> toCompile, OutputSink sink, boolean tests) {
|
||||
final Set<VirtualFile> allToCompile = new LinkedHashSet<VirtualFile>(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<VirtualFile> 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<VirtualFile>(allToCompile), false, getMainOutput(context, module, tests), sink, tests);
|
||||
}
|
||||
|
||||
private void addIntermediateGroovyClasses(Set<VirtualFile> allToCompile, final Set<VirtualFile> groovyFiles) {
|
||||
final Set<VirtualFile> initialFiles = new THashSet<VirtualFile>(allToCompile);
|
||||
|
||||
final THashSet<VirtualFile> visited = new THashSet<VirtualFile>();
|
||||
for (VirtualFile aClass : initialFiles) {
|
||||
if (visited.add(aClass)) {
|
||||
goForIntermediateFiles(aClass, allToCompile, new FactoryMap<VirtualFile, Set<VirtualFile>>() {
|
||||
@Override
|
||||
protected Set<VirtualFile> create(final VirtualFile key) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Set<VirtualFile>>() {
|
||||
public Set<VirtualFile> compute() {
|
||||
return calcCodeReferenceDependencies(key, groovyFiles);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, visited);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Set<VirtualFile> enumerateGroovyFiles(final Module module) {
|
||||
final Set<VirtualFile> moduleClasses = new THashSet<VirtualFile>();
|
||||
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<VirtualFile> dirty, FactoryMap<VirtualFile, Set<VirtualFile>> deps, Set<VirtualFile> visited) {
|
||||
final Set<VirtualFile> 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<VirtualFile> calcCodeReferenceDependencies(VirtualFile vfile, final Set<VirtualFile> moduleFiles) {
|
||||
final PsiFile psi = PsiManager.getInstance(myProject).findFile(vfile);
|
||||
if (!(psi instanceof GroovyFile)) return Collections.emptySet();
|
||||
|
||||
final Set<VirtualFile> deps = new THashSet<VirtualFile>();
|
||||
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) {
|
||||
|
||||
@@ -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<String> list = new ArrayList<String>();
|
||||
|
||||
+2
-1
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+7
-2
@@ -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();
|
||||
|
||||
@@ -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];
|
||||
|
||||
+10
-3
@@ -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;
|
||||
}
|
||||
|
||||
+19
-15
@@ -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);
|
||||
}
|
||||
|
||||
+2
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
+2
-1
@@ -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) {
|
||||
+45
-3
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+1
-1
@@ -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;
|
||||
@@ -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();}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
}
|
||||
---
|
||||
@@ -0,0 +1,11 @@
|
||||
class Foo {
|
||||
Foo(List<String> l) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Bar extends Foo {
|
||||
def Bar() {
|
||||
super([])
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Set set = [1, 2, 3]
|
||||
@@ -0,0 +1,2 @@
|
||||
def foo
|
||||
foo.hashC<ref>ode()
|
||||
@@ -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<Module, ArrayList<MyInstrumentationItem>> 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()]);
|
||||
|
||||
Reference in New Issue
Block a user