Code review comment: Extract the logic out to a method. Can get rid of the nested if/else ifs.

Code before review:
public BType getActualTypeForOtherUnaryExpr(BLangUnaryExpr unaryExpr, AnalyzerData data) {
BType actualType = symTable.semanticError;
BType newExpectedType = data.expType;
LinkedHashSet<BType> basicNumericTypes;
BType referredType = types.getReferredType(data.expType);
int referredTypeTag = referredType.tag;
boolean isAddOrSubOperator = OperatorKind.SUB.equals(unaryExpr.operator) ||
OperatorKind.ADD.equals(unaryExpr.operator);
if (OperatorKind.SUB.equals(unaryExpr.operator)) {
if (data.expType == symTable.noType) {
newExpectedType = symTable.noType;
} else if (TypeTags.isIntegerTypeTag(referredTypeTag) || referredTypeTag == TypeTags.FLOAT
|| referredTypeTag == TypeTags.DECIMAL) {
BType numericTypeUnion = BUnionType.create(null,
symTable.intType, symTable.floatType, symTable.decimalType);
if (TypeTags.isIntegerTypeTag(referredTypeTag)) {
newExpectedType =
types.getTypeIntersection(Types.IntersectionContext.compilerInternalIntersectionTestContext(),
numericTypeUnion, symTable.intType, data.env);
} else {
newExpectedType =
types.getTypeIntersection(Types.IntersectionContext.compilerInternalIntersectionTestContext(),
numericTypeUnion, referredType, data.env);
}
} else if (referredTypeTag == TypeTags.FINITE || referredTypeTag == TypeTags.UNION) {
basicNumericTypes = referredTypeTag == TypeTags.FINITE ?
getBasicNumericTypesInFiniteType(referredType) : getBasicNumericTypesInUnionType(referredType);
if (basicNumericTypes.size() == 1) {
newExpectedType = basicNumericTypes.iterator().next();
} else if (basicNumericTypes.size() > 1) {
newExpectedType = BUnionType.create(null, basicNumericTypes);
}
} else if (referredTypeTag == TypeTags.JSON || referredTypeTag == TypeTags.ANYDATA ||
referredTypeTag == TypeTags.ANY) {
newExpectedType = BUnionType.create(null, symTable.intType, symTable.floatType,
symTable.decimalType);
}
}
newExpectedType = silentTypeCheckExpr(unaryExpr.expr, newExpectedType, data);
BType exprType;
if (newExpectedType != symTable.semanticError) {
exprType = isAddOrSubOperator ? checkExpr(unaryExpr.expr, newExpectedType, data) :
checkExpr(unaryExpr.expr, data);
} else {
exprType = isAddOrSubOperator ? checkExpr(unaryExpr.expr, data.expType, data) :
checkExpr(unaryExpr.expr, data);
}
if (exprType != symTable.semanticError) {
BSymbol symbol = symResolver.resolveUnaryOperator(unaryExpr.operator, exprType);
if (symbol == symTable.notFoundSymbol) {
symbol = symResolver.getUnaryOpsForTypeSets(unaryExpr.operator, exprType);
}
if (symbol == symTable.notFoundSymbol) {
dlog.error(unaryExpr.pos, DiagnosticErrorCode.UNARY_OP_INCOMPATIBLE_TYPES,
unaryExpr.operator, exprType);
} else {
unaryExpr.opSymbol = (BOperatorSymbol) symbol;
actualType = symbol.type.getReturnType();
}
}
if (isAddOrSubOperator && exprType != symTable.semanticError &&
unaryExpr.expr.getKind() == NodeKind.NUMERIC_LITERAL && (referredTypeTag == TypeTags.FINITE ||
referredTypeTag == TypeTags.UNION)) {
if (referredTypeTag == TypeTags.FINITE) {
actualType = createFiniteTypeForNumericUnaryExpr(unaryExpr, data);
} else {
if (silentCompatibleFiniteMembersInUnionTypeCheck(unaryExpr, (BUnionType) referredType, data)) {
return createFiniteTypeForNumericUnaryExpr(unaryExpr, data);
}
LinkedHashSet<BType> intTypesInUnion = getIntSubtypesInUnionType((BUnionType) referredType);
if (!intTypesInUnion.isEmpty()) {
BType newReferredType = BUnionType.create(null, intTypesInUnion);
BType tempActualType = checkCompatibilityWithConstructedNumericLiteral(unaryExpr, newReferredType,
data);
if (tempActualType != symTable.semanticError) {
return  tempActualType;
}
}
}
} else if (isAddOrSubOperator && exprType != symTable.semanticError &&
TypeTags.isIntegerTypeTag(referredTypeTag) && referredTypeTag != TypeTags.INT) {
BType tempActualType = checkCompatibilityWithConstructedNumericLiteral(unaryExpr, referredType, data);
if (tempActualType != symTable.semanticError) {
return  tempActualType;
}
}
return actualType;
}

