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 int CounterAnonymousMethods { get; set; }
- public int CounterAnonymousContainers { get; set; }
- public int CounterSwitchTypes { get; set; }
public AssemblyDefinition DeclaringAssembly {
get {
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);
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 ()