示例#1
0
        private static List <FieldDeclarationSyntax> SortFields(List <FieldDeclarationSyntax> fields)
        {
            if (fields.Count == 0)
            {
                return(fields);
            }

            var dependencies =
                fields.ToDictionary(
                    o => TypeProcessor.GetDeclaredSymbol(o.Declaration.Variables.First()).As <IFieldSymbol>(),
                    o => new { Syntax = o, Dependicies = new List <IFieldSymbol>() });

            foreach (var dep in dependencies)
            {
                foreach (
                    var fieldDepend in
                    dep.Value.Syntax.DescendantNodes()
                    .OfType <ExpressionSyntax>()
                    .Select(o => TypeProcessor.GetSymbolInfo(o).Symbol)
                    .OfType <IFieldSymbol>())
                {
                    if (dependencies.ContainsKey(fieldDepend))
                    {
                        dep.Value.Dependicies.Add(fieldDepend);
                    }
                }
            }

            var ret          = new List <FieldDeclarationSyntax>();
            var symbolsAdded = new HashSet <IFieldSymbol>();

            while (dependencies.Count > 0)
            {
                foreach (var dep in dependencies.ToList())
                {
                    for (int i = 0; i < dep.Value.Dependicies.Count; i++)
                    {
                        if (symbolsAdded.Contains(dep.Value.Dependicies[i]))
                        {
                            dep.Value.Dependicies.RemoveAt(i--);
                        }
                    }

                    if (dep.Value.Dependicies.Count == 0)
                    {
                        ret.Add(dep.Value.Syntax);
                        symbolsAdded.Add(dep.Key);
                        dependencies.Remove(dep.Key);
                    }
                }
            }

            return(ret);
        }
示例#2
0
        public void Write(OutputWriter writer)
        {
            if (StringOpt != null)
            {
                writer.Write(StringOpt);
            }
            else
            {
                if (ArgumentOpt.NameColon != null)
                {
                    Core.Write(writer, ArgumentOpt.NameColon.Name);
                    writer.Write(" = ");
                }

                var symbol = TypeProcessor.GetSymbolInfo(ArgumentOpt.Expression);
                var type   = TypeProcessor.GetTypeInfo(ArgumentOpt.Expression);

                if (symbol.Symbol != null && type.ConvertedType != null && symbol.Symbol.Kind == SymbolKind.Method &&
                    type.ConvertedType.TypeKind == TypeKind.Delegate)
                {
                    var typeString = TypeProcessor.ConvertType(type.ConvertedType);

                    var createNew = !(ArgumentOpt.Parent.Parent is ObjectCreationExpressionSyntax); //Ugly hack

                    if (createNew)
                    {
                        if (type.ConvertedType.TypeKind == TypeKind.TypeParameter)
                        {
                            writer.Write(" __TypeNew!(" + typeString + ")(");
                        }
                        else
                        {
                            writer.Write("new " + typeString + "(");
                        }
                    }

                    var isStatic = symbol.Symbol.IsStatic;
//                    if (isStatic) //Not Needed, delegate class now supports functions directly
//                        writer.Write("__ToDelegate(");
                    MemberUtilities.WriteMethodPointer(writer, ArgumentOpt.Expression);
//                    if (isStatic)
//                        writer.Write(")");

                    if (createNew)
                    {
                        writer.Write(")");
                    }
                    return;
                }

                Core.Write(writer, ArgumentOpt.Expression);
            }
        }
/// <summary>
///     Determines if the passed symbol is used in any ref or out clauses
/// </summary>
        private static bool UsedAsRef(VariableDeclaratorSyntax variable, ISymbol symbol)
        {
            SyntaxNode  node = variable;
            BlockSyntax scope;

            do
            {
                scope = (node = node.Parent) as BlockSyntax;
            }while (scope == null);

            return(scope.DescendantNodes().OfType <InvocationExpressionSyntax>()
                   .SelectMany(o => o.ArgumentList.Arguments)
                   .Where(o => o.RefOrOutKeyword.RawKind != (decimal)SyntaxKind.None)
                   .Any(o => TypeProcessor.GetSymbolInfo(o.Expression).Symbol == symbol));
        }
示例#4
0
        public static void WriteMember(OutputWriter writer, ExpressionSyntax expression)
        {
            var symbol = TypeProcessor.GetSymbolInfo(expression).Symbol;

            if (symbol is INamedTypeSymbol)
            {
                var str = TypeProcessor.ConvertType(symbol.As <INamedTypeSymbol>());
                if (str == "Array_T")
                {
                    // Array is the only special case, otherwise generics have to be specialized to access static members
                    str = "Array";
                }
                writer.Write(str);
            }
            else
            {
                Core.Write(writer, expression);
            }
        }
示例#5
0
 public static void WriteMethodPointer(OutputWriter writer, SyntaxNode expression)
 {
     writer.Write("&");
     var symbol = TypeProcessor.GetSymbolInfo(expression).Symbol;
     //
     //            else
     {
         Core.Write(writer, expression);
         if (symbol is IMethodSymbol && !(expression is GenericNameSyntax))
         {
             //Type inference for delegates
             var methodSymbol = symbol as IMethodSymbol;
             //   var methodName = TypeProcessor.ConvertType(methodSymbol.ContainingType) +"."+ WriteIdentifierName.TransformIdentifier(methodSymbol.Name);
             var specializedMethod = //methodName +
                                     (methodSymbol.TypeArguments.Any() ? ("!(" +
                                                                          methodSymbol.TypeArguments.Select(k => TypeProcessor.ConvertType(k))
                                                                          .Aggregate((a, b) => a + "," + b) + ")") : "");
             writer.Write(specializedMethod);
         }
     }
 }
        public static string WriteMemberToString(ExpressionSyntax expression)
        {
            var result = "";
            var symbol = TypeProcessor.GetSymbolInfo(expression).Symbol;

            if (symbol is INamedTypeSymbol)
            {
                var str = TypeProcessor.ConvertType(symbol.As <INamedTypeSymbol>());
                if (str == "Array_T")
                {
                    // Array is the only special case, otherwise generics have to be specialized to access static members
                    str = "Array";
                }
                result += (str);
            }
            else
            {
                result += Core.WriteString(expression);
            }

            return(result);
        }
示例#7
0
        public static void WritePrefix(OutputWriter writer, PrefixUnaryExpressionSyntax expression)
        {
            var isProperty = false;

            var symbol = TypeProcessor.GetSymbolInfo(expression.Operand);

            if (symbol.Symbol is IPropertySymbol)
            {
                isProperty = true;
            }


            if (isProperty)
            {
                var symbolName = Core.WriteString(expression.Operand).ToString().Trim();
                switch (expression.OperatorToken.RawKind)
                {
                case (int)SyntaxKind.MinusMinusToken:
                    if ((symbol.Symbol as IPropertySymbol).IsIndexer)
                    {
                        writer.Write(String.Format("/*--{0}*/((){{ auto v = {0};{0}=(--v);return v;}})()", symbolName));
                    }
                    else
                    {
                        writer.Write(String.Format("/*--{0}*/((){{ auto v = {0};{0}(--v);return v;}})()", symbolName));
                    }
                    break;

                case (int)SyntaxKind.PlusPlusToken:
                    if ((symbol.Symbol as IPropertySymbol).IsIndexer)
                    {
                        writer.Write(String.Format("/*++{0}*/((){{ auto v = {0};{0}=(++v);return v;}})()", symbolName));
                    }
                    else
                    {
                        writer.Write(String.Format("/*++{0}*/((){{ auto v = {0};{0}(++v);return v;}})()", symbolName));
                    }

                    break;

                default:
                    writer.Write(expression.OperatorToken.Text);

                    Core.Write(writer, expression.Operand);


                    break;
                }
            }
            else
            {
                //			Console.WriteLine (expression.ToFullString());
                //				if (expression.OperatorToken.RawKind == (decimal)SyntaxKind.MinusMinusToken)
                //				{
                //
                //					writer.Write ("--");
                //					Core.Write (writer, expression.Operand);
                //				}
                //				else if (expression.OperatorToken.RawKind == (decimal)SyntaxKind.PlusPlusToken)
                //				{
                //					writer.Write ("++");
                //					Core.Write (writer, expression.Operand);
                //				}
                //				else
                //				{
                //					//TODO: cannot take addresses of structs in 32/64-bit mode and subtract them ... really weird d-bug ... leads to wrong math ... should we do a shift ?
                ////				if (expression.OperatorToken.CSharpKind () == SyntaxKind.AmpersandToken) // Take address
                ////				{
                ////					var memberAccess = expression.Operand as MemberAccessExpressionSyntax;
                ////					var simpleName = expression.Operand as NameSyntax;
                ////
                ////					TypeInfo typeOperand;
                ////
                ////					if (memberAccess != null)
                ////						typeOperand = TypeProcessor.GetTypeInfo (memberAccess.Expression);
                ////					if (simpleName != null)
                ////						typeOperand = TypeProcessor.GetTypeInfo (simpleName);
                ////
                ////					var failed = true;
                //
                ////					if (memberAccess != null)
                ////					{
                ////						 failed = false;
                ////						if (typeOperand.Type.TypeKind == TypeKind.Struct)
                ////						{
                ////							var sNAme = (memberAccess.Expression as SimpleNameSyntax).Identifier;
                ////
                ////							writer.Write ("(cast(ulong)(&" + sNAme.ToFullString () + ") + (");
                ////							Core.Write (writer, expression.Operand);
                ////							writer.Write (".offsetof))");
                ////						}
                ////						else
                ////							failed = true;
                ////					}
                ////					else if (simpleName != null)
                ////					{
                ////						failed = false;
                ////
                ////						if (typeOperand.Type.TypeKind == TypeKind.Struct)
                ////						{
                ////							writer.Write ("(&" + simpleName.ToFullString () + " + (");
                ////							Core.Write (writer, expression.Operand);
                ////							writer.Write (".offsetof))");
                ////						}
                ////						else
                ////							failed = true;
                ////					}
                ////
                ////					if(failed)
                ////					{
                ////						writer.Write (expression.OperatorToken.ToString ());
                ////						Core.Write (writer, expression.Operand);
                ////					}
                ////
                ////				}
                ////				else
                //					{
                //						writer.Write (expression.OperatorToken.ToString ());
                //						Core.Write (writer, expression.Operand);
                //					}
                //				}

                //D's unary operators are a bit different from C# .. i.e. not static
                bool hasOpIncrement = false;
                bool hasOpDecrement = false;

                var typeSymbol = TypeProcessor.GetTypeInfo(expression.Operand).Type;
                if (typeSymbol != null)
                {
                    hasOpIncrement = typeSymbol.GetMembers("op_Increment").Any();

                    hasOpDecrement = typeSymbol.GetMembers("op_Decrement").Any();
                }

                switch (expression.OperatorToken.RawKind)
                {
                case (int)SyntaxKind.MinusMinusToken:
                    if (hasOpDecrement)
                    {
                        var texpression = Core.WriteString(expression.Operand);

                        writer.Write(String.Format("/*--{0}*/((){{ auto v = {0};{0}={0}.op_Decrement({0});return v;}})()", texpression));
                    }
                    else
                    {
                        writer.Write("--");
                        Core.Write(writer, expression.Operand);
                    }
                    break;

                case (int)SyntaxKind.PlusPlusToken:
                    if (hasOpIncrement)
                    {
                        var texpression = Core.WriteString(expression.Operand);

                        writer.Write(String.Format("/*++{0}*/((){{ auto v = {0};{0}={0}.op_Increment({0});return v;}})()", texpression));
                    }
                    else
                    {
                        writer.Write("++");
                        Core.Write(writer, expression.Operand);
                    }
                    break;

                default:
                    writer.Write(expression.OperatorToken.Text);

                    Core.Write(writer, expression.Operand);

                    // throw new Exception("No support for " + expression.OperatorToken.RawKind + " at " +
                    //Utility.Descriptor(expression));
                    break;
                }
            }
        }
示例#8
0
        public static void WritePostfix(OutputWriter writer, PostfixUnaryExpressionSyntax expression)
        {
            var isProperty = false;

            var symbol = TypeProcessor.GetSymbolInfo(expression.Operand);

            if (symbol.Symbol is IPropertySymbol)
            {
                isProperty = true;
            }


            if (isProperty)
            {
                var symbolName = Core.WriteString(expression.Operand);
                switch (expression.OperatorToken.RawKind)
                {
                case (int)SyntaxKind.MinusMinusToken:
                    if ((symbol.Symbol as IPropertySymbol).IsIndexer)
                    {
                        writer.Write(String.Format("/*{0}--*/((){{auto v={0};auto y=v;{0}=(--y);return v;}})()", symbolName));
                    }
                    else
                    {
                        writer.Write(String.Format("/*{0}--*/((){{auto v={0};auto y=v;{0}(--y);return v;}})()", symbolName));
                    }

                    break;

                case (int)SyntaxKind.PlusPlusToken:
                    if ((symbol.Symbol as IPropertySymbol).IsIndexer)
                    {
                        writer.Write(String.Format("/*{0}++*/((){{auto v={0},y={0};{0}=(++y);return v;}})()", symbolName));
                    }
                    else
                    {
                        writer.Write(String.Format("/*{0}++*/((){{auto v={0},y={0};{0}(++y);return v;}})()", symbolName));
                    }

                    break;

                default:
                    Core.Write(writer, expression.Operand);
                    writer.Write(expression.OperatorToken.Text);
                    break;
                }
            }
            else
            {
                //            if (expression.Operand is MemberAccessExpressionSyntax)
                //            {
                //                var memberAccess = expression.Operand as MemberAccessExpressionSyntax;
                //                var typeInfo = TypeProcessor.GetSymbolInfo(memberAccess.Name);

                //                if (typeInfo.Symbol.Kind == SymbolKind.Property)
                //                {
                //                    switch (expression.OperatorToken.RawKind)
                //                    {
                //                        case (int)SyntaxKind.MinusMinusToken:
                //                          var refactored=  SyntaxFactory.BinaryExpression(SyntaxKind.SimpleAssignmentExpression,
                //                                expression.Operand,
                //                                SyntaxFactory.BinaryExpression(SyntaxKind.AddExpression, expression.Operand,
                //                                    SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression,SyntaxFactory.Literal(-1)))
                //                                ).NormalizeWhitespace();
                //                            Core.Write(writer,refactored);
                //                            break;
                //                        case (int)SyntaxKind.PlusPlusToken:
                //                            var refactored1 = SyntaxFactory.BinaryExpression(SyntaxKind.SimpleAssignmentExpression,
                //                                 expression.Operand,
                //                                 SyntaxFactory.BinaryExpression(SyntaxKind.AddExpression, expression.Operand,
                //                                     SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(+1)))
                //                                 ).NormalizeWhitespace();
                //                            Core.Write(writer, refactored1);
                //                            break;
                //                        default:
                //                            throw new Exception("No support for " + expression.OperatorToken.RawKind + " at " +
                //                                                Utility.Descriptor(expression));
                //                    }
                //                }
                //                else
                //                {
                //                    switch (expression.OperatorToken.RawKind)
                //                    {
                //                        case (int)SyntaxKind.MinusMinusToken:
                //                            Core.Write(writer, expression.Operand);
                //                            writer.Write("--");
                //                            break;
                //                        case (int)SyntaxKind.PlusPlusToken:
                //                            Core.Write(writer, expression.Operand);
                //                            writer.Write("++");
                //                            break;
                //                        default:
                //                            throw new Exception("No support for " + expression.OperatorToken.RawKind + " at " +
                //                                                Utility.Descriptor(expression));
                //                    }
                //                }
                //
                //            }
                //            else
                //            {
                //D's unary operators are a bit different from C# .. i.e. not static
                bool hasOpIncrement = false;
                bool hasOpDecrement = false;

                var typeSymbol = TypeProcessor.GetTypeInfo(expression.Operand).Type;
                if (typeSymbol != null)
                {
                    hasOpIncrement = typeSymbol.GetMembers("op_Increment").Any();

                    hasOpDecrement = typeSymbol.GetMembers("op_Decrement").Any();
                }

                switch (expression.OperatorToken.RawKind)
                {
                case (int)SyntaxKind.MinusMinusToken:
                    if (hasOpDecrement)
                    {
                        var texpression = Core.WriteString(expression.Operand);

                        writer.Write(String.Format("/*{0}--*/({0}={0}.op_Decrement({0}))", texpression));
                    }
                    else
                    {
                        Core.Write(writer, expression.Operand);
                        writer.Write("--");
                    }
                    break;

                case (int)SyntaxKind.PlusPlusToken:
                    if (hasOpIncrement)
                    {
                        var texpression = Core.WriteString(expression.Operand);

                        writer.Write(String.Format("/*{0}--*/({0}={0}.op_Increment({0}))", texpression));
                    }
                    else
                    {
                        Core.Write(writer, expression.Operand);
                        writer.Write("++");
                    }
                    break;

                default:
                    throw new Exception("No support for " + expression.OperatorToken.RawKind + " at " +
                                        Utility.Descriptor(expression));
                }
            }
//            }
        }
