Use proper code style from the actual (context) file when optimizing imports

Fixes:
IDEA-223408 Java ij_java_imports_layout setting in .editorconfig not working properly
IDEA-223437 EditorConfig imports order has lower precedence than IntelliJ settings

GitOrigin-RevId: 1ad18522a107ea79d1485597f75dfc8cc744081b
This commit is contained in:
Rustam Vishnyakov
2019-10-01 14:03:21 +00:00
committed by intellij-monorepo-bot
parent 00e5fad140
commit 01d32acced
6 changed files with 118 additions and 3 deletions
@@ -1,6 +1,7 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.psi.impl.source.codeStyle;
import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.ImportFilter;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightVisitorImpl;
import com.intellij.lang.ASTNode;
@@ -129,8 +130,7 @@ public class ImportHelper{
String ext = StdFileTypes.JAVA.getDefaultExtension();
PsiFileFactory factory = PsiFileFactory.getInstance(file.getProject());
final PsiJavaFile dummyFile = (PsiJavaFile)factory.createFileFromText("_Dummy_." + ext, StdFileTypes.JAVA, text);
CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(file.getProject());
codeStyleManager.reformat(dummyFile);
CodeStyle.reformatWithFileContext(dummyFile, file);
PsiImportList newImportList = dummyFile.getImportList();
assert newImportList != null : dummyFile.getText();
@@ -0,0 +1,19 @@
package com.company;
import static org.junit.platform.commons.util.StringUtils.containsIsoControlCharacter;
import com.company.subpackage.AnotherClasss;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
public class Main {
public static void main(String[] args) {
AnotherClasss anotherClasss = new AnotherClasss();
List<String> strings = new ArrayList<>();
containsIsoControlCharacter(args[0]);
Class<?> displayName = DisplayName.class;
}
}
@@ -0,0 +1,19 @@
package com.company;
import static org.junit.platform.commons.util.StringUtils.containsIsoControlCharacter;
import com.company.subpackage.AnotherClasss;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
public class Main {
public static void main(String[] args) {
AnotherClasss anotherClasss = new AnotherClasss();
List<String> strings = new ArrayList<>();
containsIsoControlCharacter(args[0]);
Class<?> displayName = DisplayName.class;
}
}
@@ -16,9 +16,16 @@
package com.intellij.java.psi;
import com.intellij.application.options.CodeStyle;
import com.intellij.formatting.MockCodeStyleSettingsModifier;
import com.intellij.formatting.fileSet.NamedScopeDescriptor;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import com.intellij.psi.codeStyle.PackageEntry;
import com.intellij.psi.codeStyle.PackageEntryTable;
import com.intellij.psi.codeStyle.modifier.CodeStyleSettingsModifier;
import com.intellij.testFramework.ServiceContainerUtil;
public class OptimizeImportsTest extends OptimizeImportsTestCase {
private static final String BASE_PATH = PathManagerEx.getTestDataPath() + "/psi/optimizeImports";
@@ -72,6 +79,21 @@ public class OptimizeImportsTest extends OptimizeImportsTestCase {
CodeStyle.doWithTemporarySettings(getProject(), temp, () -> doTest());
}
public void testPerFileImportSettings() {
CodeStyle.dropTemporarySettings(getProject());
MockCodeStyleSettingsModifier modifier = new MockCodeStyleSettingsModifier(
getTestName(false) + ".java",
settings -> {
JavaCodeStyleSettings javaSettings = settings.getCustomSettings(JavaCodeStyleSettings.class);
javaSettings.IMPORT_LAYOUT_TABLE = new PackageEntryTable();
javaSettings.IMPORT_LAYOUT_TABLE.addEntry(PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY);
javaSettings.IMPORT_LAYOUT_TABLE.addEntry(PackageEntry.BLANK_LINE_ENTRY);
javaSettings.IMPORT_LAYOUT_TABLE.addEntry(PackageEntry.ALL_OTHER_IMPORTS_ENTRY);
});
ServiceContainerUtil.registerExtension(ApplicationManager.getApplication(), CodeStyleSettingsModifier.EP_NAME, modifier, getTestRootDisposable());
doTest();
}
private void doTest() {
doTest(".java");
}
@@ -321,7 +321,19 @@ public class CodeStyle {
return !getSettings(file).getExcludedFiles().contains(file);
}
/**
* Reformat the given {@code fileToReformat} using code style settings for the {@code contextFile}. The method may be
* useful to reformat a fragment of code (temporary file) which eventually will be inserted to the context file.
*
* @param fileToReformat The file to reformat (may be a temporary dummy file).
* @param contextFile The actual (target) file whose settings must be used.
*/
public static void reformatWithFileContext(@NotNull PsiFile fileToReformat, @NotNull PsiFile contextFile) {
final Project project = contextFile.getProject();
CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
CodeStyleSettings realFileSettings = getSettings(contextFile);
doWithTemporarySettings(project, realFileSettings, () -> codeStyleManager.reformat(fileToReformat));
}
}
@@ -0,0 +1,43 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.formatting;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.modifier.CodeStyleSettingsModifier;
import com.intellij.psi.codeStyle.modifier.CodeStyleStatusBarUIContributor;
import com.intellij.psi.codeStyle.modifier.TransientCodeStyleSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer;
public class MockCodeStyleSettingsModifier implements CodeStyleSettingsModifier {
private final String myFileName;
private final Consumer<CodeStyleSettings> mySettingsConsumer;
public MockCodeStyleSettingsModifier(@NotNull String fileName, @NotNull Consumer<CodeStyleSettings> consumer) {
myFileName = fileName;
mySettingsConsumer = consumer;
}
@Override
public boolean modifySettings(@NotNull TransientCodeStyleSettings settings,
@NotNull PsiFile file) {
if (myFileName.equals(file.getName())) {
mySettingsConsumer.accept(settings);
return true;
}
return false;
}
@Override
public String getName() {
return "Mock Code Style Modifier";
}
@Nullable
@Override
public CodeStyleStatusBarUIContributor getStatusBarUiContributor(@NotNull TransientCodeStyleSettings transientSettings) {
return null;
}
}