Code review comment: Isn't this similar to L4017-L4035? Shall we check if we can extract this logic out to a method?

Code before review:
public void visit(BLangBinaryExpr binaryExpr) {
if (expType.tag == TypeTags.FUTURE && binaryExpr.opKind == OperatorKind.BITWISE_OR) {
BType lhsResultType = checkExpr(binaryExpr.lhsExpr, env, expType);
BType rhsResultType = checkExpr(binaryExpr.rhsExpr, env, expType);
if (lhsResultType == symTable.semanticError || rhsResultType == symTable.semanticError) {
resultType = symTable.semanticError;
return;
}
resultType = BUnionType.create(null, lhsResultType, rhsResultType);
return;
}
checkDecimalCompatibilityForBinaryArithmeticOverLiteralValues(binaryExpr);
SymbolEnv rhsExprEnv;
BType lhsType;
if (binaryExpr.lhsExpr instanceof BLangNumericLiteral) {
switch (binaryExpr.opKind) {
case ADD:
case SUB:
case MUL:
case DIV:
if (binaryExpr.expectedType.tag != TypeTags.NONE && binaryExpr.expectedType.tag != TypeTags.ANY) {
lhsType = checkExpectedTypeCompatibility(binaryExpr.lhsExpr,
binaryExpr.expectedType, env);
} else {
lhsType = checkExpr(binaryExpr.lhsExpr, env);;
}
break;
default:
lhsType = checkExpr(binaryExpr.lhsExpr, env);
}
} else {
lhsType = checkExpr(binaryExpr.lhsExpr, env);
}
if (binaryExpr.opKind == OperatorKind.AND) {
rhsExprEnv = typeNarrower.evaluateTruth(binaryExpr.lhsExpr, binaryExpr.rhsExpr, env, true);
} else if (binaryExpr.opKind == OperatorKind.OR) {
rhsExprEnv = typeNarrower.evaluateFalsity(binaryExpr.lhsExpr, binaryExpr.rhsExpr, env);
} else {
rhsExprEnv = env;
}
BType rhsType;
if (binaryExpr.rhsExpr instanceof BLangNumericLiteral) {
switch (binaryExpr.opKind) {
case ADD:
case SUB:
case MUL:
case DIV:
if (binaryExpr.expectedType.tag != TypeTags.NONE && binaryExpr.expectedType.tag != TypeTags.ANY) {
rhsType = checkExpectedTypeCompatibility(binaryExpr.rhsExpr,
binaryExpr.expectedType, rhsExprEnv);
} else {
rhsType = checkExpectedTypeCompatibility(binaryExpr.rhsExpr, lhsType, rhsExprEnv);
}
break;
default:
rhsType = checkExpr(binaryExpr.rhsExpr, rhsExprEnv);
}
} else {
rhsType = checkExpr(binaryExpr.rhsExpr, rhsExprEnv);
}
BType actualType = symTable.semanticError;
switch (binaryExpr.opKind) {
case ADD:
BType leftConstituent = getXMLConstituents(lhsType);
BType rightConstituent = getXMLConstituents(rhsType);
if (leftConstituent != null && rightConstituent != null) {
actualType = new BXMLType(BUnionType.create(null, leftConstituent, rightConstituent), null);
break;
}
default:
if (lhsType != symTable.semanticError && rhsType != symTable.semanticError) {
BSymbol opSymbol = symResolver.resolveBinaryOperator(binaryExpr.opKind, lhsType, rhsType);
if (opSymbol == symTable.notFoundSymbol) {
opSymbol = symResolver.getBitwiseShiftOpsForTypeSets(binaryExpr.opKind, lhsType, rhsType);
}
if (opSymbol == symTable.notFoundSymbol) {
opSymbol = symResolver.getArithmeticOpsForTypeSets(binaryExpr.opKind, lhsType, rhsType);
}
if (opSymbol == symTable.notFoundSymbol) {
opSymbol = symResolver.getBinaryEqualityForTypeSets(binaryExpr.opKind, lhsType, rhsType,
binaryExpr);
}
if (opSymbol == symTable.notFoundSymbol) {
opSymbol = symResolver.getBinaryComparisonOpForTypeSets(binaryExpr.opKind, lhsType, rhsType);
}
if (opSymbol == symTable.notFoundSymbol) {
dlog.error(binaryExpr.pos, DiagnosticErrorCode.BINARY_OP_INCOMPATIBLE_TYPES, binaryExpr.opKind,
lhsType, rhsType);
} else {
if ((binaryExpr.opKind == OperatorKind.EQUAL || binaryExpr.opKind == OperatorKind.NOT_EQUAL) &&
(couldHoldTableValues(lhsType, new ArrayList<>()) &&
couldHoldTableValues(rhsType, new ArrayList<>()))) {
dlog.error(binaryExpr.pos, DiagnosticErrorCode.EQUALITY_NOT_YET_SUPPORTED, TABLE_TNAME);
}
binaryExpr.opSymbol = (BOperatorSymbol) opSymbol;
actualType = opSymbol.type.getReturnType();
}
}
}
resultType = types.checkType(binaryExpr, actualType, expType);
}

