示例#1
0
        /// <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();
            }
        }
示例#2
0
        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);
            }
        }