Пример #1
0
        public static void Go(HaxeWriter writer, SyntaxTokenList modifiers, string name, TypeSyntax type, EqualsValueClauseSyntax initializerOpt = null)
        {
            writer.WriteIndent();

            var isConst = IsConst(modifiers, initializerOpt, type);

            WriteFieldModifiers(writer, modifiers);
            if (isConst)
            {
                writer.Write("inline ");
            }

            writer.Write("var ");

            writer.Write(name);
            writer.Write(TypeProcessor.ConvertTypeWithColon(type));

            if (isConst)
            {
                writer.Write(" = ");
                Core.Write(writer, initializerOpt.Value);
            }

            writer.Write(";");
            writer.WriteLine();
        }
Пример #2
0
        public static void WriteIndexerDeclaration(HaxeWriter writer, IndexerDeclarationSyntax decl)
        {
            foreach (var accessor in decl.AccessorList.Accessors)
            {
                writer.WriteIndent();

                if (decl.Modifiers.Any(SyntaxKind.OverrideKeyword) || decl.Modifiers.Any(SyntaxKind.NewKeyword))
                {
                    writer.Write("override ");
                }
                if (decl.Modifiers.Any(SyntaxKind.PublicKeyword) || decl.Modifiers.Any(SyntaxKind.ProtectedKeyword) || decl.Modifiers.Any(SyntaxKind.InternalKeyword))
                {
                    writer.Write("public ");
                }
                if (decl.Modifiers.Any(SyntaxKind.PrivateKeyword))
                {
                    writer.Write("private ");
                }

                var isGet = accessor.Kind() == SyntaxKind.GetAccessorDeclaration;


                writer.Write("function ");
                writer.Write(isGet ? "Get" : "Set");
                writer.Write("Value_");
                writer.Write(Program.GetModel(decl).GetTypeInfo(decl.ParameterList.Parameters.Single().Type).Type.Name);
                writer.Write("(");

                foreach (var prm in decl.ParameterList.Parameters)
                {
                    writer.Write(prm.Identifier.ValueText);
                    writer.Write(TypeProcessor.ConvertTypeWithColon(prm.Type));
                }

                if (isGet)
                {
                    writer.Write(")");
                    writer.Write(TypeProcessor.ConvertTypeWithColon(decl.Type));
                }
                else
                {
                    writer.Write(", value");
                    writer.Write(TypeProcessor.ConvertTypeWithColon(decl.Type));
                    writer.Write("):Void");
                }
                writer.WriteLine();

                if (accessor.Body != null)
                {
                    Core.Write(writer, accessor.Body);
                }
            }
        }
Пример #3
0
        public static void Go(HaxeWriter writer, UsingStatementSyntax usingStatement)
        {
            if (usingStatement.DescendantNodes().OfType <ReturnStatementSyntax>().Any())
            {
                throw new Exception("CS2HX does not support returning from within a using block. " + Utility.Descriptor(usingStatement));
            }

            var expression = usingStatement.Expression;
            //if (expression is ExpressionStatement)
            //	expression = expression.As<ExpressionStatement>().Expression;

            //Ensure the using statement is a local variable - we can't deal with things we can't reliably repeat in the finally block
            var resource = Utility.TryGetIdentifier(expression);

            if (resource == null)
            {
                throw new Exception("Using statements must reference a local variable. " + Utility.Descriptor(usingStatement));
            }

            writer.WriteLine("var __disposed_" + resource + ":Bool = false;");
            writer.WriteLine("try");
            writer.WriteOpenBrace();

            if (usingStatement.Statement is BlockSyntax)
            {
                foreach (var s in usingStatement.Statement.As <BlockSyntax>().Statements)
                {
                    Core.Write(writer, s);
                }
            }
            else
            {
                Core.Write(writer, usingStatement.Statement);
            }

            writer.WriteLine("__disposed_" + resource + " = true;");
            writer.WriteLine(resource + ".Dispose();");
            writer.WriteCloseBrace();

            writer.WriteLine("catch (__catch_" + resource + ":Dynamic)");
            writer.WriteOpenBrace();
            writer.WriteLine("if (!__disposed_" + resource + ")");
            writer.WriteLine("    " + resource + ".Dispose();");
            writer.WriteLine("throw __catch_" + resource + ";");
            writer.WriteCloseBrace();
        }
Пример #4
0
        public static void Go(HaxeWriter writer, BreakStatementSyntax statement)
        {
            //Traverse up to figure out what we're breaking from.  If we're breaking from a loop, it's fine.  However, if we're breaking from a switch statement, throw an error as haxe doesn't allow this.
            var breakingFrom = statement.Parent;

            while (!(breakingFrom is WhileStatementSyntax || breakingFrom is ForStatementSyntax || breakingFrom is DoStatementSyntax || breakingFrom is ForEachStatementSyntax))
            {
                if (breakingFrom is SwitchStatementSyntax)
                {
                    throw new Exception("Cannot \"break\" from within a switch statement. " + Utility.Descriptor(statement));
                }

                breakingFrom = breakingFrom.Parent;
            }


            writer.WriteLine("break;");
        }
Пример #5
0
        public static void WriteConstructorsHelper(IEnumerable <INamedTypeSymbol> allTypes, string nameArg)
        {
            foreach (var t in allTypes.Select(o => o.ContainingNamespace.FullNameWithDot().ToLower() + WriteType.TypeName(o)))
            {
                AllTypes.Add(t);
            }

            var name = string.IsNullOrWhiteSpace(nameArg) ? "Constructors" : nameArg;


            using (var writer = new HaxeWriter("", name))
            {
                writer.WriteLine(@"/*
This file serves two purposes:  
    1)  It imports every type that CS2HX generated.  haXe will ignore 
        any types that aren't used by haXe code, so this ensures haXe 
        compiles all of your code.

    2)  It lists all the static constructors.  haXe doesn't have the 
        concept of static constructors, so CS2HX generated cctor()
        methods.  You must call these manually.  If you call
        Constructors.init(), all static constructors will be called 
        at once.
*/
package ;");

                foreach (var type in AllTypes.OrderBy(o => o))
                {
                    writer.WriteLine("import " + type + ";");
                }
                writer.WriteLine("import system.TimeSpan;");

                writer.WriteLine("class " + name);
                writer.WriteOpenBrace();

                writer.WriteLine("public static function init()");
                writer.WriteOpenBrace();
                writer.WriteLine("TimeSpan.cctor();");
                foreach (var cctor in StaticConstructors.OrderBy(o => o))
                {
                    writer.WriteLine(cctor + ".cctor();");
                }
                writer.WriteCloseBrace();
                writer.WriteCloseBrace();
            }
        }
