public IMethodReference Map(IMethodSymbol methodSymbol) { Contract.Requires(methodSymbol != null); IMethodReference mr = null; if (!methodSymbolCache.TryGetValue(methodSymbol, out mr)) { List <IParameterTypeInformation> ps = methodSymbol.Parameters.Length == 0 ? null : new List <IParameterTypeInformation>(); if (methodSymbol.IsGenericMethod && methodSymbol.ConstructedFrom != methodSymbol) { var gArgs = new List <ITypeReference>(); foreach (var a in methodSymbol.TypeArguments) { gArgs.Add(Map(a)); } mr = new Microsoft.Cci.MutableCodeModel.GenericMethodInstanceReference() { CallingConvention = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis, ContainingType = Map(methodSymbol.ContainingType), GenericArguments = gArgs, GenericMethod = Map(methodSymbol.ConstructedFrom), GenericParameterCount = (ushort)methodSymbol.TypeParameters.Length, InternFactory = this.host.InternFactory, Name = this.nameTable.GetNameFor(methodSymbol.Name), Parameters = ps, Type = Map(methodSymbol.ReturnType), }; } else { var m = new Microsoft.Cci.MutableCodeModel.MethodReference(); // IMPORTANT: Have to add it to the cache before doing anything else because it may // get looked up if it is generic and a parameter's type involves the generic // method parameter. this.methodSymbolCache.Add(methodSymbol, m); m.CallingConvention = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis; m.ContainingType = Map(methodSymbol.ContainingType); m.InternFactory = this.host.InternFactory; m.Name = this.nameTable.GetNameFor(methodSymbol.Name); m.Parameters = ps; m.Type = Map(methodSymbol.ReturnType); mr = m; } foreach (var p in methodSymbol.Parameters) { var p_prime = new ParameterTypeInformation() { ContainingSignature = mr, Index = (ushort)p.Ordinal, Type = Map(p.Type), }; ps.Add(p_prime); } } return(mr); }
public override void RewriteChildren(RootUnitNamespace rootUnitNamespace) { this.classHoldingThreeArgVersions = this.GetContractClass(rootUnitNamespace); base.RewriteChildren(rootUnitNamespace); #region Possibly add class for any contract methods that were defined. if (0 < this.threeArgumentVersionofContractMethod.Count) { // Only add class to assembly if any 3 arg versions were actually created rootUnitNamespace.Members.Add(classHoldingThreeArgVersions); this.allTypes.Add(classHoldingThreeArgVersions); } #endregion Possibly add class for any contract methods that were defined. #region Create a reference to [ContractReferenceAssembly] to mark the assembly with INamespaceTypeDefinition contractReferenceAssemblyAttribute = null; #region First see if we can find it in the same assembly as the one we are rewriting var unit = rootUnitNamespace.Unit; contractReferenceAssemblyAttribute = UnitHelper.FindType(this.host.NameTable, unit, "System.Diagnostics.Contracts.ContractReferenceAssemblyAttribute") as INamespaceTypeDefinition; #endregion First see if we can find it in the same assembly as the one we are rewriting #region If it doesn't exist there, then define it in the same place that the three-argument versions are defined if (contractReferenceAssemblyAttribute is Dummy) { contractReferenceAssemblyAttribute = CreateContractReferenceAssemblyAttribute(rootUnitNamespace); } #endregion If it doesn't exist there, then define it in the same place that the three-argument versions are defined #region Create a reference to the ctor var ctorRef = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = contractReferenceAssemblyAttribute, InternFactory = this.host.InternFactory, Name = host.NameTable.Ctor, Type = systemVoidType, }; var rm = ctorRef.ResolvedMethod; this.ContractReferenceAssemblyAttributeInstance = new CustomAttribute() { Constructor = ctorRef, }; #endregion Create a reference to the ctor #endregion Create a reference to [ContractReferenceAssembly] to mark the assembly with return; }
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); }
public override void TraverseChildren(IMethodCall methodCall) { if (methodCall.MethodToCall.ResolvedMethod.IsSpecialName && methodCall.MethodToCall.Name.Value == "add_BackKeyPress") { // check if it is a back key handler and if it is... // NAVIGATION TODO this only catches really locally delegate expressions. If it is created before, we see it as a BoundExpression // NAVIGATION TODO and need (again) data flow analysis bool delegateIsIdentified = false; bool delegateIsAnonymous = false; PhoneCodeHelper.instance().OnBackKeyPressOverriden = true; IBlockStatement delegateBody = null; IMethodDefinition delegateMethodRef = null; if (methodCall.Arguments.Count() == 1) { IExpression delegateArg = methodCall.Arguments.First(); ICreateDelegateInstance localDelegate = delegateArg as ICreateDelegateInstance; if (localDelegate != null) { delegateIsIdentified = true; delegateMethodRef = localDelegate.MethodToCallViaDelegate.ResolvedMethod; SourceMethodBody body = delegateMethodRef.Body as SourceMethodBody; if (body != null) { delegateBody = body.Block; } PhoneCodeHelper.instance().KnownBackKeyHandlers.Add(delegateMethodRef); } AnonymousDelegate anonDelegate = delegateArg as AnonymousDelegate; if (anonDelegate != null) { delegateIsIdentified = true; delegateIsAnonymous = true; delegateBody = anonDelegate.Body; } // NAVIGATION TODO what if it has no body? if (delegateBody != null) { bool navigates = false, cancelsNav = false; ICollection <string> navTargets; parseBlockForNavigation(delegateBody, out navigates, out navTargets); if (navigates) { ICollection <Tuple <IMethodReference, string> > targets = null; if (!PhoneCodeHelper.instance().BackKeyNavigatingOffenders.TryGetValue(typeBeingTraversed, out targets)) { targets = new HashSet <Tuple <IMethodReference, string> >(); } foreach (string tgt in navTargets) { IMethodReference dummyRef = null; if (delegateIsAnonymous) { dummyRef = new Microsoft.Cci.MutableCodeModel.MethodReference(); (dummyRef as Microsoft.Cci.MutableCodeModel.MethodReference).ContainingType = typeBeingTraversed; (dummyRef as Microsoft.Cci.MutableCodeModel.MethodReference).Name = Dummy.Name; } targets.Add(Tuple.Create <IMethodReference, string>((delegateIsAnonymous ? dummyRef : delegateMethodRef), "\"" + tgt + "\"")); } PhoneCodeHelper.instance().BackKeyNavigatingOffenders[typeBeingTraversed] = targets; } parseBlockForEventCancellation(delegateBody, out cancelsNav); if (cancelsNav) { string reason = "(via delegate "; if (delegateIsIdentified) { reason += delegateMethodRef.ContainingType.ToString() + "." + delegateMethodRef.Name.Value; } else { reason += "anonymous"; } reason += ")"; PhoneCodeHelper.instance().BackKeyCancellingOffenders.Add(Tuple.Create <ITypeReference, string>(typeBeingTraversed, reason)); } } } if (!delegateIsIdentified) { PhoneCodeHelper.instance().BackKeyHandlerOverridenByUnknownDelegate = true; PhoneCodeHelper.instance().BackKeyUnknownDelegateOffenders.Add(typeBeingTraversed); } } base.TraverseChildren(methodCall); }
/// <summary> /// Returns a method whose body is empty, but which can be replaced with the real body when it is /// available. /// </summary> /// <remarks> /// Public because it needs to get called when an anonymous delegate is encountered /// while translating a method body. Just mapping the anonymous delegate doesn't /// provide the information needed. The parameters of a method reference are not /// IParameterDefinitions. /// </remarks> public MethodDefinition TranslateMetadata(R.IMethodSymbol methodSymbol) { Contract.Requires(methodSymbol != null); Contract.Ensures(Contract.Result<MethodDefinition>() != null); var containingType = (ITypeDefinition)this.typeSymbolCache[methodSymbol.ContainingType]; var isConstructor = methodSymbol.MethodKind == R.CommonMethodKind.Constructor; List<IParameterDefinition> parameters = new List<IParameterDefinition>(); var m = new MethodDefinition() { CallingConvention = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis, ContainingTypeDefinition = containingType, InternFactory = this.host.InternFactory, IsHiddenBySignature = true, // REVIEW IsNewSlot = containingType.IsInterface, // REVIEW IsRuntimeSpecial = isConstructor, IsSpecialName = isConstructor, IsStatic = methodSymbol.IsStatic, IsVirtual = containingType.IsInterface, // REVIEW: Why doesn't using methodSymbol.Virtual work for interface methods? Locations = Helper.WrapLocations(methodSymbol.Locations), Name = this.nameTable.GetNameFor(methodSymbol.Name), Parameters = parameters, Type = this.Map(methodSymbol.ReturnType), Visibility = this.Map(methodSymbol.DeclaredAccessibility), }; // IMPORTANT: Have to add it to the cache before doing anything else because it may // get looked up if it is generic and a parameter's type involves the generic // method parameter. this.methodSymbolCache.Add(methodSymbol, m); #region Define the generic parameters if (methodSymbol.IsGenericMethod) { var genericParameters = new List<IGenericMethodParameter>(); foreach (var gp in methodSymbol.TypeParameters) { var gp2 = this.CreateTypeDefinition(gp); genericParameters.Add((IGenericMethodParameter) gp2); } m.GenericParameters = genericParameters; } #endregion #region Define the parameters ushort i = 0; foreach (var p in methodSymbol.Parameters) { var p_prime = new ParameterDefinition() { ContainingSignature = m, IsByReference = p.RefKind == RefKind.Ref, IsIn = p.RefKind == RefKind.None, IsOut = p.RefKind == RefKind.Out, Name = nameTable.GetNameFor(p.Name), Type = this.Map(p.Type), Index = i++, }; parameters.Add(p_prime); } #endregion Define the parameters #region Define default ctor, if needed if (/*methodSymbol.IsSynthesized &&*/ isConstructor) { // BUGBUG!! m.IsHiddenBySignature = true; m.IsRuntimeSpecial = true; m.IsSpecialName = true; var statements = new List<IStatement>(); var body = new SourceMethodBody(this.host, null, null) { LocalsAreZeroed = true, Block = new BlockStatement() { Statements = statements }, }; var thisRef = new ThisReference() { Type = containingType, }; // base(); foreach (var baseClass in containingType.BaseClasses) { var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = baseClass, GenericParameterCount = 0, InternFactory = this.host.InternFactory, Name = nameTable.Ctor, Type = this.host.PlatformType.SystemVoid, }; statements.Add( new ExpressionStatement() { Expression = new MethodCall() { MethodToCall = baseCtor, IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument? ThisArgument = thisRef, Type = this.host.PlatformType.SystemVoid, // REVIEW: Is this the right way to do this? Arguments = new List<IExpression>(), } } ); break; } // return; statements.Add(new ReturnStatement()); body.MethodDefinition = m; m.Body = body; } #endregion return m; }
public IMethodReference Map(R.IMethodSymbol methodSymbol) { Contract.Requires(methodSymbol != null); IMethodReference mr = null; if (!methodSymbolCache.TryGetValue(methodSymbol, out mr)) { List<IParameterTypeInformation> ps = methodSymbol.Parameters.Count == 0 ? null : new List<IParameterTypeInformation>(); if (methodSymbol.IsGenericMethod && methodSymbol.ConstructedFrom != methodSymbol) { var gArgs = new List<ITypeReference>(); foreach (var a in methodSymbol.TypeArguments){ gArgs.Add(Map(a)); } mr = new Microsoft.Cci.MutableCodeModel.GenericMethodInstanceReference() { CallingConvention = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis, ContainingType = Map(methodSymbol.ContainingType), GenericArguments = gArgs, GenericMethod = Map(methodSymbol.ConstructedFrom), GenericParameterCount = (ushort) methodSymbol.TypeParameters.Count, InternFactory = this.host.InternFactory, Name = this.nameTable.GetNameFor(methodSymbol.Name), Parameters = ps, Type = Map(methodSymbol.ReturnType), }; } else { var m = new Microsoft.Cci.MutableCodeModel.MethodReference(); // IMPORTANT: Have to add it to the cache before doing anything else because it may // get looked up if it is generic and a parameter's type involves the generic // method parameter. this.methodSymbolCache.Add(methodSymbol, m); m.CallingConvention = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis; m.ContainingType = Map(methodSymbol.ContainingType); m.InternFactory = this.host.InternFactory; m.Name = this.nameTable.GetNameFor(methodSymbol.Name); m.Parameters = ps; m.Type = Map(methodSymbol.ReturnType); mr = m; } foreach (var p in methodSymbol.Parameters) { var p_prime = new ParameterTypeInformation() { ContainingSignature = mr, Index = (ushort)p.Ordinal, Type = Map(p.Type), }; ps.Add(p_prime); } } return mr; }
public override void TraverseChildren(IMethodCall methodCall) { if (methodCall.MethodToCall.ResolvedMethod.IsSpecialName && methodCall.MethodToCall.Name.Value == "add_BackKeyPress") { // check if it is a back key handler and if it is... // NAVIGATION TODO this only catches really locally delegate expressions. If it is created before, we see it as a BoundExpression // NAVIGATION TODO and need (again) data flow analysis bool delegateIsIdentified= false; bool delegateIsAnonymous = false; PhoneCodeHelper.instance().OnBackKeyPressOverriden = true; IBlockStatement delegateBody = null; IMethodDefinition delegateMethodRef= null; if (methodCall.Arguments.Count() == 1) { IExpression delegateArg= methodCall.Arguments.First(); ICreateDelegateInstance localDelegate = delegateArg as ICreateDelegateInstance; if (localDelegate != null) { delegateIsIdentified = true; delegateMethodRef = localDelegate.MethodToCallViaDelegate.ResolvedMethod; SourceMethodBody body= delegateMethodRef.Body as SourceMethodBody; if (body != null) delegateBody = body.Block; PhoneCodeHelper.instance().KnownBackKeyHandlers.Add(delegateMethodRef); } AnonymousDelegate anonDelegate = delegateArg as AnonymousDelegate; if (anonDelegate != null) { delegateIsIdentified = true; delegateIsAnonymous = true; delegateBody = anonDelegate.Body; } // NAVIGATION TODO what if it has no body? if (delegateBody != null) { bool navigates= false, cancelsNav= false; ICollection<string> navTargets; parseBlockForNavigation(delegateBody, out navigates, out navTargets); if (navigates) { ICollection<Tuple<IMethodReference,string>> targets = null; if (!PhoneCodeHelper.instance().BackKeyNavigatingOffenders.TryGetValue(typeBeingTraversed, out targets)) { targets = new HashSet<Tuple<IMethodReference,string>>(); } foreach (string tgt in navTargets) { IMethodReference dummyRef=null; if (delegateIsAnonymous) { dummyRef = new Microsoft.Cci.MutableCodeModel.MethodReference(); (dummyRef as Microsoft.Cci.MutableCodeModel.MethodReference).ContainingType= typeBeingTraversed; (dummyRef as Microsoft.Cci.MutableCodeModel.MethodReference).Name = Dummy.Name; } targets.Add(Tuple.Create<IMethodReference, string>((delegateIsAnonymous ? dummyRef : delegateMethodRef), "\"" + tgt + "\"")); } PhoneCodeHelper.instance().BackKeyNavigatingOffenders[typeBeingTraversed] = targets; } parseBlockForEventCancellation(delegateBody, out cancelsNav); if (cancelsNav) { string reason= "(via delegate "; if (delegateIsIdentified) reason += delegateMethodRef.ContainingType.ToString() + "." + delegateMethodRef.Name.Value; else reason += "anonymous"; reason += ")"; PhoneCodeHelper.instance().BackKeyCancellingOffenders.Add(Tuple.Create<ITypeReference,string>(typeBeingTraversed, reason)); } } } if (!delegateIsIdentified) { PhoneCodeHelper.instance().BackKeyHandlerOverridenByUnknownDelegate = true; PhoneCodeHelper.instance().BackKeyUnknownDelegateOffenders.Add(typeBeingTraversed); } } base.TraverseChildren(methodCall); }
private static IMethodDefinition CreateDLMethod(IMetadataHost host, ITypeDefinition typeDef, IName name, List <IParameterDefinition> parameters, ITypeReference returnType, IMethodReference getOperatingSystem, IMethodReference linuxHelpers, IMethodReference darwinHelpers, IMethodReference bsdHelpers, bool generateSecondLoad = true) { var methodDefinition = new MethodDefinition { Name = name, Parameters = parameters, ContainingTypeDefinition = typeDef, IsStatic = true, IsHiddenBySignature = true, Visibility = TypeMemberVisibility.Public, Type = returnType }; var labels = new ILGeneratorLabel[4]; var linuxLabel = new ILGeneratorLabel(); var darwinLabel = new ILGeneratorLabel(); var bsdLabel = new ILGeneratorLabel(); var unknownLabel = new ILGeneratorLabel(); labels[0] = linuxLabel; labels[1] = darwinLabel; labels[2] = bsdLabel; labels[3] = bsdLabel; var ilGenerator = new ILGenerator(host, methodDefinition); ilGenerator.Emit(OperationCode.Call, getOperatingSystem); ilGenerator.Emit(OperationCode.Stloc_0); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldc_I4_1); ilGenerator.Emit(OperationCode.Sub); ilGenerator.Emit(OperationCode.Switch, labels); ilGenerator.Emit(OperationCode.Br_S, unknownLabel); AddOperatingSystemCase2(ilGenerator, linuxHelpers, linuxLabel, generateSecondLoad); AddOperatingSystemCase2(ilGenerator, darwinHelpers, darwinLabel, generateSecondLoad); AddOperatingSystemCase2(ilGenerator, bsdHelpers, bsdLabel, generateSecondLoad); ilGenerator.MarkLabel(unknownLabel); ilGenerator.Emit(OperationCode.Ldstr, "Platform Not Supported"); var exceptionCtor = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor(".ctor"), ContainingType = host.PlatformType.SystemException, Type = host.PlatformType.SystemVoid, CallingConvention = CallingConvention.HasThis, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemString } } }; ilGenerator.Emit(OperationCode.Newobj, exceptionCtor); ilGenerator.Emit(OperationCode.Throw); methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 2, methodDefinition, new List <ILocalDefinition> { new LocalDefinition { Type = host.PlatformType.SystemInt32 } }, new List <ITypeDefinition>()); return(methodDefinition); }
private static NamespaceTypeDefinition DefineMethodHashAttributeType(HostEnvironment host, RootUnitNamespace rootUnitNamespace) { Contract.Requires(host != null); var internFactory = host.InternFactory; #region Define the type var methodHashAttributeType = new NamespaceTypeDefinition() { BaseClasses = new List <ITypeReference> { host.PlatformType.SystemAttribute, }, ContainingUnitNamespace = rootUnitNamespace, InternFactory = internFactory, //IsBeforeFieldInit = true, IsClass = true, IsPublic = true, //IsSealed = true, Methods = new List <IMethodDefinition>(1), Name = host.NameTable.GetNameFor("MethodHashAttribute"), //Layout = LayoutKind.Auto, //StringFormat = StringFormatKind.Ansi, }; #endregion #region Define the ctor var systemVoidType = host.PlatformType.SystemVoid; List <IStatement> statements = new List <IStatement>(); SourceMethodBody body = new SourceMethodBody(host) { LocalsAreZeroed = true, Block = new BlockStatement() { Statements = statements }, }; var ctor = new MethodDefinition() { Body = body, CallingConvention = CallingConvention.HasThis, ContainingTypeDefinition = methodHashAttributeType, InternFactory = internFactory, IsRuntimeSpecial = true, IsStatic = false, IsSpecialName = true, Name = host.NameTable.Ctor, Type = systemVoidType, Visibility = TypeMemberVisibility.Public, }; var systemStringType = host.PlatformType.SystemString; var systemIntType = host.PlatformType.SystemInt32; ctor.Parameters = new List <IParameterDefinition>() { new ParameterDefinition() { ContainingSignature = ctor, Name = host.NameTable.GetNameFor("a"), Type = systemStringType, Index = 0, }, new ParameterDefinition() { ContainingSignature = ctor, Name = host.NameTable.GetNameFor("b"), Type = systemIntType, Index = 1, } }; body.MethodDefinition = ctor; var thisRef = new ThisReference() { Type = methodHashAttributeType, }; // base(); foreach (var baseClass in methodHashAttributeType.BaseClasses) { var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = baseClass, GenericParameterCount = 0, InternFactory = internFactory, Name = host.NameTable.Ctor, Type = 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 = methodHashAttributeType, }, Type = systemVoidType, // REVIEW: Is this the right way to do this? Arguments = new List <IExpression>(), } } ); break; } // return; statements.Add(new ReturnStatement()); methodHashAttributeType.Methods.Add(ctor); #endregion Define the ctor return(methodHashAttributeType); }
private static NamespaceTypeDefinition DefineMethodHashAttributeType(HostEnvironment host, RootUnitNamespace rootUnitNamespace) { Contract.Requires(host != null); var internFactory = host.InternFactory; #region Define the type var methodHashAttributeType = new NamespaceTypeDefinition() { BaseClasses = new List<ITypeReference> { host.PlatformType.SystemAttribute, }, ContainingUnitNamespace = rootUnitNamespace, InternFactory = internFactory, //IsBeforeFieldInit = true, IsClass = true, IsPublic = true, //IsSealed = true, Methods = new List<IMethodDefinition>(1), Name = host.NameTable.GetNameFor("MethodHashAttribute"), //Layout = LayoutKind.Auto, //StringFormat = StringFormatKind.Ansi, }; #endregion #region Define the ctor var systemVoidType = host.PlatformType.SystemVoid; List<IStatement> statements = new List<IStatement>(); SourceMethodBody body = new SourceMethodBody(host) { LocalsAreZeroed = true, Block = new BlockStatement() { Statements = statements }, }; var ctor = new MethodDefinition() { Body = body, CallingConvention = CallingConvention.HasThis, ContainingTypeDefinition = methodHashAttributeType, InternFactory = internFactory, IsRuntimeSpecial = true, IsStatic = false, IsSpecialName = true, Name = host.NameTable.Ctor, Type = systemVoidType, Visibility = TypeMemberVisibility.Public, }; var systemStringType = host.PlatformType.SystemString; var systemIntType = host.PlatformType.SystemInt32; ctor.Parameters = new List<IParameterDefinition>(){ new ParameterDefinition() { ContainingSignature = ctor, Name = host.NameTable.GetNameFor("a"), Type = systemStringType, Index = 0, }, new ParameterDefinition() { ContainingSignature = ctor, Name = host.NameTable.GetNameFor("b"), Type = systemIntType, Index = 1, } }; body.MethodDefinition = ctor; var thisRef = new ThisReference() { Type = methodHashAttributeType, }; // base(); foreach (var baseClass in methodHashAttributeType.BaseClasses) { var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = baseClass, GenericParameterCount = 0, InternFactory = internFactory, Name = host.NameTable.Ctor, Type = 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 = methodHashAttributeType, }, Type = systemVoidType, // REVIEW: Is this the right way to do this? Arguments = new List<IExpression>(), } } ); break; } // return; statements.Add(new ReturnStatement()); methodHashAttributeType.Methods.Add(ctor); #endregion Define the ctor return methodHashAttributeType; }
public BlockStatement GetMethodBody(IMethodDefinition cciMethod, BaseMethodDeclarationSyntax roslynMethod, bool extractContracts) { Contract.Requires(roslynMethod.Body != null); var expressionVisitor = new ExpressionVisitor(this.host, this.semanticModel, this.mapper, cciMethod); var sv = new StatementVisitor(this.host, this.semanticModel, this.mapper, cciMethod, expressionVisitor); var block = roslynMethod.Body; var statements = new List <IStatement>(); if (roslynMethod.Kind == SyntaxKind.ConstructorDeclaration) { var roslynCtor = roslynMethod as ConstructorDeclarationSyntax; var es = new List <IExpression>(); var ps = new List <IParameterTypeInformation>(); ITypeReference ctorClass = null; if (roslynCtor.Initializer != null) { switch (roslynCtor.Initializer.ThisOrBaseKeyword.Kind) { case SyntaxKind.BaseKeyword: ctorClass = cciMethod.ContainingTypeDefinition.BaseClasses.First(); // safe to assume there is always at least one? what if there are more than one? break; case SyntaxKind.ThisKeyword: ctorClass = cciMethod.ContainingType; break; default: var msg = String.Format("Was unable to convert {0} which was used for a base/this ctor call in {1}", roslynCtor.Initializer.ThisOrBaseKeyword, MemberHelper.GetMethodSignature(cciMethod)); throw new ConverterException(msg); } foreach (var a in roslynCtor.Initializer.ArgumentList.Arguments) { var e = expressionVisitor.Visit(a); es.Add(e); } } else { // Create a call to the nullary base constructor ctorClass = cciMethod.ContainingTypeDefinition.BaseClasses.First(); // safe to assume there is always at least one? what if there are more than one? } var thisRef = new ThisReference() { Type = cciMethod.ContainingType, }; var ctorRef = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = ctorClass, GenericParameterCount = 0, InternFactory = this.host.InternFactory, Name = nameTable.Ctor, Parameters = ps, Type = this.host.PlatformType.SystemVoid, }; statements.Add( new ExpressionStatement() { Expression = new MethodCall() { MethodToCall = ctorRef, IsStaticCall = false, ThisArgument = thisRef, Type = this.host.PlatformType.SystemVoid, Arguments = es, } } ); } statements.Add( new EmptyStatement() { Locations = Helper.SourceLocation(this.semanticModel.SyntaxTree, block.OpenBraceToken), } ); foreach (var s in block.Statements) { var s_prime = sv.Visit(s); statements.Add(s_prime); } // REVIEW: need to do this only if debugging info is needed? // (But if it isn't done, then there can be unreachable nops // corresponding to close curlys for blocks because of return // statements within the block. When that happens at the method // level, then peverify is unhappy with the assembly.) //if (false) { // // commented this out because it is needed only if this is being used // // to generate IL that in the end should pass peverify (and run). // statements = CreateUnifiedReturnPoint(statements, cciMethod.Type); //} BlockStatement bs = new BlockStatement() { Statements = statements, }; return(bs); }
private static IMethodDefinition CreateIsLibraryInitialized(IMetadataHost host, ITypeDefinition typeDef, IFieldReference intPtrZero) { MethodDefinition methodDefinition = new MethodDefinition { ContainingTypeDefinition = typeDef, IsStatic = true, IsNeverInlined = true, IsHiddenBySignature = true, Visibility = TypeMemberVisibility.Assembly, Type = host.PlatformType.SystemVoid, Parameters = new List <IParameterDefinition> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemString } }, Name = host.NameTable.GetNameFor("IsLibraryInitialized") }; var ilGenerator = new ILGenerator(host, methodDefinition); var retLabel = new ILGeneratorLabel(); var exceptionCtor = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor(".ctor"), ContainingType = host.PlatformType.SystemException, Type = host.PlatformType.SystemVoid, CallingConvention = CallingConvention.HasThis, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemString } } }; var stringConcat = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("Concat"), ContainingType = host.PlatformType.SystemString, Type = host.PlatformType.SystemString, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemString }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemString }, new ParameterDefinition { Index = 2, Type = host.PlatformType.SystemString }, new ParameterDefinition { Index = 3, Type = host.PlatformType.SystemString } } }; var intPtrOpEquality = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.OpEquality, ContainingType = host.PlatformType.SystemIntPtr, Type = host.PlatformType.SystemBoolean, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemIntPtr } } }; ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldsfld, intPtrZero); ilGenerator.Emit(OperationCode.Call, intPtrOpEquality); ilGenerator.Emit(OperationCode.Brfalse_S, retLabel); ilGenerator.Emit(OperationCode.Ldstr, "Library '"); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Ldstr, "' is not initialized. Load the native library (from its file path) by calling LoadLibrary"); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Call, stringConcat); ilGenerator.Emit(OperationCode.Newobj, exceptionCtor); ilGenerator.Emit(OperationCode.Throw); ilGenerator.MarkLabel(retLabel); ilGenerator.Emit(OperationCode.Ret); methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 8, methodDefinition, new List <ILocalDefinition>(), new List <ITypeDefinition>()); return(methodDefinition); }
private static IMethodDefinition CreateGetProcAddress(IMetadataHost host, ITypeDefinition typeDef, IMethodReference windowsGetProcAddress, IMethodReference unixGetProcAddress, IFieldReference isUnix, IFieldReference intPtrZero) { var methodDefinition = new MethodDefinition { Name = host.NameTable.GetNameFor("GetProcAddress"), ContainingTypeDefinition = typeDef, Parameters = new List <IParameterDefinition> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemString } }, IsStatic = true, IsHiddenBySignature = true, Visibility = TypeMemberVisibility.Public, Type = host.PlatformType.SystemIntPtr }; var ilGenerator = new ILGenerator(host, methodDefinition); var label = new ILGeneratorLabel(); var retLabel = new ILGeneratorLabel(); var dupLabel = new ILGeneratorLabel(); var exceptionCtor = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor(".ctor"), ContainingType = host.PlatformType.SystemException, Type = host.PlatformType.SystemVoid, CallingConvention = CallingConvention.HasThis, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemString } } }; var stringConcat = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("Concat"), ContainingType = host.PlatformType.SystemString, Type = host.PlatformType.SystemString, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemString }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemString } } }; var intPtrOpEquality = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.OpEquality, ContainingType = host.PlatformType.SystemIntPtr, Type = host.PlatformType.SystemBoolean, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemIntPtr } } }; ilGenerator.Emit(OperationCode.Ldsfld, isUnix); ilGenerator.Emit(OperationCode.Brtrue_S, label); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Call, windowsGetProcAddress); ilGenerator.Emit(OperationCode.Br_S, dupLabel); ilGenerator.MarkLabel(label); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Call, unixGetProcAddress); ilGenerator.MarkLabel(dupLabel); ilGenerator.Emit(OperationCode.Dup); ilGenerator.Emit(OperationCode.Ldsfld, intPtrZero); ilGenerator.Emit(OperationCode.Call, intPtrOpEquality); ilGenerator.Emit(OperationCode.Brfalse_S, retLabel); ilGenerator.Emit(OperationCode.Ldstr, "GetProcAddress failed for: "); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Call, stringConcat); ilGenerator.Emit(OperationCode.Newobj, exceptionCtor); ilGenerator.Emit(OperationCode.Throw); ilGenerator.MarkLabel(retLabel); ilGenerator.Emit(OperationCode.Ret); methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 8, methodDefinition, new List <ILocalDefinition>(), new List <ITypeDefinition>()); return(methodDefinition); }
public InteropHelperReferences(IMetadataHost host, Assembly assembly) { ITypeReference systemEnvironment = null; foreach (var typeRef in assembly.ResolvedAssembly.GetTypeReferences()) { var name = TypeHelper.GetTypeName(typeRef); if (string.Equals(name, "System.Environment", StringComparison.Ordinal)) { systemEnvironment = typeRef; continue; } if (string.Equals(name, "System.Runtime.InteropServices.Marshal", StringComparison.Ordinal)) { this.SystemRuntimeInteropServicesMarshal = typeRef; } if (string.Equals(name, "System.Runtime.CompilerServices.RuntimeHelpers", StringComparison.Ordinal)) { this.SystemRuntimeCompilerServicesRuntimeHelpers = typeRef; } } var mscorlibAsmRef = assembly.AssemblyReferences.FirstOrDefault(t => t.Name.Value.Equals("mscorlib")); if (mscorlibAsmRef == null) { var tempRef = new AssemblyReference { Name = host.NameTable.GetNameFor("mscorlib"), Version = new Version(4, 0, 0, 0), PublicKeyToken = new List <byte> { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 } }; mscorlibAsmRef = tempRef; assembly.AssemblyReferences.Add(mscorlibAsmRef); } if (systemEnvironment == null) { systemEnvironment = CreateTypeReference(host, mscorlibAsmRef, "System.Environment"); } if (this.SystemRuntimeInteropServicesMarshal == null) { var interopServicesAssembly = assembly.AssemblyReferences.FirstOrDefault(t => t.Name.Value.Equals("System.Runtime.InteropServices")) ?? mscorlibAsmRef; this.SystemRuntimeInteropServicesMarshal = CreateTypeReference(host, interopServicesAssembly, "System.Runtime.InteropServices.Marshal"); } if (this.SystemRuntimeCompilerServicesRuntimeHelpers == null) { var runtimeAssembly = assembly.AssemblyReferences.FirstOrDefault(t => t.Name.Value.Equals("System.Runtime")) ?? mscorlibAsmRef; this.SystemRuntimeCompilerServicesRuntimeHelpers = CreateTypeReference(host, runtimeAssembly, "System.Runtime.CompilerServices.RuntimeHelpers"); } var getNewLine = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("get_NewLine"), ContainingType = systemEnvironment, Type = host.PlatformType.SystemString }; var stringOpEquality = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.OpEquality, ContainingType = host.PlatformType.SystemString, Type = host.PlatformType.SystemBoolean, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemString }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemString } } }; var rootUnitNamespace = new RootUnitNamespace(); rootUnitNamespace.Members.AddRange(assembly.UnitNamespaceRoot.Members); assembly.UnitNamespaceRoot = rootUnitNamespace; rootUnitNamespace.Unit = assembly; var typeDef = CreatePInvokeHelpers(rootUnitNamespace, host); this.PInvokeHelpers = typeDef; rootUnitNamespace.Members.Add(typeDef); assembly.AllTypes.Add(typeDef); var platformSpecificHelpers = new PlatformSpecificHelpersTypeAdder(host, typeDef, this.SystemRuntimeInteropServicesMarshal); var windowsLoaderMethods = platformSpecificHelpers.WindowsLoaderMethods; var unixLoaderMethods = platformSpecificHelpers.UnixLoaderMethods; var isUnix = CreateIsUnixField(host, typeDef); var isUnixStaticFunction = CreateIsUnixStaticFunction(host, typeDef, getNewLine, stringOpEquality); var cctor = CreateCCtor(host, typeDef, isUnix, isUnixStaticFunction); var intPtrZero = new FieldReference { Name = host.NameTable.GetNameFor("Zero"), ContainingType = host.PlatformType.SystemIntPtr, Type = host.PlatformType.SystemIntPtr }; var getLength = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("get_Length"), ContainingType = host.PlatformType.SystemString, Type = host.PlatformType.SystemInt32, CallingConvention = CallingConvention.HasThis }; var getChars = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("get_Chars"), ContainingType = host.PlatformType.SystemString, Type = host.PlatformType.SystemChar, CallingConvention = CallingConvention.HasThis, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemInt32 } } }; var stringToGlobalAnsi = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("StringToHGlobalAnsi"), ContainingType = this.SystemRuntimeInteropServicesMarshal, Type = host.PlatformType.SystemIntPtr, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Type = host.PlatformType.SystemString } } }; var stringToGlobalUni = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("StringToHGlobalUni"), ContainingType = this.SystemRuntimeInteropServicesMarshal, Type = host.PlatformType.SystemIntPtr, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Type = host.PlatformType.SystemString } } }; var intPtrOpInequality = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.OpInequality, ContainingType = host.PlatformType.SystemIntPtr, Type = host.PlatformType.SystemBoolean, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemIntPtr } } }; var freeHGlobal = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("FreeHGlobal"), ContainingType = this.SystemRuntimeInteropServicesMarshal, Type = host.PlatformType.SystemVoid, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Type = host.PlatformType.SystemIntPtr } } }; this.LoadLibrary = CreateLoadLibrary(host, typeDef, windowsLoaderMethods.LoadLibrary, unixLoaderMethods.LoadLibrary, isUnix, intPtrZero); this.FreeLibrary = CreateFreeLibrary(host, typeDef, windowsLoaderMethods.FreeLibrary, unixLoaderMethods.FreeLibrary, isUnix); this.GetProcAddress = CreateGetProcAddress(host, typeDef, windowsLoaderMethods.GetProcAddress, unixLoaderMethods.GetProcAddress, isUnix, intPtrZero); this.StringToAnsiByteArray = CreateStringToAnsi(host, typeDef, getLength, getChars); this.StringArrayAnsiMarshallingProlog = CreateStringArrayMarshallingProlog(host, typeDef, stringToGlobalAnsi, "StringArrayAnsiMarshallingProlog"); this.StringArrayUnicodeMarshallingProlog = CreateStringArrayMarshallingProlog(host, typeDef, stringToGlobalUni, "StringArrayUnicodeMarshallingProlog"); this.StringArrayMarshallingEpilog = CreateStringArrayMarshallingEpilog(host, typeDef, intPtrZero, intPtrOpInequality, freeHGlobal); this.IsLibraryInitialized = CreateIsLibraryInitialized(host, typeDef, intPtrZero); typeDef.Methods = new List <IMethodDefinition> { isUnixStaticFunction, cctor, this.LoadLibrary, this.FreeLibrary, this.GetProcAddress, this.StringToAnsiByteArray, this.StringArrayAnsiMarshallingProlog, this.StringArrayUnicodeMarshallingProlog, this.StringArrayMarshallingEpilog, this.IsLibraryInitialized }; typeDef.Fields = new List <IFieldDefinition> { isUnix }; typeDef.Methods.AddRange(platformSpecificHelpers.Methods); }
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> /// Returns a method whose body is empty, but which can be replaced with the real body when it is /// available. /// </summary> /// <remarks> /// Public because it needs to get called when an anonymous delegate is encountered /// while translating a method body. Just mapping the anonymous delegate doesn't /// provide the information needed. The parameters of a method reference are not /// IParameterDefinitions. /// </remarks> public MethodDefinition TranslateMetadata(IMethodSymbol methodSymbol) { Contract.Requires(methodSymbol != null); Contract.Ensures(Contract.Result <MethodDefinition>() != null); var containingType = (ITypeDefinition)this.typeSymbolCache[methodSymbol.ContainingType]; var isConstructor = methodSymbol.MethodKind == MethodKind.Constructor; List <IParameterDefinition> parameters = new List <IParameterDefinition>(); var m = new MethodDefinition() { CallingConvention = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis, ContainingTypeDefinition = containingType, InternFactory = this.host.InternFactory, IsHiddenBySignature = true, // REVIEW IsNewSlot = containingType.IsInterface, // REVIEW IsRuntimeSpecial = isConstructor, IsSpecialName = isConstructor, IsStatic = methodSymbol.IsStatic, IsVirtual = containingType.IsInterface, // REVIEW: Why doesn't using methodSymbol.Virtual work for interface methods? Locations = Helper.WrapLocations(methodSymbol.Locations), Name = this.nameTable.GetNameFor(methodSymbol.Name), Parameters = parameters, Type = this.Map(methodSymbol.ReturnType), Visibility = this.Map(methodSymbol.DeclaredAccessibility), }; // IMPORTANT: Have to add it to the cache before doing anything else because it may // get looked up if it is generic and a parameter's type involves the generic // method parameter. this.methodSymbolCache.Add(methodSymbol, m); #region Define the generic parameters if (methodSymbol.IsGenericMethod) { var genericParameters = new List <IGenericMethodParameter>(); foreach (var gp in methodSymbol.TypeParameters) { var gp2 = this.CreateTypeDefinition(gp); genericParameters.Add((IGenericMethodParameter)gp2); } m.GenericParameters = genericParameters; } #endregion #region Define the parameters ushort i = 0; foreach (var p in methodSymbol.Parameters) { var p_prime = new ParameterDefinition() { ContainingSignature = m, IsByReference = p.RefKind == RefKind.Ref, IsIn = p.RefKind == RefKind.None, IsOut = p.RefKind == RefKind.Out, Name = nameTable.GetNameFor(p.Name), Type = this.Map(p.Type), Index = i++, }; parameters.Add(p_prime); } #endregion Define the parameters #region Define default ctor, if needed if (/*methodSymbol.IsSynthesized &&*/ isConstructor) // BUGBUG!! { m.IsHiddenBySignature = true; m.IsRuntimeSpecial = true; m.IsSpecialName = true; var statements = new List <IStatement>(); var body = new SourceMethodBody(this.host, null, null) { LocalsAreZeroed = true, Block = new BlockStatement() { Statements = statements }, }; var thisRef = new ThisReference() { Type = containingType, }; // base(); foreach (var baseClass in containingType.BaseClasses) { var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = baseClass, GenericParameterCount = 0, InternFactory = this.host.InternFactory, Name = nameTable.Ctor, Type = this.host.PlatformType.SystemVoid, }; statements.Add( new ExpressionStatement() { Expression = new MethodCall() { MethodToCall = baseCtor, IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument? ThisArgument = thisRef, Type = this.host.PlatformType.SystemVoid, // REVIEW: Is this the right way to do this? Arguments = new List <IExpression>(), } } ); break; } // return; statements.Add(new ReturnStatement()); body.MethodDefinition = m; m.Body = body; } #endregion return(m); }
private static List <IMethodDefinition> CreateUnixHelpers(IMetadataHost host, ITypeDefinition typeDef, ITypeReference marshalClass, List <IMethodDefinition> linuxMethodList, List <IMethodDefinition> darwinMethodList, List <IMethodDefinition> bsdMethodList, IModuleReference libc) { var intPtrZero = new FieldReference { Name = host.NameTable.GetNameFor("Zero"), ContainingType = host.PlatformType.SystemIntPtr, Type = host.PlatformType.SystemIntPtr }; var allocalHGlobal = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("AllocHGlobal"), ContainingType = marshalClass, Type = host.PlatformType.SystemIntPtr, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemInt32 } } }; var ptrToStringAnsi = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("PtrToStringAnsi"), ContainingType = marshalClass, Type = host.PlatformType.SystemString, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr } } }; var freeHGlobal = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("FreeHGlobal"), ContainingType = marshalClass, Type = host.PlatformType.SystemVoid, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr } } }; var intPtrOpInEquality = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.OpInequality, ContainingType = host.PlatformType.SystemIntPtr, Type = host.PlatformType.SystemBoolean, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemIntPtr } } }; var stringOpEquality = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.OpEquality, ContainingType = host.PlatformType.SystemString, Type = host.PlatformType.SystemBoolean, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemString }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemString } } }; var unamePInvokeMethod = CreateUnamePInvokeMethod(host, typeDef, libc); var unameMethod = CreateUnameMethod(host, typeDef, intPtrZero, allocalHGlobal, ptrToStringAnsi, freeHGlobal, unamePInvokeMethod, intPtrOpInEquality); var getosmethod = CreateGetOperatingSystemMethod(host, typeDef, stringOpEquality, unameMethod); var dlopen = CreateDLOpen(host, typeDef, getosmethod, linuxMethodList[0], darwinMethodList[0], bsdMethodList[0]); var dlclose = CreateDLClose(host, typeDef, getosmethod, linuxMethodList[1], darwinMethodList[1], bsdMethodList[1]); var dlsym = CreateDLSym(host, typeDef, getosmethod, linuxMethodList[2], darwinMethodList[2], bsdMethodList[2]); return(new List <IMethodDefinition> { dlopen, dlclose, dlsym, unameMethod, unamePInvokeMethod, getosmethod }); }
/// <summary> /// If the <paramref name="typeDefinition"/> has a type contract, generate a /// contract invariant method and add it to the Methods of the <paramref name="typeDefinition"/>. /// </summary> private void VisitTypeDefinition(ITypeDefinition typeDefinition) { ITypeContract typeContract = this.contractProvider.GetTypeContractFor(typeDefinition); if (typeContract != null) { #region Define the method List<IStatement> statements = new List<IStatement>(); var methodBody = new SourceMethodBody(this.host) { LocalsAreZeroed = true, Block = new BlockStatement() { Statements = statements } }; List<ICustomAttribute> attributes = new List<ICustomAttribute>(); MethodDefinition m = new MethodDefinition() { Attributes = attributes, Body = methodBody, CallingConvention = CallingConvention.HasThis, ContainingTypeDefinition = typeDefinition, InternFactory = this.host.InternFactory, IsStatic = false, Name = this.host.NameTable.GetNameFor("$InvariantMethod$"), Type = systemVoid, Visibility = TypeMemberVisibility.Private, }; methodBody.MethodDefinition = m; #region Add calls to Contract.Invariant foreach (var inv in typeContract.Invariants) { var methodCall = new MethodCall() { Arguments = new List<IExpression> { inv.Condition, }, IsStaticCall = true, MethodToCall = this.contractProvider.ContractMethods.Invariant, Type = systemVoid, Locations = new List<ILocation>(inv.Locations), }; ExpressionStatement es = new ExpressionStatement() { Expression = methodCall }; statements.Add(es); } statements.Add(new ReturnStatement()); #endregion #region Add [ContractInvariantMethod] var contractInvariantMethodType = new Immutable.NamespaceTypeReference( this.host, this.host.PlatformType.SystemDiagnosticsContractsContract.ContainingUnitNamespace, this.host.NameTable.GetNameFor("ContractInvariantMethodAttribute"), 0, false, false, true, PrimitiveTypeCode.NotPrimitive ); var contractInvariantMethodCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = contractInvariantMethodType, GenericParameterCount = 0, InternFactory = this.host.InternFactory, Name = host.NameTable.Ctor, Type = host.PlatformType.SystemVoid, }; var contractInvariantMethodAttribute = new CustomAttribute(); contractInvariantMethodAttribute.Constructor = contractInvariantMethodCtor; attributes.Add(contractInvariantMethodAttribute); #endregion var namedTypeDefinition = (NamedTypeDefinition)typeDefinition; var newMethods = new List<IMethodDefinition>(namedTypeDefinition.Methods == null ? 1 : namedTypeDefinition.Methods.Count() + 1); if (namedTypeDefinition.Methods != null) { foreach (var meth in namedTypeDefinition.Methods) { if (!ContractHelper.IsInvariantMethod(this.host, meth)) newMethods.Add(meth); } } namedTypeDefinition.Methods = newMethods; namedTypeDefinition.Methods.Add(m); #endregion Define the method } }