You've already forked linux-packaging-mono
Imported Upstream version 3.10.0
Former-commit-id: 172c8e3c300b39d5785c7a3e8dfb08ebdbc1a99b
This commit is contained in:
@@ -34,6 +34,11 @@ namespace Mono.CSharp
|
||||
Default = 3, // argument created from default parameter value
|
||||
DynamicTypeName = 4, // System.Type argument for dynamic binding
|
||||
ExtensionType = 5, // Instance expression inserted as the first argument
|
||||
|
||||
// Conditional instance expression inserted as the first argument
|
||||
ExtensionTypeConditionalAccess = 5 | ConditionalAccessFlag,
|
||||
|
||||
ConditionalAccessFlag = 1 << 7
|
||||
}
|
||||
|
||||
public readonly AType ArgType;
|
||||
@@ -60,6 +65,12 @@ namespace Mono.CSharp
|
||||
get { return ArgType == AType.Default; }
|
||||
}
|
||||
|
||||
public bool IsExtensionType {
|
||||
get {
|
||||
return (ArgType & AType.ExtensionType) == AType.ExtensionType;
|
||||
}
|
||||
}
|
||||
|
||||
public Parameter.Modifier Modifier {
|
||||
get {
|
||||
switch (ArgType) {
|
||||
@@ -105,7 +116,13 @@ namespace Mono.CSharp
|
||||
public virtual void Emit (EmitContext ec)
|
||||
{
|
||||
if (!IsByRef) {
|
||||
Expr.Emit (ec);
|
||||
if (ArgType == AType.ExtensionTypeConditionalAccess) {
|
||||
var ie = new InstanceEmitter (Expr, false);
|
||||
ie.Emit (ec, true);
|
||||
} else {
|
||||
Expr.Emit (ec);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -819,7 +819,7 @@ namespace Mono.CSharp
|
||||
args.Add (new Argument (awaiter, Argument.AType.Ref));
|
||||
args.Add (new Argument (new CompilerGeneratedThis (CurrentType, Location), Argument.AType.Ref));
|
||||
using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
|
||||
mg.EmitCall (ec, args);
|
||||
mg.EmitCall (ec, args, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,7 +897,7 @@ namespace Mono.CSharp
|
||||
args.Add (new Argument (exceptionVariable));
|
||||
|
||||
using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
|
||||
mg.EmitCall (ec, args);
|
||||
mg.EmitCall (ec, args, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -921,7 +921,7 @@ namespace Mono.CSharp
|
||||
}
|
||||
|
||||
using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
|
||||
mg.EmitCall (ec, args);
|
||||
mg.EmitCall (ec, args, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -861,9 +861,22 @@ namespace Mono.CSharp {
|
||||
((IntConstant) right).Value);
|
||||
|
||||
return new IntConstant (ec.BuiltinTypes, res, left.Location);
|
||||
} else {
|
||||
throw new Exception ( "Unexepected modulus input: " + left);
|
||||
}
|
||||
|
||||
if (left is DecimalConstant) {
|
||||
decimal res;
|
||||
|
||||
if (ec.ConstantCheckState)
|
||||
res = checked (((DecimalConstant) left).Value %
|
||||
((DecimalConstant) right).Value);
|
||||
else
|
||||
res = unchecked (((DecimalConstant) left).Value %
|
||||
((DecimalConstant) right).Value);
|
||||
|
||||
return new DecimalConstant (ec.BuiltinTypes, res, left.Location);
|
||||
}
|
||||
|
||||
throw new Exception ( "Unexepected modulus input: " + left);
|
||||
} catch (DivideByZeroException){
|
||||
ec.Report.Error (20, loc, "Division by constant zero");
|
||||
} catch (OverflowException){
|
||||
|
||||
@@ -1 +1 @@
|
||||
cda04c0e840c340724df311555d8b98032efd8bf
|
||||
b1db2644e3be19de5f04184f3f8ac5e55b99f6e9
|
||||
@@ -121,6 +121,8 @@ namespace Mono.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
public ConditionalAccessContext ConditionalAccess { get; set; }
|
||||
|
||||
public TypeSpec CurrentType {
|
||||
get { return member_context.CurrentType; }
|
||||
}
|
||||
@@ -350,6 +352,15 @@ namespace Mono.CSharp
|
||||
#endif
|
||||
}
|
||||
|
||||
public void CloseConditionalAccess (TypeSpec type)
|
||||
{
|
||||
if (type != null)
|
||||
Emit (OpCodes.Newobj, Nullable.NullableInfo.GetConstructor (type));
|
||||
|
||||
MarkLabel (ConditionalAccess.EndLabel);
|
||||
ConditionalAccess = null;
|
||||
}
|
||||
|
||||
//
|
||||
// Creates a nested container in this context for all dynamic compiler generated stuff
|
||||
//
|
||||
@@ -978,12 +989,25 @@ namespace Mono.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
public class ConditionalAccessContext
|
||||
{
|
||||
public ConditionalAccessContext (TypeSpec type, Label endLabel)
|
||||
{
|
||||
Type = type;
|
||||
EndLabel = endLabel;
|
||||
}
|
||||
|
||||
public bool Statement { get; set; }
|
||||
public Label EndLabel { get; private set; }
|
||||
public TypeSpec Type { get; private set; }
|
||||
}
|
||||
|
||||
struct CallEmitter
|
||||
{
|
||||
public Expression InstanceExpression;
|
||||
|
||||
//
|
||||
// When set leaves an extra copy of all arguments on the stack
|
||||
// When call has to leave an extra copy of all arguments on the stack
|
||||
//
|
||||
public bool DuplicateArguments;
|
||||
|
||||
@@ -998,6 +1022,8 @@ namespace Mono.CSharp
|
||||
//
|
||||
public bool HasAwaitArguments;
|
||||
|
||||
public bool ConditionalAccess;
|
||||
|
||||
//
|
||||
// When dealing with await arguments the original arguments are converted
|
||||
// into a new set with hoisted stack results
|
||||
@@ -1006,10 +1032,15 @@ namespace Mono.CSharp
|
||||
|
||||
public void Emit (EmitContext ec, MethodSpec method, Arguments Arguments, Location loc)
|
||||
{
|
||||
EmitPredefined (ec, method, Arguments, loc);
|
||||
EmitPredefined (ec, method, Arguments, false, loc);
|
||||
}
|
||||
|
||||
public void EmitPredefined (EmitContext ec, MethodSpec method, Arguments Arguments, Location? loc = null)
|
||||
public void EmitStatement (EmitContext ec, MethodSpec method, Arguments Arguments, Location loc)
|
||||
{
|
||||
EmitPredefined (ec, method, Arguments, true, loc);
|
||||
}
|
||||
|
||||
public void EmitPredefined (EmitContext ec, MethodSpec method, Arguments Arguments, bool statement = false, Location? loc = null)
|
||||
{
|
||||
Expression instance_copy = null;
|
||||
|
||||
@@ -1026,23 +1057,23 @@ namespace Mono.CSharp
|
||||
if (method.IsStatic) {
|
||||
call_op = OpCodes.Call;
|
||||
} else {
|
||||
if (IsVirtualCallRequired (InstanceExpression, method)) {
|
||||
call_op = OpCodes.Callvirt;
|
||||
} else {
|
||||
call_op = OpCodes.Call;
|
||||
}
|
||||
call_op = IsVirtualCallRequired (InstanceExpression, method) ? OpCodes.Callvirt : OpCodes.Call;
|
||||
|
||||
if (HasAwaitArguments) {
|
||||
instance_copy = InstanceExpression.EmitToField (ec);
|
||||
if (Arguments == null)
|
||||
EmitCallInstance (ec, instance_copy, method.DeclaringType, call_op);
|
||||
var ie = new InstanceEmitter (instance_copy, IsAddressCall (instance_copy, call_op, method.DeclaringType));
|
||||
|
||||
if (Arguments == null) {
|
||||
ie.EmitLoad (ec);
|
||||
}
|
||||
} else if (!InstanceExpressionOnStack) {
|
||||
var instance_on_stack_type = EmitCallInstance (ec, InstanceExpression, method.DeclaringType, call_op);
|
||||
var ie = new InstanceEmitter (InstanceExpression, IsAddressCall (InstanceExpression, call_op, method.DeclaringType));
|
||||
ie.Emit (ec, ConditionalAccess);
|
||||
|
||||
if (DuplicateArguments) {
|
||||
ec.Emit (OpCodes.Dup);
|
||||
if (Arguments != null && Arguments.Count != 0) {
|
||||
lt = new LocalTemporary (instance_on_stack_type);
|
||||
lt = new LocalTemporary (ie.GetStackType (ec));
|
||||
lt.Store (ec);
|
||||
instance_copy = lt;
|
||||
}
|
||||
@@ -1054,7 +1085,8 @@ namespace Mono.CSharp
|
||||
EmittedArguments = Arguments.Emit (ec, DuplicateArguments, HasAwaitArguments);
|
||||
if (EmittedArguments != null) {
|
||||
if (instance_copy != null) {
|
||||
EmitCallInstance (ec, instance_copy, method.DeclaringType, call_op);
|
||||
var ie = new InstanceEmitter (instance_copy, IsAddressCall (instance_copy, call_op, method.DeclaringType));
|
||||
ie.Emit (ec, ConditionalAccess);
|
||||
|
||||
if (lt != null)
|
||||
lt.Release (ec);
|
||||
@@ -1085,55 +1117,21 @@ namespace Mono.CSharp
|
||||
if (method.Parameters.HasArglist) {
|
||||
var varargs_types = GetVarargsTypes (method, Arguments);
|
||||
ec.Emit (call_op, method, varargs_types);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// If you have:
|
||||
// this.DoFoo ();
|
||||
// and DoFoo is not virtual, you can omit the callvirt,
|
||||
// because you don't need the null checking behavior.
|
||||
//
|
||||
ec.Emit (call_op, method);
|
||||
}
|
||||
|
||||
static TypeSpec EmitCallInstance (EmitContext ec, Expression instance, TypeSpec declaringType, OpCode callOpcode)
|
||||
{
|
||||
var instance_type = instance.Type;
|
||||
|
||||
//
|
||||
// Push the instance expression
|
||||
//
|
||||
if ((instance_type.IsStructOrEnum && (callOpcode == OpCodes.Callvirt || (callOpcode == OpCodes.Call && declaringType.IsStruct))) ||
|
||||
instance_type.IsGenericParameter || declaringType.IsNullableType) {
|
||||
} else {
|
||||
//
|
||||
// If the expression implements IMemoryLocation, then
|
||||
// we can optimize and use AddressOf on the
|
||||
// return.
|
||||
// If you have:
|
||||
// this.DoFoo ();
|
||||
// and DoFoo is not virtual, you can omit the callvirt,
|
||||
// because you don't need the null checking behavior.
|
||||
//
|
||||
// If not we have to use some temporary storage for
|
||||
// it.
|
||||
var iml = instance as IMemoryLocation;
|
||||
if (iml != null) {
|
||||
iml.AddressOf (ec, AddressOp.Load);
|
||||
} else {
|
||||
LocalTemporary temp = new LocalTemporary (instance_type);
|
||||
instance.Emit (ec);
|
||||
temp.Store (ec);
|
||||
temp.AddressOf (ec, AddressOp.Load);
|
||||
}
|
||||
|
||||
return ReferenceContainer.MakeType (ec.Module, instance_type);
|
||||
ec.Emit (call_op, method);
|
||||
}
|
||||
|
||||
if (instance_type.IsStructOrEnum) {
|
||||
instance.Emit (ec);
|
||||
ec.Emit (OpCodes.Box, instance_type);
|
||||
return ec.BuiltinTypes.Object;
|
||||
}
|
||||
|
||||
instance.Emit (ec);
|
||||
return instance_type;
|
||||
//
|
||||
// Pop the return value if there is one and stack should be empty
|
||||
//
|
||||
if (statement && method.ReturnType.Kind != MemberKind.Void)
|
||||
ec.Emit (OpCodes.Pop);
|
||||
}
|
||||
|
||||
static MetaType[] GetVarargsTypes (MethodSpec method, Arguments arguments)
|
||||
@@ -1169,11 +1167,199 @@ namespace Mono.CSharp
|
||||
// It's non-virtual and will never be null and it can be determined
|
||||
// whether it's known value or reference type by verifier
|
||||
//
|
||||
if (!method.IsVirtual && (instance is This || instance is New || instance is ArrayCreation || instance is DelegateCreation) &&
|
||||
!instance.Type.IsGenericParameter)
|
||||
if (!method.IsVirtual && Expression.IsNeverNull (instance) && !instance.Type.IsGenericParameter)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsAddressCall (Expression instance, OpCode callOpcode, TypeSpec declaringType)
|
||||
{
|
||||
var instance_type = instance.Type;
|
||||
return (instance_type.IsStructOrEnum && (callOpcode == OpCodes.Callvirt || (callOpcode == OpCodes.Call && declaringType.IsStruct))) ||
|
||||
instance_type.IsGenericParameter || declaringType.IsNullableType;
|
||||
}
|
||||
}
|
||||
|
||||
public struct InstanceEmitter
|
||||
{
|
||||
readonly Expression instance;
|
||||
readonly bool addressRequired;
|
||||
|
||||
public InstanceEmitter (Expression instance, bool addressLoad)
|
||||
{
|
||||
this.instance = instance;
|
||||
this.addressRequired = addressLoad;
|
||||
}
|
||||
|
||||
public void Emit (EmitContext ec, bool conditionalAccess)
|
||||
{
|
||||
Label NullOperatorLabel;
|
||||
Nullable.Unwrap unwrap;
|
||||
|
||||
if (conditionalAccess && Expression.IsNeverNull (instance))
|
||||
conditionalAccess = false;
|
||||
|
||||
if (conditionalAccess) {
|
||||
NullOperatorLabel = ec.DefineLabel ();
|
||||
unwrap = instance as Nullable.Unwrap;
|
||||
} else {
|
||||
NullOperatorLabel = new Label ();
|
||||
unwrap = null;
|
||||
}
|
||||
|
||||
IMemoryLocation instance_address = null;
|
||||
bool conditional_access_dup = false;
|
||||
|
||||
if (unwrap != null) {
|
||||
unwrap.Store (ec);
|
||||
unwrap.EmitCheck (ec);
|
||||
ec.Emit (OpCodes.Brtrue_S, NullOperatorLabel);
|
||||
} else {
|
||||
if (conditionalAccess && addressRequired) {
|
||||
//
|
||||
// Don't allocate temp variable when instance load is cheap and load and load-address
|
||||
// operate on same memory
|
||||
//
|
||||
instance_address = instance as VariableReference;
|
||||
if (instance_address == null)
|
||||
instance_address = instance as LocalTemporary;
|
||||
|
||||
if (instance_address == null) {
|
||||
EmitLoad (ec);
|
||||
ec.Emit (OpCodes.Dup);
|
||||
ec.EmitLoadFromPtr (instance.Type);
|
||||
|
||||
conditional_access_dup = true;
|
||||
} else {
|
||||
instance.Emit (ec);
|
||||
}
|
||||
|
||||
if (instance.Type.Kind == MemberKind.TypeParameter)
|
||||
ec.Emit (OpCodes.Box, instance.Type);
|
||||
} else {
|
||||
EmitLoad (ec);
|
||||
|
||||
if (conditionalAccess) {
|
||||
conditional_access_dup = !IsInexpensiveLoad ();
|
||||
if (conditional_access_dup)
|
||||
ec.Emit (OpCodes.Dup);
|
||||
}
|
||||
}
|
||||
|
||||
if (conditionalAccess) {
|
||||
ec.Emit (OpCodes.Brtrue_S, NullOperatorLabel);
|
||||
|
||||
if (conditional_access_dup)
|
||||
ec.Emit (OpCodes.Pop);
|
||||
}
|
||||
}
|
||||
|
||||
if (conditionalAccess) {
|
||||
if (!ec.ConditionalAccess.Statement) {
|
||||
if (ec.ConditionalAccess.Type.IsNullableType)
|
||||
Nullable.LiftedNull.Create (ec.ConditionalAccess.Type, Location.Null).Emit (ec);
|
||||
else
|
||||
ec.EmitNull ();
|
||||
}
|
||||
|
||||
ec.Emit (OpCodes.Br, ec.ConditionalAccess.EndLabel);
|
||||
ec.MarkLabel (NullOperatorLabel);
|
||||
|
||||
if (instance_address != null) {
|
||||
instance_address.AddressOf (ec, AddressOp.Load);
|
||||
} else if (unwrap != null) {
|
||||
unwrap.Emit (ec);
|
||||
var tmp = ec.GetTemporaryLocal (unwrap.Type);
|
||||
ec.Emit (OpCodes.Stloc, tmp);
|
||||
ec.Emit (OpCodes.Ldloca, tmp);
|
||||
ec.FreeTemporaryLocal (tmp, unwrap.Type);
|
||||
} else if (!conditional_access_dup) {
|
||||
instance.Emit (ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void EmitLoad (EmitContext ec)
|
||||
{
|
||||
var instance_type = instance.Type;
|
||||
|
||||
//
|
||||
// Push the instance expression
|
||||
//
|
||||
if (addressRequired) {
|
||||
//
|
||||
// If the expression implements IMemoryLocation, then
|
||||
// we can optimize and use AddressOf on the
|
||||
// return.
|
||||
//
|
||||
// If not we have to use some temporary storage for
|
||||
// it.
|
||||
var iml = instance as IMemoryLocation;
|
||||
if (iml != null) {
|
||||
iml.AddressOf (ec, AddressOp.Load);
|
||||
} else {
|
||||
LocalTemporary temp = new LocalTemporary (instance_type);
|
||||
instance.Emit (ec);
|
||||
temp.Store (ec);
|
||||
temp.AddressOf (ec, AddressOp.Load);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
instance.Emit (ec);
|
||||
|
||||
// Only to make verifier happy
|
||||
if (RequiresBoxing ())
|
||||
ec.Emit (OpCodes.Box, instance_type);
|
||||
}
|
||||
|
||||
public TypeSpec GetStackType (EmitContext ec)
|
||||
{
|
||||
var instance_type = instance.Type;
|
||||
|
||||
if (addressRequired)
|
||||
return ReferenceContainer.MakeType (ec.Module, instance_type);
|
||||
|
||||
if (instance_type.IsStructOrEnum)
|
||||
return ec.Module.Compiler.BuiltinTypes.Object;
|
||||
|
||||
return instance_type;
|
||||
}
|
||||
|
||||
bool RequiresBoxing ()
|
||||
{
|
||||
var instance_type = instance.Type;
|
||||
if (instance_type.IsGenericParameter && !(instance is This) && TypeSpec.IsReferenceType (instance_type))
|
||||
return true;
|
||||
|
||||
if (instance_type.IsStructOrEnum)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsInexpensiveLoad ()
|
||||
{
|
||||
if (instance is Constant)
|
||||
return instance.IsSideEffectFree;
|
||||
|
||||
if (RequiresBoxing ())
|
||||
return false;
|
||||
|
||||
var vr = instance as VariableReference;
|
||||
if (vr != null)
|
||||
return !vr.IsRef;
|
||||
|
||||
if (instance is LocalTemporary)
|
||||
return true;
|
||||
|
||||
var fe = instance as FieldExpr;
|
||||
if (fe != null)
|
||||
return fe.IsStatic || fe.InstanceExpression is This;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2031,8 +2031,6 @@ namespace Mono.CSharp {
|
||||
}
|
||||
|
||||
public class StringConstant : Constant {
|
||||
public readonly string Value;
|
||||
|
||||
public StringConstant (BuiltinTypes types, string s, Location loc)
|
||||
: this (types.String, s, loc)
|
||||
{
|
||||
@@ -2047,6 +2045,13 @@ namespace Mono.CSharp {
|
||||
Value = s;
|
||||
}
|
||||
|
||||
protected StringConstant (Location loc)
|
||||
: base (loc)
|
||||
{
|
||||
}
|
||||
|
||||
public string Value { get; protected set; }
|
||||
|
||||
public override object GetValue ()
|
||||
{
|
||||
return Value;
|
||||
@@ -2129,6 +2134,113 @@ namespace Mono.CSharp {
|
||||
}
|
||||
}
|
||||
|
||||
class NameOf : StringConstant
|
||||
{
|
||||
readonly SimpleName name;
|
||||
|
||||
public NameOf (SimpleName name)
|
||||
: base (name.Location)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
protected override Expression DoResolve (ResolveContext rc)
|
||||
{
|
||||
throw new NotSupportedException ();
|
||||
}
|
||||
|
||||
bool ResolveArgumentExpression (ResolveContext rc, Expression expr)
|
||||
{
|
||||
var sn = expr as SimpleName;
|
||||
if (sn != null) {
|
||||
Value = sn.Name;
|
||||
|
||||
if (rc.Module.Compiler.Settings.Version < LanguageVersion.V_6)
|
||||
rc.Report.FeatureIsNotAvailable (rc.Module.Compiler, Location, "nameof operator");
|
||||
|
||||
if (sn.HasTypeArguments) {
|
||||
// TODO: csc compatible but unhelpful error message
|
||||
rc.Report.Error (1001, loc, "Identifier expected");
|
||||
return true;
|
||||
}
|
||||
|
||||
sn.LookupNameExpression (rc, MemberLookupRestrictions.IgnoreArity | MemberLookupRestrictions.IgnoreAmbiguity);
|
||||
return true;
|
||||
}
|
||||
|
||||
var ma = expr as MemberAccess;
|
||||
if (ma != null) {
|
||||
FullNamedExpression fne = ma.LeftExpression as ATypeNameExpression;
|
||||
if (fne == null) {
|
||||
var qam = ma as QualifiedAliasMember;
|
||||
if (qam == null)
|
||||
return false;
|
||||
|
||||
fne = qam.CreateExpressionFromAlias (rc);
|
||||
if (fne == null)
|
||||
return true;
|
||||
}
|
||||
|
||||
Value = ma.Name;
|
||||
|
||||
if (rc.Module.Compiler.Settings.Version < LanguageVersion.V_6)
|
||||
rc.Report.FeatureIsNotAvailable (rc.Module.Compiler, Location, "nameof operator");
|
||||
|
||||
if (ma.HasTypeArguments) {
|
||||
// TODO: csc compatible but unhelpful error message
|
||||
rc.Report.Error (1001, loc, "Identifier expected");
|
||||
return true;
|
||||
}
|
||||
|
||||
var left = fne.ResolveAsTypeOrNamespace (rc, true);
|
||||
if (left == null)
|
||||
return true;
|
||||
|
||||
var ns = left as NamespaceExpression;
|
||||
if (ns != null) {
|
||||
FullNamedExpression retval = ns.LookupTypeOrNamespace (rc, ma.Name, 0, LookupMode.NameOf, loc);
|
||||
if (retval == null)
|
||||
ns.Error_NamespaceDoesNotExist (rc, ma.Name, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (left.Type.IsGenericOrParentIsGeneric && left.Type.GetDefinition () != left.Type) {
|
||||
rc.Report.Error (8071, loc, "Type arguments are not allowed in the nameof operator");
|
||||
}
|
||||
|
||||
var mexpr = MemberLookup (rc, false, left.Type, ma.Name, 0, MemberLookupRestrictions.IgnoreArity | MemberLookupRestrictions.IgnoreAmbiguity, loc);
|
||||
if (mexpr == null) {
|
||||
ma.Error_IdentifierNotFound (rc, left.Type);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Expression ResolveOverload (ResolveContext rc, Arguments args)
|
||||
{
|
||||
if (args == null || args.Count != 1) {
|
||||
name.Error_NameDoesNotExist (rc);
|
||||
return null;
|
||||
}
|
||||
|
||||
var arg = args [0];
|
||||
var res = ResolveArgumentExpression (rc, arg.Expr);
|
||||
if (!res) {
|
||||
name.Error_NameDoesNotExist (rc);
|
||||
return null;
|
||||
}
|
||||
|
||||
type = rc.BuiltinTypes.String;
|
||||
eclass = ExprClass.Value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Null constant can have its own type, think of `default (Foo)'
|
||||
//
|
||||
|
||||
@@ -14,6 +14,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Mono.CSharp
|
||||
{
|
||||
@@ -21,7 +22,8 @@ namespace Mono.CSharp
|
||||
{
|
||||
Normal = 0,
|
||||
Probing = 1,
|
||||
IgnoreAccessibility = 2
|
||||
IgnoreAccessibility = 2,
|
||||
NameOf = 3
|
||||
}
|
||||
|
||||
//
|
||||
@@ -188,6 +190,8 @@ namespace Mono.CSharp
|
||||
|
||||
TryWithCatchScope = 1 << 15,
|
||||
|
||||
ConditionalAccessReceiver = 1 << 16,
|
||||
|
||||
///
|
||||
/// Indicates the current context is in probing mode, no errors are reported.
|
||||
///
|
||||
@@ -442,6 +446,7 @@ namespace Mono.CSharp
|
||||
public class FlowAnalysisContext
|
||||
{
|
||||
readonly CompilerContext ctx;
|
||||
DefiniteAssignmentBitSet conditional_access;
|
||||
|
||||
public FlowAnalysisContext (CompilerContext ctx, ParametersBlock parametersBlock, int definiteAssignmentLength)
|
||||
{
|
||||
@@ -483,6 +488,19 @@ namespace Mono.CSharp
|
||||
return dat;
|
||||
}
|
||||
|
||||
public void BranchConditionalAccessDefiniteAssignment ()
|
||||
{
|
||||
if (conditional_access == null)
|
||||
conditional_access = BranchDefiniteAssignment ();
|
||||
}
|
||||
|
||||
public void ConditionalAccessEnd ()
|
||||
{
|
||||
Debug.Assert (conditional_access != null);
|
||||
DefiniteAssignment = conditional_access;
|
||||
conditional_access = null;
|
||||
}
|
||||
|
||||
public bool IsDefinitelyAssigned (VariableInfo variable)
|
||||
{
|
||||
return variable.IsAssigned (DefiniteAssignment);
|
||||
|
||||
@@ -345,7 +345,7 @@ namespace Mono.CSharp {
|
||||
if (target_type.Kind == MemberKind.InternalCompilerType)
|
||||
return target_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic;
|
||||
|
||||
return TypeSpec.IsReferenceType (target_type);
|
||||
return TypeSpec.IsReferenceType (target_type) || target_type.Kind == MemberKind.PointerType;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -1 +1 @@
|
||||
2cfa7f1846374357ed745eab43bf41e85fa4e9d3
|
||||
726b1f6dcdd3a442f01b3273228c570a4dc5f031
|
||||
@@ -202,7 +202,6 @@ namespace Mono.CSharp
|
||||
bool handle_get_set = false;
|
||||
bool handle_remove_add = false;
|
||||
bool handle_where;
|
||||
bool handle_typeof = false;
|
||||
bool lambda_arguments_parsing;
|
||||
List<Location> escaped_identifiers;
|
||||
int parsing_generic_less_than;
|
||||
@@ -320,11 +319,6 @@ namespace Mono.CSharp
|
||||
get { return handle_where; }
|
||||
set { handle_where = value; }
|
||||
}
|
||||
|
||||
public bool TypeOfParsing {
|
||||
get { return handle_typeof; }
|
||||
set { handle_typeof = value; }
|
||||
}
|
||||
|
||||
public XmlCommentState doc_state {
|
||||
get { return xml_doc_state; }
|
||||
@@ -729,6 +723,7 @@ namespace Mono.CSharp
|
||||
case Token.BYTE:
|
||||
case Token.CHAR:
|
||||
case Token.DECIMAL:
|
||||
case Token.DOUBLE:
|
||||
case Token.FLOAT:
|
||||
case Token.LONG:
|
||||
case Token.OBJECT:
|
||||
@@ -1144,7 +1139,7 @@ namespace Mono.CSharp
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_less_than ()
|
||||
bool parse_less_than (ref int genericDimension)
|
||||
{
|
||||
start:
|
||||
int the_token = token ();
|
||||
@@ -1181,10 +1176,23 @@ namespace Mono.CSharp
|
||||
case Token.VOID:
|
||||
break;
|
||||
case Token.OP_GENERICS_GT:
|
||||
genericDimension = 1;
|
||||
return true;
|
||||
case Token.IN:
|
||||
case Token.OUT:
|
||||
return true;
|
||||
case Token.COMMA:
|
||||
do {
|
||||
++genericDimension;
|
||||
the_token = token ();
|
||||
} while (the_token == Token.COMMA);
|
||||
|
||||
if (the_token == Token.OP_GENERICS_GT) {
|
||||
++genericDimension;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -1198,7 +1206,7 @@ namespace Mono.CSharp
|
||||
else if (the_token == Token.INTERR_NULLABLE || the_token == Token.STAR)
|
||||
goto again;
|
||||
else if (the_token == Token.OP_GENERICS_LT) {
|
||||
if (!parse_less_than ())
|
||||
if (!parse_less_than (ref genericDimension))
|
||||
return false;
|
||||
goto again;
|
||||
} else if (the_token == Token.OPEN_BRACKET) {
|
||||
@@ -1214,22 +1222,6 @@ namespace Mono.CSharp
|
||||
return false;
|
||||
}
|
||||
|
||||
bool parse_generic_dimension (out int dimension)
|
||||
{
|
||||
dimension = 1;
|
||||
|
||||
again:
|
||||
int the_token = token ();
|
||||
if (the_token == Token.OP_GENERICS_GT)
|
||||
return true;
|
||||
else if (the_token == Token.COMMA) {
|
||||
dimension++;
|
||||
goto again;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int peek_token ()
|
||||
{
|
||||
int the_token;
|
||||
@@ -1260,13 +1252,8 @@ namespace Mono.CSharp
|
||||
return Token.OP_COALESCING;
|
||||
}
|
||||
|
||||
switch (current_token) {
|
||||
case Token.CLOSE_PARENS:
|
||||
case Token.TRUE:
|
||||
case Token.FALSE:
|
||||
case Token.NULL:
|
||||
case Token.LITERAL:
|
||||
return Token.INTERR;
|
||||
if (d == '.') {
|
||||
return Token.INTERR_OPERATOR;
|
||||
}
|
||||
|
||||
if (d != ' ') {
|
||||
@@ -1280,8 +1267,14 @@ namespace Mono.CSharp
|
||||
current_token = Token.NONE;
|
||||
int next_token;
|
||||
int parens = 0;
|
||||
int generics = 0;
|
||||
|
||||
switch (xtoken ()) {
|
||||
var nt = xtoken ();
|
||||
switch (nt) {
|
||||
case Token.DOT:
|
||||
case Token.OPEN_BRACKET_EXPR:
|
||||
next_token = Token.INTERR_OPERATOR;
|
||||
break;
|
||||
case Token.LITERAL:
|
||||
case Token.TRUE:
|
||||
case Token.FALSE:
|
||||
@@ -1308,7 +1301,14 @@ namespace Mono.CSharp
|
||||
next_token = -1;
|
||||
++parens;
|
||||
break;
|
||||
|
||||
|
||||
case Token.OP_GENERICS_LT:
|
||||
case Token.OP_GENERICS_LT_DECL:
|
||||
case Token.GENERIC_DIMENSION:
|
||||
next_token = -1;
|
||||
++generics;
|
||||
break;
|
||||
|
||||
default:
|
||||
next_token = -1;
|
||||
break;
|
||||
@@ -1334,11 +1334,18 @@ namespace Mono.CSharp
|
||||
++parens;
|
||||
goto default;
|
||||
|
||||
case Token.OP_GENERICS_LT:
|
||||
case Token.OP_GENERICS_LT_DECL:
|
||||
case Token.GENERIC_DIMENSION:
|
||||
++generics;
|
||||
goto default;
|
||||
|
||||
default:
|
||||
int ntoken;
|
||||
int interrs = 1;
|
||||
int colons = 0;
|
||||
int braces = 0;
|
||||
int brackets = 0;
|
||||
//
|
||||
// All shorcuts failed, do it hard way
|
||||
//
|
||||
@@ -1355,12 +1362,33 @@ namespace Mono.CSharp
|
||||
case Token.CLOSE_BRACE:
|
||||
--braces;
|
||||
continue;
|
||||
case Token.OP_GENERICS_LT:
|
||||
case Token.OP_GENERICS_LT_DECL:
|
||||
case Token.GENERIC_DIMENSION:
|
||||
++generics;
|
||||
continue;
|
||||
case Token.OPEN_BRACKET:
|
||||
case Token.OPEN_BRACKET_EXPR:
|
||||
++brackets;
|
||||
continue;
|
||||
case Token.CLOSE_BRACKET:
|
||||
--brackets;
|
||||
continue;
|
||||
case Token.CLOSE_PARENS:
|
||||
if (parens > 0) {
|
||||
--parens;
|
||||
continue;
|
||||
}
|
||||
|
||||
PopPosition ();
|
||||
return Token.INTERR_NULLABLE;
|
||||
|
||||
case Token.OP_GENERICS_GT:
|
||||
if (generics > 0) {
|
||||
--generics;
|
||||
continue;
|
||||
}
|
||||
|
||||
PopPosition ();
|
||||
return Token.INTERR_NULLABLE;
|
||||
}
|
||||
@@ -1373,6 +1401,14 @@ namespace Mono.CSharp
|
||||
|
||||
if (parens != 0)
|
||||
continue;
|
||||
|
||||
if (ntoken == Token.COMMA) {
|
||||
if (generics != 0 || brackets != 0)
|
||||
continue;
|
||||
|
||||
PopPosition ();
|
||||
return Token.INTERR_NULLABLE;
|
||||
}
|
||||
|
||||
if (ntoken == Token.COLON) {
|
||||
if (++colons == interrs)
|
||||
@@ -3669,22 +3705,20 @@ namespace Mono.CSharp
|
||||
int TokenizeLessThan ()
|
||||
{
|
||||
int d;
|
||||
if (handle_typeof) {
|
||||
PushPosition ();
|
||||
if (parse_generic_dimension (out d)) {
|
||||
val = d;
|
||||
DiscardPosition ();
|
||||
return Token.GENERIC_DIMENSION;
|
||||
}
|
||||
PopPosition ();
|
||||
}
|
||||
|
||||
// Save current position and parse next token.
|
||||
PushPosition ();
|
||||
if (parse_less_than ()) {
|
||||
int generic_dimension = 0;
|
||||
if (parse_less_than (ref generic_dimension)) {
|
||||
if (parsing_generic_declaration && (parsing_generic_declaration_doc || token () != Token.DOT)) {
|
||||
d = Token.OP_GENERICS_LT_DECL;
|
||||
} else {
|
||||
if (generic_dimension > 0) {
|
||||
val = generic_dimension;
|
||||
DiscardPosition ();
|
||||
return Token.GENERIC_DIMENSION;
|
||||
}
|
||||
|
||||
d = Token.OP_GENERICS_LT;
|
||||
}
|
||||
PopPosition ();
|
||||
|
||||
@@ -195,11 +195,6 @@ namespace Mono.CSharp {
|
||||
|
||||
return name + "`" + args.Count;
|
||||
}
|
||||
|
||||
public static string MakeName (string name, int count)
|
||||
{
|
||||
return name + "`" + count;
|
||||
}
|
||||
}
|
||||
|
||||
public class SimpleMemberName
|
||||
|
||||
@@ -439,6 +439,7 @@ namespace Mono.CSharp {
|
||||
//
|
||||
public abstract class DelegateCreation : Expression, OverloadResolver.IErrorHandler
|
||||
{
|
||||
bool conditional_access_receiver;
|
||||
protected MethodSpec constructor_method;
|
||||
protected MethodGroupExpr method_group;
|
||||
|
||||
@@ -507,8 +508,19 @@ namespace Mono.CSharp {
|
||||
|
||||
var invoke_method = Delegate.GetInvokeMethod (type);
|
||||
|
||||
if (!ec.HasSet (ResolveContext.Options.ConditionalAccessReceiver)) {
|
||||
if (method_group.HasConditionalAccess ()) {
|
||||
conditional_access_receiver = true;
|
||||
ec.Set (ResolveContext.Options.ConditionalAccessReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
Arguments arguments = CreateDelegateMethodArguments (ec, invoke_method.Parameters, invoke_method.Parameters.Types, loc);
|
||||
method_group = method_group.OverloadResolve (ec, ref arguments, this, OverloadResolver.Restrictions.CovariantDelegate);
|
||||
|
||||
if (conditional_access_receiver)
|
||||
ec.With (ResolveContext.Options.ConditionalAccessReceiver, false);
|
||||
|
||||
if (method_group == null)
|
||||
return null;
|
||||
|
||||
@@ -564,10 +576,15 @@ namespace Mono.CSharp {
|
||||
|
||||
public override void Emit (EmitContext ec)
|
||||
{
|
||||
if (method_group.InstanceExpression == null)
|
||||
if (conditional_access_receiver)
|
||||
ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ());
|
||||
|
||||
if (method_group.InstanceExpression == null) {
|
||||
ec.EmitNull ();
|
||||
else
|
||||
method_group.InstanceExpression.Emit (ec);
|
||||
} else {
|
||||
var ie = new InstanceEmitter (method_group.InstanceExpression, false);
|
||||
ie.Emit (ec, method_group.ConditionalAccess);
|
||||
}
|
||||
|
||||
var delegate_method = method_group.BestCandidate;
|
||||
|
||||
@@ -580,11 +597,18 @@ namespace Mono.CSharp {
|
||||
}
|
||||
|
||||
ec.Emit (OpCodes.Newobj, constructor_method);
|
||||
|
||||
if (conditional_access_receiver)
|
||||
ec.CloseConditionalAccess (null);
|
||||
}
|
||||
|
||||
public override void FlowAnalysis (FlowAnalysisContext fc) {
|
||||
public override void FlowAnalysis (FlowAnalysisContext fc)
|
||||
{
|
||||
base.FlowAnalysis (fc);
|
||||
method_group.FlowAnalysis (fc);
|
||||
|
||||
if (conditional_access_receiver)
|
||||
fc.ConditionalAccessEnd ();
|
||||
}
|
||||
|
||||
void Error_ConversionFailed (ResolveContext ec, MethodSpec method, Expression return_type)
|
||||
@@ -830,13 +854,15 @@ namespace Mono.CSharp {
|
||||
class DelegateInvocation : ExpressionStatement
|
||||
{
|
||||
readonly Expression InstanceExpr;
|
||||
readonly bool conditionalAccessReceiver;
|
||||
Arguments arguments;
|
||||
MethodSpec method;
|
||||
|
||||
public DelegateInvocation (Expression instance_expr, Arguments args, Location loc)
|
||||
public DelegateInvocation (Expression instance_expr, Arguments args, bool conditionalAccessReceiver, Location loc)
|
||||
{
|
||||
this.InstanceExpr = instance_expr;
|
||||
this.arguments = args;
|
||||
this.conditionalAccessReceiver = conditionalAccessReceiver;
|
||||
this.loc = loc;
|
||||
}
|
||||
|
||||
@@ -877,29 +903,45 @@ namespace Mono.CSharp {
|
||||
return null;
|
||||
|
||||
type = method.ReturnType;
|
||||
if (conditionalAccessReceiver)
|
||||
type = LiftMemberType (ec, type);
|
||||
|
||||
eclass = ExprClass.Value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public override void Emit (EmitContext ec)
|
||||
{
|
||||
if (conditionalAccessReceiver) {
|
||||
ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ());
|
||||
}
|
||||
|
||||
//
|
||||
// Invocation on delegates call the virtual Invoke member
|
||||
// so we are always `instance' calls
|
||||
//
|
||||
var call = new CallEmitter ();
|
||||
call.InstanceExpression = InstanceExpr;
|
||||
call.EmitPredefined (ec, method, arguments, loc);
|
||||
call.Emit (ec, method, arguments, loc);
|
||||
|
||||
if (conditionalAccessReceiver)
|
||||
ec.CloseConditionalAccess (type.IsNullableType && type != method.ReturnType ? type : null);
|
||||
}
|
||||
|
||||
public override void EmitStatement (EmitContext ec)
|
||||
{
|
||||
Emit (ec);
|
||||
//
|
||||
// Pop the return value if there is one
|
||||
//
|
||||
if (type.Kind != MemberKind.Void)
|
||||
ec.Emit (OpCodes.Pop);
|
||||
if (conditionalAccessReceiver) {
|
||||
ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ()) {
|
||||
Statement = true
|
||||
};
|
||||
}
|
||||
|
||||
var call = new CallEmitter ();
|
||||
call.InstanceExpression = InstanceExpr;
|
||||
call.EmitStatement (ec, method, arguments, loc);
|
||||
|
||||
if (conditionalAccessReceiver)
|
||||
ec.CloseConditionalAccess (null);
|
||||
}
|
||||
|
||||
public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Mono.CSharp
|
||||
this.loc = loc;
|
||||
}
|
||||
|
||||
public override TypeSpec ResolveAsType (IMemberContext ec)
|
||||
public override TypeSpec ResolveAsType (IMemberContext ec, bool allowUnboundTypeArguments)
|
||||
{
|
||||
eclass = ExprClass.Type;
|
||||
type = ec.Module.Compiler.BuiltinTypes.Dynamic;
|
||||
@@ -534,7 +534,7 @@ namespace Mono.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
Expression target = new DelegateInvocation (new MemberAccess (site_field_expr, "Target", loc).Resolve (bc), args, loc).Resolve (bc);
|
||||
Expression target = new DelegateInvocation (new MemberAccess (site_field_expr, "Target", loc).Resolve (bc), args, false, loc).Resolve (bc);
|
||||
if (target != null)
|
||||
target.Emit (ec);
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
f0a9de98b6103af652e3d63bcae44183a33246f7
|
||||
5729e21b3e7e9275a1fe18a577598f104e3fe16e
|
||||
@@ -28,7 +28,7 @@ namespace Mono.CSharp {
|
||||
{
|
||||
class EnumTypeExpr : TypeExpr
|
||||
{
|
||||
public override TypeSpec ResolveAsType (IMemberContext ec)
|
||||
public override TypeSpec ResolveAsType (IMemberContext ec, bool allowUnboundTypeArguments)
|
||||
{
|
||||
type = ec.CurrentType;
|
||||
eclass = ExprClass.Type;
|
||||
@@ -64,11 +64,12 @@ namespace Mono.CSharp {
|
||||
if (expr is EnumConstant)
|
||||
expr = ((EnumConstant) expr).Child;
|
||||
|
||||
var underlying = ((Enum) Parent).UnderlyingType;
|
||||
var en = (Enum)Parent;
|
||||
var underlying = en.UnderlyingType;
|
||||
if (expr != null) {
|
||||
expr = expr.ImplicitConversionRequired (rc, underlying);
|
||||
if (expr != null && !IsValidEnumType (expr.Type)) {
|
||||
Enum.Error_1008 (Location, Report);
|
||||
en.Error_UnderlyingType (Location);
|
||||
expr = null;
|
||||
}
|
||||
}
|
||||
@@ -217,7 +218,7 @@ namespace Mono.CSharp {
|
||||
AddMember (em);
|
||||
}
|
||||
|
||||
public static void Error_1008 (Location loc, Report Report)
|
||||
public void Error_UnderlyingType (Location loc)
|
||||
{
|
||||
Report.Error (1008, loc,
|
||||
"Type byte, sbyte, short, ushort, int, uint, long or ulong expected");
|
||||
@@ -225,7 +226,21 @@ namespace Mono.CSharp {
|
||||
|
||||
protected override void DoDefineContainer ()
|
||||
{
|
||||
((EnumSpec) spec).UnderlyingType = underlying_type_expr == null ? Compiler.BuiltinTypes.Int : underlying_type_expr.Type;
|
||||
TypeSpec ut;
|
||||
if (underlying_type_expr != null) {
|
||||
ut = underlying_type_expr.ResolveAsType (this);
|
||||
if (!EnumSpec.IsValidUnderlyingType (ut)) {
|
||||
Error_UnderlyingType (underlying_type_expr.Location);
|
||||
ut = null;
|
||||
}
|
||||
} else {
|
||||
ut = null;
|
||||
}
|
||||
|
||||
if (ut == null)
|
||||
ut = Compiler.BuiltinTypes.Int;
|
||||
|
||||
((EnumSpec) spec).UnderlyingType = ut;
|
||||
|
||||
TypeBuilder.DefineField (UnderlyingValueField, UnderlyingType.GetMetaInfo (),
|
||||
FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
|
||||
|
||||
@@ -1277,7 +1277,7 @@ namespace Mono.CSharp
|
||||
|
||||
if (current_container.Containers != null)
|
||||
{
|
||||
var existing = current_container.Containers.FirstOrDefault (l => l.Basename == tc.Basename);
|
||||
var existing = current_container.Containers.FirstOrDefault (l => l.MemberName.Basename == tc.MemberName.Basename);
|
||||
if (existing != null) {
|
||||
current_container.RemoveContainer (existing);
|
||||
undo_actions.Add (() => current_container.AddTypeContainer (existing));
|
||||
|
||||
@@ -1 +1 @@
|
||||
0ab48acb382e4c47a8494814726d8a2c6ce99dff
|
||||
4fa922c0110f8f4278cecea17e40d6b036d503ac
|
||||
@@ -709,7 +709,7 @@ namespace Mono.CSharp
|
||||
loc = parameter.Location;
|
||||
}
|
||||
|
||||
public override TypeSpec ResolveAsType (IMemberContext mc)
|
||||
public override TypeSpec ResolveAsType (IMemberContext mc, bool allowUnboundTypeArguments)
|
||||
{
|
||||
return parameter.Type;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace Mono.CSharp {
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec)
|
||||
public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc, bool allowUnboundTypeArguments)
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
@@ -1147,7 +1147,7 @@ namespace Mono.CSharp {
|
||||
|
||||
if (other.targs != null) {
|
||||
foreach (var otarg in other.targs) {
|
||||
if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
|
||||
if (TypeSpecComparer.Override.IsEqual (iface, otarg)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -2426,7 +2426,7 @@ namespace Mono.CSharp {
|
||||
return type.GetSignatureForError ();
|
||||
}
|
||||
|
||||
public override TypeSpec ResolveAsType (IMemberContext mc)
|
||||
public override TypeSpec ResolveAsType (IMemberContext mc, bool allowUnboundTypeArguments = false)
|
||||
{
|
||||
if (eclass != ExprClass.Unresolved)
|
||||
return type;
|
||||
|
||||
@@ -1287,6 +1287,23 @@ namespace Mono.CSharp
|
||||
public string DefaultIndexerName;
|
||||
public bool? CLSAttributeValue;
|
||||
public TypeSpec CoClass;
|
||||
|
||||
static bool HasMissingType (ConstructorInfo ctor)
|
||||
{
|
||||
#if STATIC
|
||||
//
|
||||
// Mimic odd csc behaviour where missing type on predefined
|
||||
// attributes means the attribute is silently ignored. This can
|
||||
// happen with PCL facades
|
||||
//
|
||||
foreach (var p in ctor.GetParameters ()) {
|
||||
if (p.ParameterType.__ContainsMissingType)
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static AttributesBag Read (MemberInfo mi, MetadataImporter importer)
|
||||
{
|
||||
@@ -1361,6 +1378,9 @@ namespace Mono.CSharp
|
||||
if (dt.Namespace != "System")
|
||||
continue;
|
||||
|
||||
if (HasMissingType (a.Constructor))
|
||||
continue;
|
||||
|
||||
if (bag == null)
|
||||
bag = new AttributesBag ();
|
||||
|
||||
@@ -1379,6 +1399,9 @@ namespace Mono.CSharp
|
||||
if (dt.Namespace != "System.Runtime.InteropServices")
|
||||
continue;
|
||||
|
||||
if (HasMissingType (a.Constructor))
|
||||
continue;
|
||||
|
||||
if (bag == null)
|
||||
bag = new AttributesBag ();
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user