示例#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, LocalDeclarationStatementSyntax declaration)
        {
            foreach (var variable in declaration.Declaration.Variables)
            {
                var symbol = Program.GetModel(declaration).GetDeclaredSymbol(variable);

                var isRef = UsedAsRef(variable, symbol);

                writer.WriteIndent();
                writer.Write("var ");
                writer.Write(variable.Identifier.ValueText);

                if (isRef)
                {
                    var typeStr = TypeProcessor.ConvertType(declaration.Declaration.Type);

                    writer.Write(":CsRef<");
                    writer.Write(typeStr);
                    writer.Write(">");

                    Program.RefOutSymbols.TryAdd(symbol, null);

                    writer.Write(" = new CsRef<");
                    writer.Write(typeStr);
                    writer.Write(">(");

                    if (variable.Initializer == null)
                    {
                        writer.Write(TypeProcessor.DefaultValue(typeStr));
                    }
                    else
                    {
                        Core.Write(writer, variable.Initializer.As <EqualsValueClauseSyntax>().Value);
                    }

                    writer.Write(")");
                }
                else
                {
                    writer.Write(TypeProcessor.ConvertTypeWithColon(declaration.Declaration.Type));

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

                writer.Write(";\r\n");
            }
        }
示例#4
0
        private static void Go(HaxeWriter writer, IEnumerable <ParameterSyntax> parameters, SyntaxNode body, TypeInfo type)
        {
            var methodSymbol = type.ConvertedType.As <INamedTypeSymbol>().DelegateInvokeMethod.As <IMethodSymbol>();

            writer.Write("function (");

            for (int pi = 0; pi < parameters.Count(); pi++)
            {
                var parameter = parameters.ElementAt(pi);
                if (pi > 0)
                {
                    writer.Write(", ");
                }

                writer.Write(parameter.Identifier.ValueText);
                if (parameter.Type != null)
                {
                    writer.Write(TypeProcessor.ConvertTypeWithColon(parameter.Type));
                }
                else
                {
                    writer.Write(TypeProcessor.ConvertTypeWithColon(methodSymbol.Parameters[pi].Type));
                }
            }

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

            if (body is BlockSyntax)
            {
                writer.Write("\r\n");
                Core.Write(writer, body);
                writer.WriteIndent();
            }
            else
            {
                writer.Write(" { ");

                if (methodSymbol.ReturnsVoid == false)
                {
                    writer.Write("return ");
                }

                Core.Write(writer, body);

                writer.Write("; } ");
            }
        }
        public static void Go(HaxeWriter writer, ConversionOperatorDeclarationSyntax method)
        {
            if (method.ImplicitOrExplicitKeyword.Kind() != SyntaxKind.ExplicitKeyword)
            {
                throw new Exception("Implicit cast operators are not supported " + Utility.Descriptor(method));
            }

            writer.WriteIndent();
            writer.Write("public static function op_Explicit_");
            writer.Write(TypeProcessor.ConvertType(method.Type));
            writer.Write("(");

            bool firstParam = true;

            foreach (var param in method.ParameterList.Parameters)
            {
                if (firstParam)
                {
                    firstParam = false;
                }
                else
                {
                    writer.Write(", ");
                }

                writer.Write(param.Identifier.ValueText);
                writer.Write(TypeProcessor.ConvertTypeWithColon(param.Type));
            }

            writer.Write(")");
            writer.Write(TypeProcessor.ConvertTypeWithColon(method.Type));
            writer.Write("\r\n");

            writer.WriteOpenBrace();

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

            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 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();
            }
        }
示例#8
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();
            }
        }
