//
// Compiler generated container for static data
//
- sealed class StaticDataContainer : CompilerGeneratedClass
+ sealed class StaticDataContainer : CompilerGeneratedContainer
{
readonly Dictionary<int, Struct> size_types;
int fields;
public StaticDataContainer (ModuleContainer module)
- : base (module, new MemberName ("<PrivateImplementationDetails>" + module.builder.ModuleVersionId.ToString ("B"), Location.Null), Modifiers.STATIC)
+ : base (module, new MemberName ("<PrivateImplementationDetails>" + module.builder.ModuleVersionId.ToString ("B"), Location.Null),
+ Modifiers.STATIC | Modifiers.INTERNAL)
{
size_types = new Dictionary<int, Struct> ();
}
readonly Dictionary<TypeSpec, PointerContainer> pointer_types;
readonly Dictionary<TypeSpec, ReferenceContainer> reference_types;
readonly Dictionary<TypeSpec, MethodSpec> attrs_cache;
+ readonly Dictionary<TypeSpec, AwaiterDefinition> awaiters;
AssemblyDefinition assembly;
readonly CompilerContext context;
PredefinedTypes predefined_types;
PredefinedMembers predefined_members;
+ public Binary.PredefinedOperator[] OperatorsBinaryEqualityLifted;
+ public Binary.PredefinedOperator[] OperatorsBinaryLifted;
+
static readonly string[] attribute_targets = new string[] { "assembly", "module" };
public ModuleContainer (CompilerContext context)
pointer_types = new Dictionary<TypeSpec, PointerContainer> ();
reference_types = new Dictionary<TypeSpec, ReferenceContainer> ();
attrs_cache = new Dictionary<TypeSpec, MethodSpec> ();
+ awaiters = new Dictionary<TypeSpec, AwaiterDefinition> ();
}
#region Properties
}
}
+ public int CounterAnonymousTypes { get; set; }
+
public AssemblyDefinition DeclaringAssembly {
get {
return assembly;
public override void AddTypeContainer (TypeContainer tc)
{
- containers.Add (tc);
+ AddTypeContainerMember (tc);
}
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
DefineContainer ();
+ ExpandBaseInterfaces ();
+
base.Define ();
HasTypesFullyDefined = true;
return base.DefineContainer ();
}
+ public void EnableRedefinition ()
+ {
+ is_defined = false;
+ }
+
public override void EmitContainer ()
{
if (OptAttributes != null)
OptAttributes.Emit ();
- if (Compiler.Settings.Unsafe) {
+ if (Compiler.Settings.Unsafe && !assembly.IsSatelliteAssembly) {
var pa = PredefinedAttributes.UnverifiableCode;
if (pa.IsDefined)
pa.EmitAttribute (builder);
}
foreach (var tc in containers) {
- tc.DefineConstants ();
+ tc.PrepareEmit ();
}
base.EmitContainer ();
- if (Compiler.Report.Errors == 0)
+ if (Compiler.Report.Errors == 0 && !Compiler.Settings.WriteMetadataOnly)
VerifyMembers ();
if (anonymous_types != null) {
return null;
}
+ //
+ // Return container with awaiter definition. It never returns null
+ // but all container member can be null for easier error reporting
+ //
+ public AwaiterDefinition GetAwaiter (TypeSpec type)
+ {
+ AwaiterDefinition awaiter;
+ if (awaiters.TryGetValue (type, out awaiter))
+ return awaiter;
+
+ awaiter = new AwaiterDefinition ();
+
+ //
+ // Predefined: bool IsCompleted { get; }
+ //
+ awaiter.IsCompleted = MemberCache.FindMember (type, MemberFilter.Property ("IsCompleted", Compiler.BuiltinTypes.Bool),
+ BindingRestriction.InstanceOnly) as PropertySpec;
+
+ //
+ // Predefined: GetResult ()
+ //
+ // The method return type is also result type of await expression
+ //
+ awaiter.GetResult = MemberCache.FindMember (type, MemberFilter.Method ("GetResult", 0,
+ ParametersCompiled.EmptyReadOnlyParameters, null),
+ BindingRestriction.InstanceOnly) as MethodSpec;
+
+ //
+ // Predefined: INotifyCompletion.OnCompleted (System.Action)
+ //
+ var nc = PredefinedTypes.INotifyCompletion;
+ awaiter.INotifyCompletion = !nc.Define () || type.ImplementsInterface (nc.TypeSpec, false);
+
+ awaiters.Add (type, awaiter);
+ return awaiter;
+ }
+
public override void GetCompletionStartingWith (string prefix, List<string> results)
{
var names = Evaluator.GetVarNames ();
return "<module>";
}
+ public Binary.PredefinedOperator[] GetPredefinedEnumAritmeticOperators (TypeSpec enumType, bool nullable)
+ {
+ TypeSpec underlying;
+ Binary.Operator mask = 0;
+
+ if (nullable) {
+ underlying = Nullable.NullableInfo.GetEnumUnderlyingType (this, enumType);
+ mask = Binary.Operator.NullableMask;
+ } else {
+ underlying = EnumSpec.GetUnderlyingType (enumType);
+ }
+
+ var operators = new[] {
+ new Binary.PredefinedOperator (enumType, underlying,
+ mask | Binary.Operator.AdditionMask | Binary.Operator.SubtractionMask | Binary.Operator.DecomposedMask, enumType),
+ new Binary.PredefinedOperator (underlying, enumType,
+ mask | Binary.Operator.AdditionMask | Binary.Operator.SubtractionMask | Binary.Operator.DecomposedMask, enumType),
+ new Binary.PredefinedOperator (enumType, mask | Binary.Operator.SubtractionMask, underlying)
+ };
+
+ return operators;
+ }
+
public void InitializePredefinedTypes ()
{
predefined_attributes = new PredefinedAttributes (this);
predefined_types = new PredefinedTypes (this);
predefined_members = new PredefinedMembers (this);
+
+ OperatorsBinaryEqualityLifted = Binary.CreateEqualityLiftedOperatorsTable (this);
+ OperatorsBinaryLifted = Binary.CreateStandardLiftedOperatorsTable (this);
}
public override bool IsClsComplianceRequired ()