Beispiel #1
0
        public static void WriteInstanceConstructor(OutputWriter writer, ConstructorDeclarationSyntax method,
                                                    List <string> otherInits)
        {
            writer.WriteLine();

            var accessmodifiers = "";

            var isInterface = method.Parent is InterfaceDeclarationSyntax;

            if (method.Modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword) ||
                method.Modifiers.Any(SyntaxKind.ProtectedKeyword) || method.Modifiers.Any(SyntaxKind.AbstractKeyword) ||
                isInterface)
            {
                accessmodifiers += ("public ");
            }

            // Reflection cannot work with this, cant get address or set value
            //if (method.Modifiers.Any(SyntaxKind.PrivateKeyword))
            //    accessmodifiers += ("private ");


            if (method.Modifiers.Any(SyntaxKind.StaticKeyword))
            {
                accessmodifiers += ("static ");
            }


            var constructorName = "this";

            if (Context.Instance.Type.TypeKind == TypeKind.Struct)             // Struct
            {
                constructorName = " void __init";
            }

            writer.WriteLine(accessmodifiers + constructorName + WriteMethod.GetParameterListAsString(method.ParameterList.Parameters));

            if (isInterface || method.Modifiers.Any(SyntaxKind.AbstractKeyword))
            {
                writer.Write(" = 0;\r\n");

                return;
            }

            //if (!returnsVoid)
            //  writer.Write(" =");

//            writer.Write("\r\n");
            writer.OpenBrace();

            if (otherInits != null)             //We need to write the static initializers before anything else
            {
                foreach (var statement in otherInits)
                {
                    var nodeString = statement;

                    if (nodeString != null)
                    {
                        writer.WriteLine(nodeString);
                    }
                }
            }

            if (method.Initializer != null)
            {
                //writer.Write(":");
                Core.Write(writer, method.Initializer);
                writer.Write(";");
                writer.WriteLine(); //";\r\n");
            }

            if (method.Body != null)
            {
                foreach (var statement in method.Body.Statements)
                {
                    Core.Write(writer, statement);
                }

                TriviaProcessor.ProcessTrivias(writer, method.Body.DescendantTrivia());
            }

            writer.CloseBrace();
        }
