Allow dots in EditorConfig values for IntelliJ properties

enables imports layout and packages to use imports on demand

GitOrigin-RevId: bb6f1b88d15b57f6d542ad5692bccb9ced8b59a1
This commit is contained in:
Rustam Vishnyakov
2019-04-28 17:33:42 +03:00
committed by intellij-monorepo-bot
parent eddbe4dc7a
commit c0911cb9bb
12 changed files with 147 additions and 22 deletions
@@ -13,8 +13,8 @@ import static com.intellij.application.options.codeStyle.properties.CodeStylePro
public class JavaPackageEntryTableAccessor extends ValueListPropertyAccessor<PackageEntryTable> {
public static final String BLANK_LINE_ENTRY = "blank_line";
public static final String STATIC_PREFIX = "static";
public static final char BLANK_LINE_CHAR = '|';
public static final String STATIC_PREFIX = "$";
public JavaPackageEntryTableAccessor(@NotNull Object object, @NotNull Field field) {
super(object, field);
@@ -26,8 +26,12 @@ public class JavaPackageEntryTableAccessor extends ValueListPropertyAccessor<Pac
PackageEntryTable entryTable = new PackageEntryTable();
for (String strValue : strList) {
String parseStr = strValue.trim();
if (BLANK_LINE_ENTRY.equals(parseStr)) {
entryTable.addEntry(PackageEntry.BLANK_LINE_ENTRY);
if (parseStr.length() > 0 && parseStr.charAt(0) == BLANK_LINE_CHAR) {
for (int i = 0; i < parseStr.length(); i ++) {
if (parseStr.charAt(i) == BLANK_LINE_CHAR) {
entryTable.addEntry(PackageEntry.BLANK_LINE_ENTRY);
}
}
}
else {
boolean isStatic = false;
@@ -58,12 +62,12 @@ public class JavaPackageEntryTableAccessor extends ValueListPropertyAccessor<Pac
List<String> externalList = ContainerUtil.newArrayList();
for (PackageEntry entry : value.getEntries()) {
if (entry == PackageEntry.BLANK_LINE_ENTRY) {
externalList.add(BLANK_LINE_ENTRY);
externalList.add(String.valueOf(BLANK_LINE_CHAR));
}
else {
StringBuilder entryBuilder = new StringBuilder();
if (entry.isStatic()) {
entryBuilder.append(STATIC_PREFIX + " ");
entryBuilder.append("$");
}
if (entry.isSpecial()) {
entryBuilder.append("*");
@@ -94,11 +94,11 @@
"if_brace_force": "never",
"imports_layout": [
"*",
"blank_line",
"|",
"javax.**",
"java.**",
"blank_line",
"static *"
"|",
"$*"
],
"indent_case_from_switch": true,
"indent_size": 4,
@@ -110,7 +110,7 @@ public class JavaCodeStyleSettingsTest extends CodeStyleTestCase {
setSimple(mapper, "indent_size", "2");
setSimple(mapper, "doc_align_param_comments", "true");
setList(mapper, "imports_layout",
Arrays.asList("com.jetbrains.*", "blank_line", "org.eclipse.bar", "static **", "static org.eclipse.foo.**"));
Arrays.asList("com.jetbrains.*", "|", "org.eclipse.bar", "$**", "$org.eclipse.foo.**"));
mapper.getAccessor("repeat_annotations").setFromString(" com.jetbrains.First, com.jetbrains.Second");
final CommonCodeStyleSettings commonJavaSettings = settings.getCommonSettings(JavaLanguage.INSTANCE);
final JavaCodeStyleSettings javaSettings = settings.getCustomSettings(JavaCodeStyleSettings.class);
@@ -170,10 +170,7 @@ public class EditorConfigSettingsWriter extends OutputStreamWriter {
}
private static boolean isValueAllowed(@Nullable String value) {
if (value == null || value.trim().isEmpty()) return false;
// TODO<rv> REMOVE THE HACK
// EditorConfig implementation doesn't allow dots. We need to skip such values till the parser issue is fixed.
return !value.contains(".");
return value != null && !value.trim().isEmpty();
}
private void writeProperties(@NotNull List<OutPair> outPairs) throws IOException {
@@ -35,9 +35,6 @@ public class IntellijPropertyKindMap {
PROPERTY_KIND_MAP.put("wrap_on_typing", GENERIC);
PROPERTY_KIND_MAP.put("smart_tabs", GENERIC);
PROPERTY_KIND_MAP.put("continuation_indent_size", GENERIC);
PROPERTY_KIND_MAP.put("imports_layout", UNSUPPORTED);
PROPERTY_KIND_MAP.put("packages_to_use_import_on_demand", UNSUPPORTED);
}
@NotNull
@@ -0,0 +1,51 @@
// 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 org.editorconfig.configmanagement.lexer;
import com.intellij.lexer.Lexer;
import com.intellij.lexer.MergeFunction;
import com.intellij.lexer.MergingLexerAdapter;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.PlatformUtils;
import org.editorconfig.language.lexer.EditorConfigLexerAdapter;
import org.editorconfig.language.psi.EditorConfigElementTypes;
import org.jetbrains.annotations.NotNull;
public class EditorConfigLexerFactory {
@NotNull
public static Lexer getAdapter() {
return PlatformUtils.isRider()
? new EditorConfigLexerAdapter()
: new MyLexerAdapter(new IntellijEditorConfigLexerAdapter());
}
private static class MyLexerAdapter extends MergingLexerAdapter {
private final static TokenSet IDENTIFIER_TOKENS = TokenSet.create(
EditorConfigElementTypes.IDENTIFIER,
IntellijEditorConfigTokenTypes.VALUE_CHAR
);
private MyLexerAdapter(Lexer original) {
super(original, IDENTIFIER_TOKENS);
}
@Override
public MergeFunction getMergeFunction() {
return new MergeFunction() {
@Override
public IElementType merge(IElementType type, Lexer originalLexer) {
if (!IDENTIFIER_TOKENS.contains(type)) {
return type;
}
while (true) {
final IElementType tokenType = originalLexer.getTokenType();
if (!IDENTIFIER_TOKENS.contains(tokenType)) break;
originalLexer.advance();
}
return EditorConfigElementTypes.IDENTIFIER;
}
};
}
}
}
@@ -0,0 +1,65 @@
// 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 org.editorconfig.configmanagement.lexer;
import com.intellij.lexer.FlexAdapter;
import com.intellij.psi.tree.IElementType;
import org.editorconfig.language.lexer._EditorConfigLexer;
import org.editorconfig.language.psi.EditorConfigElementTypes;
public class IntellijEditorConfigLexerAdapter extends FlexAdapter {
private enum AdapterState {
Initial,
Header,
Key,
Value
}
private AdapterState myState = AdapterState.Initial;
public IntellijEditorConfigLexerAdapter() {
super(new _EditorConfigLexer());
}
@Override
public IElementType getTokenType() {
IElementType tokenType = super.getTokenType();
if ( tokenType == EditorConfigElementTypes.DOT && myState == AdapterState.Value) {
return IntellijEditorConfigTokenTypes.VALUE_CHAR;
}
return tokenType;
}
@Override
public void advance() {
super.advance();
if (getTokenText().contains("\n")) {
myState = AdapterState.Initial;
}
else {
if (getCurrentPosition().getState() > 0) {
myState = AdapterState.Header;
}
else {
final IElementType tokenType = getTokenType();
switch (myState) {
case Initial:
if (tokenType == EditorConfigElementTypes.IDENTIFIER) {
myState = AdapterState.Key;
}
break;
case Header:
myState = AdapterState.Initial;
break;
case Key:
if (tokenType == EditorConfigElementTypes.SEPARATOR) {
myState = AdapterState.Value;
}
break;
case Value:
break;
}
}
}
}
}
@@ -0,0 +1,9 @@
// 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 org.editorconfig.configmanagement.lexer;
import com.intellij.psi.tree.IElementType;
import org.editorconfig.language.psi.EditorConfigTokenType;
public class IntellijEditorConfigTokenTypes {
public final static IElementType VALUE_CHAR = new EditorConfigTokenType("VALUE_CHAR");
}
@@ -8,6 +8,7 @@ import com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributes
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase
import com.intellij.psi.TokenType
import com.intellij.psi.tree.IElementType
import org.editorconfig.configmanagement.lexer.EditorConfigLexerFactory
import org.editorconfig.language.lexer.EditorConfigLexerAdapter
import org.editorconfig.language.psi.EditorConfigElementTypes
@@ -41,7 +42,7 @@ object EditorConfigSyntaxHighlighter : SyntaxHighlighterBase() {
private val COMMENT_KEYS = arrayOf(COMMENT)
private val EMPTY_KEYS = emptyArray<TextAttributesKey>()
override fun getHighlightingLexer() = EditorConfigLexerAdapter()
override fun getHighlightingLexer() = EditorConfigLexerFactory.getAdapter()
override fun getTokenHighlights(tokenType: IElementType) = when (tokenType) {
EditorConfigElementTypes.SEPARATOR,
@@ -11,13 +11,14 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.TokenType
import com.intellij.psi.tree.IFileElementType
import com.intellij.psi.tree.TokenSet
import org.editorconfig.configmanagement.lexer.EditorConfigLexerFactory
import org.editorconfig.language.EditorConfigLanguage
import org.editorconfig.language.lexer.EditorConfigLexerAdapter
import org.editorconfig.language.psi.EditorConfigElementTypes
import org.editorconfig.language.psi.EditorConfigPsiFile
class EditorConfigParserDefinition : ParserDefinition {
override fun createLexer(project: Project) = EditorConfigLexerAdapter()
override fun createLexer(project: Project) = EditorConfigLexerFactory.getAdapter();
override fun createParser(project: Project): PsiParser = EditorConfigParser()
override fun getCommentTokens() = COMMENTS
@@ -2,8 +2,6 @@
package org.editorconfig.configmanagement;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import com.siyeh.ig.LightInspectionTestCase;
import org.editorconfig.Utils;
import org.editorconfig.language.codeinsight.inspections.EditorConfigValueCorrectnessInspection;
@@ -1,4 +1,6 @@
[*]
ij_formatter_off_tag = @formatter-off
ij_formatter_on_tag = @formatter-on
ij_formatter_on_tag = @formatter-on
ij_imports_layout=*,|,javax.**,java.**,$*
ij_java_packages_to_use_import_on_demand = java.awt.*,java.swing.*