Exemplo n.º 1
0
        private static void ProcessDelegates()
        {
            var delegates = _compilation.SyntaxTrees
                            .SelectMany(o => o.GetRoot().DescendantNodes().OfType <DelegateDeclarationSyntax>())
                            .Select(o => new
            {
                Syntax   = o,
                Symbol   = GetModel(o).GetDeclaredSymbol(o),
                TypeName = WriteType.TypeName(GetModel(o).GetDeclaredSymbol(o))
            }).GroupBy(o => o.Symbol.ContainingNamespace.FullNameWithDot() + o.TypeName)
                            .ToList();

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

                if (Context.Instance.DelegatePartials.Count > 0)
                {
                    WriteDelegate.Go();
                }
            });
        }
        /// <summary>
        ///     calls to Enum.Parse get re-written as calls to our special Parse methods on each enum.  We assume the first
        ///     parameter to Enum.Parse is a a typeof()
        /// </summary>
        private static void WriteEnumParse(OutputWriter writer, InvocationExpressionSyntax invocationExpression)
        {
            var args = invocationExpression.ArgumentList.Arguments;

            if (args.Count < 2 || args.Count > 3)
            {
                throw new Exception("Expected 2-3 args to Enum.Parse");
            }

            if (args.Count == 3 &&
                (!(args[2].Expression is LiteralExpressionSyntax) ||
                 args[2].Expression.As <LiteralExpressionSyntax>().ToString() != "false"))
            {
                throw new NotImplementedException("Case-insensitive Enum.Parse is not supported " +
                                                  Utility.Descriptor(invocationExpression));
            }

            if (!(args[0].Expression is TypeOfExpressionSyntax))
            {
                throw new Exception("Expected a typeof() expression as the first parameter of Enum.Parse " +
                                    Utility.Descriptor(invocationExpression));
            }

            var type = TypeProcessor.GetTypeInfo(args[0].Expression.As <TypeOfExpressionSyntax>().Type).Type;

            //ModelExtensions.GetTypeInfo(Program.GetModel(invocationExpression), args[0].Expression.As<TypeOfExpressionSyntax>().Type).Type;
            writer.Write(type.ContainingNamespace.FullNameWithDot());
            writer.Write(WriteType.TypeName((INamedTypeSymbol)type));
            writer.Write(".Parse(");
            Core.Write(writer, args[1].Expression);
            writer.Write(")");
        }
Exemplo n.º 3
0
        private static void ProcessTypes()
        {
            var allTypes = _compilation.SyntaxTrees
                           .SelectMany(o => o.GetRoot().DescendantNodes().OfType <BaseTypeDeclarationSyntax>())
                           .Select(o => new
            {
                Syntax   = o,
                Symbol   = GetModel(o).GetDeclaredSymbol(o),
                TypeName = WriteType.TypeName(GetModel(o).GetDeclaredSymbol(o))
            })
                           .GroupBy(o => o.Symbol.ContainingNamespace.FullNameWithDot() + o.TypeName)
                           .ToList();

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

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

            var symbols =
                allTypes.SelectMany(o => o)
                .Where(o => !DoNotWrite.ContainsKey(o.Syntax))
                .Select(o => o.Symbol)
                .Select(g => g)
                .Where(g => g != null);

            WriteConstructorBody.WriteConstructorsHelper(symbols);
        }
Exemplo n.º 4
0
 private static string GetGenericTypeNameWithParameters(INamedTypeSymbol named)
 {
     if (named.IsGenericType)
     {
         return(WriteType.TypeName(named, false) + (named.TypeArguments.Any() ? "!(" +
                                                    named.TypeArguments.Select(
                                                        o => GetGenericParameterType(named.TypeParameters[named.TypeArguments.IndexOf(o)], o))
                                                    .Aggregate((a, b) => a + ", " + b)
                                                    + ")" :""));
     }
     else
     {
         return(WriteType.TypeName(named));
     }
 }
        private static void WriteEnumGetValues(OutputWriter writer, InvocationExpressionSyntax invocationExpression)
        {
            if (!(invocationExpression.ArgumentList.Arguments[0].Expression is TypeOfExpressionSyntax))
            {
                throw new Exception("Expected a typeof() expression as the first parameter of Enum.GetValues " +
                                    Utility.Descriptor(invocationExpression));
            }

            //            var type = ModelExtensions.GetTypeInfo(Program.GetModel(invocationExpression), invocationExpression.ArgumentList.Arguments[0].Expression.As<TypeOfExpressionSyntax>().Type).Type;
            var type =
                TypeProcessor.GetTypeInfo(
                    invocationExpression.ArgumentList.Arguments[0].Expression.As <TypeOfExpressionSyntax>().Type).Type;

            writer.Write(type.ContainingNamespace.FullNameWithDot());
            writer.Write(WriteType.TypeName((INamedTypeSymbol)type));
            writer.Write(".Values");
        }
