Package org.eclipse.xtend.lib.annotations

Source Code of org.eclipse.xtend.lib.annotations.EqualsHashCodeProcessor$Util

package org.eclipse.xtend.lib.annotations;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Objects;
import org.eclipse.xtend.lib.annotations.Data;
import org.eclipse.xtend.lib.annotations.EqualsHashCode;
import org.eclipse.xtend.lib.macro.AbstractClassProcessor;
import org.eclipse.xtend.lib.macro.TransformationContext;
import org.eclipse.xtend.lib.macro.declaration.AnnotationReference;
import org.eclipse.xtend.lib.macro.declaration.ClassDeclaration;
import org.eclipse.xtend.lib.macro.declaration.Element;
import org.eclipse.xtend.lib.macro.declaration.FieldDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MethodDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MutableMethodDeclaration;
import org.eclipse.xtend.lib.macro.declaration.ParameterDeclaration;
import org.eclipse.xtend.lib.macro.declaration.Type;
import org.eclipse.xtend.lib.macro.declaration.TypeParameterDeclaration;
import org.eclipse.xtend.lib.macro.declaration.TypeReference;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtend2.lib.StringConcatenationClient;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.eclipse.xtext.xbase.lib.Pure;

/**
* @since 2.7
*/
@Beta
@GwtCompatible
@SuppressWarnings("all")
public class EqualsHashCodeProcessor extends AbstractClassProcessor {
  /**
   * @since 2.7
   */
  @Beta
  @GwtCompatible
  public static class Util {
    @Extension
    private TransformationContext context;
   
    public Util(final TransformationContext context) {
      this.context = context;
    }
   
    public boolean hasHashCode(final ClassDeclaration it) {
      MethodDeclaration _findDeclaredMethod = it.findDeclaredMethod("hashCode");
      return (_findDeclaredMethod != null);
    }
   
    public boolean hasEquals(final ClassDeclaration it) {
      Iterable<? extends MethodDeclaration> _declaredMethods = it.getDeclaredMethods();
      final Function1<MethodDeclaration, Boolean> _function = new Function1<MethodDeclaration, Boolean>() {
        public Boolean apply(final MethodDeclaration it) {
          boolean _and = false;
          boolean _and_1 = false;
          String _simpleName = it.getSimpleName();
          boolean _equals = Objects.equal(_simpleName, "equals");
          if (!_equals) {
            _and_1 = false;
          } else {
            Iterable<? extends ParameterDeclaration> _parameters = it.getParameters();
            int _size = IterableExtensions.size(_parameters);
            boolean _equals_1 = (_size == 1);
            _and_1 = _equals_1;
          }
          if (!_and_1) {
            _and = false;
          } else {
            Iterable<? extends ParameterDeclaration> _parameters_1 = it.getParameters();
            ParameterDeclaration _head = IterableExtensions.head(_parameters_1);
            TypeReference _type = _head.getType();
            String _name = _type.getName();
            boolean _equals_2 = Objects.equal(_name, "java.lang.Object");
            _and = _equals_2;
          }
          return Boolean.valueOf(_and);
        }
      };
      return IterableExtensions.exists(_declaredMethods, _function);
    }
   
    public boolean hasSuperEquals(final ClassDeclaration cls) {
      boolean _xifexpression = false;
      TypeReference _newTypeReference = this.context.newTypeReference(cls);
      TypeReference _object = this.context.getObject();
      boolean _equals = _newTypeReference.equals(_object);
      if (_equals) {
        _xifexpression = false;
      } else {
        boolean _xifexpression_1 = false;
        boolean _hasEquals = this.hasEquals(cls);
        if (_hasEquals) {
          _xifexpression_1 = true;
        } else {
          TypeReference _extendedClass = cls.getExtendedClass();
          Type _type = _extendedClass.getType();
          _xifexpression_1 = this.hasSuperEquals(((ClassDeclaration) _type));
        }
        _xifexpression = _xifexpression_1;
      }
      return _xifexpression;
    }
   
