/// Adds a field to the class public void BindToField(Stetic.Component obj) { if (targetObject == null) { return; } string name = GetMemberName(obj); var cls = GetClass(); if (FindField(cls.Resolve(project), name) != null) { return; } Document doc = IdeApp.Workbench.OpenDocument(cls.Region.FileName, true); IEditableTextFile editor = doc.GetContent <IEditableTextFile> (); if (editor != null) { var resolvedCls = cls.Resolve(cls.ParsedFile.GetTypeResolveContext(TypeSystemService.GetCompilation(project), cls.Region.Begin)).GetDefinition(); CodeGenerationService.AddNewMember(resolvedCls, cls, GetFieldCode(cls, obj, name)); } }
public override IClass RenameClass(RefactorerContext ctx, IClass cls, string newName) { IEditableTextFile file = ctx.GetFile(cls.Region.FileName); if (file == null) { return(null); } int pos1 = file.GetPositionFromLineColumn(cls.Region.BeginLine, cls.Region.BeginColumn); int pos2 = file.GetPositionFromLineColumn(cls.Region.EndLine, cls.Region.EndColumn); string txt = file.GetText(pos1, pos2); Regex targetExp = new Regex(@"\sclass\s*(" + cls.Name + @")\s", RegexOptions.Multiline); Match match = targetExp.Match(" " + txt + " "); if (!match.Success) { return(null); } int pos = pos1 + match.Groups [1].Index - 1; file.DeleteText(pos, cls.Name.Length); file.InsertText(pos, newName); return(GetGeneratedClass(ctx, file, cls)); }
public override int AddFoldingRegion(RefactorerContext ctx, IType cls, string regionName) { IEditableTextFile buffer = ctx.GetFile(cls.CompilationUnit.FileName); int pos = GetNewMethodPosition(buffer, cls); string eolMarker = Environment.NewLine; if (cls.SourceProject != null) { TextStylePolicy policy = cls.SourceProject.Policies.Get <TextStylePolicy> (); if (policy != null) { eolMarker = policy.GetEolMarker(); } } int line, col; buffer.GetLineColumnFromPosition(pos, out line, out col); string indent = buffer.GetText(buffer.GetPositionFromLineColumn(line, 1), pos); string pre = "#region " + regionName + eolMarker; string post = indent + "#endregion" + eolMarker; buffer.InsertText(pos, pre + post); return(pos + pre.Length); }
protected override int GetVariableNamePosition(IEditableTextFile file, LocalVariable var) { int begin = file.GetPositionFromLineColumn(var.Region.Start.Line, var.Region.Start.Column); int end = file.GetPositionFromLineColumn(var.Region.Start.Line, var.Region.End.Column); if (begin == -1 || end == -1) { return(-1); } string txt = file.GetText(begin, end); int i = 0; /* = txt.IndexOf ('='); * if (i == -1) * i = txt.Length;*/ int pos = -1; do { i = pos = txt.IndexOf(var.Name, i); } while ((pos > 0 && !Char.IsLetter(file.GetCharAt(pos - 1))) && (pos + txt.Length + 1 < file.Length) && !Char.IsLetterOrDigit(file.GetCharAt(pos + txt.Length + 1)) ); if (pos == -1) { return(-1); } return(begin + pos); }
public FindMemberAstVisitor(NRefactoryResolver resolver, IEditableTextFile file, MonoDevelop.Projects.Dom.INode searchedMember) { fileName = file.Name; text = new Mono.TextEditor.Document(); text.Text = file.Text; Init(resolver, searchedMember); }
/// Adds a field to the class public void BindToField(Stetic.Component obj) { if (targetObject == null) { return; } string name = GetMemberName(obj); IType cls = GetClass(); if (FindField(cls, name) != null) { return; } Document doc = IdeApp.Workbench.OpenDocument(cls.CompilationUnit.FileName, true); IEditableTextFile editor = doc.GetContent <IEditableTextFile> (); if (editor != null) { CodeRefactorer gen = GetCodeGenerator(); gen.AddMember(cls, GetFieldCode(obj, name)); } }
public override void PerformChange(IProgressMonitor monitor, RefactorerContext rctx) { if (rctx == null) { throw new InvalidOperationException("Refactory context not available."); } TextEditorData textEditorData = this.TextEditorData; if (textEditorData == null) { IEditableTextFile file = rctx.GetFile(FileName); if (file != null) { if (RemovedChars > 0) { file.DeleteText(Offset, RemovedChars); } if (!string.IsNullOrEmpty(InsertedText)) { file.InsertText(Offset, InsertedText); } rctx.Save(); } } else if (textEditorData != null) { int charsInserted = textEditorData.Replace(Offset, RemovedChars, InsertedText); if (MoveCaretToReplace) { textEditorData.Caret.Offset = Offset + charsInserted; } } }
public override void AddGlobalNamespaceImport(RefactorerContext ctx, string fileName, string nsName) { IEditableTextFile file = ctx.GetFile(fileName); int pos = 0; ParsedDocument parsedDocument = parser.Parse(ctx.ParserContext, fileName, file.Text); StringBuilder text = new StringBuilder(); if (parsedDocument.CompilationUnit != null) { IUsing lastUsing = null; foreach (IUsing u in parsedDocument.CompilationUnit.Usings) { if (u.IsFromNamespace) { break; } lastUsing = u; } if (lastUsing != null) { pos = file.GetPositionFromLineColumn(lastUsing.Region.End.Line, lastUsing.Region.End.Column); } } if (pos != 0) { text.AppendLine(); } text.Append("using "); text.Append(nsName); text.Append(";"); if (file is Mono.TextEditor.ITextEditorDataProvider) { Mono.TextEditor.TextEditorData data = ((Mono.TextEditor.ITextEditorDataProvider)file).GetTextEditorData(); if (pos == 0) { text.Append(data.EolMarker); } int caretOffset = data.Caret.Offset; int insertedChars = data.Insert(pos, text.ToString()); if (pos < caretOffset) { data.Caret.Offset = caretOffset + insertedChars; } } else { if (pos == 0) { text.AppendLine(); } file.InsertText(pos, text.ToString()); } }
public override DomLocation CompleteStatement(RefactorerContext ctx, string fileName, DomLocation caretLocation) { IEditableTextFile file = ctx.GetFile(fileName); int pos = file.GetPositionFromLineColumn(caretLocation.Line + 1, 1); StringBuilder line = new StringBuilder(); int lineNr = caretLocation.Line + 1, column = 1, maxColumn = 1, lastPos = pos; while (lineNr == caretLocation.Line + 1) { maxColumn = column; lastPos = pos; line.Append(file.GetCharAt(pos)); pos++; file.GetLineColumnFromPosition(pos, out lineNr, out column); } string trimmedline = line.ToString().Trim(); string indent = line.ToString().Substring(0, line.Length - line.ToString().TrimStart(' ', '\t').Length); if (trimmedline.EndsWith(";") || trimmedline.EndsWith("{")) { return(caretLocation); } if (trimmedline.StartsWith("if") || trimmedline.StartsWith("while") || trimmedline.StartsWith("switch") || trimmedline.StartsWith("for") || trimmedline.StartsWith("foreach")) { if (!trimmedline.EndsWith(")")) { file.InsertText(lastPos, " () {" + Environment.NewLine + indent + TextEditorProperties.IndentString + Environment.NewLine + indent + "}"); caretLocation.Column = maxColumn + 1; } else { file.InsertText(lastPos, " {" + Environment.NewLine + indent + TextEditorProperties.IndentString + Environment.NewLine + indent + "}"); caretLocation.Column = indent.Length + 1; caretLocation.Line++; } } else if (trimmedline.StartsWith("do")) { file.InsertText(lastPos, " {" + Environment.NewLine + indent + TextEditorProperties.IndentString + Environment.NewLine + indent + "} while ();"); caretLocation.Column = indent.Length + 1; caretLocation.Line++; } else { file.InsertText(lastPos, ";" + Environment.NewLine + indent); caretLocation.Column = indent.Length; caretLocation.Line++; } return(caretLocation); }
public override IEnumerable <MemberReference> FindClassReferences(RefactorerContext ctx, string fileName, IType cls, bool includeXmlComment) { IEditableTextFile file = ctx.GetFile(fileName); NRefactoryResolver resolver = new NRefactoryResolver(ctx.ParserContext, cls.CompilationUnit, ICSharpCode.NRefactory.SupportedLanguage.CSharp, null, fileName); FindMemberAstVisitor visitor = new FindMemberAstVisitor(resolver, file, cls); visitor.IncludeXmlDocumentation = includeXmlComment; visitor.RunVisitor(); SetContext(visitor.FoundReferences, ctx); return(visitor.FoundReferences); }
static XmlTextReader GetConfigReader(string configFile) { IEditableTextFile textFile = MonoDevelop.DesignerSupport.OpenDocumentFileProvider.Instance.GetEditableTextFile(configFile); if (textFile != null) { return(new XmlTextReader(textFile.Text, XmlNodeType.Document, null)); } else { return(new XmlTextReader(configFile)); } }
public IEditableTextFile GetEditableTextFile(FilePath filePath) { foreach (Document doc in IdeApp.Workbench.Documents) { if (doc.FileName == filePath) { IEditableTextFile ef = doc.GetContent <IEditableTextFile> (); if (ef != null) { return(ef); } } } return(null); }
// public IType ImplementInterface (ICompilationUnit pinfo, IType klass, IType iface, bool explicitly, IType declaringClass, IReturnType hintReturnType) // { // if (klass == null) // throw new ArgumentNullException ("klass"); // if (iface == null) // throw new ArgumentNullException ("iface"); // RefactorerContext gctx = GetGeneratorContext (klass); // klass = GetUpdatedClass (gctx, klass); // // bool alreadyImplemented; // IReturnType prefix = null; // // List<KeyValuePair<IMember,IReturnType>> toImplement = new List<KeyValuePair<IMember,IReturnType>> (); // // prefix = new DomReturnType (iface); // // // Stub out non-implemented events defined by @iface // foreach (IEvent ev in iface.Events) { // if (ev.IsSpecialName) // continue; // bool needsExplicitly = explicitly; // // alreadyImplemented = gctx.ParserContext.GetInheritanceTree (klass).Any (x => x.ClassType != ClassType.Interface && x.Events.Any (y => y.Name == ev.Name)); // // if (!alreadyImplemented) // toImplement.Add (new KeyValuePair<IMember,IReturnType> (ev, needsExplicitly ? prefix : null)); // } // // // Stub out non-implemented methods defined by @iface // foreach (IMethod method in iface.Methods) { // if (method.IsSpecialName) // continue; // bool needsExplicitly = explicitly; // alreadyImplemented = false; // foreach (IType t in gctx.ParserContext.GetInheritanceTree (klass)) { // if (t.ClassType == ClassType.Interface) // continue; // foreach (IMethod cmet in t.Methods) { // if (cmet.Name == method.Name && Equals (cmet.Parameters, method.Parameters)) { // if (!needsExplicitly && !cmet.ReturnType.Equals (method.ReturnType)) // needsExplicitly = true; // else // alreadyImplemented |= !needsExplicitly || (iface.FullName == GetExplicitPrefix (cmet.ExplicitInterfaces)); // } // } // } // // if (!alreadyImplemented) // toImplement.Add (new KeyValuePair<IMember,IReturnType> (method, needsExplicitly ? prefix : null)); // } // // // Stub out non-implemented properties defined by @iface // foreach (IProperty prop in iface.Properties) { // if (prop.IsSpecialName) // continue; // bool needsExplicitly = explicitly; // alreadyImplemented = false; // foreach (IType t in gctx.ParserContext.GetInheritanceTree (klass)) { // if (t.ClassType == ClassType.Interface) // continue; // foreach (IProperty cprop in t.Properties) { // if (cprop.Name == prop.Name) { // if (!needsExplicitly && !cprop.ReturnType.Equals (prop.ReturnType)) // needsExplicitly = true; // else // alreadyImplemented |= !needsExplicitly || (iface.FullName == GetExplicitPrefix (cprop.ExplicitInterfaces)); // } // } // } // if (!alreadyImplemented) // toImplement.Add (new KeyValuePair<IMember,IReturnType> (prop, needsExplicitly ? prefix : null)); } // // Ambience ambience = AmbienceService.GetAmbienceForFile (klass.CompilationUnit.FileName); // //implement members // ImplementMembers (klass, toImplement, ambience.GetString (iface, OutputFlags.ClassBrowserEntries | OutputFlags.IncludeGenerics | OutputFlags.IncludeParameters) + " implementation"); // gctx.Save (); // // klass = GetUpdatedClass (gctx, klass); // foreach (IType baseClass in iface.SourceProjectDom.GetInheritanceTree (iface)) { // if (baseClass.Equals (iface) || baseClass.FullName == "System.Object") // continue; // klass = ImplementInterface (pinfo, klass, baseClass, explicitly, declaringClass, hintReturnType); // } // // // return klass; // } IType GetUpdatedClass(RefactorerContext gctx, IType klass) { IEditableTextFile file = gctx.GetFile(klass.CompilationUnit.FileName); ParsedDocument doc = ProjectDomService.Parse(gctx.ParserContext.Project, file.Name, delegate() { return(file.Text); }); IType result = gctx.ParserContext.GetType(klass.FullName, klass.TypeParameters.Count, true); if (result is CompoundType) { IType hintType = doc.CompilationUnit.GetType(klass.FullName, klass.TypeParameters.Count); if (hintType != null) { ((CompoundType)result).SetMainPart(file.Name, hintType.Location); } } return(result); }
public virtual void Rename(string newName) { if (rctx == null) { throw new InvalidOperationException("Refactory context not available."); } IEditableTextFile file = rctx.GetFile(fileName); if (file != null) { Console.WriteLine("Replacing text \"{0}\" with \"{1}\" @ {2},{3}", name, newName, line, column); file.DeleteText(position, name.Length); file.InsertText(position, newName); rctx.Save(); } }
public IEditableTextFile GetFile(FilePath name) { if (files != null) { IEditableTextFile ef = files.GetEditableTextFile(name); if (ef != null) { return(ef); } } foreach (IEditableTextFile f in textFiles) { if (f.Name == name) { return(f); } } TextFile file = new TextFile(name); textFiles.Add(file); return(file); }
protected override DomRegion GetMemberBounds(IEditableTextFile file, IMember member) { if (!(member is IField)) { return(base.GetMemberBounds(file, member)); } // The idea here is that it is common to declare multiple fields in the same // statement, like so: // // public int fu, bar, baz; // // If @member is "bar", then we want to return the region containing: // // ", bar" // // so that when our caller uses this region to delete the text declaring @member, // it won't also delete the text declaring the other fields in this same statement. IType klass = member.DeclaringType; IField field = (IField)member; IField kfield = null, lastField = null, nextField = null; int lineBegin, lineEnd; int colBegin, colEnd; int pos; // find the offset of the field foreach (IField f in klass.Fields) { if (kfield != null) { nextField = f; break; } if (f.Name == field.Name) { kfield = f; continue; } lastField = f; } if (kfield != null && lastField.Location.CompareTo(field.Location) == 0) { // Field has other fields declared before it in the same statement pos = GetMemberNamePosition(file, member); // seek backward for declaration separator while (file.Text[pos] != ',') { pos--; } // eat up unneeded lwsp while (Char.IsWhiteSpace(file.Text[pos])) { pos--; } file.GetLineColumnFromPosition(pos, out lineBegin, out colBegin); if (nextField != null && nextField.Location.CompareTo(field.Location) == 0) { // Field also has other fields declared after it in the same statement pos = GetMemberNamePosition(file, nextField); // seek backward for declaration separator while (file.Text[pos] != ',') { pos--; } // eat up unneeded lwsp while (Char.IsWhiteSpace(file.Text[pos])) { pos--; } file.GetLineColumnFromPosition(pos, out lineEnd, out colEnd); } else { // No fields after this... colEnd = field.BodyRegion.End.Column - 1; // don't include the ';' lineEnd = field.BodyRegion.End.Line; } } else if (nextField != null && nextField.Location.CompareTo(field.Location) == 0) { // Field has other fields declared after it in the same statement pos = GetMemberNamePosition(file, member); file.GetLineColumnFromPosition(pos, out lineBegin, out colBegin); pos = GetMemberNamePosition(file, nextField); file.GetLineColumnFromPosition(pos, out lineEnd, out colEnd); } else { // Field is declared in a statement by itself // fall back to default implementation return(base.GetMemberBounds(file, member)); } return(new DomRegion(lineBegin, colBegin, lineEnd, colEnd)); }
protected override int GetMemberNamePosition(IEditableTextFile file, IMember member) { int begin = file.GetPositionFromLineColumn(member.BodyRegion.Start.Line, member.BodyRegion.Start.Column); int end = file.GetPositionFromLineColumn(member.BodyRegion.End.Line, member.BodyRegion.End.Column); if (begin == -1 || end == -1) { return(-1); } string txt = file.GetText(begin, end); string name = member.Name; int len = txt.Length; int pos = -1; if (member is IField) { // Fields are different because multiple fields can be declared // in the same region and might even reference each other // e.g. "public int fu, bar = 1, baz = bar;" do { if ((pos = txt.IndexOf(member.Name, pos + 1)) == -1) { return(-1); } } while (!IsMatchedField(txt, member.Name, pos)); return(begin + pos); } else if (member is IMethod) { if ((len = txt.IndexOf('(')) == -1) { return(-1); } if (((IMethod)member).IsConstructor) { name = member.DeclaringType.Name; } } else if (member is IEvent) { // no variables to change } else if (member is IProperty) { if (((IProperty)member).IsIndexer && (len = txt.IndexOf('[')) == -1) { return(-1); } } else { return(-1); } if ((pos = txt.LastIndexOf(name, len)) == -1) { return(-1); } return(begin + pos); }
protected override int GetParameterNamePosition(IEditableTextFile file, IParameter param) { IMember member = param.DeclaringMember; int begin = file.GetPositionFromLineColumn(member.BodyRegion.Start.Line, member.BodyRegion.Start.Column); int end = file.GetPositionFromLineColumn(member.BodyRegion.End.Line, member.BodyRegion.End.Column); if (begin == -1 || end == -1) { return(-1); } string txt = file.GetText(begin, end); int open, close, i, j; char obrace, cbrace; if (member is IProperty) // indexer { obrace = '['; cbrace = ']'; } else { obrace = '('; cbrace = ')'; } if ((open = txt.IndexOf(obrace)) == -1) { return(-1); } if ((close = txt.LastIndexOf(cbrace)) == -1) { return(-1); } open++; while (open < close) { if ((i = txt.IndexOf(param.Name, open)) == -1) { return(-1); } if (!Char.IsWhiteSpace(txt[i - 1])) { return(-1); } j = i + param.Name.Length; if (j == close || Char.IsWhiteSpace(txt[j]) || txt[j] == ',') { return(begin + i); } if ((open = txt.IndexOf(',', i)) == -1) { return(-1); } open++; } return(-1); }
protected string GetLineIndent (IEditableTextFile buffer, int line) { int pos = buffer.GetPositionFromLineColumn (line, 1); StringBuilder result = new StringBuilder (); while (pos < buffer.Length) { char ch = buffer.GetCharAt (pos); if (ch == ' ' || ch == '\t') { result.Append (ch); pos++; continue; } break; } return result.ToString (); }
public override void AddLocalNamespaceImport(RefactorerContext ctx, string fileName, string nsName, DomLocation caretLocation) { IEditableTextFile file = ctx.GetFile(fileName); int pos = 0; ParsedDocument parsedDocument = parser.Parse(ctx.ParserContext, fileName, file.Text); StringBuilder text = new StringBuilder(); string indent = ""; if (parsedDocument.CompilationUnit != null) { IUsing containingUsing = null; foreach (IUsing u in parsedDocument.CompilationUnit.Usings) { if (u.IsFromNamespace && u.Region.Contains(caretLocation)) { containingUsing = u; } } if (containingUsing != null) { indent = GetLineIndent(file, containingUsing.Region.Start.Line); IUsing lastUsing = null; foreach (IUsing u in parsedDocument.CompilationUnit.Usings) { if (u == containingUsing) { continue; } if (containingUsing.Region.Contains(u.Region)) { if (u.IsFromNamespace) { break; } lastUsing = u; } } if (lastUsing != null) { pos = file.GetPositionFromLineColumn(lastUsing.Region.End.Line, lastUsing.Region.End.Column); } else { pos = file.GetPositionFromLineColumn(containingUsing.ValidRegion.Start.Line, containingUsing.ValidRegion.Start.Column); // search line end while (pos < file.Length) { char ch = file.GetCharAt(pos); if (ch == '\n') { if (file.GetCharAt(pos + 1) == '\r') { pos++; } break; } else if (ch == '\r') { break; } pos++; } } } else { AddGlobalNamespaceImport(ctx, fileName, nsName); return; } } if (pos != 0) { text.AppendLine(); } text.Append(indent); text.Append("\t"); text.Append("using "); text.Append(nsName); text.Append(";"); if (file is Mono.TextEditor.ITextEditorDataProvider) { Mono.TextEditor.TextEditorData data = ((Mono.TextEditor.ITextEditorDataProvider)file).GetTextEditorData(); if (pos == 0) { text.Append(data.EolMarker); } int caretOffset = data.Caret.Offset; int insertedChars = data.Insert(pos, text.ToString()); if (pos < caretOffset) { data.Caret.Offset = caretOffset + insertedChars; } } else { if (pos == 0) { text.AppendLine(); } file.InsertText(pos, text.ToString()); } }
protected virtual DomRegion GetMemberBounds (IEditableTextFile file, IMember member) { int minLin = member.Location.Line; int minCol = member.Location.Column; int maxLin = member.BodyRegion.End.Line; int maxCol = member.BodyRegion.End.Column; foreach (IAttribute att in member.Attributes) { if (att.Region.Start.Line < minLin) { minLin = att.Region.Start.Line; minCol = att.Region.Start.Column; } else if (att.Region.Start.Line == minLin && att.Region.Start.Column < minCol) { minCol = att.Region.Start.Column; } if (att.Region.End.Line > maxLin) { maxLin = att.Region.End.Line; maxCol = att.Region.End.Column; } else if (att.Region.End.Line == maxLin && att.Region.End.Column > maxCol) { maxCol = att.Region.End.Column; } } return new DomRegion (minLin, minCol, maxLin, maxCol); }
protected IMember FindGeneratedMember (RefactorerContext ctx, IEditableTextFile buffer, IType cls, CodeTypeMember member, int line) { IType rclass = GetGeneratedClass (ctx, buffer, cls); if (rclass != null) { if (member is CodeMemberField) { foreach (IField m in rclass.Fields) if (m.Name == member.Name && line == m.Location.Line) return m; } else if (member is CodeMemberProperty) { foreach (IProperty m in rclass.Properties) if (m.Name == member.Name && line == m.Location.Line) return m; } else if (member is CodeMemberEvent) { foreach (IEvent m in rclass.Events) if (m.Name == member.Name && line == m.Location.Line) return m; } else if (member is CodeMemberMethod) { foreach (IMethod m in rclass.Methods) { if (m.Name == member.Name && line == m.Location.Line) return m; } } } return null; }
protected virtual int SkipBlankLine (IEditableTextFile buffer, int pos) { int i = pos; while (i < buffer.Length) { char ch = buffer.GetCharAt (i); switch (ch) { case '\n': return i + 1; case '\r': if (i + 1 < buffer.Length && buffer.GetCharAt (i + 1) == '\n') i++; return i + 1; case ' ': case '\t': i++; break; default: return pos; } } return pos; }
protected virtual int GetNewMethodPosition (IEditableTextFile buffer, IType cls) { cls = GetMainPart (cls); if (cls.MethodCount + cls.ConstructorCount == 0) { return GetNewPropertyPosition (buffer, cls); /*int pos = GetNewPropertyPosition (buffer, cls); int line, col; buffer.GetLineColumnFromPosition (pos, out line, out col); string ind = GetLineIndent (buffer, line); pos = GetNextLine (buffer, pos); return EnsurePositionIsNotInRegionsAndIndented (cls.SourceProject as Project, buffer, ind, pos);*/ } else { var m = cls.Members .Last (); int pos; if (!m.BodyRegion.IsEmpty && m.BodyRegion.End.Line > 1) { pos = buffer.GetPositionFromLineColumn (m.BodyRegion.End.Line, m.BodyRegion.End.Column); pos = GetNextLine (buffer, pos); pos = SkipBlankLine (buffer, pos); } else { // Abstract or P/Inboke methods don't have a body pos = buffer.GetPositionFromLineColumn (m.Location.Line, m.Location.Column); pos = GetNextLine (buffer, pos); } // buffer.InsertText (pos++, "\n"); string ind = GetLineIndent (buffer, m.Location.Line); pos = EnsurePositionIsNotInRegionsAndIndented (cls.SourceProject as Project, buffer, ind, pos); return pos; } }
protected override int GetMemberNamePosition (IEditableTextFile file, IMember member) { int begin = file.GetPositionFromLineColumn (member.BodyRegion.Start.Line, member.BodyRegion.Start.Column); int end = file.GetPositionFromLineColumn (member.BodyRegion.End.Line, member.BodyRegion.End.Column); if (begin == -1 || end == -1) return -1; string txt = file.GetText (begin, end); string name = member.Name; int len = txt.Length; int pos = -1; if (member is IField) { // Fields are different because multiple fields can be declared // in the same region and might even reference each other // e.g. "public int fu, bar = 1, baz = bar;" do { if ((pos = txt.IndexOf (member.Name, pos + 1)) == -1) return -1; } while (!IsMatchedField (txt, member.Name, pos)); return begin + pos; } else if (member is IMethod) { if ((len = txt.IndexOf ('(')) == -1) return -1; if (((IMethod) member).IsConstructor) name = member.DeclaringType.Name; } else if (member is IEvent) { // no variables to change } else if (member is IProperty) { if (((IProperty)member).IsIndexer && (len = txt.IndexOf ('[')) == -1) return -1; } else { return -1; } if ((pos = txt.LastIndexOf (name, len)) == -1) return -1; return begin + pos; }
protected override int GetVariableNamePosition (IEditableTextFile file, LocalVariable var) { int begin = file.GetPositionFromLineColumn (var.Region.Start.Line, var.Region.Start.Column); int end = file.GetPositionFromLineColumn (var.Region.Start.Line, var.Region.End.Column); if (begin == -1 || end == -1) return -1; string txt = file.GetText (begin, end); int i = 0; /* = txt.IndexOf ('='); if (i == -1) i = txt.Length;*/ int pos = -1; do { i = pos = txt.IndexOf (var.Name, i); } while ( (pos > 0 && !Char.IsLetter (file.GetCharAt (pos - 1))) && (pos + txt.Length + 1 < file.Length )&& !Char.IsLetterOrDigit (file.GetCharAt (pos + txt.Length + 1)) ); if (pos == -1) return -1; return begin + pos; }
protected virtual int GetVariableNamePosition (IEditableTextFile file, LocalVariable var) { return -1; }
protected int EnsurePositionIsNotInRegionsAndIndented (Project p, IEditableTextFile buffer, string indent, int position) { ParsedDocument doc = ProjectDomService.Parse (p, buffer.Name, delegate () { return buffer.Text; }); int line, column; buffer.GetLineColumnFromPosition (position, out line, out column); foreach (FoldingRegion region in doc.AdditionalFolds) { if (region.Region.Contains (line, column)) { line = region.Region.End.Line + 1; column = 1; } } int result = buffer.GetPositionFromLineColumn (line, column); if (column != 1) { string eolMarker = Environment.NewLine; buffer.InsertText (result, eolMarker); result += eolMarker.Length; } buffer.InsertText (result, indent); result += indent.Length; return result; }
protected virtual int GetNextLine (IEditableTextFile buffer, int pos) { if (pos < 0) return 0; while (pos < buffer.Length) { char ch = buffer.GetCharAt (pos); switch (ch) { case '\n': return pos + 1; case '\r': if (pos + 1 < buffer.Length && buffer.GetCharAt (pos + 1) == '\n') pos++; return pos + 1; /* case ' ': case '\t': pos++; break;*/ default: pos++; continue; } } return pos; }
protected virtual int GetNewPropertyPosition (IEditableTextFile buffer, IType cls) { cls = GetMainPart (cls); if (cls.PropertyCount == 0) { return GetNewFieldPosition (buffer, cls); /* int pos = GetNewFieldPosition (buffer, cls); int line, col; buffer.GetLineColumnFromPosition (pos, out line, out col); string indent = GetLineIndent (buffer, line); pos = GetNextLine (buffer, pos); return EnsurePositionIsNotInRegionsAndIndented (cls.SourceProject as Project, buffer, indent, pos);*/ } else { IProperty m = cls.Properties.Last (); int pos = buffer.GetPositionFromLineColumn (m.BodyRegion.End.Line, m.BodyRegion.End.Column); pos = GetNextLine (buffer, pos); pos = SkipBlankLine (buffer, pos); string indent = GetLineIndent (buffer, m.Location.Line); return EnsurePositionIsNotInRegionsAndIndented (cls.SourceProject as Project, buffer, indent, pos); } }
/// Helper overridables //////////////////////////// protected virtual int GetMemberNamePosition (IEditableTextFile file, IMember member) { return -1; }
/// Helper methods //////////////////////////// // Returns a reparsed IType instance that contains the generated code. protected IType GetGeneratedClass (RefactorerContext ctx, IEditableTextFile buffer, IType cls) { // Don't get the class from the parse results because in that class the types are not resolved. // Get the class from the database instead. ParsedDocument doc = ProjectDomService.Parse (ctx.ParserContext.Project, buffer.Name, delegate () { return buffer.Text; }); IType result = ctx.ParserContext.GetType (cls.FullName, cls.TypeParameters.Count, true, true); if (result is CompoundType) { IType hintType = doc.CompilationUnit.GetType (cls.FullName, cls.TypeParameters.Count); if (hintType != null) ((CompoundType)result).SetMainPart (buffer.Name, hintType.Location); } return result; }
protected virtual int GetNewEventPosition (IEditableTextFile buffer, IType cls) { cls = GetMainPart (cls); if (cls.EventCount == 0) { return GetNewMethodPosition (buffer, cls); /* int pos = GetNewMethodPosition (buffer, cls); int line, col; buffer.GetLineColumnFromPosition (pos, out line, out col); string ind = GetLineIndent (buffer, line); pos = GetNextLine (buffer, pos); return EnsurePositionIsNotInRegionsAndIndented (cls.SourceProject as Project, buffer, ind, pos);*/ } else { IEvent m = GetMainPart (cls).Events.Last (); int pos; if (!m.BodyRegion.IsEmpty) { pos = buffer.GetPositionFromLineColumn (m.BodyRegion.End.Line, m.BodyRegion.End.Column); pos = GetNextLine (buffer, pos); pos = SkipBlankLine (buffer, pos); } else { pos = buffer.GetPositionFromLineColumn (m.Location.Line, m.Location.Column); pos = GetNextLine (buffer, pos); } // buffer.InsertText (pos++, "\n"); string ind = GetLineIndent (buffer, m.Location.Line); return EnsurePositionIsNotInRegionsAndIndented (cls.SourceProject as Project, buffer, ind, pos); } }
public DumbTextFileProvider(IEditableTextFile file) { this.file = file; }
protected void AddMembersAtPosition (RefactorerContext ctx, IType cls, IEnumerable<CodeTypeMember> members, IEditableTextFile buffer, int pos) { int line, col; buffer.GetLineColumnFromPosition (pos, out line, out col); string indent = GetLineIndent (buffer, line); StringBuilder generatedString = new StringBuilder (); bool isFirst = true; foreach (CodeTypeMember member in members) { if (generatedString.Length > 0) { generatedString.AppendLine (); } generatedString.Append (Indent (GenerateCodeFromMember (member), indent, isFirst)); isFirst = false; } // remove last new line + indent generatedString.Length -= indent.Length + Environment.NewLine.Length; // remove indent from last generated code member generatedString.Length -= indent.Length; if (buffer.GetCharAt (pos) == '\n') pos++; buffer.InsertText (pos, generatedString.ToString ()); }
protected virtual int GetParameterNamePosition (IEditableTextFile file, IParameter param) { return -1; }
protected override int GetParameterNamePosition (IEditableTextFile file, IParameter param) { IMember member = param.DeclaringMember; int begin = file.GetPositionFromLineColumn (member.BodyRegion.Start.Line, member.BodyRegion.Start.Column); int end = file.GetPositionFromLineColumn (member.BodyRegion.End.Line, member.BodyRegion.End.Column); if (begin == -1 || end == -1) return -1; string txt = file.GetText (begin, end); int open, close, i, j; char obrace, cbrace; if (member is IProperty) { // indexer obrace = '['; cbrace = ']'; } else { obrace = '('; cbrace = ')'; } if ((open = txt.IndexOf (obrace)) == -1) return -1; if ((close = txt.LastIndexOf (cbrace)) == -1) return -1; open++; while (open < close) { if ((i = txt.IndexOf (param.Name, open)) == -1) return -1; if (!Char.IsWhiteSpace (txt[i - 1])) return -1; j = i + param.Name.Length; if (j == close || Char.IsWhiteSpace (txt[j]) || txt[j] == ',') return begin + i; if ((open = txt.IndexOf (',', i)) == -1) return -1; open++; } return -1; }
protected virtual int GetNewMemberPosition (IEditableTextFile buffer, IType cls, CodeTypeMember member) { if (member is CodeMemberField) return GetNewFieldPosition (buffer, cls); if (member is CodeMemberMethod) return GetNewMethodPosition (buffer, cls); if (member is CodeMemberEvent) return GetNewEventPosition (buffer, cls); if (member is CodeMemberProperty) return GetNewPropertyPosition (buffer, cls); throw new InvalidOperationException ("Invalid member type: " + member); }
protected override DomRegion GetMemberBounds (IEditableTextFile file, IMember member) { if (!(member is IField)) return base.GetMemberBounds (file, member); // The idea here is that it is common to declare multiple fields in the same // statement, like so: // // public int fu, bar, baz; // // If @member is "bar", then we want to return the region containing: // // ", bar" // // so that when our caller uses this region to delete the text declaring @member, // it won't also delete the text declaring the other fields in this same statement. IType klass = member.DeclaringType; IField field = (IField) member; IField kfield = null, lastField = null, nextField = null; int lineBegin, lineEnd; int colBegin, colEnd; int pos; // find the offset of the field foreach (IField f in klass.Fields) { if (kfield != null) { nextField = f; break; } if (f.Name == field.Name) { kfield = f; continue; } lastField = f; } if (kfield != null && lastField.Location.CompareTo (field.Location) == 0) { // Field has other fields declared before it in the same statement pos = GetMemberNamePosition (file, member); // seek backward for declaration separator while (file.Text[pos] != ',') pos--; // eat up unneeded lwsp while (Char.IsWhiteSpace (file.Text[pos])) pos--; file.GetLineColumnFromPosition (pos, out lineBegin, out colBegin); if (nextField != null && nextField.Location.CompareTo (field.Location) == 0) { // Field also has other fields declared after it in the same statement pos = GetMemberNamePosition (file, nextField); // seek backward for declaration separator while (file.Text[pos] != ',') pos--; // eat up unneeded lwsp while (Char.IsWhiteSpace (file.Text[pos])) pos--; file.GetLineColumnFromPosition (pos, out lineEnd, out colEnd); } else { // No fields after this... colEnd = field.BodyRegion.End.Column - 1; // don't include the ';' lineEnd = field.BodyRegion.End.Line; } } else if (nextField != null && nextField.Location.CompareTo (field.Location) == 0) { // Field has other fields declared after it in the same statement pos = GetMemberNamePosition (file, member); file.GetLineColumnFromPosition (pos, out lineBegin, out colBegin); pos = GetMemberNamePosition (file, nextField); file.GetLineColumnFromPosition (pos, out lineEnd, out colEnd); } else { // Field is declared in a statement by itself // fall back to default implementation return base.GetMemberBounds (file, member); } return new DomRegion (lineBegin, colBegin, lineEnd, colEnd); }
protected virtual int GetNewFieldPosition (IEditableTextFile buffer, IType cls) { cls = GetMainPart (cls); if (cls.FieldCount == 0) { int sp = buffer.GetPositionFromLineColumn (cls.BodyRegion.Start.Line, cls.BodyRegion.Start.Column); int ep = buffer.GetPositionFromLineColumn (cls.BodyRegion.End.Line, cls.BodyRegion.End.Column); string s = buffer.GetText (sp, ep); int i = s.IndexOf ('{'); if (i == -1) return -1; string ind = GetLineIndent (buffer, cls.BodyRegion.Start.Line) ; int pos; if (cls.BodyRegion.Start.Line == cls.BodyRegion.End.Line) { buffer.InsertText (sp + i + 1, "\n" + ind); pos = sp + i + 2; } else { pos = GetNextLine (buffer, sp + i + 1); // buffer.InsertText (pos, ind + "\n"); // pos += ind.Length + 1; } return EnsurePositionIsNotInRegionsAndIndented (cls.SourceProject as Project, buffer, ind + "\t", pos); } else { IField f = cls.Fields.Last (); int pos = buffer.GetPositionFromLineColumn (f.Location.Line, f.Location.Column); string ind = GetLineIndent (buffer, f.Location.Line); if (cls.BodyRegion.Start.Line == cls.BodyRegion.End.Line) { int sp = buffer.GetPositionFromLineColumn (cls.BodyRegion.Start.Line, cls.BodyRegion.Start.Column); int ep = buffer.GetPositionFromLineColumn (cls.BodyRegion.End.Line, cls.BodyRegion.End.Column); string s = buffer.GetText (sp, ep); int i = s.IndexOf ('}'); if (i == -1) return -1; // buffer.InsertText (sp + i, "\n" + ind + "\t\n" + ind); pos = sp + i + ind.Length + 2; } else { pos = GetNextLine (buffer, pos); } // buffer.InsertText (pos, ind); return EnsurePositionIsNotInRegionsAndIndented (cls.SourceProject as Project, buffer, ind, pos); } }