Exemplo n.º 6
0
        private static void WriteOneDelegate(OutputWriter outputWriter, Context.DelegateSyntaxAndSymbol first, bool fileExists)
        {
            Context.Instance.Namespace = first.Symbol.ContainingNamespace.FullName();
            Context.Instance.Type      = first.Symbol;
            TypeProcessor.ClearUsedTypes();
            var mynamespace = Context.Instance.Type.ContainingNamespace.FullName().RemoveFromEndOfString(".Namespace");
            // + "." + TypeState.Instance.TypeName;

            var myUsingDirective     = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(mynamespace));
            var SystemUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System"));

            // Required as certain functions like boxing are in this namespace
            Context.Instance.UsingDeclarations =
                first.Syntax.Parent.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray()
                .Union(new[]
            {
                myUsingDirective, SystemUsingDirective
            }).ToArray();
            OutputWriter writer = null;

            using (
                writer =
                    outputWriter == null
                        ? new OutputWriter(Context.Instance.Namespace, Context.Instance.TypeName)
                        : new TempWriter())
            {
                if (outputWriter != null)
                {
                    writer.WriteLine();
                    writer.Indent = outputWriter.Indent + 2;
                    writer.WriteIndent();
                }

                writer.FileExists = fileExists;

                WriteBcl.Go(writer);

                WriteStandardIncludes.Go(writer);

                //Look for generic arguments

                {
                    List <TypeParameterSyntax> genericArgs = new List <TypeParameterSyntax>();
                    if (first.Syntax.TypeParameterList != null)
                    {
                        genericArgs = first.Syntax.TypeParameterList.Parameters.ToList();
                    }

                    var name = WriteType.TypeName(Context.Instance.Type, false); //Context.Instance.TypeName;

                    if (genericArgs.Count > 0)
                    {
                        name  = "template " + name;
                        name += ("(");
                        name += (string.Join(" , ", genericArgs.Select(o => o)));
                        name += (")");

                        writer.WriteLine(name);

                        writer.OpenBrace();

                        writer.WriteLine("alias __Delegate!(" + TypeProcessor.ConvertType(first.Syntax.ReturnType) + " delegate" +
                                         WriteMethod.GetParameterListAsString(first.Syntax.ParameterList.Parameters) + ") " +
                                         WriteType.TypeName(Context.Instance.Type, false) + ";");

                        writer.CloseBrace();
                    }
                    else
                    {
                        //Non-generic
                        writer.WriteLine("alias __Delegate!(" + TypeProcessor.ConvertType(first.Syntax.ReturnType) + " delegate" +
                                         WriteMethod.GetParameterListAsString(first.Syntax.ParameterList.Parameters) + ") " +
                                         WriteType.TypeName(Context.Instance.Type, false) + ";");
                    }
                }

                if (outputWriter != null)
                {
                    outputWriter.WriteLine(writer.ToString());
                }
            }
        }
        public static void Go(OutputWriter writer, AssignmentExpressionSyntax expression)
        {
            if (expression.OperatorToken.IsKind(SyntaxKind.AsKeyword))
            {
                var typeinfo = TypeProcessor.GetTypeInfo(expression.Right);

                var isPtr = typeinfo.Type != null && typeinfo.Type.IsValueType ? "" : "";
                writer.Write("cast( ");
                writer.Write(TypeProcessor.ConvertType(expression.Right) + isPtr);
                writer.Write(" )(");
                Core.Write(writer, expression.Left);
                writer.Write(")");
            }
            else if (expression.OperatorToken.IsKind(SyntaxKind.IsKeyword)) // isCast
            {
                var leftSymbolType  = TypeProcessor.GetTypeInfo(expression.Left);
                var rightSymbolType = TypeProcessor.GetTypeInfo(expression.Right);

                if (leftSymbolType.Type.IsValueType)
                {
                    writer.Write("IsCast!(Boxed!(");
                    writer.Write(TypeProcessor.ConvertType(expression.Right));
                    writer.Write("))");
                    writer.Write("(");
                    Core.Write(writer, expression.Left);
                    writer.Write(")");

                    //						writer.Write("(cast(BOX!(");
                    //						writer.Write(TypeProcessor.ConvertType(expression.Right));
                    //						writer.Write(" ) )(Boxed!( " + TypeProcessor.ConvertType(leftSymbolType.Type));
                    //						writer.Write(" )(");
                    //						Core.Write(writer, expression.Left);
                    //						writer.Write(")) is! null)");
                    //Todo improve this ... though its silly to do this in the first place
                    //					writer.Write("(cast(BOX!(");
                    //                    writer.Write(TypeProcessor.ConvertType(expression.Right));
                    //					writer.Write("))(Boxed!(" + TypeProcessor.ConvertType(leftSymbolType.Type));
                    //					writer.Write(")(");
                    //                    Core.Write(writer, expression.Left);
                    //					writer.Write(")) is! null)");
                }
                else if (rightSymbolType.Type.IsValueType)
                {
                    writer.Write("IsCast!(Boxed!(");
                    writer.Write(TypeProcessor.ConvertType(expression.Right));
                    writer.Write("))");
                    writer.Write("(");
                    Core.Write(writer, expression.Left);
                    writer.Write(")");

                    //					writer.Write("(cast(Boxed!( ");
                    //                    writer.Write(TypeProcessor.ConvertType(expression.Right));
                    //					writer.Write(" ) )(");
                    //                    Core.Write(writer, expression.Left);
                    //					writer.Write(") is! null)");
                }
                else
                {
                    var typeinfo = TypeProcessor.GetTypeInfo(expression.Right);

                    var isPtr = typeinfo.Type != null && typeinfo.Type.IsValueType ? "" : "";
                    writer.Write("(IsCast!(");
                    writer.Write(TypeProcessor.ConvertType(expression.Right) + isPtr);
                    writer.Write(")(");
                    Core.Write(writer, expression.Left);
                    writer.Write("))");
                }
            }
            else if (expression.OperatorToken.IsKind(SyntaxKind.QuestionQuestionToken))
            {
                writer.Write("((");
                Core.Write(writer, expression.Left);
                writer.Write(")!is null?(");
                Core.Write(writer, expression.Left);
                writer.Write("):(");
                Core.Write(writer, expression.Right);
                writer.Write("))");
            }
            else
            {
                //                if (expression.Left is ElementAccessExpressionSyntax && IsAssignmentToken((SyntaxKind) expression.OperatorToken.RawKind))
                //                {
                //                    var subExpr = expression.Left.As<ElementAccessExpressionSyntax>();
                //                    var typeStr = TypeProcessor.GenericTypeName(TypeProcessor.GetTypeInfo(subExpr.Expression).Type);
                //
                //
                //
                //                }

                Action <ExpressionSyntax> write = e =>
                {
                    var type = TypeProcessor.GetTypeInfo(e);

                    //Check for enums being converted to strings by string concatenation
                    var typeSymbol = type.Type ?? type.ConvertedType;

                    if (expression.OperatorToken.RawKind == (decimal)SyntaxKind.PlusToken &&
                        typeSymbol.TypeKind == TypeKind.Enum)
                    {
                        writer.Write(typeSymbol.ContainingNamespace.FullNameWithDot());
                        writer.Write(WriteType.TypeName(typeSymbol.As <INamedTypeSymbol>()));
                        writer.Write(".ToString(");
                        Core.Write(writer, e);
                        writer.Write(")");
                    }
                    else if (expression.OperatorToken.RawKind == (decimal)SyntaxKind.PlusToken &&
                             (typeSymbol.Name == "Nullable" && typeSymbol.ContainingNamespace.FullName() == "System" &&
                              typeSymbol.As <INamedTypeSymbol>().TypeArguments.Single().TypeKind == TypeKind.Enum))
                    {
                        var enumType = typeSymbol.As <INamedTypeSymbol>().TypeArguments.Single();
                        writer.Write(enumType.ContainingNamespace.FullNameWithDot());
                        writer.Write(WriteType.TypeName(enumType.As <INamedTypeSymbol>()));
                        writer.Write(".ToString(");
                        Core.Write(writer, e);
                        writer.Write(")");
                    }
                    else
                    {
                        Core.Write(writer, e);
                    }
                };

                var symbolInfoLeft  = TypeProcessor.GetSymbolInfo(expression.Left);
                var symbolInfoRight = TypeProcessor.GetSymbolInfo(expression.Right);

                var leftExpressionType  = TypeProcessor.GetTypeInfo(expression.Left);
                var rightExpressionType = TypeProcessor.GetTypeInfo(expression.Right);

                var boxLeft = leftExpressionType.Type != null &&
                              (leftExpressionType.Type.IsValueType && (leftExpressionType.ConvertedType.IsReferenceType));
                var derefLeft = false;
                // rightExpressionType.ConvertedType != null && rightExpressionType.ConvertedType.IsReferenceType;

                var boxRight = rightExpressionType.ConvertedType != null &&
                               (rightExpressionType.Type != null && (rightExpressionType.Type.IsValueType &&
                                                                     (rightExpressionType.ConvertedType.IsReferenceType)));
                var derefRight = rightExpressionType.ConvertedType != null &&
                                 (leftExpressionType.ConvertedType != null &&
                                  !leftExpressionType.ConvertedType.IsReferenceType &&
                                  rightExpressionType.ConvertedType.IsReferenceType);
                var nullAssignment = expression.Right.ToFullString().Trim() == "null";

                //Property calls will be fixed in a preprocessor step ... i.e. just call them
                // var propertyLeft = symbolInfoLeft.Symbol != null && symbolInfoLeft.Symbol.Kind == SymbolKind.Property;
                // var propertyRight = symbolInfoRight.Symbol != null && symbolInfoRight.Symbol.Kind == SymbolKind.Property;
                if (nullAssignment)
                {
                    Core.Write(writer, expression.Left);
                    writer.Write(" = ");
                    writer.Write("null");
                    return;
                }
                //Do we have an implicit converter, if so, use it
                if (leftExpressionType.Type != rightExpressionType.Type)
                {
                    // if (boxLeft)
                    {
                        bool useType = true;

                        //We should start with exact converters and then move to more generic convertors i.e. base class or integers which are implicitly convertible
                        var correctConverter = leftExpressionType.Type.GetImplicitCoversionOp(leftExpressionType.Type,
                                                                                              rightExpressionType.Type);
                        //                            initializerType.Type.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);

                        if (correctConverter == null)
                        {
                            useType          = false;
                            correctConverter =
                                rightExpressionType.Type.GetImplicitCoversionOp(leftExpressionType.Type,
                                                                                rightExpressionType.Type);
                            //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
                        }

                        if (correctConverter != null)
                        {
                            Core.Write(writer, expression.Left);
                            writer.Write(" = ");
                            if (useType)
                            {
                                writer.Write(TypeProcessor.ConvertType(leftExpressionType.Type) + "." + "op_Implicit_" +
                                             TypeProcessor.ConvertType(correctConverter.ReturnType));
                            }
                            else
                            {
                                writer.Write(TypeProcessor.ConvertType(rightExpressionType.Type) + "." + "op_Implicit_" +
                                             TypeProcessor.ConvertType(correctConverter.ReturnType));
                            }
                            writer.Write("(");
                            Core.Write(writer, expression.Right);
                            writer.Write(")");
                            return;
                        }
                    }
                    //                    if (shouldBox)
                    //                    {
                    //                        bool useType = true;
                    //                        var correctConverter =
                    //                            initializerType.Type.GetCoversionOp(initializerType.ConvertedType, initializerType.Type);//.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.ConvertedType && h.Parameters[0].Type == initializerType.Type);
                    //
                    //                        if (correctConverter == null)
                    //                        {
                    //                            useType = false;
                    //                            correctConverter =
                    //                                initializerType.ConvertedType.GetCoversionOp(initializerType.ConvertedType,
                    //                                    initializerType.Type);
                    //                            //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.ConvertedType && h.Parameters[0].Type == initializerType.Type);
                    //                        }
                    //
                    //                        if (correctConverter != null)
                    //                        {
                    //                            if (useType)
                    //                                writer.Write(TypeProcessor.ConvertType(initializerType.Type) + "." + "op_Implicit(");
                    //                            else
                    //                            {
                    //                                writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) + "." + "op_Implicit(");
                    //
                    //                            }
                    //                            Core.Write(writer, value);
                    //                            writer.Write(")");
                    //                            return;
                    //                        }
                    //                    }
                }

                if (expression.OperatorToken.CSharpKind() == SyntaxKind.PlusEqualsToken ||
                    expression.OperatorToken.CSharpKind() == SyntaxKind.MinusEqualsToken)
                {
                    var isname = expression.Right is NameSyntax;

                    var nameexpression = expression.Right as NameSyntax;

                    var ismemberexpression = expression.Right is MemberAccessExpressionSyntax ||
                                             (isname &&
                                              TypeProcessor.GetSymbolInfo(expression.Right as NameSyntax).Symbol.Kind ==
                                              SymbolKind.Method);

                    var isdelegateassignment = ismemberexpression &&
                                               rightExpressionType.ConvertedType.TypeKind == TypeKind.Delegate;

                    var memberaccessexpression = expression.Right as MemberAccessExpressionSyntax;

                    var isstaticdelegate = isdelegateassignment &&
                                           ((memberaccessexpression != null &&
                                             TypeProcessor.GetSymbolInfo(memberaccessexpression).Symbol.IsStatic) ||
                                            (isname && TypeProcessor.GetSymbolInfo(nameexpression).Symbol.IsStatic));

                    if (isdelegateassignment)
                    {
                        write(expression.Left);

                        writer.Write(expression.OperatorToken.ToString());

                        var createNew  = !(expression.Right is ObjectCreationExpressionSyntax);
                        var typeString = TypeProcessor.ConvertType(rightExpressionType.ConvertedType);

                        if (createNew)
                        {
                            if (rightExpressionType.ConvertedType.TypeKind == TypeKind.TypeParameter)
                            {
                                writer.Write(" __TypeNew!(" + typeString + ")(");
                            }
                            else
                            {
                                writer.Write("new " + typeString + "(");
                            }
                        }

                        var isStatic = isstaticdelegate;
                        if (isStatic)
                        {
                            writer.Write("__ToDelegate(");
                        }
                        writer.Write("&");

                        write(expression.Right);
                        //Core.Write (writer, expression.Right);
                        if (isStatic)
                        {
                            writer.Write(")");
                        }

                        if (createNew)
                        {
                            writer.Write(")");
                        }
                        return;
                    }
                }
                if (leftExpressionType.Type == null || rightExpressionType.Type == null)
                {
                    // seems we have a null here obj==null or null==obj
                    if ((rightExpressionType.Type != null && rightExpressionType.Type.IsValueType) ||
                        (leftExpressionType.Type != null && leftExpressionType.Type.IsValueType))
                    {
                        writer.Write("/*value type cannot be null*/");
                        write(expression.Left);
                        switch (expression.OperatorToken.CSharpKind())
                        {
                        case SyntaxKind.EqualsEqualsToken:
                            writer.Write("!=");
                            break;

                        case SyntaxKind.NotEqualsExpression:
                            writer.Write("==");
                            break;

                        default:
                            writer.Write(expression.OperatorToken.ToString());
                            break;
                        }

                        write(expression.Right);
                    }
                    else
                    {
                        write(expression.Left);
                        if (expression.OperatorToken.CSharpKind() == SyntaxKind.EqualsEqualsToken)
                        {
                            writer.Write(" is ");
                        }
                        else if (expression.OperatorToken.CSharpKind() == SyntaxKind.ExclamationEqualsToken)
                        {
                            writer.Write(" !is ");
                        }
                        else
                        {
                            writer.Write(expression.OperatorToken.ToString());
                        }

                        write(expression.Right);
                    }
                }
                else
                //                if (symbolInfoLeft.Symbol != null && (symbolInfoLeft.Symbol.Kind == SymbolKind.Property && expression.OperatorToken.ValueText == "=")) //Assignment of property
                //                {
                //
                //                    write(expression.Left);
                //                    writer.Write("(");
                //                    write(expression.Right);
                //                    writer.Write(")");
                //                }
                //                else
                {
                    //                    writer.Write(derefLeft ? "*(" : "");
                    writer.Write(boxLeft ? "BOX!(" + TypeProcessor.ConvertType(leftExpressionType.Type) + ")(" : "");
                    write(expression.Left);

                    writer.Write(boxLeft ? ")" : "");
                    //                    writer.Write(derefLeft ? ")" : "");
                    writer.Write(expression.OperatorToken.ToString());
                    //                    writer.Write(derefRight ? "(" : "");
                    writer.Write(boxRight ? "BOX!(" + TypeProcessor.ConvertType(rightExpressionType.Type) + ")(" : "");
                    write(expression.Right);

                    writer.Write(boxRight ? ")" : "");
                    //                    writer.Write(derefRight ? ")" : "");
                }
            }
        }
