Example #1
0
        public static void WriteIt(OutputWriter writer, MethodDeclarationSyntax method, bool isProxy = true)
        {
            writer.WriteLine();
            var methodSymbol = (IMethodSymbol)TypeProcessor.GetDeclaredSymbol(method);
            var methodName   = OverloadResolver.MethodName(methodSymbol);

            var pinvokeAttributes = method.GetAttribute(Context.DllImport);

            // Fix this to actually look for the type, not just by name ...

            //TODO: Improve partial class / method support -- partials classes work, methods need minor work ...
            if (method.Modifiers.Any(SyntaxKind.PartialKeyword) && method.Body == null)
            {
                //We only want to render out one of the two partial methods.  If there's another, skip this one.
                if (Context.Instance.Partials.SelectMany(o => o.Syntax.As <ClassDeclarationSyntax>().Members)
                    .OfType <MethodDeclarationSyntax>()
                    .Except(method).Any(o => o.Identifier.ValueText == method.Identifier.ValueText))
                {
                    return;
                }
            }

            bool isoverride = ShouldUseOverrideKeyword(method, methodSymbol);

            var accessString = "";

            if (isoverride)
            {
                accessString += (" override ");
            }

            var isInterface = method.Parent is InterfaceDeclarationSyntax;

            if (methodName == "Main" /*&& method.Modifiers.Any(SyntaxKind.PublicKeyword)*/ &&
                method.Modifiers.Any(SyntaxKind.StaticKeyword))
            {
                accessString = ("public ");

                accessString += ("static ");

                var methodCall = methodSymbol.ContainingNamespace.FullName() + "." +
                                 methodSymbol.ContainingType.FullName() +
                                 "." + methodName + (method.ParameterList.Parameters.Count < 1 ? "();" : "(null);");
                //: "(new Array_T!(String)(args));"); // for now args not supported
                Context.Instance.EntryMethod = methodCall;
            }

            else
            {
                if (method.Modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword) ||
                    method.Modifiers.Any(SyntaxKind.ProtectedKeyword) ||
                    method.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface)
                {
                    accessString += ("public ");
                }

                if (method.Modifiers.Any(SyntaxKind.PrivateKeyword))
                {
                    accessString += ("private ");
                }

                //	            if (method.Modifiers.Any(SyntaxKind.VirtualKeyword) || isInterface)
                //	                writer.Write("virtual ");

                //				if (!(method.Modifiers.Any (SyntaxKind.VirtualKeyword) || (method.Modifiers.Any (SyntaxKind.AbstractKeyword) || isInterface || isoverride))) {
                //					writer.Write(" final ");
                //				}

                if (method.Modifiers.Any(SyntaxKind.AbstractKeyword))
                {
                    accessString += (" abstract ");
                }

                if (method.Modifiers.Any(SyntaxKind.StaticKeyword))
                {
                    accessString += ("static ");
                }
            }

            //	        if (isInterface)
            //	        {
            //                writer.IsInterface = true;
            //	        }

            var returnTypeString      = TypeProcessor.ConvertType(method.ReturnType) + " ";
            var methodSignatureString = "";

            if (method.ReturnType.ToString() == "void")
            {
                returnTypeString = ("void ");
            }
            else
            //  bool returnsVoid = method.ReturnType.ToString() == "void";
            //if (!returnsVoid)
            {
                var typeSymbol = TypeProcessor.GetTypeInfo(method.ReturnType).Type;

                //   var isPtr = typeSymbol != null && (typeSymbol.IsValueType || typeSymbol.TypeKind == TypeKind.TypeParameter) ? "" : "";
                //     var typeString = TypeProcessor.ConvertType(method.ReturnType) + isPtr + " ";

                //	            writer.Write(typeString);
                //	            writer.HeaderWriter.Write(typeString);

                var isPtr = typeSymbol != null &&
                            (!typeSymbol.IsValueType || typeSymbol.TypeKind == TypeKind.TypeParameter);
            }

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

            if (methodName.Contains(".")) // Explicit Interface method
            {
                //
                methodName = methodName.SubstringAfterLast('.');
                methodName = methodName.Replace('.', '_');
            }

            //			var typenameI = Regex.Replace (TypeProcessor.ConvertType (interfaceMethod.ContainingType), @" ?!\(.*?\)", 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)
                {
                    methodSignatureString += ("");
                }
                else
                {
                    var typenameI =
                        Regex.Replace(TypeProcessor.ConvertType(interfaceMethod.ContainingType.ConstructedFrom),
                                      @" ?!\(.*?\)", 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('.');
                    }
                    methodName = (typenameI + "_") + methodName;
                }
            }

            //            var explicitHeaderNAme = "";
            //FIX ME: To support explicits, all method calls are going to be prequalified with the interface name, lets just hope we dont have similar interfaces
            //
            // 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 ...
            //	            }
            //	        }
            // methodName = methodName.Replace(methodSymbol.ContainingNamespace.FullName() + ".", methodSymbol.ContainingNamespace.FullName().Replace(".", "::") + "::");
            //           (methodSymbol as).Is
            //	        (methodSymbol as Microsoft.CodeAnalysis.CSharp.Symbols.SourceMethodSymbol);
            if (method.Modifiers.Any(SyntaxKind.NewKeyword))
            {
                methodName += "_";
            }

            //            writer.Write( TypeProcessor.ConvertType(methodSymbol.ContainingType)+ "." + methodName); //Dealting with explicit VMT7
            // writer.Write(!String.IsNullOrEmpty(explicitHeaderNAme)? explicitHeaderNAme : methodName);
            //            writer.Write(methodName);
            methodSignatureString += methodName;

            if (method.TypeParameterList != null)
            {
                var genericArgs = method.TypeParameterList.Parameters.ToList();

                //				if (genericArgs.Count > 0)
                //				{
                //					writer.Write("( ");
                //					writer.Write(string.Join(" , ", genericArgs.Select(o => " " + o)));
                //					writer.Write(" )\r\n");
                //				}

                if (genericArgs.Count > 0) // && !methodSymbol.ContainingType.IsGenericType) // doesnt matter
                {
                    methodSignatureString += ("(");
                    methodSignatureString += (string.Join(",", genericArgs.Select(o => " " + o)));
                    methodSignatureString += (")");
                }
            }

            var @params = GetParameterListAsString(method.ParameterList);

            var constraints = "";

            if (method.ConstraintClauses.Count > 0)
            {
                constraints += (" if (");
                bool isFirst = true;
                foreach (var constraint in method.ConstraintClauses)
                {
                    foreach (var condition in constraint.Constraints)
                    {
                        string dlangCondition = condition.ToString();

                        if (dlangCondition == "new()")
                        {
                            continue;
                        }
                        if (dlangCondition == "class") // TODO: is there a better way to do this ?
                        {
                            dlangCondition = "NObject";
                        }

                        if (dlangCondition == "struct")
                        {
                            constraints += ((isFirst ? "" : "&&") + " !is(" + constraint.Name + " : NObject)");
                        }
                        else
                        {
                            constraints += ((isFirst ? "" : "&&") + " is(" + constraint.Name + " : " + dlangCondition +
                                            ")");
                        }

                        isFirst = false;

                        //								Console.WriteLine (condition);
                    }
                }

                constraints += (")");
            }

            if (isInterface || method.Modifiers.Any(SyntaxKind.AbstractKeyword))
            {
                writer.WriteLine(accessString + returnTypeString + methodSignatureString + @params + constraints + ";");

                return;
            }

            writer.WriteLine(accessString + returnTypeString + methodSignatureString + @params + constraints);

            writer.OpenBrace();

            if (isProxy)
            {
                @params = GetParameterListAsString(method.ParameterList, false);

                if (method.ReturnType.ToString() == "void")
                {
                    writer.WriteLine("Value." + methodName + @params + ";");
                }
                else
                {
                    writer.WriteLine("return Value." + methodName + @params + ";");
                }
            }
            else
            {
                if (method.Body != null)
                {
                    foreach (var statement in method.Body.Statements)
                    {
                        Core.Write(writer, statement);
                    }

                    TriviaProcessor.ProcessTrivias(writer, method.Body.DescendantTrivia());
                }

                if (pinvokeAttributes != null)
                {
                    WritePInvokeMethodBody.Go(writer, methodName, methodSymbol, pinvokeAttributes);
                }
            }

            writer.CloseBrace();
        }
        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, OperatorDeclarationSyntax method)
        {
            var methodSymbol     = (IMethodSymbol)TypeProcessor.GetDeclaredSymbol(method);
            var actualMethodName = OverloadResolver.MethodName(methodSymbol);

            writer.Write("\n");


            var returnType = "";

            if (method.ReturnType.ToString() == "void")
            {
                returnType = ("void ");
            }
            else
            {
                returnType = TypeProcessor.ConvertType(method.ReturnType) + " ";

                //                writer.Write(returnType);
            }

            var methodName = "";

            if (BinaryOperators.ContainsKey(actualMethodName))
            {
                methodName = "opBinary";
                var typeSymbolParam0 = TypeProcessor.GetTypeInfo(method.ParameterList.Parameters[0].Type);

                var typeSymbolParent = (methodSymbol.ContainingType);

                if (typeSymbolParam0.Type != typeSymbolParent)
                {
                    methodName += "Right";
                }
            }

            if (UnaryOperators.ContainsKey(actualMethodName))
            {
                methodName = "opUnary";
            }

            if (EqualsOperators.ContainsKey(actualMethodName))
            {
                methodName = "opEquals";
            }

            if (CmpOperators.ContainsKey(actualMethodName))
            {
                methodName = "opCmp";
            }

            if (AssignOperators.ContainsKey(actualMethodName))
            {
                methodName = "opAssign";
            }

            if (AssignOpOperators.ContainsKey(actualMethodName))
            {
                methodName = "opOpAssign"; // need to remove = from the name
            }
            var paramType = method.ParameterList.Parameters[0];

            if (method.ParameterList.Parameters.Count == 2)
            {
                if (methodName.EndsWith("Right"))
                {
                    paramType = method.ParameterList.Parameters[0];
                }
                else
                {
                    paramType = method.ParameterList.Parameters[1];
                }
            }

            var token = method.OperatorToken.Text;

            var methodBody = "";

            var temp = new TempWriter();

            foreach (var statement in method.Body.Statements)
            {
                Core.Write(temp, statement);
            }

            TriviaProcessor.ProcessTrivias(temp, method.Body.DescendantTrivia());

            methodBody = temp.ToString();


            if (methodName == "opOpAssign")
            {
                token = token.Substring(0, 1);
            }

            //We are going to have to rewrite this bit later ... for now all overloads are called directly

            /*    if (methodName == "opBinary")
             *  {
             *
             *      writer.WriteLine("public final " + returnType + " " + methodName +
             *      String.Format(
             *          " (string _op) ({0} other)\r\n\tif(_op==\"{2}\")\r\n\t{{ \r\n\t\treturn {1}(this,other); \r\n\t}}\r\n\r\n",
             *          TypeProcessor.ConvertType(paramType.Type), actualMethodName, token));
             *
             *      //Add Assignment operator if it doesn't exist
             *      if (!methodSymbol.ContainingType.GetMembers(AssignOpOperators.FirstOrDefault(k => k.Value == token + "=").Key).Any())
             *      {
             *          writer.WriteLine("public final " + returnType + " opOpAssign" +
             *      String.Format(
             *          " (string _op) ({0} other)\r\n\tif(_op==\"{2}\")\r\n\t{{ \r\n\t\treturn {1}(this,other); \r\n\t}}\r\n\r\n",
             *          TypeProcessor.ConvertType(paramType.Type), actualMethodName, token));
             *      }
             *  }
             *  else if (methodName == "opUnary")//TODO unary operators are mostly going to be direct methodCalls
             *  {
             *
             *      writer.WriteLine("public final " + returnType + " " + methodName +
             *          String.Format(
             *              " (string _op) ()\r\n\tif(_op==\"{2}\")\r\n\t{{ \r\n\t\treturn {1}(this); \r\n\t}}\r\n\r\n",
             *              TypeProcessor.ConvertType(paramType.Type), actualMethodName, token));
             *      //				writer.WriteLine ("public final ref " + returnType + " " + methodName +
             *      //					String.Format (
             *      //						" (string _op) ()\r\n\tif(_op==\"{2}\")\r\n\t{{ \r\n\t\t{3}\r\n\t}}\r\n\r\n",
             *      //TypeProcessor.ConvertType (paramType.Type), actualMethodName, token, methodBody.Replace(method.ParameterList.Parameters[0].Identifier.ValueText,"this")));
             *  }
             *  else
             *  {
             *      writer.WriteLine("public final " + returnType + " " + methodName +
             *          String.Format(
             *              " (string _op) ({0} other)\r\n\tif(_op==\"{2}\")\r\n\t{{ \r\n\t\treturn {1}(this); \r\n\t}}\r\n\r\n",
             *              TypeProcessor.ConvertType(paramType.Type), actualMethodName, token));
             *  }*/

            var @params = method.ParameterList.Parameters;



            writer.WriteLine("public static " + returnType + " " + actualMethodName + WriteMethod.GetParameterListAsString(method.ParameterList.Parameters));



            writer.OpenBrace();
            if (method.Body != null)
            {
                foreach (var statement in method.Body.Statements)
                {
                    Core.Write(writer, statement);
                }

                TriviaProcessor.ProcessTrivias(writer, method.Body.DescendantTrivia());
            }

            writer.CloseBrace();
        }