示例#9
0
        private static void ProcessInitializer(OutputWriter writer, LocalDeclarationStatementSyntax declaration,
                                               VariableDeclaratorSyntax variable)
        {
            var initializer = variable.Initializer;

            if (initializer != null)
            {
                if (initializer.Value.CSharpKind() == SyntaxKind.CollectionInitializerExpression)
                {
                    return;
                }

                var value                  = initializer.Value;
                var initializerType        = TypeProcessor.GetTypeInfo(value);
                var memberaccessexpression = value as MemberAccessExpressionSyntax;
                var nameexpression         = value as NameSyntax;
                var nullAssignment         = value.ToFullString().Trim() == "null";
                var shouldBox              = initializerType.Type != null && initializerType.Type.IsValueType &&
                                             !initializerType.ConvertedType.IsValueType;
                var shouldUnBox = initializerType.Type != null && !initializerType.Type.IsValueType &&
                                  initializerType.ConvertedType.IsValueType;
                var isname             = value is NameSyntax;
                var ismemberexpression = value is MemberAccessExpressionSyntax ||
                                         (isname &&
                                          TypeProcessor.GetSymbolInfo(value as NameSyntax).Symbol.Kind ==
                                          SymbolKind.Method);
                var isdelegateassignment = ismemberexpression &&
                                           initializerType.ConvertedType.TypeKind == TypeKind.Delegate;
                var isstaticdelegate = isdelegateassignment &&
                                       ((memberaccessexpression != null &&
                                         TypeProcessor.GetSymbolInfo(memberaccessexpression).Symbol.IsStatic) ||
                                        (isname && TypeProcessor.GetSymbolInfo(nameexpression).Symbol.IsStatic));

                //Do we have an implicit converter, if so, use it
                if (shouldBox || shouldUnBox)
                {
//			        if (shouldUnBox)
//			        {
//			            bool useType = true;
//
//                        //We should start with exact converters and then move to more generic convertors i.e. base class or integers which are implicitly convertible
//			            var correctConverter = initializerType.Type.GetImplicitCoversionOp(initializerType.Type,initializerType.ConvertedType);
////                            initializerType.Type.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
//
//			            if (correctConverter == null)
//			            {
//			                useType = false;
//                            correctConverter =
//                            initializerType.ConvertedType.GetImplicitCoversionOp(initializerType.Type, initializerType.ConvertedType); //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
//                        }
//
//			            if (correctConverter != null)
//			            {
//                            if(useType)
//			                writer.Write(TypeProcessor.ConvertType(initializerType.Type) +"."+ "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType));
//                            else
//                            {
//			                writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) +"."+ "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType));
//
//                            }
//                            writer.Write("(");
//                            Core.Write(writer, value);
//                            writer.Write(")");
//                            return;
//                        }
//                    }
//			        if (shouldBox)
                    {
                        bool useType          = true;
                        var  correctConverter =
                            initializerType.Type.GetImplicitCoversionOp(initializerType.ConvertedType,
                                                                        initializerType.Type);
                        //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.ConvertedType && h.Parameters[0].Type == initializerType.Type);

                        if (correctConverter == null)
                        {
                            useType          = false;
                            correctConverter =
                                initializerType.ConvertedType.GetImplicitCoversionOp(initializerType.ConvertedType,
                                                                                     initializerType.Type);
                            //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.ConvertedType && h.Parameters[0].Type == initializerType.Type);
                        }

                        if (correctConverter != null)
                        {
                            if (useType)
                            {
                                writer.Write(TypeProcessor.ConvertType(initializerType.Type) + "." + "op_Implicit_" +
                                             TypeProcessor.ConvertType(correctConverter.ReturnType));
                            }
                            else
                            {
                                writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) + "." +
                                             "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType));
                            }
                            writer.Write("(");
                            Core.Write(writer, value);
                            writer.Write(")");
                            return;
                        }
                    }
                }

                if (nullAssignment)
                {
                    writer.Write("null");
                    return;
                }
                if (shouldBox)
                {
                    //Box
                    writer.Write("BOX!(" + TypeProcessor.ConvertType(initializerType.Type) + ")(");
                    //When passing an argument by ref or out, leave off the .Value suffix
                    Core.Write(writer, value);
                    writer.Write(")");
                    return;
                }
                if (shouldUnBox)
                {
                    //UnBox
                    writer.Write("cast!(" + TypeProcessor.ConvertType(initializerType.Type) + ")(");
                    Core.Write(writer, value);
                    writer.Write(")");
                }
                if (isdelegateassignment)
                {
                    var createNew  = !(value is ObjectCreationExpressionSyntax);
                    var typeString = TypeProcessor.ConvertType(initializerType.ConvertedType);

                    if (createNew)
                    {
                        if (initializerType.ConvertedType.TypeKind == TypeKind.TypeParameter)
                        {
                            writer.Write(" __TypeNew!(" + typeString + ")(");
                        }
                        else
                        {
                            writer.Write("new " + typeString + "(");
                        }
                    }

                    var isStatic = isstaticdelegate;
                    if (isStatic)
                    {
                        writer.Write("__ToDelegate(");
                    }
                    writer.Write("&");

                    Core.Write(writer, value);
                    if (isStatic)
                    {
                        writer.Write(")");
                    }

                    if (createNew)
                    {
                        writer.Write(")");
                    }
                    return;
                }
                if (initializerType.Type == null && initializerType.ConvertedType == null)
                {
                    writer.Write("null");
                    return;
                }
                Core.Write(writer, value);
            }
            else
            {
                writer.Write(TypeProcessor.DefaultValue(declaration.Declaration.Type));
            }
        }
