private static void ProcessDelegates() { var delegates = _compilation.SyntaxTrees .SelectMany(o => o.GetRoot().DescendantNodes().OfType <DelegateDeclarationSyntax>()) .Select(o => new { Syntax = o, Symbol = GetModel(o).GetDeclaredSymbol(o), TypeName = WriteType.TypeName(GetModel(o).GetDeclaredSymbol(o)) }).GroupBy(o => o.Symbol.ContainingNamespace.FullNameWithDot() + o.TypeName) .ToList(); delegates.Parallel(type => //.ForEach(type => //.Parallel(type => { Context.Instance = new Context { TypeName = type.First().TypeName, DelegatePartials = type.Select( o => new Context.DelegateSyntaxAndSymbol { Symbol = o.Symbol, Syntax = o.Syntax }) .Where(o => !DoNotWrite.ContainsKey(o.Syntax)) .ToList() }; if (Context.Instance.DelegatePartials.Count > 0) { WriteDelegate.Go(); } }); }
/// <summary> /// calls to Enum.Parse get re-written as calls to our special Parse methods on each enum. We assume the first /// parameter to Enum.Parse is a a typeof() /// </summary> private static void WriteEnumParse(OutputWriter writer, InvocationExpressionSyntax invocationExpression) { var args = invocationExpression.ArgumentList.Arguments; if (args.Count < 2 || args.Count > 3) { throw new Exception("Expected 2-3 args to Enum.Parse"); } if (args.Count == 3 && (!(args[2].Expression is LiteralExpressionSyntax) || args[2].Expression.As <LiteralExpressionSyntax>().ToString() != "false")) { throw new NotImplementedException("Case-insensitive Enum.Parse is not supported " + Utility.Descriptor(invocationExpression)); } if (!(args[0].Expression is TypeOfExpressionSyntax)) { throw new Exception("Expected a typeof() expression as the first parameter of Enum.Parse " + Utility.Descriptor(invocationExpression)); } var type = TypeProcessor.GetTypeInfo(args[0].Expression.As <TypeOfExpressionSyntax>().Type).Type; //ModelExtensions.GetTypeInfo(Program.GetModel(invocationExpression), args[0].Expression.As<TypeOfExpressionSyntax>().Type).Type; writer.Write(type.ContainingNamespace.FullNameWithDot()); writer.Write(WriteType.TypeName((INamedTypeSymbol)type)); writer.Write(".Parse("); Core.Write(writer, args[1].Expression); writer.Write(")"); }
private static void ProcessTypes() { var allTypes = _compilation.SyntaxTrees .SelectMany(o => o.GetRoot().DescendantNodes().OfType <BaseTypeDeclarationSyntax>()) .Select(o => new { Syntax = o, Symbol = GetModel(o).GetDeclaredSymbol(o), TypeName = WriteType.TypeName(GetModel(o).GetDeclaredSymbol(o)) }) .GroupBy(o => o.Symbol.ContainingNamespace.FullNameWithDot() + o.TypeName) .ToList(); allTypes.Parallel(type => //.ForEach(type => //.Parallel(type => { Context.Instance = new Context { TypeName = type.First().TypeName, Partials = type.Select( o => new Context.SyntaxAndSymbol { Symbol = o.Symbol, Syntax = o.Syntax }) .Where(o => !DoNotWrite.ContainsKey(o.Syntax)) .ToList() }; if (Context.Instance.Partials.Count > 0) { try { WriteType.Go(); } catch (Exception ex) { //TODO: remove this when done with CorLib // throw ex; } } }); var symbols = allTypes.SelectMany(o => o) .Where(o => !DoNotWrite.ContainsKey(o.Syntax)) .Select(o => o.Symbol) .Select(g => g) .Where(g => g != null); WriteConstructorBody.WriteConstructorsHelper(symbols); }
private static string GetGenericTypeNameWithParameters(INamedTypeSymbol named) { if (named.IsGenericType) { return(WriteType.TypeName(named, false) + (named.TypeArguments.Any() ? "!(" + named.TypeArguments.Select( o => GetGenericParameterType(named.TypeParameters[named.TypeArguments.IndexOf(o)], o)) .Aggregate((a, b) => a + ", " + b) + ")" :"")); } else { return(WriteType.TypeName(named)); } }
private static void WriteEnumGetValues(OutputWriter writer, InvocationExpressionSyntax invocationExpression) { if (!(invocationExpression.ArgumentList.Arguments[0].Expression is TypeOfExpressionSyntax)) { throw new Exception("Expected a typeof() expression as the first parameter of Enum.GetValues " + Utility.Descriptor(invocationExpression)); } // var type = ModelExtensions.GetTypeInfo(Program.GetModel(invocationExpression), invocationExpression.ArgumentList.Arguments[0].Expression.As<TypeOfExpressionSyntax>().Type).Type; var type = TypeProcessor.GetTypeInfo( invocationExpression.ArgumentList.Arguments[0].Expression.As <TypeOfExpressionSyntax>().Type).Type; writer.Write(type.ContainingNamespace.FullNameWithDot()); writer.Write(WriteType.TypeName((INamedTypeSymbol)type)); writer.Write(".Values"); }
private static void WriteOneDelegate(OutputWriter outputWriter, Context.DelegateSyntaxAndSymbol first, bool fileExists) { Context.Instance.Namespace = first.Symbol.ContainingNamespace.FullName(); Context.Instance.Type = first.Symbol; TypeProcessor.ClearUsedTypes(); var mynamespace = Context.Instance.Type.ContainingNamespace.FullName().RemoveFromEndOfString(".Namespace"); // + "." + TypeState.Instance.TypeName; var myUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(mynamespace)); var SystemUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System")); // Required as certain functions like boxing are in this namespace Context.Instance.UsingDeclarations = first.Syntax.Parent.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray() .Union(new[] { myUsingDirective, SystemUsingDirective }).ToArray(); OutputWriter writer = null; using ( writer = outputWriter == null ? new OutputWriter(Context.Instance.Namespace, Context.Instance.TypeName) : new TempWriter()) { if (outputWriter != null) { writer.WriteLine(); writer.Indent = outputWriter.Indent + 2; writer.WriteIndent(); } writer.FileExists = fileExists; WriteBcl.Go(writer); WriteStandardIncludes.Go(writer); //Look for generic arguments { List <TypeParameterSyntax> genericArgs = new List <TypeParameterSyntax>(); if (first.Syntax.TypeParameterList != null) { genericArgs = first.Syntax.TypeParameterList.Parameters.ToList(); } var name = WriteType.TypeName(Context.Instance.Type, false); //Context.Instance.TypeName; if (genericArgs.Count > 0) { name = "template " + name; name += ("("); name += (string.Join(" , ", genericArgs.Select(o => o))); name += (")"); writer.WriteLine(name); writer.OpenBrace(); writer.WriteLine("alias __Delegate!(" + TypeProcessor.ConvertType(first.Syntax.ReturnType) + " delegate" + WriteMethod.GetParameterListAsString(first.Syntax.ParameterList.Parameters) + ") " + WriteType.TypeName(Context.Instance.Type, false) + ";"); writer.CloseBrace(); } else { //Non-generic writer.WriteLine("alias __Delegate!(" + TypeProcessor.ConvertType(first.Syntax.ReturnType) + " delegate" + WriteMethod.GetParameterListAsString(first.Syntax.ParameterList.Parameters) + ") " + WriteType.TypeName(Context.Instance.Type, false) + ";"); } } if (outputWriter != null) { outputWriter.WriteLine(writer.ToString()); } } }
public static void Go(OutputWriter writer, AssignmentExpressionSyntax expression) { if (expression.OperatorToken.IsKind(SyntaxKind.AsKeyword)) { var typeinfo = TypeProcessor.GetTypeInfo(expression.Right); var isPtr = typeinfo.Type != null && typeinfo.Type.IsValueType ? "" : ""; writer.Write("cast( "); writer.Write(TypeProcessor.ConvertType(expression.Right) + isPtr); writer.Write(" )("); Core.Write(writer, expression.Left); writer.Write(")"); } else if (expression.OperatorToken.IsKind(SyntaxKind.IsKeyword)) // isCast { var leftSymbolType = TypeProcessor.GetTypeInfo(expression.Left); var rightSymbolType = TypeProcessor.GetTypeInfo(expression.Right); if (leftSymbolType.Type.IsValueType) { writer.Write("IsCast!(Boxed!("); writer.Write(TypeProcessor.ConvertType(expression.Right)); writer.Write("))"); writer.Write("("); Core.Write(writer, expression.Left); writer.Write(")"); // writer.Write("(cast(BOX!("); // writer.Write(TypeProcessor.ConvertType(expression.Right)); // writer.Write(" ) )(Boxed!( " + TypeProcessor.ConvertType(leftSymbolType.Type)); // writer.Write(" )("); // Core.Write(writer, expression.Left); // writer.Write(")) is! null)"); //Todo improve this ... though its silly to do this in the first place // writer.Write("(cast(BOX!("); // writer.Write(TypeProcessor.ConvertType(expression.Right)); // writer.Write("))(Boxed!(" + TypeProcessor.ConvertType(leftSymbolType.Type)); // writer.Write(")("); // Core.Write(writer, expression.Left); // writer.Write(")) is! null)"); } else if (rightSymbolType.Type.IsValueType) { writer.Write("IsCast!(Boxed!("); writer.Write(TypeProcessor.ConvertType(expression.Right)); writer.Write("))"); writer.Write("("); Core.Write(writer, expression.Left); writer.Write(")"); // writer.Write("(cast(Boxed!( "); // writer.Write(TypeProcessor.ConvertType(expression.Right)); // writer.Write(" ) )("); // Core.Write(writer, expression.Left); // writer.Write(") is! null)"); } else { var typeinfo = TypeProcessor.GetTypeInfo(expression.Right); var isPtr = typeinfo.Type != null && typeinfo.Type.IsValueType ? "" : ""; writer.Write("(IsCast!("); writer.Write(TypeProcessor.ConvertType(expression.Right) + isPtr); writer.Write(")("); Core.Write(writer, expression.Left); writer.Write("))"); } } else if (expression.OperatorToken.IsKind(SyntaxKind.QuestionQuestionToken)) { writer.Write("(("); Core.Write(writer, expression.Left); writer.Write(")!is null?("); Core.Write(writer, expression.Left); writer.Write("):("); Core.Write(writer, expression.Right); writer.Write("))"); } else { // if (expression.Left is ElementAccessExpressionSyntax && IsAssignmentToken((SyntaxKind) expression.OperatorToken.RawKind)) // { // var subExpr = expression.Left.As<ElementAccessExpressionSyntax>(); // var typeStr = TypeProcessor.GenericTypeName(TypeProcessor.GetTypeInfo(subExpr.Expression).Type); // // // // } Action <ExpressionSyntax> write = e => { var type = TypeProcessor.GetTypeInfo(e); //Check for enums being converted to strings by string concatenation var typeSymbol = type.Type ?? type.ConvertedType; if (expression.OperatorToken.RawKind == (decimal)SyntaxKind.PlusToken && typeSymbol.TypeKind == TypeKind.Enum) { writer.Write(typeSymbol.ContainingNamespace.FullNameWithDot()); writer.Write(WriteType.TypeName(typeSymbol.As <INamedTypeSymbol>())); writer.Write(".ToString("); Core.Write(writer, e); writer.Write(")"); } else if (expression.OperatorToken.RawKind == (decimal)SyntaxKind.PlusToken && (typeSymbol.Name == "Nullable" && typeSymbol.ContainingNamespace.FullName() == "System" && typeSymbol.As <INamedTypeSymbol>().TypeArguments.Single().TypeKind == TypeKind.Enum)) { var enumType = typeSymbol.As <INamedTypeSymbol>().TypeArguments.Single(); writer.Write(enumType.ContainingNamespace.FullNameWithDot()); writer.Write(WriteType.TypeName(enumType.As <INamedTypeSymbol>())); writer.Write(".ToString("); Core.Write(writer, e); writer.Write(")"); } else { Core.Write(writer, e); } }; var symbolInfoLeft = TypeProcessor.GetSymbolInfo(expression.Left); var symbolInfoRight = TypeProcessor.GetSymbolInfo(expression.Right); var leftExpressionType = TypeProcessor.GetTypeInfo(expression.Left); var rightExpressionType = TypeProcessor.GetTypeInfo(expression.Right); var boxLeft = leftExpressionType.Type != null && (leftExpressionType.Type.IsValueType && (leftExpressionType.ConvertedType.IsReferenceType)); var derefLeft = false; // rightExpressionType.ConvertedType != null && rightExpressionType.ConvertedType.IsReferenceType; var boxRight = rightExpressionType.ConvertedType != null && (rightExpressionType.Type != null && (rightExpressionType.Type.IsValueType && (rightExpressionType.ConvertedType.IsReferenceType))); var derefRight = rightExpressionType.ConvertedType != null && (leftExpressionType.ConvertedType != null && !leftExpressionType.ConvertedType.IsReferenceType && rightExpressionType.ConvertedType.IsReferenceType); var nullAssignment = expression.Right.ToFullString().Trim() == "null"; //Property calls will be fixed in a preprocessor step ... i.e. just call them // var propertyLeft = symbolInfoLeft.Symbol != null && symbolInfoLeft.Symbol.Kind == SymbolKind.Property; // var propertyRight = symbolInfoRight.Symbol != null && symbolInfoRight.Symbol.Kind == SymbolKind.Property; if (nullAssignment) { Core.Write(writer, expression.Left); writer.Write(" = "); writer.Write("null"); return; } //Do we have an implicit converter, if so, use it if (leftExpressionType.Type != rightExpressionType.Type) { // if (boxLeft) { bool useType = true; //We should start with exact converters and then move to more generic convertors i.e. base class or integers which are implicitly convertible var correctConverter = leftExpressionType.Type.GetImplicitCoversionOp(leftExpressionType.Type, rightExpressionType.Type); // initializerType.Type.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType); if (correctConverter == null) { useType = false; correctConverter = rightExpressionType.Type.GetImplicitCoversionOp(leftExpressionType.Type, rightExpressionType.Type); //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType); } if (correctConverter != null) { Core.Write(writer, expression.Left); writer.Write(" = "); if (useType) { writer.Write(TypeProcessor.ConvertType(leftExpressionType.Type) + "." + "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType)); } else { writer.Write(TypeProcessor.ConvertType(rightExpressionType.Type) + "." + "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType)); } writer.Write("("); Core.Write(writer, expression.Right); writer.Write(")"); return; } } // if (shouldBox) // { // bool useType = true; // var correctConverter = // initializerType.Type.GetCoversionOp(initializerType.ConvertedType, initializerType.Type);//.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.ConvertedType && h.Parameters[0].Type == initializerType.Type); // // if (correctConverter == null) // { // useType = false; // correctConverter = // initializerType.ConvertedType.GetCoversionOp(initializerType.ConvertedType, // initializerType.Type); // //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.ConvertedType && h.Parameters[0].Type == initializerType.Type); // } // // if (correctConverter != null) // { // if (useType) // writer.Write(TypeProcessor.ConvertType(initializerType.Type) + "." + "op_Implicit("); // else // { // writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) + "." + "op_Implicit("); // // } // Core.Write(writer, value); // writer.Write(")"); // return; // } // } } if (expression.OperatorToken.CSharpKind() == SyntaxKind.PlusEqualsToken || expression.OperatorToken.CSharpKind() == SyntaxKind.MinusEqualsToken) { var isname = expression.Right is NameSyntax; var nameexpression = expression.Right as NameSyntax; var ismemberexpression = expression.Right is MemberAccessExpressionSyntax || (isname && TypeProcessor.GetSymbolInfo(expression.Right as NameSyntax).Symbol.Kind == SymbolKind.Method); var isdelegateassignment = ismemberexpression && rightExpressionType.ConvertedType.TypeKind == TypeKind.Delegate; var memberaccessexpression = expression.Right as MemberAccessExpressionSyntax; var isstaticdelegate = isdelegateassignment && ((memberaccessexpression != null && TypeProcessor.GetSymbolInfo(memberaccessexpression).Symbol.IsStatic) || (isname && TypeProcessor.GetSymbolInfo(nameexpression).Symbol.IsStatic)); if (isdelegateassignment) { write(expression.Left); writer.Write(expression.OperatorToken.ToString()); var createNew = !(expression.Right is ObjectCreationExpressionSyntax); var typeString = TypeProcessor.ConvertType(rightExpressionType.ConvertedType); if (createNew) { if (rightExpressionType.ConvertedType.TypeKind == TypeKind.TypeParameter) { writer.Write(" __TypeNew!(" + typeString + ")("); } else { writer.Write("new " + typeString + "("); } } var isStatic = isstaticdelegate; if (isStatic) { writer.Write("__ToDelegate("); } writer.Write("&"); write(expression.Right); //Core.Write (writer, expression.Right); if (isStatic) { writer.Write(")"); } if (createNew) { writer.Write(")"); } return; } } if (leftExpressionType.Type == null || rightExpressionType.Type == null) { // seems we have a null here obj==null or null==obj if ((rightExpressionType.Type != null && rightExpressionType.Type.IsValueType) || (leftExpressionType.Type != null && leftExpressionType.Type.IsValueType)) { writer.Write("/*value type cannot be null*/"); write(expression.Left); switch (expression.OperatorToken.CSharpKind()) { case SyntaxKind.EqualsEqualsToken: writer.Write("!="); break; case SyntaxKind.NotEqualsExpression: writer.Write("=="); break; default: writer.Write(expression.OperatorToken.ToString()); break; } write(expression.Right); } else { write(expression.Left); if (expression.OperatorToken.CSharpKind() == SyntaxKind.EqualsEqualsToken) { writer.Write(" is "); } else if (expression.OperatorToken.CSharpKind() == SyntaxKind.ExclamationEqualsToken) { writer.Write(" !is "); } else { writer.Write(expression.OperatorToken.ToString()); } write(expression.Right); } } else // if (symbolInfoLeft.Symbol != null && (symbolInfoLeft.Symbol.Kind == SymbolKind.Property && expression.OperatorToken.ValueText == "=")) //Assignment of property // { // // write(expression.Left); // writer.Write("("); // write(expression.Right); // writer.Write(")"); // } // else { // writer.Write(derefLeft ? "*(" : ""); writer.Write(boxLeft ? "BOX!(" + TypeProcessor.ConvertType(leftExpressionType.Type) + ")(" : ""); write(expression.Left); writer.Write(boxLeft ? ")" : ""); // writer.Write(derefLeft ? ")" : ""); writer.Write(expression.OperatorToken.ToString()); // writer.Write(derefRight ? "(" : ""); writer.Write(boxRight ? "BOX!(" + TypeProcessor.ConvertType(rightExpressionType.Type) + ")(" : ""); write(expression.Right); writer.Write(boxRight ? ")" : ""); // writer.Write(derefRight ? ")" : ""); } } }
private static string ConvertTypeUncached(ITypeSymbol typeSymbol, bool localize) { if (typeSymbol.IsAnonymousType) { return(WriteAnonymousObjectCreationExpression.TypeName(typeSymbol.As <INamedTypeSymbol>())); } var array = typeSymbol as IArrayTypeSymbol; var ptr = array != null && (array.ElementType.IsValueType == false); if (array != null) { var typeString = TryConvertType(array.ElementType, localize); if (localize) { var name = Context.Instance.UsingDeclarations.FirstOrDefault( k => typeString.StartsWith(k.Name.ToFullString() + ".Namespace.", StringComparison.Ordinal)); if (name != null) { typeString = typeString.RemoveFromStartOfString(name.Name.ToFullString() + ".Namespace."); } } //if (array.Rank == 1) // Jagged / Single return("Array_T!(" + typeString + ")"); // else // { // return "Array_T!(" + typeString + Enumerable.Range (0, array.Rank-1).Select (l => "[]").Aggregate ((a, b) => a + b).ToString () +")"; // // } } if (typeSymbol.TypeKind == TypeKind.PointerType) { var pointer = typeSymbol as IPointerTypeSymbol; return(ConvertType(pointer.PointedAtType) + "*"); } var typeInfoStr = typeSymbol.ToString(); var named = typeSymbol as INamedTypeSymbol; if (typeSymbol.TypeKind == TypeKind.TypeParameter) { return(typeSymbol.Name); } // if (typeSymbol.TypeKind == TypeKind.Delegate) { // var dlg = named.DelegateInvokeMethod.As<IMethodSymbol> (); // if (dlg.Parameters.Length == 0) // return "() => " + TryConvertType (dlg.ReturnType); // else // return "(" + string.Join (", ", dlg.Parameters.ToList ().Select (o => TryConvertType (o.Type))) + ") => " + TryConvertType (dlg.ReturnType); // } // if (typeSymbol.TypeKind == TypeKind.Enum) // return "int"; //enums are always ints if (named.ContainingNamespace.ToString() == "System" && named.Name == "Exception") { return("System.Namespace.NException"); } if (named != null && named.Name == "Nullable" && named.ContainingNamespace.ToString() == "System") { //Nullable types var convertedType = TryConvertType(named.TypeArguments.Single()); switch (convertedType) { case "Int": return("int"); case "Boolean": return("bool"); case "Byte": return("byte"); case "Short": return("short"); case "Float": return("float"); case "Double": return("double"); case "Char": return("char"); case "Long": return("long"); default: return(convertedType); } } var typeStr = GenericTypeName(typeSymbol); if (named != null && named.IsGenericType && !named.IsUnboundGenericType && TypeArguments(named).Any()) { return(TryConvertType(named.ConstructUnboundGenericType()) + "!(" + string.Join(", ", TypeArguments(named).Select(o => TryConvertType(o))) + ")"); } switch (typeStr) { case "System.Namespace.Void": return("void"); case "System.Namespace.Boolean": return("bool"); case "System.Object": case "System.Namespace.Object": return("NObject"); case "System.Namespace.UInt64": return("ulong"); case "System.Namespace.Double": return("double"); case "System.Namespace.Single": return("float"); case "System.Namespace.String": return("String"); case "System.Namespace.Int32": return("int"); case "System.Namespace.UInt16": return("ushort"); case "System.Namespace.Int64": return("long"); case "System.Namespace.UInt32": return("long"); // Looks like d's uint32 is smaller than C#'s case "System.Namespace.Byte": return("byte"); case "System.Namespace.Int16": return("short"); case "System.Namespace.Char": return("char"); case "System.Namespace.Array": return("Array_T"); //All template (generic) classes have atleast one "_T" appended default: if (named != null) { return(typeSymbol.ContainingNamespace.FullNameWithDot() + WriteType.TypeName(named)); } //This type does not get translated and gets used as-is return(typeSymbol.ContainingNamespace.FullNameWithDot() + typeSymbol.Name); } }
public static void WriteConstructorsHelper(IEnumerable <INamedTypeSymbol> allTypes) { foreach (var t in allTypes.Select(o => o.ContainingNamespace.FullNameWithDot() + WriteType.TypeName(o))) { AllTypes.Add(t); } if (StaticConstructors.Count == 0) { return; //no need for it. } }
private static void WriteOutNestedTypes(Context.SyntaxAndSymbol first, OutputWriter writer) { //WriteOut All My nested classes Context.Push(); var delegates = first.Syntax.DescendantNodes().OfType <DelegateDeclarationSyntax>() .Select(o => new { Syntax = o, Symbol = TypeProcessor.GetDeclaredSymbol(o), TypeName = WriteType.TypeName((INamedTypeSymbol)TypeProcessor.GetDeclaredSymbol(o)) }).Where(k => k.Symbol.ContainingType == Context.Instance.Type) // Ignore all nested delegates .GroupBy(o => o.Symbol.ContainingNamespace.FullNameWithDot() + o.TypeName) .ToList(); delegates.ForEach(type => //.ForEach(type => //.Parallel(type => { Context.Instance = new Context { TypeName = type.First().TypeName, DelegatePartials = type.Select( o => new Context.DelegateSyntaxAndSymbol { Symbol = (INamedTypeSymbol)o.Symbol, Syntax = o.Syntax }) .Where(o => !Program.DoNotWrite.ContainsKey(o.Syntax)) .ToList() }; if (Context.Instance.DelegatePartials.Count > 0) { WriteDelegate.Go(writer); } }); Context.Pop(); Context.Push(); var subclasses = first.Syntax.DescendantNodes().OfType <BaseTypeDeclarationSyntax>() .Select(o => new { Syntax = o, Symbol = TypeProcessor.GetDeclaredSymbol(o), TypeName = WriteType.TypeName((INamedTypeSymbol)TypeProcessor.GetDeclaredSymbol(o)) }).Where(k => k.Symbol.ContainingType == Context.Instance.Type) // Ignore all nested classes .GroupBy(o => o.Symbol.ContainingNamespace.FullNameWithDot() + o.TypeName) .ToList(); subclasses.ForEach(type => //.ForEach(type => //.Parallel(type => { Context.Instance = new Context { TypeName = type.First().TypeName, Partials = type.Select( o => new Context.SyntaxAndSymbol { Symbol = (INamedTypeSymbol)o.Symbol, Syntax = o.Syntax }) .Where(o => !Program.DoNotWrite.ContainsKey(o.Syntax)) .ToList() }; if (Context.Instance.Partials.Count > 0) { try { WriteType.Go(writer); } catch (Exception ex) { //TODO: remove this when done with CorLib throw ex; } } }); Context.Pop(); }
public static void Go(OutputWriter writer, InvocationExpressionSyntax invocationExpression) { var symbolInfo = TypeProcessor.GetSymbolInfo(invocationExpression); var expressionSymbol = TypeProcessor.GetSymbolInfo(invocationExpression.Expression); var symbol = symbolInfo.Symbol ?? symbolInfo.CandidateSymbols.FirstOrDefault(); // Resolution error var methodSymbol = symbol.OriginalDefinition.As <IMethodSymbol>().UnReduce(); var memberReferenceExpressionOpt = invocationExpression.Expression as MemberAccessExpressionSyntax; var firstParameter = true; var extensionNamespace = methodSymbol.IsExtensionMethod ? methodSymbol.ContainingNamespace.FullNameWithDot() + methodSymbol.ContainingType.FullName() : null; //null means it's not an extension method, non-null means it is string methodName; string typeParameters = null; ExpressionSyntax subExpressionOpt; if (methodSymbol.ContainingType.FullName() == "Enum") { if (methodSymbol.Name == "Parse") { WriteEnumParse(writer, invocationExpression); return; } if (methodSymbol.Name == "GetValues") { WriteEnumGetValues(writer, invocationExpression); return; } } if (expressionSymbol.Symbol is IEventSymbol) { methodName = "Invoke"; //Would need to append the number of arguments to this to support events. However, events are not currently supported } // else if (memberReferenceExpressionOpt != null && memberReferenceExpressionOpt.Expression is PredefinedTypeSyntax) // { // switch (methodSymbol.Name) // { // case "Parse": // Core.Write(writer, invocationExpression.ArgumentList.Arguments.Single().Expression); // // writer.Write(".to"); // writer.Write(TypeProcessor.ConvertType(methodSymbol.ReturnType)); // // return; // case "TryParse": // methodName = "TryParse" + TypeProcessor.ConvertType(methodSymbol.Parameters[1].Type); // extensionNamespace = "SharpNative"; // break; // default: // methodName = methodSymbol.Name; // extensionNamespace = "SharpNative"; // break; // } // } else if (methodSymbol.MethodKind == MethodKind.DelegateInvoke) { methodName = null; } else { methodName = OverloadResolver.MethodName(methodSymbol); } if (methodSymbol.MethodKind == MethodKind.DelegateInvoke) { subExpressionOpt = invocationExpression.Expression; } else if (memberReferenceExpressionOpt != null) { if (memberReferenceExpressionOpt.Expression is PredefinedTypeSyntax) { subExpressionOpt = null; } else { subExpressionOpt = memberReferenceExpressionOpt.Expression; } } else { subExpressionOpt = null; } //When the code specifically names generic arguments, include them in the method name ... dlang needs help with inference, so we give it the types anyway if (methodSymbol.IsGenericMethod) { // var genNameExpression = invocationExpression.Expression as GenericNameSyntax; // if (genNameExpression == null && memberReferenceExpressionOpt != null) // genNameExpression = memberReferenceExpressionOpt.Name as GenericNameSyntax; // if (genNameExpression != null && genNameExpression.TypeArgumentList.Arguments.Count > 0) typeParameters = "!( " + string.Join(", ", (symbol as IMethodSymbol).TypeArguments.Select(r => TypeProcessor.ConvertType(r))) + " )"; } //Determine if it's an extension method called in a non-extension way. In this case, just pretend it's not an extension method if (extensionNamespace != null && subExpressionOpt != null && TypeProcessor.GetTypeInfo(subExpressionOpt).ConvertedType.ToString() == methodSymbol.ContainingNamespace + "." + methodSymbol.ContainingType.FullName()) { extensionNamespace = null; } var memberType = memberReferenceExpressionOpt == null ? null : TypeProcessor.GetTypeInfo(memberReferenceExpressionOpt.Expression).Type; var isNullableEnum = memberType != null && (memberType.Name == "Nullable" && memberType.ContainingNamespace.FullName() == "System") && memberType.As <INamedTypeSymbol>().TypeArguments.Single().TypeKind == TypeKind.Enum; // if (isNullableEnum && methodSymbol.Name == "ToString") // { // extensionNamespace = null; //override Translations.xml for nullable enums. We want them to convert to the enum's ToString method // methodName = "toString"; // } var directInvocationOnBasics = methodSymbol.ContainingType.IsBasicType(); //Extension methods in Dlang are straightforward, although this could lead to clashes without qualification if (extensionNamespace != null || directInvocationOnBasics) { if (extensionNamespace == null) { extensionNamespace = memberType.ContainingNamespace.FullName() + "." + memberType.Name; //memberType.ContainingNamespace.FullName() +"."+ memberType.Name; } writer.Write(extensionNamespace); if (methodName != null) { writer.Write("."); writer.Write(methodName); } WriteTypeParameters(writer, typeParameters, invocationExpression); writer.Write("("); if (subExpressionOpt != null) { firstParameter = false; Core.Write(writer, subExpressionOpt); } } else { if (memberReferenceExpressionOpt != null) { //Check against lowercase toString since it gets replaced with the lowered version before we get here if (methodName == "toString") { if (memberType.TypeKind == TypeKind.Enum || isNullableEnum) { var enumType = memberType.TypeKind == TypeKind.Enum ? memberType : memberType.As <INamedTypeSymbol>().TypeArguments.Single(); //calling ToString() on an enum forwards to our enum's special ToString method writer.Write(enumType.ContainingNamespace.FullNameWithDot()); writer.Write(WriteType.TypeName((INamedTypeSymbol)enumType)); writer.Write(".ToString("); Core.Write(writer, memberReferenceExpressionOpt.Expression); writer.Write(")"); if (invocationExpression.ArgumentList.Arguments.Count > 0) { throw new Exception( "Enum's ToString detected with parameters. These are not supported " + Utility.Descriptor(invocationExpression)); } return; } if (memberType.SpecialType == SpecialType.System_Byte) { //Calling ToString on a byte needs to take special care since it's signed in the JVM writer.Write("System.SharpNative.ByteToString("); Core.Write(writer, memberReferenceExpressionOpt.Expression); writer.Write(")"); if (invocationExpression.ArgumentList.Arguments.Count > 0) { throw new Exception( "Byte's ToString detected with parameters. These are not supported " + Utility.Descriptor(invocationExpression)); } return; } } } if (subExpressionOpt != null) { WriteMemberAccessExpression.WriteMember(writer, subExpressionOpt); // if (!(subExpressionOpt is BaseExpressionSyntax)) // { // if (methodName != null && methodSymbol.IsStatic) // writer.Write("."); // else // { if (methodSymbol.MethodKind != MethodKind.DelegateInvoke) { writer.Write("."); } // } // } // writer.Write("."); } else if (methodSymbol.IsStatic && extensionNamespace == null) { var str = TypeProcessor.ConvertType(methodSymbol.ContainingType); if (str == "Array_T") { // Array is the only special case, otherwise generics have to be specialized to access static members str = "Array"; } writer.Write(str); // writer.Write(methodSymbol.ContainingNamespace.FullNameWithDot()); // writer.Write(WriteType.TypeName(methodSymbol.ContainingType)); writer.Write("."); } if (methodSymbol.MethodKind != MethodKind.DelegateInvoke) { var declaringSyntaxReferences = methodSymbol.DeclaringSyntaxReferences.Select(j => j.GetSyntax()) .OfType <MethodDeclarationSyntax>(); var any = declaringSyntaxReferences.Any(); if (any && declaringSyntaxReferences.FirstOrDefault() .As <MethodDeclarationSyntax>() .Modifiers.Any(SyntaxKind.NewKeyword)) { //TODO: this means that new is not supported on external libraries // //why doesnt roslyn give me this information ? methodName += "_"; } if (any && declaringSyntaxReferences.FirstOrDefault() .As <MethodDeclarationSyntax>() .Modifiers.Any(SyntaxKind.NewKeyword)) { writer.Write(TypeProcessor.ConvertType(methodSymbol.ContainingType) + "."); } //TODO: fix this for abstract too or whatever other combination //TODO: create a better fix fot this // ISymbol interfaceMethod = // methodSymbol.ContainingType.AllInterfaces.SelectMany ( // u => // u.GetMembers (methodName) // .Where ( // o => // methodSymbol.ContainingType.FindImplementationForInterfaceMember (o) == // methodSymbol)).FirstOrDefault (); /* if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface || * Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol), methodSymbol)) * * if ((interfaceMethod != null /*&& interfaceMethod == methodSymbol || methodSymbol.ContainingType.TypeKind == TypeKind.Interface) * { * //This is an interface method //TO * * var typenameM = Regex.Replace (TypeProcessor.ConvertType (methodSymbol.ContainingType), @" ?!\(.*?\)", string.Empty); * if (typenameM.Contains ('.')) * typenameM = typenameM.SubstringAfterLast ('.'); * if (methodSymbol.ContainingType.SpecialType == SpecialType.System_Array) * writer.Write (""); * else if (interfaceMethod != null) * { * var typenameI = Regex.Replace (TypeProcessor.ConvertType (interfaceMethod.ContainingType), @" ?!\(.*?\)", string.Empty); * if (typenameI.Contains ('.')) * typenameI = typenameI.SubstringAfterLast ('.'); * writer.Write (typenameI + "_"); * } * else // this is the interface itself * writer.Write (typenameM + "_"); * * }*/ if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface || Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol), methodSymbol)) { methodName = Regex.Replace( TypeProcessor.ConvertType(methodSymbol.ContainingType.OriginalDefinition) .RemoveFromStartOfString(methodSymbol.ContainingNamespace + ".Namespace.") + "_" + methodName, @" ?!\(.*?\)", string.Empty); } var interfaceMethods = methodSymbol.ContainingType.AllInterfaces.SelectMany( u => u.GetMembers(methodName)).ToArray(); ISymbol interfaceMethod = interfaceMethods.FirstOrDefault( o => methodSymbol.ContainingType.FindImplementationForInterfaceMember(o) == methodSymbol); // if (interfaceMethod == null) // { // //TODO: fix this for virtual method test 7, seems roslyn cannot deal with virtual // // overrides of interface methods ... so i'll provide a kludge // if (!method.Modifiers.Any(SyntaxKind.NewKeyword)) // interfaceMethod = interfaceMethods.FirstOrDefault(k => CompareMethods(k as IMethodSymbol, methodSymbol)); // } if (interfaceMethod != null) // && CompareMethods(interfaceMethod ,methodSymbol)) { { //This is an interface method //TO if (methodSymbol.ContainingType.SpecialType == SpecialType.System_Array) { writer.Write(""); } else { var typenameI = Regex.Replace( TypeProcessor.ConvertType(interfaceMethod.ContainingType.ConstructedFrom, true), @" ?!\(.*?\)", string.Empty); //TODO: we should be able to get the original interface name, or just remove all generics from this if (typenameI.Contains('.')) { typenameI = typenameI.SubstringAfterLast('.'); } writer.Write(typenameI + "_"); } } // var acc = methodSymbol.DeclaredAccessibility; // if (methodSymbol.MethodKind == MethodKind.ExplicitInterfaceImplementation) // { // var implementations = methodSymbol.ExplicitInterfaceImplementations[0]; // if (implementations != null) // { // // explicitHeaderNAme = implementations.Name; // methodName = TypeProcessor.ConvertType(implementations.ReceiverType) + "_" +implementations.Name; //Explicit fix ? // // // writer.Write(methodSymbol.ContainingType + "." + methodName); // //Looks like internal classes are not handled properly here ... // } // } writer.Write(methodName); } WriteTypeParameters(writer, typeParameters, invocationExpression); writer.Write("("); } bool inParams = false; bool foundParamsArray = false; var arguments = invocationExpression.ArgumentList.Arguments; foreach (var arg in arguments.Select(o => new TransformedArgument(o))) { if (firstParameter) { firstParameter = false; } else { writer.Write(", "); } var argumentType = TypeProcessor.GetTypeInfo(arg.ArgumentOpt.Expression); // if (!inParams && IsParamsArgument (invocationExpression, arg.ArgumentOpt, methodSymbol)) // { // foundParamsArray = true; // // if (!TypeProcessor.ConvertType (TypeProcessor.GetTypeInfo (arg.ArgumentOpt.Expression).Type).StartsWith ("System.Array<")) // { // inParams = true; // writer.Write ("Array_T!("); // } // } //Not needed for dlang // if (arg != null // && arg.ArgumentOpt.RefOrOutKeyword.RawKind != (decimal) SyntaxKind.None // && TypeProcessor.GetSymbolInfo(arg.ArgumentOpt.Expression).Symbol is IFieldSymbol) // { // // } // throw new Exception("ref/out cannot reference fields, only local variables. Consider using ref/out on a local variable and then assigning it into the field. " + Utility.Descriptor(invocationExpression)); // if (argumentType.Type == null) { // if (argumentType.ConvertedType == null) // writer.Write ("null"); // else // writer.Write ("(cast("+TypeProcessor.ConvertType(argumentType.ConvertedType)+") null)"); // } // // else if (argumentType.Type.IsValueType && !argumentType.ConvertedType.IsValueType) // { // //Box // writer.Write("BOX!("+TypeProcessor.ConvertType(argumentType.Type) +")("); // //When passing an argument by ref or out, leave off the .Value suffix // if (arg != null && arg.ArgumentOpt.RefOrOutKeyword.RawKind != (decimal)SyntaxKind.None) // WriteIdentifierName.Go(writer, arg.ArgumentOpt.Expression.As<IdentifierNameSyntax>(), true); // else // arg.Write(writer); // // writer.Write(")"); // } // else if (!argumentType.Type.IsValueType && argumentType.ConvertedType.IsValueType) // { // //UnBox // writer.Write("cast(" + TypeProcessor.ConvertType(argumentType.Type) + ")("); // if (arg != null && arg.ArgumentOpt.RefOrOutKeyword.RawKind != (decimal)SyntaxKind.None) // WriteIdentifierName.Go(writer, arg.ArgumentOpt.Expression.As<IdentifierNameSyntax>(), true); // else // arg.Write(writer); // writer.Write(")"); // } // else // { // if (arg != null && arg.ArgumentOpt.RefOrOutKeyword.RawKind != (decimal)SyntaxKind.None) // WriteIdentifierName.Go(writer, arg.ArgumentOpt.Expression.As<IdentifierNameSyntax>(), true); // else // arg.Write(writer); // } ProcessArgument(writer, arg.ArgumentOpt); } // if (inParams) // writer.Write (")"); // if (!foundParamsArray && methodSymbol.Parameters.Any () && methodSymbol.Parameters.Last ().IsParams) // writer.Write (", null"); //params method called without any params argument. Send null. writer.Write(")"); }
//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(";"); }
private static string ConvertTypeUncached(ITypeSymbol typeSymbol) { if (typeSymbol.IsAnonymousType) { return(WriteAnonymousObjectCreationExpression.TypeName(typeSymbol.As <INamedTypeSymbol>())); } var array = typeSymbol as IArrayTypeSymbol; if (array != null) { var typeString = TryConvertType(array.ElementType, false); // if (localize) // { // var name = // Context.Instance.UsingDeclarations.FirstOrDefault( // k => typeString.StartsWith(k.Name.ToFullString() + ".Namespace.", StringComparison.Ordinal)); // // if (name != null) // typeString = typeString.RemoveFromStartOfString(name.Name.ToFullString() + ".Namespace."); // } return("Array_T!(" + typeString + ")"); } if (typeSymbol.TypeKind == TypeKind.PointerType) { var pointer = typeSymbol as IPointerTypeSymbol; return(ConvertType(pointer.PointedAtType) + "*"); } var typeInfoStr = typeSymbol.ToString(); var named = typeSymbol as INamedTypeSymbol; if (typeSymbol.TypeKind == TypeKind.TypeParameter) { return(WriteIdentifierName.TransformIdentifier(typeSymbol.Name, typeSymbol)); } if (named != null && (named.ContainingNamespace.ToString() == "System" && named.Name == "Exception")) { return("System.Namespace.NException"); } //TODO: Add explicit support for Nullable if (named != null && (named.Name == "Nullable" && named.ContainingNamespace.ToString() == "System")) { //Nullable types if (named.TypeArguments.Any()) { string convertedType = ""; if (named.TypeArguments.FirstOrDefault() is IErrorTypeSymbol) { //unbound generic convertedType = "__UNBOUND"; } else { convertedType = TryConvertType(named.TypeArguments.FirstOrDefault(), false); } return("Nullable__G!(" + convertedType + ")"); } } var typeStr = GenericTypeName(typeSymbol); if (named != null && named.IsGenericType) { if (!named.IsUnboundGenericType && TypeArguments(named).Any()) { return(GetFullGenericName(named)); } else { return(GetFullGenericName(named.OriginalDefinition)); } } switch (typeStr) { case "System.Namespace.Void": return("void"); case "System.Namespace.Boolean": return("bool"); case "System.Object": case "System.Namespace.Object": return("NObject"); case "System.Namespace.UInt64": return("ulong"); case "System.Namespace.Double": return("double"); case "System.Namespace.Single": return("float"); case "System.Namespace.String": return("String"); case "System.Namespace.Int32": return("int"); case "System.Namespace.UInt16": return("ushort"); case "System.Namespace.Int64": return("long"); case "System.Namespace.UInt32": return("uint"); // /TODO: Looks like d's uint32 is smaller than C#'s case "System.Namespace.Byte": return("ubyte"); case "System.Namespace.SByte": return("byte"); case "System.Namespace.Int16": return("short"); case "System.Namespace.Char": return("wchar"); case "System.Namespace.Array": return("Array"); //All template (generic) classes have atleast one "_T" appended default: if (named != null) { return(typeSymbol.ContainingNamespace.FullNameWithDot(true, false) + WriteType.TypeName(named)); } //This type does not get translated and gets used as-is return(typeSymbol.ContainingNamespace.FullNameWithDot(true, false) + WriteIdentifierName.TransformIdentifier(typeSymbol.Name)); } }