From 6e460e179f0d1aab3de2efe4437f6022ec208963 Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Sat, 9 Jun 2012 17:25:58 +0100 Subject: [PATCH] Implement EnvDTE.CodeClass.AddVariable. --- .../Project/PackageManagement.csproj | 4 + .../Project/Src/ClassCodeGenerator.cs | 91 +++++++++ .../Project/Src/DocumentLoader.cs | 15 +- .../Project/Src/EnvDTE/CodeClass.cs | 3 +- .../Project/Src/EnvDTE/EditPoint.cs | 6 +- .../Project/Src/IDocumentLoader.cs | 4 +- .../Project/Src/IRefactoringDocumentView.cs | 15 ++ .../Project/Src/RefactoringDocumentView.cs | 39 ++++ .../Project/Src/ThreadSafeDocument.cs | 30 ++- .../Project/Src/ThreadSafeDocumentLine.cs | 70 +++++++ .../Test/PackageManagement.Tests.csproj | 8 + .../Test/Src/ClassCodeGeneratorTests.cs | 179 ++++++++++++++++++ .../Test/Src/CodeGeneratorTests.cs | 38 ++++ .../Test/Src/EnvDTE/EditPointTests.cs | 8 +- .../Test/Src/Helpers/ClassHelper.cs | 18 ++ .../Test/Src/Helpers/CompilationUnitHelper.cs | 36 ++++ .../Test/Src/Helpers/FakeCodeGenerator.cs | 34 ++++ .../Test/Src/Helpers/FieldHelper.cs | 6 +- 18 files changed, 579 insertions(+), 25 deletions(-) create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/ClassCodeGenerator.cs create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/IRefactoringDocumentView.cs create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/RefactoringDocumentView.cs create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/ThreadSafeDocumentLine.cs create mode 100644 src/AddIns/Misc/PackageManagement/Test/Src/ClassCodeGeneratorTests.cs create mode 100644 src/AddIns/Misc/PackageManagement/Test/Src/CodeGeneratorTests.cs create mode 100644 src/AddIns/Misc/PackageManagement/Test/Src/Helpers/CompilationUnitHelper.cs create mode 100644 src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeCodeGenerator.cs diff --git a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj index b40ef555d4..c0e653b7cb 100644 --- a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj +++ b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj @@ -70,6 +70,7 @@ + @@ -124,6 +125,7 @@ + @@ -220,6 +222,7 @@ + ManagePackagesView.xaml @@ -370,6 +373,7 @@ + diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/ClassCodeGenerator.cs b/src/AddIns/Misc/PackageManagement/Project/Src/ClassCodeGenerator.cs new file mode 100644 index 0000000000..6f80994c8c --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/ClassCodeGenerator.cs @@ -0,0 +1,91 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Linq; +using ICSharpCode.NRefactory.Ast; +using ICSharpCode.PackageManagement.EnvDTE; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Dom.Refactoring; + +namespace ICSharpCode.PackageManagement +{ + public class ClassCodeGenerator + { + public ClassCodeGenerator(IClass c) + : this(c, new DocumentLoader()) + { + } + + public ClassCodeGenerator(IClass c, IDocumentLoader documentLoader) + { + this.Class = c; + this.DocumentLoader = documentLoader; + } + + IClass Class { get; set; } + IDocumentLoader DocumentLoader { get; set; } + + ICompilationUnit CompilationUnit { + get { return Class.CompilationUnit; } + } + + public CodeVariable AddPublicVariable(string name, string type) + { + CodeGenerator codeGenerator = GetCodeGenerator(); + IRefactoringDocumentView view = LoadClassDocumentView(); + codeGenerator.InsertCodeAtEnd(Class.Region, view.RefactoringDocument, CreateField(name, type)); + return GetVariableInserted(view); + } + + CodeGenerator GetCodeGenerator() + { + return CompilationUnit.Language.CodeGenerator; + } + + IRefactoringDocumentView LoadClassDocumentView() + { + return DocumentLoader.LoadRefactoringDocumentView(CompilationUnit.FileName); + } + + FieldDeclaration CreateField(string name, string type) + { + return new FieldDeclaration(new List()) { + TypeReference = new TypeReference(type), + Modifier = Modifiers.Public, + Fields = CreateVariableDeclarations(name) + }; + } + + List CreateVariableDeclarations(string name) + { + var variables = new List(); + variables.Add(new VariableDeclaration(name)); + return variables; + } + + CodeVariable GetVariableInserted(IRefactoringDocumentView view) + { + IField field = FindField(view); + return new CodeVariable(field); + } + + IField FindField(IRefactoringDocumentView view) + { + ICompilationUnit unit = view.Parse(); + IClass matchedClass = FindMatchingClass(unit); + return matchedClass.Fields.Last(); + } + + IClass FindMatchingClass(ICompilationUnit unit) + { + foreach (IClass c in unit.Classes) { + if (c.FullyQualifiedName == Class.FullyQualifiedName) { + return c; + } + } + return null; + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/DocumentLoader.cs b/src/AddIns/Misc/PackageManagement/Project/Src/DocumentLoader.cs index 7a9df5fa88..49f906ec91 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/DocumentLoader.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/DocumentLoader.cs @@ -2,21 +2,24 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; -using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Dom.Refactoring; using ICSharpCode.SharpDevelop.Gui; namespace ICSharpCode.PackageManagement { public class DocumentLoader : IDocumentLoader { - public IDocument LoadDocument(string fileName) + public IRefactoringDocument LoadRefactoringDocument(string fileName) + { + return LoadRefactoringDocumentView(fileName).RefactoringDocument; + } + + public IRefactoringDocumentView LoadRefactoringDocumentView(string fileName) { if (WorkbenchSingleton.InvokeRequired) { - return WorkbenchSingleton.SafeThreadFunction(() => LoadDocument(fileName)); + return WorkbenchSingleton.SafeThreadFunction(() => LoadRefactoringDocumentView(fileName)); } else { - var textEditorProvider = FileService.OpenFile(fileName) as ITextEditorProvider; - return new ThreadSafeDocument(textEditorProvider.TextEditor.Document); + return new RefactoringDocumentView(fileName); } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass.cs index 6668c33623..9b59155337 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass.cs @@ -27,7 +27,8 @@ namespace ICSharpCode.PackageManagement.EnvDTE public virtual CodeVariable AddVariable(string name, object type, object Position = null, vsCMAccess Access = vsCMAccess.vsCMAccessPublic, object Location = null) { - throw new NotImplementedException(); + var codeGenerator = new ClassCodeGenerator(Class); + return codeGenerator.AddPublicVariable(name, (string)type); } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/EditPoint.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/EditPoint.cs index 723e46a2b8..1f2dc191d4 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/EditPoint.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/EditPoint.cs @@ -3,13 +3,13 @@ using System; using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Dom.Refactoring; namespace ICSharpCode.PackageManagement.EnvDTE { public class EditPoint : TextPoint { - IDocument document; + IRefactoringDocument document; internal EditPoint(FilePosition filePosition, IDocumentLoader documentLoader) : base(filePosition, documentLoader) @@ -31,7 +31,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE void OpenDocument() { - document = DocumentLoader.LoadDocument(FilePosition.FileName); + document = DocumentLoader.LoadRefactoringDocument(FilePosition.FileName); } int GetStartOffset() diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/IDocumentLoader.cs b/src/AddIns/Misc/PackageManagement/Project/Src/IDocumentLoader.cs index 9c8d81898a..37ac4153c0 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/IDocumentLoader.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/IDocumentLoader.cs @@ -2,12 +2,14 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using ICSharpCode.SharpDevelop.Dom.Refactoring; using ICSharpCode.SharpDevelop.Editor; namespace ICSharpCode.PackageManagement { public interface IDocumentLoader { - IDocument LoadDocument(string fileName); + IRefactoringDocument LoadRefactoringDocument(string fileName); + IRefactoringDocumentView LoadRefactoringDocumentView(string fileName); } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/IRefactoringDocumentView.cs b/src/AddIns/Misc/PackageManagement/Project/Src/IRefactoringDocumentView.cs new file mode 100644 index 0000000000..8f2191face --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/IRefactoringDocumentView.cs @@ -0,0 +1,15 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Dom.Refactoring; + +namespace ICSharpCode.PackageManagement +{ + public interface IRefactoringDocumentView + { + IRefactoringDocument RefactoringDocument { get; } + ICompilationUnit Parse(); + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/RefactoringDocumentView.cs b/src/AddIns/Misc/PackageManagement/Project/Src/RefactoringDocumentView.cs new file mode 100644 index 0000000000..4cf3f1bb92 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/RefactoringDocumentView.cs @@ -0,0 +1,39 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Dom.Refactoring; +using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Gui; + +namespace ICSharpCode.PackageManagement +{ + public class RefactoringDocumentView : IRefactoringDocumentView + { + IViewContent view; + + public RefactoringDocumentView(string fileName) + { + view = FileService.OpenFile(fileName); + RefactoringDocument = LoadDocument(); + } + + IRefactoringDocument LoadDocument() + { + var textEditorProvider = view as ITextEditorProvider; + return new RefactoringDocumentAdapter(new ThreadSafeDocument(textEditorProvider.TextEditor.Document)); + } + + public IRefactoringDocument RefactoringDocument { get; private set; } + + public ICompilationUnit Parse() + { + if (WorkbenchSingleton.InvokeRequired) { + return WorkbenchSingleton.SafeThreadFunction(() => Parse()); + } + return ParserService.ParseViewContent(view).CompilationUnit; + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/ThreadSafeDocument.cs b/src/AddIns/Misc/PackageManagement/Project/Src/ThreadSafeDocument.cs index 83e41bdf6f..07692155bf 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/ThreadSafeDocument.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/ThreadSafeDocument.cs @@ -36,7 +36,10 @@ namespace ICSharpCode.PackageManagement public int TotalNumberOfLines { get { - throw new NotImplementedException(); + if (WorkbenchSingleton.InvokeRequired) { + return WorkbenchSingleton.SafeThreadFunction(() => TotalNumberOfLines); + } + return document.TotalNumberOfLines; } } @@ -48,13 +51,19 @@ namespace ICSharpCode.PackageManagement public int TextLength { get { - throw new NotImplementedException(); + if (WorkbenchSingleton.InvokeRequired) { + return WorkbenchSingleton.SafeThreadFunction(() => TextLength); + } + return document.TextLength; } } public IDocumentLine GetLine(int lineNumber) { - throw new NotImplementedException(); + if (WorkbenchSingleton.InvokeRequired) { + return WorkbenchSingleton.SafeThreadFunction(() => GetLine(lineNumber)); + } + return new ThreadSafeDocumentLine(document.GetLine(lineNumber)); } public IDocumentLine GetLineForOffset(int offset) @@ -66,9 +75,8 @@ namespace ICSharpCode.PackageManagement { if (WorkbenchSingleton.InvokeRequired) { return WorkbenchSingleton.SafeThreadFunction(() => PositionToOffset(line, column)); - } else { - return document.PositionToOffset(line, column); } + return document.PositionToOffset(line, column); } public Location OffsetToPosition(int offset) @@ -78,7 +86,11 @@ namespace ICSharpCode.PackageManagement public void Insert(int offset, string text) { - throw new NotImplementedException(); + if (WorkbenchSingleton.InvokeRequired) { + WorkbenchSingleton.SafeThreadAsyncCall(() => Insert(offset, text)); + } else { + document.Insert(offset, text); + } } public void Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType) @@ -88,7 +100,11 @@ namespace ICSharpCode.PackageManagement public void Remove(int offset, int length) { - throw new NotImplementedException(); + if (WorkbenchSingleton.InvokeRequired) { + WorkbenchSingleton.SafeThreadAsyncCall(() => Remove(offset, length)); + } else { + document.Remove(offset, length); + } } public void Replace(int offset, int length, string newText) diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/ThreadSafeDocumentLine.cs b/src/AddIns/Misc/PackageManagement/Project/Src/ThreadSafeDocumentLine.cs new file mode 100644 index 0000000000..060c307895 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/ThreadSafeDocumentLine.cs @@ -0,0 +1,70 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Gui; + +namespace ICSharpCode.PackageManagement +{ + public class ThreadSafeDocumentLine : IDocumentLine + { + IDocumentLine line; + + public ThreadSafeDocumentLine(IDocumentLine line) + { + this.line = line; + } + + public int Offset { + get { + if (WorkbenchSingleton.InvokeRequired) { + return WorkbenchSingleton.SafeThreadFunction(() => Offset); + } + return line.Offset; + } + } + + public int Length { + get { + if (WorkbenchSingleton.InvokeRequired) { + return WorkbenchSingleton.SafeThreadFunction(() => Length); + } + return line.Length; + } + } + + public int EndOffset { + get { + throw new NotImplementedException(); + } + } + + public int TotalLength { + get { + throw new NotImplementedException(); + } + } + + public int DelimiterLength { + get { + throw new NotImplementedException(); + } + } + + public int LineNumber { + get { + throw new NotImplementedException(); + } + } + + public string Text { + get { + if (WorkbenchSingleton.InvokeRequired) { + return WorkbenchSingleton.SafeThreadFunction(() => Text); + } + return line.Text; + } + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj index 8d6ceaaf0b..1ac538f032 100644 --- a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj +++ b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj @@ -72,6 +72,8 @@ Properties\GlobalAssemblyInfo.cs + + @@ -93,6 +95,8 @@ + + @@ -306,6 +310,10 @@ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1} ICSharpCode.AvalonEdit + + {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} + NRefactory + {2748AD25-9C63-4E12-877B-4DCE96FBED54} ICSharpCode.SharpDevelop diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/ClassCodeGeneratorTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/ClassCodeGeneratorTests.cs new file mode 100644 index 0000000000..582e874257 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/ClassCodeGeneratorTests.cs @@ -0,0 +1,179 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.NRefactory.Ast; +using ICSharpCode.PackageManagement; +using ICSharpCode.PackageManagement.EnvDTE; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Dom.Refactoring; +using NUnit.Framework; +using PackageManagement.Tests.Helpers; +using Rhino.Mocks; + +namespace PackageManagement.Tests +{ + [TestFixture] + public class ClassCodeGeneratorTests + { + ClassHelper helper; + ClassCodeGenerator codeGenerator; + CodeVariable codeVariable; + IDocumentLoader documentLoader; + IRefactoringDocument document; + FakeCodeGenerator fakeCodeGenerator; + IRefactoringDocumentView documentView; + + [SetUp] + public void Init() + { + helper = new ClassHelper(); + document = MockRepository.GenerateStub(); + documentView = MockRepository.GenerateStub(); + documentLoader = MockRepository.GenerateStub(); + fakeCodeGenerator = helper.CompilationUnitHelper.FakeCodeGenerator; + } + + void CreateClass(string name) + { + helper.CreatePublicClass(name); + } + + void CreateCodeGenerator() + { + codeGenerator = new ClassCodeGenerator(helper.Class, documentLoader); + } + + void SetClassFileName(string fileName) + { + helper.SetClassFileName(fileName); + } + + void SetDocumentFileName(string fileName) + { + documentView.Stub(view => view.RefactoringDocument).Return(document); + documentLoader.Stub(loader => loader.LoadRefactoringDocumentView(fileName)).Return(documentView); + } + + void AddFieldToClassForReparse(string name) + { + AddFieldToClassForReparse(name, DomRegion.Empty); + } + + void AddFieldToClassForReparse(string name, DomRegion region) + { + ClassHelper helper = CreateClassHelper("MyClass"); + helper.AddFieldToClass(name, region); + AddClassesToReparsedCompilationUnit(helper); + } + + void AddFieldsToClassForReparse(params string[] names) + { + ClassHelper helper = CreateClassHelper("MyClass"); + foreach (string name in names) { + helper.AddFieldToClass(name); + } + AddClassesToReparsedCompilationUnit(helper); + } + + void AddClassesToReparsedCompilationUnit(params ClassHelper[] classHelpers) + { + var compilationUnitHelper = new CompilationUnitHelper(); + foreach (ClassHelper helper in classHelpers) { + compilationUnitHelper.AddClass(helper.Class); + } + documentView.Stub(d => d.Parse()).Return(compilationUnitHelper.CompilationUnit); + } + + ClassHelper CreateClassHelper(string name) + { + var helper = new ClassHelper(); + helper.CreateClass(name); + return helper; + } + + void AddPublicVariable(string name, string type) + { + codeVariable = codeGenerator.AddPublicVariable(name, type); + } + + [Test] + public void AddPublicVariable_VariableNameAndTypeIsString_ReturnsCodeVariable() + { + CreateClass("MyClass"); + CreateCodeGenerator(); + string fileName = @"d:\projects\myproject\MyClass.cs"; + SetClassFileName(fileName); + SetDocumentFileName(fileName); + AddFieldToClassForReparse("MyClass.MyVariable", new DomRegion(1, 2, 1, 5)); + + AddPublicVariable("MyVariable", "System.String"); + + TextPoint start = codeVariable.GetStartPoint(); + TextPoint end = codeVariable.GetEndPoint(); + Assert.AreEqual("MyVariable", codeVariable.Name); + Assert.AreEqual(1, start.Line); + Assert.AreEqual(2, start.LineCharOffset); + Assert.AreEqual(1, end.Line); + Assert.AreEqual(5, end.LineCharOffset); + } + + [Test] + public void AddPublicVariable_VariableNameAndTypeIsCustomType_CodeForFieldAddedAtEndOfClass() + { + CreateClass("MyClass"); + CreateCodeGenerator(); + var classRegion = new DomRegion(1, 2, 3, 4); + helper.SetClassRegion(classRegion); + string fileName = @"d:\projects\myproject\MyClass.cs"; + SetClassFileName(fileName); + SetDocumentFileName(fileName); + AddFieldToClassForReparse("MyClass.MyVariable"); + + AddPublicVariable("MyVar", "MyType"); + + FieldDeclaration field = fakeCodeGenerator.NodePassedToInsertCodeAtEnd as FieldDeclaration; + Assert.AreEqual(classRegion, fakeCodeGenerator.RegionPassedToInsertCodeAtEnd); + Assert.AreEqual(document, fakeCodeGenerator.DocumentPassedToInsertCodeAtEnd); + Assert.AreEqual(Modifiers.Public, field.Modifier); + Assert.AreEqual("MyType", field.TypeReference.Type); + Assert.AreEqual("MyVar", field.Fields[0].Name); + } + + [Test] + public void AddPublicVariable_ReparsedClassHasTwoFields_LastFieldReturned() + { + CreateClass("MyClass"); + CreateCodeGenerator(); + string fileName = @"d:\projects\myproject\MyClass.cs"; + SetClassFileName(fileName); + SetDocumentFileName(fileName); + AddFieldsToClassForReparse("MyClass.First", "MyClass.MyVariable"); + + AddPublicVariable("MyVariable", "System.String"); + + Assert.AreEqual("MyVariable", codeVariable.Name); + } + + [Test] + public void AddPublicVariable_ReparsedCompilationUnitHasThreeClasses_VariableReturnedFromCorrectClass() + { + CreateClass("MyClass2"); + CreateCodeGenerator(); + string fileName = @"d:\projects\myproject\MyClass2.cs"; + SetClassFileName(fileName); + SetDocumentFileName(fileName); + ClassHelper class1 = CreateClassHelper("MyClass1"); + ClassHelper class2 = CreateClassHelper("MyClass2"); + ClassHelper class3 = CreateClassHelper("MyClass3"); + + class2.AddFieldToClass("MyClass2.MyVariable"); + + AddClassesToReparsedCompilationUnit(class1, class2, class3); + + AddPublicVariable("MyVariable", "System.String"); + + Assert.AreEqual("MyVariable", codeVariable.Name); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/CodeGeneratorTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/CodeGeneratorTests.cs new file mode 100644 index 0000000000..89b0dcdcdc --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/CodeGeneratorTests.cs @@ -0,0 +1,38 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using ICSharpCode.NRefactory.Ast; +using ICSharpCode.SharpDevelop.Dom.Refactoring; +using NUnit.Framework; + +namespace PackageManagement.Tests +{ + [TestFixture] + public class CodeGeneratorTests + { + CSharpCodeGenerator codeGenerator; + + void CreateCodeGenerator() + { + codeGenerator = new CSharpCodeGenerator(); + } + + [Test] + public void GenerateCode_Field_CreatesField() + { + CreateCodeGenerator(); + var field = new FieldDeclaration(new List()); + field.TypeReference = new TypeReference("MyClass"); + field.Modifier = Modifiers.Public; + field.Fields.Add(new VariableDeclaration("myField")); + + string code = codeGenerator.GenerateCode(field, String.Empty); + + string expectedCode = "public MyClass myField;\r\n"; + + Assert.AreEqual(expectedCode, code); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/EditPointTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/EditPointTests.cs index 621e51c8f9..98d8b22316 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/EditPointTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/EditPointTests.cs @@ -5,7 +5,7 @@ using System; using ICSharpCode.PackageManagement; using ICSharpCode.PackageManagement.EnvDTE; using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Dom.Refactoring; using NUnit.Framework; using PackageManagement.Tests.Helpers; using Rhino.Mocks; @@ -19,7 +19,7 @@ namespace PackageManagement.Tests.EnvDTE MethodHelper methodHelper; TextPoint endPoint; EditPoint editPoint; - IDocument document; + IRefactoringDocument document; IDocumentLoader documentLoader; [SetUp] @@ -32,7 +32,7 @@ namespace PackageManagement.Tests.EnvDTE void CreateDocumentLoader() { - document = MockRepository.GenerateStub(); + document = MockRepository.GenerateStub(); documentLoader = MockRepository.GenerateStub(); } @@ -79,7 +79,7 @@ namespace PackageManagement.Tests.EnvDTE void DocumentFileName(string fileName) { - documentLoader.Stub(loader => loader.LoadDocument(fileName)).Return(document); + documentLoader.Stub(loader => loader.LoadRefactoringDocument(fileName)).Return(document); } [Test] diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ClassHelper.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ClassHelper.cs index 0371450abd..8e16fa91d2 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ClassHelper.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ClassHelper.cs @@ -12,6 +12,7 @@ namespace PackageManagement.Tests.Helpers { public IClass Class; public ProjectContentHelper ProjectContentHelper = new ProjectContentHelper(); + public CompilationUnitHelper CompilationUnitHelper = new CompilationUnitHelper(); List methods = new List(); List properties = new List(); @@ -28,6 +29,7 @@ namespace PackageManagement.Tests.Helpers Class.Stub(c => c.Methods).Return(methods); Class.Stub(c => c.Properties).Return(properties); Class.Stub(c => c.Fields).Return(fields); + Class.Stub(c => c.CompilationUnit).Return(CompilationUnitHelper.CompilationUnit); } public void AddAttributeToClass(string name) @@ -114,10 +116,16 @@ namespace PackageManagement.Tests.Helpers /// Name should include the class prefix (e.g. "Class1.MyField"); /// public void AddFieldToClass(string fullyQualifiedName) + { + AddFieldToClass(fullyQualifiedName, DomRegion.Empty); + } + + public void AddFieldToClass(string fullyQualifiedName, DomRegion region) { var helper = new FieldHelper(); helper.ProjectContentHelper = ProjectContentHelper; helper.CreateField(fullyQualifiedName); + helper.SetRegion(region); fields.Add(helper.Field); } @@ -126,5 +134,15 @@ namespace PackageManagement.Tests.Helpers { Class.Stub(c => c.Namespace).Return(name); } + + public void SetClassRegion(DomRegion classRegion) + { + Class.Stub(c => c.Region).Return(classRegion); + } + + public void SetClassFileName(string fileName) + { + CompilationUnitHelper.SetFileName(fileName); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/CompilationUnitHelper.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/CompilationUnitHelper.cs new file mode 100644 index 0000000000..c4257fa6d5 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/CompilationUnitHelper.cs @@ -0,0 +1,36 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using ICSharpCode.SharpDevelop.Dom; +using Rhino.Mocks; + +namespace PackageManagement.Tests.Helpers +{ + public class CompilationUnitHelper + { + public ICompilationUnit CompilationUnit; + public FakeCodeGenerator FakeCodeGenerator = new FakeCodeGenerator(); + public List Classes = new List(); + + public CompilationUnitHelper() + { + CompilationUnit = MockRepository.GenerateStub(); + LanguageProperties language = MockRepository.GenerateStub(StringComparer.InvariantCultureIgnoreCase); + language.Stub(lang => lang.CodeGenerator).Return(FakeCodeGenerator); + CompilationUnit.Stub(unit => unit.Language).Return(language); + CompilationUnit.Stub(unit => unit.Classes).Return(Classes); + } + + public void SetFileName(string fileName) + { + CompilationUnit.FileName = fileName; + } + + public void AddClass(IClass c) + { + Classes.Add(c); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeCodeGenerator.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeCodeGenerator.cs new file mode 100644 index 0000000000..a9d25b8118 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeCodeGenerator.cs @@ -0,0 +1,34 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Linq; +using ICSharpCode.NRefactory.Ast; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Dom.Refactoring; + +namespace PackageManagement.Tests.Helpers +{ + public class FakeCodeGenerator : CodeGenerator + { + public FakeCodeGenerator() + { + } + + public override string GenerateCode(AbstractNode node, string indentation) + { + throw new NotImplementedException(); + } + + public DomRegion RegionPassedToInsertCodeAtEnd; + public IRefactoringDocument DocumentPassedToInsertCodeAtEnd; + public AbstractNode NodePassedToInsertCodeAtEnd; + + public override void InsertCodeAtEnd(DomRegion region, IRefactoringDocument document, params AbstractNode[] nodes) + { + RegionPassedToInsertCodeAtEnd = region; + DocumentPassedToInsertCodeAtEnd = document; + NodePassedToInsertCodeAtEnd = nodes.FirstOrDefault(); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FieldHelper.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FieldHelper.cs index b40a148c67..c2a20d2c3e 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FieldHelper.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FieldHelper.cs @@ -67,9 +67,9 @@ namespace PackageManagement.Tests.Helpers public void SetCompilationUnitFileName(string fileName) { - ICompilationUnit unit = MockRepository.GenerateStub(); - unit.FileName = fileName; - Field.Stub(f => f.CompilationUnit).Return(unit); + var helper = new CompilationUnitHelper(); + helper.SetFileName(fileName); + Field.Stub(f => f.CompilationUnit).Return(helper.CompilationUnit); } } }