示例#10
0
        public static void Go(OutputWriter writer, CastExpressionSyntax expression)
        {
            var symbol = TypeProcessor.GetSymbolInfo(expression);

            var castingFrom = TypeProcessor.GetTypeInfo(expression.Expression).Type ??
                              TypeProcessor.GetTypeInfo(expression).Type;

            var srcTypeDlang  = TypeProcessor.ConvertType(castingFrom);
            var destType      = TypeProcessor.GetTypeInfo(expression.Type).Type;
            var destTypeDlang = TypeProcessor.TryConvertType(expression.Type);

            if (destTypeDlang == srcTypeDlang)
            {
                Core.Write(writer, expression.Expression);
            }
            else
            //if (symbol.Symbol != null)// && srcTypeCpp != "int" && srcTypeCpp != "System.String" && srcTypeCpp != "bool")
            {
//                if (castingFrom != destType) // Check for implicit first then explicit

                bool useType = true;

                //We should start with exact converters and then move to more generic convertors i.e. base class or integers which are implicitly convertible
                var correctConverter = destType.GetImplicitCoversionOp(destType, castingFrom, true);
                //                            initializerType.Type.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);

                if (correctConverter == null)
                {
                    useType          = false;
                    correctConverter =
                        castingFrom.GetImplicitCoversionOp(destType, castingFrom, true);
                    //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
                }

                if (correctConverter != null)
                {
                    //                            Core.Write(writer, expression.Left);
                    //                            writer.Write(" = ");
                    if (correctConverter.ReturnType != destType)
                    {
                        writer.Write("Cast!(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")(");
                    }

                    if (castingFrom.SpecialType == SpecialType.System_Decimal && destType.IsPrimitiveInteger())
                    {
                    }
                    else
                    {
                        if (useType)
                        {
                            writer.Write(TypeProcessor.ConvertType(destType) + "." + "op_Implicit_" +
                                         TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_"));
                        }
                        else
                        {
                            writer.Write(TypeProcessor.ConvertType(castingFrom) + "." + "op_Implicit_" +
                                         TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_"));
                        }
                    }
                    writer.Write("(");
                    Core.Write(writer, expression.Expression);
                    writer.Write(")");

                    if (correctConverter.ReturnType != destType)
                    {
                        writer.Write(")");
                    }

                    return;
                }

                useType = true;

                //We should start with exact converters and then move to more generic convertors i.e. base class or integers which are implicitly convertible
                correctConverter = destType.GetExplictCoversionOp(destType, castingFrom, true);
                //                            initializerType.Type.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);

                if (correctConverter == null)
                {
                    useType          = false;
                    correctConverter =
                        castingFrom.GetExplictCoversionOp(destType, castingFrom, true);
                    //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
                }

                if (correctConverter != null)
                {
                    var iscast = correctConverter.ReturnType != destType;
                    if (iscast)
                    {
                        writer.Write("Cast!(" + destTypeDlang + ")(");
                    }

                    //                            Core.Write(writer, expression.Left);
                    //                            writer.Write(" = ");

                    if (castingFrom.SpecialType == SpecialType.System_Decimal && destType.IsPrimitiveInteger())
                    {
                    }
                    else
                    {
                        if (useType)
                        {
                            writer.Write(TypeProcessor.ConvertType(destType) + "." + "op_Explicit");
                        }
                        else
                        {
                            writer.Write(TypeProcessor.ConvertType(castingFrom) + "." + "op_Explicit");
                        }
                    }

                    writer.Write("(");
                    Core.Write(writer, expression.Expression);
                    writer.Write(")");
                    if (iscast)
                    {
                        writer.Write(")");
                    }
                    return;
                }

                if (TypeProcessor.IsPrimitiveType(srcTypeDlang) && TypeProcessor.IsPrimitiveType(destTypeDlang))
                {//primitives can be directly cast
                    writer.Write("cast(" + destTypeDlang + ")");
                    Core.Write(writer, expression.Expression);
                }

                else
                {
                    var convertedType = TypeProcessor.GetTypeInfo(expression).Type;
                    var type          = TypeProcessor.GetTypeInfo(expression.Expression).Type;

                    if (type.IsValueType && !convertedType.IsValueType)
                    {
                        //We have to box then cast if not Object
                        if (destType.Name != "Object")
                        {
                            writer.Write("Cast!(" + destTypeDlang + ")(");
                        }
                        //Box
                        writer.Write("BOX!(" + TypeProcessor.ConvertType(type) + ")(");
                        //When passing an argument by ref or out, leave off the .Value suffix
//                    writer.Write(" >(");
                        Core.Write(writer, expression.Expression);
                        writer.Write(")");
                        if (destType.Name != "Object")
                        {
                            writer.Write(")");
                        }
                    }
                    else if (!type.IsValueType && convertedType.IsValueType)
                    {
                        //UnBox
                        //					writer.Write("(Cast!( Boxed!(" + TypeProcessor.ConvertType(convertedType) + ") )(");
                        //                    Core.Write(writer, expression.Expression);
                        //					writer.Write(")).Value");

                        writer.Write("UNBOX!(" + TypeProcessor.ConvertType(convertedType) + ")(");
                        Core.Write(writer, expression.Expression);
                        writer.Write(")");
                    }
                    else if (type.IsValueType && convertedType.IsValueType)
                    {
                        if (convertedType.TypeKind == TypeKind.Pointer)
                        {
                            //cannot use ascast here, its for boxed types and objects
                            writer.Write("cast(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")(");
                            Core.Write(writer, expression.Expression);
                            writer.Write(")");
                        }
                        else
                        {
                            //cannot use ascast here, its for boxed types and objects
                            writer.Write("Cast!(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")(");
                            Core.Write(writer, expression.Expression);
                            writer.Write(")");
                        }
                    }
                    else
                    {
                        writer.Write("Cast!(");
                        writer.Write(destTypeDlang);
                        writer.Write(")(");
                        Core.Write(writer, expression.Expression);
                        writer.Write(")");
                    }
                }
            }
        }
        private static void ProcessArgument(OutputWriter writer, ArgumentSyntax variable, bool isOverloaded = false)
        {
            if (variable != null)
            {
                if (variable.NameColon != null)
                {
                }

                if (CSharpExtensions.CSharpKind(variable) == SyntaxKind.CollectionInitializerExpression)
                {
                    return;
                }
                var value                  = variable;
                var initializerType        = TypeProcessor.GetTypeInfo(value.Expression);
                var memberaccessexpression = value.Expression as MemberAccessExpressionSyntax;
                var nameexpression         = value.Expression as NameSyntax;
                var nullAssignment         = value.ToFullString().Trim() == "null";
                var shouldBox              = initializerType.Type != null && (initializerType.Type != initializerType.ConvertedType) && ((initializerType.Type.IsValueType || initializerType.Type.TypeKind == TypeKind.TypeParameter) &&
                                                                                                                                         (!initializerType.ConvertedType.IsValueType));
                var shouldCast  = initializerType.Type != null && (initializerType.Type.TypeKind == TypeKind.Interface && initializerType.ConvertedType.SpecialType == SpecialType.System_Object);
                var shouldUnBox = initializerType.Type != null && (initializerType.Type != initializerType.ConvertedType) && !initializerType.Type.IsValueType &&
                                  initializerType.ConvertedType.IsValueType;
                var isname             = value.Expression is NameSyntax;
                var ismemberexpression = value.Expression is MemberAccessExpressionSyntax ||
                                         (isname &&
                                          TypeProcessor.GetSymbolInfo(value.Expression as NameSyntax).Symbol.Kind ==
                                          SymbolKind.Method);
                var isdelegateassignment = ismemberexpression &&
                                           initializerType.ConvertedType != null && initializerType.ConvertedType.TypeKind == TypeKind.Delegate;
                var isstaticdelegate = isdelegateassignment &&
                                       ((memberaccessexpression != null &&
                                         TypeProcessor.GetSymbolInfo(memberaccessexpression).Symbol.IsStatic) ||
                                        (isname && TypeProcessor.GetSymbolInfo(nameexpression).Symbol.IsStatic));


                if (isOverloaded)
                {
                    writer.Write("cast(const({0}))", TypeProcessor.ConvertType(initializerType.Type));
                }

                if (shouldCast)
                {
                    writer.Write("cast(NObject)");
                    writer.Write("(");
                    Core.Write(writer, value.Expression);
                    writer.Write(")");
                    return;
                }

                if (nullAssignment)
                {
                    writer.Write("null");
                    return;
                }

                if (shouldBox)
                {
                    bool useType = true;

                    //We should start with exact converters and then move to more generic convertors i.e. base class or integers which are implicitly convertible
                    var correctConverter = initializerType.Type.GetImplicitCoversionOp(initializerType.ConvertedType,
                                                                                       initializerType.Type, true);
                    //                            initializerType.Type.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);

                    if (correctConverter == null)
                    {
                        useType          = false;
                        correctConverter =
                            initializerType.ConvertedType.GetImplicitCoversionOp(initializerType.ConvertedType,
                                                                                 initializerType.Type, true);
                        //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
                    }

                    if (correctConverter != null)
                    {
                        if (useType)
                        {
                            writer.Write(TypeProcessor.ConvertType(initializerType.Type) + "." + "op_Implicit_" +
                                         TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_"));
                        }
                        else
                        {
                            writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) + "." + "op_Implicit_" +
                                         TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_"));
                        }
                        writer.Write("(");
                        Core.Write(writer, value.Expression);
                        writer.Write(")");
                        return;
                    }
                }
                else if (shouldUnBox)
                {
                    bool useType = true;

                    //We should start with exact converters and then move to more generic convertors i.e. base class or integers which are implicitly convertible
                    var correctConverter = initializerType.Type.GetImplicitCoversionOp(initializerType.Type,
                                                                                       initializerType.ConvertedType, true);
                    //                            initializerType.Type.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);

                    if (correctConverter == null)
                    {
                        useType          = false;
                        correctConverter =
                            initializerType.ConvertedType.GetImplicitCoversionOp(initializerType.Type,
                                                                                 initializerType.ConvertedType, true);
                        //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
                    }

                    if (correctConverter != null)
                    {
                        if (useType)
                        {
                            writer.Write(TypeProcessor.ConvertType(initializerType.Type) + "." + "op_Implicit_" +
                                         TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_"));
                        }
                        else
                        {
                            writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) + "." + "op_Implicit_" +
                                         TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_"));
                        }
                        writer.Write("(");
                        Core.Write(writer, value.Expression);
                        writer.Write(")");
                        return;
                    }
                }



                if (shouldBox)
                {
                    //Box
                    writer.Write("BOX!(" + TypeProcessor.ConvertType(initializerType.Type) + ")(");
                    //When passing an argument by ref or out, leave off the .Value suffix
                    Core.Write(writer, value.Expression);
                    writer.Write(")");
                    return;
                }
                if (shouldUnBox)
                {
                    //UnBox
                    writer.Write("Cast!(" + TypeProcessor.ConvertType(initializerType.Type) + ")(");
                    Core.Write(writer, value.Expression);
                    writer.Write(")");
                }
                if (isdelegateassignment)
                {
                    var typeString = TypeProcessor.ConvertType(initializerType.ConvertedType);

                    var createNew = !(value.Expression is ObjectCreationExpressionSyntax);

                    if (createNew)
                    {
                        if (initializerType.ConvertedType.TypeKind == TypeKind.TypeParameter)
                        {
                            writer.Write(" __TypeNew!(" + typeString + ")(");
                        }
                        else
                        {
                            writer.Write("new " + typeString + "(");
                        }
                    }

                    var isStatic = isstaticdelegate;
                    //                    if (isStatic)
                    //                        writer.Write("__ToDelegate(");
                    MemberUtilities.WriteMethodPointer(writer, value.Expression);
                    //                    if (isStatic)
                    //                        writer.Write(")");

                    if (createNew)
                    {
                        writer.Write(")");
                    }
                    return;
                }
                if (initializerType.Type == null && initializerType.ConvertedType == null)
                {
                    writer.Write("null");
                    return;
                }
                Core.Write(writer, value.Expression);
            }
        }
        public static void Go(OutputWriter writer, InvocationExpressionSyntax invocationExpression)
        {
            var symbolInfo       = TypeProcessor.GetSymbolInfo(invocationExpression);
            var expressionSymbol = TypeProcessor.GetSymbolInfo(invocationExpression.Expression);

            var symbol = symbolInfo.Symbol ?? symbolInfo.CandidateSymbols.FirstOrDefault(); // Resolution error

            if (symbol == null)
            {
                writer.WriteLine("/*" + invocationExpression.ToFullString() + "  //SharpNative Failed To Get Symbol */");
            }
            var methodSymbol = symbol.OriginalDefinition.As <IMethodSymbol>().UnReduce();

            var memberReferenceExpressionOpt = invocationExpression.Expression as MemberAccessExpressionSyntax;
            var firstParameter = true;

            var extensionNamespace = methodSymbol.IsExtensionMethod
                ? methodSymbol.ContainingNamespace.FullNameWithDot() + methodSymbol.ContainingType.FullName()
                : null; //null means it's not an extension method, non-null means it is
            string           methodName;
            string           typeParameters = null;
            ExpressionSyntax subExpressionOpt;

            if (expressionSymbol.Symbol is IEventSymbol)
            {
                methodName = "Invoke";
            }
            else if (methodSymbol.MethodKind == MethodKind.DelegateInvoke)
            {
                methodName = null;
            }
            else
            {
                methodName = OverloadResolver.MethodName(methodSymbol);
            }

            if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface ||
                Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol),
                       methodSymbol))
            {
                /*    methodName =
                 *  Regex.Replace(TypeProcessor.ConvertType(methodSymbol.ContainingType.OriginalDefinition)
                 *          .RemoveFromStartOfString(methodSymbol.ContainingNamespace + ".Namespace.") + "_" +
                 *      methodName,
                 *      @" ?!\(.*?\)", string.Empty);*/
                if (methodSymbol.ContainingType.ContainingType != null)
                {
                    methodName = methodName.RemoveFromStartOfString(methodSymbol.ContainingType.ContainingType.Name + ".");
                }
            }

            var interfaceMethods =
                methodSymbol.ContainingType.AllInterfaces.SelectMany(
                    u =>
                    u.GetMembers(methodName)).ToArray();

            ISymbol interfaceMethod =
                interfaceMethods.FirstOrDefault(
                    o => methodSymbol.ContainingType.FindImplementationForInterfaceMember(o) == methodSymbol);

            //                    if (interfaceMethod == null)
            //                    {
            //                        //TODO: fix this for virtual method test 7, seems roslyn cannot deal with virtual
            //                        // overrides of interface methods ... so i'll provide a kludge
            //                        if (!method.Modifiers.Any(SyntaxKind.NewKeyword))
            //                            interfaceMethod = interfaceMethods.FirstOrDefault(k => CompareMethods(k as IMethodSymbol, methodSymbol));
            //                    }

            if (interfaceMethod != null)
            // && CompareMethods(interfaceMethod ,methodSymbol)) {
            {
                //This is an interface method //TO
                if (methodSymbol.ContainingType.SpecialType == SpecialType.System_Array)
                {
                    writer.Write("");
                }
                else
                {
                    /* var typenameI =
                     *  Regex.Replace(
                     *      TypeProcessor.ConvertType(interfaceMethod.ContainingType.ConstructedFrom, true),
                     *      @" ?!\(.*?\)", string.Empty);
                     *  //TODO: we should be able to get the original interface name, or just remove all generics from this
                     * if (typenameI.Contains('.'))
                     *  typenameI = typenameI.SubstringAfterLast('.');
                     * writer.Write(typenameI + "_");*/
                }
            }

            var containingType = interfaceMethod == null ? methodSymbol.ContainingType : interfaceMethod.ContainingType;

            bool isVirtualGeneric = methodSymbol.IsGenericMethod &&
                                    (methodSymbol.IsVirtual ||
                                     methodSymbol.ContainingType.TypeKind == TypeKind.Interface) &&
                                    !containingType.IsAssignableFrom(Context.Instance.Type);   // !(invocationExpression.Expression is BaseExpressionSyntax);



            if (isVirtualGeneric)
            {
                methodName = TypeProcessor.ConvertType(containingType, false, false, false).Replace(".", "_") + "_" + methodName;
            }

            if (methodSymbol.MethodKind == MethodKind.DelegateInvoke)
            {
                subExpressionOpt = invocationExpression.Expression;
            }
            else if (memberReferenceExpressionOpt != null)
            {
                if (memberReferenceExpressionOpt.Expression is PredefinedTypeSyntax)
                {
                    subExpressionOpt = null;
                }
                else
                {
                    subExpressionOpt = memberReferenceExpressionOpt.Expression;
                }
            }
            else
            {
                subExpressionOpt = null;
            }

            //When the code specifically names generic arguments, include them in the method name ... dmd needs help with inference, so we give it the types anyway
            if (methodSymbol.IsGenericMethod)
            {
                //return TryConvertType(named) + (named.TypeKind == TypeKind.Struct && o.ConstraintTypes.Any(k => k.TypeKind == //TypeKind.Interface) ? ".__Boxed_" : "");

                var named = ((IMethodSymbol)symbol);
                typeParameters = "!(" +
                                 named.TypeArguments.Select(o => TypeProcessor.GetGenericParameterType(named.TypeParameters[named.TypeArguments.IndexOf(o)], o)).Aggregate((a, b) => a + ", " + b)
                                 + ")";

//                typeParameters = "!( " +
//                                 string.Join(", ",
//                                     ((IMethodSymbol) symbol).TypeArguments.Select(r => TypeProcessor.ConvertType(r)  )) +
//                                 " )";
            }

            //Determine if it's an extension method called in a non-extension way.  In this case, just pretend it's not an extension method
            if (extensionNamespace != null && subExpressionOpt != null &&
                TypeProcessor.GetTypeInfo(subExpressionOpt).ConvertedType.ToString() ==
                methodSymbol.ContainingNamespace.FullName() + "." + methodSymbol.ContainingType.FullName())
            {
                extensionNamespace = null;
            }

            var memberType = memberReferenceExpressionOpt == null
                ? null
                : TypeProcessor.GetTypeInfo(memberReferenceExpressionOpt.Expression).Type;
            var isNullableEnum = memberType != null &&
                                 (memberType.Name == "Nullable" && memberType.ContainingNamespace.FullName() == "System") &&
                                 memberType.As <INamedTypeSymbol>().TypeArguments.Single().TypeKind == TypeKind.Enum;
            //          if (isNullableEnum && methodSymbol.Name == "ToString")
            //          {
            //              extensionNamespace = null; //override Translations.xml for nullable enums. We want them to convert to the enum's ToString method
            //              methodName = "toString";
            //          }

            //Invocation on basics should come from boxing the basic then calling on the boxed type, unless static
            var directInvocationOnBasics = methodSymbol.ContainingType.IsBasicType() && methodSymbol.IsStatic;
            //&& methodSymbol.ContainingType!=Context.Instance.Type; //If we are currently working on a basic type e.g. in corlib, don't alter the code

            //Extension methods in Dlang are straightforward, although this could lead to clashes without qualification

            string instanceName = null;

            if (extensionNamespace != null || directInvocationOnBasics)
            {
                if (extensionNamespace == null)
                {
                    extensionNamespace = TypeProcessor.ConvertType(methodSymbol.ContainingType, true, false);
                    // methodSymbol.ContainingNamespace.FullName() + "." + methodSymbol.ContainingType.Name;
                    //memberType.ContainingNamespace.FullName() +"."+ memberType.Name;
                }

                if (!isVirtualGeneric)
                {
                    writer.Write(extensionNamespace);

                    if (methodName != null)
                    {
                        methodName = WriteIdentifierName.TransformIdentifier(methodName);
                        //                    if (symbolInfo.Symbol.ContainingType != Context.Instance.Type)
                        writer.Write(".");
                        writer.Write(methodName);
                    }
                }
                else
                {
                    writer.Write(methodName);
                }

                WriteTypeParameters(writer, typeParameters, invocationExpression);

                writer.Write("(");

                if (subExpressionOpt != null)
                {
                    firstParameter = false;
                    Core.Write(writer, subExpressionOpt);
                }
            }
            else
            {
                if (memberReferenceExpressionOpt != null)
                {
                }

                if (subExpressionOpt != null)
                {
                    if (!isVirtualGeneric)
                    {
                        WriteMemberAccessExpression.WriteMember(writer, subExpressionOpt);

                        //                    if (!(subExpressionOpt is BaseExpressionSyntax))
                        //                    {
                        //                        if (methodName != null && methodSymbol.IsStatic)
                        //                            writer.Write(".");
                        //                        else
                        //                      {
                        if (methodSymbol.MethodKind != MethodKind.DelegateInvoke)
                        {
                            writer.Write(".");
                        }
                    }
                    else
                    {
                        instanceName = WriteMemberAccessExpression.WriteMemberToString(subExpressionOpt);
                    }
                    //                        }
                    //                    }
                    //                  writer.Write(".");
                }
                else if (methodSymbol.IsStatic && extensionNamespace == null)
                {
                    if (methodSymbol.ContainingType != Context.Instance.Type)
                    {
                        var str = TypeProcessor.ConvertType(methodSymbol.ContainingType);
                        if (str == "Array_T")
                        {
                            // Array is the only special case, otherwise generics have to be specialized to access static members
                            str = "Array";
                        }

                        writer.Write(str);
                        //                    writer.Write(methodSymbol.ContainingNamespace.FullNameWithDot());
                        //                    writer.Write(WriteType.TypeName(methodSymbol.ContainingType));
                        writer.Write(".");
                    }
                }

                if (methodSymbol.MethodKind != MethodKind.DelegateInvoke)
                {
                    var declaringSyntaxReferences =
                        methodSymbol.DeclaringSyntaxReferences.Select(j => j.GetSyntax())
                        .OfType <MethodDeclarationSyntax>();
                    var methodDeclarationSyntaxs = declaringSyntaxReferences as MethodDeclarationSyntax[] ?? declaringSyntaxReferences.ToArray();
                    var any = methodDeclarationSyntaxs.Any();
                    if (any &&
                        methodDeclarationSyntaxs.FirstOrDefault()
                        .As <MethodDeclarationSyntax>()
                        .Modifiers.Any(SyntaxKind.NewKeyword))
                    {
                        //TODO: this means that new is not supported on external libraries
                        //                  //why doesnt roslyn give me this information ?
                        //methodName += "_"; //Not needed anymore :)
                    }

                    if (any &&
                        methodDeclarationSyntaxs.FirstOrDefault()
                        .As <MethodDeclarationSyntax>()
                        .Modifiers.Any(SyntaxKind.NewKeyword))
                    {
//                        if (symbolInfo.Symbol.ContainingType != Context.Instance.Type)
                        writer.Write(WriteIdentifierName.TransformIdentifier(methodSymbol.ContainingType.Name, methodSymbol.ContainingType) + ".");
                    }



                    methodName = WriteIdentifierName.TransformIdentifier(methodName);

                    writer.Write(methodName);
                }
                WriteTypeParameters(writer, typeParameters, invocationExpression);
                writer.Write("(");
            }

            bool inParams         = false;
            bool foundParamsArray = false;

            var arguments = invocationExpression.ArgumentList.Arguments;

            ITypeSymbol typeSymbol = null;

            bool isOverloaded = methodSymbol.ContainingType.GetMembers(methodSymbol.Name).OfType <IMethodSymbol>().Any(j => j.TypeParameters == methodSymbol.TypeParameters && ParameterMatchesWithRefOutIn(methodSymbol, j));

            WriteArguments(writer, invocationExpression, arguments, firstParameter, inParams, methodSymbol, foundParamsArray, typeSymbol, isOverloaded, symbol, instanceName);
        }
        public static void Go(OutputWriter writer, InvocationExpressionSyntax invocationExpression)
        {
            var symbolInfo       = TypeProcessor.GetSymbolInfo(invocationExpression);
            var expressionSymbol = TypeProcessor.GetSymbolInfo(invocationExpression.Expression);

            var symbol = symbolInfo.Symbol ?? symbolInfo.CandidateSymbols.FirstOrDefault(); // Resolution error

            var methodSymbol = symbol.OriginalDefinition.As <IMethodSymbol>().UnReduce();

            var memberReferenceExpressionOpt = invocationExpression.Expression as MemberAccessExpressionSyntax;
            var firstParameter = true;

            var extensionNamespace = methodSymbol.IsExtensionMethod
                ? methodSymbol.ContainingNamespace.FullNameWithDot() + methodSymbol.ContainingType.FullName()
                : null; //null means it's not an extension method, non-null means it is
            string           methodName;
            string           typeParameters = null;
            ExpressionSyntax subExpressionOpt;

            if (methodSymbol.ContainingType.FullName() == "Enum")
            {
                if (methodSymbol.Name == "Parse")
                {
                    WriteEnumParse(writer, invocationExpression);
                    return;
                }

                if (methodSymbol.Name == "GetValues")
                {
                    WriteEnumGetValues(writer, invocationExpression);
                    return;
                }
            }

            if (expressionSymbol.Symbol is IEventSymbol)
            {
                methodName = "Invoke";
                //Would need to append the number of arguments to this to support events.  However, events are not currently supported
            }
            //            else if (memberReferenceExpressionOpt != null && memberReferenceExpressionOpt.Expression is PredefinedTypeSyntax)
            //            {
            //                switch (methodSymbol.Name)
            //                {
            //                    case "Parse":
            //                        Core.Write(writer, invocationExpression.ArgumentList.Arguments.Single().Expression);
            //
            //                        writer.Write(".to");
            //                        writer.Write(TypeProcessor.ConvertType(methodSymbol.ReturnType));
            //
            //                        return;
            //                    case "TryParse":
            //                        methodName = "TryParse" + TypeProcessor.ConvertType(methodSymbol.Parameters[1].Type);
            //                        extensionNamespace = "SharpNative";
            //                        break;
            //                    default:
            //                        methodName = methodSymbol.Name;
            //                        extensionNamespace = "SharpNative";
            //                        break;
            //                }
            //            }

            else if (methodSymbol.MethodKind == MethodKind.DelegateInvoke)
            {
                methodName = null;
            }
            else
            {
                methodName = OverloadResolver.MethodName(methodSymbol);
            }

            if (methodSymbol.MethodKind == MethodKind.DelegateInvoke)
            {
                subExpressionOpt = invocationExpression.Expression;
            }
            else if (memberReferenceExpressionOpt != null)
            {
                if (memberReferenceExpressionOpt.Expression is PredefinedTypeSyntax)
                {
                    subExpressionOpt = null;
                }
                else
                {
                    subExpressionOpt = memberReferenceExpressionOpt.Expression;
                }
            }
            else
            {
                subExpressionOpt = null;
            }

            //When the code specifically names generic arguments, include them in the method name ... dlang needs help with inference, so we give it the types anyway
            if (methodSymbol.IsGenericMethod)
            {
                //				var genNameExpression = invocationExpression.Expression as GenericNameSyntax;
                //				if (genNameExpression == null && memberReferenceExpressionOpt != null)
                //					genNameExpression = memberReferenceExpressionOpt.Name as GenericNameSyntax;
                //				if (genNameExpression != null && genNameExpression.TypeArgumentList.Arguments.Count > 0)
                typeParameters = "!( " +
                                 string.Join(", ",
                                             (symbol as IMethodSymbol).TypeArguments.Select(r => TypeProcessor.ConvertType(r))) +
                                 " )";
            }

            //Determine if it's an extension method called in a non-extension way.  In this case, just pretend it's not an extension method
            if (extensionNamespace != null && subExpressionOpt != null &&
                TypeProcessor.GetTypeInfo(subExpressionOpt).ConvertedType.ToString() ==
                methodSymbol.ContainingNamespace + "." + methodSymbol.ContainingType.FullName())
            {
                extensionNamespace = null;
            }

            var memberType = memberReferenceExpressionOpt == null
                ? null
                : TypeProcessor.GetTypeInfo(memberReferenceExpressionOpt.Expression).Type;
            var isNullableEnum = memberType != null &&
                                 (memberType.Name == "Nullable" && memberType.ContainingNamespace.FullName() == "System") &&
                                 memberType.As <INamedTypeSymbol>().TypeArguments.Single().TypeKind == TypeKind.Enum;
            //			if (isNullableEnum && methodSymbol.Name == "ToString")
            //			{
            //				extensionNamespace = null; //override Translations.xml for nullable enums. We want them to convert to the enum's ToString method
            //				methodName = "toString";
            //			}

            var directInvocationOnBasics = methodSymbol.ContainingType.IsBasicType();

            //Extension methods in Dlang are straightforward, although this could lead to clashes without qualification

            if (extensionNamespace != null || directInvocationOnBasics)
            {
                if (extensionNamespace == null)
                {
                    extensionNamespace = memberType.ContainingNamespace.FullName() + "." + memberType.Name;
                    //memberType.ContainingNamespace.FullName() +"."+ memberType.Name;
                }

                writer.Write(extensionNamespace);

                if (methodName != null)
                {
                    writer.Write(".");
                    writer.Write(methodName);
                }

                WriteTypeParameters(writer, typeParameters, invocationExpression);

                writer.Write("(");

                if (subExpressionOpt != null)
                {
                    firstParameter = false;
                    Core.Write(writer, subExpressionOpt);
                }
            }
            else
            {
                if (memberReferenceExpressionOpt != null)
                {
                    //Check against lowercase toString since it gets replaced with the lowered version before we get here
                    if (methodName == "toString")
                    {
                        if (memberType.TypeKind == TypeKind.Enum || isNullableEnum)
                        {
                            var enumType = memberType.TypeKind == TypeKind.Enum
                                ? memberType
                                : memberType.As <INamedTypeSymbol>().TypeArguments.Single();

                            //calling ToString() on an enum forwards to our enum's special ToString method
                            writer.Write(enumType.ContainingNamespace.FullNameWithDot());
                            writer.Write(WriteType.TypeName((INamedTypeSymbol)enumType));
                            writer.Write(".ToString(");
                            Core.Write(writer, memberReferenceExpressionOpt.Expression);
                            writer.Write(")");

                            if (invocationExpression.ArgumentList.Arguments.Count > 0)
                            {
                                throw new Exception(
                                          "Enum's ToString detected with parameters.  These are not supported " +
                                          Utility.Descriptor(invocationExpression));
                            }

                            return;
                        }

                        if (memberType.SpecialType == SpecialType.System_Byte)
                        {
                            //Calling ToString on a byte needs to take special care since it's signed in the JVM
                            writer.Write("System.SharpNative.ByteToString(");
                            Core.Write(writer, memberReferenceExpressionOpt.Expression);
                            writer.Write(")");

                            if (invocationExpression.ArgumentList.Arguments.Count > 0)
                            {
                                throw new Exception(
                                          "Byte's ToString detected with parameters.  These are not supported " +
                                          Utility.Descriptor(invocationExpression));
                            }

                            return;
                        }
                    }
                }

                if (subExpressionOpt != null)
                {
                    WriteMemberAccessExpression.WriteMember(writer, subExpressionOpt);

                    //                    if (!(subExpressionOpt is BaseExpressionSyntax))
                    //                    {
                    //                        if (methodName != null && methodSymbol.IsStatic)
                    //                            writer.Write(".");
                    //                        else
                    //						{
                    if (methodSymbol.MethodKind != MethodKind.DelegateInvoke)
                    {
                        writer.Write(".");
                    }
                    //                        }
                    //                    }
                    //					writer.Write(".");
                }
                else if (methodSymbol.IsStatic && extensionNamespace == null)
                {
                    var str = TypeProcessor.ConvertType(methodSymbol.ContainingType);
                    if (str == "Array_T")
                    {
                        // Array is the only special case, otherwise generics have to be specialized to access static members
                        str = "Array";
                    }

                    writer.Write(str);
                    //                    writer.Write(methodSymbol.ContainingNamespace.FullNameWithDot());
                    //                    writer.Write(WriteType.TypeName(methodSymbol.ContainingType));
                    writer.Write(".");
                }

                if (methodSymbol.MethodKind != MethodKind.DelegateInvoke)
                {
                    var declaringSyntaxReferences =
                        methodSymbol.DeclaringSyntaxReferences.Select(j => j.GetSyntax())
                        .OfType <MethodDeclarationSyntax>();
                    var any = declaringSyntaxReferences.Any();
                    if (any &&
                        declaringSyntaxReferences.FirstOrDefault()
                        .As <MethodDeclarationSyntax>()
                        .Modifiers.Any(SyntaxKind.NewKeyword))
                    {
                        //TODO: this means that new is not supported on external libraries
                        //					//why doesnt roslyn give me this information ?
                        methodName += "_";
                    }

                    if (any &&
                        declaringSyntaxReferences.FirstOrDefault()
                        .As <MethodDeclarationSyntax>()
                        .Modifiers.Any(SyntaxKind.NewKeyword))
                    {
                        writer.Write(TypeProcessor.ConvertType(methodSymbol.ContainingType) + ".");
                    }

                    //TODO: fix this for abstract too or whatever other combination
                    //TODO: create a better fix fot this
                    //					ISymbol interfaceMethod =
                    //						methodSymbol.ContainingType.AllInterfaces.SelectMany (
                    //							u =>
                    //						u.GetMembers (methodName)
                    //						.Where (
                    //								o =>
                    //							methodSymbol.ContainingType.FindImplementationForInterfaceMember (o) ==
                    //								methodSymbol)).FirstOrDefault ();

                    /*      if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface ||
                     * Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol), methodSymbol))
                     *
                     *        if ((interfaceMethod != null /*&& interfaceMethod == methodSymbol || methodSymbol.ContainingType.TypeKind == TypeKind.Interface)
                     *    {
                     *        //This is an interface method //TO
                     *
                     *        var typenameM = Regex.Replace (TypeProcessor.ConvertType (methodSymbol.ContainingType), @" ?!\(.*?\)", string.Empty);
                     *        if (typenameM.Contains ('.'))
                     *            typenameM = typenameM.SubstringAfterLast ('.');
                     *        if (methodSymbol.ContainingType.SpecialType == SpecialType.System_Array)
                     *            writer.Write ("");
                     *        else if (interfaceMethod != null)
                     *        {
                     *            var typenameI = Regex.Replace (TypeProcessor.ConvertType (interfaceMethod.ContainingType), @" ?!\(.*?\)", string.Empty);
                     *            if (typenameI.Contains ('.'))
                     *                typenameI = typenameI.SubstringAfterLast ('.');
                     *            writer.Write (typenameI + "_");
                     *        }
                     *        else // this is the interface itself
                     *                writer.Write (typenameM + "_");
                     *
                     *    }*/

                    if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface ||
                        Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol),
                               methodSymbol))
                    {
                        methodName =
                            Regex.Replace(
                                TypeProcessor.ConvertType(methodSymbol.ContainingType.OriginalDefinition)
                                .RemoveFromStartOfString(methodSymbol.ContainingNamespace + ".Namespace.") + "_" +
                                methodName,
                                @" ?!\(.*?\)", string.Empty);
                    }

                    var interfaceMethods =
                        methodSymbol.ContainingType.AllInterfaces.SelectMany(
                            u =>
                            u.GetMembers(methodName)).ToArray();

                    ISymbol interfaceMethod =
                        interfaceMethods.FirstOrDefault(
                            o => methodSymbol.ContainingType.FindImplementationForInterfaceMember(o) == methodSymbol);

                    //                    if (interfaceMethod == null)
                    //                    {
                    //                        //TODO: fix this for virtual method test 7, seems roslyn cannot deal with virtual
                    //                        // overrides of interface methods ... so i'll provide a kludge
                    //                        if (!method.Modifiers.Any(SyntaxKind.NewKeyword))
                    //                            interfaceMethod = interfaceMethods.FirstOrDefault(k => CompareMethods(k as IMethodSymbol, methodSymbol));
                    //                    }

                    if (interfaceMethod != null)
                    // && CompareMethods(interfaceMethod ,methodSymbol)) {
                    {
//This is an interface method //TO
                        if (methodSymbol.ContainingType.SpecialType == SpecialType.System_Array)
                        {
                            writer.Write("");
                        }
                        else
                        {
                            var typenameI =
                                Regex.Replace(
                                    TypeProcessor.ConvertType(interfaceMethod.ContainingType.ConstructedFrom, true),
                                    @" ?!\(.*?\)", string.Empty);
                            //TODO: we should be able to get the original interface name, or just remove all generics from this
                            if (typenameI.Contains('.'))
                            {
                                typenameI = typenameI.SubstringAfterLast('.');
                            }
                            writer.Write(typenameI + "_");
                        }
                    }

                    //					var acc = methodSymbol.DeclaredAccessibility;

                    //					if (methodSymbol.MethodKind == MethodKind.ExplicitInterfaceImplementation)
                    //					{
                    //						var implementations = methodSymbol.ExplicitInterfaceImplementations[0];
                    //						if (implementations != null)
                    //						{
                    //							//  explicitHeaderNAme = implementations.Name;
                    //							methodName = TypeProcessor.ConvertType(implementations.ReceiverType) + "_" +implementations.Name; //Explicit fix ?
                    //
                    //							//			writer.Write(methodSymbol.ContainingType + "." + methodName);
                    //							//Looks like internal classes are not handled properly here ...
                    //						}
                    //					}

                    writer.Write(methodName);
                }
                WriteTypeParameters(writer, typeParameters, invocationExpression);
                writer.Write("(");
            }

            bool inParams         = false;
            bool foundParamsArray = false;

            var arguments = invocationExpression.ArgumentList.Arguments;

            foreach (var arg in arguments.Select(o => new TransformedArgument(o)))
            {
                if (firstParameter)
                {
                    firstParameter = false;
                }
                else
                {
                    writer.Write(", ");
                }

                var argumentType = TypeProcessor.GetTypeInfo(arg.ArgumentOpt.Expression);

                //				if (!inParams && IsParamsArgument (invocationExpression, arg.ArgumentOpt, methodSymbol))
                //				{
                //					foundParamsArray = true;
                //
                //					if (!TypeProcessor.ConvertType (TypeProcessor.GetTypeInfo (arg.ArgumentOpt.Expression).Type).StartsWith ("System.Array<"))
                //					{
                //						inParams = true;
                //						writer.Write ("Array_T!(");
                //					}
                //				}

                //Not needed for dlang
                //                if (arg != null
                //                    && arg.ArgumentOpt.RefOrOutKeyword.RawKind != (decimal) SyntaxKind.None
                //                    && TypeProcessor.GetSymbolInfo(arg.ArgumentOpt.Expression).Symbol is IFieldSymbol)
                //                {
                //
                //                }
                //                    throw new Exception("ref/out cannot reference fields, only local variables.  Consider using ref/out on a local variable and then assigning it into the field. " + Utility.Descriptor(invocationExpression));

                //				if (argumentType.Type == null) {
                //					if (argumentType.ConvertedType == null)
                //						writer.Write ("null");
                //					else
                //						writer.Write ("(cast("+TypeProcessor.ConvertType(argumentType.ConvertedType)+") null)");
                //				}
                //
                //                else if (argumentType.Type.IsValueType && !argumentType.ConvertedType.IsValueType)
                //                {
                //                    //Box
                //					writer.Write("BOX!("+TypeProcessor.ConvertType(argumentType.Type) +")(");
                //                    //When passing an argument by ref or out, leave off the .Value suffix
                //                    if (arg != null && arg.ArgumentOpt.RefOrOutKeyword.RawKind != (decimal)SyntaxKind.None)
                //                        WriteIdentifierName.Go(writer, arg.ArgumentOpt.Expression.As<IdentifierNameSyntax>(), true);
                //                    else
                //                        arg.Write(writer);
                //
                //                    writer.Write(")");
                //                }
                //                else if (!argumentType.Type.IsValueType && argumentType.ConvertedType.IsValueType)
                //                {
                //                    //UnBox
                //					writer.Write("cast(" + TypeProcessor.ConvertType(argumentType.Type) + ")(");
                //                    if (arg != null && arg.ArgumentOpt.RefOrOutKeyword.RawKind != (decimal)SyntaxKind.None)
                //                        WriteIdentifierName.Go(writer, arg.ArgumentOpt.Expression.As<IdentifierNameSyntax>(), true);
                //                    else
                //                        arg.Write(writer);
                //                    writer.Write(")");
                //                }
                //                else
                //                {
                //                    if (arg != null && arg.ArgumentOpt.RefOrOutKeyword.RawKind != (decimal)SyntaxKind.None)
                //                        WriteIdentifierName.Go(writer, arg.ArgumentOpt.Expression.As<IdentifierNameSyntax>(), true);
                //                    else
                //                        arg.Write(writer);
                //                }

                ProcessArgument(writer, arg.ArgumentOpt);
            }

            //			if (inParams)
            //				writer.Write (")");
            //			 if (!foundParamsArray && methodSymbol.Parameters.Any () && methodSymbol.Parameters.Last ().IsParams)
            //				writer.Write (", null"); //params method called without any params argument.  Send null.

            writer.Write(")");
        }
