IDEA-169556 Join Lines inserts redundant space in some cases

This commit is contained in:
Dmitry Batrak
2017-03-16 15:26:23 +03:00
parent c3542676b6
commit 4ae6919940
12 changed files with 60 additions and 58 deletions
@@ -253,7 +253,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
}
else {
myResult = Spacing.createSpacing(0, 0, mySettings.BLANK_LINES_AFTER_CLASS_HEADER + 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_DECLARATIONS);
myResult = Spacing.createSpacing(1, 1, mySettings.BLANK_LINES_AFTER_CLASS_HEADER + 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_DECLARATIONS);
}
}
else if (myRole2 == ChildRole.RBRACE && aClass.isEnum()) {
@@ -855,7 +855,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
}
}
myResult = Spacing.createSpacing(0, 0, blankLines, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
myResult = Spacing.createSpacing(1, 1, blankLines, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
}
else {
myResult = Spacing.createDependentLFSpacing(0, 1, textRange, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
@@ -863,7 +863,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
else if (myRole2 == ChildRole.RBRACE) {
if (!keepInOneLine) {
myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_BEFORE_RBRACE);
myResult = Spacing.createSpacing(1, 1, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_BEFORE_RBRACE);
}
else {
myResult = Spacing.createDependentLFSpacing(0, 1, textRange, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_BEFORE_RBRACE);
@@ -1,6 +1,6 @@
class Foo {
void f() {
if (ff) { /*comment*/ return null;
if (ff) { /*comment*/return null;
}
}
}
@@ -0,0 +1,4 @@
class A {
<caret>String s = System
.getProperty("blah");
}
@@ -0,0 +1,3 @@
class A {
String s = System.getProperty("blah");
}
@@ -1,3 +1,3 @@
class Test {
}<caret> // this line is mandatory
}<caret>// this line is mandatory
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* 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.
@@ -222,6 +222,13 @@ public class JoinLinesTest extends LightCodeInsightTestCase {
doTest();
}
public void testJoiningMethodCallWhenItDoesntFit() throws Exception {
CommonCodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()).getCommonSettings(JavaLanguage.INSTANCE);
settings.METHOD_CALL_CHAIN_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED;
settings.RIGHT_MARGIN = 20;
doTest();
}
private void doTest() throws Exception {
doTest(".java");
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* 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.
@@ -268,6 +268,16 @@ public abstract class CodeStyleManager {
public abstract <T> T performActionWithFormatterDisabled(Computable<T> r);
/**
* Calculates minimum spacing, allowed by formatting model (in columns) for a block starting at given offset,
* relative to its previous sibling block.
* Returns <code>-1</code>, if required block cannot be found at provided offset,
* or spacing cannot be calculated due to some other reason.
*/
public int getSpacing(@NotNull PsiFile file, int offset) {
return -1;
}
/**
* Retrieves the current formatting mode.
*
@@ -210,8 +210,8 @@ public class JoinLinesHandler extends EditorActionHandler {
return;
}
if (caretRestoreOffset.get() == CANNOT_JOIN) caretRestoreOffset.set(start == offsets.lineEndOffset ? start : start + 1);
int replaceStart = start == offsets.lineEndOffset ? start : start + 1;
if (caretRestoreOffset.get() == CANNOT_JOIN) caretRestoreOffset.set(replaceStart);
if (offsets.isStartLineEndsWithComment && offsets.isNextLineStartsWithComment) {
@@ -224,12 +224,18 @@ public class JoinLinesHandler extends EditorActionHandler {
while (end < doc.getTextLength() && (text.charAt(end) == ' ' || text.charAt(end) == '\t')) end++;
}
doc.replaceString(start == offsets.lineEndOffset ? start : start + 1, end, " ");
doc.replaceString(replaceStart, end, " ");
return;
}
while (end < doc.getTextLength() && (text.charAt(end) == ' ' || text.charAt(end) == '\t')) end++;
doc.replaceString(start == offsets.lineEndOffset ? start : start + 1, end, " ");
int spacesToCreate = CodeStyleManager.getInstance(project).getSpacing(psiFile, end);
if (spacesToCreate < 0) spacesToCreate = 1;
String spacing = StringUtil.repeatSymbol(' ', spacesToCreate);
doc.replaceString(replaceStart, end, spacing);
docManager.commitDocument(doc);
if (start <= doc.getLineStartOffset(startLine)) {
try {
@@ -241,29 +247,6 @@ public class JoinLinesHandler extends EditorActionHandler {
}
}
int prevLineCount = doc.getLineCount();
docManager.commitDocument(doc);
try {
CodeStyleManager.getInstance(project).reformatRange(psiFile, start + 1, end, true);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
if (prevLineCount < doc.getLineCount()) {
docManager.doPostponedOperationsAndUnblockDocument(doc);
end = doc.getLineEndOffset(startLine) + doc.getLineSeparatorLength(startLine);
start = end - doc.getLineSeparatorLength(startLine);
int addedLinesCount = doc.getLineCount() - prevLineCount - 1;
while (end < doc.getTextLength() &&
(text.charAt(end) == ' ' || text.charAt(end) == '\t' || text.charAt(end) == '\n' && addedLinesCount > 0)) {
if (text.charAt(end) == '\n') addedLinesCount--;
end++;
}
doc.replaceString(start, end, " ");
}
docManager.commitDocument(doc);
}
@@ -16,10 +16,6 @@
package com.intellij.codeInsight.editorActions;
import com.intellij.codeStyle.CodeStyleFacade;
import com.intellij.formatting.FormatterEx;
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.CaretModel;
import com.intellij.openapi.editor.Document;
@@ -29,8 +25,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
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.CodeStyleManager;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -80,7 +75,8 @@ public class SmartIndentingBackspaceHandler extends AbstractIndentingBackspaceHa
int prevLineEndOffset = document.getLineEndOffset(logicalPosition.line - 1);
myStartOffset = CharArrayUtil.shiftBackward(charSequence, prevLineEndOffset - 1, " \t") + 1;
if (myStartOffset != document.getLineStartOffset(logicalPosition.line - 1)) {
myReplacement = getSpacing(file, endOffset);
int spacing = CodeStyleManager.getInstance(project).getSpacing(file, endOffset);
myReplacement = StringUtil.repeatSymbol(' ', Math.max(0, spacing));
}
}
}
@@ -101,17 +97,6 @@ public class SmartIndentingBackspaceHandler extends AbstractIndentingBackspaceHa
return true;
}
private static String getSpacing(PsiFile file, int offset) {
FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
if (builder == null) {
return "";
}
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(file.getProject());
FormattingModel model = builder.createModel(file, settings);
int spacing = FormatterEx.getInstance().getSpacingForBlockAtOffset(model, offset);
return StringUtil.repeatSymbol(' ', spacing);
}
private static int getWidth(@NotNull String indent, int tabSize) {
int width = 0;
for (int i = 0; i < indent.length(); i++) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* 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.
@@ -128,7 +128,8 @@ public abstract class FormatterEx{
/**
* Calculates minimum spacing, allowed by formatting model (in columns) for a block starting at given offset,
* relative to its previous sibling block.
* Returns zero, if required block cannot be found at provided offset, or spacing cannot be calculated due to some other reason.
* Returns <code>-1</code>, if required block cannot be found at provided offset,
* or spacing cannot be calculated due to some other reason.
*/
public abstract int getSpacingForBlockAtOffset(FormattingModel model, int offset);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* 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.
@@ -124,14 +124,14 @@ public class FormatterImpl extends FormatterEx
SpacingImpl spacing = (SpacingImpl)parentBlock.getSpacing(prevBlock, targetBlock);
if (spacing != null) {
int minSpaces = spacing.getMinSpaces();
if (minSpaces > 0) {
if (minSpaces >= 0) {
return minSpaces;
}
}
}
}
}
return 0;
return -1;
}
@Nullable
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* 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.
@@ -880,4 +880,13 @@ public class CodeStyleManagerImpl extends CodeStyleManager implements Formatting
void setCurrentFormattingMode(@NotNull FormattingMode mode) {
myCurrentFormattingMode.set(mode);
}
@Override
public int getSpacing(@NotNull PsiFile file, int offset) {
FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
if (builder == null) return -1;
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(file.getProject());
FormattingModel model = builder.createModel(file, settings);
return FormatterEx.getInstance().getSpacingForBlockAtOffset(model, offset);
}
}