1 package acl2s.plugin;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.FileReader;
6 import java.io.InputStream;
7 import java.lang.reflect.Method;
8 import java.util.ArrayList;
9 import java.util.HashSet;
10
11 import org.eclipse.core.resources.IFile;
12 import org.eclipse.core.resources.ResourcesPlugin;
13 import org.eclipse.core.runtime.CoreException;
14 import org.eclipse.core.runtime.FileLocator;
15 import org.eclipse.core.runtime.IExtension;
16 import org.eclipse.core.runtime.IPath;
17 import org.eclipse.core.runtime.IStatus;
18 import org.eclipse.core.runtime.Platform;
19 import org.eclipse.core.runtime.Status;
20 import org.eclipse.jface.resource.ImageRegistry;
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.graphics.Image;
23 import org.eclipse.swt.widgets.Display;
24 import org.eclipse.swt.widgets.MessageBox;
25 import org.eclipse.swt.widgets.Shell;
26 import org.eclipse.ui.IEditorInput;
27 import org.eclipse.ui.IEditorPart;
28 import org.eclipse.ui.IEditorReference;
29 import org.eclipse.ui.IFileEditorInput;
30 import org.eclipse.ui.IPathEditorInput;
31 import org.eclipse.ui.IURIEditorInput;
32 import org.eclipse.ui.IWorkbench;
33 import org.eclipse.ui.IWorkbenchListener;
34 import org.eclipse.ui.IWorkbenchPage;
35 import org.eclipse.ui.IWorkbenchPart;
36 import org.eclipse.ui.IWorkbenchWindow;
37 import org.eclipse.ui.PartInitException;
38 import org.eclipse.ui.PlatformUI;
39 import org.eclipse.ui.part.FileEditorInput;
40 import org.eclipse.ui.plugin.AbstractUIPlugin;
41 import org.osgi.framework.Bundle;
42 import org.osgi.framework.BundleContext;
43 import org.osgi.framework.Version;
44 import org.peterd.util.Pingable;
45 import org.peterd.util.io.EmptyInputStream;
46
47 import acl2s.lib.session.IBaseConfig;
48 import acl2s.lib.session.ISessionConfig;
49 import acl2s.lib.session.MyBaseConfig;
50 import acl2s.lib.session.Versions;
51 import acl2s.plugin.certify.CertifyAcl2sSystemConsole;
52 import acl2s.plugin.dialogs.RemoveOldStuffDialog;
53 import acl2s.plugin.editors.A2sEditor;
54 import acl2s.plugin.editors.MyDocumentProvider;
55 import acl2s.plugin.editors.lisp.LispDocumentProvider;
56 import acl2s.plugin.editors.lisp.LispEditor;
57 import acl2s.plugin.editors.session.SessionDocumentProvider;
58 import acl2s.plugin.editors.session.SessionEditor;
59 import acl2s.plugin.graphics.Acl2sGraphics;
60 import acl2s.plugin.misc.DisplayAsyncRunnable;
61 import acl2s.plugin.misc.PathEditorInput;
62 import acl2s.plugin.prefs.Acl2Prefs;
63 import acl2s.uilib_driver.IAcl2sGraphics;
64 import acl2s.uilib_driver.IAcl2sGraphicsFactory;
65 import acl2s.uilib_driver.IAcl2sUiLibDriver;
66 import acl2s.uilib_driver.IAcl2sUiLibErrorHandler;
67 import acl2s.uilib_driver.IAcl2sUiLibThreadManager;
68
69 /**
70 * The main plugin class to be used in the desktop.
71 */
72 public class Acl2sPlugin extends AbstractUIPlugin
73 implements IAcl2sUiLibDriver, IAcl2sUiLibThreadManager, IAcl2sUiLibErrorHandler, IAcl2sGraphicsFactory, IWorkbenchListener {
74 // PLUGIN STUFF
75 public static final boolean DEBUG = true;
76
77 protected static final String pluginIdString = "acl2s";
78 public static final String id = pluginIdString;
79
80 private static Acl2sPlugin plugin = null;
81
82 protected static Display display = null;
83
84 protected static MyBaseConfig baseConfig = null;
85
86 protected static File hooksBundleRoot = null;
87
88 protected static File[] modedirRoots = null;
89
90 protected static File acl2sBundleRoot = null;
91
92 protected static File supportHome = null;
93
94 public Acl2sPlugin() {
95 //if (plugin != null) throw new IllegalStateException();
96 plugin = this;
97 display = Display.getCurrent();
98 if (display == null) {
99 display = Display.getDefault();
100 if (display == null) {
101 throw new IllegalStateException("Attempt to get display when there is none.");
102 }
103 }
104 }
105
106 public static Acl2sPlugin getDefault() {
107 return plugin;
108 }
109
110 public static Display getDisplay() {
111 return display;
112 }
113
114 public static Shell getShell() {
115 Display display = getDisplay();
116 Shell shell = display.getActiveShell();
117 if (shell == null) {
118 IWorkbenchWindow w = getWorkbenchWindow();
119 if (w != null) {
120 shell = w.getShell();
121 if (shell == null) {
122 Shell[] shells = display.getShells();
123 if (shells.length > 0) {
124 shell = shells[0];
125 }
126 }
127 }
128 }
129 return shell;
130 }
131
132 public static IWorkbenchWindow getWorkbenchWindow() {
133 IWorkbenchWindow w = plugin.getWorkbench().getActiveWorkbenchWindow();
134 if (w != null) {
135 return w;
136 }
137 IWorkbenchWindow[] ws = plugin.getWorkbench().getWorkbenchWindows();
138 if (ws == null || ws.length == 0) {
139 return null;
140 } else if (ws.length == 1) {
141 return ws[0];
142 } else { // ws.length > 1
143 Shell sh = getDisplay().getActiveShell();
144 if (sh != null) {
145 for (int i = 0; i < ws.length; i++) {
146 if (ws[i].getShell() == sh) {
147 return ws[i];
148 }
149 }
150 }
151 // else
152 return ws[0];
153 }
154 }
155
156 public static Image getImage(String path) {
157 ImageRegistry reg = plugin.getImageRegistry();
158 Image img = reg.get(path);
159 if (img == null) {
160 img = AbstractUIPlugin.imageDescriptorFromPlugin(id, path).createImage();
161 reg.put(path, img);
162 }
163 return img;
164 }
165
166 public void start(BundleContext context) throws Exception {
167 try {
168 super.start(context);
169 createDocumentProviders();
170 Bundle hooksBundle = Platform.getBundle("acl2s_hooks");
171 if (hooksBundle == null) {
172 logError("Could not find acl2s_hooks bundle.", null);
173 } else {
174 hooksBundleRoot = new File(FileLocator.resolve(hooksBundle.getEntry("/")).getPath());
175 }
176 acl2sBundleRoot = new File(FileLocator.resolve(context.getBundle().getEntry("/")).getPath());
177 supportHome = new File(acl2sBundleRoot, "procwrap");
178
179 ArrayList<File> modedirsFound = new ArrayList<File>();
180 IExtension[] modedirExts = Platform.getExtensionRegistry().getExtensionPoint("acl2s.modedir").getExtensions();
181 for (IExtension ext : modedirExts) {
182 Bundle b = Platform.getBundle(ext.getContributor().getName());
183 if (b != null) {
184 modedirsFound.add(new File(FileLocator.resolve(b.getEntry("/")).getPath()));
185 }
186 }
187 modedirRoots = modedirsFound.toArray(new File[modedirsFound.size()]);
188
189 //harshrc:: 3rd argument is where the cmdLine i.e acl2 image path is decided.
190 baseConfig = new MyBaseConfig(this, hooksBundleRoot, Acl2Prefs.getAcl2HomePref(null), modedirRoots);
191
192 // Check if saved ground-zero theory file does not exist or is out of date - if yes, launch an indexer.
193 // if no, load the ground-zero theory into IDocument null.
194 File groundzero = new File("groundzero.def");
195 Thread t = null;
196 if (groundzero.exists()) {
197 BufferedReader stream = new BufferedReader(new FileReader(groundzero));
198 String acl2imagepath = stream.readLine();
199 if (baseConfig.getCmdLine()[0].equals(acl2imagepath)) {
200 t = new GroundZeroIndexer(stream);
201 } else {
202 t = new GroundZeroIndexer(baseConfig);
203 stream.close();
204 }
205
206 } else {
207 t = new GroundZeroIndexer(baseConfig);
208 }
209 t.start();
210
211 PlatformUI.getWorkbench().addWorkbenchListener(this);
212 } catch (RuntimeException e) {
213 error("Exception while initializing ACL2s plugin", e);
214 } catch (Exception e) {
215 error("Exception while initializing ACL2s plugin", e);
216 throw e;
217 }
218 }
219
220
221 protected HashSet<Runnable> shutdownHooks = new HashSet<Runnable>();
222
223 public void stop(BundleContext context) throws Exception {
224 try {
225
226 } finally {
227 //plugin = null;
228 super.stop(context);
229 }
230 }
231
232 public void addShutdownHook(Runnable r) {
233 shutdownHooks.add(r);
234 }
235
236 public void removeShutdownHook(Runnable r) {
237 shutdownHooks.remove(r);
238 }
239
240
241 // PAIRING IA2sDocuments and IA2sPeerDocuments
242
243 /*
244 * Files will look like:
245 * Foo.lisp
246 * Foo.acl2
247 * Foo.lisp.a2s
248 * Foo.acl2.a2s
249 */
250
251 public static synchronized void createSessionFileFor(IFileEditorInput i) throws CoreException {
252 IPath p = i.getFile().getFullPath();
253 String ext = p.getFileExtension();
254 if (ext.equalsIgnoreCase("lisp") || ext.equalsIgnoreCase("lsp")) {
255 p = p.addFileExtension("a2s");
256 IFile a2sFile = ResourcesPlugin.getWorkspace().getRoot().getFile(p);
257 if (!a2sFile.exists()) {
258 InputStream stream = new EmptyInputStream();
259 a2sFile.create(stream, true, null);
260 }
261 } else {
262 String msg = "Unrecognized file extension for acl2 source document.";
263 throw new CoreException(new Status(IStatus.ERROR,id,IStatus.OK,msg,null));
264 }
265 }
266
267
268 protected HashSet<IPath> workspacePaths = new HashSet<IPath>();
269 protected HashSet<IPath> localPaths = new HashSet<IPath>();
270 //protected HashSet<URI> uriPaths = new HashSet<URI>();
271
272
273 public static synchronized void newA2sEditorInput(IEditorInput i) throws CoreException {
274 if (i instanceof IFileEditorInput) {
275 IPath p = ((IFileEditorInput)i).getFile().getFullPath();
276 String ext = p.getFileExtension();
277 if (ext.equalsIgnoreCase("a2s")) {
278 plugin.checkWorkspacePath(p.removeFileExtension());
279 } else {
280 /* OK
281 String msg = "Unrecognized file extension for acl2 session document.";
282 throw new CoreException(new Status(IStatus.ERROR,id,IStatus.OK,msg,null));
283 */
284 }
285 } else if (i instanceof IPathEditorInput) {
286 IPath p = ((IPathEditorInput)i).getPath();
287 String ext = p.getFileExtension();
288 if (ext.equalsIgnoreCase("a2s")) {
289 plugin.checkLocalPath(p.removeFileExtension());
290 } else {
291 /* OK
292 String msg = "Unrecognized file extension for acl2 session document.";
293 throw new CoreException(new Status(IStatus.ERROR,id,IStatus.OK,msg,null));
294 */
295 }
296 } else if (i instanceof IURIEditorInput) {
297 /* For now, always stand-alone
298 URI uri = ((IURIEditorInput)i).getURI();
299 String path = uri.getPath();
300 int dotIdx = path.lastIndexOf('.');
301 if (dotIdx < 0) {
302 String msg = "Empty file extension not supported for acl2 session document.";
303 throw new CoreException(new Status(IStatus.ERROR,id,IStatus.OK,msg,null));
304 }
305 String ext = path.substring(dotIdx + 1);
306 if (ext.equalsIgnoreCase("a2s")) {
307 try {
308 plugin.checkURIPath(new URI(uri.getScheme(),
309 uri.getAuthority(),
310 path.substring(0, dotIdx),
311 uri.getQuery(),
312 uri.getFragment()));
313 } catch (URISyntaxException e) {
314 String msg = "Problem processing URI (shouldn't happen).";
315 throw new CoreException(new Status(IStatus.ERROR,id,IStatus.OK,msg,e));
316 }
317 } else {
318 String msg = "Unrecognized file extension for acl2 session document.";
319 throw new CoreException(new Status(IStatus.ERROR,id,IStatus.OK,msg,null));
320 }
321 */
322 } else {
323 String msg = "Editor input type not supported: " + i.getClass().getName();
324 throw new CoreException(new Status(Status.ERROR,id,Status.OK,msg,null));
325 }
326 }
327
328 public static synchronized void newPeerEditorInput(IEditorInput i) throws CoreException {
329 if (i instanceof IFileEditorInput) {
330 IPath p = ((IFileEditorInput)i).getFile().getFullPath();
331 String ext = p.getFileExtension();
332 if (ext.equalsIgnoreCase("lisp") || ext.equalsIgnoreCase("lsp")) {
333 plugin.checkWorkspacePath(p);
334 } else {
335 /* OK
336 String msg = "Unrecognized file extension for acl2 source document.";
337 throw new CoreException(new Status(IStatus.ERROR,id,IStatus.OK,msg,null));
338 */
339 }
340 } else if (i instanceof IPathEditorInput) {
341 IPath p = ((IPathEditorInput)i).getPath();
342 String ext = p.getFileExtension();
343 if (ext.equalsIgnoreCase("lisp") || ext.equalsIgnoreCase("lsp")) {
344 plugin.checkLocalPath(p);
345 } else {
346 /* OK
347 String msg = "Unrecognized file extension for acl2 source document.";
348 throw new CoreException(new Status(IStatus.ERROR,id,IStatus.OK,msg,null));
349 */
350 }
351 } else if (i instanceof IURIEditorInput) {
352 /* For now, always stand-alone
353 URI uri = ((IURIEditorInput)i).getURI();
354 String path = uri.getPath();
355 int dotIdx = path.lastIndexOf('.');
356 if (dotIdx < 0) {
357 String msg = "Empty file extension not supported for acl2 source document.";
358 throw new CoreException(new Status(IStatus.ERROR,id,IStatus.OK,msg,null));
359 }
360 String ext = path.substring(dotIdx + 1);
361 if (ext.equalsIgnoreCase("lisp") || ext.equalsIgnoreCase("lsp")) {
362 plugin.checkURIPath(uri);
363 } else {
364 String msg = "Unrecognized file extension for acl2 source document.";
365 throw new CoreException(new Status(IStatus.ERROR,id,IStatus.OK,msg,null));
366 }
367 */
368 } else {
369 String msg = "Editor input type not supported: " + i.getClass().getName();
370 throw new CoreException(new Status(Status.ERROR,id,Status.OK,msg,null));
371 }
372 }
373
374 private void checkWorkspacePath(IPath basePath) throws CoreException {
375 if (workspacePaths.contains(basePath)) return;
376
377 IPath a2sPath = basePath.addFileExtension("a2s");
378
379 IFile a2sFile = ResourcesPlugin.getWorkspace().getRoot().getFile(a2sPath);
380 if (!a2sFile.exists()) return; // standalone lisp file
381
382 IPath peerPath = basePath;
383 String peerExt = basePath.getFileExtension();
384 if (peerExt == null) return; // standalone .a2s file
385
386 if (peerExt.equalsIgnoreCase("lisp") || peerExt.equalsIgnoreCase("lsp")) {
387 IFileEditorInput a2sInput = new FileEditorInput(a2sFile);
388 ISessionDocument a2sDoc = connectA2s(a2sInput);
389
390 IFile peerFile = ResourcesPlugin.getWorkspace().getRoot().getFile(peerPath);
391 IFileEditorInput peerInput = new FileEditorInput(peerFile);
392 IPeerDocument peerDoc = connectPeer(peerInput);
393
394 peerDoc.setA2s(a2sDoc);
395 a2sDoc.setPeer(peerDoc);
396 } else {
397 throw new CoreException(new Status(Status.ERROR,id,Status.OK,"Unsupported prefix to .a2s",null));
398 }
399
400 workspacePaths.add(basePath);
401 }
402
403 private void checkLocalPath(IPath basePath) throws CoreException {
404 if (localPaths.contains(basePath)) return;
405
406 IPath a2sPath = basePath.addFileExtension("a2s");
407
408 File a2sFile = a2sPath.toFile();
409 if (!a2sFile.exists()) return; // standalone lisp file
410
411 IPath peerPath = basePath;
412 String peerExt = basePath.getFileExtension();
413 if (peerExt == null) return; // standalone .a2s file
414
415 if (peerExt.equalsIgnoreCase("lisp") || peerExt.equalsIgnoreCase("lsp")) {
416 IPathEditorInput a2sInput = new PathEditorInput(a2sPath);
417 ISessionDocument a2sDoc = connectA2s(a2sInput);
418
419 //File peerFile = peerPath.toFile();
420 IPathEditorInput peerInput = new PathEditorInput(peerPath);
421 IPeerDocument peerDoc = connectPeer(peerInput);
422
423 peerDoc.setA2s(a2sDoc);
424 a2sDoc.setPeer(peerDoc);
425 } else {
426 throw new CoreException(new Status(Status.ERROR,id,Status.OK,"Unsupported prefix to .a2s",null));
427 }
428
429 localPaths.add(basePath);
430 }
431
432 /*
433 private void checkURIPath(URI basePath) throws CoreException {
434 if (uriPaths.contains(basePath)) return;
435
436 URI a2sPath = new URI(basePath.getScheme(),basePath.getAuthority(),
437 basePath.getPath().concat(".a2s"),
438 basePath.getQuery(),basePath.getFragment());
439
440 //File a2sFile = a2sPath.toFile();
441 //if (!a2sFile.exists()) return; // standalone lisp file
442
443 URI peerPath = basePath;
444 String p = basePath.getPath();
445 int dotIdx = p.lastIndexOf('.');
446 if (dotIdx < 0) return; // standalone .a2s file
447 String peerExt = p.substring(dotIdx + 1);
448
449 if (peerExt.equalsIgnoreCase("lisp") || peerExt.equalsIgnoreCase("lsp")) {
450 IURIEditorInput a2sInput = new ???;
451 ISessionDocument a2sDoc = connectA2s(a2sInput);
452
453 //File peerFile = peerPath.toFile();
454 IURIEditorInput peerInput = new ???;
455 IPeerDocument peerDoc = connectPeer(peerInput);
456
457 peerDoc.setA2s(a2sDoc);
458 a2sDoc.setPeer(peerDoc);
459 } else {
460 throw new CoreException(new Status(Status.ERROR,id,Status.OK,"Unsupported prefix to .a2s",null));
461 }
462
463 uriPaths.add(basePath);
464 }
465 */
466
467
468 // DOCUMENT PROVIDERS
469
470 ArrayList<MyDocumentProvider> providers = new ArrayList<MyDocumentProvider>();
471 LispDocumentProvider ldp = null;
472 SessionDocumentProvider adp = null;
473
474 public static LispDocumentProvider getLispDocumentProvider() { return plugin.ldp; }
475
476 public static SessionDocumentProvider getA2sDocumentProvider() { return plugin.adp; }
477
478 private void createDocumentProviders() {
479 ldp = new LispDocumentProvider();
480 providers.add(ldp);
481 adp = new SessionDocumentProvider();
482 providers.add(adp);
483 }
484
485 private ISessionDocument connectA2s(IEditorInput input) throws CoreException {
486 adp.connect(input);
487 return (ISessionDocument) adp.getDocument(input);
488 }
489
490 private IPeerDocument connectPeer(IEditorInput peerInput) throws CoreException {
491 ldp.connect(peerInput);
492 return (IPeerDocument) ldp.getDocument(peerInput);
493 }
494
495
496
497 // LOGGING
498
499 public static void logError(final String message, Throwable t) {
500 final Status status = new Status(IStatus.ERROR,pluginIdString,IStatus.OK,message,t);
501 plugin.getLog().log(status);
502
503 popupMessage("Error signalled by ACL2s Plugin", message, SWT.ICON_ERROR | SWT.OK);
504 }
505
506 public static void logWarning(final String message, Throwable t) {
507 final Status status = new Status(IStatus.WARNING,pluginIdString,IStatus.OK,message,t);
508 plugin.getLog().log(status);
509 /*
510 getDisplay().asyncExec( new Runnable() {
511 public void run() {
512 MessageBox mb = new MessageBox(getShell(),SWT.ICON_WARNING | SWT.OK);
513 mb.setText("Warning reported by ACL2s Plugin");
514 mb.setMessage(message);
515 mb.open();
516 }
517 });
518 //*/
519 }
520
521 public static void popupMessage(final Shell sh, final String title, final String message, final int swtIcon) {
522 getDisplay().asyncExec( new Runnable() {
523 public void run() {
524 Shell sh2 = sh == null ? getShell() : sh;
525 if (sh2 == null) {
526 sh2 = new Shell(getDisplay());
527 sh2.open();
528 go(sh2);
529 sh2.close();
530 } else {
531 go(sh2);
532 }
533 }
534
535 void go(Shell sh2) {
536 MessageBox mb = new MessageBox(sh2, swtIcon | SWT.OK);
537 mb.setText(title);
538 mb.setMessage(message);
539 mb.open();
540 }
541 });
542 }
543
544 public static void popupMessage(final String title, final String message, final int swtIcon) {
545 popupMessage(null, title, message, swtIcon);
546 }
547
548
549 /* =============== Collection of loops in connected documents =============== */
550 public static synchronized void disconnectedFrom(IPeerDocument doc) {
551 if (doc.getSession() == null) return; // standalone lisp
552
553 if (plugin.getDocumentRefCount(doc) == 1 &&
554 plugin.getDocumentRefCount(doc.getSession()) == 1) {
555 IPath p = doc.getOSPath()/*.removeFileExtension()*/;
556 p = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(p).getFullPath();
557 if (!plugin.workspacePaths.remove(p)) {
558 logWarning("Documents already disconnected.", null);
559 }
560 /* TODO: work on
561 if (plugin.adp.canSaveDocument(doc.getSession().getInput())) {
562 plugin.adp.
563 try {
564 getWorkbenchWindow().getActivePage().openEditor(doc.getSession().getInput(),"acl2s.plugin.editors.a2s");
565 return;
566 } catch (PartInitException e) {
567 logWarning("Couldn't create dirty editor in response to closing other one.",e);
568 }
569 }*/
570 plugin.disconnectDocument(doc);
571 plugin.disconnectDocument(doc.getSession());
572 doc.getSession().dispose();
573 doc.dispose();
574 }
575 }
576
577 public static synchronized void disconnectedFrom(ISessionDocument doc) {
578 if (doc.getPeer() == null) return; // standalone a2s
579
580 if (plugin.getDocumentRefCount(doc) == 1 &&
581 plugin.getDocumentRefCount(doc.getPeer()) == 1) {
582 IPath p = doc.getOSPath().removeFileExtension(); // fs path
583 p = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(p).getFullPath(); // to ws path
584 if (!plugin.workspacePaths.remove(p)) {
585 logWarning("Documents already disconnected.", null);
586 }
587 plugin.disconnectDocument(doc);
588 plugin.disconnectDocument(doc.getPeer());
589 doc.getPeer().dispose();
590 doc.dispose();
591 }
592 }
593
594 private int getDocumentRefCount(IDocumentWithInput doc) {
595 Object o = doc.getInput();
596 int count = 0;
597 for (MyDocumentProvider dp : providers) {
598 count += dp.getElementRefCount(o);
599 }
600 return count;
601 }
602
603 private void disconnectDocument(IDocumentWithInput doc) {
604 Object o = doc.getInput();
605 for (MyDocumentProvider dp : providers) {
606 dp.disconnect(o);
607 }
608 }
609
610 public static boolean hasEditor(IDocumentWithInput doc) {
611 int refs = plugin.getDocumentRefCount(doc);
612 if (doc instanceof ISessionDocument) {
613 if (((ISessionDocument)doc).getPeer() != null) refs--;
614 } else if (doc instanceof IPeerDocument) {
615 if (((IPeerDocument)doc).getSession() != null) refs--;
616 }
617 return refs > 0;
618 }
619
620
621 public static IPeerDocument getPeer(final ISessionDocument ses,
622 final A2sEditor ctx,
623 final boolean open,
624 final boolean focus) {
|
Event null_literal: |
Using a literal null value. |
| Also see events: |
[deref_while_null] |
|
At conditional (1): open: Taking false branch.
|
625 final IWorkbenchPage page = open ? ctx.getEditorSite().getPage() : null;
626
627 IPeerDocument peerdoc = ses.getPeer();
628
|
At conditional (2): (peerdoc != null): Taking true branch.
|
629 if (peerdoc != null) {
630 try {
631 IWorkbenchPage targetPage = page;
|
Event deref_while_null: |
Dereferencing "targetPage" while targetPage=null. |
| Also see events: |
[null_literal] |
632 IEditorPart old = targetPage.getActiveEditor();
633 if (!hasEditor(peerdoc)) {
634 // find editor of same type
635 found: for (IWorkbenchPage p : page.getWorkbenchWindow().getPages()) {
636 for (IEditorReference ref : p.getEditorReferences()) {
637 if (ref.getId().equals(LispEditor.id)) {
638 targetPage = p;
639 old = targetPage.getActiveEditor();
640 // activate it so that new one will be in same group
641 IWorkbenchPart part = ref.getPart(true);
642 if (part != null) targetPage.activate(part);
643 break found;
644 }
645 }
646 }
647 }
648 targetPage.openEditor(peerdoc.getInput(),LispEditor.id,focus);
649 if (!focus) targetPage.activate(old);
650 } catch (PartInitException e1) {
651 Acl2sPlugin.logWarning("Error opening peer editor.", e1);
652 }
653 } else {
654 ctx.errorMessageBox("Not supported", "This session has no corresponding lisp file.");
655 }
656 return peerdoc;
657 }
658
659 public static ISessionDocument getSession(final IPeerDocument peer,
660 final A2sEditor ctx,
661 final boolean open,
662 final boolean focus,
663 final boolean start) {
664 final IWorkbenchPage page = open ? ctx.getEditorSite().getPage() : null;
665
666 ISessionDocument sesdoc = tryOpenSession(peer,page,focus);
667
668 if (sesdoc == null) {
669 final Shell sh = ctx.getSite().getShell();
670 final Display display = sh.getDisplay();
671 MessageBox mb = new MessageBox(sh, SWT.ICON_INFORMATION | SWT.YES | SWT.NO | SWT.APPLICATION_MODAL);
672 mb.setText("No associated session");
673 mb.setMessage("This lisp file has no associated ACL2 session file. Would you like to create one?");
674 int v = mb.open();
675 if (v != SWT.YES) return null;
676
677 if (peer.getInput() instanceof IFileEditorInput) {
678 display.asyncExec(new Runnable() {
679 public void run() {
680 try {
681 createSessionFileFor((IFileEditorInput) peer.getInput());
682 display.asyncExec(new Runnable() {
683 public void run() {
684 ISessionDocument sesdoc = tryOpenSession(peer,page,focus);
685 if (sesdoc != null && start) sesdoc.restartSession(ctx);
686 }});
687 } catch (CoreException e1) {
688 logWarning("Error creating session file", e1);
689 String errMsg = "Error creating session file: " + e1.getMessage();
690 ctx.errorMessageBox("Error creating session file", errMsg);
691 }
692 }
693 });
694 } else {
695 String errMsg = "Associated session not supported for files outside of workspace.";
696 ctx.errorMessageBox("Error creating session file", errMsg);
697 }
698 return null;
699 } else {
700 return sesdoc;
701 }
702 }
703
704 public static ISessionDocument tryOpenSession(IPeerDocument peer, IWorkbenchPage page, boolean focus) {
705 ISessionDocument sesdoc = tryGetSession(peer);
706 if (sesdoc != null && page != null) {
707 try {
708 if (focus || !hasEditor(sesdoc)) {
709 IWorkbenchPage targetPage = page;
710 IEditorPart old = targetPage.getActiveEditor();
711 if (!hasEditor(sesdoc)) {
712 // find editor of same type
713 found: for (IWorkbenchPage p : page.getWorkbenchWindow().getPages()) {
714 for (IEditorReference ref : p.getEditorReferences()) {
715 if (ref.getId().equals(SessionEditor.id)) {
716 targetPage = p;
717 old = targetPage.getActiveEditor();
718 // activate it so that new one will be in same group
719 IWorkbenchPart part = ref.getPart(true);
720 if (part != null) targetPage.activate(part);
721 break found;
722 }
723 }
724 }
725 }
726 page.openEditor(sesdoc.getInput(),SessionEditor.id, focus);
727 if (!focus) page.activate(old);
728 }
729 } catch (PartInitException e1) {
730 logWarning("Error opening peer editor.", e1);
731 // can't really recover, so return true anyway
732 }
733 }
734 return sesdoc;
735 }
736
737 public static ISessionDocument tryGetSession(IPeerDocument peer) {
738 ISessionDocument a2s = peer.getSession();
739
740 if (a2s != null) return a2s;
741
742 if (!(peer.getInput() instanceof IFileEditorInput)) return null;
743
744 try {
745 disconnectedFrom(peer);
746 newPeerEditorInput(peer.getInput());
747 a2s = peer.getSession();
748 } catch (CoreException ce) {
749 logWarning(ce.getMessage(),ce);
750 }
751
752 return a2s;
753 }
754
755
756 // As driver for acl2s-lib
757
758 public IAcl2sUiLibErrorHandler getErrorHandler() {
759 return this;
760 }
761
762 public IAcl2sUiLibThreadManager getThreadManager() {
763 return this;
764 }
765
766 public IAcl2sGraphicsFactory getGraphicsFactory() {
767 return this;
768 }
769
770 public void syncExec(Runnable runnable) {
771 display.syncExec(runnable);
772 }
773
774 public void asyncExec(Runnable runnable) {
775 display.asyncExec(runnable);
776 }
777
778 public void delayedExec(final Runnable r, final int millis, boolean allowThisThread) {
779 if (allowThisThread && Thread.currentThread() == display.getThread()) {
780 display.timerExec(millis, r); // not allowed to call from non-display thread!
781 } else {
782 new Thread() {
783 public void run() {
784 try { Thread.sleep(millis); } catch (InterruptedException e) { }
785 r.run();
786 }
787 }.start();
788 }
789 }
790
791 public boolean inEventThread() {
792 return Thread.currentThread() == display.getThread();
793 }
794
795 public IAcl2sGraphics createGraphics(Pingable[] p, File[] searchDirs) {
796 return new Acl2sGraphics(display, p, searchDirs);
797 }
798
799
800 public String getExtraInstructionOutput() {
801 if (SWT.MOD1 == SWT.COMMAND) {
802 return " => Hold \"Command\" to follow hyperlinks and :DOCumentation references <=\n";
803 } else {
804 return " => Hold \"Ctrl\" to follow hyperlinks and :DOCumentation references <=\n";
805 }
806 }
807
808
809 // called from session thread
810 public void needsImage(ISessionConfig config) {
811 popupMessage("ACL2 image error",
812 "I was unable to start a session, either because I could not find an ACL2 image or the image I tried is incompatible." +
813 "\n\nIf you installed the \"ACL2 Image\" feature (see Help | About Eclipse... | Installation Details), and it's version >= " +
814 Versions.getAcl2MinVersionString() + " and <= " + Versions.getAcl2MaxVersionString() +
815 ", and the image matches your OS/Arch, then you should contact the ACL2s implementors about this bug." +
816 "\n\nIf you are attempting to use an external ACL2 build, make sure you specify the correct directory in Eclipse's Preferences dialog under ACL2s | ACL2, or " +
817 "consult the ACL2s documentation for more info." +
818 "",
819 SWT.ICON_ERROR | SWT.WRAP);
820 }
821
822 // called from session thread
823 public void needsHooksCertification(ISessionConfig config) {
824 new DisplayAsyncRunnable() {
825 protected void asyncRun() {
826 CertifyAcl2sSystemConsole.ensureStarted(getShell(),
827 "It appears I need to certify the ACL2s system books before a session will load properly. If in doubt, allow this to proceed.",
828 "It appears I am in the process of certifying the ACL2s system books. See the \"Console\" view for output. When that finishes, you should be able to start a session.");
829 }
830 }.run();
831 }
832
833 public void error(String message, Throwable t) {
834 logError(message,t);
835 }
836
837 public void warning(String message, Throwable t) {
838 logWarning(message,t);
839 }
840
841 public static File getAcl2sHooksDir() {
842 return hooksBundleRoot;
843 }
844
845 public static File getAcl2sBundleDir() {
846 return acl2sBundleRoot;
847 }
848
849 public static File getSessionSupportDir() {
850 return supportHome;
851 }
852
853 public static IBaseConfig getBaseConfig() {
854 if (inDisplayThread()) {
855 baseConfig.setAcl2Home(Acl2Prefs.getAcl2HomePref(getShell()));
856 }
857 return baseConfig;
858 }
859
860 public static boolean inDisplayThread() {
861 return Thread.currentThread() == display.getThread();
862 }
863
864 public void postShutdown(IWorkbench workbench) {
865 if (SWT.getPlatform().equals("carbon")) {
866 RemoveOldStuffDialog.go(null);
867 }
868 }
869
870 public boolean preShutdown(IWorkbench workbench, boolean forced) {
871 for (Runnable r : shutdownHooks) {
872 r.run();
873 }
874 if (!SWT.getPlatform().equals("carbon")) {
875 RemoveOldStuffDialog.go(getShell());
876 }
877 return true;
878 }
879
880 public static File getAcl2sLibJar() {
881 File jar = new File(acl2sBundleRoot, "acl2s-lib.jar");
882 if (!jar.exists()) {
883 File dir = new File(acl2sBundleRoot, "bin");
884 return dir;
885 }
886 return jar;
887 }
888
889 static boolean noMoreWarnOutline3_3 = false;
890
891 public static void maybeWarnOutline3_3() {
892 if (noMoreWarnOutline3_3) return;
893 try {
894 Bundle b = ResourcesPlugin.getPlugin().getBundle();
895 Method m = b.getClass().getMethod("getVersion");
896 Version v = (Version) m.invoke(b);
897 if (v.getMajor() == 3 && v.getMinor() == 3) {
898 popupMessage("ACL2s Outline + Eclipse 3.3 problem",
899 "Eclipse 3.3.x seems to generate errors when closing an Outline " +
900 "view associated with an ACL2s source file or session file. We " +
901 "have been unable to fix it and don't plan to because (1) it " +
902 "seems to be innocuous and (2) Eclipse 3.4 seems to have fixed " +
903 "the problem. Upgrade is encouraged.",
904 SWT.ICON_INFORMATION);
905 }
906 } catch (Exception e) {
907 // oh well
908 }
909 noMoreWarnOutline3_3 = true;
910 }
911
912 static HashSet<String> warnedUninstalledModes = new HashSet<String>();
913
914 public static void maybeWarnUninstalledMode(String modeName) {
915 if (!warnedUninstalledModes.contains(modeName)) {
916 warnedUninstalledModes.add(modeName);
917 Acl2sPlugin.popupMessage("Unrecognized session mode",
918 "A file just opened uses a session mode, \"" +
919 modeName + "\", which is not installed under this Eclipse/ACL2s. To " +
920 "be able to start a session in this mode, you will need to install that mode. "+
921 "(Ask the person you got the file from.)",
922 SWT.ICON_WARNING);
923 }
924 }
925 }