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

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

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

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

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

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

            return(ret);
        }
Esempio n. 2
0
        public static void WriteParameterList(OutputWriter writer, ParameterListSyntax list)
        {
            writer.Write("(");
            var firstParam = true;

            foreach (var parameter in list.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 || localSymbol.Type.TypeKind == TypeKind.TypeParameter));
                if (!isRef)
                {
                    //  var s = TypeProcessor.ConvertType(parameter.Type) + " " + ptr;
                    var s = TypeProcessor.ConvertType(parameter.Type) + " ";
                    writer.Write(s);
                }
                else
                {
                    //                    var s = "" + TypeProcessor.ConvertType(parameter.Type) + ptr + "& ";
                    var s = " ref " + TypeProcessor.ConvertType(parameter.Type) + " ";
                    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(") ");
        }
Esempio n. 3
0
        private static bool ShouldUseOverrideKeyword(MemberDeclarationSyntax member, bool isInterface)
        {
            ISymbol symbol = TypeProcessor.GetDeclaredSymbol(member);

            if (symbol is IMethodSymbol)
            {
                if ((symbol as IMethodSymbol).IsGenericMethod)
                {
                    return(false);
                }
            }

            if (symbol.ContainingType.TypeKind == TypeKind.Struct ||
                symbol.ContainingType.TypeKind == TypeKind.Interface)
            {
                return(false);
                // Structs dont have a base class to override (maybe opEquals) ... but that will be handled separately
                //Interfaces are contracts, so no overriding here// maybe we should compare the methods
            }

            if (member.GetModifiers().Any(SyntaxKind.OverrideKeyword) && !isInterface)
            {
                return(true);
            }


            if (member.GetModifiers().Any(SyntaxKind.StaticKeyword))
            {
                return(false);
            }
            //          if (method.Modifiers.Any(SyntaxKind.NewKeyword))
            //              return  symbol.ContainingType.BaseType.GetMembers(symbol.Name).Any(k=>k.IsAbstract || k.IsVirtual);

            if (member.GetModifiers().Any(SyntaxKind.PartialKeyword))
            {
                //partial methods seem exempt from C#'s normal override keyword requirement, so we have to check manually to see if it exists in a base class
                return(symbol.ContainingType.BaseType.GetMembers(symbol.Name).Any());
            }

            return(member.GetModifiers().Any(SyntaxKind.OverrideKeyword));
        }
        public static void Go(OutputWriter writer, VariableDeclarationSyntax declaration)
        {
            foreach (var variable in declaration.Variables)
            {
                ISymbol symbol = TypeProcessor.GetDeclaredSymbol(variable);

                var isRef = false; //UsedAsRef(variable, symbol);

                writer.WriteIndent();
                // writer.Write("var ");

                //                if (isRef) //Not needed c++ can passby ref
                //                {
                //
                //                    var typeStr = TypeProcessor.ConvertType(declaration.Declaration.Type);
                //
                //                    var localSymbol = symbol as ILocalSymbol;
                //                    var ptr = localSymbol != null && !localSymbol.Type.IsValueType?"*" : "";
                //                                        writer.Write("gc::gc_ptr < " + typeStr+ ptr + " >");
                //                    writer.Write("" + typeStr + ptr + "");
                //
                //                    writer.Write(" ");
                //                    writer.Write(WriteIdentifierName.TransformIdentifier(variable.Identifier.Text));
                //
                //                    Program.RefOutSymbols.TryAdd(symbol, null);
                //
                //                    writer.Write(" = std::make_shared < ");
                //                    writer.Write(typeStr + ptr);
                //                    writer.Write(" >(");
                //
                //                    WriteInitializer(writer, declaration, variable);
                //
                //                    writer.Write(")");
                //                }
                //                else
                {
                    var lsymbol = symbol as ILocalSymbol;

                    if (lsymbol != null && lsymbol.Type.IsValueType == false)
                    {
                        writer.Write(" ");
// Ideally Escape analysis should take care of this, but for now all value types are on heap and ref types on stack
                    }

                    writer.Write(TypeProcessor.ConvertType(declaration.Type));

                    if (lsymbol != null && lsymbol.Type.IsValueType == false)
                    {
                        writer.Write(" ");
                    }

                    writer.Write(" ");
                    writer.Write(WriteIdentifierName.TransformIdentifier(variable.Identifier.Text));
                    writer.Write(" = ");

                    WriteInitializer(writer, declaration, variable);
                }

                writer.Write(";\r\n");
            }
        }
