Esempio n. 1
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(";");
        }
Esempio n. 2
0
        public static void Go(OutputWriter writer, ForEachStatementSyntax foreachStatement)
        {
            var info = new LoopInfo(foreachStatement);

            var types   = TypeProcessor.GetTypeInfo(foreachStatement.Expression);
            var typeStr = TypeProcessor.GenericTypeName(types.Type);

            writer.WriteLine("");


            //   writer.WriteOpenBrace();

//                writer.WriteIndent();

            var typeinfo = TypeProcessor.GetTypeInfo(foreachStatement.Expression);

//                var isPtr = typeinfo.Type != null && typeinfo.Type.IsValueType ? "" : "";
            var typeString = TypeProcessor.ConvertType(foreachStatement.Type) + " ";

            var foreachCount = Context.Instance.ForeachCount++;
            var isListT      = types.Type.OriginalDefinition == Context.ListT;
            var isArray      = types.Type is IArrayTypeSymbol;

            if (isArray || isListT)
            {//Lets just for through the array, iterators are slow ... really slow
                var forIter  = "__for" + foreachCount;
                var forArray = "__varfor" + foreachCount;

                var temp = new TempWriter();

                Core.Write(temp, foreachStatement.Expression);

                var expressiono = temp.ToString();

                // writer.WriteIndent();
                writer.WriteLine("auto {0} = {1};", forArray, expressiono);
                writer.WriteLine("for (int {0}=0;{0} < {2}.{3}; {0}++)", forIter, //Special case to support iterating "params" array
                                 WriteIdentifierName.TransformIdentifier(foreachStatement.Identifier.Text), forArray, isListT?"Count" :"length");

                writer.OpenBrace();
                writer.WriteLine("auto {0} = {1}[{2}];", WriteIdentifierName.TransformIdentifier(foreachStatement.Identifier.Text), forArray, forIter);
                Core.WriteStatementAsBlock(writer, foreachStatement.Statement, false);
                writer.CloseBrace();


                return;
            }
            //It's faster to "while" through arrays than "for" through them

            var foreachIter = "__foreachIter" + foreachCount;

            if (typeinfo.Type.AllInterfaces.OfType <INamedTypeSymbol>().Any(j => j.MetadataName == "IEnumerable`1") ||
                typeinfo.Type.MetadataName == "IEnumerable`1")
            {
                var collections = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System.Collections.Generic"));


                Context.Instance.UsingDeclarations = Context.Instance.UsingDeclarations
                                                     .Union(new[]
                {
                    collections
                }).ToArray();

                writer.WriteLine("//ForEach");
//				writer.OpenBrace ();
                writer.WriteIndent();
                writer.Write(string.Format("auto {0} = ", foreachIter));
                Core.Write(writer, foreachStatement.Expression);
                writer.Write(String.Format(".GetEnumerator(cast(IEnumerable__G!({0}))null);\r\n", typeString));
                writer.WriteLine(string.Format("while({0}.MoveNext())", foreachIter));
                writer.OpenBrace();

                writer.WriteLine(string.Format("{0}{1} = {2}.Current(cast(IEnumerator__G!({0}))null);", typeString,
                                               WriteIdentifierName.TransformIdentifier(foreachStatement.Identifier.Text), foreachIter));

                Core.WriteStatementAsBlock(writer, foreachStatement.Statement, false);

                writer.CloseBrace();
                writer.WriteLine("");

//				writer.CloseBrace ();
                foreachCount++;
            }
            else
            {
                var collections = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System.Collections"));
                Context.Instance.UsingDeclarations = Context.Instance.UsingDeclarations
                                                     .Union(new[]
                {
                    collections
                }).ToArray();

                writer.WriteLine("//ForEach");
                writer.WriteIndent();
                writer.Write(string.Format("auto {0} = ", foreachIter));
                Core.Write(writer, foreachStatement.Expression);
                writer.Write(".GetEnumerator();\r\n");
                writer.WriteLine(string.Format("while({0}.MoveNext())", foreachIter));
                writer.OpenBrace();

                writer.WriteLine(string.Format("{0}{1} = UNBOX!({0})({2}.Current);", typeString,
                                               WriteIdentifierName.TransformIdentifier(foreachStatement.Identifier.Text), foreachIter));

                Core.WriteStatementAsBlock(writer, foreachStatement.Statement, false);

                writer.CloseBrace();
                writer.WriteLine("");

                foreachCount++;
            }
        }
Esempio n. 3
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();
        }
        public static void Go(OutputWriter writer, ElementAccessExpressionSyntax expression)
        {
            var type            = TypeProcessor.GetTypeInfo(expression.Expression).Type;
            var typeStr         = TypeProcessor.GenericTypeName(type);
            var additionalParam = "";
            var symbol          = TypeProcessor.GetSymbolInfo(expression); //This could be null

            if (symbol.Symbol != null)
            {
                var methodSymbol = symbol.Symbol as IPropertySymbol;
                //Lets find out if this is an interface implementation
                if (methodSymbol != null)
                {
                    IEnumerable <ISymbol> interfaceMethods =
                        methodSymbol.ContainingType.AllInterfaces.SelectMany(
                            u =>
                            u.GetMembers(methodSymbol.Name));

                    interfaceMethods =
                        interfaceMethods.Where(
                            o => Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(o), methodSymbol));

                    if (interfaceMethods.Any())
                    {
                        //Lets  get the best match
                        var interfaceMethod = interfaceMethods.FirstOrDefault();
                        additionalParam = "cast(" + TypeProcessor.ConvertType(interfaceMethod.ContainingType) + ")null";
                    }
                }
            }

            //type.GetMembers("this[]")
            //Todo if we are using unsafe / fast mode, just use array->Data()[i] should bypass bounds check and indirection also should be as fast as pure c++ arrays
            //though fixed syntax could fix this too ??
            //            writer.Write("(*");

            Core.Write(writer, expression.Expression);

            if (type.SpecialType == SpecialType.System_Array)
            {
//            writer.Write(")");
                writer.Write(".Items["); //TODO test this thoroughly
            }
            else
            {
                writer.Write("["); //TODO test this thoroughly
            }
            var first = true;

            foreach (var argument in expression.ArgumentList.Arguments)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    writer.Write(", ");
                }

                Core.Write(writer, argument.Expression);
            }
            if (additionalParam != "")
            {
                writer.Write("," + additionalParam);
            }
            writer.Write("]");
        }
        public static void Go(OutputWriter writer, CastExpressionSyntax expression)
        {
            var symbol = TypeProcessor.GetSymbolInfo(expression);

            var castingFrom = TypeProcessor.GetTypeInfo(expression.Expression).Type ??
                              TypeProcessor.GetTypeInfo(expression).Type;

            var srcTypeCpp    = TypeProcessor.ConvertType(castingFrom);
            var destType      = TypeProcessor.GetTypeInfo(expression.Type).Type;
            var destTypeDlang = TypeProcessor.TryConvertType(expression.Type);

            if (destTypeDlang == srcTypeCpp)
            {
                Core.Write(writer, expression.Expression);
            }
            else
            //if (symbol.Symbol != null)// && srcTypeCpp != "int" && srcTypeCpp != "System.String" && srcTypeCpp != "bool")
            {
//                if (castingFrom != destType) // Check for implicit first then explicit

                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 = destType.GetImplicitCoversionOp(destType, castingFrom, true);
                //                            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 =
                        castingFrom.GetImplicitCoversionOp(destType, castingFrom, true);
                    //.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 (correctConverter.ReturnType != destType)
                    {
                        writer.Write("cast(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")");
                    }
                    if (useType)
                    {
                        writer.Write(TypeProcessor.ConvertType(destType) + "." + "op_Implicit_" +
                                     TypeProcessor.ConvertType(correctConverter.ReturnType));
                    }
                    else
                    {
                        writer.Write(TypeProcessor.ConvertType(castingFrom) + "." + "op_Implicit_" +
                                     TypeProcessor.ConvertType(correctConverter.ReturnType));
                    }
                    writer.Write("(");
                    Core.Write(writer, expression.Expression);
                    writer.Write(")");
                    return;
                }

                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
                correctConverter = destType.GetExplictCoversionOp(destType, castingFrom, true);
                //                            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 =
                        castingFrom.GetExplictCoversionOp(destType, castingFrom, true);
                    //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
                }

                if (correctConverter != null)
                {
                    if (correctConverter.ReturnType != destType)
                    {
                        writer.Write("cast(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")");
                    }

                    //                            Core.Write(writer, expression.Left);
                    //                            writer.Write(" = ");
                    if (useType)
                    {
                        writer.Write(TypeProcessor.ConvertType(destType) + "." + "op_Explicit");
                    }
                    else
                    {
                        writer.Write(TypeProcessor.ConvertType(castingFrom) + "." + "op_Explicit");
                    }
                    writer.Write("(");
                    Core.Write(writer, expression.Expression);
                    writer.Write(")");
                    return;
                }

                if (TypeProcessor.IsPrimitiveType(srcTypeCpp) && TypeProcessor.IsPrimitiveType(destTypeDlang))
                {
                    writer.Write("(cast(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")");
                    Core.Write(writer, expression.Expression);
                    writer.Write(")");
                }

                else
                {
                    var convertedType = TypeProcessor.GetTypeInfo(expression).Type;
                    var type          = TypeProcessor.GetTypeInfo(expression.Expression).Type;

                    if (type.IsValueType && !convertedType.IsValueType)
                    {
                        //We have to box then cast if not Object
                        if (destType.Name != "Object")
                        {
                            writer.Write("cast(" + destTypeDlang + ")");
                        }
                        //Box
                        writer.Write("BOX!(" + TypeProcessor.ConvertType(type) + ")(");
                        //When passing an argument by ref or out, leave off the .Value suffix
//                    writer.Write(" >(");
                        Core.Write(writer, expression.Expression);
                        writer.Write(")");
                    }
                    else if (!type.IsValueType && convertedType.IsValueType)
                    {
                        //UnBox
//					writer.Write("(cast( Boxed!(" + TypeProcessor.ConvertType(convertedType) + ") )(");
//                    Core.Write(writer, expression.Expression);
//					writer.Write(")).Value");

                        writer.Write("UNBOX!(" + TypeProcessor.ConvertType(convertedType) + ")(");
                        Core.Write(writer, expression.Expression);
                        writer.Write(")");
                    }
                    else if (type.IsValueType && convertedType.IsValueType)
                    {
                        //cannot use ascast here, its for boxed types and objects
                        writer.Write("(cast(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")(");
                        Core.Write(writer, expression.Expression);
                        writer.Write("))");
                    }
                    else
                    {
                        writer.Write("AsCast!(");
                        writer.Write(destTypeDlang);
                        writer.Write(")(");
                        Core.Write(writer, expression.Expression);
                        writer.Write(")");
                    }
                }
            }
        }
Esempio n. 6
0
        private static string GetTypeConstraints(TypeDeclarationSyntax method)
        {
            string constraints = "";

            if (method.ConstraintClauses.Count > 0)
            {
                constraints += (" if (");
                bool isFirst = true;
                foreach (var constraint in method.ConstraintClauses)
                {
                    foreach (var condition in constraint.Constraints)
                    {
                        if (condition is TypeConstraintSyntax)
                        {
                            var type = (condition as TypeConstraintSyntax).Type;
                            constraints += (isFirst ? "" : "&&") + "is(" + WriteIdentifierName.TransformIdentifier(constraint.Name.ToFullString()) + ":" + TypeProcessor.ConvertType(type) + ")";
                        }

                        if (condition is ConstructorConstraintSyntax)
                        {
                            constraints += (isFirst ? "" : "&&") + "__isNewwable!(" + WriteIdentifierName.TransformIdentifier(constraint.Name.ToFullString()) + ")";
                        }

                        if (condition is ClassOrStructConstraintSyntax)
                        {
                            var properConstraint = condition as ClassOrStructConstraintSyntax;
                            if (properConstraint.ClassOrStructKeyword.RawKind == (decimal)SyntaxKind.StructKeyword)
                            {
                                constraints += (isFirst ? "" : "&&") + "__isCSStruct!(" + WriteIdentifierName.TransformIdentifier(constraint.Name.ToFullString()) + ")";
                            }
                            else
                            {
                                constraints += (isFirst ? "" : "&&") + "__isClass!(" + WriteIdentifierName.TransformIdentifier(constraint.Name.ToFullString()) + ")";
                            }
                        }

                        /*  string dlangCondition = condition.ToString();
                         *
                         * if (dlangCondition == "new()") // haven't got around to this yet
                         *    // constraints += " __traits(compiles, {0}())";//Fix this
                         *    dlangCondition = "";
                         * if (dlangCondition == "class") // TODO: is there a better way to do this ?
                         *    dlangCondition = "NObject";
                         *
                         * if (dlangCondition == "struct")
                         *    constraints += ((isFirst ? "" : "&&") + " !is(" + constraint.Name + " : NObject)");
                         * else
                         * {
                         *    //TODO: fix this up better
                         *    constraints += ((isFirst ? "" : "&&") + " is(" + constraint.Name + " : " + dlangCondition.Replace("<", "!(").Replace(">", ")") +
                         *                    ")");
                         * }*/

                        isFirst = false;

                        //								Console.WriteLine (condition);
                    }
                }

                constraints += (")");
            }
            return(constraints);
        }
