Skip to content

Commit

Permalink
adding Introduce parameter and doing some quickfix cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
m0rkeulv committed Jul 9, 2024
1 parent 1080dac commit e475d65
Show file tree
Hide file tree
Showing 21 changed files with 349 additions and 172 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import com.intellij.openapi.util.TextRange;
import com.intellij.plugins.haxe.HaxeBundle;
import com.intellij.plugins.haxe.HaxeLanguage;
import com.intellij.plugins.haxe.ide.refactoring.introduce.HaxeIntroduceHandler;
import com.intellij.plugins.haxe.ide.refactoring.introduceVariable.HaxeIntroduceHandler;
import com.intellij.plugins.haxe.lang.psi.*;
import com.intellij.plugins.haxe.model.type.HaxeExpressionEvaluator;
import com.intellij.plugins.haxe.model.type.ResultHolder;
Expand Down Expand Up @@ -64,7 +64,7 @@ public void invoke(@NotNull final Project project, Editor editor, PsiFile file)
HaxeValueIterator valueIterator = itr.getValueIterator();
if (valueIterator != null ) {
HaxeComponentName name = valueIterator.getComponentName();
final var introducer = new HaxeIntroduceHandler.HaxeInplaceVariableIntroducer(name, editor, List.of());
final var introducer = new HaxeIntroduceHandler.HaxeInplaceVariableIntroducer(name, editor, List.of(), "Introduce loop iterator");
introducer.setElementToRename(name);
TextRange range = name.getTextRange();
editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import com.intellij.openapi.util.TextRange;
import com.intellij.plugins.haxe.HaxeBundle;
import com.intellij.plugins.haxe.HaxeLanguage;
import com.intellij.plugins.haxe.ide.refactoring.introduce.HaxeIntroduceHandler;
import com.intellij.plugins.haxe.ide.refactoring.introduceVariable.HaxeIntroduceHandler;
import com.intellij.plugins.haxe.lang.psi.*;
import com.intellij.plugins.haxe.model.type.HaxeExpressionEvaluator;
import com.intellij.plugins.haxe.model.type.ResultHolder;
Expand Down Expand Up @@ -81,7 +81,8 @@ private static void introduceKeyValueIterators(Editor editor, HaxeKeyValueIterat
HaxeComponentName keyNamed = keyItr.getComponentName();
HaxeComponentName valueNamed = valueItr.getComponentName();

final var introducer = new HaxeIntroduceHandler.HaxeInplaceVariableIntroducer(keyNamed, editor, List.of(), Map.of( valueNamed, "value"));
final var introducer = new HaxeIntroduceHandler.HaxeInplaceVariableIntroducer(keyNamed, editor, List.of(), Map.of( valueNamed, "value"),
"Introduce key-value iterator");
introducer.setElementToRename(keyNamed);
TextRange range = keyNamed.getTextRange();
editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
import com.intellij.plugins.haxe.ide.refactoring.extractInterface.ExtractInterfaceHandler;
import com.intellij.plugins.haxe.ide.refactoring.extractMethod.HaxeExtractMethodHandler;
import com.intellij.plugins.haxe.ide.refactoring.extractSuperclass.ExtractSuperclassHandler;
import com.intellij.plugins.haxe.ide.refactoring.introduce.HaxeIntroduceVariableHandler;
import com.intellij.plugins.haxe.ide.refactoring.introduceParameter.HaxeIntroduceParameterHandler;
import com.intellij.plugins.haxe.ide.refactoring.introduceVariable.HaxeIntroduceVariableHandler;
import com.intellij.plugins.haxe.ide.refactoring.introduceField.HaxeIntroduceConstantHandler;
import com.intellij.plugins.haxe.ide.refactoring.memberPullUp.HaxePullUpHandler;
import com.intellij.plugins.haxe.ide.refactoring.memberPushDown.HaxePushDownHandler;
Expand All @@ -44,6 +45,11 @@ public RefactoringActionHandler getIntroduceVariableHandler() {
return new HaxeIntroduceVariableHandler();
}

@Override
public @Nullable RefactoringActionHandler getIntroduceParameterHandler() {
return new HaxeIntroduceParameterHandler();
}

@Nullable
@Override
public RefactoringActionHandler getExtractInterfaceHandler() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
* @author: Fedor.Korotkov
*/
public class HaxeRefactoringUtil {
public static Set<String> collectUsedNames(HaxePsiCompositeElement context) {
public static Set<String> collectUsedNames(PsiElement context) {
final Set<HaxeComponentName> usedComponentNames = new HashSet<>();
PsiTreeUtil.treeWalkUp(new ComponentNameScopeProcessor(usedComponentNames), context, null, new ResolveState());

Expand All @@ -70,10 +70,7 @@ public static Set<String> collectKeywords() {
}

@Nullable
public static HaxeExpression getSelectedExpression(@NotNull final Project project,
@NotNull PsiFile file,
@NotNull final PsiElement element1,
@NotNull final PsiElement element2) {
public static HaxeExpression getSelectedExpression(@NotNull final PsiElement element1, @NotNull final PsiElement element2) {
PsiElement parent = PsiTreeUtil.findCommonParent(element1, element2);
if (parent == null) {
return null;
Expand All @@ -83,6 +80,17 @@ public static HaxeExpression getSelectedExpression(@NotNull final Project projec
}
return PsiTreeUtil.getParentOfType(parent, HaxeExpression.class);
}
@Nullable
public static HaxeComponentName getSelectedComponentName(@NotNull final PsiElement element1, @NotNull final PsiElement element2) {
PsiElement parent = PsiTreeUtil.findCommonParent(element1, element2);
if (parent == null) {
return null;
}
if (parent instanceof HaxeComponentName) {
return (HaxeComponentName)parent;
}
return PsiTreeUtil.getParentOfType(parent, HaxeComponentName.class);
}

public static void reformat(final PsiMember movedElement) {
ApplicationManager.getApplication().runWriteAction(() -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.plugins.haxe.ide.refactoring.introduce.HaxeIntroduceHandler;
import com.intellij.plugins.haxe.ide.refactoring.introduce.HaxeIntroduceOperation;
import com.intellij.plugins.haxe.ide.refactoring.introduceVariable.HaxeIntroduceHandler;
import com.intellij.plugins.haxe.ide.refactoring.introduceVariable.HaxeIntroduceOperation;
import com.intellij.plugins.haxe.lang.psi.*;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
Expand All @@ -31,7 +31,7 @@ public HaxeExtractMethodHandler() {

@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
performAction(new HaxeIntroduceOperation(project, editor, file, null));
performAction(new HaxeIntroduceOperation(project, editor, file, null, "Extract Method"));
}

@Override
Expand Down Expand Up @@ -168,7 +168,7 @@ private static void startRenameMethod(HaxeIntroduceOperation operation, Editor e

final InplaceVariableIntroducer<PsiElement> introducer =
new HaxeInplaceVariableIntroducer(method.getComponentName(), operation,
List.of(method.getComponentName()));
List.of(method.getComponentName()), "Introduce Method");

introducer.performInplaceRefactoring(new LinkedHashSet<>(Optional.ofNullable(operation.getSuggestedNames()).orElse(List.of())));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
package com.intellij.plugins.haxe.ide.refactoring.introduceField;

import com.intellij.openapi.project.Project;
import com.intellij.plugins.haxe.ide.refactoring.introduce.HaxeIntroduceHandler;
import com.intellij.plugins.haxe.ide.refactoring.introduce.HaxeIntroduceOperation;
import com.intellij.plugins.haxe.ide.refactoring.introduceVariable.HaxeIntroduceHandler;
import com.intellij.plugins.haxe.ide.refactoring.introduceVariable.HaxeIntroduceOperation;
import com.intellij.plugins.haxe.lang.psi.HaxeClass;
import com.intellij.plugins.haxe.lang.psi.HaxeClassBody;
import com.intellij.plugins.haxe.lang.psi.HaxeExpression;
Expand Down Expand Up @@ -82,7 +82,7 @@ private static HaxeFieldDeclaration lastFieldDeclarationInList(HaxeClassBody cla
@Override
public PsiElement createDeclaration(HaxeIntroduceOperation operation) {
final Project project = operation.getProject();
final HaxeExpression initializer = operation.getInitializer();
final PsiElement initializer = operation.getInitializer();
InitializerTextBuilder builder = new InitializerTextBuilder();
initializer.accept(builder);
String assignmentText = "public static inline var " + operation.getName() + " = " + builder.result() + ";";
Expand Down Expand Up @@ -122,7 +122,7 @@ protected HaxeFieldDeclaration createDeclaration(Project project, String text, P
}

@Override
protected Collection<String> getSuggestedNames(HaxeExpression expression) {
protected Collection<String> getSuggestedNames(PsiElement expression) {
return HaxeNameSuggesterUtil.getSuggestedNames(expression, true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2014-2014 AS3Boyan
* Copyright 2014-2014 Elias Ku
*
* 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 com.intellij.plugins.haxe.ide.refactoring.introduceParameter;

import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.plugins.haxe.HaxeBundle;
import com.intellij.plugins.haxe.ide.refactoring.introduceVariable.HaxeIntroduceHandler;
import com.intellij.plugins.haxe.ide.refactoring.introduceVariable.HaxeIntroduceOperation;
import com.intellij.plugins.haxe.lang.psi.*;
import com.intellij.plugins.haxe.model.type.HaxeExpressionEvaluator;
import com.intellij.plugins.haxe.model.type.HaxeTypeResolver;
import com.intellij.plugins.haxe.model.type.ResultHolder;
import com.intellij.plugins.haxe.util.HaxeElementGenerator;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiParserFacade;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

import static com.intellij.plugins.haxe.util.HaxeElementGenerator.createSemi;

/**
* @author: Fedor.Korotkov
*/
public class HaxeIntroduceParameterHandler extends HaxeIntroduceHandler {
public HaxeIntroduceParameterHandler() {
super(HaxeBundle.message("refactoring.introduce.parameter.dialog.title"));
}

protected @NotNull String getActionName() {
return "Introduce Parameter";
}

@Override
protected boolean isValidIntroduceContext(PsiElement element) {
if( isLiteral(element)) {
if (PsiTreeUtil.getParentOfType(element, HaxeMethodDeclaration.class)!= null) {
return true;
}
}else if (isVarDeclaration(element)) {
return true;
}else {
// check for block parent, we need a block to put assign statement in
if (PsiTreeUtil.getParentOfType(element, HaxeBlockStatement.class) != null) {
return true;
}
}
return false;
}

private boolean isVarDeclaration(PsiElement element) {
HaxeLocalVarDeclarationList varDeclarations = PsiTreeUtil.getParentOfType(element, HaxeLocalVarDeclarationList.class);
if(varDeclarations.getLocalVarDeclarationList().size() == 1) {
HaxeLocalVarDeclaration varDeclaration = varDeclarations.getLocalVarDeclarationList().get(0);
if (varDeclaration != null && element instanceof HaxeComponentName varName) {
return varDeclaration.getComponentName() == varName;
}
}
return false;
}

@Override
protected void performActionOnElementOccurrences(HaxeIntroduceOperation operation) {
if(operation.getInitializer() instanceof HaxeComponentName componentName) {
operation.setName(componentName.getIdentifier().getText());
}
super.performActionOnElementOccurrences(operation);
}

@Nullable
public PsiElement createDeclaration(HaxeIntroduceOperation operation) {
PsiElement initializer = operation.getInitializer();


ResultHolder result = findType(initializer);

String typeTag = !result.isUnknown() ? ":" + result.toStringWithoutConstant() : "";
String constant = getConstantString(initializer);
String assignmentText = operation.getName() + typeTag + constant;

PsiElement anchor = operation.isReplaceAll()
? findAnchor(operation.getOccurrences())
: findAnchor(initializer);

return createDeclaration(operation.getProject(), assignmentText, anchor);
}

private ResultHolder findType(PsiElement initializer) {
if(isVarDeclaration(initializer)) {
HaxeLocalVarDeclaration varDeclaration = PsiTreeUtil.getParentOfType(initializer, HaxeLocalVarDeclaration.class);
if(varDeclaration != null) return HaxeTypeResolver.getPsiElementType(varDeclaration, null);
}
return HaxeExpressionEvaluator.evaluate(initializer, null).result;
}

private @NotNull String getConstantString(PsiElement expression) {
if (isLiteral(expression)) {
return " = " + expression.getText();
}
if (isVarDeclaration(expression)) {
HaxeLocalVarDeclaration declaration = PsiTreeUtil.getParentOfType(expression, HaxeLocalVarDeclaration.class);
if (declaration != null && declaration.getVarInit() != null) {
HaxeExpression init = declaration.getVarInit().getExpression();
if(isLiteral(init)) {
return " = " + init.getText();
}
}
}
return "";
}

private boolean isLiteral(PsiElement element) {
return element instanceof HaxeLiteralExpression || element instanceof HaxeStringLiteralExpression;
}

@Nullable
protected PsiElement createDeclaration(Project project, String text, PsiElement anchor) {
return HaxeElementGenerator.createParameter(project, text);
}

protected void modifyDeclaration(@NotNull PsiElement declaration, HaxeIntroduceOperation operation) {
PsiElement expression = operation.getInitializer();
if (declaration instanceof HaxeParameter parameter) {
if (isLiteral(expression)) {
return; // handled as parameter default value
}

if (isVarDeclaration(expression)) {
replaceVarDeclaration(parameter, expression);
return;
}

insertParameterAssignStatement(parameter, expression);
}
}

private void replaceVarDeclaration(HaxeParameter parameter, PsiElement expression) {
HaxeLocalVarDeclarationList declarations = PsiTreeUtil.getParentOfType(expression, HaxeLocalVarDeclarationList.class);
if(declarations.getLocalVarDeclarationList().size() == 1) {
HaxeLocalVarDeclaration declaration = declarations.getLocalVarDeclarationList().get(0);
if (declaration.getVarInit() != null) {
HaxeExpression init = declaration.getVarInit().getExpression();
if (isLiteral(init)) {
declarations.delete();
} else {
PsiElement replaced = declarations.replace(declaration);
replaced.add(createSemi(declaration.getProject()));
}
}
else {
declarations.delete();
}
}
}

private static void insertParameterAssignStatement(@NotNull HaxeParameter parameter, PsiElement expression) {
Project project = expression.getProject();

String paramName = parameter.getComponentName().getText();
String assignExpression = paramName + " = " + expression.getText()+";";
PsiElement assign = HaxeElementGenerator.createStatementFromText(project, assignExpression);
HaxeBlockStatement blockStatement = PsiTreeUtil.getParentOfType(expression, HaxeBlockStatement.class);
PsiElement anchor = blockStatement.addBefore(assign, findInsertBeforeElement(expression, blockStatement));

final PsiElement newLineNode = PsiParserFacade.getInstance(parameter.getProject()).createWhiteSpaceFromText("\n");
blockStatement.addAfter(newLineNode, anchor);
blockStatement.addAfter(HaxeElementGenerator.createSemi(project), anchor);

CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(expression.getContainingFile());
}

private static @NotNull PsiElement findInsertBeforeElement(@NotNull PsiElement startElement, HaxeBlockStatement block) {
PsiElement insertBeforeElement = startElement;
PsiElement parent = startElement.getParent();

while (parent != null && parent != block) {
insertBeforeElement = parent;
parent = parent.getParent();
}
return insertBeforeElement;
}


@Override
protected PsiElement addDeclaration(@NotNull final PsiElement expression,
@NotNull final PsiElement declaration,
@NotNull HaxeIntroduceOperation operation) {
return doIntroduceParameter(expression, declaration, operation.getOccurrences(), operation.isReplaceAll());
}

public static PsiElement doIntroduceParameter(PsiElement expression,
PsiElement declaration,
List<PsiElement> occurrences,
boolean replaceAll) {
PsiElement anchor = replaceAll ? findAnchor(occurrences) : findAnchor(expression);
assert anchor != null;
HaxeMethodDeclaration method = PsiTreeUtil.getParentOfType(expression, HaxeMethodDeclaration.class);


if (method != null) {
HaxeParameterList parameterList = method.getParameterList();
List<HaxeParameter> list = parameterList.getParameterList();
if (list.isEmpty()) {
return parameterList.add(declaration);
}else {
PsiUtilCore.ensureValid(parameterList);
PsiElement seperator = HaxeElementGenerator.createComma(expression.getProject());
parameterList.add(seperator);
return parameterList.add(declaration);
}

}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.plugins.haxe.ide.refactoring.introduce.HaxeIntroduceDialog">
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.plugins.haxe.ide.refactoring.introduceVariable.HaxeIntroduceDialog">
<grid id="27dc6" binding="myContentPane" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
Expand Down
Loading

0 comments on commit e475d65

Please sign in to comment.