Пример #6
0
        public static void Go(HaxeWriter writer, SyntaxTokenList modifiers, string name, TypeSyntax type, EqualsValueClauseSyntax initializerOpt = null)
        {
            writer.WriteIndent();

            var isConst = IsConst(modifiers, initializerOpt, type);

            WriteFieldModifiers(writer, modifiers);
            if (isConst)
            {
                writer.Write("inline ");
            }

            writer.Write("var ");

            writer.Write(name);
            writer.Write(TypeProcessor.ConvertTypeWithColon(type));

            if (initializerOpt != null)
            {
                writer.Write(" = ");
                Core.Write(writer, initializerOpt.Value);
            }
            else if (GenerateInitializerForFieldWithoutInitializer(type))
            {
                writer.Write(" = ");
                if (TypeProcessor.ValueToReference(type))
                {
                    writer.Write("new ");
                    writer.Write(TypeProcessor.ConvertType(type));
                    writer.Write("()");
                }
                else
                {
                    writer.Write(TypeProcessor.DefaultValue(TypeProcessor.ConvertType(type)));
                }
            }


            writer.Write(";");
            writer.WriteLine();
        }
Пример #7
0
        public static void WriteStaticConstructor(HaxeWriter writer, ConstructorDeclarationSyntax staticConstructorOpt)
        {
            if (staticConstructorOpt == null)
            {
                return; //No static constructor needed
            }
            writer.WriteLine("public static function cctor():Void");
            writer.WriteOpenBrace();


            if (staticConstructorOpt != null && staticConstructorOpt.Body != null)
            {
                foreach (var statement in staticConstructorOpt.Body.As <BlockSyntax>().Statements)
                {
                    Core.Write(writer, statement);
                }
            }

            writer.WriteCloseBrace();

            StaticConstructors.Add(TypeState.Instance.TypeName);
        }
Пример #8
0
        public static void Go(HaxeWriter writer, DoStatementSyntax statement)
        {
            writer.WriteLine("do");
            writer.WriteOpenBrace();

            if (statement.Statement is BlockSyntax)
            {
                foreach (var s in statement.Statement.As <BlockSyntax>().Statements)
                {
                    Core.Write(writer, s);
                }
            }
            else
            {
                Core.Write(writer, statement.Statement);
            }

            writer.WriteCloseBrace();
            writer.WriteIndent();
            writer.Write("while (");
            Core.Write(writer, statement.Condition);
            writer.Write(");\r\n");
        }
Пример #9
0
        public static void Go(HaxeWriter writer, UsingStatementSyntax usingStatement)
        {
            if (usingStatement.DescendantNodes().OfType <ReturnStatementSyntax>().Any())
            {
                throw new Exception("CS2HX does not support returning from within a using block. " + Utility.Descriptor(usingStatement));
            }

            var expression = usingStatement.Expression;
            //if (expression is ExpressionStatement)
            //	expression = expression.As<ExpressionStatement>().Expression;

            //Generate a resource to identify this using block.  If it's a local variable, we'll use that.
            var resource = Utility.TryGetIdentifier(expression);

            if (resource == null)
            {
                var parent = expression.Parent;
                while (!(parent is MethodDeclarationSyntax))
                {
                    parent = parent.Parent;
                }
                var containingMethod = (MethodDeclarationSyntax)parent;
                if (_identities == null)
                {
                    throw new Exception("_identities is null");
                }
                if (containingMethod == null)
                {
                    throw new Exception("containingMethod is null");
                }
                var id = _identities.ValueOrZero(containingMethod);
                _identities.AddTo(containingMethod, 1);

                resource = "__" + id + "_using";

                writer.WriteIndent();
                writer.Write("var " + resource + " = ");
                Core.Write(writer, expression);
                writer.WriteLine(";");
            }

            writer.WriteLine("var __" + resource + "_usingDisposed:Bool = false;");

            writer.WriteLine("try");
            writer.WriteOpenBrace();

            if (usingStatement.Statement is BlockSyntax)
            {
                foreach (var s in usingStatement.Statement.As <BlockSyntax>().Statements)
                {
                    Core.Write(writer, s);
                }
            }
            else
            {
                Core.Write(writer, usingStatement.Statement);
            }

            writer.WriteLine("__" + resource + "_usingDisposed = true;");
            writer.WriteLine(resource + ".Dispose();");
            writer.WriteCloseBrace();

            writer.WriteLine("catch (__catch_" + resource + ":Dynamic)");
            writer.WriteOpenBrace();
            writer.WriteLine("if (!__" + resource + "_usingDisposed)");
            writer.WriteLine("    " + resource + ".Dispose();");
            writer.WriteLine("throw __catch_" + resource + ";");
            writer.WriteCloseBrace();
        }