Esempio n. 5
0
        public static void Go(OutputWriter writer, EventDeclarationSyntax property)
        {
            writer.WriteLine("\r\n");
            var rEf = ""; //" ref ";// ref should be used based on analysis, is the return type a single var or not
            //TODO, doesnt ref make things slower ?, though it makes proprties behave as in c#

            var isInterface = property.Parent is InterfaceDeclarationSyntax;

            var add =
                property.AccessorList.Accessors.SingleOrDefault(
                    o => o.Keyword.RawKind == (decimal)SyntaxKind.AddKeyword);
            var remove =
                property.AccessorList.Accessors.SingleOrDefault(
                    o => o.Keyword.RawKind == (decimal)SyntaxKind.RemoveKeyword);
            var eventSymbol = TypeProcessor.GetDeclaredSymbol(property);

            var methodSymbol =
                (TypeProcessor.GetDeclaredSymbol(add) ?? TypeProcessor.GetDeclaredSymbol(remove)) as IMethodSymbol;

            ITypeSymbol interfaceImplemented;

            ISymbol[] proxies;
            ;

            var methodName = WriteIdentifierName.TransformIdentifier(MemberUtilities.GetMethodName(eventSymbol, ref isInterface, out interfaceImplemented, out proxies));

            Action <AccessorDeclarationSyntax, bool> writeRegion = (region, get) =>
            {
                writer.WriteIndent();

                //                if (property.Modifiers.Any(SyntaxKind.PrivateKeyword))
                //                    writer.HeaderWriter.Write("private:\n");
                //
                //                if (property.Modifiers.Any(SyntaxKind.PublicKeyword) || property.Modifiers.Any(SyntaxKind.InternalKeyword))
                //                    writer.HeaderWriter.Write("public ");
                var typeinfo = TypeProcessor.GetTypeInfo(property.Type);
                var isPtr    = "";

                var typeString = TypeProcessor.ConvertType(property.Type) + isPtr + " ";

                if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || region.Body == null)
                {
                    writer.Write(" abstract ");
                }

                if (property.Modifiers.Any(SyntaxKind.OverrideKeyword))
                {
                    writer.Write(" override ");
                }


                writer.Write("void ");



                writer.Write(
                    (get ? "Add_" : "Remove_") + methodName + "( " + typeString + " value");

                if (isInterface)
                {
                    writer.WriteLine(" , " + TypeProcessor.ConvertType(interfaceImplemented) + " __ij = null");
                }

                writer.Write(" )");

                if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || region.Body == null)
                {
                    writer.Write(";\r\n");
                }
                else
                {
                    //                    writer.Write(";\r\n");

                    writer.OpenBrace();
                    // writer.Write(" =\r\n");
                    Core.WriteBlock(writer, region.Body.As <BlockSyntax>());

                    writer.CloseBrace();
                    writer.Write("\r\n");
                }
            };

            if (add == null && remove == null)
            {
                throw new Exception("Event must have both a add and remove");
            }

            {
                var name       = WriteIdentifierName.TransformIdentifier(property.Identifier.Text);
                var type       = property.Type;
                var typeinfo   = TypeProcessor.GetTypeInfo(type);
                var modifiers  = property.Modifiers;
                var typeString = TypeProcessor.ConvertType(type) + " ";
                var isStatic   = false;
                //Handle Auto Properties

                var accessors    = property.AccessorList.Accessors; //.Where(o=>o.Body==null);
                var accessString = "";
                if (modifiers.Any(SyntaxKind.PrivateKeyword))
                {
                    accessString += (" private ");
                }

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



                var IsStatic = "";

                if (modifiers.Any(SyntaxKind.StaticKeyword))
                {
                    isStatic = true;
                    IsStatic = accessString += " static ";
                    //  writer.HeaderWriter.Write("static ");
                }

                var fieldName = "__evt__" + name + (interfaceImplemented != null?TypeProcessor.ConvertType(interfaceImplemented)
                                                    .Replace("(", "_").Replace("!", "_").Replace(")", "_").Replace(".", "_") :"");
                if (!(property.Parent is InterfaceDeclarationSyntax))
                {
                    if (!isStatic)
                    {
                        writer.Write("private " + "__Event!(" + typeString + ") " + fieldName + ";\r\n");
                        // Internal Field used for event
                        writer.Write(accessString);
                        writer.WriteLine("__Event!(" + typeString + ") " + name + "(" + (interfaceImplemented != null ? (TypeProcessor.ConvertType(interfaceImplemented) + " __ij = null") :"") + ") @property");
                        writer.OpenBrace();

                        writer.WriteLine("if (" + fieldName + " is null)");
                        writer.OpenBrace();
                        writer.Write(fieldName + " =  new " + "__Event!(" + typeString + ")(new Action__G!(" +
                                     typeString +
                                     ")(&Add_" + name + "),new Action__G!(" + typeString + ")(&Remove_" + name + ") );");
                        writer.CloseBrace();
                        writer.Write("return " + fieldName + ";");
                        writer.CloseBrace();
                    }
                    else
                    {
                        writer.Write(IsStatic);
                        writer.Write("__Event!(" + typeString + ") " + name + ";\r\n");
                    }
                }

//
                var isOverride = property.Modifiers.Any(SyntaxKind.NewKeyword) ||
                                 property.Modifiers.Any(SyntaxKind.OverrideKeyword)
                    ? " override "
                    : "";
                var isVirtual = //property.Modifiers.Any(SyntaxKind.VirtualKeyword) ||
                                property.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface
                        ? " abstract "
                        : "";

                //Adder
                if (add != null && add.Body == null)
                {
                    writer.Write(IsStatic);
                    //if (property.Modifiers.Any(SyntaxKind.AbstractKeyword)||isInterface)
                    {
                        writer.WriteLine(" " + isVirtual + " void Add_" + name + "(" + typeString + " value)" +
                                         isOverride + "" + ";");
                    }
//					else
//						writer.WriteLine(" "+isVirtual + " void Add_" + name + "(" + typeString + " value)" +
//							isOverride + " {" + fieldName + " = value;}");
                }
                else if (add != null)
                {
                    writer.Write(IsStatic);
                    writeRegion(add, true);
                }

                //Remover
                if (remove != null && remove.Body == null)
                {
                    writer.Write(IsStatic);
                    //if (property.Modifiers.Any(SyntaxKind.AbstractKeyword)||isInterface)
                    {
                        writer.WriteLine(" " + isVirtual + " void Remove_" + name + "(" + typeString + " value)" +
                                         isOverride + "" + ";");
                    }
                }
                else if (remove != null)
                {
                    writer.Write(IsStatic);
                    writeRegion(remove, false);
                }

                if (isStatic)
                {
                    var staticWriter = new OutputWriter("", "", false);

                    staticWriter.Write(name);

                    staticWriter.Write(" =  new " + "__Event!(" + typeString + ")(new Action__G!(" + typeString +
                                       ")(&Add_" + name + "),new Action__G!(" + typeString +
                                       ")(&Remove_" + name + ") )");

                    staticWriter.Write(";");

                    staticWriter.WriteLine();

                    Context.Instance.StaticInits.Add(staticWriter.ToString());
                }
            }
        }
