public void resolve(MethodScope var1) {
   if ((this.field_446 & 16) == 0) {
     if (this.binding != null && this.binding.isValidBinding()) {
       this.field_446 |= 16;
       ClassScope var2 = var1.method_582();
       if (var2 != null) {
         label338:
         {
           SourceTypeBinding var3 = var2.enclosingSourceType();
           if (var3.superclass != null) {
             FieldBinding var4 = var2.findField(var3.superclass, this.name, this, false);
             if (var4 != null && var4.isValidBinding()) {
               label334:
               {
                 if (var4 instanceof FieldBinding) {
                   FieldBinding var5 = (FieldBinding) var4;
                   if (var5.original() == this.binding || !var5.canBeSeenBy(var3, this, var1)) {
                     break label334;
                   }
                 }
                 var1.problemReporter().fieldHiding(this, var4);
                 break label338;
               }
             }
           }
           Scope var13 = var2.parent;
           if (var13.kind != 4) {
             Binding var15 = var13.getBinding(this.name, 3, this, false);
             if (var15 != null && var15.isValidBinding() && var15 != this.binding) {
               label323:
               {
                 if (var15 instanceof FieldBinding) {
                   FieldBinding var6 = (FieldBinding) var15;
                   if (var6.original() == this.binding
                       || !var6.method_431() && var3.method_226()) {
                     break label323;
                   }
                 }
                 var1.problemReporter().fieldHiding(this, var15);
               }
             }
           }
         }
       }
       if (this.type != null) {
         this.type.resolvedType = this.binding.type;
       }
       FieldBinding var12 = var1.initializedField;
       int var14 = var1.field_407;
       try {
         var1.initializedField = this.binding;
         var1.field_407 = this.binding.field_304;
         method_761(var1, this.annotations, this.binding);
         if ((this.binding.getAnnotationTagBits() & 70368744177664L) == 0L
             && (this.binding.field_300 & 1048576) != 0
             && var1.compilerOptions().field_1928 >= 3211264L) {
           var1.problemReporter().method_1675(this);
         }
         if (this.initialization == null) {
           this.binding.setConstant(Constant.NotAConstant);
         } else {
           this.binding.setConstant(Constant.NotAConstant);
           TypeBinding var17 = this.binding.type;
           this.initialization.setExpectedType(var17);
           TypeBinding var18;
           if (this.initialization instanceof ArrayInitializer) {
             if ((var18 = this.initialization.resolveTypeExpecting(var1, var17)) != null) {
               ((ArrayInitializer) this.initialization).binding = (ArrayBinding) var18;
               this.initialization.computeConversion(var1, var17, var18);
             }
           } else if ((var18 = this.initialization.resolveType(var1)) != null) {
             if (var17 != var18) {
               var1.compilationUnitScope().recordTypeConversion(var17, var18);
             }
             if (!this.initialization.isConstantValueOfTypeAssignableToType(var18, var17)
                 && (!var17.method_148() || !BaseTypeBinding.method_185(var17.id, var18.id))
                 && !var18.isCompatibleWith(var17)) {
               if (!var1.isBoxingCompatibleWith(var18, var17)
                   && (!var18.method_148()
                       || var1.compilerOptions().field_1928 < 3211264L
                       || var17.method_148()
                       || !this.initialization.isConstantValueOfTypeAssignableToType(
                           var18, var1.environment().method_486(var17)))) {
                 if ((var17.tagBits & 128L) == 0L) {
                   var1.problemReporter()
                       .typeMismatchError(var18, var17, this.initialization, (ASTNode) null);
                 }
               } else {
                 this.initialization.computeConversion(var1, var17, var18);
                 if (this.initialization instanceof CastExpression
                     && (this.initialization.field_446 & 16384) == 0) {
                   CastExpression.checkNeedForAssignedCast(
                       var1, var17, (CastExpression) this.initialization);
                 }
               }
             } else {
               this.initialization.computeConversion(var1, var17, var18);
               if (var18.method_174(var17)) {
                 var1.problemReporter().method_1806(this.initialization, var18, var17);
               }
               if (this.initialization instanceof CastExpression
                   && (this.initialization.field_446 & 16384) == 0) {
                 CastExpression.checkNeedForAssignedCast(
                     var1, var17, (CastExpression) this.initialization);
               }
             }
             if (this.binding.method_409()) {
               this.binding.setConstant(
                   this.initialization.constant.castTo(
                       (this.binding.type.id << 4) + this.initialization.constant.typeID()));
             }
           } else {
             this.binding.setConstant(Constant.NotAConstant);
           }
           if (this.binding == Assignment.method_944(this.initialization)) {
             var1.problemReporter().assignmentHasNoEffect(this, this.name);
           }
         }
         if (this.binding != null
             && this.binding.declaringClass != null
             && !this.binding.declaringClass.method_158()) {
           int var16 = this.binding.field_300 & 7;
           ProblemReporter var19 = var1.problemReporter();
           int var7 = var19.computeSeverity(-1610612250);
           if (var7 != -1) {
             if (var2 != null) {
               var16 = Util.computeOuterMostVisibility(var2.referenceType(), var16);
             }
             int var8 = this.binding.field_300 & -8 | var16;
           }
         }
       } finally {
         var1.initializedField = var12;
         var1.field_407 = var14;
         if (this.binding.constant() == null) {
           this.binding.setConstant(Constant.NotAConstant);
         }
       }
     }
   }
 }
