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()); }
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(); } } }
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(); } }
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(); }
public static void WriteIt(OutputWriter writer, MethodDeclarationSyntax method, bool isProxy = true) { writer.WriteLine(); var methodSymbol = (IMethodSymbol)TypeProcessor.GetDeclaredSymbol(method); var methodName = OverloadResolver.MethodName(methodSymbol); var pinvokeAttributes = method.GetAttribute(Context.DllImport); // Fix this to actually look for the type, not just by name ... //TODO: Improve partial class / method support -- partials classes work, methods need minor work ... if (method.Modifiers.Any(SyntaxKind.PartialKeyword) && method.Body == null) { //We only want to render out one of the two partial methods. If there's another, skip this one. if (Context.Instance.Partials.SelectMany(o => o.Syntax.As <ClassDeclarationSyntax>().Members) .OfType <MethodDeclarationSyntax>() .Except(method).Any(o => o.Identifier.ValueText == method.Identifier.ValueText)) { return; } } bool isoverride = ShouldUseOverrideKeyword(method, methodSymbol); var accessString = ""; if (isoverride) { accessString += (" override "); } var isInterface = method.Parent is InterfaceDeclarationSyntax; if (methodName == "Main" /*&& method.Modifiers.Any(SyntaxKind.PublicKeyword)*/ && method.Modifiers.Any(SyntaxKind.StaticKeyword)) { accessString = ("public "); accessString += ("static "); var methodCall = methodSymbol.ContainingNamespace.FullName() + "." + methodSymbol.ContainingType.FullName() + "." + methodName + (method.ParameterList.Parameters.Count < 1 ? "();" : "(null);"); //: "(new Array_T!(String)(args));"); // for now args not supported Context.Instance.EntryMethod = methodCall; } else { if (method.Modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword) || method.Modifiers.Any(SyntaxKind.ProtectedKeyword) || method.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface) { accessString += ("public "); } if (method.Modifiers.Any(SyntaxKind.PrivateKeyword)) { accessString += ("private "); } // if (method.Modifiers.Any(SyntaxKind.VirtualKeyword) || isInterface) // writer.Write("virtual "); // if (!(method.Modifiers.Any (SyntaxKind.VirtualKeyword) || (method.Modifiers.Any (SyntaxKind.AbstractKeyword) || isInterface || isoverride))) { // writer.Write(" final "); // } if (method.Modifiers.Any(SyntaxKind.AbstractKeyword)) { accessString += (" abstract "); } if (method.Modifiers.Any(SyntaxKind.StaticKeyword)) { accessString += ("static "); } } // if (isInterface) // { // writer.IsInterface = true; // } var returnTypeString = TypeProcessor.ConvertType(method.ReturnType) + " "; var methodSignatureString = ""; if (method.ReturnType.ToString() == "void") { returnTypeString = ("void "); } else // bool returnsVoid = method.ReturnType.ToString() == "void"; //if (!returnsVoid) { var typeSymbol = TypeProcessor.GetTypeInfo(method.ReturnType).Type; // var isPtr = typeSymbol != null && (typeSymbol.IsValueType || typeSymbol.TypeKind == TypeKind.TypeParameter) ? "" : ""; // var typeString = TypeProcessor.ConvertType(method.ReturnType) + isPtr + " "; // writer.Write(typeString); // writer.HeaderWriter.Write(typeString); var isPtr = typeSymbol != null && (!typeSymbol.IsValueType || typeSymbol.TypeKind == TypeKind.TypeParameter); } if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface || Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol), methodSymbol)) { methodName = Regex.Replace( TypeProcessor.ConvertType(methodSymbol.ContainingType.ConstructedFrom) + "_" + methodName, @" ?!\(.*?\)", string.Empty); } if (methodName.Contains(".")) // Explicit Interface method { // methodName = methodName.SubstringAfterLast('.'); methodName = methodName.Replace('.', '_'); } // var typenameI = Regex.Replace (TypeProcessor.ConvertType (interfaceMethod.ContainingType), @" ?!\(.*?\)", string.Empty); var interfaceMethods = methodSymbol.ContainingType.AllInterfaces.SelectMany( u => u.GetMembers(methodName)).ToArray(); ISymbol interfaceMethod = interfaceMethods.FirstOrDefault( o => methodSymbol.ContainingType.FindImplementationForInterfaceMember(o) == methodSymbol); if (interfaceMethod == null) { //TODO: fix this for virtual method test 7, seems roslyn cannot deal with virtual // overrides of interface methods ... so i'll provide a kludge if (!method.Modifiers.Any(SyntaxKind.NewKeyword)) { interfaceMethod = interfaceMethods.FirstOrDefault(k => CompareMethods(k as IMethodSymbol, methodSymbol)); } } if (interfaceMethod != null) // && CompareMethods(interfaceMethod ,methodSymbol)) { { //This is an interface method //TO if (methodSymbol.ContainingType.SpecialType == SpecialType.System_Array) { methodSignatureString += (""); } else { var typenameI = Regex.Replace(TypeProcessor.ConvertType(interfaceMethod.ContainingType.ConstructedFrom), @" ?!\(.*?\)", string.Empty); //TODO: we should be able to get the original interface name, or just remove all generics from this if (typenameI.Contains('.')) { typenameI = typenameI.SubstringAfterLast('.'); } methodName = (typenameI + "_") + methodName; } } // var explicitHeaderNAme = ""; //FIX ME: To support explicits, all method calls are going to be prequalified with the interface name, lets just hope we dont have similar interfaces // // if (methodSymbol.MethodKind == MethodKind.ExplicitInterfaceImplementation) // { // // var implementations = methodSymbol.ExplicitInterfaceImplementations[0]; // if (implementations != null) // { // // explicitHeaderNAme = implementations.Name; // methodName = TypeProcessor.ConvertType(implementations.ReceiverType) + "_" +implementations.Name; //Explicit fix ? // // // writer.Write(methodSymbol.ContainingType + "." + methodName); // //Looks like internal classes are not handled properly here ... // } // } // methodName = methodName.Replace(methodSymbol.ContainingNamespace.FullName() + ".", methodSymbol.ContainingNamespace.FullName().Replace(".", "::") + "::"); // (methodSymbol as).Is // (methodSymbol as Microsoft.CodeAnalysis.CSharp.Symbols.SourceMethodSymbol); if (method.Modifiers.Any(SyntaxKind.NewKeyword)) { methodName += "_"; } // writer.Write( TypeProcessor.ConvertType(methodSymbol.ContainingType)+ "." + methodName); //Dealting with explicit VMT7 // writer.Write(!String.IsNullOrEmpty(explicitHeaderNAme)? explicitHeaderNAme : methodName); // writer.Write(methodName); methodSignatureString += methodName; if (method.TypeParameterList != null) { var genericArgs = method.TypeParameterList.Parameters.ToList(); // if (genericArgs.Count > 0) // { // writer.Write("( "); // writer.Write(string.Join(" , ", genericArgs.Select(o => " " + o))); // writer.Write(" )\r\n"); // } if (genericArgs.Count > 0) // && !methodSymbol.ContainingType.IsGenericType) // doesnt matter { methodSignatureString += ("("); methodSignatureString += (string.Join(",", genericArgs.Select(o => " " + o))); methodSignatureString += (")"); } } var @params = GetParameterListAsString(method.ParameterList); var constraints = ""; if (method.ConstraintClauses.Count > 0) { constraints += (" if ("); bool isFirst = true; foreach (var constraint in method.ConstraintClauses) { foreach (var condition in constraint.Constraints) { string dlangCondition = condition.ToString(); if (dlangCondition == "new()") { continue; } if (dlangCondition == "class") // TODO: is there a better way to do this ? { dlangCondition = "NObject"; } if (dlangCondition == "struct") { constraints += ((isFirst ? "" : "&&") + " !is(" + constraint.Name + " : NObject)"); } else { constraints += ((isFirst ? "" : "&&") + " is(" + constraint.Name + " : " + dlangCondition + ")"); } isFirst = false; // Console.WriteLine (condition); } } constraints += (")"); } if (isInterface || method.Modifiers.Any(SyntaxKind.AbstractKeyword)) { writer.WriteLine(accessString + returnTypeString + methodSignatureString + @params + constraints + ";"); return; } writer.WriteLine(accessString + returnTypeString + methodSignatureString + @params + constraints); writer.OpenBrace(); if (isProxy) { @params = GetParameterListAsString(method.ParameterList, false); if (method.ReturnType.ToString() == "void") { writer.WriteLine("Value." + methodName + @params + ";"); } else { writer.WriteLine("return Value." + methodName + @params + ";"); } } else { if (method.Body != null) { foreach (var statement in method.Body.Statements) { Core.Write(writer, statement); } TriviaProcessor.ProcessTrivias(writer, method.Body.DescendantTrivia()); } if (pinvokeAttributes != null) { WritePInvokeMethodBody.Go(writer, methodName, methodSymbol, pinvokeAttributes); } } writer.CloseBrace(); }
public static void Go(OutputWriter writer, 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(); }
public static void Go(OutputWriter writer, OperatorDeclarationSyntax method) { var methodSymbol = (IMethodSymbol)TypeProcessor.GetDeclaredSymbol(method); var ActualMethodName = OverloadResolver.MethodName(methodSymbol); // var methodType = Program.GetModel(method).GetTypeInfo(method); writer.Write("\n"); var isInterface = method.Parent is InterfaceDeclarationSyntax; if (method.Modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword) || method.Modifiers.Any(SyntaxKind.ProtectedKeyword) || method.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface) { writer.Write("public "); } var returnType = ""; if (method.ReturnType.ToString() == "void") { writer.Write("void "); } else { // var typeSymbol = TypeProcessor.GetTypeInfo(method.ReturnType).Type; // var isPtr = typeSymbol != null && (typeSymbol.IsValueType || typeSymbol.TypeKind == TypeKind.TypeParameter) ? "" : ""; // var typeString = TypeProcessor.ConvertType(method.ReturnType) + isPtr + " "; // writer.Write(typeString); // writer.HeaderWriter.Write(typeString); // var isPtr = typeSymbol != null && (!typeSymbol.IsValueType || typeSymbol.TypeKind == TypeKind.TypeParameter); returnType = TypeProcessor.ConvertType(method.ReturnType) + " "; writer.Write(returnType); } var methodName = ""; if (binaryOperators.Contains(method.OperatorToken.ValueText)) { methodName = "opBinary"; var typeSymbolParam0 = TypeProcessor.GetTypeInfo(method.ParameterList.Parameters[0].Type); var typeSymbolParent = (methodSymbol.ContainingType); if (typeSymbolParam0.Type != typeSymbolParent) { methodName += "Right"; } } if (unaryOperators.Contains(method.OperatorToken.ValueText)) { methodName = "opUnary"; } if (equalsOperators.Contains(method.OperatorToken.ValueText)) { methodName = "opEquals"; } if (cmpOperators.Contains(method.OperatorToken.ValueText)) { methodName = "opCmp"; } if (assignOperators.Contains(method.OperatorToken.ValueText)) { methodName = "opAssign"; } if (assignOpOperators.Contains(method.OperatorToken.ValueText)) { methodName = "opOpAssign"; // need to remove = from the name } //method.ParameterList.Parameters[0]; var paramType = method.ParameterList.Parameters[0]; if (method.ParameterList.Parameters.Count == 2) { if (methodName.EndsWith("Right")) { paramType = method.ParameterList.Parameters[0]; } else { paramType = method.ParameterList.Parameters[1]; } } var token = method.OperatorToken.ValueText; if (methodName == "opOpAssign") { token = token.Substring(0, 1); } writer.Write(methodName + String.Format( " (string _op) ({0} other)\r\nif(_op==\"{2}\")\r\n{{ \r\nreturn {1}(this,other); \r\n}}\r\n", TypeProcessor.ConvertType(paramType.Type), ActualMethodName, token)); writer.Write("\r\n\r\npublic static " + returnType + " " + ActualMethodName); WriteParameterList(writer, method.ParameterList); writer.WriteLine(); writer.OpenBrace(); writer.WriteLine(); if (method.Body != null) { foreach (var statement in method.Body.Statements) { Core.Write(writer, statement); } TriviaProcessor.ProcessTrivias(writer, method.Body.DescendantTrivia()); } writer.WriteLine(); writer.CloseBrace(); writer.WriteLine(); }
public static void WriteInstanceConstructor(OutputWriter writer, ConstructorDeclarationSyntax method) { var methodSymbol = (IMethodSymbol)TypeProcessor.GetDeclaredSymbol(method); var methodName = OverloadResolver.MethodName(methodSymbol); // var methodType = Program.GetModel(method).GetTypeInfo(method); //TODO: Improve partial class / method support if (method.Modifiers.Any(SyntaxKind.PartialKeyword) && method.Body == null) { //We only want to render out one of the two partial methods. If there's another, skip this one. if (Context.Instance.Partials.SelectMany(o => o.Syntax.As <ClassDeclarationSyntax>().Members) .OfType <ConstructorDeclarationSyntax>() .Except(method).Any(o => o.Identifier.ValueText == method.Identifier.ValueText)) { return; } } // if (method.Identifier.ValueText == "GetEnumerator") // return; //TODO: Support enumerator methods writer.WriteLine(); // writer.WriteIndent(); var accessmodifiers = ""; var isInterface = method.Parent is InterfaceDeclarationSyntax; if (method.Modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword) || method.Modifiers.Any(SyntaxKind.ProtectedKeyword) || method.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface) { accessmodifiers += ("public "); } if (method.Modifiers.Any(SyntaxKind.PrivateKeyword)) { accessmodifiers += ("private "); } if (ShouldUseOverrideKeyword(method, methodSymbol)) { accessmodifiers += ("override "); } //D does not use the virtual keyword // if (method.Modifiers.Any(SyntaxKind.VirtualKeyword) || isInterface) // writer.Write("virtual "); //Need to improve performance by labling non virtual methods with "final" ... but we have to check the original definition of the method if (method.Modifiers.Any(SyntaxKind.StaticKeyword)) { accessmodifiers += ("static "); } if (isInterface) { // writer.IsInterface = true; } //Constructors in d dont have return types // writer.Write("void "); // writer.HeaderWriter.Write("void "); // writer.Write("this"); // writer.Write("("); // var firstParam = true; // foreach (var parameter in method.ParameterList.Parameters) // { // bool isRef = parameter.Modifiers.Any(SyntaxKind.OutKeyword) || // parameter.Modifiers.Any(SyntaxKind.RefKeyword); // // if (firstParam) // firstParam = false; // else // { // writer.Write(", "); // } // // // var localSymbol = TypeProcessor.GetTypeInfo(parameter.Type); // var ptr = (localSymbol.Type != null && !localSymbol.Type.IsValueType) ? "" : ""; // // if (!isRef) // { // var s = TypeProcessor.ConvertType(parameter.Type) + " " + ptr; // writer.Write(s); // } // else // { // // // // var s = " ref " + TypeProcessor.ConvertType(parameter.Type) + " "; // Refs in D are simple // // writer.Write(s); // // Program.RefOutSymbols.TryAdd(TypeProcessor.GetDeclaredSymbol(parameter), null); // } // // writer.Write(WriteIdentifierName.TransformIdentifier(parameter.Identifier.ValueText)); // // if (parameter.Default != null) // { // writer.Write(" = "); // Core.Write(writer, parameter.Default.Value); // } // } // // writer.Write(")"); writer.WriteLine(accessmodifiers + "this" + WriteMethod.GetParameterListAsString(method.ParameterList)); if (isInterface || method.Modifiers.Any(SyntaxKind.AbstractKeyword)) { writer.Write(" = 0;\r\n"); return; } //if (!returnsVoid) // writer.Write(" ="); // writer.Write("\r\n"); writer.OpenBrace(); if (method.Initializer != null) { //writer.Write(":"); Core.Write(writer, method.Initializer); writer.Write(";"); writer.WriteLine(); //";\r\n"); } if (method.Body != null) { foreach (var statement in method.Body.Statements) { Core.Write(writer, statement); } TriviaProcessor.ProcessTrivias(writer, method.Body.DescendantTrivia()); } writer.CloseBrace(); }
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(); } } }