/// <summary> /// Renames unit names found after the a keyword and before semicolen (;) /// </summary> /// <param name="aKeywordToken"></param> /// <param name="aOldUnitName"></param> /// <param name="aNewUnitName"></param> /// <param name="aVsTextLines"></param> /// <returns></returns> protected virtual bool RenameUnitAfterKeyword(DelphiToken aKeywordToken, string aOldUnitName, string aNewUnitName, IVsTextLines aVsTextLines) { TUnitScanner lScanner = new TUnitScanner(aVsTextLines); bool lResult = false; // any data found before Program,Package,Library,Unit is not valid lScanner.EndToken = DelphiToken.None; while (lScanner.GotoNextToken(aKeywordToken)) { lScanner.EndToken = DelphiToken.EndStatement; while (lScanner.GotoNextToken(DelphiToken.Identifier)) { if (String.Compare(lScanner.TokenValue, aOldUnitName, true) == 0) { ReplaceText(lScanner, aNewUnitName); AfterRenameUnitName(lScanner.TokenValue, aNewUnitName, lScanner); // for project files lResult = true; // // NOTE: We keep looking just in case there are compiler directives. // lScanner.EndToken = DelphiToken.EndStatement; } } lScanner.EndToken = DelphiToken.None; // // NOTE: Look for all uses clases just in case the are in compiler directives. // } return(lResult); }
/// <summary> /// After a successful rename of a project file this method is called to rename it in the DPR file. /// </summary> /// <param name="aOldFileName">full path of the old file</param> /// <param name="aNewFileName">full path of the new file</param> public virtual void RenameContainedFile(string aOldFileName, string aNewFileName) { const string FILE_Key = "{%File"; try { TUnitScanner lScanner = new TUnitScanner(GetTextLines()); lScanner.GotoNextToken(DelphiToken.EndStatement); // look for semicolen lScanner.EndToken = DelphiToken.EndStatement; // now before an semicolen look for comments while (lScanner.GotoNextToken(DelphiToken.ItemComment)) { if (lScanner.TokenValue.IndexOf(FILE_Key, StringComparison.OrdinalIgnoreCase) == 0) { // save scanner values int lSaveStartIndex = lScanner.StartIndex; int lSaveStartLine = lScanner.StartLine; // move scanner to point inside comment lScanner.StartIndex -= (lScanner.TokenValue.Length - FILE_Key.Length); // scan for delphi string if (lScanner.GotoNextToken(DelphiToken.String)) { string lFileName = TDelphiSource.DelphiStringToText(lScanner.TokenValue); // test to see if the filename is the same ones if (String.Compare(Path.GetFileName(lFileName), Path.GetFileName(aOldFileName), true) == 0) { string lNewFile = PackageUtilities.MakeRelativeIfRooted(aNewFileName, this.ProjectMgr.BaseURI); // move the index based on size of new file name lSaveStartIndex += lNewFile.Length - lFileName.Length; // replace just the string not the whole comment ReplaceText(lScanner, TDelphiSource.TextToDelphiString(lNewFile)); } } // move scanner back to where it should be lScanner.StartIndex = lSaveStartIndex; lScanner.StartLine = lSaveStartLine; } } } catch (Exception ex) { ShowErrorMessageBox(ex.Message, "RenameContainedFile() error"); } }
/// <summary> /// Replaces the text at the scanned location. After using a TUnitScanner to find some text you may want to replace /// that text with new data. /// </summary> /// <param name="aScanner">A scanner at the Token that will be replaced</param> /// <param name="aNewText">The text that will be replaced.</param> protected void ReplaceText(TUnitScanner aScanner, string aNewText) { aScanner.TextLines.LockBuffer(); try { object lObj; NativeMethods.ThrowOnFailure(aScanner.TextLines.CreateEditPoint(aScanner.StartLine, aScanner.StartIndex - aScanner.TokenValue.Length, out lObj)); IEditPoint lEditPoint = lObj as IEditPoint; if (lEditPoint != null) { lEditPoint.Delete(aScanner.TokenValue.Length); lEditPoint.Insert(aNewText); } } finally { aScanner.TextLines.UnlockBuffer(); } }
/// <summary> /// Looks for "Unit UnitName;" and renames the unit name. /// </summary> /// <param name="aOldUnitName"></param> /// Name of the old unit name this name must exist in the file or the method returns false /// <param name="aNewUnitName"></param> /// New name of the unit /// <param name="aVsTextLines"></param> /// Editor lines to modify /// <returns></returns> protected virtual bool RenameUnit(DelphiUnitType aUnitType, string aOldUnitName, string aNewUnitName, IVsTextLines aVsTextLines) { TUnitScanner lScanner = new TUnitScanner(aVsTextLines); bool lResult = false; // any data found before Program,Package,Library,Unit is not valid lScanner.EndToken = DelphiToken.EndStatement; if (lScanner.GotoNextToken((DelphiToken)aUnitType)) { if (lScanner.GotoNextToken(DelphiToken.Identifier)) { if (String.Compare(lScanner.TokenValue, aOldUnitName, true) == 0) { ReplaceText(lScanner, aNewUnitName); lResult = true; } } } return(lResult); }
/// <summary> /// Contained files are files located in {%File filename} comments /// </summary> /// <returns>returns a list of contained file names</returns> public string[] GetContainedFiles() { List <string> lResult = new List <string>(); const string FILE_Key = "{%File"; try { TUnitScanner lScanner = new TUnitScanner(GetTextLines()); lScanner.GotoNextToken(DelphiToken.EndStatement); // scan past program, library or package lScanner.EndToken = DelphiToken.EndStatement; while (lScanner.GotoNextToken(DelphiToken.ItemComment)) { if (lScanner.TokenValue.IndexOf(FILE_Key, StringComparison.OrdinalIgnoreCase) == 0) { // save scanner values int lSaveStartIndex = lScanner.StartIndex; int lSaveStartLine = lScanner.StartLine; // move scanner to the end of the comment lScanner.StartIndex -= (lScanner.TokenValue.Length - FILE_Key.Length); // scan for delphi string if (lScanner.GotoNextToken(DelphiToken.String)) { // Get the file as printed in the DPR lResult.Add(TDelphiSource.DelphiStringToText(lScanner.TokenValue)); } // move scanner back to where it should be lScanner.StartIndex = lSaveStartIndex; lScanner.StartLine = lSaveStartLine; } } } catch (Exception ex) { ShowErrorMessageBox(ex.Message, "GetContainedFiles() Error"); } return(lResult.ToArray()); }
protected virtual string[] GetUnitFilesAfterKeyword(DelphiToken aKeyword) { List <string> lResult = new List <string>(); try { TUnitScanner lScanner = new TUnitScanner(GetTextLines()); lScanner.EndToken = DelphiToken.None; if (lScanner.GotoNextToken(aKeyword)) { lScanner.EndToken = DelphiToken.EndStatement; while (lScanner.GotoNextToken(DelphiToken.String)) { lResult.Add(TDelphiSource.DelphiStringToText(lScanner.TokenValue)); } } } catch (Exception ex) { ShowErrorMessageBox(ex.Message, "GetUnitFilesAfterKeyword() Error"); } return(lResult.ToArray()); }
/// <summary> /// After a rename of the unit the a the Delphi main file /// must rename the file name if it exists. /// </summary> /// <param name="aOldUnitName"></param> /// <param name="aNewUnitName"></param> /// <param name="aScanner"></param> protected override void AfterRenameUnitName(string aOldUnitName, string aNewUnitName, TUnitScanner aScanner) { aScanner.EndToken = DelphiToken.Delimiter; if (aScanner.GotoNextToken(DelphiToken.inKeyword)) { if (aScanner.GotoNextToken(DelphiToken.String)) { string lFilePath = TDelphiSource.DelphiStringToText(aScanner.TokenValue); if (IsDelphiPasFile(lFilePath)) { lFilePath = Path.Combine(Path.GetDirectoryName(lFilePath), aNewUnitName) + ".pas"; lFilePath = TDelphiSource.TextToDelphiString(lFilePath); ReplaceText(aScanner, lFilePath); } } } }
protected virtual bool FindKeyword(string aKeyword, int aStartLine, IVsTextLines aVsTextLines, TUnitScanner aUnitScanner, out int aFindLine, out int aFindIndex) { aFindIndex = -1; aFindLine = -1; return(false); }
/// <summary> /// This method is so that project files can rename the file name as well. /// For example in the following line the unit1.pas file name must be renamed. /// <code> /// Unit1 in 'Unit1.pas', {Form} /// </code> /// Since .PAS files do not follow this format it is not coded here. /// </summary> /// <param name="aScanner">A scanner at the point where the unit was found.</param> protected virtual void AfterRenameUnitName(string aOldUnitName, string aNewUnitName, TUnitScanner aScanner) { }
/// <summary> /// Reads the {$R filename} or {$I filename} compiler definintions and returns a list of filenames with there wild card converted. /// </summary> /// <returns>list of resource files located in the file.</returns> public virtual string[] GetDirectiveFiles() { // This is a bad hack but oh well. List <string> lResult = new List <string>(); string lResKey = "{$RESOURCE"; string lIncKey = "{$INCLUDE"; if (IsDelphiCodeFile(this.FileName)) { try { TUnitScanner lScanner = new TUnitScanner(GetTextLines()); lScanner.EndToken = DelphiToken.None; while (lScanner.GotoNextToken(DelphiToken.CompilerDirective)) { if (lScanner.TokenValue.Substring(0, 3) == lResKey.Substring(0, 3) || lScanner.TokenValue.Substring(0, 3) == lIncKey.Substring(0, 3)) { int i = lScanner.TokenValue.Length - 1; char lChar; do { lChar = lScanner.TokenValue[i]; i--; } while (lChar == '}' || lChar == ' '); StringBuilder sb = new StringBuilder(); // if {$R-} or {$R+} directive found go to next directive if (lChar == '-' || lChar == '+') { continue; } // get filename out do { sb.Insert(0, lChar); lChar = lScanner.TokenValue[i]; i--; } while (lChar != ' '); string lFileName = sb.ToString(); lFileName = lFileName.Replace("*", Path.GetFileNameWithoutExtension(this.FileName)); if (lFileName[0] == '\'') { lFileName = TDelphiSource.DelphiStringToText(lFileName); } //if (aWithAbsolutePathFlag) //{ // lFileName = Path.Combine(Path.GetDirectoryName(this.Url), lFileName); // // get rid of .\ or ..\ // lFileName = Path.GetFullPath(lFileName); //} lResult.Add(lFileName); } } } catch (Exception ex) { ShowErrorMessageBox(ex.Message, "GetUnitFiles() Error"); } } return(lResult.ToArray()); }