2004-11-04 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / mcs / TODO
1 New
2 ---
3
4         It would be nice to optimize the case of:
5
6                 Method (new ValueType ())
7
8         So that no temporary is created, and we only use a newobj call
9         that remains on the stack, as opposed to ldloca, initobj, ldloc
10         call.
11
12 NEW NOTES:
13 ----------
14
15         ImplicitStandardConversionExists and ImplicitStandardConversion
16         should always be the same, but there are a few diverging lines that
17         must be studied:
18
19                         if (expr_type == target_type && !(expr is NullLiteral))
20                                 return expr;
21
22         vs:
23
24                         if (expr_type == target_type)
25                                 return true;
26
27
28 Null Type
29 ---------
30
31         Need to introduce the NullType concept into the compiler, to address a 
32         few small buglets and remove the hardcoded values for NullLiteral.
33
34         NullLiteral will be the only expression that has the NullType as its type.
35
36         This is what must be used to test for Null literals, instead of `is NullLiteral',
37         and this will introduce a couple of fixes to the rules.
38
39         Revert Martin's patch to Conditional expression that worked around this bug:
40
41                 Reference r = xx ? null : null
42
43         The right fix is to introduce NullType
44
45 ****************************************************************************************
46
47 *   The information on the rest of this file is mostly outdated, and its kept here for
48 *   historical reasons
49 *
50 ****************************************************************************************
51  
52 Error Reporting:
53 ----------------
54
55         * Make yyerror show a nice syntax error, instead of the current mess.
56
57 Iterators
58 ---------
59         * Reset should throw not implemented now.
60
61 Optimization ideas
62 ------------------
63
64         Currently when we build a type cache, it contains private members,
65         internal members, and internal protected members;   We should trim
66         these out, as it shows up on the profile.
67
68         We create too many Arraylists;  When we know the size, we should create
69         an array;
70
71         During parsing we use arraylists to accumulate data, like this:
72
73                 thing:
74                 
75                 thing_list
76                         : thing { $$ =new ArrayList (); $$.Add ($1); }
77                         | thing_list thing { ArrayList a = $1; a.Add ($2); $$ = a; }
78
79         We probably could start using "Pairs" there:
80
81                 thing_list
82                         : thing { $$ = new Pair ($1, null); }
83                         | thing_list thing { Pair p = $1; $$ = new Pair ($2, $1); }
84
85
86 EmitContext.ResolveTypeTree
87 ---------------------------
88
89         We should investigate its usage.  The problem is that by default
90         this will be set when calling FindType, that triggers a more expensive
91         lookup.
92
93         I believe we should pass the current EmitContext (which has this turned off
94         by default) to ResolveType/REsolveTypeExpr and then have the routines that
95         need ResolveType to pass null as the emit context.
96
97 DeclareLocal audit
98 ------------------
99
100         DeclareLocal is used in various statements.  The audit should be done
101         in two steps:
102
103                 * Identify all the declare locals.
104
105                 * Identify its uses.
106
107                 * Find if we can make wrapper functions for all of them.
108
109         Then we can move DeclareLocal into a helper class.
110
111         This is required to fix foreach in iterators.
112
113 Large project:
114 --------------
115
116         Drop FindMembers as our API and instead extract all the data
117         out of a type the first time into our own datastructures, and
118         use that to navigate and search the type instead of the
119         callback based FindMembers.     
120
121         Martin has some some of this work with his TypeHandle code
122         that we could use for this.
123
124 Ideas:
125 ------
126
127         Instead of the hack that *knows* about System.Object not having any children classes,
128         we should just make it simple for a probe to know that there is no need for it.
129
130 Dead Code Elimination bugs:
131 ---------------------------
132
133         I should also resolve all the children expressions in Switch, Fixed, Using.
134
135 Major tasks:
136 ------------
137         Properties and 17.6.3: Finish it.
138
139 readonly variables and ref/out
140         
141 BUGS
142 ----
143
144 * Break/Continue statements
145
146         A finally block should reset the InLoop/LoopBegin/LoopEnd, as
147         they are logically outside the scope of the loop.
148
149 * Break/continue part 2.
150
151         They should transfer control to the finally block if inside a try/catch
152         block.
153
154 * Method Registration and error CS111
155
156         The way we use the method registration to signal 111 is wrong.
157         
158         Method registration should only be used to register methodbuilders,
159         we need an alternate method of checking for duplicates.
160
161 *
162 > // CSC sets beforefieldinit
163 > class X {
164 >   // .cctor will be generated by compiler
165 >   public static readonly object O = new System.Object ();
166 >   public static void Main () {}
167 > }
168
169
170 PENDING TASKS
171 -------------
172
173 * Merge test 89 and test-34
174
175 * Code cleanup
176
177         The information when registering a method in InternalParameters
178         is duplicated, you can always get the types from the InternalParameters
179
180 * Emit modreq for volatiles
181
182         Handle modreq from public apis.
183
184 * Merge tree.cs, rootcontext.cs
185
186 OPTIMIZATIONS
187 -------------
188
189 * User Defined Conversions is doing way too many calls to do union sets that are not needed
190
191 * Add test case for destructors
192
193 * Places that use `Ldelema' are basically places where I will be
194   initializing a value type.  I could apply an optimization to 
195   disable the implicit local temporary from being created (by using
196   the method in New).
197
198 * Dropping TypeContainer as an argument to EmitContext
199
200         My theory is that I can get rid of the TypeBuilder completely from
201         the EmitContext, and have typecasts where it is used (from
202         DeclSpace to where it matters).  
203
204         The only pending problem is that the code that implements Aliases
205         is on TypeContainer, and probably should go in DeclSpace.
206
207 * Tests
208
209         Write tests for the various reference conversions.  We have
210         test for all the numeric conversions.
211
212 * Optimizations: variable allocation.
213
214         When local variables of a type are required, we should request
215         the variable and later release it when we are done, so that
216         the same local variable slot can be reused later on.
217
218 * Add a cache for the various GetArrayMethod operations.
219
220 * MakeUnionSet Callers
221
222         If the types are the same, there is no need to compute the unionset,
223         we can just use the list from one of the types.
224
225 * Factor the lookup code for class declarations an interfaces
226   (interface.cs:GetInterfaceByName)
227
228 RECOMMENDATIONS
229 ---------------
230
231 * Use of lexer.Location in the parser
232
233         Currently we do:
234
235         TOKEN nt TERMINAL nt TERMINAL nt3 {
236                 $$ = new Blah ($2, $4, $6, lexer.Location);
237         }
238
239         This is bad, because the lexer.Location is for the last item in `nt3'
240
241         We need to change that to use this pattern:
242
243         TOKEN { oob_stack.Push (lexer.Location) } nt TERMINAL nt TERMINAL nt3 {
244                 $$ = new Blah ($3, $5, $7, (Location) oob_stack.Pop ());
245         }
246
247         Notice how numbering of the arguments changes as the
248         { oob_stack.Push (lexer.Location) } takes a "slot"  in the productions.
249
250