@@ -61,108 +61,94 @@ public ObjectNotationFormatter(object o, string language, out Dictionary<string,
6161 typeof ( TryExpression )
6262 } ;
6363
64- private void WriteObjectCreation ( object o , int depth = 0 ) {
65- if ( ! o . GetType ( ) . InheritsFromOrImplementsAny ( PropertyTypes ) && ! o . GetType ( ) . InheritsFromOrImplementsAny ( NodeTypes ) ) {
66- Write ( RenderLiteral ( o , language ) ) ;
64+ private void WriteObjectCreation ( object o ) {
65+ var type = writeNew ( o ) ;
66+ var preferredOrder = preferredPropertyOrders . FirstOrDefault ( x => x . Item1 . IsAssignableFrom ( o . GetType ( ) ) ) . Item2 ;
67+ var properties = type . GetProperties ( ) . Where ( x => {
68+ if ( x . Name . In ( "CanReduce" , "TailCall" , "CanReduce" , "IsLifted" , "IsLiftedToNull" , "ArgumentCount" ) ) { return false ; }
69+ if ( x . Name == "NodeType" && hideNodeType . Contains ( type ) ) { return false ; }
70+ return true ;
71+ } ) . ToList ( ) ;
72+
73+ if ( properties . None ( ) ) {
74+ if ( language == CSharp ) { Write ( "()" ) ; }
6775 return ;
6876 }
6977
70- Write (
71- language == CSharp ? "new " :
72- language == VisualBasic ? "New " :
73- ""
74- ) ;
78+ if ( language == VisualBasic ) { Write ( " With" ) ; }
79+ Write ( " {" ) ;
80+ Indent ( ) ;
81+ WriteEOL ( ) ;
7582
76- var type = o . GetType ( ) . BaseTypes ( false , true ) . First ( x => x . IsPublic && ! x . IsInterface ) ;
77- var typename = type . FriendlyName ( language ) ;
78- Write ( typename ) ;
79-
80- if ( o is IEnumerable enumerable ) {
81- // use collection initializer
82- bool hasItems = false ;
83- enumerable . Cast < object > ( ) . ForEach ( ( x , index ) => {
84- if ( index == 0 ) {
85- hasItems = true ;
86- if ( language == VisualBasic ) { Write ( " From" ) ; }
87- Write ( " {" ) ;
88- Indent ( ) ;
89- } else if ( index > 0 ) {
90- Write ( "," ) ;
91- }
83+ properties . OrderBy ( x => {
84+ if ( x . Name . In ( "NodeType" , "Type" ) ) { return - 2 ; }
85+ if ( preferredOrder == null ) { return - 1 ; }
86+ var indexOf = Array . IndexOf ( preferredOrder , x . Name ) ;
87+ if ( indexOf == - 1 ) { return 1000 ; }
88+ return indexOf ;
89+ } )
90+ . ThenBy ( x => x . Name )
91+ . Select ( x => {
92+ object value ;
93+ try {
94+ value = x . GetValue ( o ) ;
95+ } catch ( Exception ex ) {
96+ value = ex . Message ;
97+ }
98+ return ( x , value ) ;
99+ } )
100+ . WhereT ( ( _ , value ) => {
101+ if ( value == null ) { return false ; }
102+ if ( value is IEnumerable seq && seq . None ( ) ) { return false ; }
103+ return true ;
104+ } )
105+ . ForEachT ( ( x , value , index ) => {
106+ if ( index > 0 ) {
107+ Write ( "," ) ;
92108 WriteEOL ( ) ;
93- WriteObjectCreation ( x , depth + 1 ) ;
94- } ) ;
95- if ( hasItems ) {
96- WriteEOL ( true ) ;
97- Write ( "}" ) ;
98109 }
99- } else {
100- //use object initializer
101- var preferredOrder = preferredPropertyOrders . FirstOrDefault ( x => x . Item1 . IsAssignableFrom ( o . GetType ( ) ) ) . Item2 ;
102- var properties = type . GetProperties ( ) . Where ( x => {
103- if ( x . Name . In ( "CanReduce" , "TailCall" , "CanReduce" , "IsLifted" , "IsLiftedToNull" , "ArgumentCount" ) ) { return false ; }
104- if ( x . Name == "NodeType" && hideNodeType . Contains ( type ) ) { return false ; }
105- return true ;
106- } ) . ToList ( ) ;
107- if ( properties . None ( ) ) {
108- if ( language == CSharp ) { Write ( "()" ) ; }
109- return ;
110+ if ( language == VisualBasic ) { Write ( "." ) ; }
111+ Write ( x . Name ) ;
112+ Write ( " = " ) ;
113+
114+ if ( x . PropertyType . InheritsFromOrImplementsAny ( PropertyTypes ) ) {
115+ WriteCollection ( value as IEnumerable , x . Name ) ;
116+ } else if ( x . PropertyType . InheritsFromOrImplementsAny ( NodeTypes ) ) {
117+ WriteNode ( x . Name , value ) ;
118+ } else {
119+ Write ( RenderLiteral ( value , language ) ) ;
110120 }
121+ } ) ;
111122
112- if ( language == VisualBasic ) { Write ( " With" ) ; }
113- Write ( " {" ) ;
114- Indent ( ) ;
115- WriteEOL ( ) ;
116-
117- var values = properties
118- . Where ( x => x . Name . NotIn ( "TailCall" , "CanReduce" , "IsLifted" , "IsLiftedToNull" ) )
119- . OrderBy ( x => {
120- if ( x . Name . In ( "NodeType" , "Type" ) ) { return - 2 ; }
121- if ( preferredOrder == null ) { return - 1 ; }
122- var indexOf = Array . IndexOf ( preferredOrder , x . Name ) ;
123- if ( indexOf == - 1 ) { return 1000 ; }
124- return indexOf ;
125- } ) . ThenBy ( x => x . Name )
126- . Select ( x => {
127- object value ;
128- try {
129- value = x . GetValue ( o ) ;
130- } catch ( Exception ex ) {
131- value = ex . Message ;
132- }
133- return ( x , value ) ;
134- } )
135- . WhereT ( ( instance , value ) => {
136- if ( value == null ) { return false ; }
137- if ( ! ( value is IEnumerable enumerable1 ) ) { return true ; }
138- if ( enumerable1 . None ( ) ) { return false ; }
139- return true ;
140- } )
141- . ForEachT ( ( x , value , index ) => {
142- if ( index > 0 ) {
143- Write ( "," ) ;
144- WriteEOL ( ) ;
145- }
146- if ( language == VisualBasic ) { Write ( "." ) ; }
147- Write ( x . Name ) ;
148- Write ( " = " ) ;
149-
150- var ( success , literal ) = TryRenderLiteral ( value , language ) ;
151- if ( success ) {
152- Write ( literal ) ;
153- return ;
154- }
155- if ( value . GetType ( ) == o . GetType ( ) ) {
156- Write ( "<potential recursion>" ) ;
157- return ;
158- }
159-
160- WriteObjectCreation ( value , depth + 1 ) ;
161- } ) ;
162-
163- WriteEOL ( true ) ;
164- Write ( "}" ) ;
123+ WriteEOL ( true ) ;
124+ Write ( "}" ) ;
125+ }
126+
127+ private void WriteCollection ( IEnumerable seq , string pathSegment ) {
128+ writeNew ( seq ) ;
129+ var items = seq . Cast < object > ( ) . ToList ( ) ;
130+ if ( items . None ( ) ) {
131+ if ( language == CSharp ) { Write ( "()" ) ; }
132+ return ;
165133 }
134+ if ( language == VisualBasic ) { Write ( " From" ) ; }
135+ Write ( " {" ) ;
136+ Indent ( ) ;
137+ WriteEOL ( ) ;
138+ WriteNodes ( pathSegment , items , true ) ;
139+ WriteEOL ( true ) ;
140+ Write ( "}" ) ;
141+ }
142+
143+ private Type writeNew ( object o ) {
144+ Write (
145+ language == CSharp ? "new " :
146+ language == VisualBasic ? "New " :
147+ ""
148+ ) ;
149+ var t = o . GetType ( ) . BaseTypes ( false , true ) . First ( x => x . IsPublic && ! x . IsInterface ) ;
150+ Write ( t . FriendlyName ( language ) ) ;
151+ return t ;
166152 }
167153
168154 protected override void WriteBinary ( BinaryExpression expr ) => WriteObjectCreation ( expr ) ;
@@ -194,18 +180,22 @@ private void WriteObjectCreation(object o, int depth=0) {
194180 protected override void WriteSwitchCase ( SwitchCase switchCase ) => WriteObjectCreation ( switchCase ) ;
195181 protected override void WriteCatchBlock ( CatchBlock catchBlock ) => WriteObjectCreation ( catchBlock ) ;
196182 protected override void WriteLabelTarget ( LabelTarget labelTarget ) => WriteObjectCreation ( labelTarget ) ;
197- protected override void WriteBinaryOperationBinder ( BinaryOperationBinder binaryOperationBinder , IList < Expression > args ) => WriteObjectCreation ( binaryOperationBinder ) ;
198- protected override void WriteConvertBinder ( ConvertBinder convertBinder , IList < Expression > args ) => WriteObjectCreation ( convertBinder ) ;
199- protected override void WriteCreateInstanceBinder ( CreateInstanceBinder createInstanceBinder , IList < Expression > args ) => WriteObjectCreation ( createInstanceBinder ) ;
200- protected override void WriteDeleteIndexBinder ( DeleteIndexBinder deleteIndexBinder , IList < Expression > args ) => WriteObjectCreation ( deleteIndexBinder ) ;
201- protected override void WriteDeleteMemberBinder ( DeleteMemberBinder deleteMemberBinder , IList < Expression > args ) => WriteObjectCreation ( deleteMemberBinder ) ;
202- protected override void WriteGetIndexBinder ( GetIndexBinder getIndexBinder , IList < Expression > args ) => WriteObjectCreation ( getIndexBinder ) ;
203- protected override void WriteGetMemberBinder ( GetMemberBinder getMemberBinder , IList < Expression > args ) => WriteObjectCreation ( getMemberBinder ) ;
204- protected override void WriteInvokeBinder ( InvokeBinder invokeBinder , IList < Expression > args ) => WriteObjectCreation ( invokeBinder ) ;
205- protected override void WriteInvokeMemberBinder ( InvokeMemberBinder invokeMemberBinder , IList < Expression > args ) => WriteObjectCreation ( invokeMemberBinder ) ;
206- protected override void WriteSetIndexBinder ( SetIndexBinder setIndexBinder , IList < Expression > args ) => WriteObjectCreation ( setIndexBinder ) ;
207- protected override void WriteSetMemberBinder ( SetMemberBinder setMemberBinder , IList < Expression > args ) => WriteObjectCreation ( setMemberBinder ) ;
208- protected override void WriteUnaryOperationBinder ( UnaryOperationBinder unaryOperationBinder , IList < Expression > args ) => WriteObjectCreation ( unaryOperationBinder ) ;
183+
184+ protected override void WriteDynamic ( DynamicExpression expr ) => WriteObjectCreation ( expr ) ;
185+
186+ protected override void WriteBinaryOperationBinder ( BinaryOperationBinder binaryOperationBinder , IList < Expression > args ) => throw new NotImplementedException ( ) ;
187+ protected override void WriteConvertBinder ( ConvertBinder convertBinder , IList < Expression > args ) => throw new NotImplementedException ( ) ;
188+ protected override void WriteCreateInstanceBinder ( CreateInstanceBinder createInstanceBinder , IList < Expression > args ) => throw new NotImplementedException ( ) ;
189+ protected override void WriteDeleteIndexBinder ( DeleteIndexBinder deleteIndexBinder , IList < Expression > args ) => throw new NotImplementedException ( ) ;
190+ protected override void WriteDeleteMemberBinder ( DeleteMemberBinder deleteMemberBinder , IList < Expression > args ) => throw new NotImplementedException ( ) ;
191+ protected override void WriteGetIndexBinder ( GetIndexBinder getIndexBinder , IList < Expression > args ) => throw new NotImplementedException ( ) ;
192+ protected override void WriteGetMemberBinder ( GetMemberBinder getMemberBinder , IList < Expression > args ) => throw new NotImplementedException ( ) ;
193+ protected override void WriteInvokeBinder ( InvokeBinder invokeBinder , IList < Expression > args ) => throw new NotImplementedException ( ) ;
194+ protected override void WriteInvokeMemberBinder ( InvokeMemberBinder invokeMemberBinder , IList < Expression > args ) => throw new NotImplementedException ( ) ;
195+ protected override void WriteSetIndexBinder ( SetIndexBinder setIndexBinder , IList < Expression > args ) => throw new NotImplementedException ( ) ;
196+ protected override void WriteSetMemberBinder ( SetMemberBinder setMemberBinder , IList < Expression > args ) => throw new NotImplementedException ( ) ;
197+ protected override void WriteUnaryOperationBinder ( UnaryOperationBinder unaryOperationBinder , IList < Expression > args ) => throw new NotImplementedException ( ) ;
198+
209199 protected override void WriteParameterDeclarationImpl ( ParameterExpression prm ) => WriteObjectCreation ( prm ) ;
210200 }
211201}
0 commit comments