Esempio n. 7
0
        public static void Go(OutputWriter writer, InitializerExpressionSyntax initializer)
        {
            writer.WriteIndent();
            var isCollectionInit = false;

            if (CSharpExtensions.CSharpKind(initializer) == SyntaxKind.CollectionInitializerExpression ||
                CSharpExtensions.CSharpKind(initializer) == SyntaxKind.ArrayInitializerExpression)
            {
                var tx = TypeProcessor.GetTypeInfo(initializer);

                var t = tx.Type;
                if (t == null)
                {
                    t = tx.ConvertedType;
                }
                if (t != null) // Initializer within initializer
                {
                    var elementType = t.As <IArrayTypeSymbol>().ElementType;
                    var ptr         = !elementType.IsValueType; // ? "" : "";
                    var type        = TypeProcessor.ConvertType(elementType);
                    var typeString  = "Array_T!(" + type + ")";

                    if (elementType.TypeKind == TypeKind.TypeParameter)
                    {
                        writer.Write(" __TypeNew!(" + typeString + ")(");
                    }
                    else
                    {
                        writer.Write("new " + typeString + "(");
                    }
                }
                var variableDeclarationSyntax = initializer.Parent.Parent.Parent as VariableDeclarationSyntax;
                if (variableDeclarationSyntax != null)
                {
                    var atype = variableDeclarationSyntax.Type;
                    initializer.WriteArrayInitializer(writer, atype);
                }
                else
                {
                    initializer.WriteArrayInitializer(writer);
                }
                if (t != null)
                {
                    writer.Write(")");
                }
            }
            else
            {
                //            writer.Write("goto ");
                //            foreach (var expressionSyntax in method.Expressions)
                //            {
                //                Core.Write(writer, expressionSyntax);
                //            }

                bool first = true;
                foreach (var expression in initializer.Expressions)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        writer.Write(", ");
                    }

                    Core.Write(writer, expression);
                }
            }

            //            writer.Write(";");
        }
Esempio n. 8
0
 public static void WriteMethodPointer(OutputWriter writer, SyntaxNode expression)
 {
     writer.Write("&");
     var symbol = TypeProcessor.GetSymbolInfo(expression).Symbol;
     //
     //            else
     {
         Core.Write(writer, expression);
         if (symbol is IMethodSymbol && !(expression is GenericNameSyntax))
         {
             //Type inference for delegates
             var methodSymbol = symbol as IMethodSymbol;
             //   var methodName = TypeProcessor.ConvertType(methodSymbol.ContainingType) +"."+ WriteIdentifierName.TransformIdentifier(methodSymbol.Name);
             var specializedMethod = //methodName +
                                     (methodSymbol.TypeArguments.Any() ? ("!(" +
                                                                          methodSymbol.TypeArguments.Select(k => TypeProcessor.ConvertType(k))
                                                                          .Aggregate((a, b) => a + "," + b) + ")") : "");
             writer.Write(specializedMethod);
         }
     }
 }
