// // Mono.CSharp CSharpCodeProvider Class implementation // // Author: // Daniel Stodden (stodden@in.tum.de) // // (C) 2002 Ximian, Inc. // namespace Mono.CSharp { using System; using System.CodeDom; using System.CodeDom.Compiler; using System.IO; using System.Reflection; using System.Collections; internal class CSharpCodeGenerator : CodeGenerator { // // Constructors // public CSharpCodeGenerator() { } // // Properties // protected override string NullToken { get { return "null"; } } // // Methods // protected override void GenerateArrayCreateExpression( CodeArrayCreateExpression expression ) { // // This tries to replicate MS behavior as good as // possible. // // The Code-Array stuff in ms.net seems to be broken // anyways, or I'm too stupid to understand it. // // I'm sick of it. If you try to develop array // creations, test them on windows. If it works there // but not in mono, drop me a note. I'd be especially // interested in jagged-multidimensional combinations // with proper initialization :} // TextWriter output = Output; output.Write( "new " ); CodeExpressionCollection initializers = expression.Initializers; CodeTypeReference createType = expression.CreateType; if ( initializers.Count > 0 ) { OutputType( createType ); output.WriteLine( " {" ); ++Indent; OutputExpressionList( initializers, true ); --Indent; output.Write( "}" ); } else { CodeTypeReference arrayType = createType.ArrayElementType; while ( arrayType != null ) { createType = arrayType; arrayType = arrayType.ArrayElementType; } OutputType( createType ); output.Write( '[' ); CodeExpression size = expression.SizeExpression; if ( size != null ) GenerateExpression( size ); else output.Write( expression.Size ); output.Write( ']' ); } } protected override void GenerateBaseReferenceExpression( CodeBaseReferenceExpression expression ) { Output.Write( "base" ); } protected override void GenerateCastExpression( CodeCastExpression expression ) { TextWriter output = Output; output.Write( "((" ); OutputType( expression.TargetType ); output.Write( ")(" ); GenerateExpression( expression.Expression ); output.Write( "))" ); } protected override void GenerateCompileUnitStart( CodeCompileUnit compileUnit ) { GenerateComment( new CodeComment( "------------------------------------------------------------------------------" ) ); GenerateComment( new CodeComment( " " ) ); GenerateComment( new CodeComment( " This code was generated by a tool." ) ); GenerateComment( new CodeComment( " Mono Runtime Version: " + System.Environment.Version ) ); GenerateComment( new CodeComment( "" ) ); GenerateComment( new CodeComment( " Changes to this file may cause incorrect behavior and will be lost if " ) ); GenerateComment( new CodeComment( " the code is regenerated." ) ); GenerateComment( new CodeComment( " " ) ); GenerateComment( new CodeComment( "------------------------------------------------------------------------------" ) ); Output.WriteLine(); } protected override void GenerateDelegateCreateExpression( CodeDelegateCreateExpression expression ) { TextWriter output = Output; output.Write( "new " ); OutputType( expression.DelegateType ); output.Write( '(' ); CodeExpression targetObject = expression.TargetObject; if ( targetObject != null ) { GenerateExpression( targetObject ); Output.Write( '.' ); } output.Write( expression.MethodName ); output.Write( ')' ); } protected override void GenerateFieldReferenceExpression( CodeFieldReferenceExpression expression ) { CodeExpression targetObject = expression.TargetObject; if ( targetObject != null ) { GenerateExpression( targetObject ); Output.Write( '.' ); } Output.Write( expression.FieldName ); } protected override void GenerateArgumentReferenceExpression( CodeArgumentReferenceExpression expression ) { Output.Write( expression.ParameterName ); } protected override void GenerateVariableReferenceExpression( CodeVariableReferenceExpression expression ) { Output.Write( expression.VariableName ); } protected override void GenerateIndexerExpression( CodeIndexerExpression expression ) { TextWriter output = Output; GenerateExpression( expression.TargetObject ); output.Write( '[' ); OutputExpressionList( expression.Indices ); output.Write( ']' ); } protected override void GenerateArrayIndexerExpression( CodeArrayIndexerExpression expression ) { TextWriter output = Output; GenerateExpression( expression.TargetObject ); output.Write( '[' ); OutputExpressionList( expression.Indices ); output.Write( ']' ); } protected override void GenerateSnippetExpression( CodeSnippetExpression expression ) { Output.Write( expression.Value ); } protected override void GenerateMethodInvokeExpression( CodeMethodInvokeExpression expression ) { TextWriter output = Output; GenerateMethodReferenceExpression( expression.Method ); output.Write( '(' ); OutputExpressionList( expression.Parameters ); output.Write( ')' ); } protected override void GenerateMethodReferenceExpression( CodeMethodReferenceExpression expression ) { GenerateExpression( expression.TargetObject ); Output.Write( '.' ); Output.Write( expression.MethodName ); } protected override void GenerateEventReferenceExpression( CodeEventReferenceExpression expression ) { GenerateExpression( expression.TargetObject ); Output.Write( '.' ); Output.Write( expression.EventName ); } protected override void GenerateDelegateInvokeExpression( CodeDelegateInvokeExpression expression ) { GenerateExpression( expression.TargetObject ); Output.Write( '(' ); OutputExpressionList( expression.Parameters ); Output.Write( ')' ); } protected override void GenerateObjectCreateExpression( CodeObjectCreateExpression expression ) { Output.Write( "new " ); OutputType( expression.CreateType ); Output.Write( '(' ); OutputExpressionList( expression.Parameters ); Output.Write( ')' ); } protected override void GeneratePropertyReferenceExpression( CodePropertyReferenceExpression expression ) { GenerateMemberReferenceExpression( expression.TargetObject, expression.PropertyName ); } protected override void GeneratePropertySetValueReferenceExpression( CodePropertySetValueReferenceExpression expression ) { Output.Write ( "value" ); } protected override void GenerateThisReferenceExpression( CodeThisReferenceExpression expression ) { Output.Write( "this" ); } protected override void GenerateExpressionStatement( CodeExpressionStatement statement ) { GenerateExpression( statement.Expression ); Output.WriteLine( ';' ); } protected override void GenerateIterationStatement( CodeIterationStatement statement ) { TextWriter output = Output; output.Write( "for (" ); GenerateStatement( statement.InitStatement ); output.Write( "; " ); GenerateExpression( statement.TestExpression ); output.Write( "; " ); GenerateStatement( statement.IncrementStatement ); output.Write( ") " ); GenerateStatements( statement.Statements ); } protected override void GenerateThrowExceptionStatement( CodeThrowExceptionStatement statement ) { Output.Write( "throw " ); GenerateExpression( statement.ToThrow ); } protected override void GenerateComment( CodeComment comment ) { TextWriter output = Output; if ( comment.DocComment ) output.Write( "/// " ); else output.Write( "// " ); output.WriteLine( comment.Text ); } protected override void GenerateMethodReturnStatement( CodeMethodReturnStatement statement ) { TextWriter output = Output; output.Write( "return " ); GenerateExpression( statement.Expression ); output.Write( ";" ); } protected override void GenerateConditionStatement( CodeConditionStatement statement ) { TextWriter output = Output; output.Write( "if (" ); GenerateExpression( statement.Condition ); output.WriteLine( ") {" ); ++Indent; GenerateStatements( statement.TrueStatements ); --Indent; output.Write( '}' ); CodeStatementCollection falses = statement.FalseStatements; if ( falses.Count > 0 ) { if ( Options.ElseOnClosing ) output.Write( ' ' ); else output.WriteLine(); output.WriteLine( "else {" ); ++Indent; GenerateStatements( falses ); --Indent; output.WriteLine( '}' ); } } protected override void GenerateTryCatchFinallyStatement( CodeTryCatchFinallyStatement statement ) { TextWriter output = Output; CodeGeneratorOptions options = Options; output.WriteLine( "try {" ); ++Indent; GenerateStatements( statement.TryStatements ); --Indent; output.Write( '}' ); foreach ( CodeCatchClause clause in statement.CatchClauses ) { if ( options.ElseOnClosing ) output.Write( ' ' ); else output.WriteLine(); output.Write( "catch (" ); OutputTypeNamePair( clause.CatchExceptionType, clause.LocalName ); output.WriteLine( ") {" ); ++Indent; GenerateStatements( clause.Statements ); --Indent; output.Write( '}' ); } CodeStatementCollection finallies = statement.FinallyStatements; if ( finallies.Count > 0 ) { if ( options.ElseOnClosing ) output.Write( ' ' ); else output.WriteLine(); output.WriteLine( "finally {" ); ++Indent; GenerateStatements( finallies ); --Indent; output.WriteLine( '}' ); } output.WriteLine(); } protected override void GenerateAssignStatement( CodeAssignStatement statement ) { TextWriter output = Output; GenerateExpression( statement.Left ); output.Write( " = " ); GenerateExpression( statement.Right ); output.WriteLine( ';' ); } protected override void GenerateAttachEventStatement( CodeAttachEventStatement statement ) { TextWriter output = Output; GenerateEventReferenceExpression( statement.Event ); output.Write( " += " ); GenerateExpression( statement.Listener ); output.WriteLine( ';' ); } protected override void GenerateRemoveEventStatement( CodeRemoveEventStatement statement ) { TextWriter output = Output; GenerateEventReferenceExpression( statement.Event ); Output.Write( " -= " ); GenerateExpression( statement.Listener ); output.WriteLine( ';' ); } protected override void GenerateGotoStatement( CodeGotoStatement statement ) { TextWriter output = Output; output.Write( "goto " ); output.Write( statement.Label ); output.Write( ";" ); } protected override void GenerateLabeledStatement( CodeLabeledStatement statement ) { TextWriter output = Output; output.Write( statement.Label ); GenerateStatement( statement.Statement ); } protected override void GenerateVariableDeclarationStatement( CodeVariableDeclarationStatement statement ) { TextWriter output = Output; OutputTypeNamePair( statement.Type, statement.Name ); CodeExpression initExpression = statement.InitExpression; if ( initExpression != null ) { output.Write( " = " ); GenerateExpression( initExpression ); } output.WriteLine( ';' ); } protected override void GenerateLinePragmaStart( CodeLinePragma linePragma ) { Output.Write( "" ); } protected override void GenerateLinePragmaEnd( CodeLinePragma linePragma ) { Output.Write( "" ); } protected override void GenerateEvent( CodeMemberEvent eventRef, CodeTypeDeclaration declaration ) { Output.Write( "" ); } protected override void GenerateField( CodeMemberField field ) { TextWriter output = Output; if (field.CustomAttributes.Count > 0) OutputAttributeDeclarations( field.CustomAttributes ); MemberAttributes attributes = field.Attributes; OutputMemberAccessModifier( attributes ); OutputFieldScopeModifier( attributes ); OutputTypeNamePair( field.Type, field.Name ); CodeExpression initExpression = field.InitExpression; if ( initExpression != null ) { output.Write( " = " ); GenerateExpression( initExpression ); } output.WriteLine( ';' ); } protected override void GenerateSnippetMember( CodeSnippetTypeMember member ) { Output.Write( "" ); } protected override void GenerateEntryPointMethod( CodeEntryPointMethod method, CodeTypeDeclaration declaration ) { method.Name = "Main"; GenerateMethod( method, declaration ); } protected override void GenerateMethod( CodeMemberMethod method, CodeTypeDeclaration declaration ) { TextWriter output = Output; if (method.CustomAttributes.Count > 0) OutputAttributeDeclarations( method.CustomAttributes ); MemberAttributes attributes = method.Attributes; OutputMemberAccessModifier( attributes ); OutputMemberScopeModifier( attributes ); OutputType( method.ReturnType ); output.Write( ' ' ); CodeTypeReference privateType = method.PrivateImplementationType; if ( privateType != null ) { OutputType( privateType ); output.Write( '.' ); } output.Write( method.Name ); output.Write( '(' ); OutputParameters( method.Parameters ); output.Write( ')' ); if ( (attributes & MemberAttributes.ScopeMask) == MemberAttributes.Abstract ) output.WriteLine( ';' ); else { output.WriteLine( " {" ); ++Indent; GenerateStatements( method.Statements ); --Indent; output.WriteLine( '}' ); } } protected override void GenerateProperty( CodeMemberProperty property, CodeTypeDeclaration declaration ) { TextWriter output = Output; if (property.CustomAttributes.Count > 0) OutputAttributeDeclarations( property.CustomAttributes ); MemberAttributes attributes = property.Attributes; OutputMemberAccessModifier( attributes ); OutputFieldScopeModifier( attributes ); OutputTypeNamePair( property.Type, property.Name ); output.WriteLine (" {"); ++Indent; if (property.HasGet) { output.WriteLine ("get {"); ++Indent; GenerateStatements (property.GetStatements); output.WriteLine (); output.WriteLine ("}"); --Indent; } if (property.HasSet) { output.WriteLine ("set {"); ++Indent; GenerateStatements (property.SetStatements); output.WriteLine (); output.WriteLine ("}"); --Indent; } --Indent; output.WriteLine ("}"); } protected override void GenerateConstructor( CodeConstructor constructor, CodeTypeDeclaration declaration ) { Output.Write( "" ); } protected override void GenerateTypeConstructor( CodeTypeConstructor constructor ) { Output.Write( "" ); } protected override void GenerateTypeStart( CodeTypeDeclaration declaration ) { TextWriter output = Output; TypeAttributes attributes = declaration.TypeAttributes; OutputTypeAttributes( attributes, declaration.IsStruct, declaration.IsEnum ); output.Write( declaration.Name ); output.Write( ' ' ); IEnumerator enumerator = declaration.BaseTypes.GetEnumerator(); if ( enumerator.MoveNext() ) { CodeTypeReference type = (CodeTypeReference)enumerator.Current; output.Write( ": " ); OutputType( type ); while ( enumerator.MoveNext() ) { type = (CodeTypeReference)enumerator.Current; output.Write( ", " ); OutputType( type ); } output.Write( ' ' ); } output.WriteLine( "{" ); ++Indent; } protected override void GenerateTypeEnd( CodeTypeDeclaration declaration ) { --Indent; Output.WriteLine( "}" ); } protected override void GenerateNamespaceStart( CodeNamespace ns ) { TextWriter output = Output; string name = ns.Name; if ( name != null && name != "" ) { output.Write( "namespace " ); output.Write( name ); output.WriteLine( " {" ); ++Indent; } } protected override void GenerateNamespaceEnd( CodeNamespace ns ) { string name = ns.Name; if ( name != null && name != "" ) { --Indent; Output.WriteLine( "}" ); } } protected override void GenerateNamespaceImport( CodeNamespaceImport import ) { TextWriter output = Output; output.Write( "using " ); output.Write( import.Namespace ); output.WriteLine( ';' ); } protected override void GenerateAttributeDeclarationsStart( CodeAttributeDeclarationCollection attributes ) { Output.Write( '[' ); } protected override void GenerateAttributeDeclarationsEnd( CodeAttributeDeclarationCollection attributes ) { Output.WriteLine( ']' ); } protected override void OutputType( CodeTypeReference type ) { Output.Write( GetTypeOutput( type ) ); } protected override string QuoteSnippetString( string value ) { return "\"" + value + "\""; // FIXME: escape quotes } private void GenerateDeclaration( CodeTypeReference type, string name, CodeExpression initExpression ) { TextWriter output = Output; OutputTypeNamePair( type, name ); if ( initExpression != null ) { output.Write( " = " ); GenerateExpression( initExpression ); } output.WriteLine( ';' ); } private void GenerateMemberReferenceExpression( CodeExpression targetObject, string memberName ) { GenerateExpression( targetObject ); Output.Write( '.' ); Output.Write( memberName ); } /* * ICodeGenerator */ //[MonoTODO] protected override string CreateEscapedIdentifier( string value ) { return value; } //[MonoTODO] protected override string CreateValidIdentifier( string value ) { return value; } protected override string GetTypeOutput( CodeTypeReference type ) { string output; CodeTypeReference arrayType; arrayType = type.ArrayElementType; if ( arrayType != null ) output = GetTypeOutput( arrayType ); else { switch ( type.BaseType ) { case "System.Decimal": output = "decimal"; break; case "System.Double": output = "double"; break; case "System.Single": output = "float"; break; case "System.Byte": output = "byte"; break; case "System.SByte": output = "sbyte"; break; case "System.Int32": output = "int"; break; case "System.UInt32": output = "uint"; break; case "System.Int64": output = "long"; break; case "System.UInt64": output = "ulong"; break; case "System.Int16": output = "short"; break; case "System.UInt16": output = "ushort"; break; case "System.Boolean": output = "bool"; break; case "System.Char": output = "char"; break; case "System.String": output = "string"; break; case "System.Object": output = "object"; break; case "System.Void": output = "void"; break; default: output = type.BaseType; break; } } int rank = type.ArrayRank; if ( rank > 0 ) { output += "["; for ( --rank; rank > 0; --rank ) output += ","; output += "]"; } return output; } protected override bool IsValidIdentifier( string identifier ) { return true; } protected override bool Supports( GeneratorSupport supports ) { if ( (supports & GeneratorSupport.Win32Resources) != 0 ) return false; return true; } #if false //[MonoTODO] public override void ValidateIdentifier( string identifier ) { } #endif } }