Exemplo n.º 8
0
        private static string ConvertTypeUncached(ITypeSymbol typeSymbol, bool localize)
        {
            if (typeSymbol.IsAnonymousType)
            {
                return(WriteAnonymousObjectCreationExpression.TypeName(typeSymbol.As <INamedTypeSymbol>()));
            }

            var array = typeSymbol as IArrayTypeSymbol;

            var ptr = array != null && (array.ElementType.IsValueType == false);

            if (array != null)
            {
                var typeString = TryConvertType(array.ElementType, localize);
                if (localize)
                {
                    var name =
                        Context.Instance.UsingDeclarations.FirstOrDefault(
                            k => typeString.StartsWith(k.Name.ToFullString() + ".Namespace.", StringComparison.Ordinal));

                    if (name != null)
                    {
                        typeString = typeString.RemoveFromStartOfString(name.Name.ToFullString() + ".Namespace.");
                    }
                }
                //if (array.Rank == 1) // Jagged / Single
                return("Array_T!(" + typeString + ")");
//				else
//				{
//					return  "Array_T!(" + typeString + Enumerable.Range (0, array.Rank-1).Select (l => "[]").Aggregate ((a, b) => a + b).ToString () +")";
//
//				}
            }

            if (typeSymbol.TypeKind == TypeKind.PointerType)
            {
                var pointer = typeSymbol as IPointerTypeSymbol;
                return(ConvertType(pointer.PointedAtType) + "*");
            }

            var typeInfoStr = typeSymbol.ToString();

            var named = typeSymbol as INamedTypeSymbol;

            if (typeSymbol.TypeKind == TypeKind.TypeParameter)
            {
                return(typeSymbol.Name);
            }

//			if (typeSymbol.TypeKind == TypeKind.Delegate) {
//				var dlg = named.DelegateInvokeMethod.As<IMethodSymbol> ();
//				if (dlg.Parameters.Length == 0)
//					return "() => " + TryConvertType (dlg.ReturnType);
//				else
//					return "(" + string.Join (", ", dlg.Parameters.ToList ().Select (o => TryConvertType (o.Type))) + ") => " + TryConvertType (dlg.ReturnType);

//			}

            // if (typeSymbol.TypeKind == TypeKind.Enum)
            //   return "int"; //enums are always ints

            if (named.ContainingNamespace.ToString() == "System" && named.Name == "Exception")
            {
                return("System.Namespace.NException");
            }

            if (named != null && named.Name == "Nullable" && named.ContainingNamespace.ToString() == "System")
            {
                //Nullable types
                var convertedType = TryConvertType(named.TypeArguments.Single());

                switch (convertedType)
                {
                case "Int":
                    return("int");

                case "Boolean":
                    return("bool");

                case "Byte":
                    return("byte");

                case "Short":
                    return("short");

                case "Float":
                    return("float");

                case "Double":
                    return("double");

                case "Char":
                    return("char");

                case "Long":
                    return("long");

                default:
                    return(convertedType);
                }
            }

            var typeStr = GenericTypeName(typeSymbol);

            if (named != null && named.IsGenericType && !named.IsUnboundGenericType && TypeArguments(named).Any())
            {
                return(TryConvertType(named.ConstructUnboundGenericType()) + "!(" +
                       string.Join(", ", TypeArguments(named).Select(o => TryConvertType(o))) + ")");
            }

            switch (typeStr)
            {
            case "System.Namespace.Void":
                return("void");

            case "System.Namespace.Boolean":
                return("bool");

            case "System.Object":
            case "System.Namespace.Object":
                return("NObject");

            case "System.Namespace.UInt64":
                return("ulong");

            case "System.Namespace.Double":
                return("double");

            case "System.Namespace.Single":
                return("float");

            case "System.Namespace.String":
                return("String");

            case "System.Namespace.Int32":
                return("int");

            case "System.Namespace.UInt16":
                return("ushort");

            case "System.Namespace.Int64":
                return("long");

            case "System.Namespace.UInt32":
                return("long");    // Looks like d's uint32 is smaller than C#'s

            case "System.Namespace.Byte":
                return("byte");

            case "System.Namespace.Int16":
                return("short");

            case "System.Namespace.Char":
                return("char");

            case "System.Namespace.Array":
                return("Array_T");    //All template (generic) classes have atleast one "_T" appended

            default:

                if (named != null)
                {
                    return(typeSymbol.ContainingNamespace.FullNameWithDot() + WriteType.TypeName(named));
                }

                //This type does not get translated and gets used as-is
                return(typeSymbol.ContainingNamespace.FullNameWithDot() + typeSymbol.Name);
            }
        }