    public void addEquals(final MutableClassDeclaration cls, final Iterable<? extends FieldDeclaration> includedFields, final boolean includeSuper) {
      final Procedure1<MutableMethodDeclaration> _function = new Procedure1<MutableMethodDeclaration>() {
        public void apply(final MutableMethodDeclaration it) {
          Element _primarySourceElement = Util.this.context.getPrimarySourceElement(cls);
          Util.this.context.setPrimarySourceElement(it, _primarySourceElement);
          TypeReference _primitiveBoolean = Util.this.context.getPrimitiveBoolean();
          it.setReturnType(_primitiveBoolean);
          AnnotationReference _newAnnotationReference = Util.this.context.newAnnotationReference(Override.class);
          it.addAnnotation(_newAnnotationReference);
          AnnotationReference _newAnnotationReference_1 = Util.this.context.newAnnotationReference(Pure.class);
          it.addAnnotation(_newAnnotationReference_1);
          TypeReference _object = Util.this.context.getObject();
          it.addParameter("obj", _object);
          StringConcatenationClient _client = new StringConcatenationClient() {
            @Override
            protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
              _builder.append("if (this == obj)");
              _builder.newLine();
              _builder.append("  ");
              _builder.append("return true;");
              _builder.newLine();
              _builder.append("if (obj == null)");
              _builder.newLine();
              _builder.append("  ");
              _builder.append("return false;");
              _builder.newLine();
              _builder.append("if (getClass() != obj.getClass())");
              _builder.newLine();
              _builder.append("  ");
              _builder.append("return false;");
              _builder.newLine();
              {
                if (includeSuper) {
                  _builder.append("if (!super.equals(obj))");
                  _builder.newLine();
                  _builder.append("  ");
                  _builder.append("return false;");
                  _builder.newLine();
                }
              }
              TypeReference _newWildCardSelfTypeReference = Util.this.newWildCardSelfTypeReference(cls);
              _builder.append(_newWildCardSelfTypeReference, "");
              _builder.append(" other = (");
              TypeReference _newWildCardSelfTypeReference_1 = Util.this.newWildCardSelfTypeReference(cls);
              _builder.append(_newWildCardSelfTypeReference_1, "");
              _builder.append(") obj;");
              _builder.newLineIfNotEmpty();
              {
                for(final FieldDeclaration field : includedFields) {
                  String _contributeToEquals = Util.this.contributeToEquals(field);
                  _builder.append(_contributeToEquals, "");
                  _builder.newLineIfNotEmpty();
                }
              }
              _builder.append("return true;");
              _builder.newLine();
            }
          };
          it.setBody(_client);
        }
      };
      cls.addMethod("equals", _function);
    }
   
    private TypeReference newWildCardSelfTypeReference(final ClassDeclaration cls) {
      Iterable<? extends TypeParameterDeclaration> _typeParameters = cls.getTypeParameters();
      final Function1<TypeParameterDeclaration, TypeReference> _function = new Function1<TypeParameterDeclaration, TypeReference>() {
        public TypeReference apply(final TypeParameterDeclaration it) {
          TypeReference _object = Util.this.context.getObject();
          return Util.this.context.newWildcardTypeReference(_object);
        }
      };
      Iterable<TypeReference> _map = IterableExtensions.map(_typeParameters, _function);
      return this.context.newTypeReference(cls, ((TypeReference[])Conversions.unwrapArray(_map, TypeReference.class)));
    }
   
