Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@ -0,0 +1,96 @@
//
// Binder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Linq.Expressions;
using System.Reflection;
namespace Microsoft.CSharp.RuntimeBinder
{
public static class Binder
{
public static CallSiteBinder BinaryOperation (CSharpBinderFlags flags, ExpressionType operation, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
{
return new CSharpBinaryOperationBinder (operation, flags, context, argumentInfo);
}
public static CallSiteBinder Convert (CSharpBinderFlags flags, Type type, Type context)
{
return new CSharpConvertBinder (type, context, flags);
}
public static CallSiteBinder GetIndex (CSharpBinderFlags flags, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
{
return new CSharpGetIndexBinder (context, argumentInfo);
}
public static CallSiteBinder GetMember (CSharpBinderFlags flags, string name, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
{
return new CSharpGetMemberBinder (name, context, argumentInfo);
}
public static CallSiteBinder Invoke (CSharpBinderFlags flags, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
{
return new CSharpInvokeBinder (flags, context, argumentInfo);
}
public static CallSiteBinder InvokeConstructor (CSharpBinderFlags flags, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
{
// What are flags for here
return new CSharpInvokeConstructorBinder (context, argumentInfo);
}
public static CallSiteBinder InvokeMember (CSharpBinderFlags flags, string name, IEnumerable<Type> typeArguments, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
{
return new CSharpInvokeMemberBinder (flags, name, context, typeArguments, argumentInfo);
}
public static CallSiteBinder IsEvent (CSharpBinderFlags flags, string name, Type context)
{
return new CSharpIsEventBinder (name, context);
}
public static CallSiteBinder SetIndex (CSharpBinderFlags flags, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
{
return new CSharpSetIndexBinder (flags, context, argumentInfo);
}
public static CallSiteBinder SetMember (CSharpBinderFlags flags, string name, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
{
return new CSharpSetMemberBinder (flags, name, context, argumentInfo);
}
public static CallSiteBinder UnaryOperation (CSharpBinderFlags flags, ExpressionType operation, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
{
return new CSharpUnaryOperationBinder (operation, flags, context, argumentInfo);
}
}
}

View File

@ -0,0 +1,83 @@
//
// CSharpArgumentInfo.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using Compiler = Mono.CSharp;
namespace Microsoft.CSharp.RuntimeBinder
{
public sealed class CSharpArgumentInfo
{
readonly CSharpArgumentInfoFlags flags;
readonly string name;
CSharpArgumentInfo (CSharpArgumentInfoFlags flags, string name)
{
this.flags = flags;
this.name = name;
}
public static CSharpArgumentInfo Create (CSharpArgumentInfoFlags flags, string name)
{
return new CSharpArgumentInfo (flags, name);
}
internal Compiler.Argument.AType ArgumentModifier {
get {
if ((flags & CSharpArgumentInfoFlags.IsRef) != 0)
return Compiler.Argument.AType.Ref;
if ((flags & CSharpArgumentInfoFlags.IsOut) != 0)
return Compiler.Argument.AType.Out;
return Compiler.Argument.AType.None;
}
}
internal static CallInfo CreateCallInfo (IEnumerable<CSharpArgumentInfo> argumentInfo, int skipCount)
{
var named = from arg in argumentInfo.Skip (skipCount) where arg.IsNamed select arg.name;
return new CallInfo (Math.Max (0, argumentInfo.Count () - skipCount), named);
}
internal CSharpArgumentInfoFlags Flags {
get { return flags; }
}
internal bool IsNamed {
get { return (flags & CSharpArgumentInfoFlags.NamedArgument) != 0; }
}
internal string Name {
get { return name; }
}
}
}

View File

@ -0,0 +1,44 @@
//
// CSharpArgumentInfoFlags.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
namespace Microsoft.CSharp.RuntimeBinder
{
[Flags]
public enum CSharpArgumentInfoFlags
{
None = 0,
UseCompileTimeType = 1,
Constant = 2,
NamedArgument = 4,
IsRef = 8,
IsOut = 16,
IsStaticType = 32
}
}

View File

@ -0,0 +1,160 @@
//
// CSharpBinaryOperationBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using Compiler = Mono.CSharp;
namespace Microsoft.CSharp.RuntimeBinder
{
class CSharpBinaryOperationBinder : BinaryOperationBinder
{
IList<CSharpArgumentInfo> argumentInfo;
readonly CSharpBinderFlags flags;
readonly Type context;
public CSharpBinaryOperationBinder (ExpressionType operation, CSharpBinderFlags flags, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
: base (operation)
{
this.argumentInfo = new ReadOnlyCollectionBuilder<CSharpArgumentInfo> (argumentInfo);
if (this.argumentInfo.Count != 2)
throw new ArgumentException ("Binary operation requires 2 arguments");
this.flags = flags;
this.context = context;
}
Compiler.Binary.Operator GetOperator (out bool isCompound)
{
isCompound = false;
switch (Operation) {
case ExpressionType.Add:
return Compiler.Binary.Operator.Addition;
case ExpressionType.AddAssign:
isCompound = true;
return Compiler.Binary.Operator.Addition;
case ExpressionType.And:
return (flags & CSharpBinderFlags.BinaryOperationLogical) != 0 ?
Compiler.Binary.Operator.LogicalAnd : Compiler.Binary.Operator.BitwiseAnd;
case ExpressionType.AndAssign:
isCompound = true;
return Compiler.Binary.Operator.BitwiseAnd;
case ExpressionType.Divide:
return Compiler.Binary.Operator.Division;
case ExpressionType.DivideAssign:
isCompound = true;
return Compiler.Binary.Operator.Division;
case ExpressionType.Equal:
return Compiler.Binary.Operator.Equality;
case ExpressionType.ExclusiveOr:
return Compiler.Binary.Operator.ExclusiveOr;
case ExpressionType.ExclusiveOrAssign:
isCompound = true;
return Compiler.Binary.Operator.ExclusiveOr;
case ExpressionType.GreaterThan:
return Compiler.Binary.Operator.GreaterThan;
case ExpressionType.GreaterThanOrEqual:
return Compiler.Binary.Operator.GreaterThanOrEqual;
case ExpressionType.LeftShift:
return Compiler.Binary.Operator.LeftShift;
case ExpressionType.LeftShiftAssign:
isCompound = true;
return Compiler.Binary.Operator.LeftShift;
case ExpressionType.LessThan:
return Compiler.Binary.Operator.LessThan;
case ExpressionType.LessThanOrEqual:
return Compiler.Binary.Operator.LessThanOrEqual;
case ExpressionType.Modulo:
return Compiler.Binary.Operator.Modulus;
case ExpressionType.ModuloAssign:
isCompound = true;
return Compiler.Binary.Operator.Modulus;
case ExpressionType.Multiply:
return Compiler.Binary.Operator.Multiply;
case ExpressionType.MultiplyAssign:
isCompound = true;
return Compiler.Binary.Operator.Multiply;
case ExpressionType.NotEqual:
return Compiler.Binary.Operator.Inequality;
case ExpressionType.Or:
return (flags & CSharpBinderFlags.BinaryOperationLogical) != 0 ?
Compiler.Binary.Operator.LogicalOr : Compiler.Binary.Operator.BitwiseOr;
case ExpressionType.OrAssign:
isCompound = true;
return Compiler.Binary.Operator.BitwiseOr;
case ExpressionType.OrElse:
return Compiler.Binary.Operator.LogicalOr;
case ExpressionType.RightShift:
return Compiler.Binary.Operator.RightShift;
case ExpressionType.RightShiftAssign:
isCompound = true;
return Compiler.Binary.Operator.RightShift;
case ExpressionType.Subtract:
return Compiler.Binary.Operator.Subtraction;
case ExpressionType.SubtractAssign:
isCompound = true;
return Compiler.Binary.Operator.Subtraction;
default:
throw new NotImplementedException (Operation.ToString ());
}
}
public override DynamicMetaObject FallbackBinaryOperation (DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion)
{
var ctx = DynamicContext.Create ();
var left = ctx.CreateCompilerExpression (argumentInfo [0], target);
var right = ctx.CreateCompilerExpression (argumentInfo [1], arg);
bool is_compound;
var oper = GetOperator (out is_compound);
Compiler.Expression expr;
if (is_compound) {
var target_expr = new Compiler.RuntimeValueExpression (target, ctx.ImportType (target.LimitType));
expr = new Compiler.CompoundAssign (oper, target_expr, right, left);
} else {
expr = new Compiler.Binary (oper, left, right);
}
expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
if ((flags & CSharpBinderFlags.CheckedContext) != 0)
expr = new Compiler.CheckedExpr (expr, Compiler.Location.Null);
var binder = new CSharpBinder (this, expr, errorSuggestion);
binder.AddRestrictions (target);
binder.AddRestrictions (arg);
return binder.Bind (ctx, context);
}
}
}

View File

@ -0,0 +1,128 @@
//
// CSharpBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Linq.Expressions;
using Compiler = Mono.CSharp;
using System.Reflection;
using System.Collections.Generic;
namespace Microsoft.CSharp.RuntimeBinder
{
class CSharpBinder
{
static ConstructorInfo binder_exception_ctor;
static object resolver = new object ();
DynamicMetaObjectBinder binder;
Compiler.Expression expr;
BindingRestrictions restrictions;
DynamicMetaObject errorSuggestion;
public CSharpBinder (DynamicMetaObjectBinder binder, Compiler.Expression expr, DynamicMetaObject errorSuggestion)
{
this.binder = binder;
this.expr = expr;
this.restrictions = BindingRestrictions.Empty;
this.errorSuggestion = errorSuggestion;
}
public Compiler.ResolveContext.Options ResolveOptions { get; set; }
public void AddRestrictions (DynamicMetaObject arg)
{
restrictions = restrictions.Merge (CreateRestrictionsOnTarget (arg));
}
public void AddRestrictions (DynamicMetaObject[] args)
{
restrictions = restrictions.Merge (CreateRestrictionsOnTarget (args));
}
public DynamicMetaObject Bind (DynamicContext ctx, Type callingType)
{
Expression res;
try {
var rc = new Compiler.ResolveContext (new RuntimeBinderContext (ctx, callingType), ResolveOptions);
// Static typemanager and internal caches are not thread-safe
lock (resolver) {
expr = expr.Resolve (rc, Compiler.ResolveFlags.VariableOrValue);
}
if (expr == null)
throw new RuntimeBinderInternalCompilerException ("Expression resolved to null");
res = expr.MakeExpression (new Compiler.BuilderContext ());
} catch (RuntimeBinderException e) {
if (errorSuggestion != null)
return errorSuggestion;
res = CreateBinderException (e.Message);
} catch (Exception) {
if (errorSuggestion != null)
return errorSuggestion;
throw;
}
return new DynamicMetaObject (res, restrictions);
}
Expression CreateBinderException (string message)
{
if (binder_exception_ctor == null)
binder_exception_ctor = typeof (RuntimeBinderException).GetConstructor (new[] { typeof (string) });
//
// Uses target type to keep expressions composition working
//
return Expression.Throw (Expression.New (binder_exception_ctor, Expression.Constant (message)), binder.ReturnType);
}
static BindingRestrictions CreateRestrictionsOnTarget (DynamicMetaObject arg)
{
return arg.HasValue && arg.Value == null ?
BindingRestrictions.GetInstanceRestriction (arg.Expression, null) :
BindingRestrictions.GetTypeRestriction (arg.Expression, arg.LimitType);
}
public static BindingRestrictions CreateRestrictionsOnTarget (DynamicMetaObject[] args)
{
if (args.Length == 0)
return BindingRestrictions.Empty;
var res = CreateRestrictionsOnTarget (args[0]);
for (int i = 1; i < args.Length; ++i)
res = res.Merge (CreateRestrictionsOnTarget (args[i]));
return res;
}
}
}

View File

@ -0,0 +1,47 @@
//
// CSharpBinderFlags.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
namespace Microsoft.CSharp.RuntimeBinder
{
[Flags]
public enum CSharpBinderFlags
{
None = 0,
CheckedContext = 1,
InvokeSimpleName = 1 << 1,
InvokeSpecialName = 1 << 2,
BinaryOperationLogical = 1 << 3,
ConvertExplicit = 1 << 4,
ConvertArrayIndex = 1 << 5,
ResultIndexed = 1 << 6,
ValueFromCompoundAssignment = 1 << 7,
ResultDiscarded = 1 << 8
}
}

View File

@ -0,0 +1,68 @@
//
// CSharpConvertBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using Compiler = Mono.CSharp;
namespace Microsoft.CSharp.RuntimeBinder
{
class CSharpConvertBinder : ConvertBinder
{
readonly CSharpBinderFlags flags;
readonly Type context;
public CSharpConvertBinder (Type type, Type context, CSharpBinderFlags flags)
: base (type, (flags & CSharpBinderFlags.ConvertExplicit) != 0)
{
this.flags = flags;
this.context = context;
}
public override DynamicMetaObject FallbackConvert (DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
var ctx = DynamicContext.Create ();
var expr = ctx.CreateCompilerExpression (null, target);
if (Explicit)
expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (Type), Compiler.Location.Null), expr, Compiler.Location.Null);
else
expr = new Compiler.ImplicitCast (expr, ctx.ImportType (Type), (flags & CSharpBinderFlags.ConvertArrayIndex) != 0);
if ((flags & CSharpBinderFlags.CheckedContext) != 0)
expr = new Compiler.CheckedExpr (expr, Compiler.Location.Null);
var binder = new CSharpBinder (this, expr, errorSuggestion);
binder.AddRestrictions (target);
return binder.Bind (ctx, context);
}
}
}

View File

@ -0,0 +1,71 @@
//
// CSharpGetIndexBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using Compiler = Mono.CSharp;
namespace Microsoft.CSharp.RuntimeBinder
{
class CSharpGetIndexBinder : GetIndexBinder
{
IList<CSharpArgumentInfo> argumentInfo;
Type callingContext;
public CSharpGetIndexBinder (Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
: base (CSharpArgumentInfo.CreateCallInfo (argumentInfo, 1))
{
this.callingContext = callingContext;
this.argumentInfo = argumentInfo.ToReadOnly ();
}
public override DynamicMetaObject FallbackGetIndex (DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion)
{
if (argumentInfo.Count != indexes.Length + 1) {
if (errorSuggestion == null)
throw new NotImplementedException ();
return errorSuggestion;
}
var ctx = DynamicContext.Create ();
var expr = ctx.CreateCompilerExpression (argumentInfo [0], target);
var args = ctx.CreateCompilerArguments (argumentInfo.Skip (1), indexes);
expr = new Compiler.ElementAccess (expr, args, Compiler.Location.Null);
expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
var binder = new CSharpBinder (this, expr, errorSuggestion);
binder.AddRestrictions (target);
binder.AddRestrictions (indexes);
return binder.Bind (ctx, callingContext);
}
}
}

View File

@ -0,0 +1,63 @@
//
// CSharpGetMemberBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using Compiler = Mono.CSharp;
namespace Microsoft.CSharp.RuntimeBinder
{
class CSharpGetMemberBinder : GetMemberBinder
{
IList<CSharpArgumentInfo> argumentInfo;
Type callingContext;
public CSharpGetMemberBinder (string name, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
: base (name, false)
{
this.callingContext = callingContext;
this.argumentInfo = argumentInfo.ToReadOnly ();
}
public override DynamicMetaObject FallbackGetMember (DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
var ctx = DynamicContext.Create ();
var expr = ctx.CreateCompilerExpression (argumentInfo [0], target);
expr = new Compiler.MemberAccess (expr, Name);
expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
var binder = new CSharpBinder (this, expr, errorSuggestion);
binder.AddRestrictions (target);
return binder.Bind (ctx, callingContext);
}
}
}

View File

@ -0,0 +1,70 @@
//
// CSharpInvokeBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using Compiler = Mono.CSharp;
namespace Microsoft.CSharp.RuntimeBinder
{
class CSharpInvokeBinder : InvokeBinder
{
readonly CSharpBinderFlags flags;
IList<CSharpArgumentInfo> argumentInfo;
Type callingContext;
public CSharpInvokeBinder (CSharpBinderFlags flags, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
: base (CSharpArgumentInfo.CreateCallInfo (argumentInfo, 1))
{
this.flags = flags;
this.callingContext = callingContext;
this.argumentInfo = argumentInfo.ToReadOnly ();
}
public override DynamicMetaObject FallbackInvoke (DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
{
var ctx = DynamicContext.Create ();
var expr = ctx.CreateCompilerExpression (argumentInfo [0], target);
var c_args = ctx.CreateCompilerArguments (argumentInfo.Skip (1), args);
expr = new Compiler.Invocation (expr, c_args);
if ((flags & CSharpBinderFlags.ResultDiscarded) == 0)
expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
else
expr = new Compiler.DynamicResultCast (ctx.ImportType (ReturnType), expr);
var binder = new CSharpBinder (this, expr, errorSuggestion);
binder.AddRestrictions (target);
binder.AddRestrictions (args);
return binder.Bind (ctx, callingContext);
}
}
}

View File

@ -0,0 +1,73 @@
//
// CSharpInvokeConstructorBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using Compiler = Mono.CSharp;
namespace Microsoft.CSharp.RuntimeBinder
{
class CSharpInvokeConstructorBinder : DynamicMetaObjectBinder
{
IList<CSharpArgumentInfo> argumentInfo;
Type callingContext;
Type target_return_type;
public CSharpInvokeConstructorBinder (Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
{
this.callingContext = callingContext;
this.argumentInfo = argumentInfo.ToReadOnly ();
}
public override DynamicMetaObject Bind (DynamicMetaObject target, DynamicMetaObject[] args)
{
var ctx = DynamicContext.Create ();
var type = ctx.CreateCompilerExpression (argumentInfo [0], target);
target_return_type = type.Type.GetMetaInfo ();
var c_args = ctx.CreateCompilerArguments (argumentInfo.Skip (1), args);
var binder = new CSharpBinder (
this, new Compiler.New (type, c_args, Compiler.Location.Null), null);
binder.AddRestrictions (target);
binder.AddRestrictions (args);
return binder.Bind (ctx, callingContext);
}
public override Type ReturnType {
get {
return target_return_type;
}
}
}
}

View File

@ -0,0 +1,194 @@
//
// CSharpInvokeMemberBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using Compiler = Mono.CSharp;
using SLE = System.Linq.Expressions;
namespace Microsoft.CSharp.RuntimeBinder
{
class CSharpInvokeMemberBinder : InvokeMemberBinder
{
//
// A custom runtime invocation is needed to deal with member invocation which
// is not real member invocation but invocation on invocalble member.
//
// An example:
// class C {
// dynamic f;
// void Foo ()
// {
// dynamic d = new C ();
// d.f.M ();
// }
//
// The runtime value of `f' can be a delegate in which case we are invoking result
// of member invocation, this is already handled by DoResolveDynamic but we need
// more runtime dependencies which require Microsoft.CSharp assembly reference or
// a lot of reflection calls
//
class Invocation : Compiler.Invocation
{
sealed class RuntimeDynamicInvocation : Compiler.ShimExpression
{
Invocation invoke;
public RuntimeDynamicInvocation (Invocation invoke, Compiler.Expression memberExpr)
: base (memberExpr)
{
this.invoke = invoke;
}
protected override Compiler.Expression DoResolve (Compiler.ResolveContext rc)
{
type = expr.Type;
eclass = Compiler.ExprClass.Value;
return this;
}
//
// Creates an invoke call on invocable expression
//
public override System.Linq.Expressions.Expression MakeExpression (Compiler.BuilderContext ctx)
{
var invokeBinder = invoke.invokeBinder;
var binder = Binder.Invoke (invokeBinder.flags, invokeBinder.callingContext, invokeBinder.argumentInfo);
var args = invoke.Arguments;
var args_expr = new SLE.Expression[invokeBinder.argumentInfo.Count];
var types = new Type [args_expr.Length + 2];
// Required by MakeDynamic
types[0] = typeof (System.Runtime.CompilerServices.CallSite);
types[1] = expr.Type.GetMetaInfo ();
args_expr[0] = expr.MakeExpression (ctx);
for (int i = 0; i < args.Count; ++i) {
args_expr[i + 1] = args[i].Expr.MakeExpression (ctx);
int type_index = i + 2;
types[type_index] = args[i].Type.GetMetaInfo ();
if (args[i].IsByRef)
types[type_index] = types[type_index].MakeByRefType ();
}
// Return type goes last
bool void_result = (invokeBinder.flags & CSharpBinderFlags.ResultDiscarded) != 0;
types[types.Length - 1] = void_result ? typeof (void) : invokeBinder.ReturnType;
//
// Much easier to use Expression.Dynamic cannot be used because it ignores ByRef arguments
// and it always generates either Func or Action and any value type argument is lost
//
Type delegateType = SLE.Expression.GetDelegateType (types);
return SLE.Expression.MakeDynamic (delegateType, binder, args_expr);
}
}
readonly CSharpInvokeMemberBinder invokeBinder;
public Invocation (Compiler.Expression expr, Compiler.Arguments arguments, CSharpInvokeMemberBinder invokeBinder)
: base (expr, arguments)
{
this.invokeBinder = invokeBinder;
}
protected override Compiler.Expression DoResolveDynamic (Compiler.ResolveContext ec, Compiler.Expression memberExpr)
{
return new RuntimeDynamicInvocation (this, memberExpr).Resolve (ec);
}
}
readonly CSharpBinderFlags flags;
IList<CSharpArgumentInfo> argumentInfo;
IList<Type> typeArguments;
Type callingContext;
public CSharpInvokeMemberBinder (CSharpBinderFlags flags, string name, Type callingContext, IEnumerable<Type> typeArguments, IEnumerable<CSharpArgumentInfo> argumentInfo)
: base (name, false, CSharpArgumentInfo.CreateCallInfo (argumentInfo, 1))
{
this.flags = flags;
this.callingContext = callingContext;
this.argumentInfo = argumentInfo.ToReadOnly ();
this.typeArguments = typeArguments.ToReadOnly ();
}
public override DynamicMetaObject FallbackInvoke (DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
{
var b = new CSharpInvokeBinder (flags, callingContext, argumentInfo);
// TODO: Is errorSuggestion ever used?
return b.Defer (target, args);
}
public override DynamicMetaObject FallbackInvokeMember (DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
{
var ctx = DynamicContext.Create ();
var c_args = ctx.CreateCompilerArguments (argumentInfo.Skip (1), args);
var t_args = typeArguments == null ?
null :
new Compiler.TypeArguments (typeArguments.Select (l => new Compiler.TypeExpression (ctx.ImportType (l), Compiler.Location.Null)).ToArray ());
var expr = ctx.CreateCompilerExpression (argumentInfo[0], target);
//
// Simple name invocation is actually member access invocation
// to capture original this argument. This brings problem when
// simple name is resolved as a static invocation and member access
// has to be reduced back to simple name without reporting an error
//
if ((flags & CSharpBinderFlags.InvokeSimpleName) != 0) {
var value = expr as Compiler.RuntimeValueExpression;
if (value != null)
value.IsSuggestionOnly = true;
}
expr = new Compiler.MemberAccess (expr, Name, t_args, Compiler.Location.Null);
expr = new Invocation (expr, c_args, this);
if ((flags & CSharpBinderFlags.ResultDiscarded) == 0)
expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
else
expr = new Compiler.DynamicResultCast (ctx.ImportType (ReturnType), expr);
var binder = new CSharpBinder (this, expr, errorSuggestion);
binder.AddRestrictions (target);
binder.AddRestrictions (args);
if ((flags & CSharpBinderFlags.InvokeSpecialName) != 0)
binder.ResolveOptions |= Compiler.ResolveContext.Options.InvokeSpecialName;
return binder.Bind (ctx, callingContext);
}
}
}

View File

@ -0,0 +1,71 @@
//
// CSharpIsEventBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using Compiler = Mono.CSharp;
namespace Microsoft.CSharp.RuntimeBinder
{
class CSharpIsEventBinder : DynamicMetaObjectBinder
{
Type callingContext;
string name;
public CSharpIsEventBinder (string name, Type callingContext)
{
this.name = name;
this.callingContext = callingContext;
}
public override DynamicMetaObject Bind (DynamicMetaObject target, DynamicMetaObject[] args)
{
var ctx = DynamicContext.Create ();
var context_type = ctx.ImportType (callingContext);
var queried_type = ctx.ImportType (target.LimitType);
var rc = new Compiler.ResolveContext (new RuntimeBinderContext (ctx, context_type), 0);
var expr = Compiler.Expression.MemberLookup (rc, false, queried_type,
name, 0, Compiler.Expression.MemberLookupRestrictions.ExactArity, Compiler.Location.Null);
var binder = new CSharpBinder (
this, new Compiler.BoolConstant (ctx.CompilerContext.BuiltinTypes, expr is Compiler.EventExpr, Compiler.Location.Null), null);
binder.AddRestrictions (target);
return binder.Bind (ctx, callingContext);
}
public override Type ReturnType {
get {
return typeof (bool);
}
}
}
}

View File

@ -0,0 +1,86 @@
//
// CSharpSetIndexBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using Compiler = Mono.CSharp;
namespace Microsoft.CSharp.RuntimeBinder
{
class CSharpSetIndexBinder : SetIndexBinder
{
readonly CSharpBinderFlags flags;
IList<CSharpArgumentInfo> argumentInfo;
Type callingContext;
public CSharpSetIndexBinder (CSharpBinderFlags flags, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
: base (CSharpArgumentInfo.CreateCallInfo (argumentInfo, 2))
{
this.flags = flags;
this.callingContext = callingContext;
this.argumentInfo = argumentInfo.ToReadOnly ();
}
public override DynamicMetaObject FallbackSetIndex (DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
{
if (argumentInfo.Count != indexes.Length + 2) {
if (errorSuggestion == null)
throw new NotImplementedException ();
return errorSuggestion;
}
var ctx = DynamicContext.Create ();
var expr = ctx.CreateCompilerExpression (argumentInfo [0], target);
var args = ctx.CreateCompilerArguments (argumentInfo.Skip (1), indexes);
expr = new Compiler.ElementAccess (expr, args, Compiler.Location.Null);
var source = ctx.CreateCompilerExpression (argumentInfo [indexes.Length + 1], value);
// Same conversion as in SetMemberBinder
if ((flags & CSharpBinderFlags.ValueFromCompoundAssignment) != 0) {
expr = new Compiler.RuntimeExplicitAssign (expr, source);
} else {
expr = new Compiler.SimpleAssign (expr, source);
}
expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
if ((flags & CSharpBinderFlags.CheckedContext) != 0)
expr = new Compiler.CheckedExpr (expr, Compiler.Location.Null);
var binder = new CSharpBinder (this, expr, errorSuggestion);
binder.AddRestrictions (target);
binder.AddRestrictions (value);
binder.AddRestrictions (indexes);
return binder.Bind (ctx, callingContext);
}
}
}

View File

@ -0,0 +1,82 @@
//
// CSharpSetMemberBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using Compiler = Mono.CSharp;
namespace Microsoft.CSharp.RuntimeBinder
{
class CSharpSetMemberBinder : SetMemberBinder
{
readonly CSharpBinderFlags flags;
IList<CSharpArgumentInfo> argumentInfo;
Type callingContext;
public CSharpSetMemberBinder (CSharpBinderFlags flags, string name, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
: base (name, false)
{
this.flags = flags;
this.callingContext = callingContext;
this.argumentInfo = argumentInfo.ToReadOnly ();
}
public override DynamicMetaObject FallbackSetMember (DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
{
var ctx = DynamicContext.Create ();
var source = ctx.CreateCompilerExpression (argumentInfo [1], value);
var expr = ctx.CreateCompilerExpression (argumentInfo [0], target);
// Field assignment
expr = new Compiler.MemberAccess (expr, Name);
// Compound assignment under dynamic context does not convert result
// expression but when setting member type we need to do explicit
// conversion to ensure type match between member type and dynamic
// expression type
if ((flags & CSharpBinderFlags.ValueFromCompoundAssignment) != 0) {
expr = new Compiler.RuntimeExplicitAssign (expr, source);
} else {
expr = new Compiler.SimpleAssign (expr, source);
}
expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
if ((flags & CSharpBinderFlags.CheckedContext) != 0)
expr = new Compiler.CheckedExpr (expr, Compiler.Location.Null);
var binder = new CSharpBinder (this, expr, errorSuggestion);
binder.AddRestrictions (target);
binder.AddRestrictions (value);
return binder.Bind (ctx, callingContext);
}
}
}

View File

@ -0,0 +1,101 @@
//
// CSharpUnaryOperationBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Compiler = Mono.CSharp;
namespace Microsoft.CSharp.RuntimeBinder
{
class CSharpUnaryOperationBinder : UnaryOperationBinder
{
IList<CSharpArgumentInfo> argumentInfo;
readonly CSharpBinderFlags flags;
readonly Type context;
public CSharpUnaryOperationBinder (ExpressionType operation, CSharpBinderFlags flags, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
: base (operation)
{
this.argumentInfo = argumentInfo.ToReadOnly ();
if (this.argumentInfo.Count != 1)
throw new ArgumentException ("Unary operation requires 1 argument");
this.flags = flags;
this.context = context;
}
Compiler.Unary.Operator GetOperator ()
{
switch (Operation) {
case ExpressionType.Negate:
return Compiler.Unary.Operator.UnaryNegation;
case ExpressionType.Not:
return Compiler.Unary.Operator.LogicalNot;
case ExpressionType.OnesComplement:
return Compiler.Unary.Operator.OnesComplement;
case ExpressionType.UnaryPlus:
return Compiler.Unary.Operator.UnaryPlus;
default:
throw new NotImplementedException (Operation.ToString ());
}
}
public override DynamicMetaObject FallbackUnaryOperation (DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
var ctx = DynamicContext.Create ();
var expr = ctx.CreateCompilerExpression (argumentInfo [0], target);
if (Operation == ExpressionType.IsTrue) {
expr = new Compiler.BooleanExpression (expr);
} else if (Operation == ExpressionType.IsFalse) {
expr = new Compiler.BooleanExpressionFalse (expr);
} else {
if (Operation == ExpressionType.Increment)
expr = new Compiler.UnaryMutator (Compiler.UnaryMutator.Mode.PreIncrement, expr, Compiler.Location.Null);
else if (Operation == ExpressionType.Decrement)
expr = new Compiler.UnaryMutator (Compiler.UnaryMutator.Mode.PreDecrement, expr, Compiler.Location.Null);
else
expr = new Compiler.Unary (GetOperator (), expr, Compiler.Location.Null);
expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
if ((flags & CSharpBinderFlags.CheckedContext) != 0)
expr = new Compiler.CheckedExpr (expr, Compiler.Location.Null);
}
var binder = new CSharpBinder (this, expr, errorSuggestion);
binder.AddRestrictions (target);
return binder.Bind (ctx, context);
}
}
}

View File

@ -0,0 +1,138 @@
2010-06-16 Marek Safar <marek.safar@gmail.com>
* CSharpInvokeMemberBinder.cs: Construct MemberAccess for simple
name expressions.
2010-05-27 Marek Safar <marek.safar@gmail.com>
* *.cs: Sync with the latest gmcs.
2010-02-10 Marek Safar <marek.safar@gmail.com>
* *.cs: Track RC API changes.
2009-12-09 Marek Safar <marek.safar@gmail.com>
* CSharpBinder.cs: Actually use merged restrictions.
2009-11-18 Marek Safar <marek.safar@gmail.com>
* CSharpBinder.cs: Fixed unsafe initialization.
2009-11-16 Marek Safar <marek.safar@gmail.com>
* RuntimeBinderContext.cs, ErrorPrinter.cs, CSharpBinder.cs: Reject
unsafe type.
2009-11-11 Marek Safar <marek.safar@gmail.com>
* CSharpInvokeBinder.cs, CSharpBinder.cs,
CSharpInvokeMemberBinder.cs: Convert discarded result expressions.
2009-11-04 Marek Safar <marek.safar@gmail.com>
* CSharpIsEventBinder.cs: Dynamic events implementation.
* *.cs: Make CSharpBinder instance and share common checks.
2009-11-03 Marek Safar <marek.safar@gmail.com>
* CSharpInvokeConstructorBinder.cs: Dynamic constructors.
2009-10-30 Marek Safar <marek.safar@gmail.com>
* CSharpBinder.cs, CSharpInvokeMemberBinder.cs,
CSharpSetIndexBinder.cs: Simple member binder.
2009-10-23 Marek Safar <marek.safar@gmail.com>
* RuntimeBinderContext.cs, Extensions.cs, CSharpBinder.cs: More
literal and constant work.
2009-10-22 Marek Safar <marek.safar@gmail.com>
* *.cs: Cleanup the old API.
2009-10-20 Marek Safar <marek.safar@gmail.com>
* *.cs: Update to the latest API.
2009-10-14 Marek Safar <marek.safar@gmail.com>
* CSharpBinaryOperationBinder.cs, CSharpGetIndexBinder.cs,
CSharpGetMemberBinder.cs, CSharpArgumentInfo.cs, CSharpBinder.cs,
CSharpUnaryOperationBinder.cs, CSharpConvertBinder.cs,
CSharpSetIndexBinder.cs, CSharpSetMemberBinder.cs: Index setters
implemented.
2009-10-07 Marek Safar <marek.safar@gmail.com>
* RuntimeBinderContext.cs, CSharpBinaryOperationBinder.cs,
CSharpGetMemberBinder.cs, CSharpBinder.cs,
CSharpUnaryOperationBinder.cs, CSharpSetMemberBinder.cs: Member
access implemented.
2009-09-30 Marek Safar <marek.safar@gmail.com>
* CSharpBinaryOperationBinder.cs, CSharpBinder.cs,
CSharpUnaryOperationBinder.cs, CSharpConvertBinder.cs: Implicit
and explicit conversions implemented.
2009-09-29 Marek Safar <marek.safar@gmail.com>
* CSharpBinaryOperationBinder.cs, Extensions.cs, CSharpBinder.cs,
CSharpUnaryOperationBinder.cs: Dynamic unary expressions.
2009-09-25 Marek Safar <marek.safar@gmail.com>
* CSharpBinaryOperationBinder.cs, CSharpBinder.cs: More dynamic
binary expressions.
2009-09-18 Marek Safar <marek.safar@gmail.com>
* CSharpBinaryOperationBinder.cs, CSharpBinder.cs: Implemented
binary AddAssign operator.
2009-09-16 Marek Safar <marek.safar@gmail.com>
* RuntimeBinderContext.cs, CSharpBinaryOperationBinder.cs,
CSharpBinder.cs: Fully implemented binary Add operator.
2009-09-11 Marek Safar <marek.safar@gmail.com>
* RuntimeBinderContext.cs, CSharpBinaryOperationBinder.cs,
ErrorPrinter.cs, Extensions.cs, CSharpBinder.cs: Binary binder.
2009-08-10 Marek Safar <marek.safar@gmail.com>
* CSharpInvokeBinder.cs, CSharpGetMemberBinder.cs,
CSharpInvokeMemberBinder.cs: Defer fallback for now.
2009-08-07 Marek Safar <marek.safar@gmail.com>
* CSharpInvokeBinder.cs, CSharpGetIndexBinder.cs, Extensions.cs,
CSharpArgumentInfo.cs, CSharpInvokeMemberBinder.cs,
CSharpSetIndexBinder.cs: Skip overhead arguments.
2009-08-04 Marek Safar <marek.safar@gmail.com>
* RuntimeBinderInternalCompilerException.cs,
RuntimeBinderException.cs: New files.
2009-07-14 Marek Safar <marek.safar@gmail.com>
* CSharpInvokeBinder.cs, CSharpBinaryOperationBinder.cs,
CSharpGetMemberBinder.cs, CSharpGetIndexBinder.cs, Extensions.cs,
CSharpIsEventBinder.cs, CSharpUnaryOperationBinder.cs,
CSharpConvertBinder.cs, CSharpSetIndexBinder.cs,
CSharpInvokeMemberBinder.cs, CSharpSetMemberBinder.cs: New files.
2009-07-02 Marek Safar <marek.safar@gmail.com>
* CSharpConversionKind.cs, CSharpArgumentInfo.cs,
CSharpInvokeMemberBinder.cs, CSharpCallFlags.cs: New files.
2009-06-29 Marek Safar <marek.safar@gmail.com>
* ChangeLog: Added

View File

@ -0,0 +1,192 @@
//
// DynamicContext.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using Compiler = Mono.CSharp;
using System.Reflection;
using System.Collections.Generic;
namespace Microsoft.CSharp.RuntimeBinder
{
class DynamicContext
{
static DynamicContext dc;
static object compiler_initializer = new object ();
static object lock_object = new object ();
readonly Compiler.ModuleContainer module;
readonly Compiler.ReflectionImporter importer;
private DynamicContext (Compiler.ModuleContainer module, Compiler.ReflectionImporter importer)
{
this.module = module;
this.importer = importer;
}
public Compiler.CompilerContext CompilerContext {
get {
return module.Compiler;
}
}
public Compiler.ModuleContainer Module {
get {
return module;
}
}
public static DynamicContext Create ()
{
if (dc != null)
return dc;
lock (compiler_initializer) {
if (dc != null)
return dc;
var settings = new Compiler.CompilerSettings () {
WarningLevel = 0
};
var cc = new Compiler.CompilerContext (settings, ErrorPrinter.Instance) {
IsRuntimeBinder = true
};
//
// Any later loaded assemblies are handled internally by GetAssemblyDefinition
// domain.AssemblyLoad cannot be used as that would be too destructive as we
// would hold all loaded assemblies even if they can be never visited
//
// TODO: Remove this code and rely on GetAssemblyDefinition only
//
var module = new Compiler.ModuleContainer (cc);
module.HasTypesFullyDefined = true;
// Setup fake assembly, it's used mostly to simplify checks like friend-access
var temp = new Compiler.AssemblyDefinitionDynamic (module, "dynamic");
module.SetDeclaringAssembly (temp);
var importer = new Compiler.ReflectionImporter (module, cc.BuiltinTypes) {
IgnorePrivateMembers = false
};
// Import all currently loaded assemblies
// TODO: Rewrite this to populate type cache on-demand, that should greatly
// reduce our start-up cost
var domain = AppDomain.CurrentDomain;
foreach (var a in AppDomain.CurrentDomain.GetAssemblies ()) {
importer.ImportAssembly (a, module.GlobalRootNamespace);
}
cc.BuiltinTypes.CheckDefinitions (module);
module.InitializePredefinedTypes ();
dc = new DynamicContext (module, importer);
}
return dc;
}
//
// Creates mcs expression from dynamic object
//
public Compiler.Expression CreateCompilerExpression (CSharpArgumentInfo info, DynamicMetaObject value)
{
//
// No type details provider, go with runtime type
//
if (info == null) {
if (value.LimitType == typeof (object))
return new Compiler.NullLiteral (Compiler.Location.Null);
return new Compiler.RuntimeValueExpression (value, ImportType (value.RuntimeType));
}
//
// Value is known to be a type
//
if ((info.Flags & CSharpArgumentInfoFlags.IsStaticType) != 0)
return new Compiler.TypeExpression (ImportType ((Type) value.Value), Compiler.Location.Null);
if (value.Value == null &&
(info.Flags & (CSharpArgumentInfoFlags.IsOut | CSharpArgumentInfoFlags.IsRef | CSharpArgumentInfoFlags.UseCompileTimeType)) == 0 &&
value.LimitType == typeof (object)) {
return new Compiler.NullLiteral (Compiler.Location.Null);
}
//
// Use compilation time type when type was known not to be dynamic during compilation
//
Type value_type = (info.Flags & CSharpArgumentInfoFlags.UseCompileTimeType) != 0 ? value.Expression.Type : value.LimitType;
var type = ImportType (value_type);
if ((info.Flags & CSharpArgumentInfoFlags.Constant) != 0) {
var c = Compiler.Constant.CreateConstantFromValue (type, value.Value, Compiler.Location.Null);
//
// It can be null for misused Constant flag
//
if (c != null)
return c;
}
return new Compiler.RuntimeValueExpression (value, type);
}
//
// Creates mcs arguments from dynamic argument info
//
public Compiler.Arguments CreateCompilerArguments (IEnumerable<CSharpArgumentInfo> info, DynamicMetaObject[] args)
{
var res = new Compiler.Arguments (args.Length);
int pos = 0;
// enumerates over args
foreach (var item in info) {
var expr = CreateCompilerExpression (item, args[pos++]);
if (item.IsNamed) {
res.Add (new Compiler.NamedArgument (item.Name, Compiler.Location.Null, expr, item.ArgumentModifier));
} else {
res.Add (new Compiler.Argument (expr, item.ArgumentModifier));
}
if (pos == args.Length)
break;
}
return res;
}
public Compiler.TypeSpec ImportType (Type type)
{
lock (lock_object) {
return importer.ImportType (type);
}
}
}
}

View File

@ -0,0 +1,60 @@
//
// ErrorPrinter.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using Compiler = Mono.CSharp;
namespace Microsoft.CSharp.RuntimeBinder
{
class ErrorPrinter : Compiler.ReportPrinter
{
public static readonly ErrorPrinter Instance = new ErrorPrinter ();
private ErrorPrinter ()
{
}
public override bool HasRelatedSymbolSupport {
get {
return false;
}
}
public override void Print (Compiler.AbstractMessage msg, bool showFullPath)
{
string text;
if (msg.Code == 214) {
text = "Pointers and fixed size buffers cannot be used in a dynamic context";
} else {
text = msg.Text;
}
throw new RuntimeBinderException (text);
}
}
}

View File

@ -0,0 +1,45 @@
//
// CSharpInvokeMemberBinder.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Dynamic;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Microsoft.CSharp.RuntimeBinder
{
static class Extensions
{
public static IList<T> ToReadOnly<T> (this IEnumerable<T> col)
{
return col == null ?
null : new ReadOnlyCollectionBuilder<T> (col);
}
}
}

Some files were not shown because too many files have changed in this diff Show More