public MethodGroupResolutionFailedException(JSToCSharpExceptionType type, MethodGroup methodGroup, Dictionary<MethodInfo, MethodResolutionException> failboats, TypeInferenceContext ctx, Exception innerException) : base(type, ctx.Root.AsArray().Concat(ctx.Root.Parents()).Last(), ctx.Root, innerException) { MethodGroup = methodGroup; Failboats = failboats; try { ActualArguments = ctx.Root.ToXArgs(ctx.Inferences).ToArray(); } catch (Exception) { // sigh, the client won't get full info from the crash site // sad, but true, so just ignore possible exceptions } }
private void InferMethodGroup(MethodGroup mg, RelinqScriptExpression root, TypeInferenceCache cache) { // q: should existing but not accessible (security!) methods be included into the resolution? // a: yes and here's why: // scenario 1. Included; when overload resolution binds to an unauthorized method = crash. // scenario 2. Not included, so overload resolution binds to an unexpected method = fail. // lets us the fail fast if the resolution is unnecessary. // inferences made here won't be wasted anyways since they get cached var ctx = new TypeInferenceContext(root, cache, Integration); var preview = new TypeInferenceEngine(ctx); root.CallArgs().ForEach(child => preview.InferTypes(child)); // we cannot pass the preview.Ctx inside since it might have // potentially half-inferred lambdas that won't be able to be reinferred // by MG resolution since ctx is init only. var resolved = mg.Resolve(ctx); cache.Add(root, resolved.Signature.ReturnType); cache.Invocations.Add(root, resolved); cache.Upgrade(resolved.Inferences); }
private void InferOperator(OperatorExpression oe, TypeInferenceCache cache) { var preview = cache.Clone(); oe.Operands.ForEach(operand => InferTypes(operand, preview)); var types = oe.Operands.Select(operand => preview[operand]); if (types.Any(type => type is Variant)) { cache.Add(oe, new Variant()); cache.Upgrade(preview); } else { var alts = oe.Type.LookupOperators(types.ToArray()); // logical not can also be used to express ones complement // since they both correspond to a single LINQ expression type if (oe.Type == OperatorType.LogicalNot) { var addendum = OperatorType.OnesComplement.LookupOperators(types.ToArray()); if (addendum != null) { var original = alts == null ? new MethodInfo[0] : alts.Alts; alts = new MethodGroup(original.Concat(addendum.Alts), oe.Type.GetOpCode()); } } if (alts == null) { throw new NoSuchOperatorException(Root, oe, types); } InferMethodGroup(alts, oe, cache); } }
public MethodGroupResolutionFailedException(JSToCSharpExceptionType type, MethodGroup methodGroup, Dictionary<MethodInfo, MethodResolutionException> failboats, TypeInferenceContext ctx) : this(type, methodGroup, failboats, ctx, null) { }