    public String contributeToEquals(final FieldDeclaration it) {
      String _switchResult = null;
      TypeReference _type = it.getType();
      TypeReference _orObject = this.orObject(_type);
      String _name = _orObject.getName();
      boolean _matched = false;
      if (!_matched) {
        String _name_1 = Double.TYPE.getName();
        if (Objects.equal(_name, _name_1)) {
          _matched=true;
          StringConcatenation _builder = new StringConcatenation();
          _builder.append("if (Double.doubleToLongBits(other.");
          String _simpleName = it.getSimpleName();
          _builder.append(_simpleName, "");
          _builder.append(") != Double.doubleToLongBits(this.");
          String _simpleName_1 = it.getSimpleName();
          _builder.append(_simpleName_1, "");
          _builder.append("))");
          _builder.newLineIfNotEmpty();
          _builder.append("  ");
          _builder.append("return false; ");
          _builder.newLine();
          _switchResult = _builder.toString();
        }
      }
      if (!_matched) {
        String _name_2 = Float.TYPE.getName();
        if (Objects.equal(_name, _name_2)) {
          _matched=true;
          StringConcatenation _builder_1 = new StringConcatenation();
          _builder_1.append("if (Float.floatToIntBits(other.");
          String _simpleName_2 = it.getSimpleName();
          _builder_1.append(_simpleName_2, "");
          _builder_1.append(") != Float.floatToIntBits(this.");
          String _simpleName_3 = it.getSimpleName();
          _builder_1.append(_simpleName_3, "");
          _builder_1.append("))");
          _builder_1.newLineIfNotEmpty();
          _builder_1.append("  ");
          _builder_1.append("return false; ");
          _builder_1.newLine();
          _switchResult = _builder_1.toString();
        }
      }
      if (!_matched) {
        String _name_3 = Boolean.TYPE.getName();
        if (Objects.equal(_name, _name_3)) {
          _matched=true;
        }
        if (!_matched) {
          String _name_4 = Integer.TYPE.getName();
          if (Objects.equal(_name, _name_4)) {
            _matched=true;
          }
        }
        if (!_matched) {
          String _name_5 = Character.TYPE.getName();
          if (Objects.equal(_name, _name_5)) {
            _matched=true;
          }
        }
        if (!_matched) {
          String _name_6 = Byte.TYPE.getName();
          if (Objects.equal(_name, _name_6)) {
            _matched=true;
          }
        }
        if (!_matched) {
          String _name_7 = Short.TYPE.getName();
          if (Objects.equal(_name, _name_7)) {
            _matched=true;
          }
        }
        if (!_matched) {
          String _name_8 = Long.TYPE.getName();
          if (Objects.equal(_name, _name_8)) {
            _matched=true;
          }
        }
        if (_matched) {
          StringConcatenation _builder_2 = new StringConcatenation();
          _builder_2.append("if (other.");
          String _simpleName_4 = it.getSimpleName();
          _builder_2.append(_simpleName_4, "");
          _builder_2.append(" != this.");
          String _simpleName_5 = it.getSimpleName();
          _builder_2.append(_simpleName_5, "");
          _builder_2.append(")");
          _builder_2.newLineIfNotEmpty();
          _builder_2.append("  ");
          _builder_2.append("return false;");
          _builder_2.newLine();
          _switchResult = _builder_2.toString();
        }
      }
      if (!_matched) {
        StringConcatenation _builder_3 = new StringConcatenation();
        _builder_3.append("if (this.");
        String _simpleName_6 = it.getSimpleName();
        _builder_3.append(_simpleName_6, "");
        _builder_3.append(" == null) {");
        _builder_3.newLineIfNotEmpty();
        _builder_3.append("  ");
        _builder_3.append("if (other.");
        String _simpleName_7 = it.getSimpleName();
        _builder_3.append(_simpleName_7, "  ");
        _builder_3.append(" != null)");
        _builder_3.newLineIfNotEmpty();
        _builder_3.append("    ");
        _builder_3.append("return false;");
        _builder_3.newLine();
        _builder_3.append("} else if (!this.");
        String _simpleName_8 = it.getSimpleName();
        _builder_3.append(_simpleName_8, "");
        _builder_3.append(".equals(other.");
        String _simpleName_9 = it.getSimpleName();
        _builder_3.append(_simpleName_9, "");
        _builder_3.append("))");
        _builder_3.newLineIfNotEmpty();
        _builder_3.append("  ");
        _builder_3.append("return false;");
        _builder_3.newLine();
        _switchResult = _builder_3.toString();
      }
      return _switchResult;
    }
   
