Add feature for data and inline class parameters smart typing

When one typing data/inline class primary ctor this feature adds missing val keyword for parameters
i.e.
data class xxx(x: Int<caret>)
when typing comma symbol convert code to
data class xxx(val x: Int,<caret>)

Fixed #KT-34567
This commit is contained in:
Igor Yakovlev
2019-10-23 21:54:44 +03:00
parent 0708f574fc
commit 63e687f67e
4 changed files with 432 additions and 286 deletions
@@ -33,6 +33,7 @@ import org.jetbrains.annotations.Nullable;
public class KotlinEditorOptions implements PersistentStateComponent<KotlinEditorOptions> {
private boolean donTShowConversionDialog = false;
private boolean enableJavaToKotlinConversion = true;
private boolean autoAddValKeywordToDataClassParameters = true;
public boolean isDonTShowConversionDialog() {
return donTShowConversionDialog;
@@ -42,6 +43,14 @@ public class KotlinEditorOptions implements PersistentStateComponent<KotlinEdito
this.donTShowConversionDialog = donTShowConversionDialog;
}
public boolean isAutoAddValKeywordToDataClassParameters() {
return autoAddValKeywordToDataClassParameters;
}
public void setAutoAddValKeywordToDataClassParameters(boolean autoAddValKeywordToDataClassParameters) {
this.autoAddValKeywordToDataClassParameters = autoAddValKeywordToDataClassParameters;
}
public boolean isEnableJavaToKotlinConversion() {
return enableJavaToKotlinConversion;
}
@@ -21,6 +21,9 @@ public class KotlinEditorOptionsConfigurable extends BeanConfigurable<KotlinEdit
checkBox("Don't show Java to Kotlin conversion dialog on paste",
instance::isDonTShowConversionDialog,
instance::setDonTShowConversionDialog);
checkBox("Auto add val keyword to data/inline class constructor parameters",
instance::isAutoAddValKeywordToDataClassParameters,
instance::setAutoAddValKeywordToDataClassParameters);
}
@Override
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.editorActions.TypedHandlerDelegate;
import com.intellij.codeInsight.highlighting.BraceMatcher;
import com.intellij.codeInsight.highlighting.BraceMatchingUtil;
import com.intellij.ide.PowerSaveMode;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
@@ -82,6 +83,9 @@ public class KotlinTypedHandler extends TypedHandlerDelegate {
}
switch (c) {
case ')':
dataClassValParameterInsert(project, editor, file, /*beforeType = */ true);
break;
case '<':
kotlinLTTyped = CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET &&
LtGtTypingUtils.shouldAutoCloseAngleBracket(editor.getCaretModel().getOffset(), editor);
@@ -263,6 +267,9 @@ public class KotlinTypedHandler extends TypedHandlerDelegate {
LtGtTypingUtils.handleKotlinAutoCloseLT(editor);
return Result.STOP;
}
else if (c == ',' || c == ')') {
dataClassValParameterInsert(project, editor, file, /*beforeType = */ false);
}
else if (c == '{' && CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET) {
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
@@ -328,6 +335,46 @@ public class KotlinTypedHandler extends TypedHandlerDelegate {
return Result.CONTINUE;
}
private static void dataClassValParameterInsert(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file, boolean beforeType) {
if (!KotlinEditorOptions.getInstance().isAutoAddValKeywordToDataClassParameters()) return;
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
int commaOffset = editor.getCaretModel().getOffset();
if (!beforeType) commaOffset--;
if (commaOffset < 1) return;
PsiElement elementOnCaret = file.findElementAt(commaOffset);
if (elementOnCaret == null) return;
boolean contextMatched = false;
PsiElement parentElement = elementOnCaret.getParent();
if (parentElement instanceof KtParameterList) {
parentElement = parentElement.getParent();
if (parentElement instanceof KtPrimaryConstructor) {
parentElement = parentElement.getParent();
if (parentElement instanceof KtClass) {
KtClass klassElement = ((KtClass)parentElement);
contextMatched = klassElement.isData() || klassElement.hasModifier(KtTokens.INLINE_KEYWORD);
}
}
}
if (!contextMatched) return;
PsiElement leftElement = PsiTreeUtil.skipWhitespacesAndCommentsBackward(elementOnCaret);
if (!(leftElement instanceof KtParameter)) return;
KtParameter ktParameter = (KtParameter)leftElement;
if (ktParameter.hasValOrVar()) return;
KtTypeReference typeReference = ktParameter.getTypeReference();
if (typeReference == null) return;
if (typeReference.getTextLength() == 0) return;
editor.getDocument().insertString(leftElement.getTextOffset(), "val ");
}
/**
* Copied from
*
File diff suppressed because it is too large Load Diff