Example #4
0
        public static void Go(OutputWriter writer, OperatorDeclarationSyntax method)
        {
            var methodSymbol     = (IMethodSymbol)TypeProcessor.GetDeclaredSymbol(method);
            var ActualMethodName = OverloadResolver.MethodName(methodSymbol);

            //			var methodType = Program.GetModel(method).GetTypeInfo(method);

            writer.Write("\n");

            var isInterface = method.Parent is InterfaceDeclarationSyntax;

            if (method.Modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword) ||
                method.Modifiers.Any(SyntaxKind.ProtectedKeyword) || method.Modifiers.Any(SyntaxKind.AbstractKeyword) ||
                isInterface)
            {
                writer.Write("public ");
            }

            var returnType = "";

            if (method.ReturnType.ToString() == "void")
            {
                writer.Write("void ");
            }
            else
            {
//				var typeSymbol = TypeProcessor.GetTypeInfo(method.ReturnType).Type;

                //   var isPtr = typeSymbol != null && (typeSymbol.IsValueType || typeSymbol.TypeKind == TypeKind.TypeParameter) ? "" : "";
                //     var typeString = TypeProcessor.ConvertType(method.ReturnType) + isPtr + " ";

                //	            writer.Write(typeString);
                //	            writer.HeaderWriter.Write(typeString);

//				var isPtr = typeSymbol != null && (!typeSymbol.IsValueType || typeSymbol.TypeKind == TypeKind.TypeParameter);
                returnType = TypeProcessor.ConvertType(method.ReturnType) + " ";

                writer.Write(returnType);
            }

            var methodName = "";

            if (binaryOperators.Contains(method.OperatorToken.ValueText))
            {
                methodName = "opBinary";
                var typeSymbolParam0 = TypeProcessor.GetTypeInfo(method.ParameterList.Parameters[0].Type);

                var typeSymbolParent = (methodSymbol.ContainingType);

                if (typeSymbolParam0.Type != typeSymbolParent)
                {
                    methodName += "Right";
                }
            }

            if (unaryOperators.Contains(method.OperatorToken.ValueText))
            {
                methodName = "opUnary";
            }

            if (equalsOperators.Contains(method.OperatorToken.ValueText))
            {
                methodName = "opEquals";
            }

            if (cmpOperators.Contains(method.OperatorToken.ValueText))
            {
                methodName = "opCmp";
            }

            if (assignOperators.Contains(method.OperatorToken.ValueText))
            {
                methodName = "opAssign";
            }

            if (assignOpOperators.Contains(method.OperatorToken.ValueText))
            {
                methodName = "opOpAssign"; // need to remove = from the name
            }
            //method.ParameterList.Parameters[0];

            var paramType = method.ParameterList.Parameters[0];

            if (method.ParameterList.Parameters.Count == 2)
            {
                if (methodName.EndsWith("Right"))
                {
                    paramType = method.ParameterList.Parameters[0];
                }
                else
                {
                    paramType = method.ParameterList.Parameters[1];
                }
            }

            var token = method.OperatorToken.ValueText;

            if (methodName == "opOpAssign")
            {
                token = token.Substring(0, 1);
            }

            writer.Write(methodName +
                         String.Format(
                             " (string _op) ({0} other)\r\nif(_op==\"{2}\")\r\n{{ \r\nreturn {1}(this,other); \r\n}}\r\n",
                             TypeProcessor.ConvertType(paramType.Type), ActualMethodName, token));

            writer.Write("\r\n\r\npublic static " + returnType + " " + ActualMethodName);

            WriteParameterList(writer, method.ParameterList);

            writer.WriteLine();

            writer.OpenBrace();
            writer.WriteLine();
            if (method.Body != null)
            {
                foreach (var statement in method.Body.Statements)
                {
                    Core.Write(writer, statement);
                }

                TriviaProcessor.ProcessTrivias(writer, method.Body.DescendantTrivia());
            }

            writer.WriteLine();
            writer.CloseBrace();
            writer.WriteLine();
        }
        public static void WriteInstanceConstructor(OutputWriter writer, ConstructorDeclarationSyntax method)
        {
            var methodSymbol = (IMethodSymbol)TypeProcessor.GetDeclaredSymbol(method);
            var methodName   = OverloadResolver.MethodName(methodSymbol);

            //			var methodType = Program.GetModel(method).GetTypeInfo(method);

            //TODO: Improve partial class / method support
            if (method.Modifiers.Any(SyntaxKind.PartialKeyword) && method.Body == null)
            {
                //We only want to render out one of the two partial methods.  If there's another, skip this one.
                if (Context.Instance.Partials.SelectMany(o => o.Syntax.As <ClassDeclarationSyntax>().Members)
                    .OfType <ConstructorDeclarationSyntax>()
                    .Except(method).Any(o => o.Identifier.ValueText == method.Identifier.ValueText))
                {
                    return;
                }
            }

            //            if (method.Identifier.ValueText == "GetEnumerator")
            //                return; //TODO: Support enumerator methods

            writer.WriteLine();
            //            writer.WriteIndent();

            var accessmodifiers = "";

            var isInterface = method.Parent is InterfaceDeclarationSyntax;

            if (method.Modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword) ||
                method.Modifiers.Any(SyntaxKind.ProtectedKeyword) || method.Modifiers.Any(SyntaxKind.AbstractKeyword) ||
                isInterface)
            {
                accessmodifiers += ("public ");
            }

            if (method.Modifiers.Any(SyntaxKind.PrivateKeyword))
            {
                accessmodifiers += ("private ");
            }

            if (ShouldUseOverrideKeyword(method, methodSymbol))
            {
                accessmodifiers += ("override ");
            }

            //D does not use the virtual keyword
            //                if (method.Modifiers.Any(SyntaxKind.VirtualKeyword) || isInterface)
            //                    writer.Write("virtual ");
            //Need to improve performance by labling non virtual methods with "final" ... but we have to check the original definition of the method

            if (method.Modifiers.Any(SyntaxKind.StaticKeyword))
            {
                accessmodifiers += ("static ");
            }

            if (isInterface)
            {
//                writer.IsInterface = true;
            }

            //Constructors in d dont have return types
