protected override Expression DoResolve (ResolveContext rc)
{
Expression res = null;
-
- res = expr.Resolve (rc);
+ using (rc.With (ResolveContext.Options.DontSetConditionalAccessReceiver, false)) {
+ res = expr.Resolve (rc);
+ }
var constant = res as Constant;
if (constant != null && constant.IsLiteral) {
}
right.Emit (ec);
- switch (rtype.BuiltinType) {
- case BuiltinTypeSpec.Type.SByte:
- case BuiltinTypeSpec.Type.Byte:
- case BuiltinTypeSpec.Type.Short:
- case BuiltinTypeSpec.Type.UShort:
- ec.Emit (OpCodes.Conv_I);
- break;
- case BuiltinTypeSpec.Type.UInt:
- ec.Emit (OpCodes.Conv_U);
- break;
+ if (right_const == null) {
+ switch (rtype.BuiltinType) {
+ case BuiltinTypeSpec.Type.SByte:
+ case BuiltinTypeSpec.Type.Byte:
+ case BuiltinTypeSpec.Type.Short:
+ case BuiltinTypeSpec.Type.UShort:
+ case BuiltinTypeSpec.Type.Int:
+ ec.Emit (OpCodes.Conv_I);
+ break;
+ case BuiltinTypeSpec.Type.UInt:
+ ec.Emit (OpCodes.Conv_U);
+ break;
+ }
}
if (right_const == null && size != 1){
}
New n_source = source as New;
- if (n_source != null) {
+ if (n_source != null && n_source.CanEmitOptimizedLocalTarget (ec)) {
if (!n_source.Emit (ec, this)) {
if (leave_copy) {
EmitLoad (ec);
}
}
- return new DynamicInvocation (expr as ATypeNameExpression, args, loc).Resolve (ec);
+ return new DynamicInvocation (expr as ATypeNameExpression, args, conditional_access_receiver, loc).Resolve (ec);
}
protected virtual MethodGroupExpr DoResolveOverload (ResolveContext ec)
ec.Emit (OpCodes.Pop);
}
+ public virtual bool CanEmitOptimizedLocalTarget (EmitContext ec)
+ {
+ return true;
+ }
+
public override void FlowAnalysis (FlowAnalysisContext fc)
{
if (arguments != null)
return retval;
}
+ var cma = this as ConditionalMemberAccess;
+
MemberExpr me;
TypeSpec expr_type = expr.Type;
if (expr_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
Arguments args = new Arguments (1);
args.Add (new Argument (expr));
+
+ if (cma != null)
+ return new DynamicConditionalMemberBinder (Name, args, loc);
+
return new DynamicMemberBinder (Name, args, loc);
}
- var cma = this as ConditionalMemberAccess;
if (cma != null) {
if (!IsNullPropagatingValid (expr.Type)) {
expr.Error_OperatorCannotBeApplied (rc, loc, "?", expr.Type);
args.AddRange (arguments);
best_candidate = null;
- return new DynamicIndexBinder (args, loc);
+ return new DynamicIndexBinder (args, conditional_access_receiver, ConditionalAccess, loc);
}
//
args.Add (new Argument (rc.CurrentInitializerVariable));
target = new DynamicMemberBinder (Name, args, loc);
} else {
-
var member = MemberLookup (rc, false, t, Name, 0, MemberLookupRestrictions.ExactArity, loc);
if (member == null) {
member = Expression.MemberLookup (rc, true, t, Name, 0, MemberLookupRestrictions.ExactArity, loc);
public override void Emit (EmitContext ec)
{
- if (method == null && TypeSpec.IsValueType (type) && initializers.Initializers.Count > 1 && ec.HasSet (BuilderContext.Options.AsyncBody) && initializers.ContainsEmitWithAwait ()) {
+ if (!CanEmitOptimizedLocalTarget (ec)) {
var fe = ec.GetTemporaryField (type);
if (!Emit (ec, fe))
return true;
}
+ public override bool CanEmitOptimizedLocalTarget (EmitContext ec)
+ {
+ return !(method == null && TypeSpec.IsValueType (type) &&
+ initializers.Initializers.Count > 1 && ec.HasSet (BuilderContext.Options.AsyncBody) &&
+ initializers.ContainsEmitWithAwait ());
+ }
+
protected override IMemoryLocation EmitAddressOf (EmitContext ec, AddressOp Mode)
{
instance = base.EmitAddressOf (ec, Mode);
str = start.Value;
arguments = new Arguments (1);
} else {
- for (int i = 0; i < interpolations.Count; i += 2) {
- var ipi = (InterpolatedStringInsert)interpolations [i];
- ipi.Resolve (rc);
- }
-
arguments = new Arguments (interpolations.Count);
var sb = new StringBuilder (start.Value);
}
sb.Append ('}');
- arguments.Add (new Argument (interpolations [i]));
+ arguments.Add (new Argument (isi.Resolve (rc)));
} else {
sb.Append (((StringLiteral)interpolations [i]).Value);
}
ca.Emit (ec, best, arguments, loc);
}
+ public override void FlowAnalysis (FlowAnalysisContext fc)
+ {
+ if (interpolations != null) {
+ foreach (var expr in interpolations) {
+ expr.FlowAnalysis (fc);
+ }
+ }
+ }
+
MethodSpec ResolveBestFormatOverload (ResolveContext rc)
{
var members = MemberCache.FindMembers (rc.BuiltinTypes.String, "Format", true);
return Convert.ImplicitConversionRequired (rc, expr, rc.BuiltinTypes.Object, expr.Location);
}
+ public override void FlowAnalysis (FlowAnalysisContext fc)
+ {
+ Child.FlowAnalysis (fc);
+ }
+
public int? ResolveAligment (ResolveContext rc)
{
var c = Alignment.ResolveLabelConstant (rc);