Skip to content

Commit

Permalink
Minor refactoring + README update.
Browse files Browse the repository at this point in the history
  • Loading branch information
jwaliszko committed Sep 17, 2017
1 parent fa765b3 commit eb408ff
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 14 deletions.
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ A small .NET and JavaScript library which provides annotation-based conditional
- [How to control frequency of dependent fields validation?](#how-to-control-frequency-of-dependent-fields-validation) <sup>(re client-side)</sup>
- [Can I increase web console verbosity for debug purposes?](#can-i-increase-web-console-verbosity-for-debug-purposes) <sup>(re client-side)</sup>
- [I prefer enum values to be rendered as numbers, is it allowed?](#i-prefer-enum-values-to-be-rendered-as-numbers-is-it-allowed) <sup>(re client-side)</sup>
- [How to access one method from another?](#how-to-access-one-method-from-another) <sup>(re client-side)</sup>
- [How to fetch field's value or its display name in error message?](#how-to-fetch-fields-value-or-its-display-name-in-error-message) <sup>(re client and server-side)</sup>
- [Is there any event raised when validation is done?](#is-there-any-event-raised-when-validation-is-done) <sup>(re client-side)</sup>
- [Can I decorate conditionally required fields with asterisks?](#can-i-decorate-conditionally-required-fields-with-asterisks) <sup>(re client-side)</sup>
Expand Down Expand Up @@ -771,6 +772,22 @@ There is a possibility to setup of how enumeration values are internally process

This setting should be consistent with the way of how input fields values are stored in HTML, e.g. `@Html.EditorFor(m => m.EnumValue)` renders to string identifier by default, in contrast to `@Html.EditorFor("EnumValue", (int)Model.EnumValue)` statement, where value is explicitly casted to `int`. The flag setup should reflect that behavior, to have the internal JS model context deserialized accordingly.

##### <a id="how-to-access-one-method-from-another">How to access one method from another?</a>

Through `this`. You may want to turn the `registerAllMethods` option on. When enabled, EA attempts to register all of the methods within the model context, unless naming conflict with field identifier occurs - registration of such a particular method is then skipped.

```JavaScript
<script>
ea.settings.registerAllMethods = true;

ea.addMethod('MethodA', function() {
...
});
ea.addMethod('MethodB', function() {
return this.MethodA();
});
```

##### <a id="how-to-fetch-fields-value-or-its-display-name-in-error-message">How to fetch field's value or its display name in error message?</a>

* to get a value, wrap the field name in braces, e.g. `{field}`, or for nested fields - `{field.field}`,
Expand Down Expand Up @@ -869,7 +886,7 @@ For the needs of this example, the code above makes assumptions:
</li>
```

* implicit data-val-required attributes addition is disabled for value types in HTML (edit `Global.asax`):
* implicit `data-val-required` attributes addition is disabled for value types in HTML (edit `Global.asax`):

```C#
protected void Application_Start()
Expand Down
4 changes: 4 additions & 0 deletions src/ExpressiveAnnotations.Tests/ParserTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1564,6 +1564,10 @@ public void verify_various_parsing_errors()
Assert.Equal("Expected subproperty identifier. Unexpected end of expression.", e.Error);
Assert.Equal(new Location(1, 6), e.Location, new LocationComparer());

e = Assert.Throws<ParseErrorException>(() => parser.Parse<object, bool>("1 ? 2 : 3"));
Assert.Equal("Argument must be of type 'System.Boolean'.", e.Error);
Assert.Equal(new Location(1, 1), e.Location, new LocationComparer());

e = Assert.Throws<ParseErrorException>(() => parser.Parse<object, bool>("[0][1 > 0 ? 0*2.0 : ''] == 1"));
Assert.Equal("Type of conditional expression cannot be determined because there is no implicit conversion between 'System.Double' and 'System.String'.", e.Error);
Assert.Equal(new Location(1, 11), e.Location, new LocationComparer());
Expand Down
10 changes: 4 additions & 6 deletions src/ExpressiveAnnotations/Analysis/Expr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ public Expression Divide(Expression arg1, Expression arg2, Token oper)
{
var type1 = arg1.Type;
var type2 = arg2.Type;
Wall.Mul(arg1, arg2, type1, type2, oper);
TypeAdapter.MakeTypesCompatible(arg1, arg2, out arg1, out arg2, oper.Type);
Wall.Mul(arg1, arg2, type1, type2, oper);

try
{
Expand Down Expand Up @@ -361,14 +361,12 @@ public Expression OnesComplement(Expression arg, Token oper)
}
}

public Expression Condition(Expression arg1, Expression arg2, Expression arg3, Token start, Token oper)
public Expression Condition(Expression arg1, Expression arg2, Expression arg3, Token start, Token qmark)
{
Wall.OfType<bool>(arg1, start.Location);

var type2 = arg2.Type;
var type3 = arg3.Type;
TypeAdapter.MakeTypesCompatible(arg2, arg3, out arg2, out arg3, oper.Type);
Wall.Cond(arg2, arg3, type2, type3, oper.Location);
TypeAdapter.MakeTypesCompatible(arg2, arg3, out arg2, out arg3, qmark.Type);
Wall.Cond(arg1, arg2, arg3, type2, type3, start.Location, qmark.Location);

return Expression.Condition(arg1, arg2, arg3);
}
Expand Down
16 changes: 9 additions & 7 deletions src/ExpressiveAnnotations/Analysis/TypeWall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,19 @@ public void Unary(Expression arg, Token oper)
$"Operator '{oper.Value}' cannot be applied to operand of type 'null'.", ExprString, oper.Location);
}

public void Cond(Expression arg1, Expression arg2, Type type1, Type type2, Location pos)
public void Cond(Expression arg1, Expression arg2, Expression arg3, Type type2, Type type3, Location start, Location qmark)
{
if (arg1.IsNullLiteral() && !arg2.IsNullLiteral())
OfType<bool>(arg1, start);

if (arg2.IsNullLiteral() && !arg3.IsNullLiteral())
throw new ParseErrorException(
$"Type of conditional expression cannot be determined because there is no implicit conversion between 'null' and '{type2}'.", ExprString, pos);
if (!arg1.IsNullLiteral() && arg2.IsNullLiteral())
$"Type of conditional expression cannot be determined because there is no implicit conversion between 'null' and '{type3}'.", ExprString, qmark);
if (!arg2.IsNullLiteral() && arg3.IsNullLiteral())
throw new ParseErrorException(
$"Type of conditional expression cannot be determined because there is no implicit conversion between '{type1}' and 'null'.", ExprString, pos);
if (arg1.Type != arg2.Type)
$"Type of conditional expression cannot be determined because there is no implicit conversion between '{type2}' and 'null'.", ExprString, qmark);
if (arg2.Type != arg3.Type)
throw new ParseErrorException(
$"Type of conditional expression cannot be determined because there is no implicit conversion between '{type1}' and '{type2}'.", ExprString, pos);
$"Type of conditional expression cannot be determined because there is no implicit conversion between '{type2}' and '{type3}'.", ExprString, qmark);
}

public void OfType<T>(Expression arg, Location pos)
Expand Down

0 comments on commit eb408ff

Please sign in to comment.