//            writer.Write("void ");
//            writer.HeaderWriter.Write("void ");

//            writer.Write("this");

//            writer.Write("(");

//            var firstParam = true;
//            foreach (var parameter in method.ParameterList.Parameters)
//            {
//                bool isRef = parameter.Modifiers.Any(SyntaxKind.OutKeyword) ||
//                             parameter.Modifiers.Any(SyntaxKind.RefKeyword);
//
//                if (firstParam)
//                    firstParam = false;
//                else
//                {
//                    writer.Write(", ");
//                }
//
//
//                var localSymbol = TypeProcessor.GetTypeInfo(parameter.Type);
//                var ptr = (localSymbol.Type != null && !localSymbol.Type.IsValueType) ? "" : "";
//
//                if (!isRef)
//                {
//                    var s = TypeProcessor.ConvertType(parameter.Type) + " " + ptr;
//                    writer.Write(s);
//                }
//                else
//                {
//
//
//
//                    var s = " ref " + TypeProcessor.ConvertType(parameter.Type) + " "; // Refs in D are simple
//
//                    writer.Write(s);
//
//                    Program.RefOutSymbols.TryAdd(TypeProcessor.GetDeclaredSymbol(parameter), null);
//                }
//
//                writer.Write(WriteIdentifierName.TransformIdentifier(parameter.Identifier.ValueText));
//
//                if (parameter.Default != null)
//                {
//                    writer.Write(" = ");
//                    Core.Write(writer, parameter.Default.Value);
//                }
//            }
//
//            writer.Write(")");

            writer.WriteLine(accessmodifiers + "this" + WriteMethod.GetParameterListAsString(method.ParameterList));

            if (isInterface || method.Modifiers.Any(SyntaxKind.AbstractKeyword))
            {
                writer.Write(" = 0;\r\n");

                return;
            }

            //if (!returnsVoid)
            //  writer.Write(" =");

