You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2064 lines
60 KiB
2064 lines
60 KiB
// <file> |
|
// <copyright see="prj:///doc/copyright.txt"/> |
|
// <license see="prj:///doc/license.txt"/> |
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/> |
|
// <version>$Revision$</version> |
|
// </file> |
|
|
|
using System; |
|
using System.Collections; |
|
using System.IO; |
|
using System.Linq; |
|
|
|
using ICSharpCode.Core; |
|
using ICSharpCode.SharpDevelop.Dom; |
|
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver; |
|
using ICSharpCode.SharpDevelop.Project; |
|
using NUnit.Framework; |
|
|
|
namespace ICSharpCode.SharpDevelop.Tests |
|
{ |
|
[TestFixture] |
|
public class NRefactoryResolverTests |
|
{ |
|
ProjectContentRegistry projectContentRegistry = ParserService.DefaultProjectContentRegistry; |
|
|
|
#region Test helper methods |
|
public ICompilationUnit Parse(string fileName, string fileContent) |
|
{ |
|
ICSharpCode.NRefactory.IParser p = ICSharpCode.NRefactory.ParserFactory.CreateParser(ICSharpCode.NRefactory.SupportedLanguage.CSharp, new StringReader(fileContent)); |
|
p.ParseMethodBodies = false; |
|
p.Parse(); |
|
DefaultProjectContent pc = new DefaultProjectContent(); |
|
pc.ReferencedContents.Add(projectContentRegistry.Mscorlib); |
|
pc.ReferencedContents.Add(projectContentRegistry.GetProjectContentForReference("System.Windows.Forms", "System.Windows.Forms")); |
|
HostCallback.GetCurrentProjectContent = delegate { |
|
return pc; |
|
}; |
|
lastPC = pc; |
|
NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(pc); |
|
visitor.VisitCompilationUnit(p.CompilationUnit, null); |
|
visitor.Cu.FileName = fileName; |
|
Assert.AreEqual(0, p.Errors.Count, "Parse error preparing compilation unit"); |
|
visitor.Cu.ErrorsDuringCompile = p.Errors.Count > 0; |
|
foreach (IClass c in visitor.Cu.Classes) { |
|
pc.AddClassToNamespaceList(c); |
|
} |
|
|
|
return visitor.Cu; |
|
} |
|
|
|
public IProjectContent lastPC; |
|
|
|
ICompilationUnit ParseVB(string fileName, string fileContent) |
|
{ |
|
ICSharpCode.NRefactory.IParser p = ICSharpCode.NRefactory.ParserFactory.CreateParser(ICSharpCode.NRefactory.SupportedLanguage.VBNet, new StringReader(fileContent)); |
|
p.ParseMethodBodies = false; |
|
p.Parse(); |
|
DefaultProjectContent pc = new DefaultProjectContent(); |
|
HostCallback.GetCurrentProjectContent = delegate { |
|
return pc; |
|
}; |
|
pc.ReferencedContents.Add(projectContentRegistry.Mscorlib); |
|
pc.ReferencedContents.Add(projectContentRegistry.GetProjectContentForReference("System.Windows.Forms", "System.Windows.Forms")); |
|
pc.ReferencedContents.Add(projectContentRegistry.GetProjectContentForReference("Microsoft.VisualBasic", "Microsoft.VisualBasic")); |
|
pc.Language = LanguageProperties.VBNet; |
|
lastPC = pc; |
|
NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(pc); |
|
visitor.VisitCompilationUnit(p.CompilationUnit, null); |
|
visitor.Cu.FileName = fileName; |
|
Assert.AreEqual(0, p.Errors.Count, "Parse error preparing compilation unit"); |
|
visitor.Cu.ErrorsDuringCompile = p.Errors.Count > 0; |
|
foreach (IClass c in visitor.Cu.Classes) { |
|
pc.AddClassToNamespaceList(c); |
|
} |
|
|
|
return visitor.Cu; |
|
} |
|
|
|
ParseInformation AddCompilationUnit(ICompilationUnit parserOutput, string fileName) |
|
{ |
|
return ParserService.RegisterParseInformation(fileName, parserOutput); |
|
} |
|
|
|
public ResolveResult Resolve(string program, string expression, int line) |
|
{ |
|
return Resolve(program, expression, line, 0, ExpressionContext.Default); |
|
} |
|
|
|
public ResolveResult Resolve(string program, string expression, int line, int column, ExpressionContext context) |
|
{ |
|
ParseInformation parseInfo = AddCompilationUnit(Parse("a.cs", program), "a.cs"); |
|
|
|
NRefactoryResolver resolver = new NRefactoryResolver(LanguageProperties.CSharp); |
|
ExpressionResult expressionResult = new ExpressionResult(expression, new DomRegion(line, column), context, null); |
|
return resolver.Resolve(expressionResult, parseInfo, program); |
|
} |
|
|
|
public ResolveResult ResolveVB(string program, string expression, int line) |
|
{ |
|
ParseInformation parseInfo = AddCompilationUnit(ParseVB("a.vb", program), "a.vb"); |
|
|
|
NRefactoryResolver resolver = new NRefactoryResolver(LanguageProperties.VBNet); |
|
ExpressionResult expressionResult = new ExpressionResult(expression, new DomRegion(line, 0), ExpressionContext.Default, null); |
|
return resolver.Resolve(expressionResult, parseInfo, program); |
|
} |
|
|
|
public T Resolve<T>(string program, string expression, int line) where T : ResolveResult |
|
{ |
|
ResolveResult rr = Resolve(program, expression, line); |
|
Assert.IsNotNull(rr, "Resolve returned null (expression=" + expression + ")"); |
|
Assert.AreEqual(typeof(T), rr.GetType()); |
|
return (T)rr; |
|
} |
|
|
|
public T Resolve<T>(string program, string expression, int line, int column, ExpressionContext context) where T : ResolveResult |
|
{ |
|
ResolveResult rr = Resolve(program, expression, line, column, context); |
|
Assert.IsNotNull(rr, "Resolve returned null (expression=" + expression + ")"); |
|
Assert.AreEqual(typeof(T), rr.GetType()); |
|
return (T)rr; |
|
} |
|
|
|
public T ResolveVB<T>(string program, string expression, int line) where T : ResolveResult |
|
{ |
|
ResolveResult rr = ResolveVB(program, expression, line); |
|
Assert.IsNotNull(rr, "Resolve returned null (expression=" + expression + ")"); |
|
Assert.AreEqual(typeof(T), rr.GetType()); |
|
return (T)rr; |
|
} |
|
#endregion |
|
|
|
#region Test for old issues (Fidalgo) |
|
// Issue SD-291 |
|
[Test] |
|
public void VBNetMultipleVariableDeclarationsTest() |
|
{ |
|
string program = @"Class X |
|
Shared Sub Main |
|
Dim a, b As String |
|
|
|
End Sub |
|
End Class |
|
"; |
|
ResolveResult result = ResolveVB<LocalResolveResult>(program, "a", 4); |
|
Assert.AreEqual("System.String", result.ResolvedType.FullyQualifiedName); |
|
|
|
result = ResolveVB<LocalResolveResult>(program, "b", 4); |
|
Assert.AreEqual("System.String", result.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
// Issue SD-258 |
|
[Test] |
|
public void VBNetForeachLoopVariableTest() |
|
{ |
|
string program = @"Class Test |
|
Shared Sub Main() |
|
For Each c As String In MyColl |
|
|
|
Next |
|
End Sub |
|
End Class |
|
"; |
|
ResolveResult result = ResolveVB<LocalResolveResult>(program, "c", 4); |
|
Assert.AreEqual("System.String", result.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
// Issue SD-265 |
|
[Test] |
|
public void VBNetStaticMembersOnInstanceTest() |
|
{ |
|
string program = @"Class X |
|
Sub Z() |
|
Dim a As String |
|
|
|
End Sub |
|
End Class |
|
"; |
|
ResolveResult result = ResolveVB(program, "a", 4); |
|
Assert.IsNotNull(result, "result"); |
|
ArrayList arr = result.GetCompletionData(lastPC); |
|
Assert.IsNotNull(arr, "arr"); |
|
foreach (object o in arr) { |
|
if (o is IMember) { |
|
if (((IMember)o).FullyQualifiedName == "System.String.Empty") |
|
return; |
|
} |
|
} |
|
Assert.Fail("Static member empty not found on string instance!"); |
|
} |
|
|
|
// Issue SD-217 |
|
[Test] |
|
public void VBNetLocalArrayLookupTest() |
|
{ |
|
string program = @"Module Main |
|
Sub Main() |
|
Dim t As String() |
|
|
|
End Sub |
|
End Module |
|
"; |
|
ResolveResult result = ResolveVB<LocalResolveResult>(program, "t", 4); |
|
|
|
ArrayList arr = result.GetCompletionData(lastPC); |
|
Assert.IsNotNull(arr, "arr"); |
|
foreach (object o in arr) { |
|
if (o is IMember) { |
|
if (((IMember)o).FullyQualifiedName == "System.Array.Length") |
|
return; |
|
} |
|
} |
|
Assert.Fail("Length not found on array instance (resolve result was " + result.ResolvedType.ToString() + ")"); |
|
} |
|
#endregion |
|
|
|
#region Simple Tests |
|
[Test] |
|
public void InheritedInterfaceResolveTest() |
|
{ |
|
string program = @"using System; |
|
class A { |
|
void Method(IInterface1 a) { |
|
|
|
} |
|
} |
|
interface IInterface1 : IInterface2, IDisposable { |
|
void Method1(); |
|
} |
|
interface IInterface2 { |
|
void Method2(); |
|
} |
|
"; |
|
ResolveResult result = Resolve<LocalResolveResult>(program, "a", 4); |
|
ArrayList arr = result.GetCompletionData(lastPC); |
|
Assert.IsNotNull(arr, "arr"); |
|
bool m1 = false; |
|
bool m2 = false; |
|
bool disp = false; |
|
bool getType = false; |
|
foreach (IMethod m in arr) { |
|
if (m.Name == "Method1") |
|
m1 = true; |
|
if (m.Name == "Method2") |
|
m2 = true; |
|
if (m.Name == "Dispose") |
|
disp = true; |
|
if (m.Name == "GetType") |
|
getType = true; |
|
} |
|
Assert.IsTrue(m1, "Method1 not found"); |
|
Assert.IsTrue(m2, "Method2 not found"); |
|
Assert.IsTrue(disp, "Dispose not found"); |
|
Assert.IsTrue(getType, "GetType not found"); |
|
} |
|
|
|
[Test] |
|
public void InvalidMethodCallTest() |
|
{ |
|
string program = @"class A { |
|
void Method(string b) { |
|
|
|
} |
|
} |
|
"; |
|
ResolveResult result = Resolve(program, "b.ThisMethodDoesNotExistOnString()", 3); |
|
Assert.IsNull(result, "result"); |
|
} |
|
|
|
[Test] |
|
public void GenericObjectCreation() |
|
{ |
|
string program = @"using System.Collections.Generic; |
|
class A { |
|
static void Main() { |
|
|
|
} |
|
} |
|
"; |
|
MemberResolveResult result = Resolve<MemberResolveResult>(program, "new List<string>()", 4); |
|
Assert.AreEqual("System.Collections.Generic.List.#ctor", result.ResolvedMember.FullyQualifiedName); |
|
Assert.AreEqual("System.Collections.Generic.List{System.String}", result.ResolvedType.DotNetName); |
|
} |
|
|
|
[Test] |
|
public void InvalidConstructorCallTest() |
|
{ |
|
string program = @"class A { |
|
void Method() { |
|
|
|
} |
|
} |
|
"; |
|
ResolveResult result = Resolve(program, "new ThisClassDoesNotExist()", 3); |
|
Assert.IsNull(result); |
|
} |
|
|
|
[Test] |
|
public void OverriddenMethodCallTest() |
|
{ |
|
string program = @"class A { |
|
void Method() { |
|
|
|
} |
|
|
|
public abstract int GetRandomNumber(); |
|
} |
|
class B : A { |
|
public override int GetRandomNumber() { |
|
return 4; // chosen by fair dice roll. |
|
// guaranteed to be random |
|
} |
|
} |
|
"; |
|
MemberResolveResult result = Resolve<MemberResolveResult>(program, "new B().GetRandomNumber()", 3); |
|
Assert.AreEqual("B.GetRandomNumber", result.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void OverriddenMethodCallTest2() |
|
{ |
|
string program = @"class A { |
|
void Method() { |
|
|
|
} |
|
|
|
public abstract int GetRandomNumber(string a, A b); |
|
} |
|
class B : A { |
|
public override int GetRandomNumber(string b, A a) { |
|
return 4; // chosen by fair dice roll. |
|
// guaranteed to be random |
|
} |
|
} |
|
"; |
|
MemberResolveResult result = Resolve<MemberResolveResult>(program, "new B().GetRandomNumber(\"x\", this)", 3); |
|
Assert.AreEqual("B.GetRandomNumber", result.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void MethodCallTest() |
|
{ |
|
string program = @"class A { |
|
void Method() { |
|
|
|
} |
|
|
|
int TargetMethod() { |
|
return 3; |
|
} |
|
} |
|
"; |
|
ResolveResult result = Resolve<MemberResolveResult>(program, "TargetMethod()", 3); |
|
Assert.AreEqual("System.Int32", result.ResolvedType.FullyQualifiedName, "'TargetMethod()'"); |
|
} |
|
|
|
[Test] |
|
public void MethodGroupResolveTest() |
|
{ |
|
string program = @"class A { |
|
void Method() { |
|
|
|
} |
|
|
|
void TargetMethod(int a) { } |
|
void TargetMethod<T>(T a) { } |
|
} |
|
"; |
|
MethodGroupResolveResult result = Resolve<MethodGroupResolveResult>(program, "TargetMethod", 3); |
|
Assert.AreEqual("TargetMethod", result.Name); |
|
Assert.AreEqual(2, result.Methods[0].Count); |
|
|
|
result = Resolve<MethodGroupResolveResult>(program, "TargetMethod<string>", 3); |
|
Assert.AreEqual("TargetMethod", result.Name); |
|
Assert.AreEqual(1, result.Methods[0].Count); |
|
Assert.AreEqual("System.String", result.GetMethodIfSingleOverload().Parameters[0].ReturnType.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void ThisMethodCallTest() |
|
{ |
|
string program = @"class A { |
|
void Method() { |
|
|
|
} |
|
|
|
int TargetMethod() { |
|
return 3; |
|
} |
|
} |
|
"; |
|
ResolveResult result = Resolve<MemberResolveResult>(program, "this.TargetMethod()", 3); |
|
Assert.AreEqual("System.Int32", result.ResolvedType.FullyQualifiedName, "'this.TargetMethod()'"); |
|
} |
|
|
|
[Test] |
|
public void EventCallTest() |
|
{ |
|
string program = @"using System; |
|
class A { |
|
void Method() { |
|
|
|
} |
|
|
|
public event EventHandler TestEvent; |
|
} |
|
"; |
|
MemberResolveResult result = Resolve<MemberResolveResult>(program, "TestEvent(this, EventArgs.Empty)", 4); |
|
Assert.AreEqual("A.TestEvent", result.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void VoidTest() |
|
{ |
|
string program = @"using System; |
|
class A { |
|
void TestMethod() { |
|
|
|
} |
|
} |
|
"; |
|
ResolveResult result = Resolve(program, "TestMethod()", 4); |
|
Assert.IsNotNull(result); |
|
Assert.AreSame(VoidReturnType.Instance, result.ResolvedType, result.ResolvedType.ToString()); |
|
Assert.AreEqual(0, result.GetCompletionData(lastPC).Count); |
|
} |
|
|
|
[Test] |
|
public void ThisEventCallTest() |
|
{ |
|
string program = @"using System; |
|
class A { |
|
void Method() { |
|
|
|
} |
|
|
|
public event EventHandler TestEvent; |
|
} |
|
"; |
|
MemberResolveResult result = Resolve<MemberResolveResult>(program, "this.TestEvent(this, EventArgs.Empty)", 4); |
|
Assert.AreEqual("A.TestEvent", result.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void DelegateCallTest() |
|
{ |
|
string program = @"using System.Reflection; |
|
class A { |
|
void Method() { |
|
ModuleResolveEventHandler eh = SomeClass.SomeProperty; |
|
|
|
} |
|
} |
|
"; |
|
LocalResolveResult result = Resolve<LocalResolveResult>(program, "eh(this, new ResolveEventArgs())", 5); |
|
Assert.AreEqual("eh", result.Field.Name); |
|
|
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "eh(this, new ResolveEventArgs()).GetType(\"bla\")", 5); |
|
Assert.AreEqual("System.Reflection.Module.GetType", mrr.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void DelegateReturnedFromMethodCallTest() |
|
{ |
|
string program = @"using System; |
|
class A { |
|
void Method() { |
|
|
|
} |
|
abstract Predicate<string> GetHandler(); |
|
} |
|
"; |
|
ResolveResult result = Resolve<MemberResolveResult>(program, "GetHandler()(abc)", 4); |
|
Assert.AreEqual("System.Boolean", result.ResolvedType.FullyQualifiedName); |
|
|
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "GetHandler()(abc).ToString()", 4); |
|
Assert.AreEqual("System.Boolean.ToString", mrr.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void OverloadLookupTest() |
|
{ |
|
string program = @"class A { |
|
void Method() { |
|
|
|
} |
|
|
|
int Multiply(int a, int b) { return a * b; } |
|
double Multiply(double a, double b) { return a * b; } |
|
} |
|
"; |
|
ResolveResult result = Resolve<MemberResolveResult>(program, "Multiply(1, 1)", 3); |
|
Assert.AreEqual("System.Int32", result.ResolvedType.FullyQualifiedName, "'Multiply(1,1)'"); |
|
|
|
result = Resolve<MemberResolveResult>(program, "Multiply(1.0, 1.0)", 3); |
|
Assert.AreEqual("System.Double", result.ResolvedType.FullyQualifiedName, "'Multiply(1.0,1.0)'"); |
|
} |
|
|
|
[Test] |
|
public void CTorOverloadLookupTest() |
|
{ |
|
string program = @"class A { |
|
void Method() { |
|
|
|
} |
|
|
|
static A() {} |
|
A() {} |
|
A(int intVal) {} |
|
A(double dblVal) {} |
|
} |
|
"; |
|
MemberResolveResult result = Resolve<MemberResolveResult>(program, "new A()", 3); |
|
IMethod m = (IMethod)result.ResolvedMember; |
|
Assert.IsFalse(m.IsStatic, "new A() is static"); |
|
Assert.AreEqual(0, m.Parameters.Count, "new A() parameter count"); |
|
Assert.AreEqual("A", result.ResolvedType.FullyQualifiedName); |
|
|
|
result = Resolve<MemberResolveResult>(program, "new A(10)", 3); |
|
m = (IMethod)result.ResolvedMember; |
|
Assert.AreEqual(1, m.Parameters.Count, "new A(10) parameter count"); |
|
Assert.AreEqual("intVal", m.Parameters[0].Name, "new A(10) parameter"); |
|
|
|
result = Resolve<MemberResolveResult>(program, "new A(11.1)", 3); |
|
m = (IMethod)result.ResolvedMember; |
|
Assert.AreEqual(1, m.Parameters.Count, "new A(11.1) parameter count"); |
|
Assert.AreEqual("dblVal", m.Parameters[0].Name, "new A(11.1) parameter"); |
|
} |
|
|
|
[Test] |
|
public void DefaultCTorOverloadLookupTest() |
|
{ |
|
string program = @"class A { |
|
void Method() { |
|
|
|
} |
|
} |
|
"; |
|
MemberResolveResult result = Resolve<MemberResolveResult>(program, "new A()", 3); |
|
IMethod m = (IMethod)result.ResolvedMember; |
|
Assert.IsNotNull(m); |
|
Assert.AreEqual("A", result.ResolvedType.FullyQualifiedName); |
|
|
|
ArrayList ar = result.GetCompletionData(result.CallingClass.ProjectContent); |
|
Assert.IsTrue(ContainsMember(ar, "A.Method")); |
|
} |
|
|
|
[Test] |
|
public void ValueInsideSetterTest() |
|
{ |
|
string program = @"class A { |
|
public string Property { |
|
set { |
|
|
|
} |
|
} |
|
} |
|
"; |
|
LocalResolveResult result = Resolve<LocalResolveResult>(program, "value", 4); |
|
Assert.AreEqual("System.String", result.ResolvedType.FullyQualifiedName); |
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "value.ToString()", 4); |
|
Assert.AreEqual("System.String.ToString", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
int valueParameterCount = 0; |
|
foreach (object o in CtrlSpaceResolveCSharp(program, 4, ExpressionContext.Default)) { |
|
IField f = o as IField; |
|
if (f != null && f.Name == "value") { |
|
valueParameterCount++; |
|
Assert.IsTrue(f.IsParameter); |
|
Assert.AreEqual("System.String", f.ReturnType.FullyQualifiedName); |
|
} |
|
} |
|
Assert.IsTrue(valueParameterCount == 1); |
|
} |
|
|
|
[Test] |
|
public void ValueInsideEventTest() |
|
{ |
|
string program = @"using System; class A { |
|
public event EventHandler Ev { |
|
add { |
|
|
|
} |
|
remove {} |
|
} |
|
} |
|
"; |
|
LocalResolveResult result = Resolve<LocalResolveResult>(program, "value", 4); |
|
Assert.AreEqual("System.EventHandler", result.ResolvedType.FullyQualifiedName); |
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "value.DynamicInvoke(null)", 4); |
|
Assert.AreEqual("System.Delegate.DynamicInvoke", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
int valueParameterCount = 0; |
|
foreach (object o in CtrlSpaceResolveCSharp(program, 4, ExpressionContext.Default)) { |
|
IField f = o as IField; |
|
if (f != null && f.Name == "value") { |
|
valueParameterCount++; |
|
Assert.IsTrue(f.IsParameter); |
|
Assert.AreEqual("System.EventHandler", f.ReturnType.FullyQualifiedName); |
|
} |
|
} |
|
Assert.IsTrue(valueParameterCount == 1); |
|
} |
|
|
|
[Test] |
|
public void ValueInsideIndexerSetterTest() |
|
{ |
|
string program = @"using System; class A { |
|
public string this[int arg] { |
|
set { |
|
|
|
} |
|
} |
|
} |
|
"; |
|
LocalResolveResult result = Resolve<LocalResolveResult>(program, "value", 4); |
|
Assert.AreEqual("System.String", result.ResolvedType.FullyQualifiedName); |
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "value.ToString()", 4); |
|
Assert.AreEqual("System.String.ToString", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
int valueParameterCount = 0; |
|
foreach (object o in CtrlSpaceResolveCSharp(program, 4, ExpressionContext.Default)) { |
|
IField f = o as IField; |
|
if (f != null && f.Name == "value") { |
|
valueParameterCount++; |
|
Assert.IsTrue(f.IsParameter); |
|
Assert.AreEqual("System.String", f.ReturnType.FullyQualifiedName); |
|
} |
|
} |
|
Assert.IsTrue(valueParameterCount == 1); |
|
} |
|
|
|
[Test] |
|
public void AnonymousMethodParameters() |
|
{ |
|
string program = @"using System; |
|
class A { |
|
void Method() { |
|
SomeEvent += delegate(object sender, EventArgs e) { |
|
|
|
}; |
|
} } |
|
"; |
|
ResolveResult result = Resolve<LocalResolveResult>(program, "e", 5); |
|
Assert.AreEqual("System.EventArgs", result.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void DefaultTypeCSharp() |
|
{ |
|
string program = @"class A { |
|
void Method() { |
|
|
|
} } |
|
"; |
|
ResolveResult result = Resolve<TypeResolveResult>(program, "int", 3); |
|
Assert.AreEqual("System.Int32", result.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void DefaultTypeVB() |
|
{ |
|
string program = @"Class A |
|
Sub Method() |
|
|
|
End Sub |
|
End Class |
|
"; |
|
ResolveResult result = ResolveVB<TypeResolveResult>(program, "inTeGer", 3); |
|
Assert.AreEqual("System.Int32", result.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
// PrimitiveTypeOutsideClass and OtherTypeOutsideClass |
|
// are necessary for delegate declarations and class inheritance |
|
// (because "outside" is everything before {, so the reference to the |
|
// base class is outside the class) |
|
[Test] |
|
public void PrimitiveTypeOutsideClass() |
|
{ |
|
string program = @"class A { |
|
|
|
} |
|
|
|
class B { |
|
|
|
} |
|
"; |
|
ResolveResult result = Resolve<TypeResolveResult>(program, "int", 4); |
|
Assert.AreEqual("System.Int32", result.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void OtherTypeOutsideClass() |
|
{ |
|
string program = @"using System; |
|
class A { |
|
|
|
} |
|
|
|
class B { |
|
|
|
} |
|
"; |
|
ResolveResult result = Resolve<TypeResolveResult>(program, "Activator", 5); |
|
Assert.AreEqual("System.Activator", result.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void FullyQualifiedTypeOutsideClass() |
|
{ |
|
string program = @"class A { |
|
|
|
} |
|
|
|
class B { |
|
|
|
} |
|
"; |
|
ResolveResult result = Resolve<TypeResolveResult>(program, "System.Activator", 4); |
|
Assert.AreEqual("System.Activator", result.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void LoopVariableScopeTest() |
|
{ |
|
string program = @"using System; |
|
class TestClass { |
|
void Test() { |
|
for (int i = 0; i < 10; i++) { |
|
|
|
} |
|
for (long i = 0; i < 10; i++) { |
|
|
|
} |
|
} |
|
} |
|
"; |
|
LocalResolveResult lr = Resolve<LocalResolveResult>(program, "i", 5); |
|
Assert.AreEqual("System.Int32", lr.ResolvedType.FullyQualifiedName); |
|
lr = Resolve<LocalResolveResult>(program, "i", 8); |
|
Assert.AreEqual("System.Int64", lr.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void ShortMaxValueTest() |
|
{ |
|
string program = @"using System; |
|
class TestClass { |
|
void Test() { |
|
|
|
} |
|
} |
|
"; |
|
ResolveResult rr = Resolve<MemberResolveResult>(program, "short.MaxValue", 4); |
|
Assert.AreEqual("System.Int16", rr.ResolvedType.FullyQualifiedName); |
|
|
|
rr = Resolve<ResolveResult>(program, "(short.MaxValue)", 4); |
|
Assert.AreEqual("System.Int16", rr.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void VBNetArrayReturnedFromMethodTest() |
|
{ |
|
string program = @"Module Main |
|
Sub Main() |
|
|
|
End Sub |
|
Function F() As String() |
|
End Function |
|
End Module |
|
"; |
|
MemberResolveResult result = ResolveVB<MemberResolveResult>(program, "F()(0)", 3); |
|
Assert.AreEqual("System.String", result.ResolvedType.FullyQualifiedName); |
|
Assert.IsFalse(result.ResolvedType.IsArrayReturnType); |
|
Assert.IsInstanceOfType(typeof(IProperty), result.ResolvedMember); |
|
Assert.IsTrue((result.ResolvedMember as IProperty).IsIndexer); |
|
} |
|
|
|
[Test] |
|
public void ConstructorBaseCall() |
|
{ |
|
string program = @"using System; |
|
class A { |
|
public A(int a) {} |
|
} |
|
class B : A { |
|
public B(int a) |
|
: base(a) /*7*/ |
|
{} |
|
} |
|
class C : B { |
|
public C(int a) |
|
: base(a) /*12*/ |
|
{} |
|
} |
|
"; |
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "new A(2)", 3); |
|
IMember aCtor = mrr.ResolvedMember; |
|
Assert.AreEqual("A.#ctor", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "new B(2)", 3); |
|
IMember bCtor = mrr.ResolvedMember; |
|
Assert.AreEqual("B.#ctor", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "base(a)", 7); |
|
Assert.AreEqual("A.#ctor", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "base(a)", 12); |
|
Assert.AreEqual("B.#ctor", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
// ensure that the reference pointing to the B ctor is not seen as a reference |
|
// to the A ctor. |
|
Assert.IsTrue(Refactoring.RefactoringService.IsReferenceToMember(bCtor, mrr)); |
|
Assert.IsFalse(Refactoring.RefactoringService.IsReferenceToMember(aCtor, mrr)); |
|
} |
|
|
|
[Test] |
|
public void ConstructorCallInCreationContext() |
|
{ |
|
string program = @"using System; |
|
class A { |
|
public A(int a) {} |
|
} |
|
"; |
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "new A(2)", 3, 0, ExpressionContext.ObjectCreation); |
|
Assert.AreEqual("A.#ctor", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "A(2)", 3, 0, ExpressionContext.ObjectCreation); |
|
Assert.AreEqual("A.#ctor", mrr.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void VBIndexerCall() |
|
{ |
|
string program = @"Imports Microsoft.VisualBasic |
|
Class A |
|
Sub Method() |
|
Dim c As Collection |
|
|
|
End Sub |
|
End Class |
|
"; |
|
MemberResolveResult result = ResolveVB<MemberResolveResult>(program, "c(3)", 5); |
|
Assert.AreEqual("Microsoft.VisualBasic.Collection.Item", result.ResolvedMember.FullyQualifiedName); |
|
IProperty p = (IProperty)result.ResolvedMember; |
|
Assert.IsTrue(p.IsIndexer); |
|
|
|
result = ResolveVB<MemberResolveResult>(program, "c.Item(3)", 5); |
|
Assert.AreEqual("Microsoft.VisualBasic.Collection.Item", result.ResolvedMember.FullyQualifiedName); |
|
p = (IProperty)result.ResolvedMember; |
|
Assert.IsTrue(p.IsIndexer); |
|
} |
|
|
|
[Test] |
|
public void VBPInvokeCall() |
|
{ |
|
string program = @"Imports Microsoft.VisualBasic |
|
Class A |
|
Declare Function GetRectangleArea Lib ""..\..\PinvokeLib.dll"" (ByRef rectangle As MyRectangle) As Integer |
|
Sub Method(r1 As MyRectangle) |
|
|
|
End Sub |
|
End Class |
|
"; |
|
MemberResolveResult result = ResolveVB<MemberResolveResult>(program, "GetRectangleArea(r1)", 5); |
|
Assert.AreEqual("A.GetRectangleArea", result.ResolvedMember.FullyQualifiedName); |
|
|
|
IMethod m = (IMethod)result.ResolvedMember; |
|
Assert.IsTrue(m.IsStatic); |
|
Assert.AreEqual("System.Int32", m.ReturnType.FullyQualifiedName); |
|
Assert.AreEqual(1, m.Parameters.Count); |
|
Assert.AreEqual("rectangle", m.Parameters[0].Name); |
|
Assert.IsTrue(m.Parameters[0].IsRef); |
|
} |
|
#endregion |
|
|
|
#region Import namespace tests |
|
[Test] |
|
public void NamespacePreferenceTest() |
|
{ |
|
// Classes in the current namespace are preferred over classes from |
|
// imported namespaces |
|
string program = @"using System; |
|
namespace Testnamespace { |
|
class A { |
|
|
|
} |
|
|
|
class Activator { |
|
|
|
} |
|
} |
|
"; |
|
ResolveResult result = Resolve<TypeResolveResult>(program, "Activator", 4); |
|
Assert.AreEqual("Testnamespace.Activator", result.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void ParentNamespaceTypeLookup() |
|
{ |
|
// Classes in the current namespace are preferred over classes from |
|
// imported namespaces |
|
string program = @"using System; |
|
namespace Root { |
|
class Alpha {} |
|
} |
|
namespace Root.Child { |
|
class Beta { |
|
|
|
} |
|
} |
|
"; |
|
ResolveResult result = Resolve<TypeResolveResult>(program, "Alpha", 7); |
|
Assert.AreEqual("Root.Alpha", result.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
ArrayList CtrlSpaceResolveCSharp(string program, int line, ExpressionContext context) |
|
{ |
|
ParseInformation parseInfo = AddCompilationUnit(Parse("a.cs", program), "a.cs"); |
|
|
|
NRefactoryResolver resolver = new NRefactoryResolver(LanguageProperties.CSharp); |
|
return resolver.CtrlSpace(line, 0, parseInfo, program, context); |
|
} |
|
|
|
[Test] |
|
public void ParentNamespaceCtrlSpace() |
|
{ |
|
string program = @"using System; |
|
namespace Root { |
|
class Alpha {} |
|
} |
|
namespace Root.Child { |
|
class Beta { |
|
|
|
} |
|
} |
|
"; |
|
ArrayList m = CtrlSpaceResolveCSharp(program, 7, ExpressionContext.Default); |
|
Assert.IsTrue(TypeExists(m, "Beta"), "Beta must exist"); |
|
Assert.IsTrue(TypeExists(m, "Alpha"), "Alpha must exist"); |
|
} |
|
|
|
bool TypeExists(ArrayList m, string name) |
|
{ |
|
foreach (object o in m) { |
|
IClass c = o as IClass; |
|
if (c != null && c.Name == name) |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
[Test] |
|
public void ImportedSubnamespaceTestCSharp() |
|
{ |
|
// using an import in this way is not possible in C# |
|
string program = @"using System; |
|
class TestClass { |
|
void Test() { |
|
Collections.ArrayList a; |
|
|
|
} |
|
} |
|
"; |
|
ResolveResult result = Resolve(program, "Collections.ArrayList", 4); |
|
Assert.IsNull(result, "Collections.ArrayList should not resolve"); |
|
LocalResolveResult local = Resolve<LocalResolveResult>(program, "a", 5); |
|
Assert.IsNull(local.ResolvedType, "the full type should not be resolved"); |
|
} |
|
|
|
[Test] |
|
public void ImportedSubnamespaceTestVBNet() |
|
{ |
|
// using an import this way IS possible in VB.NET |
|
string program = @"Imports System |
|
Class TestClass |
|
Sub Test() |
|
Dim a As Collections.ArrayList |
|
|
|
End Sub |
|
End Class |
|
"; |
|
TypeResolveResult type = ResolveVB<TypeResolveResult>(program, "Collections.ArrayList", 4); |
|
Assert.AreEqual("System.Collections.ArrayList", type.ResolvedClass.FullyQualifiedName, "TypeResolveResult"); |
|
LocalResolveResult local = ResolveVB<LocalResolveResult>(program, "a", 5); |
|
Assert.AreEqual("System.Collections.ArrayList", local.ResolvedType.FullyQualifiedName, |
|
"the full type should be resolved"); |
|
} |
|
|
|
[Test] |
|
public void ImportAliasTest() |
|
{ |
|
string program = @"using COL = System.Collections; |
|
class TestClass { |
|
void Test() { |
|
COL.ArrayList a; |
|
|
|
} |
|
} |
|
"; |
|
TypeResolveResult type = Resolve<TypeResolveResult>(program, "COL.ArrayList", 4); |
|
Assert.IsNotNull(type, "COL.ArrayList should resolve to a type"); |
|
Assert.AreEqual("System.Collections.ArrayList", type.ResolvedClass.FullyQualifiedName, "TypeResolveResult"); |
|
LocalResolveResult local = Resolve<LocalResolveResult>(program, "a", 5); |
|
Assert.AreEqual("System.Collections.ArrayList", local.ResolvedType.FullyQualifiedName, |
|
"the full type should be resolved"); |
|
} |
|
|
|
[Test] |
|
public void ImportAliasNamespaceResolveTest() |
|
{ |
|
NamespaceResolveResult ns; |
|
string program = "using COL = System.Collections;\r\nclass A {\r\n\r\n}\r\n"; |
|
ns = Resolve<NamespaceResolveResult>(program, "COL", 3); |
|
Assert.AreEqual("System.Collections", ns.Name, "COL"); |
|
ns = Resolve<NamespaceResolveResult>(program, "COL.Generic", 3); |
|
Assert.AreEqual("System.Collections.Generic", ns.Name, "COL.Generic"); |
|
} |
|
|
|
[Test] |
|
public void ImportAliasClassResolveTest() |
|
{ |
|
string program = @"using COL = System.Collections.ArrayList; |
|
class TestClass { |
|
void Test() { |
|
COL a = new COL(); |
|
|
|
} |
|
} |
|
"; |
|
TypeResolveResult rr = Resolve<TypeResolveResult>(program, "COL", 4); |
|
Assert.AreEqual("System.Collections.ArrayList", rr.ResolvedClass.FullyQualifiedName, "COL"); |
|
LocalResolveResult lr = Resolve<LocalResolveResult>(program, "a", 5); |
|
Assert.AreEqual("System.Collections.ArrayList", lr.ResolvedType.FullyQualifiedName, "a"); |
|
} |
|
|
|
[Test] |
|
public void ResolveNamespaceSD2_863() |
|
{ |
|
string program = @"using System; |
|
namespace A.C { class D {} } |
|
namespace A.B.C { class D {} } |
|
namespace A.B { |
|
class TestClass { |
|
void Test() { |
|
|
|
} |
|
} |
|
} |
|
"; |
|
NamespaceResolveResult nrr = Resolve<NamespaceResolveResult>(program, "C", 7); |
|
Assert.AreEqual("A.B.C", nrr.Name, "nrr.Name"); |
|
TypeResolveResult trr = Resolve<TypeResolveResult>(program, "C.D", 7); |
|
Assert.AreEqual("A.B.C.D", trr.ResolvedClass.FullyQualifiedName, "trr.ResolvedClass.FullyQualifiedName"); |
|
} |
|
|
|
[Test] |
|
public void ResolveTypeSD2_863() |
|
{ |
|
string program = @"using System; |
|
namespace A { class C {} } |
|
namespace A.B { |
|
class C {} |
|
class TestClass { |
|
void Test() { |
|
|
|
} |
|
} |
|
} |
|
"; |
|
TypeResolveResult trr = Resolve<TypeResolveResult>(program, "C", 7); |
|
Assert.AreEqual("A.B.C", trr.ResolvedClass.FullyQualifiedName, "trr.ResolvedClass.FullyQualifiedName"); |
|
} |
|
|
|
[Test] |
|
public void VBBaseConstructorCall() |
|
{ |
|
string program = @"Class A |
|
Inherits B |
|
Sub New() |
|
|
|
End Sub |
|
Sub Test() |
|
|
|
End Sub |
|
End Class |
|
Class B |
|
Sub New(a As String) |
|
End Sub |
|
End Class |
|
"; |
|
MemberResolveResult mrr = ResolveVB<MemberResolveResult>(program, "mybase.new(\"bb\")", 4); |
|
Assert.AreEqual("B", mrr.ResolvedMember.DeclaringType.FullyQualifiedName); |
|
Assert.IsTrue(((IMethod)mrr.ResolvedMember).IsConstructor); |
|
|
|
ResolveResult result = ResolveVB<VBBaseOrThisReferenceInConstructorResolveResult>(program, "mybase", 4); |
|
Assert.AreEqual("B", result.ResolvedType.FullyQualifiedName); |
|
Assert.IsTrue(ContainsMember(result.GetCompletionData(result.CallingClass.ProjectContent), mrr.ResolvedMember.FullyQualifiedName)); |
|
|
|
result = ResolveVB<BaseResolveResult>(program, "mybase", 7); |
|
Assert.AreEqual("B", result.ResolvedType.FullyQualifiedName); |
|
Assert.IsFalse(ContainsMember(result.GetCompletionData(result.CallingClass.ProjectContent), mrr.ResolvedMember.FullyQualifiedName)); |
|
} |
|
|
|
bool ContainsMember(IEnumerable input, string fullMemberName) |
|
{ |
|
return input.OfType<IMember>().Any(m => m.FullyQualifiedName == fullMemberName); |
|
} |
|
#endregion |
|
|
|
#region Import class tests |
|
const string importClassProgram = @"Imports System |
|
Imports System.Math |
|
|
|
Class TestClass |
|
Sub Main() |
|
|
|
End Sub |
|
End Class |
|
"; |
|
|
|
[Test] |
|
public void TestImportClassMember() |
|
{ |
|
MemberResolveResult mrr = ResolveVB<MemberResolveResult>(importClassProgram, "Pi", 6); |
|
Assert.AreEqual("System.Math.PI", mrr.ResolvedMember.FullyQualifiedName); |
|
mrr = ResolveVB<MemberResolveResult>(importClassProgram, "Pi.ToString()", 6); |
|
Assert.AreEqual("System.Double.ToString", mrr.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void TestImportClassMethod() |
|
{ |
|
MemberResolveResult mrr = ResolveVB<MemberResolveResult>(importClassProgram, "Sin(3)", 6); |
|
Assert.AreEqual("System.Math.Sin", mrr.ResolvedMember.FullyQualifiedName); |
|
mrr = ResolveVB<MemberResolveResult>(importClassProgram, "Sin(3).ToString()", 6); |
|
Assert.AreEqual("System.Double.ToString", mrr.ResolvedMember.FullyQualifiedName); |
|
} |
|
#endregion |
|
|
|
#region Visibility tests |
|
[Test] |
|
public void PrivateMemberTest() |
|
{ |
|
string program = @"using System; |
|
class A { |
|
void TestMethod(B b) { |
|
|
|
} |
|
} |
|
class B { |
|
int member; |
|
} |
|
"; |
|
ResolveResult result = Resolve(program, "b", 4); |
|
Assert.IsNotNull(result); |
|
ArrayList cd = result.GetCompletionData(lastPC); |
|
Assert.IsFalse(MemberExists(cd, "member"), "member should not be in completion lookup"); |
|
result = Resolve(program, "b.member", 4); |
|
Assert.IsTrue(result != null && result.IsValid, "member should be found even though it is not visible!"); |
|
} |
|
|
|
[Test] |
|
public void ProtectedVisibleMemberTest() |
|
{ |
|
string program = @"using System; |
|
class A : B { |
|
static void TestMethod(A a) { |
|
|
|
} |
|
} |
|
class B { |
|
protected int member; |
|
} |
|
"; |
|
ResolveResult result = Resolve(program, "a", 4); |
|
Assert.IsNotNull(result); |
|
ArrayList cd = result.GetCompletionData(lastPC); |
|
Assert.IsTrue(MemberExists(cd, "member"), "member should be in completion lookup"); |
|
result = Resolve(program, "a.member", 4); |
|
Assert.IsTrue(result != null && result.IsValid, "member should be found!"); |
|
} |
|
|
|
[Test] |
|
public void ProtectedMemberVisibleWithImplicitThisReferenceTest() |
|
{ |
|
string program = @"using System; |
|
class A : B { |
|
void TestMethod(A a) { |
|
|
|
} |
|
} |
|
class B { |
|
protected int member; |
|
} |
|
"; |
|
ArrayList results = CtrlSpaceResolveCSharp(program, 4, ExpressionContext.Default); |
|
Assert.IsTrue(MemberExists(results, "member"), "member should be in completion lookup"); |
|
ResolveResult result = Resolve(program, "member", 4); |
|
Assert.IsTrue(result != null && result.IsValid, "member should be found!"); |
|
} |
|
|
|
[Test] |
|
public void ProtectedInvisibleMemberTest() |
|
{ |
|
string program = @"using System; |
|
class A { |
|
void TestMethod(B b) { |
|
|
|
} |
|
} |
|
class B { |
|
protected int member; |
|
} |
|
"; |
|
ResolveResult result = Resolve(program, "b", 4); |
|
Assert.IsNotNull(result); |
|
ArrayList cd = result.GetCompletionData(lastPC); |
|
Assert.IsFalse(MemberExists(cd, "member"), "member should not be in completion lookup"); |
|
result = Resolve(program, "b.member", 4); |
|
Assert.IsTrue(result != null && result.IsValid, "member should be found even though it is not visible!"); |
|
} |
|
|
|
[Test] |
|
public void ProtectedMemberInvisibleWhenNotUsingReferenceOfCurrentTypeTest() |
|
{ |
|
string program = @"using System; |
|
class A : B { |
|
void TestMethod(B b) { |
|
|
|
} |
|
} |
|
class B { |
|
protected int member; |
|
} |
|
"; |
|
ResolveResult result = Resolve(program, "b", 4); |
|
Assert.IsNotNull(result); |
|
ArrayList cd = result.GetCompletionData(lastPC); |
|
Assert.IsFalse(MemberExists(cd, "member"), "member should not be in completion lookup"); |
|
result = Resolve(program, "b.member", 4); |
|
Assert.IsTrue(result != null && result.IsValid, "member should be found even though it is not visible!"); |
|
} |
|
|
|
[Test] |
|
public void ProtectedMemberVisibleWhenUsingBaseReference() |
|
{ |
|
string program = @"using System; |
|
class A : B { |
|
void TestMethod(B b) { |
|
|
|
} |
|
} |
|
class B { |
|
protected int member; |
|
} |
|
"; |
|
ResolveResult result = Resolve(program, "base", 4); |
|
Assert.IsNotNull(result); |
|
ArrayList cd = result.GetCompletionData(lastPC); |
|
Assert.IsTrue(MemberExists(cd, "member"), "member should be in completion lookup"); |
|
result = Resolve(program, "base.member", 4); |
|
Assert.IsTrue(result != null && result.IsValid, "member should be found!"); |
|
} |
|
|
|
[Test] |
|
public void ProtectedMethodInvisibleWhenNotUsingReferenceOfCurrentTypeTest() |
|
{ |
|
string program = @"using System; |
|
class A : B { |
|
void TestMethod(B b) { |
|
|
|
} |
|
} |
|
class B { |
|
protected int Method(); |
|
} |
|
"; |
|
ResolveResult result = Resolve(program, "b", 4); |
|
Assert.IsNotNull(result); |
|
ArrayList cd = result.GetCompletionData(lastPC); |
|
Assert.IsFalse(MemberExists(cd, "Method"), "member should not be in completion lookup"); |
|
result = Resolve(program, "b.Method()", 4); |
|
Assert.IsTrue(result != null && result.IsValid, "method should be found even though it is invisible!"); |
|
} |
|
|
|
[Test] |
|
public void ProtectedMethodVisibleWhenUsingBaseReference() |
|
{ |
|
string program = @"using System; |
|
class A : B { |
|
void TestMethod(B b) { |
|
|
|
} |
|
} |
|
class B { |
|
protected int Method(); |
|
} |
|
"; |
|
ResolveResult result = Resolve(program, "base", 4); |
|
Assert.IsNotNull(result); |
|
ArrayList cd = result.GetCompletionData(lastPC); |
|
Assert.IsTrue(MemberExists(cd, "Method"), "member should be in completion lookup"); |
|
result = Resolve(program, "base.Method()", 4); |
|
Assert.IsTrue(result != null && result.IsValid, "method should be found!"); |
|
} |
|
|
|
[Test] |
|
public void ProtectedMethodVisibleWithImplicitThisReferenceTest() |
|
{ |
|
string program = @"using System; |
|
class A : B { |
|
void TestMethod(A a) { |
|
|
|
} |
|
} |
|
class B { |
|
protected int Method(); |
|
} |
|
"; |
|
ArrayList results = CtrlSpaceResolveCSharp(program, 4, ExpressionContext.Default); |
|
Assert.IsTrue(MemberExists(results, "Method"), "method should be in completion lookup"); |
|
ResolveResult result = Resolve(program, "Method()", 4); |
|
Assert.IsTrue(result != null && result.IsValid, "method should be found!"); |
|
} |
|
|
|
[Test] |
|
public void ProtectedMethodVisibleWithImplicitThisReferenceConflictsWithClassNameTest() |
|
{ |
|
string program = @"using System; |
|
class A : B { |
|
void TestMethod(A a) { |
|
|
|
} |
|
} |
|
class B { |
|
protected int Method(); |
|
} |
|
class Method { } |
|
"; |
|
ArrayList results = CtrlSpaceResolveCSharp(program, 4, ExpressionContext.Default); |
|
Assert.IsTrue(MemberExists(results, "Method"), "method should be in completion lookup"); |
|
ResolveResult result = Resolve(program, "Method()", 4); |
|
Assert.IsTrue(result != null && result.IsValid, "method should be found!"); |
|
} |
|
|
|
bool MemberExists(ArrayList members, string name) |
|
{ |
|
foreach (object o in members) { |
|
IMember m = o as IMember; |
|
if (m != null && m.Name == name) return true; |
|
} |
|
return false; |
|
} |
|
|
|
[Test] |
|
public void OverriddenMemberVisibilityTest() |
|
{ |
|
string program = @"using System; |
|
public abstract class GrandParent { |
|
protected abstract void OverrideMe(); |
|
} |
|
public class Parent: GrandParent { |
|
protected override void OverrideMe() { |
|
} |
|
} |
|
public class Child: Parent { |
|
} |
|
"; |
|
ResolveResult result = Resolve(program, "(Child)someVar", 6); |
|
Assert.AreEqual("Child", result.ResolvedType.FullyQualifiedName); |
|
int count = 0; |
|
// foreach (IMethod m in result.ResolvedType.GetMethods()) { |
|
// if (m.Name == "OverrideMe") |
|
// count += 1; |
|
// } |
|
// Assert.AreEqual(1, count); |
|
count = 0; |
|
foreach (object o in result.GetCompletionData(lastPC)) { |
|
IMethod m = o as IMethod; |
|
if (m != null && m.Name == "OverrideMe") |
|
count += 1; |
|
} |
|
Assert.AreEqual(1, count); |
|
} |
|
|
|
[Test] |
|
public void ShadowingTest() |
|
{ |
|
string program = @"Imports System.Windows.Forms |
|
Class F |
|
Inherits Form |
|
Sub M |
|
|
|
End Sub |
|
Friend WithEvents Shadows cancelButton As Button |
|
End Class |
|
"; |
|
MemberResolveResult result = ResolveVB<MemberResolveResult>(program, "CancelButton", 5); |
|
Assert.AreEqual("F.cancelButton", result.ResolvedMember.FullyQualifiedName); |
|
|
|
result = ResolveVB<MemberResolveResult>(program, "MyBase.CancelButton", 5); |
|
Assert.AreEqual("System.Windows.Forms.Form.CancelButton", result.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void PreferExtensionMethodToInaccessibleMethod() |
|
{ |
|
string program = @"static class Program { |
|
static void Main() { |
|
new BaseClass().Test(3); |
|
Console.ReadKey(); |
|
} |
|
} |
|
class BaseClass { |
|
private void Test(int a) { } |
|
} |
|
static class Extensions { |
|
public static void Test(this BaseClass b, object a) { } |
|
}"; |
|
MemberResolveResult result = Resolve<MemberResolveResult>(program, "new BaseClass().Test(3)", 4); |
|
Assert.AreEqual("Extensions.Test", result.ResolvedMember.FullyQualifiedName); |
|
} |
|
#endregion |
|
|
|
#region MixedType tests |
|
const string arrayListMixedTypeProgram = @"using System.Collections; |
|
class A { |
|
void Test() { |
|
|
|
} |
|
|
|
ArrayList arrayList; |
|
public ArrayList ArrayList { |
|
get { |
|
return arrayList; |
|
} |
|
} |
|
} |
|
"; |
|
|
|
[Test] |
|
public void PropertyTypeConflictTest() |
|
{ |
|
ResolveResult result = Resolve<MemberResolveResult>(arrayListMixedTypeProgram, "arrayList", 4); |
|
Assert.AreEqual("System.Collections.ArrayList", result.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void PropertyTypeConflictTestResolveInTypeContext() |
|
{ |
|
TypeResolveResult result = (TypeResolveResult)Resolve(arrayListMixedTypeProgram, "ArrayList", 4, 0, ExpressionContext.Type); |
|
Assert.AreEqual("System.Collections.ArrayList", result.ResolvedClass.FullyQualifiedName); |
|
|
|
result = (TypeResolveResult)Resolve(arrayListMixedTypeProgram, "ArrayList", 8, 10, ExpressionContext.Type); |
|
Assert.AreEqual("System.Collections.ArrayList", result.ResolvedClass.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void PropertyTypeConflictCompletionResultTest() |
|
{ |
|
ResolveResult result = Resolve(arrayListMixedTypeProgram, "ArrayList", 4); |
|
Assert.IsTrue(result is MixedResolveResult); |
|
// CC should offer both static and non-static results |
|
ArrayList list = result.GetCompletionData(lastPC); |
|
bool ok = false; |
|
foreach (object o in list) { |
|
IMethod method = o as IMethod; |
|
if (method != null && method.Name == "AddRange") |
|
ok = true; |
|
} |
|
Assert.IsTrue(ok, "AddRange should exist"); |
|
ok = false; |
|
foreach (object o in list) { |
|
IMethod method = o as IMethod; |
|
if (method != null && method.Name == "Adapter") |
|
ok = true; |
|
} |
|
Assert.IsTrue(ok, "Adapter should exist"); |
|
} |
|
|
|
const string mixedTypeTestProgram = @"using System; |
|
class A { |
|
void TestMethod() { |
|
|
|
} |
|
public Project Project { get { return new Project(); } } |
|
public Project OtherName { get { return new Project(); } } |
|
} |
|
class Project { |
|
public static string Static; |
|
public int Instance; |
|
} |
|
namespace OtherName { class Bla { } } |
|
"; |
|
|
|
[Test] |
|
public void MixedResolveResultTest() |
|
{ |
|
ResolveResult result = Resolve(mixedTypeTestProgram, "Project", 4); |
|
Assert.IsInstanceOfType(typeof(MixedResolveResult), result); |
|
MixedResolveResult mrr = (MixedResolveResult)result; |
|
Assert.IsInstanceOfType(typeof(MemberResolveResult), mrr.PrimaryResult); |
|
Assert.AreEqual("Project", mrr.TypeResult.ResolvedClass.Name); |
|
} |
|
|
|
[Test] |
|
public void MixedStaticAccessTest() |
|
{ |
|
ResolveResult result = Resolve(mixedTypeTestProgram, "Project.Static", 4); |
|
Assert.IsInstanceOfType(typeof(MemberResolveResult), result); |
|
Assert.AreEqual("Static", (result as MemberResolveResult).ResolvedMember.Name); |
|
} |
|
|
|
[Test] |
|
public void MixedInstanceAccessTest() |
|
{ |
|
ResolveResult result = Resolve(mixedTypeTestProgram, "Project.Instance", 4); |
|
Assert.IsInstanceOfType(typeof(MemberResolveResult), result); |
|
Assert.AreEqual("Instance", (result as MemberResolveResult).ResolvedMember.Name); |
|
} |
|
|
|
[Test] |
|
public void NamespaceMixResolveResultTest() |
|
{ |
|
ResolveResult result = Resolve(mixedTypeTestProgram, "OtherName", 4); |
|
Assert.IsInstanceOfType(typeof(MemberResolveResult), result); |
|
Assert.AreEqual("OtherName", (result as MemberResolveResult).ResolvedMember.Name); |
|
} |
|
|
|
[Test] |
|
public void NamespaceMixMemberAccessTest() |
|
{ |
|
ResolveResult result = Resolve(mixedTypeTestProgram, "OtherName.Instance", 4); |
|
Assert.IsInstanceOfType(typeof(MemberResolveResult), result); |
|
Assert.AreEqual("Instance", (result as MemberResolveResult).ResolvedMember.Name); |
|
} |
|
#endregion |
|
|
|
#region Attribute tests |
|
[Test] |
|
public void NamespaceInAttributeContext() |
|
{ |
|
string program = @"using System; |
|
class Test { |
|
|
|
} |
|
"; |
|
NamespaceResolveResult result = Resolve<NamespaceResolveResult>(program, "System", 2, 1, ExpressionContext.Attribute); |
|
Assert.AreEqual("System", result.Name); |
|
|
|
result = Resolve<NamespaceResolveResult>(program, "System.Runtime", 2, 1, ExpressionContext.Attribute); |
|
Assert.AreEqual("System.Runtime", result.Name); |
|
} |
|
|
|
[Test] |
|
public void AttributeWithShortName() |
|
{ |
|
string program = @"using System; |
|
class Test { |
|
|
|
} |
|
"; |
|
|
|
TypeResolveResult result = Resolve<TypeResolveResult>(program, "Obsolete", 2, 1, ExpressionContext.Attribute); |
|
Assert.AreEqual("System.ObsoleteAttribute", result.ResolvedClass.FullyQualifiedName); |
|
|
|
result = Resolve<TypeResolveResult>(program, "System.Obsolete", 2, 1, ExpressionContext.Attribute); |
|
Assert.AreEqual("System.ObsoleteAttribute", result.ResolvedClass.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void AttributeConstructor() |
|
{ |
|
string program = @"using System; |
|
class Test { |
|
|
|
} |
|
"; |
|
|
|
MemberResolveResult result = Resolve<MemberResolveResult>(program, "LoaderOptimization(3)", 2, 1, ExpressionContext.Attribute); |
|
Assert.AreEqual("System.Byte", ((IMethod)result.ResolvedMember).Parameters[0].ReturnType.FullyQualifiedName); |
|
|
|
result = Resolve<MemberResolveResult>(program, "LoaderOptimization(LoaderOptimization.NotSpecified)", 2, 1, ExpressionContext.Attribute); |
|
Assert.AreEqual("System.LoaderOptimization", ((IMethod)result.ResolvedMember).Parameters[0].ReturnType.FullyQualifiedName); |
|
|
|
result = Resolve<MemberResolveResult>(program, "LoaderOptimizationAttribute(0)", 2, 1, ExpressionContext.Attribute); |
|
Assert.AreEqual("System.Byte", ((IMethod)result.ResolvedMember).Parameters[0].ReturnType.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void AttributeArgumentInClassContext1() |
|
{ |
|
string program = @"using System; |
|
[AttributeUsage(XXX)] class MyAttribute : Attribute { |
|
public const AttributeTargets XXX = AttributeTargets.All; |
|
} |
|
"; |
|
MemberResolveResult result = Resolve<MemberResolveResult>(program, "XXX", 2, 17, ExpressionContext.Default); |
|
Assert.AreEqual("MyAttribute.XXX", result.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void AttributeArgumentInClassContext2() |
|
{ |
|
string program = @"using System; namespace MyNamespace { |
|
[SomeAttribute(E.A)] class Test { |
|
|
|
} |
|
enum E { A, B } |
|
} |
|
"; |
|
MemberResolveResult result = Resolve<MemberResolveResult>(program, "E.A", 2, 16, ExpressionContext.Default); |
|
Assert.AreEqual("MyNamespace.E.A", result.ResolvedMember.FullyQualifiedName); |
|
} |
|
#endregion |
|
|
|
#region C# 3.0 tests |
|
[Test] |
|
public void TypeInferenceTest() |
|
{ |
|
string program = @"class TestClass { |
|
static void Test() { |
|
var a = 3; |
|
|
|
} |
|
} |
|
"; |
|
var lrr = Resolve<LocalResolveResult>(program, "a", 4); |
|
Assert.AreEqual("System.Int32", lrr.ResolvedType.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void TypeInferenceCycleTest() |
|
{ |
|
string program = @"class TestClass { |
|
static void Test() { |
|
var a = a; |
|
|
|
} |
|
} |
|
"; |
|
var lrr = Resolve<LocalResolveResult>(program, "a", 4); |
|
Assert.IsNull(lrr.ResolvedType.GetUnderlyingClass()); |
|
} |
|
|
|
[Test] |
|
public void ExtensionMethodsTest() |
|
{ |
|
string program = @"using XN; |
|
class TestClass { |
|
static void Test(A a, B b, C c) { |
|
|
|
} |
|
} |
|
class A { } |
|
class B { |
|
public void F(int i) { } |
|
} |
|
class C { |
|
public void F(object obj) { } |
|
} |
|
namespace XN { |
|
public static class XC { |
|
public static void F(this object obj, int i) { } |
|
public static void F(this object obj, string s) { } |
|
} |
|
} |
|
"; |
|
MemberResolveResult mrr; |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "a.F(1)", 4); |
|
Assert.AreEqual("XN.XC.F", mrr.ResolvedMember.FullyQualifiedName); |
|
Assert.AreEqual("System.Int32", ((IMethod)mrr.ResolvedMember).Parameters[1].ReturnType.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "a.F(\"text\")", 4); |
|
Assert.AreEqual("XN.XC.F", mrr.ResolvedMember.FullyQualifiedName); |
|
Assert.AreEqual("System.String", ((IMethod)mrr.ResolvedMember).Parameters[1].ReturnType.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "b.F(1)", 4); |
|
Assert.AreEqual("B.F", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "b.F(\"text\")", 4); |
|
Assert.AreEqual("XN.XC.F", mrr.ResolvedMember.FullyQualifiedName); |
|
Assert.AreEqual("System.String", ((IMethod)mrr.ResolvedMember).Parameters[1].ReturnType.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "c.F(1)", 4); |
|
Assert.AreEqual("C.F", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "c.F(\"text\")", 4); |
|
Assert.AreEqual("C.F", mrr.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void ExtensionMethodsTest2() |
|
{ |
|
string program = @"using System; using System.Collections.Generic; |
|
class TestClass { |
|
static void Test(string[] args) { |
|
|
|
} |
|
} |
|
public static class XC { |
|
public static int ToInt32(this string s) { return int.Parse(s); } |
|
public static T[] Slice<T>(this T[] source, int index, int count) { throw new NotImplementedException(); } |
|
public static IEnumerable<T> Filter<T>(this IEnumerable<T> source, Predicate<T> predicate) { throw new NotImplementedException(); } |
|
} |
|
"; |
|
MemberResolveResult mrr; |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "\"text\".ToInt32()", 4); |
|
Assert.AreEqual("XC.ToInt32", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "args.Slice(1, 2)", 4); |
|
Assert.AreEqual("XC.Slice", mrr.ResolvedMember.FullyQualifiedName); |
|
Assert.AreEqual("System.String[]", mrr.ResolvedType.DotNetName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "args.Filter(delegate { return true; })", 4); |
|
Assert.AreEqual("XC.Filter", mrr.ResolvedMember.FullyQualifiedName); |
|
Assert.AreEqual("System.Collections.Generic.IEnumerable{System.String}", mrr.ResolvedType.DotNetName); |
|
} |
|
|
|
[Test] |
|
public void SimpleLinqTest() |
|
{ |
|
string program = @"using System; |
|
class TestClass { |
|
void Test(string[] input) { |
|
var r = from e in input |
|
where e.StartsWith(""/"") |
|
select e.Trim(); |
|
|
|
} |
|
} |
|
"; |
|
LocalResolveResult lrr = Resolve<LocalResolveResult>(program, "e", 5); |
|
Assert.AreEqual("System.String", lrr.ResolvedType.FullyQualifiedName); |
|
lrr = Resolve<LocalResolveResult>(program, "e", 6); |
|
Assert.AreEqual("System.String", lrr.ResolvedType.FullyQualifiedName); |
|
|
|
lrr = Resolve<LocalResolveResult>(program, "r", 7); |
|
Assert.AreEqual("System.Collections.Generic.IEnumerable", lrr.ResolvedType.FullyQualifiedName); |
|
Assert.AreEqual("System.String", lrr.ResolvedType.CastToConstructedReturnType().TypeArguments[0].FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void ParenthesizedLinqTest() |
|
{ |
|
string program = @"using System; using System.Linq; |
|
class TestClass { |
|
void Test(string[] input) { |
|
(from e in input select e.Length) |
|
} |
|
} |
|
"; |
|
ResolveResult rr = Resolve(program, |
|
"(from e in input select e.Length)", |
|
4, 3, ExpressionContext.Default); |
|
Assert.IsNotNull(rr); |
|
Assert.AreEqual("System.Collections.Generic.IEnumerable", rr.ResolvedType.FullyQualifiedName); |
|
Assert.AreEqual("System.Int32", rr.ResolvedType.CastToConstructedReturnType().TypeArguments[0].FullyQualifiedName); |
|
} |
|
|
|
const string objectInitializerTestProgram = @"using System; using System.Threading; |
|
class TestClass { |
|
static void Test() { |
|
Rectangle r1 = new Rectangle { |
|
|
|
}; |
|
Rectangle r2 = new Rectangle { |
|
P1 = { |
|
|
|
} |
|
}; |
|
MyCollectionType mct = new MyCollectionType { |
|
|
|
}; |
|
} |
|
} |
|
public class Point |
|
{ |
|
int x; |
|
public int X { get { return x; } set { x = value; } } |
|
public int Y; |
|
} |
|
public class Rectangle |
|
{ |
|
Point p1 = new Point(); |
|
Point p2 = new Point(); |
|
public Point P1 { get { return p1; } } |
|
public Point P2 { get { return p2; } } |
|
} |
|
public class MyCollectionType : System.Collections.IEnumerable |
|
{ |
|
public void Add(object o) {} |
|
public int Field; |
|
public readonly int ReadOnlyValueTypeField; |
|
public int ReadOnlyValueTypeProperty { get; } |
|
} |
|
"; |
|
|
|
[Test] |
|
public void ObjectInitializerCtrlSpaceCompletion() |
|
{ |
|
ArrayList results = CtrlSpaceResolveCSharp(objectInitializerTestProgram, 5, ExpressionContext.ObjectInitializer); |
|
Assert.AreEqual(new[] { "P1", "P2" }, (from IMember p in results orderby p.Name select p.Name).ToArray() ); |
|
|
|
results = CtrlSpaceResolveCSharp(objectInitializerTestProgram, 9, ExpressionContext.ObjectInitializer); |
|
Assert.AreEqual(new[] { "X", "Y" }, (from IMember p in results orderby p.Name select p.Name).ToArray() ); |
|
|
|
results = CtrlSpaceResolveCSharp(objectInitializerTestProgram, 13, ExpressionContext.ObjectInitializer); |
|
// collection type: expect system types |
|
Assert.IsTrue(results.OfType<IClass>().Any((IClass c) => c.FullyQualifiedName == "System.Int32")); |
|
Assert.IsTrue(results.OfType<IClass>().Any((IClass c) => c.FullyQualifiedName == "System.AppDomain")); |
|
// expect local variables |
|
Assert.IsTrue(results.OfType<IField>().Any((IField f) => f.IsLocalVariable && f.Name == "r1")); |
|
// but also expect MyCollectionType.Field |
|
Assert.IsTrue(results.OfType<IField>().Any((IField f) => f.FullyQualifiedName == "MyCollectionType.Field")); |
|
Assert.IsFalse(results.OfType<IField>().Any((IField f) => f.FullyQualifiedName == "MyCollectionType.ReadOnlyValueTypeField")); |
|
Assert.IsFalse(results.OfType<IProperty>().Any((IProperty f) => f.FullyQualifiedName == "MyCollectionType.ReadOnlyValueTypeProperty")); |
|
} |
|
|
|
[Test] |
|
public void ObjectInitializerCompletion() |
|
{ |
|
MemberResolveResult mrr = (MemberResolveResult)Resolve(objectInitializerTestProgram, "P2", 5, 1, ExpressionContext.ObjectInitializer); |
|
Assert.IsNotNull(mrr); |
|
Assert.AreEqual("Rectangle.P2", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = (MemberResolveResult)Resolve(objectInitializerTestProgram, "X", 9, 1, ExpressionContext.ObjectInitializer); |
|
Assert.IsNotNull(mrr); |
|
Assert.AreEqual("Point.X", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = (MemberResolveResult)Resolve(objectInitializerTestProgram, "Field", 13, 1, ExpressionContext.ObjectInitializer); |
|
Assert.IsNotNull(mrr); |
|
Assert.AreEqual("MyCollectionType.Field", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
LocalResolveResult lrr = (LocalResolveResult)Resolve(objectInitializerTestProgram, "r1", 13, 1, ExpressionContext.ObjectInitializer); |
|
Assert.IsNotNull(lrr); |
|
Assert.AreEqual("r1", lrr.Field.Name); |
|
} |
|
#endregion |
|
|
|
[Test] |
|
public void ClassWithSameNameAsNamespace() |
|
{ |
|
string program = @"using System; namespace XX { |
|
class Test { |
|
static void X() { |
|
|
|
} |
|
} |
|
class XX { |
|
public static void Test() {} |
|
} }"; |
|
TypeResolveResult trr = Resolve<TypeResolveResult>(program, "XX", 4); |
|
Assert.AreEqual("XX.XX", trr.ResolvedClass.FullyQualifiedName); |
|
|
|
NamespaceResolveResult nrr = Resolve<NamespaceResolveResult>(program, "global::XX", 4); |
|
Assert.AreEqual("XX", nrr.Name); |
|
|
|
trr = Resolve<TypeResolveResult>(program, "global::XX.XX", 4); |
|
Assert.AreEqual("XX.XX", trr.ResolvedClass.FullyQualifiedName); |
|
|
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "XX.Test()", 4); |
|
Assert.AreEqual("XX.XX.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void InvocableRule() |
|
{ |
|
string program = @"using System; |
|
class DerivedClass : BaseClass { |
|
static void X() { |
|
|
|
} |
|
private static new int Test; |
|
} |
|
class BaseClass { |
|
public static string Test() {} |
|
}"; |
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "BaseClass.Test()", 4); |
|
Assert.AreEqual("BaseClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "Test", 4); |
|
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test", 4); |
|
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
// returns BaseClass.Test because DerivedClass.Test is not invocable |
|
mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test()", 4); |
|
Assert.AreEqual("BaseClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void InvocableRule2() |
|
{ |
|
string program = @"using System; |
|
class DerivedClass : BaseClass { |
|
static void X() { |
|
|
|
} |
|
private static new int Test; |
|
} |
|
delegate string SomeDelegate(); |
|
class BaseClass { |
|
public static SomeDelegate Test; |
|
}"; |
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "BaseClass.Test()", 4); |
|
Assert.AreEqual("BaseClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "Test", 4); |
|
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test", 4); |
|
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
// returns BaseClass.Test because DerivedClass.Test is not invocable |
|
mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test()", 4); |
|
Assert.AreEqual("BaseClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void AccessibleRule() |
|
{ |
|
string program = @"using System; |
|
class BaseClass { |
|
static void X() { |
|
|
|
} |
|
public static int Test; |
|
} |
|
class DerivedClass : BaseClass { |
|
private static new int Test; |
|
} |
|
"; |
|
// returns BaseClass.Test because DerivedClass.Test is not accessible |
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test", 4); |
|
Assert.AreEqual("BaseClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void FieldHidingProperty() |
|
{ |
|
string program = @"using System; |
|
class DerivedClass : BaseClass { |
|
static void X() { |
|
|
|
} |
|
public static new int Test; |
|
} |
|
class BaseClass { |
|
public static int Test { get { return 0; } } |
|
} |
|
"; |
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "Test", 4); |
|
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test", 4); |
|
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void PropertyHidingField() |
|
{ |
|
string program = @"using System; |
|
class DerivedClass : BaseClass { |
|
static void X() { |
|
|
|
} |
|
public static new int Test { get { return 0; } } |
|
} |
|
class BaseClass { |
|
public static int Test; |
|
} |
|
"; |
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "Test", 4); |
|
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test", 4); |
|
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void TestOverloadingByRef() |
|
{ |
|
string program = @"using System; |
|
class Program { |
|
public static void Main() { |
|
int a = 42; |
|
T(a); |
|
T(ref a); |
|
} |
|
static void T(int x) {} |
|
static void T(ref int y) {} |
|
}"; |
|
|
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "T(a)", 5); |
|
Assert.IsFalse(((IMethod)mrr.ResolvedMember).Parameters[0].IsRef); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "T(ref a)", 5); |
|
Assert.IsTrue(((IMethod)mrr.ResolvedMember).Parameters[0].IsRef); |
|
} |
|
|
|
[Test] |
|
public void AddedOverload() |
|
{ |
|
string program = @"class BaseClass { |
|
static void Main() { |
|
new DerivedClass().Test(3); |
|
Console.ReadKey(); |
|
} |
|
public void Test(int a) { } |
|
} |
|
class DerivedClass : BaseClass { |
|
public void Test(object a) { } |
|
}"; |
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "new DerivedClass().Test(3);", 4); |
|
Assert.AreEqual("DerivedClass.Test", (mrr.ResolvedMember).FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void AddedNonApplicableOverload() |
|
{ |
|
string program = @"class BaseClass { |
|
static void Main() { |
|
new DerivedClass().Test(3); |
|
Console.ReadKey(); |
|
} |
|
public void Test(int a) { } |
|
} |
|
class DerivedClass : BaseClass { |
|
public void Test(string a) { } |
|
}"; |
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "new DerivedClass().Test(3);", 4); |
|
Assert.AreEqual("BaseClass.Test", (mrr.ResolvedMember).FullyQualifiedName); |
|
|
|
mrr = Resolve<MemberResolveResult>(program, "new DerivedClass().Test(\"3\");", 4); |
|
Assert.AreEqual("DerivedClass.Test", (mrr.ResolvedMember).FullyQualifiedName); |
|
} |
|
|
|
[Test] |
|
public void OverrideShadowed() |
|
{ |
|
string program = @"using System; |
|
class BaseClass { |
|
static void Main() { |
|
new DerivedClass().Test(3); |
|
Console.ReadKey(); |
|
} |
|
public virtual void Test(int a) { } |
|
} |
|
class MiddleClass : BaseClass { |
|
public void Test(object a) { } |
|
} |
|
class DerivedClass : MiddleClass { |
|
public override void Test(int a) { } |
|
}"; |
|
|
|
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "new DerivedClass().Test(3);", 4); |
|
Assert.AreEqual("MiddleClass.Test", (mrr.ResolvedMember).FullyQualifiedName); |
|
} |
|
} |
|
}
|
|
|