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("]"); }
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(" )"); } }
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++; } }
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(")"); * }*/ }