Esempio n. 9
0
        public static void Go()
        {
            var partials = Context.Instance.Partials;
            var first    = partials.First();

            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;
            Console.WriteLine("Writing out type: " + Context.Instance.Namespace + "." + Context.Instance.TypeName);
            if ((Context.Instance.Namespace + "." + Context.Instance.TypeName) ==
                "Mono.Security.X509.Namespace.X509Chain")
            {
            }

            var myUsingDirective     = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(mynamespace));
            var SystemUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System"));
            // Required as certain functions like boxing are in this namespace
            var namespaces      = first.Syntax.Parent.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray();
            var usingStatements = first.Syntax.Parent.DescendantNodes().OfType <UsingStatementSyntax>().ToArray();

            Context.Instance.UsingDeclarations = namespaces
                                                 .Union(new[]
            {
                myUsingDirective, SystemUsingDirective
            }).ToArray();

            var objectType =
                TypeProcessor.GetSemanticModel(partials.First().Syntax)
                .Compilation.GetTypeByMetadataName("System.Object");

            using (var writer = new OutputWriter(Context.Instance.Namespace, Context.Instance.TypeName))
            {
                var bases = partials
                            .Select(o => o.Syntax.BaseList)
                            .Where(o => o != null)
                            .SelectMany(o => o.Types)
                            .Select(o => TypeProcessor.GetTypeInfo(o.Type).ConvertedType)
                            .Distinct()
                            .ToList();

                //                var interfaces = bases.Where(o => o.TypeKind == TypeKind.Interface).ToList();

                if (!bases.Any((j => j.TypeKind != TypeKind.Interface)) &&
                    !(first.Symbol.TypeKind == TypeKind.Interface || first.Symbol.TypeKind == TypeKind.Struct))
                {
                    //TODO: fix structs using mixins / alias this
                    bases.Add(objectType);
                }

                //                    WriteStandardIncludes.Go(writer);

                //                    writer.WriteLine(String.Format("#include \"{0}\"", TypeState.Instance.TypeName + ".h"));

                WriteBcl.Go(writer);

                //TypeState.Instance.DerivesFromObject = bases.Count == interfaces.Count;

                var @namespace = first.Symbol.ContainingNamespace.FullName();

                //Module name = namespace + "." + typename;

                WriteStandardIncludes.Go(writer);

                //                    var namespaces = @namespace.Split(new string[] { "." }, StringSplitOptions.None);
                //
                //                    if (@namespace.Length > 0)
                //                    {
                //                        foreach (var ns in namespaces)
                //                        {
                //                            writer.WriteLine("namespace " + ns + "\r\n{");
                //                            writer.WriteLine("namespace " + ns + "\r\n{");
                //                        }
                //
                //                    }

                //TODO: Fix enum support
                if (first.Syntax is EnumDeclarationSyntax)
                {
                    WriteEnum.Go(writer,
                                 Context.Instance.Partials.Select(o => o.Syntax)
                                 .Cast <EnumDeclarationSyntax>()
                                 .SelectMany(o => o.Members)
                                 .Where(o => !Program.DoNotWrite.ContainsKey(o)));

                    return;
                }

                Context.Instance.AllMembers =
                    partials.Select(o => o.Syntax)
                    .Cast <TypeDeclarationSyntax>()
                    .SelectMany(o => o.Members)
                    .Where(o => !Program.DoNotWrite.ContainsKey(o))
                    .ToList();

                var allMembersToWrite = Context.Instance.AllMembers
                                        .Where(member => !(member is TypeDeclarationSyntax) &&
                                               !(member is EnumDeclarationSyntax) &&
                                               !(member is DelegateDeclarationSyntax) &&
                                               !(member is ConstructorDeclarationSyntax))
                                        .ToList();

                var instanceCtors = Context.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>()
                                    .Where(o => !o.Modifiers.Any(SyntaxKind.StaticKeyword))
                                    .ToList();

                var staticCtors = Context.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>()
                                  .Where(o => (o.Modifiers.Any(SyntaxKind.StaticKeyword)))
                                  .ToList();

                //TODO: Add support for overloading constructing
                //                    if (instanceCtors.Count > 1)
                //                        throw new Exception(
                //                            "Overloaded constructors are not supported.  Consider changing all but one to static Create methods " +
                //                            Utility.Descriptor(first.Syntax));

                //                    var ctorOpt = instanceCtors.SingleOrDefault();
                //TODO: Handle interfaces by

                /*
                 * class Interface
                 * {
                 *  public:
                 *      virtual ~Interface() { }
                 *      virtual void test() = 0; // Functions, must all be virtual
                 * }
                 */

                var membersToWrite = allMembersToWrite.ToList();
                //.Where(o => IsStatic(o) == staticMembers).ToList();

                //                    if (membersToWrite.Count == 0 && (partials.Any(o => o.Syntax.Modifiers.Any(SyntaxKind.StaticKeyword))))
                //                        continue;

                //                    if (staticMembers)
                //                        writer.Write("object ");
                //                    else if (first.Syntax.Kind == SyntaxKind.InterfaceDeclaration)
                //                        writer.Write("trait ");
                //                    else
                //                    {
                //                        if (partials.Any(o => o.Syntax.Modifiers.Any(SyntaxKind.AbstractKeyword)))
                //                            writer.Write("abstract ");

                //                    }

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

                if (first.Syntax is TypeDeclarationSyntax)
                {
                    //Look for generic arguments
                    var genericArgs = partials
                                      .Select(o => o.Syntax)
                                      .Cast <TypeDeclarationSyntax>()
                                      .Where(o => o.TypeParameterList != null)
                                      .SelectMany(o => o.TypeParameterList.Parameters)
                                      .ToList();

                    if (Context.Instance.Type.TypeKind == TypeKind.Class)
                    {
                        writer.Write("class ");
                    }
                    else if (Context.Instance.Type.TypeKind == TypeKind.Interface)
                    {
                        writer.Write("interface ");
                    }
                    else if (Context.Instance.Type.TypeKind == TypeKind.Struct)
                    {
                        writer.Write("struct ");
                        //						writer.Write (" class "); // Allows inheritance ... but too many issues, will look at this when it gets relevant
                    }
                    else
                    {
                        throw new Exception("don't know how to write type: " + Context.Instance.Type.TypeKind);
                    }
                    //writer.Write (((TypeState.Instance.Type.TypeKind== TypeKind.Interface)?" interface ": ) );

                    writer.Write(Context.Instance.TypeName);

                    if (genericArgs.Count > 0)
                    {
                        writer.Write("( ");
                        writer.Write(string.Join(" , ", genericArgs.Select(o => o)));
                        writer.Write(" )");
                    }

                    bool firstBase = true;

                    if (Context.Instance.Type.TypeKind != TypeKind.Struct)
                    {
                        foreach (var baseType in bases.OrderBy(o => o.TypeKind == TypeKind.Interface ? 1 : 0))
                        {
                            writer.Write(firstBase ? " : " : " ,");

                            writer.Write(TypeProcessor.ConvertType(baseType));

                            //                            if (firstBase && ctorOpt != null && ctorOpt.Initializer != null &&
                            //                                ctorOpt.Initializer.ArgumentList.Arguments.Count > 0)
                            //                            {
                            //                                writer.Write("(");
                            //                                bool firstArg = true;
                            //                                foreach (var init in ctorOpt.Initializer.ArgumentList.Arguments)
                            //                                {
                            //                                    if (firstArg)
                            //                                        firstArg = false;
                            //                                    else
                            //                                        writer.Write(", ");
                            //
                            //                                    Core.Write(writer, init.Expression);
                            //                                }
                            //                                writer.Write(")");
                            //                            }

                            firstBase = false;
                        }
                    }
                }

                writer.WriteLine();

                writer.OpenBrace();

                var fields    = membersToWrite.OfType <FieldDeclarationSyntax>().ToList();
                var nonFields = membersToWrite.Except(fields); // also static fields should be separately dealt with

                var structLayout = first.Syntax.GetAttribute(Context.StructLayout);
                if (structLayout != null)
                {
                    LayoutKind value = LayoutKind.Auto;
                    if (
                        structLayout.ArgumentList.Arguments.Any(
                            k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Value"))
                    {
                        value =
                            (LayoutKind)
                            Enum.Parse(typeof(LayoutKind),
                                       structLayout.ArgumentList.Arguments.FirstOrDefault(
                                           k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Value")
                                       .Expression.ToFullString()
                                       .SubstringAfterLast('.'));
                        //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                    }
                    //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                    else if (structLayout.ArgumentList.Arguments.Count > 0 &&
                             structLayout.ArgumentList.Arguments[0].NameEquals == null)
                    {
                        value =
                            (LayoutKind)
                            Enum.Parse(typeof(LayoutKind),
                                       structLayout.ArgumentList.Arguments[0].Expression.ToFullString()
                                       .SubstringAfterLast('.'));
                    }
                    int     pack    = -1;
                    int     size    = -1;
                    CharSet charset = CharSet.Auto;
//					if (structLayout.ArgumentList.Arguments.Count > 1)
                    {
                        try
                        {
                            if (
                                structLayout.ArgumentList.Arguments.Any(
                                    k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "CharSet"))
                            {
                                charset =
                                    (CharSet)
                                    Enum.Parse(typeof(CharSet),
                                               structLayout.ArgumentList.Arguments.FirstOrDefault(
                                                   k =>
                                                   k.NameEquals != null &&
                                                   k.NameEquals.Name.ToFullString().Trim() == "CharSet")
                                               .Expression.ToFullString()
                                               .SubstringAfterLast('.'));
                                //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                            }
                            //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                            else if (structLayout.ArgumentList.Arguments.Count > 1 &&
                                     structLayout.ArgumentList.Arguments[1].NameEquals == null)
                            {
                                charset =
                                    (CharSet)
                                    Enum.Parse(typeof(CharSet),
                                               structLayout.ArgumentList.Arguments[1].Expression.ToFullString()
                                               .SubstringAfterLast('.'));
                            }
                        }
                        catch (Exception ex)
                        {
                        }

                        try
                        {
                            if (
                                structLayout.ArgumentList.Arguments.Any(
                                    k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Pack"))
                            {
                                pack =
                                    int.Parse(
                                        structLayout.ArgumentList.Arguments.FirstOrDefault(
                                            k =>
                                            k.NameEquals != null &&
                                            k.NameEquals.Name.ToFullString().Trim() == "Pack")
                                        .Expression.ToFullString());
                            }
                            //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                            else if (structLayout.ArgumentList.Arguments.Count > 2 &&
                                     structLayout.ArgumentList.Arguments[2].NameEquals == null)
                            {
                                pack = int.Parse(structLayout.ArgumentList.Arguments[2].Expression.ToFullString());
                            }
                        }
                        catch (Exception ex)
                        {
                        }

                        try
                        {
                            if (
                                structLayout.ArgumentList.Arguments.Any(
                                    k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Size"))
                            {
                                size =
                                    int.Parse(
                                        structLayout.ArgumentList.Arguments.FirstOrDefault(
                                            k => k.NameColon != null && k.NameColon.ToFullString().Trim() == "Size")
                                        .Expression.ToFullString());
                            }
                            //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                            else if (structLayout.ArgumentList.Arguments.Count > 3 &&
                                     structLayout.ArgumentList.Arguments[3].NameEquals == null)
                            {
                                size = int.Parse(structLayout.ArgumentList.Arguments[3].Expression.ToFullString());
                            }
                        }
                        catch (Exception ex)
                        {
                        }

//						size = int.Parse (structLayout.ArgumentList.Arguments [3].Expression.ToFullString ());
                    }
                    //					var pack = structLayout.ArgumentList.Arguments.FirstOrDefault (k => k.NameColon.Name.ToFullString() == "Pack");
//					var charset = structLayout.ArgumentList.Arguments.FirstOrDefault (k => k.NameColon.Name.ToFullString() == "CharSet");
//					var size = structLayout.ArgumentList.Arguments.FirstOrDefault (k => k.NameColon.Name.ToFullString() == "Size");

                    if (value == LayoutKind.Explicit)
                    {
                        var fieldGroups =
                            fields.GroupBy(f => f.GetAttribute(Context.FieldOffset).ArgumentList.Arguments[0].ToString())
                            .OrderBy(k => k.Key);
                        writer.Indent++;

                        foreach (var group in fieldGroups)
                        {
                            writer.WriteLine("//FieldOffset(" + @group.Key + ")");
                            writer.WriteLine("union {");
                            foreach (var member in group)
                            {
                                Core.Write(writer, member);
                            }
                            writer.WriteLine("}");
                        }

//						foreach (var member in fields)
//						{
//							//                    writer.WriteLine();
//							Core.Write (writer, member);
//						}
                    }
                    else if (value == LayoutKind.Sequential)
                    {
                        fields = SortFields(fields);

                        writer.Indent++;

                        foreach (var member in fields)
                        {
                            if (pack != -1)
                            {
                                writer.WriteLine("align (" + pack + "): //Pack = " + pack);
                            }
                            //                    writer.WriteLine();
                            Core.Write(writer, member);
                        }
                    }

                    else
                    {
                        //Looks like C# aligns to 1 by default ... don't know about D...
                        fields = SortFields(fields);

                        writer.Indent++;
                        foreach (var member in fields)
                        {
                            pack = 1;
                            writer.WriteLine("align (" + pack + "): //Pack = " + pack + "C# default");
                            //                    writer.WriteLine();
                            Core.Write(writer, member);
                        }
                    }
                }
                else
                {
                    //Looks like C# aligns to 1 by default ... don't know about D...
                    fields = SortFields(fields);

                    writer.Indent++;
                    foreach (var member in fields)
                    {
                        var pack = 1;
                        writer.WriteLine("align (" + pack + "): //Pack = " + pack + "C# default");
                        //                    writer.WriteLine();
                        Core.Write(writer, member);
                    }
                }

                foreach (var member in nonFields)
                {
//                    writer.WriteLine();
                    Core.Write(writer, member);
                }

                foreach (var constructor in instanceCtors)
                {
//                    writer.WriteLine();
                    Core.Write(writer, constructor);
                }

                if (staticCtors.Count == 0)
                {
                    if (Context.Instance.StaticInits.Count > 0)
                    {
                        var constructor = SyntaxFactory.ConstructorDeclaration(Context.Instance.TypeName);
                        constructor =
                            constructor.WithModifiers(
                                SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.StaticKeyword)));

                        WriteConstructorBody.WriteStaticConstructor(writer, constructor, Context.Instance.StaticInits);

                        staticCtors.Add(constructor);
                    }
                }
                else
                {
                    var isFirst = true;
                    foreach (ConstructorDeclarationSyntax constructor in staticCtors)
                    {
                        if (isFirst)
                        {
                            WriteConstructorBody.WriteStaticConstructor(writer, constructor,
                                                                        Context.Instance.StaticInits);
                        }
                        else
                        {
                            WriteConstructorBody.Go(writer, constructor);
                        }

                        isFirst = false;
                    }
                }

                var dllImports = Context.Instance.DllImports;
                // This should only be written once ... I guess we have to put the detection logic in Program.cs

                if (Context.Instance.EntryMethod != null)
                {
                    if (dllImports.Count > 0)
                    {
                        writer.WriteLine();

                        writer.WriteLine(String.Format("static void * __DllImportMap[{0}];", dllImports.Count));
                        writer.WriteLine("static void __SetupDllImports()");

                        writer.OpenBrace();

                        for (int index = 0; index < dllImports.Count; index++)
                        {
                            var dllImport = dllImports[index];
                            writer.WriteLine(String.Format("__DllImportMap[{0}] = LoadNativeLibrary(cast(string){1});",
                                                           index, dllImport.ArgumentList.Arguments.FirstOrDefault(k => k.Expression != null)));
                        }
                        writer.CloseBrace();
                        writer.WriteLine();
                        writer.WriteLine("static void __FreeDllImports()");
                        writer.OpenBrace();
                        writer.WriteLine(String.Format(@"for(int i=0;i<{0};i++)", dllImports.Count));
                        writer.OpenBrace();
                        writer.WriteLine("if(__DllImportMap[i]!=null)");
                        writer.WriteLine("\tFreeNativeLibrary(__DllImportMap[i]);");
                        writer.CloseBrace();
                        writer.CloseBrace();

                        //                            if (hModule != null)
                        //                            {
                        //    ::FreeLibrary(hModule);
                        //                            }
                    }
                }
                writer.Indent--;
                writer.CloseBrace();

                //Implement Boxed!Interface
                if (Context.Instance.Type.TypeKind == TypeKind.Struct)
                {
                    writer.WriteLine();
                    var typeName = Context.Instance.TypeName;
                    writer.Write("public class __Boxed_" + typeName + " : Boxed!(" + typeName + ")");
                    foreach (var baseType in bases.OrderBy(o => o.TypeKind == TypeKind.Interface ? 1 : 0))
                    {
                        writer.Write(" ,");

                        writer.Write(TypeProcessor.ConvertType(baseType, false));
                    }

                    writer.OpenBrace();

                    //FIXME:This is giving issues, we will just generate them here

//					writer.WriteLine ("import Irio.Utilities;");

                    writer.WriteLine("import std.traits;");

                    foreach (var baseType in bases.Where(o => o.TypeKind == TypeKind.Interface))
                    {
                        //FIXME:This is giving issues, we will just generate them here
//						writer.WriteLine ("mixin(__ImplementInterface!({0}, Value));",TypeProcessor.ConvertType(baseType,false));
                        var ifacemembers = baseType.GetMembers();

                        foreach (var member in ifacemembers)
                        {
                            var ifacemethod =
                                Context.Instance.Type.FindImplementationForInterfaceMember(member)
                                .DeclaringSyntaxReferences.First()
                                .GetSyntax();
//								.Where(member => !(member is TypeDeclarationSyntax)
//									&& !(member is EnumDeclarationSyntax)
//									&& !(member is DelegateDeclarationSyntax) && !(member is ConstructorDeclarationSyntax))
//								.ToList();

                            //                    writer.WriteLine();
//							Core.Write(writer, member);

                            if (ifacemethod is MethodDeclarationSyntax)
                            {
                                WriteMethod.WriteIt(writer, (MethodDeclarationSyntax)ifacemethod);
                            }
                            else if (ifacemethod is PropertyDeclarationSyntax)
                            {
                                WriteProperty.Go(writer, (PropertyDeclarationSyntax)ifacemethod, 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({0}.init);", typeName);
                    writer.CloseBrace();

                    if (Context.Instance.Type.GetMembers("ToString").Count() >= 1) // 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.CloseBrace();
                }

                if (Context.Instance.EntryMethod != null)
                {
                    //TODO: DllImports should be centralized

                    //
                    writer.WriteLine();
                    writer.WriteLine("void main(string[] args)");
                    writer.OpenBrace();

                    if (dllImports.Count > 0)
                    {
                        writer.WriteLine(Context.Instance.TypeName + ".__SetupDllImports();");
                    }
                    writer.WriteLine(Context.Instance.EntryMethod);
                    if (dllImports.Count > 0)
                    {
                        writer.WriteLine(Context.Instance.TypeName + ".__FreeDllImports();");
                    }

                    writer.CloseBrace();
                }

                //				var mySpecializations = Program.AllGenericSpecializations.Where (t => t.OriginalDefinition == TypeState.Instance.Type);
                //
                //
                //				foreach (var specialization in mySpecializations) {
                //
                //					var specializationText = ("template class " + specialization.GetFullNameD (false) + " (" +
                //					                                            (string.Join (" , ",
                //						                                            specialization.TypeArguments.Select (
                //							                                            o =>
                //                                                                       TypeProcessor.ConvertType (o) +
                //							                                            ((o.IsValueType ||
                //							                                            o.TypeKind == TypeKind.TypeParameter)
                //                                                                           ? ""
                //                                                                           : "*"))) +
                //							");"));
                //					writer.Write (specializationText);
                //				}

                //                    if (@namespace.Length > 0)
                //                    {
                //                        foreach (var ns in namespaces)
                //                        {
                //                            writer.WriteLine("\n\n}");
                //                            writer.WriteLine("\n\n}");
                //                        }
                //                    }
            }
        }
Esempio n. 10
0
        /*
         * template Action(T) {
         * alias void delegate(T obj) Action;
         * }
         *
         */


        public static void Go()
        {
            var partials = Context.Instance.DelegatePartials;
            var first    = partials.First();

            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();

            using (var writer = new OutputWriter(Context.Instance.Namespace, Context.Instance.TypeName))
            {
                var objectType =
                    TypeProcessor.GetSemanticModel(partials.First().Syntax)
                    .Compilation.GetTypeByMetadataName("System.Object");

                WriteBcl.Go(writer);

                var @namespace = first.Symbol.ContainingNamespace.FullName();

                WriteStandardIncludes.Go(writer);

                //Look for generic arguments

                //Look for generic arguments
                var genericArgs = partials.Select(o => o.Syntax)
                                  .Where(o => o.TypeParameterList != null)
                                  .SelectMany(o => o.TypeParameterList.Parameters)
                                  .ToList();

                var name = Context.Instance.TypeName;

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

                    writer.Write(name);

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

                    writer.OpenBrace();
                    writer.Indent++;

                    writer.Write("alias Delegate!(" + TypeProcessor.ConvertType(first.Syntax.ReturnType) + " delegate" +
                                 WriteMethod.GetParameterListAsString(first.Syntax.ParameterList));

                    writer.Write(") " + Context.Instance.TypeName + ";");

                    writer.Indent--;
                    writer.Write("\r\n");
                    writer.CloseBrace();
                }
                else
                {
                    //Non-generic
                    writer.Write("alias Delegate!(" + TypeProcessor.ConvertType(first.Syntax.ReturnType) + " delegate" +
                                 WriteMethod.GetParameterListAsString(first.Syntax.ParameterList));

                    writer.Write(") " + Context.Instance.TypeName + ";");
                }
            }
        }
        public static void Go(OutputWriter writer, MemberAccessExpressionSyntax expression)
        {
            var memberName = expression.Name.Identifier.Text;
            var type       = TypeProcessor.GetTypeInfo(expression.Expression).ConvertedType;
            var typeStr    = TypeProcessor.GenericTypeName(type);

            var isLiteral = expression.Expression is LiteralExpressionSyntax;

            var isStringLiteral = false;

            if (isLiteral)
            {
                var literal = expression.Expression as LiteralExpressionSyntax;

                if (literal.RawKind == (decimal)SyntaxKind.StringLiteralExpression)
                {
                    isStringLiteral = true;
                    // writer.Write("((System.String)"); Not needed for strings at all
                }
            }

            memberName = WriteIdentifierName.TransformIdentifier(memberName);

            var typeInfo     = TypeProcessor.GetTypeInfo(expression.Expression);
            var symbolInfo   = TypeProcessor.GetSymbolInfo(expression);
            var methodSymbol = symbolInfo.Symbol;

            if (methodSymbol == null)
            {
                symbolInfo = TypeProcessor.GetSymbolInfo(expression.Expression);
            }
            if (type != null && methodSymbol != null)
            //if type is null, then we're just a namespace.  We can ignore these.
            {
                var directInvocationOnBasics = methodSymbol.ContainingType.IsBasicType() && methodSymbol.IsStatic;

                if (directInvocationOnBasics)
                {
                    //Extension methods in Dlang are straightforward, although this could lead to clashes without qualification
                    if (methodSymbol.ContainingType != Context.Instance.Type)
                    {
                        var extensionNamespace = TypeProcessor.ConvertType(type, true, false);

                        writer.Write(extensionNamespace);
                    }
                }
                else
                {
                    WriteMember(writer, expression.Expression);
                }

                if (isLiteral && !isStringLiteral)
                {
                    writer.Write(")"); //Not needed for strings at all
                }
                writer.Write(".");
                // Ideally Escape analysis should take care of this, but for now all value types are on heap and ref types on stack
            }

            if (methodSymbol != null && methodSymbol.Kind == SymbolKind.Property)
            {
                if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface ||
                    Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol),
                           methodSymbol))
                {
                    /* memberName =
                     *   Regex.Replace(
                     *       TypeProcessor.ConvertType(methodSymbol.ContainingType.OriginalDefinition)
                     *           .RemoveFromStartOfString(methodSymbol.ContainingNamespace + ".Namespace.") +
                     *       "_" + memberName,
                     *       @" ?!\(.*?\)", string.Empty);*/
                    if (methodSymbol.ContainingType.ContainingType != null)
                    {
                        memberName = memberName.RemoveFromStartOfString(methodSymbol.ContainingType.ContainingType.Name + ".");
                    }
                }

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

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

                if (interfaceMethod != null)

                {
                    //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 + "_");*/
                    }
                }

                /*  if (!methodSymbol.ContainingType.IsAnonymousType &&
                 *    (methodSymbol.DeclaringSyntaxReferences.Any() &&
                 *     methodSymbol.DeclaringSyntaxReferences.FirstOrDefault()
                 *         .GetSyntax()
                 *         .As<PropertyDeclarationSyntax>()
                 *         .Modifiers.Any(SyntaxKind.NewKeyword)))
                 * {
                 *    //TODO: this means that new is not supported on external libraries, anonymous types cannot be extended
                 *    //					//why doesnt roslyn give me this information ?
                 *    memberName += "_";
                 * }*/
            }

            var isGet = false;

            writer.Write(memberName);

//            if (methodSymbol is IMethodSymbol) //Lets specialize it
//            {
//                //                //Type inference for delegates
//                var mmethodSymbol = methodSymbol as IMethodSymbol;
//
//                var specialization =
//                                        (mmethodSymbol.TypeArguments.Any() ? ("!(" +
//                                        mmethodSymbol.TypeArguments.Select(k => TypeProcessor.ConvertType(k))
//                                            .Aggregate((a, b) => a + "," + b) + ")") : "");
//                writer.Write(specialization);
//            }

            /* if (expression.Name is GenericNameSyntax)
             * {
             *   var gen = expression.Name.As<GenericNameSyntax>();
             *
             *   writer.Write("!(");
             *
             *   bool first = true;
             *   foreach (var g in gen.TypeArgumentList.Arguments)
             *   {
             *       if (first)
             *           first = false;
             *       else
             *           writer.Write(", ");
             *
             *       writer.Write(TypeProcessor.ConvertType(g));
             *   }
             *
             *   writer.Write(")");
             * }*/
        }
        private static void ProcessArgument(OutputWriter writer, ArgumentSyntax variable)
        {
            if (variable != null)
            {
                if (variable.NameColon != null)
                {
                }

                if (CSharpExtensions.CSharpKind(variable) == SyntaxKind.CollectionInitializerExpression)
                {
                    return;
                }
                var value                  = variable;
                var initializerType        = TypeProcessor.GetTypeInfo(value.Expression);
                var memberaccessexpression = value.Expression as MemberAccessExpressionSyntax;
                var nameexpression         = value.Expression as NameSyntax;
                var nullAssignment         = value.ToFullString().Trim() == "null";
                var shouldBox              = initializerType.Type != null && initializerType.Type.IsValueType &&
                                             !initializerType.ConvertedType.IsValueType;
                var shouldUnBox = initializerType.Type != null && !initializerType.Type.IsValueType &&
                                  initializerType.ConvertedType.IsValueType;
                var isname             = value.Expression is NameSyntax;
                var ismemberexpression = value.Expression is MemberAccessExpressionSyntax ||
                                         (isname &&
                                          TypeProcessor.GetSymbolInfo(value.Expression as NameSyntax).Symbol.Kind ==
                                          SymbolKind.Method);
                var isdelegateassignment = ismemberexpression &&
                                           initializerType.ConvertedType.TypeKind == TypeKind.Delegate;
                var isstaticdelegate = isdelegateassignment &&
                                       ((memberaccessexpression != null &&
                                         TypeProcessor.GetSymbolInfo(memberaccessexpression).Symbol.IsStatic) ||
                                        (isname && TypeProcessor.GetSymbolInfo(nameexpression).Symbol.IsStatic));

                if (nullAssignment)
                {
                    writer.Write("null");
                    return;
                }

                if (shouldBox)
                {
                    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 = initializerType.Type.GetImplicitCoversionOp(initializerType.ConvertedType,
                                                                                       initializerType.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 =
                            initializerType.ConvertedType.GetImplicitCoversionOp(initializerType.ConvertedType,
                                                                                 initializerType.Type);
                        //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
                    }

                    if (correctConverter != null)
                    {
                        if (useType)
                        {
                            writer.Write(TypeProcessor.ConvertType(initializerType.Type) + "." + "op_Implicit_" +
                                         TypeProcessor.ConvertType(correctConverter.ReturnType));
                        }
                        else
                        {
                            writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) + "." + "op_Implicit_" +
                                         TypeProcessor.ConvertType(correctConverter.ReturnType));
                        }
                        writer.Write("(");
                        Core.Write(writer, value.Expression);
                        writer.Write(")");
                        return;
                    }
                }
                else if (shouldUnBox)
                {
                    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 = initializerType.Type.GetImplicitCoversionOp(initializerType.Type,
                                                                                       initializerType.ConvertedType);
                    //                            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 =
                            initializerType.ConvertedType.GetImplicitCoversionOp(initializerType.Type,
                                                                                 initializerType.ConvertedType);
                        //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
                    }

                    if (correctConverter != null)
                    {
                        if (useType)
                        {
                            writer.Write(TypeProcessor.ConvertType(initializerType.Type) + "." + "op_Implicit_" +
                                         TypeProcessor.ConvertType(correctConverter.ReturnType));
                        }
                        else
                        {
                            writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) + "." + "op_Implicit_" +
                                         TypeProcessor.ConvertType(correctConverter.ReturnType));
                        }
                        writer.Write("(");
                        Core.Write(writer, value.Expression);
                        writer.Write(")");
                        return;
                    }
                }

                if (shouldBox)
                {
                    //Box
                    writer.Write("BOX!(" + TypeProcessor.ConvertType(initializerType.Type) + ")(");
                    //When passing an argument by ref or out, leave off the .Value suffix
                    Core.Write(writer, value.Expression);
                    writer.Write(")");
                    return;
                }
                if (shouldUnBox)
                {
                    //UnBox
                    writer.Write("cast!(" + TypeProcessor.ConvertType(initializerType.Type) + ")(");
                    Core.Write(writer, value.Expression);
                    writer.Write(")");
                }
                if (isdelegateassignment)
                {
                    var typeString = TypeProcessor.ConvertType(initializerType.ConvertedType);

                    var createNew = !(value.Expression is ObjectCreationExpressionSyntax);

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

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

                    Core.Write(writer, value.Expression);
                    if (isStatic)
                    {
                        writer.Write(")");
                    }

                    if (createNew)
                    {
                        writer.Write(")");
                    }
                    return;
                }
                if (initializerType.Type == null && initializerType.ConvertedType == null)
                {
                    writer.Write("null");
                    return;
                }
                Core.Write(writer, value.Expression);
            }
        }
        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(")");
        }
