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)); } }
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); } }
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 ? ")" : ""); } } }