Пример #10
0
        public static void Go(HaxeWriter writer, PropertyDeclarationSyntax property)
        {
            var  propertySymbol = Program.GetModel(property).GetDeclaredSymbol(property);
            var  isInterface    = propertySymbol.ContainingType.TypeKind == TypeKind.Interface;
            bool isAutoProperty = false;

            Action <AccessorDeclarationSyntax, bool> writeRegion = (region, get) =>
            {
                writer.WriteIndent();

                if (property.Modifiers.Any(SyntaxKind.OverrideKeyword))
                {
                    writer.Write("override ");
                }
                if (property.Modifiers.Any(SyntaxKind.PublicKeyword) || property.Modifiers.Any(SyntaxKind.ProtectedKeyword) || property.Modifiers.Any(SyntaxKind.InternalKeyword))
                {
                    writer.Write("public ");
                }
                if (property.Modifiers.Any(SyntaxKind.PrivateKeyword))
                {
                    writer.Write("private ");
                }
                if (property.Modifiers.Any(SyntaxKind.StaticKeyword))
                {
                    writer.Write("static ");
                }

                writer.Write("function ");
                writer.Write(get ? "get_" : "set_");
                writer.Write(property.Identifier.ValueText);

                string type = TypeProcessor.ConvertType(property.Type);

                if (get)
                {
                    writer.Write("():" + type);
                }
                else
                {
                    writer.Write("(value:" + type + "):" + type);
                }

                var isAbstract = property.Modifiers.Any(SyntaxKind.AbstractKeyword);

                writer.WriteLine();
                writer.WriteOpenBrace();

                if (isAbstract)
                {
                    writer.WriteLine("return throw new Exception(\"Abstract item called\");");
                }
                else
                {
                    if (region.Body == null)
                    {
                        //When we leave the body off in C#, it resolves to an automatic property.
                        isAutoProperty = true;
                        if (get)
                        {
                            writer.WriteLine("return __autoProp_" + property.Identifier.ValueText + ";");
                        }
                        else
                        {
                            writer.WriteLine("__autoProp_" + property.Identifier.Value + " = value;");
                        }
                    }
                    else
                    {
                        foreach (var statement in region.Body.As <BlockSyntax>().Statements)
                        {
                            Core.Write(writer, statement);
                        }
                    }

                    if (!get)
                    {
                        //all haXe property setters must return a value.
                        writer.WriteLine("return value;");
                    }
                }

                writer.WriteCloseBrace();
                writer.WriteLine();
            };

            var getter = property.AccessorList.Accessors.SingleOrDefault(o => o.Keyword.Kind() == SyntaxKind.GetKeyword);
            var setter = property.AccessorList.Accessors.SingleOrDefault(o => o.Keyword.Kind() == SyntaxKind.SetKeyword);

            if (getter == null && setter == null)
            {
                throw new Exception("Property must have either a get or a set");
            }


            if (!property.Modifiers.Any(SyntaxKind.OverrideKeyword))
            {
                //Write the property declaration.  Overridden properties don't need this.
                writer.WriteIndent();
                if (property.Modifiers.Any(SyntaxKind.PublicKeyword) || property.Modifiers.Any(SyntaxKind.InternalKeyword))
                {
                    writer.Write("public ");
                }
                if (property.Modifiers.Any(SyntaxKind.StaticKeyword))
                {
                    writer.Write("static ");
                }

                writer.Write("var ");
                writer.Write(property.Identifier.ValueText);
                writer.Write("(");

                if (getter != null)
                {
                    writer.Write("get_" + property.Identifier.ValueText);
                }
                else
                {
                    writer.Write("never");
                }

                writer.Write(", ");

                if (setter != null)
                {
                    writer.Write("set_" + property.Identifier.ValueText);
                }
                else
                {
                    writer.Write("never");
                }

                writer.Write("):");
                writer.Write(TypeProcessor.ConvertType(property.Type));
                writer.Write(";\r\n");
            }

            if (!isInterface) //interfaces get only the property decl, never the functions
            {
                if (getter != null)
                {
                    writeRegion(getter, true);
                }
                if (setter != null)
                {
                    writeRegion(setter, false);
                }
            }

            if (isAutoProperty)
            {
                writer.WriteLine("var __autoProp_" + property.Identifier.ValueText + TypeProcessor.ConvertTypeWithColon(property.Type) + " = " + TypeProcessor.DefaultValue(TypeProcessor.ConvertType(property.Type)) + ";");
            }
        }
Пример #11
0
        private static void GoInternal(HaxeWriter writer, BaseMethodDeclarationSyntax method, TypeSyntax returnType, TypeParameterListSyntax typeParameterListOpt, SyntaxList <TypeParameterConstraintClauseSyntax>?constraintClassesOpt)
        {
            var methodSymbol = Program.GetModel(method).GetDeclaredSymbol(method);

            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 (TypeState.Instance.Partials.SelectMany(o => o.Syntax.As <ClassDeclarationSyntax>().Members)
                    .OfType <MethodDeclarationSyntax>()
                    .Except(method as MethodDeclarationSyntax)
                    .Where(o => o.Identifier.ValueText == methodSymbol.Name)
                    .Any())
                {
                    return;
                }
            }

            if (methodSymbol.Name == "System.Collections.IEnumerable.GetEnumerator")
            {
                return; //we don't support the non-generic enumerator
            }
            if (methodSymbol.Name == "GetEnumerator")
            {
                WriteGetEnumeratorFunction(writer, method, methodSymbol);
                return;
            }

            writer.WriteIndent();

            if (ShouldUseOverrideKeyword(method, methodSymbol))
            {
                writer.Write("override ");
            }
            if (method.Modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.ProtectedKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword))
            {
                writer.Write("public ");
            }
            if (method.Modifiers.Any(SyntaxKind.PrivateKeyword))
            {
                writer.Write("private ");
            }
            if (method.Modifiers.Any(SyntaxKind.StaticKeyword))
            {
                writer.Write("static ");
            }

            writer.Write("function ");
            var methodName = OverloadResolver.MethodName(methodSymbol);

            if (methodName == "ToString")
            {
                methodName = "toString";
            }

            writer.Write(methodName);

            if (typeParameterListOpt != null)
            {
                writer.Write("<");
                writer.Write(string.Join(", ", typeParameterListOpt.Parameters.Select(o => TypeParameter(o, constraintClassesOpt))));
                writer.Write(">");
            }

            writer.Write("(");

            Dictionary <string, ExpressionSyntax> deferredDefaults;

            WriteParameters(writer, method, methodSymbol, out deferredDefaults);

            writer.Write(")");
            writer.Write(TypeProcessor.ConvertTypeWithColon(returnType));

            if (method.Modifiers.Any(SyntaxKind.AbstractKeyword))
            {
                writer.WriteLine();
                writer.WriteOpenBrace();
                writer.WriteIndent();

                if (returnType.ToString() != "void")
                {
                    writer.Write("return ");                     //"return" the throw statement to work around haxe limitations
                }
                writer.Write("throw new Exception(\"Abstract item called\");\r\n");
                writer.WriteCloseBrace();
            }
            else if (method.Parent is InterfaceDeclarationSyntax)
            {
                writer.Write(";\r\n");
            }
            else
            {
                writer.WriteLine();
                writer.WriteOpenBrace();

                foreach (var defer in deferredDefaults)
                {
                    writer.WriteLine("if (" + defer.Key + " == null)");
                    writer.Indent++;
                    writer.WriteIndent();
                    writer.Write(defer.Key);
                    writer.Write(" = ");
                    Core.Write(writer, defer.Value);
                    writer.Write(";\r\n");
                    writer.Indent--;
                }

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

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

                writer.WriteCloseBrace();
            }
        }