示例#14
0
        public static void Go(OutputWriter writer, MemberAccessExpressionSyntax expression)
        {
            var memberName = expression.Name.Identifier.ValueText;
            var type       = TypeProcessor.GetTypeInfo(expression.Expression).ConvertedType;
            var typeStr    = TypeProcessor.GenericTypeName(type);

            var isLiteral = expression.Expression is LiteralExpressionSyntax;

            var isStringLiteral = false;

            if (isLiteral)
            {
                var literal = expression.Expression as LiteralExpressionSyntax;

                if (literal.RawKind == (decimal)SyntaxKind.StringLiteralExpression)
                {
                    isStringLiteral = true;
                    // writer.Write("((System.String)"); Not needed for strings at all
                }
            }

            memberName = WriteIdentifierName.TransformIdentifier(memberName);

            var typeInfo   = TypeProcessor.GetTypeInfo(expression.Expression);
            var symbolInfo = TypeProcessor.GetSymbolInfo(expression);

            if (symbolInfo.Symbol == null)
            {
                symbolInfo = TypeProcessor.GetSymbolInfo(expression.Expression);
            }
            if (type != null && symbolInfo.Symbol != null)
            //if type is null, then we're just a namespace.  We can ignore these.
            {
                var directInvocationOnBasics = symbolInfo.Symbol.ContainingType.IsBasicType();

                if (directInvocationOnBasics)
                {
//						var extensionNamespace =  symbolInfo.Symbol.ContainingNamespace.FullNameWithDot() + symbolInfo.Symbol.ContainingType.FullName(); //null means it's not an extension method, non-null means it is

                    //Extension methods in Dlang are straightforward, although this could lead to clashes without qualification

                    var extensionNamespace = type.ContainingNamespace.FullName() + "." + type.Name;
                    //memberType.ContainingNamespace.FullName() +"."+ memberType.Name;

                    writer.Write(extensionNamespace);
                }
                else
                {
                    WriteMember(writer, expression.Expression);
                }

                if (isLiteral && !isStringLiteral)
                {
                    writer.Write(")"); //Not needed for strings at all
                }
                writer.Write(".");
                // Ideally Escape analysis should take care of this, but for now all value types are on heap and ref types on stack
            }

            if (symbolInfo.Symbol != null && symbolInfo.Symbol.Kind == SymbolKind.Property)
            {
                if (symbolInfo.Symbol.ContainingType.TypeKind == TypeKind.Interface ||
                    Equals(symbolInfo.Symbol.ContainingType.FindImplementationForInterfaceMember(symbolInfo.Symbol),
                           symbolInfo.Symbol))
                {
                    memberName =
                        Regex.Replace(
                            TypeProcessor.ConvertType(symbolInfo.Symbol.ContainingType.OriginalDefinition)
                            .RemoveFromStartOfString(symbolInfo.Symbol.ContainingNamespace + ".Namespace.") +
                            "_" + memberName,
                            @" ?!\(.*?\)", string.Empty);
                }

                var interfaceMethods =
                    symbolInfo.Symbol.ContainingType.AllInterfaces.SelectMany(
                        u =>
                        u.GetMembers(memberName)).ToArray();

                ISymbol interfaceMethod =
                    interfaceMethods.FirstOrDefault(
                        o =>
                        symbolInfo.Symbol.ContainingType.FindImplementationForInterfaceMember(o) ==
                        symbolInfo.Symbol);

                if (interfaceMethod != null)

                {
//This is an interface method //TO
                    if (symbolInfo.Symbol.ContainingType.SpecialType == SpecialType.System_Array)
                    {
                        writer.Write("");
                    }
                    else
                    {
                        var typenameI =
                            Regex.Replace(
                                TypeProcessor.ConvertType(interfaceMethod.ContainingType.ConstructedFrom, true),
                                @" ?!\(.*?\)", string.Empty);
                        //TODO: we should be able to get the original interface name, or just remove all generics from this
                        if (typenameI.Contains('.'))
                        {
                            typenameI = typenameI.SubstringAfterLast('.');
                        }
                        writer.Write(typenameI + "_");
                    }
                }

                if (!symbolInfo.Symbol.ContainingType.IsAnonymousType &&
                    (symbolInfo.Symbol.DeclaringSyntaxReferences.Any() &&
                     symbolInfo.Symbol.DeclaringSyntaxReferences.FirstOrDefault()
                     .GetSyntax()
                     .As <PropertyDeclarationSyntax>()
                     .Modifiers.Any(SyntaxKind.NewKeyword)))
                {
                    //TODO: this means that new is not supported on external libraries, anonymous types cannot be extended
                    //					//why doesnt roslyn give me this information ?
                    memberName += "_";
                }
            }

            var isGet = false;

            writer.Write(memberName);

            if (expression.Name is GenericNameSyntax)
            {
                var gen = expression.Name.As <GenericNameSyntax>();

                writer.Write("!( ");

                bool first = true;
                foreach (var g in gen.TypeArgumentList.Arguments)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        writer.Write(", ");
                    }

                    writer.Write(TypeProcessor.ConvertType(g));
                }

                writer.Write(" )");
            }
        }
        public static void Go(OutputWriter writer, MemberAccessExpressionSyntax expression)
        {
            var memberName = expression.Name.Identifier.Text;
            var type       = TypeProcessor.GetTypeInfo(expression.Expression).ConvertedType;
            var typeStr    = TypeProcessor.GenericTypeName(type);

            var isLiteral = expression.Expression is LiteralExpressionSyntax;

            var isStringLiteral = false;

            if (isLiteral)
            {
                var literal = expression.Expression as LiteralExpressionSyntax;

                if (literal.RawKind == (decimal)SyntaxKind.StringLiteralExpression)
                {
                    isStringLiteral = true;
                    // writer.Write("((System.String)"); Not needed for strings at all
                }
            }

            memberName = WriteIdentifierName.TransformIdentifier(memberName);

            var typeInfo     = TypeProcessor.GetTypeInfo(expression.Expression);
            var symbolInfo   = TypeProcessor.GetSymbolInfo(expression);
            var methodSymbol = symbolInfo.Symbol;

            if (methodSymbol == null)
            {
                symbolInfo = TypeProcessor.GetSymbolInfo(expression.Expression);
            }
            if (type != null && methodSymbol != null)
            //if type is null, then we're just a namespace.  We can ignore these.
            {
                var directInvocationOnBasics = methodSymbol.ContainingType.IsBasicType() && methodSymbol.IsStatic;

                if (directInvocationOnBasics)
                {
                    //Extension methods in Dlang are straightforward, although this could lead to clashes without qualification
                    if (methodSymbol.ContainingType != Context.Instance.Type)
                    {
                        var extensionNamespace = TypeProcessor.ConvertType(type, true, false);

                        writer.Write(extensionNamespace);
                    }
                }
                else
                {
                    WriteMember(writer, expression.Expression);
                }

                if (isLiteral && !isStringLiteral)
                {
                    writer.Write(")"); //Not needed for strings at all
                }
                writer.Write(".");
                // Ideally Escape analysis should take care of this, but for now all value types are on heap and ref types on stack
            }

            if (methodSymbol != null && methodSymbol.Kind == SymbolKind.Property)
            {
                if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface ||
                    Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol),
                           methodSymbol))
                {
                    /* memberName =
                     *   Regex.Replace(
                     *       TypeProcessor.ConvertType(methodSymbol.ContainingType.OriginalDefinition)
                     *           .RemoveFromStartOfString(methodSymbol.ContainingNamespace + ".Namespace.") +
                     *       "_" + memberName,
                     *       @" ?!\(.*?\)", string.Empty);*/
                    if (methodSymbol.ContainingType.ContainingType != null)
                    {
                        memberName = memberName.RemoveFromStartOfString(methodSymbol.ContainingType.ContainingType.Name + ".");
                    }
                }

                string name             = memberName;
                var    interfaceMethods =
                    methodSymbol.ContainingType.AllInterfaces.SelectMany(
                        u =>
                        u.GetMembers(name)).ToArray();

                ISymbol interfaceMethod =
                    interfaceMethods.FirstOrDefault(
                        o =>
                        Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(o), methodSymbol));

                if (interfaceMethod != null)

                {
                    //This is an interface method //TO
                    if (methodSymbol.ContainingType.SpecialType == SpecialType.System_Array)
                    {
                        writer.Write("");
                    }
                    else
                    {
                        /* var typenameI =
                         *   Regex.Replace(
                         *       TypeProcessor.ConvertType(interfaceMethod.ContainingType.ConstructedFrom, true),
                         *       @" ?!\(.*?\)", string.Empty);
                         * //TODO: we should be able to get the original interface name, or just remove all generics from this
                         * if (typenameI.Contains('.'))
                         *   typenameI = typenameI.SubstringAfterLast('.');
                         * writer.Write(typenameI + "_");*/
                    }
                }

                /*  if (!methodSymbol.ContainingType.IsAnonymousType &&
                 *    (methodSymbol.DeclaringSyntaxReferences.Any() &&
                 *     methodSymbol.DeclaringSyntaxReferences.FirstOrDefault()
                 *         .GetSyntax()
                 *         .As<PropertyDeclarationSyntax>()
                 *         .Modifiers.Any(SyntaxKind.NewKeyword)))
                 * {
                 *    //TODO: this means that new is not supported on external libraries, anonymous types cannot be extended
                 *    //					//why doesnt roslyn give me this information ?
                 *    memberName += "_";
                 * }*/
            }

            var isGet = false;

            writer.Write(memberName);

