Browse Source

fix XAML binding unit tests

pull/32/merge
Siegfried Pammer 13 years ago
parent
commit
df360130fc
  1. 27
      SharpDevelop.Tests.sln
  2. 43
      src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/CodeCompletionTests.cs
  3. 60
      src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/MockTextEditor.cs
  4. 105
      src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/ResolveContextTests.cs
  5. 83
      src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/TextEditorBasedTests.cs
  6. 35
      src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/UtilsTests.cs
  7. 17
      src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/XamlBinding.Tests.csproj
  8. 42
      src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/XamlExpressionFinderTests.cs
  9. 42
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs
  10. 4
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj
  11. 4
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCodeCompletionBinding.cs
  12. 8
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContextResolver.cs
  13. 1
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs
  14. 39
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlResolver.cs

27
SharpDevelop.Tests.sln

@ -85,6 +85,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Scripting", "sr @@ -85,6 +85,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Scripting", "sr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Scripting.Tests", "src\AddIns\BackendBindings\Scripting\Test\ICSharpCode.Scripting.Tests.csproj", "{85C09AD8-183B-403A-869A-7226646218A9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlBinding.Tests", "src\AddIns\BackendBindings\XamlBinding\XamlBinding.Tests\XamlBinding.Tests.csproj", "{CAD4D128-5A67-444B-88AE-37E0AF79C57E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{F3662720-9EA2-4591-BBC6-97361DCE50A9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelpViewer", "src\AddIns\Misc\HelpViewer\HelpViewer.csproj", "{80F76D10-0B44-4D55-B4BD-DAEB5464090C}"
@ -769,6 +771,14 @@ Global @@ -769,6 +771,14 @@ Global
{85226AFB-CE71-4851-9A75-7EEC663A8E8A}.Release|Any CPU.Build.0 = Release|Any CPU
{85226AFB-CE71-4851-9A75-7EEC663A8E8A}.Release|x86.ActiveCfg = Release|Any CPU
{85226AFB-CE71-4851-9A75-7EEC663A8E8A}.Release|x86.Build.0 = Release|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Debug|x86.ActiveCfg = Debug|x86
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Debug|x86.Build.0 = Debug|x86
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Release|Any CPU.Build.0 = Release|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Release|x86.ActiveCfg = Release|x86
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Release|x86.Build.0 = Release|x86
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Debug|x86.ActiveCfg = Debug|Any CPU
@ -873,14 +883,14 @@ Global @@ -873,14 +883,14 @@ Global
{3DF4060F-5EE0-41CF-8096-F27355FD5511}.Release|Any CPU.Build.0 = Release|Any CPU
{3DF4060F-5EE0-41CF-8096-F27355FD5511}.Release|x86.ActiveCfg = Release|Any CPU
{3DF4060F-5EE0-41CF-8096-F27355FD5511}.Release|x86.Build.0 = Release|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Debug|x86.ActiveCfg = Debug|x86
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Debug|x86.Build.0 = Debug|x86
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Release|Any CPU.Build.0 = Release|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Release|x86.ActiveCfg = Release|x86
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Release|x86.Build.0 = Release|x86
{CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Debug|x86.ActiveCfg = Debug|x86
{CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Debug|x86.Build.0 = Debug|x86
{CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Release|Any CPU.Build.0 = Release|Any CPU
{CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Release|x86.ActiveCfg = Release|x86
{CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -923,6 +933,7 @@ Global @@ -923,6 +933,7 @@ Global
{388E7B64-0393-4EB4-A3E3-5C474F141853} = {E0646C25-36F2-4524-969F-FA621353AB94}
{7048AE18-EB93-4A84-82D0-DD60EB58ADBD} = {E0646C25-36F2-4524-969F-FA621353AB94}
{85C09AD8-183B-403A-869A-7226646218A9} = {E0646C25-36F2-4524-969F-FA621353AB94}
{CAD4D128-5A67-444B-88AE-37E0AF79C57E} = {E0646C25-36F2-4524-969F-FA621353AB94}
{F3662720-9EA2-4591-BBC6-97361DCE50A9} = {39327899-ED91-4F7F-988C-4FE4E17C014D}
{80F76D10-0B44-4D55-B4BD-DAEB5464090C} = {F3662720-9EA2-4591-BBC6-97361DCE50A9}
{9196DD8A-B4D4-4780-8742-C5762E547FC2} = {F3662720-9EA2-4591-BBC6-97361DCE50A9}

43
src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/CodeCompletionTests.cs

@ -6,8 +6,17 @@ using System.Collections.Generic; @@ -6,8 +6,17 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Workbench;
using NUnit.Framework;
using Rhino.Mocks;
namespace ICSharpCode.XamlBinding.Tests
{
@ -834,8 +843,12 @@ namespace ICSharpCode.XamlBinding.Tests @@ -834,8 +843,12 @@ namespace ICSharpCode.XamlBinding.Tests
});
}
[Test]
public void InCommentPressTest()
static readonly object[] KeyTestData = {
'<', '.', ':', '/', 'a'
};
[Test, TestCaseSourceAttribute("KeyTestData")]
public void InCommentPressTest(char key)
{
string fileHeader = @"<Window x:Class='ICSharpCode.XamlBinding.Tests.CompletionTestsBase'
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
@ -846,15 +859,11 @@ namespace ICSharpCode.XamlBinding.Tests @@ -846,15 +859,11 @@ namespace ICSharpCode.XamlBinding.Tests
</Grid>
</Window>";
TestKeyPress(fileHeader, fileFooter, '<', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, '.', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, ':', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, '/', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, 'a', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, key, CodeCompletionKeyPressResult.None, list => {});
}
[Test]
public void InCDataPressTest()
[Test, TestCaseSourceAttribute("KeyTestData")]
public void InCDataPressTest(char key)
{
string fileHeader = @"<Window x:Class='ICSharpCode.XamlBinding.Tests.CompletionTestsBase'
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
@ -865,15 +874,11 @@ namespace ICSharpCode.XamlBinding.Tests @@ -865,15 +874,11 @@ namespace ICSharpCode.XamlBinding.Tests
</Grid>
</Window>";
TestKeyPress(fileHeader, fileFooter, '<', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, '.', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, ':', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, '/', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, 'a', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, key, CodeCompletionKeyPressResult.None, list => {});
}
[Test]
public void InPlainTextPressTest()
[Test, TestCaseSourceAttribute("KeyTestData")]
public void InPlainTextPressTest(char key)
{
string fileHeader = @"<Window x:Class='ICSharpCode.XamlBinding.Tests.CompletionTestsBase'
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
@ -884,11 +889,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -884,11 +889,7 @@ namespace ICSharpCode.XamlBinding.Tests
</Grid>
</Window>";
TestKeyPress(fileHeader, fileFooter, '.', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, ':', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, '/', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, 'a', CodeCompletionKeyPressResult.None, list => {});
TestKeyPress(fileHeader, fileFooter, '<', CodeCompletionKeyPressResult.Completed, list => {});
TestKeyPress(fileHeader, fileFooter, key, key == '<' ? CodeCompletionKeyPressResult.Completed : CodeCompletionKeyPressResult.None, list => {});
}
#endregion
}

60
src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/MockTextEditor.cs

@ -3,14 +3,14 @@ @@ -3,14 +3,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.AvalonEdit;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using System.Diagnostics;
using ICSharpCode.SharpDevelop.Parser;
namespace ICSharpCode.XamlBinding.Tests
{
@ -22,52 +22,23 @@ namespace ICSharpCode.XamlBinding.Tests @@ -22,52 +22,23 @@ namespace ICSharpCode.XamlBinding.Tests
/// </summary>
public class MockTextEditor : AvalonEditTextEditorAdapter
{
DefaultProjectContent pc;
XamlLanguageBinding langBinding;
public MockTextEditor()
: base(new TextEditor())
{
PropertyService.InitializeServiceForUnitTests();
pc = new DefaultProjectContent();
pc.ReferencedContents.Add(AssemblyParserService.DefaultProjectContentRegistry.Mscorlib);
Dictionary<string, string> referencedAssemblies = new Dictionary<string, string>() {
{ "System", typeof(Uri).Assembly.Location },
{ "System.Xml", typeof(System.Xml.XmlDocument).Assembly.Location },
{ "System.Xaml", typeof(System.Xaml.XamlReader).Assembly.Location },
{ "WindowsBase", typeof(System.Windows.Media.Matrix).Assembly.Location },
{ "System.Core", typeof(System.Linq.Enumerable).Assembly.Location },
{ "PresentationCore", typeof(System.Windows.Media.Brush).Assembly.Location },
{ "PresentationFramework", typeof(System.Windows.EventSetter).Assembly.Location }
};
foreach (var assembly in referencedAssemblies) {
IProjectContent referenceProjectContent = AssemblyParserService.DefaultProjectContentRegistry.GetProjectContentForReference(assembly.Key, assembly.Value ?? assembly.Key);
if (referenceProjectContent == null)
throw new Exception("Error loading " + assembly.Key);
pc.ReferencedContents.Add(referenceProjectContent);
if (referenceProjectContent is ReflectionProjectContent) {
(referenceProjectContent as ReflectionProjectContent).InitializeReferences();
}
}
// this.TextEditor.TextArea.TextView.Services.AddService(typeof(ISyntaxHighlighter), new AvalonEditSyntaxHighlighterAdapter(this.TextEditor));
this.TextEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("XML");
new XamlLanguageBinding().Attach(this);
this.langBinding = new XamlLanguageBinding();
this.TextEditor.TextArea.TextView.Services.AddService(typeof(XamlLanguageBinding), langBinding);
}
public override FileName FileName {
get { return new FileName("mockFileName.xaml"); }
}
public void CreateParseInformation()
public ParseInformation CreateParseInformation()
{
ParserService.RegisterAvailableParsers(new ParserDescriptor(typeof(XamlParser), "XAML", new string[] { ".xaml" }));
var parser = new XamlBinding.XamlParser();
parser.LexerTags = new string[0];
var cu = parser.Parse(pc, this.FileName, this.Document);
ParserService.RegisterParseInformation(this.FileName, cu);
pc.UpdateCompilationUnit(null, cu, this.FileName);
var parser = new XamlParser();
return parser.Parse(this.FileName, this.Document, true, null, CancellationToken.None);
}
ICompletionItemList lastCompletionItemList;
@ -82,17 +53,18 @@ namespace ICSharpCode.XamlBinding.Tests @@ -82,17 +53,18 @@ namespace ICSharpCode.XamlBinding.Tests
return null;
}
IEnumerable<IInsightItem> lastInsightItems;
public IEnumerable<IInsightItem> LastInsightItems {
get { return lastInsightItems; }
public override ICSharpCode.SharpDevelop.ILanguageBinding Language {
get {
return langBinding;
}
}
IList<IInsightItem> lastInsightItemList = null;
public override IInsightWindow ShowInsightWindow(IEnumerable<IInsightItem> items)
{
this.lastInsightItems = items;
this.lastInsightItemList = items.ToList();
return null;
}
}
}

105
src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/ResolveContextTests.cs

@ -3,21 +3,61 @@ @@ -3,21 +3,61 @@
using System;
using System.Linq;
using System.Threading;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Workbench;
using ICSharpCode.XmlEditor;
using NUnit.Framework;
using System.IO;
using Rhino.Mocks;
namespace ICSharpCode.XamlBinding.Tests
{
[TestFixture]
public class ResolveContextTests
[RequiresSTA]
public class ResolveContextTests : TextEditorBasedTests
{
void SetUpWithCode(FileName fileName, ITextSource textSource)
{
IProject project = MockRepository.GenerateStrictMock<IProject>();
var parseInfo = new XamlParser() { TaskListTokens = TaskListTokens }.Parse(fileName, textSource, true, project, CancellationToken.None);
var pc = new CSharpProjectContent().AddOrUpdateFiles(parseInfo.UnresolvedFile);
pc = pc.AddAssemblyReferences(new[] { Corlib, PresentationCore, PresentationFramework, SystemXaml });
var compilation = pc.CreateCompilation();
SD.Services.AddService(typeof(IParserService), MockRepository.GenerateStrictMock<IParserService>());
SD.ParserService.Stub(p => p.GetCachedParseInformation(fileName)).Return(parseInfo);
SD.ParserService.Stub(p => p.GetCompilation(project)).Return(compilation);
SD.ParserService.Stub(p => p.GetCompilationForFile(fileName)).Return(compilation);
SD.ParserService.Stub(p => p.Parse(fileName, textSource)).WhenCalled(
i => {
i.ReturnValue = new XamlParser() { TaskListTokens = TaskListTokens }.Parse(fileName, textSource, true, project, CancellationToken.None);
}).Return(parseInfo); // fake Return to make it work
SD.Services.AddService(typeof(IFileService), MockRepository.GenerateStrictMock<IFileService>());
IViewContent view = MockRepository.GenerateStrictMock<IViewContent>();
SD.FileService.Stub(f => f.OpenFile(fileName, false)).Return(view);
}
XamlContext TestContext(string xaml, int offset)
{
var fileName = new FileName("test.xaml");
var textSource = new StringTextSource(xaml);
SetUpWithCode(fileName, textSource);
return XamlContextResolver.ResolveContext(fileName, textSource, offset);
}
[Test]
public void ContextNoneDescriptionTest()
{
string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n</Grid>";
int offset = "<Grid>\n".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.None, context.Description);
}
@ -27,7 +67,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -27,7 +67,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n</Grid>";
int offset = "<Grid>".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.None, context.Description);
}
@ -37,7 +77,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -37,7 +77,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n</Grid>";
int offset = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.None, context.Description);
}
@ -47,7 +87,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -47,7 +87,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n</Grid>";
int offset = "<G".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.AtTag, context.Description);
}
@ -57,7 +97,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -57,7 +97,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" /> <\n</Grid>";
int offset = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" /> <".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.AtTag, context.Description);
}
@ -67,7 +107,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -67,7 +107,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n</Grid>";
int offset = "<Grid>\n".Length + 10;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.AtTag, context.Description);
}
@ -77,7 +117,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -77,7 +117,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = "<Grid>\n\t<\n</Grid>";
int offset = "<Grid>\n\t<".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.AtTag, context.Description);
}
@ -87,7 +127,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -87,7 +127,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n</Grid>";
int offset = "<Grid>\n".Length + 26;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InTag, context.Description);
}
@ -114,7 +154,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -114,7 +154,7 @@ namespace ICSharpCode.XamlBinding.Tests
<StackPanel>
<RadioButton ".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InTag, context.Description);
}
@ -142,7 +182,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -142,7 +182,7 @@ namespace ICSharpCode.XamlBinding.Tests
<RadioButton
</Stack".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.AtTag, context.Description);
}
@ -153,7 +193,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -153,7 +193,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = "<Grid>\n\t<Grid.ColumnDefinitions />\n</Grid>";
int offset = "<Grid>\n".Length + 12;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual("Grid.ColumnDefinitions", context.ActiveElement.Name);
}
@ -163,7 +203,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -163,7 +203,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = File.ReadAllText("Test4.xaml");
int offset = 413;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.AtTag, context.Description);
}
@ -174,7 +214,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -174,7 +214,7 @@ namespace ICSharpCode.XamlBinding.Tests
string xaml = "<Test attr=\"{Test}\" />";
int offset = "<Test attr=\"{Te".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InMarkupExtension, context.Description);
}
@ -185,7 +225,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -185,7 +225,7 @@ namespace ICSharpCode.XamlBinding.Tests
string xaml = "<Test attr=\"Test\" />";
int offset = "<Test attr=\"Te".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description);
}
@ -196,7 +236,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -196,7 +236,7 @@ namespace ICSharpCode.XamlBinding.Tests
string xaml = "<Test attr=\"{}{Test}\" />";
int offset = "<Test attr=\"{}{Te".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description);
}
@ -207,7 +247,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -207,7 +247,7 @@ namespace ICSharpCode.XamlBinding.Tests
string xaml = "<Test attr=\"Test />";
int offset = "<Test attr=\"Te".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description);
}
@ -218,7 +258,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -218,7 +258,7 @@ namespace ICSharpCode.XamlBinding.Tests
string xaml = "<Test attr=\"Test />";
int offset = "<Test attr=\"".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description);
}
@ -228,7 +268,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -228,7 +268,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = File.ReadAllText("Test1.xaml");
int offset = 272;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual("CheckBox", context.ActiveElement.Name);
Assert.AreEqual("Grid", context.ParentElement.Name);
@ -239,7 +279,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -239,7 +279,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = File.ReadAllText("Test4.xaml");
int offset = 413;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual("Grid", context.ActiveElement.Name);
Assert.AreEqual("Grid", context.ParentElement.Name);
@ -250,7 +290,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -250,7 +290,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = File.ReadAllText("Test1.xaml");
int offset = 31;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual("Window", context.ActiveElement.Name);
Assert.AreEqual(null, context.ParentElement);
@ -261,7 +301,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -261,7 +301,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = File.ReadAllText("Test2.xaml");
int offset = 447;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(1, context.IgnoredXmlns.Count);
Assert.AreEqual("d", context.IgnoredXmlns[0]);
@ -272,7 +312,7 @@ namespace ICSharpCode.XamlBinding.Tests @@ -272,7 +312,7 @@ namespace ICSharpCode.XamlBinding.Tests
{
string xaml = File.ReadAllText("Test5.xaml");
int offset = 881;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset);
XamlContext context = TestContext(xaml, offset);
string[] ancestors = new string[] {
"DoubleAnimation", "Storyboard",
@ -286,5 +326,24 @@ namespace ICSharpCode.XamlBinding.Tests @@ -286,5 +326,24 @@ namespace ICSharpCode.XamlBinding.Tests
Assert.AreEqual(8, context.Ancestors.Count);
Assert.AreEqual(ancestors, context.Ancestors.Select(item => item.Name).ToArray());
}
[Test]
public void InValueTestWithOpenValue()
{
string fileHeader = @"<Window x:Class='ICSharpCode.XamlBinding.Tests.CompletionTestsBase'
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width='";
string fileFooter = @"
<Button AllowDrop='True' Grid.Row='0' />
</Grid>
</Window>";
XamlContext context = TestContext(fileHeader + fileFooter, fileHeader.Length);
Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description);
}
}
}

