//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(";"); }
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, OperatorDeclarationSyntax method) { var methodSymbol = (IMethodSymbol)TypeProcessor.GetDeclaredSymbol(method); var ActualMethodName = OverloadResolver.MethodName(methodSymbol); // var methodType = Program.GetModel(method).GetTypeInfo(method); writer.Write("\n"); var isInterface = method.Parent is InterfaceDeclarationSyntax; if (method.Modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword) || method.Modifiers.Any(SyntaxKind.ProtectedKeyword) || method.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface) { writer.Write("public "); } var returnType = ""; if (method.ReturnType.ToString() == "void") { writer.Write("void "); } else { // var typeSymbol = TypeProcessor.GetTypeInfo(method.ReturnType).Type; // var isPtr = typeSymbol != null && (typeSymbol.IsValueType || typeSymbol.TypeKind == TypeKind.TypeParameter) ? "" : ""; // var typeString = TypeProcessor.ConvertType(method.ReturnType) + isPtr + " "; // writer.Write(typeString); // writer.HeaderWriter.Write(typeString); // var isPtr = typeSymbol != null && (!typeSymbol.IsValueType || typeSymbol.TypeKind == TypeKind.TypeParameter); returnType = TypeProcessor.ConvertType(method.ReturnType) + " "; writer.Write(returnType); } var methodName = ""; if (binaryOperators.Contains(method.OperatorToken.ValueText)) { methodName = "opBinary"; var typeSymbolParam0 = TypeProcessor.GetTypeInfo(method.ParameterList.Parameters[0].Type); var typeSymbolParent = (methodSymbol.ContainingType); if (typeSymbolParam0.Type != typeSymbolParent) { methodName += "Right"; } } if (unaryOperators.Contains(method.OperatorToken.ValueText)) { methodName = "opUnary"; } if (equalsOperators.Contains(method.OperatorToken.ValueText)) { methodName = "opEquals"; } if (cmpOperators.Contains(method.OperatorToken.ValueText)) { methodName = "opCmp"; } if (assignOperators.Contains(method.OperatorToken.ValueText)) { methodName = "opAssign"; } if (assignOpOperators.Contains(method.OperatorToken.ValueText)) { methodName = "opOpAssign"; // need to remove = from the name } //method.ParameterList.Parameters[0]; var paramType = method.ParameterList.Parameters[0]; if (method.ParameterList.Parameters.Count == 2) { if (methodName.EndsWith("Right")) { paramType = method.ParameterList.Parameters[0]; } else { paramType = method.ParameterList.Parameters[1]; } } var token = method.OperatorToken.ValueText; if (methodName == "opOpAssign") { token = token.Substring(0, 1); } writer.Write(methodName + String.Format( " (string _op) ({0} other)\r\nif(_op==\"{2}\")\r\n{{ \r\nreturn {1}(this,other); \r\n}}\r\n", TypeProcessor.ConvertType(paramType.Type), ActualMethodName, token)); writer.Write("\r\n\r\npublic static " + returnType + " " + ActualMethodName); WriteParameterList(writer, method.ParameterList); writer.WriteLine(); writer.OpenBrace(); writer.WriteLine(); if (method.Body != null) { foreach (var statement in method.Body.Statements) { Core.Write(writer, statement); } TriviaProcessor.ProcessTrivias(writer, method.Body.DescendantTrivia()); } writer.WriteLine(); writer.CloseBrace(); writer.WriteLine(); }
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, CastExpressionSyntax expression) { var symbol = TypeProcessor.GetSymbolInfo(expression); var castingFrom = TypeProcessor.GetTypeInfo(expression.Expression).Type ?? TypeProcessor.GetTypeInfo(expression).Type; var srcTypeCpp = TypeProcessor.ConvertType(castingFrom); var destType = TypeProcessor.GetTypeInfo(expression.Type).Type; var destTypeDlang = TypeProcessor.TryConvertType(expression.Type); if (destTypeDlang == srcTypeCpp) { Core.Write(writer, expression.Expression); } else //if (symbol.Symbol != null)// && srcTypeCpp != "int" && srcTypeCpp != "System.String" && srcTypeCpp != "bool") { // if (castingFrom != destType) // Check for implicit first then explicit 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 = destType.GetImplicitCoversionOp(destType, castingFrom, true); // 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 = castingFrom.GetImplicitCoversionOp(destType, castingFrom, true); //.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 (correctConverter.ReturnType != destType) { writer.Write("cast(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")"); } if (useType) { writer.Write(TypeProcessor.ConvertType(destType) + "." + "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType)); } else { writer.Write(TypeProcessor.ConvertType(castingFrom) + "." + "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType)); } writer.Write("("); Core.Write(writer, expression.Expression); writer.Write(")"); return; } 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 correctConverter = destType.GetExplictCoversionOp(destType, castingFrom, true); // 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 = castingFrom.GetExplictCoversionOp(destType, castingFrom, true); //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType); } if (correctConverter != null) { if (correctConverter.ReturnType != destType) { writer.Write("cast(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")"); } // Core.Write(writer, expression.Left); // writer.Write(" = "); if (useType) { writer.Write(TypeProcessor.ConvertType(destType) + "." + "op_Explicit"); } else { writer.Write(TypeProcessor.ConvertType(castingFrom) + "." + "op_Explicit"); } writer.Write("("); Core.Write(writer, expression.Expression); writer.Write(")"); return; } if (TypeProcessor.IsPrimitiveType(srcTypeCpp) && TypeProcessor.IsPrimitiveType(destTypeDlang)) { writer.Write("(cast(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")"); Core.Write(writer, expression.Expression); writer.Write(")"); } else { var convertedType = TypeProcessor.GetTypeInfo(expression).Type; var type = TypeProcessor.GetTypeInfo(expression.Expression).Type; if (type.IsValueType && !convertedType.IsValueType) { //We have to box then cast if not Object if (destType.Name != "Object") { writer.Write("cast(" + destTypeDlang + ")"); } //Box writer.Write("BOX!(" + TypeProcessor.ConvertType(type) + ")("); //When passing an argument by ref or out, leave off the .Value suffix // writer.Write(" >("); Core.Write(writer, expression.Expression); writer.Write(")"); } else if (!type.IsValueType && convertedType.IsValueType) { //UnBox // writer.Write("(cast( Boxed!(" + TypeProcessor.ConvertType(convertedType) + ") )("); // Core.Write(writer, expression.Expression); // writer.Write(")).Value"); writer.Write("UNBOX!(" + TypeProcessor.ConvertType(convertedType) + ")("); Core.Write(writer, expression.Expression); writer.Write(")"); } else if (type.IsValueType && convertedType.IsValueType) { //cannot use ascast here, its for boxed types and objects writer.Write("(cast(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")("); Core.Write(writer, expression.Expression); writer.Write("))"); } else { writer.Write("AsCast!("); writer.Write(destTypeDlang); writer.Write(")("); Core.Write(writer, expression.Expression); writer.Write(")"); } } } }
private static string GetTypeConstraints(TypeDeclarationSyntax method) { string constraints = ""; if (method.ConstraintClauses.Count > 0) { constraints += (" if ("); bool isFirst = true; foreach (var constraint in method.ConstraintClauses) { foreach (var condition in constraint.Constraints) { if (condition is TypeConstraintSyntax) { var type = (condition as TypeConstraintSyntax).Type; constraints += (isFirst ? "" : "&&") + "is(" + WriteIdentifierName.TransformIdentifier(constraint.Name.ToFullString()) + ":" + TypeProcessor.ConvertType(type) + ")"; } if (condition is ConstructorConstraintSyntax) { constraints += (isFirst ? "" : "&&") + "__isNewwable!(" + WriteIdentifierName.TransformIdentifier(constraint.Name.ToFullString()) + ")"; } if (condition is ClassOrStructConstraintSyntax) { var properConstraint = condition as ClassOrStructConstraintSyntax; if (properConstraint.ClassOrStructKeyword.RawKind == (decimal)SyntaxKind.StructKeyword) { constraints += (isFirst ? "" : "&&") + "__isCSStruct!(" + WriteIdentifierName.TransformIdentifier(constraint.Name.ToFullString()) + ")"; } else { constraints += (isFirst ? "" : "&&") + "__isClass!(" + WriteIdentifierName.TransformIdentifier(constraint.Name.ToFullString()) + ")"; } } /* string dlangCondition = condition.ToString(); * * if (dlangCondition == "new()") // haven't got around to this yet * // constraints += " __traits(compiles, {0}())";//Fix this * dlangCondition = ""; * if (dlangCondition == "class") // TODO: is there a better way to do this ? * dlangCondition = "NObject"; * * if (dlangCondition == "struct") * constraints += ((isFirst ? "" : "&&") + " !is(" + constraint.Name + " : NObject)"); * else * { * //TODO: fix this up better * constraints += ((isFirst ? "" : "&&") + " is(" + constraint.Name + " : " + dlangCondition.Replace("<", "!(").Replace(">", ")") + * ")"); * }*/ isFirst = false; // Console.WriteLine (condition); } } constraints += (")"); } return(constraints); }
public static void Go(OutputWriter writer, InitializerExpressionSyntax initializer) { writer.WriteIndent(); var isCollectionInit = false; if (CSharpExtensions.CSharpKind(initializer) == SyntaxKind.CollectionInitializerExpression || CSharpExtensions.CSharpKind(initializer) == SyntaxKind.ArrayInitializerExpression) { var tx = TypeProcessor.GetTypeInfo(initializer); var t = tx.Type; if (t == null) { t = tx.ConvertedType; } if (t != null) // Initializer within initializer { var elementType = t.As <IArrayTypeSymbol>().ElementType; var ptr = !elementType.IsValueType; // ? "" : ""; var type = TypeProcessor.ConvertType(elementType); var typeString = "Array_T!(" + type + ")"; if (elementType.TypeKind == TypeKind.TypeParameter) { writer.Write(" __TypeNew!(" + typeString + ")("); } else { writer.Write("new " + typeString + "("); } } var variableDeclarationSyntax = initializer.Parent.Parent.Parent as VariableDeclarationSyntax; if (variableDeclarationSyntax != null) { var atype = variableDeclarationSyntax.Type; initializer.WriteArrayInitializer(writer, atype); } else { initializer.WriteArrayInitializer(writer); } if (t != null) { writer.Write(")"); } } else { // writer.Write("goto "); // foreach (var expressionSyntax in method.Expressions) // { // Core.Write(writer, expressionSyntax); // } bool first = true; foreach (var expression in initializer.Expressions) { if (first) { first = false; } else { writer.Write(", "); } Core.Write(writer, expression); } } // writer.Write(";"); }
public static void WriteMethodPointer(OutputWriter writer, SyntaxNode expression) { writer.Write("&"); var symbol = TypeProcessor.GetSymbolInfo(expression).Symbol; // // else { Core.Write(writer, expression); if (symbol is IMethodSymbol && !(expression is GenericNameSyntax)) { //Type inference for delegates var methodSymbol = symbol as IMethodSymbol; // var methodName = TypeProcessor.ConvertType(methodSymbol.ContainingType) +"."+ WriteIdentifierName.TransformIdentifier(methodSymbol.Name); var specializedMethod = //methodName + (methodSymbol.TypeArguments.Any() ? ("!(" + methodSymbol.TypeArguments.Select(k => TypeProcessor.ConvertType(k)) .Aggregate((a, b) => a + "," + b) + ")") : ""); writer.Write(specializedMethod); } } }
public static void Go() { var partials = Context.Instance.Partials; var first = partials.First(); 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; Console.WriteLine("Writing out type: " + Context.Instance.Namespace + "." + Context.Instance.TypeName); if ((Context.Instance.Namespace + "." + Context.Instance.TypeName) == "Mono.Security.X509.Namespace.X509Chain") { } var myUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(mynamespace)); var SystemUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System")); // Required as certain functions like boxing are in this namespace var namespaces = first.Syntax.Parent.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray(); var usingStatements = first.Syntax.Parent.DescendantNodes().OfType <UsingStatementSyntax>().ToArray(); Context.Instance.UsingDeclarations = namespaces .Union(new[] { myUsingDirective, SystemUsingDirective }).ToArray(); var objectType = TypeProcessor.GetSemanticModel(partials.First().Syntax) .Compilation.GetTypeByMetadataName("System.Object"); using (var writer = new OutputWriter(Context.Instance.Namespace, Context.Instance.TypeName)) { var bases = partials .Select(o => o.Syntax.BaseList) .Where(o => o != null) .SelectMany(o => o.Types) .Select(o => TypeProcessor.GetTypeInfo(o.Type).ConvertedType) .Distinct() .ToList(); // var interfaces = bases.Where(o => o.TypeKind == TypeKind.Interface).ToList(); if (!bases.Any((j => j.TypeKind != TypeKind.Interface)) && !(first.Symbol.TypeKind == TypeKind.Interface || first.Symbol.TypeKind == TypeKind.Struct)) { //TODO: fix structs using mixins / alias this bases.Add(objectType); } // WriteStandardIncludes.Go(writer); // writer.WriteLine(String.Format("#include \"{0}\"", TypeState.Instance.TypeName + ".h")); WriteBcl.Go(writer); //TypeState.Instance.DerivesFromObject = bases.Count == interfaces.Count; var @namespace = first.Symbol.ContainingNamespace.FullName(); //Module name = namespace + "." + typename; WriteStandardIncludes.Go(writer); // var namespaces = @namespace.Split(new string[] { "." }, StringSplitOptions.None); // // if (@namespace.Length > 0) // { // foreach (var ns in namespaces) // { // writer.WriteLine("namespace " + ns + "\r\n{"); // writer.WriteLine("namespace " + ns + "\r\n{"); // } // // } //TODO: Fix enum support if (first.Syntax is EnumDeclarationSyntax) { WriteEnum.Go(writer, Context.Instance.Partials.Select(o => o.Syntax) .Cast <EnumDeclarationSyntax>() .SelectMany(o => o.Members) .Where(o => !Program.DoNotWrite.ContainsKey(o))); return; } Context.Instance.AllMembers = partials.Select(o => o.Syntax) .Cast <TypeDeclarationSyntax>() .SelectMany(o => o.Members) .Where(o => !Program.DoNotWrite.ContainsKey(o)) .ToList(); var allMembersToWrite = Context.Instance.AllMembers .Where(member => !(member is TypeDeclarationSyntax) && !(member is EnumDeclarationSyntax) && !(member is DelegateDeclarationSyntax) && !(member is ConstructorDeclarationSyntax)) .ToList(); var instanceCtors = Context.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>() .Where(o => !o.Modifiers.Any(SyntaxKind.StaticKeyword)) .ToList(); var staticCtors = Context.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>() .Where(o => (o.Modifiers.Any(SyntaxKind.StaticKeyword))) .ToList(); //TODO: Add support for overloading constructing // if (instanceCtors.Count > 1) // throw new Exception( // "Overloaded constructors are not supported. Consider changing all but one to static Create methods " + // Utility.Descriptor(first.Syntax)); // var ctorOpt = instanceCtors.SingleOrDefault(); //TODO: Handle interfaces by /* * class Interface * { * public: * virtual ~Interface() { } * virtual void test() = 0; // Functions, must all be virtual * } */ var membersToWrite = allMembersToWrite.ToList(); //.Where(o => IsStatic(o) == staticMembers).ToList(); // if (membersToWrite.Count == 0 && (partials.Any(o => o.Syntax.Modifiers.Any(SyntaxKind.StaticKeyword)))) // continue; // if (staticMembers) // writer.Write("object "); // else if (first.Syntax.Kind == SyntaxKind.InterfaceDeclaration) // writer.Write("trait "); // else // { // if (partials.Any(o => o.Syntax.Modifiers.Any(SyntaxKind.AbstractKeyword))) // writer.Write("abstract "); // } // writer.Write(TypeState.Instance.TypeName); if (first.Syntax is TypeDeclarationSyntax) { //Look for generic arguments var genericArgs = partials .Select(o => o.Syntax) .Cast <TypeDeclarationSyntax>() .Where(o => o.TypeParameterList != null) .SelectMany(o => o.TypeParameterList.Parameters) .ToList(); if (Context.Instance.Type.TypeKind == TypeKind.Class) { writer.Write("class "); } else if (Context.Instance.Type.TypeKind == TypeKind.Interface) { writer.Write("interface "); } else if (Context.Instance.Type.TypeKind == TypeKind.Struct) { writer.Write("struct "); // writer.Write (" class "); // Allows inheritance ... but too many issues, will look at this when it gets relevant } else { throw new Exception("don't know how to write type: " + Context.Instance.Type.TypeKind); } //writer.Write (((TypeState.Instance.Type.TypeKind== TypeKind.Interface)?" interface ": ) ); writer.Write(Context.Instance.TypeName); if (genericArgs.Count > 0) { writer.Write("( "); writer.Write(string.Join(" , ", genericArgs.Select(o => o))); writer.Write(" )"); } bool firstBase = true; if (Context.Instance.Type.TypeKind != TypeKind.Struct) { foreach (var baseType in bases.OrderBy(o => o.TypeKind == TypeKind.Interface ? 1 : 0)) { writer.Write(firstBase ? " : " : " ,"); writer.Write(TypeProcessor.ConvertType(baseType)); // if (firstBase && ctorOpt != null && ctorOpt.Initializer != null && // ctorOpt.Initializer.ArgumentList.Arguments.Count > 0) // { // writer.Write("("); // bool firstArg = true; // foreach (var init in ctorOpt.Initializer.ArgumentList.Arguments) // { // if (firstArg) // firstArg = false; // else // writer.Write(", "); // // Core.Write(writer, init.Expression); // } // writer.Write(")"); // } firstBase = false; } } } writer.WriteLine(); writer.OpenBrace(); var fields = membersToWrite.OfType <FieldDeclarationSyntax>().ToList(); var nonFields = membersToWrite.Except(fields); // also static fields should be separately dealt with var structLayout = first.Syntax.GetAttribute(Context.StructLayout); if (structLayout != null) { LayoutKind value = LayoutKind.Auto; if ( structLayout.ArgumentList.Arguments.Any( k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Value")) { value = (LayoutKind) Enum.Parse(typeof(LayoutKind), structLayout.ArgumentList.Arguments.FirstOrDefault( k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Value") .Expression.ToFullString() .SubstringAfterLast('.')); //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value"); } //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value"); else if (structLayout.ArgumentList.Arguments.Count > 0 && structLayout.ArgumentList.Arguments[0].NameEquals == null) { value = (LayoutKind) Enum.Parse(typeof(LayoutKind), structLayout.ArgumentList.Arguments[0].Expression.ToFullString() .SubstringAfterLast('.')); } int pack = -1; int size = -1; CharSet charset = CharSet.Auto; // if (structLayout.ArgumentList.Arguments.Count > 1) { try { if ( structLayout.ArgumentList.Arguments.Any( k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "CharSet")) { charset = (CharSet) Enum.Parse(typeof(CharSet), structLayout.ArgumentList.Arguments.FirstOrDefault( k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "CharSet") .Expression.ToFullString() .SubstringAfterLast('.')); //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value"); } //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value"); else if (structLayout.ArgumentList.Arguments.Count > 1 && structLayout.ArgumentList.Arguments[1].NameEquals == null) { charset = (CharSet) Enum.Parse(typeof(CharSet), structLayout.ArgumentList.Arguments[1].Expression.ToFullString() .SubstringAfterLast('.')); } } catch (Exception ex) { } try { if ( structLayout.ArgumentList.Arguments.Any( k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Pack")) { pack = int.Parse( structLayout.ArgumentList.Arguments.FirstOrDefault( k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Pack") .Expression.ToFullString()); } //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value"); else if (structLayout.ArgumentList.Arguments.Count > 2 && structLayout.ArgumentList.Arguments[2].NameEquals == null) { pack = int.Parse(structLayout.ArgumentList.Arguments[2].Expression.ToFullString()); } } catch (Exception ex) { } try { if ( structLayout.ArgumentList.Arguments.Any( k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Size")) { size = int.Parse( structLayout.ArgumentList.Arguments.FirstOrDefault( k => k.NameColon != null && k.NameColon.ToFullString().Trim() == "Size") .Expression.ToFullString()); } //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value"); else if (structLayout.ArgumentList.Arguments.Count > 3 && structLayout.ArgumentList.Arguments[3].NameEquals == null) { size = int.Parse(structLayout.ArgumentList.Arguments[3].Expression.ToFullString()); } } catch (Exception ex) { } // size = int.Parse (structLayout.ArgumentList.Arguments [3].Expression.ToFullString ()); } // var pack = structLayout.ArgumentList.Arguments.FirstOrDefault (k => k.NameColon.Name.ToFullString() == "Pack"); // var charset = structLayout.ArgumentList.Arguments.FirstOrDefault (k => k.NameColon.Name.ToFullString() == "CharSet"); // var size = structLayout.ArgumentList.Arguments.FirstOrDefault (k => k.NameColon.Name.ToFullString() == "Size"); if (value == LayoutKind.Explicit) { var fieldGroups = fields.GroupBy(f => f.GetAttribute(Context.FieldOffset).ArgumentList.Arguments[0].ToString()) .OrderBy(k => k.Key); writer.Indent++; foreach (var group in fieldGroups) { writer.WriteLine("//FieldOffset(" + @group.Key + ")"); writer.WriteLine("union {"); foreach (var member in group) { Core.Write(writer, member); } writer.WriteLine("}"); } // foreach (var member in fields) // { // // writer.WriteLine(); // Core.Write (writer, member); // } } else if (value == LayoutKind.Sequential) { fields = SortFields(fields); writer.Indent++; foreach (var member in fields) { if (pack != -1) { writer.WriteLine("align (" + pack + "): //Pack = " + pack); } // writer.WriteLine(); Core.Write(writer, member); } } else { //Looks like C# aligns to 1 by default ... don't know about D... fields = SortFields(fields); writer.Indent++; foreach (var member in fields) { pack = 1; writer.WriteLine("align (" + pack + "): //Pack = " + pack + "C# default"); // writer.WriteLine(); Core.Write(writer, member); } } } else { //Looks like C# aligns to 1 by default ... don't know about D... fields = SortFields(fields); writer.Indent++; foreach (var member in fields) { var pack = 1; writer.WriteLine("align (" + pack + "): //Pack = " + pack + "C# default"); // writer.WriteLine(); Core.Write(writer, member); } } foreach (var member in nonFields) { // writer.WriteLine(); Core.Write(writer, member); } foreach (var constructor in instanceCtors) { // writer.WriteLine(); Core.Write(writer, constructor); } if (staticCtors.Count == 0) { if (Context.Instance.StaticInits.Count > 0) { var constructor = SyntaxFactory.ConstructorDeclaration(Context.Instance.TypeName); constructor = constructor.WithModifiers( SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.StaticKeyword))); WriteConstructorBody.WriteStaticConstructor(writer, constructor, Context.Instance.StaticInits); staticCtors.Add(constructor); } } else { var isFirst = true; foreach (ConstructorDeclarationSyntax constructor in staticCtors) { if (isFirst) { WriteConstructorBody.WriteStaticConstructor(writer, constructor, Context.Instance.StaticInits); } else { WriteConstructorBody.Go(writer, constructor); } isFirst = false; } } var dllImports = Context.Instance.DllImports; // This should only be written once ... I guess we have to put the detection logic in Program.cs if (Context.Instance.EntryMethod != null) { if (dllImports.Count > 0) { writer.WriteLine(); writer.WriteLine(String.Format("static void * __DllImportMap[{0}];", dllImports.Count)); writer.WriteLine("static void __SetupDllImports()"); writer.OpenBrace(); for (int index = 0; index < dllImports.Count; index++) { var dllImport = dllImports[index]; writer.WriteLine(String.Format("__DllImportMap[{0}] = LoadNativeLibrary(cast(string){1});", index, dllImport.ArgumentList.Arguments.FirstOrDefault(k => k.Expression != null))); } writer.CloseBrace(); writer.WriteLine(); writer.WriteLine("static void __FreeDllImports()"); writer.OpenBrace(); writer.WriteLine(String.Format(@"for(int i=0;i<{0};i++)", dllImports.Count)); writer.OpenBrace(); writer.WriteLine("if(__DllImportMap[i]!=null)"); writer.WriteLine("\tFreeNativeLibrary(__DllImportMap[i]);"); writer.CloseBrace(); writer.CloseBrace(); // if (hModule != null) // { // ::FreeLibrary(hModule); // } } } writer.Indent--; writer.CloseBrace(); //Implement Boxed!Interface if (Context.Instance.Type.TypeKind == TypeKind.Struct) { writer.WriteLine(); var typeName = Context.Instance.TypeName; writer.Write("public class __Boxed_" + typeName + " : Boxed!(" + typeName + ")"); foreach (var baseType in bases.OrderBy(o => o.TypeKind == TypeKind.Interface ? 1 : 0)) { writer.Write(" ,"); writer.Write(TypeProcessor.ConvertType(baseType, false)); } writer.OpenBrace(); //FIXME:This is giving issues, we will just generate them here // writer.WriteLine ("import Irio.Utilities;"); writer.WriteLine("import std.traits;"); foreach (var baseType in bases.Where(o => o.TypeKind == TypeKind.Interface)) { //FIXME:This is giving issues, we will just generate them here // writer.WriteLine ("mixin(__ImplementInterface!({0}, Value));",TypeProcessor.ConvertType(baseType,false)); var ifacemembers = baseType.GetMembers(); foreach (var member in ifacemembers) { var ifacemethod = Context.Instance.Type.FindImplementationForInterfaceMember(member) .DeclaringSyntaxReferences.First() .GetSyntax(); // .Where(member => !(member is TypeDeclarationSyntax) // && !(member is EnumDeclarationSyntax) // && !(member is DelegateDeclarationSyntax) && !(member is ConstructorDeclarationSyntax)) // .ToList(); // writer.WriteLine(); // Core.Write(writer, member); if (ifacemethod is MethodDeclarationSyntax) { WriteMethod.WriteIt(writer, (MethodDeclarationSyntax)ifacemethod); } else if (ifacemethod is PropertyDeclarationSyntax) { WriteProperty.Go(writer, (PropertyDeclarationSyntax)ifacemethod, 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({0}.init);", typeName); writer.CloseBrace(); if (Context.Instance.Type.GetMembers("ToString").Count() >= 1) // 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.CloseBrace(); } if (Context.Instance.EntryMethod != null) { //TODO: DllImports should be centralized // writer.WriteLine(); writer.WriteLine("void main(string[] args)"); writer.OpenBrace(); if (dllImports.Count > 0) { writer.WriteLine(Context.Instance.TypeName + ".__SetupDllImports();"); } writer.WriteLine(Context.Instance.EntryMethod); if (dllImports.Count > 0) { writer.WriteLine(Context.Instance.TypeName + ".__FreeDllImports();"); } writer.CloseBrace(); } // var mySpecializations = Program.AllGenericSpecializations.Where (t => t.OriginalDefinition == TypeState.Instance.Type); // // // foreach (var specialization in mySpecializations) { // // var specializationText = ("template class " + specialization.GetFullNameD (false) + " (" + // (string.Join (" , ", // specialization.TypeArguments.Select ( // o => // TypeProcessor.ConvertType (o) + // ((o.IsValueType || // o.TypeKind == TypeKind.TypeParameter) // ? "" // : "*"))) + // ");")); // writer.Write (specializationText); // } // if (@namespace.Length > 0) // { // foreach (var ns in namespaces) // { // writer.WriteLine("\n\n}"); // writer.WriteLine("\n\n}"); // } // } } }
/* * template Action(T) { * alias void delegate(T obj) Action; * } * */ public static void Go() { var partials = Context.Instance.DelegatePartials; var first = partials.First(); 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(); using (var writer = new OutputWriter(Context.Instance.Namespace, Context.Instance.TypeName)) { var objectType = TypeProcessor.GetSemanticModel(partials.First().Syntax) .Compilation.GetTypeByMetadataName("System.Object"); WriteBcl.Go(writer); var @namespace = first.Symbol.ContainingNamespace.FullName(); WriteStandardIncludes.Go(writer); //Look for generic arguments //Look for generic arguments var genericArgs = partials.Select(o => o.Syntax) .Where(o => o.TypeParameterList != null) .SelectMany(o => o.TypeParameterList.Parameters) .ToList(); var name = Context.Instance.TypeName; if (genericArgs.Count > 0) { name = "template " + name; name += ("( "); name += (string.Join(" , ", genericArgs.Select(o => o))); name += (" )"); writer.Write(name); writer.Write("\r\n"); writer.OpenBrace(); writer.Indent++; writer.Write("alias Delegate!(" + TypeProcessor.ConvertType(first.Syntax.ReturnType) + " delegate" + WriteMethod.GetParameterListAsString(first.Syntax.ParameterList)); writer.Write(") " + Context.Instance.TypeName + ";"); writer.Indent--; writer.Write("\r\n"); writer.CloseBrace(); } else { //Non-generic writer.Write("alias Delegate!(" + TypeProcessor.ConvertType(first.Syntax.ReturnType) + " delegate" + WriteMethod.GetParameterListAsString(first.Syntax.ParameterList)); writer.Write(") " + Context.Instance.TypeName + ";"); } } }
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(")"); * }*/ }
private static void ProcessArgument(OutputWriter writer, ArgumentSyntax variable) { if (variable != null) { if (variable.NameColon != null) { } if (CSharpExtensions.CSharpKind(variable) == SyntaxKind.CollectionInitializerExpression) { return; } var value = variable; var initializerType = TypeProcessor.GetTypeInfo(value.Expression); var memberaccessexpression = value.Expression as MemberAccessExpressionSyntax; var nameexpression = value.Expression as NameSyntax; var nullAssignment = value.ToFullString().Trim() == "null"; var shouldBox = initializerType.Type != null && initializerType.Type.IsValueType && !initializerType.ConvertedType.IsValueType; var shouldUnBox = initializerType.Type != null && !initializerType.Type.IsValueType && initializerType.ConvertedType.IsValueType; var isname = value.Expression is NameSyntax; var ismemberexpression = value.Expression is MemberAccessExpressionSyntax || (isname && TypeProcessor.GetSymbolInfo(value.Expression as NameSyntax).Symbol.Kind == SymbolKind.Method); var isdelegateassignment = ismemberexpression && initializerType.ConvertedType.TypeKind == TypeKind.Delegate; var isstaticdelegate = isdelegateassignment && ((memberaccessexpression != null && TypeProcessor.GetSymbolInfo(memberaccessexpression).Symbol.IsStatic) || (isname && TypeProcessor.GetSymbolInfo(nameexpression).Symbol.IsStatic)); if (nullAssignment) { writer.Write("null"); return; } if (shouldBox) { 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 = initializerType.Type.GetImplicitCoversionOp(initializerType.ConvertedType, initializerType.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 = initializerType.ConvertedType.GetImplicitCoversionOp(initializerType.ConvertedType, initializerType.Type); //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType); } if (correctConverter != null) { if (useType) { writer.Write(TypeProcessor.ConvertType(initializerType.Type) + "." + "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType)); } else { writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) + "." + "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType)); } writer.Write("("); Core.Write(writer, value.Expression); writer.Write(")"); return; } } else if (shouldUnBox) { 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 = initializerType.Type.GetImplicitCoversionOp(initializerType.Type, initializerType.ConvertedType); // 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 = initializerType.ConvertedType.GetImplicitCoversionOp(initializerType.Type, initializerType.ConvertedType); //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType); } if (correctConverter != null) { if (useType) { writer.Write(TypeProcessor.ConvertType(initializerType.Type) + "." + "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType)); } else { writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) + "." + "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType)); } writer.Write("("); Core.Write(writer, value.Expression); writer.Write(")"); return; } } if (shouldBox) { //Box writer.Write("BOX!(" + TypeProcessor.ConvertType(initializerType.Type) + ")("); //When passing an argument by ref or out, leave off the .Value suffix Core.Write(writer, value.Expression); writer.Write(")"); return; } if (shouldUnBox) { //UnBox writer.Write("cast!(" + TypeProcessor.ConvertType(initializerType.Type) + ")("); Core.Write(writer, value.Expression); writer.Write(")"); } if (isdelegateassignment) { var typeString = TypeProcessor.ConvertType(initializerType.ConvertedType); var createNew = !(value.Expression is ObjectCreationExpressionSyntax); if (createNew) { if (initializerType.ConvertedType.TypeKind == TypeKind.TypeParameter) { writer.Write(" __TypeNew!(" + typeString + ")("); } else { writer.Write("new " + typeString + "("); } } var isStatic = isstaticdelegate; if (isStatic) { writer.Write("__ToDelegate("); } writer.Write("&"); Core.Write(writer, value.Expression); if (isStatic) { writer.Write(")"); } if (createNew) { writer.Write(")"); } return; } if (initializerType.Type == null && initializerType.ConvertedType == null) { writer.Write("null"); return; } Core.Write(writer, value.Expression); } }
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(")"); }
public static void Go(OutputWriter writer, IdentifierNameSyntax identifier, bool byRef = false) { var symbol = TypeProcessor.GetSymbolInfo(identifier).Symbol; if (symbol.IsStatic) { writer.Write(symbol.ContainingNamespace.FullNameWithDot()); writer.Write(symbol.ContainingType.FullName()); writer.Write("."); } // if (!byRef && Program.RefOutSymbols.ContainsKey(symbol)) //Not neccessary, c++ can pass by ref // { // writer.Write("(*"); // writer.Write(TransformIdentifier(identifier.Identifier.ToString())); // writer.Write(")"); // } // else // { var binExpression = identifier.Parent as BinaryExpressionSyntax; string memberName = TransformIdentifier(identifier.Identifier.ToString()); if (symbol.Kind == SymbolKind.Property) // Using dlang properties { if (symbol.ContainingType.TypeKind == TypeKind.Interface || Equals(symbol.ContainingType.FindImplementationForInterfaceMember(symbol), symbol)) { memberName = Regex.Replace( TypeProcessor.ConvertType(symbol.ContainingType.OriginalDefinition) .RemoveFromStartOfString(symbol.ContainingNamespace + ".Namespace.") + "_" + memberName, @" ?!\(.*?\)", string.Empty); } var interfaceMethods = symbol.ContainingType.AllInterfaces.SelectMany( u => u.GetMembers(memberName)).ToArray(); ISymbol interfaceMethod = interfaceMethods.FirstOrDefault( o => symbol.ContainingType.FindImplementationForInterfaceMember(o) == symbol); // 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 (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 + "_"); } } // var closeBraces = binExpression != null && binExpression.IsKind(SyntaxKind.SimpleAssignmentExpression) && binExpression.Left == identifier?"()" :""; // if (binExpression != null && binExpression.OperatorToken.RawKind == (decimal) SyntaxKind.EqualsToken) // { // // writer.Write("set_" + memberName + closeBraces); // // } // else // { // writer.Write("get_" + memberName+ closeBraces); // // } } // else { writer.Write(memberName); } // } }
private static void WriteOutOneType(OutputWriter parentModuleWriter, Context.SyntaxAndSymbol[] typeSymbols, bool fileExists) { TypeProcessor.ClearUsedTypes(); var mynamespace = Context.Instance.Type.ContainingNamespace.FullName().RemoveFromEndOfString(".Namespace"); var fullname = Context.Instance.Namespace + "." + Context.Instance.TypeName; if (TypeRenames.ContainsKey(fullname)) { Context.Instance.TypeName = TypeRenames[fullname]; } // + "." + TypeState.Instance.TypeName; // if (Driver.Verbose) // Console.WriteLine("Writing out type: " + fullname); if (fullname.StartsWith( "System.Collections.Generic.Dictionary")) { } var myUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(mynamespace)); var SystemUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System")); // Required as certain functions like boxing are in this namespace var namespaces = typeSymbols.First().Syntax.Parent.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray(); var usingStatements = typeSymbols.First().Syntax.Parent.DescendantNodes().OfType <UsingStatementSyntax>().ToArray(); var allTypeAliases = typeSymbols.First().Syntax.DescendantNodes().OfType <QualifiedNameSyntax>().ToArray(); Context.Instance.UsingDeclarations = namespaces .Union(new[] { myUsingDirective, SystemUsingDirective }).ToArray(); TypeProcessor.AddAlias(Context.Instance.Type.ContainingNamespace as INamespaceSymbol, Context.Instance.Type.ContainingNamespace.GetModuleName()); foreach (var ns in namespaces) { //TODO: Add support for type aliases ... var symbol = TypeProcessor.GetSymbolInfo(ns.Name).Symbol; if (allTypeAliases.All(o => TypeProcessor.GetSymbolInfo(o.Left).Symbol != symbol)) { TypeProcessor.AddAlias(symbol as INamespaceSymbol, (symbol as INamespaceSymbol).GetModuleName()); } } var aliases = allTypeAliases.DistinctBy(j => TypeProcessor.GetSymbolInfo(j.Left)); foreach (var alias in aliases) { var left = alias.Left; var type = TypeProcessor.GetSymbolInfo(left).Symbol as INamespaceSymbol; var name = left.ToString(); if (type != null && type.ToString() != name) { TypeProcessor.AddAlias(type, name); } } OutputWriter writer = null; using ( writer = parentModuleWriter == null ? new OutputWriter(Context.Instance.Namespace, Context.Instance.TypeName) : new TempWriter()) { writer.FileExists = fileExists; if (parentModuleWriter != null) { writer.WriteLine(); writer.Indent = parentModuleWriter.Indent + 2; writer.WriteIndent(); } var bases = new List <ITypeSymbol>(); var baselist = typeSymbols.Select(k => k.Syntax.As <BaseTypeDeclarationSyntax>()).Select(o => o.BaseList).Where(k => k != null).ToArray(); if (baselist.Any()) { bases = baselist.SelectMany(k => k.Types) .Select(o => TypeProcessor.GetTypeInfo(o.Type).ConvertedType ?? TypeProcessor.GetTypeInfo(o.Type).Type) .Where(k => k != null) .Distinct() .ToList(); } // var interfaces = bases.Where(o => o.TypeKind == TypeKind.Interface).ToList(); if (Context.Instance.Type != Context.Object) { if (bases != null && (!bases.Any((j => j.TypeKind != TypeKind.Interface)) && !(typeSymbols.First().Symbol.TypeKind == TypeKind.Interface || typeSymbols.First().Symbol.TypeKind == TypeKind.Struct))) { //TODO: fix structs using mixins / alias this bases.Add(Context.Object); } } if (bases == null) { bases = new List <ITypeSymbol>(); } foreach (var type in bases) { TypeProcessor.AddUsedType(type); } //TODO: Fix enum support if (typeSymbols.First().Syntax is EnumDeclarationSyntax) { WriteEnum.Go(writer, Context.Instance.Partials.Select(o => o.Syntax) .Cast <EnumDeclarationSyntax>() .SelectMany(o => o.Members) .Where(o => !Program.DoNotWrite.ContainsKey(o))); if (parentModuleWriter != null) { parentModuleWriter.Write(writer.ToString()); } return; } Context.Instance.AllMembers = typeSymbols.Select(k => k.Syntax.As <TypeDeclarationSyntax>()).SelectMany(o => o.Members) .Where(o => !Program.DoNotWrite.ContainsKey(o)) .ToList(); var allMembersToWrite = Context.Instance.AllMembers .Where(member => !(member is TypeDeclarationSyntax) && !(member is EnumDeclarationSyntax) && !(member is DelegateDeclarationSyntax) && !(member is ConstructorDeclarationSyntax)) .ToList(); Context.Instance.MemberNames = allMembersToWrite.Select(k => k.GetCSharpName()).ToList(); if (Context.Instance.Type.ContainingType != null) { Context.Instance.MemberNames.AddRange(Context.Instance.Type.ContainingType.MemberNames); } { // WriteStandardIncludes.Go(writer); // writer.WriteLine(String.Format("#include \"{0}\"", TypeState.Instance.TypeName + ".h")); WriteBcl.Go(writer); //TypeState.Instance.DerivesFromObject = bases.Count == interfaces.Count; var @namespace = typeSymbols.First().Symbol.ContainingNamespace.FullName(); var genericArgs = Context.Instance.Type.TypeParameters.Select(l => l as ITypeSymbol).ToList(); //Module name = namespace + "." + typename; WriteStandardIncludes.Go(writer); // var namespaces = @namespace.Split(new string[] { "." }, StringSplitOptions.None); // // if (@namespace.Length > 0) // { // foreach (var ns in namespaces) // { // writer.WriteLine("namespace " + ns + "\r\n{"); // writer.WriteLine("namespace " + ns + "\r\n{"); // } // // } var instanceCtors = Context.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>() .Where(o => !o.Modifiers.Any(SyntaxKind.StaticKeyword)) .ToList(); var staticCtors = Context.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>() .Where(o => (o.Modifiers.Any(SyntaxKind.StaticKeyword))) .ToList(); //TODO: Add support for overloading constructing // if (instanceCtors.Count > 1) // throw new Exception( // "Overloaded constructors are not supported. Consider changing all but one to static Create methods " + // Utility.Descriptor(first.Syntax)); // var ctorOpt = instanceCtors.SingleOrDefault(); //TODO: Handle interfaces by /* * class Interface * { * public: * virtual ~Interface() { } * virtual void test() = 0; // Functions, must all be virtual * } */ var membersToWrite = allMembersToWrite.ToList(); //.Where(o => IsStatic(o) == staticMembers).ToList(); // if (membersToWrite.Count == 0 && (partials.Any(o => o.Syntax.Modifiers.Any(SyntaxKind.StaticKeyword)))) // continue; // if (staticMembers) // writer.Write("object "); // else if (first.Syntax.Kind == SyntaxKind.InterfaceDeclaration) // writer.Write("trait "); // else // { // if (partials.Any(o => o.Syntax.Modifiers.Any(SyntaxKind.AbstractKeyword))) // writer.Write("abstract "); // } // writer.Write(TypeState.Instance.TypeName); if (typeSymbols.First().Syntax is TypeDeclarationSyntax) { //Internal classes/structs are declared static in D to behave correctly if (parentModuleWriter != null) { writer.Write("static "); } if (Context.Instance.Type.TypeKind == TypeKind.Class) { writer.Write("class "); } else if (Context.Instance.Type.TypeKind == TypeKind.Interface) { writer.Write("interface "); } else if (Context.Instance.Type.TypeKind == TypeKind.Struct) { writer.Write("struct "); // writer.Write (" class "); // Allows inheritance ... but too many issues, will look at this when it gets relevant } else { throw new Exception("don't know how to write type: " + Context.Instance.Type.TypeKind); } List <ITypeSymbol> parentTypeParameters; if (Context.Instance.Type.ContainingType != null) { parentTypeParameters = GetParentTypeParameters(Context.Instance.Type); } else { parentTypeParameters = new List <ITypeSymbol>(); } writer.Write(TypeName(Context.Instance.Type, false)); //TypeProcessor.ConvertType(Context.Instance.Type, true, false,true)); if (Context.Instance.Type.IsGenericType) { { foreach (var @base in bases) { var namedTypeSymbol = @base as INamedTypeSymbol; if (namedTypeSymbol != null) { foreach (var arg in namedTypeSymbol.TypeArguments) { if (arg.TypeKind == TypeKind.TypeParameter && !parentTypeParameters.Contains(arg)) { if (!genericArgs.Any(k => k.Name == arg.Name)) { genericArgs.Add(arg); } } } } } if (genericArgs.Any()) { writer.Write("(" + string.Join(" , ", genericArgs.Select(o => TypeProcessor.ConvertType(o, true, true, false))) + ")"); } } } bool firstBase = true; if (Context.Instance.Type.TypeKind != TypeKind.Struct) { foreach (var baseType in bases.OrderBy(o => o.TypeKind == TypeKind.Interface ? 1 : 0)) { var convertType = TypeProcessor.ConvertType(baseType); writer.Write(firstBase ? " : " : " ,"); writer.Write(convertType); firstBase = false; } } string constraints = GetTypeConstraints((TypeDeclarationSyntax)typeSymbols.First().Syntax); writer.Write(constraints); } writer.WriteLine(); writer.OpenBrace(); var nonFields = WriteFields(membersToWrite, typeSymbols.First(), writer); foreach (var member in nonFields) { // writer.WriteLine(); Core.Write(writer, member); } WriteConstructors(instanceCtors, writer); WriteStaticConstructors(staticCtors, writer); //PInvoke is now centralized, so we can call it on all libraries etc without issue writer.Indent--; WriteOutNestedTypes(typeSymbols.First(), writer); var methodSymbols = membersToWrite.OfType <MethodDeclarationSyntax>().Select(TypeProcessor.GetDeclaredSymbol); //TypeProcessor.GetDeclaredSymbol(method); if (!methodSymbols.OfType <IMethodSymbol>() .Any(k => k.Name == "ToString" && k.Parameters.Length == 0 && k.ReturnType == Context.String)) { if (Context.Instance.Type.TypeKind == TypeKind.Struct || (Context.Instance.Type.TypeKind == TypeKind.Class)) { var overrideS = Context.Instance.Type.TypeKind == TypeKind.Struct ? "" : "override "; writer.WriteLine(); writer.WriteLine("public " + overrideS + "String ToString()"); writer.OpenBrace(); writer.WriteLine("return GetType().FullName;");//Better names based on specialization writer.CloseBrace(); } } WriteOutBoxed(writer, genericArgs, bases); } if (Context.Instance.Type.TypeKind == TypeKind.Struct) { writer.WriteLine(); writer.WriteLine("public __Boxed_ __Get_Boxed()"); writer.OpenBrace(); writer.WriteLine("return new __Boxed_(this);"); writer.CloseBrace(); writer.WriteLine("alias __Get_Boxed this;"); } if (Context.Instance.Type.TypeKind != TypeKind.Interface) { writer.WriteLine(); if (Context.Instance.Type.TypeKind == TypeKind.Class) { writer.WriteLine("public override Type GetType()"); } // else if (Context.Instance.Type.TypeKind == TypeKind.Interface) // Messes with GetType overrides of objects // { // writer.WriteLine ("public final Type GetType()"); // } else if (Context.Instance.Type.TypeKind == TypeKind.Struct) { writer.WriteLine("public Type GetType()"); } writer.OpenBrace(); //if (Context.Instance.Type.TypeKind == TypeKind.Class) writer.WriteLine("return __TypeOf!(typeof(this));"); // else // writer.WriteLine("return __TypeOf!(__Boxed_);"); writer.CloseBrace(); } writer.CloseBrace(); WriteEntryMethod(writer); if (parentModuleWriter != null) { writer.Finalize(); parentModuleWriter.Write(writer.ToString()); } } }
public static bool IsConst(SyntaxTokenList modifiers, EqualsValueClauseSyntax initializerOpt, TypeSyntax type) { var t = TypeProcessor.ConvertType(type); return(modifiers.Any(SyntaxKind.ConstKeyword)); }
private static void WriteOutBoxed(OutputWriter writer, List <ITypeSymbol> genericArgs, List <ITypeSymbol> bases) { //Implement Boxed!T if (Context.Instance.Type.TypeKind == TypeKind.Struct) { writer.WriteLine(); var typeName = TypeProcessor.ConvertType(Context.Instance.Type); /*TypeName(Context.Instance.Type, false) + * (Context.Instance.Type.IsGenericType && genericArgs.Any() * ? ("!(" + string.Join(" , ", genericArgs.Select(o => o)) + ")") * : "");*/ var baseString = ""; foreach (var baseType in bases.OrderBy(o => o.TypeKind == TypeKind.Interface ? 1 : 0)) { baseString += (" ,"); baseString += (TypeProcessor.ConvertType(baseType, false)); } 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)) { members.AddRange(Utility.GetAllMembers(baseType)); } // 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 findImplementationForInterfaceMember = Context.Instance.Type.FindImplementationForInterfaceMember(member); if (findImplementationForInterfaceMember == null) { continue; } var ifacemethod = findImplementationForInterfaceMember .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); } } // { // writer.WriteLine("public override String ToString()"); // writer.OpenBrace(); // writer.WriteLine("return __Value.ToString();", Program.GetGenericMetadataName(Context.Instance.Type)); // writer.CloseBrace(); // } //} //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({0}.init);", typeName); //TODO fix this for another TypeNew that calls the valuetype constructor only writer.CloseBrace(); // if (Context.Instance.Type.GetMembers("ToString").Any()) // Use better matching ? { // writer.WriteLine (); writer.WriteLine("public 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(); } }
public static void Go(OutputWriter writer, MemberDeclarationSyntax field, SyntaxTokenList modifiers, string name, TypeSyntax type, EqualsValueClauseSyntax initializerOpt = null) { writer.WriteIndent(); var typeinfo = TypeProcessor.GetTypeInfo(type); // var isPtr = typeinfo.Type != null && (typeinfo.Type.IsValueType || typeinfo.Type.TypeKind==TypeKind.TypeParameter) ? "" : ""; var typeStringNoPtr = TypeProcessor.ConvertType(type); var typeString = typeStringNoPtr + " "; var isConst = IsConst(modifiers, initializerOpt, type); var isStatic = isConst; //Handle Auto Properties if (modifiers.Any(SyntaxKind.PrivateKeyword)) { writer.Write("private "); } if (modifiers.Any(SyntaxKind.PublicKeyword) || modifiers.Any(SyntaxKind.InternalKeyword) || modifiers.Any(SyntaxKind.ProtectedKeyword) || modifiers.Any(SyntaxKind.AbstractKeyword)) { writer.Write("public "); } if (modifiers.Any(SyntaxKind.StaticKeyword) || modifiers.Any(SyntaxKind.ConstKeyword)) { isStatic = true; writer.Write("static "); } if (isConst) { writer.Write("const "); // writer.Write("const "); } var @event = field is EventFieldDeclarationSyntax; if (@event) { typeString = ("Event!(" + typeString + ")"); } writer.Write(typeString); // if (isStatic) // writer.Write(typeString); writer.Write(name); if (isStatic) { // var fieldInfo = TypeProcessor.GetDeclaredSymbol(field.Parent); // if (fieldInfo != null) // writer.Write((!string.IsNullOrEmpty(fieldInfo.ContainingNamespace.FullName())?(fieldInfo.ContainingNamespace.FullName()+".") :"") + fieldInfo.Name+"."+name); // writer.Write(name); } if (!isStatic || isConst) { if (initializerOpt != null) { writer.Write(" = "); if (CSharpExtensions.CSharpKind(initializerOpt.Value) == SyntaxKind.CollectionInitializerExpression || CSharpExtensions.CSharpKind(initializerOpt.Value) == SyntaxKind.ArrayInitializerExpression) { // writer.Write("gc::gc_ptr< " + typeStringNoPtr + " >("); writer.Write(" new " + typeString + " ("); var intializer = initializerOpt.Value as InitializerExpressionSyntax; intializer.WriteArrayInitializer(writer, type); writer.Write(")"); } else { Core.Write(writer, initializerOpt.Value); } } else { if (typeinfo.Type.TypeKind != TypeKind.Struct) { writer.Write(" = "); if (typeinfo.Type.TypeKind == TypeKind.Delegate) { writer.Write("new " + typeString + "()"); } else { writer.Write(TypeProcessor.DefaultValue(type)); } } } } else { var staticWriter = new OutputWriter("", "", false); if (initializerOpt != null) { staticWriter.Write(name); staticWriter.Write(" = "); if (CSharpExtensions.CSharpKind(initializerOpt.Value) == SyntaxKind.CollectionInitializerExpression || CSharpExtensions.CSharpKind(initializerOpt.Value) == SyntaxKind.ArrayInitializerExpression) { staticWriter.Write("new " + typeStringNoPtr + " ("); var intializer = initializerOpt.Value as InitializerExpressionSyntax; intializer.WriteArrayInitializer(staticWriter, type); staticWriter.Write(")"); } else { Core.Write(staticWriter, initializerOpt.Value); } // if (CSharpExtensions.CSharpKind(initializerOpt.Value) == SyntaxKind.CollectionInitializerExpression || CSharpExtensions.CSharpKind(initializerOpt.Value) == SyntaxKind.ArrayInitializerExpression) // { // // // staticWriter.Write("])"); // } } else if (typeinfo.Type.TypeKind != TypeKind.Struct) { staticWriter.Write(name); staticWriter.Write(" = "); if (typeinfo.Type.TypeKind == TypeKind.Delegate) { staticWriter.Write("new " + typeString + "()"); } else { staticWriter.Write(TypeProcessor.DefaultValue(type)); } } // staticWriter.Write (" SharpNative"); staticWriter.Write(";"); staticWriter.WriteLine(); Context.Instance.StaticInits.Add(staticWriter.ToString()); } writer.Write(";"); writer.WriteLine(); }
public static void WriteAnonymousType(AnonymousObjectCreationExpressionSyntax syntax) { var type = TypeProcessor.GetTypeInfo(syntax).Type.As <INamedTypeSymbol>(); Context.Instance.Type = type; TypeProcessor.ClearUsedTypes(); var mynamespace = Context.Instance.Type.ContainingNamespace.FullName().RemoveFromEndOfString(".Namespace"); // + "." + TypeState.Instance.TypeName; Context.Instance.Namespace = mynamespace; 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 = syntax.Parent.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray() .Union(new[] { myUsingDirective, SystemUsingDirective }).ToArray(); //using (var writer = new CppWriter (TypeState.Instance.Namespace, )) { //Ty var anonName = TypeName(type); using (var writer = new OutputWriter(Context.Instance.Namespace, StripGeneric(anonName))) { var fields = type.GetMembers().OfType <IPropertySymbol>().OrderBy(o => o.Name).ToList(); // writer.WriteLine("namespace anonymoustypes {"); WriteStandardIncludes.Go(writer); writer.WriteIndent(); writer.Write("class "); writer.Write(anonName); writer.OpenBrace(); foreach (var field in fields) { writer.WriteIndent(); writer.Write("public "); writer.Write(TypeProcessor.ConvertType(field.Type) + " "); writer.Write(WriteIdentifierName.TransformIdentifier(field.Name)); writer.Write(" = " + TypeProcessor.DefaultValue(field.Type)); writer.Write(";\r\n"); } //Must Write a constructor here ... writer.Write("\r\nthis ("); bool first = true; foreach (var field in fields) { if (first) { first = false; } else { writer.Write(", "); } writer.Write(TypeProcessor.ConvertType(field.Type) + " "); writer.Write("_" + WriteIdentifierName.TransformIdentifier(field.Name)); } writer.Write(")\r\n"); writer.OpenBrace(); writer.Indent++; foreach (var field in fields) { var fieldNAme = WriteIdentifierName.TransformIdentifier(field.Name); writer.WriteLine(fieldNAme + " = _" + fieldNAme + ";"); } writer.Indent--; writer.CloseBrace(); writer.CloseBrace(); // writer.Write("};"); // writer.Write("}"); } }
public static void Go(OutputWriter writer, IndexerDeclarationSyntax property) { // writer.WriteLine ("\r\n"); var rEf = ""; //" ref ";// ref should be used based on analysis, is the return type a single var or not //TODO, doesnt ref make things slower ?, though it makes proprties behave as in c# var isInterface = property.Parent is InterfaceDeclarationSyntax; var getter = property.AccessorList.Accessors.SingleOrDefault( o => o.Keyword.RawKind == (decimal)SyntaxKind.GetKeyword); var setter = property.AccessorList.Accessors.SingleOrDefault( o => o.Keyword.RawKind == (decimal)SyntaxKind.SetKeyword); var methodSymbol = (TypeProcessor.GetDeclaredSymbol(getter) ?? TypeProcessor.GetDeclaredSymbol(setter)) as IMethodSymbol; Action <AccessorDeclarationSyntax, bool> writeRegion = (region, get) => { var typeinfo = TypeProcessor.GetTypeInfo(property.Type); var isPtr = ""; var typeString = TypeProcessor.ConvertType(property.Type) + isPtr + " "; if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || region.Body == null) { writer.Write(" abstract "); } if (property.Modifiers.Any(SyntaxKind.OverrideKeyword)) { writer.Write(" override "); } //TODO: look at final and other optimizations //no inline in D if (get) { writer.Write(rEf + typeString + " "); } else { writer.Write("void "); } var methodName = (get ? "opIndex" : "opIndexAssign"); var explicitHeaderNAme = ""; if (methodSymbol != null && methodSymbol.MethodKind == MethodKind.ExplicitInterfaceImplementation) { var implementations = methodSymbol.ExplicitInterfaceImplementations[0]; if (implementations != null) { explicitHeaderNAme = implementations.Name; methodName = //implementations.ReceiverType.FullName() + "." + implementations.Name; //Explicit fix ? // writer.Write(methodSymbol.ContainingType + "." + methodName); //Looks like internal classes are not handled properly here ... } } if (methodSymbol != null) { // methodName = methodName.Replace(methodSymbol.ContainingNamespace.FullName() + ".", methodSymbol.ContainingNamespace.FullName() + "."); // writer.Write((methodSymbol.ContainingType.FullName() + "." + methodName) + (get ? "()" : "( " + typeString + " value )")); //Dealting with explicit VMT7 } if (property.Modifiers.Any(SyntaxKind.NewKeyword)) { methodName += "_"; } var parameters = GetParameterList(methodSymbol.Parameters); writer.Write((!String.IsNullOrEmpty(explicitHeaderNAme) ? explicitHeaderNAme : methodName) + "( " + (get ? "" : (typeString + " value, ")) + parameters + " )"); if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || region.Body == null) { writer.Write(";\r\n"); } else { writer.OpenBrace(); Core.WriteBlock(writer, region.Body.As <BlockSyntax>()); writer.CloseBrace(); writer.Write("\r\n"); } }; if (getter == null && setter == null) { throw new Exception("Property must have either a get or a set"); } { // var name = WriteIdentifierName.TransformIdentifier (property..ValueText); var type = property.Type; var typeinfo = TypeProcessor.GetTypeInfo(type); var modifiers = property.Modifiers; var isPtr = typeinfo.Type != null && (typeinfo.Type.IsValueType || typeinfo.Type.TypeKind == TypeKind.TypeParameter) ? "" : ""; var typeString = TypeProcessor.ConvertType(type) + isPtr + " "; var isStatic = false; var acccessmodifiers = ""; if (modifiers.Any(SyntaxKind.PrivateKeyword)) { acccessmodifiers += ("private "); } if (modifiers.Any(SyntaxKind.PublicKeyword) || modifiers.Any(SyntaxKind.InternalKeyword) || modifiers.Any(SyntaxKind.ProtectedKeyword) || modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface) { acccessmodifiers += ("public "); } var IsStatic = ""; if (modifiers.Any(SyntaxKind.StaticKeyword)) { isStatic = true; IsStatic = "static "; acccessmodifiers += IsStatic; } //Auto Property // var isOverride = property.Modifiers.Any (SyntaxKind.NewKeyword) || // property.Modifiers.Any (SyntaxKind.OverrideKeyword) // ? " override " // : ""; // var isVirtual = //property.Modifiers.Any(SyntaxKind.VirtualKeyword) || // property.Modifiers.Any (SyntaxKind.AbstractKeyword) || isInterface // ? " abstract " // : ""; // if (!isInterface) //Getter if (getter != null) { writer.WriteIndent(); writer.Write(acccessmodifiers); writeRegion(getter, true); } //Setter if (setter != null) { writer.WriteIndent(); writer.Write(acccessmodifiers); writeRegion(setter, false); } } }
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); // } }
private static void ProcessExpression(OutputWriter writer, SyntaxToken operatorToken, CSharpSyntaxNode rightExpression, CSharpSyntaxNode leftExpression) { TypeInfo leftExpressionType = TypeProcessor.GetTypeInfo(leftExpression ?? rightExpression); var rightExpressionType = TypeProcessor.GetTypeInfo(rightExpression); var boxLeft = leftExpressionType.Type != null && (leftExpressionType.Type != leftExpressionType.ConvertedType) && ((leftExpressionType.Type.IsValueType || leftExpressionType.Type.TypeKind == TypeKind.TypeParameter) && (leftExpressionType.ConvertedType.IsReferenceType)); var boxRight = (rightExpressionType.ConvertedType != null && (rightExpressionType.Type != null && ((rightExpressionType.Type.IsValueType || rightExpressionType.Type.TypeKind == TypeKind.TypeParameter) && (rightExpressionType.ConvertedType.IsReferenceType)))) || (rightExpressionType.Type != null && rightExpressionType.Type.IsValueType && leftExpressionType.Type != null && leftExpressionType.Type.TypeKind == TypeKind.Error); //Fix for yield ... why does it give errortypes ? var unboxRight = rightExpressionType.ConvertedType != null && (rightExpressionType.Type != null && (rightExpressionType.Type.IsReferenceType && (rightExpressionType.ConvertedType.IsValueType))); var rightnull = rightExpression != null && rightExpression.ToFullString().Trim() == "null"; var leftnull = leftExpression != null && leftExpression.ToFullString().Trim() == "null"; var nullAssignment = (rightnull || leftnull); var val = WriteOperatorDeclaration.AllBinaryOperators.FirstOrDefault(k => k.Value == operatorToken.Text); //Matching Binary Operator Overload if (!String.IsNullOrEmpty(val.Value)) { //Try Left IEnumerable <ISymbol> members = new List <ISymbol>(); if (leftExpressionType.Type != null) { members = leftExpressionType.Type.GetMembers(val.Key); } if (rightExpressionType.Type != null) { members = members. Union(rightExpressionType.Type.GetMembers(val.Key)); } var leftExpressionString = Core.WriteString(leftExpression); if (members != null && members.Any()) { if (!(leftExpressionType.Type.IsPrimitive() && rightExpressionType.Type.IsPrimitive())) { var correctOverload = members.OfType <IMethodSymbol>() .FirstOrDefault( u => u.Parameters[0].Type == leftExpressionType.Type && u.Parameters[1].Type == rightExpressionType.Type); if (correctOverload != null) { var name = WriteIdentifierName.TransformIdentifier(OverloadResolver.MethodName(correctOverload)); writer.Write(TypeProcessor.ConvertType(correctOverload.ContainingType) + "." + name + "(" + leftExpressionString + "," + Core.WriteString(rightExpression) + ")"); return; } } } else { if (WriteOperatorDeclaration.AssignOpOperators.ContainsKey(val.Key)) { var methodName = WriteOperatorDeclaration.AllBinaryOperators.FirstOrDefault( k => k.Value == val.Value.Substring(0, 1)); // emulate c# facility to use the lower op ... //Try Left members = null; if (leftExpressionType.Type != null) { members = leftExpressionType.Type.GetMembers(methodName.Key); } if (rightExpressionType.Type != null) { members = members. Union(rightExpressionType.Type.GetMembers(methodName.Key)); } if (members != null && members.Any()) { if (!(leftExpressionType.Type.IsPrimitive() && rightExpressionType.Type.IsPrimitive())) { var correctOverload = members.OfType <IMethodSymbol>() .FirstOrDefault( u => u.Parameters[0].Type == leftExpressionType.Type && u.Parameters[1].Type == rightExpressionType.Type); if (correctOverload != null) { var name = WriteIdentifierName.TransformIdentifier( OverloadResolver.MethodName(correctOverload)); writer.Write(leftExpressionString + " = " + TypeProcessor.ConvertType(correctOverload.ContainingType) + "." + name + "(" + leftExpressionString + "," + Core.WriteString(rightExpression) + ")"); return; } } } } } } //Property calls will be fixed in a preprocessor step ... i.e. just call them if (nullAssignment) { if (rightnull) { switch (operatorToken.CSharpKind()) { case SyntaxKind.EqualsEqualsToken: writer.Write(""); break; case SyntaxKind.NotEqualsExpression: case SyntaxKind.ExclamationEqualsToken: writer.Write("!"); break; default: writer.Write(operatorToken.ToString()); break; } writer.Write("__IsNull("); Core.Write(writer, leftExpression); writer.Write(")"); return; } if (leftnull) { // writer.Write("null"); // // switch (operatorToken.CSharpKind()) // { // case SyntaxKind.EqualsEqualsToken: // writer.Write(" is "); // break; // case SyntaxKind.NotEqualsExpression: // case SyntaxKind.ExclamationEqualsToken: // writer.Write(" !is "); // break; // default: // writer.Write(operatorToken.ToString()); // break; // } // // Core.Write(writer, rightExpression); // // return; switch (operatorToken.CSharpKind()) { case SyntaxKind.EqualsEqualsToken: writer.Write(""); break; case SyntaxKind.NotEqualsExpression: case SyntaxKind.ExclamationEqualsToken: writer.Write("!"); break; default: writer.Write(operatorToken.ToString()); break; } writer.Write("__IsNull("); Core.Write(writer, rightExpression); writer.Write(")"); return; } } //Do we have an implicit converter, if so, use it if (leftExpressionType.Type != rightExpressionType.Type && rightExpressionType.Type != null) { 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, true); if (correctConverter == null) { useType = false; correctConverter = rightExpressionType.Type.GetImplicitCoversionOp(leftExpressionType.Type, rightExpressionType.Type, true); } if (correctConverter != null) { Core.Write(writer, leftExpression); writer.Write(operatorToken.ToString()); if (useType) { writer.Write(TypeProcessor.ConvertType(leftExpressionType.Type) + "." + "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_")); } else { writer.Write(TypeProcessor.ConvertType(rightExpressionType.Type) + "." + "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_")); } writer.Write("("); Core.Write(writer, rightExpression); writer.Write(")"); return; } } if (operatorToken.CSharpKind() == SyntaxKind.PlusEqualsToken || operatorToken.CSharpKind() == SyntaxKind.MinusEqualsToken) { var isname = rightExpression is NameSyntax; var nameexpression = rightExpression as NameSyntax; var ismemberexpression = rightExpression is MemberAccessExpressionSyntax || (isname && TypeProcessor.GetSymbolInfo(rightExpression as NameSyntax).Symbol.Kind == SymbolKind.Method); var isdelegateassignment = rightExpressionType.ConvertedType != null && (ismemberexpression && rightExpressionType.ConvertedType .TypeKind == TypeKind.Delegate); var memberaccessexpression = rightExpression as MemberAccessExpressionSyntax; var isstaticdelegate = isdelegateassignment && ((memberaccessexpression != null && TypeProcessor.GetSymbolInfo(memberaccessexpression).Symbol.IsStatic) || (isname && TypeProcessor.GetSymbolInfo(nameexpression).Symbol.IsStatic)); if (isdelegateassignment) { Core.Write(writer, leftExpression); writer.Write(operatorToken.ToString()); var typeString = TypeProcessor.ConvertType(rightExpressionType.ConvertedType); if (rightExpressionType.ConvertedType.TypeKind == TypeKind.TypeParameter) { writer.Write(" __TypeNew!(" + typeString + ")("); } else { writer.Write("new " + typeString + "("); } var isStatic = isstaticdelegate; // if (isStatic) // writer.Write("__ToDelegate("); MemberUtilities.WriteMethodPointer(writer, rightExpression); // if (isStatic) // writer.Write(")"); writer.Write(")"); return; } } if (leftExpressionType.Type == null || (rightExpressionType.Type == null && rightExpression != 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*/"); Core.Write(writer, leftExpression); switch (operatorToken.CSharpKind()) { case SyntaxKind.EqualsEqualsToken: writer.Write("!="); break; case SyntaxKind.NotEqualsExpression: writer.Write("=="); break; default: writer.Write(operatorToken.ToString()); break; } Core.Write(writer, rightExpression); } else { Core.Write(writer, leftExpression); if (operatorToken.CSharpKind() == SyntaxKind.EqualsEqualsToken) { writer.Write(" is "); } else if (operatorToken.CSharpKind() == SyntaxKind.ExclamationEqualsToken) { writer.Write(" !is "); } else { writer.Write(operatorToken.ToString()); } if (rightExpression != null) { Core.Write(writer, rightExpression); } } } else { writer.Write(boxLeft ? "BOX!(" + TypeProcessor.ConvertType(leftExpressionType.Type) + ")(" : ""); Core.Write(writer, leftExpression); writer.Write(boxLeft ? ")" : ""); writer.Write(operatorToken.ToString()); if (rightExpression != null) { writer.Write(unboxRight ? "UNBOX!(" + TypeProcessor.ConvertType(rightExpressionType.ConvertedType) + ")(" : ""); writer.Write(boxRight ? "BOX!(" + TypeProcessor.ConvertType(rightExpressionType.Type) + ")(" : ""); Core.Write(writer, rightExpression); writer.Write(boxRight ? ")" : ""); writer.Write(unboxRight ? ")" : ""); } } }
public static void Go(OutputWriter writer, PropertyDeclarationSyntax property, bool isProxy = false) { writer.WriteLine(); //var rEf = "";//" ref ";// ref should be used based on analysis, is the return type a single var or not //TODO, doesnt ref make things slower ?, though it makes proprties behave as in c# var isInterface = property.Parent is InterfaceDeclarationSyntax; var getter = property.AccessorList.Accessors.SingleOrDefault( o => o.Keyword.RawKind == (decimal)SyntaxKind.GetKeyword); var setter = property.AccessorList.Accessors.SingleOrDefault( o => o.Keyword.RawKind == (decimal)SyntaxKind.SetKeyword); var methodSymbol = TypeProcessor.GetDeclaredSymbol(property); var name = WriteIdentifierName.TransformIdentifier(property.Identifier.ValueText); if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface) { isInterface = true; } if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface || Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol), methodSymbol)) { name = Regex.Replace( TypeProcessor.ConvertType(methodSymbol.ContainingType.ConstructedFrom) + "_" + name, @" ?!\(.*?\)", string.Empty); } if (name.Contains(".")) // Explicit Interface method { // name = name.SubstringAfterLast('.'); name = name.Replace('.', '_'); } var interfaceMethods = methodSymbol.ContainingType.AllInterfaces.SelectMany( u => u.GetMembers(name)).ToArray(); ISymbol interfaceMethod = interfaceMethods.FirstOrDefault( o => methodSymbol.ContainingType.FindImplementationForInterfaceMember(o) == methodSymbol); if (interfaceMethod != null) { //This is an interface property //TO if (methodSymbol.ContainingType.SpecialType == SpecialType.System_Array) { writer.Write(""); } else { var typenameI = Regex.Replace(TypeProcessor.ConvertType(interfaceMethod.ContainingType.ConstructedFrom), @" ?!\(.*?\)", 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('.'); } name = (typenameI + "_") + name; } } Action <AccessorDeclarationSyntax, bool> writeRegion = (region, get) => { var accessString = ""; // var typeinfo = TypeProcessor.GetTypeInfo(property.Type); var isPtr = ""; var typeString = TypeProcessor.ConvertType(property.Type) + isPtr + " "; //no inline in D if (get) { writer.Write(typeString + " "); } else { writer.Write("void "); } var methodName = (get ? "" : "") + name; var explicitHeaderNAme = ""; if (property.Modifiers.Any(SyntaxKind.NewKeyword)) { methodName += "_"; } writer.Write((!String.IsNullOrEmpty(explicitHeaderNAme) ? explicitHeaderNAme : methodName) + (get ? "()" : "( " + typeString + " value )") + " @property"); if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || region.Body == null) { writer.Write(";\r\n"); } else { writer.WriteLine(); writer.OpenBrace(); Core.WriteBlock(writer, region.Body.As <BlockSyntax>(), false); writer.CloseBrace(); writer.WriteLine(); } }; if (getter == null && setter == null) { throw new Exception("Property must have either a get or a set"); } { var type = property.Type; var typeinfo = TypeProcessor.GetTypeInfo(type); var modifiers = property.Modifiers; var isPtr = ""; var typeString = TypeProcessor.ConvertType(type) + isPtr + " "; var isStatic = false; var acccessmodifiers = ""; if (modifiers.Any(SyntaxKind.PrivateKeyword)) { acccessmodifiers += ("private "); } if (modifiers.Any(SyntaxKind.PublicKeyword) || modifiers.Any(SyntaxKind.InternalKeyword) || modifiers.Any(SyntaxKind.ProtectedKeyword) || modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface) { acccessmodifiers += ("public "); } if (property.Modifiers.Any(SyntaxKind.AbstractKeyword)) { acccessmodifiers += "abstract "; } if (property.Modifiers.Any(SyntaxKind.OverrideKeyword) && !isInterface) { acccessmodifiers += "override "; } //TODO: look at final and other optimizations var IsStatic = ""; if (modifiers.Any(SyntaxKind.StaticKeyword)) { isStatic = true; IsStatic = "static "; acccessmodifiers += IsStatic; } //Auto Property var fieldName = "__prop_" + name; var isOverride = (property.Modifiers.Any(SyntaxKind.NewKeyword) || property.Modifiers.Any(SyntaxKind.OverrideKeyword)) && !isInterface ? " override " : ""; // var isVirtual = //property.Modifiers.Any(SyntaxKind.VirtualKeyword) || // property.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface // ? " abstract " // : ""; if (!isInterface) // Auto property { if ((getter != null && getter.Body == null) && (setter != null && setter.Body == null) && (!property.Modifiers.Any(SyntaxKind.AbstractKeyword))) { writer.WriteLine("private " + typeString + fieldName + ";"); } } if (getter != null && isProxy) { writer.WriteLine(acccessmodifiers + isOverride + typeString + "" + name + "() " + "@property " + "{ return Value." + name + ";}"); } else //Getter if (getter != null && getter.Body == null) { if (isProxy) { } else if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface) { writer.WriteLine(acccessmodifiers + typeString + " " + name + "()" + isOverride + " @property;"); } else { writer.WriteLine(acccessmodifiers + isOverride + typeString + "" + name + "() " + "@property " + "{ return " + fieldName + ";}"); } } else if (getter != null) { writer.WriteIndent(); writer.Write(acccessmodifiers); writeRegion(getter, true); } if (setter != null && isProxy) { writer.WriteLine(acccessmodifiers + " void " + name + "(" + typeString + " value) @property" + isOverride + " { Value." + name + " = value;}"); } else //Setter if (setter != null && setter.Body == null) { if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface) { writer.WriteLine(acccessmodifiers + " void " + name + "(" + typeString + " value)" + isOverride + "" + " @property;"); } else { writer.WriteLine(acccessmodifiers + " void " + name + "(" + typeString + " value) @property" + isOverride + " {" + fieldName + " = value;}"); } } else if (setter != null) { writer.WriteIndent(); writer.Write(acccessmodifiers); writeRegion(setter, false); } } }
public static void Go(OutputWriter writer, ReturnStatementSyntax statement) { var slambda = statement.Ancestors().OfType <SimpleLambdaExpressionSyntax>().FirstOrDefault(); var plambda = statement.Ancestors().OfType <ParenthesizedLambdaExpressionSyntax>().FirstOrDefault(); var mlambda = statement.Ancestors().OfType <AnonymousMethodExpressionSyntax>().FirstOrDefault(); var method = statement.Ancestors().OfType <MethodDeclarationSyntax>().FirstOrDefault(); var property = statement.Ancestors().OfType <PropertyDeclarationSyntax>().FirstOrDefault(); var indexer = statement.Ancestors().OfType <IndexerDeclarationSyntax>().FirstOrDefault(); var converter = statement.Ancestors().OfType <ConversionOperatorDeclarationSyntax>().FirstOrDefault(); var @operator = statement.Ancestors().OfType <OperatorDeclarationSyntax>().FirstOrDefault(); ITypeSymbol returnTypeSymbol = null; if (method != null) { returnTypeSymbol = TypeProcessor.GetTypeInfo(method.ReturnType).Type; } if (property != null) { returnTypeSymbol = TypeProcessor.GetTypeInfo(property.Type).Type; } if (indexer != null) { returnTypeSymbol = TypeProcessor.GetTypeInfo(indexer.Type).Type; } if (converter != null) { returnTypeSymbol = TypeProcessor.GetTypeInfo(converter.Type).Type; } if (@operator != null) { returnTypeSymbol = TypeProcessor.GetTypeInfo(@operator.ReturnType).Type; } if (plambda != null) { returnTypeSymbol = TypeProcessor.GetTypeInfo(plambda).Type; } if (slambda != null) { returnTypeSymbol = TypeProcessor.GetTypeInfo(slambda).Type; } if (mlambda != null) { returnTypeSymbol = TypeProcessor.GetTypeInfo(statement.Expression).ConvertedType; } writer.WriteIndent(); writer.Write("return"); if (statement.Expression != null) { { var rightExpressionType = TypeProcessor.GetTypeInfo(statement.Expression); var boxRight = rightExpressionType.ConvertedType != null && (rightExpressionType.Type != null && (rightExpressionType.Type != rightExpressionType.ConvertedType) && ((rightExpressionType.Type.IsValueType || rightExpressionType.Type.TypeKind == TypeKind.TypeParameter) && (rightExpressionType.ConvertedType.IsReferenceType))); boxRight = boxRight && (rightExpressionType.Type != returnTypeSymbol); if (!boxRight && returnTypeSymbol != Context.Object) { if (!Equals(returnTypeSymbol, rightExpressionType.Type) && !rightExpressionType.Type.IsSubclassOf(returnTypeSymbol)) { writer.Write(" cast(" + TypeProcessor.ConvertType(returnTypeSymbol) + ")"); } } writer.Write(boxRight ? " BOX!(" + TypeProcessor.ConvertType(rightExpressionType.Type) + ")(" : " "); Core.Write(writer, statement.Expression); writer.Write(boxRight ? ")" : ""); } } writer.Write(";\r\n"); }
public void Write(OutputWriter writer) { if (StringOpt != null) { writer.Write(StringOpt); } else { if (ArgumentOpt.NameColon != null) { Core.Write(writer, ArgumentOpt.NameColon.Name); writer.Write(" = "); } var symbol = TypeProcessor.GetSymbolInfo(ArgumentOpt.Expression); var type = TypeProcessor.GetTypeInfo(ArgumentOpt.Expression); if (symbol.Symbol != null && type.ConvertedType != null && symbol.Symbol.Kind == SymbolKind.Method && type.ConvertedType.TypeKind == TypeKind.Delegate) { var typeString = TypeProcessor.ConvertType(type.ConvertedType); var createNew = !(ArgumentOpt.Parent.Parent is ObjectCreationExpressionSyntax); //Ugly hack if (createNew) { if (type.ConvertedType.TypeKind == TypeKind.TypeParameter) { writer.Write(" __TypeNew!(" + typeString + ")("); } else { writer.Write("new " + typeString + "("); } } var isStatic = symbol.Symbol.IsStatic; if (isStatic) { writer.Write("__ToDelegate("); } writer.Write("&"); Core.Write(writer, ArgumentOpt.Expression); if (isStatic) { writer.Write(")"); } if (createNew) { writer.Write(")"); } return; } Core.Write(writer, ArgumentOpt.Expression); WriteEnum.Check(ArgumentOpt.Expression); } }
private static void WriteSetter(OutputWriter writer, bool isProxy, bool hasSetter, string acccessmodifiers, string name, string typeString, ITypeSymbol iface, string isOverride, bool setterHasBody, SyntaxTokenList modifiers, bool isInterface, string fieldName, string setterbody, string parameters, bool isindexer, bool hasGetter) { if (isindexer) { name = "opIndexAssign"; } var args = _set; if (hasSetter && isProxy) { if (!isindexer) { writer.WriteLine(string.Format("{0} {2} {5}{1}({2} value{3}{4}){4} {{ __Value.{1} = value; return value;}}", acccessmodifiers, name, hasGetter ? typeString : "void", (iface != null ? ("," + TypeProcessor.ConvertType(iface) + " __ig=null") : ""), isOverride, args)); } else { writer.WriteLine(string.Format("{0} {2} {1}({2} value,{3}{4}) {4} {{ __Value.{1} = value;return value;}}", acccessmodifiers, name, typeString, parameters, isOverride)); } } else if (hasSetter && !setterHasBody) //Setter { if (modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface) { if (!isindexer) { writer.WriteLine(string.Format("{0} {2} {5}{1}({2} value{3}{4});", acccessmodifiers, name, hasGetter ? typeString : "void", (iface != null ? ("," + TypeProcessor.ConvertType(iface) + " __ig=null") : ""), isOverride, args)); } else { writer.WriteLine(string.Format("{0} {2} {1}({2} value,{3}{4});", acccessmodifiers, name, typeString, parameters, isOverride)); } } else { if (!isindexer) { var returnValue = hasGetter ? writer.WriteIndentToString() + "return value;" :""; writer.WriteLine(string.Format("{0} {2} {6}{1}({2} value{3}){4} {{{5} = value;{7}}}", acccessmodifiers, name, hasGetter?typeString :"void", (iface != null ? ("," + TypeProcessor.ConvertType(iface) + " __ig=null") : ""), isOverride, fieldName, args, returnValue)); } else { var returnValue = hasGetter ? writer.WriteIndentToString() + "return value;" : ""; writer.WriteLine(string.Format("{0} {2} {1}({2} value,{3}){4} {{{5} = value;{6}}}", acccessmodifiers, name, typeString, parameters, isOverride, fieldName, returnValue)); } } } else if (hasSetter) { writer.WriteIndent(); writer.Write(acccessmodifiers); WriteRegion(false, setterbody, iface, writer, typeString, name, modifiers, parameters, isindexer, hasGetter); } }
public static void Go(OutputWriter writer, string methodName, IMethodSymbol methodSymbol, AttributeSyntax pinvokeAttributes) { //Do Pinvoke stuff //PInvokeFunction < int (int, double)> foo(library, "foo"); //int i = foo(42, 2.0); // var methodParams = methodSymbol.Parameters.Any () ? methodSymbol.Parameters.Select (h => ConvertPInvokeType (h.Type)).Aggregate ((k, y) => (k) + " ," + y) : ""; var returnString = ConvertPInvokeType(methodSymbol.ReturnType); if (pinvokeAttributes != null) { var attributeArgumentSyntax = pinvokeAttributes.ArgumentList.Arguments.FirstOrDefault(k => k.Expression != null); string dllImport = attributeArgumentSyntax.ToFullString(); // AttributeSyntax import = // Context.Instance.DllImports.FirstOrDefault( // d => // d.ArgumentList.Arguments.FirstOrDefault( // k => // k.Expression != null && // k.Expression.ToString() == // pinvokeAttributes.ArgumentList.Arguments.FirstOrDefault(g => g.Expression != null) // .Expression.ToString()) != null); // if (import != null) // dllImportId = Context.Instance.DllImports.IndexOf(import); // // if (dllImportId == -1) // { // Context.Instance.DllImports.Add(pinvokeAttributes); // dllImportId = Context.Instance.DllImports.IndexOf(pinvokeAttributes); // } var functionCall = String.Format("extern (C) {0} function ({1})", returnString, GetParameterList(methodSymbol.Parameters)); writer.WriteLine("alias " + functionCall + " " + methodName + "_func_alias;"); var convertedParameters = ConvertParameters(methodSymbol.Parameters); if (attributeArgumentSyntax.Expression is IdentifierNameSyntax) { writer.WriteLine( String.Format("auto {1} = cast({2}) __LoadLibraryFunc(__DllImportMap[{0}.text], \"{1}\");", dllImport, methodName, methodName + "_func_alias")); } else { writer.WriteLine( String.Format("auto {1} = cast({2}) __LoadLibraryFunc(__DllImportMap[{0}], \"{1}\");", dllImport, methodName, methodName + "_func_alias")); } writer.WriteLine(String.Format((returnString != "void" ? "return " : "") + "{0}({1});", methodName, convertedParameters.Count > 0 ? convertedParameters.Select(h => h).Aggregate((k, y) => (k) + " ," + y) : "")); if (dllImport != null && !Context.Instance.DllImports.Contains(dllImport)) { var staticWriter = new TempWriter(); if (attributeArgumentSyntax.Expression is IdentifierNameSyntax) { staticWriter.WriteLine("__SetupDllImport({0}.text);", dllImport); } else { staticWriter.WriteLine("__SetupDllImport({0});", dllImport); } Context.Instance.StaticInits.Add(staticWriter.ToString()); Context.Instance.DllImports.Add(dllImport); } } else { var convertedParameters = ConvertParameters(methodSymbol.Parameters); writer.WriteLine("//Extern (Internal) Method Call"); var methodInternalName = TypeProcessor.ConvertType(methodSymbol.ContainingType, false).Replace(".Namespace.", "_").Replace(".", "_") + "_" + methodName; writer.WriteLine(String.Format((returnString != "void" ? "return " : "") + "{0}({1});", methodInternalName, convertedParameters.Count > 0 ? convertedParameters.Select(h => h).Aggregate((k, y) => (k) + " ," + y) : "")); } }