Esempio n. 15
0

        
Esempio n. 16
0
        public static void Go(OutputWriter writer, IdentifierNameSyntax identifier, bool byRef = false)
        {
            var symbol = TypeProcessor.GetSymbolInfo(identifier).Symbol;

            if (symbol.IsStatic)
            {
                writer.Write(symbol.ContainingNamespace.FullNameWithDot());
                writer.Write(symbol.ContainingType.FullName());
                writer.Write(".");
            }

            //            if (!byRef && Program.RefOutSymbols.ContainsKey(symbol)) //Not neccessary, c++ can pass by ref
            //            {
            //                    writer.Write("(*");
            //                    writer.Write(TransformIdentifier(identifier.Identifier.ToString()));
            //                    writer.Write(")");
            //            }
            //            else
            //            {
            var    binExpression = identifier.Parent as BinaryExpressionSyntax;
            string memberName    = TransformIdentifier(identifier.Identifier.ToString());

            if (symbol.Kind == SymbolKind.Property) // Using dlang properties
            {
                if (symbol.ContainingType.TypeKind == TypeKind.Interface ||
                    Equals(symbol.ContainingType.FindImplementationForInterfaceMember(symbol), symbol))
                {
                    memberName =
                        Regex.Replace(
                            TypeProcessor.ConvertType(symbol.ContainingType.OriginalDefinition)
                            .RemoveFromStartOfString(symbol.ContainingNamespace + ".Namespace.") + "_" + memberName,
                            @" ?!\(.*?\)", string.Empty);
                }

                var interfaceMethods =
                    symbol.ContainingType.AllInterfaces.SelectMany(
                        u =>
                        u.GetMembers(memberName)).ToArray();

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

                //                    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 (symbol.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 closeBraces = binExpression != null && binExpression.IsKind(SyntaxKind.SimpleAssignmentExpression) && binExpression.Left == identifier?"()" :"";
//                if (binExpression != null && binExpression.OperatorToken.RawKind == (decimal) SyntaxKind.EqualsToken)
//                {
//
//                    writer.Write("set_" + memberName + closeBraces);
//
//                }
//                else
//                {
//                    writer.Write("get_" + memberName+ closeBraces);
//
//                }
            }
//            else
            {
                writer.Write(memberName);
            }

//            }
        }
