mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Refactoring: extracted IndentOptionsAdjuster which is responsible only for adjusting passed IndentOptions
This commit is contained in:
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.psi.codeStyle.autodetect;
|
||||
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
class IndentOptionsAdjuster {
|
||||
private static final double RATE_THRESHOLD = 0.8;
|
||||
private static final int MAX_INDENT_TO_DETECT = 8;
|
||||
|
||||
private final boolean isTabsUsed;
|
||||
private final boolean isSpacesUsed;
|
||||
private final int newIndentSize;
|
||||
|
||||
public IndentOptionsAdjuster(IndentUsageStatistics stats) {
|
||||
isTabsUsed = isTabsUsed(stats);
|
||||
isSpacesUsed = isSpacesUsed(stats);
|
||||
newIndentSize = isSpacesUsed ? getPositiveIndentSize(stats) : 0;
|
||||
}
|
||||
|
||||
public void adjust(@NotNull CommonCodeStyleSettings.IndentOptions indentOptions) {
|
||||
if (isTabsUsed) {
|
||||
adjustForTabUsage(indentOptions);
|
||||
}
|
||||
else if (isSpacesUsed) {
|
||||
indentOptions.USE_TAB_CHARACTER = false;
|
||||
if (newIndentSize > 0 && indentOptions.INDENT_SIZE != newIndentSize) {
|
||||
indentOptions.INDENT_SIZE = newIndentSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void adjustForTabUsage(@NotNull CommonCodeStyleSettings.IndentOptions indentOptions) {
|
||||
if (indentOptions.USE_TAB_CHARACTER) return;
|
||||
|
||||
int continuationRatio = indentOptions.INDENT_SIZE == 0 ? 1 : indentOptions.CONTINUATION_INDENT_SIZE / indentOptions.INDENT_SIZE;
|
||||
|
||||
indentOptions.USE_TAB_CHARACTER = true;
|
||||
indentOptions.INDENT_SIZE = indentOptions.TAB_SIZE;
|
||||
indentOptions.CONTINUATION_INDENT_SIZE = indentOptions.TAB_SIZE * continuationRatio;
|
||||
}
|
||||
|
||||
private static boolean isSpacesUsed(IndentUsageStatistics stats) {
|
||||
int spaces = stats.getTotalLinesWithLeadingSpaces();
|
||||
int total = stats.getTotalLinesWithLeadingSpaces() + stats.getTotalLinesWithLeadingTabs();
|
||||
return (double)spaces / total > RATE_THRESHOLD;
|
||||
}
|
||||
|
||||
private static boolean isTabsUsed(IndentUsageStatistics stats) {
|
||||
return stats.getTotalLinesWithLeadingTabs() > stats.getTotalLinesWithLeadingSpaces();
|
||||
}
|
||||
|
||||
private static int getPositiveIndentSize(@NotNull IndentUsageStatistics stats) {
|
||||
int totalIndentSizesDetected = stats.getTotalIndentSizesDetected();
|
||||
if (totalIndentSizesDetected == 0) return -1;
|
||||
|
||||
IndentUsageInfo maxUsedIndentInfo = stats.getKMostUsedIndentInfo(0);
|
||||
int maxUsedIndentSize = maxUsedIndentInfo.getIndentSize();
|
||||
|
||||
if (maxUsedIndentSize == 0) {
|
||||
if (totalIndentSizesDetected < 2) return -1;
|
||||
|
||||
maxUsedIndentInfo = stats.getKMostUsedIndentInfo(1);
|
||||
maxUsedIndentSize = maxUsedIndentInfo.getIndentSize();
|
||||
}
|
||||
|
||||
if (maxUsedIndentSize <= MAX_INDENT_TO_DETECT) {
|
||||
double usageRate = (double)maxUsedIndentInfo.getTimesUsed() / stats.getTotalLinesWithLeadingSpaces();
|
||||
if (usageRate > RATE_THRESHOLD) {
|
||||
return maxUsedIndentSize;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
+7
-74
@@ -19,7 +19,6 @@ import com.intellij.formatting.Block;
|
||||
import com.intellij.formatting.FormattingModel;
|
||||
import com.intellij.formatting.FormattingModelBuilder;
|
||||
import com.intellij.lang.LanguageFormatting;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
@@ -36,11 +35,6 @@ import java.util.List;
|
||||
import static com.intellij.psi.codeStyle.CommonCodeStyleSettings.IndentOptions;
|
||||
|
||||
public class IndentOptionsDetectorImpl implements IndentOptionsDetector {
|
||||
private static Logger LOG = Logger.getInstance("#com.intellij.psi.codeStyle.CommonCodeStyleSettings.IndentOptionsDetector");
|
||||
|
||||
private static final double RATE_THRESHOLD = 0.8;
|
||||
private static final int MAX_INDENT_TO_DETECT = 8;
|
||||
|
||||
private final PsiFile myFile;
|
||||
private final Project myProject;
|
||||
private final Document myDocument;
|
||||
@@ -54,12 +48,14 @@ public class IndentOptionsDetectorImpl implements IndentOptionsDetector {
|
||||
@Override
|
||||
@NotNull
|
||||
public IndentOptions getIndentOptions() {
|
||||
IndentOptions indentOptions = (IndentOptions)CodeStyleSettingsManager.getSettings(myProject).getIndentOptions(myFile.getFileType()).clone();
|
||||
IndentOptions indentOptions =
|
||||
(IndentOptions)CodeStyleSettingsManager.getSettings(myProject).getIndentOptions(myFile.getFileType()).clone();
|
||||
|
||||
List<LineIndentInfo> linesInfo = calcLineIndentInfo();
|
||||
if (linesInfo != null) {
|
||||
IndentUsageStatistics stats = new IndentUsageStatisticsImpl(linesInfo);
|
||||
adjustIndentOptions(indentOptions, stats);
|
||||
IndentOptionsAdjuster adjuster = new IndentOptionsAdjuster(stats);
|
||||
adjuster.adjust(indentOptions);
|
||||
}
|
||||
|
||||
return indentOptions;
|
||||
@@ -70,11 +66,11 @@ public class IndentOptionsDetectorImpl implements IndentOptionsDetector {
|
||||
if (myDocument == null || myDocument.getLineCount() < 3 || isFileBigToDetect()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(myProject);
|
||||
FormattingModelBuilder modelBuilder = LanguageFormatting.INSTANCE.forContext(myFile);
|
||||
if (modelBuilder == null) return null;
|
||||
|
||||
|
||||
FormattingModel model = modelBuilder.createModel(myFile, settings);
|
||||
Block rootBlock = model.getRootBlock();
|
||||
return new FormatterBasedLineIndentInfoBuilder(myDocument, rootBlock).build();
|
||||
@@ -83,72 +79,9 @@ public class IndentOptionsDetectorImpl implements IndentOptionsDetector {
|
||||
private boolean isFileBigToDetect() {
|
||||
VirtualFile file = myFile.getVirtualFile();
|
||||
if (file != null && file.getLength() > FileUtilRt.MEGABYTE) {
|
||||
LOG.debug("Indent detector disabled for this file");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void adjustIndentOptions(@NotNull IndentOptions indentOptions, @NotNull IndentUsageStatistics stats) {
|
||||
if (isTabsUsed(stats)) {
|
||||
adjustForTabUsage(indentOptions);
|
||||
}
|
||||
else if (isSpacesUsed(stats)) {
|
||||
indentOptions.USE_TAB_CHARACTER = false;
|
||||
|
||||
int newIndentSize = getPositiveIndentSize(stats);
|
||||
if (newIndentSize > 0) {
|
||||
if (indentOptions.INDENT_SIZE != newIndentSize) {
|
||||
indentOptions.INDENT_SIZE = newIndentSize;
|
||||
LOG.debug("Detected indent size: " + newIndentSize + " for file " + myFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSpacesUsed(IndentUsageStatistics stats) {
|
||||
int spaces = stats.getTotalLinesWithLeadingSpaces();
|
||||
int total = stats.getTotalLinesWithLeadingSpaces() + stats.getTotalLinesWithLeadingTabs();
|
||||
return (double)spaces / total > RATE_THRESHOLD;
|
||||
}
|
||||
|
||||
private static boolean isTabsUsed(IndentUsageStatistics stats) {
|
||||
return stats.getTotalLinesWithLeadingTabs() > stats.getTotalLinesWithLeadingSpaces();
|
||||
}
|
||||
|
||||
private void adjustForTabUsage(@NotNull IndentOptions indentOptions) {
|
||||
if (indentOptions.USE_TAB_CHARACTER) return;
|
||||
|
||||
int continuationRatio = indentOptions.INDENT_SIZE == 0 ? 1 : indentOptions.CONTINUATION_INDENT_SIZE / indentOptions.INDENT_SIZE;
|
||||
|
||||
indentOptions.USE_TAB_CHARACTER = true;
|
||||
indentOptions.INDENT_SIZE = indentOptions.TAB_SIZE;
|
||||
indentOptions.CONTINUATION_INDENT_SIZE = indentOptions.TAB_SIZE * continuationRatio;
|
||||
|
||||
LOG.debug("Using tabs for: " + myFile);
|
||||
}
|
||||
|
||||
private static int getPositiveIndentSize(@NotNull IndentUsageStatistics stats) {
|
||||
int totalIndentSizesDetected = stats.getTotalIndentSizesDetected();
|
||||
if (totalIndentSizesDetected == 0) return -1;
|
||||
|
||||
IndentUsageInfo maxUsedIndentInfo = stats.getKMostUsedIndentInfo(0);
|
||||
int maxUsedIndentSize = maxUsedIndentInfo.getIndentSize();
|
||||
|
||||
if (maxUsedIndentSize == 0) {
|
||||
if (totalIndentSizesDetected < 2) return -1;
|
||||
|
||||
maxUsedIndentInfo = stats.getKMostUsedIndentInfo(1);
|
||||
maxUsedIndentSize = maxUsedIndentInfo.getIndentSize();
|
||||
}
|
||||
|
||||
if (maxUsedIndentSize <= MAX_INDENT_TO_DETECT) {
|
||||
double usageRate = (double)maxUsedIndentInfo.getTimesUsed() / stats.getTotalLinesWithLeadingSpaces();
|
||||
if (usageRate > RATE_THRESHOLD) {
|
||||
return maxUsedIndentSize;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user