Пример #1
0
        public static void Go(ScalaWriter writer, ElementAccessExpressionSyntax expression)
        {
            var typeStr = TypeProcessor.GenericTypeName(Program.GetModel(expression).GetTypeInfo(expression.Expression).Type);
            var trans   = ElementAccessTranslation.Get(typeStr);

            Core.Write(writer, expression.Expression);

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

            writer.Write("(");

            bool first = true;

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

                Core.Write(writer, argument.Expression);
            }
            writer.Write(")");
        }
Пример #2
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);
            }
        }
Пример #3
0
        public static bool NeedsClassTag(INamedTypeSymbol symbol, string templateID)
        {
            //For types, unlike methods, this requires that they're specified in Translations.xml. TODO: Determine these programmatically.
            //var symbol = Program.GetModel(typeSyntax).GetDeclaredSymbol(typeSyntax);

            var trans = NeedsClassTagTranslation.Get(TypeProcessor.GenericTypeName(symbol));

            if (trans == null || trans.TypesHashSet == null)
            {
                return(false);
            }
            else
            {
                return(trans.TypesHashSet.Contains(templateID));
            }
        }
Пример #4
0
        private static HashSet <string> TryGetBCLClassTags(IMethodSymbol method)
        {
            var methodStr = TypeProcessor.GenericTypeName(method.ContainingType) + "." + method.Name;

            var trans = NeedsClassTagTranslation.Get(methodStr);

            if (trans == null)
            {
                return(null);
            }

            if (trans.TypesHashSet != null)
            {
                return(trans.TypesHashSet);
            }
            else
            {
                return(method.TypeParameters.ToArray().Select(o => o.ToString()).ToHashSet(true));
            }
        }
        public static void Go(ScalaWriter writer, ForEachStatementSyntax foreachStatement)
        {
            var info = new LoopInfo(foreachStatement);

            var types   = Program.GetModel(foreachStatement).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();
                info.WritePreLoop(writer);

                writer.WriteLine("var __foreachindex:Int = 0;");

                writer.WriteIndent();
                writer.Write("val __foreacharray = ");
                Core.Write(writer, foreachStatement.Expression);
                writer.Write(";\r\n");


                writer.WriteLine("while (__foreachindex < __foreacharray.length)");
                writer.WriteOpenBrace();

                writer.WriteIndent();
                writer.Write("val ");
                writer.Write(WriteIdentifierName.TransformIdentifier(foreachStatement.Identifier.ValueText));
                writer.Write(" = __foreacharray(__foreachindex);\r\n");

                info.WriteLoopOpening(writer);
                Core.WriteStatementAsBlock(writer, foreachStatement.Statement, false);
                info.WriteLoopClosing(writer);

                writer.WriteLine("__foreachindex += 1;");
                writer.WriteCloseBrace();

                info.WritePostLoop(writer);
                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);
            }
        }
        private static void Go(ScalaWriter writer, ExpressionSyntax left, SyntaxToken operatorToken, ExpressionSyntax right)
        {
            if (operatorToken.Kind() == SyntaxKind.AsKeyword)
            {
                writer.Write("CsScala.As[");
                writer.Write(TypeProcessor.ConvertType(right));
                writer.Write("](");
                Core.Write(writer, left);
                writer.Write(")");
            }
            else if (operatorToken.Kind() == SyntaxKind.IsKeyword)
            {
                Core.Write(writer, left);
                writer.Write(".isInstanceOf[");
                writer.Write(TypeProcessor.ConvertType(right));
                writer.Write("]");
            }
            else if (operatorToken.Kind() == SyntaxKind.QuestionQuestionToken)
            {
                writer.Write("CsScala.Coalesce(");
                Core.Write(writer, left);
                writer.Write(", ");
                Core.Write(writer, right);
                writer.Write(")");
            }
            else
            {
                if (left is ElementAccessExpressionSyntax && IsAssignmentToken(operatorToken.Kind()))
                {
                    var subExpr = left.As <ElementAccessExpressionSyntax>();
                    var typeStr = TypeProcessor.GenericTypeName(Program.GetModel(left).GetTypeInfo(subExpr.Expression).Type);
                    var trans   = ElementAccessTranslation.Get(typeStr);

                    if (trans != null)
                    {
                        Core.Write(writer, subExpr.Expression);
                        writer.Write(".");

                        if (operatorToken.Kind() == SyntaxKind.EqualsToken)
                        {
                            writer.Write(trans.ReplaceAssign);
                        }
                        else
                        {
                            throw new Exception(operatorToken.Kind() + " is not supported on " + typeStr + " " + Utility.Descriptor(left.Parent));
                        }

                        writer.Write("(");
                        foreach (var arg in subExpr.ArgumentList.Arguments)
                        {
                            Core.Write(writer, arg.Expression);
                            writer.Write(", ");
                        }

                        Core.Write(writer, right);
                        writer.Write(")");

                        return;
                    }
                }

                Action <ExpressionSyntax> write = e =>
                {
                    var model = Program.GetModel(left);
                    var type  = model.GetTypeInfo(e);

                    //Check for enums being converted to strings by string concatenation
                    if (operatorToken.Kind() == SyntaxKind.PlusToken && type.Type.TypeKind == TypeKind.Enum)
                    {
                        writer.Write(type.Type.ContainingNamespace.FullNameWithDot());
                        writer.Write(WriteType.TypeName(type.Type.As <INamedTypeSymbol>()));
                        writer.Write(".ToString(");
                        Core.Write(writer, e);
                        writer.Write(")");
                    }
                    else if (operatorToken.Kind() == SyntaxKind.PlusToken && (type.Type.Name == "Nullable" && type.Type.ContainingNamespace.FullName() == "System" && type.Type.As <INamedTypeSymbol>().TypeArguments.Single().TypeKind == TypeKind.Enum))
                    {
                        var enumType = type.Type.As <INamedTypeSymbol>().TypeArguments.Single();
                        writer.Write(enumType.ContainingNamespace.FullNameWithDot());
                        writer.Write(WriteType.TypeName(enumType.As <INamedTypeSymbol>()));
                        writer.Write(".ToString(");
                        Core.Write(writer, e);
                        writer.Write(")");
                    }
                    else if (operatorToken.Kind() == SyntaxKind.PlusToken && IsException(type.Type))     //Check for exceptions being converted to strings by string concatenation
                    {
                        writer.Write("System.CsScala.ExceptionToString(");
                        Core.Write(writer, e);
                        writer.Write(")");
                    }
                    else if (operatorToken.Kind() == SyntaxKind.PlusToken && type.Type.SpecialType == SpecialType.System_Byte && !Utility.IsNumeric(type.ConvertedType))
                    {
                        //bytes are signed in the JVM, so we need to take care when converting them to strings.  Exclude numeric types, since Core.Writer will convert these to ints
                        writer.Write("System.CsScala.ByteToString(");
                        Core.Write(writer, e);
                        writer.Write(")");
                    }
                    else if (operatorToken.Kind() == SyntaxKind.PlusToken && !(e is BinaryExpressionSyntax) && type.Type.SpecialType == SpecialType.System_String && CouldBeNullString(model, e))
                    {
                        //In .net, concatenating a null string does not alter the output. However, in the JVM, it produces the "null" string. To counter this, we must check non-const strings.
                        writer.Write("System.CsScala.NullCheck(");
                        Core.Write(writer, e);
                        writer.Write(")");
                    }
                    else if (operatorToken.Kind() == SyntaxKind.PlusToken && !(e is BinaryExpressionSyntax) && type.Type is INamedTypeSymbol && type.Type.As <INamedTypeSymbol>().ConstructedFrom.SpecialType == SpecialType.System_Nullable_T)
                    {
                        //Concatening a nullable type in .net just produces an empty string if it's null.  In scala it produces "null" or a null reference exception -- we want neither.
                        writer.Write("System.CsScala.NullCheck(");
                        Core.Write(writer, e);
                        writer.Write(")");
                    }
                    else if (operatorToken.Kind() == SyntaxKind.PlusToken && !(e is BinaryExpressionSyntax) && type.Type.SpecialType == SpecialType.System_Boolean)
                    {
                        writer.Write("System.CsScala.BooleanToString(");
                        Core.Write(writer, e);
                        writer.Write(")");
                    }
                    else
                    {
                        Core.Write(writer, e);
                    }
                };

                write(left);
                writer.Write(" ");
                writer.Write(operatorToken.ToString());
                writer.Write(" ");
                write(right);
            }
        }