//            if (methodSymbol is IMethodSymbol) //Lets specialize it
//            {
//                //                //Type inference for delegates
//                var mmethodSymbol = methodSymbol as IMethodSymbol;
//
//                var specialization =
//                                        (mmethodSymbol.TypeArguments.Any() ? ("!(" +
//                                        mmethodSymbol.TypeArguments.Select(k => TypeProcessor.ConvertType(k))
//                                            .Aggregate((a, b) => a + "," + b) + ")") : "");
//                writer.Write(specialization);
//            }

            /* if (expression.Name is GenericNameSyntax)
             * {
             *   var gen = expression.Name.As<GenericNameSyntax>();
             *
             *   writer.Write("!(");
             *
             *   bool first = true;
             *   foreach (var g in gen.TypeArgumentList.Arguments)
             *   {
             *       if (first)
             *           first = false;
             *       else
             *           writer.Write(", ");
             *
             *       writer.Write(TypeProcessor.ConvertType(g));
             *   }
             *
             *   writer.Write(")");
             * }*/
        }
示例#16
0
        public void Write(OutputWriter writer)
        {
            if (StringOpt != null)
            {
                writer.Write(StringOpt);
            }
            else
            {
                if (ArgumentOpt.NameColon != null)
                {
                    Core.Write(writer, ArgumentOpt.NameColon.Name);
                    writer.Write(" = ");
                }

                var symbol = TypeProcessor.GetSymbolInfo(ArgumentOpt.Expression);
                var type   = TypeProcessor.GetTypeInfo(ArgumentOpt.Expression);

                if (symbol.Symbol != null && type.ConvertedType != null && symbol.Symbol.Kind == SymbolKind.Method &&
                    type.ConvertedType.TypeKind == TypeKind.Delegate)
                {
                    var typeString = TypeProcessor.ConvertType(type.ConvertedType);

                    var createNew = !(ArgumentOpt.Parent.Parent is ObjectCreationExpressionSyntax); //Ugly hack

                    if (createNew)
                    {
                        if (type.ConvertedType.TypeKind == TypeKind.TypeParameter)
                        {
                            writer.Write(" __TypeNew!(" + typeString + ")(");
                        }
                        else
                        {
                            writer.Write("new " + typeString + "(");
                        }
                    }

                    var isStatic = symbol.Symbol.IsStatic;
                    if (isStatic)
                    {
                        writer.Write("__ToDelegate(");
                    }
                    writer.Write("&");

                    Core.Write(writer, ArgumentOpt.Expression);
                    if (isStatic)
                    {
                        writer.Write(")");
                    }

                    if (createNew)
                    {
                        writer.Write(")");
                    }
                    return;
                }

                Core.Write(writer, ArgumentOpt.Expression);

                WriteEnum.Check(ArgumentOpt.Expression);
            }
        }