예제 #2
0
  private MethodDeclaration createHashCode(
      EclipseNode type,
      Collection<EclipseNode> fields,
      boolean callSuper,
      ASTNode source,
      FieldAccess fieldAccess) {
    int pS = source.sourceStart, pE = source.sourceEnd;
    long p = (long) pS << 32 | pE;

    MethodDeclaration method =
        new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
    Eclipse.setGeneratedBy(method, source);

    method.modifiers = EclipseHandlerUtil.toEclipseModifier(AccessLevel.PUBLIC);
    method.returnType = TypeReference.baseTypeReference(TypeIds.T_int, 0);
    Eclipse.setGeneratedBy(method.returnType, source);
    method.annotations =
        new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source)};
    method.selector = "hashCode".toCharArray();
    method.thrownExceptions = null;
    method.typeParameters = null;
    method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
    method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart;
    method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd;
    method.arguments = null;

    List<Statement> statements = new ArrayList<Statement>();
    List<Expression> intoResult = new ArrayList<Expression>();

    final char[] PRIME = "PRIME".toCharArray();
    final char[] RESULT = "result".toCharArray();
    final boolean isEmpty = fields.isEmpty();

    /* final int PRIME = 31; */ {
      /* Without fields, PRIME isn't used, and that would trigger a 'local variable not used' warning. */
      if (!isEmpty || callSuper) {
        LocalDeclaration primeDecl = new LocalDeclaration(PRIME, pS, pE);
        Eclipse.setGeneratedBy(primeDecl, source);
        primeDecl.modifiers |= Modifier.FINAL;
        primeDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0);
        primeDecl.type.sourceStart = pS;
        primeDecl.type.sourceEnd = pE;
        Eclipse.setGeneratedBy(primeDecl.type, source);
        primeDecl.initialization = new IntLiteral("31".toCharArray(), pS, pE);
        Eclipse.setGeneratedBy(primeDecl.initialization, source);
        statements.add(primeDecl);
      }
    }

    /* int result = 1; */ {
      LocalDeclaration resultDecl = new LocalDeclaration(RESULT, pS, pE);
      Eclipse.setGeneratedBy(resultDecl, source);
      resultDecl.initialization = new IntLiteral("1".toCharArray(), pS, pE);
      Eclipse.setGeneratedBy(resultDecl.initialization, source);
      resultDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0);
      resultDecl.type.sourceStart = pS;
      resultDecl.type.sourceEnd = pE;
      Eclipse.setGeneratedBy(resultDecl.type, source);
      statements.add(resultDecl);
    }

    if (callSuper) {
      MessageSend callToSuper = new MessageSend();
      Eclipse.setGeneratedBy(callToSuper, source);
      callToSuper.sourceStart = pS;
      callToSuper.sourceEnd = pE;
      callToSuper.receiver = new SuperReference(pS, pE);
      Eclipse.setGeneratedBy(callToSuper.receiver, source);
      callToSuper.selector = "hashCode".toCharArray();
      intoResult.add(callToSuper);
    }

    int tempCounter = 0;
    for (EclipseNode field : fields) {
      TypeReference fType = getFieldType(field, fieldAccess);
      char[] token = fType.getLastToken();
      Expression fieldAccessor = createFieldAccessor(field, fieldAccess, source);
      if (fType.dimensions() == 0 && token != null) {
        if (Arrays.equals(TypeConstants.FLOAT, token)) {
          /* Float.floatToIntBits(fieldName) */
          MessageSend floatToIntBits = new MessageSend();
          floatToIntBits.sourceStart = pS;
          floatToIntBits.sourceEnd = pE;
          Eclipse.setGeneratedBy(floatToIntBits, source);
          floatToIntBits.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_FLOAT);
          floatToIntBits.selector = "floatToIntBits".toCharArray();
          floatToIntBits.arguments = new Expression[] {fieldAccessor};
          intoResult.add(floatToIntBits);
        } else if (Arrays.equals(TypeConstants.DOUBLE, token)) {
          /* longToIntForHashCode(Double.doubleToLongBits(fieldName)) */
          MessageSend doubleToLongBits = new MessageSend();
          doubleToLongBits.sourceStart = pS;
          doubleToLongBits.sourceEnd = pE;
          Eclipse.setGeneratedBy(doubleToLongBits, source);
          doubleToLongBits.receiver =
              generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_DOUBLE);
          doubleToLongBits.selector = "doubleToLongBits".toCharArray();
          doubleToLongBits.arguments = new Expression[] {fieldAccessor};
          final char[] tempName = ("temp" + ++tempCounter).toCharArray();
          LocalDeclaration tempVar = new LocalDeclaration(tempName, pS, pE);
          Eclipse.setGeneratedBy(tempVar, source);
          tempVar.initialization = doubleToLongBits;
          tempVar.type = TypeReference.baseTypeReference(TypeIds.T_long, 0);
          tempVar.type.sourceStart = pS;
          tempVar.type.sourceEnd = pE;
          Eclipse.setGeneratedBy(tempVar.type, source);
          tempVar.modifiers = Modifier.FINAL;
          statements.add(tempVar);
          SingleNameReference copy1 = new SingleNameReference(tempName, p);
          Eclipse.setGeneratedBy(copy1, source);
          SingleNameReference copy2 = new SingleNameReference(tempName, p);
          Eclipse.setGeneratedBy(copy2, source);
          intoResult.add(longToIntForHashCode(copy1, copy2, source));
        } else if (Arrays.equals(TypeConstants.BOOLEAN, token)) {
          /* booleanField ? 1231 : 1237 */
          IntLiteral int1231 = new IntLiteral("1231".toCharArray(), pS, pE);
          Eclipse.setGeneratedBy(int1231, source);
          IntLiteral int1237 = new IntLiteral("1237".toCharArray(), pS, pE);
          Eclipse.setGeneratedBy(int1237, source);
          ConditionalExpression int1231or1237 =
              new ConditionalExpression(fieldAccessor, int1231, int1237);
          Eclipse.setGeneratedBy(int1231or1237, source);
          intoResult.add(int1231or1237);
        } else if (Arrays.equals(TypeConstants.LONG, token)) {
          intoResult.add(
              longToIntForHashCode(
                  fieldAccessor, createFieldAccessor(field, fieldAccess, source), source));
        } else if (BUILT_IN_TYPES.contains(new String(token))) {
          intoResult.add(fieldAccessor);
        } else /* objects */ {
          /* this.fieldName == null ? 0 : this.fieldName.hashCode() */
          MessageSend hashCodeCall = new MessageSend();
          hashCodeCall.sourceStart = pS;
          hashCodeCall.sourceEnd = pE;
          Eclipse.setGeneratedBy(hashCodeCall, source);
          hashCodeCall.receiver = createFieldAccessor(field, fieldAccess, source);
          hashCodeCall.selector = "hashCode".toCharArray();
          NullLiteral nullLiteral = new NullLiteral(pS, pE);
          Eclipse.setGeneratedBy(nullLiteral, source);
          EqualExpression objIsNull =
              new EqualExpression(fieldAccessor, nullLiteral, OperatorIds.EQUAL_EQUAL);
          Eclipse.setGeneratedBy(objIsNull, source);
          IntLiteral int0 = new IntLiteral("0".toCharArray(), pS, pE);
          Eclipse.setGeneratedBy(int0, source);
          ConditionalExpression nullOrHashCode =
              new ConditionalExpression(objIsNull, int0, hashCodeCall);
          nullOrHashCode.sourceStart = pS;
          nullOrHashCode.sourceEnd = pE;
          Eclipse.setGeneratedBy(nullOrHashCode, source);
          intoResult.add(nullOrHashCode);
        }
      } else if (fType.dimensions() > 0 && token != null) {
        /* Arrays.deepHashCode(array)  //just hashCode for simple arrays */
        MessageSend arraysHashCodeCall = new MessageSend();
        arraysHashCodeCall.sourceStart = pS;
        arraysHashCodeCall.sourceEnd = pE;
        Eclipse.setGeneratedBy(arraysHashCodeCall, source);
        arraysHashCodeCall.receiver =
            generateQualifiedNameRef(
                source, TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray());
        if (fType.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token))) {
          arraysHashCodeCall.selector = "deepHashCode".toCharArray();
        } else {
          arraysHashCodeCall.selector = "hashCode".toCharArray();
        }
        arraysHashCodeCall.arguments = new Expression[] {fieldAccessor};
        intoResult.add(arraysHashCodeCall);
      }
    }

    /* fold each intoResult entry into:
    result = result * PRIME + (item); */ {
      for (Expression ex : intoResult) {
        SingleNameReference resultRef = new SingleNameReference(RESULT, p);
        Eclipse.setGeneratedBy(resultRef, source);
        SingleNameReference primeRef = new SingleNameReference(PRIME, p);
        Eclipse.setGeneratedBy(primeRef, source);
        BinaryExpression multiplyByPrime =
            new BinaryExpression(resultRef, primeRef, OperatorIds.MULTIPLY);
        multiplyByPrime.sourceStart = pS;
        multiplyByPrime.sourceEnd = pE;
        Eclipse.setGeneratedBy(multiplyByPrime, source);
        BinaryExpression addItem = new BinaryExpression(multiplyByPrime, ex, OperatorIds.PLUS);
        addItem.sourceStart = pS;
        addItem.sourceEnd = pE;
        Eclipse.setGeneratedBy(addItem, source);
        resultRef = new SingleNameReference(RESULT, p);
        Eclipse.setGeneratedBy(resultRef, source);
        Assignment assignment = new Assignment(resultRef, addItem, pE);
        assignment.sourceStart = pS;
        assignment.sourceEnd = pE;
        Eclipse.setGeneratedBy(assignment, source);
        statements.add(assignment);
      }
    }

    /* return result; */ {
      SingleNameReference resultRef = new SingleNameReference(RESULT, p);
      Eclipse.setGeneratedBy(resultRef, source);
      ReturnStatement returnStatement = new ReturnStatement(resultRef, pS, pE);
      Eclipse.setGeneratedBy(returnStatement, source);
      statements.add(returnStatement);
    }
    method.statements = statements.toArray(new Statement[statements.size()]);
    return method;
  }