// 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; }