private static void WriteDelegateAssignment(OutputWriter writer, ITypeSymbol convertedType, bool isstaticdelegate, ExpressionSyntax value) { var typeString = TypeProcessor.ConvertType(convertedType); if (convertedType.TypeKind == TypeKind.TypeParameter) { writer.Write(" __TypeNew!(" + typeString + ")("); } else { writer.Write("new " + typeString + "("); } var isStatic = isstaticdelegate; // if (isStatic) // writer.Write("__ToDelegate("); MemberUtilities.WriteMethodPointer(writer, value); // if (isStatic) // writer.Write(")"); writer.Write(")"); return; }
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) //Not Needed, delegate class now supports functions directly // writer.Write("__ToDelegate("); MemberUtilities.WriteMethodPointer(writer, ArgumentOpt.Expression); // if (isStatic) // writer.Write(")"); if (createNew) { writer.Write(")"); } return; } Core.Write(writer, ArgumentOpt.Expression); } }
private static void ProcessInitializer(OutputWriter writer, VariableDeclarationSyntax declaration, VariableDeclaratorSyntax variable) { var initializer = variable.Initializer; if (initializer != null) { if (CSharpExtensions.CSharpKind(initializer.Value) == SyntaxKind.CollectionInitializerExpression) { return; } var value = initializer.Value; var initializerType = TypeProcessor.GetTypeInfo(value); var memberaccessexpression = value as MemberAccessExpressionSyntax; var nameexpression = value 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 is NameSyntax; var ismemberexpression = value is MemberAccessExpressionSyntax || (isname && TypeProcessor.GetSymbolInfo(value 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)); var shouldCast = initializerType.Type != initializerType.ConvertedType && initializerType.ConvertedType != null; if (nullAssignment) { if (initializerType.Type != null) //Nullable Support { if (initializerType.Type.Name == "Nullable") { var atype = TypeProcessor.ConvertType(initializerType.Type); writer.Write(atype + "()"); } } else { writer.Write("null"); } 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); writer.Write(")"); return; } if (shouldUnBox) { writer.Write("cast(" + TypeProcessor.ConvertType(initializerType.Type) + ")("); Core.Write(writer, value); writer.Write(")"); return; } if (initializer.Parent.Parent.Parent is FixedStatementSyntax) // Fixed is a bit special { //TODO write a better fix var type = TypeProcessor.GetTypeInfo(declaration.Type); writer.Write("cast(" + TypeProcessor.ConvertType(type.Type) + ")("); Core.Write(writer, value); writer.Write(")"); return; } if (isdelegateassignment) { var typeString = TypeProcessor.ConvertType(initializerType.ConvertedType); var createNew = !(value 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("); MemberUtilities.WriteMethodPointer(writer, value); // if (isStatic) // writer.Write(")"); if (createNew) { writer.Write(")"); } return; } if (initializerType.Type == null && initializerType.ConvertedType == null) { writer.Write("null"); return; } Core.Write(writer, value); } else { writer.Write(TypeProcessor.DefaultValue(declaration.Type)); } }
public static void Go(OutputWriter writer, EventDeclarationSyntax 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 add = property.AccessorList.Accessors.SingleOrDefault( o => o.Keyword.RawKind == (decimal)SyntaxKind.AddKeyword); var remove = property.AccessorList.Accessors.SingleOrDefault( o => o.Keyword.RawKind == (decimal)SyntaxKind.RemoveKeyword); var eventSymbol = TypeProcessor.GetDeclaredSymbol(property); var methodSymbol = (TypeProcessor.GetDeclaredSymbol(add) ?? TypeProcessor.GetDeclaredSymbol(remove)) as IMethodSymbol; ITypeSymbol interfaceImplemented; ISymbol[] proxies; ; var methodName = WriteIdentifierName.TransformIdentifier(MemberUtilities.GetMethodName(eventSymbol, ref isInterface, out interfaceImplemented, out proxies)); Action <AccessorDeclarationSyntax, bool> writeRegion = (region, get) => { writer.WriteIndent(); // if (property.Modifiers.Any(SyntaxKind.PrivateKeyword)) // writer.HeaderWriter.Write("private:\n"); // // if (property.Modifiers.Any(SyntaxKind.PublicKeyword) || property.Modifiers.Any(SyntaxKind.InternalKeyword)) // writer.HeaderWriter.Write("public "); 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 "); } writer.Write("void "); writer.Write( (get ? "Add_" : "Remove_") + methodName + "( " + typeString + " value"); if (isInterface) { writer.WriteLine(" , " + TypeProcessor.ConvertType(interfaceImplemented) + " __ij = null"); } writer.Write(" )"); if (property.Modifiers.Any(SyntaxKind.AbstractKeyword) || region.Body == null) { writer.Write(";\r\n"); } else { // writer.Write(";\r\n"); writer.OpenBrace(); // writer.Write(" =\r\n"); Core.WriteBlock(writer, region.Body.As <BlockSyntax>()); writer.CloseBrace(); writer.Write("\r\n"); } }; if (add == null && remove == null) { throw new Exception("Event must have both a add and remove"); } { var name = WriteIdentifierName.TransformIdentifier(property.Identifier.Text); var type = property.Type; var typeinfo = TypeProcessor.GetTypeInfo(type); var modifiers = property.Modifiers; var typeString = TypeProcessor.ConvertType(type) + " "; var isStatic = false; //Handle Auto Properties var accessors = property.AccessorList.Accessors; //.Where(o=>o.Body==null); var accessString = ""; if (modifiers.Any(SyntaxKind.PrivateKeyword)) { accessString += (" private "); } if (modifiers.Any(SyntaxKind.PublicKeyword) || modifiers.Any(SyntaxKind.InternalKeyword) || modifiers.Any(SyntaxKind.ProtectedKeyword) || modifiers.Any(SyntaxKind.AbstractKeyword) || isInterface) { accessString += (" public "); } var IsStatic = ""; if (modifiers.Any(SyntaxKind.StaticKeyword)) { isStatic = true; IsStatic = accessString += " static "; // writer.HeaderWriter.Write("static "); } var fieldName = "__evt__" + name + (interfaceImplemented != null?TypeProcessor.ConvertType(interfaceImplemented) .Replace("(", "_").Replace("!", "_").Replace(")", "_").Replace(".", "_") :""); if (!(property.Parent is InterfaceDeclarationSyntax)) { if (!isStatic) { writer.Write("private " + "__Event!(" + typeString + ") " + fieldName + ";\r\n"); // Internal Field used for event writer.Write(accessString); writer.WriteLine("__Event!(" + typeString + ") " + name + "(" + (interfaceImplemented != null ? (TypeProcessor.ConvertType(interfaceImplemented) + " __ij = null") :"") + ") @property"); writer.OpenBrace(); writer.WriteLine("if (" + fieldName + " is null)"); writer.OpenBrace(); writer.Write(fieldName + " = new " + "__Event!(" + typeString + ")(new Action__G!(" + typeString + ")(&Add_" + name + "),new Action__G!(" + typeString + ")(&Remove_" + name + ") );"); writer.CloseBrace(); writer.Write("return " + fieldName + ";"); writer.CloseBrace(); } else { writer.Write(IsStatic); writer.Write("__Event!(" + typeString + ") " + name + ";\r\n"); } } // 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 " : ""; //Adder if (add != null && add.Body == null) { writer.Write(IsStatic); //if (property.Modifiers.Any(SyntaxKind.AbstractKeyword)||isInterface) { writer.WriteLine(" " + isVirtual + " void Add_" + name + "(" + typeString + " value)" + isOverride + "" + ";"); } // else // writer.WriteLine(" "+isVirtual + " void Add_" + name + "(" + typeString + " value)" + // isOverride + " {" + fieldName + " = value;}"); } else if (add != null) { writer.Write(IsStatic); writeRegion(add, true); } //Remover if (remove != null && remove.Body == null) { writer.Write(IsStatic); //if (property.Modifiers.Any(SyntaxKind.AbstractKeyword)||isInterface) { writer.WriteLine(" " + isVirtual + " void Remove_" + name + "(" + typeString + " value)" + isOverride + "" + ";"); } } else if (remove != null) { writer.Write(IsStatic); writeRegion(remove, false); } if (isStatic) { var staticWriter = new OutputWriter("", "", false); staticWriter.Write(name); staticWriter.Write(" = new " + "__Event!(" + typeString + ")(new Action__G!(" + typeString + ")(&Add_" + name + "),new Action__G!(" + typeString + ")(&Remove_" + name + ") )"); staticWriter.Write(";"); staticWriter.WriteLine(); Context.Instance.StaticInits.Add(staticWriter.ToString()); } } }
private static void ProcessArgument(OutputWriter writer, ArgumentSyntax variable, bool isOverloaded = false) { 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 != initializerType.ConvertedType) && ((initializerType.Type.IsValueType || initializerType.Type.TypeKind == TypeKind.TypeParameter) && (!initializerType.ConvertedType.IsValueType)); var shouldCast = initializerType.Type != null && (initializerType.Type.TypeKind == TypeKind.Interface && initializerType.ConvertedType.SpecialType == SpecialType.System_Object); var shouldUnBox = initializerType.Type != null && (initializerType.Type != initializerType.ConvertedType) && !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 != null && initializerType.ConvertedType.TypeKind == TypeKind.Delegate; var isstaticdelegate = isdelegateassignment && ((memberaccessexpression != null && TypeProcessor.GetSymbolInfo(memberaccessexpression).Symbol.IsStatic) || (isname && TypeProcessor.GetSymbolInfo(nameexpression).Symbol.IsStatic)); if (isOverloaded) { writer.Write("cast(const({0}))", TypeProcessor.ConvertType(initializerType.Type)); } if (shouldCast) { writer.Write("cast(NObject)"); writer.Write("("); Core.Write(writer, value.Expression); writer.Write(")"); return; } 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, 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 = initializerType.ConvertedType.GetImplicitCoversionOp(initializerType.ConvertedType, initializerType.Type, true); //.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, false, true, false).Replace(".", "_")); } else { writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) + "." + "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_")); } 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, 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 = initializerType.ConvertedType.GetImplicitCoversionOp(initializerType.Type, initializerType.ConvertedType, true); //.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, false, true, false).Replace(".", "_")); } else { writer.Write(TypeProcessor.ConvertType(initializerType.ConvertedType) + "." + "op_Implicit_" + TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_")); } 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("); MemberUtilities.WriteMethodPointer(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, BasePropertyDeclarationSyntax property, bool isProxy = false) { writer.WriteLine(); //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 isYield = getter != null && getter.DescendantNodes().OfType <YieldStatementSyntax>().Any(); var isStatic = property.Modifiers.Any(k => k.IsKind(SyntaxKind.StaticKeyword)); ITypeSymbol iface; ISymbol[] proxies; var name = MemberUtilities.GetMethodName(property, ref isInterface, out iface, out proxies); var modifiers = property.Modifiers; var propertySymbol = (IPropertySymbol)TypeProcessor.GetDeclaredSymbol(property); var type = propertySymbol.Type; var acccessmodifiers = MemberUtilities.GetAccessModifiers(property, isInterface || propertySymbol.IsAbstract); var typeString = TypeProcessor.ConvertType(type); var hasGetter = getter != null; var getterHasBody = hasGetter && getter.Body != null; var hasSetter = setter != null; var setterHasBody = hasSetter && setter.Body != null; var indexerDeclarationSyntax = property as IndexerDeclarationSyntax; var isindexer = indexerDeclarationSyntax != null; string getterbody = null; if (getterHasBody) { getterbody = Core.WriteBlock(getter.Body, false, writer.Indent + 2); if (!isProxy && isYield) { var namedTypeSymbol = propertySymbol.Type as INamedTypeSymbol; if (namedTypeSymbol != null) { // var iteratortype = namedTypeSymbol.TypeArguments[0]; // getterbody=String.Format("return new __IteratorBlock!({0})(delegate(__IteratorBlock!({0}) __iter){{ {1} }});", // TypeProcessor.ConvertType(iteratortype),getterbody); var className = propertySymbol.GetYieldClassName() + ( (((INamedTypeSymbol)propertySymbol.Type).TypeArguments.Any() && ((INamedTypeSymbol)propertySymbol.Type).TypeArguments[0].TypeKind == TypeKind.TypeParameter) ? "__G" : ""); // writer.WriteLine(accessString + returnTypeString + methodSignatureString + @params2 + constraints); //writer.OpenBrace(); if (!propertySymbol.IsStatic) { getterbody = writer.WriteIndentToString() + ("return new " + className + "(this);"); } else { getterbody = writer.WriteIndentToString() + ("return new " + className + "();"); } } } } string setterbody = null; if (setterHasBody) { setterbody = Core.WriteString(setter.Body, false, writer.Indent + 2); if (isindexer) { setterbody += writer.WriteIndentToString() + "return value;"; } else { if (hasGetter) { setterbody += writer.WriteIndentToString() + "return " + name + ";"; } } } if (getter == null && setter == null) { throw new Exception("Property must have either a get or a set"); } string isOverride; var fieldName = WriteAutoFieldName(writer, name, modifiers, isInterface, hasGetter, getterHasBody, hasSetter, setterHasBody, typeString, out isOverride, (property is IndexerDeclarationSyntax)); BracketedParameterListSyntax @params = null; if (indexerDeclarationSyntax != null) { @params = indexerDeclarationSyntax.ParameterList; } string parameters = null; if (@params != null) { parameters = WriteMethod.GetParameterListAsString(@params.Parameters, iface: proxies == null ? iface : null, writebraces: false); } WriteGetter(writer, isProxy, hasGetter, acccessmodifiers, typeString, name, proxies == null ? iface : null, getterHasBody, modifiers, isInterface, fieldName, getterbody, parameters, indexerDeclarationSyntax != null); WriteSetter(writer, isProxy, hasSetter, acccessmodifiers, name, typeString, proxies == null ? iface : null, isOverride, setterHasBody, modifiers, isInterface, fieldName, setterbody, parameters, isindexer, hasGetter); // if (!isindexer && !isInterface) //TODO: Find a better solution // { // var fieldacccessmodifiers = acccessmodifiers.Replace ("abstract", "").Replace ("virtual","").Replace("override",""); // // writer.WriteLine(fieldacccessmodifiers + "__Property!(" + typeString + ")" + name + ";"); // if (isStatic) // { // var staticWriter = new TempWriter (); // // staticWriter.WriteLine (name + String.Format (" = __Property!(" + typeString + ")(__ToDelegate(&set{0}), __ToDelegate(&get{0}));", name)); // Context.Instance.StaticInits.Add (staticWriter.ToString ()); // } // else // { // var instanceWriter = new TempWriter (); // // instanceWriter.WriteLine (name + String.Format (" = __Property!(" + typeString + ")((&set{0}), (&get{0}));", name)); // Context.Instance.InstanceInits.Add (instanceWriter.ToString ()); // } // } if (proxies != null) { foreach (var proxy in proxies) { if (indexerDeclarationSyntax == null) { setterbody = writer.WriteIndentToString() + name + "=" + "value" + ";"; getterbody = writer.WriteIndentToString() + "return " + name + ";"; } else { string parameters2 = ""; if (@params != null) { parameters2 = WriteMethod.GetParameterListAsString(@params.Parameters, iface: null, includeTypes: false, writebraces: false); // parameters2 = WriteMethod.GetParameterListAsString(@params.Parameters, iface: proxies == null ? iface : null, writebraces: false); } setterbody = writer.WriteIndentToString() + "return opIndexAssign(value," + parameters2 + ");";// + "=" + "value" + ";"; getterbody = writer.WriteIndentToString() + "return opIndex(" + parameters2 + ");"; } parameters = null; if (@params != null) { parameters = WriteMethod.GetParameterListAsString(@params.Parameters, iface: proxy.ContainingType, writebraces: false); } WriteGetter(writer, isProxy, hasGetter, acccessmodifiers, typeString, name, proxy.ContainingType, getterHasBody, modifiers, isInterface, fieldName, getterbody, parameters, isindexer); WriteSetter(writer, isProxy, hasSetter, acccessmodifiers, name, typeString, proxy.ContainingType, isOverride, setterHasBody, modifiers, isInterface, fieldName, setterbody, parameters, isindexer, hasGetter); } } }
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 WriteIt(OutputWriter writer, MethodDeclarationSyntax method, bool isProxy = true, IEnumerable <ITypeSymbol> virtualGenericClasses = null) { var methodSymbol = (IMethodSymbol)TypeProcessor.GetDeclaredSymbol(method); var isYield = YieldChecker.HasYield(method);//method.DescendantNodes().OfType<YieldStatementSyntax>().Any(); writer.WriteLine(); var pinvokeAttributes = method.GetAttribute(Context.DllImport); var isInternalPInvoke = pinvokeAttributes == null && method.Modifiers.Any(SyntaxKind.ExternKeyword); //TODO: Improve partial class / method support -- partials classes work, methods need minor work ... if (method.Modifiers.Any(SyntaxKind.PartialKeyword) && method.Body == null) { //We only want to render out one of the two partial methods. If there's another, skip this one. if (Context.Instance.Partials.SelectMany(o => o.Syntax.As <ClassDeclarationSyntax>().Members) .OfType <MethodDeclarationSyntax>() .Except(method).Any(o => o.Identifier.Text == method.Identifier.Text)) { return; } } var accessString = ""; var isInterface = method.Parent is InterfaceDeclarationSyntax; ITypeSymbol iface; ISymbol[] proxies; var methodName = MemberUtilities.GetMethodName(method, ref isInterface, out iface, out proxies); // var originalMethodName = methodName; var containingType = iface == null ? methodSymbol.ContainingType : iface; if (virtualGenericClasses != null) { methodName = TypeProcessor.ConvertType(containingType, false, false, false).Replace(".", "_") + "_" + methodName; accessString = "public static final "; } else if (methodName == "Main" /*&& method.Modifiers.Any(SyntaxKind.PublicKeyword)*/ && method.Modifiers.Any(SyntaxKind.StaticKeyword)) { accessString = ("public "); accessString += ("static "); var methodCall = methodSymbol.ContainingNamespace.FullName() + "." + methodSymbol.ContainingType.FullName() + "." + methodName + (method.ParameterList.Parameters.Count < 1 ? "();" : "(null);"); //: "(new Array_T!(String)(args));"); // for now args not supported Context.Instance.EntryMethod = methodCall; } else { accessString = MemberUtilities.GetAccessModifiers(method, isInterface || methodSymbol.IsAbstract); } var returnTypeString = TypeProcessor.ConvertType(method.ReturnType, true) + " "; var methodSignatureString = ""; if (method.ReturnType.ToString() == "void") { returnTypeString = ("void "); } methodSignatureString += methodName; var genericParameters = ""; if (method.TypeParameterList != null) { var genericArgs = method.TypeParameterList.Parameters.ToList(); // if (genericArgs.Count > 0) // { // writer.Write("( "); // writer.Write(string.Join(" , ", genericArgs.Select(o => " " + o))); // writer.Write(" )\r\n"); // } if (genericArgs.Count > 0) // && !methodSymbol.ContainingType.IsGenericType) // doesnt matter { genericParameters += ("("); genericParameters += (string.Join(",", genericArgs.Select(o => o))); genericParameters += (")"); } } methodSignatureString += genericParameters; var @params = GetParameterListAsString(method.ParameterList.Parameters, iface: proxies == null ? iface : null, genericClass: virtualGenericClasses != null ? containingType : null); // if (virtualGenericClasses != null) // { // @params = TypeProcessor.ConvertType() + ", " + @params; // } string constraints = GetMethodConstraints(method); if (isInterface || method.Modifiers.Any(SyntaxKind.AbstractKeyword)) { writer.WriteLine(accessString + returnTypeString + methodSignatureString + @params + constraints + ";"); return; } writer.WriteLine(accessString + returnTypeString + methodSignatureString + @params + constraints); writer.OpenBrace(); if (isProxy) { @params = GetParameterListAsString(method.ParameterList.Parameters, includeTypes: false); if (virtualGenericClasses != null) { /* * public final static void Program_IBase_GenericVirtual_Dispatch(T)(Program.IBase aobj) * { * Object obj = cast(Object) aobj; * if((typeid(obj)==typeid(Program.B))) * (cast(Program.B)obj).GenericVirtual!(T)(); * if((typeid(obj)==typeid(Program.A))) * (cast(Program.A)obj).GenericVirtual!(T)(); * * } */ writer.WriteLine("NObject ___obj = cast(NObject)__obj;"); foreach (var virtualGenericClass in virtualGenericClasses) { var className = TypeProcessor.ConvertType(virtualGenericClass); writer.WriteLine("if(typeid(___obj)==typeid({0}))", className); if (method.ReturnType.ToString() == "void") { writer.WriteLine("(cast({0})___obj)." + originalMethodName + "!" + genericParameters + @params + ";", className); } else { writer.WriteLine("return (cast({0})___obj)." + methodSignatureString + "!" + genericParameters + ";", className); } } } else { if (method.ReturnType.ToString() == "void") { writer.WriteLine("__Value." + methodName + @params + ";"); } else { writer.WriteLine("return __Value." + methodName + @params + ";"); } } } else { if (!isProxy && isYield) { var namedTypeSymbol = methodSymbol.ReturnType as INamedTypeSymbol; if (namedTypeSymbol != null) { // var iteratortype = namedTypeSymbol.TypeArguments[0]; var className = methodSymbol.GetYieldClassName() + ( (((INamedTypeSymbol)methodSymbol.ReturnType).TypeArguments.Any() && ((INamedTypeSymbol)methodSymbol.ReturnType).TypeArguments[0].TypeKind == TypeKind.TypeParameter) ? "__G" : ""); methodSignatureString = methodName + genericParameters; if (!String.IsNullOrEmpty(genericParameters)) { className = className + "!" + genericParameters; } var @params2 = GetParameterListAsString(method.ParameterList.Parameters, iface: methodSymbol.ContainingType); var @params3 = GetParameterListAsString(method.ParameterList.Parameters, iface: null, includeTypes: false, writebraces: false); // writer.WriteLine(accessString + returnTypeString + methodSignatureString + @params2 + constraints); //writer.OpenBrace(); if (!methodSymbol.IsStatic) { if (method.ParameterList.Parameters.Count > 0) { writer.WriteLine("return new " + className + "(this," + @params3 + ");"); } else { writer.WriteLine("return new " + className + "(this);"); } } else { writer.WriteLine("return new " + className + "(" + @params3 + ");"); } } } else if (method.Body != null) { foreach (var statement in method.Body.Statements) { Core.Write(writer, statement); } TriviaProcessor.ProcessTrivias(writer, method.Body.DescendantTrivia()); } if (pinvokeAttributes != null) { WritePInvokeMethodBody.Go(writer, methodName, methodSymbol, pinvokeAttributes); } if (isInternalPInvoke) { WritePInvokeMethodBody.Go(writer, methodName, methodSymbol, null); } if (!isProxy && isYield) { //writer.WriteLine("});"); } } writer.CloseBrace(); if (proxies != null) { foreach (var proxy in proxies) { //Need to write proxy signature here ... methodSignatureString = methodName + genericParameters; var @params2 = GetParameterListAsString(method.ParameterList.Parameters, iface: proxy.ContainingType); var @params3 = GetParameterListAsString(method.ParameterList.Parameters, iface: null, includeTypes: false); writer.WriteLine(accessString + returnTypeString + methodSignatureString + @params2 + constraints); writer.OpenBrace(); if (method.ReturnType.ToString() == "void") { writer.WriteLine("" + methodName + @params3 + ";"); } else { writer.WriteLine("return " + methodName + @params3 + ";"); } writer.CloseBrace(); } } }
public static bool IsNew(this ISymbol symbol) { switch (symbol.Kind) { case SymbolKind.Event: { var @event = symbol as IEventSymbol; if (@event != null && (@event.ContainingType.BaseType != null && @event.ContainingType.BaseType.GetAllMembers().OfType <IEventSymbol>().Any(k => k.Name == @event.Name) && @event.IsOverride == false)) { return(true); } } break; case SymbolKind.Method: { var @method = symbol as IMethodSymbol; if (@method != null && (@method.ContainingType.BaseType != null && @method.ContainingType.BaseType.GetAllMembers().OfType <IMethodSymbol>().Any(k => MemberUtilities.CompareMethods(k, @method)) && @method.IsOverride == false)) { return(true); } } break; case SymbolKind.Property: { var @property = symbol as IPropertySymbol; if (@property != null && (@property.ContainingType.BaseType != null && @property.ContainingType.BaseType.GetAllMembers().OfType <IPropertySymbol>().Any(k => k.Name == @property.Name) && @property.IsOverride == false)) { return(true); } } break; case SymbolKind.Field: // New Field is nothing special, base field { /* var @field = symbol as IFieldSymbol; * if (@field != null && (@field.ContainingType.BaseType != null && @field.ContainingType.BaseType.GetAllMembers().OfType<IFieldSymbol>().Any(k => k.Name == @field.Name) && @field.IsOverride == false)) * { * return true; * }*/ return(false); } break; } return(false); }