示例#1
0
        private static bool IsAmbiguousType(ITypeSymbol type)
        {
            switch (TypeProcessor.GenericTypeName(type))
            {
            case "System.UInt16":
            case "System.UInt32":
            case "System.UInt64":
                return(true);

            default:
                return(false);
            }
        }
        public static void Go(OutputWriter writer, ElementAccessExpressionSyntax expression)
        {
            var type    = TypeProcessor.GetTypeInfo(expression.Expression).Type;
            var typeStr = TypeProcessor.GenericTypeName(type);

            //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);
            }
            writer.Write("]");
        }
示例#3
0
        public static void Go(OutputWriter writer, MemberAccessExpressionSyntax expression)
        {
            var memberName = expression.Name.Identifier.ValueText;
            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);

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

                if (directInvocationOnBasics)
                {
//						var extensionNamespace =  symbolInfo.Symbol.ContainingNamespace.FullNameWithDot() + symbolInfo.Symbol.ContainingType.FullName(); //null means it's not an extension method, non-null means it is

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

                    var extensionNamespace = type.ContainingNamespace.FullName() + "." + type.Name;
                    //memberType.ContainingNamespace.FullName() +"."+ memberType.Name;

                    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 (symbolInfo.Symbol != null && symbolInfo.Symbol.Kind == SymbolKind.Property)
            {
                if (symbolInfo.Symbol.ContainingType.TypeKind == TypeKind.Interface ||
                    Equals(symbolInfo.Symbol.ContainingType.FindImplementationForInterfaceMember(symbolInfo.Symbol),
                           symbolInfo.Symbol))
                {
                    memberName =
                        Regex.Replace(
                            TypeProcessor.ConvertType(symbolInfo.Symbol.ContainingType.OriginalDefinition)
                            .RemoveFromStartOfString(symbolInfo.Symbol.ContainingNamespace + ".Namespace.") +
                            "_" + memberName,
                            @" ?!\(.*?\)", string.Empty);
                }

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

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

                if (interfaceMethod != null)

                {
//This is an interface method //TO
                    if (symbolInfo.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 + "_");
                    }
                }

                if (!symbolInfo.Symbol.ContainingType.IsAnonymousType &&
                    (symbolInfo.Symbol.DeclaringSyntaxReferences.Any() &&
                     symbolInfo.Symbol.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 (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(" )");
            }
        }
示例#4
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++;
            }
        }
示例#5
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);
//            }
        }
        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, 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(")");
             * }*/
        }