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);
        }
Beispiel #2
0
        private static void Factory(OutputWriter writer, SyntaxNode node, bool isConst)
        {
            if (node is ConstructorInitializerSyntax)
            {
                WriteConstructorInitializer.Go(writer, node.As <ConstructorInitializerSyntax>());
            }
            else if (node is CheckedExpressionSyntax)
            {
                WriteChecked.Go(writer, node.As <CheckedExpressionSyntax>());
            }
            else if (node is CheckedStatementSyntax)
            {
                WriteChecked.Go(writer, node.As <CheckedStatementSyntax>());
            }
            else if (node is UnsafeStatementSyntax)
            {
                WriteUnsafeStatement.Go(writer, node.As <UnsafeStatementSyntax>());
            }
            else if (node is InitializerExpressionSyntax)
            {
                WriteInitializer.Go(writer, node.As <InitializerExpressionSyntax>());
            }
            else if (node is GotoStatementSyntax)
            {
                WriteGoto.Go(writer, node.As <GotoStatementSyntax>());
            }
            else if (node is CaseSwitchLabelSyntax)
            {
                WriteLabel.Go(writer, node.As <CaseSwitchLabelSyntax>());
            }
            else if (node is LabeledStatementSyntax)
            {
                WriteLabel.Go(writer, node.As <LabeledStatementSyntax>());
            }
            else if (node is OperatorDeclarationSyntax)
            {
                WriteOperatorDeclaration.Go(writer, node.As <OperatorDeclarationSyntax>());
            }
            else if (node is MethodDeclarationSyntax)
            {
                WriteMethod.Go(writer, node.As <MethodDeclarationSyntax>());
            }
            else if (node is PropertyDeclarationSyntax)
            {
                WriteProperty.Go(writer, node.As <PropertyDeclarationSyntax>());
            }
            else if (node is EventDeclarationSyntax)
            {
                WriteEvent.Go(writer, node.As <EventDeclarationSyntax>());
            }
            else if (node is FieldDeclarationSyntax)
            {
                WriteField.Go(writer, node.As <FieldDeclarationSyntax>());
            }
            else if (node is EventFieldDeclarationSyntax)
            {
                WriteField.Go(writer, node.As <EventFieldDeclarationSyntax>());
            }
            else if (node is ConstructorDeclarationSyntax)
            {
                WriteConstructorBody.Go(writer, node.As <ConstructorDeclarationSyntax>());
            }
            else if (node is ExpressionStatementSyntax)
            {
                WriteStatement(writer, node.As <ExpressionStatementSyntax>());
            }
            else if (node is FixedStatementSyntax)
            {
                WriteFixedStatement(writer, node.As <FixedStatementSyntax>());
            }
            else if (node is LocalDeclarationStatementSyntax)
            {
                WriteLocalDeclaration.Go(writer, node.As <LocalDeclarationStatementSyntax>());
            }
            else if (node is VariableDeclarationSyntax)
            {
                WriteVariableDeclaration.Go(writer, node.As <VariableDeclarationSyntax>());
            }
            else if (node is BlockSyntax)
            {
                WriteBlock(writer, node.As <BlockSyntax>());
            }
            else if (node is InvocationExpressionSyntax)
            {
                WriteInvocationExpression.Go(writer, node.As <InvocationExpressionSyntax>());
            }
            else if (node is LiteralExpressionSyntax)
            {
                WriteLiteralExpression.Go(writer, node.As <LiteralExpressionSyntax>(), isConst);
            }
            else if (node is IdentifierNameSyntax)
            {
                WriteIdentifierName.Go(writer, node.As <IdentifierNameSyntax>());
            }
            else if (node is ImplicitArrayCreationExpressionSyntax)
            {
                WriteArrayCreationExpression.Go(writer, node.As <ImplicitArrayCreationExpressionSyntax>());
            }
            else if (node is ArrayCreationExpressionSyntax)
            {
                WriteArrayCreationExpression.Go(writer, node.As <ArrayCreationExpressionSyntax>());
            }
            else if (node is MemberAccessExpressionSyntax)
            {
                WriteMemberAccessExpression.Go(writer, node.As <MemberAccessExpressionSyntax>());
            }
            else if (node is ParenthesizedLambdaExpressionSyntax)
            {
                WriteLambdaExpression.Go(writer, node.As <ParenthesizedLambdaExpressionSyntax>());
            }
            else if (node is SimpleLambdaExpressionSyntax)
            {
                WriteLambdaExpression.Go(writer, node.As <SimpleLambdaExpressionSyntax>());
            }
            else if (node is AnonymousMethodExpressionSyntax)
            {
                WriteLambdaExpression.Go(writer, node.As <AnonymousMethodExpressionSyntax>());
            }
            else if (node is ReturnStatementSyntax)
            {
                WriteReturnStatement.Go(writer, node.As <ReturnStatementSyntax>());
            }
            else if (node is ObjectCreationExpressionSyntax)
            {
                WriteObjectCreationExpression.Go(writer, node.As <ObjectCreationExpressionSyntax>());
            }
            else if (node is ElementAccessExpressionSyntax)
            {
                WriteElementAccessExpression.Go(writer, node.As <ElementAccessExpressionSyntax>());
            }
            else if (node is ForEachStatementSyntax)
            {
                WriteForEachStatement.Go(writer, node.As <ForEachStatementSyntax>());
            }
            else if (node is IfStatementSyntax)
            {
                WriteIfStatement.Go(writer, node.As <IfStatementSyntax>());
            }
            else if (node is BinaryExpressionSyntax)
            {
                WriteBinaryExpression.Go(writer, node.As <BinaryExpressionSyntax>());
            }
            else if (node is AssignmentExpressionSyntax)
            {
                WriteAssignmentExpression.Go(writer, node.As <AssignmentExpressionSyntax>());
            }
            else if (node is ConditionalExpressionSyntax)
            {
                WriteConditionalExpression.Go(writer, node.As <ConditionalExpressionSyntax>());
            }
            else if (node is BaseExpressionSyntax)
            {
                WriteBaseExpression.Go(writer, node.As <BaseExpressionSyntax>());
            }
            else if (node is ThisExpressionSyntax)
            {
                WriteThisExpression.Go(writer, node.As <ThisExpressionSyntax>());
            }
            else if (node is CastExpressionSyntax)
            {
                WriteCastExpression.Go(writer, node.As <CastExpressionSyntax>());
            }
            else if (node is ThrowStatementSyntax)
            {
                WriteThrowStatement.Go(writer, node.As <ThrowStatementSyntax>());
            }
            else if (node is EqualsValueClauseSyntax)
            {
                WriteEqualsValueClause.Go(writer, node.As <EqualsValueClauseSyntax>());
            }
            else if (node is ForStatementSyntax)
            {
                WriteForStatement.Go(writer, node.As <ForStatementSyntax>());
            }
            else if (node is WhileStatementSyntax)
            {
                WriteWhileStatement.Go(writer, node.As <WhileStatementSyntax>());
            }
            else if (node is BreakStatementSyntax)
            {
                WriteBreakStatement.Go(writer, node.As <BreakStatementSyntax>());
            }
            else if (node is ContinueStatementSyntax)
            {
                WriteContinueStatement.Go(writer, node.As <ContinueStatementSyntax>());
            }
            else if (node is DoStatementSyntax)
            {
                WriteDoStatement.Go(writer, node.As <DoStatementSyntax>());
            }
            else if (node is SwitchStatementSyntax)
            {
                WriteSwitchStatement.Go(writer, node.As <SwitchStatementSyntax>());
            }
            else if (node is TryStatementSyntax)
            {
                WriteTryStatement.Go(writer, node.As <TryStatementSyntax>());
            }
            else if (node is UsingStatementSyntax)
            {
                WriteUsingStatement.Go(writer, node.As <UsingStatementSyntax>());
            }
            else if (node is ParenthesizedExpressionSyntax)
            {
                WriteParenthesizedExpression.Go(writer, node.As <ParenthesizedExpressionSyntax>());
            }
            else if (node is LockStatementSyntax)
            {
                WriteLockStatement.Go(writer, node.As <LockStatementSyntax>());
            }
            else if (node is TypeOfExpressionSyntax)
            {
                WriteTypeOfExpression.Go(writer, node.As <TypeOfExpressionSyntax>());
            }
            else if (node is AnonymousObjectCreationExpressionSyntax)
            {
                WriteAnonymousObjectCreationExpression.Go(writer, node.As <AnonymousObjectCreationExpressionSyntax>());
            }
            else if (node is EmptyStatementSyntax)
            {
                return; //ignore empty statements
            }
            else if (node is DelegateDeclarationSyntax)
            {
                return; //don't write delegates - TypeProcessor converts them to function types directly
            }
            else if (node is DefaultExpressionSyntax)
            {
                WriteDefaultExpression.Go(writer, node.As <DefaultExpressionSyntax>());
            }
            else if (node is GenericNameSyntax)
            {
                WriteGenericName.Go(writer, node.As <GenericNameSyntax>());
            }
            else if (node is ConversionOperatorDeclarationSyntax)
            {
                WriteConversionOperatorDeclaration.Go(writer, node.As <ConversionOperatorDeclarationSyntax>());
            }
            else if (node is PrefixUnaryExpressionSyntax)
            {
                WriteUnaryExpression.WritePrefix(writer, node.As <PrefixUnaryExpressionSyntax>());
            }
            else if (node is PostfixUnaryExpressionSyntax)
            {
                WriteUnaryExpression.WritePostfix(writer, node.As <PostfixUnaryExpressionSyntax>());
            }
            else if (node is SizeOfExpressionSyntax)
            {
                WriteSizeOfExpression.Go(writer, node.As <SizeOfExpressionSyntax>());
            }
            else if (node is DestructorDeclarationSyntax)
            {
                WriteDestructorBody.WriteDestructor(writer, node.As <DestructorDeclarationSyntax>());
            }
            else if (node is IndexerDeclarationSyntax)
            {
                WriteIndexer.Go(writer, node.As <IndexerDeclarationSyntax>());
            }
            else if (node is StackAllocArrayCreationExpressionSyntax)
            {
                WriteStackArrayCreation.Go(writer, node.As <StackAllocArrayCreationExpressionSyntax>());
            }
//                writer.Write(node.ToFullString() + "//TODO: StackAlloc not supported yet");
            else if (node is YieldStatementSyntax)
            {
                WriteYieldStatement.Go(writer, node.As <YieldStatementSyntax>());
            }
            else
            {
                throw new NotImplementedException(node.GetType().Name + " is not supported. " + Utility.Descriptor(node));
            }
        }
        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(")");
        }