public IErrorReporter ErrorIsTypeAlienSealed() { NameResolver resolver = null; foreach (var mutability in Options.AllMutabilityModes) { var env = Environment.Create(new Options() { }.SetMutability(mutability)); var root_ns = env.Root; root_ns.AddBuilder(TypeBuilder.CreateInterface("IWhat")); root_ns.AddBuilder(TypeBuilder.Create("What") .Parents("IWhat")); // comparison does not make sense, because string is sealed and it is not possible to be given interface IsType is_type = IsType.Create(NameReference.Create("x"), NameFactory.StringNameReference()); root_ns.AddBuilder(FunctionBuilder.Create("foo", NameFactory.BoolNameReference(), Block.CreateStatement( VariableDeclaration.CreateStatement("x", NameFactory.PointerNameReference("IWhat"), Undef.Create()), Return.Create(is_type) ))); resolver = NameResolver.Create(env); Assert.AreEqual(1, resolver.ErrorManager.Errors.Count); Assert.IsTrue(resolver.ErrorManager.HasError(ErrorCode.TypeMismatch, is_type)); } return(resolver); }
public IErrorReporter TypeTesting() { NameResolver resolver = null; foreach (var mutability in Options.AllMutabilityModes) { var env = Language.Environment.Create(new Options() { GlobalVariables = true, RelaxedMode = true }.SetMutability(mutability)); var root_ns = env.Root; var system_ns = env.SystemNamespace; IsType is_type = IsType.Create(NameReference.Create("foo"), NameFactory.PointerNameReference(NameFactory.RealNameReference())); var decl_src = VariableDeclaration.CreateStatement("foo", NameFactory.PointerNameReference(NameFactory.IObjectNameReference()), initValue: Undef.Create(), modifier: EntityModifier.Public); var decl_dst = VariableDeclaration.CreateStatement("bar", null, initValue: is_type, modifier: EntityModifier.Public); root_ns.AddNode(decl_src); root_ns.AddNode(decl_dst); resolver = NameResolver.Create(env); Assert.AreEqual(0, resolver.ErrorManager.Errors.Count); } return(resolver); }
public IInterpreter CheckingTraitRuntimeType() { var interpreter = new Interpreter.Interpreter(); foreach (var mutability in Options.AllMutabilityModes) { var env = Environment.Create(new Options() { DebugThrowOnError = true, AllowInvalidMainResult = true }.SetMutability(mutability)); var root_ns = env.Root; root_ns.AddBuilder(TypeBuilder.CreateInterface("ISay") .With(FunctionBuilder.CreateDeclaration("say", ExpressionReadMode.ReadRequired, NameFactory.Int64NameReference()))); root_ns.AddBuilder(TypeBuilder.Create("Say") .With(FunctionBuilder.Create("say", ExpressionReadMode.ReadRequired, NameFactory.Int64NameReference(), Block.CreateStatement(new[] { Return.Create(Int64Literal.Create("7")) })) .SetModifier(EntityModifier.Override)) .Parents("ISay")); root_ns.AddBuilder(TypeBuilder.Create("Greeter", "T")); root_ns.AddBuilder(TypeBuilder.Create("Greeter", "X") .Constraints(ConstraintBuilder.Create("X").Inherits("ISay")) .SetModifier(EntityModifier.Trait) .Parents("ISay") .With(FunctionBuilder.Create("say", ExpressionReadMode.ReadRequired, NameFactory.Int64NameReference(), Block.CreateStatement( Return.Create(Int64Literal.Create("2")) )).SetModifier(EntityModifier.Override))); root_ns.AddBuilder(FunctionBuilder.Create( "main", ExpressionReadMode.OptionalUse, NameFactory.Int64NameReference(), Block.CreateStatement( VariableDeclaration.CreateStatement("g", NameFactory.PointerNameReference(NameFactory.IObjectNameReference()), ExpressionFactory.HeapConstructor(NameReference.Create("Greeter", NameReference.Create("Say")))), Return.Create(ExpressionFactory.Ternary(IsType.Create(NameReference.Create("g"), NameReference.Create("ISay")), Int64Literal.Create("2"), Int64Literal.Create("88"))) ))); ExecValue result = interpreter.TestRun(env); Assert.AreEqual(2L, result.RetValue.PlainValue); } return(interpreter); }
public IInterpreter ResolvingGenericArgumentInRuntime() { var interpreter = new Interpreter.Interpreter(); foreach (var mutability in Options.AllMutabilityModes) { var env = Environment.Create(new Options() { DebugThrowOnError = true }.SetMutability(mutability)); var root_ns = env.Root; root_ns.AddBuilder(FunctionBuilder.Create("oracle", "O", VarianceMode.None, NameFactory.BoolNameReference(), Block.CreateStatement( Return.Create(IsType.Create(NameReference.Create("thing"), NameReference.Create("O"))) )) .Parameters(FunctionParameter.Create("thing", NameFactory.ReferenceNameReference(NameFactory.IObjectNameReference())))); root_ns.AddBuilder(FunctionBuilder.Create( "main", ExpressionReadMode.OptionalUse, NameFactory.Nat8NameReference(), Block.CreateStatement( VariableDeclaration.CreateStatement("acc", null, Nat8Literal.Create("0"), env.Options.ReassignableModifier()), VariableDeclaration.CreateStatement("i", null, ExpressionFactory.HeapConstructor(NameFactory.IntNameReference(), IntLiteral.Create("7"))), VariableDeclaration.CreateStatement("d", null, ExpressionFactory.HeapConstructor(NameFactory.RealNameReference(), RealLiteral.Create("3.3"))), IfBranch.CreateIf(FunctionCall.Create(NameReference.Create("oracle", NameFactory.IntNameReference()), NameReference.Create("i")), new[] { ExpressionFactory.IncBy("acc", Nat8Literal.Create("2")) }), IfBranch.CreateIf(FunctionCall.Create(NameReference.Create("oracle", NameFactory.IntNameReference()), NameReference.Create("d")), new[] { ExpressionFactory.IncBy("acc", Nat8Literal.Create("88")) }), Return.Create(NameReference.Create("acc")) ))); ExecValue result = interpreter.TestRun(env); Assert.AreEqual((byte)2, result.RetValue.PlainValue); } return(interpreter); }
public void Converter_IsTypeTests() { IsType conv = new IsType(); conv.Type = typeof(double); double dval = 1.0f; float fval = 1.0f; Assert.AreEqual(true, conv.Convert(dval, typeof(bool), null, CultureInfo.CurrentCulture), "IsType Convert did not return the correct value"); Assert.AreEqual(false, conv.Convert(fval, typeof(bool), null, CultureInfo.CurrentCulture), "IsType Convert did not return the correct value"); try { conv.ConvertBack(true, typeof(object), null, CultureInfo.CurrentCulture); Assert.Fail("IsType ConvertBack did not throw a NotImplemented exception"); } catch (NotImplementedException) { } }
public IErrorReporter ErrorTestingValueType() { NameResolver resolver = null; foreach (var mutability in Options.AllMutabilityModes) { var env = Language.Environment.Create(new Options() { GlobalVariables = true, RelaxedMode = true, DiscardingAnyExpressionDuringTests = true }.SetMutability(mutability)); var root_ns = env.Root; var system_ns = env.SystemNamespace; IsType is_type = IsType.Create(NameReference.Create("foo"), NameFactory.RealNameReference()); var decl_src = VariableDeclaration.CreateStatement("foo", NameFactory.IObjectNameReference(), initValue: Undef.Create(), modifier: EntityModifier.Public); var decl_dst = VariableDeclaration.CreateStatement("bar", null, initValue: is_type, modifier: EntityModifier.Public); root_ns.AddNode(decl_src); root_ns.AddNode(decl_dst); IsType is_type_ref = IsType.Create(NameReference.Create("u"), NameFactory.ISequenceNameReference("G")); root_ns.AddBuilder(FunctionBuilder.Create("more", "G", VarianceMode.None, NameFactory.UnitNameReference(), Block.CreateStatement( ExpressionFactory.Readout(is_type_ref) )) .Parameters(FunctionParameter.Create("u", NameFactory.ReferenceNameReference( NameFactory.ISequenceNameReference("G", mutability: TypeMutability.ReadOnly))))); resolver = NameResolver.Create(env); Assert.AreEqual(2, resolver.ErrorManager.Errors.Count); Assert.IsTrue(resolver.ErrorManager.HasError(ErrorCode.IsTypeOfKnownTypes, is_type)); Assert.IsTrue(resolver.ErrorManager.HasError(ErrorCode.IsTypeOfKnownTypes, is_type_ref)); } return(resolver); }
/// <summary> /// 获得当前页面客户端的IP /// </summary> /// <returns>当前页面客户端的IP</returns> public static string GetIP() { var ip = ""; var context = HttpContext.Current; if (context != null) { ip = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (string.IsNullOrWhiteSpace(ip)) { ip = context.Request.ServerVariables["REMOTE_ADDR"]; } if (string.IsNullOrWhiteSpace(ip) || !IsType.IsIP(ip)) { ip = context.Request.UserHostAddress; } if (string.IsNullOrWhiteSpace(ip) || !IsType.IsIP(ip)) { return("0.0.0.0"); } return(ip); } else { var strHostName = Dns.GetHostName(); var ipHost = Dns.GetHostEntry(strHostName); foreach (var item in ipHost.AddressList) { if (item.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { ip = item.ToString(); } } } return(ip); }
/// <summary> /// 将方法转换成T-SQL特殊函数名 /// </summary> /// <param name="m">自定义特殊的函数</param> protected override Expression VisitMethodCall(MethodCallExpression m) { base.VisitMethodCall(m); if (ClearCallSql()) { return(m); } #region 字段、参数、值类型 Type fieldType; Type paramType; string fieldName, paramName; if (m.Object == null) { if (!m.Arguments[0].Type.IsGenericType || m.Arguments[0].Type.GetGenericTypeDefinition() == typeof(Nullable <>)) { fieldType = m.Arguments[0].Type; paramType = m.Arguments[1].Type; fieldName = SqlList.Pop(); paramName = SqlList.Pop(); } else { paramType = m.Arguments[0].Type; fieldType = m.Arguments[1].Type; paramName = SqlList.Pop(); fieldName = SqlList.Pop(); } } else { if (!m.Object.Type.IsGenericType || m.Object.Type.GetGenericTypeDefinition() == typeof(Nullable <>)) { fieldType = m.Object.Type; paramType = m.Arguments[0].Type; paramName = SqlList.Pop(); fieldName = SqlList.Pop(); } else { paramType = m.Object.Type; fieldType = m.Arguments[0].Type; fieldName = SqlList.Pop(); paramName = SqlList.Pop(); } } #endregion switch (m.Method.Name.ToUpper()) { case "CONTAINS": { if (!paramType.IsGenericType || paramType.GetGenericTypeDefinition() == typeof(Nullable <>)) { #region 搜索值串的处理 var param = ParamsList.Find(o => o.ParameterName == paramName); if (param != null && IsType.IsDigital(param.Value.ToString()) && (Type.GetTypeCode(fieldType) == TypeCode.Int16 || Type.GetTypeCode(fieldType) == TypeCode.Int32 || Type.GetTypeCode(fieldType) == TypeCode.Decimal || Type.GetTypeCode(fieldType) == TypeCode.Double || Type.GetTypeCode(fieldType) == TypeCode.Int64 || Type.GetTypeCode(fieldType) == TypeCode.UInt16 || Type.GetTypeCode(fieldType) == TypeCode.UInt32 || Type.GetTypeCode(fieldType) == TypeCode.UInt64)) { param.Value = "," + param.Value + ","; param.DbType = DbType.String; if (dbProvider.CreateTableAegis("").Length > 0) { fieldName = "','+" + fieldName.Substring(1, fieldName.Length - 2) + "+','"; } else { fieldName = "','+" + fieldName + "+','"; } } #endregion SqlList.Push(String.Format("{0} LIKE {1}", fieldName, paramName)); } else { if (Type.GetTypeCode(fieldType) == TypeCode.String) { base.ParamsList.GetLast().Value = "'" + base.ParamsList.GetLast().Value.ToString().Replace(",", "','") + "'"; } SqlList.Push(String.Format("{0} IN ({1})", fieldName, base.ParamsList.GetLast().Value)); base.ParamsList.Remove(base.ParamsList.GetLast()); } break; } case "STARTSWITH": { SqlList.Push(String.Format("{0} LIKE {1}", fieldName, paramName)); ParamsList.GetLast().Value = string.Format("{0}%", ParamsList.GetLast().Value); break; } case "ENDSWITH": { SqlList.Push(String.Format("{0} LIKE {1}", fieldName, paramName)); ParamsList.GetLast().Value = string.Format("%{0}", ParamsList.GetLast().Value); break; } case "ISEQUALS": { SqlList.Push(String.Format("{0} = {1}", fieldName, paramName)); break; } default: { if (m.Arguments.Count == 0 && m.Object != null) { return(m); } else { return(VisitConvert(m)); throw new Exception(string.Format("暂不支持该方法的SQL转换:" + m.Method.Name.ToUpper())); } } } return(m); }
object Evaluate(IsType t) { return(t.IncludeSubtypes ? _reflection.IsSubtype(Evaluate(t.Object), t.Type.FullName) : _reflection.IsType(Evaluate(t.Object), t.Type.FullName)); }
private static bool IsTypeConversion(ConversionBlock block, Expression expression, ResolveResult rr, IType expectedType, Conversion conversion, string typeName, IsType isType) { if (conversion.IsUserDefined) { var m = conversion.Method; if (isType(m.ReturnType, block.Emitter.Resolver)) { return(false); } } var invocationExpression = expression.Parent as InvocationExpression; if (invocationExpression != null && invocationExpression.Arguments.Any(a => a == expression)) { var index = invocationExpression.Arguments.ToList().IndexOf(expression); var methodResolveResult = block.Emitter.Resolver.ResolveNode(invocationExpression, block.Emitter) as MemberResolveResult; if (methodResolveResult != null) { var m = methodResolveResult.Member as IMethod; var arg = m.Parameters[index < m.Parameters.Count ? index : (m.Parameters.Count - 1)]; if (isType(arg.Type, block.Emitter.Resolver, arg.IsParams) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } return(true); } } } var objectCreateExpression = expression.Parent as ObjectCreateExpression; if (objectCreateExpression != null && objectCreateExpression.Arguments.Any(a => a == expression)) { var index = objectCreateExpression.Arguments.ToList().IndexOf(expression); var methodResolveResult = block.Emitter.Resolver.ResolveNode(objectCreateExpression, block.Emitter) as MemberResolveResult; if (methodResolveResult != null) { var m = methodResolveResult.Member as IMethod; var arg = m.Parameters[index < m.Parameters.Count ? index : (m.Parameters.Count - 1)]; if (isType(arg.Type, block.Emitter.Resolver, arg.IsParams) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } return(true); } } } var namedArgExpression = expression.Parent as NamedArgumentExpression; if (namedArgExpression != null) { var namedArgResolveResult = block.Emitter.Resolver.ResolveNode(namedArgExpression, block.Emitter) as NamedArgumentResolveResult; if (isType(namedArgResolveResult.Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } return(true); } } var namedExpression = expression.Parent as NamedExpression; if (namedExpression != null) { var namedResolveResult = block.Emitter.Resolver.ResolveNode(namedExpression, block.Emitter); if (isType(namedResolveResult.Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } return(true); } } var binaryOpExpr = expression.Parent as BinaryOperatorExpression; if (binaryOpExpr != null) { var idx = binaryOpExpr.Left == expression ? 0 : 1; var binaryOpRr = block.Emitter.Resolver.ResolveNode(binaryOpExpr, block.Emitter) as OperatorResolveResult; if (binaryOpRr != null && isType(binaryOpRr.Operands[idx].Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } return(true); } } var conditionalExpr = expression.Parent as ConditionalExpression; if (conditionalExpr != null && conditionalExpr.Condition != expression) { var idx = conditionalExpr.TrueExpression == expression ? 0 : 1; var conditionalrr = block.Emitter.Resolver.ResolveNode(conditionalExpr, block.Emitter) as OperatorResolveResult; if (conditionalrr != null && isType(conditionalrr.Operands[idx].Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } return(true); } } var assignmentExpr = expression.Parent as AssignmentExpression; if (assignmentExpr != null) { var assigmentRr = block.Emitter.Resolver.ResolveNode(assignmentExpr, block.Emitter) as OperatorResolveResult; if (isType(assigmentRr.Operands[1].Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } return(true); } } var arrayInit = expression.Parent as ArrayInitializerExpression; if (arrayInit != null) { while (arrayInit.Parent is ArrayInitializerExpression) { arrayInit = (ArrayInitializerExpression)arrayInit.Parent; } IType elementType = null; var arrayCreate = arrayInit.Parent as ArrayCreateExpression; if (arrayCreate != null) { var rrArrayType = block.Emitter.Resolver.ResolveNode(arrayCreate, block.Emitter); if (rrArrayType.Type is TypeWithElementType) { elementType = ((TypeWithElementType)rrArrayType.Type).ElementType; } else { elementType = rrArrayType.Type; } } else { var rrElemenet = block.Emitter.Resolver.ResolveNode(arrayInit.Parent, block.Emitter); var pt = rrElemenet.Type as ParameterizedType; if (pt != null) { elementType = pt.TypeArguments.Count > 0 ? pt.TypeArguments.First() : null; } else { var arrayType = rrElemenet.Type as TypeWithElementType; if (arrayType != null) { elementType = arrayType.ElementType; } else { elementType = rrElemenet.Type; } } } if (elementType != null && isType(elementType, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } return(true); } else if (Helpers.Is64Type(rr.Type, block.Emitter.Resolver) && Helpers.IsFloatType(elementType, block.Emitter.Resolver) && !Helpers.IsDecimalType(elementType, block.Emitter.Resolver) && isType(rr.Type, block.Emitter.Resolver)) { if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } return(true); } } if (isType(expectedType, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver) && !(conversion.IsExplicit && conversion.IsNumericConversion)) { var castExpr = expression.Parent as CastExpression; ResolveResult castTypeRr = null; if (castExpr != null) { castTypeRr = block.Emitter.Resolver.ResolveNode(castExpr.Type, block.Emitter); } /*if (castTypeRr == null || !isType(castTypeRr.Type, block.Emitter.Resolver))*/ if (castTypeRr == null || !conversion.IsExplicit) { if (expression.IsNull) { return(false); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } return(true); } } return(false); }
private static bool CheckTypeConversion(ConversionBlock block, Expression expression, ResolveResult rr, IType expectedType, Conversion conversion, string typeName, IsType isType, bool ignoreConversionResolveResult) { if (conversion.IsUserDefined) { var m = conversion.Method; if (isType(m.ReturnType, block.Emitter.Resolver)) { return(false); } } if (expression is CastExpression && !ignoreConversionResolveResult) { var nestedExpr = ((CastExpression)expression).Expression; var nested_rr = block.Emitter.Resolver.ResolveNode(nestedExpr, block.Emitter); if (!(nested_rr is ConversionResolveResult)) { return(false); } } var invocationExpression = expression.Parent as InvocationExpression; if (invocationExpression != null && invocationExpression.Arguments.Any(a => a == expression)) { var index = invocationExpression.Arguments.ToList().IndexOf(expression); var methodResolveResult = block.Emitter.Resolver.ResolveNode(invocationExpression, block.Emitter) as MemberResolveResult; if (methodResolveResult != null) { var m = methodResolveResult.Member as IMethod; var arg = m.Parameters[index < m.Parameters.Count ? index : (m.Parameters.Count - 1)]; if (isType(arg.Type, block.Emitter.Resolver, arg.IsParams) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } block.Write(typeName); if (NullableType.IsNullable(arg.Type) && ConversionBlock.ShouldBeLifted(expression)) { block.Write("." + JS.Funcs.Math.LIFT); } if (!ignoreConversionResolveResult && expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } block.WriteOpenParentheses(); return(true); } } } var objectCreateExpression = expression.Parent as ObjectCreateExpression; if (objectCreateExpression != null && objectCreateExpression.Arguments.Any(a => a == expression)) { var index = objectCreateExpression.Arguments.ToList().IndexOf(expression); var methodResolveResult = block.Emitter.Resolver.ResolveNode(objectCreateExpression, block.Emitter) as MemberResolveResult; if (methodResolveResult != null) { var m = methodResolveResult.Member as IMethod; var arg = m.Parameters[index < m.Parameters.Count ? index : (m.Parameters.Count - 1)]; if (isType(arg.Type, block.Emitter.Resolver, arg.IsParams) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } block.Write(typeName); if (NullableType.IsNullable(arg.Type) && ConversionBlock.ShouldBeLifted(expression)) { block.Write("." + JS.Funcs.Math.LIFT); } if (!ignoreConversionResolveResult && expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } block.WriteOpenParentheses(); return(true); } } } var namedArgExpression = expression.Parent as NamedArgumentExpression; if (namedArgExpression != null) { var namedArgResolveResult = block.Emitter.Resolver.ResolveNode(namedArgExpression, block.Emitter) as NamedArgumentResolveResult; if (isType(namedArgResolveResult.Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } block.Write(typeName); if (NullableType.IsNullable(namedArgResolveResult.Type) && ConversionBlock.ShouldBeLifted(expression)) { block.Write("." + JS.Funcs.Math.LIFT); } if (!ignoreConversionResolveResult && expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } block.WriteOpenParentheses(); return(true); } } var namedExpression = expression.Parent as NamedExpression; if (namedExpression != null) { var namedResolveResult = block.Emitter.Resolver.ResolveNode(namedExpression, block.Emitter); if (isType(namedResolveResult.Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } block.Write(typeName); if (NullableType.IsNullable(namedResolveResult.Type) && ConversionBlock.ShouldBeLifted(expression)) { block.Write("." + JS.Funcs.Math.LIFT); } if (!ignoreConversionResolveResult && expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } block.WriteOpenParentheses(); return(true); } } var binaryOpExpr = expression.Parent as BinaryOperatorExpression; if (binaryOpExpr != null) { var idx = binaryOpExpr.Left == expression ? 0 : 1; var binaryOpRr = block.Emitter.Resolver.ResolveNode(binaryOpExpr, block.Emitter) as OperatorResolveResult; if (binaryOpRr != null && isType(binaryOpRr.Operands[idx].Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { var isNullable = NullableType.IsNullable(binaryOpRr.Operands[idx].Type); if (expression.IsNull) { return(false); } block.Write(typeName); if (isNullable && ConversionBlock.ShouldBeLifted(expression)) { block.Write("." + JS.Funcs.Math.LIFT); } if (!ignoreConversionResolveResult && expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } block.WriteOpenParentheses(); return(true); } } var conditionalExpr = expression.Parent as ConditionalExpression; if (conditionalExpr != null && conditionalExpr.Condition != expression) { var idx = conditionalExpr.TrueExpression == expression ? 1 : 2; var conditionalrr = block.Emitter.Resolver.ResolveNode(conditionalExpr, block.Emitter) as OperatorResolveResult; if (conditionalrr != null && isType(conditionalrr.Operands[idx].Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } block.Write(typeName); if (NullableType.IsNullable(conditionalrr.Operands[idx].Type) && ConversionBlock.ShouldBeLifted(expression)) { block.Write("." + JS.Funcs.Math.LIFT); } if (!ignoreConversionResolveResult && expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } block.WriteOpenParentheses(); return(true); } } var assignmentExpr = expression.Parent as AssignmentExpression; if (assignmentExpr != null) { var assigmentRr = block.Emitter.Resolver.ResolveNode(assignmentExpr, block.Emitter) as OperatorResolveResult; if (isType(assigmentRr.Operands[1].Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } block.Write(typeName); if (NullableType.IsNullable(assigmentRr.Operands[1].Type) && ConversionBlock.ShouldBeLifted(expression)) { block.Write("." + JS.Funcs.Math.LIFT); } if (!ignoreConversionResolveResult && expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } block.WriteOpenParentheses(); return(true); } } var indexerExpr = expression.Parent as IndexerExpression; if (indexerExpr != null) { var index = indexerExpr.Arguments.ToList().IndexOf(expression); if (index >= 0) { var invocationrr = block.Emitter.Resolver.ResolveNode(indexerExpr, block.Emitter) as InvocationResolveResult; if (invocationrr != null) { var parameters = invocationrr.Member.Parameters; if (parameters.Count <= index) { index = parameters.Count - 1; } if (isType(invocationrr.Member.Parameters.ElementAt(index).Type, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } block.Write(typeName); if (NullableType.IsNullable(invocationrr.Member.Parameters.ElementAt(index).Type) && ConversionBlock.ShouldBeLifted(expression)) { block.Write("." + JS.Funcs.Math.LIFT); } if (!ignoreConversionResolveResult && expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } block.WriteOpenParentheses(); return(true); } } } } var arrayInit = expression.Parent as ArrayInitializerExpression; if (arrayInit != null) { while (arrayInit.Parent is ArrayInitializerExpression) { arrayInit = (ArrayInitializerExpression)arrayInit.Parent; } IType elementType = null; var arrayCreate = arrayInit.Parent as ArrayCreateExpression; if (arrayCreate != null) { var rrArrayType = block.Emitter.Resolver.ResolveNode(arrayCreate, block.Emitter); if (rrArrayType.Type is TypeWithElementType) { elementType = ((TypeWithElementType)rrArrayType.Type).ElementType; } else { elementType = rrArrayType.Type; } } else { var rrElemenet = block.Emitter.Resolver.ResolveNode(arrayInit.Parent, block.Emitter); var pt = rrElemenet.Type as ParameterizedType; if (pt != null && pt.TypeArguments.Count > 0) { if (pt.TypeArguments.Count == 1) { elementType = pt.TypeArguments.First(); } else { var index = 0; arrayInit = expression.Parent as ArrayInitializerExpression; for (int i = 0; i < arrayInit.Elements.Count; i++) { if (expression == arrayInit.Elements.ElementAt(i)) { index = i; break; } } elementType = index < pt.TypeArguments.Count ? pt.TypeArguments.ElementAt(index) : pt.TypeArguments.ElementAt(0); } } else { var arrayType = rrElemenet.Type as TypeWithElementType; if (arrayType != null) { elementType = arrayType.ElementType; } else { elementType = rrElemenet.Type; } } } if (elementType != null && isType(elementType, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver)) { if (expression.IsNull) { return(false); } block.Write(typeName); if (NullableType.IsNullable(elementType) && ConversionBlock.ShouldBeLifted(expression)) { block.Write("." + JS.Funcs.Math.LIFT); } if (!ignoreConversionResolveResult && expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } block.WriteOpenParentheses(); return(true); } else if (Helpers.Is64Type(rr.Type, block.Emitter.Resolver) && Helpers.IsFloatType(elementType, block.Emitter.Resolver) && !Helpers.IsDecimalType(elementType, block.Emitter.Resolver) && isType(rr.Type, block.Emitter.Resolver)) { block.Write(JS.Types.System.Int64.TONUMBER); if (!ignoreConversionResolveResult && expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } block.WriteOpenParentheses(); return(true); } } if (isType(expectedType, block.Emitter.Resolver) && !isType(rr.Type, block.Emitter.Resolver) && !(conversion.IsExplicit && conversion.IsNumericConversion)) { var castExpr = expression.Parent as CastExpression; ResolveResult castTypeRr = null; if (castExpr != null) { castTypeRr = block.Emitter.Resolver.ResolveNode(castExpr.Type, block.Emitter); } /*if (castTypeRr == null || !isType(castTypeRr.Type, block.Emitter.Resolver))*/ if (castTypeRr == null || !conversion.IsExplicit) { if (expression.IsNull) { return(false); } block.Write(typeName); if (NullableType.IsNullable(expectedType) && ConversionBlock.ShouldBeLifted(expression)) { block.Write("." + JS.Funcs.Math.LIFT); } if (!ignoreConversionResolveResult && expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(false); } block.WriteOpenParentheses(); return(true); } } return(false); }
public IErrorReporter DuckTypingOnEmptyInterface() { NameResolver resolver = null; foreach (var mutability in Options.AllMutabilityModes) { var env = Environment.Create(new Options() { DiscardingAnyExpressionDuringTests = true, // we test this option here or more precisely duck typing InterfaceDuckTyping = true }.SetMutability(mutability)); var root_ns = env.Root; // please note it is not the interface is empty (it is not because IObject is not empty), // but it does not add anything, so in this sense it is empty root_ns.AddBuilder(TypeBuilder.CreateInterface("IWhat")); root_ns.AddBuilder(FunctionBuilder.Create("foo", NameFactory.UnitNameReference(), Block.CreateStatement( VariableDeclaration.CreateStatement("x", NameFactory.PointerNameReference(NameFactory.IObjectNameReference()), Undef.Create()), // should be legal despite duck typing, i.e. we should not error that the types are exchangable // they are in sense of duck typing but checking if the type IS another type should be duck-free ExpressionFactory.Readout(IsType.Create(NameReference.Create("x"), NameReference.Create("IWhat"))), VariableDeclaration.CreateStatement("y", NameFactory.PointerNameReference(NameReference.Create("IWhat")), Undef.Create()), ExpressionFactory.Readout(IsSame.Create(NameReference.Create("x"), NameReference.Create("y"))) ))); resolver = NameResolver.Create(env); Assert.AreEqual(0, resolver.ErrorManager.Errors.Count); } return(resolver); }
/// <summary> /// IExpressionリスト取得 /// </summary> /// <param name="operation">IOperationインスタンス</param> /// <param name="container">イベントコンテナ</param> /// <returns>IExpressionリスト</returns> public static List <IExpression> GetExpressionList(IOperation operation, EventContainer container) { List <IExpression> result = new List <IExpression>(); AbstractOperation instance = null; switch (operation) { // 式系 case ISimpleAssignmentOperation param: instance = new SimpleAssignment(param, container); break; case IInvocationOperation param: instance = new Invocation(param, container); break; case IBinaryOperation param: instance = new Binary(param, container); break; case IIncrementOrDecrementOperation param: instance = new Increment(param, container); break; case ICompoundAssignmentOperation param: instance = new CompoundAssignment(param, container); break; case IConversionOperation param: result.AddRange(GetExpressionList(param.Operand, container)); break; // 参照系 case IInstanceReferenceOperation param: instance = new InstanceReference(param, container); break; case IFieldReferenceOperation param: instance = new FieldReference(param, container); break; case IPropertyReferenceOperation param: instance = new PropertyReference(param, container); break; case ILocalReferenceOperation param: instance = new LocalReference(param, container); break; case IParameterReferenceOperation param: instance = new ParameterReference(param, container); break; case IArrayElementReferenceOperation param: instance = new ArrayElementReference(param, container); break; case IArgumentOperation param: instance = new Argument(param, container); break; // 生成系 case IObjectCreationOperation param: instance = new ObjectCreation(param, container); break; case IArrayCreationOperation param: instance = new ArrayCreation(param, container); break; case IArrayInitializerOperation param: instance = new ArrayInitializer(param, container); break; case IVariableDeclaratorOperation param: instance = new VariableDeclarator(param, container); break; // 直値 case ILiteralOperation param: instance = new Literal(param, container); break; // Switch Case系 case IDefaultCaseClauseOperation param: instance = new DefalutCase(param, container); break; case IDeclarationPatternOperation param: instance = new DeclarationPattern(param, container); break; //If系 case IIsPatternOperation param: instance = new IsPattern(param, container); break; case IIsTypeOperation param: instance = new IsType(param, container); break; default: Console.Write($" [{operation.Kind} is none] "); break; } // リスト追加 if (instance != null) { result.AddRange(instance.Expressions); } return(result); }