PSI file-based code style API

This commit is contained in:
Rustam Vishnyakov
2017-11-09 20:15:39 +03:00
parent ff50234b6b
commit 5a17f77e46
7 changed files with 165 additions and 20 deletions
@@ -0,0 +1,152 @@
// Copyright 2000-2017 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.application.options;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
import org.jetbrains.annotations.NotNull;
/**
* Utility class for miscellaneous code style settings retrieving methods.
*/
public class CodeStyle {
private CodeStyle() {
}
/**
* @return Default application-wide root code style settings.
*/
@NotNull
public static CodeStyleSettings getDefaultSettings() {
return CodeStyleSettingsManager.getInstance().getCurrentSettings();
}
/**
* Returns root code style settings for the given project. For configurable language settings use {@link #getLanguageSettings(PsiFile)} or
* {@link #getLanguageSettings(PsiFile, Language)}.
* @param project The project to get code style settings for.
* @return The current root code style settings associated with the project.
*/
@NotNull
public static CodeStyleSettings getSettings(@NotNull Project project) {
return CodeStyleSettingsManager.getInstance(project).getCurrentSettings();
}
/**
* Returns root code style settings for the given PSI file. For configurable language settings use {@link #getLanguageSettings(PsiFile)} or
* {@link #getLanguageSettings(PsiFile, Language)}.
* @param file The file to get code style settings for.
* @return The current root code style settings associated with the file or default settings if the file is invalid.
*/
@NotNull
public static CodeStyleSettings getSettings(@NotNull PsiFile file) {
if (file.isValid()) {
Project project = file.getProject();
return CodeStyleSettingsManager.getInstance(project).getCurrentSettings();
}
return getDefaultSettings();
}
/**
* Returns custom settings for the given PSI file.
* @param file The file.
* @param customSettingsClass The class of a settings object to be returned.
* @param <T> Settings class type.
* @return The current custom settings associated with the PSI file.
*/
@NotNull
public static <T extends CustomCodeStyleSettings> T getCustomSettings(@NotNull PsiFile file, Class<T> customSettingsClass) {
CodeStyleSettings rootSettings = getSettings(file);
return rootSettings.getCustomSettings(customSettingsClass);
}
/**
* Returns language settings for the given PSI file. The language is taken from the file itself.
* @param file The file to retrieve language settings for.
* @return The associated language settings.
*/
@NotNull
public static CommonCodeStyleSettings getLanguageSettings(@NotNull PsiFile file) {
CodeStyleSettings rootSettings = getSettings(file);
return rootSettings.getCommonSettings(file.getLanguage());
}
/**
* Returns language settings for the given PSI file and language. This method may be useful when PSI file contains elements for multiple
* languages and language settings should be taken from a specific language context.
* @param file The file to retrieve language settings for.
* @return The associated language settings.
*/
public static CommonCodeStyleSettings getLanguageSettings(@NotNull PsiFile file, @NotNull Language language) {
CodeStyleSettings rootSettings = getSettings(file);
return rootSettings.getCommonSettings(language);
}
/**
* Returns indent options for the given PSI file. The method attempts to use {@link com.intellij.psi.codeStyle.FileIndentOptionsProvider}
* if applicable to the file. If there are no suitable indent options providers, it takes configurable language indent options or
* retrieves indent options by file type.
* @param file The file to get indent options for.
* @return The file indent options.
* @see com.intellij.psi.codeStyle.FileIndentOptionsProvider
*/
@NotNull
public static CommonCodeStyleSettings.IndentOptions getIndentOptions(@NotNull PsiFile file) {
CodeStyleSettings rootSettings = getSettings(file);
return rootSettings.getIndentOptionsByFile(file);
}
/**
* Explicitly retrieves indent options by file type.
* @param file The file to get indent options for.
* @return The indent options associated with the file type.
*/
@NotNull
public static CommonCodeStyleSettings.IndentOptions getIndentOptionsByFileType(@NotNull PsiFile file) {
return getSettings(file).getIndentOptions(file.getFileType());
}
/**
* Returns indent options for the given project and document.
* @param project The current project.
* @param document The document to get indent options for.
* @return The indent options associated with document's PSI file if the file is available or other indent options otherwise.
*/
@NotNull
public static CommonCodeStyleSettings.IndentOptions getIndentOptions(@NotNull Project project, @NotNull Document document) {
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (file != null) {
return getIndentOptions(file);
}
return getSettings(project).getIndentOptions(null);
}
/**
* Returns indent size for the given PSI file.
* @param file The file to get indent size for.
* @return The indent size to be used with the PSI file.
*/
public static int getIndentSize(@NotNull PsiFile file) {
return getIndentOptions(file).INDENT_SIZE;
}
}
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.completion;
import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Document;
@@ -22,7 +23,6 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;
@@ -139,6 +139,6 @@ public class InsertionContext {
public CommonCodeStyleSettings getCodeStyleSettings() {
Language lang = PsiUtilCore.getLanguageAtOffset(getFile(), getTailOffset());
return CodeStyleSettingsManager.getSettings(getProject()).getCommonSettings(lang);
return CodeStyle.getLanguageSettings(getFile(), lang);
}
}
@@ -16,6 +16,7 @@
package com.intellij.codeInsight.editorActions.enter;
import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.editorActions.EnterHandler;
import com.intellij.codeInsight.editorActions.JavaLikeQuoteHandler;
import com.intellij.codeInsight.editorActions.QuoteHandler;
@@ -37,8 +38,6 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.StringEscapesTokenTypes;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import org.jetbrains.annotations.NotNull;
public class EnterInStringLiteralHandler extends EnterHandlerDelegateAdapter {
@@ -86,9 +85,7 @@ public class EnterInStringLiteralHandler extends EnterHandlerDelegateAdapter {
document.insertString(caretOffset, insertedFragment + " " + literalStart);
caretOffset += insertedFragment.length();
caretAdvance = 1;
CommonCodeStyleSettings langSettings =
CodeStyleSettingsManager.getSettings(file.getProject()).getCommonSettings(file.getLanguage());
if (langSettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE) {
if (CodeStyle.getLanguageSettings(file).BINARY_OPERATION_SIGN_ON_NEXT_LINE) {
caretOffset -= 1;
caretAdvance = 3;
}
@@ -16,6 +16,7 @@
package com.intellij.psi.formatter;
import com.intellij.application.options.CodeStyle;
import com.intellij.formatting.FormattingDocumentModel;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
@@ -28,7 +29,6 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.impl.PsiDocumentManagerImpl;
import com.intellij.psi.impl.PsiToDocumentSynchronizer;
@@ -50,7 +50,7 @@ public class FormattingDocumentModelImpl implements FormattingDocumentModel {
myFile = file;
Language language = file.getLanguage();
myWhiteSpaceStrategy = WhiteSpaceFormattingStrategyFactory.getStrategy(language);
mySettings = CodeStyleSettingsManager.getSettings(file.getProject());
mySettings = CodeStyle.getSettings(file);
}
public static FormattingDocumentModelImpl createOn(@NotNull PsiFile file) {
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl.source.codeStyle.lineIndent;
import com.intellij.application.options.CodeStyle;
import com.intellij.formatting.Indent;
import com.intellij.formatting.IndentInfo;
import com.intellij.lang.Language;
@@ -23,8 +24,6 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.impl.source.codeStyle.SemanticEditorPosition;
import com.intellij.util.text.CharArrayUtil;
@@ -71,11 +70,10 @@ public class IndentCalculator {
Document document = myEditor.getDocument();
PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
if (file != null) {
CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(myProject);
CommonCodeStyleSettings.IndentOptions fileOptions = codeStyleSettings.getIndentOptionsByFile(file);
CommonCodeStyleSettings.IndentOptions fileOptions = CodeStyle.getIndentOptions(file);
CommonCodeStyleSettings.IndentOptions options =
!fileOptions.isOverrideLanguageOptions() && language != null && !(language.is(file.getLanguage()) || language.is(Language.ANY)) ?
codeStyleSettings.getCommonSettings(language).getIndentOptions() :
CodeStyle.getLanguageSettings(file, language).getIndentOptions() :
fileOptions;
return
baseIndent + new IndentInfo(0, indentTypeToSize(myIndentType, options), 0, false).generateNewWhiteSpace(options);
@@ -16,6 +16,7 @@
package com.intellij.openapi.editor.actions;
import com.intellij.application.options.CodeStyle;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.command.CommandProcessor;
@@ -28,7 +29,6 @@ import com.intellij.openapi.editor.ex.util.EditorUIUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -71,7 +71,7 @@ public class TabAction extends EditorAction {
columnNumber = editor.getCaretModel().getLogicalPosition().column;
}
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project);
CodeStyleSettings settings = project != null ? CodeStyle.getSettings(project) : CodeStyle.getDefaultSettings();
final Document doc = editor.getDocument();
CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptionsByDocument(project, doc);
@@ -15,6 +15,7 @@
*/
package com.jetbrains.python.codeInsight;
import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.editorActions.TypedHandlerDelegate;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Document;
@@ -27,8 +28,6 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.PyTokenTypes;
@@ -95,8 +94,7 @@ public class PyMethodNameTypedHandler extends TypedHandlerDelegate {
paramName = "";
}
// TODO: only print the ")" if Settings require it
final CodeStyleSettings settingsManager = CodeStyleSettingsManager.getSettings(project);
final CommonCodeStyleSettings settings = settingsManager.getCommonSettings(PythonLanguage.getInstance());
final CommonCodeStyleSettings settings = CodeStyle.getLanguageSettings(file, PythonLanguage.getInstance());
final StringBuilder textToType = new StringBuilder();
textToType.append("(");
if (!paramName.isEmpty()) {