Пример #12
0
        public static void Go(HaxeWriter writer, MethodDeclarationSyntax method)
        {
            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 (TypeState.Instance.Partials.SelectMany(o => o.Syntax.As <ClassDeclarationSyntax>().Members)
                    .OfType <MethodDeclarationSyntax>()
                    .Except(method)
                    .Where(o => o.Identifier.ValueText == method.Identifier.ValueText)
                    .Any())
                {
                    return;
                }
            }

            if (method.Identifier.ValueText == "GetEnumerator")
            {
                return;                 //skip GetEnumerator methods -- haxe can't enumerate on objects.  TODO: Render these out, but convert them to array-returning methods
            }
            var methodSymbol = Program.GetModel(method).GetDeclaredSymbol(method);

            writer.WriteIndent();

            if (ShouldUseOverrideKeyword(method, methodSymbol))
            {
                writer.Write("override ");
            }
            if (method.Modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.ProtectedKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword))
            {
                writer.Write("public ");
            }
            if (method.Modifiers.Any(SyntaxKind.PrivateKeyword))
            {
                writer.Write("private ");
            }
            if (method.Modifiers.Any(SyntaxKind.StaticKeyword))
            {
                writer.Write("static ");
            }

            writer.Write("function ");
            var methodName = OverloadResolver.MethodName(methodSymbol);

            if (methodName == "ToString")
            {
                methodName = "toString";
            }

            writer.Write(methodName);

            if (method.TypeParameterList != null)
            {
                writer.Write("<");
                writer.Write(string.Join(", ", method.TypeParameterList.Parameters.Select(o => TypeParameter(o, method.ConstraintClauses))));
                writer.Write(">");
            }

            writer.Write("(");
            var deferredDefaults = new Dictionary <string, ExpressionSyntax>();

            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(", ");
                }

                writer.Write(parameter.Identifier.ValueText);

                if (isRef)
                {
                    writer.Write(":CsRef<");
                    writer.Write(TypeProcessor.ConvertType(parameter.Type));
                    writer.Write(">");

                    Program.RefOutSymbols.TryAdd(Program.GetModel(method).GetDeclaredSymbol(parameter), null);
                }
                else
                {
                    writer.Write(TypeProcessor.ConvertTypeWithColon(parameter.Type));
                }

                if (parameter.Default != null)
                {
                    writer.Write(" = ");

                    if (TypeProcessor.ConvertType(parameter.Type).StartsWith("Nullable"))
                    {
                        writer.Write("null");
                        deferredDefaults.Add(parameter.Identifier.ValueText, parameter.Default.Value);
                    }
                    else
                    {
                        Core.Write(writer, parameter.Default.Value);
                    }
                }
            }

            writer.Write(")");
            writer.Write(TypeProcessor.ConvertTypeWithColon(method.ReturnType));

            if (method.Modifiers.Any(SyntaxKind.AbstractKeyword))
            {
                writer.WriteLine();
                writer.WriteOpenBrace();
                writer.WriteIndent();

                if (method.ReturnType.ToString() != "void")
                {
                    writer.Write("return ");                     //"return" the throw statement to work around haxe limitations
                }
                writer.Write("throw new Exception(\"Abstract item called\");\r\n");
                writer.WriteCloseBrace();
            }
            else if (method.Parent is InterfaceDeclarationSyntax)
            {
                writer.Write(";\r\n");
            }
            else
            {
                writer.WriteLine();
                writer.WriteOpenBrace();

                foreach (var defer in deferredDefaults)
                {
                    writer.WriteLine("if (" + defer.Key + " == null)");
                    writer.Indent++;
                    writer.WriteIndent();
                    writer.Write(defer.Key);
                    writer.Write(" = ");
                    Core.Write(writer, defer.Value);
                    writer.Write(";\r\n");
                    writer.Indent--;
                }

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

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

                writer.WriteCloseBrace();
            }
        }