示例#17
0
        private static void ProcessExpression(OutputWriter writer, SyntaxToken operatorToken, CSharpSyntaxNode rightExpression,
                                              CSharpSyntaxNode leftExpression)
        {
            TypeInfo leftExpressionType = TypeProcessor.GetTypeInfo(leftExpression ?? rightExpression);

            var rightExpressionType = TypeProcessor.GetTypeInfo(rightExpression);

            var boxLeft = leftExpressionType.Type != null && (leftExpressionType.Type != leftExpressionType.ConvertedType) &&
                          ((leftExpressionType.Type.IsValueType || leftExpressionType.Type.TypeKind == TypeKind.TypeParameter) &&
                           (leftExpressionType.ConvertedType.IsReferenceType));

            var boxRight = (rightExpressionType.ConvertedType != null &&
                            (rightExpressionType.Type != null &&
                             ((rightExpressionType.Type.IsValueType ||
                               rightExpressionType.Type.TypeKind == TypeKind.TypeParameter) &&
                              (rightExpressionType.ConvertedType.IsReferenceType))))
                           ||
                           (rightExpressionType.Type != null && rightExpressionType.Type.IsValueType &&
                            leftExpressionType.Type != null && leftExpressionType.Type.TypeKind == TypeKind.Error);
            //Fix for yield ... why does it give errortypes ?

            var unboxRight = rightExpressionType.ConvertedType != null &&
                             (rightExpressionType.Type != null && (rightExpressionType.Type.IsReferenceType &&
                                                                   (rightExpressionType.ConvertedType.IsValueType)));

            var rightnull = rightExpression != null && rightExpression.ToFullString().Trim() == "null";
            var leftnull  = leftExpression != null && leftExpression.ToFullString().Trim() == "null";

            var nullAssignment = (rightnull || leftnull);

            var val = WriteOperatorDeclaration.AllBinaryOperators.FirstOrDefault(k => k.Value == operatorToken.Text);

            //Matching Binary Operator Overload
            if (!String.IsNullOrEmpty(val.Value))
            {
                //Try Left
                IEnumerable <ISymbol> members = new List <ISymbol>();
                if (leftExpressionType.Type != null)
                {
                    members = leftExpressionType.Type.GetMembers(val.Key);
                }
                if (rightExpressionType.Type != null)
                {
                    members = members.
                              Union(rightExpressionType.Type.GetMembers(val.Key));
                }

                var leftExpressionString = Core.WriteString(leftExpression);
                if (members != null && members.Any())
                {
                    if (!(leftExpressionType.Type.IsPrimitive() && rightExpressionType.Type.IsPrimitive()))
                    {
                        var correctOverload =
                            members.OfType <IMethodSymbol>()
                            .FirstOrDefault(
                                u =>
                                u.Parameters[0].Type == leftExpressionType.Type &&
                                u.Parameters[1].Type == rightExpressionType.Type);

                        if (correctOverload != null)
                        {
                            var name =
                                WriteIdentifierName.TransformIdentifier(OverloadResolver.MethodName(correctOverload));
                            writer.Write(TypeProcessor.ConvertType(correctOverload.ContainingType) + "." + name +
                                         "(" +
                                         leftExpressionString + "," + Core.WriteString(rightExpression)
                                         + ")");
                            return;
                        }
                    }
                }
                else
                {
                    if (WriteOperatorDeclaration.AssignOpOperators.ContainsKey(val.Key))
                    {
                        var methodName =
                            WriteOperatorDeclaration.AllBinaryOperators.FirstOrDefault(
                                k => k.Value == val.Value.Substring(0, 1));
                        // emulate c# facility to use the lower op ...
                        //Try Left
                        members = null;
                        if (leftExpressionType.Type != null)
                        {
                            members = leftExpressionType.Type.GetMembers(methodName.Key);
                        }
                        if (rightExpressionType.Type != null)
                        {
                            members = members.
                                      Union(rightExpressionType.Type.GetMembers(methodName.Key));
                        }

                        if (members != null && members.Any())
                        {
                            if (!(leftExpressionType.Type.IsPrimitive() && rightExpressionType.Type.IsPrimitive()))
                            {
                                var correctOverload =
                                    members.OfType <IMethodSymbol>()
                                    .FirstOrDefault(
                                        u =>
                                        u.Parameters[0].Type == leftExpressionType.Type &&
                                        u.Parameters[1].Type == rightExpressionType.Type);

                                if (correctOverload != null)
                                {
                                    var name =
                                        WriteIdentifierName.TransformIdentifier(
                                            OverloadResolver.MethodName(correctOverload));
                                    writer.Write(leftExpressionString + " = " +
                                                 TypeProcessor.ConvertType(correctOverload.ContainingType) + "." +
                                                 name +
                                                 "(" +
                                                 leftExpressionString + "," + Core.WriteString(rightExpression)
                                                 + ")");
                                    return;
                                }
                            }
                        }
                    }
                }
            }

            //Property calls will be fixed in a preprocessor step ... i.e. just call them
            if (nullAssignment)
            {
                if (rightnull)
                {
                    switch (operatorToken.CSharpKind())
                    {
                    case SyntaxKind.EqualsEqualsToken:
                        writer.Write("");
                        break;

                    case SyntaxKind.NotEqualsExpression:
                    case SyntaxKind.ExclamationEqualsToken:
                        writer.Write("!");
                        break;

                    default:
                        writer.Write(operatorToken.ToString());
                        break;
                    }


                    writer.Write("__IsNull(");
                    Core.Write(writer, leftExpression);
                    writer.Write(")");
                    return;
                }

                if (leftnull)
                {
                    //                    writer.Write("null");
                    //
                    //                    switch (operatorToken.CSharpKind())
                    //                    {
                    //                        case SyntaxKind.EqualsEqualsToken:
                    //                            writer.Write(" is ");
                    //                            break;
                    //                        case SyntaxKind.NotEqualsExpression:
                    //                        case SyntaxKind.ExclamationEqualsToken:
                    //                            writer.Write(" !is ");
                    //                            break;
                    //                        default:
                    //                            writer.Write(operatorToken.ToString());
                    //                            break;
                    //                    }
                    //
                    //                    Core.Write(writer, rightExpression);
                    //
                    //                    return;
                    switch (operatorToken.CSharpKind())
                    {
                    case SyntaxKind.EqualsEqualsToken:
                        writer.Write("");
                        break;

                    case SyntaxKind.NotEqualsExpression:
                    case SyntaxKind.ExclamationEqualsToken:
                        writer.Write("!");
                        break;

                    default:
                        writer.Write(operatorToken.ToString());
                        break;
                    }


                    writer.Write("__IsNull(");
                    Core.Write(writer, rightExpression);
                    writer.Write(")");
                    return;
                }
            }

            //Do we have an implicit converter, if so, use it
            if (leftExpressionType.Type != rightExpressionType.Type && rightExpressionType.Type != null)
            {
                bool useType = true;

                //We should start with exact converters and then move to more generic convertors i.e. base class or integers which are implicitly convertible
                var correctConverter = leftExpressionType.Type.GetImplicitCoversionOp(leftExpressionType.Type,
                                                                                      rightExpressionType.Type, true);

                if (correctConverter == null)
                {
                    useType          = false;
                    correctConverter =
                        rightExpressionType.Type.GetImplicitCoversionOp(leftExpressionType.Type,
                                                                        rightExpressionType.Type, true);
                }

                if (correctConverter != null)
                {
                    Core.Write(writer, leftExpression);
                    writer.Write(operatorToken.ToString());
                    if (useType)
                    {
                        writer.Write(TypeProcessor.ConvertType(leftExpressionType.Type) + "." + "op_Implicit_" +
                                     TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_"));
                    }
                    else
                    {
                        writer.Write(TypeProcessor.ConvertType(rightExpressionType.Type) + "." + "op_Implicit_" +
                                     TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_"));
                    }
                    writer.Write("(");
                    Core.Write(writer, rightExpression);
                    writer.Write(")");
                    return;
                }
            }

            if (operatorToken.CSharpKind() == SyntaxKind.PlusEqualsToken ||
                operatorToken.CSharpKind() == SyntaxKind.MinusEqualsToken)
            {
                var isname = rightExpression is NameSyntax;

                var nameexpression = rightExpression as NameSyntax;

                var ismemberexpression = rightExpression is MemberAccessExpressionSyntax ||
                                         (isname &&
                                          TypeProcessor.GetSymbolInfo(rightExpression as NameSyntax).Symbol.Kind ==
                                          SymbolKind.Method);

                var isdelegateassignment = rightExpressionType.ConvertedType != null && (ismemberexpression &&
                                                                                         rightExpressionType.ConvertedType
                                                                                         .TypeKind == TypeKind.Delegate);

                var memberaccessexpression = rightExpression as MemberAccessExpressionSyntax;

                var isstaticdelegate = isdelegateassignment &&
                                       ((memberaccessexpression != null &&
                                         TypeProcessor.GetSymbolInfo(memberaccessexpression).Symbol.IsStatic) ||
                                        (isname && TypeProcessor.GetSymbolInfo(nameexpression).Symbol.IsStatic));

                if (isdelegateassignment)
                {
                    Core.Write(writer, leftExpression);

                    writer.Write(operatorToken.ToString());

                    var typeString = TypeProcessor.ConvertType(rightExpressionType.ConvertedType);

                    if (rightExpressionType.ConvertedType.TypeKind == TypeKind.TypeParameter)
                    {
                        writer.Write(" __TypeNew!(" + typeString + ")(");
                    }
                    else
                    {
                        writer.Write("new " + typeString + "(");
                    }

                    var isStatic = isstaticdelegate;
                    //                        if (isStatic)
                    //                            writer.Write("__ToDelegate(");

                    MemberUtilities.WriteMethodPointer(writer, rightExpression);
                    //                        if (isStatic)
                    //                            writer.Write(")");

                    writer.Write(")");
                    return;
                }
            }
            if (leftExpressionType.Type == null || (rightExpressionType.Type == null && rightExpression != null))
            {
                // seems we have a null here obj==null or null==obj
                if ((rightExpressionType.Type != null && rightExpressionType.Type.IsValueType) ||
                    (leftExpressionType.Type != null && leftExpressionType.Type.IsValueType))
                {
                    writer.Write("/*value type cannot be null*/");
                    Core.Write(writer, leftExpression);
                    switch (operatorToken.CSharpKind())
                    {
                    case SyntaxKind.EqualsEqualsToken:
                        writer.Write("!=");
                        break;

                    case SyntaxKind.NotEqualsExpression:
                        writer.Write("==");
                        break;

                    default:
                        writer.Write(operatorToken.ToString());
                        break;
                    }

                    Core.Write(writer, rightExpression);
                }
                else
                {
                    Core.Write(writer, leftExpression);
                    if (operatorToken.CSharpKind() == SyntaxKind.EqualsEqualsToken)
                    {
                        writer.Write(" is ");
                    }
                    else if (operatorToken.CSharpKind() == SyntaxKind.ExclamationEqualsToken)
                    {
                        writer.Write(" !is ");
                    }
                    else
                    {
                        writer.Write(operatorToken.ToString());
                    }
                    if (rightExpression != null)
                    {
                        Core.Write(writer, rightExpression);
                    }
                }
            }
            else
            {
                writer.Write(boxLeft ? "BOX!(" + TypeProcessor.ConvertType(leftExpressionType.Type) + ")(" : "");
                Core.Write(writer, leftExpression);
                writer.Write(boxLeft ? ")" : "");
                writer.Write(operatorToken.ToString());
                if (rightExpression != null)
                {
                    writer.Write(unboxRight
                        ? "UNBOX!(" + TypeProcessor.ConvertType(rightExpressionType.ConvertedType) + ")("
                        : "");
                    writer.Write(boxRight ? "BOX!(" + TypeProcessor.ConvertType(rightExpressionType.Type) + ")(" : "");
                    Core.Write(writer, rightExpression);
                    writer.Write(boxRight ? ")" : "");
                    writer.Write(unboxRight ? ")" : "");
                }
            }
        }
示例#18
0
        public static void Go(OutputWriter writer, IdentifierNameSyntax identifier, bool byRef = false)
        {
            var symbol = TypeProcessor.GetSymbolInfo(identifier).Symbol;

            if (symbol.IsStatic)
            {
                writer.Write(symbol.ContainingNamespace.FullNameWithDot());
                writer.Write(symbol.ContainingType.FullName());
                writer.Write(".");
            }

            //            if (!byRef && Program.RefOutSymbols.ContainsKey(symbol)) //Not neccessary, c++ can pass by ref
            //            {
            //                    writer.Write("(*");
            //                    writer.Write(TransformIdentifier(identifier.Identifier.ToString()));
            //                    writer.Write(")");
            //            }
            //            else
            //            {
            var    binExpression = identifier.Parent as BinaryExpressionSyntax;
            string memberName    = TransformIdentifier(identifier.Identifier.ToString());

            if (symbol.Kind == SymbolKind.Property) // Using dlang properties
            {
                if (symbol.ContainingType.TypeKind == TypeKind.Interface ||
                    Equals(symbol.ContainingType.FindImplementationForInterfaceMember(symbol), symbol))
                {
                    memberName =
                        Regex.Replace(
                            TypeProcessor.ConvertType(symbol.ContainingType.OriginalDefinition)
                            .RemoveFromStartOfString(symbol.ContainingNamespace + ".Namespace.") + "_" + memberName,
                            @" ?!\(.*?\)", string.Empty);
                }

                var interfaceMethods =
                    symbol.ContainingType.AllInterfaces.SelectMany(
                        u =>
                        u.GetMembers(memberName)).ToArray();

                ISymbol interfaceMethod =
                    interfaceMethods.FirstOrDefault(
                        o => symbol.ContainingType.FindImplementationForInterfaceMember(o) == symbol);

                //                    if (interfaceMethod == null)
                //                    {
                //                        //TODO: fix this for virtual method test 7, seems roslyn cannot deal with virtual
                //                        // overrides of interface methods ... so i'll provide a kludge
                //                        if (!method.Modifiers.Any(SyntaxKind.NewKeyword))
                //                            interfaceMethod = interfaceMethods.FirstOrDefault(k => CompareMethods(k as IMethodSymbol, methodSymbol));
                //                    }

                if (interfaceMethod != null)
                // && CompareMethods(interfaceMethod ,methodSymbol)) {
                {
//This is an interface method //TO
                    if (symbol.ContainingType.SpecialType == SpecialType.System_Array)
                    {
                        writer.Write("");
                    }
                    else
                    {
                        var typenameI =
                            Regex.Replace(
                                TypeProcessor.ConvertType(interfaceMethod.ContainingType.ConstructedFrom, true),
                                @" ?!\(.*?\)", string.Empty);
                        //TODO: we should be able to get the original interface name, or just remove all generics from this
                        if (typenameI.Contains('.'))
                        {
                            typenameI = typenameI.SubstringAfterLast('.');
                        }
                        writer.Write(typenameI + "_");
                    }
                }
//                var closeBraces = binExpression != null && binExpression.IsKind(SyntaxKind.SimpleAssignmentExpression) && binExpression.Left == identifier?"()" :"";
//                if (binExpression != null && binExpression.OperatorToken.RawKind == (decimal) SyntaxKind.EqualsToken)
//                {
//
//                    writer.Write("set_" + memberName + closeBraces);
//
//                }
//                else
//                {
//                    writer.Write("get_" + memberName+ closeBraces);
//
//                }
            }
//            else
            {
                writer.Write(memberName);
            }

//            }
        }
示例#19
0
        private static void ProcessInitializer(OutputWriter writer, LocalDeclarationStatementSyntax declaration,
                                               VariableDeclaratorSyntax variable)
        {
            var initializer = variable.Initializer;

            if (initializer != null)
            {
                if (initializer.Value.CSharpKind() == SyntaxKind.CollectionInitializerExpression)
                {
                    return;
                }

                var value                  = initializer.Value;
                var initializerType        = TypeProcessor.GetTypeInfo(value);
                var memberaccessexpression = value as MemberAccessExpressionSyntax;
                var nameexpression         = value as NameSyntax;
                var nullAssignment         = value.ToFullString().Trim() == "null";
                var convertedType          = initializerType.ConvertedType;
                var type = initializerType.Type;
                if (type == null && convertedType == null) //TODO: Rare Case (Compiling csnative corlib... need to find a solution, for now just write it out
                {
                    Core.Write(writer, value);
                    return;
                }

                var shouldBox = type != null && (type.IsValueType) &&
                                !convertedType.IsValueType;
                var shouldUnBox = type != null && !type.IsValueType &&
                                  convertedType.IsValueType;
                var isname             = value is NameSyntax;
                var ismemberexpression = value is MemberAccessExpressionSyntax ||
                                         (isname &&
                                          TypeProcessor.GetSymbolInfo(value as NameSyntax).Symbol.Kind ==
                                          SymbolKind.Method);


                var isdelegateassignment = ismemberexpression &&
                                           convertedType.TypeKind == TypeKind.Delegate;
                var isstaticdelegate = isdelegateassignment &&
                                       ((memberaccessexpression != null &&
                                         TypeProcessor.GetSymbolInfo(memberaccessexpression).Symbol.IsStatic) ||
                                        (isname && TypeProcessor.GetSymbolInfo(nameexpression).Symbol.IsStatic));

                //Do we have an implicit converter, if so, use it
                if (shouldBox || shouldUnBox)
                {
                    if (WriteConverter(writer, type, convertedType, value))
                    {
                        return;
                    }
                }

                if (nullAssignment)
                {
                    if (convertedType != null) //Nullable Support
                    {
                        if (convertedType.Name == "Nullable")
                        {
                            var atype = TypeProcessor.ConvertType(convertedType);
                            writer.Write(atype + "()");
                        }
                        else
                        {
                            writer.Write("null");
                        }
                    }
                    return;
                }
                if (shouldBox)
                {
                    WriteBox(writer, type, value);
                    return;
                }
                if (shouldUnBox)
                {
                    WriteUnbox(writer, type, value);
                    return;
                }

                if (isdelegateassignment)
                {
                    WriteDelegateAssignment(writer, convertedType, isstaticdelegate, value);
                    return;
                }

//                if (type == null && convertedType == null)
//                {
//                    writer.Write("null");
//                    return;
//                }

                //CTFE

                /* var aVal =  EvaluateValue(value);
                 * if (String.IsNullOrEmpty(aVal))
                 * {
                 *    writer.Write(aVal);
                 * }
                 * else*/
                Core.Write(writer, value);
            }
            else
            {
                writer.Write(TypeProcessor.DefaultValue(declaration.Declaration.Type));
            }
        }
示例#20
0
        private static void WriteOutOneType(OutputWriter parentModuleWriter, Context.SyntaxAndSymbol[] typeSymbols, bool fileExists)
        {
            TypeProcessor.ClearUsedTypes();
            var mynamespace = Context.Instance.Type.ContainingNamespace.FullName().RemoveFromEndOfString(".Namespace");

            var fullname = Context.Instance.Namespace + "." + Context.Instance.TypeName;

            if (TypeRenames.ContainsKey(fullname))
            {
                Context.Instance.TypeName = TypeRenames[fullname];
            }

            // + "." + TypeState.Instance.TypeName;
            // if (Driver.Verbose)
            //    Console.WriteLine("Writing out type: " + fullname);
            if (fullname.StartsWith(
                    "System.Collections.Generic.Dictionary"))
            {
            }

            var myUsingDirective     = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(mynamespace));
            var SystemUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System"));
            // Required as certain functions like boxing are in this namespace
            var namespaces      = typeSymbols.First().Syntax.Parent.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray();
            var usingStatements = typeSymbols.First().Syntax.Parent.DescendantNodes().OfType <UsingStatementSyntax>().ToArray();
            var allTypeAliases  = typeSymbols.First().Syntax.DescendantNodes().OfType <QualifiedNameSyntax>().ToArray();

            Context.Instance.UsingDeclarations = namespaces
                                                 .Union(new[]
            {
                myUsingDirective, SystemUsingDirective
            }).ToArray();



            TypeProcessor.AddAlias(Context.Instance.Type.ContainingNamespace as INamespaceSymbol, Context.Instance.Type.ContainingNamespace.GetModuleName());


            foreach (var ns in namespaces)
            {
                //TODO: Add support for type aliases ...
                var symbol = TypeProcessor.GetSymbolInfo(ns.Name).Symbol;
                if (allTypeAliases.All(o => TypeProcessor.GetSymbolInfo(o.Left).Symbol != symbol))
                {
                    TypeProcessor.AddAlias(symbol as INamespaceSymbol, (symbol as INamespaceSymbol).GetModuleName());
                }
            }

            var aliases = allTypeAliases.DistinctBy(j => TypeProcessor.GetSymbolInfo(j.Left));

            foreach (var alias in aliases)
            {
                var left = alias.Left;
                var type = TypeProcessor.GetSymbolInfo(left).Symbol as INamespaceSymbol;
                var name = left.ToString();
                if (type != null && type.ToString() != name)
                {
                    TypeProcessor.AddAlias(type, name);
                }
            }
            OutputWriter writer = null;

            using (
                writer =
                    parentModuleWriter == null
                        ? new OutputWriter(Context.Instance.Namespace, Context.Instance.TypeName)
                        : new TempWriter())
            {
                writer.FileExists = fileExists;

                if (parentModuleWriter != null)
                {
                    writer.WriteLine();
                    writer.Indent = parentModuleWriter.Indent + 2;
                    writer.WriteIndent();
                }

                var bases    = new List <ITypeSymbol>();
                var baselist = typeSymbols.Select(k => k.Syntax.As <BaseTypeDeclarationSyntax>()).Select(o => o.BaseList).Where(k => k != null).ToArray();

                if (baselist.Any())
                {
                    bases = baselist.SelectMany(k => k.Types)
                            .Select(o => TypeProcessor.GetTypeInfo(o.Type).ConvertedType ?? TypeProcessor.GetTypeInfo(o.Type).Type)
                            .Where(k => k != null)
                            .Distinct()
                            .ToList();
                }

                //                var interfaces = bases.Where(o => o.TypeKind == TypeKind.Interface).ToList();

                if (Context.Instance.Type != Context.Object)
                {
                    if (bases != null && (!bases.Any((j => j.TypeKind != TypeKind.Interface)) &&
                                          !(typeSymbols.First().Symbol.TypeKind == TypeKind.Interface || typeSymbols.First().Symbol.TypeKind == TypeKind.Struct)))
                    {
                        //TODO: fix structs using mixins / alias this
                        bases.Add(Context.Object);
                    }
                }
                if (bases == null)
                {
                    bases = new List <ITypeSymbol>();
                }

                foreach (var type in bases)
                {
                    TypeProcessor.AddUsedType(type);
                }

                //TODO: Fix enum support
                if (typeSymbols.First().Syntax is EnumDeclarationSyntax)
                {
                    WriteEnum.Go(writer,
                                 Context.Instance.Partials.Select(o => o.Syntax)
                                 .Cast <EnumDeclarationSyntax>()
                                 .SelectMany(o => o.Members)
                                 .Where(o => !Program.DoNotWrite.ContainsKey(o)));

                    if (parentModuleWriter != null)
                    {
                        parentModuleWriter.Write(writer.ToString());
                    }

                    return;
                }

                Context.Instance.AllMembers =
                    typeSymbols.Select(k => k.Syntax.As <TypeDeclarationSyntax>()).SelectMany(o => o.Members)
                    .Where(o => !Program.DoNotWrite.ContainsKey(o))
                    .ToList();

                var allMembersToWrite = Context.Instance.AllMembers
                                        .Where(member => !(member is TypeDeclarationSyntax) &&
                                               !(member is EnumDeclarationSyntax) &&
                                               !(member is DelegateDeclarationSyntax) &&
                                               !(member is ConstructorDeclarationSyntax))
                                        .ToList();

                Context.Instance.MemberNames = allMembersToWrite.Select(k => k.GetCSharpName()).ToList();
                if (Context.Instance.Type.ContainingType != null)
                {
                    Context.Instance.MemberNames.AddRange(Context.Instance.Type.ContainingType.MemberNames);
                }


                {
                    //                    WriteStandardIncludes.Go(writer);

                    //                    writer.WriteLine(String.Format("#include \"{0}\"", TypeState.Instance.TypeName + ".h"));



                    WriteBcl.Go(writer);

                    //TypeState.Instance.DerivesFromObject = bases.Count == interfaces.Count;

                    var @namespace  = typeSymbols.First().Symbol.ContainingNamespace.FullName();
                    var genericArgs = Context.Instance.Type.TypeParameters.Select(l => l as ITypeSymbol).ToList();

                    //Module name = namespace + "." + typename;

                    WriteStandardIncludes.Go(writer);

                    //                    var namespaces = @namespace.Split(new string[] { "." }, StringSplitOptions.None);
                    //
                    //                    if (@namespace.Length > 0)
                    //                    {
                    //                        foreach (var ns in namespaces)
                    //                        {
                    //                            writer.WriteLine("namespace " + ns + "\r\n{");
                    //                            writer.WriteLine("namespace " + ns + "\r\n{");
                    //                        }
                    //
                    //                    }

                    var instanceCtors = Context.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>()
                                        .Where(o => !o.Modifiers.Any(SyntaxKind.StaticKeyword))
                                        .ToList();

                    var staticCtors = Context.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>()
                                      .Where(o => (o.Modifiers.Any(SyntaxKind.StaticKeyword)))
                                      .ToList();

                    //TODO: Add support for overloading constructing
                    //                    if (instanceCtors.Count > 1)
                    //                        throw new Exception(
                    //                            "Overloaded constructors are not supported.  Consider changing all but one to static Create methods " +
                    //                            Utility.Descriptor(first.Syntax));

                    //                    var ctorOpt = instanceCtors.SingleOrDefault();
                    //TODO: Handle interfaces by

                    /*
                     * class Interface
                     * {
                     * public:
                     *  virtual ~Interface() { }
                     *  virtual void test() = 0; // Functions, must all be virtual
                     * }
                     */

                    var membersToWrite = allMembersToWrite.ToList();
                    //.Where(o => IsStatic(o) == staticMembers).ToList();

                    //                    if (membersToWrite.Count == 0 && (partials.Any(o => o.Syntax.Modifiers.Any(SyntaxKind.StaticKeyword))))
                    //                        continue;

                    //                    if (staticMembers)
                    //                        writer.Write("object ");
                    //                    else if (first.Syntax.Kind == SyntaxKind.InterfaceDeclaration)
                    //                        writer.Write("trait ");
                    //                    else
                    //                    {
                    //                        if (partials.Any(o => o.Syntax.Modifiers.Any(SyntaxKind.AbstractKeyword)))
                    //                            writer.Write("abstract ");

                    //                    }

                    // writer.Write(TypeState.Instance.TypeName);

                    if (typeSymbols.First().Syntax is TypeDeclarationSyntax)
                    {
                        //Internal classes/structs are declared static in D to behave correctly
                        if (parentModuleWriter != null)
                        {
                            writer.Write("static ");
                        }
                        if (Context.Instance.Type.TypeKind == TypeKind.Class)
                        {
                            writer.Write("class ");
                        }
                        else if (Context.Instance.Type.TypeKind == TypeKind.Interface)
                        {
                            writer.Write("interface ");
                        }
                        else if (Context.Instance.Type.TypeKind == TypeKind.Struct)
                        {
                            writer.Write("struct ");
                            //						writer.Write (" class "); // Allows inheritance ... but too many issues, will look at this when it gets relevant
                        }
                        else
                        {
                            throw new Exception("don't know how to write type: " + Context.Instance.Type.TypeKind);
                        }
                        List <ITypeSymbol> parentTypeParameters;
                        if (Context.Instance.Type.ContainingType != null)
                        {
                            parentTypeParameters = GetParentTypeParameters(Context.Instance.Type);
                        }
                        else
                        {
                            parentTypeParameters = new List <ITypeSymbol>();
                        }

                        writer.Write(TypeName(Context.Instance.Type, false));
                        //TypeProcessor.ConvertType(Context.Instance.Type, true, false,true));

                        if (Context.Instance.Type.IsGenericType)
                        {
                            {
                                foreach (var @base in bases)
                                {
                                    var namedTypeSymbol = @base as INamedTypeSymbol;
                                    if (namedTypeSymbol != null)
                                    {
                                        foreach (var arg in namedTypeSymbol.TypeArguments)
                                        {
                                            if (arg.TypeKind == TypeKind.TypeParameter && !parentTypeParameters.Contains(arg))
                                            {
                                                if (!genericArgs.Any(k => k.Name == arg.Name))
                                                {
                                                    genericArgs.Add(arg);
                                                }
                                            }
                                        }
                                    }
                                }
                                if (genericArgs.Any())
                                {
                                    writer.Write("(" +
                                                 string.Join(" , ",
                                                             genericArgs.Select(o => TypeProcessor.ConvertType(o, true, true, false))) + ")");
                                }
                            }
                        }

                        bool firstBase = true;

                        if (Context.Instance.Type.TypeKind != TypeKind.Struct)
                        {
                            foreach (var baseType in bases.OrderBy(o => o.TypeKind == TypeKind.Interface ? 1 : 0))
                            {
                                var convertType = TypeProcessor.ConvertType(baseType);

                                writer.Write(firstBase ? " : " : " ,");

                                writer.Write(convertType);

                                firstBase = false;
                            }
                        }

                        string constraints = GetTypeConstraints((TypeDeclarationSyntax)typeSymbols.First().Syntax);
                        writer.Write(constraints);
                    }

                    writer.WriteLine();

                    writer.OpenBrace();

                    var nonFields = WriteFields(membersToWrite, typeSymbols.First(), writer);

                    foreach (var member in nonFields)
                    {
                        //                    writer.WriteLine();
                        Core.Write(writer, member);
                    }

                    WriteConstructors(instanceCtors, writer);

                    WriteStaticConstructors(staticCtors, writer);

                    //PInvoke is now centralized, so we can call it on all libraries etc without issue

                    writer.Indent--;
                    WriteOutNestedTypes(typeSymbols.First(), writer);

                    var methodSymbols = membersToWrite.OfType <MethodDeclarationSyntax>().Select(TypeProcessor.GetDeclaredSymbol);
                    //TypeProcessor.GetDeclaredSymbol(method);

                    if (!methodSymbols.OfType <IMethodSymbol>()
                        .Any(k => k.Name == "ToString" && k.Parameters.Length == 0 && k.ReturnType == Context.String))
                    {
                        if (Context.Instance.Type.TypeKind == TypeKind.Struct ||
                            (Context.Instance.Type.TypeKind == TypeKind.Class))
                        {
                            var overrideS = Context.Instance.Type.TypeKind == TypeKind.Struct ? "" : "override ";
                            writer.WriteLine();
                            writer.WriteLine("public " + overrideS + "String ToString()");
                            writer.OpenBrace();
                            writer.WriteLine("return GetType().FullName;");//Better names based on specialization
                            writer.CloseBrace();
                        }
                    }

                    WriteOutBoxed(writer, genericArgs, bases);
                }

                if (Context.Instance.Type.TypeKind == TypeKind.Struct)
                {
                    writer.WriteLine();
                    writer.WriteLine("public __Boxed_ __Get_Boxed()");
                    writer.OpenBrace();
                    writer.WriteLine("return new __Boxed_(this);");
                    writer.CloseBrace();
                    writer.WriteLine("alias __Get_Boxed this;");
                }

                if (Context.Instance.Type.TypeKind != TypeKind.Interface)
                {
                    writer.WriteLine();
                    if (Context.Instance.Type.TypeKind == TypeKind.Class)
                    {
                        writer.WriteLine("public override Type GetType()");
                    }
                    //					else if (Context.Instance.Type.TypeKind == TypeKind.Interface) // Messes with GetType overrides of objects
                    //					{
                    //						writer.WriteLine ("public final Type GetType()");
                    //					}
                    else if (Context.Instance.Type.TypeKind == TypeKind.Struct)
                    {
                        writer.WriteLine("public Type GetType()");
                    }
                    writer.OpenBrace();
                    //if (Context.Instance.Type.TypeKind == TypeKind.Class)
                    writer.WriteLine("return __TypeOf!(typeof(this));");
                    // else
                    //     writer.WriteLine("return __TypeOf!(__Boxed_);");

                    writer.CloseBrace();
                }

                writer.CloseBrace();

                WriteEntryMethod(writer);

                if (parentModuleWriter != null)
                {
                    writer.Finalize();
                    parentModuleWriter.Write(writer.ToString());
                }
            }
        }
示例#21
0
        public static void Go(OutputWriter writer, ObjectCreationExpressionSyntax expression)
        {
            var type = TypeProcessor.GetTypeInfo(expression).Type;

            if (expression.Initializer != null)
            {
                if (expression.Initializer.IsKind(SyntaxKind.CollectionInitializerExpression))
                {
                    var isPtr      = type.IsPointer() ? "" : "";
                    var typeString = TypeProcessor.ConvertType(type); // + isPtr + " ";

                    WriteNewOperator(writer, type, typeString);

                    writer.Write("(");
                    var intializer = expression.Initializer;
                    intializer.WriteArrayInitializer(writer, expression.Type);

                    writer.Write(")");

                    return;
                }
                writer.Write("(");
                Core.Write(writer, expression.Initializer);
            }

            if (type.SpecialType == SpecialType.System_Object)
            {
                //new object() results in the NObject type being made.  This is only really useful for locking
                writer.Write("new NObject()");
            }
            else if (type.OriginalDefinition is INamedTypeSymbol &&
                     type.OriginalDefinition.As <INamedTypeSymbol>().SpecialType == SpecialType.System_Nullable_T)
            {
                //new'ing up a Nullable<T> has special sematics in C#.  If we're calling this with no parameters, just use null. Otherwise just use the parameter.
                if (expression.ArgumentList.Arguments.Count == 0)
                {
                    writer.Write("null");
                }
                else
                {
                    Core.Write(writer, expression.ArgumentList.Arguments.Single().Expression);
                }
            }
            else
            {
                var methodSymbol = TypeProcessor.GetSymbolInfo(expression).Symbol.As <IMethodSymbol>();

                var typeString = TypeProcessor.ConvertType(expression.Type);

                WriteNewOperator(writer, type, typeString);

                if (expression.ArgumentList != null)
                {
                    bool first = true;
                    foreach (var param in TranslateParameters(expression.ArgumentList.Arguments))
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            writer.Write(", ");
                        }

                        param.Write(writer);
                    }
                }

                writer.Write(")");
            }
        }