Beispiel #2
0
        private static void WriteOneDelegate(OutputWriter outputWriter, Context.DelegateSyntaxAndSymbol first, bool fileExists)
        {
            Context.Instance.Namespace = first.Symbol.ContainingNamespace.FullName();
            Context.Instance.Type      = first.Symbol;
            TypeProcessor.ClearUsedTypes();
            var mynamespace = Context.Instance.Type.ContainingNamespace.FullName().RemoveFromEndOfString(".Namespace");
            // + "." + TypeState.Instance.TypeName;

            var myUsingDirective     = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(mynamespace));
            var SystemUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System"));

            // Required as certain functions like boxing are in this namespace
            Context.Instance.UsingDeclarations =
                first.Syntax.Parent.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray()
                .Union(new[]
            {
                myUsingDirective, SystemUsingDirective
            }).ToArray();
            OutputWriter writer = null;

            using (
                writer =
                    outputWriter == null
                        ? new OutputWriter(Context.Instance.Namespace, Context.Instance.TypeName)
                        : new TempWriter())
            {
                if (outputWriter != null)
                {
                    writer.WriteLine();
                    writer.Indent = outputWriter.Indent + 2;
                    writer.WriteIndent();
                }

                writer.FileExists = fileExists;

                WriteBcl.Go(writer);

                WriteStandardIncludes.Go(writer);

                //Look for generic arguments

                {
                    List <TypeParameterSyntax> genericArgs = new List <TypeParameterSyntax>();
                    if (first.Syntax.TypeParameterList != null)
                    {
                        genericArgs = first.Syntax.TypeParameterList.Parameters.ToList();
                    }

                    var name = WriteType.TypeName(Context.Instance.Type, false); //Context.Instance.TypeName;

                    if (genericArgs.Count > 0)
                    {
                        name  = "template " + name;
                        name += ("(");
                        name += (string.Join(" , ", genericArgs.Select(o => o)));
                        name += (")");

                        writer.WriteLine(name);

                        writer.OpenBrace();

                        writer.WriteLine("alias __Delegate!(" + TypeProcessor.ConvertType(first.Syntax.ReturnType) + " delegate" +
                                         WriteMethod.GetParameterListAsString(first.Syntax.ParameterList.Parameters) + ") " +
                                         WriteType.TypeName(Context.Instance.Type, false) + ";");

                        writer.CloseBrace();
                    }
                    else
                    {
                        //Non-generic
                        writer.WriteLine("alias __Delegate!(" + TypeProcessor.ConvertType(first.Syntax.ReturnType) + " delegate" +
                                         WriteMethod.GetParameterListAsString(first.Syntax.ParameterList.Parameters) + ") " +
                                         WriteType.TypeName(Context.Instance.Type, false) + ";");
                    }
                }

                if (outputWriter != null)
                {
                    outputWriter.WriteLine(writer.ToString());
                }
            }
        }
        public static void Go(OutputWriter writer, OperatorDeclarationSyntax method)
        {
            var methodSymbol     = (IMethodSymbol)TypeProcessor.GetDeclaredSymbol(method);
            var actualMethodName = OverloadResolver.MethodName(methodSymbol);

            writer.Write("\n");


            var returnType = "";

            if (method.ReturnType.ToString() == "void")
            {
                returnType = ("void ");
            }
            else
            {
                returnType = TypeProcessor.ConvertType(method.ReturnType) + " ";

                //                writer.Write(returnType);
            }

            var methodName = "";

            if (BinaryOperators.ContainsKey(actualMethodName))
            {
                methodName = "opBinary";
                var typeSymbolParam0 = TypeProcessor.GetTypeInfo(method.ParameterList.Parameters[0].Type);

                var typeSymbolParent = (methodSymbol.ContainingType);

                if (typeSymbolParam0.Type != typeSymbolParent)
                {
                    methodName += "Right";
                }
            }

            if (UnaryOperators.ContainsKey(actualMethodName))
            {
                methodName = "opUnary";
            }

            if (EqualsOperators.ContainsKey(actualMethodName))
            {
                methodName = "opEquals";
            }

            if (CmpOperators.ContainsKey(actualMethodName))
            {
                methodName = "opCmp";
            }

            if (AssignOperators.ContainsKey(actualMethodName))
            {
                methodName = "opAssign";
            }

            if (AssignOpOperators.ContainsKey(actualMethodName))
            {
                methodName = "opOpAssign"; // need to remove = from the name
            }
            var paramType = method.ParameterList.Parameters[0];

            if (method.ParameterList.Parameters.Count == 2)
            {
                if (methodName.EndsWith("Right"))
                {
                    paramType = method.ParameterList.Parameters[0];
                }
                else
                {
                    paramType = method.ParameterList.Parameters[1];
                }
            }

            var token = method.OperatorToken.Text;

            var methodBody = "";

            var temp = new TempWriter();

            foreach (var statement in method.Body.Statements)
            {
                Core.Write(temp, statement);
            }

            TriviaProcessor.ProcessTrivias(temp, method.Body.DescendantTrivia());

            methodBody = temp.ToString();


            if (methodName == "opOpAssign")
            {
                token = token.Substring(0, 1);
            }

            //We are going to have to rewrite this bit later ... for now all overloads are called directly

            /*    if (methodName == "opBinary")
             *  {
             *
             *      writer.WriteLine("public final " + returnType + " " + methodName +
             *      String.Format(
             *          " (string _op) ({0} other)\r\n\tif(_op==\"{2}\")\r\n\t{{ \r\n\t\treturn {1}(this,other); \r\n\t}}\r\n\r\n",
             *          TypeProcessor.ConvertType(paramType.Type), actualMethodName, token));
             *
             *      //Add Assignment operator if it doesn't exist
             *      if (!methodSymbol.ContainingType.GetMembers(AssignOpOperators.FirstOrDefault(k => k.Value == token + "=").Key).Any())
             *      {
             *          writer.WriteLine("public final " + returnType + " opOpAssign" +
             *      String.Format(
             *          " (string _op) ({0} other)\r\n\tif(_op==\"{2}\")\r\n\t{{ \r\n\t\treturn {1}(this,other); \r\n\t}}\r\n\r\n",
             *          TypeProcessor.ConvertType(paramType.Type), actualMethodName, token));
             *      }
             *  }
             *  else if (methodName == "opUnary")//TODO unary operators are mostly going to be direct methodCalls
             *  {
             *
             *      writer.WriteLine("public final " + returnType + " " + methodName +
             *          String.Format(
             *              " (string _op) ()\r\n\tif(_op==\"{2}\")\r\n\t{{ \r\n\t\treturn {1}(this); \r\n\t}}\r\n\r\n",
             *              TypeProcessor.ConvertType(paramType.Type), actualMethodName, token));
             *      //				writer.WriteLine ("public final ref " + returnType + " " + methodName +
             *      //					String.Format (
             *      //						" (string _op) ()\r\n\tif(_op==\"{2}\")\r\n\t{{ \r\n\t\t{3}\r\n\t}}\r\n\r\n",
             *      //TypeProcessor.ConvertType (paramType.Type), actualMethodName, token, methodBody.Replace(method.ParameterList.Parameters[0].Identifier.ValueText,"this")));
             *  }
             *  else
             *  {
             *      writer.WriteLine("public final " + returnType + " " + methodName +
             *          String.Format(
             *              " (string _op) ({0} other)\r\n\tif(_op==\"{2}\")\r\n\t{{ \r\n\t\treturn {1}(this); \r\n\t}}\r\n\r\n",
             *              TypeProcessor.ConvertType(paramType.Type), actualMethodName, token));
             *  }*/

            var @params = method.ParameterList.Parameters;



            writer.WriteLine("public static " + returnType + " " + actualMethodName + WriteMethod.GetParameterListAsString(method.ParameterList.Parameters));



            writer.OpenBrace();
            if (method.Body != null)
            {
                foreach (var statement in method.Body.Statements)
                {
                    Core.Write(writer, statement);
                }

                TriviaProcessor.ProcessTrivias(writer, method.Body.DescendantTrivia());
            }

            writer.CloseBrace();
        }
Beispiel #4
0
        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));
            }
        }
