Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix] Add missing selectors for NSExpression. #57

Merged
merged 1 commit into from
May 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions src/Foundation/NSExpression.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// TODO: The NSExpression class is a cluster class in cococa. This means that now all the properties are supported by all the types of NSExpressions.
// At the point of this written all the properties have been tested with all types EXCEPT NSExpressionType.Subquery and NSExpressionType.Conditional because writting
// tests for those was not possible. The properties for these two types have been deduced from the other types yet bugs are possible and an objc excection will be thrown.
using System;
using System.Runtime.InteropServices;
using XamCore.ObjCRuntime;

namespace XamCore.Foundation {

public partial class NSExpression {

[Export ("arguments")]
public virtual NSExpression[] Arguments {
get {
var type = ExpressionType;
if (type != NSExpressionType.Function && type != NSExpressionType.Block && type != NSExpressionType.KeyPath)
throw new InvalidOperationException (
$"NSExpressions of type {type} do not support the Arguments property. Expressions that support the property "
+ "are of type Function, Block and KeyPath");
return _Arguments;
}
}


[Export ("collection")]
public virtual NSObject Collection {
get {
var type = ExpressionType;
if (type != NSExpressionType.NSAggregate)
throw new InvalidOperationException (
$"NSExpressions of type {type} do not support the Collection property. Expressions that support the property "
+ "are of type NSAggregate");
return _Collection;
}
}

[Export ("predicate")]
public virtual NSPredicate Predicate {
get {
var type = ExpressionType;
if (type != NSExpressionType.Conditional && type != NSExpressionType.Subquery)
throw new InvalidOperationException (
$"NSExpressions of type {type} do not support the Predicate property. Expressions that support the property "
+ "are of type Conditional and Subquery");
return _Predicate;
}
}

[Export ("expressionBlock")]
public virtual NSExpressionCallbackHandler Block {
get {
if (ExpressionType != NSExpressionType.Block)
throw new InvalidOperationException (
$"NSExpressions of type {ExpressionType} do not support the Block property. Expressions that support the property "
+ "are created via the FromFunction (NSExpressionHandler target, NSExpression[] parameters) method.");
return _Block;
}
}

[Export ("constantValue")]
public virtual NSObject ConstantValue {
get {
if (ExpressionType != NSExpressionType.ConstantValue)
throw new InvalidOperationException (
$"NSExpressions of type {ExpressionType} do not support the ConstantValue property. Expressions that support the property "
+ "are created via the FromConstant methods.");
return _ConstantValue;
}
}

[Export ("keyPath")]
public virtual string KeyPath {
get {
if (ExpressionType != NSExpressionType.KeyPath)
throw new InvalidOperationException (
$"NSExpressions of type {ExpressionType} do not support the KeyPath property. Expressions that support the property "
+ "are created via the FromKeyPath method.");
return _KeyPath;
}
}

[Export ("leftExpression")]
public virtual NSExpression LeftExpression {
get {
var type = ExpressionType;
if (type != NSExpressionType.Conditional && type != NSExpressionType.IntersectSet && type != NSExpressionType.MinusSet
&& type != NSExpressionType.Subquery && type != NSExpressionType.UnionSet)
throw new InvalidOperationException (
$"NSExpressions of type {type} do not support the LeftExpression property. Expressions that support the property "
+ "are of type Conditional, IntersectSet, MinusSet, Subquery or UnionSet");
return _LeftExpression;
}
}

[Mac(10,11),iOS(9,0)]
[Export ("trueExpression")]
public virtual NSExpression TrueExpression {
get {
var type = ExpressionType;
if (type != NSExpressionType.Conditional && type != NSExpressionType.Subquery)
throw new InvalidOperationException (
$"NSExpressions of type {type} do not support the TrueExpression property. Expressions that support the property "
+ "are of type Conditional and Subquery");
return _TrueExpression;
}
}

[Mac(10,11),iOS(9,0)]
[Export ("falseExpression")]
public virtual NSExpression FalseExpression {
get {
var type = ExpressionType;
if (type != NSExpressionType.Conditional && type != NSExpressionType.Subquery)
throw new InvalidOperationException (
$"NSExpressions of type {type} do not support the FalseExpression property. Expressions that support the property "
+ "are of type Conditional and Subquery");
return _FalseExpression;
}
}

[Export ("rightExpression")]
public virtual NSExpression RightExpression {
get {
var type = ExpressionType;
if (type != NSExpressionType.Conditional && type != NSExpressionType.IntersectSet && type != NSExpressionType.MinusSet
&& type != NSExpressionType.Subquery && type != NSExpressionType.UnionSet)
throw new InvalidOperationException (
$"NSExpressions of type {type} do not support the RightExpression property. Expressions that support the property "
+ "are of type Conditional, IntersectSet, MinusSet, Subquery or UnionSet");
return _RightExpression;
}
}

[Export ("function")]
public virtual string Function {
get {
if (ExpressionType != NSExpressionType.Function)
throw new InvalidOperationException (
$"NSExpressions of type {ExpressionType} do not support the Function property. Expressions that support the property "
+ "are created via the FromFunction (FromFunction (string name, NSExpression[] parameters) or FromFormat methods.");
return _Function;
}
}

[Export ("variable")]
public virtual string Variable {
get {
if (ExpressionType != NSExpressionType.Variable)
throw new InvalidOperationException (
$"NSExpressions of type {ExpressionType} do not support the Function property. Expressions that support the property "
+ "are created via the FromVariable method.");
return _Variable;
}
}

[Export ("operand")]
public virtual NSExpression Operand {
get {
var type = ExpressionType;
if (type != NSExpressionType.KeyPath && type != NSExpressionType.Function)
throw new InvalidOperationException (
$"NSExpressions of type {type} do not support the Arguments property. Expressions that support the property "
+ "are of type Function, Block and KeyPath");
return _Operand;
}
}
}
}
85 changes: 56 additions & 29 deletions src/foundation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3152,8 +3152,11 @@ public interface NSException : NSCoding, NSCopying {
string[] CallStackSymbols { get; }
}

