From fa6afb250a7662d43e48284983d41f3424110bf6 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sun, 17 Jul 2011 10:56:08 +0200 Subject: [PATCH] Fix ResolveVisitor.VisitArrayCreateExpression. --- .../CSharp/Resolver/ArrayCreationTests.cs | 63 +++++++++++++++++++ .../ICSharpCode.NRefactory.Tests.csproj | 1 + .../CSharp/Resolver/ResolveVisitor.cs | 39 +++++++----- .../CompositeTypeResolveContext.cs | 2 +- 4 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 ICSharpCode.NRefactory.Tests/CSharp/Resolver/ArrayCreationTests.cs diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ArrayCreationTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ArrayCreationTests.cs new file mode 100644 index 0000000000..335b42e7c5 --- /dev/null +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ArrayCreationTests.cs @@ -0,0 +1,63 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT license (for details please see \doc\license.txt) + +using System; +using ICSharpCode.NRefactory.TypeSystem; +using NUnit.Framework; + +namespace ICSharpCode.NRefactory.CSharp.Resolver +{ + [TestFixture] + [Ignore("Parser produces incorrect positions")] + public class ArrayCreationTests : ResolverTestBase + { + [Test] + public void SimpleArrayCreation() + { + string program = @"using System.Collections.Generic; +class A { + static void Main() { + var a = $new int[] { 42 }$; + } +} +"; + var result = Resolve(program); + Assert.AreEqual("System.Int32[]", result.Type.ReflectionName); + } + + [Test] + public void NestedArrayCreation() + { + string program = @"using System.Collections.Generic; +class A { + static void Main() { + var a = $new int[2][,][,,]$; + } +} +"; + var result = Resolve(program); + // a one-dimensional array of two-dimensional arrays of three-dimensional arrays + ArrayType a1 = (ArrayType)result.Type; + Assert.AreEqual(1, a1.Dimensions); + ArrayType a2 = (ArrayType)a1.ElementType; + Assert.AreEqual(2, a2.Dimensions); + ArrayType a3 = (ArrayType)a2.ElementType; + Assert.AreEqual(3, a3.Dimensions); + Assert.AreEqual("System.Int32", a3.ElementType.ReflectionName); + } + + [Test] + public void InferredType() + { + string program = @"using System.Collections.Generic; +class A { + static void Main() { + var a = $new [] { 1, 1L }$; + } +} +"; + var result = Resolve(program); + Assert.AreEqual("System.Int64[]", result.Type.ReflectionName); + } + } +} diff --git a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj index cebee2aa59..dd21e09282 100644 --- a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj +++ b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj @@ -117,6 +117,7 @@ + diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs index 60d3fa608f..4ef1ec26a5 100644 --- a/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs +++ b/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs @@ -1,7 +1,7 @@ // Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + // This code is distributed under MIT X11 license (for details please see \doc\license.txt) -using System; + using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -562,7 +562,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver resolveExpr = expr; return ((MemberReferenceExpression)expr).MemberName; } - if (expr is IdentifierExpression) { + if (expr is IdentifierExpression) { resolveExpr = expr; return ((IdentifierExpression)expr).Identifier; } @@ -594,26 +594,31 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver { Scan(arrayCreateExpression.Initializer); if (resolverEnabled) { - ArrayTypeReference arrType; + IType arrType; if (arrayCreateExpression.Type.IsNull) { - var types = new List(); + var elements = new List(); foreach (var init in arrayCreateExpression.Initializer.Elements) { - var def = Resolve(init).Type.GetDefinition (); - if (def == null) - continue; - types.Add(def); + var rr = Resolve(init); + if (!rr.IsError) + elements.Add(rr); } - var elementType = types.FirstOrDefault(t => !types.Any(s => !s.IsDerivedFrom(t, resolver.Context))) ?? SharedTypes.UnknownType; - arrType = new ArrayTypeReference (elementType, 1); + TypeInference typeInference = new TypeInference(resolver.Context, new Conversions(resolver.Context)); + bool success; + IType elementType = typeInference.GetBestCommonType(elements, out success); + arrType = new ArrayType(elementType, 1); } else { - var baseType = MakeTypeReference(arrayCreateExpression.Type); - arrType = new ArrayTypeReference (baseType, 1 + arrayCreateExpression.Arguments.Count); - foreach (var spec in arrayCreateExpression.AdditionalArraySpecifiers) { - arrType = new ArrayTypeReference (arrType, spec.Dimensions); + arrType = ResolveType(arrayCreateExpression.Type); + foreach (var spec in arrayCreateExpression.AdditionalArraySpecifiers.Reverse()) { + arrType = new ArrayType(arrType, spec.Dimensions); + } + // HACK: find a better way to represent this in the AST + if (arrayCreateExpression.Arguments.Count == 0) { + arrType = new ArrayType(arrType, 1); + } else { + arrType = new ArrayType(arrType, arrayCreateExpression.Arguments.Count); } } - - return new ResolveResult (arrType.Resolve (resolver.Context)); + return new ResolveResult (arrType); } return null; } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/CompositeTypeResolveContext.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/CompositeTypeResolveContext.cs index d8d9d2319d..3e12c921bf 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/CompositeTypeResolveContext.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/CompositeTypeResolveContext.cs @@ -100,7 +100,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation for (int i = 0; i < sync.Length; i++) { sync[i] = children[i].Synchronize(); if (sync[i] == null) - throw new InvalidOperationException(children[i] + ".ToString() returned null"); + throw new InvalidOperationException(children[i] + ".Synchronize() returned null"); } ISynchronizedTypeResolveContext r = new CompositeSynchronizedTypeResolveContext(sync, new CacheManager(), true); success = true;