Line under review: rhsExprEnv = typeNarrower.evaluateTruth(binaryExpr.lhsExpr, binaryExpr.rhsExpr, env, true);

Code after addressing the review:
public void visit(BLangBinaryExpr binaryExpr) {
if (expType.tag == TypeTags.FUTURE && binaryExpr.opKind == OperatorKind.BITWISE_OR) {
BType lhsResultType = checkExpr(binaryExpr.lhsExpr, env, expType);
BType rhsResultType = checkExpr(binaryExpr.rhsExpr, env, expType);
if (lhsResultType == symTable.semanticError || rhsResultType == symTable.semanticError) {
resultType = symTable.semanticError;
return;
}
resultType = BUnionType.create(null, lhsResultType, rhsResultType);
return;
}
checkDecimalCompatibilityForBinaryArithmeticOverLiteralValues(binaryExpr);
SymbolEnv rhsExprEnv;
BType lhsType;
if (binaryExpr.expectedType.tag == TypeTags.FLOAT || binaryExpr.expectedType.tag == TypeTags.DECIMAL) {
lhsType = checkAndGetType(binaryExpr.lhsExpr, env, binaryExpr);
} else {
lhsType = checkExpr(binaryExpr.lhsExpr, env);
}
if (binaryExpr.opKind == OperatorKind.AND) {
rhsExprEnv = typeNarrower.evaluateTruth(binaryExpr.lhsExpr, binaryExpr.rhsExpr, env, true);
} else if (binaryExpr.opKind == OperatorKind.OR) {
rhsExprEnv = typeNarrower.evaluateFalsity(binaryExpr.lhsExpr, binaryExpr.rhsExpr, env);
} else {
rhsExprEnv = env;
}
BType rhsType;
if (binaryExpr.expectedType.tag == TypeTags.FLOAT || binaryExpr.expectedType.tag == TypeTags.DECIMAL) {
rhsType = checkAndGetType(binaryExpr.rhsExpr, rhsExprEnv, binaryExpr);
} else {
rhsType = checkExpr(binaryExpr.rhsExpr, rhsExprEnv);
}
BType actualType = symTable.semanticError;
switch (binaryExpr.opKind) {
case ADD:
BType leftConstituent = getXMLConstituents(lhsType);
BType rightConstituent = getXMLConstituents(rhsType);
if (leftConstituent != null && rightConstituent != null) {
actualType = new BXMLType(BUnionType.create(null, leftConstituent, rightConstituent), null);
break;
}
default:
if (lhsType != symTable.semanticError && rhsType != symTable.semanticError) {
BSymbol opSymbol = symResolver.resolveBinaryOperator(binaryExpr.opKind, lhsType, rhsType);
if (opSymbol == symTable.notFoundSymbol) {
opSymbol = symResolver.getBitwiseShiftOpsForTypeSets(binaryExpr.opKind, lhsType, rhsType);
}
if (opSymbol == symTable.notFoundSymbol) {
opSymbol = symResolver.getArithmeticOpsForTypeSets(binaryExpr.opKind, lhsType, rhsType);
}
if (opSymbol == symTable.notFoundSymbol) {
opSymbol = symResolver.getBinaryEqualityForTypeSets(binaryExpr.opKind, lhsType, rhsType,
binaryExpr);
}
if (opSymbol == symTable.notFoundSymbol) {
opSymbol = symResolver.getBinaryComparisonOpForTypeSets(binaryExpr.opKind, lhsType, rhsType);
}
if (opSymbol == symTable.notFoundSymbol) {
dlog.error(binaryExpr.pos, DiagnosticErrorCode.BINARY_OP_INCOMPATIBLE_TYPES, binaryExpr.opKind,
lhsType, rhsType);
} else {
if ((binaryExpr.opKind == OperatorKind.EQUAL || binaryExpr.opKind == OperatorKind.NOT_EQUAL) &&
(couldHoldTableValues(lhsType, new ArrayList<>()) &&
couldHoldTableValues(rhsType, new ArrayList<>()))) {
dlog.error(binaryExpr.pos, DiagnosticErrorCode.EQUALITY_NOT_YET_SUPPORTED, TABLE_TNAME);
}
binaryExpr.opSymbol = (BOperatorSymbol) opSymbol;
actualType = opSymbol.type.getReturnType();
}
}
}
resultType = types.checkType(binaryExpr, actualType, expType);
}