Beispiel #5
0
        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);
                }
            }
        }
        public static void WriteInstanceConstructor(OutputWriter writer, ConstructorDeclarationSyntax method)
        {
            var methodSymbol = (IMethodSymbol)TypeProcessor.GetDeclaredSymbol(method);
            var methodName   = OverloadResolver.MethodName(methodSymbol);

            //			var methodType = Program.GetModel(method).GetTypeInfo(method);

            //TODO: Improve partial class / method support
            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 <ConstructorDeclarationSyntax>()
                    .Except(method).Any(o => o.Identifier.ValueText == method.Identifier.ValueText))
                {
                    return;
                }
            }

            //            if (method.Identifier.ValueText == "GetEnumerator")
            //                return; //TODO: Support enumerator methods

            writer.WriteLine();
            //            writer.WriteIndent();

            var accessmodifiers = "";

            var isInterface = method.Parent is InterfaceDeclarationSyntax;

            if (method.Modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword) ||
                method.Modifiers.Any(SyntaxKind.ProtectedKeyword) || method.Modifiers.Any(SyntaxKind.AbstractKeyword) ||
                isInterface)
            {
                accessmodifiers += ("public ");
            }

            if (method.Modifiers.Any(SyntaxKind.PrivateKeyword))
            {
                accessmodifiers += ("private ");
            }

            if (ShouldUseOverrideKeyword(method, methodSymbol))
            {
                accessmodifiers += ("override ");
            }

            //D does not use the virtual keyword
            //                if (method.Modifiers.Any(SyntaxKind.VirtualKeyword) || isInterface)
            //                    writer.Write("virtual ");
            //Need to improve performance by labling non virtual methods with "final" ... but we have to check the original definition of the method

            if (method.Modifiers.Any(SyntaxKind.StaticKeyword))
            {
                accessmodifiers += ("static ");
            }

            if (isInterface)
            {
//                writer.IsInterface = true;
            }

            //Constructors in d dont have return types
//            writer.Write("void ");
//            writer.HeaderWriter.Write("void ");

//            writer.Write("this");

//            writer.Write("(");

//            var firstParam = true;
//            foreach (var parameter in method.ParameterList.Parameters)
//            {
//                bool isRef = parameter.Modifiers.Any(SyntaxKind.OutKeyword) ||
//                             parameter.Modifiers.Any(SyntaxKind.RefKeyword);
//
//                if (firstParam)
//                    firstParam = false;
//                else
//                {
//                    writer.Write(", ");
//                }
//
//
//                var localSymbol = TypeProcessor.GetTypeInfo(parameter.Type);
//                var ptr = (localSymbol.Type != null && !localSymbol.Type.IsValueType) ? "" : "";
//
//                if (!isRef)
//                {
//                    var s = TypeProcessor.ConvertType(parameter.Type) + " " + ptr;
//                    writer.Write(s);
//                }
//                else
//                {
//
//
//
//                    var s = " ref " + TypeProcessor.ConvertType(parameter.Type) + " "; // Refs in D are simple
//
//                    writer.Write(s);
//
//                    Program.RefOutSymbols.TryAdd(TypeProcessor.GetDeclaredSymbol(parameter), null);
//                }
//
//                writer.Write(WriteIdentifierName.TransformIdentifier(parameter.Identifier.ValueText));
//
//                if (parameter.Default != null)
//                {
//                    writer.Write(" = ");
//                    Core.Write(writer, parameter.Default.Value);
//                }
//            }
//
//            writer.Write(")");

            writer.WriteLine(accessmodifiers + "this" + WriteMethod.GetParameterListAsString(method.ParameterList));

            if (isInterface || method.Modifiers.Any(SyntaxKind.AbstractKeyword))
            {
                writer.Write(" = 0;\r\n");

                return;
            }

            //if (!returnsVoid)
            //  writer.Write(" =");

//            writer.Write("\r\n");
            writer.OpenBrace();

            if (method.Initializer != null)
            {
                //writer.Write(":");
                Core.Write(writer, method.Initializer);
                writer.Write(";");
                writer.WriteLine(); //";\r\n");
            }

            if (method.Body != null)
            {
                foreach (var statement in method.Body.Statements)
                {
                    Core.Write(writer, statement);
                }

                TriviaProcessor.ProcessTrivias(writer, method.Body.DescendantTrivia());
            }

            writer.CloseBrace();
        }
