Пример #1
0
        public static string WriteBlock(BlockSyntax block, bool writeBraces = true, int indent = 0)
        {
            var writer = new TempWriter();

            writer.Indent = indent;
            if (writeBraces)
            {
                writer.OpenBrace();
            }

            //writer.Indent++;
            foreach (var statement in block.Statements)
            {
                // writer.WriteIndent();
                Write(writer, statement);
            }

            TriviaProcessor.ProcessTrivias(writer, block.DescendantTrivia());
            // writer.Indent--;

            if (writeBraces)
            {
                writer.CloseBrace();
            }

            return(writer.ToString());
        }
Пример #2
0
        public static void Write(OutputWriter writer, SyntaxNode node, bool isConst = false)
        {
            //Write Leading Trivia
            TriviaProcessor.WriteLeadingTrivia(writer, node);

            TriviaProcessor.ProcessNode(writer, node);

            if (Program.DoNotWrite.ContainsKey(node))
            {
                return;
            }

            Factory(writer, node, isConst);

            TriviaProcessor.WriteTrailingTrivia(writer, node);
        }
Пример #3
0
        public static void WriteStatementAsBlock(OutputWriter writer, StatementSyntax statement, bool writeBraces = true)
        {
            if (statement is BlockSyntax)
            {
                WriteBlock(writer, statement.As <BlockSyntax>(), writeBraces);
            }
            else
            {
                if (writeBraces)
                {
                    writer.OpenBrace();
                }

                Write(writer, statement);
                TriviaProcessor.ProcessTrivias(writer, statement.DescendantTrivia());

                if (writeBraces)
                {
                    writer.CloseBrace();
                }
            }
        }
Пример #4
0
        public static void WriteBlock(OutputWriter writer, BlockSyntax block, bool writeBraces = true)
        {
            if (writeBraces)
            {
                writer.OpenBrace();
            }

            //writer.Indent++;
            foreach (var statement in block.Statements)
            {
                // writer.WriteIndent();
                Write(writer, statement);
            }

            TriviaProcessor.ProcessTrivias(writer, block.DescendantTrivia());
            // writer.Indent--;

            if (writeBraces)
            {
                writer.CloseBrace();
            }
        }
Пример #5
0
        public static void WriteInstanceConstructor(OutputWriter writer, ConstructorDeclarationSyntax method,
                                                    List <string> otherInits)
        {
            writer.WriteLine();

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

            // Reflection cannot work with this, cant get address or set value
            //if (method.Modifiers.Any(SyntaxKind.PrivateKeyword))
            //    accessmodifiers += ("private ");


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


            var constructorName = "this";

            if (Context.Instance.Type.TypeKind == TypeKind.Struct)             // Struct
            {
                constructorName = " void __init";
            }

            writer.WriteLine(accessmodifiers + constructorName + WriteMethod.GetParameterListAsString(method.ParameterList.Parameters));

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

                return;
            }

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

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

            if (otherInits != null)             //We need to write the static initializers before anything else
            {
                foreach (var statement in otherInits)
                {
                    var nodeString = statement;

                    if (nodeString != null)
                    {
                        writer.WriteLine(nodeString);
                    }
                }
            }

            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();
        }
Пример #6
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();
        }
Пример #7
0
        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();
        }
Пример #8
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();
        }
Пример #9
0
        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();
        }
Пример #10
0
        public static void WriteIt(OutputWriter writer, MethodDeclarationSyntax method, bool isProxy = true, IEnumerable <ITypeSymbol> virtualGenericClasses = null)
        {
            var methodSymbol = (IMethodSymbol)TypeProcessor.GetDeclaredSymbol(method);
            var isYield      = YieldChecker.HasYield(method);//method.DescendantNodes().OfType<YieldStatementSyntax>().Any();


            writer.WriteLine();



            var pinvokeAttributes = method.GetAttribute(Context.DllImport);
            var isInternalPInvoke = pinvokeAttributes == null && method.Modifiers.Any(SyntaxKind.ExternKeyword);

            //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.Text == method.Identifier.Text))
                {
                    return;
                }
            }



            var accessString = "";



            var isInterface = method.Parent is InterfaceDeclarationSyntax;

            ITypeSymbol iface;

            ISymbol[] proxies;
            var       methodName         = MemberUtilities.GetMethodName(method, ref isInterface, out iface, out proxies); //
            var       originalMethodName = methodName;
            var       containingType     = iface == null ? methodSymbol.ContainingType : iface;

            if (virtualGenericClasses != null)
            {
                methodName   = TypeProcessor.ConvertType(containingType, false, false, false).Replace(".", "_") + "_" + methodName;
                accessString = "public static final ";
            }
            else 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
            {
                accessString = MemberUtilities.GetAccessModifiers(method, isInterface || methodSymbol.IsAbstract);
            }


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

            if (method.ReturnType.ToString() == "void")
            {
                returnTypeString = ("void ");
            }

            methodSignatureString += methodName;

            var genericParameters = "";

            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
                {
                    genericParameters += ("(");
                    genericParameters += (string.Join(",", genericArgs.Select(o => o)));
                    genericParameters += (")");
                }
            }
            methodSignatureString += genericParameters;
            var @params = GetParameterListAsString(method.ParameterList.Parameters,
                                                   iface: proxies == null ? iface : null, genericClass: virtualGenericClasses != null ? containingType : null);