Exemplo n.º 9
0
        public static void WriteConstructorsHelper(IEnumerable <INamedTypeSymbol> allTypes)
        {
            foreach (var t in allTypes.Select(o => o.ContainingNamespace.FullNameWithDot() + WriteType.TypeName(o)))
            {
                AllTypes.Add(t);
            }

            if (StaticConstructors.Count == 0)
            {
                return; //no need for it.
            }
        }
Exemplo n.º 10
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();
        }
        public static void Go(OutputWriter writer, InvocationExpressionSyntax invocationExpression)
        {
            var symbolInfo       = TypeProcessor.GetSymbolInfo(invocationExpression);
            var expressionSymbol = TypeProcessor.GetSymbolInfo(invocationExpression.Expression);

            var symbol = symbolInfo.Symbol ?? symbolInfo.CandidateSymbols.FirstOrDefault(); // Resolution error

            var methodSymbol = symbol.OriginalDefinition.As <IMethodSymbol>().UnReduce();

            var memberReferenceExpressionOpt = invocationExpression.Expression as MemberAccessExpressionSyntax;
            var firstParameter = true;

            var extensionNamespace = methodSymbol.IsExtensionMethod
                ? methodSymbol.ContainingNamespace.FullNameWithDot() + methodSymbol.ContainingType.FullName()
                : null; //null means it's not an extension method, non-null means it is
            string           methodName;
            string           typeParameters = null;
            ExpressionSyntax subExpressionOpt;

            if (methodSymbol.ContainingType.FullName() == "Enum")
            {
                if (methodSymbol.Name == "Parse")
                {
                    WriteEnumParse(writer, invocationExpression);
                    return;
                }

                if (methodSymbol.Name == "GetValues")
                {
                    WriteEnumGetValues(writer, invocationExpression);
                    return;
                }
            }

            if (expressionSymbol.Symbol is IEventSymbol)
            {
                methodName = "Invoke";
                //Would need to append the number of arguments to this to support events.  However, events are not currently supported
            }
            //            else if (memberReferenceExpressionOpt != null && memberReferenceExpressionOpt.Expression is PredefinedTypeSyntax)
            //            {
            //                switch (methodSymbol.Name)
            //                {
            //                    case "Parse":
            //                        Core.Write(writer, invocationExpression.ArgumentList.Arguments.Single().Expression);
            //
            //                        writer.Write(".to");
            //                        writer.Write(TypeProcessor.ConvertType(methodSymbol.ReturnType));
            //
            //                        return;
            //                    case "TryParse":
            //                        methodName = "TryParse" + TypeProcessor.ConvertType(methodSymbol.Parameters[1].Type);
            //                        extensionNamespace = "SharpNative";
            //                        break;
            //                    default:
            //                        methodName = methodSymbol.Name;
            //                        extensionNamespace = "SharpNative";
            //                        break;
            //                }
            //            }

            else if (methodSymbol.MethodKind == MethodKind.DelegateInvoke)
            {
                methodName = null;
            }
            else
            {
                methodName = OverloadResolver.MethodName(methodSymbol);
            }

            if (methodSymbol.MethodKind == MethodKind.DelegateInvoke)
            {
                subExpressionOpt = invocationExpression.Expression;
            }
            else if (memberReferenceExpressionOpt != null)
            {
                if (memberReferenceExpressionOpt.Expression is PredefinedTypeSyntax)
                {
                    subExpressionOpt = null;
                }
                else
                {
                    subExpressionOpt = memberReferenceExpressionOpt.Expression;
                }
            }
            else
            {
                subExpressionOpt = null;
            }

            //When the code specifically names generic arguments, include them in the method name ... dlang needs help with inference, so we give it the types anyway
            if (methodSymbol.IsGenericMethod)
            {
                //				var genNameExpression = invocationExpression.Expression as GenericNameSyntax;
                //				if (genNameExpression == null && memberReferenceExpressionOpt != null)
                //					genNameExpression = memberReferenceExpressionOpt.Name as GenericNameSyntax;
                //				if (genNameExpression != null && genNameExpression.TypeArgumentList.Arguments.Count > 0)
                typeParameters = "!( " +
                                 string.Join(", ",
                                             (symbol as IMethodSymbol).TypeArguments.Select(r => TypeProcessor.ConvertType(r))) +
                                 " )";
            }

            //Determine if it's an extension method called in a non-extension way.  In this case, just pretend it's not an extension method
            if (extensionNamespace != null && subExpressionOpt != null &&
                TypeProcessor.GetTypeInfo(subExpressionOpt).ConvertedType.ToString() ==
                methodSymbol.ContainingNamespace + "." + methodSymbol.ContainingType.FullName())
            {
                extensionNamespace = null;
            }

            var memberType = memberReferenceExpressionOpt == null
                ? null
                : TypeProcessor.GetTypeInfo(memberReferenceExpressionOpt.Expression).Type;
            var isNullableEnum = memberType != null &&
                                 (memberType.Name == "Nullable" && memberType.ContainingNamespace.FullName() == "System") &&
                                 memberType.As <INamedTypeSymbol>().TypeArguments.Single().TypeKind == TypeKind.Enum;
            //			if (isNullableEnum && methodSymbol.Name == "ToString")
            //			{
            //				extensionNamespace = null; //override Translations.xml for nullable enums. We want them to convert to the enum's ToString method
            //				methodName = "toString";
            //			}

            var directInvocationOnBasics = methodSymbol.ContainingType.IsBasicType();

            //Extension methods in Dlang are straightforward, although this could lead to clashes without qualification

            if (extensionNamespace != null || directInvocationOnBasics)
            {
                if (extensionNamespace == null)
                {
                    extensionNamespace = memberType.ContainingNamespace.FullName() + "." + memberType.Name;
                    //memberType.ContainingNamespace.FullName() +"."+ memberType.Name;
                }

                writer.Write(extensionNamespace);

                if (methodName != null)
                {
                    writer.Write(".");
                    writer.Write(methodName);
                }

                WriteTypeParameters(writer, typeParameters, invocationExpression);

                writer.Write("(");

                if (subExpressionOpt != null)
                {
                    firstParameter = false;
                    Core.Write(writer, subExpressionOpt);
                }
            }
            else
            {
                if (memberReferenceExpressionOpt != null)
                {
                    //Check against lowercase toString since it gets replaced with the lowered version before we get here
                    if (methodName == "toString")
                    {
                        if (memberType.TypeKind == TypeKind.Enum || isNullableEnum)
                        {
                            var enumType = memberType.TypeKind == TypeKind.Enum
                                ? memberType
                                : memberType.As <INamedTypeSymbol>().TypeArguments.Single();

                            //calling ToString() on an enum forwards to our enum's special ToString method
                            writer.Write(enumType.ContainingNamespace.FullNameWithDot());
                            writer.Write(WriteType.TypeName((INamedTypeSymbol)enumType));
                            writer.Write(".ToString(");
                            Core.Write(writer, memberReferenceExpressionOpt.Expression);
                            writer.Write(")");

                            if (invocationExpression.ArgumentList.Arguments.Count > 0)
                            {
                                throw new Exception(
                                          "Enum's ToString detected with parameters.  These are not supported " +
                                          Utility.Descriptor(invocationExpression));
                            }

                            return;
                        }

                        if (memberType.SpecialType == SpecialType.System_Byte)
                        {
                            //Calling ToString on a byte needs to take special care since it's signed in the JVM
                            writer.Write("System.SharpNative.ByteToString(");
                            Core.Write(writer, memberReferenceExpressionOpt.Expression);
                            writer.Write(")");

                            if (invocationExpression.ArgumentList.Arguments.Count > 0)
                            {
                                throw new Exception(
                                          "Byte's ToString detected with parameters.  These are not supported " +
                                          Utility.Descriptor(invocationExpression));
                            }

                            return;
                        }
                    }
                }

                if (subExpressionOpt != null)
                {
                    WriteMemberAccessExpression.WriteMember(writer, subExpressionOpt);

                    //                    if (!(subExpressionOpt is BaseExpressionSyntax))
                    //                    {
                    //                        if (methodName != null && methodSymbol.IsStatic)
                    //                            writer.Write(".");
                    //                        else
                    //						{
                    if (methodSymbol.MethodKind != MethodKind.DelegateInvoke)
                    {
                        writer.Write(".");
                    }
                    //                        }
                    //                    }
                    //					writer.Write(".");
                }
                else if (methodSymbol.IsStatic && extensionNamespace == null)
                {
                    var str = TypeProcessor.ConvertType(methodSymbol.ContainingType);
                    if (str == "Array_T")
                    {
                        // Array is the only special case, otherwise generics have to be specialized to access static members
                        str = "Array";
                    }

                    writer.Write(str);
                    //                    writer.Write(methodSymbol.ContainingNamespace.FullNameWithDot());
                    //                    writer.Write(WriteType.TypeName(methodSymbol.ContainingType));
                    writer.Write(".");
                }

                if (methodSymbol.MethodKind != MethodKind.DelegateInvoke)
                {
                    var declaringSyntaxReferences =
                        methodSymbol.DeclaringSyntaxReferences.Select(j => j.GetSyntax())
                        .OfType <MethodDeclarationSyntax>();
                    var any = declaringSyntaxReferences.Any();
                    if (any &&
                        declaringSyntaxReferences.FirstOrDefault()
                        .As <MethodDeclarationSyntax>()
                        .Modifiers.Any(SyntaxKind.NewKeyword))
                    {
                        //TODO: this means that new is not supported on external libraries
                        //					//why doesnt roslyn give me this information ?
                        methodName += "_";
                    }

                    if (any &&
                        declaringSyntaxReferences.FirstOrDefault()
                        .As <MethodDeclarationSyntax>()
                        .Modifiers.Any(SyntaxKind.NewKeyword))
                    {
                        writer.Write(TypeProcessor.ConvertType(methodSymbol.ContainingType) + ".");
                    }

                    //TODO: fix this for abstract too or whatever other combination
                    //TODO: create a better fix fot this
                    //					ISymbol interfaceMethod =
                    //						methodSymbol.ContainingType.AllInterfaces.SelectMany (
                    //							u =>
                    //						u.GetMembers (methodName)
                    //						.Where (
                    //								o =>
                    //							methodSymbol.ContainingType.FindImplementationForInterfaceMember (o) ==
                    //								methodSymbol)).FirstOrDefault ();

                    /*      if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface ||
                     * Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol), methodSymbol))
                     *
                     *        if ((interfaceMethod != null /*&& interfaceMethod == methodSymbol || methodSymbol.ContainingType.TypeKind == TypeKind.Interface)
                     *    {
                     *        //This is an interface method //TO
                     *
                     *        var typenameM = Regex.Replace (TypeProcessor.ConvertType (methodSymbol.ContainingType), @" ?!\(.*?\)", string.Empty);
                     *        if (typenameM.Contains ('.'))
                     *            typenameM = typenameM.SubstringAfterLast ('.');
                     *        if (methodSymbol.ContainingType.SpecialType == SpecialType.System_Array)
                     *            writer.Write ("");
                     *        else if (interfaceMethod != null)
                     *        {
                     *            var typenameI = Regex.Replace (TypeProcessor.ConvertType (interfaceMethod.ContainingType), @" ?!\(.*?\)", string.Empty);
                     *            if (typenameI.Contains ('.'))
                     *                typenameI = typenameI.SubstringAfterLast ('.');
                     *            writer.Write (typenameI + "_");
                     *        }
                     *        else // this is the interface itself
                     *                writer.Write (typenameM + "_");
                     *
                     *    }*/

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

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

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

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

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

                    //					var acc = methodSymbol.DeclaredAccessibility;

                    //					if (methodSymbol.MethodKind == MethodKind.ExplicitInterfaceImplementation)
                    //					{
                    //						var implementations = methodSymbol.ExplicitInterfaceImplementations[0];
                    //						if (implementations != null)
                    //						{
                    //							//  explicitHeaderNAme = implementations.Name;
                    //							methodName = TypeProcessor.ConvertType(implementations.ReceiverType) + "_" +implementations.Name; //Explicit fix ?
                    //
                    //							//			writer.Write(methodSymbol.ContainingType + "." + methodName);
                    //							//Looks like internal classes are not handled properly here ...
                    //						}
                    //					}

                    writer.Write(methodName);
                }
                WriteTypeParameters(writer, typeParameters, invocationExpression);
                writer.Write("(");
            }

            bool inParams         = false;
            bool foundParamsArray = false;

            var arguments = invocationExpression.ArgumentList.Arguments;

            foreach (var arg in arguments.Select(o => new TransformedArgument(o)))
            {
                if (firstParameter)
                {
                    firstParameter = false;
                }
                else
                {
                    writer.Write(", ");
                }

                var argumentType = TypeProcessor.GetTypeInfo(arg.ArgumentOpt.Expression);

                //				if (!inParams && IsParamsArgument (invocationExpression, arg.ArgumentOpt, methodSymbol))
                //				{
                //					foundParamsArray = true;
                //
                //					if (!TypeProcessor.ConvertType (TypeProcessor.GetTypeInfo (arg.ArgumentOpt.Expression).Type).StartsWith ("System.Array<"))
                //					{
                //						inParams = true;
                //						writer.Write ("Array_T!(");
                //					}
                //				}

                //Not needed for dlang
                //                if (arg != null
                //                    && arg.ArgumentOpt.RefOrOutKeyword.RawKind != (decimal) SyntaxKind.None
                //                    && TypeProcessor.GetSymbolInfo(arg.ArgumentOpt.Expression).Symbol is IFieldSymbol)
                //                {
                //
                //                }
                //                    throw new Exception("ref/out cannot reference fields, only local variables.  Consider using ref/out on a local variable and then assigning it into the field. " + Utility.Descriptor(invocationExpression));

                //				if (argumentType.Type == null) {
                //					if (argumentType.ConvertedType == null)
                //						writer.Write ("null");
                //					else
                //						writer.Write ("(cast("+TypeProcessor.ConvertType(argumentType.ConvertedType)+") null)");
                //				}
                //
                //                else if (argumentType.Type.IsValueType && !argumentType.ConvertedType.IsValueType)
                //                {
                //                    //Box
                //					writer.Write("BOX!("+TypeProcessor.ConvertType(argumentType.Type) +")(");
                //                    //When passing an argument by ref or out, leave off the .Value suffix
                //                    if (arg != null && arg.ArgumentOpt.RefOrOutKeyword.RawKind != (decimal)SyntaxKind.None)
                //                        WriteIdentifierName.Go(writer, arg.ArgumentOpt.Expression.As<IdentifierNameSyntax>(), true);
                //                    else
                //                        arg.Write(writer);
                //
                //                    writer.Write(")");
                //                }
                //                else if (!argumentType.Type.IsValueType && argumentType.ConvertedType.IsValueType)
                //                {
                //                    //UnBox
                //					writer.Write("cast(" + TypeProcessor.ConvertType(argumentType.Type) + ")(");
                //                    if (arg != null && arg.ArgumentOpt.RefOrOutKeyword.RawKind != (decimal)SyntaxKind.None)
                //                        WriteIdentifierName.Go(writer, arg.ArgumentOpt.Expression.As<IdentifierNameSyntax>(), true);
                //                    else
                //                        arg.Write(writer);
                //                    writer.Write(")");
                //                }
                //                else
                //                {
                //                    if (arg != null && arg.ArgumentOpt.RefOrOutKeyword.RawKind != (decimal)SyntaxKind.None)
                //                        WriteIdentifierName.Go(writer, arg.ArgumentOpt.Expression.As<IdentifierNameSyntax>(), true);
                //                    else
                //                        arg.Write(writer);
                //                }

                ProcessArgument(writer, arg.ArgumentOpt);
            }

            //			if (inParams)
            //				writer.Write (")");
            //			 if (!foundParamsArray && methodSymbol.Parameters.Any () && methodSymbol.Parameters.Last ().IsParams)
            //				writer.Write (", null"); //params method called without any params argument.  Send null.

            writer.Write(")");
        }