Esempio n. 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();
        }
Esempio n. 7
0
        public static void Go(OutputWriter writer, EventDeclarationSyntax property)
        {
            writer.WriteLine("\r\n");
            var rEf = ""; //" ref ";// ref should be used based on analysis, is the return type a single var or not
            //TODO, doesnt ref make things slower ?, though it makes proprties behave as in c#

            var isInterface = property.Parent is InterfaceDeclarationSyntax;

            var add =
                property.AccessorList.Accessors.SingleOrDefault(
                    o => o.Keyword.RawKind == (decimal)SyntaxKind.AddKeyword);
            var remove =
                property.AccessorList.Accessors.SingleOrDefault(
                    o => o.Keyword.RawKind == (decimal)SyntaxKind.RemoveKeyword);

            var methodSymbol =
                (TypeProcessor.GetDeclaredSymbol(add) ?? TypeProcessor.GetDeclaredSymbol(remove)) as IMethodSymbol;

            Action <AccessorDeclarationSyntax, bool> writeRegion = (region, get) =>
            {
                writer.WriteIndent();

                //                if (property.Modifiers.Any(SyntaxKind.PrivateKeyword))
                //                    writer.HeaderWriter.Write("private:\n");
                //
                //                if (property.Modifiers.Any(SyntaxKind.PublicKeyword) || property.Modifiers.Any(SyntaxKind.InternalKeyword))
                //                    writer.HeaderWriter.Write("public ");
                var typeinfo = TypeProcessor.GetTypeInfo(property.Type);
                var isPtr    = "";

                var typeString = TypeProcessor.ConvertType(property.Type) + isPtr + " ";

                if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || region.Body == null)
                {
                    writer.Write(" abstract ");
                }

                if (property.Modifiers.Any(SyntaxKind.OverrideKeyword))
                {
                    writer.Write(" override ");
                }

                //TODO: look at final and other optimizations
                //				if (!(property.Modifiers.Any (SyntaxKind.VirtualKeyword) || (property.Modifiers.Any (SyntaxKind.AbstractKeyword)) || isInterface || property.Modifiers.Any(SyntaxKind.OverrideKeyword)) ) {
                //					writer.Write(" final ");
                //				}

                //no inline in D
                //	if (get)
                //	{

                //		writer.Write(" " + rEf+ typeString + " ");
                //                    writer.Write(typeString + " ");
                //	}
                //	else
                //	{
                //                    writer.Write("_=(value");
                //                    writer.Write(TypeProcessor.ConvertTypeWithColon(property.Type));
                //                    writer.Write(")");

                writer.Write("void ");
                //                    writer.Write(" " + "void ");

                //	}
                //not needed for Dlang
                var methodName = (get ? "" : "") +
                                 WriteIdentifierName.TransformIdentifier(property.Identifier.ValueText);
                var explicitHeaderNAme = "";
                if (methodSymbol != null && methodSymbol.MethodKind == MethodKind.ExplicitInterfaceImplementation)
                {
                    var implementations = methodSymbol.ExplicitInterfaceImplementations[0];
                    if (implementations != null)
                    {
                        explicitHeaderNAme = implementations.Name;
                        methodName         =                       //implementations.ReceiverType.FullName() + "." +
                                             implementations.Name; //Explicit fix ?

                        //			writer.Write(methodSymbol.ContainingType + "." + methodName);
                        //Looks like internal classes are not handled properly here ...
                    }
                }
                if (methodSymbol != null)
                {
                    // methodName = methodName.Replace(methodSymbol.ContainingNamespace.FullName() + ".", methodSymbol.ContainingNamespace.FullName() + ".");

                    //   writer.Write((methodSymbol.ContainingType.FullName() + "." + methodName) + (get ? "()" : "( " + typeString + " value )")); //Dealing with explicit VMT7
                }
                if (property.Modifiers.Any(SyntaxKind.NewKeyword))
                {
                    methodName += "_";
                }

                writer.Write(
                    //(!String.IsNullOrEmpty(explicitHeaderNAme) ? explicitHeaderNAme : methodName)
                    (get ? "Add_" : "Remove_") + methodName + "( " + typeString + " value )");

                if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || region.Body == null)
                {
                    writer.Write(";\r\n");
                }
                else
                {
                    //                    writer.Write(";\r\n");

                    writer.OpenBrace();
                    // writer.Write(" =\r\n");
                    Core.WriteBlock(writer, region.Body.As <BlockSyntax>());

                    writer.CloseBrace();
                    writer.Write("\r\n");
                }
            };

            if (add == null && remove == null)
            {
                throw new Exception("Property must have either a get or a set");
            }

            // if (getter != null && setter != null && setter.Body == null && getter.Body == null)
            {
                //Both get and set are null, which means this is an automatic property.  For our purposes, this is the equivilant of a field//Nope

                //                WriteField.Go(writer,property, property.Modifiers, WriteIdentifierName.TransformIdentifier(property.Identifier.ValueText), property.Type);
                var name      = WriteIdentifierName.TransformIdentifier(property.Identifier.ValueText);
                var type      = property.Type;
                var typeinfo  = TypeProcessor.GetTypeInfo(type);
                var modifiers = property.Modifiers;
                var isPtr     = typeinfo.Type != null &&
                                (typeinfo.Type.IsValueType || typeinfo.Type.TypeKind == TypeKind.TypeParameter)
                    ? ""
                    : "";
                var typeString = TypeProcessor.ConvertType(type) + isPtr + " ";
                var isStatic   = false;
                //Handle Auto Properties

                var accessors    = property.AccessorList.Accessors; //.Where(o=>o.Body==null);
                var accessString = "";
                if (modifiers.Any(SyntaxKind.PrivateKeyword))
                {
                    accessString += (" private ");
                }

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

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

                //                if (modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword) || modifiers.Any(SyntaxKind.ProtectedKeyword) || modifiers.Any(SyntaxKind.AbstractKeyword))
                //                        writer.HeaderWriter.WriteLine("public: ");

                var IsStatic = "";

                if (modifiers.Any(SyntaxKind.StaticKeyword))
                {
                    isStatic = true;
                    IsStatic = accessString += " static ";
                    //  writer.HeaderWriter.Write("static ");
                }

                var fieldName = "__evt__" + name;
                if (!isStatic)
                {
                    writer.Write("private " + "Event!(" + typeString + ") " + fieldName + ";\r\n");
                    // Internal Field used for event
                    writer.Write(accessString);
                    writer.WriteLine("Event!(" + typeString + ") " + name + "() @property");
                    writer.OpenBrace();

                    writer.WriteLine("if (" + fieldName + " is null)");
                    writer.OpenBrace();
                    writer.Write(fieldName + " =  new " + "Event!(" + typeString + ")(new Action_T!(" + typeString +
                                 ")(&Add_" + name + "),new Action_T!(" + typeString + ")(&Remove_" + name + ") );");
                    writer.CloseBrace();
                    writer.Write("return " + fieldName + ";");
                    writer.CloseBrace();
                }
                else
                {
                    writer.Write(IsStatic);
                    writer.Write("Event!(" + typeString + ") " + name + ";\r\n");
                }

//
                var isOverride = property.Modifiers.Any(SyntaxKind.NewKeyword) ||
                                 property.Modifiers.Any(SyntaxKind.OverrideKeyword)
                    ? " override "
                    : "";
                var isVirtual = //property.Modifiers.Any(SyntaxKind.VirtualKeyword) ||
                                property.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface
                        ? " abstract "
                        : "";
//				if(!isInterface)
//				if ((add!=null && add.Body == null) ||
//					(remove != null && remove.Body == null) && (!property.Modifiers.Any(SyntaxKind.AbstractKeyword)))
//				{
//
//					writer.Write (IsStatic);
//					var initString = "";//isStatic?"":(" = " + TypeProcessor.DefaultValue (type));
//					writer.Write (typeString + fieldName + initString + ";\r\n");
//
//				}

                //Adder
                if (add != null && add.Body == null)
                {
                    writer.Write(IsStatic);
                    //if (property.Modifiers.Any(SyntaxKind.AbstractKeyword)||isInterface)
                    {
                        writer.WriteLine(" " + isVirtual + " void Add_" + name + "(" + typeString + " value)" +
                                         isOverride + "" + ";");
                    }
//					else
//						writer.WriteLine(" "+isVirtual + " void Add_" + name + "(" + typeString + " value)" +
//							isOverride + " {" + fieldName + " = value;}");
                }
                else if (add != null)
                {
                    writer.Write(IsStatic);
                    writeRegion(add, true);
                }

                //Remover
                if (remove != null && remove.Body == null)
                {
                    writer.Write(IsStatic);
                    //if (property.Modifiers.Any(SyntaxKind.AbstractKeyword)||isInterface)
                    {
                        writer.WriteLine(" " + isVirtual + " void Remove_" + name + "(" + typeString + " value)" +
                                         isOverride + "" + ";");
                    }
                    //else
                    //	writer.WriteLine(" "+isVirtual + " void Remove_" + name + "(" + typeString + " value)" +
                    //		isOverride + " {" + fieldName + " = value;}");
                }
                else if (remove != null)
                {
                    writer.Write(IsStatic);
                    writeRegion(remove, false);
                }

                if (isStatic)
                {
                    var staticWriter = new OutputWriter("", "", false);

                    staticWriter.Write(name);

                    staticWriter.Write(" =  new " + "Event!(" + typeString + ")(new Action_T!(" + typeString +
                                       ")(__ToDelegate(&Add_" + name + ")),new Action_T!(" + typeString +
                                       ")(__ToDelegate(&Remove_" + name + ")) )");

                    staticWriter.Write(";");

                    staticWriter.WriteLine();

                    Context.Instance.StaticInits.Add(staticWriter.ToString());
                }
                else
                {
                    var staticWriter = new OutputWriter("", "", false);

                    staticWriter.Write(name);

                    staticWriter.Write(" =  new " + "Event!(" + typeString + ")(new Action_T!(" + typeString +
                                       ")((&Add_" + name + ")),new Action_T!(" + typeString + ")((&Remove_" + name +
                                       ")) )");

                    staticWriter.Write(";");

                    staticWriter.WriteLine();

                    Context.Instance.InstanceInits.Add(staticWriter.ToString());
                }
//						if (CSharpExtensions.CSharpKind (initializerOpt.Value) == SyntaxKind.CollectionInitializerExpression || CSharpExtensions.CSharpKind (initializerOpt.Value) == SyntaxKind.ArrayInitializerExpression)
//						{
//
//
//							staticWriter.Write ("new " + typeStringNoPtr + " ([");
//
//
//						}
//						Core.Write (staticWriter, initializerOpt.Value);
//						if (CSharpExtensions.CSharpKind (initializerOpt.Value) == SyntaxKind.CollectionInitializerExpression || CSharpExtensions.CSharpKind (initializerOpt.Value) == SyntaxKind.ArrayInitializerExpression)
//						{
//
//
//							staticWriter.Write ("])");
//						}
            }
        }
        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();
        }