83
src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/TextEditorBasedTests.cs

@ -1,10 +1,24 @@ @@ -1,10 +1,24 @@
// 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 ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using System;
using ICSharpCode.SharpDevelop.Dom;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Workbench;
using NUnit.Framework;
using Rhino.Mocks;
namespace ICSharpCode.XamlBinding.Tests
{
@ -12,33 +26,67 @@ namespace ICSharpCode.XamlBinding.Tests @@ -12,33 +26,67 @@ namespace ICSharpCode.XamlBinding.Tests
{
protected MockTextEditor textEditor;
protected static readonly IReadOnlyList<string> TaskListTokens = new List<string> {
"TODO", "HACK", "FIXME"
};
[SetUp]
public void SetupTest()
{
this.textEditor = new MockTextEditor();
SD.InitializeForUnitTests();
textEditor = new MockTextEditor();
}
protected void TestCtrlSpace(string fileHeader, string fileFooter, bool expected, Action<ICompletionItemList> constraint)
[TearDown]
public void TearDownTest()
{
this.textEditor.Document.Text = fileHeader + fileFooter;
this.textEditor.Caret.Offset = fileHeader.Length;
this.textEditor.CreateParseInformation();
SD.TearDownForUnitTests();
}
bool invoked = new XamlCodeCompletionBinding().CtrlSpace(textEditor);
protected static readonly IUnresolvedAssembly Corlib = new CecilLoader().LoadAssemblyFile(typeof(object).Assembly.Location);
protected static readonly IUnresolvedAssembly PresentationCore = new CecilLoader().LoadAssemblyFile(typeof(System.Windows.UIElement).Assembly.Location);
protected static readonly IUnresolvedAssembly PresentationFramework = new CecilLoader().LoadAssemblyFile(typeof(System.Windows.Application).Assembly.Location);
protected static readonly IUnresolvedAssembly SystemXaml = new CecilLoader().LoadAssemblyFile(typeof(System.Xaml.XamlException).Assembly.Location);
Assert.AreEqual(expected, invoked);
ICompletionItemList list = this.textEditor.LastCompletionItemList;
void SetUpWithCode(string code, int offset)
{
textEditor.Document.Text = code;
textEditor.Caret.Offset = offset;
var parseInfo = textEditor.CreateParseInformation();
IProject project = MockRepository.GenerateStrictMock<IProject>();
var pc = new CSharpProjectContent().AddOrUpdateFiles(parseInfo.UnresolvedFile);
pc = pc.AddAssemblyReferences(new[] { Corlib, PresentationCore, PresentationFramework, SystemXaml });
var compilation = pc.CreateCompilation();
SD.Services.AddService(typeof(IParserService), MockRepository.GenerateStrictMock<IParserService>());
SD.ParserService.Stub(p => p.GetCachedParseInformation(textEditor.FileName)).Return(parseInfo);
SD.ParserService.Stub(p => p.GetCompilation(project)).Return(compilation);
SD.ParserService.Stub(p => p.GetCompilationForFile(textEditor.FileName)).Return(compilation);
SD.ParserService.Stub(p => p.Parse(textEditor.FileName, textEditor.Document)).WhenCalled(
i => {
var p = new XamlParser();
p.TaskListTokens = TaskListTokens;
i.ReturnValue = p.Parse(textEditor.FileName, textEditor.Document, true, project, CancellationToken.None);
}).Return(parseInfo); // fake Return to make it work
SD.Services.AddService(typeof(IFileService), MockRepository.GenerateStrictMock<IFileService>());
IViewContent view = MockRepository.GenerateStrictMock<IViewContent>();
view.Stub(v => v.GetService(typeof(ITextEditor))).Return(textEditor);
SD.FileService.Stub(f => f.OpenFile(textEditor.FileName, false)).Return(view);
}
protected void TestCtrlSpace(string fileHeader, string fileFooter, bool expected, Action<ICompletionItemList> constraint)
{
SetUpWithCode(fileHeader + fileFooter, fileHeader.Length);
bool invoked = new XamlCodeCompletionBinding().CtrlSpace(textEditor);
Assert.AreEqual(expected, invoked);
ICompletionItemList list = textEditor.LastCompletionItemList;
Assert.NotNull(list);
constraint(list);
}
protected void TestKeyPress(string fileHeader, string fileFooter, char keyPressed, CodeCompletionKeyPressResult keyPressResult, Action<ICompletionItemList> constraint)
{
this.textEditor.Document.Text = fileHeader + fileFooter;
this.textEditor.Caret.Offset = fileHeader.Length;
this.textEditor.CreateParseInformation();
SetUpWithCode(fileHeader + fileFooter, fileHeader.Length);
CodeCompletionKeyPressResult result = new XamlCodeCompletionBinding().HandleKeyPress(textEditor, keyPressed);
Assert.AreEqual(keyPressResult, result);
@ -50,9 +98,8 @@ namespace ICSharpCode.XamlBinding.Tests @@ -50,9 +98,8 @@ namespace ICSharpCode.XamlBinding.Tests
protected void TestTextInsert(string fileHeader, string fileFooter, char completionChar, ICompletionItemList list, ICompletionItem item, string expectedOutput, int expectedOffset)
{
this.textEditor.Document.Text = fileHeader + fileFooter;
this.textEditor.Caret.Offset = fileHeader.Length;
this.textEditor.CreateParseInformation();
textEditor.Document.Text = fileHeader + fileFooter;
textEditor.Caret.Offset = fileHeader.Length;
CompletionContext context = new CompletionContext() {
Editor = this.textEditor,

35
src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/UtilsTests.cs

@ -1,11 +1,8 @@ @@ -1,11 +1,8 @@
// 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 ICSharpCode.NRefactory;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using ICSharpCode.NRefactory;
using NUnit.Framework;
namespace ICSharpCode.XamlBinding.Tests
@ -128,7 +125,7 @@ libraries for compilation. But when you compile a project @@ -128,7 +125,7 @@ libraries for compilation. But when you compile a project
inside SharpDevelop, there's more going on than a
simple call to MSBuild.";
Location location = Utils.GetLocationInfoFromOffset(text, 0);
TextLocation location = Utils.GetLocationInfoFromOffset(text, 0);
Assert.AreEqual(1, location.Line);
Assert.AreEqual(1, location.Column);
@ -144,7 +141,7 @@ simple call to MSBuild."; @@ -144,7 +141,7 @@ simple call to MSBuild.";
int offset = "SharpDevelop".Length;
Location location = Utils.GetLocationInfoFromOffset(text, offset);
TextLocation location = Utils.GetLocationInfoFromOffset(text, offset);
Assert.AreEqual(1, location.Line);
Assert.AreEqual(13, location.Column);
@ -161,7 +158,7 @@ simple call to MSBuild."; @@ -161,7 +158,7 @@ simple call to MSBuild.";
int offset = @"SharpDevelop uses the MSBuild
".Length;
Location location = Utils.GetLocationInfoFromOffset(text, offset);
TextLocation location = Utils.GetLocationInfoFromOffset(text, offset);
Assert.AreEqual(2, location.Line);
Assert.AreEqual(1, location.Column);
@ -178,7 +175,7 @@ simple call to MSBuild."; @@ -178,7 +175,7 @@ simple call to MSBuild.";
int offset = @"SharpDevelop uses the MSBuild
libraries".Length;
Location location = Utils.GetLocationInfoFromOffset(text, offset);
TextLocation location = Utils.GetLocationInfoFromOffset(text, offset);
Assert.AreEqual(2, location.Line);
Assert.AreEqual(10, location.Column);
@ -194,10 +191,30 @@ simple call to MSBuild."; @@ -194,10 +191,30 @@ simple call to MSBuild.";
int offset = @"SharpDevelop uses the MSBuild".Length;
Location location = Utils.GetLocationInfoFromOffset(text, offset);
TextLocation location = Utils.GetLocationInfoFromOffset(text, offset);
Assert.AreEqual(1, location.Line);
Assert.AreEqual(30, location.Column);
}
static object[] ParseNameCases = {
new[] { "Name", "", "Name", "" },
new[] { "x:Name", "x", "Name", "" },
new[] { "x:Name.Member", "x", "Name", "Member" },
new[] { "x:N.M", "x", "N", "M" },
new[] { "N.M", "", "N", "M" }
};
[Test, TestCaseSource("ParseNameCases")]
public void ParseNameTest(string input, string expectedPrefix, string expectedName, string expectedMember)
{
string outputPrefix, outputMember;
string outputName = XamlResolver.ParseName(input, out outputPrefix, out outputMember);
Assert.AreEqual(expectedPrefix, outputPrefix);
Assert.AreEqual(expectedMember, outputMember);
Assert.AreEqual(expectedName, outputName);
}
}
}

17
src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/XamlBinding.Tests.csproj

@ -48,6 +48,10 @@ @@ -48,6 +48,10 @@
<Reference Include="PresentationFramework">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="Rhino.Mocks">
<HintPath>..\..\..\..\Libraries\RhinoMocks\Rhino.Mocks.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
@ -85,7 +89,6 @@ @@ -85,7 +89,6 @@
<Compile Include="TextEditorBasedTests.cs" />
<Compile Include="TokenizerTests.cs" />
<Compile Include="UtilsTests.cs" />
<Compile Include="XamlExpressionFinderTests.cs" />
<Compile Include="XmlTests.cs" />
</ItemGroup>
<ItemGroup>
@ -93,6 +96,18 @@ @@ -93,6 +96,18 @@
<Project>{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}</Project>
<Name>ICSharpCode.AvalonEdit</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Libraries\NRefactory\ICSharpCode.NRefactory.CSharp\ICSharpCode.NRefactory.CSharp.csproj">
<Project>{53DCA265-3C3C-42F9-B647-F72BA678122B}</Project>
<Name>ICSharpCode.NRefactory.CSharp</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Libraries\NRefactory\ICSharpCode.NRefactory.Xml\ICSharpCode.NRefactory.Xml.csproj">
<Project>{DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}</Project>
<Name>ICSharpCode.NRefactory.Xml</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Libraries\NRefactory\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
<Project>{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}</Project>
<Name>ICSharpCode.NRefactory</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj">
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project>
<Name>ICSharpCode.SharpDevelop</Name>

42
src/AddIns/BackendBindings/XamlBinding/XamlBinding.Tests/XamlExpressionFinderTests.cs

@ -1,42 +0,0 @@ @@ -1,42 +0,0 @@
// 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 ICSharpCode.SharpDevelop.Dom;
using System;
using NUnit.Framework;
namespace ICSharpCode.XamlBinding.Tests
{
[TestFixture]
public class XamlExpressionFinderTests
{
XamlExpressionContext GetXamlContext(string text)
{
return (XamlExpressionContext)GetContext(text);
}
ExpressionContext GetContext(string text)
{
return XamlExpressionFinder.Instance.FindExpression(text, text.Length).Context;
}
[Test]
public void FindContextAfterElementName()
{
XamlExpressionContext c = GetXamlContext("<Window><Grid");
Assert.AreEqual(2, c.ElementPath.Elements.Count);
Assert.AreEqual("Window > Grid", c.ElementPath.ToString());
Assert.IsNull(c.AttributeName);
Assert.IsFalse(c.InAttributeValue);
}
[Test]
public void FindContextAtElementStart()
{
XamlExpressionContext c = GetXamlContext("<Window><");
Assert.AreEqual(0, c.ElementPath.Elements.Count);
Assert.IsNull(c.AttributeName);
Assert.IsFalse(c.InAttributeValue);
}
}
}

42
src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs

@ -72,10 +72,7 @@ namespace ICSharpCode.XamlBinding @@ -72,10 +72,7 @@ namespace ICSharpCode.XamlBinding
string word = editor.GetWordBeforeCaretExtended();
if (context.PressedKey == '.' || word.Contains(".")) {
string ns = "";
int pos = word.IndexOf(':');
if (pos > -1)
ns = word.Substring(0, pos);
string element = word.Substring(pos + 1, word.Length - pos - 1);
string className = word;
@ -95,7 +92,7 @@ namespace ICSharpCode.XamlBinding @@ -95,7 +92,7 @@ namespace ICSharpCode.XamlBinding
ITypeDefinition typeClass = trr != null ? trr.Type.GetDefinition() : null;
if (typeClass != null && typeClass.HasAttached(true, true))
list.Items.AddRange(GetListOfAttached(context, ns, typeClass, true, true));
list.Items.AddRange(GetListOfAttached(context, typeClass, true, true));
} else {
list.Items.AddRange(CreateAttributeList(context, true));
list.Items.AddRange(standardAttributes);
@ -267,13 +264,13 @@ namespace ICSharpCode.XamlBinding @@ -267,13 +264,13 @@ namespace ICSharpCode.XamlBinding
&& context.ParentElement.LocalName.StartsWith(lastElement.LocalName.TrimEnd('.'), StringComparison.OrdinalIgnoreCase)) {
AddAttributes(type, list, includeEvents);
}
AddAttachedProperties(lastElement.Prefix, type.GetDefinition(), list);
AddAttachedProperties(type.GetDefinition(), list);
} else {
if (type.Kind == TypeKind.Unknown) {
list.Add(new XamlCompletionItem(xKey + "Uid"));
} else {
AddAttributes(type, list, includeEvents);
list.AddRange(GetListOfAttached(context, null, null, includeEvents, true));
list.AddRange(GetListOfAttached(context, null, includeEvents, true));
list.AddRange(
XamlConst.XamlNamespaceAttributes
.Where(localName => XamlConst.IsAttributeAllowed(context.InRoot, localName))
@ -498,14 +495,17 @@ namespace ICSharpCode.XamlBinding @@ -498,14 +495,17 @@ namespace ICSharpCode.XamlBinding
public ICompletionItemList CreateMarkupExtensionCompletion(XamlCompletionContext context)
{
var list = new XamlCompletionItemList(context);
compilation = SD.ParserService.GetCompilationForFile(context.Editor.FileName);
string visibleValue = context.RawAttributeValue.Substring(0, Utils.MinMax(context.ValueStartOffset, 0, context.RawAttributeValue.Length));
if (context.PressedKey == '=')
visibleValue += "=";
var markup = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset);
var resolver = new XamlResolver(compilation);
var type = (resolver.ResolveExpression(markup.ExtensionType, context) ?? resolver.ResolveExpression(markup.ExtensionType + "Extension", context)).Type;
var type = resolver.ResolveExpression(markup.ExtensionType, context).Type;
if (type.Kind == TypeKind.Unknown)
type = resolver.ResolveExpression(markup.ExtensionType + "Extension", context).Type;
if (type == null) {
if (type.Kind == TypeKind.Unknown) {
list.Items.AddRange(CreateListOfMarkupExtensions(context));
list.PreselectionLength = markup.ExtensionType.Length;
} else {
@ -530,7 +530,7 @@ namespace ICSharpCode.XamlBinding @@ -530,7 +530,7 @@ namespace ICSharpCode.XamlBinding
if (context.RawAttributeValue.EndsWith("=", StringComparison.OrdinalIgnoreCase) ||
(item.Value.IsString && item.Value.StringValue.EndsWith(context.Editor.GetWordBeforeCaretExtended(), StringComparison.Ordinal))) {
var resolver = new XamlResolver(compilation);
MemberResolveResult mrr = resolver.ResolveExpression(item.Key, context) as MemberResolveResult;
MemberResolveResult mrr = resolver.ResolveAttributeValue(item.Key, context) as MemberResolveResult;
if (mrr != null && mrr.Member != null && mrr.Member.ReturnType != null) {
IType memberType = mrr.Member.ReturnType;
list.Items.AddRange(MemberCompletion(context, memberType, string.Empty));
@ -584,7 +584,7 @@ namespace ICSharpCode.XamlBinding @@ -584,7 +584,7 @@ namespace ICSharpCode.XamlBinding
var resolver = new XamlResolver(compilation);
if (context.PressedKey == '.') {
if (selItem != null && selItem.IsString) {
var rr = resolver.ResolveExpression(selItem.StringValue, context) as TypeResolveResult;
var rr = resolver.ResolveAttributeValue(selItem.StringValue, context) as TypeResolveResult;
if (rr != null)
list.Items.AddRange(MemberCompletion(context, rr.Type, string.Empty));
return false;
@ -593,8 +593,8 @@ namespace ICSharpCode.XamlBinding @@ -593,8 +593,8 @@ namespace ICSharpCode.XamlBinding
if (selItem != null && selItem.IsString) {
int index = selItem.StringValue.IndexOf('.');
string s = (index > -1) ? selItem.StringValue.Substring(0, index) : selItem.StringValue;
var rr = resolver.ResolveExpression(s, context) as TypeResolveResult;
if (rr != null) {
var rr = resolver.ResolveAttributeValue(s, context) as TypeResolveResult;
if (rr != null && rr.Type.Kind != TypeKind.Unknown) {
list.Items.AddRange(MemberCompletion(context, rr.Type, (index == -1) ? "." : string.Empty));
list.PreselectionLength = (index > -1) ? selItem.StringValue.Length - index - 1 : 0;
@ -816,16 +816,16 @@ namespace ICSharpCode.XamlBinding @@ -816,16 +816,16 @@ namespace ICSharpCode.XamlBinding
}
#region Attached Properties and Events
internal List<ICompletionItem> GetListOfAttached(XamlContext context, string prefix, ITypeDefinition attachedType, bool events, bool properties)
internal List<ICompletionItem> GetListOfAttached(XamlContext context, ITypeDefinition attachedType, bool events, bool properties)
{
List<ICompletionItem> result = new List<ICompletionItem>();
if (attachedType != null) {
if (attachedType.Kind == TypeKind.Class && !attachedType.IsDerivedFrom(KnownTypeCode.Attribute)) {
if (properties)
AddAttachedProperties(prefix, attachedType, result);
AddAttachedProperties(attachedType, result);
if (events)
AddAttachedEvents(prefix, attachedType, result);
AddAttachedEvents(attachedType, result);
}
} else {
foreach (var ns in context.XmlnsDefinitions) {
@ -843,13 +843,11 @@ namespace ICSharpCode.XamlBinding @@ -843,13 +843,11 @@ namespace ICSharpCode.XamlBinding
return result;
}
public static void AddAttachedProperties(string prefix, ITypeDefinition td, List<ICompletionItem> result)
public static void AddAttachedProperties(ITypeDefinition td, List<ICompletionItem> result)
{
var attachedProperties = td.Fields.Where(f => f.IsAttached(true, false));
var unresolvedType = td.Parts.First();
var resolveContext = new SimpleTypeResolveContext(td);
if (!string.IsNullOrEmpty(prefix))
prefix += ":";
result.AddRange(
attachedProperties.Select(
@ -857,19 +855,17 @@ namespace ICSharpCode.XamlBinding @@ -857,19 +855,17 @@ namespace ICSharpCode.XamlBinding
string propertyName = property.Name.Remove(property.Name.Length - "Property".Length);
IUnresolvedProperty item = new DefaultUnresolvedProperty(unresolvedType, propertyName);
IMember entity = item.CreateResolved(resolveContext);
return new XamlCompletionItem(prefix + propertyName, entity);
return new XamlCompletionItem(propertyName, entity);
}
)
);
}
static void AddAttachedEvents(string prefix, ITypeDefinition td, List<ICompletionItem> result)
static void AddAttachedEvents(ITypeDefinition td, List<ICompletionItem> result)
{
var attachedEvents = td.Fields.Where(f => f.IsAttached(false, true));
var unresolvedType = td.Parts.First();
var resolveContext = new SimpleTypeResolveContext(td);
if (!string.IsNullOrEmpty(prefix))
prefix += ":";
result.AddRange(
attachedEvents.Select(
@ -877,7 +873,7 @@ namespace ICSharpCode.XamlBinding @@ -877,7 +873,7 @@ namespace ICSharpCode.XamlBinding
string eventName = GetEventNameFromField(field);
IUnresolvedEvent item = new DefaultUnresolvedEvent(unresolvedType, eventName);
IMember entity = item.CreateResolved(resolveContext);
return new XamlCompletionItem(prefix + eventName, entity);
return new XamlCompletionItem(eventName, entity);
}
)
);

4
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj

@ -46,6 +46,10 @@ @@ -46,6 +46,10 @@
<Reference Include="PresentationFramework">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="Rhino.Mocks">
<HintPath>..\..\..\..\Libraries\RhinoMocks\Rhino.Mocks.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>

4
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCodeCompletionBinding.cs

@ -190,7 +190,7 @@ namespace ICSharpCode.XamlBinding @@ -190,7 +190,7 @@ namespace ICSharpCode.XamlBinding
|| context.ActiveElement == null) {
return false;
}
if (context.Description != XamlContextDescription.InAttributeValue) {
if (!context.InAttributeValueOrMarkupExtension) {
XamlCompletionItemList list = generator.CreateListForContext(context);
string starter = editor.GetWordBeforeCaretExtended().TrimStart('/');
if (context.Description != XamlContextDescription.None && !string.IsNullOrEmpty(starter)) {
@ -210,8 +210,10 @@ namespace ICSharpCode.XamlBinding @@ -210,8 +210,10 @@ namespace ICSharpCode.XamlBinding
completionList.PreselectionLength = editor.GetWordBeforeCaretExtended().Length;
if ((context.ActiveElement.Name == "Setter" || context.ActiveElement.Name == "EventSetter") && (context.Attribute.Name == "Property" || context.Attribute.Name == "Value")) {
DoSetterAndEventSetterCompletion(context, completionList);
editor.ShowCompletionWindow(completionList);
} else if ((context.ActiveElement.Name.EndsWith("Trigger", StringComparison.Ordinal) || context.ActiveElement.Name == "Condition") && context.Attribute.Name == "Value") {
DoTriggerCompletion(context, completionList);
editor.ShowCompletionWindow(completionList);
} else if (!DoAttributeCompletion(context, completionList)) {
DoXmlAttributeCompletion(context, completionList);
}

8
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContextResolver.cs

@ -85,7 +85,8 @@ namespace ICSharpCode.XamlBinding @@ -85,7 +85,8 @@ namespace ICSharpCode.XamlBinding
attributeValue = a.Value;
value = MarkupExtensionParser.ParseValue(attributeValue);
if (offset >= valueStartOffset && offset < a.EndOffset) {
if (offset >= valueStartOffset && (offset < a.EndOffset // if length is < 2 one quote is missing
|| (a.ValueSegment.Length <= 1 && offset <= a.EndOffset))) {
offsetFromValueStart = offset - valueStartOffset;
description = XamlContextDescription.InAttributeValue;
@ -96,6 +97,7 @@ namespace ICSharpCode.XamlBinding @@ -96,6 +97,7 @@ namespace ICSharpCode.XamlBinding
description = XamlContextDescription.InAttributeValue;
} else
description = XamlContextDescription.InTag;
active = a.ParentElement;
} else if (currentData is AXmlTag) {
AXmlTag tag = currentData as AXmlTag;
if (tag.IsStartOrEmptyTag || tag.IsEndTag) {
@ -146,7 +148,7 @@ namespace ICSharpCode.XamlBinding @@ -146,7 +148,7 @@ namespace ICSharpCode.XamlBinding
if (binding == null)
throw new InvalidOperationException("Can only use ResolveCompletionContext with a XamlLanguageBinding.");
var context = new XamlCompletionContext(ResolveContext(editor.FileName, editor.Document.CreateSnapshot(), editor.Caret.Offset)) {
var context = new XamlCompletionContext(ResolveContext(editor.FileName, editor.Document, editor.Caret.Offset)) {
PressedKey = typedValue,
Editor = editor
};
@ -161,7 +163,7 @@ namespace ICSharpCode.XamlBinding @@ -161,7 +163,7 @@ namespace ICSharpCode.XamlBinding
if (binding == null)
throw new InvalidOperationException("Can only use ResolveCompletionContext with a XamlLanguageBinding.");
var context = new XamlCompletionContext(ResolveContext(editor.FileName, editor.Document.CreateSnapshot(), offset)) {
var context = new XamlCompletionContext(ResolveContext(editor.FileName, editor.Document, offset)) {
PressedKey = typedValue,
Editor = editor
};

1
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs

@ -38,6 +38,7 @@ namespace ICSharpCode.XamlBinding @@ -38,6 +38,7 @@ namespace ICSharpCode.XamlBinding
public XamlParser()
{
TaskListTokens = EmptyList<string>.Instance;
}
public bool CanParse(string fileName)

39
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlResolver.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Remoting.Lifetime;
@ -37,6 +38,7 @@ namespace ICSharpCode.XamlBinding @@ -37,6 +38,7 @@ namespace ICSharpCode.XamlBinding
string prefix, memberName;
string name = ParseName(expression, out prefix, out memberName);
string namespaceUrl;
if (prefix == "")
namespaceUrl = context.ActiveElement.Namespace;
else
@ -75,14 +77,41 @@ namespace ICSharpCode.XamlBinding @@ -75,14 +77,41 @@ namespace ICSharpCode.XamlBinding
return ResolveExpression(typeNameString, context);
}
string GetTypeNameFromTypeExtension(MarkupExtensionInfo info, XamlContext context)
public ResolveResult ResolveAttributeValue(string expression, XamlContext context)
{
ResolveResult rr = ResolveExpression(info.ExtensionType, context)
?? ResolveExpression(info.ExtensionType + "Extension", context);
if (!context.InAttributeValueOrMarkupExtension)
return ErrorResolveResult.UnknownError;
if (context.AttributeValue.IsString)
return ResolveExpression(expression, context);
MarkupExtensionInfo info = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset);
object data = Utils.GetMarkupDataAtPosition(info, context.ValueStartOffset);
IType extensionType = ResolveExpression(info.ExtensionType, context).Type;
if (extensionType.Kind == TypeKind.Unknown)
extensionType = ResolveExpression(info.ExtensionType + "Extension", context).Type;
if (data is KeyValuePair<string, AttributeValue>) {
var kv = (KeyValuePair<string, AttributeValue>)data;
if (kv.Value.StartOffset >= context.ValueStartOffset) {
IProperty member = extensionType.GetProperties(p => p.Name == expression).FirstOrDefault();
if (member != null)
return new MemberResolveResult(new TypeResolveResult(extensionType), member);
return new UnknownMemberResolveResult(extensionType, expression, EmptyList<IType>.Instance);
} else {
}
}
return ResolveExpression(expression, context);
}
IType type = rr.Type;
string GetTypeNameFromTypeExtension(MarkupExtensionInfo info, XamlContext context)
{
IType type = ResolveExpression(info.ExtensionType, context).Type;
if (type.Kind == TypeKind.Unknown)
type = ResolveExpression(info.ExtensionType + "Extension", context).Type;
if (type == null || type.FullName != "System.Windows.Markup.TypeExtension")
if (type.FullName != "System.Windows.Markup.TypeExtension")
return string.Empty;
var item = info.PositionalArguments.FirstOrDefault();

Loading…
Cancel
Save