Exemplo n.º 12
0
        //TODO should enum be light class of static members ? or just a plain enum ? (using plain enum for now)
        public static void Go(OutputWriter writer, IEnumerable <EnumMemberDeclarationSyntax> allChildren)
        {
            //            writer.IsInterface = true;
            writer.Write("struct ");
            writer.Write(WriteType.TypeName(Context.Instance.Type, false) + "// Enum");

            //            writer.Write(Context.Instance.TypeName);

            //TODO: Find a better fix for this, casting integers to e.g. enum of ubyte gives lots of issues
            // writer.Write(":" + TypeProcessor.ConvertType(Context.Instance.Type.EnumUnderlyingType));
            writer.Write("\r\n");



            writer.OpenBrace();

            writer.WriteLine("public " + TypeProcessor.ConvertType(Context.Instance.Type.EnumUnderlyingType) + " __Value;");
            writer.WriteLine("alias __Value this;");

            writer.WriteLine("public enum __IsEnum = true; // Identifies struct as enum");

            string flagsvalue = "false";

            if (Context.Instance.Type.GetAttributes().Any(k => k.AttributeClass != null && k.AttributeClass.Name == "FlagsAttribute"))
            {
                flagsvalue = "true";
            }

            writer.WriteLine("public enum __HasFlags = {0}; // Identifies struct as enum", flagsvalue);



            writer.WriteLine(string.Format("public this({0} value)", TypeProcessor.ConvertType(Context.Instance.Type.EnumUnderlyingType)));
            writer.OpenBrace();
            writer.WriteLine("__Value = value;");
            writer.CloseBrace();


            writer.WriteLine();
            writer.WriteLine("public Type GetType()");
            writer.OpenBrace();
            writer.WriteLine("return __TypeOf!(typeof(this));");
            writer.CloseBrace();


            long lastEnumValue = 0;
            var  children      = allChildren.ToArray();
            var  values        =
                children.Select(
                    o => new { Syntax = o, Value = o.EqualsValue != null ? o.EqualsValue.Value : null })
                .ToList();

            var actualValues = new List <string>();

            for (int index = 0; index < values.Count; index++)
            {
                var value = values[index];
                var text  = "";

                text = "public enum " + WriteType.TypeName(Context.Instance.Type, false) + " "
                       + WriteIdentifierName.TransformIdentifier(value.Syntax.Identifier.Text);
                var expressionSyntax = value.Value;
                var expression       = expressionSyntax;

                //lets try parsing the value so we can evaluate it
                if (expression != null)
                {
                    var type = TypeProcessor.GetTypeInfo(expression);

                    var tempw = new TempWriter();

                    Core.Write(tempw, expression);

                    var temp = tempw.ToString();

                    if (type.Type != Context.Instance.Type.EnumUnderlyingType)
                    {
                        //TODO: only int enums are supported properly ... should we change them to static structs with constants ?
                        //						temp = "cast(" + TypeProcessor.ConvertType (Context.Instance.Type.EnumUnderlyingType) + ")" + temp;
                        temp = "cast(" + TypeProcessor.ConvertType(Context.Instance.Type.EnumUnderlyingType) + ")" +
                               temp;
                    }

                    actualValues.Add(temp);
                    text += " = " + temp;
                    tempw.Dispose();
                    ;
                }
                else
                {
                    if (expressionSyntax != null && expressionSyntax.ToFullString().Trim() != "")
                    {
                        text += expressionSyntax;
                    }
                    else
                    {
                        if (index > 0)
                        {
                            var temp =
                                WriteIdentifierName.TransformIdentifier(values[index - 1].Syntax.Identifier.Text) + " + 1";
                            text += " = " +
                                    temp;
                            actualValues.Add(temp);
                        }
                        else
                        {
                            text += " = 0";
                            actualValues.Add("0");
                        }
                    }
                }

                writer.WriteLine(text + ";");
            }

            //TODO: Need Fix
            var list = new List <string>();

            for (int index = 0; index < values.Count; index++)
            {
                var item = actualValues[index];
                for (int i = 0; i < values.Count; i++)
                {
                    var value = values[i];
                    if ((value.Value is LiteralExpressionSyntax) || value.Value == null)
                    {
                        item =
                            item.Replace(
                                TypeProcessor.ConvertType(Context.Instance.Type, true, false, false) + "." +
                                value.Syntax.Identifier.Text, actualValues[i]);
                        actualValues[i] = item;
                    }
                }
                list.Add(item);
            }

            writer.WriteLine("public enum __values =[" + list.Aggregate((a, b) => a + "," + b) + "];");
            writer.WriteLine("public enum __names =[" + values.Select(j => "\"" + WriteIdentifierName.TransformIdentifier(j.Syntax.Identifier.Text) + "\"").Aggregate((a, b) => a + "," + b) + "];");


            writer.WriteLine();
            var typeName = WriteType.TypeName(Context.Instance.Type, false);

            var baseString = "";


            writer.WriteLine();

            writer.WriteLine("{0} opBinary(string op)({0} rhs)", typeName);
            writer.OpenBrace();
            writer.WriteLine("return mixin(\"{0}(__Value \"~op~\" rhs.__Value)\");", typeName);
            writer.CloseBrace();

            writer.WriteLine("bool opEquals(const {0} a)", typeName);
            writer.OpenBrace();
            writer.WriteLine("return a.__Value == this.__Value;", typeName);
            writer.CloseBrace();

            writer.WriteLine("bool opEquals(const {0} a)", TypeProcessor.ConvertType(Context.Instance.Type.EnumUnderlyingType));
            writer.OpenBrace();
            writer.WriteLine("return a == this.__Value;", typeName);
            writer.CloseBrace();


            writer.WriteLine("public string toString()");
            writer.OpenBrace();

            /*  foreach (var membername in values)
             * {
             *    var name = WriteIdentifierName.TransformIdentifier(membername.Syntax.Identifier.Text);
             *    writer.WriteLine("if (this == {0}.__Value)", name);
             *    writer.OpenBrace();
             *    writer.WriteLine("return \"{0}\";", name);
             *    writer.CloseBrace();
             * }
             * writer.WriteLine("return std.conv.to!string(BOX(this.__Value).ToString().Text);");*/
            writer.WriteLine("return __ConvertEnumToString(this);");

            writer.CloseBrace();

            //Not needed for enum ... all enum should have a ToString function ...
            //            writer.WriteLine("public static class __Boxed_" + " " +
            //                                 //(genericArgs.Any() ? ("( " + (string.Join(" , ", genericArgs.Select(o => o)) + " )")) : "") +//Internal boxed should not be generic
            //                                 ": Boxed!(" + typeName + ")" + baseString);
            //
            //            writer.OpenBrace();
            //
            //
            //
            //            writer.WriteLine("import std.traits;");
            //
            //            var members = new List<ISymbol>();
            //
            //
            //
            //            //  foreach (var baseType in bases.Where(o => o.TypeKind == TypeKind.Interface))
            //            //{
            //
            //            var ifacemembers = members.DistinctBy(k => k);//Utility.GetAllMembers(Context.Instance.Type);
            //
            //            foreach (var member in ifacemembers)
            //            {
            //                var ifacemethod =
            //                    Context.Instance.Type.FindImplementationForInterfaceMember(member)
            //                        .DeclaringSyntaxReferences.First()
            //                        .GetSyntax();
            //
            //                var syntax = ifacemethod as MethodDeclarationSyntax;
            //                if (syntax != null)
            //                    WriteMethod.WriteIt(writer, syntax);
            //
            //                var property = ifacemethod as PropertyDeclarationSyntax;
            //                if (property != null)
            //                    WriteProperty.Go(writer, property, true);
            //
            //            }
            //            //}
            //
            //            //This is required to be able to create an instance at runtime / reflection
            //            //					this()
            //            //					{
            //            //						super(SimpleStruct.init);
            //            //					}
            //
            //            writer.WriteLine();
            //            writer.WriteLine("this()");
            //            writer.OpenBrace();
            //            writer.WriteLine("super(__TypeNew!({0})());", typeName);
            //            writer.CloseBrace();
            //
            //            writer.WriteLine();
            //            writer.WriteLine("public override Type GetType()");
            //            writer.OpenBrace();
            //            writer.WriteLine("return __TypeOf!(typeof(__Value));");
            //            writer.CloseBrace();
            //
            //
            //            if (Context.Instance.Type.GetMembers("ToString").Any()) // Use better matching ?
            //            {
            //                //					writer.WriteLine ();
            //                writer.WriteLine("override String ToString()");
            //                writer.OpenBrace();
            //                writer.WriteLine("return Value.ToString();");
            //                writer.CloseBrace();
            //            }
            //
            //            writer.WriteLine();
            //            writer.WriteLine("this(ref " + typeName + " value)");
            //            writer.OpenBrace();
            //            writer.WriteLine("super(value);");
            //            writer.CloseBrace();
            //
            //            writer.WriteLine();
            //            writer.WriteLine("U opCast(U)()");
            //            writer.WriteLine("if(is(U:{0}))", typeName);
            //            writer.OpenBrace();
            //            writer.WriteLine("return Value;");
            //            writer.CloseBrace();
            //
            //            writer.WriteLine();
            //            writer.WriteLine("U opCast(U)()");
            //            writer.WriteLine("if(!is(U:{0}))", typeName);
            //            writer.OpenBrace();
            //            writer.WriteLine("return this;");
            //            writer.CloseBrace();
            //
            //            writer.WriteLine();
            //            writer.WriteLine("auto opDispatch(string op, Args...)(Args args)");
            //            writer.OpenBrace();
            //            writer.WriteLine("enum name = op;");
            //            writer.WriteLine("return __traits(getMember, Value, name)(args);");
            //            writer.CloseBrace();

            //            writer.WriteLine();
            //            writer.WriteLine("public override Type GetType()");
            //            writer.OpenBrace();
            //            writer.WriteLine("return __Value.GetType();");
            //            writer.CloseBrace();


            //            writer.CloseBrace();

            writer.CloseBrace();
            //            writer.Write(";");
        }
