本文整理汇总了C#中IronRuby.Runtime.Calls.MetaObjectBuilder.AddTargetTypeTest方法的典型用法代码示例。如果您正苦于以下问题:C# MetaObjectBuilder.AddTargetTypeTest方法的具体用法?C# MetaObjectBuilder.AddTargetTypeTest怎么用?C# MetaObjectBuilder.AddTargetTypeTest使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类IronRuby.Runtime.Calls.MetaObjectBuilder
的用法示例。
在下文中一共展示了MetaObjectBuilder.AddTargetTypeTest方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: TryBind
public static DynamicMetaObject TryBind(RubyContext/*!*/ context, GetMemberBinder/*!*/ binder, DynamicMetaObject/*!*/ target) {
Assert.NotNull(context, target);
var metaBuilder = new MetaObjectBuilder();
var contextExpression = AstUtils.Constant(context);
RubyClass targetClass = context.GetImmediateClassOf(target.Value);
MethodResolutionResult method;
RubyMemberInfo methodMissing = null;
using (targetClass.Context.ClassHierarchyLocker()) {
metaBuilder.AddTargetTypeTest(target.Value, targetClass, target.Expression, context, contextExpression);
method = targetClass.ResolveMethodForSiteNoLock(binder.Name, RubyClass.IgnoreVisibility);
if (method.Found) {
methodMissing = targetClass.ResolveMethodForSiteNoLock(Symbols.MethodMissing, RubyClass.IgnoreVisibility).Info;
}
}
if (method.Found) {
// we need to create a bound member:
metaBuilder.Result = AstUtils.Constant(new RubyMethod(target.Value, method.Info, binder.Name));
} else {
// TODO:
// We need to throw an exception if we don't find method_missing so that our version update optimization works:
// This limits interop with other languages.
//
// class B CLR type with method 'foo'
// class C < B Ruby class
// x = C.new
//
// 1. x.GET("foo") from Ruby
// No method found or CLR method found -> fallback to Python
// Python might see its method foo or might just fallback to .NET,
// in any case it will add rule [1] with restriction on type of C w/o Ruby version check.
// 2. B.define_method("foo")
// This doesn't update C due to the optimization (there is no overridden method foo in C).
// 3. x.GET("foo") from Ruby
// This will not invoke the binder since the rule [1] is still valid.
//
object symbol = SymbolTable.StringToId(binder.Name);
RubyCallAction.BindToMethodMissing(metaBuilder,
new CallArguments(
new DynamicMetaObject(contextExpression, BindingRestrictions.Empty, context),
new[] {
target,
new DynamicMetaObject(AstUtils.Constant(symbol), BindingRestrictions.Empty, symbol)
},
RubyCallSignature.Simple(1)
),
binder.Name,
methodMissing,
method.IncompatibleVisibility,
false
);
}
// TODO: we should return null if we fail, we need to throw exception for now:
return metaBuilder.CreateMetaObject(binder, DynamicMetaObject.EmptyMetaObjects);
}
示例2: TryBind
public static MetaObject TryBind(RubyContext/*!*/ context, GetMemberBinder/*!*/ binder, MetaObject/*!*/ target) {
Assert.NotNull(context, target);
var metaBuilder = new MetaObjectBuilder();
var contextExpression = Ast.Constant(context);
metaBuilder.AddTargetTypeTest(target.Value, target.Expression, context, contextExpression);
RubyMemberInfo method = context.ResolveMethod(target.Value, binder.Name, true).InvalidateSitesOnOverride();
if (method != null && RubyModule.IsMethodVisible(method, false)) {
// we need to create a bound member:
metaBuilder.Result = Ast.Constant(new RubyMethod(target.Value, method, binder.Name));
} else {
// TODO:
// We need to throw an exception if we don't find method_missing so that our version update optimization works:
// This limits interop with other languages.
//
// class B CLR type with method 'foo'
// class C < B Ruby class
// x = C.new
//
// 1. x.GET("foo") from Ruby
// No method found or CLR method found -> fallback to Python
// Python might see its method foo or might just fallback to .NET,
// in any case it will add rule [1] with restriction on type of C w/o Ruby version check.
// 2. B.define_method("foo")
// This doesn't update C due to the optimization (there is no overridden method foo in C).
// 3. x.GET("foo") from Ruby
// This will not invoke the binder since the rule [1] is still valid.
//
object symbol = SymbolTable.StringToId(binder.Name);
RubyCallAction.BindToMethodMissing(metaBuilder, binder.Name,
new CallArguments(
new MetaObject(contextExpression, Restrictions.Empty, context),
new[] {
target,
new MetaObject(Ast.Constant(symbol), Restrictions.Empty, symbol)
},
RubyCallSignature.Simple(1)
),
method != null
);
}
// TODO: we should return null if we fail, we need to throw exception for now:
return metaBuilder.CreateMetaObject(binder, MetaObject.EmptyMetaObjects);
}
示例3: BuildConversion
internal static void BuildConversion(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) {
const string ToS = "to_s";
if (TryImplicitConversion(metaBuilder, args)) {
metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression);
return;
}
RubyMemberInfo conversionMethod, methodMissing = null;
RubyClass targetClass = args.RubyContext.GetImmediateClassOf(args.Target);
using (targetClass.Context.ClassHierarchyLocker()) {
metaBuilder.AddTargetTypeTest(args.Target, targetClass, args.TargetExpression, args.MetaContext,
new[] { ToS, Symbols.MethodMissing }
);
conversionMethod = targetClass.ResolveMethodForSiteNoLock(ToS, VisibilityContext.AllVisible).Info;
// find method_missing - we need to add "to_xxx" methods to the missing methods table:
if (conversionMethod == null) {
methodMissing = targetClass.ResolveMethodMissingForSite(ToS, RubyMethodVisibility.None);
}
}
// invoke target.to_s and if successful convert the result to string unless it is already:
if (conversionMethod != null) {
conversionMethod.BuildCall(metaBuilder, args, ToS);
if (metaBuilder.Error) {
return;
}
} else {
RubyCallAction.BuildMethodMissingCall(metaBuilder, args, ToS, methodMissing, RubyMethodVisibility.None, false, true);
}
metaBuilder.Result = Methods.ToSDefaultConversion.OpCall(
AstUtils.Convert(args.MetaContext.Expression, typeof(RubyContext)),
AstFactory.Box(args.TargetExpression),
AstFactory.Box(metaBuilder.Result)
);
}
示例4: Build
protected override void Build(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) {
const string ToS = "to_s";
// no conversion for a subclass of string:
var stringTarget = args.Target as MutableString;
if (stringTarget != null) {
metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression);
metaBuilder.Result = AstUtils.Convert(args.TargetExpression, typeof(MutableString));
return;
}
RubyMemberInfo conversionMethod, methodMissing = null;
RubyClass targetClass = args.RubyContext.GetImmediateClassOf(args.Target);
using (targetClass.Context.ClassHierarchyLocker()) {
metaBuilder.AddTargetTypeTest(args.Target, targetClass, args.TargetExpression, args.MetaContext);
conversionMethod = targetClass.ResolveMethodForSiteNoLock(ToS, RubyClass.IgnoreVisibility).Info;
// find method_missing - we need to add "to_xxx" methods to the missing methods table:
if (conversionMethod == null) {
methodMissing = targetClass.ResolveMethodMissingForSite(ToS, RubyMethodVisibility.None);
}
}
// invoke target.to_s and if successful convert the result to string unless it is already:
if (conversionMethod != null) {
conversionMethod.BuildCall(metaBuilder, args, ToS);
if (metaBuilder.Error) {
return;
}
} else {
RubyCallAction.BindToMethodMissing(metaBuilder, args, ToS, methodMissing, RubyMethodVisibility.None, false, true);
}
metaBuilder.Result = Methods.ToSDefaultConversion.OpCall(
AstUtils.Convert(args.MetaContext.Expression, typeof(RubyContext)),
AstFactory.Box(args.TargetExpression),
AstFactory.Box(metaBuilder.Result)
);
}
示例5: Resolve
internal static MethodResolutionResult Resolve(MetaObjectBuilder/*!*/ metaBuilder, string/*!*/ methodName, CallArguments/*!*/ args,
out RubyMemberInfo methodMissing) {
MethodResolutionResult method;
var targetClass = args.TargetClass;
var visibilityContext = GetVisibilityContext(args.Signature, args.Scope);
using (targetClass.Context.ClassHierarchyLocker()) {
metaBuilder.AddTargetTypeTest(args.Target, targetClass, args.TargetExpression, args.MetaContext,
new[] { methodName, Symbols.MethodMissing }
);
if (args.Signature.IsSuperCall) {
Debug.Assert(!args.Signature.IsVirtualCall && args.Signature.HasImplicitSelf);
method = targetClass.ResolveSuperMethodNoLock(methodName, targetClass).InvalidateSitesOnOverride();
} else {
var options = args.Signature.IsVirtualCall ? MethodLookup.Virtual : MethodLookup.Default;
method = targetClass.ResolveMethodForSiteNoLock(methodName, visibilityContext, options);
}
if (!method.Found) {
methodMissing = targetClass.ResolveMethodMissingForSite(methodName, method.IncompatibleVisibility);
} else {
methodMissing = null;
}
}
// Whenever the current self's class changes we need to invalidate the rule, if a protected method is being called.
if (method.Info != null && method.Info.IsProtected && visibilityContext.Class != null) {
// We don't need to compare versions, just the class objects (super-class relationship cannot be changed).
// Since we don't want to hold on a class object (to make it collectible) we compare references to the version handlers.
metaBuilder.AddCondition(Ast.Equal(
Methods.GetSelfClassVersionHandle.OpCall(AstUtils.Convert(args.MetaScope.Expression, typeof(RubyScope))),
Ast.Constant(visibilityContext.Class.Version)
));
}
return method;
}
示例6: Build
protected override bool Build(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, bool defaultFallback)
{
RubyModule currentDeclaringModule;
string currentMethodName;
var scope = args.Scope;
var scopeExpr = AstUtils.Convert(args.MetaScope.Expression, typeof(RubyScope));
RubyScope targetScope;
int scopeNesting = scope.GetSuperCallTarget(out currentDeclaringModule, out currentMethodName, out targetScope);
if (scopeNesting == -1) {
metaBuilder.AddCondition(Methods.IsSuperOutOfMethodScope.OpCall(scopeExpr));
metaBuilder.SetError(Methods.MakeTopLevelSuperException.OpCall());
return true;
}
object target = targetScope.SelfObject;
var targetExpression = metaBuilder.GetTemporary(typeof(object), "#super-self");
var assignTarget = Ast.Assign(
targetExpression,
Methods.GetSuperCallTarget.OpCall(scopeExpr, AstUtils.Constant(scopeNesting))
);
if (_signature.HasImplicitArguments && targetScope.Kind == ScopeKind.BlockMethod) {
metaBuilder.AddCondition(Ast.NotEqual(assignTarget, Ast.Field(null, Fields.NeedsUpdate)));
metaBuilder.SetError(Methods.MakeImplicitSuperInBlockMethodError.OpCall());
return true;
}
// If we need to update we return RubyOps.NeedsUpdate instance that will cause the subsequent conditions to fail:
metaBuilder.AddInitialization(assignTarget);
args.SetTarget(targetExpression, target);
Debug.Assert(currentDeclaringModule != null);
RubyMemberInfo method;
RubyMemberInfo methodMissing = null;
// MRI bug: Uses currentDeclaringModule for method look-up so we can end up with an instance method of class C
// called on a target of another class. See http://redmine.ruby-lang.org/issues/show/2419.
// we need to lock the hierarchy of the target class:
var targetClass = scope.RubyContext.GetImmediateClassOf(target);
using (targetClass.Context.ClassHierarchyLocker()) {
// initialize all methods in ancestors:
targetClass.InitializeMethodsNoLock();
// target is stored in a local, therefore it cannot be part of the restrictions:
metaBuilder.TreatRestrictionsAsConditions = true;
metaBuilder.AddTargetTypeTest(target, targetClass, targetExpression, args.MetaContext,
new[] { Symbols.MethodMissing } // currentMethodName is resolved for super, which cannot be an instance singleton
);
metaBuilder.TreatRestrictionsAsConditions = false;
method = targetClass.ResolveSuperMethodNoLock(currentMethodName, currentDeclaringModule).InvalidateSitesOnOverride().Info;
if (_signature.ResolveOnly) {
metaBuilder.Result = AstUtils.Constant(method != null);
return true;
}
if (method == null) {
// MRI: method_missing is called for the targetClass, not for the super:
methodMissing = targetClass.ResolveMethodMissingForSite(currentMethodName, RubyMethodVisibility.None);
}
}
if (method != null) {
method.BuildSuperCall(metaBuilder, args, currentMethodName, currentDeclaringModule);
} else {
return RubyCallAction.BuildMethodMissingCall(metaBuilder, args, currentMethodName, methodMissing, RubyMethodVisibility.None, true, defaultFallback);
}
return true;
}
示例7: Build
protected override bool Build(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, bool defaultFallback) {
RubyModule currentDeclaringModule;
string currentMethodName;
var scope = args.Scope;
object target;
scope.GetSuperCallTarget(out currentDeclaringModule, out currentMethodName, out target);
var targetExpression = metaBuilder.GetTemporary(typeof(object), "#super-self");
metaBuilder.AddCondition(
Methods.IsSuperCallTarget.OpCall(
AstUtils.Convert(args.MetaScope.Expression, typeof(RubyScope)),
AstUtils.Constant(currentDeclaringModule),
AstUtils.Constant(currentMethodName),
targetExpression
)
);
args.SetTarget(targetExpression, target);
Debug.Assert(currentDeclaringModule != null);
RubyMemberInfo method;
RubyMemberInfo methodMissing = null;
// we need to lock the hierarchy of the target class:
var targetClass = scope.RubyContext.GetImmediateClassOf(target);
using (targetClass.Context.ClassHierarchyLocker()) {
// initialize all methods in ancestors:
targetClass.InitializeMethodsNoLock();
// target is stored in a local, therefore it cannot be part of the restrictions:
metaBuilder.TreatRestrictionsAsConditions = true;
metaBuilder.AddTargetTypeTest(target, targetClass, targetExpression, args.MetaContext,
new[] { Symbols.MethodMissing } // currentMethodName is resolved for super, which cannot be an instance singleton
);
metaBuilder.TreatRestrictionsAsConditions = false;
method = targetClass.ResolveSuperMethodNoLock(currentMethodName, currentDeclaringModule).InvalidateSitesOnOverride().Info;
if (_signature.ResolveOnly) {
metaBuilder.Result = AstUtils.Constant(method != null);
return true;
}
if (method == null) {
// MRI: method_missing is called for the targetClass, not for the super:
methodMissing = targetClass.ResolveMethodMissingForSite(currentMethodName, RubyMethodVisibility.None);
}
}
if (method != null) {
method.BuildSuperCall(metaBuilder, args, currentMethodName, currentDeclaringModule);
} else {
return RubyCallAction.BuildMethodMissingCall(metaBuilder, args, currentMethodName, methodMissing, RubyMethodVisibility.None, true, defaultFallback);
}
return true;
}
示例8: Resolve
internal static MethodResolutionResult Resolve(MetaObjectBuilder/*!*/ metaBuilder, string/*!*/ methodName, CallArguments/*!*/ args,
out RubyMemberInfo methodMissing) {
MethodResolutionResult method;
RubyClass targetClass = args.RubyContext.GetImmediateClassOf(args.Target);
using (targetClass.Context.ClassHierarchyLocker()) {
metaBuilder.AddTargetTypeTest(args.Target, targetClass, args.TargetExpression, args.MetaContext);
// TODO: All sites should have either implicit-self or has-scope flag set?
var visibilityContext = args.Signature.HasImplicitSelf || !args.Signature.HasScope ? RubyClass.IgnoreVisibility : args.Scope.SelfImmediateClass;
method = targetClass.ResolveMethodForSiteNoLock(methodName, visibilityContext);
if (!method.Found) {
if (args.Signature.IsTryCall) {
// TODO: this shouldn't throw. We need to fix caching of non-existing methods.
throw new MissingMethodException();
// metaBuilder.Result = AstUtils.Constant(Fields.RubyOps_MethodNotFound);
} else {
methodMissing = targetClass.ResolveMethodMissingForSite(methodName, method.IncompatibleVisibility);
}
} else {
methodMissing = null;
}
}
// Whenever the current self's class changes we need to invalidate the rule, if a protected method is being called.
if (method.Info != null && method.Info.IsProtected && !args.Signature.HasImplicitSelf) {
// We don't need to compare versions, just the class objects (super-class relationship cannot be changed).
// Since we don't want to hold on a class object (to make it collectible) we compare references to the version boxes.
metaBuilder.AddCondition(Ast.Equal(
Methods.GetSelfClassVersionHandle.OpCall(AstUtils.Convert(args.MetaScope.Expression, typeof(RubyScope))),
Ast.Constant(args.Scope.SelfImmediateClass.Version)
));
}
return method;
}