1 package acl2s.plugin.editors.lisp;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.File;
5 import java.io.InputStream;
6 import java.util.ArrayList;
7 import java.util.HashSet;
8 import java.util.LinkedList;
9 import java.util.TreeSet;
10
11 import org.eclipse.core.runtime.CoreException;
12 import org.eclipse.jface.text.BadLocationException;
13 import org.eclipse.jface.text.DocumentEvent;
14 import org.eclipse.jface.text.DocumentPartitioningChangedEvent;
15 import org.eclipse.jface.text.IRegion;
16 import org.eclipse.jface.text.Region;
17 import org.eclipse.ui.IEditorInput;
18 import org.eclipse.ui.IFileEditorInput;
19 import org.peterd.util.io.MiscIO;
20
21 import acl2s.lib.certify.Certifier;
22 import acl2s.lib.parse.EmptyParse;
23 import acl2s.lib.parse.IParseContext;
24 import acl2s.lib.parse.ParseException;
25 import acl2s.lib.parse.PositionedParseException;
26 import acl2s.lib.parse.StringParser;
27 import acl2s.lib.parse.SubstringParser;
28 import acl2s.lib.parse.obj.LispObject;
29 import acl2s.lib.session.IEnvInfo;
30 import acl2s.lib.session.IStatusInfo;
31 import acl2s.lib.session.SessionDeadException;
32 import acl2s.lib.session.SessionException;
33 import acl2s.lib.session.SessionMode;
34 import acl2s.plugin.Acl2sPlugin;
35 import acl2s.plugin.IPeerDocument;
36 import acl2s.plugin.ISessionDocument;
37 import acl2s.plugin.editors.A2sDocument;
38 import acl2s.plugin.editors.A2sEditor;
39 import acl2s.plugin.editors.AbstractDocumentPartitioner;
40 import acl2s.plugin.editors.MyDocumentProvider;
41 import acl2s.plugin.editors.MyTypedRegion;
42 import acl2s.plugin.parse.DocumentParser;
43 import acl2s.plugin.parse.LispToken;
44 import acl2s.plugin.parse.LispTokens;
45 import acl2s.plugin.prefs.InteractionPrefs;
46 import acl2s.uilib.cmd.BadCmdException;
47 import acl2s.uilib.cmd.ResolvableUserInput;
48 import acl2s.uilib.cmd.ResolvedInput;
49 import acl2s.uilib.session.IInputInfo;
50 import acl2s.uilib.session.ISessionModel;
51 import acl2s.uilib.session.ISessionStatusListener;
52 import acl2s.uilib.session.RedoInput;
53 import acl2s.uilib.session.StartupInputAndEnv;
54 import acl2s.uilib.session.UndoInput;
55
56 public class LispDocument extends A2sDocument implements IPeerDocument {
57 public static String ID = LispDocument.class.getCanonicalName();
58
59 protected final Partitioner ldp = new Partitioner();
60 protected ISessionDocument ses = null;
61
62 // ====== DATA / ACCESS / STORAGE =======
63 private class DoneInfo {
64 int modelIdx;
65 ResolvedInput input;
66
67 protected DoneInfo(int modelIdx, ResolvedInput input) {
68 this.modelIdx = modelIdx;
69 this.input = input;
70 }
71
72 public int getInputType() {
73 if (input == null) {
74 return ResolvedInput.UNKNOWN;
75 } else {
76 return input.getType();
77 }
78 }
79 }
80
81 private class AboveInfo {
82 Region region;
83 ResolvableUserInput resolvable;
84
85 protected AboveInfo(Region region, ResolvableUserInput resolvable) {
86 this.region = region;
87 this.resolvable = resolvable;
88 }
89 }
90
91 protected final ArrayList<AboveInfo> aboveInfo = new ArrayList<AboveInfo>();
92 protected final ArrayList<DoneInfo> doneInfo = new ArrayList<DoneInfo>();
93
94 /* protected BeginBookCmdInput beginBookInput = null;
95 protected int beginBookIdx = -1;*/
96 protected SessionMode acl2Mode = SessionMode.compatible;
97 protected LineMode lineMode = LineMode.getDefault();
98
99 // just a view
100 protected transient int lineIdx = 0;
101 protected transient int todoIdx = 0;
102
103 protected void updateIdxs() {
104 lineIdx = getPreviousEnd(doneInfo.size());
105 todoIdx = getPreviousEnd(aboveInfo.size());
106 }
107
108 protected void checkIdxs() {
109 if (lineIdx != getPreviousEnd(doneInfo.size())) {
110 throw new IllegalStateException();
111 }
112 if (todoIdx != getPreviousEnd(aboveInfo.size())) {
113 throw new IllegalStateException();
114 }
115 }
116
117 private int getPreviousEnd(int i) {
118 assert i <= aboveInfo.size();
119 if (i > 0) {
120 return regionEnd(aboveInfo.get(i-1).region);
121 } else {
122 return 0;
123 }
124 }
125
126 public static int regionEnd(Region r) {
127 return r.getOffset() + r.getLength();
128 }
129
130 public MyTypedRegion getTodoRegion() {
131 return new MyTypedRegion(lineIdx,todoIdx-lineIdx,TODO);
132 }
133
134 public MyTypedRegion getBelowRegion() {
135 return new MyTypedRegion(todoIdx,getLength()-todoIdx,DEFAULT);
136 }
137
138 public int readOnlyPoint() { return todoIdx; }
139
140 @Override
141 protected boolean allowReplace(final int pos, final int length, final String text) {
142 if (pos < todoIdx) {
143 String pref = InteractionPrefs.getAboveEditPref(Acl2sPlugin.inDisplayThread() ? Acl2sPlugin.getShell() : null, this);
144 if (pref == InteractionPrefs.ABOVE_EDIT_UBT) {
145 display.asyncExec(new Runnable() {
146 public void run() {
147 int oldTodoIdx;
148 do {
149 oldTodoIdx = todoIdx;
150 retreatLine2(null);
151 } while (oldTodoIdx > todoIdx && pos < todoIdx);
152 LispDocument.this.replace2(pos, length, text);
153 }
154 });
155 }
156 return false;
157 } else {
158 return true;
159 }
160 }
161
162 public void replace(int pos, int length, String text) throws BadLocationException {
163 if (text != null && text.indexOf('\t') >= 0) {
164 text = text.replace("\t"," ");
165 // shouldn't happen ordinarily with sourceviewer autoedits
166 // not a general solution because caret doesn't cooperate
167 }
168 super.replace(pos, length, text);
169 }
170
171 public SessionMode getAcl2Mode() { return acl2Mode; }
172
173 public void setAcl2Mode(SessionMode mode) {
174 if (ses != null && ses.getManager().getStatus() != ISessionStatusListener.NO_SESSION) {
175 throw new IllegalStateException();
176 }
177 if (!mode.equals(acl2Mode)) {
178 acl2Mode = mode;
179 ensureDirty();
180 }
181 updateDescriptions();
182 }
183
184 public LineMode getLineMode() { return lineMode; }
185
186 public void setLineMode(LineMode mode) {
187 if (ses != null && ses.getManager().getStatus() != ISessionStatusListener.NO_SESSION) {
188 throw new IllegalStateException();
189 }
190 if (!mode.equals(lineMode)) {
191 lineMode = mode;
192 ensureDirty();
193 if (!lineMode.isAdvancable()) {
194 resetLineAndTodo();
195 }
196 }
197 updateDescriptions();
198 }
199
200 protected String doGetDescription() {
201 String desc;
202 if (ses != null) {
203 desc = "" + acl2Mode.getName() + " Mode";
204 if (!lineMode.equals(LineMode.getDefault())) {
205 desc += " (" + lineMode.getName() + ")";
206 }
207 if (!acl2Mode.getUsable()) {
208 desc += " (not installed!)";
209 }
210 } else {
211 desc = "(no associated session)";
212 }
213 if (acl2Mode.getBookDevAllowed() && hasBookCode()) {
214 desc += " + book code";
215 }
216 return desc;
217 }
218
219 public boolean hasBookCode() {
220 return tokens.pastBeginBookForm() > 0;
221 }
222
223 public String getPreamble() {
224 int pastIdx = tokens.pastBeginBookForm();
225 if (pastIdx > 0) {
226 return get2(0,pastIdx);
227 } else {
228 return null;
229 }
230 }
231
232 public boolean hasCompletedTangent() {
233 int i = 0;
234 for (;;) {
235 if (i >= doneInfo.size()) {
236 return false;
237 }
238 if (doneInfo.get(i).getInputType() == ResolvedInput.BEGIN_BOOK) {
239 break;
240 }
241 i++;
242 }
243 i++;
244 if (i >= doneInfo.size()) {
245 return false;
246 }
247 if (doneInfo.get(i).getInputType() != ResolvedInput.IN_PACKAGE) {
248 return false;
249 }
250 for (;;) {
251 i++;
252 if (i >= doneInfo.size()) {
253 return false;
254 }
255 if (doneInfo.get(i).input == null ||
256 !doneInfo.get(i).input.isEmbeddedEvent()) {
257 return true;
258 }
259 }
260 }
261
262 // CREATION/SETUP
263
264 public LispDocument(MyDocumentProvider dp) {
265 super(dp);
266 setDocumentPartitioner(ldp);
267 ldp.connect(this);
268 tokens = new LispTokens();
269 tokens.connect(this);
270 }
271
272 public ISessionDocument getSession() { return ses; }
273
274 public void dispose() {
275 tokens.disconnect();
276 }
277
278 public void setA2s(ISessionDocument a) {
279 if (ses != a) {
280 ses = a;
281 if (ses != null) {
282 ses.killSession(null);
283 }
284 doneInfo.clear();
285 updateIdxs();
286 }
287 /*
288 int max = ses.getModel().countCompletedCmds();
289 for (int i = 0; i < doneInfo.size(); i++) {
290 int idx = doneInfo.get(i).modelIdx;
291 if (idx < 0 || idx >= max) {
292 Acl2sPlugin.logWarning("Session model index out of bounds. Moving completed line appropriately.",null);
293 removeBadModelIdxsFrom(i);
294 ensureDirty();
295 break;
296 }
297 IInputInfo in = ses.getModel().getInput(doneInfo.get(i).modelIdx);
298 boolean formMatch = aboveInfo.get(i).resolvable.getInputString().equals(in.getInputString());
299 if (formMatch && in instanceof ResolvedInput) {
300 doneInfo.get(i).input = (ResolvedInput) in;
301 } else if (formMatch && in instanceof RedoInput) {
302 doneInfo.get(i).input = (ResolvedInput) (((RedoInput)in).getOriginalInput());
303 } else {
304 Acl2sPlugin.logWarning("Session history doesn't match indices stored for .lisp file. Moving completed line appropriately.",null);
305 removeBadModelIdxsFrom(i);
306 ensureDirty();
307 break;
308 }
309 }*/
310 partitioningChangedAll();
311 updateDescriptions();
312 }
313
314 /*
315 private void removeBadModelIdxsFrom(int i) {
316 for (int j = doneInfo.size() - 1; j >= i; j--) {
317 doneInfo.remove(i);
318 }
319 int oldLineIdx = lineIdx;
320 updateIdxs();
321 partitioningChanged(lineIdx,oldLineIdx - lineIdx);
322 }
323 */
324
325
326 // LOAD & SAVE
327
328 static class Annotation implements Comparable<Annotation> {
329 int idx;
330 int prio;
331 String str;
332
333 public Annotation(int idx, String str, int prio) {
334 this.idx = idx;
335 this.str = str;
336 this.prio = prio;
337 }
338
339 public int compareTo(Annotation that) {
340 if (this.idx == that.idx) {
341 return this.prio - that.prio;
342 } else {
343 return this.idx - that.idx;
344 }
345 }
346 }
347
348 public final static String TODO_STRING = "#|ACL2s-ToDo-Line|#\n";
349 public final static String SMODE_PREFIX = ";$ACL2s-SMode$;";
350 public final static String LMODE_PREFIX = ";$ACL2s-LMode$;";
351
352 public final static String PREAMBLE_START = "#|$ACL2s-Preamble$;\n";
353 public final static int PREAMBLE_START_LEN = PREAMBLE_START.length();
354 public final static String PREAMBLE_END = ";$ACL2s-Preamble$|#\n";
355 public final static int PREAMBLE_END_LEN = PREAMBLE_END.length();
356
357 public final static String OLD_LINE_STRING = ";$ACL2-A2S-LINE$;";
358 public final static String OLD_TODO_STRING = "#|THE-LINE-INPROGRESS|#\n";
359 public final static String OLD_SMODE_PREFIX = ";$ACL2-A2S-MODE$;";
360 public final static String OLD_LMODE_PREFIX = ";$ACL2-A2S-LMODE$;";
361
362 public final static String OLD_PREAMBLE_START = "#|$ACL2-A2S-PREAMBLE$;\n";
363 public final static int OLD_PREAMBLE_START_LEN = OLD_PREAMBLE_START.length();
364 public final static String OLD_PREAMBLE_END = ";$ACL2-A2S-PREAMBLE$|#\n";
365 public final static int OLD_PREAMBLE_END_LEN = OLD_PREAMBLE_END.length();
366
367 public InputStream getDumpStream() {
368 StringBuilder dump = new StringBuilder();
369
370 int pastIdx = 0;
371 if (acl2Mode.getBookDevAllowed()) {
372 pastIdx = tokens.pastBeginBookForm();
373 }
374 if (pastIdx > 0) {
375 dump.append(PREAMBLE_START);
376 }
377
378 // mode output
379 if (acl2Mode != SessionMode.compatible) {
380 String[] modeInit = acl2Mode.getInitStrings();
381 if (modeInit != null) {
382 for (int i = 0; i < modeInit.length; i++) {
383 dump.append(modeInit[i]);
384 }
385 }
386 dump.append(SMODE_PREFIX);
387 dump.append(acl2Mode.getName());
388 dump.append('\n');
389 }
390
391 if (lineMode != LineMode.enforced) {
392 dump.append(LMODE_PREFIX);
393 dump.append(lineMode.getName());
394 dump.append('\n');
395 }
396
397 TreeSet<Annotation> annotations = new TreeSet<Annotation>();
398
399
400 if (lineMode.savePositions() && todoIdx > 0) {
401 annotations.add(new Annotation(todoIdx,TODO_STRING,1));
402 }
403
404 if (pastIdx > 0) {
405 annotations.add(new Annotation(pastIdx,PREAMBLE_END,2));
406 }
407
408
409 int pos = 0;
410 for (Annotation a : annotations) { // in order
411 assert pos <= a.idx;
412 dump.append(get2(pos,a.idx-pos));
413 dump.append(a.str);
414 pos = a.idx;
415 }
416 dump.append(get2(pos,getLength()-pos));
417
418 return new ByteArrayInputStream(dump.toString().getBytes());
419 }
420
421 public void set(String init) {
422 aboveInfo.clear();
423 doneInfo.clear();
424 setDocumentPartitioner(null);
425 ldp.disconnect();
426 acl2Mode = SessionMode.compatible;
427
428 StringBuilder content = new StringBuilder(init);
429
430 int idx = 0; // translate all tabs to 8 spaces
431 for (; idx < content.length();) {
432 idx = content.indexOf("\t", idx+1);
433 if (idx < 0) break;
434 content.replace(idx,idx+1," ");
435 }
436 idx = 0; // remove all carriage returns
437 for (; idx < content.length();) {
438 idx = content.indexOf("\r", idx+1);
439 if (idx < 0) break;
440 content.replace(idx,idx+1,"");
441 }
442
443
444 // get rid of preamble markings; they're really for .lisp compatibility
445 idx = content.indexOf(PREAMBLE_START);
446 if (idx >= 0) {
447 content.replace(idx, idx + PREAMBLE_START_LEN, "");
448 } else {
449 idx = content.indexOf(OLD_PREAMBLE_START);
450 if (idx >= 0) {
451 content.replace(idx, idx + OLD_PREAMBLE_START_LEN, "");
452 }
453 }
454 idx = content.indexOf(PREAMBLE_END);
455 if (idx >= 0) {
456 content.replace(idx, idx + PREAMBLE_END_LEN, "");
457 } else {
458 idx = content.indexOf(OLD_PREAMBLE_END);
459 if (idx >= 0) {
460 content.replace(idx, idx + OLD_PREAMBLE_END_LEN, "");
461 }
462 }
463
464 // read and get rid of code before any session mode spec
465 idx = content.indexOf(SMODE_PREFIX);
466 if (idx < 0) idx = content.indexOf(OLD_SMODE_PREFIX);
467
468 if (idx >= 0) {
469 int after = content.indexOf(";", idx+1) + 1;
470 int eol = after;
471 while (eol < content.length()) {
472 char ch = content.charAt(eol);
473 if (ch == '\r' || ch == '\n') break;
474 eol++;
475 }
476 String modeString = content.substring(after,eol);
477 acl2Mode = Acl2sPlugin.getBaseConfig().lookupMode(modeString);
478 if (acl2Mode == null) {
479 acl2Mode = SessionMode.getUninstalledMode(modeString, new String[] { content.substring(0, idx) });
480 Acl2sPlugin.maybeWarnUninstalledMode(modeString);
481 // old approach:
482 //Acl2sPlugin.logWarning("Unrecognized session mode (using default instead): " + modeString, null);
483 //acl2Mode = Acl2sPlugin.getBaseConfig().getDefaultMode();
484 //ensureDirty();
485 }
486 int pastModeDef = eol+1;
487 if (pastModeDef < content.length() && content.charAt(eol) == '\r' &&
488 content.charAt(pastModeDef) == '\n') {
489 pastModeDef++;
490 }
491 content.delete(0,pastModeDef);
492 }
493
494 // read and get rid of any line mode spec
495 idx = content.indexOf(LMODE_PREFIX);
496 if (idx < 0) idx = content.indexOf(OLD_LMODE_PREFIX);
497
498 if (idx >= 0) {
499 int after = content.indexOf(";", idx+1) + 1;
500 int eol = after;
501 while (eol < content.length()) {
502 char ch = content.charAt(eol);
503 if (ch == '\r' || ch == '\n') break;
504 eol++;
505 }
506 String modeString = content.substring(after,eol);
507 lineMode = LineMode.lookup(modeString);
508 if (lineMode == null) {
509 Acl2sPlugin.logWarning("Unrecognized line mode (using default instead): " + modeString, null);
510 lineMode = LineMode.getDefault();
511 ensureDirty();
512 }
513 int pastModeDef = eol+1;
514 if (pastModeDef < content.length() && content.charAt(eol) == '\r' &&
515 content.charAt(pastModeDef) == '\n') {
516 pastModeDef++;
517 }
518 content.delete(0,pastModeDef);
519 }
520
521 // { Get rid of & ignore any old "line" spec
522 idx = content.indexOf(OLD_LINE_STRING);
523 if (idx >= 0) {
524 int eol = idx;
525 while (eol < content.length()) {
526 char ch = content.charAt(eol);
527 if (ch == '\r' || ch == '\n') break;
528 eol++;
529 }
530 int after = eol+1;
531 if (after < content.length() && content.charAt(eol) == '\r' &&
532 content.charAt(after) == '\n') {
533 after++;
534 }
535 content.delete(idx,after);
536 }
537 // }
538
539 lineIdx = 0;
540
541 // now find actual todo position
542 todoIdx = content.indexOf(TODO_STRING);
543 if (todoIdx < 0) todoIdx = content.indexOf(OLD_TODO_STRING);
544
545 if (todoIdx < 0) {
546 todoIdx = 0;
547 } else {
548 int after = content.indexOf("\n", todoIdx) + 1; // to accommodate either old or new
549 content.delete(todoIdx, after);
550
551
552 SubstringParser p = new SubstringParser(null,content,0,todoIdx);
553 try {
554 while (!p.eof()) {
555 int start = p.getPos();
556 ResolvableUserInput in = ResolvableUserInput.parse(p, ID, this.getSession());
557 /*if (in instanceof BeginBookCmdInput && beginBookInput == null) {
558 beginBookInput = (BeginBookCmdInput) in;
559 beginBookIdx = inputs.size() - 1;
560 }*/
561 int end = p.getPos();
562 aboveInfo.add(new AboveInfo(new Region(start,end-start),in));
563 }
564 } catch (EmptyParse ep) {
565 // ok
566 } catch (ParseException pe) {
567 lineIdx = 0;
568 todoIdx = 0;
569 aboveInfo.clear();
570 doneInfo.clear();
571 Acl2sPlugin.logWarning("Error restoring line position.",pe);
572 ensureDirty();
573 } catch (BadCmdException bce) {
574 lineIdx = 0;
575 todoIdx = 0;
576 aboveInfo.clear();
577 doneInfo.clear();
578 Acl2sPlugin.logWarning("Error restoring line position.",bce);
579 ensureDirty();
580 }
581
582 }
583 super.set(content.toString());
584 setDocumentPartitioner(ldp);
585 ldp.connect(this);
586 partitioningChangedAll();
587 updateDescriptions();
588 }
589
590 public LispDocumentProvider getProvider() {
591 return Acl2sPlugin.getLispDocumentProvider();
592 }
593
594
595 // LINE MANIPULATION
596
597 protected void doResetLine() {
598 if (doneInfo.size() == 0) return;
599 int oldLineIdx = lineIdx;
600 doneInfo.clear();
601 updateIdxs();
602 partitioningChanged(lineIdx,oldLineIdx - lineIdx);
603 //if (lineMode.savePositions()) ensureDirty(); // not anymore!
604 }
605
606 protected void doResetTodo() {
607 if (todoIdx == lineIdx) return;
608 int oldTodoIdx = todoIdx;
609 while (aboveInfo.size() > doneInfo.size()) {
610 aboveInfo.remove(aboveInfo.size()-1);
611 }
612 updateIdxs();
613 partitioningChanged(todoIdx,oldTodoIdx - todoIdx);
614 if (lineMode.savePositions()) ensureDirty();
615 }
616
617 protected void doResetLineAndTodo() {
618 if (aboveInfo.size() == 0) return;
619
620 int oldTodoIdx = todoIdx;
621 doneInfo.clear();
622 aboveInfo.clear();
623 updateIdxs();
624 partitioningChanged(0,oldTodoIdx);
625 if (oldTodoIdx != todoIdx)
626 if (lineMode.savePositions())
627 ensureDirty();
628 }
629
630 public boolean inOrAboveLine(int offset) {
631 return offset < todoIdx;
632 }
633
634 protected void doAdvanceLine(int modelIdx, ResolvedInput in) {
635 if (doneInfo.size() >= aboveInfo.size()) throw new IllegalStateException();
636 int oldLineIdx = lineIdx;
637 doneInfo.add(new DoneInfo(modelIdx,in));
638 updateIdxs();
639 partitioningChanged(oldLineIdx,lineIdx-oldLineIdx);
640 }
641
642 protected void doRetreatLine() {
643 if (doneInfo.size() == 0 || aboveInfo.size() > doneInfo.size()) throw new IllegalStateException();
644 int oldLineIdx = lineIdx;
645 doneInfo.remove(doneInfo.size()-1);
646 aboveInfo.remove(doneInfo.size());
647 updateIdxs();
648 partitioningChanged(lineIdx,oldLineIdx-lineIdx);
649 if (lineMode.savePositions()) ensureDirty();
650 }
651
652 protected void doRetreatTodo() {
653 if (todoIdx == lineIdx) throw new IllegalStateException();
654 int oldTodoIdx = todoIdx;
655 aboveInfo.remove(aboveInfo.size()-1);
656 updateIdxs();
657 partitioningChanged(todoIdx,oldTodoIdx - todoIdx);
658 if (lineMode.savePositions()) ensureDirty();
659 }
660
661 protected void addNextForm() throws BadCmdException, PositionedParseException, EmptyParse {
662 String below = getBelowRegion().getFromDocument(this);
663 StringParser p = new StringParser(null, below);
664 int start = todoIdx + p.getPos();
665 ResolvableUserInput in;
666 try {
667 in = ResolvableUserInput.parse(p,ID,this.getSession());
668 } catch (EmptyParse e) {
669 throw e;
670 } catch (ParseException pe) {
671 throw new PositionedParseException(pe,todoIdx + p.getPos());
672 }
673 int end = todoIdx + p.getPos();
674 aboveInfo.add(new AboveInfo(new Region(start,end-start),in));
675 }
676
677 protected void doAdvanceTodo() throws PositionedParseException, BadCmdException, EmptyParse {
678 int oldTodoIdx = todoIdx;
679 addNextForm();
680 updateIdxs();
681 partitioningChanged(oldTodoIdx,todoIdx-oldTodoIdx);
682 if (lineMode.savePositions()) ensureDirty();
683 notifyLineAdvancement();
684 resetUndoStuff();
685 }
686
687 public boolean isEmptyBelow() {
688 String below = getBelowRegion().getFromDocument(this);
689 StringParser p = new StringParser(null, below);
690 try {
691 p.skipSpaceAndComments();
692 } catch (ParseException e) {
693 return false;
694 }
695 return p.eof();
696 }
697
698 // ADVANCEMENT (for clearing undo history stuff)
699
700 protected final HashSet<LineAdvancementListener> ladvListeners = new HashSet<LineAdvancementListener>();
701
702 static interface LineAdvancementListener {
703 public void lineAdvanced();
704 }
705
706 public void addLineAdvancementListener(LineAdvancementListener l) {
707 ladvListeners.add(l);
708 }
709
710 public void removeLineAdvancementListener(LineAdvancementListener l) {
711 ladvListeners.remove(l);
712 }
713
714 protected void notifyLineAdvancement() {
715 for (LineAdvancementListener l : ladvListeners) {
716 l.lineAdvanced();
717 }
718 }
719
720 // PARTITIONER
721
722 public final static String PREAMBLE = "__a2s_preamble";
723 public final static String BOOK = "__a2s_book";
724 public final static String TANGENT = "__a2s_tangent";
725 public final static String TODO = "__a2s_line_todo";
726 public final static String DEFAULT = Partitioner.DEFAULT;
727
728 protected void partitioningChangedAll() {
729 partitioningChanged(0,getLength());
730 }
731
732 protected void partitioningChanged(int start, int len) {
733 ldp.computePartitions();
734 DocumentPartitioningChangedEvent dpce;
735 dpce = new DocumentPartitioningChangedEvent(this);
736 dpce.setPartitionChange(DEFAULT_PARTITIONING, start, len);
737 fireDocumentPartitioningChanged(dpce);
738 }
739
740 public static String[] getContentTypes() {
741 return new String[] { PREAMBLE, BOOK, TANGENT, TODO, DEFAULT };
742 }
743
744 public String[] getLegalContentTypes() {
745 return getContentTypes();
746 }
747
748 protected class Partitioner extends AbstractDocumentPartitioner {
749 private static final long serialVersionUID = 1L;
750
751 public String[] getLegalContentTypes() {
752 return getContentTypes();
753 }
754
755 public IRegion documentChanged2(DocumentEvent event) {
756 //computePartitions();
757
758 updateLast();
759
760 //return null;
761 //return new Region(todoIdx,doc.getLength()-todoIdx);
762
763 //int docLen = doc.getLength();
764 int added = event.fText.length() - event.fLength;
765 if (added < 0) added = 0;
766 return null; //new Region(docLen-added,added);
767 }
768
769 private void updateLast() {
770 updateIdxs();
771 int docLen = LispDocument.this.getLength();
772 int lastIdx = regions.size() - 1;
773 if (lastIdx >= 0 && regions.get(lastIdx).getType() == DEFAULT) {
774 MyTypedRegion r = new MyTypedRegion(todoIdx,docLen-todoIdx,DEFAULT);
775 replaceRegion(lastIdx,r,true);
776 } else {
777 addRegion(todoIdx,docLen,DEFAULT);
778 }
779 }
780
781 private void computePartitions() {
782 clearRegions();
783
784 int docLen = LispDocument.this.getLength();
785 int idx = 0;
786
787 //updateIdxs(); PREREQUISITE!
788 checkIdxs();
789
790 if (lineIdx > idx) { // <=> modelIdxs.size() > 0
791 int i = 0;
792 int toIdx;
793 if (i < doneInfo.size() && doneInfo.get(i).getInputType() != ResolvedInput.BEGIN_BOOK) {
794 do {
795 toIdx = regionEnd(aboveInfo.get(i).region);
796 i++;
797 } while (i < doneInfo.size() && doneInfo.get(i).getInputType() != ResolvedInput.BEGIN_BOOK);
798 addRegion(idx, toIdx, PREAMBLE);
799 idx = toIdx;
800 }
801 if (i < doneInfo.size()) { // <=> lineIdx > idx
802 toIdx = regionEnd(aboveInfo.get(i).region);
803 i++;
804 if (i < doneInfo.size() && (doneInfo.get(i).getInputType() == ResolvedInput.IN_PACKAGE)) {
805 do {
806 toIdx = regionEnd(aboveInfo.get(i).region);
807 i++;
808 } while (i < doneInfo.size() &&
809 doneInfo.get(i).input != null &&
810 doneInfo.get(i).input.isEmbeddedEvent());
811 }
812 addRegion(idx, toIdx, BOOK);
813 idx = toIdx;
814 if (lineIdx > idx) {
815 addRegion(idx, lineIdx, TANGENT);
816 idx = lineIdx;
817 }
818 }
819 }
820 if (todoIdx > idx) {
821 addRegion(idx, todoIdx, TODO);
822 idx = todoIdx;
823 }
824 if (docLen > idx) {
825 addRegion(idx, docLen, DEFAULT);
826 idx = docLen;
827 }
828 }
829 }
830
831
832 /*===================== to be called by A2s =================*/
833 protected IInputInfo curInput = null;
834 protected final LinkedList<UndoInput> undoInput = new LinkedList<UndoInput>();
835 //protected boolean deleteOnError = false;
836
837 private UndoInput getUndo(ResolvedInput in, int superIdx) {
838 return new UndoInput(in,superIdx,
839 ses.getManager().getSecret(),
840 in.getUndoMsg());
841 }
842
843 public IInputInfo nextInputOption() {
844 if (!lineMode.isAdvancable()) return null;
845 if (!undoInput.isEmpty()) {
846 curInput = undoInput.removeFirst();
847 return curInput;
848 }
849 // else no pending undo
850 if (doneInfo.size() == aboveInfo.size()) {
851 curInput = null;
852 return curInput;
853 }
854 // else pending 'todo' form(s)
855 ResolvableUserInput foo = aboveInfo.get(doneInfo.size()).resolvable;
856 ResolvedInput bar = null;
857 if (ses.getManager().isAlive()) {
858 try {
859 bar = foo.resolve(ses.getManager());
860 } catch (SessionException e) {
861 // shouldn't happen
862 Acl2sPlugin.logError("Acl2 session problem for system command.", e);
863 return null;
864 }
865 }
866 if (!lineMode.cancelOnError()) doAdvanceLine(0,bar);
867 curInput = bar;
868 if (ses.getManager().isAlive() && bar != null) { // bar != null probably redundant
869 if (!bar.couldNeedUndo() ||
870 bar.getUndoMsg() != null) {
871 return curInput;
872 }
873 }
874 if (!lineMode.cancelOnError()) { return curInput; } // no REDOs
875 // else REDO might be possible. keep checking...
876 ISessionModel model = ses.getModel();
877 IEnvInfo env = model.getEnv(model.countCompletedCmds());
878 if (env == null) return curInput; // no session yet!
879 if (env.getSuperUndoneSize() == 0) return curInput;
880 LispObject parsed = bar == null ? null : bar.getParsed();
881 int preDone = env.getSuperDoneSize();
882 int i = model.countCompletedCmds() - 1;
883 int balance = 0;
884 IEnvInfo oldPostEnv = env;
885 IEnvInfo oldPreEnv;
886 for (;i > 0;) { // the i > 0 shouldn't be needed
887 IInputInfo old = model.getInput(i);
888 oldPreEnv = model.getEnv(i);
889 if (old instanceof StartupInputAndEnv) {
890 return curInput;
891 } else if (old instanceof RedoInput) {
892 balance++;
893 } else if (old instanceof UndoInput && balance > 0) {
894 balance--;
895 } else if (old instanceof UndoInput) {
896 if (oldPostEnv.getSuperDoneSize() != preDone) return curInput;
897
898 UndoInput oldUndo = (UndoInput) old;
899 IInputInfo orig = oldUndo.getOriginalInput();
900 if (!(orig instanceof ResolvedInput)) return curInput;
901 ResolvedInput orig2 = (ResolvedInput) orig;
902
903 if (parsed != null) { // if post-resolved parsing is available, use it
904 LispObject oldParsed = orig2.getParsed();
905 if (!(parsed.equals(oldParsed))) return curInput;
906 } else {
907 if (!(orig2.abstractlyEquals(foo,env.getParseContext()))) return curInput;
908 }
909
910 int hist = oldPreEnv.getSuperDoneSize();
911 if (hist > env.getSuperDoneSize() + env.getSuperUndoneSize()) return curInput;
912 // everything checks out! make it a REDO
913 curInput = new RedoInput(orig,oldPreEnv.getSuperDoneSize(),ses.getManager().getSecret());
914 return curInput;
915 } else if (old instanceof ResolvedInput) {
916 ResolvedInput old2 = (ResolvedInput) old;
917 if (old2.couldNeedUndo()) {
918 // return curInput;
919 // break here if we want something that *potentially* affects
920 // history (but doesn't) to interfere with allowability of REDO
921 }
922 if (old2.getUndoMsg() != null) {
923 return curInput;
924 // could be something fishy
925 }
926 }
927 if (preDone > oldPostEnv.getSuperDoneSize() + oldPostEnv.getSuperUndoneSize()) {
928 return curInput;
929 // optimization to clip search when we know we've past
930 // where a matching undo would have been
931 }
932
933 // rewind one top-level form
934 do {
935 i--;
936 } while (i > 0 && model.getEnv(i).inWormhole());
937 oldPostEnv = oldPreEnv;
938 }
939 return curInput;
940 }
941
942 public void commandCompleted(IInputInfo in, IStatusInfo status, int modelIdx) {
943 if (!lineMode.cancelOnError()) return;
944 if (in == curInput) {
945 if (in instanceof ResolvedInput) {
946 if (!status.wasSuccess()) {
947 doResetTodo();
948 } else {
949 doAdvanceLine(modelIdx,(ResolvedInput) in);
950 }
951 } else if (in instanceof RedoInput) {
952 if (!status.wasSuccess()) {
953 Acl2sPlugin.logError("Error while redoing in ACL2:" + ses.getModel().getOutput(modelIdx), null);
954 ses.getManager().killSession();
955 }
956 IInputInfo orig = ((RedoInput)in).getOriginalInput();
957 if (!(orig instanceof ResolvedInput)) {
958 throw new IllegalStateException();
959 }
960 doAdvanceLine(modelIdx,(ResolvedInput) orig);
961 } else if (in instanceof UndoInput) {
962 if (!status.wasSuccess()) {
963 Acl2sPlugin.logError("Error while undoing in ACL2:" + ses.getModel().getOutput(modelIdx), null);
964 ses.getManager().killSession();
965 }
966 // nothing else to do
967 } else {
968 // impossible
969 throw new IllegalStateException();
970 }
971 curInput = null;
972 } else if (in.getSource().equals(ID)) {
973 if (status.extendedLogicalState()) {
974 if (!status.wasSuccess()) { // weird. we'll just fix it.
975 int superHistIdx = ses.getModel().getEnv(modelIdx).getSuperDoneSize();
976 String cmd = UndoInput.buildUndoString(superHistIdx, ses.getManager().getSecret());
977 try {
978 /* (void) */ ses.getManager().systemCmd2(cmd);
979 ses.getManager().updateModelEnv();
980 } catch (SessionException e) {
981 Acl2sPlugin.logError("Session died unexpectedly.", e);
982 }
983 } else { // it seems we canceled this in the mean time
984 // Undo to last superhistory index
985 int superIdx;
986 int doneCount = doneInfo.size();
987 if (doneCount == 0) {
988 superIdx = StartupInputAndEnv.instance.getSuperDoneSize();
989 } else {
990 superIdx = ses.getModel().getStatus(doneInfo.get(doneCount - 1).modelIdx).getSuperDoneSize();
991 }
992 undoInput.addFirst(getUndo((ResolvedInput) in, superIdx));
993 }
994 }
995 } else if (in instanceof ResolvedInput &&
996 status.extendedLogicalState()) {
997 // didn't come from line action
998 // & ResolvedInput means it came from user
999 // & we only care if it modified the world
1000 ResolvedInput c = (ResolvedInput) in;
1001
1002 String pref = InteractionPrefs.getRelevantCmdPref(Acl2sPlugin.inDisplayThread() ? Acl2sPlugin.getShell() : null, ses);
1003 if (pref.equals(InteractionPrefs.RELEVANT_CMD_INSERT)) {
1004 int oldTodoIdx = todoIdx;
1005 String formString = c.getInputString();
1006 int formStart;
1007 if (todoIdx == 0) {
1008 formStart = todoIdx;
1009 formString = formString + "\n\n";
1010 } else {
1011 formStart = todoIdx + 2;
1012 formString = "\n\n" + formString;
1013 }
1014 replace2(todoIdx,0,formString);
1015 aboveInfo.add(new AboveInfo(new Region(formStart,c.getInputString().length()),c));
1016 doneInfo.add(new DoneInfo(modelIdx,c));
1017 updateIdxs();
1018 partitioningChanged(oldTodoIdx,todoIdx-oldTodoIdx);
1019 notifyLineAdvancement();
1020 resetUndoStuff();
1021 } else {
1022 // Undo to last superhistory index
1023 int superIdx;
1024 int doneCount = doneInfo.size();
1025 if (doneCount == 0) {
1026 superIdx = StartupInputAndEnv.instance.getSuperDoneSize();
1027 } else {
1028 superIdx = ses.getModel().getStatus(doneInfo.get(doneCount - 1).modelIdx).getSuperDoneSize();
1029 }
1030 undoInput.addFirst(getUndo((ResolvedInput) in, superIdx));
1031 }
1032 }
1033 }
1034
1035 public void resetLineAndTodo() { // called by a2s on clean session
1036 curInput = null;
1037 doResetLineAndTodo();
1038 }
1039
1040 public void resetLine() { // called by a2s on restart/stop session
1041 curInput = null;
1042 doResetLine();
1043 undoInput.clear();
1044 }
1045
1046
1047 /*=================== to be called from editors (by ADs) ================*/
1048 /*protected boolean checkA2s(A2sEditor ctx) {
1049 if (a2s == null) {
1050 ctx.infoMessageBox("Not supported", "Operation not supported because this lisp file has no associated session. Go to menu `ACL2' | `Set session mode...' to change.");
1051 return false;
1052 } else {
1053 return true;
1054 }
1055 }*/
1056
1057 // allow null ctx!
1058 public void cancelTodo(A2sEditor ctx) {
1059 if (ses != null && curInput instanceof ResolvedInput) {
1060 try {
1061 ses.interrupt();
1062 } catch (SessionException e) {
1063 }
1064 curInput = null;
1065 }
1066 int oldTodoIdx = todoIdx;
1067 doResetTodo();
1068 if (ctx instanceof LispEditor)
1069 ctx.revealRange(todoIdx,oldTodoIdx-todoIdx);
1070 }
1071
1072 protected void advanceTodo2(A2sEditor ctx, boolean emptyOk) {
1073 try {
1074 doAdvanceTodo();
1075 if (ses != null) {
1076 ses.ping();
1077 }
1078 } catch (EmptyParse e) {
1079 if (!emptyOk) {
1080 ctx.infoMessageBox("Could not advance todo", "No more forms in Lisp file.");
1081 }
1082 } catch (PositionedParseException e) {
1083 ctx.setHighlightRange(e.getPos(),0,true);
1084 ctx.errorMessageBox("Parse Error", e.getMessage() + "\n\nCursor has been positioned at spot of error.");
1085 } catch (BadCmdException e) {
1086 String below = getBelowRegion().getFromDocument(this);
1087 StringParser p = new StringParser(null, below);
1088 try {
1089 p.skipSpaceAndComments();
1090 } catch (ParseException e1) {
1091 }
1092 ctx.setHighlightRange(todoIdx+p.getPos(),0,true);
1093 ctx.errorMessageBox("Bad Command", e.getMessage() + "\n\nCursor has been positioned at violating command.");
1094 }
1095 }
1096
1097 public void advanceTodo(A2sEditor ctx) {
1098 if (!lineMode.isAdvancable()) {
1099 ctx.infoMessageBox("Not supported", "Operation not supported in this line mode. Go to menu `ACL2' | `Set line mode...' to enable line tracking.");
1100 return;
1101 }
1102 int oldTodoIdx = todoIdx;
1103 advanceTodo2(ctx,false);
1104 if (ctx instanceof LispEditor)
1105 ctx.revealRange(oldTodoIdx,todoIdx-oldTodoIdx);
1106 }
1107
1108 public void allTodo(A2sEditor ctx) {
1109 if (!lineMode.isAdvancable()) {
1110 ctx.infoMessageBox("Not supported", "Operation not supported in this line mode. Go to menu `ACL2' | `Set line mode...' to enable line tracking.");
1111 return;
1112 }
1113 int savedTodoIdx;
1114 do {
1115 savedTodoIdx = todoIdx;
1116 advanceTodo2(ctx,true);
1117 } while (savedTodoIdx < todoIdx);
1118 }
1119
1120 // allow null ctx!
1121 protected void retreatLine2(A2sEditor ctx) {
1122 if (doneInfo.size() < aboveInfo.size()) {
1123 if (doneInfo.size() < aboveInfo.size() - 1) {
1124 doRetreatTodo();
1125 } else {
1126 cancelTodo(ctx);
1127 }
1128 } else {
1129 int inputIdx = doneInfo.size() - 1;
1130 int modelIdx = doneInfo.get(inputIdx).modelIdx;
1131 ResolvedInput input = doneInfo.get(inputIdx).input;
1132 assert input != null;
1133 /*if (input == null) {
1134 ctx.errorMessageBox("Error moving line", "Could not retreat line because document is still initializing.");
1135 return;
1136 }*/
1137 doRetreatLine();
1138 if (ses != null && lineMode.cancelOnError() && input.couldNeedUndo()) {
1139 IEnvInfo env = ses.getModel().getEnv(modelIdx);
1140 UndoInput undo = getUndo(input,env.getSuperDoneSize());
1141
1142 undoInput.addLast(undo);
1143 ses.ping();
1144 }
1145 }
1146 }
1147
1148 public void retreatLine(A2sEditor ctx) {
1149 if (aboveInfo.size() == 0) return;
1150
1151 int oldTodoIdx = todoIdx;
1152
1153 retreatLine2(ctx);
1154
1155 if (ctx instanceof LispEditor)
1156 ctx.revealRange(todoIdx,oldTodoIdx-todoIdx);
1157 }
1158
1159 public void retreatBackThrough(A2sEditor ctx, int modelIdx) {
1160 int oldTodoIdx = todoIdx;
1161
1162 for (;;) {
1163 int lastDone = doneInfo.size() - 1;
1164 if (lastDone < 0) break;
1165 if (doneInfo.get(lastDone).modelIdx < modelIdx) break;
1166 retreatLine2(ctx);
1167 }
1168
1169 if (ctx instanceof LispEditor)
1170 ctx.revealRange(todoIdx,oldTodoIdx-todoIdx);
1171 }
1172
1173 public void resetLineAndTodo(A2sEditor ctx) {
1174 if (aboveInfo.size() == 0) return;
1175 int oldTodoIdx;
1176 do {
1177 oldTodoIdx = todoIdx;
1178 retreatLine2(ctx);
1179 } while (aboveInfo.size() > 0);
1180
1181 if (ctx instanceof LispEditor)
1182 ctx.revealRange(todoIdx,oldTodoIdx-todoIdx);
1183 }
1184
1185 public void moveTodoPastPoint(int index, A2sEditor ctx) {
1186 if (index > todoIdx || (index == todoIdx && index == 0)) {
1187 // skip to beginning of whitespace if in it
1188 LispToken t = tokens.getToken(tokens.getTokenIdxContaining(index));
1189 if (index < t.offset || t.type == LispToken.EOF_TOK) {
1190 index = t.absoluteStart();
1191 }
1192
1193 int oldTodoIdx;
1194 do {
1195 oldTodoIdx = todoIdx;
1196 advanceTodo2(ctx, false);
1197 } while (oldTodoIdx < todoIdx && index > todoIdx);
1198 } else {
1199 int oldTodoIdx;
1200 do {
1201 if (aboveInfo.size() == 0) return;
1202 oldTodoIdx = todoIdx;
1203 retreatLine2(ctx);
1204 } while (oldTodoIdx > todoIdx && index < todoIdx);
1205 }
1206 }
1207
1208 public void moveTodoPastCursor(A2sEditor ctx) {
1209 if (!(ctx instanceof LispEditor)) {
1210 ctx.errorMessageBox("Not supported", "The invoked action is only supported in an ACL2/Lisp editor.");
1211 return;
1212 }
1213 int cursor = ctx.getDocCaret();
1214 if (lineMode.isAdvancable()) { // move line
1215 moveTodoPastPoint(cursor,ctx);
1216 } else { // submit form
1217 if (ses == null) {
1218 ctx.errorMessageBox("No associated session", "The invoked action is only supported with an " +
1219 "associated session that is running and ready for command input.");
1220 }
1221 if (ses.getManager().getStatus() != ISessionStatusListener.READY_CMD_SESSION) {
1222 ctx.errorMessageBox("Session not ready", "The invoked action is only supported with an " +
1223 "associated session that is running and ready for command input.");
1224 return;
1225 }
1226 int len = getLength();
1227 int backSearchFrom = len;
1228 if (cursor < backSearchFrom) {
1229 int tIdx = tokens.getTokenIdxContaining(cursor);
1230 backSearchFrom = tokens.getToken(tIdx).offset + 1;
1231 }
1232
1233 if (backSearchFrom >= len) {
1234 ctx.errorMessageBox("No more input", "No more input forms after cursor.");
1235 return;
1236 }
1237
1238 int start = tokens.formSearch(backSearchFrom, false);
1239
1240 try {
1241 IParseContext pc;
1242 DocumentParser dp;
1243 ResolvableUserInput preCmd;
1244 ResolvedInput cmd;
1245
1246 pc = ses.getManager().getCurrentEnv().getParseContext();
1247 dp = new DocumentParser(pc,this,start);
1248 try {
1249 preCmd = ResolvableUserInput.parse(dp,ID, this.getSession());
1250 cmd = preCmd.resolve(ses.getManager());
1251 cmd.throwIfBad();
1252 } catch (ParseException pe) {
1253 ctx.setDocCaret(dp.getPos());
1254 ctx.errorMessageBox("Parse Error", pe.getMessage() +
1255 "\n\nCursor has been positioned at spot of error.");
1256 return;
1257 } catch (BadCmdException e) {
1258 ctx.setDocCaret(start);
1259 ctx.errorMessageBox("Bad Command", e.getMessage() +
1260 "\n\nCursor has been positioned at violating command.");
1261 return;
1262 }
1263
1264 ses.getManager().submitCmdInput(cmd);
1265 try {
1266 dp.skipSpaceAndComments();
1267 } catch (ParseException e) {
1268 // don't care anymore
1269 }
1270 ctx.setDocCaret(Math.min(dp.getPos(),getLength()));
1271 } catch (SessionDeadException e) {
1272 ctx.errorMessageBox("Session died",
1273 "Session died before requested input could be submitted.");
1274 return;
1275 } catch (SessionException e) {
1276 ctx.errorMessageBox("Unexpected session state",
1277 "Unexpected session state before submitting input:\n\n" +
1278 e.getMessage());
1279 return;
1280 }
1281 }
1282 }
1283
1284 public String suckForm(A2sEditor ctx) {
1285 if (!lineMode.isAdvancable()) {
1286 ctx.infoMessageBox("Not supported", "Operation not supported in this line mode. Go to menu `ACL2' | `Set line mode...' to enable line tracking.");
1287 return null;
1288 }
1289 try {
1290 String inputString;
1291 if (lineMode.cancelOnError()) {
1292 addNextForm();
1293 AboveInfo a = aboveInfo.remove(aboveInfo.size() - 1);
1294 replace2(a.region.getOffset(),a.region.getLength(),"");
1295 inputString = a.resolvable.getInputString();
1296 } else {
1297 doAdvanceTodo();
1298 doAdvanceLine(0,null);
1299 inputString = aboveInfo.get(aboveInfo.size() - 1).resolvable.getInputString();
1300 }
1301 return inputString;
1302 } catch (EmptyParse e) {
1303 ctx.infoMessageBox("Cannot read next form", "No more forms in Lisp file.");
1304 return null;
1305 } catch (PositionedParseException e) {
1306 ctx.errorMessageBox("Parse Error", e.getMessage());
1307 return null;
1308 } catch (BadCmdException e) {
1309 ctx.errorMessageBox("Bad Command", e.getMessage());
1310 return null;
1311 }
1312 }
1313
1314 public void reparse() {
1315 tokens.reparse();
1316 }
1317
1318 public void cleanOutputFiles(A2sEditor ctx) {
1319 // GCL == .o SBCL == .fasl OpenMCL == .dfsl + .acl2 + .cert
1320
|
Event model_returns_null: |
"acl2s.plugin.editors.A2sDocument.getOSFile(...)" might return null. [checked 2 of 3 uses] [details] |
| Also see events: |
[model_unchecked_deref] |
1321 File f = getOSFile();
|
Event model_unchecked_deref: |
Dereferencing "f" while f=null in "acl2s.lib.certify.Certifier.legalLispFile(...)". [details] |
| Also see events: |
[model_returns_null] |
1322 if (!Certifier.legalLispFile(f)) return; // quietly do nothing
1323
1324 String base = MiscIO.removeFileExtension(f.getPath());
1325 new File(base + ".acl2").delete();
1326 new File(base + ".cert").delete();
1327 new File(base + ".o").delete();
1328 new File(base + ".fasl").delete();
1329 new File(base + ".dfsl").delete();
1330
1331 IEditorInput input = getInput();
1332 if (input instanceof IFileEditorInput) {
1333 IFileEditorInput finput = (IFileEditorInput) input;
1334 try {
1335 finput.getFile().getParent().refreshLocal(1, null);
1336 } catch (CoreException e) {
1337 Acl2sPlugin.logError("Error refreshing directory after cleaning output files", e);
1338 }
1339 } // else, no need
1340 }
1341 }