public override void RewriteChildren(NestedUnitNamespace unitNamespace) { if (!this.once) { List <INamespaceTypeDefinition> genericTypes = new List <INamespaceTypeDefinition>(); int count = 0; for (int i = 0, n = unitNamespace.Members.Count; i < n; i++) { INamespaceTypeDefinition typ = unitNamespace.Members[i] as INamespaceTypeDefinition; if (typ != null && typ.IsGeneric && !typ.Name.Value.Contains("<<>>")) { this.once = true; if (count == this.number) { genericTypes.Add(typ); break; } count++; } } if (genericTypes.Count > 0) { foreach (var t in this.WithMoreGenericParameters(genericTypes)) { unitNamespace.Members.Add(t); } } } base.RewriteChildren(unitNamespace); }
/// <summary> /// Creates a nested namespace (because only the root namespace is not nested /// and that is created when the assembly is created). /// Adds it to the namespace cache. /// </summary> /// <param name="namespaceSymbol"></param> /// <returns></returns> private NestedUnitNamespace CreateNamespaceDefinition(INamespaceSymbol namespaceSymbol) { var ns = new NestedUnitNamespace() { ContainingUnitNamespace = (IUnitNamespace)this.namespaceSymbolCache[namespaceSymbol.ContainingNamespace], Locations = Helper.WrapLocations(namespaceSymbol.Locations), Name = this.host.NameTable.GetNameFor(namespaceSymbol.Name), //Unit = (IUnit)this.assemblySymbolCache[namespaceSymbol.ContainingAssembly], }; this.namespaceSymbolCache.Add(namespaceSymbol, ns); return(ns); }
private NamespaceTypeDefinition CreateContractClass(UnitNamespace unitNamespace) { var contractTypeName = this.host.NameTable.GetNameFor("Contract"); var contractNamespaceName = this.host.NameTable.GetNameFor("System.Diagnostics.Contracts"); Microsoft.Cci.MethodReference compilerGeneratedCtor = new Microsoft.Cci.MethodReference( this.host, this.compilerGeneratedAttributeType, CallingConvention.HasThis, this.systemVoidType, this.host.NameTable.Ctor, 0); CustomAttribute compilerGeneratedAttribute = new CustomAttribute(); compilerGeneratedAttribute.Constructor = compilerGeneratedCtor; var contractsNs = new NestedUnitNamespace() { ContainingUnitNamespace = unitNamespace, Name = contractNamespaceName, }; NamespaceTypeDefinition result = new NamespaceTypeDefinition() { // NB: The string name must be kept in sync with the code that recognizes contract // methods!! Name = contractTypeName, Attributes = new List <ICustomAttribute> { compilerGeneratedAttribute }, BaseClasses = new List <ITypeReference> { this.systemObjectType }, ContainingUnitNamespace = contractsNs, InternFactory = this.host.InternFactory, IsBeforeFieldInit = true, IsClass = true, IsSealed = true, Layout = LayoutKind.Auto, StringFormat = StringFormatKind.Ansi, }; return(result); }
private void MergeNamespaces(UnitNamespace result, IUnitNamespace namespaceToMerge) { Contract.Requires(result != null); Contract.Requires(namespaceToMerge != null); foreach (var member in namespaceToMerge.Members) { var nestedNs = member as NestedUnitNamespace; if (nestedNs != null) { UnitNamespace nestedResult = null; foreach (var rmember in result.Members) { Contract.Assume(rmember != null); if (rmember.Name != nestedNs.Name) { continue; } nestedResult = rmember as UnitNamespace; if (nestedResult != null) { break; } } if (nestedResult == null) { nestedResult = new NestedUnitNamespace() { ContainingUnitNamespace = result, Name = nestedNs.Name } } ; this.MergeNamespaces(nestedResult, nestedNs); continue; } result.Members.Add(member); } }
private NamespaceTypeDefinition CreateContractReferenceAssemblyAttribute(IRootUnitNamespace rootNs) { var internFactory = this.host.InternFactory; var nameTable = this.host.NameTable; var contractReferenceAssemblyAttributeName = nameTable.GetNameFor("ContractReferenceAssemblyAttribute"); var contractNamespaceName = nameTable.GetNameFor("System.Diagnostics.Contracts"); #region Define type CustomAttribute compilerGeneratedAttribute = new CustomAttribute() { Constructor = new Microsoft.Cci.MethodReference( this.host, this.compilerGeneratedAttributeType, CallingConvention.HasThis, this.systemVoidType, this.host.NameTable.Ctor, 0) }; var contractsNs = new NestedUnitNamespace() { ContainingUnitNamespace = rootNs, Name = contractNamespaceName, }; NamespaceTypeDefinition result = new NamespaceTypeDefinition() { Name = contractReferenceAssemblyAttributeName, Attributes = new List<ICustomAttribute>{ compilerGeneratedAttribute }, BaseClasses = new List<ITypeReference>{ this.systemAttributeType }, ContainingUnitNamespace = contractsNs, //unitNamespace, InternFactory = internFactory, IsBeforeFieldInit = true, IsClass = true, IsSealed = true, Methods = new List<IMethodDefinition>(), Layout = LayoutKind.Auto, StringFormat = StringFormatKind.Ansi, }; contractsNs.Members.Add(result); this.allTypes.Add(result); #endregion Define type #region Define the ctor List<IStatement> statements = new List<IStatement>(); SourceMethodBody body = new SourceMethodBody(this.host) { LocalsAreZeroed = true, Block = new BlockStatement() { Statements = statements }, }; MethodDefinition ctor = new MethodDefinition() { Body = body, CallingConvention = CallingConvention.HasThis, ContainingTypeDefinition = result, InternFactory = internFactory, IsRuntimeSpecial = true, IsStatic = false, IsSpecialName = true, Name = nameTable.Ctor, Type = this.systemVoidType, Visibility = TypeMemberVisibility.Public, }; body.MethodDefinition = ctor; var thisRef = new ThisReference() { Type = result, }; // base(); foreach (var baseClass in result.BaseClasses) { var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = baseClass, GenericParameterCount = 0, InternFactory = this.host.InternFactory, Name = nameTable.Ctor, Type = this.systemVoidType, }; statements.Add( new ExpressionStatement() { Expression = new MethodCall() { MethodToCall = baseCtor, IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument? ThisArgument = new ThisReference() { Type = result, }, Type = this.systemVoidType, // REVIEW: Is this the right way to do this? Arguments = new List<IExpression>(), } } ); break; } // return; statements.Add(new ReturnStatement()); result.Methods.Add(ctor); #endregion Define the ctor return result; }
private NamespaceTypeDefinition CreateContractClass(UnitNamespace unitNamespace) { var contractTypeName = this.host.NameTable.GetNameFor("Contract"); var contractNamespaceName = this.host.NameTable.GetNameFor("System.Diagnostics.Contracts"); Microsoft.Cci.MethodReference compilerGeneratedCtor = new Microsoft.Cci.MethodReference( this.host, this.compilerGeneratedAttributeType, CallingConvention.HasThis, this.systemVoidType, this.host.NameTable.Ctor, 0); CustomAttribute compilerGeneratedAttribute = new CustomAttribute(); compilerGeneratedAttribute.Constructor = compilerGeneratedCtor; var contractsNs = new NestedUnitNamespace() { ContainingUnitNamespace = unitNamespace, Name = contractNamespaceName, }; NamespaceTypeDefinition result = new NamespaceTypeDefinition() { // NB: The string name must be kept in sync with the code that recognizes contract // methods!! Name = contractTypeName, Attributes = new List<ICustomAttribute>{ compilerGeneratedAttribute }, BaseClasses = new List<ITypeReference>{ this.systemObjectType }, ContainingUnitNamespace = contractsNs, InternFactory = this.host.InternFactory, IsBeforeFieldInit = true, IsClass = true, IsSealed = true, Layout = LayoutKind.Auto, StringFormat = StringFormatKind.Ansi, }; return result; }
private NamespaceTypeDefinition CreateContractReferenceAssemblyAttribute(IRootUnitNamespace rootNs) { var internFactory = this.host.InternFactory; var nameTable = this.host.NameTable; var contractReferenceAssemblyAttributeName = nameTable.GetNameFor("ContractReferenceAssemblyAttribute"); var contractNamespaceName = nameTable.GetNameFor("System.Diagnostics.Contracts"); #region Define type CustomAttribute compilerGeneratedAttribute = new CustomAttribute() { Constructor = new Microsoft.Cci.MethodReference( this.host, this.compilerGeneratedAttributeType, CallingConvention.HasThis, this.systemVoidType, this.host.NameTable.Ctor, 0) }; var contractsNs = new NestedUnitNamespace() { ContainingUnitNamespace = rootNs, Name = contractNamespaceName, }; NamespaceTypeDefinition result = new NamespaceTypeDefinition() { Name = contractReferenceAssemblyAttributeName, Attributes = new List <ICustomAttribute> { compilerGeneratedAttribute }, BaseClasses = new List <ITypeReference> { this.systemAttributeType }, ContainingUnitNamespace = contractsNs, //unitNamespace, InternFactory = internFactory, IsBeforeFieldInit = true, IsClass = true, IsSealed = true, Methods = new List <IMethodDefinition>(), Layout = LayoutKind.Auto, StringFormat = StringFormatKind.Ansi, }; contractsNs.Members.Add(result); this.allTypes.Add(result); #endregion Define type #region Define the ctor List <IStatement> statements = new List <IStatement>(); SourceMethodBody body = new SourceMethodBody(this.host) { LocalsAreZeroed = true, Block = new BlockStatement() { Statements = statements }, }; MethodDefinition ctor = new MethodDefinition() { Body = body, CallingConvention = CallingConvention.HasThis, ContainingTypeDefinition = result, InternFactory = internFactory, IsRuntimeSpecial = true, IsStatic = false, IsSpecialName = true, Name = nameTable.Ctor, Type = this.systemVoidType, Visibility = TypeMemberVisibility.Public, }; body.MethodDefinition = ctor; var thisRef = new ThisReference() { Type = result, }; // base(); foreach (var baseClass in result.BaseClasses) { var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = baseClass, GenericParameterCount = 0, InternFactory = this.host.InternFactory, Name = nameTable.Ctor, Type = this.systemVoidType, }; statements.Add( new ExpressionStatement() { Expression = new MethodCall() { MethodToCall = baseCtor, IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument? ThisArgument = new ThisReference() { Type = result, }, Type = this.systemVoidType, // REVIEW: Is this the right way to do this? Arguments = new List <IExpression>(), } } ); break; } // return; statements.Add(new ReturnStatement()); result.Methods.Add(ctor); #endregion Define the ctor return(result); }
/// <summary> /// Creates a nested namespace (because only the root namespace is not nested /// and that is created when the assembly is created). /// Adds it to the namespace cache. /// </summary> /// <param name="namespaceSymbol"></param> /// <returns></returns> private NestedUnitNamespace CreateNamespaceDefinition(R.INamespaceSymbol namespaceSymbol) { var ns = new NestedUnitNamespace() { ContainingUnitNamespace = (IUnitNamespace)this.namespaceSymbolCache[namespaceSymbol.ContainingNamespace], Locations = Helper.WrapLocations(namespaceSymbol.Locations), Name = this.host.NameTable.GetNameFor(namespaceSymbol.Name), //Unit = (IUnit)this.assemblySymbolCache[namespaceSymbol.ContainingAssembly], }; this.namespaceSymbolCache.Add(namespaceSymbol, ns); return ns; }
private IModule CreateNewDll(string assemblyName) { var host = new PeReader.DefaultHost(); var core = host.LoadAssembly(host.CoreAssemblySymbolicIdentity); var assembly = new Assembly(); assembly.Name = host.NameTable.GetNameFor(assemblyName); assembly.ModuleName = host.NameTable.GetNameFor(assemblyName + ".dll"); assembly.Kind = ModuleKind.DynamicallyLinkedLibrary; assembly.PlatformType = host.PlatformType; assembly.TargetRuntimeVersion = core.TargetRuntimeVersion; assembly.AssemblyReferences.Add(core); foreach (var referencePath in model.ReferencePaths) { assembly.AssemblyReferences.Add(host.LoadUnitFrom(referencePath) as IAssembly); } var root = new RootUnitNamespace(); root.Unit = assembly; assembly.UnitNamespaceRoot = root; var module = new NamespaceTypeDefinition(); module.Name = host.NameTable.GetNameFor("<Module>"); module.IsClass = true; module.InternFactory = host.InternFactory; module.ContainingUnitNamespace = root; assembly.AllTypes.Add(module); var rootTypeNamespace = new NestedUnitNamespace(); rootTypeNamespace.Name = host.NameTable.GetNameFor(assembly.Name.Value); root.Members.Add(rootTypeNamespace); foreach (var classConfiguration in model.Classes) { var newClass = new NamespaceTypeDefinition(); newClass.IsAbstract = classConfiguration.IsAbstract; newClass.IsClass = true; newClass.BaseClasses = new List<ITypeReference>{ host.PlatformType.SystemObject }; newClass.IsPublic = true; if (classConfiguration.IsStatic) { newClass.IsStatic = true; newClass.IsAbstract = true; newClass.IsSealed = true; } if (!String.IsNullOrEmpty(classConfiguration.Namespace)) { NestedUnitNamespace classContainer = rootTypeNamespace; var namespaceNames = classConfiguration.Namespace.Split('.'); foreach (var namespaceName in namespaceNames) { var existingMembers = classContainer.GetMembersNamed(host.NameTable.GetNameFor(namespaceName), false); var nestedNamespace = new NestedUnitNamespace(); foreach (var existing in existingMembers) { if (existing as NestedUnitNamespace != null) { nestedNamespace = existing as NestedUnitNamespace; break; } } nestedNamespace.Name = host.NameTable.GetNameFor(namespaceName); nestedNamespace.ContainingUnitNamespace = classContainer; classContainer.Members.Add(nestedNamespace); classContainer = nestedNamespace; } newClass.ContainingUnitNamespace = classContainer; } else { newClass.ContainingUnitNamespace = rootTypeNamespace; } newClass.InternFactory = host.InternFactory; newClass.Name = host.NameTable.GetNameFor(classConfiguration.Name); newClass.Methods = new List<IMethodDefinition>(classConfiguration.Methods.Count); newClass.Fields = new List<IFieldDefinition>(classConfiguration.Fields.Count); foreach (var methodConfiguration in classConfiguration.Methods) { var newMethod = new MethodDefinition(); newMethod.Name = host.NameTable.GetNameFor(methodConfiguration.Name); newMethod.IsStatic = methodConfiguration.IsStatic; newMethod.ContainingTypeDefinition = newClass; newMethod.IsCil = true; newMethod.IsHiddenBySignature = true; newMethod.InternFactory = host.InternFactory; newMethod.Visibility = TypeMemberVisibility.Public; newMethod.Type = host.PlatformType.SystemVoid; var newMethodParameters = new List<IParameterDefinition>(); foreach (var param in methodConfiguration.Parameters) { var newMethodParameter = new ParameterDefinition(); newMethodParameter.ContainingSignature = newMethod; newMethodParameter.Index = (ushort)methodConfiguration.Parameters.IndexOf(param); newMethodParameter.Name = host.NameTable.GetNameFor(param.Key); newMethodParameter.Type = new UnitReflector(host).Get(param.Value); newMethodParameters.Add(newMethodParameter); } newMethod.Parameters = newMethodParameters; var methodBody = new SourceMethodBody(host, null); methodBody.MethodDefinition = newMethod; methodBody.LocalsAreZeroed = true; var block = new BlockStatement(); var returnStatement = new ReturnStatement(); if (methodConfiguration.ReturnType != null) { newMethod.Type = new UnitReflector(host).Get(methodConfiguration.ReturnType); returnStatement.Expression = new CompileTimeConstant(); } if (methodConfiguration.MethodBody != null) { var codeBuilder = new CodeBuilder(host, newMethod.Parameters); methodConfiguration.MethodBody(codeBuilder); foreach (var statement in codeBuilder.Statements) { block.Statements.Add(statement); } } // "Stack must be empty on return from a void method" //returnStatement.Expression = new CompileTimeConstant(); //block.Statements.Add(returnStatement); methodBody.Block = block; newMethod.Body = methodBody; newClass.Methods.Add(newMethod); } foreach (var field in classConfiguration.Fields) { var fieldDefinition = new FieldDefinition(); fieldDefinition.ContainingTypeDefinition = newClass; fieldDefinition.InternFactory = host.InternFactory; fieldDefinition.IsReadOnly = field.IsReadonly; fieldDefinition.IsStatic = field.IsStatic; fieldDefinition.Name = host.NameTable.GetNameFor(field.Name); fieldDefinition.Type = new UnitReflector(host).Get(field.FieldType); fieldDefinition.Visibility = field.Accessibility.ToTypeMemberVisibility(); newClass.Fields.Add(fieldDefinition); } assembly.AllTypes.Add(newClass); } using (var dll = File.Create(assemblyName + ".dll")) { PeWriter.WritePeToStream(assembly, host, dll); dll.Close(); } return assembly; }