public IEnumerable<KeyValuePair<string, string>> AllStringSlots() { if (stringSlots == null) stringSlots = new SlotAllocation<string>(env.DebugMode, NameFlavor.Identifier, FriendlyStringName); return stringSlots; }
public string ResolveStringToSlot(string str) { if (stringSlots == null) { // String slots are only used as object fields stringSlots = new SlotAllocation<string>(env.DebugMode, NameFlavor.Identifier, FriendlyStringName); // Collect statistincs on string literals var stringStats = new StringStats(); stringStats.Collect(env.Global, assemblyDef, typeDef); // Setup slots for shared strings foreach (var kv in stringStats) { if (kv.Value == StringBindScope.Type) stringSlots.Add(kv.Key); } } return stringSlots.HasSlot(str) ? stringSlots.For(ctxt, str) : null; }
private static void AddNames( CompilerEnvironment env, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, SlotAllocation<CST.QualifiedMemberName> methodSlots, SlotAllocation<CST.QualifiedMemberName> fieldSlots, SlotAllocation<CST.QualifiedMemberName> eventSlots, SlotAllocation<CST.QualifiedMemberName> propSlots) { // Allocate slots for any base type so that this type's slots won't collide with them. // NOTE: Not strictly necessary for methods, since only virtual methods of supertype may find their // way into derived type, but seems easiest to just allocate them all. // NOTE: Interface method slots need only be unique within their interface type since the type // id is included in the final slot name. if (typeDef.Extends != null) { var extAssemblyDef = default(CST.AssemblyDef); var extTypeDef = default(CST.TypeDef); if (typeDef.Extends.PrimTryResolve(env.Global, out extAssemblyDef, out extTypeDef)) AddNames(env, extAssemblyDef, extTypeDef, methodSlots, fieldSlots, eventSlots, propSlots); } // Members are already in canonical order foreach (var memberDef in typeDef.Members.Where(m => m.IsUsed && m.Invalid == null)) { var name = memberDef.QualifiedMemberName(env.Global, assemblyDef, typeDef); switch (memberDef.Flavor) { case CST.MemberDefFlavor.Field: { fieldSlots.Add(name); break; } case CST.MemberDefFlavor.Event: { eventSlots.Add(name); break; } case CST.MemberDefFlavor.Method: { methodSlots.Add(name); break; } case CST.MemberDefFlavor.Property: { propSlots.Add(name); break; } default: throw new ArgumentOutOfRangeException(); } } return; }
public TypeMapping(CompilerEnvironment env, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef) { ctxt = CST.MessageContextBuilders.Type(env.Global, assemblyDef, typeDef); this.env = env; this.assemblyDef = assemblyDef; this.typeDef = typeDef; // Method slots appear as field names in type structures and directory names on disk. // Thus we use lower-case identifiers. methodSlots = new SlotAllocation<CST.QualifiedMemberName> (env.DebugMode, NameFlavor.LowercaseIdentifier, FriendlyMemberName); // Field slots appear in object annd type structuers, but always prefixed by 'S' or 'F'. // Thus we use arbitrary identifiers. fieldSlots = new SlotAllocation<CST.QualifiedMemberName> (env.DebugMode, NameFlavor.Identifier, FriendlyMemberName); // Similarly for event slots, but prefixed by 'E'. eventSlots = new SlotAllocation<CST.QualifiedMemberName> (env.DebugMode, NameFlavor.Identifier, FriendlyMemberName); // Similarly for property slots (needed only by reflection), but prefixed by 'R' propSlots = new SlotAllocation<CST.QualifiedMemberName> (env.DebugMode, NameFlavor.Identifier, FriendlyMemberName); AddNames(env, assemblyDef, typeDef, methodSlots, fieldSlots, eventSlots, propSlots); // Defer till ask for string slot stringSlots = null; }
public AssemblyMapping(CompilerEnvironment env, CST.AssemblyDef assemblyDef) { ctxt = CST.MessageContextBuilders.Assembly(env.Global, assemblyDef); // Type slots appear as field names in assembly structure, possibly without prefixes, and // as directory names on disk types = new SlotAllocation<CST.TypeName>(env.DebugMode, NameFlavor.LowercaseIdentifier, FriendlyTypeName); if (assemblyDef.Name.Equals(env.Global.MsCorLibName)) { types.Add(env.Global.ArrayTypeConstructorRef.QualifiedTypeName.Type); types.Add(env.Global.ManagedPointerTypeConstructorRef.QualifiedTypeName.Type); } // Types are already in canonical order foreach (var typeDef in assemblyDef.Types.Where(t => t.IsUsed && t.Invalid == null)) types.Add(typeDef.EffectiveName(env.Global)); // Assembly slots appear as field names in assembly structures, prefixed by 'A' referencedAssemblies = new SlotAllocation<CST.AssemblyName> (env.DebugMode, NameFlavor.Identifier, FriendlyAssemblyName); var assmEnv = env.Global.Environment().AddAssembly(assemblyDef); foreach (var nm in assmEnv.AllAssembliesInLoadOrder()) { if (!nm.Equals(env.Global.MsCorLibName) && !nm.Equals(assemblyDef.Name)) referencedAssemblies.Add(nm); // else: mscorlib is bound into root structure, don't need self ref } }