Esempio n. 9
0
        public static void Go(OutputWriter writer, BasePropertyDeclarationSyntax property, bool isProxy = false)
        {
            writer.WriteLine();
            //TODO, doesnt ref make things slower ?, though it makes proprties behave as in c#

            var isInterface = property.Parent is InterfaceDeclarationSyntax;

            var getter =
                property.AccessorList.Accessors.SingleOrDefault(
                    o => o.Keyword.RawKind == (decimal)SyntaxKind.GetKeyword);
            var setter =
                property.AccessorList.Accessors.SingleOrDefault(
                    o => o.Keyword.RawKind == (decimal)SyntaxKind.SetKeyword);

            var isYield  = getter != null && getter.DescendantNodes().OfType <YieldStatementSyntax>().Any();
            var isStatic = property.Modifiers.Any(k => k.IsKind(SyntaxKind.StaticKeyword));

            ITypeSymbol iface;

            ISymbol[] proxies;

            var name = MemberUtilities.GetMethodName(property, ref isInterface, out iface, out proxies);

            var modifiers      = property.Modifiers;
            var propertySymbol = (IPropertySymbol)TypeProcessor.GetDeclaredSymbol(property);
            var type           = propertySymbol.Type;


            var acccessmodifiers = MemberUtilities.GetAccessModifiers(property, isInterface || propertySymbol.IsAbstract);

            var typeString = TypeProcessor.ConvertType(type);

            var hasGetter     = getter != null;
            var getterHasBody = hasGetter && getter.Body != null;

            var hasSetter     = setter != null;
            var setterHasBody = hasSetter && setter.Body != null;



            var    indexerDeclarationSyntax = property as IndexerDeclarationSyntax;
            var    isindexer  = indexerDeclarationSyntax != null;
            string getterbody = null;

            if (getterHasBody)
            {
                getterbody = Core.WriteBlock(getter.Body, false, writer.Indent + 2);

                if (!isProxy && isYield)
                {
                    var namedTypeSymbol = propertySymbol.Type as INamedTypeSymbol;
                    if (namedTypeSymbol != null)
                    {
                        //                        var iteratortype = namedTypeSymbol.TypeArguments[0];
                        //                        getterbody=String.Format("return new __IteratorBlock!({0})(delegate(__IteratorBlock!({0}) __iter){{ {1} }});",
                        //                            TypeProcessor.ConvertType(iteratortype),getterbody);

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



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

                        //writer.OpenBrace();

                        if (!propertySymbol.IsStatic)
                        {
                            getterbody = writer.WriteIndentToString() + ("return new " + className + "(this);");
                        }
                        else
                        {
                            getterbody = writer.WriteIndentToString() + ("return new " + className + "();");
                        }
                    }
                }
            }
            string setterbody = null;

            if (setterHasBody)
            {
                setterbody = Core.WriteString(setter.Body, false, writer.Indent + 2);
                if (isindexer)
                {
                    setterbody += writer.WriteIndentToString() + "return value;";
                }
                else
                {
                    if (hasGetter)
                    {
                        setterbody += writer.WriteIndentToString() + "return " + name + ";";
                    }
                }
            }

            if (getter == null && setter == null)
            {
                throw new Exception("Property must have either a get or a set");
            }

            string isOverride;

            var fieldName = WriteAutoFieldName(writer, name, modifiers, isInterface, hasGetter, getterHasBody,
                                               hasSetter, setterHasBody, typeString, out isOverride, (property is IndexerDeclarationSyntax));


            BracketedParameterListSyntax @params = null;

            if (indexerDeclarationSyntax != null)
            {
                @params = indexerDeclarationSyntax.ParameterList;
            }

            string parameters = null;

            if (@params != null)
            {
                parameters = WriteMethod.GetParameterListAsString(@params.Parameters, iface: proxies == null ? iface : null, writebraces: false);
            }

            WriteGetter(writer, isProxy, hasGetter, acccessmodifiers, typeString, name, proxies == null ? iface : null, getterHasBody, modifiers, isInterface, fieldName, getterbody, parameters, indexerDeclarationSyntax != null);

            WriteSetter(writer, isProxy, hasSetter, acccessmodifiers, name, typeString, proxies == null ? iface : null, isOverride, setterHasBody, modifiers, isInterface, fieldName, setterbody, parameters, isindexer, hasGetter);

//			if (!isindexer && !isInterface) //TODO: Find a better solution
//			{
//				var fieldacccessmodifiers = acccessmodifiers.Replace ("abstract", "").Replace ("virtual","").Replace("override","");
//
//				writer.WriteLine(fieldacccessmodifiers +  "__Property!(" + typeString + ")" + name + ";");
//				if (isStatic)
//				{
//					var staticWriter = new TempWriter ();
//
//					staticWriter.WriteLine (name + String.Format (" = __Property!(" + typeString + ")(__ToDelegate(&set{0}), __ToDelegate(&get{0}));", name));
//					Context.Instance.StaticInits.Add (staticWriter.ToString ());
//				}
//				else
//				{
//					var instanceWriter = new TempWriter ();
//
//					instanceWriter.WriteLine (name + String.Format (" = __Property!(" + typeString + ")((&set{0}), (&get{0}));", name));
//					Context.Instance.InstanceInits.Add (instanceWriter.ToString ());
//				}
//			}


            if (proxies != null)
            {
                foreach (var proxy in proxies)
                {
                    if (indexerDeclarationSyntax == null)
                    {
                        setterbody = writer.WriteIndentToString() + name + "=" + "value" + ";";
                        getterbody = writer.WriteIndentToString() + "return " + name + ";";
                    }
                    else
                    {
                        string parameters2 = "";
                        if (@params != null)
                        {
                            parameters2 = WriteMethod.GetParameterListAsString(@params.Parameters, iface: null, includeTypes: false, writebraces: false);
                            // parameters2 = WriteMethod.GetParameterListAsString(@params.Parameters, iface: proxies == null ? iface : null, writebraces: false);
                        }

                        setterbody = writer.WriteIndentToString() + "return opIndexAssign(value," + parameters2 + ");";// + "=" + "value" + ";";
                        getterbody = writer.WriteIndentToString() + "return opIndex(" + parameters2 + ");";
                    }


                    parameters = null;
                    if (@params != null)
                    {
                        parameters = WriteMethod.GetParameterListAsString(@params.Parameters, iface: proxy.ContainingType, writebraces: false);
                    }

                    WriteGetter(writer, isProxy, hasGetter, acccessmodifiers, typeString, name, proxy.ContainingType, getterHasBody, modifiers, isInterface, fieldName, getterbody, parameters, isindexer);

                    WriteSetter(writer, isProxy, hasSetter, acccessmodifiers, name, typeString, proxy.ContainingType, isOverride, setterHasBody, modifiers, isInterface, fieldName, setterbody, parameters, isindexer, hasGetter);
                }
            }
        }
