public override DynamicMetaObject FallbackBinaryOperation (DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion)
{
- var left = CSharpBinder.CreateCompilerExpression (argumentInfo [0], target);
- var right = CSharpBinder.CreateCompilerExpression (argumentInfo [1], arg);
+ 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 = CSharpBinder.CreateCompilerExpression (argumentInfo[0], target);
+ var target_expr = ctx.CreateCompilerExpression (argumentInfo[0], target);
expr = new Compiler.CompoundAssign (oper, target_expr, right, left, Compiler.Location.Null);
} else {
expr = new Compiler.Binary (oper, left, right, Compiler.Location.Null);
}
- expr = new Compiler.Cast (new Compiler.TypeExpression (TypeImporter.Import (ReturnType), Compiler.Location.Null), 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);
binder.AddRestrictions (target);
binder.AddRestrictions (arg);
- return binder.Bind (context);
+ return binder.Bind (ctx, context);
}
}
}
class CSharpBinder
{
static ConstructorInfo binder_exception_ctor;
- static object compiler_initializer = new object ();
static object resolver = new object ();
DynamicMetaObjectBinder binder;
restrictions = restrictions.Merge (CreateRestrictionsOnTarget (args));
}
- public DynamicMetaObject Bind (Type callingType, DynamicMetaObject target)
+ public DynamicMetaObject Bind (DynamicContext ctx, Type callingType, DynamicMetaObject target)
{
if (target.Value == null) {
if (errorSuggestion != null)
return new DynamicMetaObject (ex, restrictions);
}
- return Bind (callingType);
+ return Bind (ctx, callingType);
}
- public DynamicMetaObject Bind (Type callingType)
+ public DynamicMetaObject Bind (DynamicContext ctx, Type callingType)
{
- var ctx = CreateDefaultCompilerContext ();
-
- InitializeCompiler (ctx);
-
Expression res;
try {
- var rc = new Compiler.ResolveContext (new RuntimeBinderContext (ctx, TypeImporter.Import (callingType)), ResolveOptions);
+ var rc = new Compiler.ResolveContext (new RuntimeBinderContext (ctx, ctx.ImportType (callingType)), ResolveOptions);
// Static typemanager and internal caches are not thread-safe
lock (resolver) {
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;
+ }
+ }
+
+ class DynamicContext
+ {
+ static DynamicContext dc;
+ static object compiler_initializer = new object ();
+ static object lock_object = new object ();
+
+ readonly Compiler.CompilerContext cc;
+
+ private DynamicContext (Compiler.CompilerContext cc)
+ {
+ this.cc = cc;
+ }
+
+ public Compiler.CompilerContext CompilerContext {
+ get {
+ return cc;
+ }
+ }
+
+ public static DynamicContext Create ()
+ {
+ if (dc != null)
+ return dc;
+
+ lock (compiler_initializer) {
+ if (dc != null)
+ return dc;
+
+ var importer = new Compiler.ReflectionMetaImporter () {
+ IgnorePrivateMembers = false
+ };
+
+ var core_types = Compiler.TypeManager.InitCoreTypes ();
+ importer.Initialize ();
+
+ // I don't think dynamically loaded assemblies can be used as dynamic
+ // expression without static type to be loaded first
+ // AppDomain.CurrentDomain.AssemblyLoad += (sender, e) => { throw new NotImplementedException (); };
+
+ // Import all currently loaded assemblies
+ var ns = Compiler.GlobalRootNamespace.Instance;
+ foreach (System.Reflection.Assembly a in AppDomain.CurrentDomain.GetAssemblies ()) {
+ ns.AddAssemblyReference (a);
+ importer.ImportAssembly (a, ns);
+ }
+
+ var reporter = new Compiler.Report (ErrorPrinter.Instance) {
+ WarningLevel = 0
+ };
+
+ var cc = new Compiler.CompilerContext (importer, reporter) {
+ IsRuntimeBinder = true
+ };
+
+ Compiler.TypeManager.InitCoreTypes (cc, core_types);
+ Compiler.TypeManager.InitOptionalCoreTypes (cc);
+
+ dc = new DynamicContext (cc);
+ }
+
+ return dc;
+ }
+
//
// Creates mcs expression from dynamic method object
//
- public static Compiler.Expression CreateCompilerExpression (CSharpArgumentInfo info, DynamicMetaObject value)
+ public 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.CreateConstantFromValue (TypeImporter.Import (value.LimitType), null, Compiler.Location.Null);
+ return Compiler.Constant.CreateConstantFromValue (ImportType (value.LimitType), null, Compiler.Location.Null);
}
bool is_compile_time;
if (info != null) {
if ((info.Flags & CSharpArgumentInfoFlags.Constant) != 0) {
- InitializeCompiler (null);
- return Compiler.Constant.CreateConstantFromValue (TypeImporter.Import (value.LimitType), value.Value, Compiler.Location.Null);
+ return Compiler.Constant.CreateConstantFromValue (ImportType (value.LimitType), value.Value, Compiler.Location.Null);
}
if ((info.Flags & CSharpArgumentInfoFlags.IsStaticType) != 0)
- return new Compiler.TypeExpression (TypeImporter.Import ((Type) value.Value), Compiler.Location.Null);
+ return new Compiler.TypeExpression (ImportType ((Type) value.Value), Compiler.Location.Null);
is_compile_time = (info.Flags & CSharpArgumentInfoFlags.UseCompileTimeType) != 0;
} else {
is_compile_time = false;
}
- return new Compiler.RuntimeValueExpression (value, TypeImporter.Import (is_compile_time ? value.LimitType : value.RuntimeType));
+ return new Compiler.RuntimeValueExpression (value, ImportType (is_compile_time ? value.LimitType : value.RuntimeType));
}
- public static Compiler.Arguments CreateCompilerArguments (IEnumerable<CSharpArgumentInfo> info, DynamicMetaObject[] args)
+ //
+ // 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++]);
+ var expr = CreateCompilerExpression (item, args[pos++]);
if (item.IsNamed) {
res.Add (new Compiler.NamedArgument (item.Name, Compiler.Location.Null, expr));
} else {
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 ?
- 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;
- }
-
- public static void InitializeCompiler (Compiler.CompilerContext ctx)
- {
- if (TypeImporter.Predefined == null)
- return;
-
- lock (compiler_initializer) {
- if (TypeImporter.Predefined == null)
- return;
-
- // I don't think dynamically loaded assemblies can be used as dynamic
- // expression without static type to be loaded first
- // AppDomain.CurrentDomain.AssemblyLoad += (sender, e) => { throw new NotImplementedException (); };
-
- // Import all currently loaded assemblies
- var ns = Compiler.GlobalRootNamespace.Instance;
- foreach (System.Reflection.Assembly a in AppDomain.CurrentDomain.GetAssemblies ()) {
- ns.AddAssemblyReference (a);
- ns.ImportAssembly (a);
- }
-
- if (ctx == null)
- ctx = CreateDefaultCompilerContext ();
-
- Compiler.TypeManager.InitCoreTypes (ctx, TypeImporter.Predefined);
- TypeImporter.Predefined = null;
-
- Compiler.TypeManager.InitOptionalCoreTypes (ctx);
- }
- }
- }
-
- static class TypeImporter
- {
- static object lock_object;
- public static IList<Compiler.PredefinedTypeSpec> Predefined;
-
- static TypeImporter ()
- {
- lock_object = new object ();
- Predefined = Compiler.TypeManager.InitCoreTypes ();
- Compiler.Import.Initialize ();
- }
-
- public static Compiler.TypeSpec Import (Type type)
+ public Compiler.TypeSpec ImportType (Type type)
{
lock (lock_object) {
- return Compiler.Import.ImportType (type);
+ return cc.MetaImporter.ImportType (type);
}
}
}
public override DynamicMetaObject FallbackConvert (DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
- var expr = CSharpBinder.CreateCompilerExpression (null, target);
+ var ctx = DynamicContext.Create ();
+ var expr = ctx.CreateCompilerExpression (null, target);
if (Explicit)
- expr = new Compiler.Cast (new Compiler.TypeExpression (TypeImporter.Import (Type), Compiler.Location.Null), expr, Compiler.Location.Null);
+ expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (Type), Compiler.Location.Null), expr, Compiler.Location.Null);
else
- expr = new Compiler.ImplicitCast (expr, TypeImporter.Import (Type), (flags & CSharpBinderFlags.ConvertArrayIndex) != 0);
+ 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 (context);
+ return binder.Bind (ctx, context);
}
}
}
return errorSuggestion;
}
- var expr = CSharpBinder.CreateCompilerExpression (argumentInfo [0], target);
- var args = CSharpBinder.CreateCompilerArguments (argumentInfo.Skip (1), indexes);
+ 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 (TypeImporter.Import (ReturnType), Compiler.Location.Null), expr, 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 (callingContext, target);
+ return binder.Bind (ctx, callingContext, target);
}
}
}
public override DynamicMetaObject FallbackGetMember (DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
- var expr = CSharpBinder.CreateCompilerExpression (argumentInfo [0], target);
+ var ctx = DynamicContext.Create ();
+
+ var expr = ctx.CreateCompilerExpression (argumentInfo [0], target);
expr = new Compiler.MemberAccess (expr, Name);
- expr = new Compiler.Cast (new Compiler.TypeExpression (TypeImporter.Import (ReturnType), Compiler.Location.Null), expr, 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);
- return binder.Bind (callingContext, target);
+ return binder.Bind (ctx, callingContext, target);
}
}
}
public override DynamicMetaObject FallbackInvoke (DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
{
- var expr = CSharpBinder.CreateCompilerExpression (argumentInfo [0], target);
- var c_args = CSharpBinder.CreateCompilerArguments (argumentInfo.Skip (1), args);
+ 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 (TypeImporter.Import (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
+ expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
else
- expr = new Compiler.DynamicResultCast (TypeImporter.Import (ReturnType), expr);
+ expr = new Compiler.DynamicResultCast (ctx.ImportType (ReturnType), expr);
var binder = new CSharpBinder (this, expr, errorSuggestion);
binder.AddRestrictions (target);
binder.AddRestrictions (args);
- return binder.Bind (callingContext, target);
+ return binder.Bind (ctx, callingContext, target);
}
}
}
public override DynamicMetaObject Bind (DynamicMetaObject target, DynamicMetaObject[] args)
{
- var type = CSharpBinder.CreateCompilerExpression (argumentInfo [0], target);
+ var ctx = DynamicContext.Create ();
+
+ var type = ctx.CreateCompilerExpression (argumentInfo [0], target);
target_return_type = type.Type.GetMetaInfo ();
- var c_args = CSharpBinder.CreateCompilerArguments (argumentInfo.Skip (1), args);
+ 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 (callingContext, target);
+ return binder.Bind (ctx, callingContext, target);
}
public override Type ReturnType {
public override DynamicMetaObject FallbackInvokeMember (DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
{
- var c_args = CSharpBinder.CreateCompilerArguments (argumentInfo.Skip (1), args);
+ 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 (TypeImporter.Import (l), Compiler.Location.Null)).ToArray ());
+ new Compiler.TypeArguments (typeArguments.Select (l => new Compiler.TypeExpression (ctx.ImportType (l), Compiler.Location.Null)).ToArray ());
- var expr = CSharpBinder.CreateCompilerExpression (argumentInfo[0], target);
+ var expr = ctx.CreateCompilerExpression (argumentInfo[0], target);
//
// Simple name invocation is actually member access invocation
expr = new Compiler.Invocation (expr, c_args);
if ((flags & CSharpBinderFlags.ResultDiscarded) == 0)
- expr = new Compiler.Cast (new Compiler.TypeExpression (TypeImporter.Import (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
+ expr = new Compiler.Cast (new Compiler.TypeExpression (ctx.ImportType (ReturnType), Compiler.Location.Null), expr, Compiler.Location.Null);
else
- expr = new Compiler.DynamicResultCast (TypeImporter.Import (ReturnType), expr);
+ expr = new Compiler.DynamicResultCast (ctx.ImportType (ReturnType), expr);
var binder = new CSharpBinder (this, expr, errorSuggestion);
binder.AddRestrictions (target);
if ((flags & CSharpBinderFlags.InvokeSpecialName) != 0)
binder.ResolveOptions |= Compiler.ResolveContext.Options.InvokeSpecialName;
- return binder.Bind (callingContext, target);
+ return binder.Bind (ctx, callingContext, target);
}
}
}
public override DynamicMetaObject Bind (DynamicMetaObject target, DynamicMetaObject[] args)
{
- var ctx = CSharpBinder.CreateDefaultCompilerContext ();
- CSharpBinder.InitializeCompiler (ctx);
- var context_type = TypeImporter.Import (callingContext);
+ var ctx = DynamicContext.Create ();
+ var context_type = ctx.ImportType (callingContext);
var rc = new Compiler.ResolveContext (new RuntimeBinderContext (ctx, context_type), 0);
var expr = Compiler.Expression.MemberLookup (rc, context_type, context_type, name, 0, false, Compiler.Location.Null);
this, new Compiler.BoolConstant (expr is Compiler.EventExpr, Compiler.Location.Null), null);
binder.AddRestrictions (target);
- return binder.Bind (callingContext, target);
+ return binder.Bind (ctx, callingContext, target);
}
public override Type ReturnType {
return errorSuggestion;
}
- var expr = CSharpBinder.CreateCompilerExpression (argumentInfo [0], target);
- var args = CSharpBinder.CreateCompilerArguments (argumentInfo.Skip (1), indexes);
+ 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 = CSharpBinder.CreateCompilerExpression (argumentInfo [indexes.Length + 1], value);
+ var source = ctx.CreateCompilerExpression (argumentInfo [indexes.Length + 1], value);
expr = new Compiler.SimpleAssign (expr, source);
- expr = new Compiler.Cast (new Compiler.TypeExpression (TypeImporter.Import (ReturnType), Compiler.Location.Null), expr, 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 (value);
binder.AddRestrictions (indexes);
- return binder.Bind (callingContext, target);
+ return binder.Bind (ctx, callingContext, target);
}
}
}
public override DynamicMetaObject FallbackSetMember (DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
{
- var source = CSharpBinder.CreateCompilerExpression (argumentInfo [1], value);
- var expr = CSharpBinder.CreateCompilerExpression (argumentInfo [0], target);
+ 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);
expr = new Compiler.SimpleAssign (expr, source);
- expr = new Compiler.Cast (new Compiler.TypeExpression (TypeImporter.Import (ReturnType), Compiler.Location.Null), expr, 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 (value);
- return binder.Bind (callingContext, target);
+ return binder.Bind (ctx, callingContext, target);
}
}
}
public override DynamicMetaObject FallbackUnaryOperation (DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
- Compiler.Expression expr = CSharpBinder.CreateCompilerExpression (argumentInfo [0], target);
+ var ctx = DynamicContext.Create ();
+ var expr = ctx.CreateCompilerExpression (argumentInfo [0], target);
if (Operation == ExpressionType.IsTrue) {
expr = new Compiler.BooleanExpression (expr);
else
expr = new Compiler.Unary (GetOperator (), expr, Compiler.Location.Null);
- expr = new Compiler.Cast (new Compiler.TypeExpression (TypeImporter.Import (ReturnType), Compiler.Location.Null), 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 (context);
+ return binder.Bind (ctx, context);
}
}
}
readonly Compiler.CompilerContext ctx;
readonly Compiler.TypeSpec currentType;
- public RuntimeBinderContext (Compiler.CompilerContext ctx, Compiler.TypeSpec currentType)
+ public RuntimeBinderContext (DynamicContext ctx, Compiler.TypeSpec currentType)
{
- this.ctx = ctx;
+ this.ctx = ctx.CompilerContext;
this.currentType = currentType;
}
}
}
- var char_set = Import.ImportType (typeof (CharSet));
+ var char_set = rc.Compiler.MetaImporter.ImportType (typeof (CharSet)); // TODO: typeof
NamedArguments.Add (new NamedArgument (CharSetEnumMember, loc,
Constant.CreateConstant (rc, char_set, RootContext.ToplevelTypes.DefaultCharSet, Location)));
}
public class CompilerContext
{
readonly Report report;
+ readonly ReflectionMetaImporter meta_importer;
- public CompilerContext (Report report)
+ public CompilerContext (ReflectionMetaImporter metaImporter, Report report)
{
+ this.meta_importer = metaImporter;
this.report = report;
}
public bool IsRuntimeBinder { get; set; }
+ public ReflectionMetaImporter MetaImporter {
+ get {
+ return meta_importer;
+ }
+ }
+
public Report Report {
- get { return report; }
+ get {
+ return report;
+ }
}
//public PredefinedAttributes PredefinedAttributes {
}
TypeSpec t = FindDocumentedTypeNonArray (mc, identifier, ds, cref, r);
if (t != null && is_array)
- t = Import.ImportType (Array.CreateInstance (t.GetMetaInfo (), 0).GetType ());
+ t = ArrayContainer.MakeType (t);
return t;
}
//
Encoding encoding;
- readonly CompilerContext ctx;
+ internal readonly CompilerContext ctx;
static readonly char[] argument_value_separator = new char [] { ';', ',' };
public static Driver Create (string[] args, bool require_files, ReportPrinter printer)
{
- Driver d = new Driver (new CompilerContext (new Report (printer)));
+ Driver d = new Driver (new CompilerContext (new ReflectionMetaImporter (), new Report (printer)));
if (!d.ParseArguments (args, require_files))
return null;
if (timestamps)
ShowTime ("Loading references");
- Import.Initialize ();
+ ctx.MetaImporter.Initialize ();
LoadReferences ();
if (modules.Count > 0) {
if (driver == null)
throw new Exception ("Failed to create compiler driver with the given arguments");
+ ctx = driver.ctx;
+
RootContext.ToplevelTypes = new ModuleCompiled (ctx, true);
driver.ProcessDefaultConfig ();
RootContext.ToplevelTypes = new ModuleCompiled (ctx, true);
/*var ctypes = */TypeManager.InitCoreTypes ();
- Import.Initialize ();
+ ctx.MetaImporter.Initialize ();
driver.LoadReferences ();
TypeManager.InitOptionalCoreTypes (ctx);
} else
printer = new StreamReportPrinter (MessageOutput);
- ctx = new CompilerContext (new Report (printer));
+ ctx = new CompilerContext (new ReflectionMetaImporter (), new Report (printer));
RootContext.ToplevelTypes = new ModuleCompiled (ctx, true);
+ ctx.MetaImporter.Initialize ();
+
//
// PartialReset should not reset the core types, this is very redundant.
//
if (interactive_base_class != null)
return interactive_base_class;
- return Import.ImportType (typeof (InteractiveBase));
+ return ctx.MetaImporter.ImportType (typeof (InteractiveBase));
}
}
throw new ArgumentNullException ();
lock (evaluator_lock)
- interactive_base_class = Import.ImportType (type);
+ interactive_base_class = ctx.MetaImporter.ImportType (type);
}
/// <summary>
lock (evaluator_lock){
// GlobalRootNamespace.Instance.AddAssemblyReference (a);
// GlobalRootNamespace.Instance.ComputeNamespaces (ctx);
- GlobalRootNamespace.Instance.ImportAssembly (a);
+ ctx.MetaImporter.ImportAssembly (a, GlobalRootNamespace.Instance);
}
}
namespace Mono.CSharp
{
- public static class Import
+ public class ReflectionMetaImporter
{
- static Dictionary<Type, TypeSpec> import_cache;
- static Dictionary<Type, PredefinedTypeSpec> type_2_predefined;
+ Dictionary<Type, TypeSpec> import_cache;
+ Dictionary<Type, PredefinedTypeSpec> type_2_predefined;
- public static void Initialize ()
+ public ReflectionMetaImporter ()
{
import_cache = new Dictionary<Type, TypeSpec> (1024, ReferenceEquality<Type>.Default);
+ IgnorePrivateMembers = true;
+ }
+
+ #region Properties
+
+ public bool IgnorePrivateMembers { get; set; }
+ #endregion
+
+ public void Initialize ()
+ {
// Setup mapping for predefined types
type_2_predefined = new Dictionary<Type, PredefinedTypeSpec> () {
{ typeof (object), TypeManager.object_type },
};
}
- public static FieldSpec CreateField (FieldInfo fi, TypeSpec declaringType)
+ public FieldSpec CreateField (FieldInfo fi, TypeSpec declaringType)
{
Modifiers mod = 0;
var fa = fi.Attributes;
}
// Ignore private fields (even for error reporting) to not require extra dependencies
- if (mod == Modifiers.PRIVATE)
+ if (mod == Modifiers.PRIVATE && IgnorePrivateMembers)
return null;
var definition = new ImportedMemberDefinition (fi);
} catch (Exception e) {
// TODO: I should construct fake TypeSpec based on TypeRef signature
// but there is no way to do it with System.Reflection
- throw new InternalErrorException (e, "Cannot import field `{0}.{1}' in assembly `{2}'",
+ throw new InternalErrorException (e, "Cannot import field `{0}.{1}' referenced in assembly `{2}'",
declaringType.GetSignatureForError (), fi.Name, declaringType.Assembly);
}
return new FieldSpec (declaringType, definition, field_type, fi, mod);
}
- public static EventSpec CreateEvent (EventInfo ei, TypeSpec declaringType, MethodSpec add, MethodSpec remove)
+ public EventSpec CreateEvent (EventInfo ei, TypeSpec declaringType, MethodSpec add, MethodSpec remove)
{
add.IsAccessor = true;
remove.IsAccessor = true;
return new EventSpec (declaringType, definition, ImportType (ei.EventHandlerType), add.Modifiers, add, remove);
}
- static T[] CreateGenericParameters<T> (Type type, TypeSpec declaringType) where T : TypeSpec
+ T[] CreateGenericParameters<T> (Type type, TypeSpec declaringType) where T : TypeSpec
{
Type[] tparams = type.GetGenericArguments ();
return CreateGenericParameters<T> (parent_owned_count, tparams);
}
- static T[] CreateGenericParameters<T> (int first, Type[] tparams) where T : TypeSpec
+ T[] CreateGenericParameters<T> (int first, Type[] tparams) where T : TypeSpec
{
var tspec = new T [tparams.Length - first];
for (int pos = first; pos < tparams.Length; ++pos) {
return tspec;
}
- public static MethodSpec CreateMethod (MethodBase mb, TypeSpec declaringType)
+ public MethodSpec CreateMethod (MethodBase mb, TypeSpec declaringType)
{
Modifiers mod = ReadMethodModifiers (mb, declaringType);
TypeParameterSpec[] tparams;
ImportedMethodDefinition definition;
- var parameters = ParametersImported.Create (declaringType, mb);
+ var parameters = CreateParameters (declaringType, mb.GetParameters (), mb);
if (mb.IsGenericMethod) {
if (!mb.IsGenericMethodDefinition)
return ms;
}
+ //
+ // Imports System.Reflection parameters
+ //
+ AParametersCollection CreateParameters (TypeSpec parent, ParameterInfo[] pi, MethodBase method)
+ {
+ int varargs = method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0 ? 1 : 0;
+
+ if (pi.Length == 0 && varargs == 0)
+ return ParametersCompiled.EmptyReadOnlyParameters;
+
+ TypeSpec[] types = new TypeSpec[pi.Length + varargs];
+ IParameterData[] par = new IParameterData[pi.Length + varargs];
+ bool is_params = false;
+ for (int i = 0; i < pi.Length; i++) {
+ ParameterInfo p = pi[i];
+ Parameter.Modifier mod = 0;
+ Expression default_value = null;
+ if (p.ParameterType.IsByRef) {
+ if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out)
+ mod = Parameter.Modifier.OUT;
+ else
+ mod = Parameter.Modifier.REF;
+
+ //
+ // Strip reference wrapping
+ //
+ types[i] = ImportType (p.ParameterType.GetElementType ());
+ } else if (i == 0 && method.IsStatic && parent.IsStatic && // TODO: parent.Assembly.IsExtension &&
+ HasExtensionAttribute (CustomAttributeData.GetCustomAttributes (method)) != null) {
+ mod = Parameter.Modifier.This;
+ types[i] = ImportType (p.ParameterType);
+ } else {
+ types[i] = ImportType (p.ParameterType);
+
+ if (i >= pi.Length - 2 && types[i] is ArrayContainer) {
+ var cattrs = CustomAttributeData.GetCustomAttributes (p);
+ if (cattrs != null && cattrs.Any (l => l.Constructor.DeclaringType == typeof (ParamArrayAttribute))) {
+ mod = Parameter.Modifier.PARAMS;
+ is_params = true;
+ }
+ }
+
+ if (!is_params && p.IsOptional) {
+ object value = p.DefaultValue;
+ if (value == Missing.Value) {
+ default_value = EmptyExpression.Null;
+ } else if (value == null) {
+ default_value = new NullLiteral (Location.Null);
+ } else {
+ default_value = Constant.CreateConstant (null, ImportType (value.GetType ()), value, Location.Null);
+ }
+ }
+ }
+
+ par[i] = new ParameterData (p.Name, mod, default_value);
+ }
+
+ if (varargs != 0) {
+ par[par.Length - 1] = new ArglistParameter (Location.Null);
+ types[types.Length - 1] = InternalType.Arglist;
+ }
+
+ return method != null ?
+ new ParametersImported (par, types, varargs != 0, is_params) :
+ new ParametersImported (par, types, is_params);
+ }
+
+
//
// Returns null when the property is not valid C# property
//
- public static PropertySpec CreateProperty (PropertyInfo pi, TypeSpec declaringType, MethodSpec get, MethodSpec set)
+ public PropertySpec CreateProperty (PropertyInfo pi, TypeSpec declaringType, MethodSpec get, MethodSpec set)
{
var definition = new ImportedMemberDefinition (pi);
return spec;
}
- public static TypeSpec CreateType (Type type)
+ public TypeSpec CreateType (Type type)
{
TypeSpec declaring_type;
if (type.IsNested && !type.IsGenericParameter)
return CreateType (type, declaring_type);
}
- public static TypeSpec CreateType (Type type, TypeSpec declaringType)
+ public TypeSpec CreateType (Type type, TypeSpec declaringType)
{
TypeSpec spec;
if (import_cache.TryGetValue (type, out spec))
mod |= Modifiers.SEALED;
}
- var definition = new ImportedTypeDefinition (type);
+ var definition = new ImportedTypeDefinition (this, type);
PredefinedTypeSpec pt;
if (kind == MemberKind.Enum) {
var type_members = type.GetFields (underlying_member);
foreach (var type_member in type_members) {
- spec = new EnumSpec (declaringType, definition, Import.CreateType (type_member.FieldType), type, mod);
+ spec = new EnumSpec (declaringType, definition, CreateType (type_member.FieldType), type, mod);
break;
}
var ifaces = type.GetInterfaces ();
if (ifaces.Length > 0) {
foreach (Type iface in ifaces) {
- spec.AddInterface (Import.CreateType (iface));
+ spec.AddInterface (CreateType (iface));
}
}
return spec;
}
- static TypeParameterSpec CreateTypeParameter (Type type, TypeSpec declaringType)
+ TypeParameterSpec CreateTypeParameter (Type type, TypeSpec declaringType)
{
Variance variance;
switch (type.GenericParameterAttributes & GenericParameterAttributes.VarianceMask) {
return spec;
}
- public static TypeSpec ImportType (Type type)
+ static Type HasExtensionAttribute (IList<CustomAttributeData> attributes)
+ {
+ foreach (var attr in attributes) {
+ var dt = attr.Constructor.DeclaringType;
+ if (dt.Name == "ExtensionAttribute" && dt.Namespace == "System.Runtime.CompilerServices") {
+ return dt;
+ }
+ }
+
+ return null;
+ }
+
+ public void ImportAssembly (Assembly assembly, Namespace targetNamespace)
+ {
+ Type extension_type = HasExtensionAttribute (CustomAttributeData.GetCustomAttributes (assembly));
+
+ //
+ // This part tries to simulate loading of top-level
+ // types only, any missing dependencies are ignores here.
+ // Full error report is reported later when the type is
+ // actually used
+ //
+ Type[] all_types;
+ try {
+ all_types = assembly.GetTypes ();
+ } catch (ReflectionTypeLoadException e) {
+ all_types = e.Types;
+ }
+
+ Namespace ns = targetNamespace;
+ string prev_namespace = null;
+ foreach (var t in all_types) {
+ if (t == null || t.IsNested)
+ continue;
+
+ if (t.Name[0] == '<')
+ continue;
+
+ var it = CreateType (t, null);
+ if (it == null)
+ continue;
+
+ if (prev_namespace != t.Namespace) {
+ ns = t.Namespace == null ? targetNamespace : targetNamespace.GetNamespace (t.Namespace, true);
+ prev_namespace = t.Namespace;
+ }
+
+ ns.AddType (it);
+
+ if (it.IsStatic && extension_type != null && t.IsDefined (extension_type, false)) {
+ it.SetExtensionMethodContainer ();
+ }
+ }
+ }
+
+ public TypeSpec ImportType (Type type)
{
if (type.HasElementType) {
var element = type.GetElementType ();
{
TypeParameterSpec[] tparams;
string name;
+ ReflectionMetaImporter meta_import;
- public ImportedTypeDefinition (Type type)
+ public ImportedTypeDefinition (ReflectionMetaImporter metaImport, Type type)
: base (type)
{
+ this.meta_import = metaImport;
}
#region Properties
if (attr.Length < 1)
return null;
- return Import.CreateType (((CoClassAttribute) attr[0]).CoClass);
+ return meta_import.CreateType (((CoClassAttribute) attr[0]).CoClass);
}
public string GetAttributeDefaultMember ()
public MemberCache LoadMembers (TypeSpec declaringType)
{
+ //
+ // Not interested in members of nested private types unless the importer needs them
+ //
+ if (declaringType.IsPrivate && meta_import.IgnorePrivateMembers)
+ return MemberCache.Empty;
+
var loading_type = (Type) provider;
const BindingFlags all_members = BindingFlags.DeclaredOnly |
BindingFlags.Static | BindingFlags.Instance |
if (mb.IsPrivate && mb.IsDefined (typeof (CompilerGeneratedAttribute), false))
continue;
- imported = Import.CreateMethod (mb, declaringType);
+ imported = meta_import.CreateMethod (mb, declaringType);
if (imported.Kind == MemberKind.Method && !imported.IsGeneric) {
if (possible_accessors == null)
possible_accessors = new Dictionary<MethodBase, MethodSpec> (ReferenceEquality<MethodBase>.Default);
if (get == null && set == null)
continue;
- imported = Import.CreateProperty (p, declaringType, get, set);
+ imported = meta_import.CreateProperty (p, declaringType, get, set);
if (imported == null)
continue;
if (add == null || remove == null)
continue;
- imported = Import.CreateEvent (e, declaringType, add, remove);
+ imported = meta_import.CreateEvent (e, declaringType, add, remove);
break;
case MemberTypes.Field:
var fi = (FieldInfo) member;
if (fi.IsPrivate && fi.IsDefined (typeof (CompilerGeneratedAttribute), false))
continue;
- imported = Import.CreateField (fi, declaringType);
+ imported = meta_import.CreateField (fi, declaringType);
if (imported == null)
continue;
if (t.IsNotPublic && t.IsDefined (typeof (CompilerGeneratedAttribute), false))
continue;
- imported = Import.CreateType (t, declaringType);
+ imported = meta_import.CreateType (t, declaringType);
break;
default:
throw new NotImplementedException (member.ToString ());
{
foreach (Assembly a in referenced_assemblies) {
try {
- ImportAssembly (a);
+ ctx.MetaImporter.ImportAssembly (a, this);
} catch (TypeLoadException e) {
ctx.Report.Error (11, Location.Null, e.Message);
} catch (System.IO.FileNotFoundException) {
GetNamespace (dotted_name, true);
}
- public void ImportAssembly (Assembly assembly)
- {
- Type extension_type = null;
- var all_attributes = CustomAttributeData.GetCustomAttributes (assembly);
- foreach (var attr in all_attributes) {
- var dt = attr.Constructor.DeclaringType;
- if (dt.Name == "ExtensionAttribute" && dt.Namespace == "System.Runtime.CompilerServices") {
- extension_type = dt;
- break;
- }
- }
-
- //
- // This part tries to simulate loading of top-level
- // types only, any missing dependencies are ignores here.
- // Full error report is reported later when the type is
- // actually used
- //
- Type[] all_types;
- try {
- all_types = assembly.GetTypes ();
- } catch (ReflectionTypeLoadException e) {
- all_types = e.Types;
- }
-
- Namespace ns = this;
- string prev_namespace = null;
- foreach (var t in all_types) {
- if (t == null || t.IsNested)
- continue;
-
- if (t.Name[0] == '<')
- continue;
-
- var it = Import.CreateType (t, null);
- if (it == null)
- continue;
-
- if (prev_namespace != t.Namespace) {
- ns = t.Namespace == null ? this : GetNamespace (t.Namespace, true);
- prev_namespace = t.Namespace;
- }
-
- ns.AddType (it);
-
- if (it.IsStatic && extension_type != null && t.IsDefined (extension_type, false)) {
- it.SetExtensionMethodContainer ();
- }
- }
- }
-
public override string GetSignatureForError ()
{
return alias_name + "::";
//
public class ParametersImported : AParametersCollection
{
- ParametersImported (AParametersCollection param, TypeSpec[] types)
- {
- this.parameters = param.FixedParameters;
- this.types = types;
- has_arglist = param.HasArglist;
- has_params = param.HasParams;
- }
-
- ParametersImported (IParameterData [] parameters, TypeSpec [] types, bool hasArglist, bool hasParams)
+ public ParametersImported (IParameterData [] parameters, TypeSpec [] types, bool hasArglist, bool hasParams)
{
this.parameters = parameters;
this.types = types;
this.types = types;
this.has_params = hasParams;
}
-
- public static AParametersCollection Create (TypeSpec parent, MethodBase method)
- {
- return Create (parent, method.GetParameters (), method);
- }
-
- //
- // Imports System.Reflection parameters
- //
- public static AParametersCollection Create (TypeSpec parent, ParameterInfo [] pi, MethodBase method)
- {
- int varargs = method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0 ? 1 : 0;
-
- if (pi.Length == 0 && varargs == 0)
- return ParametersCompiled.EmptyReadOnlyParameters;
-
- TypeSpec [] types = new TypeSpec [pi.Length + varargs];
- IParameterData [] par = new IParameterData [pi.Length + varargs];
- bool is_params = false;
- for (int i = 0; i < pi.Length; i++) {
- ParameterInfo p = pi [i];
- Parameter.Modifier mod = 0;
- Expression default_value = null;
- if (p.ParameterType.IsByRef) {
- if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out)
- mod = Parameter.Modifier.OUT;
- else
- mod = Parameter.Modifier.REF;
-
- //
- // Strip reference wrapping
- //
- types [i] = Import.ImportType (p.ParameterType.GetElementType ());
- } else if (i == 0 && method.IsStatic && parent.IsStatic && // TODO: parent.Assembly.IsExtension &&
- HasExtensionAttribute (method)) {
- mod = Parameter.Modifier.This;
- types[i] = Import.ImportType (p.ParameterType);
- } else {
- types[i] = Import.ImportType (p.ParameterType);
-
- if (i >= pi.Length - 2 && types[i] is ArrayContainer) {
- var cattrs = CustomAttributeData.GetCustomAttributes (p);
- if (cattrs != null && cattrs.Any (l => l.Constructor.DeclaringType == typeof (ParamArrayAttribute))) {
- mod = Parameter.Modifier.PARAMS;
- is_params = true;
- }
- }
-
- if (!is_params && p.IsOptional) {
- object value = p.DefaultValue;
- if (value == Missing.Value) {
- default_value = EmptyExpression.Null;
- } else if (value == null) {
- default_value = new NullLiteral (Location.Null);
- } else {
- default_value = Constant.CreateConstant (null, Import.ImportType (value.GetType ()), value, Location.Null);
- }
- }
- }
-
- par [i] = new ParameterData (p.Name, mod, default_value);
- }
-
- if (varargs != 0) {
- par [par.Length - 1] = new ArglistParameter (Location.Null);
- types [types.Length - 1] = InternalType.Arglist;
- }
-
- return method != null ?
- new ParametersImported (par, types, varargs != 0, is_params) :
- new ParametersImported (par, types, is_params);
- }
-
- static bool HasExtensionAttribute (MethodBase mb)
- {
- var all_attributes = CustomAttributeData.GetCustomAttributes (mb);
- foreach (var attr in all_attributes) {
- var dt = attr.Constructor.DeclaringType;
- if (dt.Name == "ExtensionAttribute" && dt.Namespace == "System.Runtime.CompilerServices") {
- return true;
- }
- }
-
- return false;
- }
}
/// <summary>
protected virtual void InitializeMemberCache (bool onlyTypes)
{
- //
- // Not interested in members of nested private types
- //
- if (IsPrivate) {
- cache = new MemberCache (0);
- } else {
- cache = MemberDefinition.LoadMembers (this);
- }
+ cache = MemberDefinition.LoadMembers (this);
}
//
--- /dev/null
+using System;
+
+// Tests private accessibility for dynamic binder
+
+class Test
+{
+ private delegate int D ();
+ private int field = 9;
+
+ public static int Main ()
+ {
+ D del = () => 5;
+ dynamic d = del;
+ if (d () != 5)
+ return 1;
+
+ d = new Test ();
+ if (d.field != 9)
+ return 2;
+
+ return 0;
+ }
+}
--- /dev/null
+public class List<X>
+{
+ public class Comp<Y>
+ {
+ public List<Y>.Comp<X> flip (Y y, X x)
+ {
+ return new Flip<Y> (this);
+ }
+ }
+ public class Flip<Z> : List<Z>.Comp<X>
+ {
+ Comp<Z> c;
+ public Flip (Comp<Z> cc) { c = cc; }
+ }
+}
+
+class C
+{
+ public static int Main ()
+ {
+ var a = new List<short>.Comp<bool> ().flip (true, 3);
+ return 0;
+ }
+}
</method>
</type>
</test>
+ <test name="dtest-024.cs">
+ <type name="Test">
+ <method name="Int32 Main()">
+ <size>524</size>
+ </method>
+ <method name="Int32 <Main>m__0()">
+ <size>2</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>15</size>
+ </method>
+ </type>
+ <type name="Test+D">
+ <method name="Int32 Invoke()">
+ <size>0</size>
+ </method>
+ <method name="IAsyncResult BeginInvoke(System.AsyncCallback, System.Object)">
+ <size>0</size>
+ </method>
+ <method name="Int32 EndInvoke(IAsyncResult)">
+ <size>0</size>
+ </method>
+ <method name="Void .ctor(Object, IntPtr)">
+ <size>0</size>
+ </method>
+ </type>
+ </test>
<test name="dtest-error-01.cs">
<type name="Helper">
<method name="Int32* Foo(Int32)">
</method>
</type>
</test>
+ <test name="gtest-533.cs">
+ <type name="List`1[X]">
+ <method name="Void .ctor()">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="List`1+Comp`1[X,Y]">
+ <method name="List`1+Comp`1[Y,X] flip(Y, X)">
+ <size>7</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="List`1+Flip`1[X,Z]">
+ <method name="Void .ctor(Comp`1)">
+ <size>14</size>
+ </method>
+ </type>
+ <type name="C">
+ <method name="Int32 Main()">
+ <size>15</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="gtest-anon-1.cs">
<type name="X">
<method name="Void .ctor()">