Пример #13
0
        public static void WriteInstanceConstructor(HaxeWriter writer, ConstructorDeclarationSyntax ctorOpt)
        {
            writer.WriteIndent();

            writer.Write("public function new(");

            Dictionary <string, ExpressionSyntax> deferredDefaults = null;

            if (ctorOpt != null)
            {
                var methodSymbol = Program.GetModel(ctorOpt).GetDeclaredSymbol(ctorOpt);
                WriteMethod.WriteParameters(writer, ctorOpt, methodSymbol, out deferredDefaults);
            }

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

            if (deferredDefaults != null)
            {
                foreach (var defer in deferredDefaults)
                {
                    writer.WriteLine("if (" + defer.Key + " == null)");
                    writer.Indent++;
                    writer.WriteIndent();
                    writer.Write(defer.Key);
                    writer.Write(" = ");
                    Core.Write(writer, defer.Value);
                    writer.Write(";\r\n");
                    writer.Indent--;
                }
            }

            if (!TypeState.Instance.DerivesFromObject)
            {
                if (ctorOpt == null || ctorOpt.Initializer == null)
                {
                    writer.WriteLine("super();");
                }
                else
                {
                    if (ctorOpt.Initializer.ThisOrBaseKeyword.ToString() != "base")
                    {
                        throw new Exception("Constructor overloading not supported " + Utility.Descriptor(ctorOpt));
                    }

                    writer.WriteIndent();
                    writer.Write("super(");

                    bool first = true;
                    foreach (var init in ctorOpt.Initializer.ArgumentList.Arguments)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            writer.Write(", ");
                        }

                        Core.Write(writer, init.Expression);
                    }

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


            if (ctorOpt != null && ctorOpt.Body != null)
            {
                foreach (var statement in ctorOpt.Body.As <BlockSyntax>().Statements)
                {
                    Core.Write(writer, statement);
                }

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

            writer.WriteCloseBrace();
        }
Пример #14
0
 public static void Go(HaxeWriter writer)
 {
     writer.WriteLine(StandardImports);
 }
Пример #15
0
        public static void Go(HaxeWriter writer, TryStatementSyntax tryStatement)
        {
            if (tryStatement.Finally != null)
            {
                throw new Exception("Finally blocks are not supported in haxe. " + Utility.Descriptor(tryStatement.Finally));
            }

            writer.WriteLine("try");
            Core.Write(writer, tryStatement.Block);

            foreach (var catchClause in tryStatement.Catches)
            {
                if (Program.DoNotWrite.ContainsKey(catchClause))
                {
                    continue;
                }

                writer.WriteIndent();
                writer.Write("catch (");

                if (catchClause.Declaration == null)
                {
                    writer.Write("__ex:Dynamic");
                }
                else
                {
                    var varName = catchClause.Declaration.Identifier.ValueText;

                    if (string.IsNullOrWhiteSpace(varName))
                    {
                        varName = "__ex";
                    }


                    writer.Write(varName);

                    var type = TypeProcessor.ConvertTypeWithColon(catchClause.Declaration.Type);

                    if (type == ":system.Exception")
                    {
                        //when the C# code catches Exception, we assume they want to catch everything, and in haxe we do that by catching Dynamic.  In this case, we also want to ensure the C# code never treats the exception as an Exception, since it might not be an actual Exception type in haxe.  C# code should be changed to only call .ToString() on it.
                        writer.Write(":Dynamic");

                        Func <IdentifierNameSyntax, bool> isOkUseOfException = node =>
                        {
                            //Calling .ToString() is OK on exceptions
                            if (node.Parent is MemberAccessExpressionSyntax &&
                                node.Parent.Parent is InvocationExpressionSyntax &&
                                node.Parent.Parent.As <InvocationExpressionSyntax>().Expression is MemberAccessExpressionSyntax &&
                                node.Parent.Parent.As <InvocationExpressionSyntax>().Expression.As <MemberAccessExpressionSyntax>().Name.Identifier.ValueText == "ToString")
                            {
                                return(true);
                            }

                            //Using them as concatenation in strings is OK
                            if (node.Parent is BinaryExpressionSyntax && node.Parent.As <BinaryExpressionSyntax>().OperatorToken.Kind() == SyntaxKind.PlusToken)
                            {
                                return(true); //we only check that it's a PlusToken, which could be addition or string concatenation, but C# doesn't allow adding exceptions so it's not necessary to check further
                            }
                            var typeInfo = Program.GetModel(node).GetTypeInfo(node);
                            if (typeInfo.ConvertedType.SpecialType == SpecialType.System_Object)
                            {
                                return(true); //OK to use it as an object, since that becomes Dynamic in haxe
                            }
                            return(false);
                        };

                        var usesException = catchClause.Block.DescendantNodes()
                                            .OfType <IdentifierNameSyntax>()
                                            .Where(o => o.Identifier.ValueText == varName)
                                            .Where(o => !isOkUseOfException(o))
                                            .ToList();

                        if (usesException.Count > 0)
                        {
                            throw new Exception("When catching an Exception, you cannot use the object as an Exception object, since the destination platform supports throwing things that don't derive from Exception.  Instead, call .ToString() on it if you need details of it.  " + string.Join(",  ", usesException.Select(Utility.Descriptor)));
                        }
                    }
                    else
                    {
                        writer.Write(type);
                    }
                }
                writer.Write(")\r\n");
                Core.Write(writer, catchClause.Block);
            }
        }
Пример #16
0
 public static void Go(HaxeWriter writer, ContinueStatementSyntax statement)
 {
     writer.WriteLine("continue;");
 }
Пример #17
0
 public static void Go(HaxeWriter writer, BreakStatementSyntax statement)
 {
     writer.WriteLine("break;");
 }
Пример #18
0
        public static void Go(HaxeWriter writer, IEnumerable <EnumMemberDeclarationSyntax> allChildren)
        {
            int nextEnumValue = 0;

            var values = allChildren.Select(o => new { Syntax = o, Value = DetermineEnumValue(o, ref nextEnumValue) }).ToList();

            foreach (var value in values)
            {
                writer.WriteLine("public static inline var " + value.Syntax.Identifier.ValueText + ":Int = " + value.Value + ";");
            }

            writer.WriteLine();

            writer.WriteLine("public static function ToString(e:Int):String");
            writer.WriteOpenBrace();
            writer.WriteLine("switch (e)");
            writer.WriteOpenBrace();

            foreach (var value in values)
            {
                writer.WriteLine("case " + value.Value + ": return \"" + value.Syntax.Identifier.ValueText + "\";");
            }

            writer.WriteLine("default: return Std.string(e);");

            writer.WriteCloseBrace();
            writer.WriteCloseBrace();

            writer.WriteLine();
            writer.WriteLine("public static function Parse(s:String):Int");
            writer.WriteOpenBrace();
            writer.WriteLine("switch (s)");
            writer.WriteOpenBrace();

            foreach (var value in values)
            {
                writer.WriteLine("case \"" + value.Syntax.Identifier.ValueText + "\": return " + value.Value + ";");
            }

            writer.WriteLine("default: throw new InvalidOperationException(s);");
            writer.WriteCloseBrace();
            writer.WriteCloseBrace();

            writer.WriteLine();
            writer.WriteLine("public static function Values():Array<Int>");
            writer.WriteOpenBrace();

            writer.WriteIndent();
            writer.Write("return [");
            writer.Write(string.Join(", ", values.Select(o => o.Value.ToString())));
            writer.Write("];\r\n");
            writer.WriteCloseBrace();
        }
Пример #19
0
        public static void WriteAnonymousType(AnonymousObjectCreationExpressionSyntax syntax)
        {
            var type     = Program.GetModel(syntax).GetTypeInfo(syntax).Type.As <INamedTypeSymbol>();
            var anonName = TypeName(type);

            using (var writer = new HaxeWriter("anonymoustypes", StripGeneric(anonName)))
            {
                writer.WriteLine("package anonymoustypes;");
                WriteImports.Go(writer);

                writer.WriteLine("class " + anonName);
                writer.WriteOpenBrace();

                var fields = type.GetMembers().OfType <IPropertySymbol>().OrderBy(o => o.Name).ToList();

                foreach (var field in fields)
                {
                    writer.WriteIndent();
                    writer.Write("public var ");
                    writer.Write(field.Name);
                    writer.Write(TypeProcessor.ConvertTypeWithColon(field.Type));
                    writer.Write(";\r\n");
                }

                writer.WriteIndent();
                writer.Write("public function new(");

                bool first = true;
                foreach (var field in fields)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        writer.Write(", ");
                    }

                    writer.Write(field.Name);
                    writer.Write(TypeProcessor.ConvertTypeWithColon(field.Type));
                }
                writer.Write(")\r\n");

                writer.WriteOpenBrace();

                foreach (var field in fields)
                {
                    writer.WriteIndent();
                    writer.Write("this.");
                    writer.Write(field.Name);
                    writer.Write(" = ");
                    writer.Write(field.Name);
                    writer.Write(";\r\n");
                }

                writer.WriteCloseBrace();

                writer.WriteCloseBrace();
            }
        }
