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