#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
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.
 
 
 
 
 
 

201 lines
7.5 KiB

// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.Semantics;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
// assign short name to the fake reflection type
using dynamic = ICSharpCode.NRefactory.TypeSystem.ReflectionHelper.Dynamic;
[TestFixture]
public class ConditionalOperatorTests : ResolverTestBase
{
CSharpResolver resolver;
public override void SetUp()
{
base.SetUp();
resolver = new CSharpResolver(compilation);
}
void TestOperator(ResolveResult condition, ResolveResult trueExpr, ResolveResult falseExpr,
Conversion conditionConv, Conversion trueConv, Conversion falseConv,
Type expectedResultType)
{
var corr = (OperatorResolveResult)resolver.ResolveConditional(condition, trueExpr, falseExpr);
AssertType(expectedResultType, corr);
AssertConversion(corr.Operands[0], condition, conditionConv, "Condition Conversion");
AssertConversion(corr.Operands[1], trueExpr, trueConv, "True Conversion");
AssertConversion(corr.Operands[2], falseExpr, falseConv, "False Conversion");
}
[Test]
public void PickMoreGeneralOfTheTypes()
{
TestOperator(MakeResult(typeof(bool)), MakeResult(typeof(string)), MakeResult(typeof(object)),
Conversion.IdentityConversion, Conversion.ImplicitReferenceConversion, Conversion.IdentityConversion,
typeof(object));
TestOperator(MakeResult(typeof(bool)), MakeResult(typeof(int)), MakeResult(typeof(long)),
Conversion.IdentityConversion, Conversion.ImplicitNumericConversion, Conversion.IdentityConversion,
typeof(long));
}
[Test]
public void StringAndNull()
{
ResolveResult condition = MakeResult(typeof(bool));
ResolveResult trueExpr = MakeResult(typeof(string));
var result = (OperatorResolveResult)resolver.ResolveConditional(
condition, trueExpr, MakeConstant(null));
AssertType(typeof(string), result);
AssertConversion(result.Operands[0], condition, Conversion.IdentityConversion, "Condition Conversion");
AssertConversion(result.Operands[1], trueExpr, Conversion.IdentityConversion, "True Conversion");
Assert.IsTrue(result.Operands[2].IsCompileTimeConstant);
Assert.IsNull(result.Operands[2].ConstantValue);
Assert.AreEqual("System.String", result.Operands[2].Type.FullName);
}
[Test]
public void NullAndString()
{
ResolveResult condition = MakeResult(typeof(bool));
ResolveResult falseExpr = MakeResult(typeof(string));
var result = (OperatorResolveResult)resolver.ResolveConditional(
condition, MakeConstant(null), falseExpr);
AssertType(typeof(string), result);
AssertConversion(result.Operands[0], condition, Conversion.IdentityConversion, "Condition Conversion");
Assert.IsTrue(result.Operands[1].IsCompileTimeConstant);
Assert.IsNull(result.Operands[1].ConstantValue);
Assert.AreEqual("System.String", result.Operands[1].Type.FullName);
AssertConversion(result.Operands[2], falseExpr, Conversion.IdentityConversion, "False Conversion");
}
[Test]
public void DynamicInArguments()
{
TestOperator(MakeResult(typeof(bool)), MakeResult(typeof(dynamic)), MakeResult(typeof(double)),
Conversion.IdentityConversion, Conversion.IdentityConversion, Conversion.BoxingConversion,
typeof(dynamic));
TestOperator(MakeResult(typeof(bool)), MakeResult(typeof(double)), MakeResult(typeof(dynamic)),
Conversion.IdentityConversion, Conversion.BoxingConversion, Conversion.IdentityConversion,
typeof(dynamic));
}
[Test]
public void DynamicInCondition()
{
TestOperator(MakeResult(typeof(dynamic)), MakeResult(typeof(float)), MakeResult(typeof(double)),
Conversion.ImplicitDynamicConversion, Conversion.ImplicitNumericConversion, Conversion.IdentityConversion,
typeof(double));
}
[Test]
public void AllDynamic()
{
TestOperator(MakeResult(typeof(dynamic)), MakeResult(typeof(dynamic)), MakeResult(typeof(dynamic)),
Conversion.ImplicitDynamicConversion, Conversion.IdentityConversion, Conversion.IdentityConversion,
typeof(dynamic));
}
[Test]
public void ListOfDynamicAndListOfObject()
{
AssertError(typeof(List<object>), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeResult(typeof(List<object>)), MakeResult(typeof(List<dynamic>))));
AssertError(typeof(List<dynamic>), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeResult(typeof(List<dynamic>)), MakeResult(typeof(List<object>))));
}
[Test]
public void Constant()
{
AssertConstant(1L, resolver.ResolveConditional(
MakeConstant(true), MakeConstant(1), MakeConstant(2L)));
AssertConstant(2L, resolver.ResolveConditional(
MakeConstant(false), MakeConstant(1), MakeConstant(2L)));
}
[Test]
public void NotConstantIfFalsePortionNotConstant()
{
AssertType(typeof(long), resolver.ResolveConditional(
MakeConstant(true), MakeConstant(1), MakeResult(typeof(long))));
}
[Test]
public void ByteAndZeroLiteral()
{
AssertType(typeof(int), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeResult(typeof(byte)), MakeConstant(0)));
}
[Test]
public void ByteAndUShort()
{
AssertType(typeof(ushort), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeResult(typeof(byte)), MakeResult(typeof(ushort))));
}
[Test]
public void EnumAndZeroLiteral()
{
AssertType(typeof(StringComparison), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeResult(typeof(StringComparison)), MakeConstant(0)));
}
[Test]
public void TypeWithImplicitConversionToBool()
{
string program = @"struct MyBool {
public static implicit operator bool(MyBool b) {}
void Test() {
var x = $this$ ? 1 : 0;
}
}";
Assert.AreEqual("System.Boolean", GetExpectedType(program).ReflectionName);
Conversion c = GetConversion(program);
Assert.IsTrue(c.IsValid);
Assert.IsTrue(c.IsUserDefined);
Assert.AreEqual("op_Implicit", c.Method.Name);
}
[Test]
public void TypeWithOperatorTrue()
{
string program = @"struct MyBool {
public static bool operator true(MyBool b) {}
void Test() {
var x = $this$ ? 1 : 0;
}
}";
Assert.AreEqual("System.Boolean", GetExpectedType(program).ReflectionName);
Conversion c = GetConversion(program);
Assert.IsTrue(c.IsValid);
Assert.IsTrue(c.IsUserDefined);
Assert.AreEqual("op_True", c.Method.Name);
}
}
}