Exemplo n.º 13
0
        private static string ConvertTypeUncached(ITypeSymbol typeSymbol)
        {
            if (typeSymbol.IsAnonymousType)
            {
                return(WriteAnonymousObjectCreationExpression.TypeName(typeSymbol.As <INamedTypeSymbol>()));
            }

            var array = typeSymbol as IArrayTypeSymbol;

            if (array != null)
            {
                var typeString = TryConvertType(array.ElementType, false);
//                if (localize)
//                {
//                    var name =
//                        Context.Instance.UsingDeclarations.FirstOrDefault(
//                            k => typeString.StartsWith(k.Name.ToFullString() + ".Namespace.", StringComparison.Ordinal));
//
//                    if (name != null)
//                        typeString = typeString.RemoveFromStartOfString(name.Name.ToFullString() + ".Namespace.");
//                }
                return("Array_T!(" + typeString + ")");
            }

            if (typeSymbol.TypeKind == TypeKind.PointerType)
            {
                var pointer = typeSymbol as IPointerTypeSymbol;
                return(ConvertType(pointer.PointedAtType) + "*");
            }

            var typeInfoStr = typeSymbol.ToString();

            var named = typeSymbol as INamedTypeSymbol;

            if (typeSymbol.TypeKind == TypeKind.TypeParameter)
            {
                return(WriteIdentifierName.TransformIdentifier(typeSymbol.Name, typeSymbol));
            }


            if (named != null && (named.ContainingNamespace.ToString() == "System" && named.Name == "Exception"))
            {
                return("System.Namespace.NException");
            }

            //TODO: Add explicit support for Nullable
            if (named != null && (named.Name == "Nullable" && named.ContainingNamespace.ToString() == "System"))
            {
                //Nullable types
                if (named.TypeArguments.Any())
                {
                    string convertedType = "";

                    if (named.TypeArguments.FirstOrDefault() is IErrorTypeSymbol)
                    {
                        //unbound generic
                        convertedType = "__UNBOUND";
                    }
                    else
                    {
                        convertedType = TryConvertType(named.TypeArguments.FirstOrDefault(), false);
                    }


                    return("Nullable__G!(" + convertedType + ")");
                }
            }

            var typeStr = GenericTypeName(typeSymbol);

            if (named != null && named.IsGenericType)
            {
                if (!named.IsUnboundGenericType && TypeArguments(named).Any())
                {
                    return(GetFullGenericName(named));
                }
                else
                {
                    return(GetFullGenericName(named.OriginalDefinition));
                }
            }


            switch (typeStr)
            {
            case "System.Namespace.Void":
                return("void");

            case "System.Namespace.Boolean":
                return("bool");

            case "System.Object":
            case "System.Namespace.Object":
                return("NObject");

            case "System.Namespace.UInt64":
                return("ulong");

            case "System.Namespace.Double":
                return("double");

            case "System.Namespace.Single":
                return("float");

            case "System.Namespace.String":
                return("String");

            case "System.Namespace.Int32":
                return("int");

            case "System.Namespace.UInt16":
                return("ushort");

            case "System.Namespace.Int64":
                return("long");

            case "System.Namespace.UInt32":
                return("uint");    // /TODO: Looks like d's uint32 is smaller than C#'s

            case "System.Namespace.Byte":
                return("ubyte");

            case "System.Namespace.SByte":
                return("byte");

            case "System.Namespace.Int16":
                return("short");

            case "System.Namespace.Char":
                return("wchar");

            case "System.Namespace.Array":
                return("Array");    //All template (generic) classes have atleast one "_T" appended

            default:

                if (named != null)
                {
                    return(typeSymbol.ContainingNamespace.FullNameWithDot(true, false) + WriteType.TypeName(named));
                }

                //This type does not get translated and gets used as-is
                return(typeSymbol.ContainingNamespace.FullNameWithDot(true, false) + WriteIdentifierName.TransformIdentifier(typeSymbol.Name));
            }
        }