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 if (symbol == null) { writer.WriteLine("/*" + invocationExpression.ToFullString() + " //SharpNative Failed To Get Symbol */"); } 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 (expressionSymbol.Symbol is IEventSymbol) { methodName = "Invoke"; } else if (methodSymbol.MethodKind == MethodKind.DelegateInvoke) { methodName = null; } else { methodName = OverloadResolver.MethodName(methodSymbol); } 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);*/ if (methodSymbol.ContainingType.ContainingType != null) { methodName = methodName.RemoveFromStartOfString(methodSymbol.ContainingType.ContainingType.Name + "."); } } 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 containingType = interfaceMethod == null ? methodSymbol.ContainingType : interfaceMethod.ContainingType; bool isVirtualGeneric = methodSymbol.IsGenericMethod && (methodSymbol.IsVirtual || methodSymbol.ContainingType.TypeKind == TypeKind.Interface) && !containingType.IsAssignableFrom(Context.Instance.Type); // !(invocationExpression.Expression is BaseExpressionSyntax); if (isVirtualGeneric) { methodName = TypeProcessor.ConvertType(containingType, false, false, false).Replace(".", "_") + "_" + methodName; } 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 ... dmd needs help with inference, so we give it the types anyway if (methodSymbol.IsGenericMethod) { //return TryConvertType(named) + (named.TypeKind == TypeKind.Struct && o.ConstraintTypes.Any(k => k.TypeKind == //TypeKind.Interface) ? ".__Boxed_" : ""); var named = ((IMethodSymbol)symbol); typeParameters = "!(" + named.TypeArguments.Select(o => TypeProcessor.GetGenericParameterType(named.TypeParameters[named.TypeArguments.IndexOf(o)], o)).Aggregate((a, b) => a + ", " + b) + ")"; // typeParameters = "!( " + // string.Join(", ", // ((IMethodSymbol) symbol).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.FullName() + "." + 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"; // } //Invocation on basics should come from boxing the basic then calling on the boxed type, unless static var directInvocationOnBasics = methodSymbol.ContainingType.IsBasicType() && methodSymbol.IsStatic; //&& methodSymbol.ContainingType!=Context.Instance.Type; //If we are currently working on a basic type e.g. in corlib, don't alter the code //Extension methods in Dlang are straightforward, although this could lead to clashes without qualification string instanceName = null; if (extensionNamespace != null || directInvocationOnBasics) { if (extensionNamespace == null) { extensionNamespace = TypeProcessor.ConvertType(methodSymbol.ContainingType, true, false); // methodSymbol.ContainingNamespace.FullName() + "." + methodSymbol.ContainingType.Name; //memberType.ContainingNamespace.FullName() +"."+ memberType.Name; } if (!isVirtualGeneric) { writer.Write(extensionNamespace); if (methodName != null) { methodName = WriteIdentifierName.TransformIdentifier(methodName); // if (symbolInfo.Symbol.ContainingType != Context.Instance.Type) writer.Write("."); writer.Write(methodName); } } else { writer.Write(methodName); } WriteTypeParameters(writer, typeParameters, invocationExpression); writer.Write("("); if (subExpressionOpt != null) { firstParameter = false; Core.Write(writer, subExpressionOpt); } } else { if (memberReferenceExpressionOpt != null) { } if (subExpressionOpt != null) { if (!isVirtualGeneric) { WriteMemberAccessExpression.WriteMember(writer, subExpressionOpt); // if (!(subExpressionOpt is BaseExpressionSyntax)) // { // if (methodName != null && methodSymbol.IsStatic) // writer.Write("."); // else // { if (methodSymbol.MethodKind != MethodKind.DelegateInvoke) { writer.Write("."); } } else { instanceName = WriteMemberAccessExpression.WriteMemberToString(subExpressionOpt); } // } // } // writer.Write("."); } else if (methodSymbol.IsStatic && extensionNamespace == null) { if (methodSymbol.ContainingType != Context.Instance.Type) { 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 methodDeclarationSyntaxs = declaringSyntaxReferences as MethodDeclarationSyntax[] ?? declaringSyntaxReferences.ToArray(); var any = methodDeclarationSyntaxs.Any(); if (any && methodDeclarationSyntaxs.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 += "_"; //Not needed anymore :) } if (any && methodDeclarationSyntaxs.FirstOrDefault() .As <MethodDeclarationSyntax>() .Modifiers.Any(SyntaxKind.NewKeyword)) { // if (symbolInfo.Symbol.ContainingType != Context.Instance.Type) writer.Write(WriteIdentifierName.TransformIdentifier(methodSymbol.ContainingType.Name, methodSymbol.ContainingType) + "."); } methodName = WriteIdentifierName.TransformIdentifier(methodName); writer.Write(methodName); } WriteTypeParameters(writer, typeParameters, invocationExpression); writer.Write("("); } bool inParams = false; bool foundParamsArray = false; var arguments = invocationExpression.ArgumentList.Arguments; ITypeSymbol typeSymbol = null; bool isOverloaded = methodSymbol.ContainingType.GetMembers(methodSymbol.Name).OfType <IMethodSymbol>().Any(j => j.TypeParameters == methodSymbol.TypeParameters && ParameterMatchesWithRefOutIn(methodSymbol, j)); WriteArguments(writer, invocationExpression, arguments, firstParameter, inParams, methodSymbol, foundParamsArray, typeSymbol, isOverloaded, symbol, instanceName); }
private static void Factory(OutputWriter writer, SyntaxNode node, bool isConst) { if (node is ConstructorInitializerSyntax) { WriteConstructorInitializer.Go(writer, node.As <ConstructorInitializerSyntax>()); } else if (node is CheckedExpressionSyntax) { WriteChecked.Go(writer, node.As <CheckedExpressionSyntax>()); } else if (node is CheckedStatementSyntax) { WriteChecked.Go(writer, node.As <CheckedStatementSyntax>()); } else if (node is UnsafeStatementSyntax) { WriteUnsafeStatement.Go(writer, node.As <UnsafeStatementSyntax>()); } else if (node is InitializerExpressionSyntax) { WriteInitializer.Go(writer, node.As <InitializerExpressionSyntax>()); } else if (node is GotoStatementSyntax) { WriteGoto.Go(writer, node.As <GotoStatementSyntax>()); } else if (node is CaseSwitchLabelSyntax) { WriteLabel.Go(writer, node.As <CaseSwitchLabelSyntax>()); } else if (node is LabeledStatementSyntax) { WriteLabel.Go(writer, node.As <LabeledStatementSyntax>()); } else if (node is OperatorDeclarationSyntax) { WriteOperatorDeclaration.Go(writer, node.As <OperatorDeclarationSyntax>()); } else if (node is MethodDeclarationSyntax) { WriteMethod.Go(writer, node.As <MethodDeclarationSyntax>()); } else if (node is PropertyDeclarationSyntax) { WriteProperty.Go(writer, node.As <PropertyDeclarationSyntax>()); } else if (node is EventDeclarationSyntax) { WriteEvent.Go(writer, node.As <EventDeclarationSyntax>()); } else if (node is FieldDeclarationSyntax) { WriteField.Go(writer, node.As <FieldDeclarationSyntax>()); } else if (node is EventFieldDeclarationSyntax) { WriteField.Go(writer, node.As <EventFieldDeclarationSyntax>()); } else if (node is ConstructorDeclarationSyntax) { WriteConstructorBody.Go(writer, node.As <ConstructorDeclarationSyntax>()); } else if (node is ExpressionStatementSyntax) { WriteStatement(writer, node.As <ExpressionStatementSyntax>()); } else if (node is FixedStatementSyntax) { WriteFixedStatement(writer, node.As <FixedStatementSyntax>()); } else if (node is LocalDeclarationStatementSyntax) { WriteLocalDeclaration.Go(writer, node.As <LocalDeclarationStatementSyntax>()); } else if (node is VariableDeclarationSyntax) { WriteVariableDeclaration.Go(writer, node.As <VariableDeclarationSyntax>()); } else if (node is BlockSyntax) { WriteBlock(writer, node.As <BlockSyntax>()); } else if (node is InvocationExpressionSyntax) { WriteInvocationExpression.Go(writer, node.As <InvocationExpressionSyntax>()); } else if (node is LiteralExpressionSyntax) { WriteLiteralExpression.Go(writer, node.As <LiteralExpressionSyntax>(), isConst); } else if (node is IdentifierNameSyntax) { WriteIdentifierName.Go(writer, node.As <IdentifierNameSyntax>()); } else if (node is ImplicitArrayCreationExpressionSyntax) { WriteArrayCreationExpression.Go(writer, node.As <ImplicitArrayCreationExpressionSyntax>()); } else if (node is ArrayCreationExpressionSyntax) { WriteArrayCreationExpression.Go(writer, node.As <ArrayCreationExpressionSyntax>()); } else if (node is MemberAccessExpressionSyntax) { WriteMemberAccessExpression.Go(writer, node.As <MemberAccessExpressionSyntax>()); } else if (node is ParenthesizedLambdaExpressionSyntax) { WriteLambdaExpression.Go(writer, node.As <ParenthesizedLambdaExpressionSyntax>()); } else if (node is SimpleLambdaExpressionSyntax) { WriteLambdaExpression.Go(writer, node.As <SimpleLambdaExpressionSyntax>()); } else if (node is AnonymousMethodExpressionSyntax) { WriteLambdaExpression.Go(writer, node.As <AnonymousMethodExpressionSyntax>()); } else if (node is ReturnStatementSyntax) { WriteReturnStatement.Go(writer, node.As <ReturnStatementSyntax>()); } else if (node is ObjectCreationExpressionSyntax) { WriteObjectCreationExpression.Go(writer, node.As <ObjectCreationExpressionSyntax>()); } else if (node is ElementAccessExpressionSyntax) { WriteElementAccessExpression.Go(writer, node.As <ElementAccessExpressionSyntax>()); } else if (node is ForEachStatementSyntax) { WriteForEachStatement.Go(writer, node.As <ForEachStatementSyntax>()); } else if (node is IfStatementSyntax) { WriteIfStatement.Go(writer, node.As <IfStatementSyntax>()); } else if (node is BinaryExpressionSyntax) { WriteBinaryExpression.Go(writer, node.As <BinaryExpressionSyntax>()); } else if (node is AssignmentExpressionSyntax) { WriteAssignmentExpression.Go(writer, node.As <AssignmentExpressionSyntax>()); } else if (node is ConditionalExpressionSyntax) { WriteConditionalExpression.Go(writer, node.As <ConditionalExpressionSyntax>()); } else if (node is BaseExpressionSyntax) { WriteBaseExpression.Go(writer, node.As <BaseExpressionSyntax>()); } else if (node is ThisExpressionSyntax) { WriteThisExpression.Go(writer, node.As <ThisExpressionSyntax>()); } else if (node is CastExpressionSyntax) { WriteCastExpression.Go(writer, node.As <CastExpressionSyntax>()); } else if (node is ThrowStatementSyntax) { WriteThrowStatement.Go(writer, node.As <ThrowStatementSyntax>()); } else if (node is EqualsValueClauseSyntax) { WriteEqualsValueClause.Go(writer, node.As <EqualsValueClauseSyntax>()); } else if (node is ForStatementSyntax) { WriteForStatement.Go(writer, node.As <ForStatementSyntax>()); } else if (node is WhileStatementSyntax) { WriteWhileStatement.Go(writer, node.As <WhileStatementSyntax>()); } else if (node is BreakStatementSyntax) { WriteBreakStatement.Go(writer, node.As <BreakStatementSyntax>()); } else if (node is ContinueStatementSyntax) { WriteContinueStatement.Go(writer, node.As <ContinueStatementSyntax>()); } else if (node is DoStatementSyntax) { WriteDoStatement.Go(writer, node.As <DoStatementSyntax>()); } else if (node is SwitchStatementSyntax) { WriteSwitchStatement.Go(writer, node.As <SwitchStatementSyntax>()); } else if (node is TryStatementSyntax) { WriteTryStatement.Go(writer, node.As <TryStatementSyntax>()); } else if (node is UsingStatementSyntax) { WriteUsingStatement.Go(writer, node.As <UsingStatementSyntax>()); } else if (node is ParenthesizedExpressionSyntax) { WriteParenthesizedExpression.Go(writer, node.As <ParenthesizedExpressionSyntax>()); } else if (node is LockStatementSyntax) { WriteLockStatement.Go(writer, node.As <LockStatementSyntax>()); } else if (node is TypeOfExpressionSyntax) { WriteTypeOfExpression.Go(writer, node.As <TypeOfExpressionSyntax>()); } else if (node is AnonymousObjectCreationExpressionSyntax) { WriteAnonymousObjectCreationExpression.Go(writer, node.As <AnonymousObjectCreationExpressionSyntax>()); } else if (node is EmptyStatementSyntax) { return; //ignore empty statements } else if (node is DelegateDeclarationSyntax) { return; //don't write delegates - TypeProcessor converts them to function types directly } else if (node is DefaultExpressionSyntax) { WriteDefaultExpression.Go(writer, node.As <DefaultExpressionSyntax>()); } else if (node is GenericNameSyntax) { WriteGenericName.Go(writer, node.As <GenericNameSyntax>()); } else if (node is ConversionOperatorDeclarationSyntax) { WriteConversionOperatorDeclaration.Go(writer, node.As <ConversionOperatorDeclarationSyntax>()); } else if (node is PrefixUnaryExpressionSyntax) { WriteUnaryExpression.WritePrefix(writer, node.As <PrefixUnaryExpressionSyntax>()); } else if (node is PostfixUnaryExpressionSyntax) { WriteUnaryExpression.WritePostfix(writer, node.As <PostfixUnaryExpressionSyntax>()); } else if (node is SizeOfExpressionSyntax) { WriteSizeOfExpression.Go(writer, node.As <SizeOfExpressionSyntax>()); } else if (node is DestructorDeclarationSyntax) { WriteDestructorBody.WriteDestructor(writer, node.As <DestructorDeclarationSyntax>()); } else if (node is IndexerDeclarationSyntax) { WriteIndexer.Go(writer, node.As <IndexerDeclarationSyntax>()); } else if (node is StackAllocArrayCreationExpressionSyntax) { WriteStackArrayCreation.Go(writer, node.As <StackAllocArrayCreationExpressionSyntax>()); } // writer.Write(node.ToFullString() + "//TODO: StackAlloc not supported yet"); else if (node is YieldStatementSyntax) { WriteYieldStatement.Go(writer, node.As <YieldStatementSyntax>()); } else { throw new NotImplementedException(node.GetType().Name + " is not supported. " + Utility.Descriptor(node)); } }
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(")"); }