示例#9
0
        public static void WriteParameters(HaxeWriter writer, BaseMethodDeclarationSyntax method, IMethodSymbol methodSymbol, out Dictionary <string, ExpressionSyntax> deferredDefaults)
        {
            deferredDefaults = new Dictionary <string, ExpressionSyntax>();

            var prms = method.ParameterList.Parameters.Select(o => new TransformedArgument(o)).ToList();

            var translateOpt = MethodTranslation.Get(methodSymbol);

            if (translateOpt != null)
            {
                prms = translateOpt.As <MethodTranslation>().TranslateParameters(prms, null).ToList();
            }

            var firstParam = true;

            foreach (var parameter in prms)
            {
                bool isRef = parameter.ParameterOpt != null && (parameter.ParameterOpt.Modifiers.Any(SyntaxKind.OutKeyword) || parameter.ParameterOpt.Modifiers.Any(SyntaxKind.RefKeyword));

                if (parameter.StringOpt != null)
                {
                    continue; //these are only used on invocations
                }
                if (firstParam)
                {
                    firstParam = false;
                }
                else
                {
                    writer.Write(", ");
                }

                writer.Write(parameter.ParameterOpt.Identifier.ValueText);


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

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

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

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


            int tIndex = 1;

            foreach (var genericVar in Utility.PassTypeArgsToMethod(methodSymbol))
            {
                if (firstParam)
                {
                    firstParam = false;
                }
                else
                {
                    writer.Write(", ");
                }

                writer.Write("t" + tIndex.ToString());
                writer.Write(":Class<");
                writer.Write(TypeProcessor.ConvertType(genericVar));
                writer.Write(">");
                tIndex++;
            }
        }
示例#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
        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();
        }
示例#12
0
        public static void Go(HaxeWriter writer, MemberAccessExpressionSyntax expression)
        {
            var model = Program.GetModel(expression);

            var memberName = expression.Name.Identifier.ValueText;
            var type       = model.GetTypeInfo(expression.Expression).ConvertedType;
            var typeStr    = TypeProcessor.GenericTypeName(type);

            if (expression.Expression is PredefinedTypeSyntax)
            {
                //Support int.MaxValue/int.MaxValue/etc. We change MinValue/MaxValue for some types since haXe can't deal with the real MinValue (it's even stricter when compiling to java).  Any checks against this should use <= in place of ==
                if (memberName == "Empty" && typeStr == "System.String")
                {
                    writer.Write("\"\"");
                }
                else if (memberName == "MaxValue" && typeStr == "System.Double")
                {
                    writer.Write("3.4028235e+38");
                }
                else if (memberName == "MinValue" && typeStr == "System.Double")
                {
                    writer.Write("1.4e-45");
                }
                else if (memberName == "MaxValue" && typeStr == "System.Int64")
                {
                    writer.Write("999900000000000000");
                }
                else if (memberName == "NaN")
                {
                    writer.Write("Math.NaN");
                }
                else
                {
                    var val = System.Type.GetType(typeStr).GetField(memberName).GetValue(null);
                    if (val is string)
                    {
                        writer.Write("\"" + val + "\"");
                    }
                    else
                    {
                        writer.Write(val.ToString());
                    }
                }
            }
            else
            {
                var translate = PropertyTranslation.Get(typeStr, memberName);

                if (translate != null && translate.ExtensionNamespace != null)
                {
                    writer.Write(translate.ExtensionNamespace);
                    writer.Write(".");
                    writer.Write(translate.ReplaceWith);
                    writer.Write("(");

                    if (!translate.SkipExtensionParameter)
                    {
                        WriteMember(writer, expression.Expression);
                    }

                    writer.Write(")");
                    return;
                }

                if (translate != null)
                {
                    memberName = translate.ReplaceWith;
                }

                if (type != null)                 //if type is null, then we're just a namespace.  We can ignore these.
                {
                    WriteMember(writer, expression.Expression);
                    writer.Write(".");
                }

                writer.Write(memberName);

                if (expression.Name is GenericNameSyntax)
                {
                    var gen = expression.Name.As <GenericNameSyntax>();

                    writer.Write("<");

                    bool first = true;
                    foreach (var g in gen.TypeArgumentList.Arguments)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            writer.Write(", ");
                        }

                        writer.Write(TypeProcessor.ConvertTypeWithColon(g));
                    }

                    writer.Write(">");
                }
            }
        }
示例#13
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");
        }
示例#14
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);
            }
        }
示例#15
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();
            }
        }