diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java index 2b74b60aa371..647a74dc6ae5 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java @@ -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); diff --git a/java/java-tests/testData/codeInsight/joinLines/ConvertComment_after.java b/java/java-tests/testData/codeInsight/joinLines/ConvertComment_after.java index 89435b3e02d5..62dcee91d16f 100644 --- a/java/java-tests/testData/codeInsight/joinLines/ConvertComment_after.java +++ b/java/java-tests/testData/codeInsight/joinLines/ConvertComment_after.java @@ -1,6 +1,6 @@ class Foo { void f() { - if (ff) { /*comment*/ return null; + if (ff) { /*comment*/return null; } } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/joinLines/JoiningMethodCallWhenItDoesntFit.java b/java/java-tests/testData/codeInsight/joinLines/JoiningMethodCallWhenItDoesntFit.java new file mode 100644 index 000000000000..bedc8848a3cb --- /dev/null +++ b/java/java-tests/testData/codeInsight/joinLines/JoiningMethodCallWhenItDoesntFit.java @@ -0,0 +1,4 @@ +class A { + String s = System + .getProperty("blah"); +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/joinLines/JoiningMethodCallWhenItDoesntFit_after.java b/java/java-tests/testData/codeInsight/joinLines/JoiningMethodCallWhenItDoesntFit_after.java new file mode 100644 index 000000000000..84981f268e6b --- /dev/null +++ b/java/java-tests/testData/codeInsight/joinLines/JoiningMethodCallWhenItDoesntFit_after.java @@ -0,0 +1,3 @@ +class A { + String s = System.getProperty("blah"); +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/joinLines/SCR5959_after.java b/java/java-tests/testData/codeInsight/joinLines/SCR5959_after.java index 0b7842ea80b7..6c003c1813a1 100644 --- a/java/java-tests/testData/codeInsight/joinLines/SCR5959_after.java +++ b/java/java-tests/testData/codeInsight/joinLines/SCR5959_after.java @@ -1,3 +1,3 @@ class Test { -} // this line is mandatory +}// this line is mandatory diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/JoinLinesTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/JoinLinesTest.java index 717bc581d084..19b8e59ef976 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/JoinLinesTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/JoinLinesTest.java @@ -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"); } diff --git a/platform/core-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java b/platform/core-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java index 1ec14c92b581..481762a0740a 100644 --- a/platform/core-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java +++ b/platform/core-api/src/com/intellij/psi/codeStyle/CodeStyleManager.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 performActionWithFormatterDisabled(Computable r); + /** + * Calculates minimum spacing, allowed by formatting model (in columns) for a block starting at given offset, + * relative to its previous sibling block. + * Returns -1, 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. * diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java index 9c92e968866c..28712aaf5af7 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java @@ -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); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SmartIndentingBackspaceHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SmartIndentingBackspaceHandler.java index fa67438cfbf8..3d425bd0e30c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SmartIndentingBackspaceHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SmartIndentingBackspaceHandler.java @@ -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++) { diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatterEx.java b/platform/lang-impl/src/com/intellij/formatting/FormatterEx.java index 2d32c89e3606..60c35e38f7f2 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatterEx.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatterEx.java @@ -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 -1, 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); diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java index 2e07c9221a45..4558accd235d 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java @@ -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 diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java index 543f5115bd97..06b6f883cd29 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java @@ -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); + } }