-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
executable file
·539 lines (409 loc) · 22.6 KB
/
README
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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
_ _ ____
| | | | __ _ | _ \ ___
| |_| |/ _` | | |_) / _ \
| _ | (_| | | _ < __/
|_| |_|\__,_| |_| \_\___|
HaRe, the Haskell Refactorer
a snapshot of our current prototype
07/07/2010
http://www.cs.kent.ac.uk/projects/refactor-fp/hare.html
--------------------------------------------------------------------------------
This snapshot includes most dependencies (version A below), and
should build and work on Windows/Cygwin and Unix, with either gvim
6.2 or with emacs 21.4.
HaRe_07072010 (HaRe 0.6) is still a prototype, made available so
you can play with basic refactoring support for Haskell, and give us
feedback or bug reports (see below for changes since HaRe 0.5 and
known remaining issues). The major new feature in this 0.6 release -
apart from bug fixes - is a number of new refactorings.
WE DO NOT RECOMMEND TO USE THIS PROTOTYPE ON YOUR PRODUCTION SOURCES JUST YET!
--------------------------------------------------------------------------------
--------------- what you need
0 basics:
1. ghc-6.12.1
2. hint-0.3.2.3 (available from cabal)
3. unix/gnu tools (or cygwin tools, if on windows)
4. vim or emacs (we've tested with gvim 6.2 and with emacs 21.4)
5. If you intend on running the test suite, HUnit-1.0.
A [recommended] partial build
(fewer tools needed, but tied to particular snapshot):
1. fetch refactorer snapshot. this includes:
- modified Programatica snapshot (includes happy output)
- refactorer sources
--------------- one easy way to arrange these things
the following text assumes this directory structure
and unix/cygwin tools (adapt makefile if necessary):
README.txt <- you're reading this
makefile
editors <- editor interface scripts for Vim/Emacs
refactorer <- refactorer
StrategyLib-4.0-beta <- Strafunski's library for strategic programming
diffs <- modified files for tools
tools <- programatica snapshot
You might want to check the paths in makefile,
refactorer/HuMakefile and refactorer/myghc--make for sanity wrt to
your system (you should not actually need Happy for A). They should
work without change on windows/cygwin (windows/mingw has also been
reported to work), and feedback from the first release suggests the
same for unixish systems, from Max OS X to Linux (please let us know
if not, or if you can add new platforms).
If on Suns, the call to ghc in refactorer/myghc--make needs a little
looking after: in principle, you could remove the SunOS*) case and
use the default case *). In practice, at least on Suns, you will
want to make sure that ghc uses the linker from binutils instead of
the Sun linker (order of magnitude difference in linking time..),
which is what setting GCC_EXEC_PREFIX before calling ghc does - just
put in the path to your local binutils installation.
***IMPORTANT*** for Mac OS users: please make sure that the .gvimrc
file contains the lines
set noguipty
set nocompatible
--------------- how to build
1. run:
runhaskell Setup.hs configure --prefix /path/to/hare
(where /path/to/hare is a folder with read/write access)
runhaskell Setup.hs build
runhaskell Setup.hs install
export PATH=/path/to/hare/bin:$PATH
--------------- how to use
2. load the scripted interface into your favourite editor
(you may or may not want to include this in your standard
startup files for Haskell)
- emacs:
M-x load-file /path/to/hare/share/hare-0.6/haskell-refac.el
M-x haskell-refac-mode
(to switch off: M-x haskell-refac-mode)
You will then need to customize HaRe to point to your installation
so Programatica can find its chase files.
In the refactoring menu, go to customize -> chasepaths.
Replace HaskellLibraries with: /path/to/hare/share/hare-0.6
Choose Save.
- gvim:
:source editors/refactor.vim
:RefacStart (or select start from menu)
:RefacStop (or select stop from menu)
You will then need to customize HaRe to point to your installation
so Programatica can find its chase files.
In the refactoring menu, go to customize -> chasepaths.
Replace HaskellLibraries with: /path/to/hare/share/hare-0.6
Choose Save.
3. this should give you a menu with refactoring commands,
and a separate refactoring process.
4. the Programatica frontend we use is project-based. before
doing any refactorings, you have to start a project (select
"new" to start a project with only the current module in it,
then select "chase" to add the Prelude modules). project
settings are kept in a "hi" directory, created in the current
directory (it is recommended to edit files from within the
directory they reside in).
***IMPORTANT:*** Please re-create your projects once you have
updated your HaRe to a new snapshot/release.
5. for most refactorings, the editor interface will pass the
current filename (should be the module name, as well), the
refactoring command, and the current cursor position. For
some refactorings, you'll also need to highlight an
expression, or enter a new name. Here's the current list:
Introduce Pattern Match : place cursor over pattern variable
Introduce Sub pattern : place cursor over pattern variable
Introduce Case Expression : place cursor over pattern variable
Generative Fold : highlight expression to fold.
Must have equation in comment directly before
definition of highlighted expression.
Clone Analysis : select from menu
Clone Extraction : highlight clone from the clone class to extract, follow
step-by-step instructions.
Converting Let to Where : place cursor at start of identifer whose
definition is to be moved
Converting Where to Let : place cursor at start of identifer whose
definition is to be moved.
create type signatures : select from menu
remove redundant declarations
: highlight definition to clean up
add constructor to data
type : place cursor at start of data type, you'll
be prompted to add the new Constructor
name, followed by any Type parameters as a
complete string
Split a tuple : place cureso at start of top level definition that
returns a tuple.
Slicing based on a subexpression
: highlight sub-expression to extract.
Instantiate a general pattern
: select a function equation and enter
the new instances for each pattern in the argument set.
Extract an expression : highlight an expression within a definition
Convert data type to
newtype : place cursor at start of data type
add definition to merge : place cursor at start of definition that is to be merged
merge definitions : use "add definition for merge" for each definition to be merged.
then choose merge definitions from menu.
fold function definition : highlight function equation to fold against.
fold constant definition : highlight constant equation to foldl against.
convert pattern to an as pattern
: highlight pattern to convert.
unfold references to as patterns
: place cursor over as pattern name.
remove field from a data type
: place cursor at start of field to remove.
add field to data type
: place cursor over start of constructor.
enter new field name.
add debug information : add trace calls to function by placing cursor at the
start of the function to trace
rename : place cursor at start of identifier to
be renamed, you'll be prompted for a
new name
Lift def to top level : place cursor at start of identifier
whose definition is to be moved
Lift def one level : place cursor at start of identifier
whose definition is to be moved
Demote : place cursor at start of identifier
whose definition is to be moved
Introduce new def : highlight expression to be named,
you'll be prompted for a new name
Unfold def : place cursor at start of identifier
where its definition is to be unfolded
Generalise def : place cursor at start of identifier
where its definition is to be unfolded
Remove def : place cursor at start of identifier
whose definition is to be removed
Duplicate def : place cursor at start of identifier
whose definition is to be duplicated,
you'll be prompted for a new name
Add one parameter : place cursor at start of identifier
whose definition is to be modified,
you'll be prompted for a new name
rm one parameter : place cursor in formal parameter
which is to be removed
Move def to another module : place cursor at start of the identifier
whose definition is to be moved, you'll
be prompted for the module name
Clean imports : cursor position does not matter, just
choose the command from the refactor menu
Make import explicit : place cursor at the start of the module
name in the import declaration
Add to export : place cursor at start of the identifier
which is to be added to the export
Remove from export : place cursor at start of the entry to
be removed in the export list
From concrete to abstract data type: place cursor at start of the data type name
Add field names : place cursor at start of the data type name
Add discriminators : place cursor at start of the data type name
Add constructors : place cursor at start of the data type name
Eliminate nested patterns : place cursor at start of the data type name
Eliminate patterns : place cursor at start of the data type name
Create an ADT module : place cursor at start of the data type name
Eliminate intermidiate list: cusor position does not matter, just choose
the command from the menu.
6. If the 'Customize' menu in Emacs does not work, you can do the customisation by:
M-x customize-group / haskell-refac
--------------- known issues
- the editor interface still needs improvement, although
all known bugs have been fixed (windows vim users: it is
recommended to install vim in its standard location).
- there is no standard for associating comments with
semantic entities. we use heuristics to decide when
to move/remove comments together with definitions
=> these heuristics may not match everyone's
commenting style
outline:
when (re-)moving a definition, we also (re-)move the last
consecutive comments right before this definition (with at most one
empty line between the comments and the definition); we also
(re-)move the comment whose start location is in the same line as
the definition's last line of code.
Example:
....
--Comment1
--Comment2
--Comment3
fun1 x = x+1 --Comment4
--Comment5
...
In this case, Comment2, Comment3 and Comment4 belong to function fun1.
- if you're routinely working in a mixed Windows/Unix setup, you'll
notice that the file-format (encoding of line endings) of HaRe
output depends on whether you're using a Windows or a Unix HaRe,
not on whether the input is in Windows or Unix format.
- the Programatica frontend is currently limited to Haskell 98
- the Programatica frontend does not work with no-source files.
---------------change from 08/05/2009
-- general
+ make HaRe compatible with the latest version of GHC
+ ported to hint library, as an abstraction for GHC API.
+ bug fixes.
---------------change from 22/11/2006
-- general
+ make HaRE compatible with the latest version of GHC
+ several refactorings and bug fixes relating to slicing refactorings have
been added
+ API has been extended
+ Now uses GHC API for some refactorings
---------------changes from 15/04/2005
-- general
+ make HaRe compatable with the latest version of GHC and Programatica.
+ Several refactorings related to slicing and data types have been
added.
+ A pointwise to pointfree transformation has been added.
---------------changes from 11/03/2005
-- bugfix
-- Introduce new defintion: only replaced the highlighted expression if the expression
contains negative numbers.
-- checking for inscoped identifiers.
-- checking for conflicting export list.
---------------changes from 03/12/2004
--gereral
removed the unnecessary files in the snapshot.
--bugfix
-- Introduce new definition: only replaced the highlighted expression if the expression
contains literals.
----------------changes from 19/11/2004
-- general
+ Updated to a new Programatica version which supports hierarchical modules.
+ Adding an refactoring to the editor now only need to modify only file.
-- bugfixes
+ the 'Customize' menu did not work.
----------------changes from 16/09/2004
-- general
+ The API. An API for program analysis and tranformation. Together with Programatica and Strafunski,
this API can be used for the implementation for elementary refactorings. The file that contains
this API is RefacUtils.hs (the module name is RefacUtils). You can find the documentation for the
API at HaRe_20012008/refactorer/doc.
+ The hidden token stream manipulation. The basic idea is to move the token stream manipulations
from the implementation of individual refactorings to the API, so that a program transformation
function from the API modifies not only the AST but also the token stream. This liberates the
implementator of refactoring from caring about the token stream.
+ For those users who are interested in the implementation of refactorings, we have written and
documented the implementation of two very simple refactorings: swapping the first two arguments
of a function, and from it-then-else expression to case expression. You can find the implementation
at HaRe_20012008/refactorer/RefacSwapArgs.hs, and HaRe_20012008/refactorer/RefacCase.hs.
+ We have a test suite to HaRe 0.3, and you can find it at HaRe_20012008/testing. There is a README file
to explain how it works.
--------------- changes from 09/08/2004
-- bugfixes
+ demote directly recursive definition.
+ non-break space
---------------changes from 26/04/2004
- features
+ The refactor menu has been switched to hierarchical menus to reduce clutter.
+ In 'generalise a definition', 'replace all' has been switched on.
- refactoring
- new refactorings:
+ 'from concrete to abstract data type': transforms a concrete data type defintion into an abstract one.
This is a composite refactoring. It consists of five elementary refactorings:
+ 'Add field names': add field names to a data type declaration.
+ 'Add disriminators': add a discriminator for each data constructor defined in the identified data type.
+ 'Add constructors': add a constructor function for each data constructor defined in the identified data type.
+ 'Eliminate nested patterns': remove patterns nested in a pattern specified by the data constructor defined
in the identified data type.
+ 'Eliminate patterns': remove those patterns specified by the data constructor defined in the identified data type.
+ 'Create an ADT module': create the ADT module interface.
+ 'eliminate intermidiate list' (this refactoring is still in an experimental stage)
-bug fixes
+ After generalising a function with a type signature, the type signature is now commented out in the program source.
+ wrong layout when refactoring on operator functions.
+ wrong layout when refactoring on an expression ending with [] or ()
--------------- changes from 26/02/2004
- general
- update to a new Programmatica version
- refactoring
- new refactorings:
+ 'move def to another module' : move a definition from the current
module to a user-specified module
+ 'clean imports' : remove redundancies from the imports
+ 'make import implicit' : make the used entities from an
import explicit in the declaration
+ 'add to export' : add an entity to the export list
+ 'remove from export' : remove an entity from the export list
- bugfixes:
+ qualified uses of a top-level identifier becomes
unqualified after its definition has been demoted.
--------------- changes from 27/01/2004
- refactoring
- features:
+ in 'introduce a new definition', 'replace all' has been
switched on. The refactorer should be able to detect all
identical expressions in the scope.
+ operators can now be renamed
- bugfixes:
+ module names can differ from file names
+ avoid dangling parenthesis after unfoldDef
(could trigger layout rule syntax errors)
+ do not reverse names of new variables introduced
by unfoldDef (did you know that 0_x is legal?-)
+ do not trip over hard tabs
+ give an error message when trying to lifting a definition
in a class/instance declaration to the top level.
+ only write client modules when they are really changed.
+ renaming data types should not rename data constructors as well
+ lifting defs should not add globally available ids as parameters
+ the reported layout bugs with lifitng and intro new defs have
been fixed
- known issues
+ hard tabs are not counted correctly yet
+ refactorings shouldn't introduce hard tabs!
- editor interfaces
- features:
+ Emacs: thanks to help from JP Bernardy, we have now moved the
emacs lisp script to a subset that both Emacs and XEmacs can
work with; in the process, the gui has been cleaned up a bit
and should now operate more like a normal minor mode..
+ Vim: don't try to open files modified by the refactorer,
unless they are already associated with a buffer; show
warning dialog instead (now in line with emacs version)
- bugfixes:
+ Emacs: don't create separate refactoring processes per buffer
- known issues
+ in Vim, it is still possible to start refactorings while
there are modified buffers (fixed in Emacs a while ago)
--------------- changes from 01/10/2003
- general:
- Programatica and HaRe have added workarounds for the Template
Haskell syntax problems in ghc-6.0, so HaRe now builds with
ghc-6.0.1 (ghc-6.2.1 has introduced yet another change, so does
not work yet..)
- upgraded to StrategyLib-4.0-beta
- refactoring:
- Programatica frontend does now give source location information
for all literals
=> refactorings should no longer have problems with String and
Char literals
- HaRe is now module-aware: all refactorings have been updated to
try and take import/export relations into account.
- following your requests, HaRe can now work with literate Haskell
files. This relies on some guesswork, so expect to find some
rough corners - please report your experience so we can try to
fix problems. Might also interact oddly with our heuristics for
attaching comments to definitions.
- Automatic renaming has been disabled during liftOneLevel,
liftToTopLevel, demote and generaliseDef. In the case that one
of these refactorings will cause name clash/capture, the user
will be prompted to do renaming first.
- refactoring bugfixes:
+ introNewDef and generaliseDef now replace the marked expression
itself, not the first occurrence of the marked expression
+ wrong layout during liftOneLevel
+ non-exhaustive case in RefacLocUtils.hs
+ missing parentheses during generaliseDef
+ a parameter can be now be removed from a direct recursive
definition if it is not used in the definition.
+ when adding an parameter to a direct recursive definition, use
the new formal parameter name, instead of the default actual argument
name, as the actual argument inside this function.
+ the way to created a new name has been changed. For example add a
new parameter 'y' to a definition 'f', the default argument name is
f_y instead of 'f_y_1'.
+ erroneous caching of export list
+ multi-module undo
...
- editor interfaces:
- Emacs now reloads files modified by the refactorer without
prompting the user, and warns when a refactoring has changed
files not currently opened.
- editor interface bugfixes:
Emacs:
+ the error-in-mini-buffer effects preventing file reloading
in some Emacs configurations were finally traced and
eliminated (the stopwatch issue also seems to be gone).
+ refac buffer now automatically scrolls to last line
+ refactorings are now blocked while there are unsaved buffers