Merge branch 'master' into changeSignature

This commit is contained in:
Maxim Medvedev
2010-05-29 17:23:45 +04:00
152 changed files with 3194 additions and 1454 deletions
@@ -94,7 +94,7 @@ public class GenerateAntBuildAction extends CompileActionBase {
}
int rc = Messages
.showOkCancelDialog(project, CompilerBundle.message("generate.ant.build.custom.compiler.conflict.message", msg.toString()),
CompilerBundle.message("generate.ant.build.custom.compiler.conflict.titile"), Messages.getErrorIcon());
CompilerBundle.message("generate.ant.build.custom.compiler.conflict.title"), Messages.getErrorIcon());
if (rc != 0) {
return false;
}
@@ -42,144 +42,147 @@ import java.io.IOException;
// todo: move path variables properties and jdk home properties into te generated property file
public class BuildPropertiesImpl extends BuildProperties {
public BuildPropertiesImpl(Project project, final GenerationOptions genOptions) {
add(new Property(getPropertyFileName(project)));
public BuildPropertiesImpl(Project project, final GenerationOptions genOptions) {
add(new Property(getPropertyFileName(project)));
//noinspection HardCodedStringLiteral
add(new Comment(CompilerBundle.message("generated.ant.build.disable.tests.property.comment"),
new Property(PROPERTY_SKIP_TESTS, "true")));
final JavacSettings javacSettings = JavacSettings.getInstance(project);
if (genOptions.enableFormCompiler) {
//noinspection HardCodedStringLiteral
add(new Property(PROPERTY_JAVAC2_HOME, propertyRelativePath(PROPERTY_IDEA_HOME, "lib")));
Path javac2 = new Path(PROPERTY_JAVAC2_CLASSPATH_ID);
javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "javac2.jar")));
javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "jdom.jar")));
javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "asm.jar")));
javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "asm-commons.jar")));
add(javac2);
//noinspection HardCodedStringLiteral
add(new Tag("taskdef", Pair.create("name", "javac2"), Pair.create("classname", "com.intellij.ant.Javac2"),
Pair.create("classpathref", PROPERTY_JAVAC2_CLASSPATH_ID)));
add(new Tag("taskdef", Pair.create("name", "instrumentIdeaExtensions"),
Pair.create("classname", "com.intellij.ant.InstrumentIdeaExtensions"),
Pair.create("classpathref", PROPERTY_JAVAC2_CLASSPATH_ID)));
}
//noinspection HardCodedStringLiteral
add(new Comment(CompilerBundle.message("generated.ant.build.disable.tests.property.comment"),
new Property(PROPERTY_SKIP_TESTS, "true")));
final JavacSettings javacSettings = JavacSettings.getInstance(project);
add(new Comment(CompilerBundle.message("generated.ant.build.compiler.options.comment")), 1);
//noinspection HardCodedStringLiteral
add(new Property(PROPERTY_COMPILER_GENERATE_DEBUG_INFO, javacSettings.DEBUGGING_INFO ? "on" : "off"), 1);
//noinspection HardCodedStringLiteral
add(new Property(PROPERTY_COMPILER_GENERATE_NO_WARNINGS, javacSettings.GENERATE_NO_WARNINGS ? "on" : "off"));
add(new Property(PROPERTY_COMPILER_ADDITIONAL_ARGS, javacSettings.ADDITIONAL_OPTIONS_STRING));
//noinspection HardCodedStringLiteral
add(new Property(PROPERTY_COMPILER_MAX_MEMORY, Integer.toString(javacSettings.MAXIMUM_HEAP_SIZE) + "m"));
add(new Comment(CompilerBundle.message("generated.ant.build.compiler.options.comment")), 1);
//noinspection HardCodedStringLiteral
add(new Property(PROPERTY_COMPILER_GENERATE_DEBUG_INFO, javacSettings.DEBUGGING_INFO ? "on" : "off"), 1);
//noinspection HardCodedStringLiteral
add(new Property(PROPERTY_COMPILER_GENERATE_NO_WARNINGS, javacSettings.GENERATE_NO_WARNINGS ? "on" : "off"));
add(new Property(PROPERTY_COMPILER_ADDITIONAL_ARGS, javacSettings.ADDITIONAL_OPTIONS_STRING));
//noinspection HardCodedStringLiteral
add(new Property(PROPERTY_COMPILER_MAX_MEMORY, Integer.toString(javacSettings.MAXIMUM_HEAP_SIZE) + "m"));
add(new IgnoredFiles());
add(new IgnoredFiles());
if (CompilerExcludes.isAvailable(project)) {
add(new CompilerExcludes(project, genOptions));
}
if (!genOptions.expandJarDirectories) {
add(new LibraryPatterns(project, genOptions));
}
add(new CompilerResourcePatterns(project));
if (genOptions.forceTargetJdk) {
createJdkGenerators(project);
}
LibraryDefinitionsGeneratorFactory factory = new LibraryDefinitionsGeneratorFactory((ProjectEx)project, genOptions);
final LibraryTablesRegistrar registrar = LibraryTablesRegistrar.getInstance();
final Generator projectLibs = factory.create(registrar.getLibraryTable(project), getProjectBaseDir(project),
CompilerBundle.message("generated.ant.build.project.libraries.comment"));
if (projectLibs != null) {
add(projectLibs);
}
final Generator globalLibs =
factory.create(registrar.getLibraryTable(), null, CompilerBundle.message("generated.ant.build.global.libraries.comment"));
if (globalLibs != null) {
add(globalLibs);
}
for (final LibraryTable table : registrar.getCustomLibraryTables()) {
if (table.getLibraries().length != 0) {
final Generator appServerLibs = factory.create(table, null, table.getPresentation().getDisplayName(true));
if (appServerLibs != null) {
add(appServerLibs);
}
}
}
final ChunkCustomCompilerExtension[] customCompilers = genOptions.getCustomCompilers();
if (customCompilers.length > 0) {
add(new Comment(CompilerBundle.message("generated.ant.build.custom.compilers.comment")), 1);
for (ChunkCustomCompilerExtension ext : customCompilers) {
ext.generateCustomCompilerTaskRegistration(project, genOptions, this);
}
}
if (CompilerExcludes.isAvailable(project)) {
add(new CompilerExcludes(project, genOptions));
}
protected void createJdkGenerators(final Project project) {
final Sdk[] jdks = getUsedJdks(project);
if (jdks.length > 0) {
add(new Comment(CompilerBundle.message("generated.ant.build.jdk.definitions.comment")), 1);
for (final Sdk jdk : jdks) {
if (jdk.getHomeDirectory() == null) {
continue;
}
final SdkType sdkType = jdk.getSdkType();
if (!(sdkType instanceof JavaSdkType) || ((JavaSdkType)sdkType).getBinPath(jdk) == null) {
continue;
}
final File home = VfsUtil.virtualToIoFile(jdk.getHomeDirectory());
File homeDir;
try {
// use canonical path in order to resolve symlinks
homeDir = home.getCanonicalFile();
}
catch (IOException e) {
homeDir = home;
}
final String jdkName = jdk.getName();
final String jdkHomeProperty = getJdkHomeProperty(jdkName);
final FileSet fileSet = new FileSet(propertyRef(jdkHomeProperty));
final String[] urls = jdk.getRootProvider().getUrls(OrderRootType.CLASSES);
for (String url : urls) {
final String path = GenerationUtils.trimJarSeparator(VirtualFileManager.extractPath(url));
final File pathElement = new File(path);
final String relativePath = FileUtil.getRelativePath(homeDir, pathElement);
if (relativePath != null) {
fileSet.add(new Include(relativePath.replace(File.separatorChar, '/')));
}
}
final File binPath = toCanonicalFile(new File(((JavaSdkType)sdkType).getBinPath(jdk)));
final String relativePath = FileUtil.getRelativePath(homeDir, binPath);
if (relativePath != null) {
add(new Property(BuildProperties.getJdkBinProperty(jdkName),
propertyRef(jdkHomeProperty) + "/" + FileUtil.toSystemIndependentName(relativePath)), 1);
}
else {
add(new Property(BuildProperties.getJdkBinProperty(jdkName), FileUtil.toSystemIndependentName(binPath.getPath())), 1);
}
final Path jdkPath = new Path(getJdkPathId(jdkName));
jdkPath.add(fileSet);
add(jdkPath);
}
}
final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectJdk();
add(new Property(PROPERTY_PROJECT_JDK_HOME, projectJdk != null ? propertyRef(getJdkHomeProperty(projectJdk.getName())) : ""), 1);
add(new Property(PROPERTY_PROJECT_JDK_BIN, projectJdk != null ? propertyRef(getJdkBinProperty(projectJdk.getName())) : ""));
add(new Property(PROPERTY_PROJECT_JDK_CLASSPATH, projectJdk != null ? getJdkPathId(projectJdk.getName()) : ""));
if (!genOptions.expandJarDirectories) {
add(new LibraryPatterns(project, genOptions));
}
add(new CompilerResourcePatterns(project));
if (genOptions.forceTargetJdk) {
createJdkGenerators(project);
}
LibraryDefinitionsGeneratorFactory factory = new LibraryDefinitionsGeneratorFactory((ProjectEx)project, genOptions);
final LibraryTablesRegistrar registrar = LibraryTablesRegistrar.getInstance();
final Generator projectLibs = factory.create(registrar.getLibraryTable(project), getProjectBaseDir(project),
CompilerBundle.message("generated.ant.build.project.libraries.comment"));
if (projectLibs != null) {
add(projectLibs);
}
final Generator globalLibs =
factory.create(registrar.getLibraryTable(), null, CompilerBundle.message("generated.ant.build.global.libraries.comment"));
if (globalLibs != null) {
add(globalLibs);
}
for (final LibraryTable table : registrar.getCustomLibraryTables()) {
if (table.getLibraries().length != 0) {
final Generator appServerLibs = factory.create(table, null, table.getPresentation().getDisplayName(true));
if (appServerLibs != null) {
add(appServerLibs);
}
}
}
final ChunkCustomCompilerExtension[] customCompilers = genOptions.getCustomCompilers();
if (genOptions.enableFormCompiler || customCompilers.length > 0) {
add(new Comment(CompilerBundle.message("generated.ant.build.custom.compilers.comment")));
Target register = new Target(TARGET_REGISTER_CUSTOM_COMPILERS, null, null, null);
if (genOptions.enableFormCompiler) {
//noinspection HardCodedStringLiteral
add(new Property(PROPERTY_JAVAC2_HOME, propertyRelativePath(PROPERTY_IDEA_HOME, "lib")));
Path javac2 = new Path(PROPERTY_JAVAC2_CLASSPATH_ID);
javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "javac2.jar")));
javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "jdom.jar")));
javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "asm.jar")));
javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "asm-commons.jar")));
javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "jgoodies-forms.jar")));
add(javac2);
//noinspection HardCodedStringLiteral
register.add(new Tag("taskdef", Pair.create("name", "javac2"), Pair.create("classname", "com.intellij.ant.Javac2"),
Pair.create("classpathref", PROPERTY_JAVAC2_CLASSPATH_ID)));
register.add(new Tag("taskdef", Pair.create("name", "instrumentIdeaExtensions"),
Pair.create("classname", "com.intellij.ant.InstrumentIdeaExtensions"),
Pair.create("classpathref", PROPERTY_JAVAC2_CLASSPATH_ID)));
}
if (customCompilers.length > 0) {
for (ChunkCustomCompilerExtension ext : customCompilers) {
ext.generateCustomCompilerTaskRegistration(project, genOptions, register);
}
}
add(register);
}
}
protected void createJdkGenerators(final Project project) {
final Sdk[] jdks = getUsedJdks(project);
if (jdks.length > 0) {
add(new Comment(CompilerBundle.message("generated.ant.build.jdk.definitions.comment")), 1);
for (final Sdk jdk : jdks) {
if (jdk.getHomeDirectory() == null) {
continue;
}
final SdkType sdkType = jdk.getSdkType();
if (!(sdkType instanceof JavaSdkType) || ((JavaSdkType)sdkType).getBinPath(jdk) == null) {
continue;
}
final File home = VfsUtil.virtualToIoFile(jdk.getHomeDirectory());
File homeDir;
try {
// use canonical path in order to resolve symlinks
homeDir = home.getCanonicalFile();
}
catch (IOException e) {
homeDir = home;
}
final String jdkName = jdk.getName();
final String jdkHomeProperty = getJdkHomeProperty(jdkName);
final FileSet fileSet = new FileSet(propertyRef(jdkHomeProperty));
final String[] urls = jdk.getRootProvider().getUrls(OrderRootType.CLASSES);
for (String url : urls) {
final String path = GenerationUtils.trimJarSeparator(VirtualFileManager.extractPath(url));
final File pathElement = new File(path);
final String relativePath = FileUtil.getRelativePath(homeDir, pathElement);
if (relativePath != null) {
fileSet.add(new Include(relativePath.replace(File.separatorChar, '/')));
}
}
final File binPath = toCanonicalFile(new File(((JavaSdkType)sdkType).getBinPath(jdk)));
final String relativePath = FileUtil.getRelativePath(homeDir, binPath);
if (relativePath != null) {
add(new Property(BuildProperties.getJdkBinProperty(jdkName),
propertyRef(jdkHomeProperty) + "/" + FileUtil.toSystemIndependentName(relativePath)), 1);
}
else {
add(new Property(BuildProperties.getJdkBinProperty(jdkName), FileUtil.toSystemIndependentName(binPath.getPath())), 1);
}
final Path jdkPath = new Path(getJdkPathId(jdkName));
jdkPath.add(fileSet);
add(jdkPath);
}
}
final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectJdk();
add(new Property(PROPERTY_PROJECT_JDK_HOME, projectJdk != null ? propertyRef(getJdkHomeProperty(projectJdk.getName())) : ""), 1);
add(new Property(PROPERTY_PROJECT_JDK_BIN, projectJdk != null ? propertyRef(getJdkBinProperty(projectJdk.getName())) : ""));
add(new Property(PROPERTY_PROJECT_JDK_CLASSPATH, projectJdk != null ? getJdkPathId(projectJdk.getName()) : ""));
}
}
@@ -61,8 +61,10 @@ public class ChunkBuild extends CompositeGenerator{
add(new Property(BuildProperties.getOutputPathForTestsProperty(chunk.getName()), location));
add(createBootclasspath(chunk), 1);
add(new ModuleChunkClasspath(chunk, genOptions, false), 1);
add(new ModuleChunkClasspath(chunk, genOptions, true), 1);
add(new ModuleChunkClasspath(chunk, genOptions, false, false), 1);
add(new ModuleChunkClasspath(chunk, genOptions, true, false), 1);
add(new ModuleChunkClasspath(chunk, genOptions, false, true), 1);
add(new ModuleChunkClasspath(chunk, genOptions, true, true), 1);
final ModuleChunkSourcepath moduleSources = new ModuleChunkSourcepath(project, chunk, genOptions);
add(moduleSources, 1);
@@ -33,173 +33,181 @@ import java.util.Map;
* Date: Mar 19, 2004
*/
public class CompileModuleChunkTarget extends CompositeGenerator {
private final Target myMainTarget;
private final Target myProductionTarget;
private final Target myTestsTarget;
public CompileModuleChunkTarget(final Project project,
ModuleChunk moduleChunk,
VirtualFile[] sourceRoots,
VirtualFile[] testSourceRoots,
File baseDir,
GenerationOptions genOptions) {
final String moduleChunkName = moduleChunk.getName();
//noinspection HardCodedStringLiteral
final Tag compilerArgs = new Tag("compilerarg", Pair.create("line", BuildProperties.propertyRef(
BuildProperties.getModuleChunkCompilerArgsProperty(moduleChunkName))));
//noinspection HardCodedStringLiteral
final Pair<String, String> classpathRef = Pair.create("refid", BuildProperties.getClasspathProperty(moduleChunkName));
final Tag classpathTag = new Tag("classpath", classpathRef);
//noinspection HardCodedStringLiteral
final Tag bootclasspathTag =
new Tag("bootclasspath", Pair.create("refid", BuildProperties.getBootClasspathProperty(moduleChunkName)));
final PatternSetRef compilerExcludes = new PatternSetRef(BuildProperties.getExcludedFromCompilationProperty(moduleChunkName));
public CompileModuleChunkTarget(final Project project,
ModuleChunk moduleChunk,
VirtualFile[] sourceRoots,
VirtualFile[] testSourceRoots,
File baseDir,
GenerationOptions genOptions) {
final String moduleChunkName = moduleChunk.getName();
//noinspection HardCodedStringLiteral
final Tag compilerArgs = new Tag("compilerarg", Pair.create("line", BuildProperties.propertyRef(
BuildProperties.getModuleChunkCompilerArgsProperty(moduleChunkName))));
//noinspection HardCodedStringLiteral
final Pair<String, String> classpathRef = Pair.create("refid", BuildProperties.getClasspathProperty(moduleChunkName));
final Tag classpathTag = new Tag("classpath", classpathRef);
//noinspection HardCodedStringLiteral
final Tag bootclasspathTag =
new Tag("bootclasspath", Pair.create("refid", BuildProperties.getBootClasspathProperty(moduleChunkName)));
final PatternSetRef compilerExcludes = new PatternSetRef(BuildProperties.getExcludedFromCompilationProperty(moduleChunkName));
final String mainTargetName = BuildProperties.getCompileTargetName(moduleChunkName);
final @NonNls String productionTargetName = mainTargetName + ".production";
final @NonNls String testsTargetName = mainTargetName + ".tests";
final String mainTargetName = BuildProperties.getCompileTargetName(moduleChunkName);
final @NonNls String productionTargetName = mainTargetName + ".production";
final @NonNls String testsTargetName = mainTargetName + ".tests";
final int modulesCount = moduleChunk.getModules().length;
myMainTarget = new Target(mainTargetName, productionTargetName + "," + testsTargetName,
CompilerBundle.message("generated.ant.build.compile.modules.main.target.comment", modulesCount,
moduleChunkName), null);
myProductionTarget = new Target(productionTargetName, getChunkDependenciesString(moduleChunk),
CompilerBundle.message("generated.ant.build.compile.modules.production.classes.target.comment",
modulesCount, moduleChunkName), null);
myTestsTarget = new Target(testsTargetName, productionTargetName,
CompilerBundle.message("generated.ant.build.compile.modules.tests.target.comment", modulesCount,
moduleChunkName), BuildProperties.PROPERTY_SKIP_TESTS);
final ChunkCustomCompilerExtension[] customCompilers = moduleChunk.getCustomCompilers();
final ChunkCustomCompilerExtension[] customCompilers = moduleChunk.getCustomCompilers();
final String customCompilersDependency = customCompilers.length != 0 || genOptions.enableFormCompiler ?
BuildProperties.TARGET_REGISTER_CUSTOM_COMPILERS : "";
final int modulesCount = moduleChunk.getModules().length;
Target mainTarget = new Target(mainTargetName, productionTargetName + "," + testsTargetName,
CompilerBundle.message("generated.ant.build.compile.modules.main.target.comment", modulesCount,
moduleChunkName), null);
String dependenciesProduction = getChunkDependenciesString(moduleChunk);
if (customCompilersDependency.length() > 0) {
if (dependenciesProduction != null && dependenciesProduction.length() > 0) {
dependenciesProduction = customCompilersDependency + "," + dependenciesProduction;
}
else {
dependenciesProduction = customCompilersDependency;
}
}
Target productionTarget = new Target(productionTargetName, dependenciesProduction,
CompilerBundle.message("generated.ant.build.compile.modules.production.classes.target.comment",
modulesCount, moduleChunkName), null);
String dependenciesTests = (customCompilersDependency.length() != 0 ? customCompilersDependency + "," : "") + productionTargetName;
Target testsTarget = new Target(testsTargetName, dependenciesTests,
CompilerBundle.message("generated.ant.build.compile.modules.tests.target.comment", modulesCount,
moduleChunkName), BuildProperties.PROPERTY_SKIP_TESTS);
if (sourceRoots.length > 0) {
final String outputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(moduleChunkName));
final Tag srcTag = new Tag("src", Pair.create("refid", BuildProperties.getSourcepathProperty(moduleChunkName)));
myProductionTarget.add(new Mkdir(outputPathRef));
createCustomCompilerTasks(project, moduleChunk, genOptions, false, customCompilers, compilerArgs, bootclasspathTag,
classpathTag, compilerExcludes, srcTag, outputPathRef);
if (customCompilers.length == 0 || genOptions.enableFormCompiler) {
final Javac javac = new Javac(genOptions, moduleChunk, outputPathRef);
javac.add(compilerArgs);
javac.add(bootclasspathTag);
javac.add(classpathTag);
//noinspection HardCodedStringLiteral
javac.add(srcTag);
javac.add(compilerExcludes);
myProductionTarget.add(javac);
}
myProductionTarget.add(createCopyTask(project, moduleChunk, sourceRoots, outputPathRef, baseDir, genOptions));
}
if (testSourceRoots.length > 0) {
final String testOutputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathForTestsProperty(moduleChunkName));
final Tag srcTag = new Tag("src", Pair.create("refid", BuildProperties.getTestSourcepathProperty(moduleChunkName)));
final Tag testClassPath = new Tag("classpath");
testClassPath.add(new Tag("path", classpathRef));
testClassPath.add(new PathElement(BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(moduleChunkName))));
myTestsTarget.add(new Mkdir(testOutputPathRef));
createCustomCompilerTasks(project, moduleChunk, genOptions, true, customCompilers, compilerArgs, bootclasspathTag,
testClassPath, compilerExcludes, srcTag, testOutputPathRef);
if (customCompilers.length == 0 || genOptions.enableFormCompiler) {
final Javac javac = new Javac(genOptions, moduleChunk, testOutputPathRef);
javac.add(compilerArgs);
javac.add(classpathTag);
//noinspection HardCodedStringLiteral
javac.add(testClassPath);
//noinspection HardCodedStringLiteral
javac.add(srcTag);
javac.add(compilerExcludes);
myTestsTarget.add(javac);
}
myTestsTarget.add(createCopyTask(project, moduleChunk, testSourceRoots, testOutputPathRef, baseDir, genOptions));
}
add(myMainTarget);
add(myProductionTarget, 1);
add(myTestsTarget, 1);
if (sourceRoots.length > 0) {
final String outputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(moduleChunkName));
final Tag srcTag = new Tag("src", Pair.create("refid", BuildProperties.getSourcepathProperty(moduleChunkName)));
productionTarget.add(new Mkdir(outputPathRef));
createCustomCompilerTasks(project, moduleChunk, genOptions, false, customCompilers, compilerArgs, bootclasspathTag,
classpathTag, compilerExcludes, srcTag, outputPathRef, productionTarget);
if (customCompilers.length == 0 || genOptions.enableFormCompiler) {
final Javac javac = new Javac(genOptions, moduleChunk, outputPathRef);
javac.add(compilerArgs);
javac.add(bootclasspathTag);
javac.add(classpathTag);
javac.add(srcTag);
javac.add(compilerExcludes);
productionTarget.add(javac);
}
productionTarget.add(createCopyTask(project, moduleChunk, sourceRoots, outputPathRef, baseDir, genOptions));
}
/**
* Create custom compiler tasks
*
* @param project the proejct
* @param moduleChunk the module chunkc
* @param genOptions generation options
* @param compileTests if true tests are being compiled
* @param customCompilers an array of custom compilers for this cunk
* @param compilerArgs the javac compilier arguements
* @param bootclasspathTag the boot classpath element for the javac compiler
* @param classpathTag the classpath tag for the javac compiler
* @param compilerExcludes the compiler excluded tag
* @param srcTag the soruce tag
* @param outputPathRef the output path references
*/
private void createCustomCompilerTasks(Project project,
ModuleChunk moduleChunk,
GenerationOptions genOptions,
boolean compileTests,
ChunkCustomCompilerExtension[] customCompilers,
Tag compilerArgs,
Tag bootclasspathTag,
Tag classpathTag,
PatternSetRef compilerExcludes,
Tag srcTag,
String outputPathRef) {
if (customCompilers.length > 1) {
myProductionTarget.add(new Tag("fail", Pair.create("message", CompilerBundle.message(
"generated.ant.build.compile.modules.fail.custom.comipilers"))));
}
for (ChunkCustomCompilerExtension ext : customCompilers) {
ext.generateCustomCompile(project, moduleChunk, genOptions, compileTests, myProductionTarget, compilerArgs, bootclasspathTag,
classpathTag, compilerExcludes, srcTag, outputPathRef);
}
if (testSourceRoots.length > 0) {
final String testOutputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathForTestsProperty(moduleChunkName));
final Tag srcTag = new Tag("src", Pair.create("refid", BuildProperties.getTestSourcepathProperty(moduleChunkName)));
final Pair<String, String> testClasspathRef = Pair.create("refid", BuildProperties.getTestClasspathProperty(moduleChunkName));
final Tag testClassPath = new Tag("classpath", testClasspathRef);
testsTarget.add(new Mkdir(testOutputPathRef));
createCustomCompilerTasks(project, moduleChunk, genOptions, true, customCompilers, compilerArgs, bootclasspathTag,
testClassPath, compilerExcludes, srcTag, testOutputPathRef, testsTarget);
if (customCompilers.length == 0 || genOptions.enableFormCompiler) {
final Javac javac = new Javac(genOptions, moduleChunk, testOutputPathRef);
javac.add(compilerArgs);
javac.add(bootclasspathTag);
javac.add(testClassPath);
javac.add(srcTag);
javac.add(compilerExcludes);
testsTarget.add(javac);
}
testsTarget.add(createCopyTask(project, moduleChunk, testSourceRoots, testOutputPathRef, baseDir, genOptions));
}
private String getChunkDependenciesString(ModuleChunk moduleChunk) {
final StringBuffer moduleDependencies = new StringBuffer();
final ModuleChunk[] dependencies = moduleChunk.getDependentChunks();
for (int idx = 0; idx < dependencies.length; idx++) {
final ModuleChunk dependency = dependencies[idx];
if (idx > 0) {
moduleDependencies.append(",");
}
moduleDependencies.append(BuildProperties.getCompileTargetName(dependency.getName()));
}
return moduleDependencies.toString();
}
add(mainTarget);
add(productionTarget, 1);
add(testsTarget, 1);
}
private static Generator createCopyTask(final Project project,
ModuleChunk chunk,
VirtualFile[] sourceRoots,
String toDir,
File baseDir,
final GenerationOptions genOptions) {
//noinspection HardCodedStringLiteral
final Tag filesSelector = new Tag("type", Pair.create("type", "file"));
final PatternSetRef excludes = CompilerExcludes.isAvailable(project) ? new PatternSetRef(
BuildProperties.getExcludedFromCompilationProperty(chunk.getName())) : null;
final PatternSetRef resourcePatternsPatternSet = new PatternSetRef(BuildProperties.PROPERTY_COMPILER_RESOURCE_PATTERNS);
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
final CompositeGenerator composite = new CompositeGenerator();
final Map<String, Copy> outputDirToTaskMap = new HashMap<String, Copy>();
for (final VirtualFile root : sourceRoots) {
final String packagePrefix = fileIndex.getPackageNameByDirectory(root);
final String targetDir =
packagePrefix != null && packagePrefix.length() > 0 ? toDir + "/" + packagePrefix.replace('.', '/') : toDir;
Copy copy = outputDirToTaskMap.get(targetDir);
if (copy == null) {
copy = new Copy(targetDir);
outputDirToTaskMap.put(targetDir, copy);
composite.add(copy);
}
final FileSet fileSet = new FileSet(
GenerationUtils.toRelativePath(root, baseDir, BuildProperties.getModuleChunkBasedirProperty(chunk), genOptions));
fileSet.add(resourcePatternsPatternSet);
fileSet.add(filesSelector);
if (excludes != null) {
fileSet.add(excludes);
}
copy.add(fileSet);
}
return composite;
/**
* Create custom compiler tasks
*
* @param project the project
* @param moduleChunk the module chunk
* @param genOptions generation options
* @param compileTests if true tests are being compiled
* @param customCompilers an array of custom compilers for this chunk
* @param compilerArgs the javac compiler arguments
* @param bootclasspathTag the boot classpath element for the javac compiler
* @param classpathTag the classpath tag for the javac compiler
* @param compilerExcludes the compiler excluded tag
* @param srcTag the source tag
* @param outputPathRef the output path references
* @param target the target where to add custom compiler
*/
private static void createCustomCompilerTasks(Project project,
ModuleChunk moduleChunk,
GenerationOptions genOptions,
boolean compileTests,
ChunkCustomCompilerExtension[] customCompilers,
Tag compilerArgs,
Tag bootclasspathTag,
Tag classpathTag,
PatternSetRef compilerExcludes,
Tag srcTag,
String outputPathRef,
Target target) {
if (customCompilers.length > 1) {
target.add(new Tag("fail", Pair.create("message", CompilerBundle.message(
"generated.ant.build.compile.modules.fail.custom.compilers"))));
}
for (ChunkCustomCompilerExtension ext : customCompilers) {
ext.generateCustomCompile(project, moduleChunk, genOptions, compileTests, target, compilerArgs, bootclasspathTag,
classpathTag, compilerExcludes, srcTag, outputPathRef);
}
}
private static String getChunkDependenciesString(ModuleChunk moduleChunk) {
final StringBuffer moduleDependencies = new StringBuffer();
final ModuleChunk[] dependencies = moduleChunk.getDependentChunks();
for (int idx = 0; idx < dependencies.length; idx++) {
final ModuleChunk dependency = dependencies[idx];
if (idx > 0) {
moduleDependencies.append(",");
}
moduleDependencies.append(BuildProperties.getCompileTargetName(dependency.getName()));
}
return moduleDependencies.toString();
}
private static Generator createCopyTask(final Project project,
ModuleChunk chunk,
VirtualFile[] sourceRoots,
String toDir,
File baseDir,
final GenerationOptions genOptions) {
//noinspection HardCodedStringLiteral
final Tag filesSelector = new Tag("type", Pair.create("type", "file"));
final PatternSetRef excludes = CompilerExcludes.isAvailable(project) ? new PatternSetRef(
BuildProperties.getExcludedFromCompilationProperty(chunk.getName())) : null;
final PatternSetRef resourcePatternsPatternSet = new PatternSetRef(BuildProperties.PROPERTY_COMPILER_RESOURCE_PATTERNS);
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
final CompositeGenerator composite = new CompositeGenerator();
final Map<String, Copy> outputDirToTaskMap = new HashMap<String, Copy>();
for (final VirtualFile root : sourceRoots) {
final String packagePrefix = fileIndex.getPackageNameByDirectory(root);
final String targetDir =
packagePrefix != null && packagePrefix.length() > 0 ? toDir + "/" + packagePrefix.replace('.', '/') : toDir;
Copy copy = outputDirToTaskMap.get(targetDir);
if (copy == null) {
copy = new Copy(targetDir);
outputDirToTaskMap.put(targetDir, copy);
composite.add(copy);
}
final FileSet fileSet = new FileSet(
GenerationUtils.toRelativePath(root, baseDir, BuildProperties.getModuleChunkBasedirProperty(chunk), genOptions));
fileSet.add(resourcePatternsPatternSet);
fileSet.add(filesSelector);
if (excludes != null) {
fileSet.add(excludes);
}
copy.add(fileSet);
}
return composite;
}
}
@@ -45,12 +45,14 @@ public class ModuleChunkClasspath extends Path {
* @param chunk a chunk to process
* @param genOptions a generation options
* @param generateRuntimeClasspath if true, runtime classpath is being generated. Otherwise a compile time classpath is constructed
* @param generateTestClasspath if true, a test classpath is generated.
*/
@SuppressWarnings({"unchecked"})
public ModuleChunkClasspath(final ModuleChunk chunk, final GenerationOptions genOptions, final boolean generateRuntimeClasspath) {
super(generateRuntimeClasspath
? BuildProperties.getRuntimeClasspathProperty(chunk.getName())
: BuildProperties.getClasspathProperty(chunk.getName()));
public ModuleChunkClasspath(final ModuleChunk chunk,
final GenerationOptions genOptions,
final boolean generateRuntimeClasspath,
final boolean generateTestClasspath) {
super(generateClasspathName(chunk, generateRuntimeClasspath, generateTestClasspath));
final OrderedSet<ClasspathItem> pathItems =
new OrderedSet<ClasspathItem>((TObjectHashingStrategy<ClasspathItem>)TObjectHashingStrategy.CANONICAL);
@@ -87,6 +89,28 @@ public class ModuleChunkClasspath extends Path {
if (!orderEntry.isValid()) {
continue;
}
if (orderEntry instanceof ExportableOrderEntry) {
ExportableOrderEntry e = (ExportableOrderEntry)orderEntry;
switch (e.getScope()) {
case COMPILE:
break;
case PROVIDED:
if (generateRuntimeClasspath && !generateTestClasspath) {
continue;
}
break;
case RUNTIME:
if (!generateRuntimeClasspath) {
continue;
}
break;
case TEST:
if (!generateTestClasspath) {
continue;
}
break;
}
}
if (!generateRuntimeClasspath) {
// needed for compilation classpath only
if ((orderEntry instanceof ModuleSourceOrderEntry)) {
@@ -122,7 +146,9 @@ public class ModuleChunkClasspath extends Path {
if (!processedChunks.contains(depChunk)) {
// chunk references are included in the runtime classpath only once
processedChunks.add(depChunk);
pathItems.add(new PathRefItem(BuildProperties.getRuntimeClasspathProperty(depChunk.getName())));
String property = generateTestClasspath ? BuildProperties.getTestRuntimeClasspathProperty(depChunk.getName())
: BuildProperties.getRuntimeClasspathProperty(depChunk.getName());
pathItems.add(new PathRefItem(property));
}
}
else {
@@ -145,9 +171,10 @@ public class ModuleChunkClasspath extends Path {
pathItems.add(new PathRefItem(BuildProperties.getLibraryPathId(libraryName)));
}
}
else {
else if (orderEntry instanceof ModuleSourceOrderEntry) {
// Module source entry?
for (String url : getCompilationClasses(orderEntry, ((GenerationOptionsImpl)genOptions), generateRuntimeClasspath)) {
for (String url : getCompilationClasses(orderEntry, ((GenerationOptionsImpl)genOptions), generateRuntimeClasspath,
generateTestClasspath, dependencyLevel == 0)) {
if (url.endsWith(JarFileSystem.JAR_SEPARATOR)) {
url = url.substring(0, url.length() - JarFileSystem.JAR_SEPARATOR.length());
}
@@ -162,6 +189,11 @@ public class ModuleChunkClasspath extends Path {
}
}
}
else {
// Unknown order entry type. If it is actually encountered, extension point should be implemented
pathItems.add(new GeneratorItem(orderEntry.getClass().getName(),
new Comment("Unknown OrderEntryType: " + orderEntry.getClass().getName())));
}
}
}
}.processModule(module, 0, false);
@@ -172,16 +204,45 @@ public class ModuleChunkClasspath extends Path {
}
}
/**
* Generate classpath name
*
* @param chunk a chunk
* @param generateRuntimeClasspath
* @param generateTestClasspath
* @return a name for the classpath
*/
private static String generateClasspathName(ModuleChunk chunk, boolean generateRuntimeClasspath, boolean generateTestClasspath) {
if (generateTestClasspath) {
return generateRuntimeClasspath
? BuildProperties.getTestRuntimeClasspathProperty(chunk.getName())
: BuildProperties.getTestClasspathProperty(chunk.getName());
}
else {
return generateRuntimeClasspath
? BuildProperties.getRuntimeClasspathProperty(chunk.getName())
: BuildProperties.getClasspathProperty(chunk.getName());
}
}
private static String[] getCompilationClasses(final OrderEntry orderEntry,
final GenerationOptionsImpl options,
final boolean forRuntime) {
final boolean forRuntime,
final boolean forTest,
final boolean firstLevel) {
if (!forRuntime) {
return orderEntry.getUrls(OrderRootType.COMPILATION_CLASSES);
if (forTest) {
return orderEntry.getUrls(firstLevel ? OrderRootType.PRODUCTION_COMPILATION_CLASSES : OrderRootType.COMPILATION_CLASSES);
}
else {
return firstLevel ? new String[0] : orderEntry.getUrls(OrderRootType.PRODUCTION_COMPILATION_CLASSES);
}
}
final Set<String> jdkUrls = options.getAllJdkUrls();
final OrderedSet<String> urls = new OrderedSet<String>();
urls.addAll(Arrays.asList(orderEntry.getUrls(OrderRootType.CLASSES_AND_OUTPUT)));
urls.addAll(Arrays.asList(orderEntry.getUrls(forTest ? OrderRootType.COMPILATION_CLASSES
: OrderRootType.PRODUCTION_COMPILATION_CLASSES)));
urls.removeAll(jdkUrls);
return ArrayUtil.toStringArray(urls);
}
@@ -35,231 +35,242 @@ import java.util.HashSet;
import java.util.Set;
public abstract class BuildProperties extends CompositeGenerator {
public static final @NonNls String TARGET_ALL = "all";
public static final @NonNls String TARGET_BUILD_MODULES = "build.modules";
public static final @NonNls String TARGET_CLEAN = "clean";
public static final @NonNls String TARGET_INIT = "init";
public static final @NonNls String DEFAULT_TARGET = TARGET_ALL;
public static final @NonNls String PROPERTY_COMPILER_NAME = "compiler.name";
public static final @NonNls String PROPERTY_COMPILER_ADDITIONAL_ARGS = "compiler.args";
public static final @NonNls String PROPERTY_COMPILER_MAX_MEMORY = "compiler.max.memory";
public static final @NonNls String PROPERTY_COMPILER_EXCLUDES = "compiler.excluded";
public static final @NonNls String PROPERTY_COMPILER_RESOURCE_PATTERNS = "compiler.resources";
public static final @NonNls String PROPERTY_IGNORED_FILES = "ignored.files";
public static final @NonNls String PROPERTY_COMPILER_GENERATE_DEBUG_INFO = "compiler.debug";
public static final @NonNls String PROPERTY_COMPILER_GENERATE_NO_WARNINGS = "compiler.generate.no.warnings";
public static final @NonNls String PROPERTY_PROJECT_JDK_HOME = "project.jdk.home";
public static final @NonNls String PROPERTY_PROJECT_JDK_BIN = "project.jdk.bin";
public static final @NonNls String PROPERTY_PROJECT_JDK_CLASSPATH = "project.jdk.classpath";
public static final @NonNls String PROPERTY_SKIP_TESTS = "skip.tests";
public static final @NonNls String PROPERTY_LIBRARIES_PATTERNS = "library.patterns";
public static final @NonNls String PROPERTY_IDEA_HOME = "idea.home";
public static final @NonNls String PROPERTY_JAVAC2_HOME = "javac2.home";
public static final @NonNls String PROPERTY_JAVAC2_CLASSPATH_ID = "javac2.classpath";
public static final @NonNls String TARGET_ALL = "all";
public static final @NonNls String TARGET_BUILD_MODULES = "build.modules";
public static final @NonNls String TARGET_CLEAN = "clean";
public static final @NonNls String TARGET_INIT = "init";
public static final @NonNls String TARGET_REGISTER_CUSTOM_COMPILERS = "register.custom.compilers";
public static final @NonNls String DEFAULT_TARGET = TARGET_ALL;
public static final @NonNls String PROPERTY_COMPILER_NAME = "compiler.name";
public static final @NonNls String PROPERTY_COMPILER_ADDITIONAL_ARGS = "compiler.args";
public static final @NonNls String PROPERTY_COMPILER_MAX_MEMORY = "compiler.max.memory";
public static final @NonNls String PROPERTY_COMPILER_EXCLUDES = "compiler.excluded";
public static final @NonNls String PROPERTY_COMPILER_RESOURCE_PATTERNS = "compiler.resources";
public static final @NonNls String PROPERTY_IGNORED_FILES = "ignored.files";
public static final @NonNls String PROPERTY_COMPILER_GENERATE_DEBUG_INFO = "compiler.debug";
public static final @NonNls String PROPERTY_COMPILER_GENERATE_NO_WARNINGS = "compiler.generate.no.warnings";
public static final @NonNls String PROPERTY_PROJECT_JDK_HOME = "project.jdk.home";
public static final @NonNls String PROPERTY_PROJECT_JDK_BIN = "project.jdk.bin";
public static final @NonNls String PROPERTY_PROJECT_JDK_CLASSPATH = "project.jdk.classpath";
public static final @NonNls String PROPERTY_SKIP_TESTS = "skip.tests";
public static final @NonNls String PROPERTY_LIBRARIES_PATTERNS = "library.patterns";
public static final @NonNls String PROPERTY_IDEA_HOME = "idea.home";
public static final @NonNls String PROPERTY_JAVAC2_HOME = "javac2.home";
public static final @NonNls String PROPERTY_JAVAC2_CLASSPATH_ID = "javac2.classpath";
protected abstract void createJdkGenerators(Project project);
protected abstract void createJdkGenerators(Project project);
public static Sdk[] getUsedJdks(Project project) {
final Set<Sdk> jdks = new HashSet<Sdk>();
Module[] modules = ModuleManager.getInstance(project).getModules();
for (Module module : modules) {
Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
if (jdk != null) {
jdks.add(jdk);
}
}
return jdks.toArray(new Sdk[jdks.size()]);
public static Sdk[] getUsedJdks(Project project) {
final Set<Sdk> jdks = new HashSet<Sdk>();
Module[] modules = ModuleManager.getInstance(project).getModules();
for (Module module : modules) {
Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
if (jdk != null) {
jdks.add(jdk);
}
}
return jdks.toArray(new Sdk[jdks.size()]);
}
@NonNls
public static String getPropertyFileName(Project project) {
return getProjectBuildFileName(project) + ".properties";
@NonNls
public static String getPropertyFileName(Project project) {
return getProjectBuildFileName(project) + ".properties";
}
@NonNls
public static String getJdkPathId(@NonNls final String jdkName) {
return "jdk.classpath." + convertName(jdkName);
}
@NonNls
public static String getModuleChunkJdkClasspathProperty(@NonNls final String moduleChunkName) {
return "module.jdk.classpath." + convertName(moduleChunkName);
}
@NonNls
public static String getModuleChunkJdkHomeProperty(@NonNls final String moduleChunkName) {
return "module.jdk.home." + convertName(moduleChunkName);
}
@NonNls
public static String getModuleChunkJdkBinProperty(@NonNls final String moduleChunkName) {
return "module.jdk.bin." + convertName(moduleChunkName);
}
@NonNls
public static String getModuleChunkCompilerArgsProperty(@NonNls final String moduleName) {
return "compiler.args." + convertName(moduleName);
}
@NonNls
public static String getLibraryPathId(@NonNls final String libraryName) {
return "library." + convertName(libraryName) + ".classpath";
}
@NonNls
public static String getJdkHomeProperty(@NonNls final String jdkName) {
return "jdk.home." + convertName(jdkName);
}
@NonNls
public static String getJdkBinProperty(@NonNls final String jdkName) {
return "jdk.bin." + convertName(jdkName);
}
@NonNls
public static String getCompileTargetName(@NonNls String moduleName) {
return "compile.module." + convertName(moduleName);
}
@NonNls
public static String getOutputPathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".output.dir";
}
@NonNls
public static String getOutputPathForTestsProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".testoutput.dir";
}
@NonNls
public static String getClasspathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".module.production.classpath";
}
@NonNls
public static String getTestClasspathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".module.classpath";
}
@NonNls
public static String getRuntimeClasspathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".runtime.production.module.classpath";
}
@NonNls
public static String getTestRuntimeClasspathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".runtime.module.classpath";
}
@NonNls
public static String getBootClasspathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".module.bootclasspath";
}
@NonNls
public static String getSourcepathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".module.sourcepath";
}
@NonNls
public static String getTestSourcepathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".module.test.sourcepath";
}
@NonNls
public static String getExcludedFromModuleProperty(@NonNls String moduleName) {
return "excluded.from.module." + convertName(moduleName);
}
@NonNls
public static String getExcludedFromCompilationProperty(@NonNls String moduleName) {
return "excluded.from.compilation." + convertName(moduleName);
}
@NonNls
public static String getProjectBuildFileName(Project project) {
return convertName(project.getName());
}
@NonNls
public static String getModuleChunkBuildFileName(final ModuleChunk chunk) {
return "module_" + convertName(chunk.getName());
}
@NonNls
public static String getModuleCleanTargetName(@NonNls String moduleName) {
return "clean.module." + convertName(moduleName);
}
@NonNls
public static String getModuleChunkBasedirProperty(ModuleChunk chunk) {
return "module." + convertName(chunk.getName()) + ".basedir";
}
/**
* left for compatibility
*
* @param module the module to get property for
* @return name of the property
*/
@NonNls
public static String getModuleBasedirProperty(Module module) {
return "module." + convertName(module.getName()) + ".basedir";
}
@NonNls
public static String getProjectBaseDirProperty() {
return "basedir";
}
public static File getModuleChunkBaseDir(ModuleChunk chunk) {
return chunk.getBaseDir();
}
public static File getProjectBaseDir(final Project project) {
final VirtualFile baseDir = project.getBaseDir();
assert baseDir != null;
return VfsUtil.virtualToIoFile(baseDir);
}
/**
* Convert name. All double quotes are removed and spaces are replaced with underscore.
*
* @param name a name to convert
* @return a converted name
*/
@NonNls
public static String convertName(@NonNls final String name) {
//noinspection HardCodedStringLiteral
return name.replaceAll("\"", "").replaceAll("\\s+", "_").toLowerCase();
}
@NonNls
public static String getPathMacroProperty(@NonNls String pathMacro) {
return "path.variable." + convertName(pathMacro);
}
@NonNls
public static String propertyRef(@NonNls String propertyName) {
return "${" + propertyName + "}";
}
/**
* Construct path relative to the specified property
*
* @param propertyName the property name
* @param relativePath the relative path
* @return the path relative to the property
*/
@NonNls
public static String propertyRelativePath(@NonNls String propertyName, @NonNls String relativePath) {
return "${" + propertyName + "}/" + relativePath;
}
public static File toCanonicalFile(final File file) {
File canonicalFile;
try {
canonicalFile = file.getCanonicalFile();
}
@NonNls
public static String getJdkPathId(@NonNls final String jdkName) {
return "jdk.classpath." + convertName(jdkName);
catch (IOException e) {
canonicalFile = file;
}
return canonicalFile;
}
@NonNls
public static String getModuleChunkJdkClasspathProperty(@NonNls final String moduleChunkName) {
return "module.jdk.classpath." + convertName(moduleChunkName);
}
@NonNls
public static String getModuleChunkJdkHomeProperty(@NonNls final String moduleChunkName) {
return "module.jdk.home." + convertName(moduleChunkName);
}
@NonNls
public static String getModuleChunkJdkBinProperty(@NonNls final String moduleChunkName) {
return "module.jdk.bin." + convertName(moduleChunkName);
}
@NonNls
public static String getModuleChunkCompilerArgsProperty(@NonNls final String moduleName) {
return "compiler.args." + convertName(moduleName);
}
@NonNls
public static String getLibraryPathId(@NonNls final String libraryName) {
return "library." + convertName(libraryName) + ".classpath";
}
@NonNls
public static String getJdkHomeProperty(@NonNls final String jdkName) {
return "jdk.home." + convertName(jdkName);
}
@NonNls
public static String getJdkBinProperty(@NonNls final String jdkName) {
return "jdk.bin." + convertName(jdkName);
}
@NonNls
public static String getCompileTargetName(@NonNls String moduleName) {
return "compile.module." + convertName(moduleName);
}
@NonNls
public static String getOutputPathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".output.dir";
}
@NonNls
public static String getOutputPathForTestsProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".testoutput.dir";
}
@NonNls
public static String getClasspathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".module.classpath";
}
@NonNls
public static String getRuntimeClasspathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".runtime.module.classpath";
}
@NonNls
public static String getBootClasspathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".module.bootclasspath";
}
@NonNls
public static String getSourcepathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".module.sourcepath";
}
@NonNls
public static String getTestSourcepathProperty(@NonNls String moduleName) {
return convertName(moduleName) + ".module.test.sourcepath";
}
@NonNls
public static String getExcludedFromModuleProperty(@NonNls String moduleName) {
return "excluded.from.module." + convertName(moduleName);
}
@NonNls
public static String getExcludedFromCompilationProperty(@NonNls String moduleName) {
return "excluded.from.compilation." + convertName(moduleName);
}
@NonNls
public static String getProjectBuildFileName(Project project) {
return convertName(project.getName());
}
@NonNls
public static String getModuleChunkBuildFileName(final ModuleChunk chunk) {
return "module_" + convertName(chunk.getName());
}
@NonNls
public static String getModuleCleanTargetName(@NonNls String moduleName) {
return "clean.module." + convertName(moduleName);
}
@NonNls
public static String getModuleChunkBasedirProperty(ModuleChunk chunk) {
return "module." + convertName(chunk.getName()) + ".basedir";
}
/**
* left for compatibility
*
* @param module the module to get property for
* @return name of the property
*/
@NonNls
public static String getModuleBasedirProperty(Module module) {
return "module." + convertName(module.getName()) + ".basedir";
}
@NonNls
public static String getProjectBaseDirProperty() {
return "basedir";
}
public static File getModuleChunkBaseDir(ModuleChunk chunk) {
return chunk.getBaseDir();
}
public static File getProjectBaseDir(final Project project) {
final VirtualFile baseDir = project.getBaseDir();
assert baseDir != null;
return VfsUtil.virtualToIoFile(baseDir);
}
/**
* Convert name. All double quotes are removed and spaces are replaced with underscore.
*
* @param name a name to convert
* @return a converted name
*/
@NonNls
public static String convertName(@NonNls final String name) {
//noinspection HardCodedStringLiteral
return name.replaceAll("\"", "").replaceAll("\\s+", "_").toLowerCase();
}
@NonNls
public static String getPathMacroProperty(@NonNls String pathMacro) {
return "path.variable." + convertName(pathMacro);
}
@NonNls
public static String propertyRef(@NonNls String propertyName) {
return "${" + propertyName + "}";
}
/**
* Construct path relative to the specified property
*
* @param propertyName the property name
* @param relativePath the relative path
* @return the path relative to the property
*/
@NonNls
public static String propertyRelativePath(@NonNls String propertyName, @NonNls String relativePath) {
return "${" + propertyName + "}/" + relativePath;
}
public static File toCanonicalFile(final File file) {
File canonicalFile;
try {
canonicalFile = file.getCanonicalFile();
}
catch (IOException e) {
canonicalFile = file;
}
return canonicalFile;
}
@NonNls
public static String getTempDirForModuleProperty(@NonNls String moduleName) {
return "tmp.dir." + convertName(moduleName);
}
}
@NonNls
public static String getTempDirForModuleProperty(@NonNls String moduleName) {
return "tmp.dir." + convertName(moduleName);
}
}
@@ -67,7 +67,6 @@ public class GenerationUtils {
* @param baseDir base director for relative path calculation
* @param baseDirPropertyName property name for the base directory
* @param genOptions generation options
* @param useAbsolutePathsForOuterPaths if true absolute paths will be used for outer paths.
* @return a relative path
*/
@Nullable
@@ -87,6 +86,9 @@ public class GenerationUtils {
@NonNls final String baseDirPropertyName,
GenerationOptions genOptions) {
path = normalizePath(path);
if(path.length() == 0) {
return path;
}
final String substitutedPath = genOptions.subsitutePathWithMacros(path);
if (!substitutedPath.equals(path)) {
// path variable substitution has highest priority
@@ -103,12 +105,9 @@ public class GenerationUtils {
}
final String relativepath = FileUtil.getRelativePath(base, new File(path));
if (relativepath != null) {
final boolean shouldUseAbsolutePath = relativepath.indexOf("..") >= 0;
if (!shouldUseAbsolutePath) {
final String _relativePath = relativepath.replace(File.separatorChar, '/');
final String root = BuildProperties.propertyRef(baseDirPropertyName);
return ".".equals(_relativePath) ? root : root + "/" + _relativePath;
}
final String _relativePath = relativepath.replace(File.separatorChar, '/');
final String root = BuildProperties.propertyRef(baseDirPropertyName);
return ".".equals(_relativePath) ? root : root + "/" + _relativePath;
}
}
return substitutedPath;
@@ -55,8 +55,8 @@ import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessListener;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.runners.ExecutionUtil;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -137,7 +137,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
protected CompoundPositionManager myPositionManager = null;
private volatile DebuggerManagerThreadImpl myDebuggerManagerThread;
private final HashMap myUserData = new HashMap();
private static final int LOCAL_START_TIMEOUT = 15000;
private static final int LOCAL_START_TIMEOUT = 30000;
private final Semaphore myWaitFor = new Semaphore();
private final AtomicBoolean myBreakpointsMuted = new AtomicBoolean(false);
@@ -111,7 +111,7 @@ class ReloadClassesWorker {
final BreakpointManager breakpointManager = (DebuggerManagerEx.getInstanceEx(project)).getBreakpointManager();
breakpointManager.disableBreakpoints(debugProcess);
virtualMachineProxy.suspend();
//virtualMachineProxy.suspend();
try {
final Map<ReferenceType, byte[]> redefineMap = new HashMap<ReferenceType,byte[]>();
@@ -192,12 +192,12 @@ class ReloadClassesWorker {
catch (Exception e) {
processException(e);
}
try {
virtualMachineProxy.resume();
}
catch (Exception e) {
processException(e);
}
//try {
// virtualMachineProxy.resume();
//}
//catch (Exception e) {
// processException(e);
//}
}
public Priority getPriority() {
@@ -28,10 +28,8 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiClassUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.containers.Convertor;
import gnu.trove.THashSet;
import junit.runner.BaseTestRunner;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@@ -40,10 +38,12 @@ import org.junit.runners.Parameterized;
import java.util.*;
@SuppressWarnings({"UtilityClassWithoutPrivateConstructor"})
public class JUnitUtil {
@NonNls private static final String TESTCASE_CLASS = "junit.framework.TestCase";
@NonNls private static final String TEST_INTERFACE = "junit.framework.Test";
@NonNls private static final String TESTSUITE_CLASS = "junit.framework.TestSuite";
@NonNls private static final String TEST_ANNOTATION = "org.junit.Test";
@NonNls public static final String RUN_WITH = "org.junit.runner.RunWith";
public static boolean isSuiteMethod(final PsiMethod psiMethod) {
@@ -91,34 +91,28 @@ public class JUnitUtil {
/**
*
* @param aClassLocation
* @return true iff aClassLocation can be used as JUnit test class.
* @return true if aClassLocation can be used as JUnit test class.
*/
private static boolean isTestClass(final Location<? extends PsiClass> aClassLocation) {
return isTestClass(aClassLocation.getPsiElement());
}
public static boolean isTestClass(final PsiClass psiClass) {
return isTestClass(psiClass, true, null, true);
return isTestClass(psiClass, true, true);
}
private static boolean isTestClass(final PsiClass psiClass, boolean checkAbstract, @Nullable Set<PsiClass> visited, boolean checkForTestCaseInheritance) {
private static boolean isTestClass(final PsiClass psiClass, boolean checkAbstract, boolean checkForTestCaseInheritance) {
if (!PsiClassUtil.isRunnableClass(psiClass, true, checkAbstract)) return false;
if (checkForTestCaseInheritance && isTestCaseInheritor(psiClass)) return true;
final PsiModifierList modifierList = psiClass.getModifierList();
if (modifierList == null) return false;
if (AnnotationUtil.isAnnotated(psiClass, RUN_WITH, true)) return true;
for (final PsiMethod method : psiClass.getMethods()) {
for (final PsiMethod method : psiClass.getAllMethods()) {
if (isSuiteMethod(method)) return true;
if (isTestAnnotated(method)) return true;
}
PsiClass superClass = psiClass.getSuperClass();
if (superClass != null && !"java.lang.Object".equals(superClass.getQualifiedName()) && !superClass.isInterface()) {
if (visited != null && visited.contains(psiClass)) return false;
if (visited == null) visited = new THashSet<PsiClass>();
visited.add(psiClass);
return isTestClass(superClass, false, visited, false);
}
return false;
}
@@ -127,29 +121,24 @@ public class JUnitUtil {
}
public static boolean isJUnit4TestClass(final PsiClass psiClass) {
return isJUnit4TestClass(psiClass, true,null);
return isJUnit4TestClass(psiClass, true);
}
private static boolean isJUnit4TestClass(final PsiClass psiClass, boolean checkAbstract, @Nullable Set<PsiClass> visited) {
private static boolean isJUnit4TestClass(final PsiClass psiClass, boolean checkAbstract) {
if (!PsiClassUtil.isRunnableClass(psiClass, true, checkAbstract)) return false;
final PsiModifierList modifierList = psiClass.getModifierList();
if (modifierList == null) return false;
if (AnnotationUtil.isAnnotated(psiClass, RUN_WITH, true)) return true;
for (final PsiMethod method : psiClass.getMethods()) {
for (final PsiMethod method : psiClass.getAllMethods()) {
if (isTestAnnotated(method)) return true;
}
PsiClass superClass = psiClass.getSuperClass();
if (superClass != null && !"java.lang.Object".equals(superClass.getQualifiedName()) && !superClass.isInterface()) {
if (visited != null && visited.contains(psiClass)) return false;
if (visited == null) visited = new THashSet<PsiClass>();
visited.add(psiClass);
return isJUnit4TestClass(superClass, false, visited);
}
return false;
}
public static boolean isTestAnnotated(final PsiMethod method) {
if (AnnotationUtil.isAnnotated(method, "org.junit.Test", false)) {
if (AnnotationUtil.isAnnotated(method, TEST_ANNOTATION, false)) {
final PsiAnnotation annotation = AnnotationUtil.findAnnotationInHierarchy(method.getContainingClass(), Collections.singleton(RUN_WITH));
if (annotation != null) {
final PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
@@ -34,5 +34,6 @@ public class JavaCodeFoldingOptionsProvider extends BeanConfigurable<JavaCodeFol
checkBox("COLLAPSE_CLOSURES", ApplicationBundle.message("checkbox.collapse.closures"));
checkBox("COLLAPSE_CONSTRUCTOR_GENERIC_PARAMETERS", ApplicationBundle.message("checkbox.collapse.generic.constructor.parameters"));
checkBox("COLLAPSE_I18N_MESSAGES", ApplicationBundle.message("checkbox.collapse.i18n.messages"));
checkBox("COLLAPSE_SUPPRESS_WARNINGS", ApplicationBundle.message("checkbox.collapse.suppress.warnings"));
}
}
@@ -0,0 +1,97 @@
/*
* 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.
*/
/*
* User: anna
* Date: 25-May-2010
*/
package com.intellij.codeInsight.daemon.impl.actions;
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
import com.intellij.lang.ASTNode;
import com.intellij.lang.folding.FoldingBuilderEx;
import com.intellij.lang.folding.FoldingDescriptor;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class SuppressWarningsFoldingBuilder extends FoldingBuilderEx {
@NotNull
@Override
public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) {
if (!(root instanceof PsiJavaFile) || quick || !JavaCodeFoldingSettings.getInstance().isCollapseSuppressWarnings()) {
return FoldingDescriptor.EMPTY;
}
if (!PsiUtil.isLanguageLevel5OrHigher(root)) {
return FoldingDescriptor.EMPTY;
}
final List<FoldingDescriptor> result = new ArrayList<FoldingDescriptor>();
root.accept(new JavaRecursiveElementWalkingVisitor(){
@Override
public void visitAnnotation(PsiAnnotation annotation) {
if (Comparing.strEqual(annotation.getQualifiedName(), SuppressWarnings.class.getName())) {
result.add(new FoldingDescriptor(annotation, annotation.getTextRange()));
}
super.visitAnnotation(annotation);
}
});
return result.toArray(new FoldingDescriptor[result.size()]);
}
@Override
public String getPlaceholderText(@NotNull ASTNode node) {
final PsiElement element = node.getPsi();
if (element instanceof PsiAnnotation) {
return "/" + StringUtil.join(((PsiAnnotation)element).getParameterList().getAttributes(), new Function<PsiNameValuePair, String>() {
public String fun(PsiNameValuePair value) {
return getMemberValueText(value.getValue());
}
}, ", ") + "/";
}
return element.getText();
}
private static String getMemberValueText(PsiAnnotationMemberValue memberValue) {
if (memberValue instanceof PsiArrayInitializerMemberValue) {
final PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)memberValue).getInitializers();
return StringUtil.join(initializers, new Function<PsiAnnotationMemberValue, String>() {
public String fun(PsiAnnotationMemberValue psiAnnotationMemberValue) {
return getMemberValueText(psiAnnotationMemberValue);
}
}, ", ");
}
if (memberValue instanceof PsiLiteral) {
final Object o = ((PsiLiteral)memberValue).getValue();
if (o != null) {
return o.toString();
}
}
return memberValue.getText();
}
@Override
public boolean isCollapsedByDefault(@NotNull ASTNode node) {
return JavaCodeFoldingSettings.getInstance().isCollapseSuppressWarnings();
}
}
@@ -315,16 +315,14 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
}
@Override public void visitDocTagValue(PsiDocTagValue value) {
if (value.getReference() != null) {
PsiReference reference = value.getReference();
if (reference != null) {
PsiElement element = reference.resolve();
if (element instanceof PsiMethod) {
myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod)element, ((PsiDocMethodOrFieldRef)value).getNameElement(), false));
}
else if (element instanceof PsiParameter) {
myHolder.add(HighlightNamesUtil.highlightVariable((PsiVariable)element, value.getNavigationElement()));
}
PsiReference reference = value.getReference();
if (reference != null) {
PsiElement element = reference.resolve();
if (element instanceof PsiMethod) {
myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod)element, ((PsiDocMethodOrFieldRef)value).getNameElement(), false));
}
else if (element instanceof PsiParameter) {
myHolder.add(HighlightNamesUtil.highlightVariable((PsiVariable)element, value.getNavigationElement()));
}
}
}
@@ -128,6 +128,16 @@ public class JavaCodeFoldingSettingsImpl extends JavaCodeFoldingSettings impleme
COLLAPSE_I18N_MESSAGES = value;
}
@Override
public boolean isCollapseSuppressWarnings() {
return COLLAPSE_SUPPRESS_WARNINGS;
}
@Override
public void setCollapseSuppressWarnings(boolean value) {
COLLAPSE_SUPPRESS_WARNINGS = value;
}
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_ACCESSORS = false;
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_INNER_CLASSES = false;
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_ANONYMOUS_CLASSES = false;
@@ -135,6 +145,7 @@ public class JavaCodeFoldingSettingsImpl extends JavaCodeFoldingSettings impleme
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_CLOSURES = false;
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_CONSTRUCTOR_GENERIC_PARAMETERS = true;
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_I18N_MESSAGES = true;
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_SUPPRESS_WARNINGS = true;
@NotNull
public File[] getExportFiles() {
@@ -32,9 +32,11 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
@@ -51,11 +53,19 @@ public class CreateFieldFromParameterAction implements IntentionAction {
private String myName = "";
@Nullable
private static PsiType getType(final PsiParameter parameter) {
private static PsiType[] getTypes(final PsiParameter parameter) {
if (parameter == null) return null;
PsiType type = parameter.getType();
if (type instanceof PsiEllipsisType) type = ((PsiEllipsisType)type).toArrayType();
return type;
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
if (psiClass instanceof PsiTypeParameter && parameter.getDeclarationScope() == ((PsiTypeParameter)psiClass).getOwner()) {
final PsiReferenceList extendsList = psiClass.getExtendsList();
LOG.assertTrue(extendsList != null);
final PsiClassType[] types = extendsList.getReferencedTypes();
if (types.length > 0) return types;
return new PsiType[]{PsiType.getJavaLangObject(parameter.getManager(), GlobalSearchScope.allScope(parameter.getProject()))};
}
return new PsiType[]{type};
}
@NotNull
@@ -67,15 +77,15 @@ public class CreateFieldFromParameterAction implements IntentionAction {
PsiParameter myParameter = findParameterAtCursor(file, editor);
if (myParameter == null) return false;
myName = myParameter.getName();
final PsiType type = getType(myParameter);
final PsiType[] types = getTypes(myParameter);
PsiClass targetClass = PsiTreeUtil.getParentOfType(myParameter, PsiClass.class);
return
myParameter.isValid()
&& myParameter.getDeclarationScope() instanceof PsiMethod
&& ((PsiMethod)myParameter.getDeclarationScope()).getBody() != null
&& myParameter.getManager().isInProject(myParameter)
&& type != null
&& type.isValid()
&& types != null
&& types[0].isValid()
&& !isParameterAssignedToField(myParameter)
&& targetClass != null
&& !targetClass.isInterface()
@@ -125,21 +135,21 @@ public class CreateFieldFromParameterAction implements IntentionAction {
if (!CodeInsightUtilBase.prepareFileForWrite(myParameter.getContainingFile())) return;
IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace();
final PsiType type = getType(myParameter);
final PsiType[] types = getTypes(myParameter);
final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project);
final String parameterName = myParameter.getName();
String propertyName = styleManager.variableNameToPropertyName(parameterName, VariableKind.PARAMETER);
String fieldNameToCalc;
boolean isFinalToCalc;
PsiType type;
final PsiClass targetClass = PsiTreeUtil.getParentOfType(myParameter, PsiClass.class);
final PsiMethod method = (PsiMethod)myParameter.getDeclarationScope();
final boolean isMethodStatic = method.hasModifierProperty(PsiModifier.STATIC);
VariableKind kind = isMethodStatic ? VariableKind.STATIC_FIELD : VariableKind.FIELD;
SuggestedNameInfo suggestedNameInfo = styleManager.suggestVariableName(kind, propertyName, null, type);
SuggestedNameInfo suggestedNameInfo = styleManager.suggestVariableName(kind, propertyName, null, types[0]);
String[] names = suggestedNameInfo.names;
if (isInteractive) {
@@ -158,11 +168,12 @@ public class CreateFieldFromParameterAction implements IntentionAction {
CreateFieldFromParameterDialog dialog = new CreateFieldFromParameterDialog(
project,
names,
type.getCanonicalText(), targetClass, myBeFinal);
targetClass, myBeFinal, types);
dialog.show();
if (!dialog.isOK()) return;
type = dialog.getType();
if (type == null) return;
fieldNameToCalc = dialog.getEnteredName();
isFinalToCalc = dialog.isDeclareFinal();
@@ -171,17 +182,19 @@ public class CreateFieldFromParameterAction implements IntentionAction {
else {
isFinalToCalc = !isMethodStatic;
fieldNameToCalc = names[0];
type= types[0];
}
final boolean isFinal = isFinalToCalc;
final String fieldName = fieldNameToCalc;
final PsiType fieldType = type;
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
try {
PsiManager psiManager = PsiManager.getInstance(project);
PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
PsiField field = factory.createField(fieldName, type);
PsiField field = factory.createField(fieldName, fieldType);
PsiModifierList modifierList = field.getModifierList();
modifierList.setModifierProperty(PsiModifier.STATIC, isMethodStatic);
modifierList.setModifierProperty(PsiModifier.FINAL, isFinal);
@@ -24,8 +24,11 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiType;
import com.intellij.refactoring.ui.TypeSelector;
import com.intellij.ui.DocumentAdapter;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
@@ -35,19 +38,23 @@ import java.awt.event.*;
class CreateFieldFromParameterDialog extends DialogWrapper {
private final Project myProject;
private final String[] myNames;
private final String myType;
private final PsiType[] myTypes;
private final PsiClass myTargetClass;
private final boolean myFieldMayBeFinal;
private JComponent myNameField;
private JCheckBox myCbFinal;
private static final @NonNls String PROPERTY_NAME = "CREATE_FIELD_FROM_PARAMETER_DECLARE_FINAL";
private TypeSelector myTypeSelector;
public CreateFieldFromParameterDialog(Project project, String[] names, String type, PsiClass targetClass, final boolean fieldMayBeFinal) {
public CreateFieldFromParameterDialog(Project project,
String[] names,
PsiClass targetClass,
final boolean fieldMayBeFinal, PsiType... types) {
super(project, true);
myProject = project;
myNames = names;
myType = type;
myTypes = types;
myTargetClass = targetClass;
myFieldMayBeFinal = fieldMayBeFinal;
@@ -175,13 +182,21 @@ class CreateFieldFromParameterDialog extends DialogWrapper {
gbConstraints.anchor = GridBagConstraints.EAST;
gbConstraints.fill = GridBagConstraints.BOTH;
gbConstraints.gridwidth = 2;
gbConstraints.gridwidth = 1;
gbConstraints.weightx = 1;
gbConstraints.weighty = 1;
gbConstraints.gridx = 0;
gbConstraints.gridy = 0;
JLabel type = new JLabel(CodeInsightBundle.message("dialog.create.field.from.parameter.field.type.label", myType));
panel.add(type, gbConstraints);
final JLabel typeLabel = new JLabel(CodeInsightBundle.message("dialog.create.field.from.parameter.field.type.label"));
panel.add(typeLabel, gbConstraints);
gbConstraints.gridx = 1;
if (myTypes.length > 1) {
myTypeSelector = new TypeSelector();
myTypeSelector.setTypes(myTypes);
} else {
myTypeSelector = new TypeSelector(myTypes[0]);
}
panel.add(myTypeSelector.getComponent(), gbConstraints);
gbConstraints.gridwidth = 1;
gbConstraints.weightx = 0;
@@ -249,4 +264,9 @@ class CreateFieldFromParameterDialog extends DialogWrapper {
public JComponent getPreferredFocusedComponent() {
return myNameField;
}
@Nullable
public PsiType getType() {
return myTypeSelector.getSelectedType();
}
}
@@ -21,6 +21,7 @@ import com.intellij.formatting.alignment.AlignmentInColumnsHelper;
import com.intellij.formatting.alignment.AlignmentStrategy;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
@@ -47,7 +48,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
/**
* Holds types of the elements for which <code>'align in column'</code> rule may be preserved.
*
* @see CodeStyleSettings#ALIGN_MULTILINE_SUBSEQUENT_DECLARATIONS
* @see CodeStyleSettings#ALIGN_GROUP_FIELDS_VARIABLES
*/
protected static final Set<IElementType> ALIGN_IN_COLUMNS_ELEMENT_TYPES = Collections.unmodifiableSet(new HashSet<IElementType>(asList(
JavaElementType.FIELD, JavaElementType.DECLARATION_STATEMENT, JavaElementType.LOCAL_VARIABLE
@@ -58,10 +59,10 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
/**
* Shared thread-safe config object to use during <code>'align in column'</code> processing.
*
* @see CodeStyleSettings#ALIGN_MULTILINE_SUBSEQUENT_DECLARATIONS
* @see CodeStyleSettings#ALIGN_GROUP_FIELDS_VARIABLES
*/
private static final AlignmentInColumnsConfig ALIGNMENT_IN_COLUMNS_CONFIG = new AlignmentInColumnsConfig(
JavaTokenType.IDENTIFIER, StdTokenSets.WHITE_SPACE_OR_COMMENT_BIT_SET, ElementType.COMMENT_BIT_SET, JavaTokenType.EQ,
JavaTokenType.IDENTIFIER, ElementType.WHITE_SPACE_BIT_SET, ElementType.JAVA_COMMENT_BIT_SET, JavaTokenType.EQ,
JavaElementType.FIELD, JavaElementType.LOCAL_VARIABLE
);
@@ -73,6 +74,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
));
protected final CodeStyleSettings mySettings;
protected final CodeStyleSettings.IndentOptions myIndentSettings;
private final Indent myIndent;
protected Indent myChildIndent;
protected Alignment myChildAlignment;
@@ -105,6 +107,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
{
super(node, wrap, alignmentStrategy.getAlignment(node.getElementType()));
mySettings = settings;
myIndentSettings = settings.getIndentOptions(StdFileTypes.JAVA);
myIndent = indent;
myWrapManager = wrapManager;
myAlignmentStrategy = alignmentStrategy;
@@ -134,7 +137,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
AlignmentStrategy alignmentStrategy,
int startOffset
) {
Indent actualIndent = indent == null ? getDefaultSubtreeIndent(child) : indent;
Indent actualIndent = indent == null ? getDefaultSubtreeIndent(child, settings.getIndentOptions(StdFileTypes.JAVA)) : indent;
final IElementType elementType = child.getElementType();
Alignment alignment = alignmentStrategy.getAlignment(elementType);
@@ -202,11 +205,12 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
public static Block createJavaBlock(final ASTNode child, final CodeStyleSettings settings) {
return createJavaBlock(child, settings, getDefaultSubtreeIndent(child), null, AlignmentStrategy.getNullStrategy());
return createJavaBlock(child, settings, getDefaultSubtreeIndent(child, settings.getIndentOptions(StdFileTypes.JAVA)),
null, AlignmentStrategy.getNullStrategy());
}
@Nullable
private static Indent getDefaultSubtreeIndent(final ASTNode child) {
private static Indent getDefaultSubtreeIndent(final ASTNode child, final CodeStyleSettings.IndentOptions indentOptions) {
final ASTNode parent = child.getTreeParent();
final IElementType childNodeType = child.getElementType();
if (childNodeType == JavaElementType.ANNOTATION) {
@@ -226,7 +230,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
if (childNodeType == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS) return Indent.getSpaceIndent(1);
if (child.getPsi() instanceof PsiFile) return Indent.getNoneIndent();
if (parent != null) {
final Indent defaultChildIndent = getChildIndent(parent);
final Indent defaultChildIndent = getChildIndent(parent, indentOptions);
if (defaultChildIndent != null) return defaultChildIndent;
}
@@ -234,7 +238,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
@Nullable
private static Indent getChildIndent(final ASTNode parent) {
private static Indent getChildIndent(final ASTNode parent, final CodeStyleSettings.IndentOptions indentOptions) {
final IElementType parentType = parent.getElementType();
if (parentType == JavaElementType.MODIFIER_LIST) return Indent.getNoneIndent();
if (parentType == JspElementType.JSP_CODE_BLOCK) return Indent.getNormalIndent();
@@ -255,7 +259,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
if (parentType == JavaDocElementType.DOC_TAG) return Indent.getNoneIndent();
if (parentType == JavaDocElementType.DOC_INLINE_TAG) return Indent.getNoneIndent();
if (parentType == JavaElementType.IMPORT_LIST) return Indent.getNoneIndent();
if (parentType == JavaElementType.FIELD) return Indent.getContinuationWithoutFirstIndent();
if (parentType == JavaElementType.FIELD) return Indent.getContinuationWithoutFirstIndent(indentOptions.USE_RELATIVE_INDENTS);
if (parentType == JavaElementType.EXPRESSION_STATEMENT) return Indent.getNoneIndent();
if (SourceTreeToPsiMap.treeElementToPsi(parent) instanceof PsiFile) {
return Indent.getNoneIndent();
@@ -546,8 +550,12 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
final ArrayList<Block> localResult = new ArrayList<Block>();
while (child != null) {
if (!FormatterUtil.containsWhiteSpacesOnly(child)) {
localResult.add(createJavaBlock(child, getSettings(), Indent.getContinuationWithoutFirstIndent(),
arrangeChildWrap(child, defaultWrap), alignmentStrategy));
localResult.add(createJavaBlock(child,
getSettings(),
Indent.getContinuationWithoutFirstIndent(myIndentSettings.USE_RELATIVE_INDENTS),
arrangeChildWrap(child, defaultWrap),
alignmentStrategy)
);
}
if (child == lastFieldInGroup) break;
@@ -674,8 +682,8 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
subBlocks.add(createSynthBlock(subNodes, wrap, alignmentToUseForSubBlock));
}
return new SyntheticCodeBlock(subBlocks, alignment, mySettings, Indent.getContinuationWithoutFirstIndent(),
blockWrap);
return new SyntheticCodeBlock(subBlocks, alignment, mySettings,
Indent.getContinuationWithoutFirstIndent(myIndentSettings.USE_RELATIVE_INDENTS), blockWrap);
}
private Block createSynthBlock(final ArrayList<ASTNode> subNodes, final Wrap wrap, final Alignment alignment) {
@@ -687,18 +695,19 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
if (!subNodes.isEmpty()) {
subBlocks.add(createSynthBlock(subNodes, wrap, null));
}
return new SyntheticCodeBlock(subBlocks, alignment, mySettings, Indent.getContinuationIndent(), wrap);
return new SyntheticCodeBlock(subBlocks, alignment, mySettings,
Indent.getContinuationIndent(myIndentSettings.USE_RELATIVE_INDENTS), wrap);
}
else {
return new SyntheticCodeBlock(createJavaBlocks(subNodes), alignment, mySettings,
Indent.getContinuationWithoutFirstIndent(), null);
Indent.getContinuationWithoutFirstIndent(myIndentSettings.USE_RELATIVE_INDENTS), null);
}
}
private List<Block> createJavaBlocks(final ArrayList<ASTNode> subNodes) {
final ArrayList<Block> result = new ArrayList<Block>();
for (ASTNode node : subNodes) {
result.add(createJavaBlock(node, getSettings(), Indent.getContinuationWithoutFirstIndent(), null,
result.add(createJavaBlock(node, getSettings(), Indent.getContinuationWithoutFirstIndent(myIndentSettings.USE_RELATIVE_INDENTS), null,
AlignmentStrategy.getNullStrategy()));
}
return result;
@@ -861,14 +870,14 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
*
* @param child variable declaration child node which alignment is to be defined
* @return alignment to use for the given node
* @see CodeStyleSettings#ALIGN_MULTILINE_SUBSEQUENT_DECLARATIONS
* @see CodeStyleSettings#ALIGN_GROUP_FIELDS_VARIABLES
*/
@Nullable
private Alignment getVariableDeclarationSubElementAlignment(ASTNode child) {
// The whole idea of variable declarations alignment is that complete declaration blocks which children are to be aligned hold
// reference to the same AlignmentStrategy object, hence, reuse the same Alignment objects. So, there is no point in checking
// if it's necessary to align sub-blocks if shared strategy is not defined.
if (myAlignmentStrategy == null || !mySettings.ALIGN_MULTILINE_SUBSEQUENT_DECLARATIONS) {
if (myAlignmentStrategy == null || !mySettings.ALIGN_GROUP_FIELDS_VARIABLES) {
return null;
}
@@ -949,11 +958,18 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
final WrappingStrategy wrappingStrategy, final boolean doAlign
) {
final Indent externalIndent = Indent.getNoneIndent();
final Indent internalIndent = Indent.getContinuationIndent();
final Indent internalIndent = Indent.getContinuationIndent(myIndentSettings.USE_RELATIVE_INDENTS);
AlignmentStrategy alignmentStrategy = AlignmentStrategy.wrap(createAlignment(doAlign, null), ElementType.COMMA);
setChildIndent(internalIndent);
setChildAlignment(alignmentStrategy.getAlignment(null));
Alignment bracketAlignment = mySettings.ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION ? Alignment.createAlignment() : null;
boolean methodParametersBlock = true;
ASTNode lBracketParent = child.getTreeParent();
if (lBracketParent != null) {
ASTNode methodCandidate = lBracketParent.getTreeParent();
methodParametersBlock = methodCandidate != null && (methodCandidate.getElementType() == JavaElementType.METHOD
|| methodCandidate.getElementType() == JavaElementType.METHOD_CALL_EXPRESSION);
}
Alignment bracketAlignment = methodParametersBlock && mySettings.ALIGN_MULTILINE_METHOD_BRACKETS ? Alignment.createAlignment() : null;
boolean isAfterIncomplete = false;
@@ -1161,7 +1177,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
@Nullable
protected Indent getChildIndent() {
return getChildIndent(myNode);
return getChildIndent(myNode, myIndentSettings);
}
public CodeStyleSettings getSettings() {
@@ -1196,7 +1212,8 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
@Nullable
protected ASTNode composeCodeBlock(final ArrayList<Block> result, ASTNode child, final Indent indent, final int childrenIndent) {
protected ASTNode composeCodeBlock(final ArrayList<Block> result, ASTNode child, final Indent indent, final int childrenIndent,
final Wrap childWrap) {
final ArrayList<Block> localResult = new ArrayList<Block>();
processChild(localResult, child, AlignmentStrategy.getNullStrategy(), null, Indent.getNoneIndent());
child = child.getTreeNext();
@@ -1207,7 +1224,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
while (child != null) {
// We consider that subsequent fields shouldn't be aligned if they are separated by blank line(s).
if (!FormatterUtil.containsWhiteSpacesOnly(child)) {
if (!shouldUseVarDeclarationAlignment(child)) {
if (!ElementType.JAVA_COMMENT_BIT_SET.contains(child.getElementType()) && !shouldUseVarDeclarationAlignment(child)) {
// Reset var declaration alignment.
varDeclarationAlignmentStrategy = AlignmentStrategy.createAlignmentPerTypeStrategy(VAR_DECLARATION_ELEMENT_TYPES_TO_ALIGN, true);
}
@@ -1215,7 +1232,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
final Indent childIndent = rBrace ? Indent.getNoneIndent() : getCodeBlockInternalIndent(childrenIndent);
AlignmentStrategy alignmentStrategyToUse = ALIGN_IN_COLUMNS_ELEMENT_TYPES.contains(child.getElementType())
? varDeclarationAlignmentStrategy : AlignmentStrategy.getNullStrategy();
child = processChild(localResult, child, alignmentStrategyToUse, null, childIndent);
child = processChild(localResult, child, alignmentStrategyToUse, childWrap, childIndent);
if (rBrace) {
result.add(createCodeBlockBlock(localResult, indent, childrenIndent));
return child;
@@ -1244,7 +1261,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
* @return
*/
protected boolean shouldUseVarDeclarationAlignment(ASTNode node) {
return mySettings.ALIGN_MULTILINE_SUBSEQUENT_DECLARATIONS && ALIGN_IN_COLUMNS_ELEMENT_TYPES.contains(node.getElementType())
return mySettings.ALIGN_GROUP_FIELDS_VARIABLES && ALIGN_IN_COLUMNS_ELEMENT_TYPES.contains(node.getElementType())
&& !myAlignmentInColumnsHelper.useDifferentVarDeclarationAlignment(node, ALIGNMENT_IN_COLUMNS_CONFIG);
}
@@ -76,14 +76,14 @@ public class BlockContainingJavaBlock extends AbstractJavaBlock{
&& !JavaTokenType.COMMENT_BIT_SET.contains(child.getElementType()))
{
prevChild = child;
child = composeCodeBlock(result, child, Indent.getNoneIndent(), 0);
child = composeCodeBlock(result, child, Indent.getNoneIndent(), 0, null);
}
else {
prevChild = child;
child = processChild(result, child, childAlignment, childWrap, indent);
}
for (int i = myIndentsBefore.size(); i < result.size(); i++) {
myIndentsBefore.add(Indent.getContinuationIndent());
myIndentsBefore.add(Indent.getContinuationIndent(myIndentSettings.USE_RELATIVE_INDENTS));
}
}
if (child != null) {
@@ -148,7 +148,7 @@ public class BlockContainingJavaBlock extends AbstractJavaBlock{
return getCodeBlockInternalIndent(1);
}
else {
return Indent.getContinuationIndent();
return Indent.getContinuationIndent(myIndentSettings.USE_RELATIVE_INDENTS);
}
}
}
@@ -170,7 +170,7 @@ public class BlockContainingJavaBlock extends AbstractJavaBlock{
if (child.getElementType() == ElementType.ELSE_KEYWORD)
return getCodeBlockExternalIndent();
return Indent.getContinuationIndent();
return Indent.getContinuationIndent(myIndentSettings.USE_RELATIVE_INDENTS);
}
private static boolean isSimpleStatement(final ASTNode child) {
@@ -87,12 +87,12 @@ public class CodeBlockBlock extends AbstractJavaBlock {
child = processCaseAndStatementAfter(result, child, childAlignment, childWrap, indent);
}
else if (myNode.getElementType() == ElementType.CLASS && child.getElementType() == ElementType.LBRACE) {
child = composeCodeBlock(result, child, getCodeBlockExternalIndent(), myChildrenIndent);
child = composeCodeBlock(result, child, getCodeBlockExternalIndent(), myChildrenIndent, null);
}
else if (myNode.getElementType() == ElementType.CODE_BLOCK && child.getElementType() == ElementType.LBRACE
&& myNode.getTreeParent().getElementType() == JavaElementType.METHOD)
{
child = composeCodeBlock(result, child, indent, myChildrenIndent);
child = composeCodeBlock(result, child, indent, myChildrenIndent, childWrap);
}
else {
child = processChild(result, child, childAlignment, childWrap, indent);
@@ -217,7 +217,7 @@ public class CodeBlockBlock extends AbstractJavaBlock {
return Indent.getNoneIndent();
}
else {
return Indent.getContinuationIndent();
return Indent.getContinuationIndent(myIndentSettings.USE_RELATIVE_INDENTS);
}
}
else {
@@ -36,7 +36,7 @@ public class ExtendsListBlock extends AbstractJavaBlock{
final ArrayList<Block> result = new ArrayList<Block>();
ArrayList<Block> elementsExceptKeyword = new ArrayList<Block>();
myChildAlignment = createChildAlignment();
myChildIndent = Indent.getContinuationIndent();
myChildIndent = Indent.getContinuationIndent(myIndentSettings.USE_RELATIVE_INDENTS);
myUseChildAttributes = true;
Wrap childWrap = createChildWrap();
ASTNode child = myNode.getFirstChildNode();
@@ -201,9 +201,8 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
PsiIdentifier nameIdentifier = aClass.getNameIdentifier();
int dependanceStart = nameIdentifier == null ? myParent.getTextRange().getStartOffset() : nameIdentifier.getTextRange().getStartOffset();
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_CLASS_LBRACE, mySettings.CLASS_BRACE_STYLE,
new TextRange(dependanceStart,
myChild1.getTextRange().getEndOffset()),
false);
new TextRange(dependanceStart, myChild1.getTextRange().getEndOffset()),
false, true);
}
else if (myRole1 == ChildRole.LBRACE) {
if (aClass.isEnum()) {
@@ -536,9 +535,8 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
else if (myRole2 == ChildRole.LOOP_BODY || myChild2.getElementType() == JavaElementType.CODE_BLOCK) {
if (myChild2.getElementType() == JavaElementType.BLOCK_STATEMENT) {
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_WHILE_LBRACE, mySettings.BRACE_STYLE,
new TextRange(myParent.getTextRange().getStartOffset(),
myChild1.getTextRange().getEndOffset()),
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
new TextRange(myParent.getTextRange().getStartOffset(), myChild1.getTextRange().getEndOffset()),
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, true);
} else {
createSpacingBeforeElementInsideControlStatement();
}
@@ -556,7 +554,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
else if (myRole2 == ChildRole.LOOP_BODY) {
if (myChild2.getElementType() == JavaElementType.BLOCK_STATEMENT) {
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_DO_LBRACE, mySettings.BRACE_STYLE, null,
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, true);
} else {
createSpacingBeforeElementInsideControlStatement();
}
@@ -602,7 +600,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
if (myRole2 == ChildRole.TRY_BLOCK || myRole2 == ChildRole.FINALLY_BLOCK) {
boolean useSpaceBeforeLBrace = myRole2 == ChildRole.TRY_BLOCK ? mySettings.SPACE_BEFORE_TRY_LBRACE
: mySettings.SPACE_BEFORE_FINALLY_LBRACE;
myResult = getSpaceBeforeLBrace(useSpaceBeforeLBrace, mySettings.BRACE_STYLE, null, mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
myResult = getSpaceBeforeLBrace(useSpaceBeforeLBrace, mySettings.BRACE_STYLE, null, mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, true);
}
}
@@ -622,9 +620,8 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
else if (myRole2 == ChildRole.LOOP_BODY) {
if (myChild2.getElementType() == JavaElementType.BLOCK_STATEMENT) {
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_FOR_LBRACE, mySettings.BRACE_STYLE,
new TextRange(myParent.getTextRange().getStartOffset(),
myChild1.getTextRange().getEndOffset()),
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
new TextRange(myParent.getTextRange().getStartOffset(), myChild1.getTextRange().getEndOffset()),
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, true);
}
else if (mySettings.KEEP_CONTROL_STATEMENT_IN_ONE_LINE) {
myResult = Spacing
@@ -708,10 +705,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
else if (myChild1.getElementType() == JavaElementType.SWITCH_LABEL_STATEMENT && myChild2.getElementType() ==
JavaElementType
.BLOCK_STATEMENT) {
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_SWITCH_LBRACE,
mySettings.BRACE_STYLE,
null,
false);
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_SWITCH_LBRACE, mySettings.BRACE_STYLE, null, false, true);
}
else if (myRole1 == ChildRole.STATEMENT_IN_BLOCK && myRole2 == ChildRole.STATEMENT_IN_BLOCK) {
@@ -753,9 +747,8 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
else {
if (myChild2.getElementType() == JavaElementType.BLOCK_STATEMENT || myChild2.getElementType() == JavaElementType.CODE_BLOCK) {
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_ELSE_LBRACE, mySettings.BRACE_STYLE,
null,
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_ELSE_LBRACE, mySettings.BRACE_STYLE, null,
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, true);
}
else {
createSpacingBeforeElementInsideControlStatement();
@@ -764,9 +757,9 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
else if (myChild2.getElementType() == JavaElementType.BLOCK_STATEMENT || myChild2.getElementType() == JavaElementType.CODE_BLOCK) {
boolean space = myRole2 == ChildRole.ELSE_BRANCH ? mySettings.SPACE_BEFORE_ELSE_LBRACE : mySettings.SPACE_BEFORE_IF_LBRACE;
myResult = getSpaceBeforeLBrace(space, mySettings.BRACE_STYLE, new TextRange(myParent.getTextRange().getStartOffset(),
myChild1.getTextRange().getEndOffset()),
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
myResult = getSpaceBeforeLBrace(space, mySettings.BRACE_STYLE,
new TextRange(myParent.getTextRange().getStartOffset(), myChild1.getTextRange().getEndOffset()),
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, true);
}
else if (myRole2 == ChildRole.LPARENTH) {
createSpaceInCode(mySettings.SPACE_BEFORE_IF_PARENTHESES);
@@ -816,7 +809,8 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
private Spacing getSpaceBeforeLBrace(final boolean spaceBeforeLbrace,
int braceStyle,
TextRange dependantRange,
boolean keepOneLine) {
boolean keepOneLine,
boolean useParentBlockAsDependencyAllTheTime) {
if (dependantRange != null && braceStyle == CodeStyleSettings.NEXT_LINE_IF_WRAPPED) {
int space = spaceBeforeLbrace ? 1 : 0;
return createNonLFSpace(space, dependantRange, false);
@@ -826,9 +820,12 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
return createNonLFSpace(space, null, false);
}
else if (keepOneLine) {
TextRange dependencyRangeToUse = dependantRange == null || useParentBlockAsDependencyAllTheTime
? myParent.getTextRange() : dependantRange;
int space = spaceBeforeLbrace ? 1 : 0;
return Spacing
.createDependentLFSpacing(space, space, myParent.getTextRange(), mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
return Spacing.createDependentLFSpacing(
space, space, dependencyRangeToUse, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE
);
}
else {
return Spacing.createSpacing(0, 0, 1, false, mySettings.KEEP_BLANK_LINES_IN_CODE);
@@ -930,11 +927,25 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
else if (myRole2 == ChildRole.METHOD_BODY) {
PsiElement methodName = method.getNameIdentifier();
int dependancyStart = methodName == null ? myParent.getTextRange().getStartOffset() : methodName.getTextRange().getStartOffset();
int dependencyStart = methodName == null ? myParent.getTextRange().getStartOffset() : methodName.getTextRange().getStartOffset();
PsiModifierList modifierList = method.getModifierList();
PsiAnnotation[] annotations = modifierList.getAnnotations();
boolean useParentBlockAsDependencyAllTheTime = true;
if (annotations.length > 0) {
useParentBlockAsDependencyAllTheTime = false;
PsiAnnotation annotation = annotations[annotations.length - 1];
ASTNode nextModifier = FormattingAstUtil.getNextNonWhiteSpaceNode(annotation.getNode());
if (nextModifier == null) {
PsiElement element = modifierList.getNextSibling();
if (element != null) dependencyStart = element.getTextRange().getStartOffset();
} else {
dependencyStart = nextModifier.getStartOffset();
}
}
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_METHOD_LBRACE, mySettings.METHOD_BRACE_STYLE,
new TextRange(dependancyStart,
myChild1.getTextRange().getEndOffset()),
mySettings.KEEP_SIMPLE_METHODS_IN_ONE_LINE);
new TextRange(dependencyStart, myChild1.getTextRange().getEndOffset()),
mySettings.KEEP_SIMPLE_METHODS_IN_ONE_LINE, useParentBlockAsDependencyAllTheTime);
}
else if (myRole1 == ChildRole.MODIFIER_LIST) {
processModifierList();
@@ -1052,9 +1063,8 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
createSpaceInCode(mySettings.SPACE_WITHIN_SYNCHRONIZED_PARENTHESES);
}
else if (myRole2 == ChildRole.BLOCK) {
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_SYNCHRONIZED_LBRACE,
mySettings.BRACE_STYLE, null,
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_SYNCHRONIZED_LBRACE, mySettings.BRACE_STYLE, null,
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, true);
}
}
@@ -1074,7 +1084,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
else if (myRole2 == ChildRole.SWITCH_BODY) {
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_SWITCH_LBRACE, mySettings.BRACE_STYLE, null,
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, true);
}
}
@@ -1119,9 +1129,8 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
else if (myRole2 == ChildRole.LOOP_BODY || myChild2.getElementType() == JavaElementType.CODE_BLOCK) {
if (myChild2.getElementType() == JavaElementType.BLOCK_STATEMENT) {
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_FOR_LBRACE, mySettings.BRACE_STYLE,
new TextRange(myParent.getTextRange().getStartOffset(),
myChild1.getTextRange().getEndOffset()),
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
new TextRange(myParent.getTextRange().getStartOffset(), myChild1.getTextRange().getEndOffset()),
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, true);
}
else if (mySettings.KEEP_CONTROL_STATEMENT_IN_ONE_LINE) {
myResult = Spacing
@@ -1145,7 +1154,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
@Override public void visitCatchSection(PsiCatchSection section) {
if (myRole2 == ChildRole.CATCH_BLOCK) {
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_CATCH_LBRACE, mySettings.BRACE_STYLE, null,
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE);
mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, true);
}
else if (myRole2 == ChildRole.CATCH_BLOCK_PARAMETER_LPARENTH) {
createSpaceInCode(mySettings.SPACE_BEFORE_CATCH_PARENTHESES);
@@ -1328,9 +1337,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
@Override public void visitClassInitializer(PsiClassInitializer initializer) {
if (myChild2.getElementType() == JavaElementType.CODE_BLOCK) {
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_METHOD_LBRACE, mySettings.BRACE_STYLE,
null,
false);
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_METHOD_LBRACE, mySettings.BRACE_STYLE, null, false, true);
}
}
@@ -1405,10 +1412,8 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
createSpaceInCode(mySettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES);
}
else if (myRole2 == ChildRole.ANONYMOUS_CLASS) {
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_CLASS_LBRACE,
mySettings.METHOD_BRACE_STYLE,
enumConstant.getTextRange(),
mySettings.KEEP_SIMPLE_METHODS_IN_ONE_LINE);
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_CLASS_LBRACE, mySettings.METHOD_BRACE_STYLE, enumConstant.getTextRange(),
mySettings.KEEP_SIMPLE_METHODS_IN_ONE_LINE, true);
}
}
@@ -71,7 +71,7 @@ public class SimpleJavaBlock extends AbstractJavaBlock {
offset = child.getTextRange().getStartOffset();
}
if (indent != null && !(myNode.getPsi() instanceof PsiFile) && child != null && child.getElementType() != ElementType.MODIFIER_LIST) {
indent = Indent.getContinuationIndent();
indent = Indent.getContinuationIndent(myIndentSettings.USE_RELATIVE_INDENTS);
}
//indent = FormatterEx.getInstance().getContinuationIndent();
}
@@ -49,9 +49,12 @@ import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
@SuppressWarnings({"HardCodedStringLiteral"})
public class ClsStubBuilder {
private static final Pattern REGEX_PATTERN = Pattern.compile("(?<=[^\\$])\\${1}(?=[^\\$])");
private ClsStubBuilder() {
}
@@ -677,6 +680,12 @@ public class ClsStubBuilder {
private static String getTypeText(final Type type) {
final String raw = type.getClassName();
return raw.replace('$', '.');
// As the '$' char is a valid java identifier and is actively used by bytecode genarators, the problem is
// which occurrences of this char should be replaced and which should not.
// Heuristic: replace only those $ occurrences that are surrounded non-"$" chars
// (most likely generated by javac to separate inner or anonymoys class name)
// Leading and trailing $ chars should be left unchanged.
return raw.contains("$")? REGEX_PATTERN.matcher(raw).replaceAll("\\.") : raw;
}
}
@@ -291,6 +291,11 @@ public class LightClass extends LightElement implements PsiClass {
return myDelegate;
}
@Override
public boolean isValid() {
return myDelegate.isValid();
}
@Override
public boolean isEquivalentTo(PsiElement another) {
return this == another || getDelegate().isEquivalentTo(another);
@@ -37,20 +37,12 @@ import org.jetbrains.annotations.NotNull;
* @author mike
*/
public class PsiDocParamRef extends CompositePsiElement implements PsiDocTagValue {
private volatile PsiReference myCachedReference;
public PsiDocParamRef() {
super(Constants.DOC_PARAMETER_REF);
}
public void clearCaches() {
myCachedReference = null;
super.clearCaches();
}
public PsiReference getReference() {
PsiReference cachedReference = myCachedReference;
if (cachedReference != null) return cachedReference;
final PsiDocComment comment = PsiTreeUtil.getParentOfType(this, PsiDocComment.class);
if (comment == null) return null;
final PsiDocCommentOwner owner = comment.getOwner();
@@ -79,7 +71,7 @@ public class PsiDocParamRef extends CompositePsiElement implements PsiDocTagValu
}
final PsiElement resultReference = reference;
myCachedReference = cachedReference = new PsiJavaReference() {
return new PsiJavaReference() {
public PsiElement resolve() {
return resultReference;
}
@@ -155,7 +147,6 @@ public class PsiDocParamRef extends CompositePsiElement implements PsiDocTagValu
: new JavaResolveResult[]{new CandidateInfo(resultReference, PsiSubstitutor.EMPTY)};
}
};
return cachedReference;
}
public void accept(@NotNull PsiElementVisitor visitor) {
@@ -53,7 +53,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
myActualParameterTypes = actualParameterTypes;
}
public CandidateInfo resolveConflict(List<CandidateInfo> conflicts){ if (conflicts.isEmpty()) return null;
public CandidateInfo resolveConflict(List<CandidateInfo> conflicts){
if (conflicts.isEmpty()) return null;
if (conflicts.size() == 1) return conflicts.get(0);
boolean atLeastOneMatch = checkParametersNumber(conflicts, myActualParameterTypes.length, true);
@@ -135,10 +136,23 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
// candidates should go in order of class hierarchy traversal
// in order for this to work
Map<MethodSignature, CandidateInfo> signatures = new HashMap<MethodSignature, CandidateInfo>();
nextConflict:
for (int i=0; i<conflicts.size();i++) {
CandidateInfo info = conflicts.get(i);
PsiMethod method = (PsiMethod)info.getElement();
assert method != null;
if (!method.hasModifierProperty(PsiModifier.STATIC)) {
for (int k=i-1; k>=0; k--) {
PsiMethod existingMethod = (PsiMethod)conflicts.get(k).getElement();
if (PsiSuperMethodUtil.isSuperMethod(existingMethod, method)) {
conflicts.remove(i);
i--;
continue nextConflict;
}
}
}
PsiClass class1 = method.getContainingClass();
PsiSubstitutor infoSubstitutor = info.getSubstitutor();
MethodSignature signature = method.getSignature(infoSubstitutor);
@@ -23,7 +23,7 @@ import com.intellij.psi.search.GlobalSearchScope;
public abstract class JavaTestFrameworkDescriptor implements TestFrameworkDescriptor {
public boolean isLibraryAttached(Module m) {
GlobalSearchScope scope = GlobalSearchScope.moduleWithLibrariesScope(m);
GlobalSearchScope scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(m);
PsiClass c = JavaPsiFacade.getInstance(m.getProject()).findClass(getMarkerClassFQName(), scope);
return c != null;
}
@@ -143,7 +143,9 @@ public class CreateTestDialog extends DialogWrapper {
}
}
}
myDefaultLibraryButton = attachedLibraries.get(0).second;
if (myDefaultLibraryButton == null) {
myDefaultLibraryButton = attachedLibraries.get(0).second;
}
}
if (myDefaultLibraryButton == null) {
myDefaultLibraryButton = myLibraryButtons.get(0);
@@ -415,7 +417,7 @@ public class CreateTestDialog extends DialogWrapper {
protected void doOKAction() {
RecentsManager.getInstance(myProject).registerRecentEntry(RECENTS_KEY, myTargetPackageField.getText());
String errorMessage = null;
String errorMessage;
try {
myTargetDirectory = selectTargetDirectory();
if (myTargetDirectory == null) return;
@@ -465,8 +467,9 @@ public class CreateTestDialog extends DialogWrapper {
private PsiDirectory chooseDefaultDirectory(String packageName) {
for (ContentEntry e : ModuleRootManager.getInstance(myTargetModule).getContentEntries()) {
for (SourceFolder f : e.getSourceFolders()) {
if (f.getFile() != null && f.isTestSource()) {
return PsiManager.getInstance(myProject).findDirectory(f.getFile());
final VirtualFile file = f.getFile();
if (file != null && f.isTestSource()) {
return PsiManager.getInstance(myProject).findDirectory(file);
}
}
}
@@ -3,6 +3,6 @@ class Foo {
public void foo() {
int someVariable = (y +
z
);
);
}
}
@@ -14,7 +14,7 @@ public class Foo {
if (x < 0) {
int someVariable = (y +
z
);
);
someVariable = x =
x +
y;
@@ -0,0 +1,5 @@
public class T<caret>oFind {
void foo() {
new ToFind();
}
}
@@ -109,7 +109,8 @@ public class JavaFormatterAlignmentTest extends AbstractJavaFormatterTest {
public void testMethodBrackets() throws Exception {
// Inspired by IDEA-53013
getSettings().ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION = true;
getSettings().ALIGN_MULTILINE_METHOD_BRACKETS = true;
getSettings().ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION = false;
getSettings().ALIGN_MULTILINE_PARAMETERS = true;
getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
getSettings().CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = true;
@@ -136,11 +137,22 @@ public class JavaFormatterAlignmentTest extends AbstractJavaFormatterTest {
" );\n" +
"}"
);
// Inspired by IDEA-55306
getSettings().ALIGN_MULTILINE_METHOD_BRACKETS = false;
getSettings().CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = false;
String method =
"executeCommand(new Command<Boolean>() {\n" +
" public Boolean run() throws ExecutionException {\n" +
" return doInterrupt();\n" +
" }\n" +
"});";
doMethodTest(method, method);
}
public void testVariableDeclarationAlignment() {
// Inspired by IDEA-55147
getSettings().ALIGN_MULTILINE_SUBSEQUENT_DECLARATIONS = true;
getSettings().ALIGN_GROUP_FIELDS_VARIABLES = true;
getSettings().FIELD_ANNOTATION_WRAP = CodeStyleSettings.DO_NOT_WRAP;
getSettings().VARIABLE_ANNOTATION_WRAP = CodeStyleSettings.DO_NOT_WRAP;
@@ -192,4 +192,22 @@ public class JavaFormatterNewLineTest extends AbstractJavaFormatterTest {
"}"
);
}
public void testSimpleAnnotatedMethodAndBraceOnNextLineStyle() throws Exception {
// Inspired by IDEA-53542
getSettings().METHOD_BRACE_STYLE = CodeStyleSettings.NEXT_LINE;
getSettings().KEEP_SIMPLE_METHODS_IN_ONE_LINE = true;
getSettings().KEEP_LINE_BREAKS = true;
getSettings().KEEP_BLANK_LINES_IN_CODE = 2;
String methodWithAnnotation = "@Override\n" +
"void foo() {}";
String methodWithAnnotationAndVisibility = "@Override\n" +
"public void foo() {}";
// Don't expect that simple method to be spread on multiple lines.
doClassTest(methodWithAnnotation, methodWithAnnotation);
doClassTest(methodWithAnnotationAndVisibility, methodWithAnnotationAndVisibility);
}
}
@@ -6,9 +6,14 @@ import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.rename.RenameProcessor;
import com.intellij.refactoring.rename.RenameUtil;
import com.intellij.refactoring.util.MoveRenameUsageInfo;
import com.intellij.testFramework.LightCodeInsightTestCase;
import com.intellij.usageView.UsageInfo;
import org.junit.Assert;
import java.util.HashMap;
/**
* @author sashache
*/
@@ -165,4 +170,17 @@ public class RenameCollisionsTest extends LightCodeInsightTestCase {
protected Sdk getProjectJDK() {
return JavaSdkImpl.getMockJdk15("java 1.5");
}
public void testAllUsagesInCode() throws Exception {
configureByFile(BASE_PATH + getTestName(false) + ".java");
PsiElement element = TargetElementUtilBase
.findTargetElement(myEditor, TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
assertNotNull(element);
final UsageInfo[] usageInfos = RenameUtil.findUsages(element, "newName", true, true, new HashMap<PsiElement, String>());
assertSize(1, usageInfos);
for (UsageInfo usageInfo : usageInfos) {
assertTrue(usageInfo instanceof MoveRenameUsageInfo);
assertFalse(usageInfo.isNonCodeUsage);
}
}
}
@@ -56,4 +56,8 @@ public abstract class JavaCodeFoldingSettings {
public abstract boolean isCollapseI18nMessages();
public abstract void setCollapseI18nMessages(boolean value);
public abstract boolean isCollapseSuppressWarnings();
public abstract void setCollapseSuppressWarnings(boolean value);
}
@@ -802,7 +802,7 @@ public final class PsiUtil extends PsiUtilBase {
}
} else {
final PsiClass superClass = clazz.getSuperClass();
return superClass == null || hasDefaultConstructor(superClass);
return superClass == null || hasDefaultConstructor(superClass, true);
}
return false;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

@@ -15,11 +15,43 @@
*/
package com.intellij.formatting;
import com.intellij.openapi.diagnostic.Logger;
/**
* The indent setting for a formatting model block. Indicates how the block is indented
* relative to its parent block.
* <p/>
* Number of factory methods of this class use <code>'indent relative to direct parent'</code> flag. It specified anchor parent block
* to use to apply indent.
* <p/>
* Consider the following situation:
* <p/>
* <pre>
* return a == 0
&& (b == 0
|| c == 0);
* </pre>
* <p/>
* Here is the following blocks hierarchy (going from child to parent):
* <p/>
* <ul>
* <li><code>'|| c == 0`</code>;</li>
* <li><code>'b == 0 || c == 0'</code>;</li>
* <li><code>'(b == 0 || c == 0)'</code>;</li>
* <li><code>'a == 0 && (b == 0 || c == 0)'</code>;</li>
* <li><code>'return a == 0 && (b == 0 || c == 0)'</code>;</li>
* </ul>
* <p/>
* By default formatter applies block indent to the first block ancestor (direct or indirect) that starts on a new line. That means
* that such an ancestor for both blocks <code>'|| c == 0'</code> and <code>'&& (b == 0 || c == 0)'</code>
* is <code>'return a == 0 && (b == 0 || c == 0)'</code>. That means that the code above is formatted as follows:
* <p/>
* <pre>
* return a == 0
* && (b == 0
* || c == 0);
* </pre>
* <p/>
* In contrast, it's possible to specify that direct parent block that starts on a line before target child block is used as an anchor.
* Initial formatting example illustrates such approach.
*
* @see com.intellij.formatting.Block#getIndent()
* @see com.intellij.formatting.ChildAttributes#getChildIndent()
@@ -28,8 +60,6 @@ import com.intellij.openapi.diagnostic.Logger;
public abstract class Indent {
private static IndentFactory myFactory;
private static final Logger LOG = Logger.getInstance("#com.intellij.formatting.Indent");
static void setFactory(IndentFactory factory) {
myFactory = factory;
}
@@ -37,11 +67,26 @@ public abstract class Indent {
/**
* Returns an instance of a regular indent, with the width specified
* in "Project Code Style | General | Indent".
* <p/>
* <b>Note:</b> returned indent is not set to be <code>'relative'</code> to it's direct parent block
*
* @return the indent instance.
* @see #getNormalIndent(boolean)
*/
public static Indent getNormalIndent() {
return myFactory.getNormalIndent();
return myFactory.getNormalIndent(false);
}
/**
* Returns an instance of a regular indent, with the width specified
* in "Project Code Style | General | Indent" and given <code>'relative to direct parent'</code> flag
*
* @param relativeToDirectParent flag the indicates if current indent object anchors direct block parent (feel free
* to get more information about that at class-level javadoc)
* @return newly created indent instance configured in accordance with the given parameter
*/
public static Indent getNormalIndent(boolean relativeToDirectParent) {
return myFactory.getNormalIndent(relativeToDirectParent);
}
/**
@@ -90,11 +135,27 @@ public abstract class Indent {
* Returns the "continuation" indent instance, indicating that the block will be indented by
* the number of spaces indicated in the "Project Code Style | General | Continuation indent"
* setting relative to its parent block.
* <p/>
* <b>Note:</b> returned indent is not set to be <code>'relative'</code> to it's direct parent block
*
* @return the indent instance.
* @see #getContinuationIndent(boolean)
*/
public static Indent getContinuationIndent() {
return myFactory.getContinuationIndent();
return myFactory.getContinuationIndent(false);
}
/**
* Returns the "continuation" indent instance, indicating that the block will be indented by
* the number of spaces indicated in the "Project Code Style | General | Continuation indent"
* setting relative to its parent block and given <code>'relative to direct parent'</code> flag.
*
* @param relativeToDirectParent flag the indicates if current indent object anchors direct block parent (feel free
* to get more information about that at class-level javadoc)
* @return newly created indent instance configured in accordance with the given parameter
*/
public static Indent getContinuationIndent(boolean relativeToDirectParent) {
return myFactory.getContinuationIndent(relativeToDirectParent);
}
/**
@@ -103,20 +164,54 @@ public abstract class Indent {
* setting relative to its parent block, unless this block is the first of the children of its
* parent having the same indent type. This is used for things like parameter lists, where the first parameter
* does not have any indent and the remaining parameters are indented by the continuation indent.
* <p/>
* <b>Note:</b> returned indent is not set to be <code>'relative'</code> to it's direct parent block
*
* @return the indent instance.
* @see #getContinuationWithoutFirstIndent(boolean)
*/
public static Indent getContinuationWithoutFirstIndent() {//is default
return myFactory.getContinuationWithoutFirstIndent();
return myFactory.getContinuationWithoutFirstIndent(false);
}
/**
* Returns the "continuation without first" indent instance, indicating that the block will
* be indented by the number of spaces indicated in the "Project Code Style | General | Continuation indent"
* setting relative to its parent block, unless this block is the first of the children of its
* parent having the same indent type. This is used for things like parameter lists, where the first parameter
* does not have any indent and the remaining parameters are indented by the continuation indent and given
* <code>'relative to direct parent'</code> flag.
*
* @param relativeToDirectParent flag the indicates if current indent object anchors direct block parent (feel free
* to get more information about that at class-level javadoc)
* @return newly created indent instance configured in accordance with the given parameter
*/
public static Indent getContinuationWithoutFirstIndent(boolean relativeToDirectParent) {
return myFactory.getContinuationWithoutFirstIndent(relativeToDirectParent);
}
/**
* Returns an indent with the specified width.
* <p/>
* <b>Note:</b> returned indent is not set to be <code>'relative'</code> to it's direct parent block
*
* @param spaces the number of spaces in the indent.
* @return the indent instance.
* @see #getSpaceIndent(int, boolean)
*/
public static Indent getSpaceIndent(final int spaces) {
return myFactory.getSpaceIndent(spaces);
return myFactory.getSpaceIndent(spaces, false);
}
/**
* Returns an indent with the specified width and given <code>'relative to direct parent'</code> flag.
*
* @param spaces the number of spaces in the indent
* @param relativeToDirectParent flag the indicates if current indent object anchors direct block parent (feel free
* to get more information about that at class-level javadoc)
* @return newly created indent instance configured in accordance with the given parameter
*/
public static Indent getSpaceIndent(final int spaces, final boolean relativeToDirectParent) {
return myFactory.getSpaceIndent(spaces, relativeToDirectParent);
}
}
@@ -17,15 +17,17 @@ package com.intellij.formatting;
/**
* Internal interface for creating indent instances.
* <p/>
* Methods of this interface define contract for implementing {@link Indent} factory methods, so, feel free to check
* their contracts.
*/
interface IndentFactory {
public abstract Indent getNormalIndent();
public abstract Indent getNoneIndent();
public abstract Indent getAbsoluteNoneIndent();
public abstract Indent getAbsoluteLabelIndent();
public abstract Indent getLabelIndent();
public abstract Indent getContinuationIndent();
public abstract Indent getContinuationWithoutFirstIndent();//is default
public abstract Indent getSpaceIndent(final int spaces);
Indent getNormalIndent(boolean relativeToDirectParent);
Indent getNoneIndent();
Indent getAbsoluteNoneIndent();
Indent getAbsoluteLabelIndent();
Indent getLabelIndent();
Indent getContinuationIndent(boolean relativeToDirectParent);
Indent getContinuationWithoutFirstIndent(boolean relativeToDirectParent);
Indent getSpaceIndent(final int spaces, boolean relativeToDirectParent);
}
@@ -19,6 +19,20 @@ package com.intellij.openapi.roots;
import org.jdom.Element;
/**
* The table below specifies which order entries are used during compilation and runtime.
* <table border=1>
* <thead><td></td><td>Production<br/>Compile</td><td>Production<br/>Runtime</td>
* <td>Test<br/>Compile</td><td>Test<br/>Runtime</td></thead>
* <tbody>
* <tr><td>{@link #COMPILE}</td> <td>*</td><td>*</td><td>*</td><td>*</td></tr>
* <tr><td>{@link #TEST}</td> <td> </td><td> </td><td>*</td><td>*</td></tr>
* <tr><td>{@link #RUNTIME}</td> <td> </td><td>*</td><td> </td><td>*</td></tr>
* <tr><td>{@link #PROVIDED}</td> <td>*</td><td> </td><td>*</td><td>*</td></tr>
* <tr><td>Production<br/>Output</td> <td> </td><td>*</td><td>*</td><td>*</td></tr>
* <tr><td>Test<br/>Output</td> <td> </td><td> </td><td> </td><td>*</td></tr>
* </tbody>
* </table>
*
* @author yole
*/
public enum DependencyScope {
@@ -425,18 +425,19 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
public boolean ALIGN_MULTILINE_TERNARY_OPERATION = false;
public boolean ALIGN_MULTILINE_THROWS_LIST = false;
public boolean ALIGN_MULTILINE_EXTENDS_LIST = false;
public boolean ALIGN_MULTILINE_METHOD_BRACKETS = false;
public boolean ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION = false;
public boolean ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION = false;
//----------------- Group alignments ---------------
/**
* Specifies if subsequent fields/variables declarations and initialisations should be aligned in columns like below:
* int start = 1;
* int end = 10;
*/
public boolean ALIGN_MULTILINE_SUBSEQUENT_DECLARATIONS = false;
public boolean ALIGN_MULTILINE_EXTENDS_LIST = false;
public boolean ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION = false;
public boolean ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION = false;
//----------------- Group alignments ---------------
public boolean ALIGN_GROUP_FIELDS_VARIABLES = false;
public boolean ALIGN_GROUP_FIELD_DECLARATIONS = false;
@@ -73,6 +73,7 @@ public class CodeStyleIndentAndBracesPanel extends MultilanguageCodeStyleAbstrac
private JCheckBox myAlignChainedMethods;
private JCheckBox myAlignDeclarationParameters;
private JCheckBox myAlignCallParameters;
private JCheckBox myAlignMethodBrackets;
private JCheckBox myAlignExtendsList;
private JCheckBox myAlignForStatement;
private JCheckBox myAlignThrowsList;
@@ -206,13 +207,16 @@ public class CodeStyleIndentAndBracesPanel extends MultilanguageCodeStyleAbstrac
myAlignCallParameters = createCheckBox(ApplicationBundle.message("checkbox.align.multiline.call.arguments"));
optionGroup.add(myAlignCallParameters);
myAlignMethodBrackets = createCheckBox(ApplicationBundle.message("checkbox.align.multiline.method.parentheses"));
optionGroup.add(myAlignMethodBrackets);
myAlignExtendsList = createCheckBox(ApplicationBundle.message("checkbox.align.multiline.extends.list"));
optionGroup.add(myAlignExtendsList);
myAlignThrowsList = createCheckBox(ApplicationBundle.message("checkbox.align.multiline.throws.list"));
optionGroup.add(myAlignThrowsList);
myAlignSubsequentDeclarations = createCheckBox(ApplicationBundle.message("checkbox.align.multiline.subsequent.declarations"));
myAlignSubsequentDeclarations = createCheckBox(ApplicationBundle.message("checkbox.align.multiline.fields.variables.groups"));
optionGroup.add(myAlignSubsequentDeclarations);
myAlignParenthesizedExpression = createCheckBox(ApplicationBundle.message("checkbox.align.multiline.parenthesized.expression"));
@@ -325,13 +329,14 @@ public class CodeStyleIndentAndBracesPanel extends MultilanguageCodeStyleAbstrac
isModified |= isModified(myAlignAssignment, settings.ALIGN_MULTILINE_ASSIGNMENT);
isModified |= isModified(myAlignBinaryExpression, settings.ALIGN_MULTILINE_BINARY_OPERATION);
isModified |= isModified(myAlignCallParameters, settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS);
isModified |= isModified(myAlignMethodBrackets, settings.ALIGN_MULTILINE_METHOD_BRACKETS);
isModified |= isModified(myAlignDeclarationParameters, settings.ALIGN_MULTILINE_PARAMETERS);
isModified |= isModified(myAlignExtendsList, settings.ALIGN_MULTILINE_EXTENDS_LIST);
isModified |= isModified(myAlignForStatement, settings.ALIGN_MULTILINE_FOR);
isModified |= isModified(myAlignParenthesizedExpression, settings.ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION);
isModified |= isModified(myAlignTernaryExpression, settings.ALIGN_MULTILINE_TERNARY_OPERATION);
isModified |= isModified(myAlignThrowsList, settings.ALIGN_MULTILINE_THROWS_LIST);
isModified |= isModified(myAlignSubsequentDeclarations, settings.ALIGN_MULTILINE_SUBSEQUENT_DECLARATIONS);
isModified |= isModified(myAlignSubsequentDeclarations, settings.ALIGN_GROUP_FIELDS_VARIABLES);
isModified |= isModified(myAlignArrayInitializerExpression, settings.ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION);
isModified |= settings.FOR_BRACE_FORCE != getForceBracesValue(myForForceCombo);
@@ -370,6 +375,7 @@ public class CodeStyleIndentAndBracesPanel extends MultilanguageCodeStyleAbstrac
myAlignAssignment.setSelected(settings.ALIGN_MULTILINE_ASSIGNMENT);
myAlignBinaryExpression.setSelected(settings.ALIGN_MULTILINE_BINARY_OPERATION);
myAlignCallParameters.setSelected(settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS);
myAlignMethodBrackets.setSelected(settings.ALIGN_MULTILINE_METHOD_BRACKETS);
myAlignChainedMethods.setSelected(settings.ALIGN_MULTILINE_CHAINED_METHODS);
myAlignDeclarationParameters.setSelected(settings.ALIGN_MULTILINE_PARAMETERS);
myAlignExtendsList.setSelected(settings.ALIGN_MULTILINE_EXTENDS_LIST);
@@ -377,7 +383,7 @@ public class CodeStyleIndentAndBracesPanel extends MultilanguageCodeStyleAbstrac
myAlignParenthesizedExpression.setSelected(settings.ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION);
myAlignTernaryExpression.setSelected(settings.ALIGN_MULTILINE_TERNARY_OPERATION);
myAlignThrowsList.setSelected(settings.ALIGN_MULTILINE_THROWS_LIST);
myAlignSubsequentDeclarations.setSelected(settings.ALIGN_MULTILINE_SUBSEQUENT_DECLARATIONS);
myAlignSubsequentDeclarations.setSelected(settings.ALIGN_GROUP_FIELDS_VARIABLES);
myAlignArrayInitializerExpression.setSelected(settings.ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION);
setForceBracesComboValue(myForForceCombo, settings.FOR_BRACE_FORCE);
@@ -410,6 +416,7 @@ public class CodeStyleIndentAndBracesPanel extends MultilanguageCodeStyleAbstrac
settings.ALIGN_MULTILINE_ASSIGNMENT = myAlignAssignment.isSelected();
settings.ALIGN_MULTILINE_BINARY_OPERATION = myAlignBinaryExpression.isSelected();
settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = myAlignCallParameters.isSelected();
settings.ALIGN_MULTILINE_METHOD_BRACKETS = myAlignMethodBrackets.isSelected();
settings.ALIGN_MULTILINE_CHAINED_METHODS = myAlignChainedMethods.isSelected();
settings.ALIGN_MULTILINE_PARAMETERS = myAlignDeclarationParameters.isSelected();
settings.ALIGN_MULTILINE_EXTENDS_LIST = myAlignExtendsList.isSelected();
@@ -417,7 +424,7 @@ public class CodeStyleIndentAndBracesPanel extends MultilanguageCodeStyleAbstrac
settings.ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION = myAlignParenthesizedExpression.isSelected();
settings.ALIGN_MULTILINE_TERNARY_OPERATION = myAlignTernaryExpression.isSelected();
settings.ALIGN_MULTILINE_THROWS_LIST = myAlignThrowsList.isSelected();
settings.ALIGN_MULTILINE_SUBSEQUENT_DECLARATIONS = myAlignSubsequentDeclarations.isSelected();
settings.ALIGN_GROUP_FIELDS_VARIABLES = myAlignSubsequentDeclarations.isSelected();
settings.ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION = myAlignArrayInitializerExpression.isSelected();
// mySettings.LABEL_INDENT =
@@ -49,6 +49,7 @@ import java.util.List;
*/
public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
private final AnnotationHolderImpl myAnnotationHolder = new AnnotationHolderImpl() {
// need synchronize since several annotators can run concurrently
@Override
protected synchronized Annotation createAnnotation(TextRange range, HighlightSeverity severity, String message) {
return super.createAnnotation(range, severity, message);
@@ -58,10 +59,12 @@ public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
public static final ExtensionPointName<HighlightErrorFilter> FILTER_EP_NAME = ExtensionPointName.create("com.intellij.highlightErrorFilter");
private final HighlightErrorFilter[] myErrorFilters;
private final Project myProject;
private final DumbService myDumbService;
public DefaultHighlightVisitor(Project project) {
myProject = project;
myErrorFilters = Extensions.getExtensions(FILTER_EP_NAME, project);
myDumbService = DumbService.getInstance(project);
}
public boolean suitableForFile(final PsiFile file) {
@@ -120,7 +123,7 @@ public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
private void runAnnotators(final PsiElement element, HighlightInfoHolder holder, final AnnotationHolderImpl annotationHolder) {
List<Annotator> annotators = cachedAnnotators.get(element.getLanguage());
if (annotators.isEmpty()) return;
final boolean dumb = DumbService.getInstance(myProject).isDumb();
final boolean dumb = myDumbService.isDumb();
JobUtil.invokeConcurrentlyUnderMyProgress(annotators, new Processor<Annotator>() {
public boolean process(Annotator annotator) {
@@ -27,6 +27,7 @@ import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actions.EditorActionUtil;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
@@ -530,7 +531,8 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
}
public static void printToConsole(final LanguageConsoleImpl console, final String string, final TextAttributes textAttributes) {
final TextAttributes attributes = TextAttributes.merge(ConsoleHighlighter.OUT.getDefaultAttributes(), textAttributes);
final TextAttributes outAttrs = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(ConsoleHighlighter.OUT);
final TextAttributes attributes = TextAttributes.merge(outAttrs, textAttributes);
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
console.printToHistory(string, attributes);
@@ -35,10 +35,6 @@ public abstract class AbstractBlockWrapper {
IndentImpl.Type.NORMAL, IndentImpl.Type.CONTINUATION, IndentImpl.Type.CONTINUATION_WITHOUT_FIRST
));
private static final Set<IndentImpl.Type> CONTINUATION_INDENT_TYPES = new HashSet<IndentImpl.Type>(asList(
IndentImpl.Type.CONTINUATION, IndentImpl.Type.CONTINUATION_WITHOUT_FIRST
));
protected WhiteSpace myWhiteSpace;
protected CompositeBlockWrapper myParent;
protected int myStart;
@@ -194,9 +190,7 @@ public abstract class AbstractBlockWrapper {
}
return childIndent;
}
else if (options.USE_RELATIVE_INDENTS && child.getStartOffset() > getStartOffset()
&& (CONTINUATION_INDENT_TYPES.contains(childIndentType)))
{
else if (child.getIndent().isRelativeToDirectParent() && child.getStartOffset() > getStartOffset()) {
return childIndent.add(getNumberOfSymbolsBeforeBlock());
}
}
@@ -286,7 +280,7 @@ public abstract class AbstractBlockWrapper {
int index) {
IndentImpl childIndent = (IndentImpl)childAttributes.getChildIndent();
if (childIndent == null) childIndent = (IndentImpl)Indent.getContinuationWithoutFirstIndent();
if (childIndent == null) childIndent = (IndentImpl)Indent.getContinuationWithoutFirstIndent(indentOption.USE_RELATIVE_INDENTS);
IndentData indent = getIndent(indentOption, index, childIndent);
if (myParent == null) {
@@ -92,7 +92,7 @@ class AlignmentImpl extends Alignment {
* {@link #setParent(Alignment) its parent} using the algorithm above if any; <code>null</code> otherwise
*/
@Nullable
LeafBlockWrapper getOffsetRespBlockBefore(final AbstractBlockWrapper block) {
LeafBlockWrapper getOffsetRespBlockBefore(@Nullable final AbstractBlockWrapper block) {
if (!continueOffsetResponsibleBlockRetrieval(block)) {
return null;
}
@@ -152,7 +152,11 @@ class AlignmentImpl extends Alignment {
myOffsetRespBlocks.add(block);
}
private boolean continueOffsetResponsibleBlockRetrieval(AbstractBlockWrapper block) {
private boolean continueOffsetResponsibleBlockRetrieval(@Nullable AbstractBlockWrapper block) {
// We don't want to align block that doesn't start new line if it's not configured for 'by columns' alignment.
if (!myAllowBackwardShift && block != null && !block.getWhiteSpace().containsLineFeeds()) {
return false;
}
for (AbstractBlockWrapper offsetBlock : myOffsetRespBlocks) {
if (offsetBlock == block) {
continue;
@@ -892,7 +892,7 @@ class FormatProcessor {
}
}
private static int getAlignOffsetBefore(final Alignment alignment, final LeafBlockWrapper blockAfter) {
private static int getAlignOffsetBefore(final Alignment alignment, @Nullable final LeafBlockWrapper blockAfter) {
if (alignment == null) return -1;
final LeafBlockWrapper alignRespBlock = ((AlignmentImpl)alignment).getOffsetRespBlockBefore(blockAfter);
if (alignRespBlock != null) {
@@ -43,13 +43,18 @@ public class FormatterImpl extends FormatterEx
private static final Logger LOG = Logger.getInstance("#com.intellij.formatting.FormatterImpl");
private int myIsDisabledCount = 0;
private final IndentImpl NONE_INDENT = new IndentImpl(IndentImpl.Type.NONE, false);
private final IndentImpl myAbsoluteNoneIndent = new IndentImpl(IndentImpl.Type.NONE, true);
private final IndentImpl myLabelIndent = new IndentImpl(IndentImpl.Type.LABEL, false);
private final IndentImpl myContinuationIndent = new IndentImpl(IndentImpl.Type.CONTINUATION, false);
private final IndentImpl myContinutationWithoutFirstIndent = new IndentImpl(IndentImpl.Type.CONTINUATION_WITHOUT_FIRST, false);
private final IndentImpl myAbsoluteLabelIndent = new IndentImpl(IndentImpl.Type.LABEL, true);
private final IndentImpl myNormalIndent = new IndentImpl(IndentImpl.Type.NORMAL, false);
private final IndentImpl NONE_INDENT = new IndentImpl(IndentImpl.Type.NONE, false, false);
private final IndentImpl myAbsoluteNoneIndent = new IndentImpl(IndentImpl.Type.NONE, true, false);
private final IndentImpl myLabelIndent = new IndentImpl(IndentImpl.Type.LABEL, false, false);
private final IndentImpl myContinuationIndentRelativeToDirectParent = new IndentImpl(IndentImpl.Type.CONTINUATION, false, true);
private final IndentImpl myContinuationIndentNotRelativeToDirectParent = new IndentImpl(IndentImpl.Type.CONTINUATION, false, false);
private final IndentImpl myContinuationWithoutFirstIndentRelativeToDirectParent
= new IndentImpl(IndentImpl.Type.CONTINUATION_WITHOUT_FIRST, false, true);
private final IndentImpl myContinuationWithoutFirstIndentNotRelativeToDirectParent
= new IndentImpl(IndentImpl.Type.CONTINUATION_WITHOUT_FIRST, false, false);
private final IndentImpl myAbsoluteLabelIndent = new IndentImpl(IndentImpl.Type.LABEL, true, false);
private final IndentImpl myNormalIndentRelativeToDirectParent = new IndentImpl(IndentImpl.Type.NORMAL, false, true);
private final IndentImpl myNormalIndentNotRelativeToDirectParent = new IndentImpl(IndentImpl.Type.NORMAL, false, false);
private final SpacingImpl myReadOnlySpacing = new SpacingImpl(0, 0, 0, true, false, true, 0, false, 0);
public FormatterImpl() {
@@ -70,8 +75,8 @@ public class FormatterImpl extends FormatterEx
return result;
}
public Indent getNormalIndent() {
return myNormalIndent;
public Indent getNormalIndent(boolean relative) {
return relative ? myNormalIndentRelativeToDirectParent : myNormalIndentNotRelativeToDirectParent;
}
public Indent getNoneIndent() {
@@ -500,8 +505,8 @@ public class FormatterImpl extends FormatterEx
return new PsiBasedFormattingModel(file, rootBlock, FormattingDocumentModelImpl.createOn(file));
}
public Indent getSpaceIndent(final int spaces) {
return new IndentImpl(IndentImpl.Type.SPACES, false, spaces);
public Indent getSpaceIndent(final int spaces, final boolean relative) {
return new IndentImpl(IndentImpl.Type.SPACES, false, spaces, relative);
}
public Indent getAbsoluteLabelIndent() {
@@ -562,13 +567,13 @@ public class FormatterImpl extends FormatterEx
return myLabelIndent;
}
public Indent getContinuationIndent() {
return myContinuationIndent;
public Indent getContinuationIndent(boolean relative) {
return relative ? myContinuationIndentRelativeToDirectParent : myContinuationIndentNotRelativeToDirectParent;
}
public Indent getContinuationWithoutFirstIndent()//is default
public Indent getContinuationWithoutFirstIndent(boolean relative)//is default
{
return myContinutationWithoutFirstIndent;
return relative ? myContinuationWithoutFirstIndentRelativeToDirectParent : myContinuationWithoutFirstIndentNotRelativeToDirectParent;
}
private final Object DISABLING_LOCK = new Object();
@@ -20,14 +20,7 @@ import org.jetbrains.annotations.NonNls;
class IndentImpl extends Indent {
private final boolean myIsAbsolute;
public boolean isContinuation() {
return myType == Type.CONTINUATION_WITHOUT_FIRST;
}
public boolean isNone() {
return getType() == Type.NONE;
}
private final boolean myRelativeToDirectParent;
static class Type{
private final String myName;
@@ -52,14 +45,15 @@ class IndentImpl extends Indent {
private final Type myType;
private final int mySpaces;
public IndentImpl(final Type type, boolean absolute, final int spaces) {
public IndentImpl(final Type type, boolean absolute, final int spaces, boolean relativeToDirectParent) {
myType = type;
myIsAbsolute = absolute;
mySpaces = spaces;
myRelativeToDirectParent = relativeToDirectParent;
}
public IndentImpl(final Type type, boolean absolute) {
this(type, absolute, 0);
public IndentImpl(final Type type, boolean absolute, boolean relativeToDirectParent) {
this(type, absolute, 0, relativeToDirectParent);
}
Type getType() {
@@ -77,6 +71,18 @@ class IndentImpl extends Indent {
return myIsAbsolute;
}
/**
* Allows to answer if current indent object is configured to anchor direct parent that lays on a different line.
* <p/>
* Feel free to check {@link Indent} class-level javadoc in order to get more information and examples about expected
* usage of this property.
*
* @return flag that indicates if this indent should anchor direct parent that lays on a different line
*/
public boolean isRelativeToDirectParent() {
return myRelativeToDirectParent;
}
@NonNls
@Override
public String toString() {
@@ -205,11 +205,11 @@ class InitialInfoBuilder {
return info;
}
private static void setDefaultIndents(final List<AbstractBlockWrapper> list) {
private void setDefaultIndents(final List<AbstractBlockWrapper> list) {
if (!list.isEmpty()) {
for (AbstractBlockWrapper wrapper : list) {
if (wrapper.getIndent() == null) {
wrapper.setIndent((IndentImpl)Indent.getContinuationWithoutFirstIndent());
wrapper.setIndent((IndentImpl)Indent.getContinuationWithoutFirstIndent(myOptions.USE_RELATIVE_INDENTS));
}
}
}
@@ -83,6 +83,6 @@ public class FileListPasteProvider implements PasteProvider {
public boolean isPasteEnabled(DataContext dataContext) {
final Transferable contents = CopyPasteManager.getInstance().getContents();
final IdeView ideView = LangDataKeys.IDE_VIEW.getData(dataContext);
return contents.isDataFlavorSupported(DataFlavor.javaFileListFlavor) && ideView != null;
return contents != null && contents.isDataFlavorSupported(DataFlavor.javaFileListFlavor) && ideView != null;
}
}
@@ -163,18 +163,20 @@ public class FileTemplateUtil{
return mergeTemplate(content, context);
}
private static String mergeTemplate(String templateContent, final VelocityContext context) throws IOException{
private static String mergeTemplate(String templateContent, final VelocityContext context) throws IOException {
initVelocity();
StringWriter stringWriter = new StringWriter();
try {
Velocity.evaluate(context, stringWriter, "", templateContent);
} catch (VelocityException e) {
}
catch (VelocityException e) {
LOG.error("Error evaluating template:\n"+templateContent,e);
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
Messages.showErrorDialog(IdeBundle.message("error.parsing.file.template"),
IdeBundle.message("title.velocity.error"));
}
});
public void run() {
Messages.showErrorDialog(IdeBundle.message("error.parsing.file.template"),
IdeBundle.message("title.velocity.error"));
}
});
}
return stringWriter.toString();
}
@@ -52,7 +52,7 @@ public final class NamedLibraryElement {
final NamedLibraryElement namedLibraryElement = (NamedLibraryElement)o;
if (!myEntry.equals(namedLibraryElement.myEntry)) return false;
if (Comparing.equal(myContextModule, namedLibraryElement.myContextModule)) return false;
if (!Comparing.equal(myContextModule, namedLibraryElement.myContextModule)) return false;
return true;
}
@@ -29,4 +29,8 @@ public abstract class ModuleRendererFactory {
}
public abstract DefaultListCellRenderer getModuleRenderer();
public boolean rendersLocationString() {
return false;
}
}
@@ -55,12 +55,18 @@ public class NavigationItemListCellRenderer extends JPanel implements ListCellRe
Font editorFont = new Font(scheme.getEditorFontName(), Font.PLAIN, scheme.getEditorFontSize());
setFont(editorFont);
removeAll();
final Component leftCellRendererComponent =
new LeftRenderer().getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
final boolean hasRightRenderer = UISettings.getInstance().SHOW_ICONS_IN_QUICK_NAVIGATION;
final ModuleRendererFactory factory = ModuleRendererFactory.getInstance();
final LeftRenderer left = new LeftRenderer(!hasRightRenderer || !factory.rendersLocationString());
final Component leftCellRendererComponent = left.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
final Color listBg = leftCellRendererComponent.getBackground();
add(leftCellRendererComponent, BorderLayout.WEST);
if (UISettings.getInstance().SHOW_ICONS_IN_QUICK_NAVIGATION){
final DefaultListCellRenderer moduleRenderer = ModuleRendererFactory.getInstance().getModuleRenderer();
if (hasRightRenderer){
final DefaultListCellRenderer moduleRenderer = factory.getModuleRenderer();
final Component rightCellRendererComponent =
moduleRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
rightCellRendererComponent.setBackground(listBg);
@@ -76,6 +82,12 @@ public class NavigationItemListCellRenderer extends JPanel implements ListCellRe
}
private static class LeftRenderer extends ColoredListCellRenderer {
public final boolean myRenderLocation;
public LeftRenderer(boolean renderLocation) {
myRenderLocation = renderLocation;
}
protected void customizeCellRenderer(
JList list,
Object value,
@@ -129,10 +141,12 @@ public class NavigationItemListCellRenderer extends JPanel implements ListCellRe
append(name, nameAttributes);
setIcon(presentation.getIcon(false));
String containerText = presentation.getLocationString();
if (myRenderLocation) {
String containerText = presentation.getLocationString();
if (containerText != null && containerText.length() > 0) {
append(" " + containerText, new SimpleTextAttributes(Font.PLAIN, Color.GRAY));
if (containerText != null && containerText.length() > 0) {
append(" " + containerText, new SimpleTextAttributes(Font.PLAIN, Color.GRAY));
}
}
}
else {
@@ -16,6 +16,8 @@
package com.intellij.ide.util;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.NavigationItem;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
@@ -33,7 +35,20 @@ public class PlatformModuleRendererFactory extends ModuleRendererFactory {
final boolean isSelected,
final boolean cellHasFocus) {
final Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
setText("");
String text = "";
if (value instanceof NavigationItem) {
final ItemPresentation presentation = ((NavigationItem)value).getPresentation();
if (presentation != null) {
String containerText = presentation.getLocationString();
if (containerText != null && containerText.length() > 0) {
text = " " + containerText;
}
}
}
setText(text);
setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2));
setHorizontalTextPosition(SwingConstants.LEFT);
setBackground(isSelected ? UIUtil.getListSelectionBackground() : UIUtil.getListBackground());
@@ -42,4 +57,9 @@ public class PlatformModuleRendererFactory extends ModuleRendererFactory {
}
};
}
@Override
public boolean rendersLocationString() {
return true;
}
}
@@ -278,8 +278,9 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
if (range.contains(offset) || range.getEndOffset() == offset/* in case of inserting at the end*/) {
TextRange rangeToModify = new TextRange(offset, Math.min(range.getEndOffset(), endOffset));
TextRange hostRangeToModify = rangeToModify.shiftRight(hostRange.getStartOffset() - curRangeStart);
CharSequence toReplace = i == myShreds.size() - 1 ? s : s.subSequence(0, Math.min(hostRangeToModify.getLength(), s.length()));
s = s.subSequence(toReplace.length(), s.length());
CharSequence toReplace = i == myShreds.size() - 1 || range.getEndOffset() + shred.suffix.length() >= endOffset
? s : s.subSequence(0, Math.min(hostRangeToModify.getLength(), s.length()));
s = toReplace == s ? "" : s.subSequence(toReplace.length(), s.length());
hostRangesToModify.add(Pair.create(hostRangeToModify, toReplace));
offset = rangeToModify.getEndOffset();
}
@@ -445,7 +445,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider {
protected void doOKAction() {
final String text = myEditor.getDocument().getText();
if (text.trim().length() == 0) return;
//if (text.trim().length() == 0) return;
myLastParsedText = text;
myLastParsedTextHashCode = text.hashCode();
@@ -69,7 +69,7 @@ public class RenameUtil {
PsiElement referenceElement = ref.getElement();
result.add(new MoveRenameUsageInfo(referenceElement, ref, ref.getRangeInElement().getStartOffset(),
ref.getRangeInElement().getEndOffset(), element,
!ref.isReferenceTo(element)));
ref.resolve() == null));
}
processor.findCollisions(element, newName, allRenames, result);
@@ -29,6 +29,7 @@ import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.ui.GuiUtils;
import com.intellij.util.ArrayUtil;
import com.intellij.util.io.ZipUtil;
import com.intellij.util.ui.OptionsDialog;
import org.jetbrains.annotations.NonNls;
@@ -38,6 +39,7 @@ import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URL;
import java.util.Arrays;
import java.util.HashSet;
@@ -192,12 +194,34 @@ public class BrowserUtil {
return new GeneralSettings();
}
private static boolean launchDefaultBrowserUsingJdk6Api(String sUrl) {
try {
Class desktopClass = BrowserUtil.class.getClassLoader().loadClass("java.awt.Desktop");
Object desktop = desktopClass.getMethod("getDesktop").invoke(null);
URL url = getURL(sUrl);
if (url == null) return false;
desktopClass.getMethod("browse", new Class[]{URI.class}).invoke(desktop, url.toURI());
return true;
}
catch (Exception e) {
return false;
}
}
public static void launchBrowser(String url, String name) {
if (url.startsWith("jar:")) {
url = extractFiles(url);
if (url == null) return;
}
if (canStartDefaultBrowser() && isUseDefaultBrowser()) {
if (launchDefaultBrowserUsingJdk6Api(url)) {
return;
}
launchBrowser(url, getDefaultBrowserCommand());
}
else {
@@ -372,7 +396,21 @@ public class BrowserUtil {
return true;
}
return false;
try {
Class desktopClass = BrowserUtil.class.getClassLoader().loadClass("java.awt.Desktop");
Object desktop = desktopClass.getMethod("getDesktop", ArrayUtil.EMPTY_CLASS_ARRAY).invoke(null);
Class browseActionClass = BrowserUtil.class.getClassLoader().loadClass("java.awt.Desktop$Action");
Object browseAction = browseActionClass.getField("BROWSE").get(null);
Object res = desktopClass.getMethod("isSupported", new Class[]{browseActionClass}).invoke(desktop, browseAction);
return (Boolean)res;
}
catch (Exception e) {
return false;
}
}
private static class ConfirmExtractDialog extends OptionsDialog {
@@ -46,6 +46,8 @@ import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.util.*;
@@ -139,6 +141,10 @@ public class AbstractTreeUi {
};
private final Set<DefaultMutableTreeNode> myNotForSmartExpand = new HashSet<DefaultMutableTreeNode>();
private TreePath myRequestedExpand;
private TreePath mySilentExpand;
private TreePath mySilentSelect;
private final ActionCallback myInitialized = new ActionCallback();
private BusyObject.Impl myBusyObject = new BusyObject.Impl() {
@Override
@@ -222,6 +228,20 @@ public class AbstractTreeUi {
Disposer.register(getBuilder(), uiNotify);
myTree.addFocusListener(myFocusListener);
myTree.addComponentListener(new ComponentListener() {
public void componentResized(ComponentEvent e) {
}
public void componentMoved(ComponentEvent e) {
}
public void componentShown(ComponentEvent e) {
}
public void componentHidden(ComponentEvent e) {
}
});
}
@@ -1247,6 +1267,30 @@ public class AbstractTreeUi {
return !node.isNodeAncestor((DefaultMutableTreeNode)myTree.getModel().getRoot());
}
private void expandSilently(TreePath path) {
assertIsDispatchThread();
try {
mySilentExpand = path;
getTree().expandPath(path);
}
finally {
mySilentExpand = null;
}
}
private void addSelectionSilently(TreePath path) {
assertIsDispatchThread();
try {
mySilentSelect = path;
getTree().getSelectionModel().addSelectionPath(path);
}
finally {
mySilentSelect = null;
}
}
private void expand(DefaultMutableTreeNode node, boolean canSmartExpand) {
expand(new TreePath(node.getPath()), canSmartExpand);
}
@@ -3074,11 +3118,26 @@ public class AbstractTreeUi {
if (!before.equals(all)) {
processInnerChange(new Runnable() {
public void run() {
Enumeration<TreePath> expanded = getTree().getExpandedDescendants(getPathFor(parentNode));
TreePath[] selected = getTree().getSelectionModel().getSelectionPaths();
parentNode.removeAllChildren();
for (TreeNode each : all) {
parentNode.add((MutableTreeNode)each);
}
myTreeModel.nodeStructureChanged(parentNode);
while (expanded.hasMoreElements()) {
expandSilently(expanded.nextElement());
}
if (selected != null) {
for (TreePath each : selected) {
if (!getTree().getSelectionModel().isPathSelected(each)) {
addSelectionSilently(each);
}
}
}
}
});
}
@@ -4021,6 +4080,8 @@ public class AbstractTreeUi {
private class MySelectionListener implements TreeSelectionListener {
public void valueChanged(final TreeSelectionEvent e) {
if (mySilentSelect != null && mySilentSelect.equals(e.getNewLeadSelectionPath())) return;
dropUpdaterStateIfExternalChange();
}
}
@@ -4028,10 +4089,12 @@ public class AbstractTreeUi {
private class MyExpansionListener implements TreeExpansionListener {
public void treeExpanded(TreeExpansionEvent event) {
dropUpdaterStateIfExternalChange();
final TreePath path = event.getPath();
if (mySilentExpand != null && mySilentExpand.equals(path)) return;
dropUpdaterStateIfExternalChange();
if (myRequestedExpand != null && !myRequestedExpand.equals(path)) {
getReady(AbstractTreeUi.this).doWhenDone(new Runnable() {
public void run() {
@@ -21,6 +21,18 @@ import com.intellij.util.xmlb.annotations.Attribute;
public class ServiceDescriptor {
@Attribute("serviceInterface")
public String serviceInterface;
@Attribute("serviceImplementation")
public String serviceImplementation;
@Attribute("overrides")
public boolean overrides = false;
public String getInterface() {
return serviceInterface != null ? serviceInterface : getImplementation();
}
public String getImplementation() {
return serviceImplementation;
}
}
@@ -45,7 +45,7 @@ public abstract class SwitchAction extends AnAction implements DumbAware {
SwitchingSession session = getSession(e);
if (session == null || session.isFinished()) {
SwitchProvider provider = getProvider(e);
session = new SwitchingSession(getManager(e), provider, (KeyEvent)e.getInputEvent(), null);
session = new SwitchingSession(getManager(e), provider, (KeyEvent)e.getInputEvent(), null, false);
initSession(e, session);
}
@@ -101,7 +101,7 @@ public class SwitchManager implements ProjectComponent, KeyEventDispatcher, AnAc
IdeFocusManager.getInstance(myProject).doWhenFocusSettlesDown(new Runnable() {
public void run() {
if (myWaitingForAutoInitSession) {
tryToInitSessionFromFocus(null);
tryToInitSessionFromFocus(null, false);
}
}
});
@@ -118,13 +118,13 @@ public class SwitchManager implements ProjectComponent, KeyEventDispatcher, AnAc
}
private ActionCallback tryToInitSessionFromFocus(@Nullable SwitchTarget preselected) {
private ActionCallback tryToInitSessionFromFocus(@Nullable SwitchTarget preselected, boolean showSpots) {
if (mySession != null && !mySession.isFinished()) return new ActionCallback.Rejected();
Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
SwitchProvider provider = SwitchProvider.KEY.getData(DataManager.getInstance().getDataContext(owner));
if (provider != null) {
return initSession(new SwitchingSession(this, provider, myAutoInitSessionEvent, preselected));
return initSession(new SwitchingSession(this, provider, myAutoInitSessionEvent, preselected, showSpots));
}
return new ActionCallback.Rejected();
@@ -132,7 +132,6 @@ public class SwitchManager implements ProjectComponent, KeyEventDispatcher, AnAc
private void cancelWaitingForAutoInit() {
myWaitingForAutoInitSession = false;
myAutoInitSessionEvent = null;
myInitSessionAlarm.cancelAllRequests();
}
@@ -212,12 +211,13 @@ public class SwitchManager implements ProjectComponent, KeyEventDispatcher, AnAc
public ActionCallback applySwitch() {
final ActionCallback result = new ActionCallback();
if (isSessionActive()) {
final boolean showSpots = mySession.isShowspots();
mySession.finish().doWhenDone(new AsyncResult.Handler<SwitchTarget>() {
public void run(final SwitchTarget switchTarget) {
mySession = null;
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(new Runnable() {
public void run() {
tryToInitSessionFromFocus(switchTarget).doWhenProcessed(new Runnable() {
tryToInitSessionFromFocus(switchTarget, showSpots).doWhenProcessed(new Runnable() {
public void run() {
result.setDone();
}
@@ -17,6 +17,7 @@ package com.intellij.ui.switcher;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.AbstractPainter;
import com.intellij.openapi.ui.Painter;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.AsyncResult;
import com.intellij.openapi.util.Disposer;
@@ -25,12 +26,16 @@ import com.intellij.openapi.wm.IdeGlassPane;
import com.intellij.openapi.wm.IdeGlassPaneUtil;
import com.intellij.openapi.wm.impl.content.GraphicsConfig;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.awt.RelativeRectangle;
import com.intellij.util.Alarm;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.util.*;
import java.util.List;
@@ -45,8 +50,7 @@ public class SwitchingSession implements KeyEventDispatcher, Disposable {
private LinkedHashSet<SwitchTarget> myTargets = new LinkedHashSet<SwitchTarget>();
private IdeGlassPane myGlassPane;
private Map<SwitchTarget, TargetPainer> myPainters = new Hashtable<SwitchTarget, TargetPainer>();
private JComponent myRootComponent;
private Component myRootComponent;
private SwitchTarget mySelection;
private SwitchTarget myStartSelection;
@@ -62,8 +66,19 @@ public class SwitchingSession implements KeyEventDispatcher, Disposable {
}
};
private SwitchManager myManager;
private Spotlight mySpotlight;
public SwitchingSession(SwitchManager mgr, SwitchProvider provider, KeyEvent e, @Nullable SwitchTarget preselected) {
private boolean myShowspots;
private Alarm myShowspotsAlarm;
private Runnable myShowspotsRunnable = new Runnable() {
public void run() {
if (!myShowspots) {
setShowspots(true);
}
}
};
public SwitchingSession(SwitchManager mgr, SwitchProvider provider, KeyEvent e, @Nullable SwitchTarget preselected, boolean showSpots) {
myManager = mgr;
myProvider = provider;
myInitialEvent = e;
@@ -103,15 +118,118 @@ public class SwitchingSession implements KeyEventDispatcher, Disposable {
myStartSelection = mySelection;
myGlassPane = IdeGlassPaneUtil.find(myProvider.getComponent());
for (SwitchTarget each : myTargets) {
TargetPainer eachPainter = new TargetPainer(each);
Disposer.register(this, eachPainter);
myRootComponent = myProvider.getComponent().getRootPane();
mySpotlight = new Spotlight(myRootComponent);
myGlassPane.addPainter(myRootComponent, mySpotlight, this);
myRootComponent = myProvider.getComponent();
myGlassPane.addPainter(each.getComponent(), eachPainter, this);
myPainters.put(each, eachPainter);
myShowspotsAlarm = new Alarm(this);
restartShowspotsAlarm();
myShowspots = showSpots;
mySpotlight.setNeedsRepaint(true);
}
private class Spotlight extends AbstractPainter {
private Component myRoot;
private Area myArea;
private BufferedImage myBackground;
private Spotlight(Component root) {
myRoot = root;
}
@Override
public boolean needsRepaint() {
return true;
}
@Override
public void executePaint(Component component, Graphics2D g) {
int inset = -1;
int selectedInset = -8;
Set<Area> shapes = new HashSet<Area>();
Area selected = null;
boolean hasIntersections = false;
Rectangle clip = g.getClipBounds();
myArea = new Area(clip);
for (SwitchTarget each : myTargets) {
RelativeRectangle eachSimpleRec = each.getRectangle();
if (eachSimpleRec == null) continue;
boolean isSelected = each.equals(mySelection);
Rectangle eachBaseRec = eachSimpleRec.getRectangleOn(myRoot);
Rectangle eachShape;
if (isSelected) {
eachShape = new Rectangle(eachBaseRec.x + selectedInset,
eachBaseRec.y + selectedInset,
eachBaseRec.width - selectedInset -selectedInset,
eachBaseRec.height - selectedInset -selectedInset);
} else {
eachShape = new Rectangle(eachBaseRec.x + inset,
eachBaseRec.y + inset,
eachBaseRec.width - inset -inset,
eachBaseRec.height - inset -inset);
}
if (!hasIntersections) {
hasIntersections = clip.contains(eachShape) || clip.intersects(eachShape);
}
Area eachArea = new Area(new RoundRectangle2D.Double(eachShape.x, eachShape.y, eachShape.width, eachShape.height, 6, 6));
shapes.add(eachArea);
if (isSelected) {
selected = eachArea;
}
}
Color fillColor = new Color(0f, 0f, 0f, 0.25f);
if (!hasIntersections && myShowspots) {
g.setColor(fillColor);
g.fillRect(clip.x, clip.y, clip.width, clip.height);
return;
}
for (Area each : shapes) {
myArea.subtract(each);
if (each != selected) {
each.subtract(selected);
}
}
GraphicsConfig cfg = new GraphicsConfig(g);
cfg.setAntialiasing(true);
if (myShowspots) {
g.setColor(fillColor);
g.fill(myArea);
g.setColor(Color.lightGray);
for (Shape each : shapes) {
if (each != selected) {
g.draw(each);
}
}
}
if (selected != null) {
Color bg = Color.darkGray;
g.setColor(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(), 180));
g.setStroke(new BasicStroke(3));
g.draw(selected);
}
cfg.restore();
}
}
public boolean dispatchKeyEvent(KeyEvent e) {
@@ -132,59 +250,6 @@ public class SwitchingSession implements KeyEventDispatcher, Disposable {
return mySelectionWasMoved;
}
private class TargetPainer extends AbstractPainter implements Disposable {
private SwitchTarget myTarget;
private RelativePoint myPoint;
private TargetPainer(SwitchTarget target) {
myTarget = target;
}
@Override
public void executePaint(Component component, Graphics2D g) {
GraphicsConfig cfg = new GraphicsConfig(g);
cfg.setAntialiasing(true);
g.setColor(Color.red);
Rectangle paintRect = myTarget.getRectangle().getRectangleOn(component);
boolean selected = myTarget.equals(getSelection());
if (selected) {
g.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, new float[] {2, 4}, 0));
g.draw(paintRect);
} else {
g.setColor(Color.red);
int d = 6;
int dX = 4;
int dY = -4;
g.fillOval(paintRect.x + dX - d / 2, paintRect.y + paintRect.height + dY - d / 2, d, d);
}
if (myPoint != null) {
g.setColor(Color.green);
Point p = myPoint.getPoint(component);
//g.fillOval(p.x - 2, p.y - 2, 4, 4);
}
cfg.restore();
}
public void setPoint(RelativePoint point) {
myPoint = point;
}
@Override
public boolean needsRepaint() {
return true;
}
public void dispose() {
myGlassPane.removePainter(this);
}
}
private enum Direction {
up, down, left, right
}
@@ -212,12 +277,12 @@ public class SwitchingSession implements KeyEventDispatcher, Disposable {
mySelectionWasMoved = !mySelection.equals(myStartSelection);
for (TargetPainer each : myPainters.values()) {
each.setNeedsRepaint(true);
}
mySpotlight.setNeedsRepaint(true);
myAutoApply.cancelAllRequests();
myAutoApply.addRequest(myAutoApplyRunnable, Registry.intValue("actionSystem.autoSelectTimeout"));
restartShowspotsAlarm();
}
private SwitchTarget getNextTarget(Direction direction) {
@@ -263,13 +328,9 @@ public class SwitchingSession implements KeyEventDispatcher, Disposable {
}
points.add(selected);
target2Point.put(each, selected);
myPainters.get(each).setPoint(new RelativePoint(myRootComponent, selected));
} else {
points.add(eachPoint);
target2Point.put(each, eachPoint);
myPainters.get(each).setPoint(new RelativePoint(myRootComponent, eachPoint));
}
}
@@ -379,4 +440,20 @@ public class SwitchingSession implements KeyEventDispatcher, Disposable {
public boolean isFinished() {
return myFinished;
}
public void setShowspots(boolean showspots) {
if (myShowspots != showspots) {
myShowspots = showspots;
mySpotlight.setNeedsRepaint(true);
}
}
public boolean isShowspots() {
return myShowspots;
}
private void restartShowspotsAlarm() {
myShowspotsAlarm.cancelAllRequests();
myShowspotsAlarm.addRequest(myShowspotsRunnable, Registry.intValue("actionSystem.quickAccessShowSpotsTime"));
}
}
@@ -534,4 +534,9 @@ public class Tree extends JTree implements ComponentWithEmptyText, Autoscroll, Q
info.put("selectedNodes", nodesText.toString());
}
}
@Override
public void reshape(int x, int y, int w, int h) {
super.reshape(x, y, w, h);
}
}
@@ -54,8 +54,7 @@ public class PasswordSafeConfigurable implements SearchableConfigurable {
* {@inheritDoc}
*/
public String getHelpTopic() {
// TODO add help
return null;
return "reference.ide.settings.password.safe";
}
/**
@@ -57,11 +57,19 @@ public class ServiceManagerImpl implements BaseComponent {
myExtensionPointListener = new ExtensionPointListener<ServiceDescriptor>() {
public void extensionAdded(final ServiceDescriptor descriptor, final PluginDescriptor pluginDescriptor) {
if (descriptor.overrides) {
ComponentAdapter oldAdapter =
picoContainer.unregisterComponent(descriptor.getInterface());// Allow to re-define service implementations in plugins.
if (oldAdapter == null) {
throw new RuntimeException("Service: " + descriptor.getInterface() + " doesn't override anything");
}
}
picoContainer.registerComponent(new MyComponentAdapter(descriptor, pluginDescriptor, (ComponentManagerEx)componentManager));
}
public void extensionRemoved(final ServiceDescriptor extension, final PluginDescriptor pluginDescriptor) {
picoContainer.unregisterComponent(extension.serviceInterface);
picoContainer.unregisterComponent(extension.getInterface());
}
};
extensionPoint.addExtensionPointListener(myExtensionPointListener);
@@ -97,11 +105,11 @@ public class ServiceManagerImpl implements BaseComponent {
}
public Object getComponentKey() {
return myDescriptor.serviceInterface;
return myDescriptor.getInterface();
}
public Class getComponentImplementation() {
return loadClass(myDescriptor.serviceInterface);
return loadClass(myDescriptor.getInterface());
}
private Class loadClass(final String className) {
@@ -144,7 +152,8 @@ public class ServiceManagerImpl implements BaseComponent {
private synchronized ComponentAdapter getDelegate() {
if (myDelegate == null) {
myDelegate = new CachingComponentAdapter(new ConstructorInjectionComponentAdapter(getComponentKey(), loadClass(myDescriptor.serviceImplementation), null, true));
myDelegate = new CachingComponentAdapter(new ConstructorInjectionComponentAdapter(getComponentKey(), loadClass(
myDescriptor.getImplementation()), null, true));
}
return myDelegate;
@@ -163,7 +172,7 @@ public class ServiceManagerImpl implements BaseComponent {
}
public String getAssignableToClassName() {
return myDescriptor.serviceInterface;
return myDescriptor.getInterface();
}
}
}
@@ -111,8 +111,8 @@ class TextEditorComponent extends JPanel implements DataProvider{
myVirtualFileListener = new MyVirtualFileListener();
myFile.getFileSystem().addVirtualFileListener(myVirtualFileListener);
myEditor=createEditor();
add (myEditor.getComponent (), BorderLayout.CENTER);
myEditor = createEditor();
add(myEditor.getComponent (), BorderLayout.CENTER);
myModified = isModifiedImpl();
myValid = isEditorValidImpl();
LOG.assertTrue(myValid);
@@ -170,7 +170,7 @@ class TextEditorComponent extends JPanel implements DataProvider{
* method.
*/
private Editor createEditor(){
Editor editor=EditorFactory.getInstance().createEditor(myDocument, myProject);
Editor editor = EditorFactory.getInstance().createEditor(myDocument, myProject);
((EditorMarkupModel) editor.getMarkupModel()).setErrorStripeVisible(true);
EditorHighlighter highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(myFile, EditorColorsManager.getInstance().getGlobalScheme(), myProject);
((EditorEx) editor).setHighlighter(highlighter);
@@ -33,7 +33,7 @@ import java.beans.PropertyChangeSupport;
/**
* @author Vladimir Kondratyev
*/
public class TextEditorImpl extends UserDataHolderBase implements TextEditor{
public class TextEditorImpl extends UserDataHolderBase implements TextEditor {
protected final Project myProject;
private final PropertyChangeSupport myChangeSupport;
private final TextEditorComponent myComponent;
@@ -299,7 +299,9 @@ private MouseEvent convertEvent(final MouseEvent e, final Component target) {
if (component.getParent() == null) continue;
final Rectangle componentBounds = SwingUtilities.convertRectangle(component.getParent(), component.getBounds(), this);
if (!painter.needsRepaint()) continue;
if (!painter.needsRepaint()) {
continue;
}
if (clip.contains(componentBounds) || clip.intersects(componentBounds)) {
final Point targetPoint = SwingUtilities.convertPoint(this, 0, 0, component);
@@ -311,6 +313,11 @@ private MouseEvent convertEvent(final MouseEvent e, final Component target) {
}
}
@Override
protected void paintChildren(Graphics g) {
super.paintChildren(g);
}
public boolean hasPainters() {
return myPainters.size() > 0;
}
@@ -340,4 +347,9 @@ private MouseEvent convertEvent(final MouseEvent e, final Component target) {
final Component lpComponent = SwingUtilities.getDeepestComponentAt(container, lpPoint.x, lpPoint.y);
return lpComponent;
}
@Override
public boolean isOptimizedDrawingEnabled() {
return hasPainters() ? false : super.isOptimizedDrawingEnabled();
}
}
@@ -144,9 +144,10 @@ title.align.when.multiline=Align When Multiline
checkbox.align.multiline.chained.methods=Chained methods
checkbox.align.multiline.method.parameters=Method parameters
checkbox.align.multiline.call.arguments=Call arguments
checkbox.align.multiline.method.parentheses=Method parentheses
checkbox.align.multiline.extends.list=Extends list
checkbox.align.multiline.throws.list=Throws list
checkbox.align.multiline.subsequent.declarations=Subsequent declarations
checkbox.align.multiline.fields.variables.groups=Fields/variables groups
checkbox.align.multiline.parenthesized.expression=Parenthesized expression
checkbox.align.multiline.binary.operation=Binary operation
checkbox.align.multiline.ternary.operation=Ternary operation
@@ -486,3 +487,4 @@ loading.include.indices=Loading include indices...
use.external.annotations=Use &external annotations
insert.override.annotation=Insert @&Override annotation
auto.import=Auto Import
checkbox.collapse.suppress.warnings=<html>@SuppressWarnings</html>
@@ -161,7 +161,7 @@ intention.color.chooser.dialog=Choose Color
dialog.create.field.from.parameter.title=Create Field
dialog.create.field.from.parameter.already.exists.text=Use existing field {0}?
dialog.create.field.from.parameter.already.exists.title=Field Already Exists
dialog.create.field.from.parameter.field.type.label=Field of type {0}
dialog.create.field.from.parameter.field.type.label=Field of type:
dialog.create.field.from.parameter.field.name.label=Name:
dialog.create.field.from.parameter.declare.final.checkbox=Declare &final
dialog.create.class.destination.package.label=Destination package:
@@ -24,6 +24,7 @@ actionSystem.keyGestureHoldTime=400
actionSystem.autoSelectTimeout=1000
actionSystem.quickAccessEnabled=false
actionSystem.quickAccessModifiers=
actionSystem.quickAccessShowSpotsTime=1500
ide.debugMode=false
ide.debugMode.description=Record additonal information to make bug reports more informative
@@ -58,12 +58,20 @@ public class CodeInsightTestUtil {
}
public static void doIntentionTest(CodeInsightTestFixture fixture, @NonNls String file, @NonNls String actionText) throws Throwable {
final List<IntentionAction> list = fixture.getAvailableIntentions(file + ".xml");
assert list.size() > 0;
final IntentionAction intentionAction = findIntentionByText(list, actionText);
assert intentionAction != null : "Action not found: " + actionText;
fixture.launchAction(intentionAction);
fixture.checkResultByFile(file + "_after.xml");
doIntentionTest(fixture, actionText, file + ".xml", file + "_after.xml");
}
public static void doIntentionTest(@NotNull final CodeInsightTestFixture fixture, @NonNls final String action,
@NotNull final String before, @NotNull final String after) throws Exception {
fixture.configureByFile(before);
final IntentionAction intentionAction = findIntentionByText(fixture.getAvailableIntentions(), action);
assert intentionAction != null : "Action not found: " + action;
new WriteCommandAction(fixture.getProject()) {
protected void run(Result result) throws Throwable {
fixture.launchAction(intentionAction);
}
}.execute();
fixture.checkResultByFile(after, false);
}
public static void doWordSelectionTest(@NotNull final CodeInsightTestFixture fixture,
@@ -72,13 +72,18 @@ public class FileUtil {
return getRelativePath(basePath, filePath, separator, SystemInfo.isFileSystemCaseSensitive);
}
private static String ensureEnds(final String s, final char endsWith) {
return StringUtil.endsWithChar(s, endsWith) ? s : s + endsWith;
}
public static String getRelativePath(String basePath, String filePath, final char separator, final boolean caseSensitive) {
if (!StringUtil.endsWithChar(basePath, separator)) basePath += separator;
basePath = ensureEnds(basePath, separator);
int len = 0;
int lastSeparatorIndex = 0; // need this for cases like this: base="/temp/abcde/base" and file="/temp/ab"
String basePathToCompare = caseSensitive ? basePath : basePath.toLowerCase();
String filePathToCompare = caseSensitive ? filePath : filePath.toLowerCase();
if (basePathToCompare.equals(ensureEnds(filePathToCompare, separator))) return ".";
while (len < filePath.length() && len < basePath.length() && filePathToCompare.charAt(len) == basePathToCompare.charAt(len)) {
if (basePath.charAt(len) == separator) {
lastSeparatorIndex = len;
@@ -509,6 +509,12 @@ public class ArrayUtil {
}
return -1;
}
public static <T> int indexOf(@NotNull List<T> objects, T object, @NotNull Comparator<T> comparator) {
for (int i = 0; i < objects.size(); i++) {
if (comparator.compare(objects.get(i), object) == 0) return i;
}
return -1;
}
public static <T> int indexOf(@NotNull T[] objects, T object, @NotNull Equality<T> comparator) {
for (int i = 0; i < objects.length; i++) {
if (comparator.equals(objects[i], object)) return i;
@@ -33,8 +33,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class ContainerUtil {
private static final int INSERTION_SORT_THRESHOLD = 10;
public static List<Object> mergeSortedLists(List<Object> list1, List<Object> list2, Comparator<Object> comparator, boolean mergeEqualItems){
ArrayList<Object> result = new ArrayList<Object>();
public static <T> List<T> mergeSortedLists(List<T> list1, List<T> list2, Comparator<? super T> comparator, boolean mergeEqualItems){
List<T> result = new ArrayList<T>(list1.size() + list2.size());
int index1 = 0;
int index2 = 0;
@@ -46,8 +46,57 @@ public class ContainerUtil {
result.add(list1.get(index1++));
}
else {
Object element1 = list1.get(index1);
Object element2 = list2.get(index2);
T element1 = list1.get(index1);
T element2 = list2.get(index2);
int c = comparator.compare(element1, element2);
if (c < 0) {
result.add(element1);
index1++;
}
else if (c > 0) {
result.add(element2);
index2++;
}
else {
result.add(element1);
if (!mergeEqualItems) {
result.add(element2);
}
index1++;
index2++;
}
}
}
return result;
}
public static <T> List<T> mergeSortedArrays(T[] list1, T[] list2, Comparator<? super T> comparator, boolean mergeEqualItems, @Nullable Processor<? super T> filter){
int index1 = 0;
int index2 = 0;
List<T> result = new ArrayList<T>(list1.length + list2.length);
while (index1 < list1.length || index2 < list2.length) {
if (index1 >= list1.length) {
T t = list2[index2++];
if (filter != null && !filter.process(t)) continue;
result.add(t);
}
else if (index2 >= list2.length) {
T t = list1[index1++];
if (filter != null && !filter.process(t)) continue;
result.add(t);
}
else {
T element1 = list1[index1];
if (filter != null && !filter.process(element1)) {
index1++;
continue;
}
T element2 = list2[index2];
if (filter != null && !filter.process(element2)) {
index2++;
continue;
}
int c = comparator.compare(element1, element2);
if (c < 0) {
result.add(element1);
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
public class MostlySingularMultiMap<K, V> {
private final Map<K, Object> myMap = new THashMap<K, Object>();
@@ -49,6 +50,10 @@ public class MostlySingularMultiMap<K, V> {
}
}
public Set<K> keySet() {
return myMap.keySet();
}
public boolean processForKey(K key, Processor<V> p) {
return processValue(p, myMap.get(key));
}
@@ -57,6 +57,7 @@ public class ConcurrentTasks<T> {
try {
task.consume(new Consumer<T>() {
public void consume(T t) {
if (myResultKnown) return;
myResult = t;
myResultKnown = true;
-- myCntAlive;
@@ -38,13 +38,13 @@ public abstract class VcsAbstractHistorySession implements VcsHistorySession {
}
}
public VcsAbstractHistorySession(List<VcsFileRevision> revisions) {
public VcsAbstractHistorySession(List<? extends VcsFileRevision> revisions) {
myLock = new Object();
myRevisions = new ArrayList<VcsFileRevision>(revisions);
myCachedRevisionNumber = calcCurrentRevisionNumber();
}
protected VcsAbstractHistorySession(List<VcsFileRevision> revisions, VcsRevisionNumber currentRevisionNumber) {
protected VcsAbstractHistorySession(List<? extends VcsFileRevision> revisions, VcsRevisionNumber currentRevisionNumber) {
myLock = new Object();
myRevisions = new ArrayList<VcsFileRevision>(revisions);
myCachedRevisionNumber = currentRevisionNumber;
@@ -0,0 +1,32 @@
/*
* 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.util;
import com.intellij.openapi.vcs.FilePath;
import java.util.Comparator;
public class FilePathByPathComparator implements Comparator<FilePath> {
private final static FilePathByPathComparator ourInstance = new FilePathByPathComparator();
public static FilePathByPathComparator getInstance() {
return ourInstance;
}
public int compare(FilePath o1, FilePath o2) {
return o1.getPath().compareTo(o2.getPath());
}
}
@@ -0,0 +1,60 @@
/*
* 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.openapi.vcs.changes.issueLinks;
import com.intellij.ide.BrowserUtil;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
public abstract class AbstractBaseTagMouseListener extends MouseAdapter implements MouseMotionListener {
public void mouseClicked(final MouseEvent e) {
if (e.getButton() == 1 && !e.isPopupTrigger()) {
Object tag = getTagAt(e);
if (tag instanceof Runnable) {
((Runnable) tag).run();
return;
}
if ((tag != null) && (! Object.class.getName().equals(tag.getClass().getName()))) {
BrowserUtil.launchBrowser(tag.toString());
}
}
}
@Nullable
protected abstract Object getTagAt(final MouseEvent e);
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
Component table = (Component) e.getSource();
Object tag = getTagAt(e);
if (tag != null) {
table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
else {
table.setCursor(Cursor.getDefaultCursor());
}
}
public void install(Component component) {
component.addMouseListener(this);
component.addMouseMotionListener(this);
}
}
@@ -15,7 +15,6 @@
*/
package com.intellij.openapi.vcs.changes.issueLinks;
import com.intellij.ide.BrowserUtil;
import com.intellij.ui.ColoredTableCellRenderer;
import com.intellij.ui.dualView.DualView;
import com.intellij.ui.dualView.TreeTableView;
@@ -24,28 +23,12 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
/**
* @author yole
*/
public class TableLinkMouseListener extends MouseAdapter implements MouseMotionListener {
public void mouseClicked(final MouseEvent e) {
if (e.getButton() == 1 && !e.isPopupTrigger()) {
Object tag = getTagAt(e);
// todo refactor more
if (tag instanceof Runnable) {
((Runnable) tag).run();
return;
}
if ((tag != null) && (! Object.class.getName().equals(tag.getClass().getName()))) {
BrowserUtil.launchBrowser(tag.toString());
}
}
}
public class TableLinkMouseListener extends AbstractBaseTagMouseListener {
@Nullable
protected Object getTagAt(final MouseEvent e) {
// TODO[yole]: don't update renderer on every event, like it's done in TreeLinkMouseListener
@@ -71,23 +54,4 @@ public class TableLinkMouseListener extends MouseAdapter implements MouseMotionL
}
return tag;
}
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
JTable table = (JTable) e.getSource();
Object tag = getTagAt(e);
if (tag != null) {
table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
else {
table.setCursor(Cursor.getDefaultCursor());
}
}
public void install(JTable table) {
table.addMouseListener(this);
table.addMouseMotionListener(this);
}
}
@@ -245,7 +245,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
if (comment != null) {
setCommitMessage(comment);
myLastKnownComment = comment;
myLastSelectedListName = initialSelection == null ? null : initialSelection.getName();
myLastSelectedListName = initialSelection == null ? myBrowser.getSelectedChangeList().getName() : initialSelection.getName();
} else {
setCommitMessage(VcsConfiguration.getInstance(project).LAST_COMMIT_MESSAGE);
updateComment();
@@ -1771,3 +1771,4 @@ ignored.io.resource.types=Ignored I/O resource types
choose.io.resource.type.to.ignore=Choose I/O resource type to ignore
ignore.accesses.from.the.same.class=ignore accesses from the same class
ignore.accesses.from.equals.method=ignore accesses from 'equals()' method
ignore.branches.of.switch.statements=ignore branches of switch statements
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2008 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,18 +32,26 @@ import java.util.Collection;
public class InnerClassMayBeStaticInspection extends BaseInspection {
@Override
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message(
"inner.class.may.be.static.display.name");
}
@Override
@NotNull
protected String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"inner.class.may.be.static.problem.descriptor");
}
@Override
public boolean runForWholeFile() {
return true;
}
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
return new InnerClassMayBeStaticFix();
}
@@ -55,6 +63,7 @@ public class InnerClassMayBeStaticInspection extends BaseInspection {
return InspectionGadgetsBundle.message("make.static.quickfix");
}
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
final PsiJavaToken classNameToken =
@@ -88,6 +97,7 @@ public class InnerClassMayBeStaticInspection extends BaseInspection {
}
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new InnerClassCanBeStaticVisitor();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,10 @@
package com.siyeh.ig.style;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiBlockStatement;
import com.intellij.psi.PsiCodeBlock;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiJavaToken;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
@@ -29,29 +28,46 @@ import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.VariableSearchUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class UnnecessaryBlockStatementInspection extends BaseInspection{
@SuppressWarnings({"PublicField"})
public boolean ignoreSwitchBranches = false;
@Override
@NotNull
public String getID(){
return "UnnecessaryCodeBlock";
}
@Override
@NotNull
public String getDisplayName(){
return InspectionGadgetsBundle.message(
"unnecessary.code.block.display.name");
}
@Override
@NotNull
public String buildErrorString(Object... infos){
return InspectionGadgetsBundle.message(
"unnecessary.block.statement.problem.descriptor");
}
@Override
public JComponent createOptionsPanel() {
return new SingleCheckboxOptionsPanel(
InspectionGadgetsBundle.message("ignore.branches.of.switch.statements"),
this, "ignoreSwitchBranches");
}
@Override
public BaseInspectionVisitor buildVisitor(){
return new UnnecessaryBlockStatementVisitor();
}
@Override
public InspectionGadgetsFix buildFix(Object... infos){
return new UnnecessaryBlockFix();
}
@@ -64,6 +80,7 @@ public class UnnecessaryBlockStatementInspection extends BaseInspection{
"unnecessary.code.block.unwrap.quickfix");
}
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
final PsiElement leftBrace = descriptor.getPsiElement();
@@ -84,11 +101,20 @@ public class UnnecessaryBlockStatementInspection extends BaseInspection{
}
}
private static class UnnecessaryBlockStatementVisitor
private class UnnecessaryBlockStatementVisitor
extends BaseInspectionVisitor {
@Override public void visitBlockStatement(PsiBlockStatement blockStatement){
@Override public void visitBlockStatement(
PsiBlockStatement blockStatement){
super.visitBlockStatement(blockStatement);
if (ignoreSwitchBranches) {
final PsiElement prevStatement =
PsiTreeUtil.skipSiblingsBackward(blockStatement,
PsiWhiteSpace.class);
if (prevStatement instanceof PsiSwitchLabelStatement) {
return;
}
}
final PsiElement parent = blockStatement.getParent();
if(!(parent instanceof PsiCodeBlock)){
return;
@@ -5,5 +5,6 @@ This inspection reports instances of code blocks which are unnecessary to the se
be replaced by their contents. Code blocks which are the bodies of <b><font color="#000080">if</font></b>, <b><font color="#000080">do</font></b>,
<b><font color="#000080">while</font></b> or <b><font color="#000080">for</font></b> statements will not be reported by this
inspection.
<p>Use the checkbox below if you wish this inspection to ignore code blocks which are used as branches of switch statements.</p>
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
</html>
@@ -483,6 +483,36 @@ public class GitUtil {
return rc.replace(File.separatorChar, '/');
}
/**
* Covert list of files to relative paths
*
* @param filePaths a parameters to convert
* @return a list of relative paths
* @throws IllegalArgumentException if some path is not under root.
*/
public static List<String> toRelativePaths(@NotNull VirtualFile root, @NotNull final Collection<FilePath> filePaths) {
ArrayList<String> rc = new ArrayList<String>(filePaths.size());
for (FilePath path : filePaths) {
rc.add(GitUtil.relativePath(root, path));
}
return rc;
}
/**
* Covert list of files to relative paths
*
* @param filePaths a parameters to convert
* @return a list of relative paths
* @throws IllegalArgumentException if some path is not under root.
*/
public static List<String> toRelativeFiles(@NotNull VirtualFile root, @NotNull final Collection<VirtualFile> files) {
ArrayList<String> rc = new ArrayList<String>(files.size());
for (VirtualFile file : files) {
rc.add(GitUtil.relativePath(root, file));
}
return rc;
}
/**
* Refresh files
*
@@ -227,6 +227,15 @@ class ChangeCollector {
handler.setStdoutSuppressed(true);
handler.endOptions();
handler.addRelativePaths(dirtyPaths);
if (handler.isLargeCommandLine()) {
// if there are too much files, just get all changes for the project
handler = new GitSimpleHandler(myProject, myVcsRoot, GitCommand.DIFF);
handler.addParameters("--name-status", "--diff-filter=ADCMRUX", "-M", "HEAD");
handler.setNoSSH(true);
handler.setSilent(true);
handler.setStdoutSuppressed(true);
handler.endOptions();
}
try {
String output = handler.run();
GitChangeUtils.parseChanges(myProject, myVcsRoot, null, GitChangeUtils.loadRevision(myProject, myVcsRoot, "HEAD"), output, myChanges,
@@ -282,6 +291,14 @@ class ChangeCollector {
handler.setStdoutSuppressed(true);
handler.endOptions();
handler.addRelativePaths(dirtyPaths);
if(handler.isLargeCommandLine()) {
handler = new GitSimpleHandler(myProject, myVcsRoot, GitCommand.LS_FILES);
handler.addParameters("-v", "--others", "--exclude-standard");
handler.setSilent(true);
handler.setNoSSH(true);
handler.setStdoutSuppressed(true);
handler.endOptions();
}
// run handler and collect changes
parseFiles(handler.run());
}
@@ -133,6 +133,7 @@ public class GitChangeUtils {
// exit if there is no next character
break;
}
assert 'M' != s.peek() : "Moves are not yet handled";
String[] tokens = s.line().split("\t");
String path = tokens[tokens.length - 1];
path = rootPath + File.separator + GitUtil.unescapePath(path);
@@ -199,7 +199,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
try {
files.addAll(added);
files.addAll(removed);
commit(myProject, root, files, messageFile, myNextCommitAuthor).run();
commit(myProject, root, files, messageFile, myNextCommitAuthor);
}
catch (VcsException ex) {
if (!isMergeCommit(ex)) {
@@ -327,7 +327,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
GitBundle.getString("commit.partial.merge.title"), null);
}
});
} );
}
catch (RuntimeException ex) {
throw ex;
@@ -416,12 +416,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
}
if (!removed.isEmpty()) {
try {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.RM);
handler.addParameters("--ignore-unmatch");
handler.endOptions();
handler.addRelativePaths(removed);
handler.setNoSSH(true);
handler.run();
GitFileUtils.delete(project, root, removed, "--ignore-unmatch");
}
catch (VcsException ex) {
exceptions.add(ex);
@@ -489,21 +484,30 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
* @param message a message file to use
* @param nextCommitAuthor a author for the next commit
* @return a simple handler that does the task
* @throws VcsException in case of git problem
*/
private static GitSimpleHandler commit(Project project,
VirtualFile root,
Collection<FilePath> files,
File message,
final String nextCommitAuthor) {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.COMMIT);
handler.setNoSSH(true);
handler.addParameters("--only", "-F", message.getAbsolutePath());
if (nextCommitAuthor != null) {
handler.addParameters("--author=" + nextCommitAuthor);
private static void commit(Project project,
VirtualFile root,
Collection<FilePath> files,
File message,
final String nextCommitAuthor) throws VcsException {
boolean isFirst = true;
for (List<String> paths : GitFileUtils.chunkPaths(root, files)) {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.COMMIT);
handler.setNoSSH(true);
if (isFirst) {
isFirst = false;
} else {
handler.addParameters("--amend");
}
handler.addParameters("--only", "-F", message.getAbsolutePath());
if (nextCommitAuthor != null) {
handler.addParameters("--author=" + nextCommitAuthor);
}
handler.endOptions();
handler.addParameters(paths);
handler.run();
}
handler.endOptions();
handler.addRelativePaths(files);
return handler;
}
@@ -19,7 +19,9 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import git4idea.GitUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -28,6 +30,12 @@ import java.util.List;
* File utilities for the git
*/
public class GitFileUtils {
/**
* If multiple paths are specified on the command line, this limit is used to split paths into chunks.
* The limit is less than OS limit to leave space to quoting, spaces, charset conversion, and commands arguments.
*/
public static final int FILE_PATH_LIMIT = 10000;
/**
* The private constructor for static utility class
*/
@@ -35,6 +43,62 @@ public class GitFileUtils {
// do nothing
}
/**
* Chunk paths on the command line
*
* @param files the paths to chunk
* @return the a list of list of relative paths
*/
public static List<List<String>> chunkRelativePaths(List<String> files) {
ArrayList<List<String>> rc = new ArrayList<List<String>>();
int start = 0;
int size = 0;
int i = 0;
for (; i < files.size(); i++) {
String p = files.get(i);
if (size + p.length() > FILE_PATH_LIMIT) {
if (start == i) {
rc.add(files.subList(i, i + 1));
start = i + 1;
}
else {
rc.add(files.subList(start, i));
start = i;
}
size = 0;
}
else {
size += p.length();
}
}
if (start != files.size()) {
rc.add(files.subList(start, i));
}
return rc;
}
/**
* The chunk paths
*
* @param root the vcs root
* @param files the file list
* @return chunked relative paths
*/
public static List<List<String>> chunkPaths(VirtualFile root, Collection<FilePath> files) {
return chunkRelativePaths(GitUtil.toRelativePaths(root, files));
}
/**
* The chunk paths
*
* @param root the vcs root
* @param files the file list
* @return chunked relative paths
*/
public static List<List<String>> chunkFiles(VirtualFile root, Collection<VirtualFile> files) {
return chunkRelativePaths(GitUtil.toRelativeFiles(root, files));
}
/**
* Delete files
*
@@ -44,12 +108,17 @@ public class GitFileUtils {
* @return a result of operation
* @throws VcsException in case of git problem
*/
public static String delete(Project project, VirtualFile root, List<FilePath> files) throws VcsException {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.RM);
handler.endOptions();
handler.addRelativePaths(files);
handler.setNoSSH(true);
return handler.run();
public static void delete(Project project, VirtualFile root, Collection<FilePath> files, String... additionalOptions)
throws VcsException {
for (List<String> paths : chunkPaths(root, files)) {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.RM);
handler.addParameters(additionalOptions);
handler.endOptions();
handler.addParameters(paths);
handler.setNoSSH(true);
handler.run();
}
}
public static void cherryPick(final Project project, final VirtualFile root, final String hash) throws VcsException {
@@ -70,12 +139,14 @@ public class GitFileUtils {
* @return a result of operation
* @throws VcsException in case of git problem
*/
public static String deleteFiles(Project project, VirtualFile root, List<VirtualFile> files) throws VcsException {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.RM);
handler.endOptions();
handler.addRelativeFiles(files);
handler.setNoSSH(true);
return handler.run();
public static void deleteFiles(Project project, VirtualFile root, List<VirtualFile> files) throws VcsException {
for (List<String> paths : chunkFiles(root, files)) {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.RM);
handler.endOptions();
handler.addParameters(paths);
handler.setNoSSH(true);
handler.run();
}
}
/**
@@ -87,8 +158,8 @@ public class GitFileUtils {
* @return a result of operation
* @throws VcsException in case of git problem
*/
public static String deleteFiles(Project project, VirtualFile root, VirtualFile... files) throws VcsException {
return deleteFiles(project, root, Arrays.asList(files));
public static void deleteFiles(Project project, VirtualFile root, VirtualFile... files) throws VcsException {
deleteFiles(project, root, Arrays.asList(files));
}
/**
@@ -100,12 +171,14 @@ public class GitFileUtils {
* @return a result of operation
* @throws VcsException in case of git problem
*/
public static String addFiles(Project project, VirtualFile root, Collection<VirtualFile> files) throws VcsException {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.ADD);
handler.endOptions();
handler.addRelativeFiles(files);
handler.setNoSSH(true);
return handler.run();
public static void addFiles(Project project, VirtualFile root, Collection<VirtualFile> files) throws VcsException {
for (List<String> paths : chunkFiles(root, files)) {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.ADD);
handler.endOptions();
handler.addParameters(paths);
handler.setNoSSH(true);
handler.run();
}
}
/**
@@ -117,8 +190,8 @@ public class GitFileUtils {
* @return a result of operation
* @throws VcsException in case of git problem
*/
public static String addFiles(Project project, VirtualFile root, VirtualFile... files) throws VcsException {
return addFiles(project, root, Arrays.asList(files));
public static void addFiles(Project project, VirtualFile root, VirtualFile... files) throws VcsException {
addFiles(project, root, Arrays.asList(files));
}
/**
@@ -130,11 +203,13 @@ public class GitFileUtils {
* @return a result of operation
* @throws VcsException in case of git problem
*/
public static String addPaths(Project project, VirtualFile root, Collection<FilePath> files) throws VcsException {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.ADD);
handler.endOptions();
handler.addRelativePaths(files);
handler.setNoSSH(true);
return handler.run();
public static void addPaths(Project project, VirtualFile root, Collection<FilePath> files) throws VcsException {
for (List<String> paths : chunkPaths(root, files)) {
GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.ADD);
handler.endOptions();
handler.addParameters(paths);
handler.setNoSSH(true);
handler.run();
}
}
}
@@ -300,6 +300,16 @@ public abstract class GitHandler {
myCommandLine.addParameters(parameters);
}
/**
* Add parameters from the list
*
* @param parameters the parameters to add
*/
public void addParameters(List<String> parameters) {
checkNotStarted();
myCommandLine.addParameters(parameters);
}
/**
* Add file path parameters. The parameters are made relative to the working directory
*
@@ -449,7 +459,7 @@ public abstract class GitHandler {
public void onTextAvailable(final ProcessEvent event, final Key outputType) {
GitHandler.this.onTextAvailable(event.getText(), outputType);
}
});
} );
myHandler.startNotify();
}
catch (Throwable t) {
@@ -653,4 +663,12 @@ public abstract class GitHandler {
assert mySuspendAction != null;
myResumeAction.run();
}
/**
* @return true if the command line is too big
*/
public boolean isLargeCommandLine() {
return myCommandLine.getCommandLineString().length() > GitFileUtils.FILE_PATH_LIMIT;
}
}
@@ -18,19 +18,22 @@ package git4idea.diff;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.TreeDiffProvider;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcsUtil.VcsUtil;
import git4idea.GitBranchesSearcher;
import git4idea.changes.GitChangeUtils;
import git4idea.commands.GitCommand;
import git4idea.commands.GitFileUtils;
import git4idea.commands.GitSimpleHandler;
import git4idea.commands.StringScanner;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class GitTreeDiffProvider implements TreeDiffProvider {
private final static Logger LOG = Logger.getInstance("#git4idea.diff.GitTreeDiffProvider");
@@ -44,21 +47,24 @@ public class GitTreeDiffProvider implements TreeDiffProvider {
try {
final GitBranchesSearcher searcher = new GitBranchesSearcher(myProject, vcsRoot, true);
if (searcher.getLocal() == null || searcher.getRemote() == null) return Collections.emptyList();
GitSimpleHandler handler = new GitSimpleHandler(myProject, vcsRoot, GitCommand.DIFF);
handler.addParameters("--name-status", "--diff-filter=ADCMRUX", "-M", "HEAD..." + searcher.getRemote().getFullName());
handler.setNoSSH(true);
handler.setSilent(true);
handler.setStdoutSuppressed(true);
handler.endOptions();
final Collection<File> files = new ArrayList<File>(paths.size());
ArrayList<String> rc = new ArrayList<String>();
final Collection<FilePath> files = new ArrayList<FilePath>(paths.size());
for (String path : paths) {
files.add(new File(path));
files.add(VcsUtil.getFilePath(path));
}
handler.addRelativePathsForFiles(files);
String output = handler.run();
return GitChangeUtils.parseDiffForPaths(vcsRoot.getPath(), new StringScanner(output));
for (List<String> pathList : GitFileUtils.chunkPaths(vcsRoot, files)) {
GitSimpleHandler handler = new GitSimpleHandler(myProject, vcsRoot, GitCommand.DIFF);
handler.addParameters("--name-status", "--diff-filter=ADCRUX", "-M", "HEAD..." + searcher.getRemote().getFullName());
handler.setNoSSH(true);
handler.setSilent(true);
handler.setStdoutSuppressed(true);
handler.endOptions();
handler.addParameters(pathList);
String output = handler.run();
Collection<String> pathCollection = GitChangeUtils.parseDiffForPaths(vcsRoot.getPath(), new StringScanner(output));
rc.addAll(pathCollection);
}
return rc;
}
catch (VcsException e) {
LOG.info(e);
@@ -263,21 +263,6 @@ public class GitMergeProvider implements MergeProvider2 {
}
}
/**
* Collect conflicts for virtual files
*
* @param root the git root
* @param files the files to describe
*/
public void collectConflicts(VirtualFile root, List<VirtualFile> files) {
GitSimpleHandler h = new GitSimpleHandler(myProject, root, GitCommand.LS_FILES);
h.setNoSSH(true);
h.addParameters("-t", "--exclude-standard", "--unmerged");
h.endOptions();
h.addRelativeFiles(files);
}
/**
* {@inheritDoc}
*/
@@ -25,6 +25,7 @@ import com.intellij.openapi.vcs.rollback.RollbackProgressListener;
import com.intellij.openapi.vfs.VirtualFile;
import git4idea.GitUtil;
import git4idea.commands.GitCommand;
import git4idea.commands.GitFileUtils;
import git4idea.commands.GitSimpleHandler;
import git4idea.i18n.GitBundle;
import org.jetbrains.annotations.NotNull;
@@ -167,12 +168,14 @@ public class GitRollbackEnvironment implements RollbackEnvironment {
* @throws VcsException Id it breaks.
*/
public void revert(final VirtualFile root, final List<FilePath> files) throws VcsException {
GitSimpleHandler handler = new GitSimpleHandler(myProject, root, GitCommand.CHECKOUT);
handler.setNoSSH(true);
handler.addParameters("HEAD");
handler.endOptions();
handler.addRelativePaths(files);
handler.run();
for (List<String> paths : GitFileUtils.chunkPaths(root, files)) {
GitSimpleHandler handler = new GitSimpleHandler(myProject, root, GitCommand.CHECKOUT);
handler.setNoSSH(true);
handler.addParameters("HEAD");
handler.endOptions();
handler.addParameters(paths);
handler.run();
}
}
/**
@@ -183,13 +186,7 @@ public class GitRollbackEnvironment implements RollbackEnvironment {
* @throws VcsException if there is a problem with running git
*/
private void unindex(final VirtualFile root, final List<FilePath> files) throws VcsException {
GitSimpleHandler handler = new GitSimpleHandler(myProject, root, GitCommand.RM);
handler.setNoSSH(true);
handler.addParameters("--cached");
handler.addParameters("-f");
handler.endOptions();
handler.addRelativePaths(files);
handler.run();
GitFileUtils.delete(myProject, root, files, "--cached", "-f");
}
@@ -32,6 +32,7 @@ import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager;
import com.intellij.openapi.vcs.changes.shelf.ShelvedBinaryFile;
import com.intellij.openapi.vcs.changes.shelf.ShelvedChange;
import com.intellij.openapi.vcs.changes.shelf.ShelvedChangeList;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcsUtil.VcsUtil;
@@ -47,6 +48,7 @@ import git4idea.ui.GitConvertFilesDialog;
import git4idea.ui.GitUIUtil;
import git4idea.vfs.GitVFSListener;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -248,6 +250,29 @@ public abstract class GitBaseRebaseProcess {
if (myShelvedChangeList != null) {
// The changes are temporary copied to the first local change list, the next operation will restore them back
myProgressIndicator.setText(GitBundle.getString("update.unshelving.changes"));
VirtualFile baseDir = myProject.getBaseDir();
assert baseDir != null;
String projectPath = baseDir.getPath() + "/";
// Refresh files that might be affected by unshelve
HashSet<File> filesToRefresh = new HashSet<File>();
for (ShelvedChange c : myShelvedChangeList.getChanges()) {
if( c.getBeforePath() != null) {
filesToRefresh.add(new File(projectPath+c.getBeforePath()));
}
if( c.getAfterPath() != null) {
filesToRefresh.add(new File(projectPath+c.getAfterPath()));
}
}
for (ShelvedBinaryFile f : myShelvedChangeList.getBinaryFiles()) {
if(f.BEFORE_PATH != null) {
filesToRefresh.add(new File(projectPath+f.BEFORE_PATH));
}
if(f.AFTER_PATH != null) {
filesToRefresh.add(new File(projectPath+f.BEFORE_PATH));
}
}
LocalFileSystem.getInstance().refreshIoFiles(filesToRefresh);
// Do unshevle
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
public void run() {
GitVFSListener l = GitVcs.getInstance(myProject).getVFSListener();
@@ -263,9 +288,6 @@ public abstract class GitBaseRebaseProcess {
}
});
Collection<FilePath> paths = new ArrayList<FilePath>();
VirtualFile baseDir = myProject.getBaseDir();
assert baseDir != null;
String projectPath = baseDir.getPath() + "/";
for (ShelvedChange c : myShelvedChangeList.getChanges()) {
if (c.getBeforePath() == null || !c.getBeforePath().equals(c.getAfterPath()) || c.getFileStatus() == FileStatus.ADDED) {
paths.add(VcsUtil.getFilePath(projectPath + c.getAfterPath()));
@@ -287,6 +309,7 @@ public abstract class GitBaseRebaseProcess {
}
}
}
// Move files back to theirs change lists
if (getUpdatePolicy() == GitVcsSettings.UpdateChangesPolicy.SHELVE || getUpdatePolicy() == GitVcsSettings.UpdateChangesPolicy.STASH) {
VcsDirtyScopeManager m = VcsDirtyScopeManager.getInstance(myProject);
for (LocalChangeList changeList : myListsCopy) {
@@ -18,6 +18,7 @@ package git4idea.update;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ui.UIUtil;
@@ -27,6 +28,7 @@ import git4idea.commands.GitCommand;
import git4idea.commands.GitSimpleHandler;
import git4idea.commands.StringScanner;
import git4idea.i18n.GitBundle;
import git4idea.rollback.GitRollbackEnvironment;
import git4idea.ui.GitUIUtil;
import javax.swing.*;
@@ -198,12 +200,12 @@ public class GitUpdateLocallyModifiedDialog extends DialogWrapper {
* @param files the files to revert
*/
private static void revertFiles(Project project, VirtualFile root, ArrayList<String> files) throws VcsException {
GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.CHECKOUT);
h.endOptions();
h.setNoSSH(true);
// TODO consider deleted files
GitRollbackEnvironment rollback = GitRollbackEnvironment.getInstance(project);
ArrayList<FilePath> list = new ArrayList<FilePath>(files.size());
for (String p : files) {
h.addRelativePaths(VcsUtil.getFilePath(p));
list.add(VcsUtil.getFilePath(p));
}
h.run();
rollback.revert(root, list);
}
}

Some files were not shown because too many files have changed in this diff Show More