Beispiel #7
0
        private static void WriteOutBoxed(OutputWriter writer, List <ITypeSymbol> genericArgs, List <ITypeSymbol> bases)
        {
            //Implement Boxed!T
            if (Context.Instance.Type.TypeKind == TypeKind.Struct)
            {
                writer.WriteLine();
                var typeName = TypeProcessor.ConvertType(Context.Instance.Type); /*TypeName(Context.Instance.Type, false) +
                                                                                  * (Context.Instance.Type.IsGenericType && genericArgs.Any()
                                                                                  * ? ("!(" + string.Join(" , ", genericArgs.Select(o => o)) + ")")
                                                                                  * : "");*/

                var baseString = "";

                foreach (var baseType in bases.OrderBy(o => o.TypeKind == TypeKind.Interface ? 1 : 0))
                {
                    baseString += (" ,");

                    baseString += (TypeProcessor.ConvertType(baseType, false));
                }

                writer.WriteLine("public static class __Boxed_" + " " +
                                 //(genericArgs.Any() ? ("( " + (string.Join(" , ", genericArgs.Select(o => o)) + " )")) : "") +//Internal boxed should not be generic
                                 ": Boxed!(" + typeName + ")" + baseString);

                writer.OpenBrace();



                writer.WriteLine("import std.traits;");

                var members = new List <ISymbol>();

                foreach (var baseType in bases.Where(o => o.TypeKind == TypeKind.Interface))
                {
                    members.AddRange(Utility.GetAllMembers(baseType));
                }

                //  foreach (var baseType in bases.Where(o => o.TypeKind == TypeKind.Interface))
                //{

                var ifacemembers = members.DistinctBy(k => k);//Utility.GetAllMembers(Context.Instance.Type);

                foreach (var member in ifacemembers)
                {
                    var findImplementationForInterfaceMember = Context.Instance.Type.FindImplementationForInterfaceMember(member);
                    if (findImplementationForInterfaceMember == null)
                    {
                        continue;
                    }
                    var ifacemethod =
                        findImplementationForInterfaceMember
                        .DeclaringSyntaxReferences.First()
                        .GetSyntax();

                    var syntax = ifacemethod as MethodDeclarationSyntax;
                    if (syntax != null)
                    {
                        WriteMethod.WriteIt(writer, syntax);
                    }

                    var property = ifacemethod as PropertyDeclarationSyntax;
                    if (property != null)
                    {
                        WriteProperty.Go(writer, property, true);
                    }
                }


                //                {
                //                    writer.WriteLine("public override String ToString()");
                //                    writer.OpenBrace();
                //                    writer.WriteLine("return __Value.ToString();", Program.GetGenericMetadataName(Context.Instance.Type));
                //                    writer.CloseBrace();
                //                }

                //}

                //This is required to be able to create an instance at runtime / reflection
                //					this()
                //					{
                //						super(SimpleStruct.init);
                //					}

                writer.WriteLine();
                writer.WriteLine("this()");
                writer.OpenBrace();
                writer.WriteLine("super({0}.init);", typeName); //TODO fix this for another TypeNew that calls the valuetype constructor only
                writer.CloseBrace();

                //                if (Context.Instance.Type.GetMembers("ToString").Any()) // Use better matching ?
                {
                    //					writer.WriteLine ();
                    writer.WriteLine("public override String ToString()");
                    writer.OpenBrace();
                    writer.WriteLine("return __Value.ToString();");
                    writer.CloseBrace();
                }

                writer.WriteLine();
                writer.WriteLine("this(ref " + typeName + " value)");
                writer.OpenBrace();
                writer.WriteLine("super(value);");
                writer.CloseBrace();

                writer.WriteLine();
                writer.WriteLine("U opCast(U)()");
                writer.WriteLine("if(is(U:{0}))", typeName);
                writer.OpenBrace();
                writer.WriteLine("return __Value;");
                writer.CloseBrace();

                writer.WriteLine();
                writer.WriteLine("U opCast(U)()");
                writer.WriteLine("if(!is(U:{0}))", typeName);
                writer.OpenBrace();
                writer.WriteLine("return this;");
                writer.CloseBrace();

                writer.WriteLine();
                writer.WriteLine("auto opDispatch(string op, Args...)(Args args)");
                writer.OpenBrace();
                writer.WriteLine("enum name = op;");
                writer.WriteLine("return __traits(getMember, __Value, name)(args);");
                writer.CloseBrace();



                writer.WriteLine();
                writer.WriteLine("public override Type GetType()");
                writer.OpenBrace();
                writer.WriteLine("return __Value.GetType();");
                writer.CloseBrace();



                writer.CloseBrace();
            }
        }
