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. 44
      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
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Scripting.Tests", "src\AddIns\BackendBindings\Scripting\Test\ICSharpCode.Scripting.Tests.csproj", "{85C09AD8-183B-403A-869A-7226646218A9}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Scripting.Tests", "src\AddIns\BackendBindings\Scripting\Test\ICSharpCode.Scripting.Tests.csproj", "{85C09AD8-183B-403A-869A-7226646218A9}"
EndProject 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}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{F3662720-9EA2-4591-BBC6-97361DCE50A9}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelpViewer", "src\AddIns\Misc\HelpViewer\HelpViewer.csproj", "{80F76D10-0B44-4D55-B4BD-DAEB5464090C}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelpViewer", "src\AddIns\Misc\HelpViewer\HelpViewer.csproj", "{80F76D10-0B44-4D55-B4BD-DAEB5464090C}"
@ -769,6 +771,14 @@ Global
{85226AFB-CE71-4851-9A75-7EEC663A8E8A}.Release|Any CPU.Build.0 = Release|Any CPU {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.ActiveCfg = Release|Any CPU
{85226AFB-CE71-4851-9A75-7EEC663A8E8A}.Release|x86.Build.0 = 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.ActiveCfg = Debug|Any CPU
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Debug|Any CPU.Build.0 = 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 {1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Debug|x86.ActiveCfg = Debug|Any CPU
@ -873,14 +883,14 @@ Global
{3DF4060F-5EE0-41CF-8096-F27355FD5511}.Release|Any CPU.Build.0 = Release|Any CPU {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.ActiveCfg = Release|Any CPU
{3DF4060F-5EE0-41CF-8096-F27355FD5511}.Release|x86.Build.0 = 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 {CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Debug|Any CPU.Build.0 = Debug|Any CPU {CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Debug|x86.ActiveCfg = Debug|x86 {CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Debug|x86.ActiveCfg = Debug|x86
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Debug|x86.Build.0 = Debug|x86 {CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Debug|x86.Build.0 = Debug|x86
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Release|Any CPU.ActiveCfg = Release|Any CPU {CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Release|Any CPU.Build.0 = Release|Any CPU {CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Release|Any CPU.Build.0 = Release|Any CPU
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Release|x86.ActiveCfg = Release|x86 {CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Release|x86.ActiveCfg = Release|x86
{9E951B9F-6AC2-4537-9D0B-0AE7C026D5A1}.Release|x86.Build.0 = Release|x86 {CAD4D128-5A67-444B-88AE-37E0AF79C57E}.Release|x86.Build.0 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -923,6 +933,7 @@ Global
{388E7B64-0393-4EB4-A3E3-5C474F141853} = {E0646C25-36F2-4524-969F-FA621353AB94} {388E7B64-0393-4EB4-A3E3-5C474F141853} = {E0646C25-36F2-4524-969F-FA621353AB94}
{7048AE18-EB93-4A84-82D0-DD60EB58ADBD} = {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} {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} {F3662720-9EA2-4591-BBC6-97361DCE50A9} = {39327899-ED91-4F7F-988C-4FE4E17C014D}
{80F76D10-0B44-4D55-B4BD-DAEB5464090C} = {F3662720-9EA2-4591-BBC6-97361DCE50A9} {80F76D10-0B44-4D55-B4BD-DAEB5464090C} = {F3662720-9EA2-4591-BBC6-97361DCE50A9}
{9196DD8A-B4D4-4780-8742-C5762E547FC2} = {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;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; 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.Editor.CodeCompletion;
using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Workbench;
using NUnit.Framework; using NUnit.Framework;
using Rhino.Mocks;
namespace ICSharpCode.XamlBinding.Tests namespace ICSharpCode.XamlBinding.Tests
{ {
@ -834,8 +843,12 @@ namespace ICSharpCode.XamlBinding.Tests
}); });
} }
[Test] static readonly object[] KeyTestData = {
public void InCommentPressTest() '<', '.', ':', '/', 'a'
};
[Test, TestCaseSourceAttribute("KeyTestData")]
public void InCommentPressTest(char key)
{ {
string fileHeader = @"<Window x:Class='ICSharpCode.XamlBinding.Tests.CompletionTestsBase' string fileHeader = @"<Window x:Class='ICSharpCode.XamlBinding.Tests.CompletionTestsBase'
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
@ -846,15 +859,11 @@ namespace ICSharpCode.XamlBinding.Tests
</Grid> </Grid>
</Window>"; </Window>";
TestKeyPress(fileHeader, fileFooter, '<', CodeCompletionKeyPressResult.None, list => {}); TestKeyPress(fileHeader, fileFooter, key, 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 => {});
} }
[Test] [Test, TestCaseSourceAttribute("KeyTestData")]
public void InCDataPressTest() public void InCDataPressTest(char key)
{ {
string fileHeader = @"<Window x:Class='ICSharpCode.XamlBinding.Tests.CompletionTestsBase' string fileHeader = @"<Window x:Class='ICSharpCode.XamlBinding.Tests.CompletionTestsBase'
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
@ -865,15 +874,11 @@ namespace ICSharpCode.XamlBinding.Tests
</Grid> </Grid>
</Window>"; </Window>";
TestKeyPress(fileHeader, fileFooter, '<', CodeCompletionKeyPressResult.None, list => {}); TestKeyPress(fileHeader, fileFooter, key, 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 => {});
} }
[Test] [Test, TestCaseSourceAttribute("KeyTestData")]
public void InPlainTextPressTest() public void InPlainTextPressTest(char key)
{ {
string fileHeader = @"<Window x:Class='ICSharpCode.XamlBinding.Tests.CompletionTestsBase' string fileHeader = @"<Window x:Class='ICSharpCode.XamlBinding.Tests.CompletionTestsBase'
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
@ -884,11 +889,7 @@ namespace ICSharpCode.XamlBinding.Tests
</Grid> </Grid>
</Window>"; </Window>";
TestKeyPress(fileHeader, fileFooter, '.', CodeCompletionKeyPressResult.None, list => {}); TestKeyPress(fileHeader, fileFooter, key, key == '<' ? CodeCompletionKeyPressResult.Completed : 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 => {});
} }
#endregion #endregion
} }

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

@ -3,14 +3,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.AvalonEdit;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion; using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using System.Diagnostics; using ICSharpCode.SharpDevelop.Parser;
namespace ICSharpCode.XamlBinding.Tests namespace ICSharpCode.XamlBinding.Tests
{ {
@ -22,52 +22,23 @@ namespace ICSharpCode.XamlBinding.Tests
/// </summary> /// </summary>
public class MockTextEditor : AvalonEditTextEditorAdapter public class MockTextEditor : AvalonEditTextEditorAdapter
{ {
DefaultProjectContent pc; XamlLanguageBinding langBinding;
public MockTextEditor() public MockTextEditor()
: base(new TextEditor()) : base(new TextEditor())
{ {
PropertyService.InitializeServiceForUnitTests(); this.langBinding = new XamlLanguageBinding();
pc = new DefaultProjectContent(); this.TextEditor.TextArea.TextView.Services.AddService(typeof(XamlLanguageBinding), langBinding);
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);
} }
public override FileName FileName { public override FileName FileName {
get { return new FileName("mockFileName.xaml"); } 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 XamlParser();
var parser = new XamlBinding.XamlParser(); return parser.Parse(this.FileName, this.Document, true, null, CancellationToken.None);
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);
} }
ICompletionItemList lastCompletionItemList; ICompletionItemList lastCompletionItemList;
@ -82,17 +53,18 @@ namespace ICSharpCode.XamlBinding.Tests
return null; return null;
} }
IEnumerable<IInsightItem> lastInsightItems; public override ICSharpCode.SharpDevelop.ILanguageBinding Language {
get {
public IEnumerable<IInsightItem> LastInsightItems { return langBinding;
get { return lastInsightItems; } }
} }
IList<IInsightItem> lastInsightItemList = null;
public override IInsightWindow ShowInsightWindow(IEnumerable<IInsightItem> items) public override IInsightWindow ShowInsightWindow(IEnumerable<IInsightItem> items)
{ {
this.lastInsightItems = items; this.lastInsightItemList = items.ToList();
return null; return null;
} }
} }
} }

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

@ -3,21 +3,61 @@
using System; using System;
using System.Linq; 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 ICSharpCode.XmlEditor;
using NUnit.Framework; using NUnit.Framework;
using System.IO; using System.IO;
using Rhino.Mocks;
namespace ICSharpCode.XamlBinding.Tests namespace ICSharpCode.XamlBinding.Tests
{ {
[TestFixture] [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] [Test]
public void ContextNoneDescriptionTest() public void ContextNoneDescriptionTest()
{ {
string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n</Grid>"; string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n</Grid>";
int offset = "<Grid>\n".Length; int offset = "<Grid>\n".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.None, context.Description); Assert.AreEqual(XamlContextDescription.None, context.Description);
} }
@ -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>"; string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n</Grid>";
int offset = "<Grid>".Length; int offset = "<Grid>".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.None, context.Description); Assert.AreEqual(XamlContextDescription.None, context.Description);
} }
@ -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>"; 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; 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); Assert.AreEqual(XamlContextDescription.None, context.Description);
} }
@ -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>"; string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n</Grid>";
int offset = "<G".Length; int offset = "<G".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.AtTag, context.Description); Assert.AreEqual(XamlContextDescription.AtTag, context.Description);
} }
@ -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>"; 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; 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); Assert.AreEqual(XamlContextDescription.AtTag, context.Description);
} }
@ -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>"; string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n</Grid>";
int offset = "<Grid>\n".Length + 10; int offset = "<Grid>\n".Length + 10;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.AtTag, context.Description); Assert.AreEqual(XamlContextDescription.AtTag, context.Description);
} }
@ -77,7 +117,7 @@ namespace ICSharpCode.XamlBinding.Tests
{ {
string xaml = "<Grid>\n\t<\n</Grid>"; string xaml = "<Grid>\n\t<\n</Grid>";
int offset = "<Grid>\n\t<".Length; int offset = "<Grid>\n\t<".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.AtTag, context.Description); Assert.AreEqual(XamlContextDescription.AtTag, context.Description);
} }
@ -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>"; string xaml = "<Grid>\n\t<CheckBox x:Name=\"asdf\" Background=\"Aqua\" Content=\"{x:Static Cursors.Arrow}\" />\n</Grid>";
int offset = "<Grid>\n".Length + 26; int offset = "<Grid>\n".Length + 26;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InTag, context.Description); Assert.AreEqual(XamlContextDescription.InTag, context.Description);
} }
@ -114,7 +154,7 @@ namespace ICSharpCode.XamlBinding.Tests
<StackPanel> <StackPanel>
<RadioButton ".Length; <RadioButton ".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InTag, context.Description); Assert.AreEqual(XamlContextDescription.InTag, context.Description);
} }
@ -142,7 +182,7 @@ namespace ICSharpCode.XamlBinding.Tests
<RadioButton <RadioButton
</Stack".Length; </Stack".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.AtTag, context.Description); Assert.AreEqual(XamlContextDescription.AtTag, context.Description);
} }
@ -153,7 +193,7 @@ namespace ICSharpCode.XamlBinding.Tests
{ {
string xaml = "<Grid>\n\t<Grid.ColumnDefinitions />\n</Grid>"; string xaml = "<Grid>\n\t<Grid.ColumnDefinitions />\n</Grid>";
int offset = "<Grid>\n".Length + 12; int offset = "<Grid>\n".Length + 12;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual("Grid.ColumnDefinitions", context.ActiveElement.Name); Assert.AreEqual("Grid.ColumnDefinitions", context.ActiveElement.Name);
} }
@ -163,7 +203,7 @@ namespace ICSharpCode.XamlBinding.Tests
{ {
string xaml = File.ReadAllText("Test4.xaml"); string xaml = File.ReadAllText("Test4.xaml");
int offset = 413; int offset = 413;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.AtTag, context.Description); Assert.AreEqual(XamlContextDescription.AtTag, context.Description);
} }
@ -174,7 +214,7 @@ namespace ICSharpCode.XamlBinding.Tests
string xaml = "<Test attr=\"{Test}\" />"; string xaml = "<Test attr=\"{Test}\" />";
int offset = "<Test attr=\"{Te".Length; int offset = "<Test attr=\"{Te".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InMarkupExtension, context.Description); Assert.AreEqual(XamlContextDescription.InMarkupExtension, context.Description);
} }
@ -185,7 +225,7 @@ namespace ICSharpCode.XamlBinding.Tests
string xaml = "<Test attr=\"Test\" />"; string xaml = "<Test attr=\"Test\" />";
int offset = "<Test attr=\"Te".Length; int offset = "<Test attr=\"Te".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description); Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description);
} }
@ -196,7 +236,7 @@ namespace ICSharpCode.XamlBinding.Tests
string xaml = "<Test attr=\"{}{Test}\" />"; string xaml = "<Test attr=\"{}{Test}\" />";
int offset = "<Test attr=\"{}{Te".Length; int offset = "<Test attr=\"{}{Te".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description); Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description);
} }
@ -207,7 +247,7 @@ namespace ICSharpCode.XamlBinding.Tests
string xaml = "<Test attr=\"Test />"; string xaml = "<Test attr=\"Test />";
int offset = "<Test attr=\"Te".Length; int offset = "<Test attr=\"Te".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description); Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description);
} }
@ -218,7 +258,7 @@ namespace ICSharpCode.XamlBinding.Tests
string xaml = "<Test attr=\"Test />"; string xaml = "<Test attr=\"Test />";
int offset = "<Test attr=\"".Length; int offset = "<Test attr=\"".Length;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description); Assert.AreEqual(XamlContextDescription.InAttributeValue, context.Description);
} }
@ -228,7 +268,7 @@ namespace ICSharpCode.XamlBinding.Tests
{ {
string xaml = File.ReadAllText("Test1.xaml"); string xaml = File.ReadAllText("Test1.xaml");
int offset = 272; int offset = 272;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual("CheckBox", context.ActiveElement.Name); Assert.AreEqual("CheckBox", context.ActiveElement.Name);
Assert.AreEqual("Grid", context.ParentElement.Name); Assert.AreEqual("Grid", context.ParentElement.Name);
@ -239,7 +279,7 @@ namespace ICSharpCode.XamlBinding.Tests
{ {
string xaml = File.ReadAllText("Test4.xaml"); string xaml = File.ReadAllText("Test4.xaml");
int offset = 413; int offset = 413;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual("Grid", context.ActiveElement.Name); Assert.AreEqual("Grid", context.ActiveElement.Name);
Assert.AreEqual("Grid", context.ParentElement.Name); Assert.AreEqual("Grid", context.ParentElement.Name);
@ -250,7 +290,7 @@ namespace ICSharpCode.XamlBinding.Tests
{ {
string xaml = File.ReadAllText("Test1.xaml"); string xaml = File.ReadAllText("Test1.xaml");
int offset = 31; int offset = 31;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual("Window", context.ActiveElement.Name); Assert.AreEqual("Window", context.ActiveElement.Name);
Assert.AreEqual(null, context.ParentElement); Assert.AreEqual(null, context.ParentElement);
@ -261,7 +301,7 @@ namespace ICSharpCode.XamlBinding.Tests
{ {
string xaml = File.ReadAllText("Test2.xaml"); string xaml = File.ReadAllText("Test2.xaml");
int offset = 447; int offset = 447;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
Assert.AreEqual(1, context.IgnoredXmlns.Count); Assert.AreEqual(1, context.IgnoredXmlns.Count);
Assert.AreEqual("d", context.IgnoredXmlns[0]); Assert.AreEqual("d", context.IgnoredXmlns[0]);
@ -272,7 +312,7 @@ namespace ICSharpCode.XamlBinding.Tests
{ {
string xaml = File.ReadAllText("Test5.xaml"); string xaml = File.ReadAllText("Test5.xaml");
int offset = 881; int offset = 881;
XamlContext context = CompletionDataHelper.ResolveContext(xaml, "", offset); XamlContext context = TestContext(xaml, offset);
string[] ancestors = new string[] { string[] ancestors = new string[] {
"DoubleAnimation", "Storyboard", "DoubleAnimation", "Storyboard",
@ -286,5 +326,24 @@ namespace ICSharpCode.XamlBinding.Tests
Assert.AreEqual(8, context.Ancestors.Count); Assert.AreEqual(8, context.Ancestors.Count);
Assert.AreEqual(ancestors, context.Ancestors.Select(item => item.Name).ToArray()); 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 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // 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) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using System; 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 NUnit.Framework;
using Rhino.Mocks;
namespace ICSharpCode.XamlBinding.Tests namespace ICSharpCode.XamlBinding.Tests
{ {
@ -12,33 +26,67 @@ namespace ICSharpCode.XamlBinding.Tests
{ {
protected MockTextEditor textEditor; protected MockTextEditor textEditor;
protected static readonly IReadOnlyList<string> TaskListTokens = new List<string> {
"TODO", "HACK", "FIXME"
};
[SetUp] [SetUp]
public void SetupTest() 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()
{
SD.TearDownForUnitTests();
}
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);
void SetUpWithCode(string code, int offset)
{ {
this.textEditor.Document.Text = fileHeader + fileFooter; textEditor.Document.Text = code;
this.textEditor.Caret.Offset = fileHeader.Length; textEditor.Caret.Offset = offset;
this.textEditor.CreateParseInformation();
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); bool invoked = new XamlCodeCompletionBinding().CtrlSpace(textEditor);
Assert.AreEqual(expected, invoked); Assert.AreEqual(expected, invoked);
ICompletionItemList list = textEditor.LastCompletionItemList;
ICompletionItemList list = this.textEditor.LastCompletionItemList; Assert.NotNull(list);
constraint(list); constraint(list);
} }
protected void TestKeyPress(string fileHeader, string fileFooter, char keyPressed, CodeCompletionKeyPressResult keyPressResult, Action<ICompletionItemList> constraint) protected void TestKeyPress(string fileHeader, string fileFooter, char keyPressed, CodeCompletionKeyPressResult keyPressResult, Action<ICompletionItemList> constraint)
{ {
this.textEditor.Document.Text = fileHeader + fileFooter; SetUpWithCode(fileHeader + fileFooter, fileHeader.Length);
this.textEditor.Caret.Offset = fileHeader.Length;
this.textEditor.CreateParseInformation();
CodeCompletionKeyPressResult result = new XamlCodeCompletionBinding().HandleKeyPress(textEditor, keyPressed); CodeCompletionKeyPressResult result = new XamlCodeCompletionBinding().HandleKeyPress(textEditor, keyPressed);
Assert.AreEqual(keyPressResult, result); Assert.AreEqual(keyPressResult, result);
@ -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) protected void TestTextInsert(string fileHeader, string fileFooter, char completionChar, ICompletionItemList list, ICompletionItem item, string expectedOutput, int expectedOffset)
{ {
this.textEditor.Document.Text = fileHeader + fileFooter; textEditor.Document.Text = fileHeader + fileFooter;
this.textEditor.Caret.Offset = fileHeader.Length; textEditor.Caret.Offset = fileHeader.Length;
this.textEditor.CreateParseInformation();
CompletionContext context = new CompletionContext() { CompletionContext context = new CompletionContext() {
Editor = this.textEditor, Editor = this.textEditor,

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

@ -1,11 +1,8 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // 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) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.NRefactory;
using System; using System;
using System.Collections.Generic; using ICSharpCode.NRefactory;
using System.Diagnostics;
using System.IO;
using NUnit.Framework; using NUnit.Framework;
namespace ICSharpCode.XamlBinding.Tests namespace ICSharpCode.XamlBinding.Tests
@ -128,7 +125,7 @@ libraries for compilation. But when you compile a project
inside SharpDevelop, there's more going on than a inside SharpDevelop, there's more going on than a
simple call to MSBuild."; 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.Line);
Assert.AreEqual(1, location.Column); Assert.AreEqual(1, location.Column);
@ -144,7 +141,7 @@ simple call to MSBuild.";
int offset = "SharpDevelop".Length; int offset = "SharpDevelop".Length;
Location location = Utils.GetLocationInfoFromOffset(text, offset); TextLocation location = Utils.GetLocationInfoFromOffset(text, offset);
Assert.AreEqual(1, location.Line); Assert.AreEqual(1, location.Line);
Assert.AreEqual(13, location.Column); Assert.AreEqual(13, location.Column);
@ -161,7 +158,7 @@ simple call to MSBuild.";
int offset = @"SharpDevelop uses the MSBuild int offset = @"SharpDevelop uses the MSBuild
".Length; ".Length;
Location location = Utils.GetLocationInfoFromOffset(text, offset); TextLocation location = Utils.GetLocationInfoFromOffset(text, offset);
Assert.AreEqual(2, location.Line); Assert.AreEqual(2, location.Line);
Assert.AreEqual(1, location.Column); Assert.AreEqual(1, location.Column);
@ -178,7 +175,7 @@ simple call to MSBuild.";
int offset = @"SharpDevelop uses the MSBuild int offset = @"SharpDevelop uses the MSBuild
libraries".Length; libraries".Length;
Location location = Utils.GetLocationInfoFromOffset(text, offset); TextLocation location = Utils.GetLocationInfoFromOffset(text, offset);
Assert.AreEqual(2, location.Line); Assert.AreEqual(2, location.Line);
Assert.AreEqual(10, location.Column); Assert.AreEqual(10, location.Column);
@ -194,10 +191,30 @@ simple call to MSBuild.";
int offset = @"SharpDevelop uses the MSBuild".Length; 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(1, location.Line);
Assert.AreEqual(30, location.Column); 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 @@
<Reference Include="PresentationFramework"> <Reference Include="PresentationFramework">
<RequiredTargetFramework>3.0</RequiredTargetFramework> <RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference> </Reference>
<Reference Include="Rhino.Mocks">
<HintPath>..\..\..\..\Libraries\RhinoMocks\Rhino.Mocks.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core"> <Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
@ -85,7 +89,6 @@
<Compile Include="TextEditorBasedTests.cs" /> <Compile Include="TextEditorBasedTests.cs" />
<Compile Include="TokenizerTests.cs" /> <Compile Include="TokenizerTests.cs" />
<Compile Include="UtilsTests.cs" /> <Compile Include="UtilsTests.cs" />
<Compile Include="XamlExpressionFinderTests.cs" />
<Compile Include="XmlTests.cs" /> <Compile Include="XmlTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -93,6 +96,18 @@
<Project>{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}</Project> <Project>{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}</Project>
<Name>ICSharpCode.AvalonEdit</Name> <Name>ICSharpCode.AvalonEdit</Name>
</ProjectReference> </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"> <ProjectReference Include="..\..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj">
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project> <Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project>
<Name>ICSharpCode.SharpDevelop</Name> <Name>ICSharpCode.SharpDevelop</Name>

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

@ -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);
}
}
}

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

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

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

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

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

@ -85,7 +85,8 @@ namespace ICSharpCode.XamlBinding
attributeValue = a.Value; attributeValue = a.Value;
value = MarkupExtensionParser.ParseValue(attributeValue); 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; offsetFromValueStart = offset - valueStartOffset;
description = XamlContextDescription.InAttributeValue; description = XamlContextDescription.InAttributeValue;
@ -96,6 +97,7 @@ namespace ICSharpCode.XamlBinding
description = XamlContextDescription.InAttributeValue; description = XamlContextDescription.InAttributeValue;
} else } else
description = XamlContextDescription.InTag; description = XamlContextDescription.InTag;
active = a.ParentElement;
} else if (currentData is AXmlTag) { } else if (currentData is AXmlTag) {
AXmlTag tag = currentData as AXmlTag; AXmlTag tag = currentData as AXmlTag;
if (tag.IsStartOrEmptyTag || tag.IsEndTag) { if (tag.IsStartOrEmptyTag || tag.IsEndTag) {
@ -146,7 +148,7 @@ namespace ICSharpCode.XamlBinding
if (binding == null) if (binding == null)
throw new InvalidOperationException("Can only use ResolveCompletionContext with a XamlLanguageBinding."); 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, PressedKey = typedValue,
Editor = editor Editor = editor
}; };
@ -161,7 +163,7 @@ namespace ICSharpCode.XamlBinding
if (binding == null) if (binding == null)
throw new InvalidOperationException("Can only use ResolveCompletionContext with a XamlLanguageBinding."); 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, PressedKey = typedValue,
Editor = editor Editor = editor
}; };

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

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

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

@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Runtime.Remoting.Lifetime; using System.Runtime.Remoting.Lifetime;
@ -37,6 +38,7 @@ namespace ICSharpCode.XamlBinding
string prefix, memberName; string prefix, memberName;
string name = ParseName(expression, out prefix, out memberName); string name = ParseName(expression, out prefix, out memberName);
string namespaceUrl; string namespaceUrl;
if (prefix == "") if (prefix == "")
namespaceUrl = context.ActiveElement.Namespace; namespaceUrl = context.ActiveElement.Namespace;
else else
@ -75,14 +77,41 @@ namespace ICSharpCode.XamlBinding
return ResolveExpression(typeNameString, context); return ResolveExpression(typeNameString, context);
} }
string GetTypeNameFromTypeExtension(MarkupExtensionInfo info, XamlContext context) public ResolveResult ResolveAttributeValue(string expression, XamlContext context)
{ {
ResolveResult rr = ResolveExpression(info.ExtensionType, context) if (!context.InAttributeValueOrMarkupExtension)
?? ResolveExpression(info.ExtensionType + "Extension", context); 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;
IType type = rr.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);
}
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; return string.Empty;
var item = info.PositionalArguments.FirstOrDefault(); var item = info.PositionalArguments.FirstOrDefault();

Loading…
Cancel
Save