-
Notifications
You must be signed in to change notification settings - Fork 411
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generate hashCode and equals with prompt
Signed-off-by: Jinbo Wang <[email protected]>
- Loading branch information
1 parent
f3552fb
commit 7170abe
Showing
9 changed files
with
317 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
190 changes: 190 additions & 0 deletions
190
...ipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/HashCodeEqualsHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2019 Microsoft Corporation and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Contributors: | ||
* Microsoft Corporation - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.jdt.ls.core.internal.handlers; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
import org.eclipse.core.runtime.CoreException; | ||
import org.eclipse.jdt.core.IType; | ||
import org.eclipse.jdt.core.JavaModelException; | ||
import org.eclipse.jdt.core.dom.CompilationUnit; | ||
import org.eclipse.jdt.core.dom.IMethodBinding; | ||
import org.eclipse.jdt.core.dom.ITypeBinding; | ||
import org.eclipse.jdt.core.dom.IVariableBinding; | ||
import org.eclipse.jdt.core.dom.Modifier; | ||
import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings; | ||
import org.eclipse.jdt.internal.corext.codemanipulation.GenerateHashCodeEqualsOperation; | ||
import org.eclipse.jdt.internal.corext.dom.ASTNodes; | ||
import org.eclipse.jdt.internal.corext.dom.IASTSharedValues; | ||
import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; | ||
import org.eclipse.jdt.ls.core.internal.text.correction.SourceAssistProcessor; | ||
import org.eclipse.lsp4j.CodeActionParams; | ||
import org.eclipse.lsp4j.WorkspaceEdit; | ||
import org.eclipse.text.edits.TextEdit; | ||
|
||
public class HashCodeEqualsHandler { | ||
private static final String METHODNAME_HASH_CODE = "hashCode"; | ||
private static final String METHODNAME_EQUALS = "equals"; | ||
|
||
public static CheckHashCodeEqualsResponse checkHashCodeEqualsStatus(CodeActionParams params) { | ||
CheckHashCodeEqualsResponse response = new CheckHashCodeEqualsResponse(); | ||
IType type = SourceAssistProcessor.getSelectionType(params); | ||
if (type == null) { | ||
return response; | ||
} | ||
|
||
try { | ||
RefactoringASTParser astParser = new RefactoringASTParser(IASTSharedValues.SHARED_AST_LEVEL); | ||
CompilationUnit astRoot = astParser.parse(type.getCompilationUnit(), true); | ||
ITypeBinding typeBinding = ASTNodes.getTypeBinding(astRoot, type); | ||
if (typeBinding == null) { | ||
return response; | ||
} | ||
|
||
HashCodeEqualsInfo info = getTypeInfo(typeBinding); | ||
IVariableBinding[] fields = typeBinding.getDeclaredFields(); | ||
List<VariableField> validFields = new ArrayList<>(); | ||
for (IVariableBinding field : fields) { | ||
if (!Modifier.isStatic(field.getModifiers())) { | ||
VariableField variableField = new VariableField(); | ||
variableField.bindingKey = field.getKey(); | ||
variableField.name = field.getName(); | ||
variableField.type = field.getType().getName(); | ||
validFields.add(variableField); | ||
} | ||
} | ||
|
||
response.type = type.getTypeQualifiedName(); | ||
response.foundEquals = info.foundEquals; | ||
response.foundHashCode = info.foundHashCode; | ||
response.fields = validFields.toArray(new VariableField[0]); | ||
response.settings = new GenerateHashCodeEqualsSettings(); | ||
response.settings.createComments = false; | ||
response.settings.overrideAnnotation = true; | ||
} catch (JavaModelException e) { | ||
// do nothing. | ||
} | ||
|
||
return response; | ||
} | ||
|
||
public static WorkspaceEdit generateHashCodeEquals(GenerateHashCodeEqualsParams params) { | ||
IType type = SourceAssistProcessor.getSelectionType(params.context); | ||
if (type == null) { | ||
return null; | ||
} | ||
|
||
try { | ||
RefactoringASTParser astParser = new RefactoringASTParser(IASTSharedValues.SHARED_AST_LEVEL); | ||
CompilationUnit astRoot = astParser.parse(type.getCompilationUnit(), true); | ||
ITypeBinding typeBinding = ASTNodes.getTypeBinding(astRoot, type); | ||
if (typeBinding == null) { | ||
return null; | ||
} | ||
|
||
IVariableBinding[] variableBindings = convertToVariableBindings(typeBinding, params.fields); | ||
boolean useInstanceOf = false; | ||
boolean useJ7HashEquals = true; | ||
boolean useBlocks = false; | ||
boolean regenerate = false; | ||
CodeGenerationSettings settings = new CodeGenerationSettings(); | ||
settings.createComments = false; | ||
settings.overrideAnnotation = true; | ||
if (params.settings != null) { | ||
useInstanceOf = params.settings.useInstanceOf; | ||
useJ7HashEquals = params.settings.useJ7HashEquals; | ||
useBlocks = params.settings.useBlocks; | ||
regenerate = params.settings.regenerate; | ||
settings.setSettings(params.settings); | ||
} | ||
|
||
GenerateHashCodeEqualsOperation operation = new GenerateHashCodeEqualsOperation(typeBinding, variableBindings, astRoot, null, settings, useInstanceOf, useJ7HashEquals, regenerate, false, false); | ||
operation.setUseBlocksForThen(useBlocks); | ||
operation.run(null); | ||
TextEdit edit = operation.getResultingEdit(); | ||
return SourceAssistProcessor.convertToWorkspaceEdit(type.getCompilationUnit(), edit); | ||
} catch (CoreException e) { | ||
return null; | ||
} | ||
} | ||
|
||
private static HashCodeEqualsInfo getTypeInfo(ITypeBinding typeBinding) { | ||
HashCodeEqualsInfo info = new HashCodeEqualsInfo(); | ||
IMethodBinding[] declaredMethods = typeBinding.getDeclaredMethods(); | ||
for (IMethodBinding method : declaredMethods) { | ||
if (method.getName().equals(METHODNAME_EQUALS)) { | ||
ITypeBinding[] b = method.getParameterTypes(); | ||
if ((b.length == 1) && (b[0].getQualifiedName().equals("java.lang.Object"))) { | ||
info.foundEquals = true; | ||
} | ||
} | ||
|
||
if (method.getName().equals(METHODNAME_HASH_CODE) && method.getParameterTypes().length == 0) { | ||
info.foundHashCode = true; | ||
} | ||
|
||
if (info.foundEquals && info.foundHashCode) { | ||
break; | ||
} | ||
} | ||
|
||
return info; | ||
} | ||
|
||
private static IVariableBinding[] convertToVariableBindings(ITypeBinding typeBinding, VariableField[] fields) { | ||
Set<String> bindingKeys = Stream.of(fields).map((field) -> field.bindingKey).collect(Collectors.toSet()); | ||
List<IVariableBinding> bindings = new ArrayList<>(); | ||
for (IVariableBinding declaredField : typeBinding.getDeclaredFields()) { | ||
if (bindingKeys.contains(declaredField.getKey())) { | ||
bindings.add(declaredField); | ||
} | ||
} | ||
|
||
return bindings.toArray(new IVariableBinding[0]); | ||
} | ||
|
||
private static class HashCodeEqualsInfo { | ||
public boolean foundHashCode = false; | ||
public boolean foundEquals = false; | ||
} | ||
|
||
public static class VariableField { | ||
public String bindingKey; | ||
public String name; | ||
public String type; | ||
} | ||
|
||
public static class GenerateHashCodeEqualsSettings extends CodeGenerationSettings { | ||
public boolean useJ7HashEquals = true; | ||
public boolean regenerate = false; | ||
public boolean useBlocks = false; | ||
public boolean useInstanceOf = false; | ||
} | ||
|
||
public static class CheckHashCodeEqualsResponse { | ||
public String type; | ||
public VariableField[] fields; | ||
public boolean foundHashCode; | ||
public boolean foundEquals; | ||
public GenerateHashCodeEqualsSettings settings; | ||
} | ||
|
||
public static class GenerateHashCodeEqualsParams { | ||
public CodeActionParams context; | ||
public VariableField[] fields; | ||
public GenerateHashCodeEqualsSettings settings; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.