    public void addHashCode(final MutableClassDeclaration cls, final Iterable<? extends FieldDeclaration> includedFields, final boolean includeSuper) {
      final Procedure1<MutableMethodDeclaration> _function = new Procedure1<MutableMethodDeclaration>() {
        public void apply(final MutableMethodDeclaration it) {
          Element _primarySourceElement = Util.this.context.getPrimarySourceElement(cls);
          Util.this.context.setPrimarySourceElement(it, _primarySourceElement);
          TypeReference _primitiveInt = Util.this.context.getPrimitiveInt();
          it.setReturnType(_primitiveInt);
          AnnotationReference _newAnnotationReference = Util.this.context.newAnnotationReference(Override.class);
          it.addAnnotation(_newAnnotationReference);
          AnnotationReference _newAnnotationReference_1 = Util.this.context.newAnnotationReference(Pure.class);
          it.addAnnotation(_newAnnotationReference_1);
          StringConcatenationClient _client = new StringConcatenationClient() {
            @Override
            protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
              _builder.append("final int prime = 31;");
              _builder.newLine();
              _builder.append("int result = ");
              {
                if (includeSuper) {
                  _builder.append("super.hashCode()");
                } else {
                  _builder.append("1");
                }
              }
              _builder.append(";");
              _builder.newLineIfNotEmpty();
              {
                for(final FieldDeclaration field : includedFields) {
                  String _contributeToHashCode = Util.this.contributeToHashCode(field);
                  _builder.append(_contributeToHashCode, "");
                  _builder.newLineIfNotEmpty();
                }
              }
              _builder.append("return result;");
              _builder.newLine();
            }
          };
          it.setBody(_client);
        }
      };
      cls.addMethod("hashCode", _function);
    }
   
    public String contributeToHashCode(final FieldDeclaration it) {
      String _switchResult = null;
      TypeReference _type = it.getType();
      TypeReference _orObject = this.orObject(_type);
      String _name = _orObject.getName();
      boolean _matched = false;
      if (!_matched) {
        String _name_1 = Double.TYPE.getName();
        if (Objects.equal(_name, _name_1)) {
          _matched=true;
          String _simpleName = it.getSimpleName();
          String _plus = ("result = prime * result + (int) (Double.doubleToLongBits(this." + _simpleName);
          String _plus_1 = (_plus +
            ") ^ (Double.doubleToLongBits(this.");
          String _simpleName_1 = it.getSimpleName();
          String _plus_2 = (_plus_1 + _simpleName_1);
          _switchResult = (_plus_2 + ") >>> 32));");
        }
      }
      if (!_matched) {
        String _name_2 = Float.TYPE.getName();
        if (Objects.equal(_name, _name_2)) {
          _matched=true;
          String _simpleName_2 = it.getSimpleName();
          String _plus_3 = ("result = prime * result + Float.floatToIntBits(this." + _simpleName_2);
          _switchResult = (_plus_3 + ");");
        }
      }
      if (!_matched) {
        String _name_3 = Boolean.TYPE.getName();
        if (Objects.equal(_name, _name_3)) {
          _matched=true;
          String _simpleName_3 = it.getSimpleName();
          String _plus_4 = ("result = prime * result + (this." + _simpleName_3);
          _switchResult = (_plus_4 + " ? 1231 : 1237);");
        }
      }
      if (!_matched) {
        String _name_4 = Integer.TYPE.getName();
        if (Objects.equal(_name, _name_4)) {
          _matched=true;
        }
        if (!_matched) {
          String _name_5 = Character.TYPE.getName();
          if (Objects.equal(_name, _name_5)) {
            _matched=true;
          }
        }
        if (!_matched) {
          String _name_6 = Byte.TYPE.getName();
          if (Objects.equal(_name, _name_6)) {
            _matched=true;
          }
        }
        if (!_matched) {
          String _name_7 = Short.TYPE.getName();
          if (Objects.equal(_name, _name_7)) {
            _matched=true;
          }
        }
        if (_matched) {
          String _simpleName_4 = it.getSimpleName();
          String _plus_5 = ("result = prime * result + this." + _simpleName_4);
          _switchResult = (_plus_5 + ";");
        }
      }
      if (!_matched) {
        String _name_8 = Long.TYPE.getName();
        if (Objects.equal(_name, _name_8)) {
          _matched=true;
          String _simpleName_5 = it.getSimpleName();
          String _plus_6 = ("result = prime * result + (int) (this." + _simpleName_5);
          String _plus_7 = (_plus_6 + " ^ (this.");
          String _simpleName_6 = it.getSimpleName();
          String _plus_8 = (_plus_7 + _simpleName_6);
          _switchResult = (_plus_8 + " >>> 32));");
        }
      }
      if (!_matched) {
        String _simpleName_7 = it.getSimpleName();
        String _plus_9 = ("result = prime * result + ((this." + _simpleName_7);
        String _plus_10 = (_plus_9 + "== null) ? 0 : this.");
        String _simpleName_8 = it.getSimpleName();
        String _plus_11 = (_plus_10 + _simpleName_8);
        _switchResult = (_plus_11 +
          ".hashCode());");
      }
      return _switchResult;
    }
   
    private TypeReference orObject(final TypeReference ref) {
      TypeReference _xifexpression = null;
      boolean _tripleEquals = (ref == null);
      if (_tripleEquals) {
        _xifexpression = this.context.getObject();
      } else {
        _xifexpression = ref;
      }
      return _xifexpression;
    }
  }
 
  public void doTransform(final MutableClassDeclaration it, @Extension final TransformationContext context) {
    Type _findTypeGlobally = context.findTypeGlobally(Data.class);
    AnnotationReference _findAnnotation = it.findAnnotation(_findTypeGlobally);
    boolean _tripleNotEquals = (_findAnnotation != null);
    if (_tripleNotEquals) {
      return;
    }
    @Extension
    final EqualsHashCodeProcessor.Util util = new EqualsHashCodeProcessor.Util(context);
    boolean _hasEquals = util.hasEquals(it);
    if (_hasEquals) {
      Type _findTypeGlobally_1 = context.findTypeGlobally(EqualsHashCode.class);
      final AnnotationReference annotation = it.findAnnotation(_findTypeGlobally_1);
      context.addWarning(annotation, "equals is already defined, this annotation has no effect");
    } else {
      boolean _hasHashCode = util.hasHashCode(it);
      if (_hasHashCode) {
        context.addWarning(it, "hashCode is already defined, this annotation has no effect");
      } else {
        final boolean hasSuperEquals = util.hasSuperEquals(it);
        Iterable<? extends MutableFieldDeclaration> _declaredFields = it.getDeclaredFields();
        final Function1<MutableFieldDeclaration, Boolean> _function = new Function1<MutableFieldDeclaration, Boolean>() {
          public Boolean apply(final MutableFieldDeclaration it) {
            boolean _and = false;
            boolean _and_1 = false;
            boolean _isStatic = it.isStatic();
            boolean _not = (!_isStatic);
            if (!_not) {
              _and_1 = false;
            } else {
              boolean _isTransient = it.isTransient();
              boolean _not_1 = (!_isTransient);
              _and_1 = _not_1;
            }
            if (!_and_1) {
              _and = false;
            } else {
              boolean _isThePrimaryGeneratedJavaElement = context.isThePrimaryGeneratedJavaElement(it);
              _and = _isThePrimaryGeneratedJavaElement;
            }
            return Boolean.valueOf(_and);
          }
        };
        final Iterable<? extends MutableFieldDeclaration> fields = IterableExtensions.filter(_declaredFields, _function);
        util.addEquals(it, fields, hasSuperEquals);
        util.addHashCode(it, fields, hasSuperEquals);
      }
    }
  }
}
TOP

Related Classes of org.eclipse.xtend.lib.annotations.EqualsHashCodeProcessor$Util

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.