Esempio n. 17
0
        private static void WriteOutOneType(OutputWriter parentModuleWriter, Context.SyntaxAndSymbol[] typeSymbols, bool fileExists)
        {
            TypeProcessor.ClearUsedTypes();
            var mynamespace = Context.Instance.Type.ContainingNamespace.FullName().RemoveFromEndOfString(".Namespace");

            var fullname = Context.Instance.Namespace + "." + Context.Instance.TypeName;

            if (TypeRenames.ContainsKey(fullname))
            {
                Context.Instance.TypeName = TypeRenames[fullname];
            }

            // + "." + TypeState.Instance.TypeName;
            // if (Driver.Verbose)
            //    Console.WriteLine("Writing out type: " + fullname);
            if (fullname.StartsWith(
                    "System.Collections.Generic.Dictionary"))
            {
            }

            var myUsingDirective     = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(mynamespace));
            var SystemUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System"));
            // Required as certain functions like boxing are in this namespace
            var namespaces      = typeSymbols.First().Syntax.Parent.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray();
            var usingStatements = typeSymbols.First().Syntax.Parent.DescendantNodes().OfType <UsingStatementSyntax>().ToArray();
            var allTypeAliases  = typeSymbols.First().Syntax.DescendantNodes().OfType <QualifiedNameSyntax>().ToArray();

            Context.Instance.UsingDeclarations = namespaces
                                                 .Union(new[]
            {
                myUsingDirective, SystemUsingDirective
            }).ToArray();



            TypeProcessor.AddAlias(Context.Instance.Type.ContainingNamespace as INamespaceSymbol, Context.Instance.Type.ContainingNamespace.GetModuleName());


            foreach (var ns in namespaces)
            {
                //TODO: Add support for type aliases ...
                var symbol = TypeProcessor.GetSymbolInfo(ns.Name).Symbol;
                if (allTypeAliases.All(o => TypeProcessor.GetSymbolInfo(o.Left).Symbol != symbol))
                {
                    TypeProcessor.AddAlias(symbol as INamespaceSymbol, (symbol as INamespaceSymbol).GetModuleName());
                }
            }

            var aliases = allTypeAliases.DistinctBy(j => TypeProcessor.GetSymbolInfo(j.Left));

            foreach (var alias in aliases)
            {
                var left = alias.Left;
                var type = TypeProcessor.GetSymbolInfo(left).Symbol as INamespaceSymbol;
                var name = left.ToString();
                if (type != null && type.ToString() != name)
                {
                    TypeProcessor.AddAlias(type, name);
                }
            }
            OutputWriter writer = null;

            using (
                writer =
                    parentModuleWriter == null
                        ? new OutputWriter(Context.Instance.Namespace, Context.Instance.TypeName)
                        : new TempWriter())
            {
                writer.FileExists = fileExists;

                if (parentModuleWriter != null)
                {
                    writer.WriteLine();
                    writer.Indent = parentModuleWriter.Indent + 2;
                    writer.WriteIndent();
                }

                var bases    = new List <ITypeSymbol>();
                var baselist = typeSymbols.Select(k => k.Syntax.As <BaseTypeDeclarationSyntax>()).Select(o => o.BaseList).Where(k => k != null).ToArray();

                if (baselist.Any())
                {
                    bases = baselist.SelectMany(k => k.Types)
                            .Select(o => TypeProcessor.GetTypeInfo(o.Type).ConvertedType ?? TypeProcessor.GetTypeInfo(o.Type).Type)
                            .Where(k => k != null)
                            .Distinct()
                            .ToList();
                }

                //                var interfaces = bases.Where(o => o.TypeKind == TypeKind.Interface).ToList();

                if (Context.Instance.Type != Context.Object)
                {
                    if (bases != null && (!bases.Any((j => j.TypeKind != TypeKind.Interface)) &&
                                          !(typeSymbols.First().Symbol.TypeKind == TypeKind.Interface || typeSymbols.First().Symbol.TypeKind == TypeKind.Struct)))
                    {
                        //TODO: fix structs using mixins / alias this
                        bases.Add(Context.Object);
                    }
                }
                if (bases == null)
                {
                    bases = new List <ITypeSymbol>();
                }

                foreach (var type in bases)
                {
                    TypeProcessor.AddUsedType(type);
                }

                //TODO: Fix enum support
                if (typeSymbols.First().Syntax is EnumDeclarationSyntax)
                {
                    WriteEnum.Go(writer,
                                 Context.Instance.Partials.Select(o => o.Syntax)
                                 .Cast <EnumDeclarationSyntax>()
                                 .SelectMany(o => o.Members)
                                 .Where(o => !Program.DoNotWrite.ContainsKey(o)));

                    if (parentModuleWriter != null)
                    {
                        parentModuleWriter.Write(writer.ToString());
                    }

                    return;
                }

                Context.Instance.AllMembers =
                    typeSymbols.Select(k => k.Syntax.As <TypeDeclarationSyntax>()).SelectMany(o => o.Members)
                    .Where(o => !Program.DoNotWrite.ContainsKey(o))
                    .ToList();

                var allMembersToWrite = Context.Instance.AllMembers
                                        .Where(member => !(member is TypeDeclarationSyntax) &&
                                               !(member is EnumDeclarationSyntax) &&
                                               !(member is DelegateDeclarationSyntax) &&
                                               !(member is ConstructorDeclarationSyntax))
                                        .ToList();

                Context.Instance.MemberNames = allMembersToWrite.Select(k => k.GetCSharpName()).ToList();
                if (Context.Instance.Type.ContainingType != null)
                {
                    Context.Instance.MemberNames.AddRange(Context.Instance.Type.ContainingType.MemberNames);
                }


                {
                    //                    WriteStandardIncludes.Go(writer);

                    //                    writer.WriteLine(String.Format("#include \"{0}\"", TypeState.Instance.TypeName + ".h"));



                    WriteBcl.Go(writer);

                    //TypeState.Instance.DerivesFromObject = bases.Count == interfaces.Count;

                    var @namespace  = typeSymbols.First().Symbol.ContainingNamespace.FullName();
                    var genericArgs = Context.Instance.Type.TypeParameters.Select(l => l as ITypeSymbol).ToList();

                    //Module name = namespace + "." + typename;

                    WriteStandardIncludes.Go(writer);

                    //                    var namespaces = @namespace.Split(new string[] { "." }, StringSplitOptions.None);
                    //
                    //                    if (@namespace.Length > 0)
                    //                    {
                    //                        foreach (var ns in namespaces)
                    //                        {
                    //                            writer.WriteLine("namespace " + ns + "\r\n{");
                    //                            writer.WriteLine("namespace " + ns + "\r\n{");
                    //                        }
                    //
                    //                    }

                    var instanceCtors = Context.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>()
                                        .Where(o => !o.Modifiers.Any(SyntaxKind.StaticKeyword))
                                        .ToList();

                    var staticCtors = Context.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>()
                                      .Where(o => (o.Modifiers.Any(SyntaxKind.StaticKeyword)))
                                      .ToList();

                    //TODO: Add support for overloading constructing
                    //                    if (instanceCtors.Count > 1)
                    //                        throw new Exception(
                    //                            "Overloaded constructors are not supported.  Consider changing all but one to static Create methods " +
                    //                            Utility.Descriptor(first.Syntax));

                    //                    var ctorOpt = instanceCtors.SingleOrDefault();
                    //TODO: Handle interfaces by

                    /*
                     * class Interface
                     * {
                     * public:
                     *  virtual ~Interface() { }
                     *  virtual void test() = 0; // Functions, must all be virtual
                     * }
                     */

                    var membersToWrite = allMembersToWrite.ToList();
                    //.Where(o => IsStatic(o) == staticMembers).ToList();

                    //                    if (membersToWrite.Count == 0 && (partials.Any(o => o.Syntax.Modifiers.Any(SyntaxKind.StaticKeyword))))
                    //                        continue;

                    //                    if (staticMembers)
                    //                        writer.Write("object ");
                    //                    else if (first.Syntax.Kind == SyntaxKind.InterfaceDeclaration)
                    //                        writer.Write("trait ");
                    //                    else
                    //                    {
                    //                        if (partials.Any(o => o.Syntax.Modifiers.Any(SyntaxKind.AbstractKeyword)))
                    //                            writer.Write("abstract ");

                    //                    }

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

                    if (typeSymbols.First().Syntax is TypeDeclarationSyntax)
                    {
                        //Internal classes/structs are declared static in D to behave correctly
                        if (parentModuleWriter != null)
                        {
                            writer.Write("static ");
                        }
                        if (Context.Instance.Type.TypeKind == TypeKind.Class)
                        {
                            writer.Write("class ");
                        }
                        else if (Context.Instance.Type.TypeKind == TypeKind.Interface)
                        {
                            writer.Write("interface ");
                        }
                        else if (Context.Instance.Type.TypeKind == TypeKind.Struct)
                        {
                            writer.Write("struct ");
                            //						writer.Write (" class "); // Allows inheritance ... but too many issues, will look at this when it gets relevant
                        }
                        else
                        {
                            throw new Exception("don't know how to write type: " + Context.Instance.Type.TypeKind);
                        }
                        List <ITypeSymbol> parentTypeParameters;
                        if (Context.Instance.Type.ContainingType != null)
                        {
                            parentTypeParameters = GetParentTypeParameters(Context.Instance.Type);
                        }
                        else
                        {
                            parentTypeParameters = new List <ITypeSymbol>();
                        }

                        writer.Write(TypeName(Context.Instance.Type, false));
                        //TypeProcessor.ConvertType(Context.Instance.Type, true, false,true));

                        if (Context.Instance.Type.IsGenericType)
                        {
                            {
                                foreach (var @base in bases)
                                {
                                    var namedTypeSymbol = @base as INamedTypeSymbol;
                                    if (namedTypeSymbol != null)
                                    {
                                        foreach (var arg in namedTypeSymbol.TypeArguments)
                                        {
                                            if (arg.TypeKind == TypeKind.TypeParameter && !parentTypeParameters.Contains(arg))
                                            {
                                                if (!genericArgs.Any(k => k.Name == arg.Name))
                                                {
                                                    genericArgs.Add(arg);
                                                }
                                            }
                                        }
                                    }
                                }
                                if (genericArgs.Any())
                                {
                                    writer.Write("(" +
                                                 string.Join(" , ",
                                                             genericArgs.Select(o => TypeProcessor.ConvertType(o, true, true, false))) + ")");
                                }
                            }
                        }

                        bool firstBase = true;

                        if (Context.Instance.Type.TypeKind != TypeKind.Struct)
                        {
                            foreach (var baseType in bases.OrderBy(o => o.TypeKind == TypeKind.Interface ? 1 : 0))
                            {
                                var convertType = TypeProcessor.ConvertType(baseType);

                                writer.Write(firstBase ? " : " : " ,");

                                writer.Write(convertType);

                                firstBase = false;
                            }
                        }

                        string constraints = GetTypeConstraints((TypeDeclarationSyntax)typeSymbols.First().Syntax);
                        writer.Write(constraints);
                    }

                    writer.WriteLine();

                    writer.OpenBrace();

                    var nonFields = WriteFields(membersToWrite, typeSymbols.First(), writer);

                    foreach (var member in nonFields)
                    {
                        //                    writer.WriteLine();
                        Core.Write(writer, member);
                    }

                    WriteConstructors(instanceCtors, writer);

                    WriteStaticConstructors(staticCtors, writer);

                    //PInvoke is now centralized, so we can call it on all libraries etc without issue

                    writer.Indent--;
                    WriteOutNestedTypes(typeSymbols.First(), writer);

                    var methodSymbols = membersToWrite.OfType <MethodDeclarationSyntax>().Select(TypeProcessor.GetDeclaredSymbol);
                    //TypeProcessor.GetDeclaredSymbol(method);

                    if (!methodSymbols.OfType <IMethodSymbol>()
                        .Any(k => k.Name == "ToString" && k.Parameters.Length == 0 && k.ReturnType == Context.String))
                    {
                        if (Context.Instance.Type.TypeKind == TypeKind.Struct ||
                            (Context.Instance.Type.TypeKind == TypeKind.Class))
                        {
                            var overrideS = Context.Instance.Type.TypeKind == TypeKind.Struct ? "" : "override ";
                            writer.WriteLine();
                            writer.WriteLine("public " + overrideS + "String ToString()");
                            writer.OpenBrace();
                            writer.WriteLine("return GetType().FullName;");//Better names based on specialization
                            writer.CloseBrace();
                        }
                    }

                    WriteOutBoxed(writer, genericArgs, bases);
                }

                if (Context.Instance.Type.TypeKind == TypeKind.Struct)
                {
                    writer.WriteLine();
                    writer.WriteLine("public __Boxed_ __Get_Boxed()");
                    writer.OpenBrace();
                    writer.WriteLine("return new __Boxed_(this);");
                    writer.CloseBrace();
                    writer.WriteLine("alias __Get_Boxed this;");
                }

                if (Context.Instance.Type.TypeKind != TypeKind.Interface)
                {
                    writer.WriteLine();
                    if (Context.Instance.Type.TypeKind == TypeKind.Class)
                    {
                        writer.WriteLine("public override Type GetType()");
                    }
                    //					else if (Context.Instance.Type.TypeKind == TypeKind.Interface) // Messes with GetType overrides of objects
                    //					{
                    //						writer.WriteLine ("public final Type GetType()");
                    //					}
                    else if (Context.Instance.Type.TypeKind == TypeKind.Struct)
                    {
                        writer.WriteLine("public Type GetType()");
                    }
                    writer.OpenBrace();
                    //if (Context.Instance.Type.TypeKind == TypeKind.Class)
                    writer.WriteLine("return __TypeOf!(typeof(this));");
                    // else
                    //     writer.WriteLine("return __TypeOf!(__Boxed_);");

                    writer.CloseBrace();
                }

                writer.CloseBrace();

                WriteEntryMethod(writer);

                if (parentModuleWriter != null)
                {
                    writer.Finalize();
                    parentModuleWriter.Write(writer.ToString());
                }
            }
        }
