diff options
author | Marek Safar <marek.safar@gmail.com> | 2013-09-04 13:28:02 +0400 |
---|---|---|
committer | Marek Safar <marek.safar@gmail.com> | 2013-09-04 13:28:02 +0400 |
commit | 6bf50d107b2edd1d8b459624b93ff46680ec04b8 (patch) | |
tree | 4609203b67cb1b057505ccdac85775f5800a9834 | |
parent | 98aef175b229fcd52f5e88d3a71d71143c1818b3 (diff) |
Implements is operator with expression as typeplayscript-mono
-rw-r--r-- | mcs/class/PlayScript.Core/PlayScript.Runtime/Operations.cs | 11 | ||||
-rw-r--r-- | mcs/mcs/convert.cs | 15 | ||||
-rw-r--r-- | mcs/mcs/ecore.cs | 20 | ||||
-rw-r--r-- | mcs/mcs/expression.cs | 26 | ||||
-rw-r--r-- | mcs/mcs/playscript.cs | 58 | ||||
-rw-r--r-- | mcs/mcs/ps-parser.jay | 69 | ||||
-rw-r--r-- | mcs/tests/test-ps-044.play | 18 | ||||
-rw-r--r-- | mcs/tests/test-ps-045.play | 55 |
8 files changed, 214 insertions, 58 deletions
diff --git a/mcs/class/PlayScript.Core/PlayScript.Runtime/Operations.cs b/mcs/class/PlayScript.Core/PlayScript.Runtime/Operations.cs index 450e0d96e7a..7986ec15ba0 100644 --- a/mcs/class/PlayScript.Core/PlayScript.Runtime/Operations.cs +++ b/mcs/class/PlayScript.Core/PlayScript.Runtime/Operations.cs @@ -150,6 +150,17 @@ namespace PlayScript.Runtime return type; } + + public static bool IsOfType<T> (ref T instance, Type expectedType) + { + if (expectedType == null) + throw new _root.TypeError (_root.Error.getErrorMessage (1009), 1009); + + if (instance == null) + return false; + + return expectedType.IsAssignableFrom (instance.GetType ()); + } public static string TypeOf (object instance) { diff --git a/mcs/mcs/convert.cs b/mcs/mcs/convert.cs index 78838ff6d3b..df424cc3db1 100644 --- a/mcs/mcs/convert.cs +++ b/mcs/mcs/convert.cs @@ -231,7 +231,13 @@ namespace Mono.CSharp { return true; // PS builtin types erasure - return target_type.BuiltinType == BuiltinTypeSpec.Type.String && expr_type.BuiltinType == BuiltinTypeSpec.Type.String; + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.String: + case BuiltinTypeSpec.Type.Type: + return target_type.BuiltinType == expr_type.BuiltinType; + default: + return false; + } } // @@ -1357,6 +1363,7 @@ namespace Mono.CSharp { if (expr_type.BuiltinType != BuiltinTypeSpec.Type.None) { switch (expr_type.BuiltinType) { case BuiltinTypeSpec.Type.String: + case BuiltinTypeSpec.Type.Type: if (expr_type.BuiltinType == target_type.BuiltinType) return expr; @@ -1471,9 +1478,13 @@ namespace Mono.CSharp { // // PS builtin types unification // - if (expr_type.BuiltinType == BuiltinTypeSpec.Type.String) { + switch (expr_type.BuiltinType) { + case BuiltinTypeSpec.Type.String: + case BuiltinTypeSpec.Type.Type: if (expr_type.BuiltinType == target_type.BuiltinType) return expr; + + break; } return null; diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs index 8bcd1459d63..df6b68cdf51 100644 --- a/mcs/mcs/ecore.cs +++ b/mcs/mcs/ecore.cs @@ -449,8 +449,7 @@ namespace Mono.CSharp { { if (eclass != ExprClass.Unresolved) { if ((flags & ExprClassToResolveFlags) == 0) { - Error_UnexpectedKind (ec, flags, loc); - return null; + return ResolveUnexpectedKind (ec, flags); } return this; @@ -464,8 +463,7 @@ namespace Mono.CSharp { return null; if ((flags & e.ExprClassToResolveFlags) == 0) { - e.Error_UnexpectedKind (ec, flags, loc); - return null; + return e.ResolveUnexpectedKind (ec, flags); } if (e.type == null) @@ -547,6 +545,12 @@ namespace Mono.CSharp { return c; } + protected virtual Expression ResolveUnexpectedKind (ResolveContext rc, ResolveFlags flags) + { + Error_UnexpectedKind (rc, flags, loc); + return null; + } + public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) { rc.Module.Compiler.Report.Error (182, loc, @@ -2923,6 +2927,14 @@ namespace Mono.CSharp { loc = l; } + protected override Expression ResolveUnexpectedKind (ResolveContext rc, ResolveFlags flags) + { + if (rc.IsPlayScriptType) + return new PlayScript.ImplicitTypeOf (this, loc).Resolve (rc); + + return base.ResolveUnexpectedKind (rc, flags); + } + public sealed override TypeSpec ResolveAsType (IMemberContext ec) { return type; diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs index 15c6f9507c0..3df0a0a6e18 100644 --- a/mcs/mcs/expression.cs +++ b/mcs/mcs/expression.cs @@ -1339,27 +1339,32 @@ namespace Mono.CSharp protected override Expression DoResolve (ResolveContext ec) { - probe_type_expr = ProbeType.ResolveAsType (ec); - if (probe_type_expr == null) - return null; - expr = expr.Resolve (ec); if (expr == null) return null; + return ResolveProbeType (ec); + } + + protected virtual Expression ResolveProbeType (ResolveContext rc) + { + probe_type_expr = ProbeType.ResolveAsType (rc); + if (probe_type_expr == null) + return null; + if (probe_type_expr.IsStatic) { - ec.Report.Error (-244, loc, "The `{0}' operator cannot be applied to an operand of a static type", + rc.Report.Error (-244, loc, "The `{0}' operator cannot be applied to an operand of a static type", OperatorName); } - + if (expr.Type.IsPointer || probe_type_expr.IsPointer) { - ec.Report.Error (244, loc, "The `{0}' operator cannot be applied to an operand of pointer type", + rc.Report.Error (244, loc, "The `{0}' operator cannot be applied to an operand of pointer type", OperatorName); return null; } if (expr.Type == InternalType.AnonymousMethod) { - ec.Report.Error (837, loc, "The `{0}' operator cannot be applied to a lambda expression or anonymous method", + rc.Report.Error (837, loc, "The `{0}' operator cannot be applied to a lambda expression or anonymous method", OperatorName); return null; } @@ -1447,8 +1452,9 @@ namespace Mono.CSharp protected override Expression DoResolve (ResolveContext ec) { - if (base.DoResolve (ec) == null) - return null; + var pexpr = base.DoResolve (ec); + if (pexpr != this) + return pexpr; TypeSpec d = expr.Type; bool d_is_nullable = false; diff --git a/mcs/mcs/playscript.cs b/mcs/mcs/playscript.cs index 7e017924fe6..f8778787e88 100644 --- a/mcs/mcs/playscript.cs +++ b/mcs/mcs/playscript.cs @@ -855,6 +855,45 @@ namespace Mono.PlayScript } } + public class Is : CSharp.Is + { + public Is (Expression expr, Expression probeType, Location loc) + : base (expr, probeType, loc) + { + } + + protected override Expression ResolveProbeType (ResolveContext rc) + { + probe_type_expr = ProbeType.TryToResolveAsType (rc); + if (probe_type_expr != null) + return this; + + var probe_type = ProbeType.Resolve (rc); + if (probe_type == null) + return null; + + probe_type = CSharp.Convert.ImplicitConversionRequired (rc, probe_type, rc.Module.PlayscriptTypes.Class, loc); + if (probe_type == null) + return null; + + var ms = rc.Module.PlayScriptMembers.OperationsIsOfType.Resolve (loc); + if (ms == null) + return null; + + var mg = MethodGroupExpr.CreatePredefined (ms, ms.DeclaringType, loc); + var targs = new TypeArguments ( + new TypeExpression (expr.Type, loc)); + targs.Resolve (rc); + mg.SetTypeArguments (rc, targs); + + var call_args = new Arguments (1); + call_args.Add (new Argument (expr, Argument.AType.Ref)); + call_args.Add (new Argument (probe_type)); + + return new Invocation (mg, call_args).Resolve (rc); + } + } + class ImplicitTypeOf : CSharp.TypeOf { public ImplicitTypeOf (TypeExpression expr, Location loc) @@ -2698,6 +2737,11 @@ namespace Mono.PlayScript Module.PlayscriptAttributes.PlayScript.EmitAttribute (TypeBuilder); } + + public override string GetSignatureForError () + { + return null; + } } class PredefinedTypes @@ -2803,14 +2847,10 @@ namespace Mono.PlayScript }, "length"); } - if (Error.Define ()) { - tostring = MemberCache.FindMember (Error.TypeSpec.BaseType, tostring_filter, BindingRestriction.DeclaredOnly) as MethodSpec; - if (tostring != null) { - Error.TypeSpec.MemberCache.AddMember ( - new MethodSpec (MemberKind.Method, Error.TypeSpec, tostring.MemberDefinition, tostring.ReturnType, tostring.Parameters, tostring.Modifiers), - "toString"); - Console.WriteLine ("aa"); - } + if (Error.Define () && tostring != null) { + Error.TypeSpec.MemberCache.AddMember ( + new MethodSpec (MemberKind.Method, Error.TypeSpec, tostring.MemberDefinition, tostring.ReturnType, tostring.Parameters, tostring.Modifiers), + "toString"); } } } @@ -2828,6 +2868,7 @@ namespace Mono.PlayScript public readonly PredefinedMember<MethodSpec> BinderDelegateInvoke; public readonly PredefinedMember<MethodSpec> OperationsTypeOf; public readonly PredefinedMember<MethodSpec> OperationsClassOf; + public readonly PredefinedMember<MethodSpec> OperationsIsOfType; public readonly PredefinedMember<MethodSpec> DefaultObjectContextCreate; public readonly PredefinedMember<MethodSpec> DefaultObjectContextRegister; public readonly PredefinedMember<MethodSpec> DefaultObjectContextUnregister; @@ -2852,6 +2893,7 @@ namespace Mono.PlayScript BinderHasProperty = new PredefinedMember<MethodSpec> (module, ptypes.Binder, "HasProperty", btypes.Object, btypes.Type, btypes.Object); OperationsTypeOf = new PredefinedMember<MethodSpec> (module, ptypes.Operations, "TypeOf", btypes.Object); OperationsClassOf = new PredefinedMember<MethodSpec> (module, ptypes.Operations, "ClassOf", btypes.Object); + OperationsIsOfType = new PredefinedMember<MethodSpec> (module, ptypes.Operations, CSharp.MemberFilter.Method ("IsOfType", 1, null, null)); DefaultObjectContextCreate = new PredefinedMember<MethodSpec> (module, ptypes.DefaultObjectContext, "Create"); DefaultObjectContextRegister = new PredefinedMember<MethodSpec> (module, ptypes.DefaultObjectContext, "Register", btypes.Object); DefaultObjectContextUnregister = new PredefinedMember<MethodSpec> (module, ptypes.DefaultObjectContext, "Unregister"); diff --git a/mcs/mcs/ps-parser.jay b/mcs/mcs/ps-parser.jay index 721c0ca7f70..12fb7eb557a 100644 --- a/mcs/mcs/ps-parser.jay +++ b/mcs/mcs/ps-parser.jay @@ -2570,6 +2570,7 @@ primary_expression | object_initializer | e4x_operators | expression_series + | builtin_types ; expression_series @@ -2644,12 +2645,12 @@ member_access $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); lbag.AddLocation ($$, GetLocation ($2)); } - | builtin_types DOT identifier_inside_body opt_type_argument_list - { - var lt = (LocatedToken) $3; - $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); - lbag.AddLocation ($$, GetLocation ($2)); - } +// | builtin_types DOT identifier_inside_body opt_type_argument_list +// { +// var lt = (LocatedToken) $3; +// $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); +// lbag.AddLocation ($$, GetLocation ($2)); +// } | SUPER DOT IDENTIFIER opt_type_argument_list { var lt = (LocatedToken) $3; @@ -2679,14 +2680,14 @@ member_access var lt = (LocatedToken) $3; $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); } - | builtin_types DOT GENERATE_COMPLETION - { - $$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location); - } - | builtin_types DOT IDENTIFIER GENERATE_COMPLETION { - var lt = (LocatedToken) $3; - $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); - } +// | builtin_types DOT GENERATE_COMPLETION +// { +// $$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location); +// } +// | builtin_types DOT IDENTIFIER GENERATE_COMPLETION { +// var lt = (LocatedToken) $3; +// $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); +// } ; e4x_operators @@ -2758,11 +2759,11 @@ invocation_expression $$ = new SuperBaseInitializer ((Arguments) $3, GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } - | builtin_types open_parens_any opt_argument_list close_parens - { - $$ = new Invocation ((Expression) $1, (Arguments) $3); - lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); - } +// | builtin_types open_parens_any opt_argument_list close_parens +// { +// $$ = new Invocation ((Expression) $1, (Arguments) $3); +// lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); +// } | primary_expression open_parens_any opt_argument_list close_parens { $$ = new Invocation ((Expression) $1, (Arguments) $3); @@ -2995,21 +2996,21 @@ element_access Error_SyntaxError (yyToken); $$ = new ElementAccess ((Expression) $1, null, GetLocation ($2)); } - | builtin_types OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET - { - $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2)); - lbag.AddLocation ($$, GetLocation ($4)); - } - | builtin_types OPEN_BRACKET_EXPR expression_list_arguments error - { - Error_SyntaxError (yyToken); - $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2)); - } - | builtin_types OPEN_BRACKET_EXPR error - { - Error_SyntaxError (yyToken); - $$ = new ElementAccess ((Expression) $1, null, GetLocation ($2)); - } +// | builtin_types OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET +// { +// $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2)); +// lbag.AddLocation ($$, GetLocation ($4)); +// } +// | builtin_types OPEN_BRACKET_EXPR expression_list_arguments error +// { +// Error_SyntaxError (yyToken); +// $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2)); +// } +// | builtin_types OPEN_BRACKET_EXPR error +// { +// Error_SyntaxError (yyToken); +// $$ = new ElementAccess ((Expression) $1, null, GetLocation ($2)); +// } ; expression_list diff --git a/mcs/tests/test-ps-044.play b/mcs/tests/test-ps-044.play new file mode 100644 index 00000000000..eeb0d692bb1 --- /dev/null +++ b/mcs/tests/test-ps-044.play @@ -0,0 +1,18 @@ +package
+{
+ class ImplicitTypeConversion
+ {
+ public static function Test (expectedType:*):void
+ {
+ }
+
+ public static function Main ():int
+ {
+ var v1:Class = int;
+ var c:Class = String;
+ Test (int);
+
+ return 0;
+ }
+ }
+}
diff --git a/mcs/tests/test-ps-045.play b/mcs/tests/test-ps-045.play new file mode 100644 index 00000000000..814a6e80edb --- /dev/null +++ b/mcs/tests/test-ps-045.play @@ -0,0 +1,55 @@ +package
+{
+ class ProbingIsOperator
+ {
+ public static function expectType1 (expectedType:*, actualObject:*):Boolean
+ {
+ var result:Boolean = (actualObject is expectedType);
+ return result;
+ }
+
+ public static function expectType2 (expectedType:Class, actualObject:Object):Boolean
+ {
+ return actualObject is expectedType;
+ }
+
+ public static function Main():int
+ {
+ if (!expectType1 (int, 1))
+ return 1;
+
+ if (expectType1 (int, "1"))
+ return 2;
+
+ if (!expectType1 (String, "1"))
+ return 3;
+
+ if (!expectType1 (Object, "1"))
+ return 4;
+
+ if (!expectType1 (Object, 4.3))
+ return 5;
+
+ if (expectType1 (Object, null))
+ return 6;
+
+ if (!expectType2 (int, 1))
+ return 10;
+
+ if (expectType2 (int, "1"))
+ return 11;
+
+ if (!expectType2 (String, "1"))
+ return 12;
+
+ if (!expectType2 (Object, "1"))
+ return 13;
+
+ if (!expectType2 (Object, 4.3))
+ return 14;
+
+ return 0;
+ }
+ }
+}
+
|