Beispiel #8
0
        public static void Go()
        {
            var partials = Context.Instance.Partials;
            var first    = partials.First();

            Context.Instance.Namespace = first.Symbol.ContainingNamespace.FullName();
            Context.Instance.Type      = first.Symbol;
            TypeProcessor.ClearUsedTypes();
            var mynamespace = Context.Instance.Type.ContainingNamespace.FullName().RemoveFromEndOfString(".Namespace");

            // + "." + TypeState.Instance.TypeName;
            Console.WriteLine("Writing out type: " + Context.Instance.Namespace + "." + Context.Instance.TypeName);
            if ((Context.Instance.Namespace + "." + Context.Instance.TypeName) ==
                "Mono.Security.X509.Namespace.X509Chain")
            {
            }

            var myUsingDirective     = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(mynamespace));
            var SystemUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System"));
            // Required as certain functions like boxing are in this namespace
            var namespaces      = first.Syntax.Parent.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray();
            var usingStatements = first.Syntax.Parent.DescendantNodes().OfType <UsingStatementSyntax>().ToArray();

            Context.Instance.UsingDeclarations = namespaces
                                                 .Union(new[]
            {
                myUsingDirective, SystemUsingDirective
            }).ToArray();

            var objectType =
                TypeProcessor.GetSemanticModel(partials.First().Syntax)
                .Compilation.GetTypeByMetadataName("System.Object");

            using (var writer = new OutputWriter(Context.Instance.Namespace, Context.Instance.TypeName))
            {
                var bases = partials
                            .Select(o => o.Syntax.BaseList)
                            .Where(o => o != null)
                            .SelectMany(o => o.Types)
                            .Select(o => TypeProcessor.GetTypeInfo(o.Type).ConvertedType)
                            .Distinct()
                            .ToList();

                //                var interfaces = bases.Where(o => o.TypeKind == TypeKind.Interface).ToList();

                if (!bases.Any((j => j.TypeKind != TypeKind.Interface)) &&
                    !(first.Symbol.TypeKind == TypeKind.Interface || first.Symbol.TypeKind == TypeKind.Struct))
                {
                    //TODO: fix structs using mixins / alias this
                    bases.Add(objectType);
                }

                //                    WriteStandardIncludes.Go(writer);

                //                    writer.WriteLine(String.Format("#include \"{0}\"", TypeState.Instance.TypeName + ".h"));

                WriteBcl.Go(writer);

                //TypeState.Instance.DerivesFromObject = bases.Count == interfaces.Count;

                var @namespace = first.Symbol.ContainingNamespace.FullName();

                //Module name = namespace + "." + typename;

                WriteStandardIncludes.Go(writer);

                //                    var namespaces = @namespace.Split(new string[] { "." }, StringSplitOptions.None);
                //
                //                    if (@namespace.Length > 0)
                //                    {
                //                        foreach (var ns in namespaces)
                //                        {
                //                            writer.WriteLine("namespace " + ns + "\r\n{");
                //                            writer.WriteLine("namespace " + ns + "\r\n{");
                //                        }
                //
                //                    }

                //TODO: Fix enum support
                if (first.Syntax is EnumDeclarationSyntax)
                {
                    WriteEnum.Go(writer,
                                 Context.Instance.Partials.Select(o => o.Syntax)
                                 .Cast <EnumDeclarationSyntax>()
                                 .SelectMany(o => o.Members)
                                 .Where(o => !Program.DoNotWrite.ContainsKey(o)));

                    return;
                }

                Context.Instance.AllMembers =
                    partials.Select(o => o.Syntax)
                    .Cast <TypeDeclarationSyntax>()
                    .SelectMany(o => o.Members)
                    .Where(o => !Program.DoNotWrite.ContainsKey(o))
                    .ToList();

                var allMembersToWrite = Context.Instance.AllMembers
                                        .Where(member => !(member is TypeDeclarationSyntax) &&
                                               !(member is EnumDeclarationSyntax) &&
                                               !(member is DelegateDeclarationSyntax) &&
                                               !(member is ConstructorDeclarationSyntax))
                                        .ToList();

                var instanceCtors = Context.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>()
                                    .Where(o => !o.Modifiers.Any(SyntaxKind.StaticKeyword))
                                    .ToList();

                var staticCtors = Context.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>()
                                  .Where(o => (o.Modifiers.Any(SyntaxKind.StaticKeyword)))
                                  .ToList();

                //TODO: Add support for overloading constructing
                //                    if (instanceCtors.Count > 1)
                //                        throw new Exception(
                //                            "Overloaded constructors are not supported.  Consider changing all but one to static Create methods " +
                //                            Utility.Descriptor(first.Syntax));

                //                    var ctorOpt = instanceCtors.SingleOrDefault();
                //TODO: Handle interfaces by

                /*
                 * class Interface
                 * {
                 *  public:
                 *      virtual ~Interface() { }
                 *      virtual void test() = 0; // Functions, must all be virtual
                 * }
                 */

                var membersToWrite = allMembersToWrite.ToList();
                //.Where(o => IsStatic(o) == staticMembers).ToList();

                //                    if (membersToWrite.Count == 0 && (partials.Any(o => o.Syntax.Modifiers.Any(SyntaxKind.StaticKeyword))))
                //                        continue;

                //                    if (staticMembers)
                //                        writer.Write("object ");
                //                    else if (first.Syntax.Kind == SyntaxKind.InterfaceDeclaration)
                //                        writer.Write("trait ");
                //                    else
                //                    {
                //                        if (partials.Any(o => o.Syntax.Modifiers.Any(SyntaxKind.AbstractKeyword)))
                //                            writer.Write("abstract ");

                //                    }

                // writer.Write(TypeState.Instance.TypeName);

                if (first.Syntax is TypeDeclarationSyntax)
                {
                    //Look for generic arguments
                    var genericArgs = partials
                                      .Select(o => o.Syntax)
                                      .Cast <TypeDeclarationSyntax>()
                                      .Where(o => o.TypeParameterList != null)
                                      .SelectMany(o => o.TypeParameterList.Parameters)
                                      .ToList();

                    if (Context.Instance.Type.TypeKind == TypeKind.Class)
                    {
                        writer.Write("class ");
                    }
                    else if (Context.Instance.Type.TypeKind == TypeKind.Interface)
                    {
                        writer.Write("interface ");
                    }
                    else if (Context.Instance.Type.TypeKind == TypeKind.Struct)
                    {
                        writer.Write("struct ");
                        //						writer.Write (" class "); // Allows inheritance ... but too many issues, will look at this when it gets relevant
                    }
                    else
                    {
                        throw new Exception("don't know how to write type: " + Context.Instance.Type.TypeKind);
                    }
                    //writer.Write (((TypeState.Instance.Type.TypeKind== TypeKind.Interface)?" interface ": ) );

                    writer.Write(Context.Instance.TypeName);

                    if (genericArgs.Count > 0)
                    {
                        writer.Write("( ");
                        writer.Write(string.Join(" , ", genericArgs.Select(o => o)));
                        writer.Write(" )");
                    }

                    bool firstBase = true;

                    if (Context.Instance.Type.TypeKind != TypeKind.Struct)
                    {
                        foreach (var baseType in bases.OrderBy(o => o.TypeKind == TypeKind.Interface ? 1 : 0))
                        {
                            writer.Write(firstBase ? " : " : " ,");

                            writer.Write(TypeProcessor.ConvertType(baseType));

                            //                            if (firstBase && ctorOpt != null && ctorOpt.Initializer != null &&
                            //                                ctorOpt.Initializer.ArgumentList.Arguments.Count > 0)
                            //                            {
                            //                                writer.Write("(");
                            //                                bool firstArg = true;
                            //                                foreach (var init in ctorOpt.Initializer.ArgumentList.Arguments)
                            //                                {
                            //                                    if (firstArg)
                            //                                        firstArg = false;
                            //                                    else
                            //                                        writer.Write(", ");
                            //
                            //                                    Core.Write(writer, init.Expression);
                            //                                }
                            //                                writer.Write(")");
                            //                            }

                            firstBase = false;
                        }
                    }
                }

                writer.WriteLine();

                writer.OpenBrace();

                var fields    = membersToWrite.OfType <FieldDeclarationSyntax>().ToList();
                var nonFields = membersToWrite.Except(fields); // also static fields should be separately dealt with

                var structLayout = first.Syntax.GetAttribute(Context.StructLayout);
                if (structLayout != null)
                {
                    LayoutKind value = LayoutKind.Auto;
                    if (
                        structLayout.ArgumentList.Arguments.Any(
                            k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Value"))
                    {
                        value =
                            (LayoutKind)
                            Enum.Parse(typeof(LayoutKind),
                                       structLayout.ArgumentList.Arguments.FirstOrDefault(
                                           k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Value")
                                       .Expression.ToFullString()
                                       .SubstringAfterLast('.'));
                        //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                    }
                    //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                    else if (structLayout.ArgumentList.Arguments.Count > 0 &&
                             structLayout.ArgumentList.Arguments[0].NameEquals == null)
                    {
                        value =
                            (LayoutKind)
                            Enum.Parse(typeof(LayoutKind),
                                       structLayout.ArgumentList.Arguments[0].Expression.ToFullString()
                                       .SubstringAfterLast('.'));
                    }
                    int     pack    = -1;
                    int     size    = -1;
                    CharSet charset = CharSet.Auto;
//					if (structLayout.ArgumentList.Arguments.Count > 1)
                    {
                        try
                        {
                            if (
                                structLayout.ArgumentList.Arguments.Any(
                                    k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "CharSet"))
                            {
                                charset =
                                    (CharSet)
                                    Enum.Parse(typeof(CharSet),
                                               structLayout.ArgumentList.Arguments.FirstOrDefault(
                                                   k =>
                                                   k.NameEquals != null &&
                                                   k.NameEquals.Name.ToFullString().Trim() == "CharSet")
                                               .Expression.ToFullString()
                                               .SubstringAfterLast('.'));
                                //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                            }
                            //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                            else if (structLayout.ArgumentList.Arguments.Count > 1 &&
                                     structLayout.ArgumentList.Arguments[1].NameEquals == null)
                            {
                                charset =
                                    (CharSet)
                                    Enum.Parse(typeof(CharSet),
                                               structLayout.ArgumentList.Arguments[1].Expression.ToFullString()
                                               .SubstringAfterLast('.'));
                            }
                        }
                        catch (Exception ex)
                        {
                        }

                        try
                        {
                            if (
                                structLayout.ArgumentList.Arguments.Any(
                                    k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Pack"))
                            {
                                pack =
                                    int.Parse(
                                        structLayout.ArgumentList.Arguments.FirstOrDefault(
                                            k =>
                                            k.NameEquals != null &&
                                            k.NameEquals.Name.ToFullString().Trim() == "Pack")
                                        .Expression.ToFullString());
                            }
                            //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                            else if (structLayout.ArgumentList.Arguments.Count > 2 &&
                                     structLayout.ArgumentList.Arguments[2].NameEquals == null)
                            {
                                pack = int.Parse(structLayout.ArgumentList.Arguments[2].Expression.ToFullString());
                            }
                        }
                        catch (Exception ex)
                        {
                        }

                        try
                        {
                            if (
                                structLayout.ArgumentList.Arguments.Any(
                                    k => k.NameEquals != null && k.NameEquals.Name.ToFullString().Trim() == "Size"))
                            {
                                size =
                                    int.Parse(
                                        structLayout.ArgumentList.Arguments.FirstOrDefault(
                                            k => k.NameColon != null && k.NameColon.ToFullString().Trim() == "Size")
                                        .Expression.ToFullString());
                            }
                            //structLayout.ArgumentList.Arguments.Where (k => k.Expression is MemberAccessExpressionSyntax).FirstOrDefault(k=>(k.Expression as MemberAccessExpressionSyntax).Name.ToFullString() == "Value");
                            else if (structLayout.ArgumentList.Arguments.Count > 3 &&
                                     structLayout.ArgumentList.Arguments[3].NameEquals == null)
                            {
                                size = int.Parse(structLayout.ArgumentList.Arguments[3].Expression.ToFullString());
                            }
                        }
                        catch (Exception ex)
                        {
                        }

//						size = int.Parse (structLayout.ArgumentList.Arguments [3].Expression.ToFullString ());
                    }
                    //					var pack = structLayout.ArgumentList.Arguments.FirstOrDefault (k => k.NameColon.Name.ToFullString() == "Pack");
//					var charset = structLayout.ArgumentList.Arguments.FirstOrDefault (k => k.NameColon.Name.ToFullString() == "CharSet");
//					var size = structLayout.ArgumentList.Arguments.FirstOrDefault (k => k.NameColon.Name.ToFullString() == "Size");

                    if (value == LayoutKind.Explicit)
                    {
                        var fieldGroups =
                            fields.GroupBy(f => f.GetAttribute(Context.FieldOffset).ArgumentList.Arguments[0].ToString())
                            .OrderBy(k => k.Key);
                        writer.Indent++;

                        foreach (var group in fieldGroups)
                        {
                            writer.WriteLine("//FieldOffset(" + @group.Key + ")");
                            writer.WriteLine("union {");
                            foreach (var member in group)
                            {
                                Core.Write(writer, member);
                            }
                            writer.WriteLine("}");
                        }

//						foreach (var member in fields)
//						{
//							//                    writer.WriteLine();
//							Core.Write (writer, member);
//						}
                    }
                    else if (value == LayoutKind.Sequential)
                    {
                        fields = SortFields(fields);

                        writer.Indent++;

                        foreach (var member in fields)
                        {
                            if (pack != -1)
                            {
                                writer.WriteLine("align (" + pack + "): //Pack = " + pack);
                            }
                            //                    writer.WriteLine();
                            Core.Write(writer, member);
                        }
                    }

                    else
                    {
                        //Looks like C# aligns to 1 by default ... don't know about D...
                        fields = SortFields(fields);

                        writer.Indent++;
                        foreach (var member in fields)
                        {
                            pack = 1;
                            writer.WriteLine("align (" + pack + "): //Pack = " + pack + "C# default");
                            //                    writer.WriteLine();
                            Core.Write(writer, member);
                        }
                    }
                }
                else
                {
                    //Looks like C# aligns to 1 by default ... don't know about D...
                    fields = SortFields(fields);

                    writer.Indent++;
                    foreach (var member in fields)
                    {
                        var pack = 1;
                        writer.WriteLine("align (" + pack + "): //Pack = " + pack + "C# default");
                        //                    writer.WriteLine();
                        Core.Write(writer, member);
                    }
                }

                foreach (var member in nonFields)
                {
//                    writer.WriteLine();
                    Core.Write(writer, member);
                }

                foreach (var constructor in instanceCtors)
                {
//                    writer.WriteLine();
                    Core.Write(writer, constructor);
                }

                if (staticCtors.Count == 0)
                {
                    if (Context.Instance.StaticInits.Count > 0)
                    {
                        var constructor = SyntaxFactory.ConstructorDeclaration(Context.Instance.TypeName);
                        constructor =
                            constructor.WithModifiers(
                                SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.StaticKeyword)));

                        WriteConstructorBody.WriteStaticConstructor(writer, constructor, Context.Instance.StaticInits);

                        staticCtors.Add(constructor);
                    }
                }
                else
                {
                    var isFirst = true;
                    foreach (ConstructorDeclarationSyntax constructor in staticCtors)
                    {
                        if (isFirst)
                        {
                            WriteConstructorBody.WriteStaticConstructor(writer, constructor,
                                                                        Context.Instance.StaticInits);
                        }
                        else
                        {
                            WriteConstructorBody.Go(writer, constructor);
                        }

                        isFirst = false;
                    }
                }

                var dllImports = Context.Instance.DllImports;
                // This should only be written once ... I guess we have to put the detection logic in Program.cs

                if (Context.Instance.EntryMethod != null)
                {
                    if (dllImports.Count > 0)
                    {
                        writer.WriteLine();

                        writer.WriteLine(String.Format("static void * __DllImportMap[{0}];", dllImports.Count));
                        writer.WriteLine("static void __SetupDllImports()");

                        writer.OpenBrace();

                        for (int index = 0; index < dllImports.Count; index++)
                        {
                            var dllImport = dllImports[index];
                            writer.WriteLine(String.Format("__DllImportMap[{0}] = LoadNativeLibrary(cast(string){1});",
                                                           index, dllImport.ArgumentList.Arguments.FirstOrDefault(k => k.Expression != null)));
                        }
                        writer.CloseBrace();
                        writer.WriteLine();
                        writer.WriteLine("static void __FreeDllImports()");
                        writer.OpenBrace();
                        writer.WriteLine(String.Format(@"for(int i=0;i<{0};i++)", dllImports.Count));
                        writer.OpenBrace();
                        writer.WriteLine("if(__DllImportMap[i]!=null)");
                        writer.WriteLine("\tFreeNativeLibrary(__DllImportMap[i]);");
                        writer.CloseBrace();
                        writer.CloseBrace();

                        //                            if (hModule != null)
                        //                            {
                        //    ::FreeLibrary(hModule);
                        //                            }
                    }
                }
                writer.Indent--;
                writer.CloseBrace();

                //Implement Boxed!Interface
                if (Context.Instance.Type.TypeKind == TypeKind.Struct)
                {
                    writer.WriteLine();
                    var typeName = Context.Instance.TypeName;
                    writer.Write("public class __Boxed_" + typeName + " : Boxed!(" + typeName + ")");
                    foreach (var baseType in bases.OrderBy(o => o.TypeKind == TypeKind.Interface ? 1 : 0))
                    {
                        writer.Write(" ,");

                        writer.Write(TypeProcessor.ConvertType(baseType, false));
                    }

                    writer.OpenBrace();

                    //FIXME:This is giving issues, we will just generate them here

//					writer.WriteLine ("import Irio.Utilities;");

                    writer.WriteLine("import std.traits;");

                    foreach (var baseType in bases.Where(o => o.TypeKind == TypeKind.Interface))
                    {
                        //FIXME:This is giving issues, we will just generate them here
//						writer.WriteLine ("mixin(__ImplementInterface!({0}, Value));",TypeProcessor.ConvertType(baseType,false));
                        var ifacemembers = baseType.GetMembers();

                        foreach (var member in ifacemembers)
                        {
                            var ifacemethod =
                                Context.Instance.Type.FindImplementationForInterfaceMember(member)
                                .DeclaringSyntaxReferences.First()
                                .GetSyntax();
//								.Where(member => !(member is TypeDeclarationSyntax)
//									&& !(member is EnumDeclarationSyntax)
//									&& !(member is DelegateDeclarationSyntax) && !(member is ConstructorDeclarationSyntax))
//								.ToList();

                            //                    writer.WriteLine();
//							Core.Write(writer, member);

                            if (ifacemethod is MethodDeclarationSyntax)
                            {
                                WriteMethod.WriteIt(writer, (MethodDeclarationSyntax)ifacemethod);
                            }
                            else if (ifacemethod is PropertyDeclarationSyntax)
                            {
                                WriteProperty.Go(writer, (PropertyDeclarationSyntax)ifacemethod, true);
                            }
                        }
                    }

                    //This is required to be able to create an instance at runtime / reflection
//					this()
                    //					{
                    //						super(SimpleStruct.init);
                    //					}

                    writer.WriteLine();
                    writer.WriteLine("this()");
                    writer.OpenBrace();
                    writer.WriteLine("super({0}.init);", typeName);
                    writer.CloseBrace();

                    if (Context.Instance.Type.GetMembers("ToString").Count() >= 1) // Use better matching ?
                    {
                        //					writer.WriteLine ();
                        writer.WriteLine("override String ToString()");
                        writer.OpenBrace();
                        writer.WriteLine("return Value.ToString();");
                        writer.CloseBrace();
                    }

                    writer.WriteLine();
                    writer.WriteLine("this(ref " + typeName + " value)");
                    writer.OpenBrace();
                    writer.WriteLine("super(value);");
                    writer.CloseBrace();

                    writer.WriteLine();
                    writer.WriteLine("U opCast(U)()");
                    writer.WriteLine("if(is(U:{0}))", typeName);
                    writer.OpenBrace();
                    writer.WriteLine("return Value;");
                    writer.CloseBrace();

                    writer.WriteLine();
                    writer.WriteLine("U opCast(U)()");
                    writer.WriteLine("if(!is(U:{0}))", typeName);
                    writer.OpenBrace();
                    writer.WriteLine("return this;");
                    writer.CloseBrace();

                    writer.WriteLine();
                    writer.WriteLine("auto opDispatch(string op, Args...)(Args args)");
                    writer.OpenBrace();
                    writer.WriteLine("enum name = op;");
                    writer.WriteLine("return __traits(getMember, Value, name)(args);");
                    writer.CloseBrace();

                    writer.CloseBrace();
                }

                if (Context.Instance.EntryMethod != null)
                {
                    //TODO: DllImports should be centralized

                    //
                    writer.WriteLine();
                    writer.WriteLine("void main(string[] args)");
                    writer.OpenBrace();

                    if (dllImports.Count > 0)
                    {
                        writer.WriteLine(Context.Instance.TypeName + ".__SetupDllImports();");
                    }
                    writer.WriteLine(Context.Instance.EntryMethod);
                    if (dllImports.Count > 0)
                    {
                        writer.WriteLine(Context.Instance.TypeName + ".__FreeDllImports();");
                    }

                    writer.CloseBrace();
                }

                //				var mySpecializations = Program.AllGenericSpecializations.Where (t => t.OriginalDefinition == TypeState.Instance.Type);
                //
                //
                //				foreach (var specialization in mySpecializations) {
                //
                //					var specializationText = ("template class " + specialization.GetFullNameD (false) + " (" +
                //					                                            (string.Join (" , ",
                //						                                            specialization.TypeArguments.Select (
                //							                                            o =>
                //                                                                       TypeProcessor.ConvertType (o) +
                //							                                            ((o.IsValueType ||
                //							                                            o.TypeKind == TypeKind.TypeParameter)
                //                                                                           ? ""
                //                                                                           : "*"))) +
                //							");"));
                //					writer.Write (specializationText);
                //				}

                //                    if (@namespace.Length > 0)
                //                    {
                //                        foreach (var ns in namespaces)
                //                        {
                //                            writer.WriteLine("\n\n}");
                //                            writer.WriteLine("\n\n}");
                //                        }
                //                    }
            }
        }
Beispiel #9
0
        /*
         * template Action(T) {
         * alias void delegate(T obj) Action;
         * }
         *
         */


        public static void Go()
        {
            var partials = Context.Instance.DelegatePartials;
            var first    = partials.First();

            Context.Instance.Namespace = first.Symbol.ContainingNamespace.FullName();
            Context.Instance.Type      = first.Symbol;
            TypeProcessor.ClearUsedTypes();
            var mynamespace = Context.Instance.Type.ContainingNamespace.FullName().RemoveFromEndOfString(".Namespace");
            // + "." + TypeState.Instance.TypeName;

            var myUsingDirective     = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(mynamespace));
            var SystemUsingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System"));

            // Required as certain functions like boxing are in this namespace
            Context.Instance.UsingDeclarations =
                first.Syntax.Parent.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray()
                .Union(new[]
            {
                myUsingDirective, SystemUsingDirective
            }).ToArray();

            using (var writer = new OutputWriter(Context.Instance.Namespace, Context.Instance.TypeName))
            {
                var objectType =
                    TypeProcessor.GetSemanticModel(partials.First().Syntax)
                    .Compilation.GetTypeByMetadataName("System.Object");

                WriteBcl.Go(writer);

                var @namespace = first.Symbol.ContainingNamespace.FullName();

                WriteStandardIncludes.Go(writer);

                //Look for generic arguments

                //Look for generic arguments
                var genericArgs = partials.Select(o => o.Syntax)
                                  .Where(o => o.TypeParameterList != null)
                                  .SelectMany(o => o.TypeParameterList.Parameters)
                                  .ToList();

                var name = Context.Instance.TypeName;

                if (genericArgs.Count > 0)
                {
                    name  = "template " + name;
                    name += ("( ");
                    name += (string.Join(" , ", genericArgs.Select(o => o)));
                    name += (" )");

                    writer.Write(name);

                    writer.Write("\r\n");

                    writer.OpenBrace();
                    writer.Indent++;

                    writer.Write("alias Delegate!(" + TypeProcessor.ConvertType(first.Syntax.ReturnType) + " delegate" +
                                 WriteMethod.GetParameterListAsString(first.Syntax.ParameterList));

                    writer.Write(") " + Context.Instance.TypeName + ";");

                    writer.Indent--;
                    writer.Write("\r\n");
                    writer.CloseBrace();
                }
                else
                {
                    //Non-generic
                    writer.Write("alias Delegate!(" + TypeProcessor.ConvertType(first.Syntax.ReturnType) + " delegate" +
                                 WriteMethod.GetParameterListAsString(first.Syntax.ParameterList));

                    writer.Write(") " + Context.Instance.TypeName + ";");
                }
            }
        }