forked from RefactoringTools/HaRe
-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathNOTES
212 lines (130 loc) · 6.26 KB
/
NOTES
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
Comparison of the hackage 0.6.0.2 version with this repo
1. editors directory removed
2. misc directory added
3. testing directory (still here :) )
4. Annotated the differences in ./refactorer
5. TODO: check StrategyLib and tools directories
-------------------------
Seems Language.Haskell.Interpreter will return an error if there are any warnings when loading a module.
Will modify tests to avoid warnings, for now, but must address in future.
Original tests (with good results) are here
https://github.com/alanz/HaRe/tree/71f80d2a59058acd6088c98d9748999f90ab0195/testing
Original data structures are here
http://www.cs.kent.ac.uk/projects/refactor-fp/hare/API_Doc/HsModule.html
-------------------------------------
Requirements for interface to GHC data structures
-------------------------------------------------
1. Allow generic queries via SYB etc.
2. Allow generic transformations via SYB etc.
3. Maintain tokens with AST fragment. In particular
a. If a fragment is duplicated, its tokens are duplicated.
b. If a fragment is removed, its tokens are removed.
c. If a partial refactor has been done, the token and AST manipulations remain sane
e.g. The new AST SrcLocs can be tied up to the new token stream.
4. Do not obscure existing AST (Renamed or TypeChecked)
i.e. allow matching on structures from AST.
5. Allow converting the structure back into a source file accurately
reflecting only the required changes (via Token stream)
Options
1. As is, but re-order everything. Problem comes with re-sequencing
source locations in AST.
2. As is, but put new interface on tokens only, to somehow tie them up to the AST.
Q: How to mark changed AST elements, and keep them indexed into the tokens structure.
Q: How to manage reconstructing the source file?
3. Some kind of virtual zipper, with the hole element being an AST
fragment and its associated tokens.
Q: how would traversals work?
Q: how would the structure be dumped at the end.
4. Variation on 2: Some kind of annotated token stream, with markers
on it to indicated tokens added to the original stream, removed
from it, or replacing others. This could be something like a list
of edit commands for an editor, and could be presented as such
(perhaps).
Observations
1. The tie-up between the AST and the tokens is via SrcLoc.Located
The rich token stream is [(Located Token, String)]
Each AST element is located.
2. We currently have fetchOrigToks in the RefactGhc monad to get
original tokens for an AST element
3. At the moment, the Located part of the AST is not updated as
re-arrangements are made. I suspect that the complexity of doing
this will not be worth the result.
4. The final output happens via the token stream.
5. The only leeway with the RealSrcLoc is the Int pairs pertaining
to the start and end line/col pairs. Perhaps use either -ve
values, or add an offset. Max value of an int is guaranteed to be
at least 2^29-1 or 536,870,911. Anything above 1M will do.
6. The bind SrcLoc does not tie up directly with the token SrcLoc
due to surrounding comments
7. The surrounding indent can perhaps be managed within this
structure.
8. The GHC ParsedSource is in linear order, the RenamedSource is not
Further thoughts on Token/AST tie up
------------------------------------
Layout is the biggest problem, in terms of knock-on effect of layout changes.
This is a solved problem, in the pretty-print world.
So, try and represent the token tree as a representation of the layout
elements of the original AST.
To do this, must identify the critical layout points, REQUIRED by haskell.
Even further thoughts
---------------------
Consider using dual-tree as in diagrams. The theory is explained here
http://www.cis.upenn.edu/~byorgey/pub/monoid-pearl.pdf.
In this case the u annotation would be the token start and end.
The d actions would be
Delete a span
Add a span
------------------------------------------------------------------------
Requirements for IDE/GHC interfacing (ghc-mod or similar)
-----------------------------------------------------
BIOS level (downward)
---------------------
0. Overall goal
Provide a set of features to enable tool writers to focus on the tool, rather
than the myriad details of interfacing with the environment.
1. Identify current project environment
This includes if it is a cabal project, whether it has a sandbox, is it
configured, etc, abstracting O/S dependencies inthe process.
Example: ghc-mod Cradle.
2. Identify possible build targets
Provide a list of all libraries, exes, benchmarks, tests in the cabal file, or
just the file concerned if no cabal file.
3. Provide a shared cache of the loaded module graph for particular components.
There is no point in having each tool separately load the module graph.
4. Potentially: provide a monad transformer stack for GHC API interaction
As in ghc-mod. This should be geared towards error handling and logging, with a
clear separation of errors/warnings in the code being operated on by the tool
and those in the tool infrastructure.
IDE (upward)
------------
Provide a common means to communicate with IDE's to interact with tooling. This
should probably be a simple protocol definition for commands and responses, and
a set of transport definitions for the protocol.
Possible transports
- RPC
- direct API call
- HTTP or similar
It should be possible to run the tooling environment on a separate host from the
IDE, whether in a docker container on the same host, or remotely, possibly even
in a cross-compilation environment.
Plugin level
------------
Provide a set of facilities to allow tools to be written that can easily make
use of the IDE and GHC interfaces above.
This could be a set of APIs that are statically linked into the tool in a
standalone fashion, or some way of having a project session running with
multiple tools all plugged into it.
E.g a future GHC based hlint, HaRe, a future GHC based hindent.
----------------------------------------------
Compilation time. 2015-11-04
------------------------------
GHC 7.10.2.20151030
$ cabal clean && cabal configure
$ time cabal build
real 11m4.113s
user 18m36.260s
sys 15m54.916s
GHC 7.10.2
real 11m17.474s
user 19m9.388s
sys 16m21.064s