mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
generate equals/hashCode: use velocity templates
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
package org.jetbrains.java.generate.psi;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
@@ -668,9 +670,16 @@ public class PsiAdapter {
|
||||
}
|
||||
|
||||
public static int getJavaVersion(PsiElement element) {
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(element);
|
||||
final JavaSdkVersion sdkVersion = JavaVersionService.getInstance().getJavaSdkVersion(element);
|
||||
int version = 0;
|
||||
switch (languageLevel) {
|
||||
switch (sdkVersion) {
|
||||
case JDK_1_0:
|
||||
case JDK_1_1:
|
||||
version = 1;
|
||||
break;
|
||||
case JDK_1_2:
|
||||
version = 2;
|
||||
break;
|
||||
case JDK_1_3:
|
||||
version = 3;
|
||||
break;
|
||||
@@ -695,4 +704,10 @@ public class PsiAdapter {
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
public static boolean isNestedArray(PsiType aType) {
|
||||
if (!(aType instanceof PsiArrayType)) return false;
|
||||
final PsiType componentType = ((PsiArrayType)aType).getComponentType();
|
||||
return componentType instanceof PsiArrayType;
|
||||
}
|
||||
}
|
||||
|
||||
+28
-3
@@ -19,6 +19,7 @@ import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.components.StoragePathMacros;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.java.generate.exception.TemplateResourceException;
|
||||
import org.jetbrains.java.generate.template.TemplateResource;
|
||||
import org.jetbrains.java.generate.template.TemplatesManager;
|
||||
@@ -33,11 +34,11 @@ import java.io.IOException;
|
||||
)}
|
||||
)
|
||||
public class EqualsHashCodeTemplatesManager extends TemplatesManager {
|
||||
private static final String DEFAULT_EQUALS = "com/intellij/codeInsight/generation/defaultEquals.vm";
|
||||
private static final String DEFAULT_HASH_CODE = "com/intellij/codeInsight/generation/defaultHashCode.vm";
|
||||
private static final String DEFAULT_EQUALS = "/com/intellij/codeInsight/generation/defaultEquals.vm";
|
||||
private static final String DEFAULT_HASH_CODE = "/com/intellij/codeInsight/generation/defaultHashCode.vm";
|
||||
|
||||
|
||||
public static TemplatesManager getInstance() {
|
||||
public static EqualsHashCodeTemplatesManager getInstance() {
|
||||
return ServiceManager.getService(EqualsHashCodeTemplatesManager.class);
|
||||
}
|
||||
|
||||
@@ -57,4 +58,28 @@ public class EqualsHashCodeTemplatesManager extends TemplatesManager {
|
||||
private static String readFile(String resourceName) throws IOException {
|
||||
return readFile(resourceName, EqualsHashCodeTemplatesManager.class);
|
||||
}
|
||||
|
||||
public TemplateResource getDefaultEqualsTemplate() {
|
||||
return getDefaultEqualsTemplate("equals", "hashCode");
|
||||
}
|
||||
|
||||
public TemplateResource getDefaultHashcodeTemplate() {
|
||||
return getDefaultEqualsTemplate("hashCode", "equals");
|
||||
}
|
||||
|
||||
private TemplateResource getDefaultEqualsTemplate(String selfSuffix, String oppositeSuffix) {
|
||||
final TemplateResource defaultTemplate = getDefaultTemplate();
|
||||
final String fileName = defaultTemplate.getFileName();
|
||||
if (fileName.endsWith(selfSuffix)) {
|
||||
return defaultTemplate;
|
||||
}
|
||||
final String equalsTemplateName = StringUtil.trimEnd(fileName, oppositeSuffix) + selfSuffix;
|
||||
for (TemplateResource resource : getAllTemplates()) {
|
||||
if (equalsTemplateName.equals(resource.getFileName())) {
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
assert false : selfSuffix + " template for " + fileName + " not found";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,12 +15,9 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.generation;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
@@ -31,8 +28,8 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.java.generate.GenerationUtil;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -45,16 +42,6 @@ public class GenerateEqualsHelper implements Runnable {
|
||||
private final PsiField[] myHashCodeFields;
|
||||
private final HashSet<PsiField> myNonNullSet;
|
||||
private final PsiElementFactory myFactory;
|
||||
private String myParameterName;
|
||||
|
||||
@NonNls private static final String BASE_OBJECT_PARAMETER_NAME = "object";
|
||||
@NonNls private static final String BASE_OBJECT_LOCAL_NAME = "that";
|
||||
@NonNls private static final String RESULT_VARIABLE = "result";
|
||||
@NonNls private static final String TEMP_VARIABLE = "temp";
|
||||
|
||||
private String myClassInstanceName;
|
||||
|
||||
@NonNls private static final HashMap<String, MessageFormat> PRIMITIVE_HASHCODE_FORMAT = new HashMap<String, MessageFormat>();
|
||||
private final boolean mySuperHasHashCode;
|
||||
private final CodeStyleManager myCodeStyleManager;
|
||||
private final JavaCodeStyleManager myJavaCodeStyleManager;
|
||||
@@ -84,28 +71,6 @@ public class GenerateEqualsHelper implements Runnable {
|
||||
myJavaCodeStyleManager = JavaCodeStyleManager.getInstance(manager.getProject());
|
||||
}
|
||||
|
||||
private static String getUniqueLocalVarName(String base, PsiField[] fields) {
|
||||
String id = base;
|
||||
int index = 0;
|
||||
while (true) {
|
||||
if (index > 0) {
|
||||
id = base + index;
|
||||
}
|
||||
index++;
|
||||
boolean anyEqual = false;
|
||||
for (PsiField equalsField : fields) {
|
||||
if (id.equals(equalsField.getName())) {
|
||||
anyEqual = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!anyEqual) break;
|
||||
}
|
||||
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
private static boolean shouldAddOverrideAnnotation(PsiElement context) {
|
||||
CodeStyleSettings style = CodeStyleSettingsManager.getSettings(context.getProject());
|
||||
|
||||
@@ -165,58 +130,35 @@ public class GenerateEqualsHelper implements Runnable {
|
||||
|
||||
|
||||
private PsiMethod createEquals() throws IncorrectOperationException {
|
||||
JavaCodeStyleManager codeStyleManager = myJavaCodeStyleManager;
|
||||
final PsiType objectType = PsiType.getJavaLangObject(myClass.getManager(), myClass.getResolveScope());
|
||||
String[] nameSuggestions = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, objectType).names;
|
||||
final String objectBaseName = nameSuggestions.length > 0 ? nameSuggestions[0] : BASE_OBJECT_PARAMETER_NAME;
|
||||
myParameterName = getUniqueLocalVarName(objectBaseName, myEqualsFields);
|
||||
final PsiType classType = myFactory.createType(myClass);
|
||||
nameSuggestions = codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, null, classType).names;
|
||||
String instanceBaseName = nameSuggestions.length > 0 && nameSuggestions[0].length() < 10 ? nameSuggestions[0] : BASE_OBJECT_LOCAL_NAME;
|
||||
myClassInstanceName = getUniqueLocalVarName(instanceBaseName, myEqualsFields);
|
||||
|
||||
@NonNls StringBuffer buffer = new StringBuffer();
|
||||
@NonNls StringBuilder buffer = new StringBuilder();
|
||||
CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(myProject);
|
||||
if (shouldAddOverrideAnnotation(myClass)) {
|
||||
buffer.append("@Override\n");
|
||||
}
|
||||
buffer.append("public boolean equals(Object ").append(myParameterName).append(") {\n");
|
||||
addEqualsPrologue(buffer);
|
||||
if (myEqualsFields.length > 0) {
|
||||
addClassInstance(buffer);
|
||||
ArrayList<PsiField> equalsFields = new ArrayList<PsiField>();
|
||||
ContainerUtil.addAll(equalsFields, myEqualsFields);
|
||||
Collections.sort(equalsFields, EqualsFieldsComparator.INSTANCE);
|
||||
|
||||
ArrayList<PsiField> equalsFields = new ArrayList<PsiField>();
|
||||
ContainerUtil.addAll(equalsFields, myEqualsFields);
|
||||
Collections.sort(equalsFields, EqualsFieldsComparator.INSTANCE);
|
||||
final HashMap<String, Object> contextMap = new HashMap<String, Object>();
|
||||
|
||||
for (PsiField field : equalsFields) {
|
||||
if (!field.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final PsiType type = field.getType();
|
||||
if (type instanceof PsiArrayType) {
|
||||
addArrayEquals(buffer, field);
|
||||
}
|
||||
else if (type instanceof PsiPrimitiveType) {
|
||||
if (PsiType.DOUBLE.equals(type) || PsiType.FLOAT.equals(type)) {
|
||||
addDoubleFieldComparison(buffer, field);
|
||||
}
|
||||
else {
|
||||
addPrimitiveFieldComparison(buffer, field);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClass aClass = ((PsiClassType)type).resolve();
|
||||
if (aClass != null && aClass.isEnum()) {
|
||||
addPrimitiveFieldComparison(buffer, field);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
addFieldComparison(buffer, field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
buffer.append("\nreturn true;\n}");
|
||||
final PsiType classType = JavaPsiFacade.getElementFactory(myClass.getProject()).createType(myClass);
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(myClass.getProject());
|
||||
String[] nameSuggestions = codeStyleManager
|
||||
.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, null, classType).names;
|
||||
String instanceBaseName = nameSuggestions.length > 0 && nameSuggestions[0].length() < 10 ? nameSuggestions[0] : "that";
|
||||
contextMap.put("instanceName", instanceBaseName);
|
||||
|
||||
final PsiType objectType = PsiType.getJavaLangObject(myClass.getManager(), myClass.getResolveScope());
|
||||
nameSuggestions = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, objectType).names;
|
||||
final String objectBaseName = nameSuggestions.length > 0 ? nameSuggestions[0] : "object";
|
||||
contextMap.put("baseParamName", objectBaseName);
|
||||
contextMap.put("superHasEquals", superMethodExists(getEqualsSignature(myProject, myClass.getResolveScope())));
|
||||
contextMap.put("checkParameterWithInstanceof", myCheckParameterWithInstanceof);
|
||||
|
||||
final String methodText = GenerationUtil
|
||||
.velocityGenerateCode(myClass, equalsFields, myNonNullSet, new HashMap<String, String>(), contextMap,
|
||||
EqualsHashCodeTemplatesManager.getInstance().getDefaultEqualsTemplate().getTemplate(), 0, false);
|
||||
buffer.append(methodText);
|
||||
PsiMethod result = myFactory.createMethodFromText(buffer.toString(), myClass);
|
||||
final PsiParameter parameter = result.getParameterList().getParameters()[0];
|
||||
PsiUtil.setModifierProperty(parameter, PsiModifier.FINAL, styleSettings.GENERATE_FINAL_PARAMETERS);
|
||||
@@ -226,109 +168,6 @@ public class GenerateEqualsHelper implements Runnable {
|
||||
return method;
|
||||
}
|
||||
|
||||
private void addDoubleFieldComparison(final StringBuffer buffer, final PsiField field) {
|
||||
@NonNls final String type = PsiType.DOUBLE.equals(field.getType()) ? "Double" : "Float";
|
||||
final Object[] parameters = new Object[]{type, myClassInstanceName, field.getName()};
|
||||
DOUBLE_FIELD_COMPARER_MF.format(parameters, buffer, null);
|
||||
}
|
||||
|
||||
@NonNls private static final MessageFormat ARRAY_COMPARER_MF =
|
||||
new MessageFormat("if(!java.util.Arrays.equals({1}, {0}.{1})) return false;\n");
|
||||
|
||||
@NonNls private static final MessageFormat ARRAY_DEEP_COMPARER_MF =
|
||||
new MessageFormat("if(!java.util.Arrays.deepEquals({1}, {0}.{1})) return false;\n");
|
||||
@NonNls private static final MessageFormat FIELD_COMPARER_MF =
|
||||
new MessageFormat("if({1}!=null ? !{1}.equals({0}.{1}) : {0}.{1}!= null)return false;\n");
|
||||
@NonNls private static final MessageFormat NON_NULL_FIELD_COMPARER_MF = new MessageFormat("if(!{1}.equals({0}.{1}))return false;\n");
|
||||
@NonNls private static final MessageFormat PRIMITIVE_FIELD_COMPARER_MF = new MessageFormat("if({1}!={0}.{1})return false;\n");
|
||||
@NonNls private static final MessageFormat DOUBLE_FIELD_COMPARER_MF =
|
||||
new MessageFormat("if({0}.compare({1}.{2}, {2}) != 0)return false;\n");
|
||||
|
||||
private void addArrayEquals(StringBuffer buffer, PsiField field) {
|
||||
final PsiType fieldType = field.getType();
|
||||
if (isNestedArray(fieldType)) {
|
||||
if (JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) {
|
||||
ARRAY_DEEP_COMPARER_MF.format(getComparerFormatParameters(field), buffer, null);
|
||||
}
|
||||
else {
|
||||
buffer.append(" ");
|
||||
buffer.append(CodeInsightBundle.message("generate.equals.compare.nested.arrays.comment", field.getName()));
|
||||
buffer.append("\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (isArrayOfObjects(fieldType)) {
|
||||
buffer.append(" ");
|
||||
buffer.append(CodeInsightBundle.message("generate.equals.compare.arrays.comment"));
|
||||
buffer.append("\n");
|
||||
}
|
||||
|
||||
ARRAY_COMPARER_MF.format(getComparerFormatParameters(field), buffer, null);
|
||||
}
|
||||
|
||||
private Object[] getComparerFormatParameters(PsiField field) {
|
||||
return new Object[]{myClassInstanceName, field.getName()};
|
||||
}
|
||||
|
||||
|
||||
private void addFieldComparison(StringBuffer buffer, PsiField field) {
|
||||
boolean canBeNull = !myNonNullSet.contains(field);
|
||||
if (canBeNull) {
|
||||
FIELD_COMPARER_MF.format(getComparerFormatParameters(field), buffer, null);
|
||||
}
|
||||
else {
|
||||
NON_NULL_FIELD_COMPARER_MF.format(getComparerFormatParameters(field), buffer, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void addPrimitiveFieldComparison(StringBuffer buffer, PsiField field) {
|
||||
PRIMITIVE_FIELD_COMPARER_MF.format(getComparerFormatParameters(field), buffer, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("HardCodedStringLiteral")
|
||||
private void addInstanceOfToText(@NonNls StringBuffer buffer, String returnValue) {
|
||||
if (myCheckParameterWithInstanceof) {
|
||||
buffer.append("if(!(").append(myParameterName).append(" instanceof ").append(myClass.getName())
|
||||
.append(")) " + "return ").append(returnValue).append(";\n");
|
||||
}
|
||||
else {
|
||||
buffer.append("if(").append(myParameterName).append("== null || getClass() != ").append(myParameterName)
|
||||
.append(".getClass()) " + "return ").append(returnValue).append(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
private void addEqualsPrologue(@NonNls StringBuffer buffer) {
|
||||
buffer.append("if(this==");
|
||||
buffer.append(myParameterName);
|
||||
buffer.append(") return true;\n");
|
||||
if (!superMethodExists(getEqualsSignature(myProject, myClass.getResolveScope()))) {
|
||||
addInstanceOfToText(buffer, Boolean.toString(false));
|
||||
}
|
||||
else {
|
||||
addInstanceOfToText(buffer, Boolean.toString(false));
|
||||
buffer.append("if(!super.equals(");
|
||||
buffer.append(myParameterName);
|
||||
buffer.append(")) return false;\n");
|
||||
}
|
||||
}
|
||||
|
||||
private void addClassInstance(@NonNls StringBuffer buffer) {
|
||||
buffer.append("\n");
|
||||
// A a = (A) object;
|
||||
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(myCodeStyleManager.getProject());
|
||||
if (settings.GENERATE_FINAL_LOCALS) {
|
||||
buffer.append("final ");
|
||||
}
|
||||
|
||||
buffer.append(myClass.getName());
|
||||
buffer.append(" ").append(myClassInstanceName).append(" = (");
|
||||
buffer.append(myClass.getName());
|
||||
buffer.append(")");
|
||||
buffer.append(myParameterName);
|
||||
buffer.append(";\n\n");
|
||||
}
|
||||
|
||||
|
||||
private boolean superMethodExists(MethodSignature methodSignature) {
|
||||
LOG.assertTrue(myClass.isValid());
|
||||
PsiMethod superEquals = MethodSignatureUtil.findMethodBySignature(myClass, methodSignature, true);
|
||||
@@ -343,173 +182,19 @@ public class GenerateEqualsHelper implements Runnable {
|
||||
if (shouldAddOverrideAnnotation(myClass)) {
|
||||
buffer.append("@Override\n");
|
||||
}
|
||||
buffer.append("public int hashCode() {\n");
|
||||
if (!mySuperHasHashCode && myHashCodeFields.length == 1) {
|
||||
PsiField field = myHashCodeFields[0];
|
||||
final String tempName = addTempForOneField(field, buffer);
|
||||
buffer.append("return ");
|
||||
if (field.getType() instanceof PsiPrimitiveType) {
|
||||
addPrimitiveFieldHashCode(buffer, field, tempName);
|
||||
}
|
||||
else {
|
||||
addFieldHashCode(buffer, field, false);
|
||||
}
|
||||
buffer.append(";\n}");
|
||||
}
|
||||
else if (myHashCodeFields.length > 0) {
|
||||
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(myCodeStyleManager.getProject());
|
||||
final String resultName = getUniqueLocalVarName(settings.LOCAL_VARIABLE_NAME_PREFIX + RESULT_VARIABLE, myHashCodeFields);
|
||||
|
||||
buffer.append("int ");
|
||||
buffer.append(resultName);
|
||||
final HashMap<String, Object> contextMap = new HashMap<String, Object>();
|
||||
contextMap.put("superHasHashCode", mySuperHasHashCode);
|
||||
|
||||
boolean resultAssigned = false;
|
||||
boolean resultDeclarationCompleted = false;
|
||||
if (mySuperHasHashCode) {
|
||||
buffer.append(" = ");
|
||||
addSuperHashCode(buffer);
|
||||
buffer.append(";\n");
|
||||
resultAssigned = true;
|
||||
resultDeclarationCompleted = true;
|
||||
}
|
||||
String tempName = addTempDeclaration(buffer, resultDeclarationCompleted);
|
||||
if (tempName != null) {
|
||||
resultDeclarationCompleted = true;
|
||||
}
|
||||
for (PsiField field : myHashCodeFields) {
|
||||
addTempAssignment(field, buffer, tempName);
|
||||
if (resultDeclarationCompleted) {
|
||||
buffer.append(resultName);
|
||||
}
|
||||
|
||||
buffer.append(" = ");
|
||||
if (resultAssigned) {
|
||||
buffer.append("31*");
|
||||
buffer.append(resultName);
|
||||
buffer.append(" + ");
|
||||
}
|
||||
if (field.getType() instanceof PsiPrimitiveType) {
|
||||
addPrimitiveFieldHashCode(buffer, field, tempName);
|
||||
}
|
||||
else {
|
||||
addFieldHashCode(buffer, field, resultAssigned);
|
||||
}
|
||||
buffer.append(";\n");
|
||||
resultAssigned = true;
|
||||
resultDeclarationCompleted = true;
|
||||
}
|
||||
buffer.append("return ");
|
||||
buffer.append(resultName);
|
||||
buffer.append(";\n}");
|
||||
}
|
||||
else {
|
||||
buffer.append("return 0;\n}");
|
||||
}
|
||||
final String methodText = GenerationUtil
|
||||
.velocityGenerateCode(myClass, Arrays.asList(myHashCodeFields), myNonNullSet, new HashMap<String, String>(), contextMap,
|
||||
EqualsHashCodeTemplatesManager.getInstance().getDefaultHashcodeTemplate().getTemplate(), 0, false);
|
||||
buffer.append(methodText);
|
||||
PsiMethod hashCode = myFactory.createMethodFromText(buffer.toString(), null);
|
||||
hashCode = (PsiMethod)myJavaCodeStyleManager.shortenClassReferences(hashCode);
|
||||
return (PsiMethod)myCodeStyleManager.reformat(hashCode);
|
||||
}
|
||||
|
||||
private static void addTempAssignment(PsiField field, StringBuilder buffer, String tempName) {
|
||||
if (PsiType.DOUBLE.equals(field.getType())) {
|
||||
buffer.append(tempName);
|
||||
addTempForDoubleInitialization(field, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addTempForDoubleInitialization(PsiField field, @NonNls StringBuilder buffer) {
|
||||
buffer.append(" = ");
|
||||
buffer.append("Double.doubleToLongBits(");
|
||||
buffer.append(field.getName());
|
||||
buffer.append(");\n");
|
||||
}
|
||||
|
||||
private String addTempDeclaration(@NonNls StringBuilder buffer, boolean resultDeclarationCompleted) {
|
||||
for (PsiField hashCodeField : myHashCodeFields) {
|
||||
if (PsiType.DOUBLE.equals(hashCodeField.getType())) {
|
||||
final String name = getUniqueLocalVarName(TEMP_VARIABLE, myHashCodeFields);
|
||||
if (!resultDeclarationCompleted) {
|
||||
buffer.append("\n;");
|
||||
}
|
||||
buffer.append("long ");
|
||||
buffer.append(name);
|
||||
buffer.append(";\n");
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("HardCodedStringLiteral")
|
||||
private String addTempForOneField(PsiField field, StringBuilder buffer) {
|
||||
if (PsiType.DOUBLE.equals(field.getType())) {
|
||||
final String name = getUniqueLocalVarName(TEMP_VARIABLE, myHashCodeFields);
|
||||
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(myCodeStyleManager.getProject());
|
||||
if (settings.GENERATE_FINAL_LOCALS) {
|
||||
buffer.append("final ");
|
||||
}
|
||||
buffer.append("long ").append(name);
|
||||
addTempForDoubleInitialization(field, buffer);
|
||||
return name;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void addPrimitiveFieldHashCode(StringBuilder buffer, PsiField field, String tempName) {
|
||||
MessageFormat format = PRIMITIVE_HASHCODE_FORMAT.get(field.getType().getCanonicalText());
|
||||
buffer.append(format.format(new Object[]{field.getName(), tempName}));
|
||||
}
|
||||
|
||||
private void addFieldHashCode(@NonNls StringBuilder buffer, PsiField field, boolean brace) {
|
||||
final String name = field.getName();
|
||||
if (myNonNullSet.contains(field)) {
|
||||
adjustHashCodeToArrays(buffer, field, name);
|
||||
}
|
||||
else {
|
||||
if (brace) {
|
||||
buffer.append("(");
|
||||
}
|
||||
buffer.append(name);
|
||||
buffer.append(" != null ? ");
|
||||
adjustHashCodeToArrays(buffer, field, name);
|
||||
buffer.append(" : 0");
|
||||
if (brace) {
|
||||
buffer.append(")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void adjustHashCodeToArrays(@NonNls StringBuilder buffer, final PsiField field, final String name) {
|
||||
final PsiType fieldType = field.getType();
|
||||
if (fieldType instanceof PsiArrayType &&
|
||||
JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) {
|
||||
if (isNestedArray(fieldType)) {
|
||||
buffer.append(" ");
|
||||
buffer.append("// Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode");
|
||||
buffer.append("\n");
|
||||
}
|
||||
buffer.append("java.util.Arrays.hashCode(");
|
||||
buffer.append(name);
|
||||
buffer.append(")");
|
||||
}
|
||||
else {
|
||||
buffer.append(name);
|
||||
buffer.append(".hashCode()");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("HardCodedStringLiteral")
|
||||
private void addSuperHashCode(StringBuilder buffer) {
|
||||
if (mySuperHasHashCode) {
|
||||
buffer.append("super.hashCode()");
|
||||
}
|
||||
else {
|
||||
buffer.append("0");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void invoke() {
|
||||
ApplicationManager.getApplication().runWriteAction(this);
|
||||
@@ -533,32 +218,6 @@ public class GenerateEqualsHelper implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
initPrimitiveHashcodeFormats();
|
||||
}
|
||||
|
||||
@SuppressWarnings("HardCodedStringLiteral")
|
||||
private static void initPrimitiveHashcodeFormats() {
|
||||
PRIMITIVE_HASHCODE_FORMAT.put("byte", new MessageFormat("(int) {0}"));
|
||||
PRIMITIVE_HASHCODE_FORMAT.put("short", new MessageFormat("(int) {0}"));
|
||||
PRIMITIVE_HASHCODE_FORMAT.put("int", new MessageFormat("{0}"));
|
||||
PRIMITIVE_HASHCODE_FORMAT.put("long", new MessageFormat("(int) ({0} ^ ({0} >>> 32))"));
|
||||
PRIMITIVE_HASHCODE_FORMAT.put("boolean", new MessageFormat("({0} ? 1 : 0)"));
|
||||
|
||||
PRIMITIVE_HASHCODE_FORMAT.put("float", new MessageFormat("({0} != +0.0f ? Float.floatToIntBits({0}) : 0)"));
|
||||
PRIMITIVE_HASHCODE_FORMAT.put("double", new MessageFormat("(int) ({1} ^ ({1} >>> 32))"));
|
||||
|
||||
PRIMITIVE_HASHCODE_FORMAT.put("char", new MessageFormat("(int) {0}"));
|
||||
PRIMITIVE_HASHCODE_FORMAT.put("void", new MessageFormat("0"));
|
||||
PRIMITIVE_HASHCODE_FORMAT.put("void", new MessageFormat("({0} ? 1 : 0)"));
|
||||
}
|
||||
|
||||
public static boolean isNestedArray(PsiType aType) {
|
||||
if (!(aType instanceof PsiArrayType)) return false;
|
||||
final PsiType componentType = ((PsiArrayType)aType).getComponentType();
|
||||
return componentType instanceof PsiArrayType;
|
||||
}
|
||||
|
||||
public static boolean isArrayOfObjects(PsiType aType) {
|
||||
if (!(aType instanceof PsiArrayType)) return false;
|
||||
final PsiType componentType = ((PsiArrayType)aType).getComponentType();
|
||||
|
||||
@@ -1,2 +1,93 @@
|
||||
//todo
|
||||
//equals template to place here
|
||||
#set($classInstanceName = $helper.getUniqueLocalVarName($instanceName, $members, $settings))
|
||||
#set($paramName = $helper.getUniqueLocalVarName($baseParamName, $members, $settings))
|
||||
public boolean equals(##
|
||||
#if ($settings.generateFinalParameters)
|
||||
final ##
|
||||
#end
|
||||
Object $paramName){
|
||||
#addEqualsPrologue()
|
||||
#if ($members.size() > 0)
|
||||
|
||||
#addClassInstance()
|
||||
|
||||
#foreach($field in $members)
|
||||
#if (!$field.static)
|
||||
#if ($field.array)
|
||||
#addArrayEquals($field)
|
||||
#elseif ($field.primitive)
|
||||
#if ($field.double || $field.float)
|
||||
#addDoubleFieldComparison($field)
|
||||
#else
|
||||
#addPrimitiveFieldComparison($field)
|
||||
#end
|
||||
#elseif ($field.enum)
|
||||
#addPrimitiveFieldComparison($field)
|
||||
#else
|
||||
#addFieldComparison($field)
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
|
||||
return true;
|
||||
}
|
||||
##
|
||||
#macro(addClassInstance)
|
||||
#if ($settings.generateFinalLocals)
|
||||
final ##
|
||||
#end
|
||||
$classname $classInstanceName = ($classname)$paramName;
|
||||
#end
|
||||
##
|
||||
#macro(addEqualsPrologue)
|
||||
if(this == $paramName) return true;
|
||||
#if (!$superHasEquals)
|
||||
#addInstanceOfToText()
|
||||
#else
|
||||
#addInstanceOfToText()
|
||||
if(!super.equals($paramName)) return false;
|
||||
#end
|
||||
#end
|
||||
##
|
||||
#macro(addInstanceOfToText)
|
||||
#if ($checkParameterWithInstanceof)
|
||||
if(!($paramName instanceof $classname)) return false;
|
||||
#else
|
||||
if($paramName == null || getClass() != ${paramName}.getClass()) return false;
|
||||
#end
|
||||
#end
|
||||
##
|
||||
#macro(addPrimitiveFieldComparison $field)
|
||||
if($field.name != ${classInstanceName}.$field.name) return false;
|
||||
#end
|
||||
##
|
||||
#macro(addDoubleFieldComparison $field)
|
||||
#if ($field.double)
|
||||
if(Double.compare(${classInstanceName}.$field.name, $field.name) != 0)return false;
|
||||
#else
|
||||
if(Float.compare(${classInstanceName}.$field.name, $field.name) != 0)return false;
|
||||
#end
|
||||
#end
|
||||
##
|
||||
#macro(addFieldComparison $field)
|
||||
#if ($field.notNull)
|
||||
if(!${field.name}.equals(${classInstanceName}.$field.name))return false;
|
||||
#else
|
||||
if($field.name != null ? !${field.name}.equals(${classInstanceName}.$field.name) : ${classInstanceName}.$field.name != null)return false;
|
||||
#end
|
||||
#end
|
||||
##
|
||||
#macro(addArrayEquals $field)
|
||||
#if ($field.nestedArray)
|
||||
#if ($java_version > 4)
|
||||
if(!java.util.Arrays.deepEquals($field.name, ${classInstanceName}.$field.name)) return false;
|
||||
#else
|
||||
// Compare nested arrays - values of $field.name here
|
||||
#end
|
||||
#break;
|
||||
#end
|
||||
#if ($field.objectArray)
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
#end
|
||||
if(!java.util.Arrays.equals($field.name, ${classInstanceName}.$field.name)) return false;
|
||||
#end
|
||||
@@ -1,2 +1,130 @@
|
||||
//todo
|
||||
//hashCode template to place here
|
||||
public int hashCode() {
|
||||
#if (!$superHasHashCode && $members.size() == 1)
|
||||
#set($field = $members.get(0))
|
||||
#if ($field.primitive)
|
||||
#addTempForOneField($field)
|
||||
return #addPrimitiveFieldHashCode($field);
|
||||
#else
|
||||
return #addFieldHashCode($field, false);
|
||||
#end
|
||||
#elseif ($members.size() > 0)
|
||||
#set($resultName = $helper.getUniqueLocalVarName("result", $members, $settings))
|
||||
int $resultName ##
|
||||
#set($resultAssigned = false)
|
||||
#set($resultDeclarationCompleted = false)
|
||||
#if ($superHasHashCode)
|
||||
= #addSuperHashCode();
|
||||
#set($resultAssigned = true)
|
||||
#set($resultDeclarationCompleted = true)
|
||||
#end
|
||||
#addTempDeclaration($resultDeclarationCompleted)
|
||||
#set($tempName = "#addTempDeclaration($resultDeclarationCompleted)")
|
||||
#foreach($field in $members)
|
||||
#addTempAssignment($field)
|
||||
#if ($resultDeclarationCompleted)
|
||||
$resultName ##
|
||||
#end
|
||||
= ##
|
||||
#if ($resultAssigned)
|
||||
31 * $resultName + ##
|
||||
#end
|
||||
#if ($field.primitive)
|
||||
#addPrimitiveFieldHashCode($field)##
|
||||
#else
|
||||
#addFieldHashCode($field, $resultAssigned)##
|
||||
#end
|
||||
;
|
||||
#set($resultAssigned = true)
|
||||
#set($resultDeclarationCompleted = true)
|
||||
#end
|
||||
return $resultName;
|
||||
#else
|
||||
return 0;
|
||||
#end
|
||||
}
|
||||
##
|
||||
#macro (addPrimitiveFieldHashCode $field)
|
||||
#set ($fName = $field.name)
|
||||
#if ($field.byte || $field.short || $field.char)
|
||||
(int) $fName##
|
||||
#elseif ($field.long)
|
||||
(int)($fName ^ ($fName >>> 32))##
|
||||
#elseif ($field.boolean)
|
||||
($fName ? 1 : 0)##
|
||||
#elseif ($field.float)
|
||||
($fName != +0.0f ? Float.floatToIntBits($fName) : 0)##
|
||||
#elseif ($field.double)
|
||||
#set($tempName = "#getTempVarName()")
|
||||
(int) ($tempName ^ ($tempName >>> 32))##
|
||||
#elseif ($field.void)
|
||||
0##
|
||||
#else
|
||||
$fName##
|
||||
#end
|
||||
#end
|
||||
##
|
||||
#macro(getTempVarName)
|
||||
$helper.getUniqueLocalVarName("temp", $members, $settings)##
|
||||
#end
|
||||
##
|
||||
#macro(addTempForOneField $field)
|
||||
#if ($field.double)
|
||||
#if ($settings.generateFinalLocals)
|
||||
final ##
|
||||
#end
|
||||
#set($tempName = "#getTempVarName()")
|
||||
long $tempName = Double.doubleToLongBits($field.name);
|
||||
#end
|
||||
#end
|
||||
##
|
||||
#macro(adjustHashCodeToArrays $field)
|
||||
#if ($field.array && $java_version > 4)
|
||||
#if ($field.nestedArray)
|
||||
// Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
#end
|
||||
java.util.Arrays.hashCode($field.name)##
|
||||
#else
|
||||
${field.name}.hashCode()##
|
||||
#end
|
||||
#end
|
||||
##
|
||||
#macro(addSuperHashCode)
|
||||
#if ($superHasHashCode)
|
||||
super.hashCode()##
|
||||
#else
|
||||
0##
|
||||
#end
|
||||
#end
|
||||
##
|
||||
#macro(addTempDeclaration $resultDeclarationCompleted)
|
||||
#foreach($member in $members)
|
||||
#if ($member.double)
|
||||
#if (!$resultDeclarationCompleted)
|
||||
;
|
||||
#end
|
||||
#set($tempName = "#getTempVarName()")
|
||||
long $tempName;
|
||||
#set($resultDeclarationCompleted = true)
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
##
|
||||
#macro(addTempAssignment $field)
|
||||
#if ($field.double)
|
||||
#set($tempName = "#getTempVarName()")
|
||||
$tempName = Double.doubleToLongBits($field.name);
|
||||
#end
|
||||
#end
|
||||
##
|
||||
#macro(addFieldHashCode $field $brace)
|
||||
#set($name = $field.name)
|
||||
#if ($field.notNull)#adjustHashCodeToArrays($field)
|
||||
#else
|
||||
#if ($brace)(##
|
||||
#end
|
||||
$name != null ? #adjustHashCodeToArrays($field) : 0##
|
||||
#if ($brace))##
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.ui.VerticalFlowLayout;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.classMembers.AbstractMemberInfoModel;
|
||||
import com.intellij.refactoring.classMembers.MemberInfoBase;
|
||||
import com.intellij.refactoring.classMembers.MemberInfoTooltipManager;
|
||||
@@ -36,6 +35,7 @@ import com.intellij.refactoring.util.classMembers.MemberInfo;
|
||||
import com.intellij.ui.NonFocusableCheckBox;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.java.generate.psi.PsiAdapter;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
@@ -269,7 +269,7 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
|
||||
final PsiField field = (PsiField)memberInfo.getMember();
|
||||
if (!JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) {
|
||||
final PsiType type = field.getType();
|
||||
if (GenerateEqualsHelper.isNestedArray(type)) {
|
||||
if (PsiAdapter.isNestedArray(type)) {
|
||||
return CodeInsightBundle .message("generate.equals.warning.equals.for.nested.arrays.not.supported");
|
||||
}
|
||||
if (GenerateEqualsHelper.isArrayOfObjects(type)) {
|
||||
@@ -285,7 +285,7 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
|
||||
if (!(member.getMember() instanceof PsiField)) return false;
|
||||
final PsiField field = (PsiField)member.getMember();
|
||||
final PsiType type = field.getType();
|
||||
return JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5) || !GenerateEqualsHelper.isNestedArray(type);
|
||||
return JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5) || !PsiAdapter.isNestedArray(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -294,7 +294,7 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
|
||||
final PsiField field = (PsiField)member.getMember();
|
||||
final PsiType type = field.getType();
|
||||
if (!JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) {
|
||||
if (GenerateEqualsHelper.isNestedArray(type)) return ERROR;
|
||||
if (PsiAdapter.isNestedArray(type)) return ERROR;
|
||||
if (GenerateEqualsHelper.isArrayOfObjects(type)) return WARNING;
|
||||
}
|
||||
return OK;
|
||||
|
||||
@@ -21,7 +21,7 @@ class Test {
|
||||
|
||||
public int hashCode() {
|
||||
int result = myOs != null ? Arrays.hashCode(myOs) : 0;
|
||||
result = 31 * result + (myIIs != null ? // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
result = 31 * result + (myIIs != null ? // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(myIIs) : 0);
|
||||
result = 31 * result + (myIs != null ? Arrays.hashCode(myIs) : 0);
|
||||
return result;
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
class A {
|
||||
Object[] a1;
|
||||
Object[][] a2;
|
||||
String[] a3;
|
||||
String[][] a4;
|
||||
int[] a5;
|
||||
int[][] a6;
|
||||
|
||||
byte a7;
|
||||
short a8;
|
||||
int a9;
|
||||
long a10;
|
||||
float a11;
|
||||
double a12;
|
||||
|
||||
Object a13;
|
||||
String a14;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final A a = (A) o;
|
||||
|
||||
if (a10 != a.a10) return false;
|
||||
if (Float.compare(a.a11, a11) != 0) return false;
|
||||
if (Double.compare(a.a12, a12) != 0) return false;
|
||||
if (a7 != a.a7) return false;
|
||||
if (a8 != a.a8) return false;
|
||||
if (a9 != a.a9) return false;
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(a1, a.a1)) return false;
|
||||
if (a13 != null ? !a13.equals(a.a13) : a.a13 != null) return false;
|
||||
if (a14 != null ? !a14.equals(a.a14) : a.a14 != null) return false;
|
||||
if (!Arrays.deepEquals(a2, a.a2)) return false;
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(a3, a.a3)) return false;
|
||||
if (!Arrays.deepEquals(a4, a.a4)) return false;
|
||||
if (!Arrays.equals(a5, a.a5)) return false;
|
||||
if (!Arrays.deepEquals(a6, a.a6)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
long temp;
|
||||
result = a1 != null ? Arrays.hashCode(a1) : 0;
|
||||
result = 31 * result + (a2 != null ? // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a2) : 0);
|
||||
result = 31 * result + (a3 != null ? Arrays.hashCode(a3) : 0);
|
||||
result = 31 * result + (a4 != null ? // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a4) : 0);
|
||||
result = 31 * result + (a5 != null ? Arrays.hashCode(a5) : 0);
|
||||
result = 31 * result + (a6 != null ? // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a6) : 0);
|
||||
result = 31 * result + (int) a7;
|
||||
result = 31 * result + (int) a8;
|
||||
result = 31 * result + a9;
|
||||
result = 31 * result + (int) (a10 ^ (a10 >>> 32));
|
||||
result = 31 * result + (a11 != +0.0f ? Float.floatToIntBits(a11) : 0);
|
||||
temp = Double.doubleToLongBits(a12);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
result = 31 * result + (a13 != null ? a13.hashCode() : 0);
|
||||
result = 31 * result + (a14 != null ? a14.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
class A {
|
||||
Object[] a1;
|
||||
Object[][] a2;
|
||||
String[] a3;
|
||||
String[][] a4;
|
||||
int[] a5;
|
||||
int[][] a6;
|
||||
|
||||
byte a7;
|
||||
short a8;
|
||||
int a9;
|
||||
long a10;
|
||||
float a11;
|
||||
double a12;
|
||||
|
||||
Object a13;
|
||||
String a14;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final A a = (A) o;
|
||||
|
||||
if (a10 != a.a10) return false;
|
||||
if (Float.compare(a.a11, a11) != 0) return false;
|
||||
if (Double.compare(a.a12, a12) != 0) return false;
|
||||
if (a7 != a.a7) return false;
|
||||
if (a8 != a.a8) return false;
|
||||
if (a9 != a.a9) return false;
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(a1, a.a1)) return false;
|
||||
if (!a13.equals(a.a13)) return false;
|
||||
if (!a14.equals(a.a14)) return false;
|
||||
if (!Arrays.deepEquals(a2, a.a2)) return false;
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(a3, a.a3)) return false;
|
||||
if (!Arrays.deepEquals(a4, a.a4)) return false;
|
||||
if (!Arrays.equals(a5, a.a5)) return false;
|
||||
if (!Arrays.deepEquals(a6, a.a6)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
long temp;
|
||||
result = Arrays.hashCode(a1);
|
||||
result = 31 * result + // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a2);
|
||||
result = 31 * result + Arrays.hashCode(a3);
|
||||
result = 31 * result + // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a4);
|
||||
result = 31 * result + Arrays.hashCode(a5);
|
||||
result = 31 * result + // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a6);
|
||||
result = 31 * result + (int) a7;
|
||||
result = 31 * result + (int) a8;
|
||||
result = 31 * result + a9;
|
||||
result = 31 * result + (int) (a10 ^ (a10 >>> 32));
|
||||
result = 31 * result + (a11 != +0.0f ? Float.floatToIntBits(a11) : 0);
|
||||
temp = Double.doubleToLongBits(a12);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
result = 31 * result + a13.hashCode();
|
||||
result = 31 * result + a14.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
class A {
|
||||
Object[] a1;
|
||||
Object[][] a2;
|
||||
String[] a3;
|
||||
String[][] a4;
|
||||
int[] a5;
|
||||
int[][] a6;
|
||||
|
||||
byte a7;
|
||||
short a8;
|
||||
int a9;
|
||||
long a10;
|
||||
float a11;
|
||||
|
||||
Object a13;
|
||||
String a14;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final A a = (A) o;
|
||||
|
||||
if (a10 != a.a10) return false;
|
||||
if (Float.compare(a.a11, a11) != 0) return false;
|
||||
if (a7 != a.a7) return false;
|
||||
if (a8 != a.a8) return false;
|
||||
if (a9 != a.a9) return false;
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(a1, a.a1)) return false;
|
||||
if (!a13.equals(a.a13)) return false;
|
||||
if (!a14.equals(a.a14)) return false;
|
||||
if (!Arrays.deepEquals(a2, a.a2)) return false;
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(a3, a.a3)) return false;
|
||||
if (!Arrays.deepEquals(a4, a.a4)) return false;
|
||||
if (!Arrays.equals(a5, a.a5)) return false;
|
||||
if (!Arrays.deepEquals(a6, a.a6)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = Arrays.hashCode(a1);
|
||||
result = 31 * result + // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a2);
|
||||
result = 31 * result + Arrays.hashCode(a3);
|
||||
result = 31 * result + // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a4);
|
||||
result = 31 * result + Arrays.hashCode(a5);
|
||||
result = 31 * result + // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a6);
|
||||
result = 31 * result + (int) a7;
|
||||
result = 31 * result + (int) a8;
|
||||
result = 31 * result + a9;
|
||||
result = 31 * result + (int) (a10 ^ (a10 >>> 32));
|
||||
result = 31 * result + (a11 != +0.0f ? Float.floatToIntBits(a11) : 0);
|
||||
result = 31 * result + a13.hashCode();
|
||||
result = 31 * result + a14.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
class B {
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
}
|
||||
class A extends B {
|
||||
Object[] a1;
|
||||
Object[][] a2;
|
||||
String[] a3;
|
||||
String[][] a4;
|
||||
int[] a5;
|
||||
int[][] a6;
|
||||
|
||||
byte a7;
|
||||
short a8;
|
||||
int a9;
|
||||
long a10;
|
||||
float a11;
|
||||
double a12;
|
||||
|
||||
Object a13;
|
||||
String a14;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
|
||||
final A a = (A) o;
|
||||
|
||||
if (a10 != a.a10) return false;
|
||||
if (Float.compare(a.a11, a11) != 0) return false;
|
||||
if (Double.compare(a.a12, a12) != 0) return false;
|
||||
if (a7 != a.a7) return false;
|
||||
if (a8 != a.a8) return false;
|
||||
if (a9 != a.a9) return false;
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(a1, a.a1)) return false;
|
||||
if (!a13.equals(a.a13)) return false;
|
||||
if (!a14.equals(a.a14)) return false;
|
||||
if (!Arrays.deepEquals(a2, a.a2)) return false;
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(a3, a.a3)) return false;
|
||||
if (!Arrays.deepEquals(a4, a.a4)) return false;
|
||||
if (!Arrays.equals(a5, a.a5)) return false;
|
||||
if (!Arrays.deepEquals(a6, a.a6)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
long temp;
|
||||
result = 31 * result + Arrays.hashCode(a1);
|
||||
result = 31 * result + // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a2);
|
||||
result = 31 * result + Arrays.hashCode(a3);
|
||||
result = 31 * result + // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a4);
|
||||
result = 31 * result + Arrays.hashCode(a5);
|
||||
result = 31 * result + // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a6);
|
||||
result = 31 * result + (int) a7;
|
||||
result = 31 * result + (int) a8;
|
||||
result = 31 * result + a9;
|
||||
result = 31 * result + (int) (a10 ^ (a10 >>> 32));
|
||||
result = 31 * result + (a11 != +0.0f ? Float.floatToIntBits(a11) : 0);
|
||||
temp = Double.doubleToLongBits(a12);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
result = 31 * result + a13.hashCode();
|
||||
result = 31 * result + a14.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
class A {
|
||||
Object[] a1;
|
||||
Object[][] a2;
|
||||
String[] a3;
|
||||
String[][] a4;
|
||||
int[] a5;
|
||||
int[][] a6;
|
||||
|
||||
byte a7;
|
||||
short a8;
|
||||
int a9;
|
||||
long a10;
|
||||
float a11;
|
||||
double temp;
|
||||
|
||||
Object result;
|
||||
String a14;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final A a = (A) o;
|
||||
|
||||
if (a10 != a.a10) return false;
|
||||
if (Float.compare(a.a11, a11) != 0) return false;
|
||||
if (a7 != a.a7) return false;
|
||||
if (a8 != a.a8) return false;
|
||||
if (a9 != a.a9) return false;
|
||||
if (Double.compare(a.temp, temp) != 0) return false;
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(a1, a.a1)) return false;
|
||||
if (!a14.equals(a.a14)) return false;
|
||||
if (!Arrays.deepEquals(a2, a.a2)) return false;
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(a3, a.a3)) return false;
|
||||
if (!Arrays.deepEquals(a4, a.a4)) return false;
|
||||
if (!Arrays.equals(a5, a.a5)) return false;
|
||||
if (!Arrays.deepEquals(a6, a.a6)) return false;
|
||||
if (!result.equals(a.result)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result1;
|
||||
long temp1;
|
||||
result1 = Arrays.hashCode(a1);
|
||||
result1 = 31 * result1 + // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a2);
|
||||
result1 = 31 * result1 + Arrays.hashCode(a3);
|
||||
result1 = 31 * result1 + // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a4);
|
||||
result1 = 31 * result1 + Arrays.hashCode(a5);
|
||||
result1 = 31 * result1 + // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(a6);
|
||||
result1 = 31 * result1 + (int) a7;
|
||||
result1 = 31 * result1 + (int) a8;
|
||||
result1 = 31 * result1 + a9;
|
||||
result1 = 31 * result1 + (int) (a10 ^ (a10 >>> 32));
|
||||
result1 = 31 * result1 + (a11 != +0.0f ? Float.floatToIntBits(a11) : 0);
|
||||
temp1 = Double.doubleToLongBits(temp);
|
||||
result1 = 31 * result1 + (int) (temp1 ^ (temp1 >>> 32));
|
||||
result1 = 31 * result1 + result.hashCode();
|
||||
result1 = 31 * result1 + a14.hashCode();
|
||||
return result1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
class A {
|
||||
Object[] a1;
|
||||
Object[][] a2;
|
||||
String[] a3;
|
||||
String[][] a4;
|
||||
int[] a5;
|
||||
int[][] a6;
|
||||
|
||||
byte a7;
|
||||
short a8;
|
||||
int a9;
|
||||
long a10;
|
||||
float a11;
|
||||
double a12;
|
||||
|
||||
Object a13;
|
||||
String a14;
|
||||
|
||||
<caret>
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
|
||||
class A {
|
||||
Object[] a1;
|
||||
Object[][] a2;
|
||||
String[] a3;
|
||||
String[][] a4;
|
||||
int[] a5;
|
||||
int[][] a6;
|
||||
|
||||
byte a7;
|
||||
short a8;
|
||||
int a9;
|
||||
long a10;
|
||||
float a11;
|
||||
double a12;
|
||||
|
||||
Object a13;
|
||||
String a14;
|
||||
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
class A {
|
||||
Object[] a1;
|
||||
Object[][] a2;
|
||||
String[] a3;
|
||||
String[][] a4;
|
||||
int[] a5;
|
||||
int[][] a6;
|
||||
|
||||
byte a7;
|
||||
short a8;
|
||||
int a9;
|
||||
long a10;
|
||||
float a11;
|
||||
|
||||
Object a13;
|
||||
String a14;
|
||||
|
||||
<caret>
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
class B {
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
}
|
||||
class A extends B {
|
||||
Object[] a1;
|
||||
Object[][] a2;
|
||||
String[] a3;
|
||||
String[][] a4;
|
||||
int[] a5;
|
||||
int[][] a6;
|
||||
|
||||
byte a7;
|
||||
short a8;
|
||||
int a9;
|
||||
long a10;
|
||||
float a11;
|
||||
double a12;
|
||||
|
||||
Object a13;
|
||||
String a14;
|
||||
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
class A {
|
||||
Object[] a1;
|
||||
Object[][] a2;
|
||||
String[] a3;
|
||||
String[][] a4;
|
||||
int[] a5;
|
||||
int[][] a6;
|
||||
|
||||
byte a7;
|
||||
short a8;
|
||||
int a9;
|
||||
long a10;
|
||||
float a11;
|
||||
double temp;
|
||||
|
||||
Object result;
|
||||
String a14;
|
||||
|
||||
<caret>
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.util.Function;
|
||||
|
||||
/**
|
||||
* @author dsl
|
||||
*/
|
||||
@@ -7,4 +10,31 @@ public class GenerateEquals15Test extends GenerateEqualsTestCase {
|
||||
public void testArraysFromJava15() throws Exception {
|
||||
doTest(new int[]{0, 1, 2}, new int[]{0, 1, 2}, new int[0], false);
|
||||
}
|
||||
|
||||
public void testDifferentTypes() throws Exception {
|
||||
doTest(Function.ID, Function.ID, new Function<PsiField[], PsiField[]>() {
|
||||
@Override
|
||||
public PsiField[] fun(PsiField[] fields) {
|
||||
return new PsiField[0];
|
||||
}
|
||||
}, true
|
||||
);
|
||||
}
|
||||
|
||||
public void testDifferentTypesAllNotNull() throws Exception {
|
||||
doTest(Function.ID, Function.ID, Function.ID, true);
|
||||
}
|
||||
|
||||
public void testDifferentTypesSuperEqualsAndHashCode() throws Exception {
|
||||
doTest(Function.ID, Function.ID, Function.ID, true);
|
||||
}
|
||||
|
||||
public void testDifferentTypesNoDouble() throws Exception {
|
||||
doTest(Function.ID, Function.ID, Function.ID, true);
|
||||
}
|
||||
|
||||
public void testNameConflicts() throws Exception {
|
||||
doTest(Function.ID, Function.ID, Function.ID, true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||
import com.intellij.util.Function;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -16,13 +17,38 @@ import java.util.ArrayList;
|
||||
* @author yole
|
||||
*/
|
||||
public abstract class GenerateEqualsTestCase extends LightCodeInsightTestCase {
|
||||
protected void doTest(int[] equals, int[] hashCode, int[] nonNull, boolean insertOverride) throws Exception {
|
||||
protected void doTest(final int[] equals,
|
||||
final int[] hashCode,
|
||||
final int[] nonNull,
|
||||
boolean insertOverride) throws Exception {
|
||||
doTest(new Function<PsiField[], PsiField[]>() {
|
||||
@Override
|
||||
public PsiField[] fun(PsiField[] fields) {
|
||||
return getIndexed(fields, equals);
|
||||
}
|
||||
}, new Function<PsiField[], PsiField[]>() {
|
||||
@Override
|
||||
public PsiField[] fun(PsiField[] fields) {
|
||||
return getIndexed(fields, hashCode);
|
||||
}
|
||||
}, new Function<PsiField[], PsiField[]>() {
|
||||
@Override
|
||||
public PsiField[] fun(PsiField[] fields) {
|
||||
return getIndexed(fields, nonNull);
|
||||
}
|
||||
}, insertOverride);
|
||||
}
|
||||
|
||||
protected void doTest(Function<PsiField[], PsiField[]> eqFunction,
|
||||
Function<PsiField[], PsiField[]> hFunction,
|
||||
Function<PsiField[], PsiField[]> nnFunction,
|
||||
boolean insertOverride) throws Exception {
|
||||
configureByFile("/codeInsight/generateEquals/before" + getTestName(false) + ".java");
|
||||
performTest(equals, hashCode, nonNull, insertOverride);
|
||||
performTest(eqFunction, hFunction, nnFunction, insertOverride);
|
||||
checkResultByFile("/codeInsight/generateEquals/after" + getTestName(false) + ".java");
|
||||
}
|
||||
|
||||
private static void performTest(int[] equals, int[] hashCode, int[] nonNull, boolean insertOverride) {
|
||||
private static void performTest(Function<PsiField[], PsiField[]> equals, Function<PsiField[], PsiField[]> hashCode, Function<PsiField[], PsiField[]> nonNull, boolean insertOverride) {
|
||||
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()).clone();
|
||||
settings.GENERATE_FINAL_LOCALS = true;
|
||||
settings.INSERT_OVERRIDE_ANNOTATION = insertOverride;
|
||||
@@ -33,9 +59,7 @@ public abstract class GenerateEqualsTestCase extends LightCodeInsightTestCase {
|
||||
PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
if (aClass == null) return;
|
||||
PsiField[] fields = aClass.getFields();
|
||||
new GenerateEqualsHelper(getProject(), aClass, getIndexed(fields, equals), getIndexed(fields, hashCode), getIndexed(fields, nonNull),
|
||||
false)
|
||||
.invoke();
|
||||
new GenerateEqualsHelper(getProject(), aClass, equals.fun(fields), hashCode.fun(fields), nonNull.fun(fields), false).invoke();
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
}
|
||||
finally {
|
||||
|
||||
@@ -765,6 +765,18 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
|
||||
return getIndentOptions(fileType).USE_TAB_CHARACTER;
|
||||
}
|
||||
|
||||
//used in generate equals/hashCode
|
||||
@SuppressWarnings("unused")
|
||||
public boolean isGenerateFinalLocals() {
|
||||
return GENERATE_FINAL_LOCALS;
|
||||
}
|
||||
|
||||
//used in generate equals/hashCode
|
||||
@SuppressWarnings("unused")
|
||||
public boolean isGenerateFinalParameters() {
|
||||
return GENERATE_FINAL_PARAMETERS;
|
||||
}
|
||||
|
||||
public static class TypeToNameMap implements JDOMExternalizable {
|
||||
private final List<String> myPatterns = new ArrayList<String>();
|
||||
private final List<String> myNames = new ArrayList<String>();
|
||||
|
||||
@@ -21,11 +21,11 @@ import com.intellij.codeInsight.generation.PsiMethodMember;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -119,14 +119,16 @@ public class GenerationUtil {
|
||||
|
||||
/**
|
||||
* Generates the code using Velocity.
|
||||
* <p/>
|
||||
* <p>
|
||||
* This is used to create the <code>toString</code> method body and it's javadoc.
|
||||
*
|
||||
* @param selectedMembers the selected members as both {@link com.intellij.psi.PsiField} and {@link com.intellij.psi.PsiMethod}.
|
||||
* @param params additional parameters stored with key/value in the map.
|
||||
* @param templateMacro the velocity macro template
|
||||
* @return code (usually javacode). Returns null if templateMacro is null.
|
||||
* @throws org.jetbrains.java.generate.exception.GenerateCodeException is thrown when there is an error generating the javacode.
|
||||
* @param clazz
|
||||
* @param selectedMembers the selected members as both {@link PsiField} and {@link PsiMethod}.
|
||||
* @param params additional parameters stored with key/value in the map.
|
||||
* @param templateMacro the velocity macro template
|
||||
* @param sortElements
|
||||
* @param useFullyQualifiedName @return code (usually javacode). Returns null if templateMacro is null.
|
||||
* @throws GenerateCodeException is thrown when there is an error generating the javacode.
|
||||
*/
|
||||
public static String velocityGenerateCode(PsiClass clazz,
|
||||
Collection<? extends PsiMember> selectedMembers,
|
||||
@@ -135,6 +137,29 @@ public class GenerationUtil {
|
||||
int sortElements,
|
||||
boolean useFullyQualifiedName)
|
||||
throws GenerateCodeException {
|
||||
return velocityGenerateCode(clazz, selectedMembers, Collections.<PsiMember>emptyList(), params, Collections.<String, Object>emptyMap(), templateMacro, sortElements, useFullyQualifiedName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the code using Velocity.
|
||||
* <p/>
|
||||
* This is used to create the <code>toString</code> method body and it's javadoc.
|
||||
*
|
||||
* @param selectedMembers the selected members as both {@link PsiField} and {@link PsiMethod}.
|
||||
* @param params additional parameters stored with key/value in the map.
|
||||
* @param templateMacro the velocity macro template
|
||||
* @return code (usually javacode). Returns null if templateMacro is null.
|
||||
* @throws GenerateCodeException is thrown when there is an error generating the javacode.
|
||||
*/
|
||||
public static String velocityGenerateCode(PsiClass clazz,
|
||||
Collection<? extends PsiMember> selectedMembers,
|
||||
Collection<? extends PsiMember> selectedNotNullMembers,
|
||||
Map<String, String> params,
|
||||
Map<String, Object> contextMap,
|
||||
String templateMacro,
|
||||
int sortElements,
|
||||
boolean useFullyQualifiedName)
|
||||
throws GenerateCodeException {
|
||||
if (templateMacro == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -155,7 +180,7 @@ public class GenerationUtil {
|
||||
|
||||
// element information (both fields and methods)
|
||||
logger.debug("Velocity Context - adding members (fields and methods)");
|
||||
List<Element> elements = ElementUtils.getOnlyAsFieldAndMethodElements(selectedMembers);
|
||||
List<Element> elements = ElementUtils.getOnlyAsFieldAndMethodElements(selectedMembers, selectedNotNullMembers);
|
||||
// sort elements if enabled and not using chooser dialog
|
||||
if (sortElements != 0) {
|
||||
Collections.sort(elements, new ElementComparator(sortElements));
|
||||
@@ -171,6 +196,11 @@ public class GenerationUtil {
|
||||
vc.put("classname", useFullyQualifiedName ? ce.getQualifiedName() : ce.getName());
|
||||
vc.put("FQClassname", ce.getQualifiedName());
|
||||
vc.put("settings", CodeStyleSettingsManager.getSettings(clazz.getProject()));
|
||||
vc.put("helper", GenerationHelper.class);
|
||||
|
||||
for (String paramName : contextMap.keySet()) {
|
||||
vc.put(paramName, contextMap.get(paramName));
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) logger.debug("Velocity Macro:\n" + templateMacro);
|
||||
|
||||
|
||||
+22
-2
@@ -53,8 +53,10 @@ public abstract class AbstractElement implements Element {
|
||||
protected boolean isModifierPackageLocal;
|
||||
protected boolean isModifierPrivate;
|
||||
protected boolean isModifierFinal;
|
||||
private boolean isNotNull;
|
||||
private boolean isNestedArray;
|
||||
|
||||
public String getName() {
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -62,6 +64,15 @@ public abstract class AbstractElement implements Element {
|
||||
return isArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNestedArray() {
|
||||
return isNestedArray;
|
||||
}
|
||||
|
||||
public void setNestedArray(boolean isNestedArray) {
|
||||
this.isNestedArray = isNestedArray;
|
||||
}
|
||||
|
||||
public boolean isCollection() {
|
||||
return isCollection;
|
||||
}
|
||||
@@ -158,7 +169,16 @@ public abstract class AbstractElement implements Element {
|
||||
return isVoid;
|
||||
}
|
||||
|
||||
public void setVoid(boolean isVoid) {
|
||||
@Override
|
||||
public boolean isNotNull() {
|
||||
return isNotNull;
|
||||
}
|
||||
|
||||
public void setNotNull(boolean isNotNull) {
|
||||
this.isNotNull = isNotNull;
|
||||
}
|
||||
|
||||
public void setVoid(boolean isVoid) {
|
||||
this.isVoid = isVoid;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ public interface Element {
|
||||
*/
|
||||
boolean isArray();
|
||||
|
||||
boolean isNestedArray();
|
||||
|
||||
/**
|
||||
* Is this element a {@link java.util.Collection} type (isAssignableFrom java.util.Collection)
|
||||
*
|
||||
@@ -153,6 +155,7 @@ public interface Element {
|
||||
boolean isDouble();
|
||||
boolean isByte();
|
||||
boolean isVoid();
|
||||
boolean isNotNull();
|
||||
|
||||
/**
|
||||
* Get's the elements type classname (etc. Object, String, List)
|
||||
|
||||
+1
-1
@@ -177,7 +177,7 @@ public class ElementFactory {
|
||||
if (PsiType.BYTE.equals(type)) element.setByte(true);
|
||||
if (PsiType.CHAR.equals(type)) element.setChar(true);
|
||||
if (PsiType.SHORT.equals(type)) element.setShort(true);
|
||||
|
||||
element.setNestedArray(PsiAdapter.isNestedArray(type));
|
||||
// modifiers
|
||||
if (modifiers != null) {
|
||||
if (modifiers.hasModifierProperty(PsiModifier.STATIC)) element.setModifierStatic(true);
|
||||
|
||||
+14
-8
@@ -73,21 +73,27 @@ public class ElementUtils {
|
||||
/**
|
||||
* Gets the list of members to be put in the VelocityContext.
|
||||
*
|
||||
* @param members a list of {@link com.intellij.psi.PsiMember} objects.
|
||||
* @param members a list of {@link PsiMember} objects.
|
||||
* @param selectedNotNullMembers a list of @NotNull objects
|
||||
* @return a filtered list of only the methods as a {@link FieldElement} or {@link MethodElement} objects.
|
||||
*/
|
||||
public static List<Element> getOnlyAsFieldAndMethodElements(Collection<? extends PsiMember> members) {
|
||||
public static List<Element> getOnlyAsFieldAndMethodElements(Collection<? extends PsiMember> members,
|
||||
Collection<? extends PsiMember> selectedNotNullMembers) {
|
||||
List<Element> elementList = new ArrayList<Element>();
|
||||
|
||||
for (PsiMember member : members) {
|
||||
AbstractElement element = null;
|
||||
if (member instanceof PsiField) {
|
||||
PsiField field = (PsiField) member;
|
||||
FieldElement fe = ElementFactory.newFieldElement(field);
|
||||
elementList.add(fe);
|
||||
element = ElementFactory.newFieldElement((PsiField) member);
|
||||
} else if (member instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod) member;
|
||||
MethodElement me = ElementFactory.newMethodElement(method);
|
||||
elementList.add(me);
|
||||
element = ElementFactory.newMethodElement((PsiMethod) member);
|
||||
}
|
||||
|
||||
if (element != null) {
|
||||
if (selectedNotNullMembers.contains(member)) {
|
||||
element.setNotNull(true);
|
||||
}
|
||||
elementList.add(element);
|
||||
}
|
||||
}
|
||||
return elementList;
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.java.generate.element;
|
||||
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GenerationHelper {
|
||||
|
||||
//used in generate equals/hashCode
|
||||
@SuppressWarnings("unused")
|
||||
public static String getUniqueLocalVarName(String base, List<Element> elements, CodeStyleSettings settings) {
|
||||
base = settings.LOCAL_VARIABLE_NAME_PREFIX + base;
|
||||
String id = base;
|
||||
int index = 0;
|
||||
while (true) {
|
||||
if (index > 0) {
|
||||
id = base + index;
|
||||
}
|
||||
index++;
|
||||
boolean anyEqual = false;
|
||||
for (Element equalsField : elements) {
|
||||
if (id.equals(equalsField.getName())) {
|
||||
anyEqual = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!anyEqual) break;
|
||||
}
|
||||
|
||||
|
||||
return id;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user