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:
@@ -33,6 +33,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
public class KotlinEditorOptions implements PersistentStateComponent<KotlinEditorOptions> {
|
public class KotlinEditorOptions implements PersistentStateComponent<KotlinEditorOptions> {
|
||||||
private boolean donTShowConversionDialog = false;
|
private boolean donTShowConversionDialog = false;
|
||||||
private boolean enableJavaToKotlinConversion = true;
|
private boolean enableJavaToKotlinConversion = true;
|
||||||
|
private boolean autoAddValKeywordToDataClassParameters = true;
|
||||||
|
|
||||||
public boolean isDonTShowConversionDialog() {
|
public boolean isDonTShowConversionDialog() {
|
||||||
return donTShowConversionDialog;
|
return donTShowConversionDialog;
|
||||||
@@ -42,6 +43,14 @@ public class KotlinEditorOptions implements PersistentStateComponent<KotlinEdito
|
|||||||
this.donTShowConversionDialog = donTShowConversionDialog;
|
this.donTShowConversionDialog = donTShowConversionDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAutoAddValKeywordToDataClassParameters() {
|
||||||
|
return autoAddValKeywordToDataClassParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoAddValKeywordToDataClassParameters(boolean autoAddValKeywordToDataClassParameters) {
|
||||||
|
this.autoAddValKeywordToDataClassParameters = autoAddValKeywordToDataClassParameters;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEnableJavaToKotlinConversion() {
|
public boolean isEnableJavaToKotlinConversion() {
|
||||||
return enableJavaToKotlinConversion;
|
return enableJavaToKotlinConversion;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ public class KotlinEditorOptionsConfigurable extends BeanConfigurable<KotlinEdit
|
|||||||
checkBox("Don't show Java to Kotlin conversion dialog on paste",
|
checkBox("Don't show Java to Kotlin conversion dialog on paste",
|
||||||
instance::isDonTShowConversionDialog,
|
instance::isDonTShowConversionDialog,
|
||||||
instance::setDonTShowConversionDialog);
|
instance::setDonTShowConversionDialog);
|
||||||
|
checkBox("Auto add val keyword to data/inline class constructor parameters",
|
||||||
|
instance::isAutoAddValKeywordToDataClassParameters,
|
||||||
|
instance::setAutoAddValKeywordToDataClassParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.CodeInsightSettings;
|
|||||||
import com.intellij.codeInsight.editorActions.TypedHandlerDelegate;
|
import com.intellij.codeInsight.editorActions.TypedHandlerDelegate;
|
||||||
import com.intellij.codeInsight.highlighting.BraceMatcher;
|
import com.intellij.codeInsight.highlighting.BraceMatcher;
|
||||||
import com.intellij.codeInsight.highlighting.BraceMatchingUtil;
|
import com.intellij.codeInsight.highlighting.BraceMatchingUtil;
|
||||||
|
import com.intellij.ide.PowerSaveMode;
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
import com.intellij.openapi.editor.Document;
|
import com.intellij.openapi.editor.Document;
|
||||||
@@ -82,6 +83,9 @@ public class KotlinTypedHandler extends TypedHandlerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case ')':
|
||||||
|
dataClassValParameterInsert(project, editor, file, /*beforeType = */ true);
|
||||||
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
kotlinLTTyped = CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET &&
|
kotlinLTTyped = CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET &&
|
||||||
LtGtTypingUtils.shouldAutoCloseAngleBracket(editor.getCaretModel().getOffset(), editor);
|
LtGtTypingUtils.shouldAutoCloseAngleBracket(editor.getCaretModel().getOffset(), editor);
|
||||||
@@ -263,6 +267,9 @@ public class KotlinTypedHandler extends TypedHandlerDelegate {
|
|||||||
LtGtTypingUtils.handleKotlinAutoCloseLT(editor);
|
LtGtTypingUtils.handleKotlinAutoCloseLT(editor);
|
||||||
return Result.STOP;
|
return Result.STOP;
|
||||||
}
|
}
|
||||||
|
else if (c == ',' || c == ')') {
|
||||||
|
dataClassValParameterInsert(project, editor, file, /*beforeType = */ false);
|
||||||
|
}
|
||||||
else if (c == '{' && CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET) {
|
else if (c == '{' && CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET) {
|
||||||
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
|
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
|
||||||
|
|
||||||
@@ -328,6 +335,46 @@ public class KotlinTypedHandler extends TypedHandlerDelegate {
|
|||||||
return Result.CONTINUE;
|
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
|
* Copied from
|
||||||
*
|
*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user