Esempio n. 10
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();
        }
Esempio n. 11
0
        public static void Go(OutputWriter writer, PropertyDeclarationSyntax property, bool isProxy = false)
        {
            writer.WriteLine();
            //var rEf = "";//" ref ";// ref should be used based on analysis, is the return type a single var or not
            //TODO, doesnt ref make things slower ?, though it makes proprties behave as in c#

            var isInterface = property.Parent is InterfaceDeclarationSyntax;

            var getter =
                property.AccessorList.Accessors.SingleOrDefault(
                    o => o.Keyword.RawKind == (decimal)SyntaxKind.GetKeyword);
            var setter =
                property.AccessorList.Accessors.SingleOrDefault(
                    o => o.Keyword.RawKind == (decimal)SyntaxKind.SetKeyword);
            var methodSymbol = TypeProcessor.GetDeclaredSymbol(property);
            var name         = WriteIdentifierName.TransformIdentifier(property.Identifier.ValueText);

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

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

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

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

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

            if (interfaceMethod != null)
            {
                //This is an interface property //TO
                if (methodSymbol.ContainingType.SpecialType == SpecialType.System_Array)
                {
                    writer.Write("");
                }
                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('.');
                    }
                    name = (typenameI + "_") + name;
                }
            }

            Action <AccessorDeclarationSyntax, bool> writeRegion = (region, get) =>
            {
                var accessString = "";

                //                var typeinfo = TypeProcessor.GetTypeInfo(property.Type);
                var isPtr = "";

                var typeString = TypeProcessor.ConvertType(property.Type) + isPtr + " ";

                //no inline in D
                if (get)
                {
                    writer.Write(typeString + " ");
                }
                else
                {
                    writer.Write("void ");
                }

                var methodName = (get ? "" : "") +
                                 name;
                var explicitHeaderNAme = "";

                if (property.Modifiers.Any(SyntaxKind.NewKeyword))
                {
                    methodName += "_";
                }

                writer.Write((!String.IsNullOrEmpty(explicitHeaderNAme) ? explicitHeaderNAme : methodName) +
                             (get ? "()" : "( " + typeString + " value )") + " @property");

                if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || region.Body == null)
                {
                    writer.Write(";\r\n");
                }
                else
                {
                    writer.WriteLine();
                    writer.OpenBrace();
                    Core.WriteBlock(writer, region.Body.As <BlockSyntax>(), false);
                    writer.CloseBrace();
                    writer.WriteLine();
                }
            };

            if (getter == null && setter == null)
            {
                throw new Exception("Property must have either a get or a set");
            }
            {
                var type       = property.Type;
                var typeinfo   = TypeProcessor.GetTypeInfo(type);
                var modifiers  = property.Modifiers;
                var isPtr      = "";
                var typeString = TypeProcessor.ConvertType(type) + isPtr + " ";
                var isStatic   = false;

                var acccessmodifiers = "";

                if (modifiers.Any(SyntaxKind.PrivateKeyword))
                {
                    acccessmodifiers += ("private ");
                }

                if (modifiers.Any(SyntaxKind.PublicKeyword) || modifiers.Any(SyntaxKind.InternalKeyword) ||
                    modifiers.Any(SyntaxKind.ProtectedKeyword) || modifiers.Any(SyntaxKind.AbstractKeyword) ||
                    isInterface)
                {
                    acccessmodifiers += ("public ");
                }

                if (property.Modifiers.Any(SyntaxKind.AbstractKeyword))
                {
                    acccessmodifiers += "abstract ";
                }

                if (property.Modifiers.Any(SyntaxKind.OverrideKeyword) && !isInterface)
                {
                    acccessmodifiers += "override ";
                }

                //TODO: look at final and other optimizations

                var IsStatic = "";

                if (modifiers.Any(SyntaxKind.StaticKeyword))
                {
                    isStatic          = true;
                    IsStatic          = "static ";
                    acccessmodifiers += IsStatic;
                }

                //Auto Property
                var fieldName = "__prop_" + name;

                var isOverride = (property.Modifiers.Any(SyntaxKind.NewKeyword) ||
                                  property.Modifiers.Any(SyntaxKind.OverrideKeyword)) && !isInterface
                    ? " override "
                    : "";
//                var isVirtual = //property.Modifiers.Any(SyntaxKind.VirtualKeyword) ||
//                    property.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface
//                        ? " abstract "
//                        : "";

                if (!isInterface) // Auto property
                {
                    if ((getter != null && getter.Body == null) &&
                        (setter != null && setter.Body == null) && (!property.Modifiers.Any(SyntaxKind.AbstractKeyword)))
                    {
                        writer.WriteLine("private " + typeString + fieldName + ";");
                    }
                }

                if (getter != null && isProxy)
                {
                    writer.WriteLine(acccessmodifiers + isOverride + typeString + "" + name + "() " + "@property " +
                                     "{ return Value." + name + ";}");
                }
                else
                //Getter
                if (getter != null && getter.Body == null)
                {
                    if (isProxy)
                    {
                    }
                    else if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface)
                    {
                        writer.WriteLine(acccessmodifiers + typeString + " " + name + "()" + isOverride +
                                         " @property;");
                    }

                    else
                    {
                        writer.WriteLine(acccessmodifiers + isOverride + typeString + "" + name + "() " +
                                         "@property " + "{ return " + fieldName + ";}");
                    }
                }
                else if (getter != null)
                {
                    writer.WriteIndent();
                    writer.Write(acccessmodifiers);
                    writeRegion(getter, true);
                }

                if (setter != null && isProxy)
                {
                    writer.WriteLine(acccessmodifiers + " void " + name + "(" + typeString + " value) @property" +
                                     isOverride + " {  Value." + name + " = value;}");
                }
                else
                //Setter
                if (setter != null && setter.Body == null)
                {
                    if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface)
                    {
                        writer.WriteLine(acccessmodifiers + " void " + name + "(" + typeString + " value)" +
                                         isOverride + "" + " @property;");
                    }
                    else
                    {
                        writer.WriteLine(acccessmodifiers + " void " + name + "(" + typeString + " value) @property" +
                                         isOverride + " {" + fieldName + " = value;}");
                    }
                }
                else if (setter != null)
                {
                    writer.WriteIndent();
                    writer.Write(acccessmodifiers);
                    writeRegion(setter, false);
                }
            }
        }
