public FlowInfo analyseAssignment(
      BlockScope currentScope,
      FlowContext flowContext,
      FlowInfo flowInfo,
      Assignment assignment,
      boolean isCompound) {
    // compound assignment extra work
    if (isCompound) { // check the variable part is initialized if blank final
      if (this.binding.isBlankFinal()
          && this.receiver.isThis()
          && currentScope.needBlankFinalFieldInitializationCheck(this.binding)) {
        FlowInfo fieldInits =
            flowContext.getInitsForFinalBlankInitializationCheck(
                this.binding.declaringClass.original(), flowInfo);
        if (!fieldInits.isDefinitelyAssigned(this.binding)) {
          currentScope.problemReporter().uninitializedBlankFinalField(this.binding, this);
          // we could improve error msg here telling "cannot use compound assignment on final blank
          // field"
        }
      }
      manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
    }
    flowInfo =
        this.receiver
            .analyseCode(currentScope, flowContext, flowInfo, !this.binding.isStatic())
            .unconditionalInits();
    if (assignment.expression != null) {
      flowInfo =
          assignment
              .expression
              .analyseCode(currentScope, flowContext, flowInfo)
              .unconditionalInits();
    }
    manageSyntheticAccessIfNecessary(currentScope, flowInfo, false /*write-access*/);

    // check if assigning a final field
    if (this.binding.isFinal()) {
      // in a context where it can be assigned?
      if (this.binding.isBlankFinal()
          && !isCompound
          && this.receiver.isThis()
          && !(this.receiver instanceof QualifiedThisReference)
          && ((this.receiver.bits & ASTNode.ParenthesizedMASK) == 0) // (this).x is forbidden
          && currentScope.allowBlankFinalFieldAssignment(this.binding)) {
        if (flowInfo.isPotentiallyAssigned(this.binding)) {
          currentScope
              .problemReporter()
              .duplicateInitializationOfBlankFinalField(this.binding, this);
        } else {
          flowContext.recordSettingFinal(this.binding, this, flowInfo);
        }
        flowInfo.markAsDefinitelyAssigned(this.binding);
      } else {
        // assigning a final field outside an initializer or constructor or wrong reference
        currentScope.problemReporter().cannotAssignToFinalField(this.binding, this);
      }
    } else if (this.binding.isNonNull()) {
      // in a context where it can be assigned?
      if (!isCompound
          && this.receiver.isThis()
          && !(this.receiver instanceof QualifiedThisReference)
          && this.receiver.resolvedType
              == this.binding.declaringClass // inherited fields are not tracked here
          && ((this.receiver.bits & ASTNode.ParenthesizedMASK) == 0)) { // (this).x is forbidden
        flowInfo.markAsDefinitelyAssigned(this.binding);
      }
    }
    return flowInfo;
  }