#if !XAMCORE_4_0
[Obsolete("NSExpressionHandler is deprecated, please use FromFormat (string, NSObject[]) instead.")]
public delegate void NSExpressionHandler (NSObject evaluatedObject, NSExpression [] expressions, NSMutableDictionary context);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since it's unused by Xamarin.*.dll, except for obsolete API, it should be:

  1. decorated with it's own [Obsolete] attribute, so external usage of the delegate trigger warnings (and code reviews);
  2. under a #if !XAMCORE_4_0 block so our next, if ever, breaking changes release can drop it;


#endif
public delegate NSObject NSExpressionCallbackHandler (NSObject evaluatedObject, NSExpression [] expressions, NSMutableDictionary context);
[BaseType (typeof (NSObject))]
// Objective-C exception thrown. Name: NSInvalidArgumentException Reason: *** -predicateFormat cannot be sent to an abstract object of class NSExpression: Create a concrete instance!
[DisableDefaultCtor]
Expand All @@ -3173,9 +3176,18 @@ public interface NSExpression : NSSecureCoding, NSCopying {
[Static, Export ("expressionForFunction:arguments:")]
NSExpression FromFunction (string name, NSExpression[] parameters);

[Static, Export ("expressionWithFormat:argumentArray:")]
[Static, Export ("expressionWithFormat:")]
NSExpression FromFormat (string expressionFormat);

#if !XAMCORE_4_0
[Obsolete("FromFormat (string, NSExpression[]) is deprecated, please use FromFormat (string, NSObject[]) instead.")]
[Sealed, Static, Export ("expressionWithFormat:argumentArray:")]
NSExpression FromFormat (string format, NSExpression [] parameters);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

under a #if !XAMCORE_4_0 block


#endif

[Static, Export ("expressionWithFormat:argumentArray:")]
NSExpression FromFormat (string format, NSObject [] parameters);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the confusion comes from

@property (nullable, readonly, copy) NSArray<NSExpression *> *arguments;

but your tests shows it works... what does arguments shows on them ? (I'll try it out later)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe those arguments there are for the subclass that takes a function and not a format. Lets TDD to get this right. I'll write all the tests for the expected behaviour and change the bindings accordingly.


//+ (NSExpression *)expressionForAggregate:(NSArray *)subexpressions;
[Static, Export ("expressionForAggregate:")]
NSExpression FromAggregate (NSExpression [] subexpressions);
Expand All @@ -3196,8 +3208,14 @@ public interface NSExpression : NSSecureCoding, NSCopying {
[Static, Export ("expressionForFunction:selectorName:arguments:")]
NSExpression FromFunction (NSExpression target, string name, NSExpression[] parameters);

[Static, Export ("expressionForBlock:arguments:")]
#if !XAMCORE_4_0
[Obsolete("FromFunction (NSExpressionHandler, NSExpression[]) is deprecated, please use FromFunction (NSExpressionCallbackHandler, NSExpression[]) instead.")]
[Sealed, Static, Export ("expressionForBlock:arguments:")]
NSExpression FromFunction (NSExpressionHandler target, NSExpression[] parameters);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put inside a #if !XAMCORE_4_0 block

#endif

[Static, Export ("expressionForBlock:arguments:")]
NSExpression FromFunction (NSExpressionCallbackHandler target, NSExpression[] parameters);

[Since (7,0), Mavericks]
[Static]
Expand All @@ -3220,46 +3238,55 @@ public interface NSExpression : NSSecureCoding, NSCopying {
[Export ("expressionType")]
NSExpressionType ExpressionType { get; }

[Export ("constantValue")]
NSObject ConstantValue { get; }
[Sealed, Internal, Export ("expressionBlock")]
NSExpressionCallbackHandler _Block { get; }

[Export ("keyPath")]
string KeyPath { get; }
[Sealed, Internal, Export ("constantValue")]
NSObject _ConstantValue { get; }

[Export ("function")]
string Function { get; }
[Sealed, Internal, Export ("keyPath")]
string _KeyPath { get; }

[Export ("variable")]
string Variable { get; }
[Sealed, Internal, Export ("function")]
string _Function { get; }

[Export ("operand")]
NSExpression Operand { get; }
[Sealed, Internal, Export ("variable")]
string _Variable { get; }

[Export ("arguments")]
NSExpression[] Arguments { get; }
[Sealed, Internal, Export ("operand")]
NSExpression _Operand { get; }

[Export ("collection")]
NSObject Collection { get; }
[Sealed, Internal, Export ("arguments")]
NSExpression[] _Arguments { get; }

[Export ("predicate")]
NSPredicate Predicate { get; }
[Sealed, Internal, Export ("collection")]
NSObject _Collection { get; }

[Export ("leftExpression")]
NSExpression LeftExpression { get; }
[Sealed, Internal, Export ("predicate")]
NSPredicate _Predicate { get; }

[Export ("rightExpression")]
NSExpression RightExpression { get; }
[Sealed, Internal, Export ("leftExpression")]
NSExpression _LeftExpression { get; }

[Sealed, Internal, Export ("rightExpression")]
NSExpression _RightExpression { get; }

[Mac(10,11),iOS(9,0)]
[Export ("trueExpression")]
NSExpression TrueExpression { get; }
[Sealed, Internal, Export ("trueExpression")]
NSExpression _TrueExpression { get; }

[Mac(10,11),iOS(9,0)]
[Export ("falseExpression")]
NSExpression FalseExpression { get; }
[Sealed, Internal, Export ("falseExpression")]
NSExpression _FalseExpression { get; }

#if !XAMCORE_4_0
[Obsolete("ValueWithObject is deprecated, please use EvaluateWith instead.")]
[Sealed, Export ("expressionValueWithObject:context:")]
NSExpression ExpressionValueWithObject (NSObject object1, NSMutableDictionary context);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

under a #if !XAMCORE_4_0 block

#endif

[Export ("expressionValueWithObject:context:")]
NSExpression ExpressionValueWithObject (NSObject object1, NSMutableDictionary context);
NSObject EvaluateWith ([NullAllowed] NSObject obj, [NullAllowed] NSMutableDictionary context);
}

[iOS (8,0)][Mac (10,10, onlyOn64 : true)] // Not defined in 32-bit
Expand Down
1 change: 1 addition & 0 deletions src/frameworks.sources
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ FOUNDATION_SOURCES = \
Foundation/NSDirectoryEnumerator.cs \
Foundation/NSDistributedNotificationCenter.cs \
Foundation/NSErrorException.cs \
Foundation/NSExpression.cs \
Foundation/NSExtension.cs \
Foundation/NSFastEnumerationState.cs \
Foundation/NSFastEnumerator.cs \
Expand Down