Пример #20
0
        public static void Go(HaxeWriter writer, ForStatementSyntax forStatement)
        {
            if (forStatement.DescendantNodes().OfType <ContinueStatementSyntax>().Any())
            {
                throw new Exception("Cannot use \"continue\" in a \"for\" loop.  Consider changing to a while loop instead. " + Utility.Descriptor(forStatement));
            }

            writer.WriteLine("{ //for");
            writer.Indent++;

            if (forStatement.Declaration != null)
            {
                foreach (var variable in forStatement.Declaration.Variables)
                {
                    writer.WriteIndent();
                    writer.Write("var ");
                    writer.Write(variable.Identifier.ValueText);
                    writer.Write(TypeProcessor.ConvertTypeWithColon(forStatement.Declaration.Type));

                    if (variable.Initializer != null)
                    {
                        writer.Write(" = ");
                        Core.Write(writer, variable.Initializer.Value);
                    }

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

            foreach (var init in forStatement.Initializers)
            {
                writer.WriteIndent();
                Core.Write(writer, init);
                writer.Write(";\r\n");
            }

            writer.WriteIndent();
            writer.Write("while (");

            if (forStatement.Condition == null)
            {
                writer.Write("true");
            }
            else
            {
                Core.Write(writer, forStatement.Condition);
            }

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

            if (forStatement.Statement is BlockSyntax)
            {
                foreach (var statement in forStatement.Statement.As <BlockSyntax>().Statements)
                {
                    Core.Write(writer, statement);
                }
            }
            else
            {
                Core.Write(writer, forStatement.Statement);
            }

            foreach (var iterator in forStatement.Incrementors)
            {
                writer.WriteIndent();
                Core.Write(writer, iterator);
                writer.Write(";\r\n");
            }

            writer.WriteCloseBrace();
            writer.Indent--;
            writer.WriteLine("} //end for");
        }
Пример #21
0
        public static void Go(HaxeWriter writer, SwitchStatementSyntax switchStatement)
        {
            writer.WriteIndent();
            writer.Write("switch (");
            Core.Write(writer, switchStatement.Expression);
            writer.Write(")\r\n");
            writer.WriteOpenBrace();

            //First process all blocks except the section with the default block
            foreach (var section in switchStatement.Sections.Where(o => o.Labels.None(z => z.Keyword.Kind() == SyntaxKind.DefaultKeyword)))
            {
                writer.WriteIndent();
                writer.Write("case ");


                var firstLabel = true;
                foreach (var label in section.Labels)
                {
                    if (firstLabel)
                    {
                        firstLabel = false;
                    }
                    else
                    {
                        writer.Write(", ");
                    }

                    Core.Write(writer, label.ChildNodes().Single());
                }
                writer.Write(":\r\n");
                writer.Indent++;

                //Remove any break statements at the end of the block.  If we have a single BlockSyntax node, eat it and repeat the process.
                var    statements  = section.Statements.ToList();
                Action clearBreaks = () =>
                {
                    if (statements.Last() is BreakStatementSyntax)
                    {
                        statements.RemoveAt(statements.Count - 1);
                    }
                };
                clearBreaks();
                if (statements.Count == 1 && statements[0] is BlockSyntax)
                {
                    statements = statements[0].As <BlockSyntax>().Statements.ToList();
                    clearBreaks();
                }

                foreach (var statement in statements)
                {
                    Core.Write(writer, statement);
                }

                writer.Indent--;
            }

            //Now write the default section
            var defaultSection = switchStatement.Sections.SingleOrDefault(o => o.Labels.Any(z => z.Keyword.Kind() == SyntaxKind.DefaultKeyword));

            if (defaultSection != null)
            {
                if (defaultSection.Labels.Count > 1)
                {
                    throw new Exception("Cannot fall-through into or out of the default section of switch statement " + Utility.Descriptor(defaultSection));
                }

                writer.WriteLine("default:");
                writer.Indent++;

                foreach (var statement in defaultSection.Statements)
                {
                    if (!(statement is BreakStatementSyntax))
                    {
                        Core.Write(writer, statement);
                    }
                }

                writer.Indent--;
            }


            writer.WriteCloseBrace();
        }
Пример #22
0
        public static void Go(HaxeWriter writer, PropertyDeclarationSyntax property)
        {
            Action <AccessorDeclarationSyntax, bool> writeRegion = (region, get) =>
            {
                writer.WriteIndent();

                if (property.Modifiers.Any(SyntaxKind.OverrideKeyword))
                {
                    writer.Write("override ");
                }
                if (property.Modifiers.Any(SyntaxKind.PublicKeyword) || property.Modifiers.Any(SyntaxKind.ProtectedKeyword) || property.Modifiers.Any(SyntaxKind.InternalKeyword))
                {
                    writer.Write("public ");
                }
                if (property.Modifiers.Any(SyntaxKind.PrivateKeyword))
                {
                    writer.Write("private ");
                }
                if (property.Modifiers.Any(SyntaxKind.StaticKeyword))
                {
                    writer.Write("static ");
                }

                writer.Write("function ");
                writer.Write(get ? "get_" : "set_");
                writer.Write(property.Identifier.ValueText);

                string type = TypeProcessor.ConvertType(property.Type);

                if (get)
                {
                    writer.Write("():" + type);
                }
                else
                {
                    writer.Write("(value:" + type + "):" + type);
                }

                writer.WriteLine();
                writer.WriteOpenBrace();

                if (property.Modifiers.Any(SyntaxKind.AbstractKeyword))
                {
                    writer.WriteLine("return throw new Exception(\"Abstract item called\");");
                }
                else if (region.Body == null)
                {
                    throw new NotImplementedException("Properties in interfaces are not supported " + Utility.Descriptor(region));
                }
                else
                {
                    foreach (var statement in region.Body.As <BlockSyntax>().Statements)
                    {
                        Core.Write(writer, statement);
                    }

                    if (!get)
                    {
                        //Unfortunately, all haXe property setters must return a value.
                        writer.WriteLine("return " + TypeProcessor.DefaultValue(type) + ";");
                    }
                }

                writer.WriteCloseBrace();
                writer.WriteLine();
            };

            var getter = property.AccessorList.Accessors.SingleOrDefault(o => o.Keyword.Kind() == SyntaxKind.GetKeyword);
            var setter = property.AccessorList.Accessors.SingleOrDefault(o => o.Keyword.Kind() == SyntaxKind.SetKeyword);

            if (getter == null && setter == null)
            {
                throw new Exception("Property must have either a get or a set");
            }

            if (getter != null && setter != null && setter.Body == null && getter.Body == null)
            {
                //Both get and set are null, which means this is an automatic property.  This is the equivilant of a field in haxe.
                WriteField.Go(writer, property.Modifiers, property.Identifier.ValueText, property.Type);
            }
            else
            {
                if (!property.Modifiers.Any(SyntaxKind.OverrideKeyword))
                {
                    //Write the property declaration.  Overridden properties don't need this.
                    writer.WriteIndent();
                    if (property.Modifiers.Any(SyntaxKind.PublicKeyword) || property.Modifiers.Any(SyntaxKind.InternalKeyword))
                    {
                        writer.Write("public ");
                    }
                    if (property.Modifiers.Any(SyntaxKind.StaticKeyword))
                    {
                        writer.Write("static ");
                    }

                    writer.Write("var ");
                    writer.Write(property.Identifier.ValueText);
                    writer.Write("(");

                    if (getter != null)
                    {
                        writer.Write("get_" + property.Identifier.ValueText);
                    }
                    else
                    {
                        writer.Write("never");
                    }

                    writer.Write(", ");

                    if (setter != null)
                    {
                        writer.Write("set_" + property.Identifier.ValueText);
                    }
                    else
                    {
                        writer.Write("never");
                    }

                    writer.Write("):");
                    writer.Write(TypeProcessor.ConvertType(property.Type));
                    writer.Write(";\r\n");
                }

                if (getter != null)
                {
                    writeRegion(getter, true);
                }
                if (setter != null)
                {
                    writeRegion(setter, false);
                }
            }
        }
Пример #23
0
        public static void Go()
        {
            var partials = TypeState.Instance.Partials;
            var first    = partials.First();


            using (var writer = new HaxeWriter(first.Symbol.ContainingNamespace.FullName(), TypeState.Instance.TypeName))
            {
                var bases = partials
                            .Select(o => o.Syntax.BaseList)
                            .Where(o => o != null)
                            .SelectMany(o => o.Types)
                            .Select(o => Program.GetModel(o).GetTypeInfo(o.Type).ConvertedType)
                            .Distinct()
                            .ToList();

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

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

                writer.WriteLine("package " + first.Symbol.ContainingNamespace.FullName().ToLower() + @";");

                WriteImports.Go(writer);

                switch (first.Syntax.Kind())
                {
                case SyntaxKind.ClassDeclaration:
                case SyntaxKind.StructDeclaration:
                case SyntaxKind.EnumDeclaration:
                    writer.Write("class ");
                    break;

                case SyntaxKind.InterfaceDeclaration:
                    writer.Write("interface ");
                    break;

                default:
                    throw new Exception(first.Syntax.Kind().ToString());
                }

                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 (genericArgs.Count > 0)
                    {
                        writer.Write("<");
                        writer.Write(string.Join(", ", genericArgs.Select(o => WriteMethod.TypeParameter(o, partials.SelectMany(z => z.Syntax.As <TypeDeclarationSyntax>().ConstraintClauses)))));
                        writer.Write(">");
                    }

                    foreach (var baseType in bases)
                    {
                        var baseTypeHaxe = TypeProcessor.ConvertType(baseType);

                        if (baseTypeHaxe.StartsWith("Array<"))
                        {
                            continue;
                        }

                        writer.Write(" ");

                        if (baseType.TypeKind == TypeKind.Interface)
                        {
                            writer.Write("implements ");
                            writer.Write(baseTypeHaxe);
                        }
                        else
                        {
                            writer.Write("extends ");
                            writer.Write(baseTypeHaxe);
                        }
                    }
                }

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

                writer.WriteOpenBrace();

                if (first.Syntax is EnumDeclarationSyntax)
                {
                    WriteEnumBody.Go(writer, TypeState.Instance.Partials.Select(o => o.Syntax).Cast <EnumDeclarationSyntax>().SelectMany(o => o.Members).Where(o => !Program.DoNotWrite.ContainsKey(o)));
                }
                else
                {
                    TypeState.Instance.AllMembers = partials.Select(o => o.Syntax).Cast <TypeDeclarationSyntax>().SelectMany(o => o.Members).Where(o => !Program.DoNotWrite.ContainsKey(o)).ToList();

                    foreach (var partial in partials)
                    {
                        foreach (var member in partial.Syntax.As <TypeDeclarationSyntax>().Members)
                        {
                            if (!(member is ClassDeclarationSyntax) && !(member is EnumDeclarationSyntax))
                            {
                                Core.Write(writer, member);
                            }
                        }
                    }

                    if (first.Syntax.Kind() != SyntaxKind.InterfaceDeclaration)
                    {
                        //Normally constructors will be written as we traverse the tree.  However, if there are no constructors, we must manually write them out since there are cases where we need a constructor in haxe while C# had none.
                        var ctors         = TypeState.Instance.AllMembers.OfType <ConstructorDeclarationSyntax>().ToList();
                        var instanceCtors = ctors.Where(o => !o.Modifiers.Any(SyntaxKind.StaticKeyword));

                        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));
                        }

                        if (ctors.None(o => o.Modifiers.Any(SyntaxKind.StaticKeyword)))
                        {
                            WriteConstructor.WriteStaticConstructor(writer, null);
                        }
                        if (instanceCtors.None())
                        {
                            WriteConstructor.WriteInstanceConstructor(writer, null);
                        }
                    }
                }

                writer.WriteCloseBrace();
            }
        }
