private static void Generate() { Console.WriteLine("Parsing..."); var sw = Stopwatch.StartNew(); if (!Directory.Exists(OutDir)) { Directory.CreateDirectory(OutDir); } var allTypes = Compilation.SyntaxTrees .SelectMany(o => o.GetRoot().DescendantNodes().OfType <BaseTypeDeclarationSyntax>()) .Select(o => new { Syntax = o, Symbol = GetModel(o).GetDeclaredSymbol(o), TypeName = WriteType.TypeName(GetModel(o).GetDeclaredSymbol(o)) }) .GroupBy(o => o.Symbol.ContainingNamespace.FullNameWithDot() + o.TypeName) .ToList(); Utility.Parallel(Compilation.SyntaxTrees.ToList(), tree => { foreach (var n in TriviaProcessor.DoNotWrite(tree)) { DoNotWrite.TryAdd(n, null); } //Init ClassTags foreach (var method in tree.GetRoot().DescendantNodes().OfType <MethodDeclarationSyntax>().Where(o => o.TypeParameterList != null)) { ClassTags.InitMethod(GetModel(method).GetDeclaredSymbol(method), method); } }); Console.WriteLine("Parsed in " + sw.Elapsed + ". Writing out scala..."); sw.Restart(); Compilation.SyntaxTrees.SelectMany(o => o.GetRoot().DescendantNodes().OfType <AnonymousObjectCreationExpressionSyntax>()) .Select(o => new { Syntax = o, Name = WriteAnonymousObjectCreationExpression.TypeName(o) }) .GroupBy(o => o.Name) .Parallel(o => WriteAnonymousObjectCreationExpression.WriteAnonymousType(o.First().Syntax)); allTypes.Parallel(type => { TypeState.Instance = new TypeState(); TypeState.Instance.TypeName = type.First().TypeName; TypeState.Instance.Partials = type.Select(o => new TypeState.SyntaxAndSymbol { Symbol = o.Symbol, Syntax = o.Syntax }) .Where(o => !DoNotWrite.ContainsKey(o.Syntax)) .ToList(); if (TypeState.Instance.Partials.Count > 0) { WriteType.Go(); } }); WriteConstructorBody.WriteConstructorsHelper(allTypes.SelectMany(o => o).Where(o => !DoNotWrite.ContainsKey(o.Syntax)).Select(o => o.Symbol)); Console.WriteLine("Scala written out in " + sw.Elapsed); }
private static string ConvertTypeUncached(ITypeSymbol typeSymbol) { if (typeSymbol.IsAnonymousType) { return(WriteAnonymousObjectCreationExpression.TypeName(typeSymbol.As <INamedTypeSymbol>())); } var array = typeSymbol as IArrayTypeSymbol; if (array != null) { return("Array[" + TryConvertType(array.ElementType) + "]"); } var typeInfoStr = typeSymbol.ToString(); var named = typeSymbol as INamedTypeSymbol; if (typeSymbol.TypeKind == TypeKind.TypeParameter) { return(typeSymbol.Name); } if (typeSymbol.TypeKind == TypeKind.Delegate) { var dlg = named.DelegateInvokeMethod.As <IMethodSymbol>(); if (dlg.Parameters.Length == 0) { return("() => " + TryConvertType(dlg.ReturnType)); } else { return("(" + string.Join(", ", dlg.Parameters.ToList().Select(o => TryConvertType(o.Type))) + ") => " + TryConvertType(dlg.ReturnType)); } } if (typeSymbol.TypeKind == TypeKind.Enum) { return("Int"); //enums are always ints } if (named != null && named.Name == "Nullable" && named.ContainingNamespace.ToString() == "System") { //Nullable types, if value types, get replaced with the java.lang alternatives. If reference types, just use them as-is var convertedType = TryConvertType(named.TypeArguments.Single()); switch (convertedType) { case "Int": return("java.lang.Integer"); case "Boolean": return("java.lang.Boolean"); case "Byte": return("java.lang.Byte"); case "Short": return("java.lang.Short"); case "Float": return("java.lang.Float"); case "Double": return("java.lang.Double"); case "Char": return("java.lang.Char"); case "Long": return("java.lang.Long"); default: return(convertedType); } } var typeStr = GenericTypeName(typeSymbol); var trans = TypeTranslation.Get(typeStr, named); if (named.IsGenericType() && !named.IsUnboundGenericType && (trans == null || trans.SkipGenericTypes == false)) { return(TryConvertType(named.ConstructUnboundGenericType()) + "[" + string.Join(", ", TypeArguments(named).Select(o => TryConvertType(o))) + "]"); } switch (typeStr) { case "System.Void": return("Unit"); case "System.Boolean": return("Boolean"); case "System.Object": return("Any"); case "System.UInt64": case "System.Double": return("Double"); case "System.Single": return("Float"); case "System.String": return("String"); case "System.Int32": case "System.UInt16": return("Int"); case "System.Int64": case "System.UInt32": return("Long"); case "System.Byte": return("Byte"); case "System.Int16": return("Short"); case "System.Char": return("Char"); case "System.Array": return(null); //in scala, unlike C#, array must always have type arguments. To work around this, just avoid printing the type anytime we see a bare Array type in C#. scala will infer it. default: if (trans != null) { return(trans.As <TypeTranslation>().Replace(named)); } if (named != null) { return(typeSymbol.ContainingNamespace.FullNameWithDot() + WriteType.TypeName(named)); } //This type does not get translated and gets used as-is return(typeSymbol.ContainingNamespace.FullNameWithDot() + typeSymbol.Name); } }