Esempio n. 18
0
        public static bool IsConst(SyntaxTokenList modifiers, EqualsValueClauseSyntax initializerOpt, TypeSyntax type)
        {
            var t = TypeProcessor.ConvertType(type);

            return(modifiers.Any(SyntaxKind.ConstKeyword));
        }
Esempio n. 19
0
        private static void WriteOutBoxed(OutputWriter writer, List <ITypeSymbol> genericArgs, List <ITypeSymbol> bases)
        {
            //Implement Boxed!T
            if (Context.Instance.Type.TypeKind == TypeKind.Struct)
            {
                writer.WriteLine();
                var typeName = TypeProcessor.ConvertType(Context.Instance.Type); /*TypeName(Context.Instance.Type, false) +
                                                                                  * (Context.Instance.Type.IsGenericType && genericArgs.Any()
                                                                                  * ? ("!(" + string.Join(" , ", genericArgs.Select(o => o)) + ")")
                                                                                  * : "");*/

                var baseString = "";

                foreach (var baseType in bases.OrderBy(o => o.TypeKind == TypeKind.Interface ? 1 : 0))
                {
                    baseString += (" ,");

                    baseString += (TypeProcessor.ConvertType(baseType, false));
                }

                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))
                {
                    members.AddRange(Utility.GetAllMembers(baseType));
                }

                //  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 findImplementationForInterfaceMember = Context.Instance.Type.FindImplementationForInterfaceMember(member);
                    if (findImplementationForInterfaceMember == null)
                    {
                        continue;
                    }
                    var ifacemethod =
                        findImplementationForInterfaceMember
                        .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);
                    }
                }


                //                {
                //                    writer.WriteLine("public override String ToString()");
                //                    writer.OpenBrace();
                //                    writer.WriteLine("return __Value.ToString();", Program.GetGenericMetadataName(Context.Instance.Type));
                //                    writer.CloseBrace();
                //                }

                //}

                //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({0}.init);", typeName); //TODO fix this for another TypeNew that calls the valuetype constructor only
                writer.CloseBrace();

                //                if (Context.Instance.Type.GetMembers("ToString").Any()) // Use better matching ?
                {
                    //					writer.WriteLine ();
                    writer.WriteLine("public 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();
            }
        }
Esempio n. 20
0
        public static void Go(OutputWriter writer, MemberDeclarationSyntax field, SyntaxTokenList modifiers, string name,
                              TypeSyntax type, EqualsValueClauseSyntax initializerOpt = null)
        {
            writer.WriteIndent();

            var typeinfo = TypeProcessor.GetTypeInfo(type);

//            var isPtr = typeinfo.Type != null && (typeinfo.Type.IsValueType || typeinfo.Type.TypeKind==TypeKind.TypeParameter) ? "" : "";

            var typeStringNoPtr = TypeProcessor.ConvertType(type);

            var typeString = typeStringNoPtr + " ";

            var isConst = IsConst(modifiers, initializerOpt, type);

            var isStatic = isConst;

            //Handle Auto Properties

            if (modifiers.Any(SyntaxKind.PrivateKeyword))
            {
                writer.Write("private ");
            }

            if (modifiers.Any(SyntaxKind.PublicKeyword) || modifiers.Any(SyntaxKind.InternalKeyword) ||
                modifiers.Any(SyntaxKind.ProtectedKeyword) || modifiers.Any(SyntaxKind.AbstractKeyword))
            {
                writer.Write("public ");
            }

            if (modifiers.Any(SyntaxKind.StaticKeyword) || modifiers.Any(SyntaxKind.ConstKeyword))
            {
                isStatic = true;
                writer.Write("static ");
            }

            if (isConst)
            {
                writer.Write("const ");
//                writer.Write("const ");
            }

            var @event = field is EventFieldDeclarationSyntax;

            if (@event)
            {
                typeString = ("Event!(" + typeString + ")");
            }

            writer.Write(typeString);
//                if (isStatic)
//                    writer.Write(typeString);

            writer.Write(name);
            if (isStatic)
            {
//                var fieldInfo = TypeProcessor.GetDeclaredSymbol(field.Parent);
//                if (fieldInfo != null)
//                    writer.Write((!string.IsNullOrEmpty(fieldInfo.ContainingNamespace.FullName())?(fieldInfo.ContainingNamespace.FullName()+".") :"") + fieldInfo.Name+"."+name);
//				writer.Write(name);
            }

            if (!isStatic || isConst)
            {
                if (initializerOpt != null)
                {
                    writer.Write(" = ");

                    if (CSharpExtensions.CSharpKind(initializerOpt.Value) == SyntaxKind.CollectionInitializerExpression ||
                        CSharpExtensions.CSharpKind(initializerOpt.Value) == SyntaxKind.ArrayInitializerExpression)
                    {
//                        writer.Write("gc::gc_ptr< " + typeStringNoPtr + " >(");
                        writer.Write(" new " + typeString + " (");
                        var intializer = initializerOpt.Value as InitializerExpressionSyntax;
                        intializer.WriteArrayInitializer(writer, type);

                        writer.Write(")");
                    }

                    else
                    {
                        Core.Write(writer, initializerOpt.Value);
                    }
                }

                else
                {
                    if (typeinfo.Type.TypeKind != TypeKind.Struct)
                    {
                        writer.Write(" = ");
                        if (typeinfo.Type.TypeKind == TypeKind.Delegate)
                        {
                            writer.Write("new " + typeString + "()");
                        }
                        else
                        {
                            writer.Write(TypeProcessor.DefaultValue(type));
                        }
                    }
                }
            }
            else
            {
                var staticWriter = new OutputWriter("", "", false);

                if (initializerOpt != null)
                {
                    staticWriter.Write(name);

                    staticWriter.Write(" = ");

                    if (CSharpExtensions.CSharpKind(initializerOpt.Value) == SyntaxKind.CollectionInitializerExpression ||
                        CSharpExtensions.CSharpKind(initializerOpt.Value) == SyntaxKind.ArrayInitializerExpression)
                    {
                        staticWriter.Write("new " + typeStringNoPtr + " (");

                        var intializer = initializerOpt.Value as InitializerExpressionSyntax;

                        intializer.WriteArrayInitializer(staticWriter, type);
                        staticWriter.Write(")");
                    }
                    else
                    {
                        Core.Write(staticWriter, initializerOpt.Value);
                    }
//                    if (CSharpExtensions.CSharpKind(initializerOpt.Value) == SyntaxKind.CollectionInitializerExpression || CSharpExtensions.CSharpKind(initializerOpt.Value) == SyntaxKind.ArrayInitializerExpression)
//                    {
//
//
//						staticWriter.Write("])");
//                    }
                }

                else if (typeinfo.Type.TypeKind != TypeKind.Struct)

                {
                    staticWriter.Write(name);
                    staticWriter.Write(" = ");

                    if (typeinfo.Type.TypeKind == TypeKind.Delegate)
                    {
                        staticWriter.Write("new " + typeString + "()");
                    }
                    else
                    {
                        staticWriter.Write(TypeProcessor.DefaultValue(type));
                    }
                }

//				staticWriter.Write (" SharpNative");

                staticWriter.Write(";");

                staticWriter.WriteLine();

                Context.Instance.StaticInits.Add(staticWriter.ToString());
            }

            writer.Write(";");
            writer.WriteLine();
        }
        public static void WriteAnonymousType(AnonymousObjectCreationExpressionSyntax syntax)
        {
            var type = TypeProcessor.GetTypeInfo(syntax).Type.As <INamedTypeSymbol>();

            Context.Instance.Type = type;

            TypeProcessor.ClearUsedTypes();

            var mynamespace = Context.Instance.Type.ContainingNamespace.FullName().RemoveFromEndOfString(".Namespace");

            // + "." + TypeState.Instance.TypeName;
            Context.Instance.Namespace = mynamespace;
            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 =
                syntax.Parent.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray()
                .Union(new[]
            {
                myUsingDirective, SystemUsingDirective
            }).ToArray();

            //using (var writer = new CppWriter (TypeState.Instance.Namespace, )) {

            //Ty

            var anonName = TypeName(type);

            using (var writer = new OutputWriter(Context.Instance.Namespace, StripGeneric(anonName)))
            {
                var fields = type.GetMembers().OfType <IPropertySymbol>().OrderBy(o => o.Name).ToList();

//                writer.WriteLine("namespace anonymoustypes {");
                WriteStandardIncludes.Go(writer);

                writer.WriteIndent();
                writer.Write("class ");
                writer.Write(anonName);

                writer.OpenBrace();

                foreach (var field in fields)
                {
                    writer.WriteIndent();
                    writer.Write("public ");
                    writer.Write(TypeProcessor.ConvertType(field.Type) + " ");
                    writer.Write(WriteIdentifierName.TransformIdentifier(field.Name));
                    writer.Write(" = " + TypeProcessor.DefaultValue(field.Type));
                    writer.Write(";\r\n");
                }

                //Must Write a constructor here ...
                writer.Write("\r\nthis (");
                bool first = true;
                foreach (var field in fields)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        writer.Write(", ");
                    }

                    writer.Write(TypeProcessor.ConvertType(field.Type) + " ");
                    writer.Write("_" + WriteIdentifierName.TransformIdentifier(field.Name));
                }
                writer.Write(")\r\n");
                writer.OpenBrace();
                writer.Indent++;

                foreach (var field in fields)
                {
                    var fieldNAme = WriteIdentifierName.TransformIdentifier(field.Name);

                    writer.WriteLine(fieldNAme + " = _" + fieldNAme + ";");
                }
                writer.Indent--;

                writer.CloseBrace();

                writer.CloseBrace();
//                writer.Write("};");
//                writer.Write("}");
            }
        }