Пример #24
0
        public static void WriteStaticConstructor(HaxeWriter writer, ConstructorDeclarationSyntax staticConstructorOpt)
        {
            var staticFieldsNeedingInitialization = TypeState.Instance.AllMembers
                                                    .OfType <BaseFieldDeclarationSyntax>()
                                                    .Where(o => o.Modifiers.Any(SyntaxKind.StaticKeyword))
                                                    .SelectMany(o => o.Declaration.Variables)
                                                    .Where(o =>
                                                           (o.Initializer != null && !WriteField.IsConst(o.Parent.Parent.As <BaseFieldDeclarationSyntax>().Modifiers, o.Initializer, o.Parent.As <VariableDeclarationSyntax>().Type))
                                                           ||
                                                           (o.Initializer == null && GenerateInitializerForFieldWithoutInitializer(o.Parent.As <VariableDeclarationSyntax>().Type))
                                                           ||
                                                           o.Parent.Parent is EventFieldDeclarationSyntax)
                                                    .ToList();

            if (staticConstructorOpt == null && staticFieldsNeedingInitialization.Count == 0)
            {
                return; //No static constructor needed
            }
            writer.WriteLine("public static function cctor():Void");
            writer.WriteOpenBrace();

            foreach (var field in staticFieldsNeedingInitialization)
            {
                var parentType = field.Parent.As <VariableDeclarationSyntax>().Type;

                writer.WriteIndent();
                writer.Write(field.Identifier.ValueText);
                writer.Write(" = ");

                if (field.Parent.Parent is EventFieldDeclarationSyntax)
                {
                    writer.Write("new CsEvent<");
                    writer.Write(TypeProcessor.ConvertType(parentType));
                    writer.Write(">()");
                }
                else if (field.Initializer == null)
                {
                    if (TypeProcessor.ValueToReference(parentType))
                    {
                        writer.Write("new ");
                        writer.Write(TypeProcessor.ConvertType(parentType));
                        writer.Write("()");
                    }
                    else
                    {
                        writer.Write(TypeProcessor.DefaultValue(TypeProcessor.ConvertType(parentType)));
                    }
                }
                else
                {
                    Core.Write(writer, field.Initializer.As <EqualsValueClauseSyntax>().Value);
                }
                writer.Write(";\r\n");
            }

            if (staticConstructorOpt != null && staticConstructorOpt.Body != null)
            {
                foreach (var statement in staticConstructorOpt.Body.As <BlockSyntax>().Statements)
                {
                    Core.Write(writer, statement);
                }
            }

            writer.WriteCloseBrace();

            StaticConstructors.Add(TypeState.Instance.TypeName);
        }
