CreateCLRProperty( SymbolEngine.PropertyExpEntry symProperty ) { string stName = symProperty.Name; // Get class that we're defined in TypeBuilder bldClass = symProperty.SymbolClass.CLRType as TypeBuilder; Debug.Assert(bldClass != null); PropertyAttributes attrs = PropertyAttributes.None; // Create the property builder PropertyBuilder bld = bldClass.DefineProperty( stName, attrs, symProperty.PropertyType.CLRType, new Type[0] ); // Create builders for the get / set accessors if (symProperty.SymbolGet != null) { symProperty.SymbolGet.SetInfo(this); bld.SetGetMethod(symProperty.SymbolGet.Info as MethodBuilder); } if (symProperty.SymbolSet != null) { symProperty.SymbolSet.SetInfo(this); bld.SetSetMethod(symProperty.SymbolSet.Info as MethodBuilder); } return bld; }
CreateCLRMethod( SymbolEngine.MethodExpEntry symBlueMethod ) { // Call DefineMethod on the TypeBuilder to get a MethodBuilder // MethodBuilder derives from MethodInfo string stMethodName = symBlueMethod.Name; Debug.Assert(symBlueMethod.Node != null); AST.Modifiers mods = symBlueMethod.Node.Mods; MethodAttributes attrMethod = (MethodAttributes) 0; // Everything seems to have this; but what does it do? attrMethod = MethodAttributes.HideBySig; if (mods.IsPublic) attrMethod |= MethodAttributes.Public; else if (mods.IsProtected) attrMethod |= MethodAttributes.Family; else if (mods.IsPrivate) attrMethod |= MethodAttributes.Private; else if (mods.IsInternal) attrMethod |= MethodAttributes.Assembly; if (symBlueMethod.IsSpecialName) attrMethod |= MethodAttributes.SpecialName; if (mods.IsStatic) { attrMethod |= MethodAttributes.Static; } if (mods.IsVirtual) attrMethod |= MethodAttributes.Virtual | MethodAttributes.NewSlot; if (mods.IsAbstract) attrMethod |= MethodAttributes.Abstract | MethodAttributes.Virtual | MethodAttributes.NewSlot; if (mods.IsOverride) { attrMethod |= MethodAttributes.Virtual; } if (mods.IsSealed) attrMethod |= MethodAttributes.Final; // Overloaded operators have a magical bit sit if (symBlueMethod.Node.IsOpOverload) attrMethod |= MethodAttributes.SpecialName; // Get signature from the parameters #if false Type [] alParamTypes = new Type[symBlueMethod.ParamCount]; for(int iParam = 0; iParam < symBlueMethod.ParamCount; iParam++) { alParamTypes[iParam] = symBlueMethod.ParamCLRType(iParam); } #else Type [] alParamTypes = symBlueMethod.ParamTypes(false); #endif // Get class that we're defined in TypeBuilder bldClass = symBlueMethod.SymbolClass.CLRType as TypeBuilder; Debug.Assert(bldClass != null); bool fIsCtor = symBlueMethod.IsCtor; System.Reflection.MethodBase bld = null; // Get the builder if (fIsCtor) { ConstructorBuilder bldCtor = bldClass.DefineConstructor(attrMethod, CallingConventions.Standard, alParamTypes); if (AST.DelegateDecl.IsDelegate(symBlueMethod.SymbolClass.CLRType)) { bldCtor.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); } //return bldCtor; bld = bldCtor; } else { Type typeReturn = symBlueMethod.RetType.CLRType; Debug.Assert(typeReturn != null, "Semantic check should catch null return type"); MethodBuilder bldMethod = bldClass.DefineMethod(stMethodName, attrMethod, typeReturn, alParamTypes); // The members of a delegate are special because they're implemented by the runtime. if (AST.DelegateDecl.IsDelegate(symBlueMethod.SymbolClass.CLRType)) { bldMethod.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); } //return bldMethod; bld = bldMethod; } // Double check that we set the attributes on the new CLR method properly. // Do this by converting back to blue modifier from CLR method and comparing // that modifier to the original. #if DEBUG AST.Modifiers modsCheck = new AST.Modifiers(bld); string stPretty = symBlueMethod.PrettyDecoratedName; string stBlue = mods.ToString(); string stCLR = modsCheck.ToString(); // The 'new' modifier just tells the C# compiler to suppress warnings. There's // no IL bit for it, so we lose it when we roundtrip. So just add it to both // of them. mods.SetNew(); modsCheck.SetNew(); Debug.Assert(modsCheck == mods, "Modifer mismatch in creating CLR method"); #endif return bld; }
CreateCLRClass( SymbolEngine.TypeEntry symBlueType ) { // We call DefineType to get a TypeBuilder, which derives from Type // We have to pass DefineType all the interesting parameters (ie, we // have to know stuff like the base class now, not later) // We get namespaces for free by using the full name // We also handle nested classes here. string stClassName = symBlueType.FullName; System.Type typeBaseClass = null; TypeAttributes attrClass = (TypeAttributes) 0; SymbolEngine.TypeEntry [] arBlueInterfaces = symBlueType.BaseInterfaces; System.Type [] arClrInterfaces = new System.Type[arBlueInterfaces.Length]; for(int i =0; i < arClrInterfaces.Length; i++) { arClrInterfaces[i] = arBlueInterfaces[i].CLRType; Debug.Assert(arClrInterfaces[i] != null); } // Setup modifiers AST.Modifiers mods = symBlueType.Mods; TypeBuilder bldClass; if (symBlueType.IsInterface) attrClass |= TypeAttributes.Interface | TypeAttributes.Abstract; else { typeBaseClass = symBlueType.Super.CLRType; Debug.Assert(typeBaseClass != null); } if (mods.IsSealed) attrClass |= TypeAttributes.Sealed; if (mods.IsAbstract) attrClass |= TypeAttributes.Abstract; if (mods.IsSealed) attrClass |= TypeAttributes.Sealed; // Handle nesting SymbolEngine.TypeEntry tParent = symBlueType.GetContainingType(); if (tParent == null) { // Not nested if (mods.IsPublic) attrClass |= TypeAttributes.Public; else attrClass |= TypeAttributes.NotPublic; Log.WriteLine(Log.LF.CodeGen, "Define type:{0}", stClassName); bldClass = m_bldModule.DefineType( stClassName, attrClass, typeBaseClass, arClrInterfaces ); } else { // Nested if (mods.IsPublic) attrClass |= TypeAttributes.NestedPublic; else if (mods.IsPrivate) attrClass |= TypeAttributes.NestedPrivate; else if (mods.IsProtected) attrClass |= TypeAttributes.NestedFamily; else if (mods.IsInternal) attrClass |= TypeAttributes.NestedAssembly; Log.WriteLine(Log.LF.CodeGen, "Define nested type:{0}", stClassName); TypeBuilder bldParent = tParent.CLRType as TypeBuilder; bldClass = bldParent.DefineNestedType(symBlueType.Name, attrClass, typeBaseClass, arClrInterfaces); } Debug.Assert(bldClass != null, "Should have TypeBuilder by now"); // Make sure that we can lookup the type that we just created #if DEBUG System.Type tNatural = this.FindType(stClassName); Debug.Assert(tNatural == bldClass); #endif // Sanity check that the type builder is complete enough to do // clr inheritence checks #if DEBUG if (typeBaseClass != null) Debug.Assert(bldClass.IsSubclassOf(typeBaseClass)); foreach(System.Type t in arClrInterfaces) { bool f1 = SymbolEngine.TypeEntry.IsAssignable(bldClass, t); Debug.Assert(f1); } #endif // Return the type and the symbol engine will set it return bldClass; }
CreateCLREvent( SymbolEngine.EventExpEntry symEvent ) { string stName = symEvent.Name; // Get class that we're defined in TypeBuilder bldClass = symEvent.SymbolClass.CLRType as TypeBuilder; Debug.Assert(bldClass != null); EventAttributes attrs = EventAttributes.None; AST.Modifiers mods = symEvent.Node.Mods; EventBuilder bld = bldClass.DefineEvent( stName, attrs, symEvent.EventType.CLRType ); Debug.Assert(bld != null); return null; }
CreateCLRLiteralField( SymbolEngine.LiteralFieldExpEntry sym) { Type t = sym.SymbolClass.CLRType; #if Bug_In_EnumBuilder TypeBuilder bld = t as TypeBuilder; Debug.Assert(bld != null); FieldAttributes mods = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal; FieldBuilder f = bld.DefineField(sym.Name, bld, mods); f.SetConstant(sym.Data); #else if (t is EnumBuilder) { EnumBuilder bld = t as EnumBuilder; f = bld.DefineLiteral(sym.Name, sym.Data); } else if (t is TypeBuilder) { Debug.Assert(false, "Literals not supported on non-enum Types"); } #endif // The new field should have the following properties: Debug.Assert(f.IsStatic); Debug.Assert(f.IsPublic); Debug.Assert(f.IsLiteral); Debug.Assert(f.FieldType == bld); // this is where the EnumBuilder breaks return f; }
/***************************************************************************\ * * EmitCodeGen.CreateCLREnumType * \***************************************************************************/ public virtual System.Type CreateCLREnumType(SymbolEngine.EnumTypeEntry symEnum) { TypeAttributes mods = TypeAttributes.Sealed; #if Bug_In_EnumBuilder string stName = symEnum.FullName; TypeBuilder bld; // Handle nesting SymbolEngine.TypeEntry tParent = symEnum.GetContainingType(); if (tParent == null) { if (symEnum.Mods.IsPublic) mods |= TypeAttributes.Public; else mods |= TypeAttributes.NotPublic; Log.WriteLine(Log.LF.CodeGen, "Define enum:{0}", stName); bld = m_bldModule.DefineType(stName, mods, typeof(System.Enum)); } else { if (symEnum.Mods.IsPublic) mods |= TypeAttributes.NestedPublic; else if (symEnum.Mods.IsPrivate) mods |= TypeAttributes.NestedPrivate; else if (symEnum.Mods.IsProtected) mods |= TypeAttributes.NestedFamily; else if (symEnum.Mods.IsInternal) mods |= TypeAttributes.NestedAssembly; Log.WriteLine(Log.LF.CodeGen, "Define nested enum:{0}", stName); TypeBuilder bldParent = tParent.CLRType as TypeBuilder; bld = bldParent.DefineNestedType(symEnum.Name, mods, typeof(System.Enum)); // DefineNestedType says it wants the 'full name', but name Name can't inclue [,],\,+ // So we're in a pickle. And then when the TypeResolve event is fired, we don't // get enough info (we just get the short name). //string stName2 = symEnum.FullName.Replace('+', '\\'); //bld = bldParent.DefineNestedType(stName2, mods, typeof(System.Enum)); } // Enums have a default magical field: bld.DefineField("value__", typeof(int), FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName); #else #error - need a DefineNestedEnum() EnumBuilder bld = m_bldModule.DefineEnum(stName, mods, typeof(int)); #endif return bld; }
CreateCLRArrayType( SymbolEngine.ArrayTypeEntry symBlueType ) { // Get name of an array, like T[], T[,,][,][] string st = symBlueType.ToString(); System.Type t = this.FindType(st); // Semantic checking should have caught this. Debug.Assert(t != null); return t; }
CreateCLRField( SymbolEngine.FieldExpEntry symBlueField ) { FieldAttributes attr = (FieldAttributes) 0; AST.Modifiers mods = symBlueField.Node.Mods; if (mods.IsPublic) attr |= FieldAttributes.Public; else if (mods.IsProtected) attr |= FieldAttributes.Family; else if (mods.IsPrivate) attr |= FieldAttributes.Private; else if (mods.IsInternal) attr |= FieldAttributes.Assembly; if (mods.IsReadOnly) attr |= FieldAttributes.InitOnly; if (mods.IsStatic) attr |= FieldAttributes.Static; // Get class that we're defined in TypeBuilder bldClass = symBlueField.SymbolClass.CLRType as TypeBuilder; Debug.Assert(bldClass != null); // Create the field FieldInfo f = bldClass.DefineField(symBlueField.Name, symBlueField.FieldType.CLRType, attr); Debug.Assert(f != null); return f; }
// Emit a call/callvirt to the specified symbol void EmitCall(SymbolEngine.MethodExpEntry sym) { Debug.Assert(sym != null); MethodInfo mdInfo = sym.Info as MethodInfo; Debug.Assert(mdInfo != null); if (mdInfo.IsVirtual && !sym.SymbolClass.CLRType.IsValueType) { m_ilGenerator.Emit(OpCodes.Callvirt, mdInfo); } else { m_ilGenerator.Emit(OpCodes.Call, mdInfo); } }
void EmitNonPolymorphicCall(SymbolEngine.MethodExpEntry sym) { Debug.Assert(sym != null); MethodInfo mdInfo = sym.Info as MethodInfo; Debug.Assert(mdInfo != null); m_ilGenerator.Emit(OpCodes.Call, mdInfo); }
public NamespaceExp( SymbolEngine.NamespaceEntry symbol ) { m_symbol = symbol; }
public ParamExp( SymbolEngine.ParamVarExpEntry symbol ) { m_symbol = symbol; }
public LocalExp( SymbolEngine.LocalVarExpEntry symbol ) { m_symbol = symbol; }