Esempio n. 22
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. 23
0
        public static void Go(OutputWriter writer, ForEachStatementSyntax foreachStatement)
        {
            var info = new LoopInfo(foreachStatement);

            var types   = TypeProcessor.GetTypeInfo(foreachStatement.Expression);
            var typeStr = TypeProcessor.GenericTypeName(types.Type);

            //  if (types.Type is IArrayTypeSymbol)
//            {
            //It's faster to "while" through arrays than "for" through them
            //   writer.WriteOpenBrace();
            writer.WriteLine("");

//                writer.WriteIndent();

            var typeinfo = TypeProcessor.GetTypeInfo(foreachStatement.Expression);

//                var isPtr = typeinfo.Type != null && typeinfo.Type.IsValueType ? "" : "";
            var typeString = TypeProcessor.ConvertType(foreachStatement.Type) + " ";

            var foreachIter = "__foreachIter" + foreachCount;

            if (typeinfo.Type.AllInterfaces.OfType <INamedTypeSymbol>().Any(j => j.MetadataName == "IEnumerable`1") ||
                typeinfo.Type.MetadataName == "IEnumerable`1")
            {
                writer.WriteLine("//ForEach");
//				writer.OpenBrace ();
                writer.WriteIndent();
                writer.Write(string.Format("auto {0} = ", foreachIter));
                Core.Write(writer, foreachStatement.Expression);
                writer.Write(".IEnumerable_T_GetEnumerator();\r\n");
                writer.WriteLine(string.Format("while({0}.IEnumerator_MoveNext())", foreachIter));
                writer.OpenBrace();

                writer.WriteLine(string.Format("{0}{1} = {2}.IEnumerator_T_Current;", typeString,
                                               WriteIdentifierName.TransformIdentifier(foreachStatement.Identifier.ValueText), foreachIter));

                Core.WriteStatementAsBlock(writer, foreachStatement.Statement, false);

                writer.CloseBrace();
                writer.WriteLine("");

//				writer.CloseBrace ();
                foreachCount++;
            }
            else
            {
                writer.WriteLine("//ForEach");
                writer.WriteIndent();
                writer.Write(string.Format("auto {0} = ", foreachIter));
                Core.Write(writer, foreachStatement.Expression);
                writer.Write(".IEnumerable_GetEnumerator();\r\n");
                writer.WriteLine(string.Format("while({0}.IEnumerator_MoveNext())", foreachIter));
                writer.OpenBrace();

                writer.WriteLine(string.Format("{0}{1} = UNBOX!({0})({2}.IEnumerator_Current);", typeString,
                                               WriteIdentifierName.TransformIdentifier(foreachStatement.Identifier.ValueText), foreachIter));

                Core.WriteStatementAsBlock(writer, foreachStatement.Statement, false);

                writer.CloseBrace();
                writer.WriteLine("");

                //				writer.CloseBrace ();
                foreachCount++;
            }
//				writer.Write(string.Format("foreach ({1}; ", typeString, WriteIdentifierName.TransformIdentifier(foreachStatement.Identifier.ValueText)));
//                writer.Write(")\r\n");
//
//                writer.OpenBrace();
//
//                writer.WriteIndent();
//
//                Core.WriteStatementAsBlock(writer, foreachStatement.Statement, false);
//
//                writer.CloseBrace();

            //    writer.WriteCloseBrace();
//            }
//            else if (typeStr == "System.Collections.Generic.List<>"
//                //|| typeStr == "System.Collections.Generic.Dictionary<,>"
//                || typeStr == "System.Collections.Generic.Dictionary<,>.KeyCollection"
//                || typeStr == "System.Collections.Generic.Dictionary<,>.ValueCollection")
//            {
//                //It's faster to "while" over a list's iterator than to "for" through it
//                writer.WriteOpenBrace();
//                info.WritePreLoop(writer);
//
//                writer.WriteIndent();
//                writer.Write("val __foreachiterator = ");
//                Core.Write(writer, foreachStatement.Expression);
//                writer.Write(".iterator();\r\n");
//
//
//                writer.WriteLine("while (__foreachiterator.hasNext())");
//                writer.WriteOpenBrace();
//
//                writer.WriteIndent();
//                writer.Write("val ");
//                writer.Write(WriteIdentifierName.TransformIdentifier(foreachStatement.Identifier.ValueText));
//                writer.Write(" = __foreachiterator.next();\r\n");
//
//                info.WriteLoopOpening(writer);
//                Core.WriteStatementAsBlock(writer, foreachStatement.Statement, false);
//                info.WriteLoopClosing(writer);
//                writer.WriteCloseBrace();
//
//                info.WritePostLoop(writer);
//                writer.WriteCloseBrace();
//            }
//            else
//            {
//
//                info.WritePreLoop(writer);
//                writer.WriteIndent();
//                writer.Write("for (");
//                writer.Write(WriteIdentifierName.TransformIdentifier(foreachStatement.Identifier.ValueText));
//                writer.Write(" = ");
//                Core.Write(writer, foreachStatement.Expression);
//                writer.Write(")\r\n");
//                writer.WriteOpenBrace();
//                info.WriteLoopOpening(writer);
//                Core.WriteStatementAsBlock(writer, foreachStatement.Statement, false);
//                info.WriteLoopClosing(writer);
//                writer.WriteCloseBrace();
//                info.WritePostLoop(writer);
//            }
        }