Пример #25
0
        public static void Go(HaxeWriter writer, SwitchStatementSyntax switchStatement)
        {
            writer.WriteIndent();
            writer.Write("switch (");
            Core.Write(writer, switchStatement.Expression);
            writer.Write(")\r\n");
            writer.WriteOpenBrace();

            //First process all blocks except the section with the default block
            foreach (var section in switchStatement.Sections.Where(o => o.Labels.None(z => z.Keyword.Kind() == SyntaxKind.DefaultKeyword)))
            {
                writer.WriteIndent();
                writer.Write("case ");


                var firstLabel = true;
                foreach (var label in section.Labels)
                {
                    if (firstLabel)
                    {
                        firstLabel = false;
                    }
                    else
                    {
                        writer.Write(", ");
                    }

                    Core.Write(writer, label.ChildNodes().Single());
                }
                writer.Write(":\r\n");
                writer.Indent++;

                foreach (var statement in section.Statements)
                {
                    if (!(statement is BreakStatementSyntax))
                    {
                        Core.Write(writer, statement);
                    }
                }

                writer.Indent--;
            }

            //Now write the default section
            var defaultSection = switchStatement.Sections.SingleOrDefault(o => o.Labels.Any(z => z.Keyword.Kind() == SyntaxKind.DefaultKeyword));

            if (defaultSection != null)
            {
                if (defaultSection.Labels.Count > 1)
                {
                    throw new Exception("Cannot fall-through into or out of the default section of switch statement " + Utility.Descriptor(defaultSection));
                }

                writer.WriteLine("default:");
                writer.Indent++;

                foreach (var statement in defaultSection.Statements)
                {
                    if (!(statement is BreakStatementSyntax))
                    {
                        Core.Write(writer, statement);
                    }
                }

                writer.Indent--;
            }


            writer.WriteCloseBrace();
        }
Пример #26
0
        public static void WriteInstanceConstructor(HaxeWriter writer, ConstructorDeclarationSyntax ctorOpt)
        {
            writer.WriteIndent();

            writer.Write("public function new(");


            if (ctorOpt != null)
            {
                var firstParameter = true;
                foreach (var parameter in ctorOpt.ParameterList.Parameters)
                {
                    if (firstParameter)
                    {
                        firstParameter = false;
                    }
                    else
                    {
                        writer.Write(", ");
                    }

                    writer.Write(parameter.Identifier.ValueText);
                    writer.Write(TypeProcessor.ConvertTypeWithColon(parameter.Type));

                    if (parameter.Default != null)
                    {
                        writer.Write(" = ");
                        Core.Write(writer, parameter.Default.Value);
                    }
                }
            }

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

            if (!TypeState.Instance.DerivesFromObject)
            {
                if (ctorOpt == null || ctorOpt.Initializer == null)
                {
                    writer.WriteLine("super();");
                }
                else
                {
                    if (ctorOpt.Initializer.ThisOrBaseKeyword.ToString() != "base")
                    {
                        throw new Exception("Constructor overloading not supported " + Utility.Descriptor(ctorOpt));
                    }

                    writer.WriteIndent();
                    writer.Write("super(");

                    bool first = true;
                    foreach (var init in ctorOpt.Initializer.ArgumentList.Arguments)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            writer.Write(", ");
                        }

                        Core.Write(writer, init.Expression);
                    }

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


            foreach (var field in TypeState.Instance.AllMembers
                     .OfType <BaseFieldDeclarationSyntax>()
                     .Where(o => !o.Modifiers.Any(SyntaxKind.StaticKeyword))
                     .SelectMany(o => o.Declaration.Variables)
                     .Where(o =>
                            (o.Initializer != null && !WriteField.IsConst(o.Parent.Parent.As <BaseFieldDeclarationSyntax>().Modifiers, o.Initializer, o.Parent.As <VariableDeclarationSyntax>().Type))
                            ||
                            (o.Initializer == null && GenerateInitializerForFieldWithoutInitializer(o.Parent.As <VariableDeclarationSyntax>().Type))
                            ||
                            o.Parent.Parent is EventFieldDeclarationSyntax))
            {
                var parentType = field.Parent.As <VariableDeclarationSyntax>().Type;

                writer.WriteIndent();
                writer.Write(field.Identifier.ValueText);
                writer.Write(" = ");

                if (field.Parent.Parent is EventFieldDeclarationSyntax)
                {
                    writer.Write("new CsEvent<");
                    writer.Write(TypeProcessor.ConvertType(parentType));
                    writer.Write(">()");
                }
                else if (field.Initializer == null)
                {
                    if (TypeProcessor.ValueToReference(parentType))
                    {
                        writer.Write("new ");
                        writer.Write(TypeProcessor.ConvertType(parentType));
                        writer.Write("()");
                    }
                    else
                    {
                        writer.Write(TypeProcessor.DefaultValue(TypeProcessor.ConvertType(parentType)));
                    }
                }
                else
                {
                    Core.Write(writer, field.Initializer.Value);
                }

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



            if (ctorOpt != null && ctorOpt.Body != null)
            {
                foreach (var statement in ctorOpt.Body.As <BlockSyntax>().Statements)
                {
                    Core.Write(writer, statement);
                }

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

            writer.WriteCloseBrace();
        }