예제 #1
0
        /// 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));
            }
        }
예제 #2
0
        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));
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
 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);
 }
예제 #6
0
        /// 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));
            }
        }
예제 #7
0
        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;
                }
            }
        }
예제 #8
0
        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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        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));
            }
        }
예제 #12
0
 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);
 }
예제 #13
0
//		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);
        }
예제 #14
0
        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);
        }
예제 #16
0
        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));
        }
예제 #17
0
        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);
        }
예제 #18
0
        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);
        }
예제 #19
0
		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 ();
		}
예제 #20
0
        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());
            }
        }
예제 #21
0
		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);
		}
예제 #22
0
		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;
		}
예제 #23
0
		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;
		}
예제 #24
0
		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;
		}
예제 #27
0
		protected virtual int GetVariableNamePosition (IEditableTextFile file, LocalVariable var)
		{
			return -1;
		}
예제 #28
0
		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;
		}
예제 #29
0
		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;
		}
예제 #30
0
		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);
			}
		}
예제 #31
0
		/// Helper overridables ////////////////////////////

		protected virtual int GetMemberNamePosition (IEditableTextFile file, IMember member)
		{
			return -1;
		}
예제 #32
0
		/// 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;
		}
예제 #33
0
		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);
			}
		}
예제 #34
0
 public DumbTextFileProvider(IEditableTextFile file)
 {
     this.file = file;
 }
예제 #35
0
		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 ());
		}
예제 #36
0
		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;
		}
예제 #38
0
		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);
		}
예제 #40
0
		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);
			}
		}