Esempio n. 24
0
        private static void ProcessExpression(OutputWriter writer, SyntaxToken operatorToken, CSharpSyntaxNode rightExpression,
                                              CSharpSyntaxNode leftExpression)
        {
            TypeInfo leftExpressionType = TypeProcessor.GetTypeInfo(leftExpression ?? rightExpression);

            var rightExpressionType = TypeProcessor.GetTypeInfo(rightExpression);

            var boxLeft = leftExpressionType.Type != null && (leftExpressionType.Type != leftExpressionType.ConvertedType) &&
                          ((leftExpressionType.Type.IsValueType || leftExpressionType.Type.TypeKind == TypeKind.TypeParameter) &&
                           (leftExpressionType.ConvertedType.IsReferenceType));

            var boxRight = (rightExpressionType.ConvertedType != null &&
                            (rightExpressionType.Type != null &&
                             ((rightExpressionType.Type.IsValueType ||
                               rightExpressionType.Type.TypeKind == TypeKind.TypeParameter) &&
                              (rightExpressionType.ConvertedType.IsReferenceType))))
                           ||
                           (rightExpressionType.Type != null && rightExpressionType.Type.IsValueType &&
                            leftExpressionType.Type != null && leftExpressionType.Type.TypeKind == TypeKind.Error);
            //Fix for yield ... why does it give errortypes ?

            var unboxRight = rightExpressionType.ConvertedType != null &&
                             (rightExpressionType.Type != null && (rightExpressionType.Type.IsReferenceType &&
                                                                   (rightExpressionType.ConvertedType.IsValueType)));

            var rightnull = rightExpression != null && rightExpression.ToFullString().Trim() == "null";
            var leftnull  = leftExpression != null && leftExpression.ToFullString().Trim() == "null";

            var nullAssignment = (rightnull || leftnull);

            var val = WriteOperatorDeclaration.AllBinaryOperators.FirstOrDefault(k => k.Value == operatorToken.Text);

            //Matching Binary Operator Overload
            if (!String.IsNullOrEmpty(val.Value))
            {
                //Try Left
                IEnumerable <ISymbol> members = new List <ISymbol>();
                if (leftExpressionType.Type != null)
                {
                    members = leftExpressionType.Type.GetMembers(val.Key);
                }
                if (rightExpressionType.Type != null)
                {
                    members = members.
                              Union(rightExpressionType.Type.GetMembers(val.Key));
                }

                var leftExpressionString = Core.WriteString(leftExpression);
                if (members != null && members.Any())
                {
                    if (!(leftExpressionType.Type.IsPrimitive() && rightExpressionType.Type.IsPrimitive()))
                    {
                        var correctOverload =
                            members.OfType <IMethodSymbol>()
                            .FirstOrDefault(
                                u =>
                                u.Parameters[0].Type == leftExpressionType.Type &&
                                u.Parameters[1].Type == rightExpressionType.Type);

                        if (correctOverload != null)
                        {
                            var name =
                                WriteIdentifierName.TransformIdentifier(OverloadResolver.MethodName(correctOverload));
                            writer.Write(TypeProcessor.ConvertType(correctOverload.ContainingType) + "." + name +
                                         "(" +
                                         leftExpressionString + "," + Core.WriteString(rightExpression)
                                         + ")");
                            return;
                        }
                    }
                }
                else
                {
                    if (WriteOperatorDeclaration.AssignOpOperators.ContainsKey(val.Key))
                    {
                        var methodName =
                            WriteOperatorDeclaration.AllBinaryOperators.FirstOrDefault(
                                k => k.Value == val.Value.Substring(0, 1));
                        // emulate c# facility to use the lower op ...
                        //Try Left
                        members = null;
                        if (leftExpressionType.Type != null)
                        {
                            members = leftExpressionType.Type.GetMembers(methodName.Key);
                        }
                        if (rightExpressionType.Type != null)
                        {
                            members = members.
                                      Union(rightExpressionType.Type.GetMembers(methodName.Key));
                        }

                        if (members != null && members.Any())
                        {
                            if (!(leftExpressionType.Type.IsPrimitive() && rightExpressionType.Type.IsPrimitive()))
                            {
                                var correctOverload =
                                    members.OfType <IMethodSymbol>()
                                    .FirstOrDefault(
                                        u =>
                                        u.Parameters[0].Type == leftExpressionType.Type &&
                                        u.Parameters[1].Type == rightExpressionType.Type);

                                if (correctOverload != null)
                                {
                                    var name =
                                        WriteIdentifierName.TransformIdentifier(
                                            OverloadResolver.MethodName(correctOverload));
                                    writer.Write(leftExpressionString + " = " +
                                                 TypeProcessor.ConvertType(correctOverload.ContainingType) + "." +
                                                 name +
                                                 "(" +
                                                 leftExpressionString + "," + Core.WriteString(rightExpression)
                                                 + ")");
                                    return;
                                }
                            }
                        }
                    }
                }
            }

            //Property calls will be fixed in a preprocessor step ... i.e. just call them
            if (nullAssignment)
            {
                if (rightnull)
                {
                    switch (operatorToken.CSharpKind())
                    {
                    case SyntaxKind.EqualsEqualsToken:
                        writer.Write("");
                        break;

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

                    default:
                        writer.Write(operatorToken.ToString());
                        break;
                    }


                    writer.Write("__IsNull(");
                    Core.Write(writer, leftExpression);
                    writer.Write(")");
                    return;
                }

                if (leftnull)
                {
                    //                    writer.Write("null");
                    //
                    //                    switch (operatorToken.CSharpKind())
                    //                    {
                    //                        case SyntaxKind.EqualsEqualsToken:
                    //                            writer.Write(" is ");
                    //                            break;
                    //                        case SyntaxKind.NotEqualsExpression:
                    //                        case SyntaxKind.ExclamationEqualsToken:
                    //                            writer.Write(" !is ");
                    //                            break;
                    //                        default:
                    //                            writer.Write(operatorToken.ToString());
                    //                            break;
                    //                    }
                    //
                    //                    Core.Write(writer, rightExpression);
                    //
                    //                    return;
                    switch (operatorToken.CSharpKind())
                    {
                    case SyntaxKind.EqualsEqualsToken:
                        writer.Write("");
                        break;

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

                    default:
                        writer.Write(operatorToken.ToString());
                        break;
                    }


                    writer.Write("__IsNull(");
                    Core.Write(writer, rightExpression);
                    writer.Write(")");
                    return;
                }
            }

            //Do we have an implicit converter, if so, use it
            if (leftExpressionType.Type != rightExpressionType.Type && rightExpressionType.Type != null)
            {
                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, true);

                if (correctConverter == null)
                {
                    useType          = false;
                    correctConverter =
                        rightExpressionType.Type.GetImplicitCoversionOp(leftExpressionType.Type,
                                                                        rightExpressionType.Type, true);
                }

                if (correctConverter != null)
                {
                    Core.Write(writer, leftExpression);
                    writer.Write(operatorToken.ToString());
                    if (useType)
                    {
                        writer.Write(TypeProcessor.ConvertType(leftExpressionType.Type) + "." + "op_Implicit_" +
                                     TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_"));
                    }
                    else
                    {
                        writer.Write(TypeProcessor.ConvertType(rightExpressionType.Type) + "." + "op_Implicit_" +
                                     TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_"));
                    }
                    writer.Write("(");
                    Core.Write(writer, rightExpression);
                    writer.Write(")");
                    return;
                }
            }

            if (operatorToken.CSharpKind() == SyntaxKind.PlusEqualsToken ||
                operatorToken.CSharpKind() == SyntaxKind.MinusEqualsToken)
            {
                var isname = rightExpression is NameSyntax;

                var nameexpression = rightExpression as NameSyntax;

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

                var isdelegateassignment = rightExpressionType.ConvertedType != null && (ismemberexpression &&
                                                                                         rightExpressionType.ConvertedType
                                                                                         .TypeKind == TypeKind.Delegate);

                var memberaccessexpression = rightExpression as MemberAccessExpressionSyntax;

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

                if (isdelegateassignment)
                {
                    Core.Write(writer, leftExpression);

                    writer.Write(operatorToken.ToString());

                    var typeString = TypeProcessor.ConvertType(rightExpressionType.ConvertedType);

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

                    var isStatic = isstaticdelegate;
                    //                        if (isStatic)
                    //                            writer.Write("__ToDelegate(");

                    MemberUtilities.WriteMethodPointer(writer, rightExpression);
                    //                        if (isStatic)
                    //                            writer.Write(")");

                    writer.Write(")");
                    return;
                }
            }
            if (leftExpressionType.Type == null || (rightExpressionType.Type == null && rightExpression != 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*/");
                    Core.Write(writer, leftExpression);
                    switch (operatorToken.CSharpKind())
                    {
                    case SyntaxKind.EqualsEqualsToken:
                        writer.Write("!=");
                        break;

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

                    default:
                        writer.Write(operatorToken.ToString());
                        break;
                    }

                    Core.Write(writer, rightExpression);
                }
                else
                {
                    Core.Write(writer, leftExpression);
                    if (operatorToken.CSharpKind() == SyntaxKind.EqualsEqualsToken)
                    {
                        writer.Write(" is ");
                    }
                    else if (operatorToken.CSharpKind() == SyntaxKind.ExclamationEqualsToken)
                    {
                        writer.Write(" !is ");
                    }
                    else
                    {
                        writer.Write(operatorToken.ToString());
                    }
                    if (rightExpression != null)
                    {
                        Core.Write(writer, rightExpression);
                    }
                }
            }
            else
            {
                writer.Write(boxLeft ? "BOX!(" + TypeProcessor.ConvertType(leftExpressionType.Type) + ")(" : "");
                Core.Write(writer, leftExpression);
                writer.Write(boxLeft ? ")" : "");
                writer.Write(operatorToken.ToString());
                if (rightExpression != null)
                {
                    writer.Write(unboxRight
                        ? "UNBOX!(" + TypeProcessor.ConvertType(rightExpressionType.ConvertedType) + ")("
                        : "");
                    writer.Write(boxRight ? "BOX!(" + TypeProcessor.ConvertType(rightExpressionType.Type) + ")(" : "");
                    Core.Write(writer, rightExpression);
                    writer.Write(boxRight ? ")" : "");
                    writer.Write(unboxRight ? ")" : "");
                }
            }
        }
Esempio n. 25
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. 26
0
        public static void Go(OutputWriter writer, ReturnStatementSyntax statement)
        {
            var slambda = statement.Ancestors().OfType <SimpleLambdaExpressionSyntax>().FirstOrDefault();
            var plambda = statement.Ancestors().OfType <ParenthesizedLambdaExpressionSyntax>().FirstOrDefault();
            var mlambda = statement.Ancestors().OfType <AnonymousMethodExpressionSyntax>().FirstOrDefault();


            var method    = statement.Ancestors().OfType <MethodDeclarationSyntax>().FirstOrDefault();
            var property  = statement.Ancestors().OfType <PropertyDeclarationSyntax>().FirstOrDefault();
            var indexer   = statement.Ancestors().OfType <IndexerDeclarationSyntax>().FirstOrDefault();
            var converter = statement.Ancestors().OfType <ConversionOperatorDeclarationSyntax>().FirstOrDefault();
            var @operator = statement.Ancestors().OfType <OperatorDeclarationSyntax>().FirstOrDefault();

            ITypeSymbol returnTypeSymbol = null;

            if (method != null)
            {
                returnTypeSymbol = TypeProcessor.GetTypeInfo(method.ReturnType).Type;
            }

            if (property != null)
            {
                returnTypeSymbol = TypeProcessor.GetTypeInfo(property.Type).Type;
            }

            if (indexer != null)
            {
                returnTypeSymbol = TypeProcessor.GetTypeInfo(indexer.Type).Type;
            }

            if (converter != null)
            {
                returnTypeSymbol = TypeProcessor.GetTypeInfo(converter.Type).Type;
            }


            if (@operator != null)
            {
                returnTypeSymbol = TypeProcessor.GetTypeInfo(@operator.ReturnType).Type;
            }

            if (plambda != null)
            {
                returnTypeSymbol = TypeProcessor.GetTypeInfo(plambda).Type;
            }

            if (slambda != null)
            {
                returnTypeSymbol = TypeProcessor.GetTypeInfo(slambda).Type;
            }

            if (mlambda != null)
            {
                returnTypeSymbol = TypeProcessor.GetTypeInfo(statement.Expression).ConvertedType;
            }


            writer.WriteIndent();
            writer.Write("return");

            if (statement.Expression != null)
            {
                {
                    var rightExpressionType = TypeProcessor.GetTypeInfo(statement.Expression);

                    var boxRight = rightExpressionType.ConvertedType != null &&
                                   (rightExpressionType.Type != null && (rightExpressionType.Type != rightExpressionType.ConvertedType) &&
                                    ((rightExpressionType.Type.IsValueType ||
                                      rightExpressionType.Type.TypeKind == TypeKind.TypeParameter) &&
                                     (rightExpressionType.ConvertedType.IsReferenceType)));
                    boxRight = boxRight && (rightExpressionType.Type != returnTypeSymbol);

                    if (!boxRight && returnTypeSymbol != Context.Object)
                    {
                        if (!Equals(returnTypeSymbol, rightExpressionType.Type) && !rightExpressionType.Type.IsSubclassOf(returnTypeSymbol))
                        {
                            writer.Write(" cast(" + TypeProcessor.ConvertType(returnTypeSymbol) + ")");
                        }
                    }

                    writer.Write(boxRight ? " BOX!(" + TypeProcessor.ConvertType(rightExpressionType.Type) + ")(" : " ");
                    Core.Write(writer, statement.Expression);

                    writer.Write(boxRight ? ")" : "");
                }
            }
            writer.Write(";\r\n");
        }
Esempio n. 27
0

        
Esempio n. 28
0
        public void Write(OutputWriter writer)
        {
            if (StringOpt != null)
            {
                writer.Write(StringOpt);
            }
            else
            {
                if (ArgumentOpt.NameColon != null)
                {
                    Core.Write(writer, ArgumentOpt.NameColon.Name);
                    writer.Write(" = ");
                }

                var symbol = TypeProcessor.GetSymbolInfo(ArgumentOpt.Expression);
                var type   = TypeProcessor.GetTypeInfo(ArgumentOpt.Expression);

                if (symbol.Symbol != null && type.ConvertedType != null && symbol.Symbol.Kind == SymbolKind.Method &&
                    type.ConvertedType.TypeKind == TypeKind.Delegate)
                {
                    var typeString = TypeProcessor.ConvertType(type.ConvertedType);

                    var createNew = !(ArgumentOpt.Parent.Parent is ObjectCreationExpressionSyntax); //Ugly hack

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

                    var isStatic = symbol.Symbol.IsStatic;
                    if (isStatic)
                    {
                        writer.Write("__ToDelegate(");
                    }
                    writer.Write("&");

                    Core.Write(writer, ArgumentOpt.Expression);
                    if (isStatic)
                    {
                        writer.Write(")");
                    }

                    if (createNew)
                    {
                        writer.Write(")");
                    }
                    return;
                }

                Core.Write(writer, ArgumentOpt.Expression);

                WriteEnum.Check(ArgumentOpt.Expression);
            }
        }
Esempio n. 29
0
        private static void WriteSetter(OutputWriter writer, bool isProxy, bool hasSetter, string acccessmodifiers, string name, string typeString, ITypeSymbol iface, string isOverride, bool setterHasBody, SyntaxTokenList modifiers, bool isInterface, string fieldName, string setterbody, string parameters, bool isindexer, bool hasGetter)
        {
            if (isindexer)
            {
                name = "opIndexAssign";
            }

            var args = _set;

            if (hasSetter && isProxy)
            {
                if (!isindexer)
                {
                    writer.WriteLine(string.Format("{0} {2} {5}{1}({2} value{3}{4}){4} {{  __Value.{1} = value; return value;}}", acccessmodifiers, name, hasGetter ? typeString : "void", (iface != null ? ("," + TypeProcessor.ConvertType(iface) + " __ig=null") : ""), isOverride, args));
                }
                else
                {
                    writer.WriteLine(string.Format("{0} {2} {1}({2} value,{3}{4}) {4} {{  __Value.{1} = value;return value;}}", acccessmodifiers, name, typeString, parameters, isOverride));
                }
            }
            else if (hasSetter && !setterHasBody) //Setter
            {
                if (modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface)
                {
                    if (!isindexer)
                    {
                        writer.WriteLine(string.Format("{0} {2} {5}{1}({2} value{3}{4});", acccessmodifiers, name, hasGetter ? typeString : "void", (iface != null ? ("," + TypeProcessor.ConvertType(iface) + " __ig=null") : ""), isOverride, args));
                    }
                    else
                    {
                        writer.WriteLine(string.Format("{0} {2} {1}({2} value,{3}{4});", acccessmodifiers, name, typeString, parameters, isOverride));
                    }
                }
                else
                {
                    if (!isindexer)
                    {
                        var returnValue = hasGetter ? writer.WriteIndentToString() + "return value;" :"";
                        writer.WriteLine(string.Format("{0} {2} {6}{1}({2} value{3}){4} {{{5} = value;{7}}}", acccessmodifiers, name, hasGetter?typeString :"void", (iface != null ? ("," + TypeProcessor.ConvertType(iface) + " __ig=null") : ""), isOverride, fieldName, args, returnValue));
                    }
                    else
                    {
                        var returnValue = hasGetter ? writer.WriteIndentToString() + "return value;" : "";

                        writer.WriteLine(string.Format("{0} {2} {1}({2} value,{3}){4} {{{5} = value;{6}}}", acccessmodifiers, name, typeString, parameters, isOverride, fieldName, returnValue));
                    }
                }
            }
            else if (hasSetter)
            {
                writer.WriteIndent();
                writer.Write(acccessmodifiers);

                WriteRegion(false, setterbody, iface, writer, typeString, name, modifiers, parameters, isindexer, hasGetter);
            }
        }
Esempio n. 30
0
        public static void Go(OutputWriter writer, string methodName, IMethodSymbol methodSymbol,
                              AttributeSyntax pinvokeAttributes)
        {
            //Do Pinvoke stuff
            //PInvokeFunction < int (int, double)> foo(library, "foo");
            //int i = foo(42, 2.0);

//			var methodParams = methodSymbol.Parameters.Any () ? methodSymbol.Parameters.Select (h => ConvertPInvokeType (h.Type)).Aggregate ((k, y) => (k) + " ," + y) : "";
            var returnString = ConvertPInvokeType(methodSymbol.ReturnType);

            if (pinvokeAttributes != null)
            {
                var    attributeArgumentSyntax = pinvokeAttributes.ArgumentList.Arguments.FirstOrDefault(k => k.Expression != null);
                string dllImport = attributeArgumentSyntax.ToFullString();
//                AttributeSyntax import =
//                    Context.Instance.DllImports.FirstOrDefault(
//                        d =>
//                            d.ArgumentList.Arguments.FirstOrDefault(
//                                k =>
//                                    k.Expression != null &&
//                                    k.Expression.ToString() ==
//                                    pinvokeAttributes.ArgumentList.Arguments.FirstOrDefault(g => g.Expression != null)
//                                        .Expression.ToString()) != null);
//                if (import != null)
//                    dllImportId = Context.Instance.DllImports.IndexOf(import);
//
//                if (dllImportId == -1)
//                {
//                    Context.Instance.DllImports.Add(pinvokeAttributes);
//                    dllImportId = Context.Instance.DllImports.IndexOf(pinvokeAttributes);
//                }

                var functionCall = String.Format("extern (C) {0} function ({1})", returnString,
                                                 GetParameterList(methodSymbol.Parameters));
                writer.WriteLine("alias " + functionCall + " " + methodName + "_func_alias;");
                var convertedParameters = ConvertParameters(methodSymbol.Parameters);

                if (attributeArgumentSyntax.Expression is IdentifierNameSyntax)
                {
                    writer.WriteLine(
                        String.Format("auto {1} = cast({2}) __LoadLibraryFunc(__DllImportMap[{0}.text], \"{1}\");",
                                      dllImport, methodName, methodName + "_func_alias"));
                }
                else
                {
                    writer.WriteLine(
                        String.Format("auto {1} = cast({2}) __LoadLibraryFunc(__DllImportMap[{0}], \"{1}\");",
                                      dllImport, methodName, methodName + "_func_alias"));
                }

                writer.WriteLine(String.Format((returnString != "void" ? "return " : "") + "{0}({1});", methodName,
                                               convertedParameters.Count > 0
                        ? convertedParameters.Select(h => h).Aggregate((k, y) => (k) + " ," + y)
                        : ""));


                if (dllImport != null && !Context.Instance.DllImports.Contains(dllImport))
                {
                    var staticWriter = new TempWriter();

                    if (attributeArgumentSyntax.Expression is IdentifierNameSyntax)
                    {
                        staticWriter.WriteLine("__SetupDllImport({0}.text);", dllImport);
                    }
                    else
                    {
                        staticWriter.WriteLine("__SetupDllImport({0});", dllImport);
                    }

                    Context.Instance.StaticInits.Add(staticWriter.ToString());

                    Context.Instance.DllImports.Add(dllImport);
                }
            }
            else
            {
                var convertedParameters = ConvertParameters(methodSymbol.Parameters);
                writer.WriteLine("//Extern (Internal) Method Call");
                var methodInternalName = TypeProcessor.ConvertType(methodSymbol.ContainingType, false).Replace(".Namespace.", "_").Replace(".", "_") + "_" + methodName;

                writer.WriteLine(String.Format((returnString != "void" ? "return " : "") + "{0}({1});", methodInternalName,
                                               convertedParameters.Count > 0
                        ? convertedParameters.Select(h => h).Aggregate((k, y) => (k) + " ," + y)
                        : ""));
            }
        }