Browse Source

Add ResolveVisitor-based tests to SimpleNameLookupTests.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
0eeedc4d75
  1. 25
      ICSharpCode.NRefactory.Demo/MainForm.cs
  2. 92
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs
  3. 32
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/SimpleNameLookupTests.cs
  4. 17
      ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs
  5. 5
      ICSharpCode.NRefactory/CSharp/Resolver/NodeListResolveVisitorNavigator.cs
  6. 6
      ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs

25
ICSharpCode.NRefactory.Demo/MainForm.cs

@ -186,25 +186,26 @@ namespace ICSharpCode.NRefactory.Demo @@ -186,25 +186,26 @@ namespace ICSharpCode.NRefactory.Demo
{
SimpleProjectContent project = new SimpleProjectContent();
TypeSystemConvertVisitor convertVisitor = new TypeSystemConvertVisitor(project, "dummy.cs");
convertVisitor.VisitCompilationUnit(compilationUnit, null);
compilationUnit.AcceptVisitor(convertVisitor, null);
project.UpdateProjectContent(null, convertVisitor.ParsedFile.TopLevelTypeDefinitions, null, null);
List<ITypeResolveContext> projects = new List<ITypeResolveContext>();
projects.Add(project);
projects.AddRange(builtInLibs.Value);
ITypeResolveContext context = new CompositeTypeResolveContext(projects);
CSharpResolver resolver = new CSharpResolver(context);
IResolveVisitorNavigator navigator = null;
if (csharpTreeView.SelectedNode != null) {
navigator = new NodeListResolveVisitorNavigator(new[] { (INode)csharpTreeView.SelectedNode.Tag });
using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
CSharpResolver resolver = new CSharpResolver(context);
IResolveVisitorNavigator navigator = null;
if (csharpTreeView.SelectedNode != null) {
navigator = new NodeListResolveVisitorNavigator(new[] { (INode)csharpTreeView.SelectedNode.Tag });
}
ResolveVisitor visitor = new ResolveVisitor(resolver, convertVisitor.ParsedFile, navigator);
visitor.Scan(compilationUnit);
csharpTreeView.BeginUpdate();
ShowResolveResultsInTree(csharpTreeView.Nodes, visitor);
csharpTreeView.EndUpdate();
}
ResolveVisitor visitor = new ResolveVisitor(resolver, convertVisitor.ParsedFile, navigator);
visitor.Scan(compilationUnit);
csharpTreeView.BeginUpdate();
ShowResolveResultsInTree(csharpTreeView.Nodes, visitor);
csharpTreeView.EndUpdate();
}
void ShowResolveResultsInTree(TreeNodeCollection c, ResolveVisitor v)

92
ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs

