mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' into changeSignature
This commit is contained in:
@@ -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();
|
||||
|
||||
+1
@@ -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"));
|
||||
}
|
||||
}
|
||||
+97
@@ -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();
|
||||
}
|
||||
}
|
||||
+8
-10
@@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -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() {
|
||||
|
||||
+24
-11
@@ -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);
|
||||
|
||||
+26
-6
@@ -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();
|
||||
|
||||
+48
-43
@@ -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) {
|
||||
|
||||
+15
-1
@@ -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();
|
||||
}
|
||||
}
|
||||
+14
-2
@@ -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;
|
||||
|
||||
|
||||
+11
-4
@@ -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 =
|
||||
|
||||
|
||||
+4
-1
@@ -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();
|
||||
}
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -54,8 +54,7 @@ public class PasswordSafeConfigurable implements SearchableConfigurable {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getHelpTopic() {
|
||||
// TODO add help
|
||||
return null;
|
||||
return "reference.ide.settings.password.safe";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+14
-5
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -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);
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+14
-6
@@ -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;
|
||||
|
||||
+2
-2
@@ -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());
|
||||
}
|
||||
}
|
||||
+60
@@ -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);
|
||||
}
|
||||
}
|
||||
+1
-37
@@ -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);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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
|
||||
|
||||
+11
-1
@@ -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();
|
||||
}
|
||||
|
||||
+33
-7
@@ -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
Reference in New Issue
Block a user