You've already forked linux-packaging-mono
Imported Upstream version 5.8.0.22
Former-commit-id: df344e34b07851d296efb3e6604c8db42b6f7aa3
This commit is contained in:
parent
5f4a27cc8a
commit
7d05485754
@@ -839,6 +839,11 @@ namespace Mono.CSharp {
|
||||
{
|
||||
GetFieldExpression (ec).EmitAssign (ec, source, leave_copy, false);
|
||||
}
|
||||
|
||||
public void EmitAssignFromStack (EmitContext ec)
|
||||
{
|
||||
GetFieldExpression (ec).EmitAssignFromStack (ec);
|
||||
}
|
||||
}
|
||||
|
||||
public class HoistedParameter : HoistedVariable
|
||||
|
||||
@@ -473,6 +473,13 @@ namespace Mono.CSharp
|
||||
Emit (ec, false, false);
|
||||
}
|
||||
|
||||
public void EmitPrepare (EmitContext ec)
|
||||
{
|
||||
foreach (var a in args) {
|
||||
a.Expr.EmitPrepare (ec);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// if `dup_args' is true or any of arguments contains await.
|
||||
// A copy of all arguments will be returned to the caller
|
||||
|
||||
@@ -390,6 +390,7 @@ namespace Mono.CSharp {
|
||||
|
||||
return System.Linq.Expressions.Expression.Assign (target_object, source_object);
|
||||
}
|
||||
|
||||
protected virtual Expression ResolveConversions (ResolveContext ec)
|
||||
{
|
||||
source = Convert.ImplicitConversionRequired (ec, source, target.Type, source.Location);
|
||||
@@ -501,6 +502,12 @@ namespace Mono.CSharp {
|
||||
pe.SetBackingFieldAssigned (fc);
|
||||
return;
|
||||
}
|
||||
|
||||
var td = target as TupleDeconstruct;
|
||||
if (td != null) {
|
||||
td.SetGeneratedFieldAssigned (fc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override Reachability MarkReachable (Reachability rc)
|
||||
|
||||
@@ -258,6 +258,11 @@ namespace Mono.CSharp {
|
||||
Report.Error (1970, loc, "Do not use `{0}' directly. Use `dynamic' keyword instead", GetSignatureForError ());
|
||||
}
|
||||
|
||||
public void Error_MisusedTupleAttribute ()
|
||||
{
|
||||
Report.Error (8138, loc, "Do not use `{0}' directly. Use the tuple syntax instead", GetSignatureForError ());
|
||||
}
|
||||
|
||||
void Error_AttributeEmitError (string inner)
|
||||
{
|
||||
Report.Error (647, Location, "Error during emitting `{0}' attribute. The reason is `{1}'",
|
||||
@@ -1126,6 +1131,11 @@ namespace Mono.CSharp {
|
||||
}
|
||||
|
||||
if (!IsConditionallyExcluded (ctor.DeclaringType)) {
|
||||
if (Type == predefined.TupleElementNames) {
|
||||
Error_MisusedTupleAttribute ();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
foreach (Attributable target in targets)
|
||||
target.ApplyAttributeBuilder (this, ctor, cdata, predefined);
|
||||
@@ -1742,6 +1752,9 @@ namespace Mono.CSharp {
|
||||
// New in .NET 4.5
|
||||
public readonly PredefinedStateMachineAttribute AsyncStateMachine;
|
||||
|
||||
// New in .NET 4.7
|
||||
public readonly PredefinedTupleElementNamesAttribute TupleElementNames;
|
||||
|
||||
//
|
||||
// Optional types which are used as types and for member lookup
|
||||
//
|
||||
@@ -1821,6 +1834,8 @@ namespace Mono.CSharp {
|
||||
CallerLineNumberAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerLineNumberAttribute");
|
||||
CallerFilePathAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerFilePathAttribute");
|
||||
|
||||
TupleElementNames = new PredefinedTupleElementNamesAttribute (module, "System.Runtime.CompilerServices", "TupleElementNamesAttribute");
|
||||
|
||||
// TODO: Should define only attributes which are used for comparison
|
||||
const System.Reflection.BindingFlags all_fields = System.Reflection.BindingFlags.Public |
|
||||
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly;
|
||||
@@ -2171,4 +2186,83 @@ namespace Mono.CSharp {
|
||||
return tctor != null;
|
||||
}
|
||||
}
|
||||
|
||||
public class PredefinedTupleElementNamesAttribute : PredefinedAttribute
|
||||
{
|
||||
MethodSpec tctor;
|
||||
|
||||
public PredefinedTupleElementNamesAttribute (ModuleContainer module, string ns, string name)
|
||||
: base (module, ns, name)
|
||||
{
|
||||
}
|
||||
|
||||
public void EmitAttribute (FieldBuilder builder, TypeSpec type, Location loc)
|
||||
{
|
||||
var cab = CreateCustomAttributeBuilder (type, loc);
|
||||
if (cab != null)
|
||||
builder.SetCustomAttribute (cab);
|
||||
}
|
||||
|
||||
public void EmitAttribute (ParameterBuilder builder, TypeSpec type, Location loc)
|
||||
{
|
||||
var cab = CreateCustomAttributeBuilder (type, loc);
|
||||
if (cab != null)
|
||||
builder.SetCustomAttribute (cab);
|
||||
}
|
||||
|
||||
public void EmitAttribute (PropertyBuilder builder, TypeSpec type, Location loc)
|
||||
{
|
||||
var cab = CreateCustomAttributeBuilder (type, loc);
|
||||
if (cab != null)
|
||||
builder.SetCustomAttribute (cab);
|
||||
}
|
||||
|
||||
public void EmitAttribute (TypeBuilder builder, TypeSpec type, Location loc)
|
||||
{
|
||||
var cab = CreateCustomAttributeBuilder (type, loc);
|
||||
if (cab != null)
|
||||
builder.SetCustomAttribute (cab);
|
||||
}
|
||||
|
||||
CustomAttributeBuilder CreateCustomAttributeBuilder (TypeSpec type, Location loc)
|
||||
{
|
||||
if (tctor == null) {
|
||||
tctor = module.PredefinedMembers.TupleElementNamesAttributeCtor.Resolve (loc);
|
||||
if (tctor == null)
|
||||
return null;
|
||||
}
|
||||
|
||||
var names = new List<string> (type.TypeArguments.Length);
|
||||
BuildStringElements (type, names);
|
||||
return new CustomAttributeBuilder ((ConstructorInfo)tctor.GetMetaInfo (), new object [] { names.ToArray () });
|
||||
}
|
||||
|
||||
//
|
||||
// Returns an array of names when any element of the type is
|
||||
// tuple with named element. The array is built for top level
|
||||
// type therefore it can contain multiple tuple types
|
||||
//
|
||||
// Example: Func<(int, int), int, (int a, int b)[]>
|
||||
// Output: { null, null, "a", "b" }
|
||||
//
|
||||
static void BuildStringElements (TypeSpec type, List<string> names)
|
||||
{
|
||||
while (type is ArrayContainer) {
|
||||
type = ((ArrayContainer)type).Element;
|
||||
}
|
||||
|
||||
var nts = type as NamedTupleSpec;
|
||||
if (nts != null) {
|
||||
names.AddRange (nts.Elements);
|
||||
} else {
|
||||
for (int i = 0; i < type.Arity; ++i) {
|
||||
names.Add (null);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var ta in type.TypeArguments) {
|
||||
BuildStringElements (ta, names);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
ee417ec7ad5d2e297019767f451d0f61dde6f3e9
|
||||
48b1c6921f3c897fe0b8e5780e59fe5f34a514aa
|
||||
@@ -679,6 +679,78 @@ namespace Mono.CSharp {
|
||||
return null;
|
||||
}
|
||||
|
||||
static Expression ImplicitTupleLiteralConversion (ResolveContext rc, Expression source, TypeSpec targetType, Location loc)
|
||||
{
|
||||
var targetTypeArgument = targetType.TypeArguments;
|
||||
if (source.Type.Arity != targetTypeArgument.Length)
|
||||
return null;
|
||||
|
||||
var namedTarget = targetType as NamedTupleSpec;
|
||||
var tupleLiteral = source as TupleLiteral;
|
||||
Expression instance;
|
||||
|
||||
if (tupleLiteral == null && !ExpressionAnalyzer.IsInexpensiveLoad (source)) {
|
||||
var expr_variable = LocalVariable.CreateCompilerGenerated (source.Type, rc.CurrentBlock, loc);
|
||||
source = new CompilerAssign (expr_variable.CreateReferenceExpression (rc, loc), source, loc);
|
||||
instance = expr_variable.CreateReferenceExpression (rc, loc);
|
||||
} else {
|
||||
instance = null;
|
||||
}
|
||||
|
||||
var converted = new List<Expression> (targetType.Arity);
|
||||
for (int i = 0; i < targetType.Arity; ++i) {
|
||||
Expression elementSrc;
|
||||
if (tupleLiteral != null) {
|
||||
elementSrc = tupleLiteral.Elements [i].Expr;
|
||||
|
||||
if (namedTarget != null) {
|
||||
var elementSrcName = tupleLiteral.Elements [i].Name;
|
||||
if (elementSrcName != null && elementSrcName != namedTarget.Elements [i]) {
|
||||
rc.Report.Warning (8123, 1, loc,
|
||||
"The tuple element name `{0}' is ignored because a different name or no name is specified by the target type `{1}'",
|
||||
elementSrcName, namedTarget.GetSignatureForErrorWithNames ());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
elementSrc = new MemberAccess (instance, NamedTupleSpec.GetElementPropertyName (i)).Resolve (rc);
|
||||
}
|
||||
|
||||
var res = ImplicitConversionStandard (rc, elementSrc, targetTypeArgument [i], loc);
|
||||
if (res == null)
|
||||
return null;
|
||||
|
||||
converted.Add (res);
|
||||
}
|
||||
|
||||
return new TupleLiteralConversion (source, targetType, converted, loc);
|
||||
}
|
||||
|
||||
static bool ImplicitTupleLiteralConversionExists (Expression source, TypeSpec targetType)
|
||||
{
|
||||
if (source.Type.Arity != targetType.Arity)
|
||||
return false;
|
||||
|
||||
var srcTypeArgument = source.Type.TypeArguments;
|
||||
var targetTypeArgument = targetType.TypeArguments;
|
||||
|
||||
var tupleLiteralElements = (source as TupleLiteral)?.Elements;
|
||||
|
||||
for (int i = 0; i < targetType.Arity; ++i) {
|
||||
if (tupleLiteralElements != null) {
|
||||
if (!ImplicitStandardConversionExists (tupleLiteralElements[i].Expr, targetTypeArgument [i])) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!ImplicitStandardConversionExists (new EmptyExpression (srcTypeArgument [i]), targetTypeArgument [i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Full version of implicit conversion
|
||||
//
|
||||
@@ -758,7 +830,10 @@ namespace Mono.CSharp {
|
||||
|
||||
if (ImplicitBoxingConversion (null, expr_type, target_type) != null)
|
||||
return true;
|
||||
|
||||
|
||||
if (expr_type.IsTupleType && target_type.IsTupleType)
|
||||
return ImplicitTupleLiteralConversionExists (expr, target_type);
|
||||
|
||||
//
|
||||
// Implicit Constant Expression Conversions
|
||||
//
|
||||
@@ -1420,6 +1495,14 @@ namespace Mono.CSharp {
|
||||
return c;
|
||||
}
|
||||
|
||||
if (expr_type.IsTupleType) {
|
||||
if (target_type.IsTupleType)
|
||||
return ImplicitTupleLiteralConversion (ec, expr, target_type, loc);
|
||||
|
||||
if (expr is TupleLiteral && TupleLiteral.ContainsNoTypeElement (expr_type))
|
||||
return null;
|
||||
}
|
||||
|
||||
e = ImplicitNumericConversion (expr, expr_type, target_type);
|
||||
if (e != null)
|
||||
return e;
|
||||
@@ -1499,14 +1582,15 @@ namespace Mono.CSharp {
|
||||
/// ImplicitConversion. If there is no implicit conversion, then
|
||||
/// an error is signaled
|
||||
/// </summary>
|
||||
static public Expression ImplicitConversionRequired (ResolveContext ec, Expression source,
|
||||
public static Expression ImplicitConversionRequired (ResolveContext ec, Expression source,
|
||||
TypeSpec target_type, Location loc)
|
||||
{
|
||||
Expression e = ImplicitConversion (ec, source, target_type, loc);
|
||||
if (e != null)
|
||||
return e;
|
||||
|
||||
source.Error_ValueCannotBeConverted (ec, target_type, false);
|
||||
if (target_type != InternalType.ErrorType)
|
||||
source.Error_ValueCannotBeConverted (ec, target_type, false);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
2df53e916640209092711ab75dee2489d0e8f64d
|
||||
5f885a77763b8ccebc07be47fb643c310be926f5
|
||||
@@ -1027,7 +1027,7 @@ namespace Mono.CSharp
|
||||
}
|
||||
|
||||
//
|
||||
// Open parens micro parser. Detects both lambda and cast ambiguity.
|
||||
// Open parens micro parser
|
||||
//
|
||||
int TokenizeOpenParens ()
|
||||
{
|
||||
@@ -1037,6 +1037,7 @@ namespace Mono.CSharp
|
||||
int bracket_level = 0;
|
||||
bool is_type = false;
|
||||
bool can_be_type = false;
|
||||
bool at_least_one_comma = false;
|
||||
|
||||
while (true) {
|
||||
ptoken = current_token;
|
||||
@@ -1052,6 +1053,12 @@ namespace Mono.CSharp
|
||||
if (current_token == Token.ARROW)
|
||||
return Token.OPEN_PARENS_LAMBDA;
|
||||
|
||||
//
|
||||
// Expression inside parens is deconstruct expression, (a, x.y) = ...
|
||||
//
|
||||
if (current_token == Token.ASSIGN && at_least_one_comma)
|
||||
return Token.OPEN_PARENS_DECONSTRUCT;
|
||||
|
||||
//
|
||||
// Expression inside parens is single type, (int[])
|
||||
//
|
||||
@@ -1164,6 +1171,7 @@ namespace Mono.CSharp
|
||||
if (bracket_level == 0) {
|
||||
bracket_level = 100;
|
||||
can_be_type = is_type = false;
|
||||
at_least_one_comma = true;
|
||||
}
|
||||
continue;
|
||||
|
||||
@@ -1264,6 +1272,21 @@ namespace Mono.CSharp
|
||||
}
|
||||
|
||||
return false;
|
||||
case Token.OPEN_PARENS:
|
||||
if (!parsing_generic_declaration)
|
||||
return false;
|
||||
|
||||
while (true) {
|
||||
switch (token ()) {
|
||||
case Token.COMMA:
|
||||
// tuple declaration after <
|
||||
return true;
|
||||
case Token.OP_GENERICS_GT:
|
||||
case Token.EOF:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -3481,6 +3504,7 @@ namespace Mono.CSharp
|
||||
case Token.DEFAULT:
|
||||
case Token.DELEGATE:
|
||||
case Token.OP_GENERICS_GT:
|
||||
case Token.REFVALUE:
|
||||
return Token.OPEN_PARENS;
|
||||
}
|
||||
|
||||
|
||||
@@ -926,6 +926,7 @@ namespace Mono.CSharp {
|
||||
MissingDependency = 1 << 5,
|
||||
HasDynamicElement = 1 << 6,
|
||||
ConstraintsChecked = 1 << 7,
|
||||
HasNamedTupleElement = 1 << 8,
|
||||
|
||||
IsAccessor = 1 << 9, // Method is an accessor
|
||||
IsGeneric = 1 << 10, // Member contains type arguments
|
||||
@@ -942,6 +943,7 @@ namespace Mono.CSharp {
|
||||
GenericIterateInterface = 1 << 21,
|
||||
GenericTask = 1 << 22,
|
||||
InterfacesImported = 1 << 23,
|
||||
Tuple = 1 << 24
|
||||
}
|
||||
|
||||
//
|
||||
@@ -951,7 +953,7 @@ namespace Mono.CSharp {
|
||||
StateFlags.CLSCompliant | StateFlags.CLSCompliant_Undetected |
|
||||
StateFlags.Obsolete | StateFlags.Obsolete_Undetected |
|
||||
StateFlags.MissingDependency | StateFlags.MissingDependency_Undetected |
|
||||
StateFlags.HasDynamicElement;
|
||||
StateFlags.HasDynamicElement | StateFlags.HasNamedTupleElement;
|
||||
|
||||
protected Modifiers modifiers;
|
||||
public StateFlags state;
|
||||
|
||||
@@ -101,9 +101,7 @@ namespace Mono.CSharp {
|
||||
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
|
||||
{
|
||||
if (a.Target == AttributeTargets.ReturnValue) {
|
||||
if (return_attributes == null)
|
||||
return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location);
|
||||
|
||||
CreateReturnBuilder ();
|
||||
return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
|
||||
return;
|
||||
}
|
||||
@@ -122,6 +120,11 @@ namespace Mono.CSharp {
|
||||
}
|
||||
}
|
||||
|
||||
ReturnParameter CreateReturnBuilder ()
|
||||
{
|
||||
return return_attributes ?? (return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location));
|
||||
}
|
||||
|
||||
protected override bool DoDefineMembers ()
|
||||
{
|
||||
var builtin_types = Compiler.BuiltinTypes;
|
||||
@@ -329,13 +332,16 @@ namespace Mono.CSharp {
|
||||
}
|
||||
}
|
||||
|
||||
if (ReturnType.Type != null) {
|
||||
if (ReturnType.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
|
||||
return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location);
|
||||
Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
|
||||
} else if (ReturnType.Type.HasDynamicElement) {
|
||||
return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location);
|
||||
Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType.Type, Location);
|
||||
var rtype = ReturnType.Type;
|
||||
if (rtype != null) {
|
||||
if (rtype.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
|
||||
Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder);
|
||||
} else if (rtype.HasDynamicElement) {
|
||||
Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder, rtype, Location);
|
||||
}
|
||||
|
||||
if (rtype.HasNamedTupleElement) {
|
||||
Module.PredefinedAttributes.TupleElementNames.EmitAttribute (CreateReturnBuilder ().Builder, rtype, Location);
|
||||
}
|
||||
|
||||
ConstraintChecker.Check (this, ReturnType.Type, ReturnType.Location);
|
||||
|
||||
@@ -1 +1 @@
|
||||
73e50c4068f62902fd8f04dd4062e324366dd717
|
||||
9486475305452e2ab5c326d264e3f0954e58a661
|
||||
@@ -22,10 +22,35 @@ using MetaType = System.Type;
|
||||
using System.Reflection;
|
||||
#endif
|
||||
|
||||
namespace Mono.CSharp {
|
||||
namespace Mono.CSharp
|
||||
{
|
||||
|
||||
public class EnumMember : Const
|
||||
{
|
||||
#if !STATIC
|
||||
class MemberTypeDelegator : TypeDelegator
|
||||
{
|
||||
Type underlyingType;
|
||||
|
||||
public MemberTypeDelegator (Type delegatingType, Type underlyingType)
|
||||
: base (delegatingType)
|
||||
{
|
||||
this.underlyingType = underlyingType;
|
||||
}
|
||||
|
||||
public override Type GetEnumUnderlyingType ()
|
||||
{
|
||||
return underlyingType;
|
||||
}
|
||||
|
||||
public override Type UnderlyingSystemType {
|
||||
get {
|
||||
return underlyingType;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
class EnumTypeExpr : TypeExpr
|
||||
{
|
||||
public override TypeSpec ResolveAsType (IMemberContext ec, bool allowUnboundTypeArguments)
|
||||
@@ -85,8 +110,17 @@ namespace Mono.CSharp {
|
||||
if (!ResolveMemberType ())
|
||||
return false;
|
||||
|
||||
MetaType ftype = MemberType.GetMetaInfo ();
|
||||
#if !STATIC
|
||||
//
|
||||
// Workaround for .net SRE limitation which cannot define field of unbaked enum type
|
||||
// which is how all enums are declared
|
||||
//
|
||||
ftype = new MemberTypeDelegator (ftype, ((Enum)Parent).UnderlyingType.GetMetaInfo ());
|
||||
#endif
|
||||
|
||||
const FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal;
|
||||
FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType.GetMetaInfo (), attr);
|
||||
FieldBuilder = Parent.TypeBuilder.DefineField (Name, ftype, attr);
|
||||
spec = new ConstSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags, initializer);
|
||||
|
||||
Parent.MemberCache.AddMember (spec);
|
||||
|
||||
@@ -1 +1 @@
|
||||
da37657867ed0e59f43a1d9eefdd010e977e9ae8
|
||||
113ed29910c155493a769098bc9e058a05712a96
|
||||
@@ -244,6 +244,10 @@ namespace Mono.CSharp
|
||||
Module.PredefinedAttributes.Dynamic.EmitAttribute (FieldBuilder, member_type, Location);
|
||||
}
|
||||
|
||||
if (member_type.HasNamedTupleElement) {
|
||||
Module.PredefinedAttributes.TupleElementNames.EmitAttribute (FieldBuilder, member_type, Location);
|
||||
}
|
||||
|
||||
if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
|
||||
Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (FieldBuilder);
|
||||
if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
|
||||
@@ -312,7 +316,7 @@ namespace Mono.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
public FieldInfo GetMetaInfo ()
|
||||
{
|
||||
|
||||
@@ -1772,7 +1772,10 @@ namespace Mono.CSharp {
|
||||
foreach (var arg in targs) {
|
||||
if (arg.HasDynamicElement || arg.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
|
||||
state |= StateFlags.HasDynamicElement;
|
||||
break;
|
||||
}
|
||||
|
||||
if (arg.HasNamedTupleElement) {
|
||||
state |= StateFlags.HasNamedTupleElement;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1852,6 +1855,12 @@ namespace Mono.CSharp {
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsTupleType {
|
||||
get {
|
||||
return (open_type.state & StateFlags.Tuple) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Types used to inflate the generic type
|
||||
//
|
||||
@@ -3095,6 +3104,9 @@ namespace Mono.CSharp {
|
||||
bound.Type == InternalType.ThrowExpr)
|
||||
return;
|
||||
|
||||
if (bound.Type.IsTupleType && TupleLiteral.ContainsNoTypeElement (bound.Type))
|
||||
return;
|
||||
|
||||
var a = bounds [index];
|
||||
if (a == null) {
|
||||
a = new List<BoundInfo> (2);
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace Mono.CSharp
|
||||
if (t.Name[0] == '<')
|
||||
continue;
|
||||
|
||||
var it = CreateType (t, null, new DynamicTypeReader (t), true);
|
||||
var it = CreateType (t, null, new AttributesTypeInfoReader (t), true);
|
||||
if (it == null)
|
||||
continue;
|
||||
|
||||
@@ -520,13 +520,23 @@ namespace Mono.CSharp
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((an.Flags & AssemblyNameFlags.PublicKey) == (loaded_name.Flags & AssemblyNameFlags.PublicKey)) {
|
||||
compiler.Report.SymbolRelatedToPreviousError (entry.Item2);
|
||||
compiler.Report.SymbolRelatedToPreviousError (fileName);
|
||||
compiler.Report.Error (1703,
|
||||
"An assembly `{0}' with the same identity has already been imported. Consider removing one of the references",
|
||||
an.Name);
|
||||
return null;
|
||||
AssemblyComparisonResult result;
|
||||
if ((an.Flags & AssemblyNameFlags.PublicKey) == (loaded_name.Flags & AssemblyNameFlags.PublicKey) &&
|
||||
(domain.CompareAssemblyIdentity (an.FullName, false, loaded_name.FullName, false, out result))) {
|
||||
|
||||
//
|
||||
// Roslyn is much more lenient than native compiler here
|
||||
//
|
||||
switch (result) {
|
||||
case AssemblyComparisonResult.EquivalentFXUnified:
|
||||
case AssemblyComparisonResult.EquivalentUnified:
|
||||
compiler.Report.SymbolRelatedToPreviousError (entry.Item2);
|
||||
compiler.Report.SymbolRelatedToPreviousError (fileName);
|
||||
compiler.Report.Error (1703,
|
||||
"An assembly `{0}' with the same identity has already been imported. Consider removing one of the references",
|
||||
an.Name);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,15 +30,18 @@ namespace Mono.CSharp
|
||||
public abstract class MetadataImporter
|
||||
{
|
||||
//
|
||||
// Dynamic types reader with additional logic to reconstruct a dynamic
|
||||
// type using DynamicAttribute values
|
||||
// Types reader with additional logic to reconstruct extra
|
||||
// type information encoded in custom attributes values
|
||||
//
|
||||
protected struct DynamicTypeReader
|
||||
protected struct AttributesTypeInfoReader
|
||||
{
|
||||
static readonly bool[] single_attribute = { true };
|
||||
|
||||
public int Position;
|
||||
bool[] flags;
|
||||
public int DynamicPosition;
|
||||
bool[] dynamicFlags;
|
||||
|
||||
public int TuplePosition;
|
||||
string[] tupleNames;
|
||||
|
||||
// There is no common type for CustomAttributeData and we cannot
|
||||
// use ICustomAttributeProvider
|
||||
@@ -47,10 +50,12 @@ namespace Mono.CSharp
|
||||
//
|
||||
// A member provider which can be used to get CustomAttributeData
|
||||
//
|
||||
public DynamicTypeReader (object provider)
|
||||
public AttributesTypeInfoReader (object provider)
|
||||
{
|
||||
Position = 0;
|
||||
flags = null;
|
||||
DynamicPosition = 0;
|
||||
TuplePosition = 0;
|
||||
dynamicFlags = null;
|
||||
tupleNames = null;
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@@ -62,7 +67,7 @@ namespace Mono.CSharp
|
||||
if (provider != null)
|
||||
ReadAttribute ();
|
||||
|
||||
return flags != null && Position < flags.Length && flags[Position];
|
||||
return dynamicFlags != null && DynamicPosition < dynamicFlags.Length && dynamicFlags [DynamicPosition];
|
||||
}
|
||||
|
||||
//
|
||||
@@ -73,7 +78,34 @@ namespace Mono.CSharp
|
||||
if (provider != null)
|
||||
ReadAttribute ();
|
||||
|
||||
return flags != null;
|
||||
return dynamicFlags != null;
|
||||
}
|
||||
|
||||
public bool HasNamedTupleAttribute ()
|
||||
{
|
||||
if (provider != null)
|
||||
ReadAttribute ();
|
||||
|
||||
return tupleNames != null;
|
||||
}
|
||||
|
||||
public IList<string> GetNamedTupleElements (int length)
|
||||
{
|
||||
if (TuplePosition == 0 && length == tupleNames.Length)
|
||||
return tupleNames;
|
||||
|
||||
for (int i = TuplePosition; i < length + TuplePosition; ++i) {
|
||||
if (tupleNames [i] != null) {
|
||||
var res = new string [length];
|
||||
Array.Copy (tupleNames, TuplePosition, res, 0, length);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Current range can be just padding
|
||||
//
|
||||
return null;
|
||||
}
|
||||
|
||||
IList<CustomAttributeData> GetCustomAttributes ()
|
||||
@@ -100,22 +132,40 @@ namespace Mono.CSharp
|
||||
if (cad.Count > 0) {
|
||||
foreach (var ca in cad) {
|
||||
var dt = ca.Constructor.DeclaringType;
|
||||
if (dt.Name != "DynamicAttribute" || dt.Namespace != CompilerServicesNamespace)
|
||||
if (dt.Namespace != CompilerServicesNamespace)
|
||||
continue;
|
||||
|
||||
if (ca.ConstructorArguments.Count == 0) {
|
||||
flags = single_attribute;
|
||||
switch (dt.Name) {
|
||||
case "DynamicAttribute":
|
||||
if (ca.ConstructorArguments.Count == 0) {
|
||||
dynamicFlags = single_attribute;
|
||||
break;
|
||||
}
|
||||
|
||||
var arg_type = ca.ConstructorArguments [0].ArgumentType;
|
||||
|
||||
if (arg_type.IsArray && MetaType.GetTypeCode (arg_type.GetElementType ()) == TypeCode.Boolean) {
|
||||
var carg = (IList<CustomAttributeTypedArgument>)ca.ConstructorArguments [0].Value;
|
||||
dynamicFlags = new bool [carg.Count];
|
||||
for (int i = 0; i < dynamicFlags.Length; ++i) {
|
||||
if (MetaType.GetTypeCode (carg [i].ArgumentType) == TypeCode.Boolean)
|
||||
dynamicFlags [i] = (bool)carg [i].Value;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "TupleElementNamesAttribute":
|
||||
if (ca.ConstructorArguments.Count != 1)
|
||||
break;
|
||||
|
||||
var arg_type = ca.ConstructorArguments[0].ArgumentType;
|
||||
|
||||
if (arg_type.IsArray && MetaType.GetTypeCode (arg_type.GetElementType ()) == TypeCode.Boolean) {
|
||||
var carg = (IList<CustomAttributeTypedArgument>) ca.ConstructorArguments[0].Value;
|
||||
flags = new bool[carg.Count];
|
||||
for (int i = 0; i < flags.Length; ++i) {
|
||||
if (MetaType.GetTypeCode (carg[i].ArgumentType) == TypeCode.Boolean)
|
||||
flags[i] = (bool) carg[i].Value;
|
||||
var tuple_arg_type = ca.ConstructorArguments [0].ArgumentType;
|
||||
if (tuple_arg_type.IsArray && MetaType.GetTypeCode (tuple_arg_type.GetElementType ()) == TypeCode.String) {
|
||||
var carg = (IList<CustomAttributeTypedArgument>)ca.ConstructorArguments [0].Value;
|
||||
tupleNames = new string [carg.Count];
|
||||
for (int i = 0; i < tupleNames.Length; ++i) {
|
||||
if (MetaType.GetTypeCode (carg [i].ArgumentType) == TypeCode.String)
|
||||
tupleNames [i] = (string)carg [i].Value;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -195,7 +245,7 @@ namespace Mono.CSharp
|
||||
TypeSpec field_type;
|
||||
|
||||
try {
|
||||
field_type = ImportType (fi.FieldType, new DynamicTypeReader (fi), declaringType);
|
||||
field_type = ImportType (fi.FieldType, new AttributesTypeInfoReader (fi), declaringType);
|
||||
|
||||
//
|
||||
// Private field has private type which is not fixed buffer
|
||||
@@ -275,7 +325,7 @@ namespace Mono.CSharp
|
||||
if (add.Modifiers != remove.Modifiers)
|
||||
throw new NotImplementedException ("Different accessor modifiers " + ei.Name);
|
||||
|
||||
var event_type = ImportType (ei.EventHandlerType, new DynamicTypeReader (ei), declaringType);
|
||||
var event_type = ImportType (ei.EventHandlerType, new AttributesTypeInfoReader (ei), declaringType);
|
||||
var definition = new ImportedMemberDefinition (ei, event_type, this);
|
||||
return new EventSpec (declaringType, definition, event_type, add.Modifiers, add, remove);
|
||||
}
|
||||
@@ -327,15 +377,15 @@ namespace Mono.CSharp
|
||||
var type = tparams[pos];
|
||||
int index = pos - first;
|
||||
|
||||
tspec[index] = (TypeParameterSpec) CreateType (type, new DynamicTypeReader (), false);
|
||||
tspec[index] = (TypeParameterSpec) CreateType (type, new AttributesTypeInfoReader (), false);
|
||||
}
|
||||
|
||||
return tspec;
|
||||
}
|
||||
|
||||
TypeSpec[] CreateGenericArguments (int first, MetaType[] tparams, DynamicTypeReader dtype)
|
||||
TypeSpec[] CreateGenericArguments (int first, MetaType[] tparams, AttributesTypeInfoReader dtype)
|
||||
{
|
||||
++dtype.Position;
|
||||
++dtype.DynamicPosition;
|
||||
|
||||
var tspec = new TypeSpec [tparams.Length - first];
|
||||
for (int pos = first; pos < tparams.Length; ++pos) {
|
||||
@@ -345,7 +395,7 @@ namespace Mono.CSharp
|
||||
TypeSpec spec;
|
||||
if (type.HasElementType) {
|
||||
var element = type.GetElementType ();
|
||||
++dtype.Position;
|
||||
++dtype.DynamicPosition;
|
||||
spec = ImportType (element, dtype, null);
|
||||
|
||||
if (!type.IsArray) {
|
||||
@@ -374,7 +424,7 @@ namespace Mono.CSharp
|
||||
if (spec == null)
|
||||
return null;
|
||||
|
||||
++dtype.Position;
|
||||
++dtype.DynamicPosition;
|
||||
tspec[index] = spec;
|
||||
}
|
||||
|
||||
@@ -415,7 +465,7 @@ namespace Mono.CSharp
|
||||
returnType = module.Compiler.BuiltinTypes.Void;
|
||||
} else {
|
||||
var mi = (MethodInfo)mb;
|
||||
returnType = ImportType (mi.ReturnType, new DynamicTypeReader (mi.ReturnParameter), declaringType);
|
||||
returnType = ImportType (mi.ReturnType, new AttributesTypeInfoReader (mi.ReturnParameter), declaringType);
|
||||
|
||||
//
|
||||
// Detect operators and destructors
|
||||
@@ -545,13 +595,13 @@ namespace Mono.CSharp
|
||||
// Strip reference wrapping
|
||||
//
|
||||
var el = p.ParameterType.GetElementType ();
|
||||
types[i] = ImportType (el, new DynamicTypeReader (p), parent); // TODO: 1-based positio to be csc compatible
|
||||
types[i] = ImportType (el, new AttributesTypeInfoReader (p), parent); // TODO: 1-based positio to be csc compatible
|
||||
} else if (i == 0 && method.IsStatic && (parent.Modifiers & Modifiers.METHOD_EXTENSION) != 0 &&
|
||||
HasAttribute (CustomAttributeData.GetCustomAttributes (method), "ExtensionAttribute", CompilerServicesNamespace)) {
|
||||
mod = Parameter.Modifier.This;
|
||||
types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p), parent);
|
||||
types[i] = ImportType (p.ParameterType, new AttributesTypeInfoReader (p), parent);
|
||||
} else {
|
||||
types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p), parent);
|
||||
types[i] = ImportType (p.ParameterType, new AttributesTypeInfoReader (p), parent);
|
||||
|
||||
if (i >= pi.Length - 2 && types[i] is ArrayContainer) {
|
||||
if (HasAttribute (CustomAttributeData.GetCustomAttributes (p), "ParamArrayAttribute", "System")) {
|
||||
@@ -734,26 +784,26 @@ namespace Mono.CSharp
|
||||
|
||||
public TypeSpec CreateType (MetaType type)
|
||||
{
|
||||
return CreateType (type, new DynamicTypeReader (), true);
|
||||
return CreateType (type, new AttributesTypeInfoReader (), true);
|
||||
}
|
||||
|
||||
public TypeSpec CreateNestedType (MetaType type, TypeSpec declaringType)
|
||||
{
|
||||
return CreateType (type, declaringType, new DynamicTypeReader (type), false);
|
||||
return CreateType (type, declaringType, new AttributesTypeInfoReader (type), false);
|
||||
}
|
||||
|
||||
TypeSpec CreateType (MetaType type, DynamicTypeReader dtype, bool canImportBaseType)
|
||||
TypeSpec CreateType (MetaType type, AttributesTypeInfoReader dtype, bool canImportBaseType)
|
||||
{
|
||||
TypeSpec declaring_type;
|
||||
if (type.IsNested && !type.IsGenericParameter)
|
||||
declaring_type = CreateType (type.DeclaringType, new DynamicTypeReader (type.DeclaringType), true);
|
||||
declaring_type = CreateType (type.DeclaringType, new AttributesTypeInfoReader (type.DeclaringType), true);
|
||||
else
|
||||
declaring_type = null;
|
||||
|
||||
return CreateType (type, declaring_type, dtype, canImportBaseType);
|
||||
}
|
||||
|
||||
protected TypeSpec CreateType (MetaType type, TypeSpec declaringType, DynamicTypeReader dtype, bool canImportBaseType)
|
||||
protected TypeSpec CreateType (MetaType type, TypeSpec declaringType, AttributesTypeInfoReader dtype, bool canImportBaseType)
|
||||
{
|
||||
TypeSpec spec;
|
||||
if (import_cache.TryGetValue (type, out spec)) {
|
||||
@@ -796,7 +846,7 @@ namespace Mono.CSharp
|
||||
return null;
|
||||
if (declaringType == null) {
|
||||
// Simple case, no nesting
|
||||
spec = CreateType (type_def, null, new DynamicTypeReader (), canImportBaseType);
|
||||
spec = CreateType (type_def, null, new AttributesTypeInfoReader (), canImportBaseType);
|
||||
spec = spec.MakeGenericType (module, targs);
|
||||
} else {
|
||||
//
|
||||
@@ -851,6 +901,14 @@ namespace Mono.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
if (spec.IsTupleType && dtype.HasNamedTupleAttribute ()) {
|
||||
var names = dtype.GetNamedTupleElements (spec.Arity);
|
||||
if (names != null)
|
||||
return NamedTupleSpec.MakeType (module, (InflatedTypeSpec) spec, names);
|
||||
|
||||
dtype.TuplePosition += spec.Arity;
|
||||
}
|
||||
|
||||
// Don't add generic type with dynamic arguments, they can interfere with same type
|
||||
// using object type arguments
|
||||
if (!spec.HasDynamicElement) {
|
||||
@@ -1071,7 +1129,7 @@ namespace Mono.CSharp
|
||||
else if (type.BaseType != null) {
|
||||
TypeSpec base_type;
|
||||
if (!IsMissingType (type.BaseType) && type.BaseType.IsGenericType)
|
||||
base_type = CreateType (type.BaseType, new DynamicTypeReader (type), true);
|
||||
base_type = CreateType (type.BaseType, new AttributesTypeInfoReader (type), true);
|
||||
else
|
||||
base_type = CreateType (type.BaseType);
|
||||
|
||||
@@ -1100,7 +1158,7 @@ namespace Mono.CSharp
|
||||
if (t.Name[0] == '<')
|
||||
continue;
|
||||
|
||||
var it = CreateType (t, null, new DynamicTypeReader (t), true);
|
||||
var it = CreateType (t, null, new AttributesTypeInfoReader (t), true);
|
||||
if (it == null)
|
||||
continue;
|
||||
|
||||
@@ -1192,14 +1250,14 @@ namespace Mono.CSharp
|
||||
|
||||
public TypeSpec ImportType (MetaType type)
|
||||
{
|
||||
return ImportType (type, new DynamicTypeReader (type), null);
|
||||
return ImportType (type, new AttributesTypeInfoReader (type), null);
|
||||
}
|
||||
|
||||
TypeSpec ImportType (MetaType type, DynamicTypeReader dtype, TypeSpec currentType)
|
||||
TypeSpec ImportType (MetaType type, AttributesTypeInfoReader dtype, TypeSpec currentType)
|
||||
{
|
||||
if (type.HasElementType) {
|
||||
var element = type.GetElementType ();
|
||||
++dtype.Position;
|
||||
++dtype.DynamicPosition;
|
||||
var spec = ImportType (element, dtype, currentType);
|
||||
|
||||
if (type.IsArray)
|
||||
|
||||
@@ -157,6 +157,7 @@
|
||||
<Compile Include="field.cs" />
|
||||
<Compile Include="typespec.cs" />
|
||||
<Compile Include="visit.cs" />
|
||||
<Compile Include="tuples.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="IKVM.Reflection">
|
||||
<Compile Include="..\..\external\ikvm\reflect\*.cs">
|
||||
|
||||
@@ -49,6 +49,7 @@ statement.cs
|
||||
support.cs
|
||||
typemanager.cs
|
||||
typespec.cs
|
||||
tuples.cs
|
||||
visit.cs
|
||||
../class/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs
|
||||
../class/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs
|
||||
|
||||
@@ -1501,6 +1501,12 @@ namespace Mono.CSharp {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var pm_member = (MethodCore)member;
|
||||
if (!NamedTupleSpec.CheckOverrideName (pm, pm_member) || !NamedTupleSpec.CheckOverrideName (pm.MemberType, pm_member.MemberType)) {
|
||||
Report.Error (8142, member.Location,
|
||||
"A partial method declaration and partial method implementation must both use the same tuple element names");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user