private void SetupTypes(Seq <JST.Statement> body) { var need = new Set <CST.TypeName>(); switch (Env.CompilationMode) { case CompilationMode.Plain: { // Take all types in this assembly to phase 3, in an order where hopefully a types .cctor // only depends on earlier .ctors. foreach (var typeDef in typeDefs.Where(d => d.Arity == 0 && !d.IsModule)) { need.Add(typeDef.EffectiveName(Env.Global)); } break; } case CompilationMode.Collecting: // Don't setup any types, every reference will go via a call to the type builder return; case CompilationMode.Traced: { // Setup types defined in this assembly's trace foreach (var typeDef in typeDefs.Where(d => d.Arity == 0 && !d.IsModule)) { var nm = typeDef.EffectiveName(Env.Global); var typeTrace = default(TypeTrace); if (assemblyTrace.TypeMap.TryGetValue(nm, out typeTrace) && typeTrace.IncludeType) { need.Add(nm); } } break; } default: throw new ArgumentOutOfRangeException(); } foreach (var name in Env.Validity.TypeInitializationOrder.Where (name => name.Assembly.Equals(AssmEnv.Assembly.Name) && need.Contains(name.Type))) { var tyconEnv = name.Enter(AssmEnv); var slotName = Env.GlobalMapping.ResolveTypeDefToSlot(tyconEnv.Assembly, tyconEnv.Type); // Invoke builder to force initialization body.Add (JST.Statement.DotCall (assemblyId.ToE(), new JST.Identifier(Constants.AssemblyTypeBuilderSlot(slotName)))); } }