示例#22
0
        public static void Go(OutputWriter writer, IdentifierNameSyntax identifier, bool byRef = false)
        {
            var symbolInfo = TypeProcessor.GetSymbolInfo(identifier);
            var symbol     = symbolInfo.Symbol;

            if (symbol == null)
            {
                //Yield issue ...
                symbol = symbolInfo.CandidateSymbols[0];
            }

            if (symbol.IsStatic)
            {
                //                writer.Write(symbol.ContainingNamespace.FullNameWithDot());
                //                writer.Write(symbol.ContainingType.FullName());
                writer.Write(TypeProcessor.ConvertType(symbol.ContainingType) + ".");
            }


            var    binExpression = identifier.Parent as BinaryExpressionSyntax;
            string memberName    = TransformIdentifier(identifier.Identifier.ToString());

            if (symbol.Kind == SymbolKind.Property) // Using dlang properties
            {
                if (symbol.ContainingType.TypeKind == TypeKind.Interface ||
                    Equals(symbol.ContainingType.FindImplementationForInterfaceMember(symbol), symbol))
                {
                    memberName =
                        Regex.Replace(
                            TypeProcessor.ConvertType(symbol.ContainingType.OriginalDefinition)
                            .RemoveFromStartOfString(symbol.ContainingNamespace + ".Namespace.") + "_" + memberName,
                            @" ?!\(.*?\)", string.Empty);
                }

                var interfaceMethods =
                    symbol.ContainingType.AllInterfaces.SelectMany(
                        u =>
                        u.GetMembers(memberName)).ToArray();

                ISymbol interfaceMethod =
                    interfaceMethods.FirstOrDefault(
                        o => symbol.ContainingType.FindImplementationForInterfaceMember(o) == symbol);



                if (interfaceMethod != null)
                {
                    if (symbol.ContainingType.SpecialType == SpecialType.System_Array)
                    {
                        writer.Write("");
                    }
                    else
                    {
                        var typenameI =
                            Regex.Replace(
                                TypeProcessor.ConvertType(interfaceMethod.ContainingType.ConstructedFrom, true),
                                @" ?!\(.*?\)", string.Empty);
                        //TODO: we should be able to get the original interface name, or just remove all generics from this
                        if (typenameI.Contains('.'))
                        {
                            typenameI = typenameI.SubstringAfterLast('.');
                        }
                        writer.Write(typenameI + "_");
                    }
                }
            }
            writer.Write(memberName);
        }
        public static void Go(OutputWriter writer, ElementAccessExpressionSyntax expression)
        {
            var type            = TypeProcessor.GetTypeInfo(expression.Expression).Type;
            var typeStr         = TypeProcessor.GenericTypeName(type);
            var additionalParam = "";
            var symbol          = TypeProcessor.GetSymbolInfo(expression); //This could be null

            if (symbol.Symbol != null)
            {
                var methodSymbol = symbol.Symbol as IPropertySymbol;
                //Lets find out if this is an interface implementation
                if (methodSymbol != null)
                {
                    IEnumerable <ISymbol> interfaceMethods =
                        methodSymbol.ContainingType.AllInterfaces.SelectMany(
                            u =>
                            u.GetMembers(methodSymbol.Name));

                    interfaceMethods =
                        interfaceMethods.Where(
                            o => Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(o), methodSymbol));

                    if (interfaceMethods.Any())
                    {
                        //Lets  get the best match
                        var interfaceMethod = interfaceMethods.FirstOrDefault();
                        additionalParam = "cast(" + TypeProcessor.ConvertType(interfaceMethod.ContainingType) + ")null";
                    }
                }
            }

            //type.GetMembers("this[]")
            //Todo if we are using unsafe / fast mode, just use array->Data()[i] should bypass bounds check and indirection also should be as fast as pure c++ arrays
            //though fixed syntax could fix this too ??
            //            writer.Write("(*");

            Core.Write(writer, expression.Expression);

            if (type.SpecialType == SpecialType.System_Array)
            {
//            writer.Write(")");
                writer.Write(".Items["); //TODO test this thoroughly
            }
            else
            {
                writer.Write("["); //TODO test this thoroughly
            }
            var first = true;

            foreach (var argument in expression.ArgumentList.Arguments)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    writer.Write(", ");
                }

                Core.Write(writer, argument.Expression);
            }
            if (additionalParam != "")
            {
                writer.Write("," + additionalParam);
            }
            writer.Write("]");
        }
        private static void ProcessInitializer(OutputWriter writer, VariableDeclarationSyntax declaration,
                                               VariableDeclaratorSyntax variable)
        {
            var initializer = variable.Initializer;

            if (initializer != null)
            {
                if (CSharpExtensions.CSharpKind(initializer.Value) == SyntaxKind.CollectionInitializerExpression)
                {
                    return;
                }
                var value                  = initializer.Value;
                var initializerType        = TypeProcessor.GetTypeInfo(value);
                var memberaccessexpression = value as MemberAccessExpressionSyntax;
                var nameexpression         = value as NameSyntax;
                var nullAssignment         = value.ToFullString().Trim() == "null";
                var shouldBox              = initializerType.Type != null && (initializerType.Type.IsValueType) &&
                                             !initializerType.ConvertedType.IsValueType;
                var shouldUnBox = initializerType.Type != null && !initializerType.Type.IsValueType &&
                                  initializerType.ConvertedType.IsValueType;
                var isname             = value is NameSyntax;
                var ismemberexpression = value is MemberAccessExpressionSyntax ||
                                         (isname &&
                                          TypeProcessor.GetSymbolInfo(value as NameSyntax).Symbol.Kind ==
                                          SymbolKind.Method);
                var isdelegateassignment = ismemberexpression &&
                                           initializerType.ConvertedType.TypeKind == TypeKind.Delegate;
                var isstaticdelegate = isdelegateassignment &&
                                       ((memberaccessexpression != null &&
                                         TypeProcessor.GetSymbolInfo(memberaccessexpression).Symbol.IsStatic) ||
                                        (isname && TypeProcessor.GetSymbolInfo(nameexpression).Symbol.IsStatic));
                var shouldCast = initializerType.Type != initializerType.ConvertedType &&
                                 initializerType.ConvertedType != null;

                if (nullAssignment)
                {
                    if (initializerType.Type != null) //Nullable Support
                    {
                        if (initializerType.Type.Name == "Nullable")
                        {
                            var atype = TypeProcessor.ConvertType(initializerType.Type);
                            writer.Write(atype + "()");
                        }
                    }
                    else
                    {
                        writer.Write("null");
                    }

                    return;
                }
                if (shouldBox)
                {
//Box
                    writer.Write("BOX!(" + TypeProcessor.ConvertType(initializerType.Type) + ")(");
//When passing an argument by ref or out, leave off the .Value suffix
                    Core.Write(writer, value);
                    writer.Write(")");
                    return;
                }
                if (shouldUnBox)
                {
                    writer.Write("cast(" + TypeProcessor.ConvertType(initializerType.Type) + ")(");
                    Core.Write(writer, value);
                    writer.Write(")");
                    return;
                }
                if (initializer.Parent.Parent.Parent is FixedStatementSyntax) // Fixed is a bit special
                {
//TODO write a better fix
                    var type = TypeProcessor.GetTypeInfo(declaration.Type);

                    writer.Write("cast(" + TypeProcessor.ConvertType(type.Type) + ")(");
                    Core.Write(writer, value);
                    writer.Write(")");
                    return;
                }
                if (isdelegateassignment)
                {
                    var typeString = TypeProcessor.ConvertType(initializerType.ConvertedType);

                    var createNew = !(value is ObjectCreationExpressionSyntax);

                    if (createNew)
                    {
                        if (initializerType.ConvertedType.TypeKind == TypeKind.TypeParameter)
                        {
                            writer.Write(" __TypeNew!(" + typeString + ")(");
                        }
                        else
                        {
                            writer.Write("new " + typeString + "(");
                        }
                    }

                    var isStatic = isstaticdelegate;
                    //                    if (isStatic)
                    //                        writer.Write("__ToDelegate(");
                    MemberUtilities.WriteMethodPointer(writer, value);
                    //                    if (isStatic)
                    //                        writer.Write(")");

                    if (createNew)
                    {
                        writer.Write(")");
                    }
                    return;
                }
                if (initializerType.Type == null && initializerType.ConvertedType == null)
                {
                    writer.Write("null");
                    return;
                }
                Core.Write(writer, value);
            }
            else
            {
                writer.Write(TypeProcessor.DefaultValue(declaration.Type));
            }
        }
        public static void Go(OutputWriter writer, AssignmentExpressionSyntax expression)
        {
            if (expression.OperatorToken.IsKind(SyntaxKind.AsKeyword))
            {
                var typeinfo = TypeProcessor.GetTypeInfo(expression.Right);

                var isPtr = typeinfo.Type != null && typeinfo.Type.IsValueType ? "" : "";
                writer.Write("cast( ");
                writer.Write(TypeProcessor.ConvertType(expression.Right) + isPtr);
                writer.Write(" )(");
                Core.Write(writer, expression.Left);
                writer.Write(")");
            }
            else if (expression.OperatorToken.IsKind(SyntaxKind.IsKeyword)) // isCast
            {
                var leftSymbolType  = TypeProcessor.GetTypeInfo(expression.Left);
                var rightSymbolType = TypeProcessor.GetTypeInfo(expression.Right);

                if (leftSymbolType.Type.IsValueType)
                {
                    writer.Write("IsCast!(Boxed!(");
                    writer.Write(TypeProcessor.ConvertType(expression.Right));
                    writer.Write("))");
                    writer.Write("(");
                    Core.Write(writer, expression.Left);
                    writer.Write(")");

                    //						writer.Write("(cast(BOX!(");
                    //						writer.Write(TypeProcessor.ConvertType(expression.Right));
                    //						writer.Write(" ) )(Boxed!( " + TypeProcessor.ConvertType(leftSymbolType.Type));
                    //						writer.Write(" )(");
                    //						Core.Write(writer, expression.Left);
                    //						writer.Write(")) is! null)");
                    //Todo improve this ... though its silly to do this in the first place
                    //					writer.Write("(cast(BOX!(");
                    //                    writer.Write(TypeProcessor.ConvertType(expression.Right));
                    //					writer.Write("))(Boxed!(" + TypeProcessor.ConvertType(leftSymbolType.Type));
                    //					writer.Write(")(");
                    //                    Core.Write(writer, expression.Left);
                    //					writer.Write(")) is! null)");
                }
                else if (rightSymbolType.Type.IsValueType)
                {
                    writer.Write("IsCast!(Boxed!(");
                    writer.Write(TypeProcessor.ConvertType(expression.Right));
                    writer.Write("))");
                    writer.Write("(");
                    Core.Write(writer, expression.Left);
                    writer.Write(")");

                    //					writer.Write("(cast(Boxed!( ");
                    //                    writer.Write(TypeProcessor.ConvertType(expression.Right));
                    //					writer.Write(" ) )(");
                    //                    Core.Write(writer, expression.Left);
                    //					writer.Write(") is! null)");
                }
                else
                {
                    var typeinfo = TypeProcessor.GetTypeInfo(expression.Right);

                    var isPtr = typeinfo.Type != null && typeinfo.Type.IsValueType ? "" : "";
                    writer.Write("(IsCast!(");
                    writer.Write(TypeProcessor.ConvertType(expression.Right) + isPtr);
                    writer.Write(")(");
                    Core.Write(writer, expression.Left);
                    writer.Write("))");
                }
            }
            else if (expression.OperatorToken.IsKind(SyntaxKind.QuestionQuestionToken))
            {
                writer.Write("((");
                Core.Write(writer, expression.Left);
                writer.Write(")!is null?(");
                Core.Write(writer, expression.Left);
                writer.Write("):(");
                Core.Write(writer, expression.Right);
                writer.Write("))");
            }
            else
            {
                //                if (expression.Left is ElementAccessExpressionSyntax && IsAssignmentToken((SyntaxKind) expression.OperatorToken.RawKind))
                //                {
                //                    var subExpr = expression.Left.As<ElementAccessExpressionSyntax>();
                //                    var typeStr = TypeProcessor.GenericTypeName(TypeProcessor.GetTypeInfo(subExpr.Expression).Type);
                //
                //
                //
                //                }

                Action <ExpressionSyntax> write = e =>
                {
                    var type = TypeProcessor.GetTypeInfo(e);

                    //Check for enums being converted to strings by string concatenation
                    var typeSymbol = type.Type ?? type.ConvertedType;

                    if (expression.OperatorToken.RawKind == (decimal)SyntaxKind.PlusToken &&
                        typeSymbol.TypeKind == TypeKind.Enum)
                    {
                        writer.Write(typeSymbol.ContainingNamespace.FullNameWithDot());
                        writer.Write(WriteType.TypeName(typeSymbol.As <INamedTypeSymbol>()));
                        writer.Write(".ToString(");
                        Core.Write(writer, e);
                        writer.Write(")");
                    }
                    else if (expression.OperatorToken.RawKind == (decimal)SyntaxKind.PlusToken &&
                             (typeSymbol.Name == "Nullable" && typeSymbol.ContainingNamespace.FullName() == "System" &&
                              typeSymbol.As <INamedTypeSymbol>().TypeArguments.Single().TypeKind == TypeKind.Enum))
                    {
                        var enumType = typeSymbol.As <INamedTypeSymbol>().TypeArguments.Single();
                        writer.Write(enumType.ContainingNamespace.FullNameWithDot());
                        writer.Write(WriteType.TypeName(enumType.As <INamedTypeSymbol>()));
                        writer.Write(".ToString(");
                        Core.Write(writer, e);
                        writer.Write(")");
                    }
                    else
                    {
                        Core.Write(writer, e);
                    }
                };

                var symbolInfoLeft  = TypeProcessor.GetSymbolInfo(expression.Left);
                var symbolInfoRight = TypeProcessor.GetSymbolInfo(expression.Right);

                var leftExpressionType  = TypeProcessor.GetTypeInfo(expression.Left);
                var rightExpressionType = TypeProcessor.GetTypeInfo(expression.Right);

                var boxLeft = leftExpressionType.Type != null &&
                              (leftExpressionType.Type.IsValueType && (leftExpressionType.ConvertedType.IsReferenceType));
                var derefLeft = false;
                // rightExpressionType.ConvertedType != null && rightExpressionType.ConvertedType.IsReferenceType;

                var boxRight = rightExpressionType.ConvertedType != null &&
                               (rightExpressionType.Type != null && (rightExpressionType.Type.IsValueType &&
                                                                     (rightExpressionType.ConvertedType.IsReferenceType)));
                var derefRight = rightExpressionType.ConvertedType != null &&
                                 (leftExpressionType.ConvertedType != null &&
                                  !leftExpressionType.ConvertedType.IsReferenceType &&
                                  rightExpressionType.ConvertedType.IsReferenceType);
                var nullAssignment = expression.Right.ToFullString().Trim() == "null";

                //Property calls will be fixed in a preprocessor step ... i.e. just call them
                // var propertyLeft = symbolInfoLeft.Symbol != null && symbolInfoLeft.Symbol.Kind == SymbolKind.Property;
                // var propertyRight = symbolInfoRight.Symbol != null && symbolInfoRight.Symbol.Kind == SymbolKind.Property;
                if (nullAssignment)
                {
                    Core.Write(writer, expression.Left);
                    writer.Write(" = ");
                    writer.Write("null");
                    return;
                }
                //Do we have an implicit converter, if so, use it
                if (leftExpressionType.Type != rightExpressionType.Type)
                {
                    // if (boxLeft)
                    {
                        bool useType = true;

                        //We should start with exact converters and then move to more generic convertors i.e. base class or integers which are implicitly convertible
                        var correctConverter = leftExpressionType.Type.GetImplicitCoversionOp(leftExpressionType.Type,
                                                                                              rightExpressionType.Type);
                        //                            initializerType.Type.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);

                        if (correctConverter == null)
                        {
                            useType          = false;
                            correctConverter =
                                rightExpressionType.Type.GetImplicitCoversionOp(leftExpressionType.Type,
                                                                                rightExpressionType.Type);
                            //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
                        }

                        if (correctConverter != null)
                        {
                            Core.Write(writer, expression.Left);
                            writer.Write(" = ");
                            if (useType)
                            {
                                writer.Write(TypeProcessor.ConvertType(leftExpressionType.Type) + "." + "op_Implicit_" +
                                             TypeProcessor.ConvertType(correctConverter.ReturnType));
                            }
                            else
                            {
                                writer.Write(TypeProcessor.ConvertType(rightExpressionType.Type) + "." + "op_Implicit_" +
                                             TypeProcessor.ConvertType(correctConverter.ReturnType));
                            }
                            writer.Write("(");
                            Core.Write(writer, expression.Right);
                            writer.Write(")");
                            return;
                        }
                    }
                    //                    if (shouldBox)
                    //                    {
                    //                        bool useType = true;
                    //                        var correctConverter =
                    //                            initializerType.Type.GetCoversionOp(initializerType.ConvertedType, initializerType.Type);//.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.ConvertedType && h.Parameters[0].Type == initializerType.Type);
                    //
                    //                        if (correctConverter == null)
                    //                        {
                    //                            useType = false;
                    //                            correctConverter =
                    //                                initializerType.ConvertedType.GetCoversionOp(initializerType.ConvertedType,
                    //                                    initializerType.Type);
                    //                            //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.ConvertedType && h.Parameters[0].Type == initializerType.Type);
                    //                        }
                    //
                    //                        if (correctConverter != null)
                    //                        {
                    //                            if (useType)
                    //                                writer.Write(TypeProcessor.ConvertType(initializerType.Type) + "." + "op_Implicit(");
                    //                            else
                    //                            {
                    //                                writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) + "." + "op_Implicit(");
                    //
                    //                            }
                    //                            Core.Write(writer, value);
                    //                            writer.Write(")");
                    //                            return;
                    //                        }
                    //                    }
                }

                if (expression.OperatorToken.CSharpKind() == SyntaxKind.PlusEqualsToken ||
                    expression.OperatorToken.CSharpKind() == SyntaxKind.MinusEqualsToken)
                {
                    var isname = expression.Right is NameSyntax;

                    var nameexpression = expression.Right as NameSyntax;

                    var ismemberexpression = expression.Right is MemberAccessExpressionSyntax ||
                                             (isname &&
                                              TypeProcessor.GetSymbolInfo(expression.Right as NameSyntax).Symbol.Kind ==
                                              SymbolKind.Method);

                    var isdelegateassignment = ismemberexpression &&
                                               rightExpressionType.ConvertedType.TypeKind == TypeKind.Delegate;

                    var memberaccessexpression = expression.Right as MemberAccessExpressionSyntax;

                    var isstaticdelegate = isdelegateassignment &&
                                           ((memberaccessexpression != null &&
                                             TypeProcessor.GetSymbolInfo(memberaccessexpression).Symbol.IsStatic) ||
                                            (isname && TypeProcessor.GetSymbolInfo(nameexpression).Symbol.IsStatic));

                    if (isdelegateassignment)
                    {
                        write(expression.Left);

                        writer.Write(expression.OperatorToken.ToString());

                        var createNew  = !(expression.Right is ObjectCreationExpressionSyntax);
                        var typeString = TypeProcessor.ConvertType(rightExpressionType.ConvertedType);

                        if (createNew)
                        {
                            if (rightExpressionType.ConvertedType.TypeKind == TypeKind.TypeParameter)
                            {
                                writer.Write(" __TypeNew!(" + typeString + ")(");
                            }
                            else
                            {
                                writer.Write("new " + typeString + "(");
                            }
                        }

                        var isStatic = isstaticdelegate;
                        if (isStatic)
                        {
                            writer.Write("__ToDelegate(");
                        }
                        writer.Write("&");

                        write(expression.Right);
                        //Core.Write (writer, expression.Right);
                        if (isStatic)
                        {
                            writer.Write(")");
                        }

                        if (createNew)
                        {
                            writer.Write(")");
                        }
                        return;
                    }
                }
                if (leftExpressionType.Type == null || rightExpressionType.Type == null)
                {
                    // seems we have a null here obj==null or null==obj
                    if ((rightExpressionType.Type != null && rightExpressionType.Type.IsValueType) ||
                        (leftExpressionType.Type != null && leftExpressionType.Type.IsValueType))
                    {
                        writer.Write("/*value type cannot be null*/");
                        write(expression.Left);
                        switch (expression.OperatorToken.CSharpKind())
                        {
                        case SyntaxKind.EqualsEqualsToken:
                            writer.Write("!=");
                            break;

                        case SyntaxKind.NotEqualsExpression:
                            writer.Write("==");
                            break;

                        default:
                            writer.Write(expression.OperatorToken.ToString());
                            break;
                        }

                        write(expression.Right);
                    }
                    else
                    {
                        write(expression.Left);
                        if (expression.OperatorToken.CSharpKind() == SyntaxKind.EqualsEqualsToken)
                        {
                            writer.Write(" is ");
                        }
                        else if (expression.OperatorToken.CSharpKind() == SyntaxKind.ExclamationEqualsToken)
                        {
                            writer.Write(" !is ");
                        }
                        else
                        {
                            writer.Write(expression.OperatorToken.ToString());
                        }

                        write(expression.Right);
                    }
                }
                else
                //                if (symbolInfoLeft.Symbol != null && (symbolInfoLeft.Symbol.Kind == SymbolKind.Property && expression.OperatorToken.ValueText == "=")) //Assignment of property
                //                {
                //
                //                    write(expression.Left);
                //                    writer.Write("(");
                //                    write(expression.Right);
                //                    writer.Write(")");
                //                }
                //                else
                {
                    //                    writer.Write(derefLeft ? "*(" : "");
                    writer.Write(boxLeft ? "BOX!(" + TypeProcessor.ConvertType(leftExpressionType.Type) + ")(" : "");
                    write(expression.Left);

                    writer.Write(boxLeft ? ")" : "");
                    //                    writer.Write(derefLeft ? ")" : "");
                    writer.Write(expression.OperatorToken.ToString());
                    //                    writer.Write(derefRight ? "(" : "");
                    writer.Write(boxRight ? "BOX!(" + TypeProcessor.ConvertType(rightExpressionType.Type) + ")(" : "");
                    write(expression.Right);

                    writer.Write(boxRight ? ")" : "");
                    //                    writer.Write(derefRight ? ")" : "");
                }
            }
        }