//            writer.Write("\r\n");
            writer.OpenBrace();

            if (method.Initializer != null)
            {
                //writer.Write(":");
                Core.Write(writer, method.Initializer);
                writer.Write(";");
                writer.WriteLine(); //";\r\n");
            }

            if (method.Body != null)
            {
                foreach (var statement in method.Body.Statements)
                {
                    Core.Write(writer, statement);
                }

                TriviaProcessor.ProcessTrivias(writer, method.Body.DescendantTrivia());
            }

            writer.CloseBrace();
        }
Example #6
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 ? ")" : "");
                }
            }
        }
Example #7
0
        public static string GetMethodName(MemberDeclarationSyntax member, ref bool isInterface, out ITypeSymbol interfaceImplemented, out ISymbol[] proxies)
        {
            interfaceImplemented = null;
            proxies = null;
            var methodSymbol = TypeProcessor.GetDeclaredSymbol(member);
            var name         = WriteIdentifierName.TransformIdentifier(OverloadResolver.MethodName(methodSymbol));

            if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface)
            {
                isInterface          = true;
                interfaceImplemented = methodSymbol.ContainingType;
            }



            var isinterfacemethod = Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol),
                                           methodSymbol);

            if (!isinterfacemethod && methodSymbol.IsOverride)
            {
                isinterfacemethod = Equals(methodSymbol.ContainingType.BaseType.FindImplementationForInterfaceMember(methodSymbol),
                                           methodSymbol);
            }

            if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface ||
                (isinterfacemethod && methodSymbol.IsOverride))
            {
                /* name = Regex.Replace(
                 *  TypeProcessor.ConvertType(methodSymbol.ContainingType.ConstructedFrom) + "_" + name,
                 *  @" ?!\(.*?\)", String.Empty);*/

                interfaceImplemented = methodSymbol.ContainingType.ConstructedFrom;

                if (methodSymbol.ContainingType.ContainingType != null)
                {
                    name = name.RemoveFromStartOfString(methodSymbol.ContainingType.ContainingType.Name + ".");
                }
            }

            if (name.Contains(".")) // Explicit Interface method
            {
                //
                name = name.SubstringAfterLast('.');
                name = name.Replace('.', '_');
            }

            var name1 = name;

            IEnumerable <ISymbol> interfaceMethods = null;

            if (methodSymbol.IsOverride && (interfaceMethods == null || !interfaceMethods.Any()))
            {
                interfaceMethods =
                    methodSymbol.ContainingType.BaseType.AllInterfaces.SelectMany(
                        u =>
                        u.GetMembers(name1));

                if ((interfaceMethods == null || !interfaceMethods.Any()))
                {
                    interfaceMethods =
                        interfaceMethods.Where(
                            o => Equals(methodSymbol.ContainingType.BaseType.FindImplementationForInterfaceMember(o), methodSymbol));
                }
            }
            else
            {
                interfaceMethods =
                    methodSymbol.ContainingType.AllInterfaces.SelectMany(
                        u =>
                        u.GetMembers(name1));
                interfaceMethods =
                    interfaceMethods.Where(
                        o => Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(o), methodSymbol));
            }

            var enumerable      = interfaceMethods as ISymbol[] ?? interfaceMethods.ToArray();
            var interfaceMethod = enumerable.FirstOrDefault();

            if (interfaceMethods.Count() > 1)
            {
                proxies = interfaceMethods.ToArray();
            }

            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 (!member.GetModifiers().Any(SyntaxKind.NewKeyword) && methodSymbol is IMethodSymbol) // This is not neccessary for properties
                //                {
                //                    interfaceMethod =
                //                        enumerable.FirstOrDefault(k => CompareMethods(k as IMethodSymbol, (IMethodSymbol) methodSymbol));
                //                }
            }

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

                    /*  if (typenameI.Contains('.'))
                     *  typenameI = typenameI.SubstringAfterLast('.');
                     * name = (typenameI + "_") + name;*/
                }
            }

            //            if (member.GetModifiers().Any(SyntaxKind.NewKeyword) && methodSymbol.OriginalDefinition.ContainingType.TypeKind != TypeKind.Interface) //Take care of new
            //                name += "_";
            if (methodSymbol.IsNew())
            {
                // name += "_";
                interfaceImplemented = methodSymbol.OriginalDefinition.ContainingType;
            }

            GetExplicitInterface(ref interfaceImplemented, methodSymbol);

            //            if (interfaceMethods.Count() >= 1 && interfaceMethod!=null)
            //                proxies = interfaceMethods.ToArray();

            return(name);
        }
        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(")");
        }