@ -3,7 +3,12 @@ @@ -3,7 +3,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.Parser;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Resolver
@ -14,19 +19,22 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -14,19 +19,22 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public abstract class ResolverTestBase
{
protected readonly IProjectContent mscorlib = CecilLoaderTests.Mscorlib;
protected readonly ITypeResolveContext context = CecilLoaderTests.Mscorlib;
protected SimpleProjectContent project;
protected ITypeResolveContext context;
protected CSharpResolver resolver;
[SetUp]
public virtual void SetUp()
{
resolver = new CSharpResolver(CecilLoaderTests.Mscorlib);
project = new SimpleProjectContent();
context = new CompositeTypeResolveContext(new [] { project, mscorlib });
resolver = new CSharpResolver(context);
resolver.UsingScope = MakeUsingScope("");
}
protected UsingScope MakeUsingScope(string namespaceName)
{
UsingScope u = new UsingScope(mscorlib);
UsingScope u = new UsingScope(project);
if (!string.IsNullOrEmpty(namespaceName)) {
foreach (string element in namespaceName.Split('.')) {
u = new UsingScope(u, string.IsNullOrEmpty(u.NamespaceName) ? element : u.NamespaceName + "." + element);
@ -112,5 +120,83 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -112,5 +120,83 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Assert.IsFalse(rr.IsCompileTimeConstant, rr.ToString() + " is a compile-time constant");
Assert.AreEqual(expectedType.ToTypeReference().Resolve(context), rr.Type);
}
IEnumerable<DomLocation> FindDollarSigns(string code)
{
int line = 1;
int col = 1;
foreach (char c in code) {
if (c == '$') {
yield return new DomLocation(line, col);
} else if (c == '\n') {
line++;
col = 1;
} else {
col++;
}
}
}
protected ResolveResult Resolve(string code)
{
CompilationUnit cu = new CSharpParser().Parse(new StringReader(code.Replace("$", "")));
DomLocation[] dollars = FindDollarSigns(code).ToArray();
Assert.AreEqual(2, dollars.Length, "Expected 2 dollar signs marking start+end of desired node");
UsingScope rootUsingScope = resolver.UsingScope;
while (rootUsingScope.Parent != null)
rootUsingScope = rootUsingScope.Parent;
ParsedFile parsedFile = new ParsedFile("test.cs", rootUsingScope);
TypeSystemConvertVisitor convertVisitor = new TypeSystemConvertVisitor(parsedFile, resolver.UsingScope, null);
cu.AcceptVisitor(convertVisitor, null);
project.UpdateProjectContent(null, convertVisitor.ParsedFile.TopLevelTypeDefinitions, null, null);
FindNodeVisitor fnv = new FindNodeVisitor(dollars[0], dollars[1]);
cu.AcceptVisitor(fnv, null);
Assert.IsNotNull(fnv.ResultNode, "Did not find DOM node at the specified location");
var navigator = new NodeListResolveVisitorNavigator(new[] { fnv.ResultNode });
ResolveResult rr;
using (var context = this.context.Synchronize()) {
ResolveVisitor rv = new ResolveVisitor(new CSharpResolver(context), convertVisitor.ParsedFile, navigator);
rv.Scan(cu);
rr = rv.GetResolveResult(fnv.ResultNode);
}
Assert.IsNotNull(rr, "ResolveResult is null - did something go wrong while navigating to the target node?");
return rr;
}
protected T Resolve<T>(string code) where T : ResolveResult
{
ResolveResult rr = Resolve(code);
Assert.IsInstanceOf(typeof(T), rr);
return (T)rr;
}
sealed class FindNodeVisitor : AbstractDomVisitor<object, object>
{
readonly DomLocation start;
readonly DomLocation end;
public INode ResultNode;
public FindNodeVisitor(DomLocation start, DomLocation end)
{
this.start = start;
this.end = end;
}
protected override object VisitChildren(INode node, object data)
{
if (node.StartLocation == start && node.EndLocation == end) {
if (ResultNode != null)
throw new InvalidOperationException("found multiple nodes with same start+end");
return ResultNode = node;
} else {
return base.VisitChildren(node, data);
}
}
}
}
}

32
ICSharpCode.NRefactory.Tests/CSharp/Resolver/SimpleNameLookupTests.cs

@ -135,5 +135,37 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -135,5 +135,37 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
trr = (TypeResolveResult)resolver.ResolveSimpleName("T", new IType[0]);
Assert.AreSame(resolver.CurrentTypeDefinition.TypeParameters[0], trr.Type);
}
[Test]
public void SimpleParameter()
{
string program = @"class A {
void Method(string a) {
string b = $a$;
}
}
";
VariableResolveResult result = Resolve<VariableResolveResult>(program);
Assert.AreEqual("a", result.Variable.Name);
Assert.IsTrue(result.IsParameter);
Assert.AreEqual("System.String", result.Type.FullName);
}
[Test]
public void SimpleLocalVariable()
{
string program = @"class A {
void Method() {
string a;
string b = $a$;
}
}
";
VariableResolveResult result = Resolve<VariableResolveResult>(program);
Assert.AreEqual("a", result.Variable.Name);
Assert.IsFalse(result.IsParameter);
Assert.AreEqual("System.String", result.Type.FullName);
}
}
}

17
ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs

@ -370,8 +370,6 @@ namespace ICSharpCode.NRefactory.CSharp @@ -370,8 +370,6 @@ namespace ICSharpCode.NRefactory.CSharp
#endregion
#region Destructors
static readonly GetClassTypeReference voidReference = new GetClassTypeReference("System.Void", 0);
public override IEntity VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration, object data)
{
DefaultMethod dtor = new DefaultMethod(currentTypeDefinition, "Finalize");
@ -505,8 +503,21 @@ namespace ICSharpCode.NRefactory.CSharp @@ -505,8 +503,21 @@ namespace ICSharpCode.NRefactory.CSharp
#endregion
#region Types
ITypeReference ConvertType(INode node)
static readonly GetClassTypeReference voidReference = new GetClassTypeReference("System.Void", 0);
internal static ITypeReference ConvertType(INode node)
{
FullTypeName f = node as FullTypeName;
if (f != null) {
switch (f.Identifier.Name) {
case "String":
return TypeCode.String.ToTypeReference();
case "Int32":
return TypeCode.Int32.ToTypeReference();
case "Void":
return voidReference;
}
}
return SharedTypes.UnknownType;
}
#endregion

5
ICSharpCode.NRefactory/CSharp/Resolver/NodeListResolveVisitorNavigator.cs

@ -33,10 +33,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -33,10 +33,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public ResolveVisitorNavigationMode Scan(INode node)
{
ResolveVisitorNavigationMode mode;
if (dict.TryGetValue(node, out mode))
if (dict.TryGetValue(node, out mode)) {
return mode;
else
} else {
return ResolveVisitorNavigationMode.Skip;
}
}
}
}

6
ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs

@ -89,6 +89,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -89,6 +89,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
mode = navigator.Scan(node);
switch (mode) {
case ResolveVisitorNavigationMode.Skip:
if (node is VariableDeclarationStatement) {
// Enforce scanning of variable declarations.
goto case ResolveVisitorNavigationMode.Scan;
}
break;
case ResolveVisitorNavigationMode.Scan:
node.AcceptVisitor(this, null);
@ -940,7 +944,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -940,7 +944,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (initializerExpression != null && IsVar(type)) {
return new VarTypeReference(this, resolver.Clone(), initializerExpression, isForEach);
} else {
return SharedTypes.UnknownType; // TODO
return TypeSystemConvertVisitor.ConvertType(type);
}
}

Loading…
Cancel
Save