public override void LeaveMethod() { if (!bStartMonitoring) { return; } if (this.methodStack.Count == 0) { return; } var poppedMethod = this.methodStack.Pop(); this.currOffset = this.offsetStack.Pop(); var previousLoadedFields = this.lastLoadedFieldsStack.Pop(); //If the last method call is a getter, add the field just loaded by that getter method //Or any other remaining loaded fields if (poppedMethod.ShortName.StartsWith("get_")) { Field usedField; int foffset; if (DeclEntityCollector.TryGetFieldOfGetter(poppedMethod, out usedField, out foffset)) { previousLoadedFields.AddRange(usedField); } } this.lastLoadedFields.Clear(); this.lastLoadedFields.AddRange(previousLoadedFields); //Updating the defined and used field list if (this.methodStoreStack.Count > 0) { ses.AppendMethodStore(currSEMethodStore); var poppedStore = this.methodStoreStack.Pop(); if (!poppedMethod.ShortName.StartsWith("get_")) { //Do not propogate for getter methods PropagateModificationsToCaller(poppedStore, currSEMethodStore, poppedMethod); } poppedStore.AppendMethodStore(currSEMethodStore, this.currOffset); currSEMethodStore = poppedStore; } if (poppedMethod.ShortName.Equals("Main") || poppedMethod.ShortName.Equals("DUCoverTerminate")) { ses.DumpToDatabase(); bStartMonitoring = false; } }
/// <summary> /// Initializes DUCover. /// </summary> public static void Initialize(AssemblyEx assembly) { if (!bLoggerInitialized) { InitializeLogger(); bLoggerInitialized = true; logger = LogManager.GetCurrentClassLogger(); } //Check whether intialization information is required for this assembly var shortname = assembly.ShortName; if (DUCoverConstants.SystemAssemblies.Contains(shortname)) { return; } //Analyzes all classes and methods and collects all entities. DeclEntityCollector.CollectAllDeclEntitiesInAssembly(assembly); //Populate all Def-Use tables PopulateAllDUCoverTables(); }
/// <summary> /// Handles a method call. /// </summary> /// <param name="method"></param> private void HandleMethodCall(Method method) { if (lastLoadedFields.Count != 0) { bool bSuccessfulUpdate = true; //handling method calls on fields of this class if (method.ShortName.StartsWith("set_")) { //Update definition table with the current offsets these fields are modified here foreach (var field in lastLoadedFields) { FieldDefUseStore fdus = new FieldDefUseStore(field, this.GetCurrentMethod(), this.currOffset); this.lastFieldDefsDic[field.GlobalIndex] = fdus; } } else if (method.ShortName.StartsWith("get_")) { //Register all usages foreach (var field in lastLoadedFields) { FieldDefUseStore fdus; this.UpdateDUCoverTable(field, out fdus); } } else { foreach (var field in lastLoadedFields) { bool defined, used; if (ses.TryGetFieldDefOrUseByMethod(this.GetCurrentMethod(), field, this.currOffset, out defined, out used)) { FieldDefUseStore fdus; if (used) { //This field is used by this method if (this.lastFieldDefsDic.ContainsKey(field.GlobalIndex)) { this.UpdateDUCoverTable(field, out fdus); } } if (defined) { //This field is defined by this method fdus = new FieldDefUseStore(field, this.GetCurrentMethod(), this.currOffset); this.lastFieldDefsDic[field.GlobalIndex] = fdus; if (used) { //Since it is both used and defined. this.UpdateDUCoverTable(field, out fdus); } } } else { //Backup option: declaring as both used and defined. //In general, control cannot come over here FieldDefUseStore fdus; if (this.lastFieldDefsDic.ContainsKey(field.GlobalIndex)) { bSuccessfulUpdate = this.UpdateDUCoverTable(field, out fdus); } if (bSuccessfulUpdate) { //Override the current definition, since this field is being modified here fdus = new FieldDefUseStore(field, this.GetCurrentMethod(), this.currOffset); this.lastFieldDefsDic[field.GlobalIndex] = fdus; //also add a self def-use this.UpdateDUCoverTable(field, out fdus); } } } } if (bSuccessfulUpdate) { lastLoadedFields.Clear(); } } else { var shortname = method.ShortName; if (shortname.StartsWith("set_")) { Field definedField; if (DeclEntityCollector.TryGetFieldOfSetter(method, out definedField)) { //Override if there is any previous definition of this field FieldDefUseStore fdus = new FieldDefUseStore(definedField, this.GetCurrentMethod(), this.currOffset); this.lastFieldDefsDic[definedField.GlobalIndex] = fdus; } } else if (shortname.StartsWith("get_")) { int foffset; Field usedField; if (DeclEntityCollector.TryGetFieldOfGetter(method, out usedField, out foffset)) { FieldDefUseStore llfs; this.UpdateDUCoverTable(usedField, out llfs); this.lastLoadedFields.Add(usedField); } } } }