/// <summary> /// takes the existing feature receiver code, finds the method a puts the new code in there /// </summary> /// <param name="existingClassFilename"></param> private void MergeNewCodeWithClass(ProjectItem existingClassProjectItem, string featureReceiverClassName, string xmlContent) { FileCodeModel2 model = (FileCodeModel2)existingClassProjectItem.FileCodeModel; //ok, Content is xml in the following form /* * <FeatureReceiverCode> * <UsingStatement>using Microsoft.SharePoint.Administration;</UsingStatement> * <FeatureActivatedMethod>ActivateTimerJob_<#= TimerJobClass #></FeatureActivatedMethod> * <FeatureActivatedCode> */ //this needs to be added; XmlDocument allCode = new XmlDocument(); allCode.LoadXml(xmlContent); //placing the using statements in the existing file XmlNodeList usingNodes = allCode.SelectNodes("/FeatureReceiverCode/UsingStatements/UsingStatement"); foreach (XmlNode usingNode in usingNodes) { AddUsingStatement(model, model.CodeElements, usingNode.InnerText); } //next we need to add the method call to the existing methods //FeatureActivatedMethod and add it near the region #region FeatureActivatedGeneratedCode XmlNode methodNode = allCode.SelectSingleNode("/FeatureReceiverCode/FeatureActivatedMethod"); if (methodNode != null) { XmlNode methodCodeNode = allCode.SelectSingleNode("/FeatureReceiverCode/FeatureActivatedCode"); if (methodCodeNode != null) { //add the method itself to the class AddMethodCall(model.CodeElements, featureReceiverClassName, "FeatureActivated", methodNode.InnerText); //add the call to our method to FeatureActivated AddMethodToClass(model.CodeElements, featureReceiverClassName, methodCodeNode.InnerText); } } XmlNode methodNode2 = allCode.SelectSingleNode("/FeatureReceiverCode/FeatureDeactivatingMethod"); if (methodNode2 != null) { XmlNode methodCodeNode2 = allCode.SelectSingleNode("/FeatureReceiverCode/FeatureDeactivatingCode"); if (methodCodeNode2 != null) { //add the method itself to the class AddMethodCall(model.CodeElements, featureReceiverClassName, "FeatureDeactivating", methodNode2.InnerText); //add the call to our method to FeatureActivated AddMethodToClass(model.CodeElements, featureReceiverClassName, methodCodeNode2.InnerText); } } model.Synchronize(); //save automatically during tests if (model.DTE.SuppressUI) { existingClassProjectItem.Save(); } }
public void Remove() { Tuple <TextPoint, TextPoint> range = null; try { // To use RemoveMember, we'd have to cast to CodeClass, CodeStruct, CodeInterface, or CodeEnum. // However, RemoveMember won't remove a leading comment other than a DocComment, // and in VB RemoveMember doesn't remove the whitespace line after the member. // So to make our Remove consistent with GetCode, we'll use GetCodeRange and Delete. range = this.GetCodeRange(); } catch (ArgumentException ex) { // In VS 2015 Update 2, an ArgumentException can occur while removing members with explicitly // implemented interface member names if the same named non-explicitly implemented member // was just removed. The Roslyn code model seems to get out of sync on the explicit members, // and we have to look them back up to remove them. This happens, for example, on the second // GetEnumerator when sorting these lines (from DictionarySet.cs): // public IEnumerator<T> GetEnumerator() { throw new NotImplementedException(); } // bool ISet< T >.Add(T item) { throw new NotImplementedException(); } // IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); } bool rethrow = this.element.InfoLocation != vsCMInfoLocation.vsCMInfoLocationProject; if (!rethrow) { ProjectItem projectItem = this.element.ProjectItem; FileCodeModel2 codeModel = (FileCodeModel2)projectItem.FileCodeModel; codeModel.Synchronize(); this.element = MemberSorter.FindMember(codeModel.CodeElements, this.Name); if (this.element == null) { rethrow = true; } else { range = this.GetCodeRange(); } } if (rethrow) { throw new ArgumentException($"Unable to remove or reorder element {this.Name} due to VS FileCodeModel2 limitations.", ex); } } if (range != null) { EditPoint startEdit = range.Item1.CreateEditPoint(); startEdit.StartOfLine(); EditPoint endEdit = range.Item2.CreateEditPoint(); endEdit.LineDown(); if (endEdit.GetLines(endEdit.Line, endEdit.Line + 1).Trim().Length == 0) { endEdit.LineDown(); } endEdit.StartOfLine(); startEdit.Delete(endEdit); } }