public override bool PropogateExtraUsedFromMember(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MemberDef memberDef) { var newUsed = false; var methodDef = memberDef as CST.MethodDef; if (methodDef != null) { if (!methodDef.IsStatic && methodDef.IsConstructor && env.InteropManager.IsImported(assemblyDef, typeDef, methodDef) && !env.InteropManager.IsFactory(assemblyDef, typeDef, methodDef)) { // Imported instance constructor may invoke an 'importing' constructor var polyMethEnv = Global.Environment().AddAssembly(assemblyDef).AddType(typeDef).AddSelfTypeBoundArguments(). AddMethod(methodDef); var methodRef = env.InteropManager.BestImportingConstructor(polyMethEnv); if (methodRef != null) { if (ExtraUsedMethod(methodRef.QualifiedMemberName)) { newUsed = true; } } } } return(newUsed); }
public void Collect(CST.Global global, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef) { foreach (var methodDef in typeDef.Members.OfType <CST.MethodDef>().Where(m => m.IsUsed && m.Invalid == null)) { Collect(global, methodDef); } }
public AssemblyTrace(Trace parent, CST.AssemblyDef assembly) { Parent = parent; Assembly = assembly; IncludeAssembly = false; TypeMap = new Map <CST.TypeName, TypeTrace>(); }
public override bool PropogateExtraUsedFromType(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef) { var newUsed = false; var state = env.InteropManager.GetTypeRepresentation(assemblyDef, typeDef).State; if (state == InstanceState.JavaScriptOnly || state == InstanceState.ManagedAndJavaScript) { var typeEnv = Global.Environment().AddAssembly(assemblyDef).AddType(typeDef).AddSelfTypeBoundArguments(); var methodRef = env.InteropManager.DefaultImportingConstructor(typeEnv); if (methodRef != null) { // Default importing constructor is used if its type is used if (ExtraUsedMethod(methodRef.QualifiedMemberName)) { newUsed = true; } } } return(newUsed); }
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 AssemblyTrace(Trace parent, CST.AssemblyDef assembly) { Parent = parent; Assembly = assembly; IncludeAssembly = false; TypeMap = new Map<CST.TypeName, TypeTrace>(); }
// NOTE: May be called on invalid definitions public override bool FieldAlwaysUsed(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.FieldDef fieldDef) { #if false if (env.AttributeHelper.FieldHasAttribute(assemblyDef, typeDef, fieldDef, env.Global.CompilerGeneratedAttributeRef, false)) { return(false); } #endif if (env.AttributeHelper.FieldHasAttribute(assemblyDef, typeDef, fieldDef, env.AttributeHelper.IgnoreAttributeRef, true, true)) { return(false); } if (HasFullReflection(assemblyDef, typeDef)) { return(true); } var isUsed = default(bool); env.AttributeHelper.GetValueFromField(assemblyDef, typeDef, fieldDef, env.AttributeHelper.UsedAttributeRef, env.AttributeHelper.TheIsUsedProperty, true, false, ref isUsed); if (isUsed) { return(true); } return(false); }
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 } }
// Collecting mode entry point public AssemblyCompiler(CompilerEnvironment env, CST.AssemblyDef assemblyDef) : this(env) { assmEnv = env.Global.Environment().AddAssembly(assemblyDef); assemblyTrace = null; NameSupply = new JST.NameSupply(Constants.Globals); rootId = NameSupply.GenSym(); assemblyId = NameSupply.GenSym(); }
public override void ImplementableTypeDef(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef) { if (env.AttributeHelper.TypeHasAttribute (assemblyDef, typeDef, env.AttributeHelper.IgnoreAttributeRef, true, true)) { var ctxt = CST.MessageContextBuilders.Type(env.Global, assemblyDef, typeDef); Log(new CST.InvalidTypeDef(ctxt, "Type is marked as '[Ignore]'")); typeDef.Invalid = new CST.InvalidInfo("Ignored"); } }
private AssemblyTrace ResolveAssemblyTrace(CST.AssemblyDef assemblyDef) { var assemblyTrace = default(AssemblyTrace); if (!AssemblyMap.TryGetValue(assemblyDef.Name, out assemblyTrace)) { assemblyTrace = new AssemblyTrace(this, assemblyDef); AssemblyMap.Add(assemblyDef.Name, assemblyTrace); } return(assemblyTrace); }
// NOTE: May be called on invalid definitions public override bool MethodAlwaysUsed(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef) { if (typeDef.Style is CST.DelegateTypeStyle) { // All the magic delegate methods are inlined by the compiler return(false); } #if false if (env.AttributeHelper.MethodHasAttribute(assemblyDef, typeDef, methodDef, env.Global.CompilerGeneratedAttributeRef, false)) { return(false); } #endif if (env.AttributeHelper.MethodHasAttribute (assemblyDef, typeDef, methodDef, env.AttributeHelper.IgnoreAttributeRef, true, true)) { return(false); } if (typeDef.IsModule && methodDef.IsStatic && methodDef.IsConstructor) { return(true); } if (HasFullReflection(assemblyDef, typeDef)) { return(true); } var isUsed = default(bool); env.AttributeHelper.GetValueFromMethod (assemblyDef, typeDef, methodDef, env.AttributeHelper.UsedAttributeRef, env.AttributeHelper.TheIsUsedProperty, true, false, ref isUsed); if (isUsed) { return(true); } if (env.InteropManager.IsExported(assemblyDef, typeDef, methodDef)) { // Exported methods always used return(true); } return(false); }
private TypeMapping TypeMappingFor(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef) { var name = typeDef.QualifiedTypeName(env.Global, assemblyDef); var typeMapping = default(TypeMapping); if (!typeMappingCache.TryGetValue(name, out typeMapping)) { typeMapping = new TypeMapping(env, assemblyDef, typeDef); typeMappingCache.Add(name, typeMapping); } return(typeMapping); }
private AssemblyMapping AssemblyMappingFor(CST.AssemblyDef assemblyDef) { var name = assemblyDef.Name; var assemblyMapping = default(AssemblyMapping); if (!assemblyMappingCache.TryGetValue(name, out assemblyMapping)) { assemblyMapping = new AssemblyMapping(env, assemblyDef); assemblyMappingCache.Add(name, assemblyMapping); } return(assemblyMapping); }
private bool HasFullReflection(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef) { var level = default(ReflectionLevel); env.AttributeHelper.GetValueFromType (assemblyDef, typeDef, env.AttributeHelper.ReflectionAttributeRef, env.AttributeHelper.TheReflectionLevelProperty, true, true, ref level); return(level >= ReflectionLevel.Full); }
public bool CouldBeInlinableBasedOnHeaderAlone(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef) { if (methodDef.IsVirtualOrAbstract || typeDef.Style is CST.InterfaceTypeStyle) { // No virtuals or interface methods return(false); } if (typeDef.Style is CST.MultiDimArrayTypeStyle) { // Implemented by runtime return(false); } if (typeDef.IsAttributeType(env.Global, assemblyDef)) { // Don't inline attribute property methods since we invoke them directly when building attributes return(false); } var level = default(ReflectionLevel); env.AttributeHelper.GetValueFromType (assemblyDef, typeDef, env.AttributeHelper.ReflectionAttributeRef, env.AttributeHelper.TheReflectionLevelProperty, true, true, ref level); if (level >= ReflectionLevel.Full) { // No inlining in classes needing full reflection since need to support dynamic invokes return(false); } // NOTE: Method may be used in a delegate, in which case it's fine to inline but we'll still // need to emit the definition if (assemblyDef.EntryPoint != null && assemblyDef.EntryPoint.QualifiedMemberName.Equals (methodDef.QualifiedMemberName(env.Global, assemblyDef, typeDef))) { // Entry points are called directly by startup code return(false); } return(true); }
private static bool IsUpToDate(CompilerEnvironment env, CST.AssemblyDef assembly, bool complain) { var annot = assembly.Annotations.OfType <CST.AssemblyFileAnnotation>().FirstOrDefault(); if (annot == null) { throw new InvalidOperationException("assembly is missing file annotation"); } var fn = default(string); var lastCompTime = AssemblyCompiler.LastCompilationTime(env, assembly.Name, out fn); if (lastCompTime.HasValue) { if (annot.LastWriteTime <= lastCompTime.Value) { return(true); } else { if (complain) { env.Log (new OutOfDateAssemblyMessage(assembly.Name, annot.CanonicalFileName, fn)); } return(false); } } else { if (complain) { env.Log(new AssemblyNotCompiledMessage(assembly.Name, fn)); } return(false); } }
internal override void AccumUsedTypeAndMemberDefs(ValidityContext vctxt, AssemblyDef assemblyDef, TypeDef typeDef) { base.AccumUsedTypeAndMemberDefs(vctxt, assemblyDef, typeDef); var ctxt = MessageContextBuilders.Member(vctxt.Global, assemblyDef, typeDef, this); if (Get != null) { Invalid = Get.AccumUsedTypeDefs(vctxt, ctxt, usedTypes); if (Invalid != null) return; } if (Set != null) { Invalid = Set.AccumUsedTypeDefs(vctxt, ctxt, usedTypes); if (Invalid != null) return; } Invalid = FieldType.AccumUsedTypeDefs(vctxt, ctxt, usedTypes); }
internal void TopologicalAllDeps(Global global, AssemblyDef assemblyDef, TypeDef typeDef, Set<QualifiedMemberName> visitedMemberDefs, Seq<QualifiedMemberName> sortedMemberDefs) { var self = QualifiedMemberName(global, assemblyDef, typeDef); if (visitedMemberDefs.Contains(self)) return; visitedMemberDefs.Add(self); if (usedTypes == null) return; foreach (var r in usedTypes) { var usedAssemblyDef = default(AssemblyDef); var usedTypeDef = default(TypeDef); if (r.PrimTryResolve(global, out usedAssemblyDef, out usedTypeDef)) usedTypeDef.UsedBy(self); } foreach (var r in usedMembers) { var usedAssemblyDef = default(AssemblyDef); var usedTypeDef = default(TypeDef); var usedMemberDef = default(MemberDef); if (r.PrimTryResolve(global, out usedAssemblyDef, out usedTypeDef, out usedMemberDef)) { usedMemberDef.UsedBy(self); usedMemberDef.TopologicalAllDeps (global, usedAssemblyDef, usedTypeDef, visitedMemberDefs, sortedMemberDefs); } } sortedMemberDefs.Add(self); }
public bool IsInlinable(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef) { var s = MethodBodySize(methodDef.QualifiedMemberName(env.Global, assemblyDef, typeDef)); return(s >= 0 && s <= env.InlineThreshold); }
internal virtual void AccumUsedTypeAndMemberDefs(ValidityContext vctxt, AssemblyDef assemblyDef, TypeDef typeDef) { usedTypes = new Set<QualifiedTypeName>(); usedMembers = new Set<QualifiedMemberName>(); }
internal override void AccumUsedTypeAndMemberDefs(ValidityContext vctxt, AssemblyDef assemblyDef, TypeDef typeDef) { base.AccumUsedTypeAndMemberDefs(vctxt, assemblyDef, typeDef); var ctxt = MessageContextBuilders.Member(vctxt.Global, assemblyDef, typeDef, this); Invalid = FieldType.AccumUsedTypeDefs(vctxt, ctxt, usedTypes); }
public override void ImplementableMemberDef(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MemberDef memberDef) { var ctxt = CST.MessageContextBuilders.Member(env.Global, assemblyDef, typeDef, memberDef); var s = typeDef.Style; var methodDef = memberDef as CST.MethodDef; if (methodDef == null) { return; } if (s is CST.DelegateTypeStyle || s is CST.MultiDimArrayTypeStyle) { // SPECIAL CASE: Magic delegate and multi-dimensional array methods are // implemented by runtime return; } if (env.AttributeHelper.MethodHasAttribute (assemblyDef, typeDef, methodDef, env.AttributeHelper.IgnoreAttributeRef, true, true)) { Log(new CST.InvalidMemberDef(ctxt, "Method is marked as '[Ignore]'")); methodDef.Invalid = new CST.InvalidInfo("Ignored"); } try { if (!(s is CST.InterfaceTypeStyle) && methodDef.MethodStyle != CST.MethodStyle.Abstract && !env.InteropManager.IsImported(assemblyDef, typeDef, methodDef)) { switch (methodDef.CodeFlavor) { case CST.MethodCodeFlavor.Managed: { var instructions = methodDef.Instructions(Global); if (instructions == null || instructions.Body.Count == 0) { Log(new CST.InvalidMemberDef(ctxt, "Method has no body")); methodDef.Invalid = new CST.InvalidInfo("Unimplementable"); } break; } case CST.MethodCodeFlavor.ManagedExtern: Log(new CST.InvalidMemberDef(ctxt, "Method is marked as extern but has no import")); methodDef.Invalid = new CST.InvalidInfo("Unimplementable"); break; case CST.MethodCodeFlavor.Native: Log(new CST.InvalidMemberDef(ctxt, "Method invokes native code")); methodDef.Invalid = new CST.InvalidInfo("Unimplementable"); break; case CST.MethodCodeFlavor.Runtime: Log(new CST.InvalidMemberDef(ctxt, "Method is part of the CLR runtime")); methodDef.Invalid = new CST.InvalidInfo("Unimplementable"); break; case CST.MethodCodeFlavor.ForwardRef: Log(new CST.InvalidMemberDef(ctxt, "Method is a forward reference")); methodDef.Invalid = new CST.InvalidInfo("Unimplementable"); break; default: throw new ArgumentOutOfRangeException(); } } // else: no body to check } catch (DefinitionException) { Log(new CST.InvalidMemberDef(ctxt, "Method contains an interop error")); methodDef.Invalid = new CST.InvalidInfo("Unimplementable"); } }
public abstract bool PropogateExtraUsedFromType(AssemblyDef assemblyDef, TypeDef typeDef);
public MethodRef PrimMethodReference(Global global, AssemblyDef assemblyDef, TypeDef typeDef, IImSeq<TypeRef> typeBoundArguments, IImSeq<TypeRef> methodBoundArguments) { return new MethodRef (typeDef.PrimReference(global, assemblyDef, typeBoundArguments), Name, IsStatic, methodBoundArguments, ValueParameters.Select(p => p.Type).ToSeq(), Result == null ? null : Result.Type); }
public abstract bool EventAlwaysUsed(AssemblyDef assemblyDef, TypeDef typeDef, EventDef eventDef);
public abstract bool IncludeAttributes(AssemblyDef assemblyDef, TypeDef typeDef);
public abstract bool PropertyAlwaysUsed(AssemblyDef assemblyDef, TypeDef typeDef, PropertyDef propDef);
public abstract bool FieldAlwaysUsed(AssemblyDef assemblyDef, TypeDef typeDef, FieldDef fieldDef);
public abstract bool MethodAlwaysUsed(AssemblyDef assemblyDef, TypeDef typeDef, MethodDef methodDef);
internal void PropogateInvalidity(Global global, AssemblyDef assemblyDef, TypeDef typeDef) { if (Invalid == null) return; if (usedByMembers != null) { var self = PrimReference(global, assemblyDef, typeDef, null); foreach (var r in usedByMembers) { var usedByAssemblyDef = default(AssemblyDef); var usedByTypeDef = default(TypeDef); var usedByMemberDef = default(MemberDef); if (r.PrimTryResolve(global, out usedByAssemblyDef, out usedByTypeDef, out usedByMemberDef)) { if (usedByMemberDef.Invalid == null) usedByMemberDef.Invalid = new InvalidInfo(MessageContextBuilders.Member(global, self), Invalid); } } } }
public abstract bool PropogateExtraUsedFromMember(AssemblyDef assemblyDef, TypeDef typeDef, MemberDef memberDef);
internal virtual void TopologicalTypeInitFromImplementors(Global global, AssemblyDef assemblyDef, TypeDef typeDef, Set<QualifiedTypeName> visitedTypeDefs, Seq<QualifiedTypeName> sortedTypeDefs, Set<QualifiedMemberName> visitedMemberDefs) { }
public abstract bool IgnoreMethodDefBody(AssemblyDef assemblyDef, TypeDef typeDef, MethodDef methodDef);
internal override void TopologicalTypeInitFromImplementors(Global global, AssemblyDef assemblyDef, TypeDef typeDef, Set<QualifiedTypeName> visitedTypeDefs, Seq<QualifiedTypeName> sortedTypeDefs, Set<QualifiedMemberName> visitedMemberDefs) { if (implementors != null) { foreach (var r in implementors) { var usedAssemblyDef = default(AssemblyDef); var usedTypeDef = default(TypeDef); var usedMemberDef = default(MemberDef); if (r.PrimTryResolve(global, out usedAssemblyDef, out usedTypeDef, out usedMemberDef)) usedMemberDef.TopologicalTypeInit (global, usedAssemblyDef, usedTypeDef, visitedTypeDefs, sortedTypeDefs, visitedMemberDefs); } } }
public abstract void ImplementableMemberDef(AssemblyDef assemblyDef, TypeDef typeDef, MemberDef memberDef);
public override MemberRef PrimReference(Global global, AssemblyDef assemblyDef, TypeDef typeDef, IImSeq<TypeRef> typeBoundArguments) { return new EventRef(typeDef.PrimReference(global, assemblyDef, typeBoundArguments), Name); }
public abstract InvalidInfo ImplementableInstruction(MessageContext ctxt, AssemblyDef assemblyDef, TypeDef typeDef, MethodDef methodDef, Instruction instruction);
public string ResolveTypeDefToSlot(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef) { return(AssemblyMappingFor(assemblyDef).ResolveTypeDefinitionToSlot(typeDef.EffectiveName(env.Global))); }
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; }
// See also: InteropManager::IsInlinable private bool PrimIsInlinable(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef) { if (!CouldBeInlinableBasedOnHeaderAlone(assemblyDef, typeDef, methodDef)) { return(false); } if (methodDef.IsRecursive) { // No recursive methods return(false); } if (methodDef.IsConstructor) { // No instance constructors (since we can't enline NewExpressions yet), and // no static constructors (since we can't inline calls emitted in assembly Initialize) return(false); } if (env.InteropManager.IsImported(assemblyDef, typeDef, methodDef) || env.InteropManager.IsExported(assemblyDef, typeDef, methodDef)) { // No imported methods (we inline separately), and // no exported methods (we need the definition around to be able to export it) return(false); } if (methodDef.MethodBody == null || methodDef.MethodBody.Instructions.Length == 0) { // No empty methods or imported methods return(false); } var numReturns = 0; var instructions = methodDef.Instructions(env.Global); if (!instructions.IsInlinable(ref numReturns) || numReturns != 1) { // Non-inlinable instructions return(false); } var code = instructions.Body[instructions.Body.Count - 1].Code; if (code != CST.InstructionCode.Ret && code != CST.InstructionCode.RetVal) { // Last instruction is not return return(false); } // NOTE: Even though instructions have a single return, it is still possible the translated statatements // won't have a unique result, so unfortunately we need to check that below var isInline = default(bool); var overrideInline = env.AttributeHelper.GetValueFromMethod (assemblyDef, typeDef, methodDef, env.AttributeHelper.InlineAttributeRef, env.AttributeHelper.TheIsInlinedProperty, true, false, ref isInline); if (overrideInline && !isInline) { // User has supressed inlining return(false); } if (!overrideInline && instructions.Size > env.InlineThreshold) { // Method too large return(false); } var methEnv = env.Global.Environment().AddAssembly(assemblyDef).AddType(typeDef).AddSelfTypeBoundArguments(). AddMethod(methodDef).AddSelfMethodBoundArguments(); var cstmethod = CST.CSTMethod.Translate(methEnv, new JST.NameSupply(), null); var body = new Seq <CST.Statement>(); var retres = cstmethod.Body.ToReturnResult(body); if (retres.Status != CST.ReturnStatus.One) { // More than one return return(false); } return(true); }
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 override MemberRef PrimReference(Global global, AssemblyDef assemblyDef, TypeDef typeDef, IImSeq<TypeRef> typeBoundArguments) { var sig = PropertySignature; return new PropertyRef (typeDef.PrimReference(global, assemblyDef, typeBoundArguments), sig.Name, sig.IsStatic, sig.Parameters, sig.Result); }
public override bool IgnoreMethodDefBody(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef) { return(env.AttributeHelper.MethodHasAttribute(assemblyDef, typeDef, methodDef, env.AttributeHelper.InteropGeneratedAttributeRef, false, false)); }
internal bool MarkAsUsed(ValidityContext vctxt, AssemblyDef assemblyDef, TypeDef typeDef) { if (IsUsed || Invalid != null || typeDef.Invalid != null) return false; IsUsed = true; typeDef.MarkAsUsed(vctxt, assemblyDef); if (typeDef.Invalid != null) return true; if (usedTypes == null) { AccumUsedTypeAndMemberDefs(vctxt, assemblyDef, typeDef); if (Invalid != null) return true; } foreach (var r in UsedTypes) { var usedAssemblyDef = default(AssemblyDef); var usedTypeDef = default(TypeDef); if (r.PrimTryResolve(vctxt.Global, out usedAssemblyDef, out usedTypeDef)) usedTypeDef.MarkAsUsed(vctxt, usedAssemblyDef); } foreach (var r in UsedMembers) { var usedAssemblyDef = default(AssemblyDef); var usedTypeDef = default(TypeDef); var usedMemberDef = default(MemberDef); if (r.PrimTryResolve(vctxt.Global, out usedAssemblyDef, out usedTypeDef, out usedMemberDef)) usedMemberDef.MarkAsUsed(vctxt, usedAssemblyDef, usedTypeDef); } return true; }
public override bool IncludeAttributes(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef) { return(HasFullReflection(assemblyDef, typeDef)); }
internal void UsedByMembersClosure(Global global, AssemblyDef assemblyDef, TypeDef typeDef, Set<QualifiedMemberName> visitedMemberDefs, Seq<QualifiedMemberName> scc) { if (usedByMembers == null) return; var self = QualifiedMemberName(global, assemblyDef, typeDef); if (!visitedMemberDefs.Contains(self)) { visitedMemberDefs.Add(self); scc.Add(self); foreach (var r in usedByMembers) { var usedByAssemblyDef = default(AssemblyDef); var usedByTypeDef = default(TypeDef); var usedByMemberDef = default(MemberDef); if (r.PrimTryResolve(global, out usedByAssemblyDef, out usedByTypeDef, out usedByMemberDef)) usedByMemberDef.UsedByMembersClosure (global, usedByAssemblyDef, usedByTypeDef, visitedMemberDefs, scc); } } }
// NOTE: May be called on invalid definitions public override bool IsAlternateEntryPoint(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef) { return(env.AttributeHelper.MethodHasAttribute (assemblyDef, typeDef, methodDef, env.AttributeHelper.EntryPointAttributeRef, false, false)); }
internal void TopologicalTypeInit(Global global, AssemblyDef assemblyDef, TypeDef typeDef, Set<QualifiedTypeName> visitedTypeDefs, Seq<QualifiedTypeName> sortedTypeDefs, Set<QualifiedMemberName> visitedMemberDefs) { var self = QualifiedMemberName(global, assemblyDef, typeDef); if (visitedMemberDefs.Contains(self)) return; visitedMemberDefs.Add(self); if (!IsUsed || Invalid != null || typeDef.Invalid != null) return; if (usedMembers != null) { foreach (var r in usedMembers) { var usedAssemblyDef = default(AssemblyDef); var usedTypeDef = default(TypeDef); var usedMemberDef = default(MemberDef); if (r.PrimTryResolve(global, out usedAssemblyDef, out usedTypeDef, out usedMemberDef)) usedMemberDef.TopologicalTypeInit (global, usedAssemblyDef, usedTypeDef, visitedTypeDefs, sortedTypeDefs, visitedMemberDefs); } } TopologicalTypeInitFromImplementors (global, assemblyDef, typeDef, visitedTypeDefs, sortedTypeDefs, visitedMemberDefs); if (usedTypes != null) { foreach (var r in usedTypes) { var usedAssemblyDef = default(AssemblyDef); var usedTypeDef = default(TypeDef); if (r.PrimTryResolve(global, out usedAssemblyDef, out usedTypeDef)) usedTypeDef.TopologicalTypeInit(global, usedAssemblyDef, visitedTypeDefs, sortedTypeDefs); } } }
public void AddAssembly(MessageContext ctxt, CST.AssemblyDef assemblyDef) { var assemblyTrace = ResolveAssemblyTrace(assemblyDef); assemblyTrace.AddAssembly(ctxt); }
public override MemberRef PrimReference(Global global, AssemblyDef assemblyDef, TypeDef typeDef, IImSeq<TypeRef> typeBoundArguments) { return new PolymorphicMethodRef (typeDef.PrimReference(global, assemblyDef, typeBoundArguments), Name, IsStatic, TypeArity, ValueParameters.Select(p => p.Type).ToSeq(), Result == null ? null : Result.Type); }
public void AddType(MessageContext ctxt, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef) { var assemblyTrace = ResolveAssemblyTrace(assemblyDef);; assemblyTrace.AddType(ctxt, typeDef); }
internal override void AccumUsedTypeAndMemberDefs(ValidityContext vctxt, AssemblyDef assemblyDef, TypeDef typeDef) { base.AccumUsedTypeAndMemberDefs(vctxt, assemblyDef, typeDef); var ctxt = MessageContextBuilders.Member(vctxt.Global, assemblyDef, typeDef, this); for (var i = 0; i < TypeParameters.Count; i++) { var p = TypeParameters[i]; p.AccumUsedTypeDefs(vctxt, assemblyDef, false); if (p.Invalid != null) { Invalid = new InvalidInfo(MessageContextBuilders.TypeArg(ParameterFlavor.Method, i), p.Invalid); return; } } foreach (var p in ValueParameters) { Invalid = p.Type.AccumUsedTypeDefs(vctxt, ctxt, usedTypes); if (Invalid != null) return; } if (Result != null) { Invalid = Result.Type.AccumUsedTypeDefs(vctxt, ctxt, usedTypes); if (Invalid != null) return; } if (vctxt.IgnoreMethodDefBody(assemblyDef, typeDef, this)) return; foreach (var l in Locals) { Invalid = l.Type.AccumUsedTypeDefs(vctxt, ctxt, usedTypes); if (Invalid != null) return; } var instructions = Instructions(vctxt.Global); if (instructions != null) { foreach (var i in instructions.Body) { Invalid = i.AccumUsedTypeAndMemberDefs(vctxt, ctxt, usedTypes, usedMembers); if (Invalid != null) return; } } }
public void AddMethod(MessageContext ctxt, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef) { var assemblyTrace = ResolveAssemblyTrace(assemblyDef); assemblyTrace.AddMethod(ctxt, typeDef, methodDef); }
public QualifiedMemberName QualifiedMemberName(Global global, AssemblyDef assemblyDef, TypeDef typeDef) { return new QualifiedMemberName(typeDef.QualifiedTypeName(global, assemblyDef), Signature); }
public string ResolveFieldDefToSlot(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.FieldDef fieldDef) { return(TypeMappingFor(assemblyDef, typeDef).ResolveFieldToSlot (fieldDef.QualifiedMemberName(env.Global, assemblyDef, typeDef))); }
// // References and environments // public abstract MemberRef PrimReference(Global global, AssemblyDef assemblyDef, TypeDef typeDef, IImSeq<TypeRef> typeBoundArguments);
public string ResolveAssemblyReferenceToSlot(CST.AssemblyDef assemblyDef, CST.AssemblyName assemblyName) { return(AssemblyMappingFor(assemblyDef).ResolveAssemblyReferenceToSlot(assemblyName)); }
internal override void AccumUsedTypeAndMemberDefs(ValidityContext vctxt, AssemblyDef assemblyDef, TypeDef typeDef) { base.AccumUsedTypeAndMemberDefs(vctxt, assemblyDef, typeDef); var ctxt = MessageContextBuilders.Member(vctxt.Global, assemblyDef, typeDef, this); if (Add != null) { Invalid = Add.AccumUsedTypeDefs(vctxt, ctxt, usedTypes); if (Invalid != null) return; } if (Remove != null) { Invalid = Remove.AccumUsedTypeDefs(vctxt, ctxt, usedTypes); if (Invalid != null) return; } Invalid = HandlerType.AccumUsedTypeDefs(vctxt, ctxt, usedTypes); }
public override CST.InvalidInfo ImplementableInstruction(MessageContext ctxt, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef, CST.Instruction instruction) { switch (instruction.Flavor) { case CST.InstructionFlavor.Try: { var tryi = (CST.TryInstruction)instruction; if (tryi.Handlers.Any(h => h.Flavor == CST.HandlerFlavor.Filter)) { Log (new CST.InvalidInstruction (ctxt, instruction, "Exception filter blocks are not supported")); return(new CST.InvalidInfo(CST.MessageContextBuilders.Instruction(Global, instruction))); } break; } default: break; } return(null); }