Line under review: if (data.expType == symTable.noType) {

Code after addressing the review:
public BType getActualTypeForOtherUnaryExpr(BLangUnaryExpr unaryExpr, AnalyzerData data) {
BType actualType = symTable.semanticError;
BType newExpectedType = data.expType;
BType referredType = types.getReferredType(newExpectedType);
int referredTypeTag = referredType.tag;
boolean isAddOrSubOperator = OperatorKind.SUB.equals(unaryExpr.operator) ||
OperatorKind.ADD.equals(unaryExpr.operator);
if (OperatorKind.SUB.equals(unaryExpr.operator)) {
newExpectedType = setExpectedTypeForSubtractionOperator(data);
}
newExpectedType = silentTypeCheckExpr(unaryExpr.expr, newExpectedType, data);
BType exprType;
if (newExpectedType != symTable.semanticError) {
exprType = isAddOrSubOperator ? checkExpr(unaryExpr.expr, newExpectedType, data) :
checkExpr(unaryExpr.expr, data);
} else {
exprType = isAddOrSubOperator ? checkExpr(unaryExpr.expr, data.expType, data) :
checkExpr(unaryExpr.expr, data);
}
if (exprType != symTable.semanticError) {
BSymbol symbol = symResolver.resolveUnaryOperator(unaryExpr.operator, exprType);
if (symbol == symTable.notFoundSymbol) {
symbol = symResolver.getUnaryOpsForTypeSets(unaryExpr.operator, exprType);
}
if (symbol == symTable.notFoundSymbol) {
dlog.error(unaryExpr.pos, DiagnosticErrorCode.UNARY_OP_INCOMPATIBLE_TYPES,
unaryExpr.operator, exprType);
} else {
unaryExpr.opSymbol = (BOperatorSymbol) symbol;
actualType = symbol.type.getReturnType();
}
}
if (isAddOrSubOperator && exprType != symTable.semanticError && types.isExpressionInUnaryValid(unaryExpr.expr)
&& (referredTypeTag == TypeTags.FINITE || referredTypeTag == TypeTags.UNION)) {
if (referredTypeTag == TypeTags.FINITE) {
actualType = createFiniteTypeForNumericUnaryExpr(unaryExpr, data);
} else {
if (silentCompatibleFiniteMembersInUnionTypeCheck(unaryExpr, (BUnionType) referredType, data)) {
return createFiniteTypeForNumericUnaryExpr(unaryExpr, data);
}
LinkedHashSet<BType> intTypesInUnion = getIntSubtypesInUnionType((BUnionType) referredType);
if (!intTypesInUnion.isEmpty()) {
BType newReferredType = BUnionType.create(null, intTypesInUnion);
BType tempActualType = checkCompatibilityWithConstructedNumericLiteral(unaryExpr, newReferredType,
data);
if (tempActualType != symTable.semanticError) {
return  tempActualType;
}
}
}
} else if (isAddOrSubOperator && exprType != symTable.semanticError &&
TypeTags.isIntegerTypeTag(referredTypeTag) && referredTypeTag != TypeTags.INT) {
BType tempActualType = checkCompatibilityWithConstructedNumericLiteral(unaryExpr, referredType, data);
if (tempActualType != symTable.semanticError) {
return  tempActualType;
}
}
return actualType;
}