//            if (virtualGenericClasses != null)
//            {
//                @params = TypeProcessor.ConvertType() +  ", " + @params;
//            }
            string constraints = GetMethodConstraints(method);

            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.Parameters, includeTypes: false);

                if (virtualGenericClasses != null)
                {
                    /*
                     * public final static void Program_IBase_GenericVirtual_Dispatch(T)(Program.IBase aobj)
                     * {
                     * Object obj = cast(Object) aobj;
                     * if((typeid(obj)==typeid(Program.B)))
                     * (cast(Program.B)obj).GenericVirtual!(T)();
                     * if((typeid(obj)==typeid(Program.A)))
                     * (cast(Program.A)obj).GenericVirtual!(T)();
                     *
                     * }
                     */
                    writer.WriteLine("NObject ___obj = cast(NObject)__obj;");
                    foreach (var virtualGenericClass in virtualGenericClasses)
                    {
                        var className = TypeProcessor.ConvertType(virtualGenericClass);
                        writer.WriteLine("if(typeid(___obj)==typeid({0}))", className);

                        if (method.ReturnType.ToString() == "void")
                        {
                            writer.WriteLine("(cast({0})___obj)." + originalMethodName + "!" + genericParameters + @params + ";", className);
                        }
                        else
                        {
                            writer.WriteLine("return (cast({0})___obj)." + methodSignatureString + "!" + genericParameters + ";", className);
                        }
                    }
                }
                else
                {
                    if (method.ReturnType.ToString() == "void")
                    {
                        writer.WriteLine("__Value." + methodName + @params + ";");
                    }
                    else
                    {
                        writer.WriteLine("return __Value." + methodName + @params + ";");
                    }
                }
            }
            else
            {
                if (!isProxy && isYield)
                {
                    var namedTypeSymbol = methodSymbol.ReturnType as INamedTypeSymbol;
                    if (namedTypeSymbol != null)
                    {
                        // var iteratortype = namedTypeSymbol.TypeArguments[0];

                        var className = methodSymbol.GetYieldClassName() + (
                            (((INamedTypeSymbol)methodSymbol.ReturnType).TypeArguments.Any() && ((INamedTypeSymbol)methodSymbol.ReturnType).TypeArguments[0].TypeKind == TypeKind.TypeParameter) ? "__G" : "");


                        methodSignatureString = methodName + genericParameters;

                        if (!String.IsNullOrEmpty(genericParameters))
                        {
                            className = className + "!" + genericParameters;
                        }
                        var @params2 = GetParameterListAsString(method.ParameterList.Parameters, iface: methodSymbol.ContainingType);
                        var @params3 = GetParameterListAsString(method.ParameterList.Parameters, iface: null,
                                                                includeTypes: false, writebraces: false);

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

                        //writer.OpenBrace();

                        if (!methodSymbol.IsStatic)
                        {
                            if (method.ParameterList.Parameters.Count > 0)
                            {
                                writer.WriteLine("return new " + className + "(this," + @params3 + ");");
                            }
                            else
                            {
                                writer.WriteLine("return new " + className + "(this);");
                            }
                        }
                        else
                        {
                            writer.WriteLine("return new " + className + "(" + @params3 + ");");
                        }
                    }
                }
                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);
                }

                if (isInternalPInvoke)
                {
                    WritePInvokeMethodBody.Go(writer, methodName, methodSymbol, null);
                }

                if (!isProxy && isYield)
                {
                    //writer.WriteLine("});");
                }
            }

            writer.CloseBrace();

            if (proxies != null)
            {
                foreach (var proxy in proxies)
                {
                    //Need to write proxy signature here ...

                    methodSignatureString = methodName + genericParameters;
                    var @params2 = GetParameterListAsString(method.ParameterList.Parameters, iface: proxy.ContainingType);
                    var @params3 = GetParameterListAsString(method.ParameterList.Parameters, iface: null,
                                                            includeTypes: false);

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

                    writer.OpenBrace();

                    if (method.ReturnType.ToString() == "void")
                    {
                        writer.WriteLine("" + methodName + @params3 + ";");
                    }
                    else
                    {
                        writer.WriteLine("return " + methodName + @params3 + ";");
                    }

                    writer.CloseBrace();
                }
            }
        }