Permalink
Browse files

Add 'CommonTypeInference'.

  • Loading branch information...
dgrunwald committed Nov 21, 2010
1 parent 0eeedc4 commit 24eb146c74d86523ca612893296a4cee565e1819
@@ -51,6 +51,14 @@ public void ImportedType()
Assert.AreEqual("System.String", trr.Type.FullName);
}
+ [Test]
+ public void UnknownIdentifierTest()
+ {
+ UnknownIdentifierResolveResult uirr = (UnknownIdentifierResolveResult)resolver.ResolveSimpleName("xyz", new IType[0]);
+ Assert.IsTrue(uirr.IsError);
+ Assert.AreEqual("xyz", uirr.Identifier);
+ }
+
[Test]
public void GlobalIsUnknownIdentifier()
{
@@ -132,6 +132,7 @@
<Compile Include="FormattingTests\TestTypeLevelIndentation.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TypeSystem\CecilLoaderTests.cs" />
+ <Compile Include="TypeSystem\CommonTypeInferenceTests.cs" />
<Compile Include="TypeSystem\GetAllBaseTypesTest.cs" />
<Compile Include="TypeSystem\GetMembersTests.cs" />
<Compile Include="TypeSystem\ReflectionHelperTests.cs" />
@@ -0,0 +1,74 @@
+// 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)
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using ICSharpCode.NRefactory.CSharp.Resolver;
+using NUnit.Framework;
+
+namespace ICSharpCode.NRefactory.TypeSystem
+{
+ [TestFixture]
+ public class CommonTypeInferenceTests
+ {
+ CommonTypeInference cti = new CommonTypeInference(CecilLoaderTests.Mscorlib, new Conversions(CecilLoaderTests.Mscorlib));
+
+ IType[] Resolve(params Type[] types)
+ {
+ IType[] r = new IType[types.Length];
+ for (int i = 0; i < types.Length; i++) {
+ r[i] = types[i].ToTypeReference().Resolve(CecilLoaderTests.Mscorlib);
+ Assert.AreNotSame(r[i], SharedTypes.UnknownType);
+ }
+ Array.Sort(r, (a,b)=>a.ReflectionName.CompareTo(b.ReflectionName));
+ return r;
+ }
+
+ IType[] CommonBaseTypes(params Type[] types)
+ {
+ return cti.CommonBaseTypes(Resolve(types)).OrderBy(r => r.ReflectionName).ToArray();
+ }
+
+ [Test]
+ public void ListOfStringAndObject()
+ {
+ Assert.AreEqual(
+ Resolve(typeof(IList), typeof(IEnumerable<object>)),
+ CommonBaseTypes(typeof(List<string>), typeof(List<object>)));
+ }
+
+ [Test]
+ public void ListOfListOfStringAndObject()
+ {
+ Assert.AreEqual(
+ Resolve(typeof(IList), typeof(IEnumerable<IList>), typeof(IEnumerable<IEnumerable<object>>)),
+ CommonBaseTypes(typeof(List<List<string>>), typeof(List<List<object>>)));
+ }
+
+ [Test]
+ public void ShortAndInt()
+ {
+ Assert.AreEqual(
+ Resolve(typeof(int)),
+ CommonBaseTypes(typeof(short), typeof(int)));
+ }
+
+ [Test]
+ public void ListOfShortAndInt()
+ {
+ Assert.AreEqual(
+ Resolve(typeof(IList)),
+ CommonBaseTypes(typeof(List<short>), typeof(List<int>)));
+ }
+
+ [Test]
+ public void StringAndVersion()
+ {
+ Assert.AreEqual(
+ Resolve(typeof(ICloneable), typeof(IComparable)),
+ CommonBaseTypes(typeof(string), typeof(Version)));
+ }
+ }
+}
@@ -1,4 +1,4 @@
-//
+//
// AssignmentExpression.cs
//
// Author:
@@ -75,12 +75,12 @@ public enum AssignmentOperatorType
/// <summary>left %= right</summary>
Modulus,
- /// <summary>left <<= right</summary>
+ /// <summary>left &lt;&lt;= right</summary>
ShiftLeft,
/// <summary>left >>= right</summary>
ShiftRight,
- /// <summary>left &= right</summary>
+ /// <summary>left &amp;= right</summary>
BitwiseAnd,
/// <summary>left |= right</summary>
BitwiseOr,
@@ -1,4 +1,4 @@
-//
+//
// UnaryOperatorExpression.cs
//
// Author:
@@ -68,7 +68,7 @@ public enum UnaryOperatorType
PostDecrement,
/// <summary>Dereferencing (*a)</summary>
Dereference,
- /// <summary>Get address (&a)</summary>
+ /// <summary>Get address (&amp;a)</summary>
AddressOf
}
@@ -184,7 +184,7 @@ static IParameter MakeParameter(ITypeReference type, string name)
}
/// <summary>
- /// Adds the 'Invoke', 'BeginInvoke', 'EndInvoke' methods, and a constructor, to the <see cref="delegateType"/>.
+ /// Adds the 'Invoke', 'BeginInvoke', 'EndInvoke' methods, and a constructor, to the <paramref name="delegateType"/>.
/// </summary>
public static void AddDefaultMethodsToDelegate(DefaultTypeDefinition delegateType, ITypeReference returnType, IEnumerable<IParameter> parameters)
{
@@ -7,6 +7,7 @@
using System.Globalization;
using System.Linq;
using System.Text;
+using System.Threading;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
@@ -22,13 +23,15 @@ public class CSharpResolver
static readonly ResolveResult NullResult = new ResolveResult(SharedTypes.Null);
readonly ITypeResolveContext context;
+ internal readonly CancellationToken cancellationToken;
#region Constructor
- public CSharpResolver(ITypeResolveContext context)
+ public CSharpResolver(ITypeResolveContext context, CancellationToken cancellationToken = default(CancellationToken))
{
if (context == null)
throw new ArgumentNullException("context");
this.context = context;
+ this.cancellationToken = cancellationToken;
}
#endregion
@@ -335,6 +338,8 @@ public override string ToString()
#region ResolveUnaryOperator method
public ResolveResult ResolveUnaryOperator(UnaryOperatorType op, ResolveResult expression)
{
+ cancellationToken.ThrowIfCancellationRequested();
+
if (expression.Type == SharedTypes.Dynamic)
return DynamicResult;
@@ -584,6 +589,8 @@ object GetUserUnaryOperatorCandidates()
#region ResolveBinaryOperator method
public ResolveResult ResolveBinaryOperator(BinaryOperatorType op, ResolveResult lhs, ResolveResult rhs)
{
+ cancellationToken.ThrowIfCancellationRequested();
+
if (lhs.Type == SharedTypes.Dynamic || rhs.Type == SharedTypes.Dynamic)
return DynamicResult;
@@ -1427,6 +1434,8 @@ object GetUserBinaryOperatorCandidates()
#region ResolveCast
public ResolveResult ResolveCast(IType targetType, ResolveResult expression)
{
+ cancellationToken.ThrowIfCancellationRequested();
+
// C# 4.0 spec: §7.7.6 Cast expressions
if (expression.IsCompileTimeConstant) {
TypeCode code = ReflectionHelper.GetTypeCode(targetType);
@@ -1504,8 +1513,12 @@ public ResolveResult ResolveSimpleName(string identifier, IList<IType> typeArgum
}
}
- return LookupSimpleNameOrTypeName(identifier, typeArguments,
- isInvocationTarget ? SimpleNameLookupMode.InvocationTarget : SimpleNameLookupMode.Expression);
+ ResolveResult rr = LookupSimpleNameOrTypeName(
+ identifier, typeArguments,
+ isInvocationTarget ? SimpleNameLookupMode.InvocationTarget : SimpleNameLookupMode.Expression);
+ if (rr == ErrorResult && typeArguments.Count == 0)
+ rr = new UnknownIdentifierResolveResult(identifier);
+ return rr;
}
public ResolveResult LookupSimpleNamespaceOrTypeName(string identifier, IList<IType> typeArguments, bool isUsingDeclaration = false)
@@ -1523,6 +1536,8 @@ ResolveResult LookupSimpleNameOrTypeName(string identifier, IList<IType> typeArg
{
// C# 4.0 spec: §3.8 Namespace and type names; §7.6.2 Simple Names
+ cancellationToken.ThrowIfCancellationRequested();
+
int k = typeArguments.Count;
// look in type parameters of current method
@@ -1629,6 +1644,7 @@ public ResolveResult ResolveAlias(string identifier)
{
if (identifier == "global")
return new NamespaceResolveResult(string.Empty);
+
for (UsingScope n = this.UsingScope; n != null; n = n.Parent) {
if (n.ExternAliases.Contains(identifier)) {
return ResolveExternAlias(identifier);
@@ -1654,6 +1670,8 @@ public ResolveResult ResolveMemberAccess(ResolveResult target, string identifier
{
// C# 4.0 spec: §7.6.4
+ cancellationToken.ThrowIfCancellationRequested();
+
NamespaceResolveResult nrr = target as NamespaceResolveResult;
if (nrr != null) {
string fullName = NamespaceDeclaration.BuildQualifiedName(nrr.NamespaceName, identifier);
@@ -1684,6 +1702,9 @@ MemberLookup CreateMemberLookup()
public ResolveResult ResolveInvocation(ResolveResult target, ResolveResult[] arguments, string[] argumentNames = null)
{
// C# 4.0 spec: §7.6.5
+
+ cancellationToken.ThrowIfCancellationRequested();
+
if (target.Type == SharedTypes.Dynamic)
return DynamicResult;
@@ -1703,6 +1724,10 @@ public ResolveResult ResolveInvocation(ResolveResult target, ResolveResult[] arg
if (umrr != null) {
return new UnknownMethodResolveResult(umrr.TargetType, umrr.MemberName, umrr.TypeArguments, CreateParameters(arguments, argumentNames));
}
+ UnknownIdentifierResolveResult uirr = target as UnknownIdentifierResolveResult;
+ if (uirr != null && CurrentTypeDefinition != null) {
+ return new UnknownMethodResolveResult(CurrentTypeDefinition, uirr.Identifier, EmptyList<IType>.Instance, CreateParameters(arguments, argumentNames));
+ }
IMethod invokeMethod = target.Type.GetDelegateInvokeMethod();
if (invokeMethod != null) {
return new ResolveResult(invokeMethod.ReturnType.Resolve(context));
@@ -1795,6 +1820,8 @@ static string MakeParameterName(string variableName)
#region ResolveIndexer
public ResolveResult ResolveIndexer(ResolveResult target, ResolveResult[] arguments, string[] argumentNames = null)
{
+ cancellationToken.ThrowIfCancellationRequested();
+
if (target.Type == SharedTypes.Dynamic)
return DynamicResult;
@@ -1818,6 +1845,8 @@ public ResolveResult ResolveIndexer(ResolveResult target, ResolveResult[] argume
#region ResolveObjectCreation
public ResolveResult ResolveObjectCreation(IType type, ResolveResult[] arguments, string[] argumentNames = null)
{
+ cancellationToken.ThrowIfCancellationRequested();
+
OverloadResolution or = new OverloadResolution(context, arguments, argumentNames, new IType[0]);
MemberLookup lookup = CreateMemberLookup();
bool allowProtectedAccess = lookup.AllowProtectedAccess(type);
@@ -1904,6 +1933,9 @@ public ResolveResult ResolveBaseReference()
public ResolveResult ResolveConditional(ResolveResult trueExpression, ResolveResult falseExpression)
{
// C# 4.0 spec §7.14: Conditional operator
+
+ cancellationToken.ThrowIfCancellationRequested();
+
Conversions c = new Conversions(context);
bool isValid;
IType resultType;
@@ -11,7 +11,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// <summary>
/// Contains logic that determines whether an implicit conversion exists between two types.
/// </summary>
- public class Conversions
+ public class Conversions : IConversions
{
readonly ITypeResolveContext context;
readonly IType objectType;
@@ -163,7 +163,7 @@ bool NullLiteralConversion(IType fromType, IType toType)
#endregion
#region ImplicitReferenceConversion
- bool ImplicitReferenceConversion(IType fromType, IType toType)
+ public bool ImplicitReferenceConversion(IType fromType, IType toType)
{
// C# 4.0 spec: §6.1.6
@@ -54,9 +54,9 @@ public bool AllowProtectedAccess(IType targetType)
/// <summary>
/// Gets whether <paramref name="entity"/> is accessible in the current class.
/// </summary>
- /// <param name="member">The entity to test</param>
+ /// <param name="entity">The entity to test</param>
/// <param name="allowProtectedAccess">Whether protected access is allowed.
- /// True if the type of the reference is derived from the current class.</returns>
+ /// True if the type of the reference is derived from the current class.</param>
public bool IsAccessible(IEntity entity, bool allowProtectedAccess)
{
if (entity == null)
@@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
+using System.Threading;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
@@ -65,9 +65,32 @@ public UnknownMethodResolveResult(IType targetType, string methodName, IEnumerab
public ReadOnlyCollection<IParameter> Parameters {
get { return parameters; }
}
+ }
+
+ /// <summary>
+ /// Represents an unknown identifier.
+ /// </summary>
+ public class UnknownIdentifierResolveResult : ResolveResult
+ {
+ readonly string identifier;
+
+ public UnknownIdentifierResolveResult(string identifier)
+ : base(SharedTypes.UnknownType)
+ {
+ this.identifier = identifier;
+ }
+
+ public string Identifier {
+ get { return identifier; }
+ }
public override bool IsError {
get { return true; }
}
+
+ public override string ToString()
+ {
+ return string.Format("[{0} {1}]", GetType().Name, identifier);
+ }
}
}
@@ -14,6 +14,7 @@
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <NoWarn>1591</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -39,7 +40,7 @@
<Optimize>false</Optimize>
<WarningLevel>4</WarningLevel>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
- <DebugSymbols>True</DebugSymbols>
+ <DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>None</DebugType>
@@ -189,12 +190,14 @@
<Compile Include="TypeSystem\ByReferenceType.cs" />
<Compile Include="TypeSystem\CecilLoader.cs" />
<Compile Include="TypeSystem\ClassType.cs" />
+ <Compile Include="TypeSystem\CommonTypeInference.cs" />
<Compile Include="TypeSystem\DomRegion.cs" />
<Compile Include="TypeSystem\EntityType.cs" />
<Compile Include="TypeSystem\ExtensionMethods.cs" />
<Compile Include="TypeSystem\IAccessor.cs" />
<Compile Include="TypeSystem\IAttribute.cs" />
<Compile Include="TypeSystem\IConstantValue.cs" />
+ <Compile Include="TypeSystem\IConversions.cs" />
<Compile Include="TypeSystem\IEntity.cs" />
<Compile Include="TypeSystem\IEvent.cs" />
<Compile Include="TypeSystem\IExplicitInterfaceImplementation.cs" />
Oops, something went wrong.

0 comments on commit 24eb146

Please sign in to comment.