Skip to content

Commit

Permalink
Add support of HasValue/Value idiom to the ?? operator.
Browse files Browse the repository at this point in the history
Now you can write the following code:
WriteLine(VSome(42) ?? -1);
WriteLine(VNone() ?? -1);
  • Loading branch information
VladD2 committed Feb 27, 2017
1 parent 1fd32f5 commit e7d2523
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions macros/operators.n
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,16 @@ namespace Nemerle.Core
toption.Equals (t)
|| (t.BaseType != null && toption.Equals (t.BaseType))
}
def isHasValuePattern(ti : TypeInfo) : bool
{
def isBoolPropertyOrField(members : list[IMember]) : bool
{
| [member is IField] | [member is IProperty] => true
| _ => false
}
isBoolPropertyOrField(ti.LookupMember("Value", false)) &&
isBoolPropertyOrField(ti.LookupMember("HasValue", false))
}

def tExprA = typer.TypeExpr(exprA);
def tExprB = typer.TypeExpr(exprB);
Expand Down Expand Up @@ -335,12 +345,13 @@ namespace Nemerle.Core
Message.Error(exprA.Location, $"Can't infer type of left operand ($exprA) of the `??' operator");
None()

| Some (Class (tiA, _)) when tiA.IsValueType && !isNullable(tiA) =>
| Some (Class(tiA, _)) when isHasValuePattern(tiA) => resolve(isHasValuePattern, lastTry)
| Some (Class(tiA, _)) when tiA.IsValueType && !isNullable(tiA) =>
Message.Error(exprA.Location, $"Left operand ($exprA) of the `??' operator should be reference or nullable type ");
None()

| Some (Class (tiA, _)) when isNullable(tiA) => resolve(isNullable, lastTry)
| Some (Class (tiA, [_])) when isOption(tiA) => resolve(isOption, lastTry)
| Some (Class(tiA, _)) when isNullable(tiA) => resolve(isNullable, lastTry)
| Some (Class(tiA, [_])) when isOption(tiA) => resolve(isOption, lastTry)
| _ => Some(<[ if ($exprA != null) $exprA else $exprB ]>)
}
}
Expand Down

0 comments on commit e7d2523

Please sign in to comment.