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(); } }
private static void Factory(HaxeWriter writer, SyntaxNode node) { if (node is MethodDeclarationSyntax) { WriteMethod.Go(writer, node.As <MethodDeclarationSyntax>()); } else if (node is PropertyDeclarationSyntax) { WriteProperty.Go(writer, node.As <PropertyDeclarationSyntax>()); } else if (node is FieldDeclarationSyntax) { WriteField.Go(writer, node.As <FieldDeclarationSyntax>()); } else if (node is ConstructorDeclarationSyntax) { WriteConstructor.Go(writer, node.As <ConstructorDeclarationSyntax>()); } else if (node is ExpressionStatementSyntax) { WriteStatement(writer, node.As <ExpressionStatementSyntax>()); } else if (node is LocalDeclarationStatementSyntax) { WriteLocalDeclaration.Go(writer, node.As <LocalDeclarationStatementSyntax>()); } else if (node is BlockSyntax) { WriteBlock(writer, node.As <BlockSyntax>()); } else if (node is InvocationExpressionSyntax) { WriteInvocationExpression.Go(writer, node.As <InvocationExpressionSyntax>()); } else if (node is LiteralExpressionSyntax) { WriteLiteralExpression.Go(writer, node.As <LiteralExpressionSyntax>()); } else if (node is IdentifierNameSyntax) { WriteIdentifierName.Go(writer, node.As <IdentifierNameSyntax>()); } else if (node is ImplicitArrayCreationExpressionSyntax) { WriteArrayCreationExpression.Go(writer, node.As <ImplicitArrayCreationExpressionSyntax>()); } else if (node is ArrayCreationExpressionSyntax) { WriteArrayCreationExpression.Go(writer, node.As <ArrayCreationExpressionSyntax>()); } else if (node is MemberAccessExpressionSyntax) { WriteMemberAccessExpression.Go(writer, node.As <MemberAccessExpressionSyntax>()); } else if (node is ParenthesizedLambdaExpressionSyntax) { WriteLambdaExpression.Go(writer, node.As <ParenthesizedLambdaExpressionSyntax>()); } else if (node is SimpleLambdaExpressionSyntax) { WriteLambdaExpression.Go(writer, node.As <SimpleLambdaExpressionSyntax>()); } else if (node is ReturnStatementSyntax) { WriteReturnStatement.Go(writer, node.As <ReturnStatementSyntax>()); } else if (node is ObjectCreationExpressionSyntax) { WriteObjectCreationExpression.Go(writer, node.As <ObjectCreationExpressionSyntax>()); } else if (node is ElementAccessExpressionSyntax) { WriteElementAccessExpression.Go(writer, node.As <ElementAccessExpressionSyntax>()); } else if (node is ForEachStatementSyntax) { WriteForEachStatement.Go(writer, node.As <ForEachStatementSyntax>()); } else if (node is IfStatementSyntax) { WriteIfStatement.Go(writer, node.As <IfStatementSyntax>()); } else if (node is BinaryExpressionSyntax) { WriteBinaryExpression.Go(writer, node.As <BinaryExpressionSyntax>()); } else if (node is ConditionalExpressionSyntax) { WriteConditionalExpression.Go(writer, node.As <ConditionalExpressionSyntax>()); } else if (node is BaseExpressionSyntax) { WriteBaseExpression.Go(writer, node.As <BaseExpressionSyntax>()); } else if (node is ThisExpressionSyntax) { WriteThisExpression.Go(writer, node.As <ThisExpressionSyntax>()); } else if (node is CastExpressionSyntax) { WriteCastExpression.Go(writer, node.As <CastExpressionSyntax>()); } else if (node is ThrowStatementSyntax) { WriteThrowStatement.Go(writer, node.As <ThrowStatementSyntax>()); } else if (node is ThrowExpressionSyntax) { WriteThrowStatement.GoExpression(writer, node.As <ThrowExpressionSyntax>()); } else if (node is PrefixUnaryExpressionSyntax) { WriteUnaryExpression.Go(writer, node.As <PrefixUnaryExpressionSyntax>()); } else if (node is PostfixUnaryExpressionSyntax) { WriteUnaryExpression.Go(writer, node.As <PostfixUnaryExpressionSyntax>()); } else if (node is EqualsValueClauseSyntax) { WriteEqualsValueClause.Go(writer, node.As <EqualsValueClauseSyntax>()); } else if (node is ForStatementSyntax) { WriteForStatement.Go(writer, node.As <ForStatementSyntax>()); } else if (node is WhileStatementSyntax) { WriteWhileStatement.Go(writer, node.As <WhileStatementSyntax>()); } else if (node is BreakStatementSyntax) { WriteBreakStatement.Go(writer, node.As <BreakStatementSyntax>()); } else if (node is DoStatementSyntax) { WriteDoStatement.Go(writer, node.As <DoStatementSyntax>()); } else if (node is SwitchStatementSyntax) { WriteSwitchStatement.Go(writer, node.As <SwitchStatementSyntax>()); } else if (node is TryStatementSyntax) { WriteTryStatement.Go(writer, node.As <TryStatementSyntax>()); } else if (node is UsingStatementSyntax) { WriteUsingStatement.Go(writer, node.As <UsingStatementSyntax>()); } else if (node is ParenthesizedExpressionSyntax) { WriteParenthesizedExpression.Go(writer, node.As <ParenthesizedExpressionSyntax>()); } else if (node is LockStatementSyntax) { WriteLockStatement.Go(writer, node.As <LockStatementSyntax>()); } else if (node is ContinueStatementSyntax) { WriteContinueStatement.Go(writer, node.As <ContinueStatementSyntax>()); } else if (node is TypeOfExpressionSyntax) { WriteTypeOfExpression.Go(writer, node.As <TypeOfExpressionSyntax>()); } else if (node is AnonymousObjectCreationExpressionSyntax) { WriteAnonymousObjectCreationExpression.Go(writer, node.As <AnonymousObjectCreationExpressionSyntax>()); } else if (node is EmptyStatementSyntax) { return; //ignore empty statements } else if (node is DelegateDeclarationSyntax) { return; //don't write delegates - we convert them to types directly } else if (node is EventFieldDeclarationSyntax) { WriteEventFieldDeclaration.Go(writer, node.As <EventFieldDeclarationSyntax>()); } else if (node is DefaultExpressionSyntax) { WriteDefaultExpression.Go(writer, node.As <DefaultExpressionSyntax>()); } else if (node is GenericNameSyntax) { WriteGenericName.Go(writer, node.As <GenericNameSyntax>()); } else if (node is ConversionOperatorDeclarationSyntax) { WriteConversionOperatorDeclaration.Go(writer, node.As <ConversionOperatorDeclarationSyntax>()); } else if (node is AssignmentExpressionSyntax) { WriteAssignmentExpressionSyntax.Go(writer, node.As <AssignmentExpressionSyntax>()); } else if (node is OperatorDeclarationSyntax) { WriteMethod.WriteOperatorDeclaration(writer, node.As <OperatorDeclarationSyntax>()); } else if (node is IndexerDeclarationSyntax) { WriteMethod.WriteIndexerDeclaration(writer, node.As <IndexerDeclarationSyntax>()); } else { throw new NotImplementedException(node.GetType().Name + " is not supported. " + Utility.Descriptor(node)); } }
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(); }
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"); } } 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("this."); 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(); }