Esempio n. 12
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();
        }
Esempio n. 13
0
        private static void WriteOutNestedTypes(Context.SyntaxAndSymbol first, OutputWriter writer)
        {
            //WriteOut All My nested classes
            Context.Push();

            var delegates = first.Syntax.DescendantNodes().OfType <DelegateDeclarationSyntax>()
                            .Select(o => new
            {
                Syntax   = o,
                Symbol   = TypeProcessor.GetDeclaredSymbol(o),
                TypeName = WriteType.TypeName((INamedTypeSymbol)TypeProcessor.GetDeclaredSymbol(o))
            }).Where(k => k.Symbol.ContainingType == Context.Instance.Type) // Ignore all nested delegates
                            .GroupBy(o => o.Symbol.ContainingNamespace.FullNameWithDot() + o.TypeName)
                            .ToList();


            delegates.ForEach(type => //.ForEach(type => //.Parallel(type =>
            {
                Context.Instance = new Context
                {
                    TypeName         = type.First().TypeName,
                    DelegatePartials =
                        type.Select(
                            o =>
                            new Context.DelegateSyntaxAndSymbol
                    {
                        Symbol = (INamedTypeSymbol)o.Symbol,
                        Syntax = o.Syntax
                    })
                        .Where(o => !Program.DoNotWrite.ContainsKey(o.Syntax))
                        .ToList()
                };

                if (Context.Instance.DelegatePartials.Count > 0)
                {
                    WriteDelegate.Go(writer);
                }
            });
            Context.Pop();

            Context.Push();
            var subclasses = first.Syntax.DescendantNodes().OfType <BaseTypeDeclarationSyntax>()
                             .Select(o => new
            {
                Syntax   = o,
                Symbol   = TypeProcessor.GetDeclaredSymbol(o),
                TypeName = WriteType.TypeName((INamedTypeSymbol)TypeProcessor.GetDeclaredSymbol(o))
            }).Where(k => k.Symbol.ContainingType == Context.Instance.Type) // Ignore all nested classes
                             .GroupBy(o => o.Symbol.ContainingNamespace.FullNameWithDot() + o.TypeName)
                             .ToList();

            subclasses.ForEach(type => //.ForEach(type => //.Parallel(type =>
            {
                Context.Instance = new Context
                {
                    TypeName = type.First().TypeName,
                    Partials =
                        type.Select(
                            o =>
                            new Context.SyntaxAndSymbol
                    {
                        Symbol = (INamedTypeSymbol)o.Symbol,
                        Syntax = o.Syntax
                    })
                        .Where(o => !Program.DoNotWrite.ContainsKey(o.Syntax))
                        .ToList()
                };

                if (Context.Instance.Partials.Count > 0)
                {
                    try
                    {
                        WriteType.Go(writer);
                    }
                    catch (Exception ex)
                    {
                        //TODO: remove this when done with CorLib
                        throw ex;
                    }
                }
            });

            Context.Pop();
        }
