mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -38,33 +38,11 @@ abstract class BuildTasks {
|
||||
*/
|
||||
abstract void zipSourcesOfModules(Collection<String> modules, String targetFilePath)
|
||||
|
||||
/**
|
||||
* Updates search/searchableOptions.xml file in {@code targetModuleName} module output directory
|
||||
* <br>
|
||||
* todo[nik] this is temporary solution until code from layouts.gant files moved to the new builders. After that this method will
|
||||
* be called inside {@link #buildDistributions()}
|
||||
*/
|
||||
abstract void buildSearchableOptions(String targetModuleName, List<String> modulesToIndex, List<String> pathsToLicenses)
|
||||
|
||||
/**
|
||||
* Creates a copy of *ApplicationInfo.xml file with substituted __BUILD_NUMBER__ and __BUILD_DATE__ placeholders
|
||||
* <br>
|
||||
* todo[nik] this is temporary solution until code from layouts.gant files moved to the new builders. After that this method will
|
||||
* be called inside {@link #buildDistributions()}
|
||||
* @return path to the copied file
|
||||
*/
|
||||
abstract File patchApplicationInfo()
|
||||
|
||||
/**
|
||||
* Creates distribution for all operating systems from JAR files located at {@link BuildPaths#distAll}
|
||||
*/
|
||||
abstract void buildDistributions()
|
||||
|
||||
/**
|
||||
* Produces distributions for all operating systems from sources. This includes compiling required modules, packing their output into JAR
|
||||
* files accordingly to {@link ProductProperties#productLayout}, and creating distributions and installers for all OS.
|
||||
*/
|
||||
abstract void compileModulesAndBuildDistributions()
|
||||
abstract void buildDistributions()
|
||||
|
||||
abstract void compileProjectAndTests(List<String> includingTestsInModules)
|
||||
|
||||
@@ -97,6 +75,6 @@ abstract class BuildTasks {
|
||||
ProductProperties productProperties = (ProductProperties) Class.forName(productPropertiesClassName).constructors[0].newInstance(projectHome)
|
||||
def context = BuildContext.createContext(binding.ant, binding.projectBuilder, binding.project, binding.global,
|
||||
"$projectHome/$communityHomeRelativePath", projectHome, productProperties, proprietaryBuildTools)
|
||||
create(context).compileModulesAndBuildDistributions()
|
||||
create(context).buildDistributions()
|
||||
}
|
||||
}
|
||||
@@ -41,13 +41,13 @@ class IdeaCommunityBuilder {
|
||||
}
|
||||
|
||||
void buildDistJars() {
|
||||
BuildTasks.create(buildContext).compileModulesAndBuildDistributions()
|
||||
BuildTasks.create(buildContext).buildDistributions()
|
||||
layoutAdditionalArtifacts()
|
||||
}
|
||||
|
||||
void buildDistributions() {
|
||||
def tasks = BuildTasks.create(buildContext)
|
||||
tasks.compileModulesAndBuildDistributions()
|
||||
tasks.buildDistributions()
|
||||
layoutAdditionalArtifacts(true)
|
||||
tasks.buildUpdaterJar()
|
||||
}
|
||||
|
||||
@@ -164,8 +164,6 @@ abstract class ProductProperties {
|
||||
*/
|
||||
boolean enableYourkitAgentInEAP = false
|
||||
|
||||
List<String> excludedPlugins = []
|
||||
|
||||
/**
|
||||
* Specified additional modules (not included into the product layout) which need to be compiled when product is built.
|
||||
* todo[nik] get rid of this
|
||||
|
||||
@@ -311,9 +311,7 @@ class BuildContextImpl extends BuildContext {
|
||||
|
||||
private boolean isJavaSupportedInProduct() {
|
||||
def productLayout = productProperties.productLayout
|
||||
return productLayout.mainJarName == null ||
|
||||
//todo[nik] remove this condition later; currently build scripts for IDEA don't fully migrated to the new scheme
|
||||
productLayout.includedPlatformModules.contains("execution-impl")
|
||||
return productLayout.includedPlatformModules.contains("execution-impl")
|
||||
}
|
||||
|
||||
@CompileDynamic
|
||||
|
||||
@@ -91,12 +91,6 @@ class BuildTasksImpl extends BuildTasks {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void buildSearchableOptions(String targetModuleName, List<String> modulesToIndex, List<String> pathsToLicenses) {
|
||||
buildSearchableOptions(new File(buildContext.projectBuilder.moduleOutput(buildContext.findRequiredModule(targetModuleName))), modulesToIndex, pathsToLicenses)
|
||||
}
|
||||
|
||||
//todo[nik] do we need 'cp' and 'jvmArgs' parameters?
|
||||
void buildSearchableOptions(File targetDirectory, List<String> modulesToIndex, List<String> pathsToLicenses) {
|
||||
buildContext.executeStep("Build searchable options index", BuildOptions.SEARCHABLE_OPTIONS_INDEX_STEP, {
|
||||
def javaRuntimeClasses = "${buildContext.projectBuilder.moduleOutput(buildContext.findModule("java-runtime"))}"
|
||||
@@ -187,7 +181,6 @@ idea.fatal.error.notification=disabled
|
||||
return propertiesFile
|
||||
}
|
||||
|
||||
@Override
|
||||
File patchApplicationInfo() {
|
||||
def sourceFile = buildContext.findApplicationInfoInSources()
|
||||
def targetFile = new File(buildContext.paths.temp, sourceFile.name)
|
||||
@@ -229,38 +222,6 @@ idea.fatal.error.notification=disabled
|
||||
src.filterLine { String it -> !it.contains('appender-ref ref="CONSOLE-WARN"') }.writeTo(dst.newWriter()).close()
|
||||
}
|
||||
|
||||
@Override
|
||||
void buildDistributions() {
|
||||
layoutShared()
|
||||
|
||||
def propertiesFile = patchIdeaPropertiesFile()
|
||||
List<BuildTaskRunnable<String>> tasks = [
|
||||
createDistributionForOsTask("win", { BuildContext context ->
|
||||
context.windowsDistributionCustomizer?.with {new WindowsDistributionBuilder(context, it, propertiesFile)}
|
||||
}),
|
||||
createDistributionForOsTask("linux", { BuildContext context ->
|
||||
context.linuxDistributionCustomizer?.with {new LinuxDistributionBuilder(context, it, propertiesFile)}
|
||||
}),
|
||||
createDistributionForOsTask("mac", { BuildContext context ->
|
||||
context.macDistributionCustomizer?.with {new MacDistributionBuilder(context, it, propertiesFile)}
|
||||
})
|
||||
]
|
||||
|
||||
List<String> paths = runInParallel(tasks).findAll {it != null}
|
||||
|
||||
if (buildContext.productProperties.buildCrossPlatformDistribution) {
|
||||
if (paths.size() == 3) {
|
||||
buildContext.executeStep("Build cross-platform distribution", BuildOptions.CROSS_PLATFORM_DISTRIBUTION_STEP) {
|
||||
def crossPlatformBuilder = new CrossPlatformDistributionBuilder(buildContext)
|
||||
crossPlatformBuilder.buildCrossPlatformZip(paths[0], paths[1], paths[2])
|
||||
}
|
||||
}
|
||||
else {
|
||||
buildContext.messages.info("Skipping building cross-platform distribution because some OS-specific distributions were skipped")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static BuildTaskRunnable<String> createDistributionForOsTask(String taskName, Function<BuildContext, OsSpecificDistributionBuilder> factory) {
|
||||
new BuildTaskRunnable<String>(taskName) {
|
||||
@Override
|
||||
@@ -279,9 +240,11 @@ idea.fatal.error.notification=disabled
|
||||
}
|
||||
|
||||
@Override
|
||||
void compileModulesAndBuildDistributions() {
|
||||
void buildDistributions() {
|
||||
checkProductProperties()
|
||||
def distributionJARsBuilder = new DistributionJARsBuilder(buildContext)
|
||||
|
||||
def patchedApplicationInfo = patchApplicationInfo()
|
||||
def distributionJARsBuilder = new DistributionJARsBuilder(buildContext, patchedApplicationInfo)
|
||||
compileModules(buildContext.productProperties.productLayout.includedPluginModules + distributionJARsBuilder.platformModules +
|
||||
buildContext.productProperties.additionalModulesToCompile, buildContext.productProperties.modulesToCompileTests)
|
||||
buildContext.messages.block("Build platform and plugin JARs") {
|
||||
@@ -289,24 +252,56 @@ idea.fatal.error.notification=disabled
|
||||
distributionJARsBuilder.buildAdditionalArtifacts()
|
||||
}
|
||||
if (buildContext.productProperties.scrambleMainJar) {
|
||||
if (buildContext.proprietaryBuildTools.scrambleTool != null) {
|
||||
buildContext.proprietaryBuildTools.scrambleTool.scramble(buildContext.productProperties.productLayout.mainJarName, buildContext)
|
||||
scramble()
|
||||
}
|
||||
|
||||
layoutShared()
|
||||
|
||||
def propertiesFile = patchIdeaPropertiesFile()
|
||||
List<BuildTaskRunnable<String>> tasks = [
|
||||
createDistributionForOsTask("win", { BuildContext context ->
|
||||
context.windowsDistributionCustomizer?.with { new WindowsDistributionBuilder(context, it, propertiesFile, patchedApplicationInfo) }
|
||||
}),
|
||||
createDistributionForOsTask("linux", { BuildContext context ->
|
||||
context.linuxDistributionCustomizer?.with { new LinuxDistributionBuilder(context, it, propertiesFile) }
|
||||
}),
|
||||
createDistributionForOsTask("mac", { BuildContext context ->
|
||||
context.macDistributionCustomizer?.with { new MacDistributionBuilder(context, it, propertiesFile) }
|
||||
})
|
||||
]
|
||||
|
||||
List<String> paths = runInParallel(tasks).findAll { it != null }
|
||||
|
||||
if (buildContext.productProperties.buildCrossPlatformDistribution) {
|
||||
if (paths.size() == 3) {
|
||||
buildContext.executeStep("Build cross-platform distribution", BuildOptions.CROSS_PLATFORM_DISTRIBUTION_STEP) {
|
||||
def crossPlatformBuilder = new CrossPlatformDistributionBuilder(buildContext)
|
||||
crossPlatformBuilder.buildCrossPlatformZip(paths[0], paths[1], paths[2])
|
||||
}
|
||||
}
|
||||
else {
|
||||
buildContext.messages.warning("Scrambling skipped: 'scrambleTool' isn't defined")
|
||||
buildContext.messages.info("Skipping building cross-platform distribution because some OS-specific distributions were skipped")
|
||||
}
|
||||
buildContext.ant.zip(destfile: "$buildContext.paths.artifacts/internalUtilities.zip") {
|
||||
fileset(file: "$buildContext.paths.buildOutputRoot/internal/internalUtilities.jar")
|
||||
fileset(dir: "$buildContext.paths.communityHome/lib") {
|
||||
include(name: "junit-4*.jar")
|
||||
include(name: "hamcrest-core-*.jar")
|
||||
}
|
||||
zipfileset(src: "$buildContext.paths.buildOutputRoot/internal/internalUtilities.jar") {
|
||||
include(name: "*.xml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scramble() {
|
||||
if (buildContext.proprietaryBuildTools.scrambleTool != null) {
|
||||
buildContext.proprietaryBuildTools.scrambleTool.scramble(buildContext.productProperties.productLayout.mainJarName, buildContext)
|
||||
}
|
||||
else {
|
||||
buildContext.messages.warning("Scrambling skipped: 'scrambleTool' isn't defined")
|
||||
}
|
||||
buildContext.ant.zip(destfile: "$buildContext.paths.artifacts/internalUtilities.zip") {
|
||||
fileset(file: "$buildContext.paths.buildOutputRoot/internal/internalUtilities.jar")
|
||||
fileset(dir: "$buildContext.paths.communityHome/lib") {
|
||||
include(name: "junit-4*.jar")
|
||||
include(name: "hamcrest-core-*.jar")
|
||||
}
|
||||
zipfileset(src: "$buildContext.paths.buildOutputRoot/internal/internalUtilities.jar") {
|
||||
include(name: "*.xml")
|
||||
}
|
||||
}
|
||||
buildDistributions()
|
||||
}
|
||||
|
||||
private void checkProductProperties() {
|
||||
@@ -478,7 +473,7 @@ idea.fatal.error.notification=disabled
|
||||
|
||||
@Override
|
||||
void buildUnpackedDistribution(String targetDirectory) {
|
||||
def jarsBuilder = new DistributionJARsBuilder(buildContext)
|
||||
def jarsBuilder = new DistributionJARsBuilder(buildContext, patchApplicationInfo())
|
||||
jarsBuilder.buildJARs()
|
||||
layoutShared()
|
||||
|
||||
|
||||
@@ -59,7 +59,6 @@ class CrossPlatformDistributionBuilder {
|
||||
buildContext.ant.zip(zipfile: targetPath, duplicate: "fail") {
|
||||
fileset(dir: buildContext.paths.distAll) {
|
||||
exclude(name: "bin/idea.properties")
|
||||
exclude(name: "lib/libpty/**") //todo[nik] this is temporary workaround until IDEA fully migrates to the new scheme
|
||||
}
|
||||
fileset(dir: zipDir)
|
||||
|
||||
|
||||
@@ -39,8 +39,10 @@ class DistributionJARsBuilder {
|
||||
private final BuildContext buildContext
|
||||
private final Set<String> usedModules = new LinkedHashSet<>()
|
||||
private final PlatformLayout platform
|
||||
private final File patchedApplicationInfo
|
||||
|
||||
DistributionJARsBuilder(BuildContext buildContext) {
|
||||
DistributionJARsBuilder(BuildContext buildContext, File patchedApplicationInfo) {
|
||||
this.patchedApplicationInfo = patchedApplicationInfo
|
||||
this.buildContext = buildContext
|
||||
buildContext.ant.patternset(id: RESOURCES_INCLUDED) {
|
||||
include(name: "**/*Bundle*.properties")
|
||||
@@ -205,7 +207,7 @@ class DistributionJARsBuilder {
|
||||
layoutBuilder.patchModuleOutput(productLayout.searchableOptionsModule, FileUtil.toSystemIndependentName(searchableOptionsDir.absolutePath))
|
||||
}
|
||||
|
||||
def applicationInfoFile = FileUtil.toSystemIndependentName(buildTasks.patchApplicationInfo().absolutePath)
|
||||
def applicationInfoFile = FileUtil.toSystemIndependentName(patchedApplicationInfo.absolutePath)
|
||||
def applicationInfoDir = "$buildContext.paths.temp/applicationInfo"
|
||||
ant.copy(file: applicationInfoFile, todir: "$applicationInfoDir/idea")
|
||||
layoutBuilder.patchModuleOutput(buildContext.productProperties.applicationInfoModule, applicationInfoDir)
|
||||
|
||||
@@ -28,9 +28,11 @@ import org.jetbrains.jps.model.module.JpsModuleSourceRoot
|
||||
class WindowsDistributionBuilder extends OsSpecificDistributionBuilder {
|
||||
private final WindowsDistributionCustomizer customizer
|
||||
private final File ideaProperties
|
||||
private final File patchedApplicationInfo
|
||||
|
||||
WindowsDistributionBuilder(BuildContext buildContext, WindowsDistributionCustomizer customizer, File ideaProperties) {
|
||||
WindowsDistributionBuilder(BuildContext buildContext, WindowsDistributionCustomizer customizer, File ideaProperties, File patchedApplicationInfo) {
|
||||
super(BuildOptions.OS_WINDOWS, "Windows", buildContext)
|
||||
this.patchedApplicationInfo = patchedApplicationInfo
|
||||
this.customizer = customizer
|
||||
this.ideaProperties = ideaProperties
|
||||
}
|
||||
@@ -101,7 +103,6 @@ class WindowsDistributionBuilder extends OsSpecificDistributionBuilder {
|
||||
|
||||
private void generateScripts(String winDistPath) {
|
||||
String fullName = buildContext.applicationInfo.productName
|
||||
//todo[nik] looks like names without .exe were also supported, do we need this?
|
||||
String vmOptionsFileName = "${buildContext.productProperties.baseFileName}%BITS%.exe"
|
||||
|
||||
String classPath = "SET CLASS_PATH=%IDE_HOME%\\lib\\${buildContext.bootClassPathJarNames[0]}\n"
|
||||
@@ -185,7 +186,7 @@ IDS_VM_OPTIONS=$vmOptions
|
||||
buildContext.ant.java(classname: "com.pme.launcher.LauncherGeneratorMain", fork: "true", failonerror: "true") {
|
||||
sysproperty(key: "java.awt.headless", value: "true")
|
||||
arg(value: inputPath)
|
||||
arg(value: buildContext.findApplicationInfoInSources().absolutePath)
|
||||
arg(value: patchedApplicationInfo.absolutePath)
|
||||
arg(value: "$communityHome/native/WinLauncher/WinLauncher/resource.h")
|
||||
arg(value: launcherPropertiesPath)
|
||||
arg(value: outputPath)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
|
||||
import org.jetbrains.intellij.build.*
|
||||
import org.jetbrains.intellij.build.impl.BuildTasksImpl
|
||||
import org.jetbrains.jps.util.JpsPathUtil
|
||||
|
||||
import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome
|
||||
@@ -41,7 +42,7 @@ boolean setPluginAndIDEVersionInPluginXml() {
|
||||
}
|
||||
|
||||
List<String> getExcludedPlugins() {
|
||||
return isDefined("productProperties") ? productProperties.excludedPlugins : []
|
||||
return []
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,7 +52,7 @@ def layoutFull(BuildContext context) {
|
||||
binding.setVariable("productProperties", context.productProperties)
|
||||
String home = context.paths.communityHome
|
||||
String targetDirectory = context.paths.distAll
|
||||
File patchedApplicationInfo = BuildTasks.create(context).patchApplicationInfo()
|
||||
File patchedApplicationInfo = ((BuildTasksImpl)BuildTasks.create(context)).patchApplicationInfo()
|
||||
projectBuilder.stage("layout to $targetDirectory")
|
||||
|
||||
List<String> jpsCommonModules = ["jps-model-impl", "jps-model-serialization"]
|
||||
|
||||
+7
-13
@@ -195,9 +195,10 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
|
||||
return canBeConvertedToLambda(aClass, acceptParameterizedFunctionTypes, true, ignoredRuntimeAnnotations);
|
||||
}
|
||||
|
||||
public static boolean isClassAndMethodSuitableForConversion(PsiAnonymousClass aClass,
|
||||
PsiMethod method,
|
||||
Set<String> ignoredRuntimeAnnotations) {
|
||||
public static boolean isLambdaForm(PsiAnonymousClass aClass, Set<String> ignoredRuntimeAnnotations) {
|
||||
PsiMethod[] methods = aClass.getMethods();
|
||||
if(methods.length != 1) return false;
|
||||
PsiMethod method = methods[0];
|
||||
return aClass.getFields().length == 0 &&
|
||||
aClass.getInnerClasses().length == 0 &&
|
||||
aClass.getInitializers().length == 0 &&
|
||||
@@ -222,16 +223,9 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
|
||||
}
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
|
||||
if (interfaceMethod != null && (acceptParameterizedFunctionTypes || !interfaceMethod.hasTypeParameters())) {
|
||||
final PsiMethod[] methods = aClass.getMethods();
|
||||
if (methods.length == 1) {
|
||||
final PsiMethod method = methods[0];
|
||||
if (isClassAndMethodSuitableForConversion(aClass, method, ignoredRuntimeAnnotations)) {
|
||||
final PsiType inferredType = getInferredType(aClass, method);
|
||||
if (inferredType == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (isLambdaForm(aClass, ignoredRuntimeAnnotations)) {
|
||||
final PsiMethod method = aClass.getMethods()[0];
|
||||
return getInferredType(aClass, method) != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-15
@@ -66,21 +66,19 @@ public class AnonymousHasLambdaAlternativeInspection extends BaseJavaBatchLocalI
|
||||
@Override
|
||||
public void visitAnonymousClass(final PsiAnonymousClass aClass) {
|
||||
super.visitAnonymousClass(aClass);
|
||||
PsiMethod[] methods = aClass.getMethods();
|
||||
if(methods.length == 1) {
|
||||
PsiMethod method = methods[0];
|
||||
PsiExpressionList argumentList = aClass.getArgumentList();
|
||||
if (AnonymousCanBeLambdaInspection.isClassAndMethodSuitableForConversion(aClass, method, Collections.emptySet()) &&
|
||||
argumentList != null && argumentList.getExpressions().length == 0) {
|
||||
PsiClassType type = aClass.getBaseClassType();
|
||||
AnonymousLambdaAlternative alternative = getAlternative(type.resolve(), method);
|
||||
if(alternative != null) {
|
||||
final PsiElement lBrace = aClass.getLBrace();
|
||||
LOG.assertTrue(lBrace != null);
|
||||
final TextRange rangeInElement = new TextRange(0, lBrace.getStartOffsetInParent() + aClass.getStartOffsetInParent() - 1);
|
||||
holder.registerProblem(aClass.getParent(), "Anonymous #ref #loc can be replaced with "+alternative.myReplacementMessage,
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithLambdaAlternativeFix(alternative));
|
||||
}
|
||||
PsiExpressionList argumentList = aClass.getArgumentList();
|
||||
if (AnonymousCanBeLambdaInspection.isLambdaForm(aClass, Collections.emptySet()) &&
|
||||
argumentList != null &&
|
||||
argumentList.getExpressions().length == 0) {
|
||||
PsiMethod method = aClass.getMethods()[0];
|
||||
PsiClassType type = aClass.getBaseClassType();
|
||||
AnonymousLambdaAlternative alternative = getAlternative(type.resolve(), method);
|
||||
if(alternative != null) {
|
||||
final PsiElement lBrace = aClass.getLBrace();
|
||||
LOG.assertTrue(lBrace != null);
|
||||
final TextRange rangeInElement = new TextRange(0, lBrace.getStartOffsetInParent() + aClass.getStartOffsetInParent() - 1);
|
||||
holder.registerProblem(aClass.getParent(), "Anonymous #ref #loc can be replaced with "+alternative.myReplacementMessage,
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithLambdaAlternativeFix(alternative));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-1
@@ -18,6 +18,7 @@ package com.intellij.codeInspection.dataFlow;
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.AssignInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.Instruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.PushInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.ReturnInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
|
||||
@@ -47,10 +48,12 @@ import java.util.Set;
|
||||
*/
|
||||
class NullParameterConstraintChecker extends DataFlowRunner {
|
||||
private final Set<PsiParameter> myPossiblyViolatedParameters;
|
||||
private final Set<PsiParameter> myUsedParameters;
|
||||
|
||||
private NullParameterConstraintChecker(Collection<PsiParameter> parameters, boolean isOnTheFly) {
|
||||
super(false, true, isOnTheFly);
|
||||
myPossiblyViolatedParameters = new THashSet<>(parameters);
|
||||
myUsedParameters = new THashSet<>();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -73,7 +76,7 @@ class NullParameterConstraintChecker extends DataFlowRunner {
|
||||
final NullParameterConstraintChecker checker = new NullParameterConstraintChecker(nullableParameters, true);
|
||||
checker.analyzeMethod(method.getBody(), new StandardInstructionVisitor());
|
||||
|
||||
return checker.myPossiblyViolatedParameters.toArray(new PsiParameter[checker.myPossiblyViolatedParameters.size()]);
|
||||
return checker.myPossiblyViolatedParameters.stream().filter(checker.myUsedParameters::contains).toArray(PsiParameter[]::new);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -81,6 +84,16 @@ class NullParameterConstraintChecker extends DataFlowRunner {
|
||||
protected DfaInstructionState[] acceptInstruction(@NotNull InstructionVisitor visitor, @NotNull DfaInstructionState instructionState) {
|
||||
Instruction instruction = instructionState.getInstruction();
|
||||
|
||||
if (instruction instanceof PushInstruction) {
|
||||
final DfaValue var = ((PushInstruction)instruction).getValue();
|
||||
if (var instanceof DfaVariableValue) {
|
||||
final PsiModifierListOwner psiVar = ((DfaVariableValue)var).getPsiVariable();
|
||||
if (psiVar instanceof PsiParameter) {
|
||||
myUsedParameters.add((PsiParameter)psiVar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (instruction instanceof AssignInstruction) {
|
||||
final DfaValue value = ((AssignInstruction)instruction).getAssignedValue();
|
||||
if (value instanceof DfaVariableValue) {
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@ public class StringExpressionHelper {
|
||||
|
||||
Collection<? extends PsiElement> elements = DfaUtil.getPossibleInitializationElements(expression);
|
||||
for (PsiElement element : elements) {
|
||||
Pair<PsiElement, String> expr = evaluateExpression(element);
|
||||
Pair<PsiElement, String> expr = evaluateExpression(element, visited);
|
||||
if (expr != null) return expr;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -239,14 +239,14 @@ public class Java8CollectionsApiInspection extends BaseJavaBatchLocalInspectionT
|
||||
(getArgument == null || EquivalenceChecker.getCanonicalPsiEquivalence().expressionsAreEquivalent(getArgument, putKeyArgument))) {
|
||||
LocalQuickFix fix = null;
|
||||
if (ExpressionUtils.isSimpleExpression(putValueArgument)) {
|
||||
fix = new ReplaceWithMapPutIfAbsentFix(putMethodCall, "putIfAbsent");
|
||||
fix = new ReplaceConditionalMapPutFix(putMethodCall, false);
|
||||
}
|
||||
else if ((maybePutMethodCall.getParent() instanceof PsiExpressionStatement) && // only if result of put is not used
|
||||
LambdaGenerationUtil.canBeUncheckedLambda(putValueArgument)) {
|
||||
fix = new ReplaceWithMapPutIfAbsentFix(putMethodCall, "computeIfAbsent");
|
||||
fix = new ReplaceConditionalMapPutFix(putMethodCall, true);
|
||||
}
|
||||
else if (mySuggestPutIfAbsentForComplexExpression) {
|
||||
fix = new ReplaceWithMapPutIfAbsentFix(putMethodCall, "putIfAbsent");
|
||||
fix = new ReplaceConditionalMapPutFix(putMethodCall, false);
|
||||
}
|
||||
if(fix != null) {
|
||||
holder.registerProblem(context, QuickFixBundle.message("java.8.collections.api.inspection.description"), fix);
|
||||
|
||||
+7
-4
@@ -32,14 +32,17 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class ReplaceWithMapPutIfAbsentFix implements LocalQuickFix {
|
||||
public class ReplaceConditionalMapPutFix implements LocalQuickFix {
|
||||
private static final String COMPUTE_IF_ABSENT_METHOD = "computeIfAbsent";
|
||||
private static final String PUT_IF_ABSENT_METHOD = "putIfAbsent";
|
||||
|
||||
private final SmartPsiElementPointer<PsiMethodCallExpression> myPutExpressionPointer;
|
||||
private final String myMethodName;
|
||||
|
||||
public ReplaceWithMapPutIfAbsentFix(PsiMethodCallExpression putExpression, String methodName) {
|
||||
public ReplaceConditionalMapPutFix(PsiMethodCallExpression putExpression, boolean useComputeIfAbsent) {
|
||||
final SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(putExpression.getProject());
|
||||
myPutExpressionPointer = smartPointerManager.createSmartPsiElementPointer(putExpression);
|
||||
myMethodName = methodName; // either "putIfAbsent" or "computeIfAbsent"
|
||||
myMethodName = useComputeIfAbsent ? COMPUTE_IF_ABSENT_METHOD : PUT_IF_ABSENT_METHOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,7 +77,7 @@ public class ReplaceWithMapPutIfAbsentFix implements LocalQuickFix {
|
||||
final Couple<String> boundText = getBoundText(putContainingElement, putExpression);
|
||||
|
||||
String valueArgument = putExpression.getArgumentList().getExpressions()[1].getText();
|
||||
if(myMethodName.equals("computeIfAbsent")) {
|
||||
if(myMethodName.equals(COMPUTE_IF_ABSENT_METHOD)) {
|
||||
String varName = JavaCodeStyleManager.getInstance(project).suggestUniqueVariableName("k", putExpression, true);
|
||||
valueArgument = varName + " -> " + valueArgument;
|
||||
}
|
||||
+300
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.util.LambdaRefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import com.siyeh.ig.style.MethodRefCanBeReplacedWithLambdaInspection;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class InlineStreamMapAction extends PsiElementBaseIntentionAction {
|
||||
private static final Logger LOG = Logger.getInstance(InlineStreamMapAction.class.getName());
|
||||
|
||||
private static final Set<String> MAP_METHODS =
|
||||
StreamEx.of("map", "mapToInt", "mapToLong", "mapToDouble", "mapToObj", "boxed", "asLongStream", "asDoubleStream").toSet();
|
||||
|
||||
private static final Set<String> NEXT_METHODS = StreamEx
|
||||
.of("flatMap", "flatMapToInt", "flatMapToLong", "flatMapToDouble", "forEach", "forEachOrdered", "anyMatch", "noneMatch", "allMatch")
|
||||
.append(MAP_METHODS).toSet();
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull final PsiElement element) {
|
||||
if (!(element instanceof PsiIdentifier)) return false;
|
||||
final PsiElement parent = element.getParent();
|
||||
if (!(parent instanceof PsiReferenceExpression)) return false;
|
||||
final PsiElement gParent = parent.getParent();
|
||||
if (!(gParent instanceof PsiMethodCallExpression)) return false;
|
||||
PsiMethodCallExpression curCall = (PsiMethodCallExpression)gParent;
|
||||
if (!isMapCall(curCall)) return false;
|
||||
PsiMethodCallExpression nextCall = getNextExpressionToMerge(curCall);
|
||||
if(nextCall == null) return false;
|
||||
String key = curCall.getArgumentList().getExpressions().length == 0 || nextCall.getArgumentList().getExpressions().length == 0 ?
|
||||
"intention.inline.map.merge.text" : "intention.inline.map.inline.text";
|
||||
setText(CodeInsightBundle.message(key, element.getText(), nextCall.getMethodExpression().getReferenceName()));
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isMapCall(@NotNull PsiMethodCallExpression methodCallExpression) {
|
||||
String name = methodCallExpression.getMethodExpression().getReferenceName();
|
||||
if (name == null || !MAP_METHODS.contains(name)) return false;
|
||||
|
||||
final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
|
||||
final PsiExpression[] expressions = argumentList.getExpressions();
|
||||
if (!name.startsWith("map") && expressions.length == 0) return true;
|
||||
if (expressions.length != 1) return false;
|
||||
if (!isSupportedForConversion(expressions[0], true)) return false;
|
||||
|
||||
final PsiMethod method = methodCallExpression.resolveMethod();
|
||||
if (method == null) return false;
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
return InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_UTIL_STREAM_BASE_STREAM);
|
||||
}
|
||||
|
||||
private static boolean isSupportedForConversion(PsiExpression expression, boolean requireExpressionLambda) {
|
||||
if(expression instanceof PsiLambdaExpression) {
|
||||
PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)expression;
|
||||
return lambdaExpression.getParameterList().getParametersCount() == 1 &&
|
||||
(!requireExpressionLambda || LambdaUtil.extractSingleExpressionFromBody(lambdaExpression.getBody()) != null);
|
||||
} else if(expression instanceof PsiMethodReferenceExpression) {
|
||||
PsiMethodReferenceExpression methodReference = (PsiMethodReferenceExpression)expression;
|
||||
return !MethodRefCanBeReplacedWithLambdaInspection.isWithSideEffects(methodReference);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiMethodCallExpression getNextExpressionToMerge(PsiMethodCallExpression methodCallExpression) {
|
||||
PsiElement parent = methodCallExpression.getParent();
|
||||
if(!(parent instanceof PsiReferenceExpression)) return null;
|
||||
PsiElement gParent = parent.getParent();
|
||||
if(!(gParent instanceof PsiMethodCallExpression)) return null;
|
||||
String nextName = ((PsiReferenceExpression)parent).getReferenceName();
|
||||
PsiMethodCallExpression nextCall = (PsiMethodCallExpression)gParent;
|
||||
if(nextName == null || !NEXT_METHODS.contains(nextName) || translateName(methodCallExpression, nextCall) == null) return null;
|
||||
PsiExpressionList argumentList = (nextCall).getArgumentList();
|
||||
PsiExpression[] expressions = argumentList.getExpressions();
|
||||
if(expressions.length == 0) {
|
||||
if (!nextName.equals("boxed") && !nextName.equals("asLongStream") && !nextName.equals("asDoubleStream")) return null;
|
||||
return nextCall;
|
||||
}
|
||||
if (expressions.length != 1 || !isSupportedForConversion(expressions[0], false)) return null;
|
||||
|
||||
return nextCall;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate name of joint method call which combines two given calls
|
||||
*
|
||||
* @param prevCall previous call (assumed to be in MAP_METHODS)
|
||||
* @param nextCall next call (assumed to be in NEXT_METHODS)
|
||||
* @return a name of the resulting method
|
||||
*/
|
||||
@Nullable
|
||||
private static String translateName(@NotNull PsiMethodCallExpression prevCall, @NotNull PsiMethodCallExpression nextCall) {
|
||||
PsiMethod nextMethod = nextCall.resolveMethod();
|
||||
if (nextMethod == null) return null;
|
||||
String nextName = nextMethod.getName();
|
||||
PsiMethod method = prevCall.resolveMethod();
|
||||
if (method == null) return null;
|
||||
PsiClass prevClass = method.getContainingClass();
|
||||
if (prevClass == null) return null;
|
||||
String prevClassName = prevClass.getQualifiedName();
|
||||
if (prevClassName == null) return null;
|
||||
String prevName = method.getName();
|
||||
if (nextName.endsWith("Match") || nextName.startsWith("forEach")) return nextName;
|
||||
if (nextName.equals("map")) {
|
||||
return translateMap(prevName);
|
||||
}
|
||||
if (prevName.equals("map")) {
|
||||
return translateMap(nextName);
|
||||
}
|
||||
if(MAP_METHODS.contains(nextName)) {
|
||||
PsiType type = nextMethod.getReturnType();
|
||||
if(!(type instanceof PsiClassType)) return null;
|
||||
PsiClass nextClass = ((PsiClassType)type).resolve();
|
||||
if(nextClass == null) return null;
|
||||
String nextClassName = nextClass.getQualifiedName();
|
||||
if(nextClassName == null) return null;
|
||||
if(prevClassName.equals(nextClassName)) return "map";
|
||||
switch(nextClassName) {
|
||||
case CommonClassNames.JAVA_UTIL_STREAM_INT_STREAM:
|
||||
return "mapToInt";
|
||||
case CommonClassNames.JAVA_UTIL_STREAM_LONG_STREAM:
|
||||
return "mapToLong";
|
||||
case CommonClassNames.JAVA_UTIL_STREAM_DOUBLE_STREAM:
|
||||
return "mapToDouble";
|
||||
case CommonClassNames.JAVA_UTIL_STREAM_STREAM:
|
||||
return "mapToObj";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if(nextName.equals("flatMap") && prevClassName.equals(CommonClassNames.JAVA_UTIL_STREAM_STREAM)) {
|
||||
String mapMethod = translateMap(prevName);
|
||||
return "flatM"+mapMethod.substring(1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String translateMap(String nextMethod) {
|
||||
switch (nextMethod) {
|
||||
case "boxed":
|
||||
return "mapToObj";
|
||||
case "asLongStream":
|
||||
return "mapToLong";
|
||||
case "asDoubleStream":
|
||||
return "mapToDouble";
|
||||
default:
|
||||
return nextMethod;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return CodeInsightBundle.message("intention.inline.map.family");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
|
||||
PsiMethodCallExpression mapCall = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
|
||||
if(mapCall == null) return;
|
||||
|
||||
PsiMethodCallExpression nextCall = getNextExpressionToMerge(mapCall);
|
||||
if(nextCall == null) return;
|
||||
|
||||
PsiExpression nextQualifier = nextCall.getMethodExpression().getQualifierExpression();
|
||||
if(nextQualifier == null) return;
|
||||
|
||||
String newName = translateName(mapCall, nextCall);
|
||||
if(newName == null) return;
|
||||
|
||||
if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
|
||||
|
||||
PsiLambdaExpression previousLambda = getLambda(mapCall);
|
||||
|
||||
LOG.assertTrue(previousLambda != null);
|
||||
PsiExpression previousBody = LambdaUtil.extractSingleExpressionFromBody(previousLambda.getBody());
|
||||
LOG.assertTrue(previousBody != null);
|
||||
|
||||
PsiLambdaExpression lambda = getLambda(nextCall);
|
||||
LOG.assertTrue(lambda != null);
|
||||
|
||||
if(!lambda.isPhysical()) {
|
||||
lambda = (PsiLambdaExpression)nextCall.getArgumentList().add(lambda);
|
||||
}
|
||||
PsiElement body = lambda.getBody();
|
||||
LOG.assertTrue(body != null);
|
||||
|
||||
PsiParameter[] nextParameters = lambda.getParameterList().getParameters();
|
||||
LOG.assertTrue(nextParameters.length == 1);
|
||||
PsiParameter[] prevParameters = previousLambda.getParameterList().getParameters();
|
||||
LOG.assertTrue(prevParameters.length == 1);
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
for(PsiReference ref : ReferencesSearch.search(nextParameters[0], new LocalSearchScope(body)).findAll()) {
|
||||
PsiElement e = ref.getElement();
|
||||
PsiExpression replacement = previousBody;
|
||||
if (e.getParent() instanceof PsiExpression &&
|
||||
ParenthesesUtils.areParenthesesNeeded(previousBody, (PsiExpression)e.getParent(), false)) {
|
||||
replacement = factory.createExpressionFromText("(a)", e);
|
||||
PsiExpression parenthesized = ((PsiParenthesizedExpression)replacement).getExpression();
|
||||
LOG.assertTrue(parenthesized != null);
|
||||
parenthesized.replace(previousBody);
|
||||
}
|
||||
e.replace(replacement);
|
||||
}
|
||||
nextParameters[0].replace(prevParameters[0]);
|
||||
PsiElement nameElement = nextCall.getMethodExpression().getReferenceNameElement();
|
||||
if(nameElement != null && !nameElement.getText().equals(newName)) {
|
||||
nameElement.replace(factory.createIdentifier(newName));
|
||||
}
|
||||
PsiExpression prevQualifier = mapCall.getMethodExpression().getQualifierExpression();
|
||||
if(prevQualifier == null) {
|
||||
nextQualifier.delete();
|
||||
} else {
|
||||
nextQualifier.replace(prevQualifier);
|
||||
}
|
||||
CodeStyleManager.getInstance(project).reformat(lambda);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiLambdaExpression getLambda(PsiMethodCallExpression call) {
|
||||
PsiExpression[] expressions = call.getArgumentList().getExpressions();
|
||||
if(expressions.length == 1) {
|
||||
PsiExpression expression = expressions[0];
|
||||
if(expression instanceof PsiLambdaExpression) return (PsiLambdaExpression)expression;
|
||||
if(expression instanceof PsiMethodReferenceExpression) {
|
||||
return LambdaRefactoringUtil.convertMethodReferenceToLambda((PsiMethodReferenceExpression)expression, false, true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if(expressions.length != 0) return null;
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if(method == null) return null;
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
if(containingClass == null) return null;
|
||||
String className = containingClass.getQualifiedName();
|
||||
if(className == null) return null;
|
||||
String varName;
|
||||
String type;
|
||||
switch (className) {
|
||||
case CommonClassNames.JAVA_UTIL_STREAM_INT_STREAM:
|
||||
varName = "i";
|
||||
type = CommonClassNames.JAVA_LANG_INTEGER;
|
||||
break;
|
||||
case CommonClassNames.JAVA_UTIL_STREAM_LONG_STREAM:
|
||||
varName = "l";
|
||||
type = CommonClassNames.JAVA_LANG_LONG;
|
||||
break;
|
||||
case CommonClassNames.JAVA_UTIL_STREAM_DOUBLE_STREAM:
|
||||
varName = "d";
|
||||
type = CommonClassNames.JAVA_LANG_DOUBLE;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
varName = JavaCodeStyleManager.getInstance(call.getProject()).suggestUniqueVariableName(varName, call, true);
|
||||
String expression;
|
||||
if("boxed".equals(method.getName())) {
|
||||
expression = varName+" -> ("+type+")"+varName;
|
||||
} else if("asLongStream".equals(method.getName())) {
|
||||
expression = varName+" -> (long)"+varName;
|
||||
} else if("asDoubleStream".equals(method.getName())) {
|
||||
expression = varName+" -> (double)"+varName;
|
||||
} else return null;
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(call.getProject());
|
||||
return (PsiLambdaExpression)factory.createExpressionFromText(expression, call);
|
||||
}
|
||||
}
|
||||
@@ -219,30 +219,27 @@ public class JavaQualifiedNameProvider implements QualifiedNameProvider {
|
||||
final PsiExpression expression;
|
||||
try {
|
||||
expression = factory.createExpressionFromText(toInsert + suffix, elementAtCaret);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
return;
|
||||
}
|
||||
final PsiReferenceExpression referenceExpression = expression instanceof PsiMethodCallExpression
|
||||
? ((PsiMethodCallExpression)expression).getMethodExpression()
|
||||
: expression instanceof PsiReferenceExpression
|
||||
? (PsiReferenceExpression)expression
|
||||
: null;
|
||||
if (referenceExpression == null || !referenceExpression.isValid()) {
|
||||
toInsert = fqn;
|
||||
}
|
||||
else if (!isReferencedTo(referenceExpression, targetElement)) {
|
||||
try {
|
||||
referenceExpression.bindToElement(targetElement);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
// failed to bind
|
||||
}
|
||||
if (!referenceExpression.isValid() || !isReferencedTo(referenceExpression, targetElement)) {
|
||||
final PsiReferenceExpression referenceExpression = expression instanceof PsiMethodCallExpression
|
||||
? ((PsiMethodCallExpression)expression).getMethodExpression()
|
||||
: expression instanceof PsiReferenceExpression
|
||||
? (PsiReferenceExpression)expression
|
||||
: null;
|
||||
if (referenceExpression == null || !referenceExpression.isValid()) {
|
||||
toInsert = fqn;
|
||||
}
|
||||
else if (!isReferencedTo(referenceExpression, targetElement)) {
|
||||
try {
|
||||
referenceExpression.bindToElement(targetElement);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
// failed to bind
|
||||
}
|
||||
if (!referenceExpression.isValid() || !isReferencedTo(referenceExpression, targetElement)) {
|
||||
toInsert = fqn;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException ignored) {}
|
||||
}
|
||||
if (toInsert == null) toInsert = "";
|
||||
|
||||
|
||||
+12
-12
@@ -699,8 +699,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
final PsiElement chosenAnchor =
|
||||
chooseAnchor(settings.isReplaceAllOccurrences(), hasWriteAccess, nonWrite, anchorStatementIfAll, anchorStatement);
|
||||
|
||||
variable = ApplicationManager.getApplication().runWriteAction(
|
||||
introduce(project, expr, topLevelEditor, chosenAnchor, occurrences, settings));
|
||||
variable = introduce(project, expr, topLevelEditor, chosenAnchor, occurrences, settings);
|
||||
}
|
||||
finally {
|
||||
final RefactoringEventData afterData = new RefactoringEventData();
|
||||
@@ -794,12 +793,12 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
return parent3 instanceof JspHolderMethod;
|
||||
}
|
||||
|
||||
public static Computable<PsiVariable> introduce(final Project project,
|
||||
final PsiExpression expr,
|
||||
final Editor editor,
|
||||
final PsiElement anchorStatement,
|
||||
final PsiExpression[] occurrences,
|
||||
final IntroduceVariableSettings settings) {
|
||||
public static PsiVariable introduce(final Project project,
|
||||
final PsiExpression expr,
|
||||
final Editor editor,
|
||||
final PsiElement anchorStatement,
|
||||
final PsiExpression[] occurrences,
|
||||
final IntroduceVariableSettings settings) {
|
||||
final PsiElement container = anchorStatement.getParent();
|
||||
PsiElement child = anchorStatement;
|
||||
final boolean isInsideLoop = RefactoringUtil.isLoopOrIf(container);
|
||||
@@ -841,9 +840,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
|
||||
final PsiCodeBlock newDeclarationScope = PsiTreeUtil.getParentOfType(container, PsiCodeBlock.class, false);
|
||||
final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(settings.getEnteredName(), newDeclarationScope);
|
||||
return new Computable<PsiVariable>() {
|
||||
SmartPsiElementPointer<PsiVariable> pointer = ApplicationManager.getApplication().runWriteAction(new Computable<SmartPsiElementPointer<PsiVariable>> () {
|
||||
@Override
|
||||
public PsiVariable compute() {
|
||||
public SmartPsiElementPointer<PsiVariable> compute() {
|
||||
try {
|
||||
PsiStatement statement = null;
|
||||
if (!isInsideLoop && deleteSelf) {
|
||||
@@ -913,7 +912,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
PsiVariable var = (PsiVariable) declaration.getDeclaredElements()[0];
|
||||
PsiUtil.setModifierProperty(var, PsiModifier.FINAL, settings.isDeclareFinal());
|
||||
fieldConflictsResolver.fix();
|
||||
return var;
|
||||
return SmartPointerManager.getInstance(project).createSmartPsiElementPointer(var);
|
||||
} catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
@@ -945,7 +944,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
}
|
||||
return (PsiDeclarationStatement) container.addBefore(declaration, anchor);
|
||||
}
|
||||
};
|
||||
});
|
||||
return pointer != null ? pointer.getElement() : null;
|
||||
}
|
||||
|
||||
private static PsiType stripNullabilityAnnotationsFromTargetType(SmartTypePointer selectedType, final Project project) {
|
||||
|
||||
+11
-6
@@ -395,10 +395,19 @@ public class JavaVariableInplaceIntroducer extends AbstractJavaInplaceIntroducer
|
||||
|
||||
@Override
|
||||
protected PsiVariable createFieldToStartTemplateOn(String[] names, PsiType psiType) {
|
||||
final PsiVariable variable = ApplicationManager.getApplication().runWriteAction(
|
||||
IntroduceVariableBase.introduce(myProject, myExpr, myEditor, myChosenAnchor.getElement(), getOccurrences(), mySettings));
|
||||
PsiVariable variable = IntroduceVariableBase.introduce(myProject, myExpr, myEditor, myChosenAnchor.getElement(), getOccurrences(), mySettings);
|
||||
final PsiDeclarationStatement declarationStatement = PsiTreeUtil.getParentOfType(variable, PsiDeclarationStatement.class);
|
||||
myPointer = declarationStatement != null ? SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(declarationStatement) : null;
|
||||
myEditor.putUserData(ReassignVariableUtil.DECLARATION_KEY, myPointer);
|
||||
setAdvertisementText(getAdvertisementText(declarationStatement, variable.getType(), myHasTypeSuggestion));
|
||||
|
||||
PsiDocumentManager.getInstance(myProject).doPostponedOperationsAndUnblockDocument(myEditor.getDocument());
|
||||
|
||||
final PsiVariable restoredVar = getVariable();
|
||||
if (restoredVar != null) {
|
||||
variable = restoredVar;
|
||||
}
|
||||
|
||||
if (isReplaceAllOccurrences()) {
|
||||
List<RangeMarker> occurrences = new ArrayList<>();
|
||||
ReferencesSearch.search(variable).forEach(reference -> {
|
||||
@@ -407,10 +416,6 @@ public class JavaVariableInplaceIntroducer extends AbstractJavaInplaceIntroducer
|
||||
setOccurrenceMarkers(occurrences);
|
||||
}
|
||||
|
||||
final PsiDeclarationStatement declarationStatement = PsiTreeUtil.getParentOfType(variable, PsiDeclarationStatement.class);
|
||||
myPointer = declarationStatement != null ? SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(declarationStatement) : null;
|
||||
myEditor.putUserData(ReassignVariableUtil.DECLARATION_KEY, myPointer);
|
||||
setAdvertisementText(getAdvertisementText(declarationStatement, variable.getType(), myHasTypeSuggestion));
|
||||
final PsiIdentifier identifier = variable.getNameIdentifier();
|
||||
if (identifier != null) {
|
||||
myEditor.getCaretModel().moveToOffset(identifier.getTextOffset());
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Merge 'asLongStream' call and 'map' call" "true"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> (String)cs).mapToInt(String::length).mapToLong(i -> (long) i * 2).boxed().forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Merge 'boxed' call and 'forEach' call" "true"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> (String)cs).mapToInt(String::length).asLongStream().map(x -> x*2).forEach((l) -> System.out.println((Long) l));
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Merge 'map' call and 'boxed' call" "true"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> (String)cs).mapToInt(String::length).asLongStream().mapToObj(x -> (Long) (x * 2)).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Inline 'map' body into the next 'forEach' call" "true"
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> cs.subSequence(1, 5)).forEach((charSequence) -> System.out.println(charSequence.length()));
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Inline 'map' body into the next 'map' call" "true"
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> cs.subSequence(1, 5).length()).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Inline 'map' body into the next 'map' call" "true"
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> cs.subSequence(1, 5).length()).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Inline 'map' body into the next 'map' call" "true"
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map((cs) -> cs.subSequence(1, 5).length()).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Inline 'map' body into the next 'mapToInt' call" "true"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().mapToInt((cs) -> ((String) cs).length()).asLongStream().map(x -> x*2).boxed().forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Merge 'mapToInt' call and 'asLongStream' call" "true"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> (String)cs).mapToLong(s -> (long) s.length()).map(x -> x*2).boxed().forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Inline 'mapToInt' body into the next 'flatMap' call" "true"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> (String)cs).flatMapToInt(s1 -> IntStream.range(0, s1.length())).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Merge 'asLongStream' call and 'map' call" "true"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> (String)cs).mapToInt(String::length).asLon<caret>gStream().map(x -> x*2).boxed().forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Merge 'boxed' call and 'forEach' call" "true"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> (String)cs).mapToInt(String::length).asLongStream().map(x -> x*2).bo<caret>xed().forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Inline 'flatMap' body into the next 'forEach' call" "false"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> (String)cs).mapToInt(String::length).fl<caret>atMap(s -> IntStream.range(0, s)).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Merge 'map' call and 'boxed' call" "true"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> (String)cs).mapToInt(String::length).asLongStream().ma<caret>p(x -> x*2).boxed().forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Inline 'map' body into the next 'forEach' call" "true"
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> cs.subSequence(1, 5)).ma<caret>p(CharSequence::length).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Inline 'map' body into the next 'map' call" "true"
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().m<caret>ap(cs -> cs.subSequence(1, 5)).map(cs -> cs.length()).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Inline 'map' body into the next 'map' call" "true"
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().m<caret>ap(cs -> {
|
||||
return cs.subSequence(1, 5);
|
||||
}).map(cs -> cs.length()).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Inline 'map' body into the next 'map' call" "true"
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().m<caret>ap(cs -> cs.subSequence(1, 5)).map(CharSequence::length).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Inline 'map' body into the next 'mapToInt' call" "true"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().m<caret>ap(cs -> (String)cs).mapToInt(String::length).asLongStream().map(x -> x*2).boxed().forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Inline 'map' body into the next 'map' call" "false"
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().m<caret>ap(cs -> {
|
||||
cs = cs.subSequence(0, 10);
|
||||
return cs.subSequence(1, 5);
|
||||
}).map(cs -> cs.length()).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Merge 'mapToInt' call and 'asLongStream' call" "true"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> (String)cs).ma<caret>pToInt(String::length).asLongStream().map(x -> x*2).boxed().forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Inline 'mapToInt' body into the next 'flatMap' call" "true"
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
public static void test(List<CharSequence> list) {
|
||||
list.stream().map(cs -> (String)cs).ma<caret>pToInt(String::length).flatMap(s -> IntStream.range(0, s)).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class Test {
|
||||
|
||||
void m() {
|
||||
throwAnException(<warning descr="Passing 'null' argument to non annotated parameter">null</warning>);
|
||||
}
|
||||
|
||||
static void throwAnException(String arg) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class C {
|
||||
void sort(int[] array) {
|
||||
int j;
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
j = 0;
|
||||
while (j<i)&&(array[j]<caret>>array[i])
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class C {
|
||||
void sort(int[] array) {
|
||||
int j;
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
j = 0;
|
||||
while (j<i) boolean bool = array[j] > array[i];&&(array[j] > array[i])
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.codeInsight.intention;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LightIntentionActionTestCase;
|
||||
|
||||
public class InlineStreamMapActionTest extends LightIntentionActionTestCase {
|
||||
|
||||
public void test() throws Exception { doAllTests(); }
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/inlineStreamMap";
|
||||
}
|
||||
}
|
||||
@@ -405,4 +405,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
|
||||
public void testNullLiteralAndInferredMethodContract() {
|
||||
doTest();
|
||||
}
|
||||
public void testNullLiteralArgumentDoesntReportedWhenMethodOnlyThrowAnException() { doTest(); }
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.profile.Profile;
|
||||
import com.intellij.profile.codeInspection.InspectionProfileManager;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager;
|
||||
import com.intellij.profile.codeInspection.ui.header.InspectionToolsConfigurable;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
@@ -43,8 +42,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.profile.ProfileEx.serializeProfile;
|
||||
import static com.intellij.testFramework.PlatformTestUtil.assertElementsEqual;
|
||||
import static com.intellij.testFramework.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Anna.Kozlova
|
||||
@@ -80,11 +78,11 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
profile.readExternal(element);
|
||||
final ModifiableModel model = profile.getModifiableModel();
|
||||
model.commit();
|
||||
assertElementsEqual(element, serializeProfile(profile));
|
||||
assertThat(profile.writeScheme()).isEqualTo(element);
|
||||
}
|
||||
|
||||
private static InspectionProfileImpl createProfile() {
|
||||
return new InspectionProfileImpl(PROFILE, InspectionToolRegistrar.getInstance(), InspectionProfileManager.getInstance(), InspectionProfileImpl.getDefaultProfile(), null);
|
||||
return new InspectionProfileImpl(PROFILE, InspectionToolRegistrar.getInstance(), InspectionProfileManager.getInstance(), InspectionProfileImpl.getBaseProfile(), null);
|
||||
}
|
||||
private static InspectionProfileImpl createProfile(@NotNull InspectionProfileImpl base) {
|
||||
return new InspectionProfileImpl(PROFILE, InspectionToolRegistrar.getInstance(), InspectionProfileManager.getInstance(), base, null);
|
||||
@@ -100,7 +98,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
//normally on open project profile wrappers are init for both managers
|
||||
profileManager.updateProfile(localProfile);
|
||||
InspectionProfileImpl profile = new InspectionProfileImpl(PROFILE, InspectionToolRegistrar.getInstance(), projectProfileManager,
|
||||
InspectionProfileImpl.getDefaultProfile(), null);
|
||||
InspectionProfileImpl.getBaseProfile(), null);
|
||||
projectProfileManager.updateProfile(profile);
|
||||
projectProfileManager.setRootProfile(profile.getName());
|
||||
|
||||
@@ -150,7 +148,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
ModifiableModel model = profile.getModifiableModel();
|
||||
model.commit();
|
||||
|
||||
assertElementsEqual(loadProfile(), serializeProfile(profile));
|
||||
assertThat(profile.writeScheme()).isEqualTo(loadProfile());
|
||||
}
|
||||
|
||||
private static Element loadProfile() throws IOException, JDOMException {
|
||||
@@ -206,7 +204,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
profile.readExternal(element);
|
||||
final ModifiableModel model = profile.getModifiableModel();
|
||||
model.commit();
|
||||
assertElementsEqual(element, serializeProfile(profile));
|
||||
assertThat(profile.writeScheme()).isEqualTo(element);
|
||||
}
|
||||
|
||||
public void testMergeUnusedDeclarationAndUnusedSymbol() throws Exception {
|
||||
@@ -218,7 +216,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
profile.readExternal(element);
|
||||
ModifiableModel model = profile.getModifiableModel();
|
||||
model.commit();
|
||||
assertElementsEqual(element, serializeProfile(profile));
|
||||
assertThat(profile.writeScheme()).isEqualTo(element);
|
||||
|
||||
|
||||
//settings to merge
|
||||
@@ -290,7 +288,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
"</profile>";
|
||||
assertEquals(mergedText, serialize(profile));
|
||||
|
||||
Element toImportElement = serializeProfile(profile);
|
||||
Element toImportElement = profile.writeScheme();
|
||||
final InspectionProfileImpl importedProfile =
|
||||
InspectionToolsConfigurable.importInspectionProfile(toImportElement, InspectionProfileManager.getInstance(), getProject(), null);
|
||||
|
||||
@@ -300,9 +298,9 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
profile.readExternal(mergedElement);
|
||||
model = profile.getModifiableModel();
|
||||
model.commit();
|
||||
assertElementsEqual(mergedElement, serializeProfile(profile));
|
||||
assertThat(profile.writeScheme()).isEqualTo(mergedElement);
|
||||
|
||||
assertElementsEqual(mergedElement, serializeProfile(importedProfile));
|
||||
assertThat(importedProfile.writeScheme()).isEqualTo(mergedElement);
|
||||
}
|
||||
|
||||
public void testStoredMemberVisibility() throws Exception {
|
||||
@@ -510,7 +508,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
"</profile>",
|
||||
serialize(profile));
|
||||
|
||||
Element element = serializeProfile(profile);
|
||||
Element element = profile.writeScheme();
|
||||
|
||||
list.add(createTool("bar", true));
|
||||
list.add(createTool("disabled", false));
|
||||
@@ -537,7 +535,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
}
|
||||
|
||||
private static String serialize(InspectionProfileImpl profile) throws WriteExternalException {
|
||||
return JDOMUtil.writeElement(serializeProfile(profile));
|
||||
return JDOMUtil.writeElement(profile.writeScheme());
|
||||
}
|
||||
|
||||
private static InspectionProfileImpl createProfile(@NotNull InspectionToolRegistrar registrar) {
|
||||
@@ -581,7 +579,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
}
|
||||
|
||||
public void testDoNotInstantiateOnSave() throws Exception {
|
||||
InspectionProfileImpl profile = new InspectionProfileImpl("profile", InspectionToolRegistrar.getInstance(), InspectionProfileManager.getInstance(), InspectionProfileImpl.getDefaultProfile(), null);
|
||||
InspectionProfileImpl profile = new InspectionProfileImpl("profile", InspectionToolRegistrar.getInstance(), InspectionProfileManager.getInstance(), InspectionProfileImpl.getBaseProfile(), null);
|
||||
assertEquals(0, countInitializedTools(profile));
|
||||
InspectionToolWrapper[] toolWrappers = profile.getInspectionTools(null);
|
||||
assertTrue(toolWrappers.length > 0);
|
||||
@@ -596,7 +594,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
profile.enableTool(id, getProject());
|
||||
}
|
||||
assertEquals(0, countInitializedTools(profile));
|
||||
serializeProfile(profile);
|
||||
profile.writeScheme();
|
||||
List<InspectionToolWrapper> initializedTools = getInitializedTools(profile);
|
||||
if (initializedTools.size() > 0) {
|
||||
for (InspectionToolWrapper initializedTool : initializedTools) {
|
||||
@@ -619,20 +617,6 @@ public class InspectionProfileTest extends LightIdeaTestCase {
|
||||
assertEquals(1, countInitializedTools(foo));
|
||||
}
|
||||
|
||||
public void testPreserveCompatibility() throws Exception {
|
||||
InspectionProfileImpl foo = new InspectionProfileImpl("foo", InspectionToolRegistrar.getInstance(), InspectionProjectProfileManager.getInstance(getProject()));
|
||||
String test = "<profile version=\"1.0\" is_locked=\"false\">\n" +
|
||||
" <option name=\"myName\" value=\"idea.default\" />\n" +
|
||||
" <inspection_tool class=\"AbstractMethodCallInConstructor\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\" />\n" +
|
||||
" <inspection_tool class=\"AssignmentToForLoopParameter\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n" +
|
||||
" <option name=\"m_checkForeachParameters\" value=\"false\" />\n" +
|
||||
" </inspection_tool>\n" +
|
||||
"</profile>";
|
||||
foo.readExternal(JDOMUtil.loadDocument(test).getRootElement());
|
||||
foo.initInspectionTools(getProject());
|
||||
assertEquals(test, JDOMUtil.writeElement(serializeProfile(foo)));
|
||||
}
|
||||
|
||||
public static int countInitializedTools(@NotNull Profile foo) {
|
||||
return getInitializedTools((InspectionProfileImpl)foo).size();
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class InspectionSchemeTest {
|
||||
@Test fun loadSchemes() {
|
||||
val schemeFile = fsRule.fs.getPath("inspection/Bar.xml")
|
||||
val schemeData = """
|
||||
<inspections profile_name="Bar" version="1.0">
|
||||
<inspections version="1.0">
|
||||
<option name="myName" value="Bar" />
|
||||
<inspection_tool class="Since15" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||
"</inspections>""".trimIndent()
|
||||
@@ -51,7 +51,7 @@ class InspectionSchemeTest {
|
||||
profileManager.forceInitProfiles(true)
|
||||
profileManager.initProfiles()
|
||||
|
||||
assertThat(profileManager.profiles).hasSize(2)
|
||||
assertThat(profileManager.profiles).hasSize(1)
|
||||
val scheme = profileManager.profiles.first() as InspectionProfileImpl
|
||||
assertThat(scheme.name).isEqualTo("Bar")
|
||||
|
||||
@@ -61,5 +61,11 @@ class InspectionSchemeTest {
|
||||
|
||||
assertThat(schemeFile.readText()).isEqualTo(schemeData)
|
||||
profileManager.profiles
|
||||
|
||||
schemeManagerFactory.process {
|
||||
it.reload()
|
||||
}
|
||||
|
||||
assertThat(profileManager.profiles).hasSize(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +205,15 @@ public class InplaceIntroduceVariableTest extends AbstractJavaInplaceIntroduceTe
|
||||
doTestReplaceChoice(OccurrencesChooser.ReplaceChoice.ALL);
|
||||
}
|
||||
|
||||
public void testBrokenFormattingWithInValidation() throws Exception {
|
||||
doTest(new Pass<AbstractInplaceIntroducer>() {
|
||||
@Override
|
||||
public void pass(AbstractInplaceIntroducer introducer) {
|
||||
type("bool");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testStopEditing() {
|
||||
doTestStopEditing(new Pass<AbstractInplaceIntroducer>() {
|
||||
@Override
|
||||
|
||||
+14
-10
@@ -60,7 +60,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
|
||||
return ActionHint.parse(file, contents);
|
||||
}
|
||||
|
||||
private static void doTestFor(final String testName, final QuickFixTestCase quickFixTestCase) {
|
||||
private static void doTestFor(@NotNull String testName, @NotNull QuickFixTestCase quickFixTestCase) {
|
||||
final String relativePath = ObjectUtils.notNull(quickFixTestCase.getBasePath(), "") + "/" + BEFORE_PREFIX + testName;
|
||||
final String testFullPath = quickFixTestCase.getTestDataPath().replace(File.separatorChar, '/') + relativePath;
|
||||
final File testFile = new File(testFullPath);
|
||||
@@ -204,7 +204,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
|
||||
return files;
|
||||
}
|
||||
|
||||
protected void doSingleTest(String fileSuffix) {
|
||||
protected void doSingleTest(@NotNull String fileSuffix) {
|
||||
doTestFor(fileSuffix, createWrapper());
|
||||
}
|
||||
|
||||
@@ -212,10 +212,12 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
|
||||
doTestFor(fileSuffix, createWrapper(testDataPath));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected QuickFixTestCase createWrapper() {
|
||||
return createWrapper(null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected QuickFixTestCase createWrapper(final String testDataPath) {
|
||||
return new QuickFixTestCase() {
|
||||
public String myTestDataPath = testDataPath;
|
||||
@@ -225,6 +227,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
|
||||
return LightQuickFixTestCase.this.getBasePath();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getTestDataPath() {
|
||||
if (myTestDataPath == null) {
|
||||
@@ -240,27 +243,27 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeActionStarted(String testName, String contents) {
|
||||
public void beforeActionStarted(@NotNull String testName, @NotNull String contents) {
|
||||
LightQuickFixTestCase.this.beforeActionStarted(testName, contents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterActionCompleted(String testName, String contents) {
|
||||
public void afterActionCompleted(@NotNull String testName, @NotNull String contents) {
|
||||
LightQuickFixTestCase.this.afterActionCompleted(testName, contents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAction(ActionHint actionHint, String testFullPath, String testName) throws Exception {
|
||||
public void doAction(@NotNull ActionHint actionHint, @NotNull String testFullPath, @NotNull String testName) throws Exception {
|
||||
LightQuickFixTestCase.this.doAction(actionHint, testFullPath, testName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkResultByFile(String s, @NotNull String expectedFilePath, boolean b) throws Exception {
|
||||
LightQuickFixTestCase.this.checkResultByFile(s, expectedFilePath, b);
|
||||
public void checkResultByFile(@NotNull String message, @NotNull String expectedFilePath, boolean ignoreTrailingSpaces) throws Exception {
|
||||
LightQuickFixTestCase.this.checkResultByFile(message, expectedFilePath, ignoreTrailingSpaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntentionAction findActionWithText(String text) {
|
||||
public IntentionAction findActionWithText(@NotNull String text) {
|
||||
return LightQuickFixTestCase.this.findActionWithText(text);
|
||||
}
|
||||
|
||||
@@ -270,7 +273,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(IntentionAction action) {
|
||||
public void invoke(@NotNull IntentionAction action) {
|
||||
LightQuickFixTestCase.invoke(action);
|
||||
}
|
||||
|
||||
@@ -287,7 +290,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureFromFileText(String name, String contents) throws IOException {
|
||||
public void configureFromFileText(@NotNull String name, @NotNull String contents) throws IOException {
|
||||
LightPlatformCodeInsightTestCase.configureFromFileText(name, contents, true);
|
||||
}
|
||||
|
||||
@@ -313,6 +316,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
|
||||
return getAvailableActions(getEditor(), getFile());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<IntentionAction> getAvailableActions(@NotNull Editor editor, @NotNull PsiFile file) {
|
||||
return CodeInsightTestFixtureImpl.getAvailableIntentions(editor, file);
|
||||
}
|
||||
|
||||
+8
-7
@@ -31,24 +31,25 @@ import java.util.List;
|
||||
public interface QuickFixTestCase {
|
||||
String getBasePath();
|
||||
|
||||
@NotNull
|
||||
String getTestDataPath();
|
||||
|
||||
@NotNull
|
||||
ActionHint parseActionHintImpl(@NotNull PsiFile file, @NotNull String contents);
|
||||
|
||||
void beforeActionStarted(String testName, String contents);
|
||||
void beforeActionStarted(@NotNull String testName, @NotNull String contents);
|
||||
|
||||
void afterActionCompleted(String testName, String contents);
|
||||
void afterActionCompleted(@NotNull String testName, @NotNull String contents);
|
||||
|
||||
void doAction(ActionHint actionHint, String testFullPath, String testName) throws Exception;
|
||||
void doAction(@NotNull ActionHint actionHint, @NotNull String testFullPath, @NotNull String testName) throws Exception;
|
||||
|
||||
void checkResultByFile(String s, @NotNull String expectedFilePath, boolean b) throws Exception;
|
||||
void checkResultByFile(@NotNull String message, @NotNull String expectedFilePath, boolean ignoreTrailingSpaces) throws Exception;
|
||||
|
||||
IntentionAction findActionWithText(String text);
|
||||
IntentionAction findActionWithText(@NotNull String text);
|
||||
|
||||
boolean shouldBeAvailableAfterExecution();
|
||||
|
||||
void invoke(IntentionAction action);
|
||||
void invoke(@NotNull IntentionAction action);
|
||||
|
||||
@NotNull
|
||||
List<HighlightInfo> doHighlighting();
|
||||
@@ -58,7 +59,7 @@ public interface QuickFixTestCase {
|
||||
|
||||
void bringRealEditorBack();
|
||||
|
||||
void configureFromFileText(String name, String contents) throws Throwable;
|
||||
void configureFromFileText(@NotNull String name, @NotNull String contents) throws Throwable;
|
||||
|
||||
PsiFile getFile();
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.intellij.profile;
|
||||
|
||||
import com.intellij.openapi.options.Scheme;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -25,8 +24,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
* Date: 20-Nov-2005
|
||||
*/
|
||||
public interface Profile extends Comparable, Scheme {
|
||||
void copyFrom(@NotNull Profile profile);
|
||||
|
||||
@Transient
|
||||
boolean isProjectLevel();
|
||||
|
||||
@@ -42,8 +39,4 @@ public interface Profile extends Comparable, Scheme {
|
||||
|
||||
@NotNull
|
||||
ProfileManager getProfileManager();
|
||||
|
||||
void readExternal(Element element);
|
||||
|
||||
void writeExternal(Element element);
|
||||
}
|
||||
|
||||
+3
-6
@@ -26,13 +26,13 @@ import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.profile.codeInspection.InspectionProfileManager;
|
||||
import com.intellij.profile.codeInspection.SeverityProvider;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -50,7 +50,6 @@ public class InspectionProfileConvertor {
|
||||
|
||||
@NonNls private static final String NAME_ATT = "name";
|
||||
@NonNls private static final String VERSION_ATT = "version";
|
||||
@NonNls private static final String PROFILE_NAME_ATT = "profile_name";
|
||||
@NonNls private static final String OPTION_TAG = "option";
|
||||
@NonNls private static final String DISPLAY_LEVEL_MAP_OPTION = "DISPLAY_LEVEL_MAP";
|
||||
@NonNls protected static final String VALUE_ATT = "value";
|
||||
@@ -110,11 +109,9 @@ public class InspectionProfileConvertor {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Document doc = JDOMUtil.loadDocument(files[0]);
|
||||
Element root = doc.getRootElement();
|
||||
Element root = JDOMUtil.load(files[0]);
|
||||
if (root.getAttributeValue(VERSION_ATT) == null){
|
||||
root.setAttribute(PROFILE_NAME_ATT, OLD_DEFAUL_PROFILE);
|
||||
JDOMUtil.writeDocument(doc, new File(profileDirectory, OLD_DEFAUL_PROFILE + XML_EXTENSION), "\n");
|
||||
JDOMUtil.writeParent(root, new FileOutputStream(new File(profileDirectory, OLD_DEFAUL_PROFILE + XML_EXTENSION)), "\n");
|
||||
FileUtil.delete(files[0]);
|
||||
}
|
||||
}
|
||||
|
||||
+23
-38
@@ -33,10 +33,7 @@ import com.intellij.openapi.util.*;
|
||||
import com.intellij.profile.ProfileEx;
|
||||
import com.intellij.profile.ProfileManager;
|
||||
import com.intellij.profile.codeInspection.InspectionProfileManager;
|
||||
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager;
|
||||
import com.intellij.profile.codeInspection.ProjectInspectionProfileManagerKt;
|
||||
import com.intellij.profile.codeInspection.SeverityProvider;
|
||||
import com.intellij.project.ProjectKt;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.search.scope.packageSet.NamedScope;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -104,7 +101,7 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
|
||||
public InspectionProfileImpl(@NotNull String profileName,
|
||||
@NotNull InspectionToolRegistrar registrar,
|
||||
@NotNull ProfileManager profileManager) {
|
||||
this(profileName, registrar, profileManager, getDefaultProfile(), null);
|
||||
this(profileName, registrar, profileManager, getBaseProfile(), null);
|
||||
}
|
||||
|
||||
public InspectionProfileImpl(@NotNull @NonNls String profileName) {
|
||||
@@ -128,7 +125,7 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
|
||||
@NotNull InspectionToolRegistrar registrar,
|
||||
@NotNull ProfileManager profileManager,
|
||||
@Nullable SchemeDataHolder<? super InspectionProfileImpl> dataHolder) {
|
||||
this(profileName, registrar, profileManager, getDefaultProfile(), dataHolder);
|
||||
this(profileName, registrar, profileManager, getBaseProfile(), dataHolder);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -166,7 +163,7 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static InspectionProfileImpl getDefaultProfile() {
|
||||
public static InspectionProfileImpl getBaseProfile() {
|
||||
return InspectionProfileImplHolder.DEFAULT_PROFILE;
|
||||
}
|
||||
|
||||
@@ -281,26 +278,15 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
|
||||
|
||||
@NotNull
|
||||
public Element writeScheme() {
|
||||
if (myDataHolder != null) {
|
||||
return myDataHolder.read();
|
||||
}
|
||||
|
||||
Element element = new Element("profile");
|
||||
Element result = isProjectLevel() ? element.setAttribute("version", "1.0") : element.setAttribute("profile_name", getName());
|
||||
serializeInto(result, false);
|
||||
|
||||
if (isProjectLevel() && ProjectKt.isDirectoryBased(((ProjectInspectionProfileManager)myProfileManager).getProject())) {
|
||||
return new Element("component").setAttribute("name", "InspectionProjectProfileManager").addContent(result);
|
||||
}
|
||||
return result;
|
||||
return myDataHolder == null ? super.writeScheme() : myDataHolder.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeInto(@NotNull Element element, boolean preserveCompatibility) {
|
||||
public void writeExternal(@NotNull Element element) {
|
||||
// must be first - compatibility
|
||||
element.setAttribute(VERSION_TAG, VALID_VERSION);
|
||||
|
||||
super.serializeInto(element, preserveCompatibility);
|
||||
super.writeExternal(element);
|
||||
|
||||
synchronized (myLock) {
|
||||
if (!myInitialized) {
|
||||
@@ -857,24 +843,23 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
|
||||
initInspectionTools(project);
|
||||
|
||||
for (Element scopeElement : scopes.getChildren(SCOPE)) {
|
||||
final String profile = scopeElement.getAttributeValue(ProjectInspectionProfileManagerKt.PROFILE);
|
||||
if (profile != null) {
|
||||
final InspectionProfileImpl inspectionProfile = (InspectionProfileImpl)getProfileManager().getProfile(profile);
|
||||
if (inspectionProfile != null) {
|
||||
final NamedScope scope = getProfileManager().getScopesManager().getScope(scopeElement.getAttributeValue(NAME));
|
||||
if (scope != null) {
|
||||
for (InspectionToolWrapper toolWrapper : inspectionProfile.getInspectionTools(null)) {
|
||||
final HighlightDisplayKey key = HighlightDisplayKey.find(toolWrapper.getShortName());
|
||||
try {
|
||||
InspectionToolWrapper toolWrapperCopy = copyToolSettings(toolWrapper);
|
||||
HighlightDisplayLevel errorLevel = inspectionProfile.getErrorLevel(key, null, project);
|
||||
getTools(toolWrapper.getShortName(), project).addTool(scope, toolWrapperCopy, inspectionProfile.isToolEnabled(key), errorLevel);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
final String profile = scopeElement.getAttributeValue(PROFILE);
|
||||
InspectionProfileImpl inspectionProfile = profile == null ? null : (InspectionProfileImpl)getProfileManager().getProfile(profile);
|
||||
NamedScope scope = inspectionProfile == null ? null : getProfileManager().getScopesManager().getScope(scopeElement.getAttributeValue(NAME));
|
||||
if (scope == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (InspectionToolWrapper toolWrapper : inspectionProfile.getInspectionTools(null)) {
|
||||
final HighlightDisplayKey key = HighlightDisplayKey.find(toolWrapper.getShortName());
|
||||
try {
|
||||
InspectionToolWrapper toolWrapperCopy = copyToolSettings(toolWrapper);
|
||||
HighlightDisplayLevel errorLevel = inspectionProfile.getErrorLevel(key, null, project);
|
||||
getTools(toolWrapper.getShortName(), project)
|
||||
.addTool(scope, toolWrapperCopy, inspectionProfile.isToolEnabled(key), errorLevel);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
package com.intellij.profile;
|
||||
|
||||
import com.intellij.profile.codeInspection.ProjectInspectionProfileManagerKt;
|
||||
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager;
|
||||
import com.intellij.project.ProjectKt;
|
||||
import com.intellij.util.xmlb.SmartSerializer;
|
||||
import com.intellij.util.xmlb.annotations.OptionTag;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
@@ -29,6 +30,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public abstract class ProfileEx implements Profile {
|
||||
public static final String SCOPE = "scope";
|
||||
public static final String NAME = "name";
|
||||
public static final String PROFILE = "profile";
|
||||
|
||||
private final SmartSerializer mySerializer;
|
||||
|
||||
@@ -84,18 +86,12 @@ public abstract class ProfileEx implements Profile {
|
||||
myProfileManager = profileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(Element element) {
|
||||
mySerializer.readExternal(this, element);
|
||||
}
|
||||
|
||||
public void serializeInto(@NotNull Element element, boolean preserveCompatibility) {
|
||||
mySerializer.writeExternal(this, element, preserveCompatibility);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeExternal(Element element) {
|
||||
serializeInto(element, true);
|
||||
public void writeExternal(@NotNull Element element) {
|
||||
mySerializer.writeExternal(this, element, false);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
@@ -114,15 +110,21 @@ public abstract class ProfileEx implements Profile {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void copyFrom(@NotNull Profile profile) {
|
||||
readExternal(serializeProfile(profile));
|
||||
public final void copyFrom(@NotNull ProfileEx profile) {
|
||||
readExternal(profile.writeScheme());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Element serializeProfile(@NotNull Profile profile) {
|
||||
Element result = new Element(ProjectInspectionProfileManagerKt.PROFILE);
|
||||
profile.writeExternal(result);
|
||||
return result;
|
||||
public Element writeScheme() {
|
||||
Element element = new Element(PROFILE);
|
||||
if (isProjectLevel()) {
|
||||
element.setAttribute("version", "1.0");
|
||||
}
|
||||
writeExternal(element);
|
||||
|
||||
if (isProjectLevel() && ProjectKt.isDirectoryBased(((ProjectInspectionProfileManager)myProfileManager).getProject())) {
|
||||
return new Element("component").setAttribute("name", "InspectionProjectProfileManager").addContent(element);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-5
@@ -33,6 +33,7 @@ import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.packageDependencies.DependencyValidationManager
|
||||
import com.intellij.profile.Profile
|
||||
import com.intellij.profile.ProfileEx
|
||||
import com.intellij.project.isDirectoryBased
|
||||
import com.intellij.psi.search.scope.packageSet.NamedScopeManager
|
||||
import com.intellij.psi.search.scope.packageSet.NamedScopesHolder
|
||||
@@ -50,8 +51,6 @@ import org.jetbrains.concurrency.runAsync
|
||||
import java.util.*
|
||||
import java.util.function.Function
|
||||
|
||||
const val PROFILE = "profile"
|
||||
|
||||
private const val VERSION = "1.0"
|
||||
private const val SCOPE = "scope"
|
||||
private const val NAME = "name"
|
||||
@@ -99,7 +98,7 @@ class ProjectInspectionProfileManager(val project: Project,
|
||||
attributeProvider: Function<String, String?>,
|
||||
isBundled: Boolean): InspectionProfileImpl {
|
||||
val profile = InspectionProfileImpl(name, InspectionToolRegistrar.getInstance(), this@ProjectInspectionProfileManager,
|
||||
InspectionProfileImpl.getDefaultProfile(), dataHolder)
|
||||
InspectionProfileImpl.getBaseProfile(), dataHolder)
|
||||
profile.isProjectLevel = true
|
||||
return profile
|
||||
}
|
||||
@@ -307,8 +306,8 @@ class ProjectInspectionProfileManager(val project: Project,
|
||||
currentScheme = schemeManager.allSchemes.firstOrNull()
|
||||
if (currentScheme == null) {
|
||||
currentScheme = InspectionProfileImpl(PROJECT_DEFAULT_PROFILE_NAME, InspectionToolRegistrar.getInstance(), this,
|
||||
InspectionProfileImpl.getDefaultProfile(), null)
|
||||
currentScheme.copyFrom(applicationProfileManager.currentProfile)
|
||||
InspectionProfileImpl.getBaseProfile(), null)
|
||||
currentScheme.copyFrom(applicationProfileManager.currentProfile as ProfileEx)
|
||||
currentScheme.isProjectLevel = true
|
||||
currentScheme.name = PROJECT_DEFAULT_PROFILE_NAME
|
||||
schemeManager.addScheme(currentScheme)
|
||||
|
||||
@@ -233,11 +233,11 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
val bytes = URLUtil.openStream(url).readBytes()
|
||||
lazyPreloadScheme(bytes, isUseOldFileNameSanitize) { name, parser ->
|
||||
val attributeProvider = Function<String, String?> { parser.getAttributeValue(null, it) }
|
||||
val schemeName = name ?: (processor as LazySchemeProcessor).getName(attributeProvider)
|
||||
|
||||
val fileName = PathUtilRt.getFileName(url.path)
|
||||
val extension = getFileExtension(fileName, true)
|
||||
val externalInfo = ExternalInfo(fileName.substring(0, fileName.length - extension.length), extension)
|
||||
|
||||
val schemeName = name ?: (processor as LazySchemeProcessor).getName(attributeProvider, externalInfo.fileNameWithoutExtension)
|
||||
externalInfo.schemeName = schemeName
|
||||
|
||||
val scheme = (processor as LazySchemeProcessor).createScheme(SchemeDataHolderImpl(bytes, externalInfo), schemeName, attributeProvider, true)
|
||||
@@ -316,7 +316,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
processPendingCurrentSchemeName(scheme)
|
||||
}
|
||||
|
||||
messageBus?.let { it.connect().subscribe(VirtualFileManager.VFS_CHANGES, SchemeFileTracker()) }
|
||||
messageBus?.connect()?.subscribe(VirtualFileManager.VFS_CHANGES, SchemeFileTracker())
|
||||
|
||||
return schemes.subList(newSchemesOffset, schemes.size)
|
||||
}
|
||||
@@ -438,7 +438,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
val bytes = input.readBytes()
|
||||
lazyPreloadScheme(bytes, isUseOldFileNameSanitize) { name, parser ->
|
||||
val attributeProvider = Function<String, String?> { parser.getAttributeValue(null, it) }
|
||||
val schemeName = name ?: processor.getName(attributeProvider)
|
||||
val schemeName = name ?: processor.getName(attributeProvider, fileNameWithoutExtension)
|
||||
if (!checkExisting(schemeName)) {
|
||||
return null
|
||||
}
|
||||
@@ -573,7 +573,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
var externalInfo: ExternalInfo? = schemeToInfo.get(scheme)
|
||||
val currentFileNameWithoutExtension = externalInfo?.fileNameWithoutExtension
|
||||
val parent = processor.writeScheme(scheme)
|
||||
val element = if (parent is Element) parent else (parent as Document).detachRootElement()
|
||||
val element = parent as? Element ?: (parent as Document).detachRootElement()
|
||||
if (element.isEmpty()) {
|
||||
externalInfo?.scheduleDelete()
|
||||
return
|
||||
@@ -685,7 +685,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
|
||||
val bundledScheme = readOnlyExternalizableSchemes.get(scheme.name)
|
||||
if (bundledScheme == null) {
|
||||
if ((processor as? LazySchemeProcessor)?.let { it.isSchemeEqualToBundled(scheme) } ?: false) {
|
||||
if ((processor as? LazySchemeProcessor)?.isSchemeEqualToBundled(scheme) ?: false) {
|
||||
externalInfo?.scheduleDelete()
|
||||
return true
|
||||
}
|
||||
@@ -875,9 +875,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
|
||||
private fun collectExistingNames(schemes: Collection<T>): Collection<String> {
|
||||
val result = THashSet<String>(schemes.size)
|
||||
for (scheme in schemes) {
|
||||
result.add(scheme.name)
|
||||
}
|
||||
schemes.mapTo(result) { it.name }
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
package com.intellij.openapi.util;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import com.intellij.util.containers.ConcurrentIntObjectMap;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -28,24 +29,24 @@ public interface Iconable {
|
||||
@Deprecated int ICON_FLAG_OPEN = 0x0004;
|
||||
@Deprecated int ICON_FLAG_CLOSED = 0x0008;
|
||||
|
||||
@MagicConstant(flags = {ICON_FLAG_VISIBILITY, ICON_FLAG_OPEN, ICON_FLAG_CLOSED, ICON_FLAG_READ_STATUS})
|
||||
@MagicConstant(flags = {ICON_FLAG_VISIBILITY, ICON_FLAG_READ_STATUS})
|
||||
@interface IconFlags {}
|
||||
|
||||
Icon getIcon(@IconFlags int flags);
|
||||
|
||||
class LastComputedIcon {
|
||||
private static final Key<TIntObjectHashMap<Icon>> LAST_COMPUTED_ICON = Key.create("lastComputedIcon");
|
||||
private static final Key<ConcurrentIntObjectMap<Icon>> LAST_COMPUTED_ICON = Key.create("lastComputedIcon");
|
||||
|
||||
@Nullable
|
||||
public static Icon get(@NotNull UserDataHolder holder, int flags) {
|
||||
TIntObjectHashMap<Icon> map = holder.getUserData(LAST_COMPUTED_ICON);
|
||||
ConcurrentIntObjectMap<Icon> map = holder.getUserData(LAST_COMPUTED_ICON);
|
||||
return map == null ? null : map.get(flags);
|
||||
}
|
||||
|
||||
public static void put(@NotNull UserDataHolder holder, Icon icon, int flags) {
|
||||
TIntObjectHashMap<Icon> map = holder.getUserData(LAST_COMPUTED_ICON);
|
||||
ConcurrentIntObjectMap<Icon> map = holder.getUserData(LAST_COMPUTED_ICON);
|
||||
if (map == null) {
|
||||
map = ((UserDataHolderEx)holder).putUserDataIfAbsent(LAST_COMPUTED_ICON, new TIntObjectHashMap<Icon>());
|
||||
map = ((UserDataHolderEx)holder).putUserDataIfAbsent(LAST_COMPUTED_ICON, ContainerUtil.<Icon>createConcurrentIntObjectMap());
|
||||
}
|
||||
map.put(flags, icon);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.openapi.util;
|
||||
|
||||
import com.intellij.Patches;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||
@@ -26,15 +25,11 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||
*/
|
||||
@Transient
|
||||
public class SimpleModificationTracker implements ModificationTracker {
|
||||
static {
|
||||
//noinspection ConstantConditions
|
||||
assert Patches.JDK_BUG_ID_7103570;
|
||||
}
|
||||
|
||||
private static final AtomicIntegerFieldUpdater<SimpleModificationTracker> UPDATER =
|
||||
AtomicIntegerFieldUpdater.newUpdater(SimpleModificationTracker.class, "myCounter");
|
||||
|
||||
public volatile int myCounter; // is public to work around JDK-7103570
|
||||
@SuppressWarnings("unused")
|
||||
private volatile int myCounter;
|
||||
|
||||
@Override
|
||||
public long getModificationCount() {
|
||||
@@ -42,6 +37,10 @@ public class SimpleModificationTracker implements ModificationTracker {
|
||||
}
|
||||
|
||||
public void incModificationCount() {
|
||||
UPDATER.incrementAndGet(this);
|
||||
incAndGetModificationCount();
|
||||
}
|
||||
|
||||
public long incAndGetModificationCount() {
|
||||
return UPDATER.incrementAndGet(this);
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,6 @@ public abstract class DeprecatedVirtualFileSystem extends VirtualFileSystem {
|
||||
myEventDispatcher.removeListener(listener);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void firePropertyChanged(Object requestor,
|
||||
@NotNull VirtualFile file,
|
||||
@NotNull String propertyName,
|
||||
@@ -60,42 +59,36 @@ public abstract class DeprecatedVirtualFileSystem extends VirtualFileSystem {
|
||||
myEventDispatcher.getMulticaster().propertyChanged(event);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void fireContentsChanged(Object requestor, @NotNull VirtualFile file, long oldModificationStamp) {
|
||||
assertWriteAccessAllowed();
|
||||
VirtualFileEvent event = new VirtualFileEvent(requestor, file, file.getParent(), oldModificationStamp, file.getModificationStamp());
|
||||
myEventDispatcher.getMulticaster().contentsChanged(event);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void fireFileCreated(@Nullable Object requestor, @NotNull VirtualFile file) {
|
||||
assertWriteAccessAllowed();
|
||||
VirtualFileEvent event = new VirtualFileEvent(requestor, file, file.getName(), file.getParent());
|
||||
myEventDispatcher.getMulticaster().fileCreated(event);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void fireFileDeleted(Object requestor, @NotNull VirtualFile file, @NotNull String fileName, VirtualFile parent) {
|
||||
assertWriteAccessAllowed();
|
||||
VirtualFileEvent event = new VirtualFileEvent(requestor, file, fileName, parent);
|
||||
myEventDispatcher.getMulticaster().fileDeleted(event);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void fireFileMoved(Object requestor, @NotNull VirtualFile file, VirtualFile oldParent) {
|
||||
assertWriteAccessAllowed();
|
||||
VirtualFileMoveEvent event = new VirtualFileMoveEvent(requestor, file, oldParent, file.getParent());
|
||||
myEventDispatcher.getMulticaster().fileMoved(event);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void fireFileCopied(@Nullable Object requestor, @NotNull VirtualFile originalFile, @NotNull VirtualFile createdFile) {
|
||||
assertWriteAccessAllowed();
|
||||
VirtualFileCopyEvent event = new VirtualFileCopyEvent(requestor, originalFile, createdFile);
|
||||
myEventDispatcher.getMulticaster().fileCopied(event);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void fireBeforePropertyChange(Object requestor,
|
||||
@NotNull VirtualFile file,
|
||||
@NotNull String propertyName,
|
||||
@@ -106,21 +99,18 @@ public abstract class DeprecatedVirtualFileSystem extends VirtualFileSystem {
|
||||
myEventDispatcher.getMulticaster().beforePropertyChange(event);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void fireBeforeContentsChange(Object requestor, @NotNull VirtualFile file) {
|
||||
assertWriteAccessAllowed();
|
||||
VirtualFileEvent event = new VirtualFileEvent(requestor, file, file.getName(), file.getParent());
|
||||
myEventDispatcher.getMulticaster().beforeContentsChange(event);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void fireBeforeFileDeletion(Object requestor, @NotNull VirtualFile file) {
|
||||
assertWriteAccessAllowed();
|
||||
VirtualFileEvent event = new VirtualFileEvent(requestor, file, file.getName(), file.getParent());
|
||||
myEventDispatcher.getMulticaster().beforeFileDeletion(event);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void fireBeforeFileMovement(Object requestor, @NotNull VirtualFile file, VirtualFile newParent) {
|
||||
assertWriteAccessAllowed();
|
||||
VirtualFileMoveEvent event = new VirtualFileMoveEvent(requestor, file, file.getParent(), newParent);
|
||||
@@ -166,7 +156,7 @@ public abstract class DeprecatedVirtualFileSystem extends VirtualFileSystem {
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile copyFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent, @NotNull String copyName) throws IOException {
|
||||
throw unsupported("copyFile() not supported", vFile);
|
||||
throw unsupported("copyFile", vFile);
|
||||
}
|
||||
|
||||
private UnsupportedOperationException unsupported(String op, VirtualFile vFile) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -105,6 +105,9 @@ public interface CommonClassNames {
|
||||
|
||||
@NonNls String JAVA_UTIL_STREAM_BASE_STREAM = "java.util.stream.BaseStream";
|
||||
@NonNls String JAVA_UTIL_STREAM_STREAM = "java.util.stream.Stream";
|
||||
@NonNls String JAVA_UTIL_STREAM_INT_STREAM = "java.util.stream.IntStream";
|
||||
@NonNls String JAVA_UTIL_STREAM_LONG_STREAM = "java.util.stream.LongStream";
|
||||
@NonNls String JAVA_UTIL_STREAM_DOUBLE_STREAM = "java.util.stream.DoubleStream";
|
||||
@NonNls String JAVA_UTIL_STREAM_COLLECTORS = "java.util.stream.Collectors";
|
||||
@NonNls String JAVA_UTIL_FUNCTION_PREDICATE = "java.util.function.Predicate";
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.openapi.editor.impl;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.ex.MarkupIterator;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -42,6 +44,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
* User: cdr
|
||||
*/
|
||||
abstract class IntervalTreeImpl<T extends MutableInterval> extends RedBlackTree<T> implements IntervalTree<T> {
|
||||
static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.RangeMarkerTree");
|
||||
static final boolean DEBUG = LOG.isDebugEnabled() || ApplicationManager.getApplication() != null && (ApplicationManager.getApplication().isUnitTestMode() || ApplicationManager.getApplication().isInternal());
|
||||
private int keySize; // number of all intervals, counting all duplicates, some of them maybe gced
|
||||
final ReadWriteLock l = new ReentrantReadWriteLock();
|
||||
|
||||
@@ -66,7 +70,7 @@ abstract class IntervalTreeImpl<T extends MutableInterval> extends RedBlackTree<
|
||||
@NotNull
|
||||
private final IntervalTreeImpl<E> myIntervalTree;
|
||||
|
||||
public IntervalNode(@NotNull IntervalTreeImpl<E> intervalTree, @NotNull E key, int start, int end) {
|
||||
IntervalNode(@NotNull IntervalTreeImpl<E> intervalTree, @NotNull E key, int start, int end) {
|
||||
// maxEnd == 0 so to not disrupt existing maxes
|
||||
myIntervalTree = intervalTree;
|
||||
myStart = start;
|
||||
@@ -374,7 +378,9 @@ abstract class IntervalTreeImpl<T extends MutableInterval> extends RedBlackTree<
|
||||
}
|
||||
|
||||
private void assertUnderWriteLock() {
|
||||
assert isAcquired(l.writeLock()) : l.writeLock();
|
||||
if (DEBUG) {
|
||||
assert isAcquired(l.writeLock()) : l.writeLock();
|
||||
}
|
||||
}
|
||||
private static boolean isAcquired(@NotNull Lock l) {
|
||||
String s = l.toString();
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.intellij.openapi.editor.impl;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.ex.PrioritizedDocumentListener;
|
||||
@@ -38,9 +37,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
* User: cdr
|
||||
*/
|
||||
public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.RangeMarkerTree");
|
||||
private static final boolean DEBUG = LOG.isDebugEnabled() || ApplicationManager.getApplication() != null && (ApplicationManager.getApplication().isUnitTestMode() || ApplicationManager.getApplication().isInternal());
|
||||
|
||||
private final PrioritizedDocumentListener myListener;
|
||||
private final Document myDocument;
|
||||
|
||||
@@ -159,12 +155,12 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
|
||||
private static final byte EXPAND_TO_LEFT_FLAG = VALID_FLAG<<1;
|
||||
private static final byte EXPAND_TO_RIGHT_FLAG = EXPAND_TO_LEFT_FLAG<<1;
|
||||
|
||||
public RMNode(@NotNull RangeMarkerTree<T> rangeMarkerTree,
|
||||
@NotNull T key,
|
||||
int start,
|
||||
int end,
|
||||
boolean greedyToLeft,
|
||||
boolean greedyToRight) {
|
||||
RMNode(@NotNull RangeMarkerTree<T> rangeMarkerTree,
|
||||
@NotNull T key,
|
||||
int start,
|
||||
int end,
|
||||
boolean greedyToLeft,
|
||||
boolean greedyToRight) {
|
||||
super(rangeMarkerTree, key, start, end);
|
||||
setFlag(EXPAND_TO_LEFT_FLAG, greedyToLeft);
|
||||
setFlag(EXPAND_TO_RIGHT_FLAG, greedyToRight);
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.diff.util.MergeRange;
|
||||
import com.intellij.diff.util.Range;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -160,6 +161,11 @@ public class ComparisonMergeUtil {
|
||||
public static CharSequence tryResolveConflict(@NotNull CharSequence leftText,
|
||||
@NotNull CharSequence baseText,
|
||||
@NotNull CharSequence rightText) {
|
||||
return MergeResolveUtil.tryResolveConflict(leftText, baseText, rightText);
|
||||
if (Registry.is("diff.merge.resolve.conflict.action.use.greedy.approach")) {
|
||||
return MergeResolveUtil.tryGreedyResolve(leftText, baseText, rightText);
|
||||
}
|
||||
else {
|
||||
return MergeResolveUtil.tryResolve(leftText, baseText, rightText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,13 +16,29 @@
|
||||
package com.intellij.diff.comparison
|
||||
|
||||
import com.intellij.diff.fragments.DiffFragment
|
||||
import com.intellij.diff.util.DiffUtil
|
||||
import com.intellij.diff.util.Side
|
||||
import com.intellij.diff.util.Side.LEFT
|
||||
import com.intellij.diff.util.Side.RIGHT
|
||||
import com.intellij.diff.util.TextDiffType
|
||||
import com.intellij.diff.util.ThreeSide
|
||||
import com.intellij.openapi.progress.DumbProgressIndicator
|
||||
import com.intellij.util.text.MergingCharSequence
|
||||
|
||||
object MergeResolveUtil {
|
||||
@JvmStatic
|
||||
fun tryResolve(leftText: CharSequence, baseText: CharSequence, rightText: CharSequence): CharSequence? {
|
||||
try {
|
||||
val resolved = tryResolve(leftText, baseText, rightText, ComparisonPolicy.DEFAULT)
|
||||
if (resolved != null) return resolved
|
||||
|
||||
return tryResolve(leftText, baseText, rightText, ComparisonPolicy.IGNORE_WHITESPACES)
|
||||
}
|
||||
catch (e: DiffTooBigException) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we assume, that resolve results are explicitly verified by user and can be safely undone.
|
||||
* Thus we trade higher chances of incorrect resolve for higher chances of correct resolve.
|
||||
@@ -36,12 +52,12 @@ object MergeResolveUtil {
|
||||
* modifications can be considered as "insertion + deletion" and resolved accordingly.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun tryResolveConflict(leftText: CharSequence, baseText: CharSequence, rightText: CharSequence): CharSequence? {
|
||||
fun tryGreedyResolve(leftText: CharSequence, baseText: CharSequence, rightText: CharSequence): CharSequence? {
|
||||
try {
|
||||
val resolved = Helper(leftText, baseText, rightText).execute(ComparisonPolicy.DEFAULT)
|
||||
val resolved = tryGreedyResolve(leftText, baseText, rightText, ComparisonPolicy.DEFAULT)
|
||||
if (resolved != null) return resolved
|
||||
|
||||
return Helper(leftText, baseText, rightText).execute(ComparisonPolicy.IGNORE_WHITESPACES)
|
||||
return tryGreedyResolve(leftText, baseText, rightText, ComparisonPolicy.IGNORE_WHITESPACES)
|
||||
}
|
||||
catch (e: DiffTooBigException) {
|
||||
return null
|
||||
@@ -49,6 +65,46 @@ object MergeResolveUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private fun tryResolve(leftText: CharSequence, baseText: CharSequence, rightText: CharSequence,
|
||||
policy: ComparisonPolicy): CharSequence? {
|
||||
val texts = listOf(leftText, baseText, rightText)
|
||||
|
||||
val changes = ByWord.compare(leftText, baseText, rightText, policy, DumbProgressIndicator.INSTANCE)
|
||||
|
||||
val newContent = StringBuilder()
|
||||
|
||||
var last = 0
|
||||
for (fragment in changes) {
|
||||
val type = DiffUtil.getWordMergeType(fragment, texts, policy)
|
||||
if (type.diffType == TextDiffType.CONFLICT) return null;
|
||||
|
||||
val baseStart = fragment.getStartOffset(ThreeSide.BASE)
|
||||
val baseEnd = fragment.getEndOffset(ThreeSide.BASE)
|
||||
|
||||
newContent.append(baseText, last, baseStart)
|
||||
|
||||
if (type.isChange(Side.LEFT)) {
|
||||
val leftStart = fragment.getStartOffset(ThreeSide.LEFT)
|
||||
val leftEnd = fragment.getEndOffset(ThreeSide.LEFT)
|
||||
newContent.append(leftText, leftStart, leftEnd)
|
||||
}
|
||||
else {
|
||||
val rightStart = fragment.getStartOffset(ThreeSide.RIGHT)
|
||||
val rightEnd = fragment.getEndOffset(ThreeSide.RIGHT)
|
||||
newContent.append(rightText, rightStart, rightEnd)
|
||||
}
|
||||
last = baseEnd
|
||||
}
|
||||
|
||||
newContent.append(baseText, last, baseText.length)
|
||||
return newContent.toString()
|
||||
}
|
||||
|
||||
private fun tryGreedyResolve(leftText: CharSequence, baseText: CharSequence, rightText: CharSequence,
|
||||
policy: ComparisonPolicy): CharSequence? {
|
||||
return Helper(leftText, baseText, rightText).execute(policy)
|
||||
}
|
||||
|
||||
private class Helper(val leftText: CharSequence, val baseText: CharSequence, val rightText: CharSequence) {
|
||||
val newContent = StringBuilder()
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.diff.SuppressiveDiffTool;
|
||||
import com.intellij.diff.comparison.ByWord;
|
||||
import com.intellij.diff.comparison.ComparisonManager;
|
||||
import com.intellij.diff.comparison.ComparisonPolicy;
|
||||
import com.intellij.diff.comparison.ComparisonUtil;
|
||||
import com.intellij.diff.contents.DiffContent;
|
||||
import com.intellij.diff.contents.DocumentContent;
|
||||
import com.intellij.diff.contents.EmptyContent;
|
||||
@@ -30,6 +31,7 @@ import com.intellij.diff.contents.FileContent;
|
||||
import com.intellij.diff.fragments.DiffFragment;
|
||||
import com.intellij.diff.fragments.LineFragment;
|
||||
import com.intellij.diff.fragments.MergeLineFragment;
|
||||
import com.intellij.diff.fragments.MergeWordFragment;
|
||||
import com.intellij.diff.impl.DiffSettingsHolder;
|
||||
import com.intellij.diff.impl.DiffSettingsHolder.DiffSettings;
|
||||
import com.intellij.diff.requests.ContentDiffRequest;
|
||||
@@ -1069,6 +1071,36 @@ public class DiffUtil {
|
||||
return fragment.getStartLine(side) == fragment.getEndLine(side);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static MergeConflictType getWordMergeType(@NotNull MergeWordFragment fragment,
|
||||
@NotNull List<? extends CharSequence> texts,
|
||||
@NotNull ComparisonPolicy policy) {
|
||||
return getMergeType((side) -> isWordMergeIntervalEmpty(fragment, side),
|
||||
(side1, side2) -> compareWordMergeContents(fragment, texts, policy, side1, side2));
|
||||
}
|
||||
|
||||
private static boolean compareWordMergeContents(@NotNull MergeWordFragment fragment,
|
||||
@NotNull List<? extends CharSequence> texts,
|
||||
@NotNull ComparisonPolicy policy,
|
||||
@NotNull ThreeSide side1,
|
||||
@NotNull ThreeSide side2) {
|
||||
int start1 = fragment.getStartOffset(side1);
|
||||
int end1 = fragment.getEndOffset(side1);
|
||||
int start2 = fragment.getStartOffset(side2);
|
||||
int end2 = fragment.getEndOffset(side2);
|
||||
|
||||
CharSequence document1 = side1.select(texts);
|
||||
CharSequence document2 = side2.select(texts);
|
||||
|
||||
CharSequence content1 = document1.subSequence(start1, end1);
|
||||
CharSequence content2 = document2.subSequence(start2, end2);
|
||||
return ComparisonUtil.isEquals(content1, content2, policy);
|
||||
}
|
||||
|
||||
private static boolean isWordMergeIntervalEmpty(@NotNull MergeWordFragment fragment, @NotNull ThreeSide side) {
|
||||
return fragment.getStartOffset(side) == fragment.getEndOffset(side);
|
||||
}
|
||||
|
||||
//
|
||||
// Writable
|
||||
//
|
||||
|
||||
@@ -118,35 +118,35 @@ class MergeResolveUtilTest : DiffTestCase() {
|
||||
}
|
||||
|
||||
fun testNonFailureConflicts() {
|
||||
test(
|
||||
testGreedy(
|
||||
"x X x",
|
||||
"x x",
|
||||
"x X Y x",
|
||||
"x Y x"
|
||||
)
|
||||
|
||||
test(
|
||||
testGreedy(
|
||||
"x X x",
|
||||
"x x",
|
||||
"x Y X x",
|
||||
"x Y x"
|
||||
)
|
||||
|
||||
test(
|
||||
testGreedy(
|
||||
"x X Y x",
|
||||
"x X x",
|
||||
"x Y x",
|
||||
"x x"
|
||||
)
|
||||
|
||||
test(
|
||||
testGreedy(
|
||||
"x X Y Z x",
|
||||
"x X x",
|
||||
"x Z x",
|
||||
"x x"
|
||||
)
|
||||
|
||||
test(
|
||||
testGreedy(
|
||||
"x A B C D E F G H K x",
|
||||
"x C F K x",
|
||||
"x A D H x",
|
||||
@@ -157,21 +157,21 @@ class MergeResolveUtilTest : DiffTestCase() {
|
||||
fun testConfusingConflicts() {
|
||||
// these cases might be a failure as well
|
||||
|
||||
test(
|
||||
testGreedy(
|
||||
"x X x",
|
||||
"x x",
|
||||
"x Z x",
|
||||
"xZ x"
|
||||
)
|
||||
|
||||
test(
|
||||
testGreedy(
|
||||
"x X X x",
|
||||
"x X Y X x",
|
||||
"x x",
|
||||
"x Y x"
|
||||
)
|
||||
|
||||
test(
|
||||
testGreedy(
|
||||
"x X x",
|
||||
"x x",
|
||||
"x Y x",
|
||||
@@ -179,7 +179,7 @@ class MergeResolveUtilTest : DiffTestCase() {
|
||||
)
|
||||
|
||||
|
||||
test(
|
||||
testGreedy(
|
||||
"x X X x",
|
||||
"x Y x",
|
||||
"x X Y x",
|
||||
@@ -187,8 +187,25 @@ class MergeResolveUtilTest : DiffTestCase() {
|
||||
)
|
||||
}
|
||||
|
||||
private fun test(base: String, left: String, right: String, expected: String?) {
|
||||
val actual = MergeResolveUtil.tryResolveConflict(left, base, right)
|
||||
assertEquals(expected, actual?.toString())
|
||||
private fun testGreedy(base: String, left: String, right: String, expected: String?) {
|
||||
test(base, left, right, expected, true);
|
||||
}
|
||||
|
||||
private fun test(base: String, left: String, right: String, expected: String?, isGreedy: Boolean = false) {
|
||||
val simpleResult = MergeResolveUtil.tryResolve(left, base, right)
|
||||
val magicResult = MergeResolveUtil.tryGreedyResolve(left, base, right);
|
||||
|
||||
if (expected == null) {
|
||||
assertNull(simpleResult)
|
||||
assertNull(magicResult)
|
||||
}
|
||||
else if (isGreedy) {
|
||||
assertNull(simpleResult)
|
||||
assertEquals(expected, magicResult)
|
||||
}
|
||||
else {
|
||||
assertEquals(expected, simpleResult)
|
||||
assertEquals(expected, magicResult)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,8 +173,7 @@ public class UISettings extends SimpleModificationTracker implements PersistentS
|
||||
ColorBlindnessSupport support = ColorBlindnessSupport.get(COLOR_BLINDNESS);
|
||||
IconLoader.setFilter(support == null ? null : support.getFilter());
|
||||
|
||||
incModificationCount();
|
||||
if (myCounter == 1) {
|
||||
if (incAndGetModificationCount() == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable
|
||||
import com.intellij.openapi.editor.impl.InlayModelImpl
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
@@ -116,7 +117,7 @@ class ToggleInlineHintsAction : AnAction() {
|
||||
|
||||
private fun hasParameterHintAtOffset(editor: Editor): Boolean {
|
||||
val offset = editor.caretModel.offset
|
||||
return editor.inlayModel
|
||||
return editor.inlayModel is InlayModelImpl && editor.inlayModel
|
||||
.getInlineElementsInRange(offset, offset)
|
||||
.find { ParameterHintsPresentationManager.getInstance().isParameterHint(it) } != null
|
||||
}
|
||||
|
||||
+9
-28
@@ -22,7 +22,6 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.codeInsight.daemon.impl.SeveritiesProvider;
|
||||
import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingSettingsPerFile;
|
||||
import com.intellij.codeInspection.InspectionProfile;
|
||||
import com.intellij.codeInspection.InspectionsBundle;
|
||||
import com.intellij.configurationStore.BundledSchemeEP;
|
||||
import com.intellij.configurationStore.SchemeDataHolder;
|
||||
@@ -61,8 +60,6 @@ import java.util.Collections;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static com.intellij.codeInspection.ex.InspectionProfileImpl.getDefaultProfile;
|
||||
|
||||
@State(
|
||||
name = "InspectionProfileManager",
|
||||
storages = {
|
||||
@@ -93,8 +90,8 @@ public class ApplicationInspectionProfileManager extends BaseInspectionProfileMa
|
||||
mySchemeManager = schemeManagerFactory.create(INSPECTION_DIR, new InspectionProfileProcessor() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName(@NotNull Function<String, String> attributeProvider) {
|
||||
return "unnamed";
|
||||
public String getName(@NotNull Function<String, String> attributeProvider, @NotNull String fileNameWithoutExtension) {
|
||||
return fileNameWithoutExtension;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -102,11 +99,7 @@ public class ApplicationInspectionProfileManager extends BaseInspectionProfileMa
|
||||
@NotNull String name,
|
||||
@NotNull Function<String, String> attributeProvider,
|
||||
boolean isBundled) {
|
||||
InspectionProfileImpl profile = new InspectionProfileImpl(name, myRegistrar, ApplicationInspectionProfileManager.this, dataHolder);
|
||||
if (isBundled) {
|
||||
profile.lockProfile(true);
|
||||
}
|
||||
return profile;
|
||||
return new InspectionProfileImpl(name, myRegistrar, ApplicationInspectionProfileManager.this, dataHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -169,21 +162,15 @@ public class ApplicationInspectionProfileManager extends BaseInspectionProfileMa
|
||||
}
|
||||
|
||||
public void initProfiles() {
|
||||
if (!myProfilesAreInitialized.compareAndSet(false, true)) {
|
||||
if (!myProfilesAreInitialized.compareAndSet(false, true) || !LOAD_PROFILES) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!LOAD_PROFILES) return;
|
||||
|
||||
loadBundledSchemes();
|
||||
mySchemeManager.loadSchemes();
|
||||
createDefaultProfile();
|
||||
}
|
||||
|
||||
private void createDefaultProfile() {
|
||||
final InspectionProfileImpl oldDefault = mySchemeManager.findSchemeByName(InspectionProfileImpl.DEFAULT_PROFILE_NAME);
|
||||
if (oldDefault == null || !oldDefault.isProfileLocked()) {
|
||||
getSchemeManager().addScheme(createSampleProfile(InspectionProfileImpl.DEFAULT_PROFILE_NAME, getDefaultProfile()));
|
||||
if (mySchemeManager.isEmpty()) {
|
||||
mySchemeManager.addScheme(createSampleProfile(InspectionProfileImpl.DEFAULT_PROFILE_NAME, InspectionProfileImpl.getBaseProfile()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,12 +233,6 @@ public class ApplicationInspectionProfileManager extends BaseInspectionProfileMa
|
||||
return new InspectionProfileConvertor(this);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Deprecated
|
||||
public InspectionProfileImpl createProfile() {
|
||||
return createSampleProfile(InspectionProfileImpl.DEFAULT_PROFILE_NAME, getDefaultProfile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRootProfile(@Nullable String profileName) {
|
||||
mySchemeManager.setCurrentSchemeName(profileName);
|
||||
@@ -270,12 +251,12 @@ public class ApplicationInspectionProfileManager extends BaseInspectionProfileMa
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public InspectionProfile getCurrentProfile() {
|
||||
public InspectionProfileImpl getCurrentProfile() {
|
||||
initProfiles();
|
||||
|
||||
Profile current = mySchemeManager.getCurrentScheme();
|
||||
InspectionProfileImpl current = mySchemeManager.getCurrentScheme();
|
||||
if (current != null) {
|
||||
return (InspectionProfile)current;
|
||||
return current;
|
||||
}
|
||||
|
||||
// use default as base, not random custom profile
|
||||
|
||||
+4
-1
@@ -289,7 +289,10 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb
|
||||
|
||||
public boolean isExcludedOrUnderExcludedDirectory(@NotNull VirtualFile file) {
|
||||
ModifiableRootModel model = getModel();
|
||||
Project project = model != null ? model.getProject() : null;
|
||||
if (model == null) {
|
||||
throw new AssertionError(getClass() + ".getModel() returned null unexpectedly");
|
||||
}
|
||||
Project project = model.getProject();
|
||||
ContentEntry contentEntry = getContentEntry();
|
||||
if (contentEntry == null) {
|
||||
return false;
|
||||
|
||||
+1
-3
@@ -74,7 +74,6 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.FocusManager;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.TreeExpansionEvent;
|
||||
import javax.swing.event.TreeExpansionListener;
|
||||
@@ -84,8 +83,6 @@ import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.awt.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.*;
|
||||
@@ -1095,6 +1092,7 @@ public class SingleInspectionProfilePanel extends JPanel {
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
if (myTreeTable == null) return false;
|
||||
if (myModified) return true;
|
||||
if (myProfile.isChanged()) return true;
|
||||
if (myProfile.getParentProfile().isProjectLevel() != myProfile.isProjectLevel()) return true;
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private InspectionProfileImpl copyToNewProfile(ModifiableModel selectedProfile,
|
||||
private InspectionProfileImpl copyToNewProfile(@NotNull InspectionProfileImpl selectedProfile,
|
||||
@NotNull Project project,
|
||||
boolean modifyName,
|
||||
boolean modifyLevel) {
|
||||
|
||||
+4
-1
@@ -93,7 +93,10 @@ public abstract class ChangeSignatureProcessorBase extends BaseRefactoringProces
|
||||
List<UsageInfo> infos = new ArrayList<>();
|
||||
final ChangeSignatureUsageProcessor[] processors = ChangeSignatureUsageProcessor.EP_NAME.getExtensions();
|
||||
for (ChangeSignatureUsageProcessor processor : processors) {
|
||||
ContainerUtil.addAll(infos, processor.findUsages(changeInfo));
|
||||
for (UsageInfo info : processor.findUsages(changeInfo)) {
|
||||
LOG.assertTrue(info != null, processor);
|
||||
infos.add(info);
|
||||
}
|
||||
}
|
||||
infos = filterUsages(infos);
|
||||
return infos.toArray(new UsageInfo[infos.size()]);
|
||||
|
||||
+2
-1
@@ -36,6 +36,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
@@ -101,7 +102,7 @@ public class VariableInplaceRenamer extends InplaceRefactoring {
|
||||
protected void collectAdditionalElementsToRename(final List<Pair<PsiElement, TextRange>> stringUsages) {
|
||||
final String stringToSearch = myElementToRename.getName();
|
||||
final PsiFile currentFile = PsiDocumentManager.getInstance(myProject).getPsiFile(myEditor.getDocument());
|
||||
if (stringToSearch != null) {
|
||||
if (!StringUtil.isEmptyOrSpaces(stringToSearch)) {
|
||||
TextOccurrencesUtil
|
||||
.processUsagesInStringsAndComments(myElementToRename, stringToSearch, true, (psiElement, textRange) -> {
|
||||
if (psiElement.getContainingFile() == currentFile) {
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
*/
|
||||
package com.intellij.util.indexing;
|
||||
|
||||
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.DataOutputStream;
|
||||
import com.intellij.util.io.KeyDescriptor;
|
||||
import com.intellij.util.io.PersistentHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -56,15 +54,10 @@ class ValueContainerMap<Key, Value> extends PersistentHashMap<Key, ValueContaine
|
||||
// note that keys unique for indexed file have their value calculated at once (e.g. key is file id, index calculates something for particular
|
||||
// file) and there is no benefit to accumulate values for particular key because only one value exists
|
||||
if (!valueContainer.needsCompacting() && !myKeyIsUniqueForIndexedFile) {
|
||||
final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream();
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
final DataOutputStream _out = new DataOutputStream(bytes);
|
||||
valueContainer.saveTo(_out, myValueExternalizer);
|
||||
|
||||
appendData(key, new PersistentHashMap.ValueDataAppender() {
|
||||
@Override
|
||||
public void append(@NotNull final DataOutput out) throws IOException {
|
||||
out.write(bytes.getInternalBuffer(), 0, bytes.size());
|
||||
valueContainer.saveTo(out, myValueExternalizer);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Clock;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -69,19 +68,12 @@ public class IdeaGateway {
|
||||
|
||||
LocalHistoryImpl.getInstanceImpl().dispatchPendingEvents();
|
||||
|
||||
VersionedFilterData versionedFilterData;
|
||||
VfsEventDispatchContext vfsEventDispatchContext = ourCurrentEventDispatchContext.get();
|
||||
if (vfsEventDispatchContext != null) {
|
||||
versionedFilterData = vfsEventDispatchContext.myFilterData;
|
||||
if (versionedFilterData == null) versionedFilterData = vfsEventDispatchContext.myFilterData = new VersionedFilterData();
|
||||
} else {
|
||||
versionedFilterData = new VersionedFilterData();
|
||||
}
|
||||
VersionedFilterData versionedFilterData = getVersionedFilterData();
|
||||
|
||||
boolean isInContent = false;
|
||||
int numberOfOpenProjects = versionedFilterData.myOpenedProjects.size();
|
||||
for (int i = 0; i < numberOfOpenProjects; ++i) {
|
||||
if (Comparing.equal(versionedFilterData.myWorkspaceFiles.get(i), f)) return false;
|
||||
if (f.equals(versionedFilterData.myWorkspaceFiles.get(i))) return false;
|
||||
ProjectFileIndex index = versionedFilterData.myProjectFileIndices.get(i);
|
||||
|
||||
if (index.isExcluded(f)) return false;
|
||||
@@ -93,33 +85,49 @@ public class IdeaGateway {
|
||||
return numberOfOpenProjects != 0 || !FileTypeManager.getInstance().isFileIgnored(f);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected static VersionedFilterData getVersionedFilterData() {
|
||||
VersionedFilterData versionedFilterData;
|
||||
VfsEventDispatchContext vfsEventDispatchContext = ourCurrentEventDispatchContext.get();
|
||||
if (vfsEventDispatchContext != null) {
|
||||
versionedFilterData = vfsEventDispatchContext.myFilterData;
|
||||
if (versionedFilterData == null) versionedFilterData = vfsEventDispatchContext.myFilterData = new VersionedFilterData();
|
||||
} else {
|
||||
versionedFilterData = new VersionedFilterData();
|
||||
}
|
||||
return versionedFilterData;
|
||||
}
|
||||
|
||||
private static final ThreadLocal<VfsEventDispatchContext> ourCurrentEventDispatchContext = new ThreadLocal<>();
|
||||
|
||||
private static class VfsEventDispatchContext {
|
||||
private static class VfsEventDispatchContext implements AutoCloseable {
|
||||
final List<? extends VFileEvent> myEvents;
|
||||
final boolean myBeforeEvents;
|
||||
final VfsEventDispatchContext myPreviousContext;
|
||||
|
||||
VersionedFilterData myFilterData;
|
||||
|
||||
VfsEventDispatchContext(List<? extends VFileEvent> events, boolean beforeEvents, VfsEventDispatchContext context) {
|
||||
VfsEventDispatchContext(List<? extends VFileEvent> events, boolean beforeEvents) {
|
||||
myEvents = events;
|
||||
myBeforeEvents = beforeEvents;
|
||||
myPreviousContext = context;
|
||||
myPreviousContext = ourCurrentEventDispatchContext.get();
|
||||
if (myPreviousContext != null) {
|
||||
myFilterData = myPreviousContext.myFilterData;
|
||||
}
|
||||
ourCurrentEventDispatchContext.set(this);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
ourCurrentEventDispatchContext.set(myPreviousContext);
|
||||
if (myPreviousContext != null && myPreviousContext.myFilterData == null && myFilterData != null) {
|
||||
myPreviousContext.myFilterData = myFilterData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void runWithVfsEventsDispatchContext(List<? extends VFileEvent> events, boolean beforeEvents, Runnable action) {
|
||||
VfsEventDispatchContext vfsEventDispatchContext = new VfsEventDispatchContext(events, beforeEvents, ourCurrentEventDispatchContext.get());
|
||||
ourCurrentEventDispatchContext.set(vfsEventDispatchContext);
|
||||
try {
|
||||
try (VfsEventDispatchContext ignored = new VfsEventDispatchContext(events, beforeEvents)) {
|
||||
action.run();
|
||||
} finally {
|
||||
vfsEventDispatchContext.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ fun CredentialAttributes(requestor: Class<*>, userName: String?) = CredentialAtt
|
||||
fun Credentials?.isFulfilled() = this != null && userName != null && !password.isNullOrEmpty()
|
||||
fun Credentials?.hasOnlyUserName() = this != null && userName != null && password.isNullOrEmpty()
|
||||
|
||||
fun Credentials?.isEmpty() = this == null || (userName == null && password == null)
|
||||
fun Credentials?.isEmpty() = this == null || (userName == null && password.isNullOrEmpty())
|
||||
|
||||
// input will be cleared
|
||||
@JvmOverloads
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -15,19 +15,17 @@
|
||||
*/
|
||||
package com.intellij.openapi;
|
||||
|
||||
import com.intellij.Patches;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.Component;
|
||||
import java.awt.*;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author Sergey.Malenkov
|
||||
@@ -136,7 +134,7 @@ abstract class MnemonicWrapper<T extends Component> implements Runnable, Propert
|
||||
sb.append(ch);
|
||||
}
|
||||
else if (i + 1 < length) {
|
||||
code = getExtendedKeyCodeForChar(text.charAt(i + 1));
|
||||
code = KeyEvent.getExtendedKeyCodeForChar((int)text.charAt(i + 1));
|
||||
index = sb.length();
|
||||
}
|
||||
}
|
||||
@@ -200,26 +198,6 @@ abstract class MnemonicWrapper<T extends Component> implements Runnable, Propert
|
||||
return stroke;
|
||||
}
|
||||
|
||||
// TODO: HACK because of Java7 required:
|
||||
// replace later with KeyEvent.getExtendedKeyCodeForChar(ch)
|
||||
private static int getExtendedKeyCodeForChar(int ch) {
|
||||
//noinspection ConstantConditions
|
||||
assert Patches.USE_REFLECTION_TO_ACCESS_JDK7;
|
||||
try {
|
||||
Method method = KeyEvent.class.getMethod("getExtendedKeyCodeForChar", int.class);
|
||||
if (!method.isAccessible()) {
|
||||
method.setAccessible(true);
|
||||
}
|
||||
return (Integer)method.invoke(KeyEvent.class, ch);
|
||||
}
|
||||
catch (Exception exception) {
|
||||
if (ch >= 'a' && ch <= 'z') {
|
||||
ch -= ('a' - 'A');
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MenuWrapper extends ButtonWrapper {
|
||||
private MenuWrapper(AbstractButton component) {
|
||||
super(component);
|
||||
|
||||
@@ -19,7 +19,6 @@ import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.CachedSingletonsRegistry;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.messages.Topic;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -36,7 +35,7 @@ import java.util.List;
|
||||
|
||||
public abstract class FileTypeManager extends FileTypeRegistry {
|
||||
static {
|
||||
FileTypeRegistry.ourInstanceGetter = () -> FileTypeManager.getInstance();
|
||||
FileTypeRegistry.ourInstanceGetter = () -> getInstance();
|
||||
}
|
||||
|
||||
private static FileTypeManager ourInstance = CachedSingletonsRegistry.markCachedField(FileTypeManager.class);
|
||||
@@ -59,7 +58,7 @@ public abstract class FileTypeManager extends FileTypeRegistry {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link com.intellij.openapi.fileTypes.FileTypeFactory} instead
|
||||
* @deprecated use {@link FileTypeFactory} instead
|
||||
*/
|
||||
public abstract void registerFileType(@NotNull FileType type, @NotNull List<FileNameMatcher> defaultAssociations);
|
||||
|
||||
@@ -69,7 +68,7 @@ public abstract class FileTypeManager extends FileTypeRegistry {
|
||||
* @param type The file type to register.
|
||||
* @param defaultAssociatedExtensions The list of extensions which cause the file to be
|
||||
* treated as the specified file type. The extensions should not start with '.'.
|
||||
* @deprecated use {@link com.intellij.openapi.fileTypes.FileTypeFactory} instead
|
||||
* @deprecated use {@link FileTypeFactory} instead
|
||||
*/
|
||||
public final void registerFileType(@NotNull FileType type, @NonNls @Nullable String... defaultAssociatedExtensions) {
|
||||
List<FileNameMatcher> matchers = new ArrayList<>();
|
||||
|
||||
@@ -34,6 +34,10 @@ public interface ContentManager extends Disposable, BusyObject {
|
||||
|
||||
void addContent(@NotNull Content content);
|
||||
void addContent(@NotNull Content content, final int order);
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #addContent(Content)} instead, {@code constraints} parameter isn't used anyway
|
||||
*/
|
||||
void addContent(@NotNull Content content, Object constraints);
|
||||
|
||||
boolean removeContent(@NotNull Content content, final boolean dispose);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -34,7 +34,7 @@ import java.awt.*;
|
||||
import java.awt.event.MouseListener;
|
||||
|
||||
public class HintUtil {
|
||||
public static final Color INFORMATION_COLOR = new JBColor(new Color(253, 254, 226), new Color(0x4d4f51));
|
||||
public static final Color INFORMATION_COLOR = new JBColor(new Color(0xf8f8f8), new Color(0x4d4f51));
|
||||
public static final Color QUESTION_COLOR = new JBColor(new Color(181, 208, 251), new Color(55, 108, 137));
|
||||
public static final Color ERROR_COLOR = new JBColor(new Color(255, 220, 220), new Color(0x781732));
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ fun showJetBrainsAccountDialog(parent: Component, project: Project? = null): Dia
|
||||
link("Forgot password?") { BrowserUtil.browse("https://account.jetbrains.com/forgot-password?username=${userField.text.trim().encodeUrlQueryParameter()}") }
|
||||
}
|
||||
}
|
||||
noteRow("""Do not have an account? <a href="https://account.jetbrains.com/login">Sign Up</a>""")
|
||||
noteRow("""Do not have an account? <a href="https://account.jetbrains.com/login?signup">Sign Up</a>""")
|
||||
}
|
||||
|
||||
return dialog(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.ide.dnd;
|
||||
|
||||
import com.intellij.Patches;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
@@ -31,20 +30,8 @@ import java.util.List;
|
||||
*/
|
||||
abstract public class TransferableList<T> implements Transferable {
|
||||
private static final DataFlavor LIST_DATA_FLAVOR = new DataFlavor(List.class, "Transferable List");
|
||||
private static final DataFlavor ALL_HTML_DATA_FLAVOR = initHtmlDataFlavor("all"); // JDK7: DataFlavor.allHtmlFlavor
|
||||
private static final DataFlavor PART_HTML_DATA_FLAVOR = initHtmlDataFlavor("fragment"); // JDK7: DataFlavor.fragmentHtmlFlavor
|
||||
|
||||
private static DataFlavor initHtmlDataFlavor(String type) {
|
||||
// some constants were added in JDK 7 without @since 1.7 tag
|
||||
// http://bugs.openjdk.java.net/browse/JDK-7075105
|
||||
assert Patches.USE_REFLECTION_TO_ACCESS_JDK7;
|
||||
try {
|
||||
return new DataFlavor("text/html; class=java.lang.String;document=" + type + ";charset=Unicode");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private static final DataFlavor ALL_HTML_DATA_FLAVOR = DataFlavor.allHtmlFlavor;
|
||||
private static final DataFlavor PART_HTML_DATA_FLAVOR = DataFlavor.fragmentHtmlFlavor;
|
||||
|
||||
private final List<T> myList;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -33,6 +33,7 @@ import com.intellij.ui.plaf.beg.IdeaMenuUI;
|
||||
import com.intellij.ui.plaf.gtk.GtkMenuUI;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.SingleAlarm;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -40,6 +41,7 @@ import javax.swing.*;
|
||||
import javax.swing.event.MenuEvent;
|
||||
import javax.swing.event.MenuListener;
|
||||
import javax.swing.plaf.MenuItemUI;
|
||||
import javax.swing.plaf.synth.SynthMenuUI;
|
||||
import java.awt.*;
|
||||
import java.awt.event.AWTEventListener;
|
||||
import java.awt.event.ComponentEvent;
|
||||
@@ -164,12 +166,12 @@ public final class ActionMenu extends JBMenu {
|
||||
|
||||
if (myTopLevel && UIUtil.isUnderGTKLookAndFeel()) {
|
||||
Insets insets = getInsets();
|
||||
Insets newInsets = new Insets(insets.top, insets.left, insets.bottom, insets.right);
|
||||
if (insets.top + insets.bottom < 6) {
|
||||
newInsets.top = newInsets.bottom = 3;
|
||||
@SuppressWarnings("UseDPIAwareInsets") Insets newInsets = new Insets(insets.top, insets.left, insets.bottom, insets.right);
|
||||
if (insets.top + insets.bottom < JBUI.scale(6)) {
|
||||
newInsets.top = newInsets.bottom = JBUI.scale(3);
|
||||
}
|
||||
if (insets.left + insets.right < 12) {
|
||||
newInsets.left = newInsets.right = 6;
|
||||
if (insets.left + insets.right < JBUI.scale(12)) {
|
||||
newInsets.left = newInsets.right = JBUI.scale(6);
|
||||
}
|
||||
if (!newInsets.equals(insets)) {
|
||||
setBorder(BorderFactory.createEmptyBorder(newInsets.top, newInsets.left, newInsets.bottom, newInsets.right));
|
||||
@@ -178,8 +180,8 @@ public final class ActionMenu extends JBMenu {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUI(final MenuItemUI ui) {
|
||||
final MenuItemUI newUi = !myTopLevel && UIUtil.isUnderGTKLookAndFeel() && GtkMenuUI.isUiAcceptable(ui) ? new GtkMenuUI(ui) : ui;
|
||||
public void setUI(MenuItemUI ui) {
|
||||
MenuItemUI newUi = !myTopLevel && UIUtil.isUnderGTKLookAndFeel() && ui instanceof SynthMenuUI ? new GtkMenuUI((SynthMenuUI)ui) : ui;
|
||||
super.setUI(newUi);
|
||||
}
|
||||
|
||||
@@ -222,7 +224,8 @@ public final class ActionMenu extends JBMenu {
|
||||
}
|
||||
|
||||
private void updateIcon() {
|
||||
if (UISettings.getInstance().SHOW_ICONS_IN_MENUS) {
|
||||
UISettings settings = UISettings.getInstance();
|
||||
if (settings != null && settings.SHOW_ICONS_IN_MENUS) {
|
||||
final Presentation presentation = myPresentation;
|
||||
final Icon icon = presentation.getIcon();
|
||||
setIcon(icon);
|
||||
@@ -242,9 +245,7 @@ public final class ActionMenu extends JBMenu {
|
||||
}
|
||||
|
||||
public static void showDescriptionInStatusBar(boolean isIncluded, Component component, String description) {
|
||||
IdeFrame frame = component instanceof IdeFrame
|
||||
? (IdeFrame)component
|
||||
: (IdeFrame)SwingUtilities.getAncestorOfClass(IdeFrame.class, component);
|
||||
IdeFrame frame = (IdeFrame)(component instanceof IdeFrame ? component : SwingUtilities.getAncestorOfClass(IdeFrame.class, component));
|
||||
StatusBar statusBar;
|
||||
if (frame != null && (statusBar = frame.getStatusBar()) != null) {
|
||||
statusBar.setInfo(isIncluded ? description : null);
|
||||
@@ -448,4 +449,4 @@ public final class ActionMenu extends JBMenu {
|
||||
Toolkit.getDefaultToolkit().removeAWTEventListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -41,6 +41,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.MenuItemUI;
|
||||
import javax.swing.plaf.synth.SynthMenuItemUI;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
@@ -187,8 +188,8 @@ public class ActionMenuItem extends JBCheckBoxMenuItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUI(final MenuItemUI ui) {
|
||||
final MenuItemUI newUi = UIUtil.isUnderGTKLookAndFeel() && GtkMenuItemUI.isUiAcceptable(ui) ? new GtkMenuItemUI(ui) : ui;
|
||||
public void setUI(MenuItemUI ui) {
|
||||
MenuItemUI newUi = UIUtil.isUnderGTKLookAndFeel() && ui instanceof SynthMenuItemUI ? new GtkMenuItemUI((SynthMenuItemUI)ui) : ui;
|
||||
super.setUI(newUi);
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -30,6 +30,7 @@ import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.ui.EditorNotifications;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -172,6 +173,7 @@ public class AsyncEditorLoader {
|
||||
if (FileEditorManager.getInstance(myProject).getSelectedTextEditor() == myEditor) {
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(myTextEditor.getPreferredFocusedComponent(), true);
|
||||
}
|
||||
EditorNotifications.getInstance(myProject).updateNotifications(myTextEditor.myFile);
|
||||
}
|
||||
|
||||
public static void performWhenLoaded(@NotNull Editor editor, @NotNull Runnable runnable) {
|
||||
|
||||
@@ -37,11 +37,12 @@ public final class StripeButtonUI extends MetalToggleButtonUI{
|
||||
private static final Rectangle ourIconRect=new Rectangle();
|
||||
private static final Rectangle ourTextRect=new Rectangle();
|
||||
private static final Rectangle ourViewRect=new Rectangle();
|
||||
private static Insets ourViewInsets=new Insets(0,0,0,0);
|
||||
private static Insets ourViewInsets = JBUI.emptyInsets();
|
||||
|
||||
private StripeButtonUI(){}
|
||||
|
||||
/** Invoked by reflection */
|
||||
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "unused"})
|
||||
public static ComponentUI createUI(final JComponent c){
|
||||
return ourInstance;
|
||||
}
|
||||
@@ -55,6 +56,7 @@ public final class StripeButtonUI extends MetalToggleButtonUI{
|
||||
|
||||
final ToolWindowAnchor anchor=button.getAnchor();
|
||||
if(ToolWindowAnchor.LEFT==anchor||ToolWindowAnchor.RIGHT==anchor){
|
||||
//noinspection SuspiciousNameCombination
|
||||
return new Dimension(dim.height,dim.width);
|
||||
} else{
|
||||
return dim;
|
||||
@@ -127,12 +129,14 @@ public final class StripeButtonUI extends MetalToggleButtonUI{
|
||||
tr=g2.getTransform();
|
||||
if(ToolWindowAnchor.RIGHT==anchor){
|
||||
if(icon != null){ // do not rotate icon
|
||||
//noinspection SuspiciousNameCombination
|
||||
icon.paintIcon(c, g2, ourIconRect.y, ourIconRect.x);
|
||||
}
|
||||
g2.rotate(Math.PI/2);
|
||||
g2.translate(0,-c.getWidth());
|
||||
} else {
|
||||
if(icon != null){ // do not rotate icon
|
||||
//noinspection SuspiciousNameCombination
|
||||
icon.paintIcon(c, g2, ourIconRect.y, c.getHeight() - ourIconRect.x - icon.getIconHeight());
|
||||
}
|
||||
g2.rotate(-Math.PI/2);
|
||||
|
||||
@@ -451,13 +451,12 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
toolWindow.setSplitMode(true, null);
|
||||
}
|
||||
|
||||
final ActionCallback activation = toolWindow.setActivation(new ActionCallback());
|
||||
|
||||
// ToolWindow activation is not needed anymore and should be removed in 2017
|
||||
toolWindow.setActivation(new ActionCallback()).setDone();
|
||||
final DumbAwareRunnable runnable = () -> {
|
||||
if (toolWindow.isDisposed()) return;
|
||||
|
||||
toolWindow.ensureContentInitialized();
|
||||
activation.setDone();
|
||||
};
|
||||
if (visible || ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
runnable.run();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.Patches;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
@@ -26,7 +25,6 @@ import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
@@ -116,7 +114,7 @@ public class KeyStrokeAdapter implements KeyListener {
|
||||
if (Registry.is("actionSystem.extendedKeyCode.disabled")) {
|
||||
return null;
|
||||
}
|
||||
code = getExtendedKeyCode(event);
|
||||
code = event.getExtendedKeyCode();
|
||||
if (code == event.getKeyCode()) {
|
||||
return null;
|
||||
}
|
||||
@@ -146,23 +144,6 @@ public class KeyStrokeAdapter implements KeyListener {
|
||||
return KeyEvent.VK_UNDEFINED == code ? null : KeyStroke.getKeyStroke(code, modifiers, released);
|
||||
}
|
||||
|
||||
// TODO: HACK because of Java7 required:
|
||||
// replace later with event.getExtendedKeyCode()
|
||||
private static int getExtendedKeyCode(KeyEvent event) {
|
||||
//noinspection ConstantConditions
|
||||
assert Patches.USE_REFLECTION_TO_ACCESS_JDK7;
|
||||
try {
|
||||
Method method = KeyEvent.class.getMethod("getExtendedKeyCode");
|
||||
if (!method.isAccessible()) {
|
||||
method.setAccessible(true);
|
||||
}
|
||||
return (Integer)method.invoke(event);
|
||||
}
|
||||
catch (Exception exception) {
|
||||
return event.getKeyCode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string and returns the corresponding key stroke.
|
||||
* The string must have the following syntax:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -20,24 +20,20 @@ import com.intellij.util.ui.EmptyIcon;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.MenuItemUI;
|
||||
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||
import javax.swing.plaf.synth.ColorType;
|
||||
import javax.swing.plaf.synth.SynthContext;
|
||||
import javax.swing.plaf.synth.SynthMenuItemUI;
|
||||
import java.awt.*;
|
||||
|
||||
public class GtkMenuItemUI extends BasicMenuItemUI {
|
||||
private static Icon myCachedCheckIcon = null;
|
||||
|
||||
private final BasicMenuItemUI myOriginalUI;
|
||||
private final SynthMenuItemUI myOriginalUI;
|
||||
private JCheckBoxMenuItem myHiddenItem;
|
||||
|
||||
public GtkMenuItemUI(final MenuItemUI originalUI) {
|
||||
assert isUiAcceptable(originalUI) : originalUI;
|
||||
myOriginalUI = (BasicMenuItemUI)originalUI;
|
||||
}
|
||||
|
||||
public static boolean isUiAcceptable(final MenuItemUI ui) {
|
||||
return ui instanceof BasicMenuItemUI && GtkPaintingUtil.isSynthUI(ui);
|
||||
public GtkMenuItemUI(SynthMenuItemUI originalUI) {
|
||||
myOriginalUI = originalUI;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,9 +56,9 @@ public class GtkMenuItemUI extends BasicMenuItemUI {
|
||||
resetCachedCheckIcon();
|
||||
}
|
||||
|
||||
private static Icon getCheckIconFromContext(final BasicMenuItemUI originalUI, final JCheckBoxMenuItem item) {
|
||||
private static Icon getCheckIconFromContext(final SynthMenuItemUI ui, final JCheckBoxMenuItem item) {
|
||||
if (myCachedCheckIcon == null) {
|
||||
final SynthContext context = GtkPaintingUtil.getSynthContext(originalUI, item);
|
||||
SynthContext context = ui.getContext(item);
|
||||
myCachedCheckIcon = context.getStyle().getIcon(context, "CheckBoxMenuItem.checkIcon");
|
||||
}
|
||||
return myCachedCheckIcon;
|
||||
@@ -82,10 +78,12 @@ public class GtkMenuItemUI extends BasicMenuItemUI {
|
||||
|
||||
if (UIUtil.isMurrineBasedTheme()) {
|
||||
acceleratorFont = menuItem.getFont();
|
||||
final Color fg = GtkPaintingUtil.getForeground(myOriginalUI, menuItem);
|
||||
SynthContext context = myOriginalUI.getContext(menuItem);
|
||||
Color fg = context.getStyle().getColor(context, ColorType.TEXT_FOREGROUND);
|
||||
acceleratorForeground = UIUtil.mix(fg, menuItem.getBackground(), menuItem.isSelected() ? 0.4 : 0.2);
|
||||
disabledForeground = fg;
|
||||
}
|
||||
|
||||
if (checkIcon != null && !(checkIcon instanceof IconWrapper) && !(checkIcon instanceof EmptyIcon)) {
|
||||
checkIcon = new IconWrapper(checkIcon, myOriginalUI);
|
||||
}
|
||||
@@ -97,8 +95,9 @@ public class GtkMenuItemUI extends BasicMenuItemUI {
|
||||
protected void paintText(final Graphics g, final JMenuItem menuItem, final Rectangle textRect, final String text) {
|
||||
if (!menuItem.isEnabled() && UIUtil.isMurrineBasedTheme()) {
|
||||
GtkPaintingUtil.paintDisabledText(myOriginalUI, g, menuItem, textRect, text);
|
||||
return;
|
||||
}
|
||||
super.paintText(g, menuItem, textRect, text);
|
||||
else {
|
||||
super.paintText(g, menuItem, textRect, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -18,20 +18,15 @@ package com.intellij.ui.plaf.gtk;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.MenuItemUI;
|
||||
import javax.swing.plaf.basic.BasicMenuUI;
|
||||
import javax.swing.plaf.synth.SynthMenuUI;
|
||||
import java.awt.*;
|
||||
|
||||
public class GtkMenuUI extends BasicMenuUI {
|
||||
private final BasicMenuUI myOriginalUI;
|
||||
private final SynthMenuUI myOriginalUI;
|
||||
|
||||
public GtkMenuUI(final MenuItemUI originalUI) {
|
||||
assert isUiAcceptable(originalUI) : originalUI;
|
||||
myOriginalUI = (BasicMenuUI)originalUI;
|
||||
}
|
||||
|
||||
public static boolean isUiAcceptable(final MenuItemUI ui) {
|
||||
return ui instanceof BasicMenuUI && GtkPaintingUtil.isSynthUI(ui);
|
||||
public GtkMenuUI(SynthMenuUI originalUI) {
|
||||
myOriginalUI = originalUI;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,8 +50,9 @@ public class GtkMenuUI extends BasicMenuUI {
|
||||
protected void paintText(final Graphics g, final JMenuItem menuItem, final Rectangle textRect, final String text) {
|
||||
if (!menuItem.isEnabled() && UIUtil.isMurrineBasedTheme()) {
|
||||
GtkPaintingUtil.paintDisabledText(myOriginalUI, g, menuItem, textRect, text);
|
||||
return;
|
||||
}
|
||||
super.paintText(g, menuItem, textRect, text);
|
||||
else {
|
||||
super.paintText(g, menuItem, textRect, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -15,31 +15,20 @@
|
||||
*/
|
||||
package com.intellij.ui.plaf.gtk;
|
||||
|
||||
import com.intellij.Patches;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import sun.swing.SwingUtilities2;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.MenuItemUI;
|
||||
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||
import javax.swing.plaf.synth.ColorType;
|
||||
import javax.swing.plaf.synth.SynthContext;
|
||||
import javax.swing.plaf.synth.SynthUI;
|
||||
import java.awt.*;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
// todo[r.sh] get rid of SynthUI reflection after migration to JDK 7
|
||||
public class GtkPaintingUtil {
|
||||
private static final String V6_SYNTH_UI_CLASS = "sun.swing.plaf.synth.SynthUI";
|
||||
private static final String V7_SYNTH_UI_CLASS = "javax.swing.plaf.synth.SynthUI";
|
||||
|
||||
private GtkPaintingUtil() { }
|
||||
|
||||
public static Color getForeground(final BasicMenuItemUI ui, final JMenuItem menuItem) {
|
||||
final SynthContext context = getSynthContext(ui, menuItem);
|
||||
return context.getStyle().getColor(context, ColorType.TEXT_FOREGROUND);
|
||||
}
|
||||
|
||||
public static void paintDisabledText(final BasicMenuItemUI originalUI,
|
||||
public static void paintDisabledText(final SynthUI originalUI,
|
||||
final Graphics g,
|
||||
final JMenuItem menuItem,
|
||||
final Rectangle textRect,
|
||||
@@ -47,7 +36,8 @@ public class GtkPaintingUtil {
|
||||
final FontMetrics fm = SwingUtilities2.getFontMetrics(menuItem, g);
|
||||
final int index = menuItem.getDisplayedMnemonicIndex();
|
||||
|
||||
final Color fg = getForeground(originalUI, menuItem);
|
||||
final SynthContext context = originalUI.getContext(menuItem);
|
||||
final Color fg = context.getStyle().getColor(context, ColorType.TEXT_FOREGROUND);
|
||||
final Color shadow = UIUtil.shade(menuItem.getBackground(), 1.24, 0.5);
|
||||
|
||||
g.setColor(shadow);
|
||||
@@ -56,32 +46,7 @@ public class GtkPaintingUtil {
|
||||
SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, index, textRect.x, textRect.y + fm.getAscent());
|
||||
}
|
||||
|
||||
public static boolean isSynthUI(final MenuItemUI ui) {
|
||||
Class<?> aClass = ui.getClass();
|
||||
|
||||
while (aClass != null && aClass.getSimpleName().contains("Synth")) {
|
||||
final Class<?>[] interfaces = aClass.getInterfaces();
|
||||
for (int i = 0, length = interfaces.length; i < length; i++) {
|
||||
final Class<?> anInterface = interfaces[i];
|
||||
if (V6_SYNTH_UI_CLASS.equals(anInterface.getName()) || V7_SYNTH_UI_CLASS.equals(anInterface.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
aClass = aClass.getSuperclass();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static SynthContext getSynthContext(final MenuItemUI ui, final JComponent item) {
|
||||
assert Patches.USE_REFLECTION_TO_ACCESS_JDK7;
|
||||
try {
|
||||
final Method getContext = ui.getClass().getMethod("getContext", JComponent.class);
|
||||
getContext.setAccessible(true);
|
||||
return (SynthContext)getContext.invoke(ui, item);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return ((SynthUI)ui).getContext(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -18,16 +18,16 @@ package com.intellij.ui.plaf.gtk;
|
||||
import com.intellij.Patches;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.MenuItemUI;
|
||||
import javax.swing.plaf.synth.SynthContext;
|
||||
import javax.swing.plaf.synth.SynthUI;
|
||||
import java.awt.*;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class IconWrapper implements Icon {
|
||||
private final Icon myIcon;
|
||||
private final MenuItemUI myOriginalUI;
|
||||
private final SynthUI myOriginalUI;
|
||||
|
||||
public IconWrapper(final Icon icon, final MenuItemUI originalUI) {
|
||||
public IconWrapper(final Icon icon, final SynthUI originalUI) {
|
||||
myIcon = icon;
|
||||
myOriginalUI = originalUI;
|
||||
}
|
||||
@@ -36,10 +36,9 @@ public class IconWrapper implements Icon {
|
||||
public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
|
||||
if (Patches.USE_REFLECTION_TO_ACCESS_JDK7) {
|
||||
try {
|
||||
final Method paintIcon = myIcon.getClass().getMethod("paintIcon", SynthContext.class, Graphics.class,
|
||||
int.class, int.class, int.class, int.class);
|
||||
Method paintIcon = myIcon.getClass().getMethod("paintIcon", SynthContext.class, Graphics.class, int.class, int.class, int.class, int.class);
|
||||
paintIcon.setAccessible(true);
|
||||
paintIcon.invoke(myIcon, GtkPaintingUtil.getSynthContext(myOriginalUI, (JComponent)c), g, x, y, getIconWidth(), getIconHeight());
|
||||
paintIcon.invoke(myIcon, myOriginalUI.getContext((JComponent)c), g, x, y, getIconWidth(), getIconHeight());
|
||||
return;
|
||||
}
|
||||
catch (Exception ignore) { }
|
||||
@@ -56,4 +55,4 @@ public class IconWrapper implements Icon {
|
||||
public int getIconHeight() {
|
||||
return myIcon.getIconHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -22,8 +22,6 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
import static com.intellij.Patches.USE_REFLECTION_TO_ACCESS_JDK7;
|
||||
|
||||
/**
|
||||
* @author Sergey Malenkov
|
||||
*/
|
||||
@@ -166,7 +164,7 @@ public class MovablePopup {
|
||||
Window view = pop(owner);
|
||||
if (view == null) {
|
||||
view = new JWindow(owner);
|
||||
setPopupType(view);
|
||||
view.setType(Window.Type.POPUP);
|
||||
}
|
||||
setAlwaysOnTop(view, myAlwaysOnTop);
|
||||
setWindowFocusable(view, myWindowFocusable);
|
||||
@@ -265,21 +263,6 @@ public class MovablePopup {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: HACK because of Java7 required:
|
||||
// replace later with window.setType(Window.Type.POPUP)
|
||||
private static void setPopupType(@NotNull Window window) {
|
||||
//noinspection ConstantConditions,ConstantAssertCondition
|
||||
assert USE_REFLECTION_TO_ACCESS_JDK7;
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends Enum> type = (Class<? extends Enum>)Class.forName("java.awt.Window$Type");
|
||||
Object value = Enum.valueOf(type, "POPUP");
|
||||
Window.class.getMethod("setType", type).invoke(window, value);
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static JRootPane getRootPane(Window window) {
|
||||
if (window instanceof RootPaneContainer) {
|
||||
RootPaneContainer container = (RootPaneContainer)window;
|
||||
|
||||
@@ -174,6 +174,9 @@ intention.split.filter.text=Split into filter's chain
|
||||
intention.split.filter.family=Split filter
|
||||
intention.merge.filter.text=Merge filter's chain
|
||||
intention.merge.filter.family=Merge filters
|
||||
intention.inline.map.inline.text=Inline ''{0}'' body into the next ''{1}'' call
|
||||
intention.inline.map.merge.text=Merge ''{0}'' call and ''{1}'' call
|
||||
intention.inline.map.family=Inline stream mapping method
|
||||
intention.introduce.variable.text=Introduce local variable
|
||||
intention.encapsulate.field.text=Encapsulate field
|
||||
intention.implement.abstract.method.family=Implement Abstract Method
|
||||
|
||||
@@ -54,7 +54,7 @@ interface SchemeExtensionProvider {
|
||||
}
|
||||
|
||||
abstract class LazySchemeProcessor<SCHEME : Scheme, MUTABLE_SCHEME : SCHEME>(private val nameAttribute: String = "name") : SchemeProcessor<SCHEME, MUTABLE_SCHEME>() {
|
||||
open fun getName(attributeProvider: Function<String, String?>): String {
|
||||
open fun getName(attributeProvider: Function<String, String?>, fileNameWithoutExtension: String): String {
|
||||
return attributeProvider.apply(nameAttribute) ?: throw IllegalStateException("name is missed in the scheme data")
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -244,7 +244,12 @@ public abstract class GeneralTestEventsProcessor implements Disposable {
|
||||
}
|
||||
|
||||
public void stopEventProcessing() {
|
||||
UIUtil.invokeLaterIfNeeded(() -> myTransferToEDTQueue.drain());
|
||||
UIUtil.invokeLaterIfNeeded(() -> {
|
||||
if (myProject.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
myTransferToEDTQueue.drain();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -846,7 +846,7 @@ public class PlatformTestUtil {
|
||||
|
||||
public static void assertElementsEqual(final Element expected, final Element actual) throws IOException {
|
||||
if (!JDOMUtil.areElementsEqual(expected, actual)) {
|
||||
Assert.assertEquals(printElement(expected), printElement(actual));
|
||||
Assert.assertEquals(JDOMUtil.writeElement(expected), JDOMUtil.writeElement(actual));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -859,12 +859,6 @@ public class PlatformTestUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static String printElement(final Element element) throws IOException {
|
||||
final StringWriter writer = new StringWriter();
|
||||
JDOMUtil.writeElement(element, writer, "\n");
|
||||
return writer.getBuffer().toString();
|
||||
}
|
||||
|
||||
public static String getCommunityPath() {
|
||||
final String homePath = PathManager.getHomePath();
|
||||
if (new File(homePath, "community/.idea").isDirectory()) {
|
||||
@@ -877,7 +871,6 @@ public class PlatformTestUtil {
|
||||
return getCommunityPath().replace(File.separatorChar, '/') + "/platform/platform-tests/testData/";
|
||||
}
|
||||
|
||||
|
||||
public static Comparator<AbstractTreeNode> createComparator(final Queryable.PrintInfo printInfo) {
|
||||
return (o1, o2) -> {
|
||||
String displayText1 = o1.toTestString(printInfo);
|
||||
|
||||
@@ -40,7 +40,7 @@ fun configureInspections(tools: Array<InspectionProfileEntry>,
|
||||
Disposer.register(parentDisposable, Disposable {
|
||||
profileManager.deleteProfile(profile)
|
||||
profileManager.setCurrentProfile(null)
|
||||
clearAllToolsIn(InspectionProfileImpl.getDefaultProfile())
|
||||
clearAllToolsIn(InspectionProfileImpl.getBaseProfile())
|
||||
})
|
||||
|
||||
profileManager.addProfile(profile)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user