public class ParenthesizedExpression : ShimExpression
{
+ bool conditional_access_receiver;
+
public ParenthesizedExpression (Expression expr, Location loc)
: base (expr)
{
this.loc = loc;
}
- protected override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext rc)
{
- var res = expr.Resolve (ec);
+ Expression res = null;
+
+ if (!rc.HasSet (ResolveContext.Options.ConditionalAccessReceiver)) {
+ if (expr.HasConditionalAccess ()) {
+ conditional_access_receiver = true;
+ using (rc.Set (ResolveContext.Options.ConditionalAccessReceiver)) {
+ res = expr.Resolve (rc);
+ }
+ }
+ }
+
+ if (!conditional_access_receiver)
+ res = expr.Resolve (rc);
+
var constant = res as Constant;
if (constant != null && constant.IsLiteral)
return Constant.CreateConstantFromValue (res.Type, constant.GetValue (), expr.Location);
+ if (conditional_access_receiver) {
+ expr = res;
+ type = LiftMemberType (rc, res.Type);
+ eclass = expr.eclass;
+ return this;
+ }
+
return res;
}
return visitor.Visit (this);
}
+ public override void Emit (EmitContext ec)
+ {
+ if (!conditional_access_receiver)
+ base.Emit (ec);
+
+ var prev = ec.ConditionalAccess;
+ ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ());
+ expr.Emit (ec);
+ ec.CloseConditionalAccess (type.IsNullableType ? type : null);
+ ec.ConditionalAccess = prev;
+ }
+
public override bool HasConditionalAccess ()
{
- return expr.HasConditionalAccess ();
+ return false;
}
}
+++ /dev/null
-using System;
-
-class Test
-{
- static void Main ()
- {
- Test_1 ("");
- Test_1<object> (null);
-
- Test_2<object> (null);
- Test_2 ("z");
- Test_2 (0);
- Test_2 ((long?) -8);
-
- Test_3 (new int[1]);
- Test_3 (new int[] { 5 });
- }
-
- static void Test_1<T> (T x) where T : class
- {
- x?.Call ();
- }
-
- static void Test_2<T> (T x)
- {
- x?.Call ();
- }
-
- static void Test_3<T> (T[] x)
- {
- x[0]?.Call ();
- }
-}
-
-static class Ext
-{
- public static void Call<T> (this T t)
- {
- Console.WriteLine (typeof (T));
- }
-}
+++ /dev/null
-static class Crash
-{
- static string GetFoo ()
- {
- return null;
- }
-
- static void Main ()
- {
- (GetFoo ()?.ToLower ()).ToUpper ();
- }
-}
--- /dev/null
+using System;
+
+static class Crash
+{
+ static X GetFoo ()
+ {
+ return null;
+ }
+
+ static int Main ()
+ {
+ int res = (GetFoo ()?.ToLower ()).ToUpper ();
+ if (res != 0)
+ return 1;
+
+ return 0;
+ }
+}
+
+class X
+{
+ public Y ToLower ()
+ {
+ throw new ApplicationException ("should not be called");
+ }
+}
+
+class Y
+{
+}
+
+static class SS
+{
+ public static int ToUpper (this Y y)
+ {
+ if (y != null)
+ return 1;
+
+ return 0;
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+
+class Test
+{
+ static void Main ()
+ {
+ Test_1 ("");
+ Test_1<object> (null);
+
+ Test_2<object> (null);
+ Test_2 ("z");
+ Test_2 (0);
+ Test_2 ((long?) -8);
+
+ Test_3 (new int[1]);
+ Test_3 (new int[] { 5 });
+ }
+
+ static void Test_1<T> (T x) where T : class
+ {
+ x?.Call ();
+ }
+
+ static void Test_2<T> (T x)
+ {
+ x?.Call ();
+ }
+
+ static void Test_3<T> (T[] x)
+ {
+ x[0]?.Call ();
+ }
+}
+
+static class Ext
+{
+ public static void Call<T> (this T t)
+ {
+ Console.WriteLine (typeof (T));
+ }
+}
--- /dev/null
+using System.Linq;
+using System.Collections.Generic;
+
+class MM
+{
+ public IEnumerable<int> myEnumerable { get; set; }
+}
+
+class Test
+{
+ public static void Main ()
+ {
+ MM myobject = null;
+ (myobject?.myEnumerable?.Any ()).GetValueOrDefault (false);
+ }
+}
</method>
</type>
</test>
- <test name="test-null-operator-010.cs">
- <type name="Test">
- <method name="Void Main()" attrs="145">
- <size>79</size>
- </method>
- <method name="Void Test_1[T](T)" attrs="145">
- <size>22</size>
- </method>
- <method name="Void Test_2[T](T)" attrs="145">
- <size>21</size>
- </method>
- <method name="Void Test_3[T](T[])" attrs="145">
- <size>28</size>
- </method>
- <method name="Void .ctor()" attrs="6278">
- <size>7</size>
- </method>
- </type>
- <type name="Ext">
- <method name="Void Call[T](T)" attrs="150">
- <size>17</size>
- </method>
- </type>
- </test>
- <test name="test-null-operator-011.cs">
- <type name="Crash">
- <method name="System.String GetFoo()" attrs="145">
- <size>10</size>
- </method>
- <method name="Void Main()" attrs="145">
- <size>27</size>
- </method>
- </type>
- </test>
<test name="test-null-operator-02.cs">
<type name="CI">
<method name="Int32 get_Prop()" attrs="2182">
</method>
</type>
</test>
+ <test name="test-null-operator-13.cs">
+ <type name="Crash">
+ <method name="X GetFoo()" attrs="145">
+ <size>10</size>
+ </method>
+ <method name="Int32 Main()" attrs="145">
+ <size>49</size>
+ </method>
+ </type>
+ <type name="X">
+ <method name="Y ToLower()" attrs="134">
+ <size>12</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="Y">
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="SS">
+ <method name="Int32 ToUpper(Y)" attrs="150">
+ <size>23</size>
+ </method>
+ </type>
+ </test>
+ <test name="test-null-operator-14.cs">
+ <type name="Test">
+ <method name="Void Main()" attrs="145">
+ <size>79</size>
+ </method>
+ <method name="Void Test_1[T](T)" attrs="145">
+ <size>22</size>
+ </method>
+ <method name="Void Test_2[T](T)" attrs="145">
+ <size>21</size>
+ </method>
+ <method name="Void Test_3[T](T[])" attrs="145">
+ <size>28</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="Ext">
+ <method name="Void Call[T](T)" attrs="150">
+ <size>17</size>
+ </method>
+ </type>
+ </test>
+ <test name="test-null-operator-15.cs">
+ <type name="MM">
+ <method name="System.Collections.Generic.IEnumerable`1[System.Int32] get_myEnumerable()" attrs="2182">
+ <size>14</size>
+ </method>
+ <method name="Void set_myEnumerable(System.Collections.Generic.IEnumerable`1[System.Int32])" attrs="2182">
+ <size>8</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="Test">
+ <method name="Void Main()" attrs="150">
+ <size>65</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="test-partial-01.cs">
<type name="Foo.Hello">
<method name="Void .ctor()" attrs="6278">