Esempio n. 14
0
        public static void Go(OutputWriter writer, IndexerDeclarationSyntax property)
        {
//			writer.WriteLine ("\r\n");
            var rEf = ""; //" ref ";// ref should be used based on analysis, is the return type a single var or not
            //TODO, doesnt ref make things slower ?, though it makes proprties behave as in c#

            var isInterface = property.Parent is InterfaceDeclarationSyntax;

            var getter =
                property.AccessorList.Accessors.SingleOrDefault(
                    o => o.Keyword.RawKind == (decimal)SyntaxKind.GetKeyword);
            var setter =
                property.AccessorList.Accessors.SingleOrDefault(
                    o => o.Keyword.RawKind == (decimal)SyntaxKind.SetKeyword);
            var methodSymbol =
                (TypeProcessor.GetDeclaredSymbol(getter) ?? TypeProcessor.GetDeclaredSymbol(setter)) as IMethodSymbol;

            Action <AccessorDeclarationSyntax, bool> writeRegion = (region, get) =>
            {
                var typeinfo = TypeProcessor.GetTypeInfo(property.Type);
                var isPtr    = "";

                var typeString = TypeProcessor.ConvertType(property.Type) + isPtr + " ";

                if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || region.Body == null)
                {
                    writer.Write(" abstract ");
                }

                if (property.Modifiers.Any(SyntaxKind.OverrideKeyword))
                {
                    writer.Write(" override ");
                }

                //TODO: look at final and other optimizations

                //no inline in D
                if (get)
                {
                    writer.Write(rEf + typeString + " ");
                }
                else
                {
                    writer.Write("void ");
                }

                var methodName         = (get ? "opIndex" : "opIndexAssign");
                var explicitHeaderNAme = "";
                if (methodSymbol != null && methodSymbol.MethodKind == MethodKind.ExplicitInterfaceImplementation)
                {
                    var implementations = methodSymbol.ExplicitInterfaceImplementations[0];
                    if (implementations != null)
                    {
                        explicitHeaderNAme = implementations.Name;
                        methodName         =                       //implementations.ReceiverType.FullName() + "." +
                                             implementations.Name; //Explicit fix ?

                        //			writer.Write(methodSymbol.ContainingType + "." + methodName);
                        //Looks like internal classes are not handled properly here ...
                    }
                }
                if (methodSymbol != null)
                {
                    // methodName = methodName.Replace(methodSymbol.ContainingNamespace.FullName() + ".", methodSymbol.ContainingNamespace.FullName() + ".");

                    //   writer.Write((methodSymbol.ContainingType.FullName() + "." + methodName) + (get ? "()" : "( " + typeString + " value )")); //Dealting with explicit VMT7
                }
                if (property.Modifiers.Any(SyntaxKind.NewKeyword))
                {
                    methodName += "_";
                }

                var parameters = GetParameterList(methodSymbol.Parameters);

                writer.Write((!String.IsNullOrEmpty(explicitHeaderNAme) ? explicitHeaderNAme : methodName) + "( " +
                             (get ? "" : (typeString + " value, ")) + parameters + " )");

                if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || region.Body == null)
                {
                    writer.Write(";\r\n");
                }
                else
                {
                    writer.OpenBrace();
                    Core.WriteBlock(writer, region.Body.As <BlockSyntax>());

                    writer.CloseBrace();
                    writer.Write("\r\n");
                }
            };

            if (getter == null && setter == null)
            {
                throw new Exception("Property must have either a get or a set");
            }

            {
//				var name = WriteIdentifierName.TransformIdentifier (property..ValueText);
                var type      = property.Type;
                var typeinfo  = TypeProcessor.GetTypeInfo(type);
                var modifiers = property.Modifiers;
                var isPtr     = typeinfo.Type != null &&
                                (typeinfo.Type.IsValueType || typeinfo.Type.TypeKind == TypeKind.TypeParameter)
                    ? ""
                    : "";
                var typeString = TypeProcessor.ConvertType(type) + isPtr + " ";
                var isStatic   = false;

                var acccessmodifiers = "";

                if (modifiers.Any(SyntaxKind.PrivateKeyword))
                {
                    acccessmodifiers += ("private ");
                }

                if (modifiers.Any(SyntaxKind.PublicKeyword) || modifiers.Any(SyntaxKind.InternalKeyword) ||
                    modifiers.Any(SyntaxKind.ProtectedKeyword) || modifiers.Any(SyntaxKind.AbstractKeyword) ||
                    isInterface)
                {
                    acccessmodifiers += ("public ");
                }

                var IsStatic = "";

                if (modifiers.Any(SyntaxKind.StaticKeyword))
                {
                    isStatic          = true;
                    IsStatic          = "static ";
                    acccessmodifiers += IsStatic;
                }

                //Auto Property

//				var isOverride = property.Modifiers.Any (SyntaxKind.NewKeyword) ||
//				                 property.Modifiers.Any (SyntaxKind.OverrideKeyword)
//					? " override "
//					: "";
//				var isVirtual = //property.Modifiers.Any(SyntaxKind.VirtualKeyword) ||
//					property.Modifiers.Any (SyntaxKind.AbstractKeyword) || isInterface
//					? " abstract "
//					: "";
//				if (!isInterface)

                //Getter
                if (getter != null)
                {
                    writer.WriteIndent();
                    writer.Write(acccessmodifiers);
                    writeRegion(getter, true);
                }

                //Setter
                if (setter != null)
                {
                    writer.WriteIndent();
                    writer.Write(acccessmodifiers);
                    writeRegion(setter, false);
                }
            }
        }
Esempio n. 15
0
        public static string GetMethodName(MemberDeclarationSyntax member, ref bool isInterface, out ITypeSymbol interfaceImplemented, out ISymbol[] proxies)
        {
            interfaceImplemented = null;
            proxies = null;
            var methodSymbol = TypeProcessor.GetDeclaredSymbol(member);
            var name         = WriteIdentifierName.TransformIdentifier(OverloadResolver.MethodName(methodSymbol));

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



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

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

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

                interfaceImplemented = methodSymbol.ContainingType.ConstructedFrom;

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

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

            var name1 = name;

            IEnumerable <ISymbol> interfaceMethods = null;

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

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

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

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

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

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

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

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

            GetExplicitInterface(ref interfaceImplemented, methodSymbol);

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

            return(name);
        }
Esempio n. 16
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();
                }
            }
        }