KT-1712 Formatting for getters and setters
#KT-1712 fixed
This commit is contained in:
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 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 org.jetbrains.jet.plugin.formatter;
|
||||||
|
|
||||||
|
import com.intellij.formatting.Indent;
|
||||||
|
import com.intellij.lang.ASTNode;
|
||||||
|
import com.intellij.psi.tree.IElementType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nikolay Krasko
|
||||||
|
*/
|
||||||
|
public abstract class ASTIndentStrategy {
|
||||||
|
public static ASTIndentStrategy constIndent(Indent indent) {
|
||||||
|
return new ConstIndentStrategy(indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PositionStrategy forNode(@Nullable String debugInfo) {
|
||||||
|
return new PositionStrategy(debugInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public abstract Indent getIndent(@NotNull ASTNode node);
|
||||||
|
|
||||||
|
public static class ConstIndentStrategy extends ASTIndentStrategy {
|
||||||
|
private final Indent indent;
|
||||||
|
|
||||||
|
public ConstIndentStrategy(Indent indent) {
|
||||||
|
this.indent = indent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Indent getIndent(@NotNull ASTNode node) {
|
||||||
|
return indent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PositionStrategy extends ASTIndentStrategy {
|
||||||
|
private Indent defaultIndent = Indent.getNoneIndent();
|
||||||
|
|
||||||
|
private List<IElementType> in = new ArrayList<IElementType>();
|
||||||
|
private List<IElementType> notIn = new ArrayList<IElementType>();
|
||||||
|
private List<IElementType> forElement = new ArrayList<IElementType>();
|
||||||
|
private List<IElementType> notForElement = new ArrayList<IElementType>();
|
||||||
|
|
||||||
|
private String debugInfo;
|
||||||
|
|
||||||
|
public PositionStrategy(@Nullable String debugInfo) {
|
||||||
|
this.debugInfo = debugInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PositionStrategy " + (debugInfo != null ? debugInfo : "No debug info");
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionStrategy set(Indent indent) {
|
||||||
|
defaultIndent = indent;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionStrategy in(@NotNull IElementType parentType, @NotNull IElementType... orParentTypes) {
|
||||||
|
in.clear();
|
||||||
|
in.add(parentType);
|
||||||
|
Collections.addAll(in, orParentTypes);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionStrategy notIn(@NotNull IElementType parentType, @NotNull IElementType... orParentTypes) {
|
||||||
|
notIn.clear();
|
||||||
|
notIn.add(parentType);
|
||||||
|
Collections.addAll(notIn, orParentTypes);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionStrategy inAny() {
|
||||||
|
in.clear();
|
||||||
|
notIn.clear();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionStrategy forType(@NotNull IElementType elementType, @NotNull IElementType... otherTypes) {
|
||||||
|
forElement.clear();
|
||||||
|
forElement.add(elementType);
|
||||||
|
Collections.addAll(forElement, otherTypes);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionStrategy notForType(@NotNull IElementType elementType, @NotNull IElementType... otherTypes) {
|
||||||
|
notForElement.clear();
|
||||||
|
notForElement.add(elementType);
|
||||||
|
Collections.addAll(notForElement, otherTypes);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionStrategy forAny() {
|
||||||
|
forElement.clear();
|
||||||
|
notForElement.clear();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Indent getIndent(@NotNull ASTNode node) {
|
||||||
|
if (!forElement.isEmpty()) {
|
||||||
|
if (!forElement.contains(node.getElementType())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notForElement.contains(node.getElementType())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTNode parent = node.getTreeParent();
|
||||||
|
if (parent != null) {
|
||||||
|
if (!in.isEmpty()) {
|
||||||
|
if (!in.contains(parent.getElementType())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notIn.contains(parent.getElementType())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!in.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultIndent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,10 +48,6 @@ public class JetBlock extends AbstractBlock {
|
|||||||
JetNodeTypes.CLASS_BODY,
|
JetNodeTypes.CLASS_BODY,
|
||||||
JetNodeTypes.FUNCTION_LITERAL_EXPRESSION);
|
JetNodeTypes.FUNCTION_LITERAL_EXPRESSION);
|
||||||
|
|
||||||
private static final TokenSet STATEMENT_PARTS = TokenSet.create(
|
|
||||||
JetNodeTypes.THEN,
|
|
||||||
JetNodeTypes.ELSE);
|
|
||||||
|
|
||||||
// private static final List<IndentWhitespaceRule>
|
// private static final List<IndentWhitespaceRule>
|
||||||
|
|
||||||
public JetBlock(@NotNull ASTNode node,
|
public JetBlock(@NotNull ASTNode node,
|
||||||
@@ -241,35 +237,50 @@ public class JetBlock extends AbstractBlock {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
static ASTIndentStrategy[] INDENT_RULES = new ASTIndentStrategy[] {
|
||||||
protected Indent getChildIndent() {
|
ASTIndentStrategy.forNode("No indent for braces in blocks")
|
||||||
return super.getChildIndent(); //To change body of overridden methods use File | Settings | File Templates.
|
.in(JetNodeTypes.BLOCK, JetNodeTypes.CLASS_BODY, JetNodeTypes.FUNCTION_LITERAL_EXPRESSION)
|
||||||
}
|
.forType(JetTokens.RBRACE, JetTokens.LBRACE)
|
||||||
|
.set(Indent.getNoneIndent()),
|
||||||
|
|
||||||
|
ASTIndentStrategy.forNode("Indent for block content")
|
||||||
|
.in(JetNodeTypes.BLOCK, JetNodeTypes.CLASS_BODY, JetNodeTypes.FUNCTION_LITERAL_EXPRESSION)
|
||||||
|
.notForType(JetTokens.RBRACE, JetTokens.LBRACE)
|
||||||
|
.set(Indent.getNormalIndent()),
|
||||||
|
|
||||||
|
ASTIndentStrategy.forNode("Indent for property accessors")
|
||||||
|
.in(JetNodeTypes.PROPERTY)
|
||||||
|
.forType(JetNodeTypes.PROPERTY_ACCESSOR)
|
||||||
|
.set(Indent.getNormalIndent()),
|
||||||
|
|
||||||
|
ASTIndentStrategy.forNode("For a single statement if 'for'")
|
||||||
|
.in(JetNodeTypes.BODY)
|
||||||
|
.notForType(JetNodeTypes.BLOCK)
|
||||||
|
.set(Indent.getNormalIndent()),
|
||||||
|
|
||||||
|
ASTIndentStrategy.forNode("For the entry in when")
|
||||||
|
.forType(JetNodeTypes.WHEN_ENTRY)
|
||||||
|
.set(Indent.getNormalIndent()),
|
||||||
|
|
||||||
|
ASTIndentStrategy.forNode("For single statement in THEN and ELSE")
|
||||||
|
.in(JetNodeTypes.THEN, JetNodeTypes.ELSE)
|
||||||
|
.notForType(JetNodeTypes.BLOCK)
|
||||||
|
.set(Indent.getNormalIndent())
|
||||||
|
};
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected Indent createChildIndent(@NotNull ASTNode child) {
|
protected static Indent createChildIndent(@NotNull ASTNode child) {
|
||||||
CommonCodeStyleSettings commonSettings = mySettings.getCommonSettings(JetLanguage.INSTANCE);
|
|
||||||
|
|
||||||
ASTNode childParent = child.getTreeParent();
|
ASTNode childParent = child.getTreeParent();
|
||||||
IElementType childType = child.getElementType();
|
IElementType childType = child.getElementType();
|
||||||
|
|
||||||
if (CODE_BLOCKS.contains(myNode.getElementType())) {
|
for (ASTIndentStrategy strategy : INDENT_RULES) {
|
||||||
return indentIfNotBrace(child);
|
Indent indent = strategy.getIndent(child);
|
||||||
|
if (indent != null) {
|
||||||
|
return indent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (childParent != null &&
|
// TODO: Try to rewrite other rules to declarative style
|
||||||
childParent.getElementType() == JetNodeTypes.BODY &&
|
|
||||||
childType != JetNodeTypes.BLOCK) {
|
|
||||||
|
|
||||||
// For a single statement if 'for'
|
|
||||||
return Indent.getNormalIndent();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (childType == JetNodeTypes.WHEN_ENTRY) {
|
|
||||||
// For the entry in when
|
|
||||||
// TODO: Add an option for configuration?
|
|
||||||
return Indent.getNormalIndent();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (childParent != null && childParent.getElementType() == JetNodeTypes.WHEN_ENTRY) {
|
if (childParent != null && childParent.getElementType() == JetNodeTypes.WHEN_ENTRY) {
|
||||||
ASTNode prev = getPrevWithoutWhitespace(child);
|
ASTNode prev = getPrevWithoutWhitespace(child);
|
||||||
@@ -278,10 +289,6 @@ public class JetBlock extends AbstractBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STATEMENT_PARTS.contains(myNode.getElementType()) && childType != JetNodeTypes.BLOCK) {
|
|
||||||
return Indent.getNormalIndent();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (childParent != null && childParent.getElementType() == JetNodeTypes.DOT_QUALIFIED_EXPRESSION) {
|
if (childParent != null && childParent.getElementType() == JetNodeTypes.DOT_QUALIFIED_EXPRESSION) {
|
||||||
if (childParent.getFirstChildNode() != child && childParent.getLastChildNode() != child) {
|
if (childParent.getFirstChildNode() != child && childParent.getLastChildNode() != child) {
|
||||||
return Indent.getContinuationWithoutFirstIndent(false);
|
return Indent.getContinuationWithoutFirstIndent(false);
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class Test {
|
||||||
|
var test : Int
|
||||||
|
get () {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
set (value) {
|
||||||
|
throw NotSupportedException()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class Test {
|
||||||
|
var test : Int
|
||||||
|
get () {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
set (value) {
|
||||||
|
throw NotSupportedException()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// "Change getter type to Int" "true"
|
// "Change getter type to Int" "true"
|
||||||
class A() {
|
class A() {
|
||||||
val i: Int
|
val i: Int
|
||||||
get(): Int = 1
|
get(): Int = 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// "Change setter parameter type to Int" "true"
|
// "Change setter parameter type to Int" "true"
|
||||||
class A() {
|
class A() {
|
||||||
var i: Int = 0
|
var i: Int = 0
|
||||||
set(v: Int) {}
|
set(v: Int) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// "Change getter type to Int" "true"
|
// "Change getter type to Int" "true"
|
||||||
class A() {
|
class A() {
|
||||||
val i: Int
|
val i: Int
|
||||||
get(): <caret>Any = 1
|
get(): <caret>Any = 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// "Change setter parameter type to Int" "true"
|
// "Change setter parameter type to Int" "true"
|
||||||
class A() {
|
class A() {
|
||||||
var i: Int = 0
|
var i: Int = 0
|
||||||
set(v: <caret>Any) {}
|
set(v: <caret>Any) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// "Make variable mutable" "true"
|
// "Make variable mutable" "true"
|
||||||
class A() {
|
class A() {
|
||||||
var a : Int = 0
|
var a : Int = 0
|
||||||
set(v : Int) {
|
set(v : Int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
val Int.v : Int
|
val Int.v : Int
|
||||||
get() {
|
get() {
|
||||||
<caret>
|
<caret>
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
var Int.v : Int
|
var Int.v : Int
|
||||||
get() {
|
get() {
|
||||||
<caret>
|
<caret>
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -67,6 +67,10 @@ public class JetFormatterTest extends AbstractJetFormatterTest {
|
|||||||
doTest();
|
doTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testGetterAndSetter() throws Exception {
|
||||||
|
doTest();
|
||||||
|
}
|
||||||
|
|
||||||
public void testIf() throws Exception {
|
public void testIf() throws Exception {
|
||||||
doTest();
|
doTest();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
|
|||||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||||
import org.jetbrains.jet.plugin.formatter.JetCodeStyleSettings;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@@ -106,10 +105,6 @@ public class JetTypingIndentationTest extends LightCodeInsightTestCase {
|
|||||||
checkResultByFile(afterFileName);
|
checkResultByFile(afterFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JetCodeStyleSettings getJetSettings() {
|
|
||||||
return getSettings().getCustomSettings(JetCodeStyleSettings.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CodeStyleSettings getSettings() {
|
public static CodeStyleSettings getSettings() {
|
||||||
return CodeStyleSettingsManager.getSettings(getProject());
|
return CodeStyleSettingsManager.getSettings(getProject());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user