using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Cci; namespace BytecodeTranslator.Phone { public class PhoneMethodInliningMetadataTraverser : BaseMetadataTraverser { private HashSet methodsToInline; private HashSet iterMethodsToInline; private PhoneCodeHelper phoneHelper; private bool firstPassDone = false; private bool changedOnLastPass = false; private IAssemblyReference assemblyBeingTranslated; public int TotalMethodsCount { get; private set; } public int InlinedMethodsCount { get { return methodsToInline.Count(); } } public PhoneMethodInliningMetadataTraverser(PhoneCodeHelper phoneHelper) { methodsToInline = new HashSet(); iterMethodsToInline = new HashSet(); this.phoneHelper = phoneHelper; TotalMethodsCount = 0; } public override void Visit(IEnumerable modules) { foreach (IModule module in modules) { assemblyBeingTranslated= module.ContainingAssembly; this.Visit(module); } firstPassDone = true; } public override void Visit(IMethodDefinition method) { if (!firstPassDone) TotalMethodsCount++; if (iterMethodsToInline.Contains(method) || (!firstPassDone && phoneHelper.mustInlineMethod(method))) { PhoneMethodInliningCodeTraverser codeTraverser= new PhoneMethodInliningCodeTraverser(); codeTraverser.Visit(method); foreach (IMethodDefinition newMethodDef in codeTraverser.getMethodsFound()) { bool isExtern = this.assemblyBeingTranslated != null && !TypeHelper.GetDefiningUnitReference(newMethodDef.ContainingType).UnitIdentity.Equals(this.assemblyBeingTranslated.UnitIdentity); if (!methodsToInline.Contains(newMethodDef) && !isExtern) { iterMethodsToInline.Add(newMethodDef); changedOnLastPass = true; } } methodsToInline.Add(method); iterMethodsToInline.Remove(method); } } public IEnumerable getMethodsToInline() { return methodsToInline; } public bool isFinished() { return firstPassDone && !changedOnLastPass; } public void findAllMethodsToInline(List modules) { while (!isFinished()) { changedOnLastPass = false; Visit(modules); } } } class PhoneMethodInliningCodeTraverser : BaseCodeTraverser { private HashSet foundMethods = new HashSet(); public override void Visit(IMethodCall methodCall) { foundMethods.Add(methodCall.MethodToCall.ResolvedMethod); } public IEnumerable getMethodsFound() { return foundMethods; } } }