Пример #7
0
        public static void Go(ScalaWriter writer, MemberAccessExpressionSyntax expression)
        {
            var model = Program.GetModel(expression);

            var memberName = expression.Name.Identifier.ValueText;
            var type       = model.GetTypeInfo(expression.Expression).ConvertedType;
            var typeStr    = TypeProcessor.GenericTypeName(type);

            if (expression.Expression is PredefinedTypeSyntax)
            {
                if (memberName == "MaxValue" || memberName == "MinValue" || memberName == "NaN")
                {
                    var predefined = expression.Expression.ToString();

                    if (predefined.StartsWith("u"))
                    {
                        //Scala does not have unsigned types. Forward these to CsScala
                        writer.Write("System.CsScala.");
                        writer.Write(predefined);
                        writer.Write(memberName);
                    }
                    else
                    {
                        writer.Write(predefined[0].ToString().ToUpper());
                        writer.Write(predefined.Substring(1));
                        writer.Write(".");
                        writer.Write(memberName);
                    }
                }
                else
                {
                    var field = System.Type.GetType(typeStr).GetField(memberName);

                    if (field == null)
                    {
                        throw new Exception("Cannot use " + memberName + " as a field.  If you're passing a function, wrap a closure around it. " + Utility.Descriptor(expression));
                    }
                    var val = field.GetValue(null);
                    if (val is string)
                    {
                        writer.Write("\"" + val + "\"");
                    }
                    else
                    {
                        writer.Write(val.ToString());
                    }
                }
            }
            else if (type.OriginalDefinition is INamedTypeSymbol && type.OriginalDefinition.As <INamedTypeSymbol>().SpecialType == SpecialType.System_Nullable_T)
            {
                switch (memberName)
                {
                case "HasValue":
                    writer.Write("(");
                    WriteMember(writer, expression.Expression);
                    writer.Write(" != null)");
                    break;

                case "Value":
                    var nullableType = TypeProcessor.ConvertType(type.As <INamedTypeSymbol>().TypeArguments.Single());
                    WriteMember(writer, expression.Expression);

                    if (TypeProcessor.IsPrimitiveType(nullableType))
                    {
                        writer.Write(".");
                        writer.Write(nullableType[0].ToString().ToLower());
                        writer.Write(nullableType.Substring(1));
                        writer.Write("Value()");
                    }
                    break;

                default:
                    throw new Exception("Need handler for Nullable." + memberName + " " + Utility.Descriptor(expression));
                }
            }
            else
            {
                var translate = PropertyTranslation.Get(typeStr, memberName);

                if (translate != null && translate.ExtensionMethod != null)
                {
                    writer.Write(translate.ExtensionMethod);
                    writer.Write("(");
                    if (!(model.GetSymbolInfo(expression.Expression).Symbol is INamedTypeSymbol))
                    {
                        Core.Write(writer, expression.Expression);
                    }
                    writer.Write(")");
                    return;
                }

                if (translate != null)
                {
                    memberName = translate.ReplaceWith;
                }
                else
                {
                    memberName = WriteIdentifierName.TransformIdentifier(memberName);
                }

                if (type != null) //if type is null, then we're just a namespace.  We can ignore these.
                {
                    WriteMember(writer, expression.Expression);
                    writer.Write(".");
                }

                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.ConvertTypeWithColon(g));
                    }

                    writer.Write("]");
                }
            }
        }