class CSharpBinder
{
static ConstructorInfo binder_exception_ctor;
- static object compiler_initializer = new object ();
static object resolver = new object ();
DynamicMetaObjectBinder binder;
public void AddRestrictions (DynamicMetaObject arg)
{
- restrictions.Merge (CreateRestrictionsOnTarget (arg));
+ restrictions = restrictions.Merge (CreateRestrictionsOnTarget (arg));
}
public void AddRestrictions (DynamicMetaObject[] args)
{
- restrictions.Merge (CreateRestrictionsOnTarget (args));
+ restrictions = restrictions.Merge (CreateRestrictionsOnTarget (args));
}
- public DynamicMetaObject Bind (Type callingType, DynamicMetaObject target)
+ public DynamicMetaObject Bind (DynamicContext ctx, Type callingType)
{
- if (target.Value == null) {
- if (errorSuggestion != null)
- return errorSuggestion;
-
- var ex = CreateBinderException ("Cannot perform member binding on `null' value");
- return new DynamicMetaObject (ex, restrictions);
- }
-
- return Bind (callingType);
- }
-
- public DynamicMetaObject Bind ()
- {
- // Not ideal but fixes possible NRE during resolve accessibility checking
- var callingType = typeof (CSharpBinder);
-
- return Bind (callingType);
- }
-
- DynamicMetaObject Bind (Type callingType)
- {
- var ctx = CreateDefaultCompilerContext ();
-
- InitializeCompiler (ctx);
-
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 | Compiler.ResolveFlags.DisableFlowAnalysis);
+ expr = expr.Resolve (rc, Compiler.ResolveFlags.VariableOrValue);
}
if (expr == null)
return Expression.Throw (Expression.New (binder_exception_ctor, Expression.Constant (message)), binder.ReturnType);
}
- //
- // Creates mcs expression from dynamic method object
- //
- public static Compiler.Expression CreateCompilerExpression (CSharpArgumentInfo info, DynamicMetaObject value)
- {
- if (value.Value == null) {
- if (value.LimitType == typeof (object))
- return new Compiler.NullLiteral (Compiler.Location.Null);
-
- InitializeCompiler (null);
- return Compiler.Constant.CreateConstant (value.LimitType, null, Compiler.Location.Null);
- }
-
- bool is_compile_time;
-
- if (info != null) {
- if ((info.Flags & CSharpArgumentInfoFlags.LiteralConstant) != 0) {
- InitializeCompiler (null);
- return Compiler.Constant.CreateConstant (value.LimitType, value.Value, Compiler.Location.Null);
- }
-
- if ((info.Flags & CSharpArgumentInfoFlags.IsStaticType) != 0)
- return new Compiler.TypeExpression ((Type) value.Value, Compiler.Location.Null);
-
- is_compile_time = (info.Flags & CSharpArgumentInfoFlags.UseCompileTimeType) != 0;
- } else {
- is_compile_time = false;
- }
-
- return new Compiler.RuntimeValueExpression (value, is_compile_time);
- }
-
- public static 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 (new Compiler.LocatedToken (Compiler.Location.Null, item.Name), expr));
- } else {
- res.Add (new Compiler.Argument (expr, item.ArgumentModifier));
- }
-
- if (pos == args.Length)
- break;
- }
-
- return res;
- }
-
- public static Compiler.CompilerContext CreateDefaultCompilerContext ()
- {
- return new Compiler.CompilerContext (
- new Compiler.Report (ErrorPrinter.Instance) {
- WarningLevel = 0
- }) {
- IsRuntimeBinder = true
- };
- }
-
static BindingRestrictions CreateRestrictionsOnTarget (DynamicMetaObject arg)
{
return arg.HasValue && arg.Value == null ?
return res;
}
-
- public static void InitializeCompiler (Compiler.CompilerContext ctx)
- {
- if (Compiler.TypeManager.object_type != null)
- return;
-
- lock (compiler_initializer) {
- if (Compiler.TypeManager.object_type != null)
- return;
-
- // I don't think dynamically loaded assemblies can be used as dynamic
- // expression without static type be loaded first
- // AppDomain.CurrentDomain.AssemblyLoad += (sender, e) => { throw new NotImplementedException (); };
-
- // Import all currently loaded assemblies
- foreach (System.Reflection.Assembly a in AppDomain.CurrentDomain.GetAssemblies ())
- Compiler.GlobalRootNamespace.Instance.AddAssemblyReference (a);
-
- if (ctx == null)
- ctx = CreateDefaultCompilerContext ();
-
- Compiler.TypeManager.InitCoreTypes (ctx);
- Compiler.TypeManager.InitOptionalCoreTypes (ctx);
- }
- }
}
}