Warning : session_start(): open(/var/lib/php/sessions/sess_t93p31gqibnp7gauh3q34b27jm, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning : session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import java.util.function.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.imageio.*;
import java.math.*;
import javax.swing.border.*;
import static x30_pkg.x30_util.DynamicObject;
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.*;
import org.fife.ui.autocomplete.*;
import org.fife.rsta.ui.CollapsibleSectionPanel;
import org.fife.rsta.ui.GoToDialog;
import org.fife.rsta.ui.SizeGripIcon;
import org.fife.rsta.ui.search.FindDialog;
import org.fife.rsta.ui.search.ReplaceDialog;
import org.fife.rsta.ui.search.ReplaceToolBar;
import org.fife.rsta.ui.search.SearchEvent;
import org.fife.rsta.ui.search.SearchListener;
import org.fife.rsta.ui.search.FindToolBar;
import org.fife.ui.rsyntaxtextarea.ErrorStrip;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.fife.ui.rtextarea.SearchContext;
import org.fife.ui.rtextarea.SearchEngine;
import org.fife.ui.rtextarea.SearchResult;
import java.util.jar.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.DataFlavor;
import java.text.*;
import org.fife.ui.rsyntaxtextarea.*;
import java.nio.file.Path;
import javax.swing.event.AncestorListener;
import javax.swing.event.AncestorEvent;
import javax.swing.Timer;
import java.awt.geom.*;
import java.text.NumberFormat;
import javax.imageio.metadata.*;
import javax.imageio.stream.*;
import java.awt.datatransfer.StringSelection;
import java.util.TimeZone;
import javax.swing.undo.UndoManager;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.awt.datatransfer.UnsupportedFlavorException;
import javax.swing.Icon;
class main {
static class G22ProjectStoryEditor implements IFieldsToList{
G22Utils g22utils;
G22ProjectStoryEditor() {}
G22ProjectStoryEditor(G22Utils g22utils) {
this.g22utils = g22utils;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ")"; }public Object[] _fieldsToList() { return new Object[] {g22utils}; }
JTextFileEditor editor;
File textFile() { return g22utils.projectStoryTextFile(); }
IVarWithNotify varText() { return textFileAsVarWithNotify(textFile()); }
public transient JComponent visualize_cache;
public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache;}
public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); }
JComponent visualize_impl() {
editor = new JTextFileEditor(textFile()).autoSave(true);
return withTopAndBottomMargin(jRaisedCenteredSection("Project Story",
editor.visualize()
));
}
}
static String shortClassName_dropNumberPrefix(Object o) {
return dropNumberPrefix(shortClassName(o));
}
static IVarWithNotify textFileAsVarWithNotify(File file) {
return new TypedVirtualVar(String.class,
() -> loadTextFile(file),
text -> saveTextFile(file, text));
}
static A markVisualizer(Object visualizer, A a) {
return setMetaSrc(a, visualizer);
}
static int withTopAndBottomMargin_defaultWidth = 6;
static JPanel withTopAndBottomMargin(Component c) {
return withTopAndBottomMargin(withTopAndBottomMargin_defaultWidth, withTopAndBottomMargin_defaultWidth, c);
}
static JPanel withTopAndBottomMargin(int topMargin, int bottomMargin, Component c) {
return swing(() -> {
JPanel p = new JPanel(new BorderLayout());
int w = withTopAndBottomMargin_defaultWidth;
p.setBorder(BorderFactory.createEmptyBorder(topMargin, 0, bottomMargin, 0));
p.add(c);
return p;
});
}
static JPanel jRaisedCenteredSection(Component c) { return jRaisedCenteredSection("", c); }
static JPanel jRaisedCenteredSection(String title, Component c) {
return jCenteredRaisedSection(title, c);
}
static String dropNumberPrefix(String s) {
return dropFirst(s, indexOfNonDigit(s));
}
static String shortClassName(Object o) {
if (o == null) return null;
Class c = o instanceof Class ? (Class) o : o.getClass();
String name = c.getName();
return shortenClassName(name);
}
static String loadTextFile(String fileName) {
return loadTextFile(fileName, null);
}
static String loadTextFile(File f, String defaultContents) { return loadTextFile(f, defaultContents, "UTF-8"); }
static String loadTextFile(File f, String defaultContents, String encoding) { try {
checkFileNotTooBigToRead(f);
if (f == null || !f.exists()) return defaultContents;
FileInputStream fileInputStream = new FileInputStream(f);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, encoding);
return loadTextFile(inputStreamReader);
} catch (Exception __e) { throw rethrow(__e); } }
public static String loadTextFile(File fileName) {
return loadTextFile(fileName, null);
}
static String loadTextFile(String fileName, String defaultContents) {
return fileName == null ? defaultContents : loadTextFile(newFile(fileName), defaultContents);
}
static String loadTextFile(Reader reader) throws IOException {
StringBuilder builder = new StringBuilder();
try {
char[] buffer = new char[1024];
int n;
while (-1 != (n = reader.read(buffer)))
builder.append(buffer, 0, n);
} finally {
reader.close();
}
return str(builder);
}
/** writes safely (to temp file, then rename) */
static File saveTextFile(String fileName, String contents) throws IOException {
/*ifdef CriticalActions
temp beginCriticalAction("Saving file " + fileName + " (" + l(contents) + " chars)");
endifdef*/
File file = new File(fileName);
mkdirsForFile(file);
String tempFileName = fileName + "_temp";
File tempFile = new File(tempFileName);
if (contents != null) {
if (tempFile.exists()) try {
String saveName = tempFileName + ".saved." + now();
copyFile(tempFile, new File(saveName));
} catch (Throwable e) { printStackTrace(e); }
FileOutputStream fileOutputStream = newFileOutputStream(tempFile.getPath());
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8");
PrintWriter printWriter = new PrintWriter(outputStreamWriter);
printWriter.print(contents);
printWriter.close();
}
if (file.exists() && !file.delete())
throw new IOException("Can't delete " + fileName);
if (contents != null)
if (!tempFile.renameTo(file))
throw new IOException("Can't rename " + tempFile + " to " + file);
vmBus_send("wroteFile", file);
return file;
}
static File saveTextFile(File fileName, String contents) { try {
saveTextFile(fileName.getPath(), contents);
return fileName;
} catch (Exception __e) { throw rethrow(__e); } }
static A setMetaSrc(A a, Object src) {
setMetaAndVerify(a, "src", src);
return a;
}
static A setMetaSrc(A a, Object src) {
setMetaAndVerify(a, "src", src);
return a;
}
static Object swing(Object f) {
return swingAndWait(f);
}
static void swing(Runnable f) {
swingAndWait(f);
}
static A swing(F0 f) {
return (A) swingAndWait(f);
}
static A swing(IF0 f) {
return (A) swingAndWait(f);
}
static JPanel jCenteredRaisedSection(Component c) { return jCenteredRaisedSection("", c); }
static JPanel jCenteredRaisedSection(String title, Component c) {
return centerSection(jRaisedSection(title, c));
}
static String[] dropFirst(int n, String[] a) {
return drop(n, a);
}
static String[] dropFirst(String[] a) {
return drop(1, a);
}
static Object[] dropFirst(Object[] a) {
return drop(1, a);
}
static List dropFirst(List l) {
return dropFirst(1, l);
}
static List dropFirst(int n, Iterable i) { return dropFirst(n, toList(i)); }
static List dropFirst(Iterable i) { return dropFirst(toList(i)); }
static List dropFirst(int n, List l) {
return n <= 0 ? l : new ArrayList(l.subList(Math.min(n, l.size()), l.size()));
}
static List dropFirst(List l, int n) {
return dropFirst(n, l);
}
static String dropFirst(int n, String s) { return substring(s, n); }
static String dropFirst(String s, int n) { return substring(s, n); }
static String dropFirst(String s) { return substring(s, 1); }
static int indexOfNonDigit(String s) {
int n = l(s);
for (int i = 0; i < n; i++)
if (!isDigit(s.charAt(i)))
return i;
return -1;
}
static String shortenClassName(String name) {
if (name == null) return null;
int i = lastIndexOf(name, "$");
if (i < 0) i = lastIndexOf(name, ".");
return i < 0 ? name : substring(name, i+1);
}
static ThreadLocal> checkFileNotTooBigToRead_tl = new ThreadLocal();
static void checkFileNotTooBigToRead(File f) {
callF(checkFileNotTooBigToRead_tl.get(), f);
}
static RuntimeException rethrow(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static RuntimeException rethrow(String msg, Throwable t) {
throw new RuntimeException(msg, t);
}
static File newFile(File base, String... names) {
for (String name : names) base = new File(base, name);
return base;
}
static File newFile(String name) {
return name == null ? null : new File(name);
}
static File newFile(String base, String... names) {
return newFile(newFile(base), names);
}
static String str(Object o) {
return o == null ? "null" : o.toString();
}
static String str(char[] c) {
return new String(c);
}
static String str(char[] c, int offset, int count) {
return new String(c, offset, count);
}
public static File mkdirsForFile(File file) {
File dir = file.getParentFile();
if (dir != null) { // is null if file is in current dir
dir.mkdirs();
if (!dir.isDirectory())
if (dir.isFile()) throw fail("Please delete the file " + f2s(dir) + " - it is supposed to be a directory!");
else throw fail("Unknown IO exception during mkdirs of " + f2s(file));
}
return file;
}
public static String mkdirsForFile(String path) {
mkdirsForFile(new File(path));
return path;
}
static long now_virtualTime;
static long now() {
return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis();
}
static File copyFile(File src, File dest) { try {
FileInputStream inputStream = new FileInputStream(src.getPath());
FileOutputStream outputStream = newFileOutputStream(dest.getPath());
try {
copyStream(inputStream, outputStream);
inputStream.close();
} finally {
outputStream.close();
}
return dest;
} catch (Exception __e) { throw rethrow(__e); } }
static A printStackTrace(A e) {
// we go to system.out now - system.err is nonsense
if (e != null) print(getStackTrace(e));
return e;
}
static void printStackTrace() {
printStackTrace(new Throwable());
}
static void printStackTrace(String msg) {
printStackTrace(new Throwable(msg));
}
static void printStackTrace(String msg, Throwable e) {
printStackTrace(new Throwable(msg, e));
}
static FileOutputStream newFileOutputStream(File path) throws IOException {
return newFileOutputStream(path.getPath());
}
static FileOutputStream newFileOutputStream(String path) throws IOException {
return newFileOutputStream(path, false);
}
static FileOutputStream newFileOutputStream(File path, boolean append) throws IOException {
return newFileOutputStream(path.getPath(), append);
}
static FileOutputStream newFileOutputStream(String path, boolean append) throws IOException {
mkdirsForFile(path);
FileOutputStream f = new FileOutputStream(path, append);
_registerIO(f, path, true);
return f;
}
static void vmBus_send(String msg, Object... args) {
Object arg = vmBus_wrapArgs(args);
pcallFAll_minimalExceptionHandling(vm_busListeners_live(), msg, arg);
pcallFAll_minimalExceptionHandling(vm_busListenersByMessage_live().get(msg), msg, arg);
}
static void vmBus_send(String msg) {
vmBus_send(msg, (Object) null);
}
static void setMetaAndVerify(IMeta o, Object key, Object value) {
setMeta(o, key, value);
assertSame(() -> str(key), value, metaGet(o, key));
}
static void setMetaAndVerify(Object o, Object key, Object value) {
setMeta(o, key, value);
assertSame(() -> str(key), value, metaGet(o, key));
}
static void swingAndWait(Runnable r) { try {
if (isAWTThread())
r.run();
else
EventQueue.invokeAndWait(addThreadInfoToRunnable(r));
} catch (Exception __e) { throw rethrow(__e); } }
static Object swingAndWait(final Object f) {
if (isAWTThread())
return callF(f);
else {
final Var result = new Var();
swingAndWait(new Runnable() { public void run() { try {
result.set(callF(f));
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "result.set(callF(f));"; }});
return result.get();
}
}
static JPanel centerSection(JPanel section) {
if (section != null) { swing(() -> {
Border border = section.getBorder();
if (border instanceof TitledBorder)
((TitledBorder) border).setTitleJustification(TitledBorder.CENTER);
}); }
return section;
}
static JPanel jRaisedSection(Component c) {
return jRaisedSection("", c);
}
static JPanel jRaisedSection(final String title, final Component c) {
return swing(new F0() { public JPanel get() { try {
Border border = BorderFactory.createBevelBorder(BevelBorder.RAISED);
border = BorderFactory.createTitledBorder(border, title);
JPanel panel = new SingleComponentPanel(c);
panel.setBorder(border);
return panel;
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "Border border = BorderFactory.createBevelBorder(BevelBorder.RAISED);\r\n bor..."; }});
}
static JPanel jRaisedSection(String title) {
return jRaisedSection(title, new JPanel());
}
static String[] drop(int n, String[] a) {
n = Math.min(n, a.length);
String[] b = new String[a.length-n];
System.arraycopy(a, n, b, 0, b.length);
return b;
}
static Object[] drop(int n, Object[] a) {
n = Math.min(n, a.length);
Object[] b = new Object[a.length-n];
System.arraycopy(a, n, b, 0, b.length);
return b;
}
static ArrayList toList(A[] a) { return asList(a); }
static ArrayList toList(int[] a) { return asList(a); }
static ArrayList toList(Set s) { return asList(s); }
static ArrayList toList(Iterable s) { return asList(s); }
static String substring(String s, int x) {
return substring(s, x, strL(s));
}
static String substring(String s, int x, int y) {
if (s == null) return null;
if (x < 0) x = 0;
int n = s.length();
if (y < x) y = x;
if (y > n) y = n;
if (x >= y) return "";
return s.substring(x, y);
}
static String substring(String s, IntRange r) {
return r == null ? null : substring(s, r.start, r.end);
}
// convenience method for quickly dropping a prefix
static String substring(String s, CharSequence l) {
return substring(s, lCharSequence(l));
}
static int l(Object[] a) { return a == null ? 0 : a.length; }
static int l(boolean[] a) { return a == null ? 0 : a.length; }
static int l(byte[] a) { return a == null ? 0 : a.length; }
static int l(short[] a) { return a == null ? 0 : a.length; }
static int l(long[] a) { return a == null ? 0 : a.length; }
static int l(int[] a) { return a == null ? 0 : a.length; }
static int l(float[] a) { return a == null ? 0 : a.length; }
static int l(double[] a) { return a == null ? 0 : a.length; }
static int l(char[] a) { return a == null ? 0 : a.length; }
static int l(Collection c) { return c == null ? 0 : c.size(); }
static int l(Iterator i) { return iteratorCount_int_close(i); } // consumes the iterator && closes it if possible
static int l(Map m) { return m == null ? 0 : m.size(); }
static int l(CharSequence s) { return s == null ? 0 : s.length(); }
static long l(File f) { return f == null ? 0 : f.length(); }
static int l(Object o) {
return o == null ? 0
: o instanceof String ? l((String) o)
: o instanceof Map ? l((Map) o)
: o instanceof Collection ? l((Collection) o)
: o instanceof Object[] ? l((Object[]) o)
: o instanceof boolean[] ? l((boolean[]) o)
: o instanceof byte[] ? l((byte[]) o)
: o instanceof char[] ? l((char[]) o)
: o instanceof short[] ? l((short[]) o)
: o instanceof int[] ? l((int[]) o)
: o instanceof float[] ? l((float[]) o)
: o instanceof double[] ? l((double[]) o)
: o instanceof long[] ? l((long[]) o)
: (Integer) call(o, "size");
}
static int l(MultiSet ms) { return ms == null ? 0 : ms.size(); }
static int l(IntRange r) { return r == null ? 0 : r.length(); }
static int l(AppendableChain a) { return a == null ? 0 : a.size; }
static boolean isDigit(char c) {
return Character.isDigit(c);
}
static int lastIndexOf(String a, String b) {
return a == null || b == null ? -1 : a.lastIndexOf(b);
}
static int lastIndexOf(String a, char b) {
return a == null ? -1 : a.lastIndexOf(b);
}
// starts searching from i-1
static int lastIndexOf(List l, int i, A a) {
if (l == null) return -1;
for (i = min(l(l), i)-1; i >= 0; i--)
if (eq(l.get(i), a))
return i;
return -1;
}
static int lastIndexOf(List l, A a) {
if (l == null) return -1;
for (int i = l(l)-1; i >= 0; i--)
if (eq(l.get(i), a))
return i;
return -1;
}
static Map> callF_cache = newDangerousWeakHashMap();
static A callF(F0 f) {
return f == null ? null : f.get();
}
static B callF(F1 f, A a) {
return f == null ? null : f.get(a);
}
static A callF(IF0 f) {
return f == null ? null : f.get();
}
static B callF(IF1 f, A a) {
return f == null ? null : f.get(a);
}
static B callF(A a, IF1 f) {
return f == null ? null : f.get(a);
}
static C callF(IF2 f, A a, B b) {
return f == null ? null : f.get(a, b);
}
static void callF(VF1 f, A a) {
if (f != null) f.get(a);
}
static void callF(A a, IVF1 f) {
if (f != null) f.get(a);
}
static void callF(IVF1 f, A a) {
if (f != null) f.get(a);
}
static Object callF(Runnable r) { { if (r != null) r.run(); } return null; }
static Object callF(Object f, Object... args) {
return safeCallF(f, args);
}
static Object safeCallF(Object f, Object... args) {
if (f instanceof Runnable) {
((Runnable) f).run();
return null;
}
if (f == null) return null;
Class c = f.getClass();
ArrayList methods;
synchronized(callF_cache) {
methods = callF_cache.get(c);
if (methods == null)
methods = callF_makeCache(c);
}
int n = l(methods);
if (n == 0) {
if (f instanceof String)
throw fail("Legacy call: " + f);
throw fail("No get method in " + getClassName(c));
}
if (n == 1) return invokeMethod(methods.get(0), f, args);
for (int i = 0; i < n; i++) {
Method m = methods.get(i);
if (call_checkArgs(m, args, false))
return invokeMethod(m, f, args);
}
throw fail("No matching get method in " + getClassName(c));
}
// used internally
static ArrayList callF_makeCache(Class c) {
ArrayList l = new ArrayList();
Class _c = c;
do {
for (Method m : _c.getDeclaredMethods())
if (m.getName().equals("get")) {
makeAccessible(m);
l.add(m);
}
if (!l.isEmpty()) break;
_c = _c.getSuperclass();
} while (_c != null);
callF_cache.put(c, l);
return l;
}
static void _handleError(Error e) {
call(javax(), "_handleError", e);
}
static RuntimeException fail() { throw new RuntimeException("fail"); }
static RuntimeException fail(Throwable e) { throw asRuntimeException(e); }
static RuntimeException fail(Object msg) { throw new RuntimeException(String.valueOf(msg)); }
static RuntimeException fail(Object... objects) { throw new Fail(objects); }
static RuntimeException fail(String msg) { throw new RuntimeException(msg == null ? "" : msg); }
static RuntimeException fail(String msg, Throwable innerException) { throw new RuntimeException(msg, innerException); }
static String f2s(File f) {
return f == null ? null : f.getAbsolutePath();
}
static String f2s(String s) { return f2s(newFile(s)); }
static String f2s(java.nio.file.Path p) {
return p == null ? null : f2s(p.toFile());
}
static void copyStream(InputStream in, OutputStream out) { try {
byte[] buf = new byte[65536];
while (true) {
int n = in.read(buf);
if (n <= 0) return;
out.write(buf, 0, n);
}
} catch (Exception __e) { throw rethrow(__e); } }
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static boolean printAlsoToSystemOut = true;
static volatile Appendable print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
static boolean print_silent = false; // total mute if set
static Object print_byThread_lock = new Object();
static volatile ThreadLocal print_byThread; // special handling by thread - prefers F1
static volatile Object print_allThreads;
static volatile Object print_preprocess;
static void print() {
print("");
}
static A print(String s, A o) {
print(combinePrintParameters(s, o));
return o;
}
// slightly overblown signature to return original object...
static A print(A o) {
ping_okInCleanUp();
if (print_silent) return o;
String s = o + "\n";
print_noNewLine(s);
return o;
}
static void print_noNewLine(String s) {
try {
Object f = getThreadLocal(print_byThread_dontCreate());
if (f == null) f = print_allThreads;
if (f != null)
// We do need the general callF machinery here as print_byThread is sometimes shared between modules
if (isFalse(
f instanceof F1 ? ((F1) f).get(s) :
callF(f, s))) return;
} catch (Throwable e) {
System.out.println(getStackTrace(e));
}
print_raw(s);
}
static void print_raw(String s) {
if (print_preprocess != null) s = (String) callF(print_preprocess, s);
s = fixNewLines(s);
Appendable loc = local_log;
Appendable buf = print_log;
int loc_max = print_log_max;
if (buf != loc && buf != null) {
print_append(buf, s, print_log_max);
loc_max = local_log_max;
}
if (loc != null)
print_append(loc, s, loc_max);
if (printAlsoToSystemOut)
System.out.print(s);
vmBus_send("printed", mc(), s);
}
static void print_autoRotate() {
}
static String getStackTrace(Throwable throwable) {
lastException(throwable);
return getStackTrace_noRecord(throwable);
}
static String getStackTrace_noRecord(Throwable throwable) {
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
return hideCredentials(writer.toString());
}
static String getStackTrace() {
return getStackTrace_noRecord(new Throwable());
}
static String getStackTrace(String msg) {
return getStackTrace_noRecord(new Throwable(msg));
}
static void _registerIO(Object object, String path, boolean opened) {
}
static Object vmBus_wrapArgs(Object... args) {
return empty(args) ? null
: l(args) == 1 ? args[0]
: args;
}
static void pcallFAll_minimalExceptionHandling(Collection l, Object... args) {
if (l != null) for (Object f : cloneList(l)) { ping(); pcallF_minimalExceptionHandling(f, args); }
}
static void pcallFAll_minimalExceptionHandling(Iterator it, Object... args) {
while (it.hasNext()) { ping(); pcallF_minimalExceptionHandling(it.next(), args); }
}
static Set vm_busListeners_live_cache;
static Set vm_busListeners_live() { if (vm_busListeners_live_cache == null) vm_busListeners_live_cache = vm_busListeners_live_load(); return vm_busListeners_live_cache;}
static Set vm_busListeners_live_load() {
return vm_generalIdentityHashSet("busListeners");
}
static Map vm_busListenersByMessage_live_cache;
static Map vm_busListenersByMessage_live() { if (vm_busListenersByMessage_live_cache == null) vm_busListenersByMessage_live_cache = vm_busListenersByMessage_live_load(); return vm_busListenersByMessage_live_cache;}
static Map vm_busListenersByMessage_live_load() {
return vm_generalHashMap("busListenersByMessage");
}
static void setMeta(IMeta o, Object key, Object value) {
metaMapPut(o, key, value);
}
static void setMeta(Object o, Object key, Object value) {
metaMapPut(o, key, value);
}
static void assertSame(Object a, Object b) { assertSame("", a, b); }
static void assertSame(String msg, Object a, Object b) {
if (a != b)
throw fail(joinNemptiesWithColon(msg, a + " != " + b + " (" + identityHash(a) + "/" + identityHash(b) + ")"));
}
static void assertSame(IF0 msg, Object a, Object b) {
if (a != b)
throw fail(joinNemptiesWithColon(msg.get(), a + " != " + b + " (" + identityHash(a) + "/" + identityHash(b) + ")"));
}
static Object metaGet(IMeta o, Object key) {
return metaMapGet(o, key);
}
static Object metaGet(Object o, Object key) {
return metaMapGet(o, key);
}
static Object metaGet(String key, IMeta o) {
return metaMapGet(o, key);
}
static Object metaGet(String key, Object o) {
return metaMapGet(o, key);
}
// TODO: test if android complains about this
static boolean isAWTThread() {
if (isAndroid()) return false;
if (isHeadless()) return false;
return isAWTThread_awt();
}
static boolean isAWTThread_awt() {
return SwingUtilities.isEventDispatchThread();
}
static Runnable addThreadInfoToRunnable(final Object r) {
final Object info = _threadInfo();
return info == null ? asRunnable(r) : new Runnable() { public void run() { try { _inheritThreadInfo(info); callF(r);
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_inheritThreadInfo(info); callF(r);"; }};
}
// get purpose 1: access a list/array/map (safer version of x.get(y))
static A get(List l, int idx) {
return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null;
}
// seems to conflict with other signatures
/*static B get(Map map, A key) {
ret map != null ? map.get(key) : null;
}*/
static A get(A[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : null;
}
// default to false
static boolean get(boolean[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : false;
}
// get purpose 2: access a field by reflection or a map
static Object get(Object o, String field) {
try {
if (o == null) return null;
if (o instanceof Class) return get((Class) o, field);
if (o instanceof Map)
return ((Map) o).get(field);
Field f = getOpt_findField(o.getClass(), field);
if (f != null) {
makeAccessible(f);
return f.get(o);
}
if (o instanceof DynamicObject)
return getOptDynOnly(((DynamicObject) o), field);
} catch (Exception e) {
throw asRuntimeException(e);
}
throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName());
}
static Object get_raw(String field, Object o) {
return get_raw(o, field);
}
static Object get_raw(Object o, String field) { try {
if (o == null) return null;
Field f = get_findField(o.getClass(), field);
makeAccessible(f);
return f.get(o);
} catch (Exception __e) { throw rethrow(__e); } }
static Object get(Class c, String field) {
try {
Field f = get_findStaticField(c, field);
makeAccessible(f);
return f.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field get_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field get_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static Object get(String field, Object o) {
return get(o, field);
}
static boolean get(BitSet bs, int idx) {
return bs != null && bs.get(idx);
}
static AutoCloseable tempInterceptPrintIfNotIntercepted(F1 f) {
return print_byThread().get() == null ? tempInterceptPrint(f) : null;
}
// unclear semantics as to whether return null on null
static ArrayList asList(A[] a) {
return a == null ? new ArrayList () : new ArrayList (Arrays.asList(a));
}
static ArrayList asList(int[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (int i : a) l.add(i);
return l;
}
static ArrayList asList(long[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (long i : a) l.add(i);
return l;
}
static ArrayList asList(float[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (float i : a) l.add(i);
return l;
}
static ArrayList asList(double[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (double i : a) l.add(i);
return l;
}
static ArrayList asList(short[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (short i : a) l.add(i);
return l;
}
static ArrayList asList(Iterator it) {
ArrayList l = new ArrayList();
if (it != null)
while (it.hasNext())
l.add(it.next());
return l;
}
// disambiguation
static ArrayList asList(IterableIterator s) {
return asList((Iterator) s);
}
static ArrayList asList(Iterable s) {
if (s instanceof ArrayList) return (ArrayList) s;
ArrayList l = new ArrayList();
if (s != null)
for (A a : s)
l.add(a);
return l;
}
static ArrayList asList(Producer p) {
ArrayList l = new ArrayList();
A a;
if (p != null) while ((a = p.next()) != null)
l.add(a);
return l;
}
static ArrayList asList(Enumeration e) {
ArrayList l = new ArrayList();
if (e != null)
while (e.hasMoreElements())
l.add(e.nextElement());
return l;
}
static List asList(Pair p) {
return p == null ? null : ll(p.a, p.b);
}
static int strL(String s) {
return s == null ? 0 : s.length();
}
static int lCharSequence(CharSequence s) {
return s == null ? 0 : s.length();
}
static int iteratorCount_int_close(Iterator i) { try {
int n = 0;
if (i != null) while (i.hasNext()) { i.next(); ++n; }
if (i instanceof AutoCloseable) ((AutoCloseable) i).close();
return n;
} catch (Exception __e) { throw rethrow(__e); } }
static Object call(Object o) {
return callF(o);
}
// varargs assignment fixer for a single string array argument
static Object call(Object o, String method, String[] arg) {
return call(o, method, new Object[] {arg});
}
static Object call(Object o, String method, Object... args) {
//ret call_cached(o, method, args);
return call_withVarargs(o, method, args);
}
static int min(int a, int b) {
return Math.min(a, b);
}
static long min(long a, long b) {
return Math.min(a, b);
}
static float min(float a, float b) { return Math.min(a, b); }
static float min(float a, float b, float c) { return min(min(a, b), c); }
static double min(double a, double b) {
return Math.min(a, b);
}
static double min(double[] c) {
double x = Double.MAX_VALUE;
for (double d : c) x = Math.min(x, d);
return x;
}
static float min(float[] c) {
float x = Float.MAX_VALUE;
for (float d : c) x = Math.min(x, d);
return x;
}
static byte min(byte[] c) {
byte x = 127;
for (byte d : c) if (d < x) x = d;
return x;
}
static short min(short[] c) {
short x = 0x7FFF;
for (short d : c) if (d < x) x = d;
return x;
}
static int min(int[] c) {
int x = Integer.MAX_VALUE;
for (int d : c) if (d < x) x = d;
return x;
}
static boolean eq(Object a, Object b) {
return a == b || a != null && b != null && a.equals(b);
}
// a little kludge for stuff like eq(symbol, "$X")
static boolean eq(Symbol a, String b) {
return eq(str(a), b);
}
static Map newDangerousWeakHashMap() {
return _registerDangerousWeakMap(synchroMap(new WeakHashMap()));
}
// initFunction: voidfunc(Map) - is called initially, and after clearing the map
static Map newDangerousWeakHashMap(Object initFunction) {
return _registerDangerousWeakMap(synchroMap(new WeakHashMap()), initFunction);
}
static String getClassName(Object o) {
return o == null ? "null" : o instanceof Class ? ((Class) o).getName() : o.getClass().getName();
}
static Object invokeMethod(Method m, Object o, Object... args) { try {
try {
return m.invoke(o, args);
} catch (InvocationTargetException e) {
throw rethrow(getExceptionCause(e));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(e.getMessage() + " - was calling: " + m + ", args: " + joinWithSpace(classNames(args)));
}
} catch (Exception __e) { throw rethrow(__e); } }
static boolean call_checkArgs(Method m, Object[] args, boolean debug) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length) {
if (debug)
print("Bad parameter length: " + args.length + " vs " + types.length);
return false;
}
for (int i = 0; i < types.length; i++) {
Object arg = args[i];
if (!(arg == null ? !types[i].isPrimitive()
: isInstanceX(types[i], arg))) {
if (debug)
print("Bad parameter " + i + ": " + arg + " vs " + types[i]);
return false;
}
}
return true;
}
static Field makeAccessible(Field f) {
try {
f.setAccessible(true);
} catch (Throwable e) {
// Note: The error reporting only works with Java VM option --illegal-access=deny
vmBus_send("makeAccessible_error", e, f);
}
return f;
}
static Method makeAccessible(Method m) {
try {
m.setAccessible(true);
} catch (Throwable e) {
vmBus_send("makeAccessible_error", e, m);
}
return m;
}
static Constructor makeAccessible(Constructor c) {
try {
c.setAccessible(true);
} catch (Throwable e) {
vmBus_send("makeAccessible_error", e, c);
}
return c;
}
static Class javax() {
return getJavaX();
}
static RuntimeException asRuntimeException(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static String combinePrintParameters(String s, Object o) {
return (endsWithLetterOrDigit(s) ? s + ": " : s) + o;
}
static void ping_okInCleanUp() {
if (ping_pauseAll || ping_anyActions)
ping_impl(true);
}
// this syntax should be removed...
static Object getThreadLocal(Object o, String name) {
ThreadLocal t = (ThreadLocal) (getOpt(o, name));
return t != null ? t.get() : null;
}
static A getThreadLocal(ThreadLocal tl) {
return tl == null ? null : tl.get();
}
static A getThreadLocal(ThreadLocal tl, A defaultValue) {
return or(getThreadLocal(tl), defaultValue);
}
static ThreadLocal print_byThread_dontCreate() {
return print_byThread;
}
static boolean isFalse(Object o) {
return eq(false, o);
}
static String fixNewLines(String s) {
int i = indexOf(s, '\r');
if (i < 0) return s;
int l = s.length();
StringBuilder out = new StringBuilder(l);
out.append(s, 0, i);
for (; i < l; i++) {
char c = s.charAt(i);
if (c != '\r')
out.append(c);
else {
out.append('\n');
if (i+1 < l && s.charAt(i+1) == '\n') ++i;
}
}
return out.toString();
}
static void print_append(Appendable buf, String s, int max) { try {
synchronized(buf) {
buf.append(s);
if (buf instanceof StringBuffer)
rotateStringBuffer(((StringBuffer) buf), max);
else if (buf instanceof StringBuilder)
rotateStringBuilder(((StringBuilder) buf), max);
}
} catch (Exception __e) { throw rethrow(__e); } }
static Class mc() {
return main.class;
}
// PersistableThrowable doesn't hold GC-disturbing class references in backtrace
static volatile PersistableThrowable lastException_lastException;
static PersistableThrowable lastException() {
return lastException_lastException;
}
static void lastException(Throwable e) {
lastException_lastException = persistableThrowable(e);
}
static String hideCredentials(URL url) { return url == null ? null : hideCredentials(str(url)); }
static String hideCredentials(String url) {
try {
if (startsWithOneOf(url, "http://", "https://") && isAGIBlueDomain(hostNameFromURL(url))) return url;
} catch (Throwable e) {
print("HideCredentials", e);
}
return url.replaceAll("([&?])(_pass|key|cookie)=[^&\\s\"]*", "$1$2=");
}
static String hideCredentials(Object o) {
return hideCredentials(str(o));
}
static boolean empty(Collection c) { return c == null || c.isEmpty(); }
static boolean empty(Iterable c) { return c == null || !c.iterator().hasNext(); }
static boolean empty(CharSequence s) { return s == null || s.length() == 0; }
static boolean empty(Map map) { return map == null || map.isEmpty(); }
static boolean empty(Object[] o) { return o == null || o.length == 0; }
static boolean empty(BitSet bs) { return bs == null || bs.isEmpty(); }
static boolean empty(Object o) {
if (o instanceof Collection) return empty((Collection) o);
if (o instanceof String) return empty((String) o);
if (o instanceof Map) return empty((Map) o);
if (o instanceof Object[]) return empty((Object[]) o);
if (o instanceof byte[]) return empty((byte[]) o);
if (o == null) return true;
throw fail("unknown type for 'empty': " + getType(o));
}
static boolean empty(Iterator i) { return i == null || !i.hasNext(); }
static boolean empty(double[] a) { return a == null || a.length == 0; }
static boolean empty(float[] a) { return a == null || a.length == 0; }
static boolean empty(int[] a) { return a == null || a.length == 0; }
static boolean empty(long[] a) { return a == null || a.length == 0; }
static boolean empty(byte[] a) { return a == null || a.length == 0; }
static boolean empty(short[] a) { return a == null || a.length == 0; }
static boolean empty(MultiSet ms) { return ms == null || ms.isEmpty(); }
static boolean empty(MultiMap mm) { return mm == null || mm.isEmpty(); }
static boolean empty(File f) { return getFileSize(f) == 0; }
static boolean empty(IntRange r) { return r == null || r.empty(); }
static boolean empty(Rect r) { return !(r != null && r.w != 0 && r.h != 0); }
static boolean empty(AppendableChain c) { return c == null; }
static ArrayList cloneList(Iterable l) {
return l instanceof Collection ? cloneList((Collection) l) : asList(l);
}
static ArrayList cloneList(Collection l) {
if (l == null) return new ArrayList();
synchronized(collectionMutex(l)) {
return new ArrayList (l);
}
}
//sbool ping_actions_shareable = true;
static volatile boolean ping_pauseAll = false;
static int ping_sleep = 100; // poll pauseAll flag every 100
static volatile boolean ping_anyActions = false;
static Map ping_actions = newWeakHashMap();
static ThreadLocal ping_isCleanUpThread = new ThreadLocal();
// always returns true
static boolean ping() {
//ifdef useNewPing
newPing();
//endifdef
if (ping_pauseAll || ping_anyActions) ping_impl(true /* XXX */);
//ifndef LeanMode ping_impl(); endifndef
return true;
}
// returns true when it slept
static boolean ping_impl(boolean okInCleanUp) { try {
if (ping_pauseAll && !isAWTThread()) {
do
Thread.sleep(ping_sleep);
while (ping_pauseAll);
return true;
}
if (ping_anyActions) { // don't allow sharing ping_actions
if (!okInCleanUp && !isTrue(ping_isCleanUpThread.get()))
failIfUnlicensed();
Object action = null;
synchronized(ping_actions) {
if (!ping_actions.isEmpty()) {
action = ping_actions.get(currentThread());
if (action instanceof Runnable)
ping_actions.remove(currentThread());
if (ping_actions.isEmpty()) ping_anyActions = false;
}
}
if (action instanceof Runnable)
((Runnable) action).run();
else if (eq(action, "cancelled"))
throw fail("Thread cancelled.");
}
return false;
} catch (Exception __e) { throw rethrow(__e); } }
static Object pcallF_minimalExceptionHandling(Object f, Object... args) {
try {
return callFunction(f, args);
} catch (Throwable e) {
System.out.println(getStackTrace(e));
_storeException(e);
}
return null;
}
static Set vm_generalIdentityHashSet(Object name) {
synchronized(vm_generalMap()) {
Set set = (Set) (vm_generalMap_get(name));
if (set == null)
vm_generalMap_put(name, set = syncIdentityHashSet());
return set;
}
}
static Map vm_generalHashMap(Object name) {
synchronized(vm_generalMap()) {
Map m = (Map) (vm_generalMap_get(name));
if (m == null)
vm_generalMap_put(name, m = syncHashMap());
return m;
}
}
static void metaMapPut(IMeta o, Object key, Object value) {
{ if (o != null) o.metaPut(key, value); }
}
static void metaMapPut(Object o, Object key, Object value) {
var meta = initIMeta(o);
{ if (meta != null) meta.metaPut(key, value); }
}
static String joinNemptiesWithColon(String... strings) {
return joinNempties(": ", strings);
}
static String joinNemptiesWithColon(Collection strings) {
return joinNempties(": ", strings);
}
static int identityHash(Object o) {
return identityHashCode(o);
}
static Object metaMapGet(IMeta o, Object key) {
return o == null ? null : o.metaGet(key); // We now let the object itself do it (overridable!)
}
static Object metaMapGet(Object o, Object key) {
return metaMapGet(toIMeta(o), key);
}
static int isAndroid_flag;
static boolean isAndroid() {
if (isAndroid_flag == 0)
isAndroid_flag = System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0 ? 1 : -1;
return isAndroid_flag > 0;
}
static Boolean isHeadless_cache;
static boolean isHeadless() {
if (isHeadless_cache != null) return isHeadless_cache;
if (isAndroid()) return isHeadless_cache = true;
if (GraphicsEnvironment.isHeadless()) return isHeadless_cache = true;
// Also check if AWT actually works.
// If DISPLAY variable is set but no X server up, this will notice.
try {
SwingUtilities.isEventDispatchThread();
return isHeadless_cache = false;
} catch (Throwable e) { return isHeadless_cache = true; }
}
static List> _threadInfo_makers = synchroList();
static Object _threadInfo() {
if (empty(_threadInfo_makers)) return null;
HashMap map = new HashMap();
pcallFAll(_threadInfo_makers, map);
return map;
}
static Runnable asRunnable(Object o) {
return toRunnable(o);
}
static void _inheritThreadInfo(Object info) {
_threadInheritInfo(info);
}
static Field getOpt_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static Object getOptDynOnly(DynamicObject o, String field) {
if (o == null || o.fieldValues == null) return null;
return o.fieldValues.get(field);
}
static ThreadLocal print_byThread() {
synchronized(print_byThread_lock) {
if (print_byThread == null)
print_byThread = new ThreadLocal();
}
return print_byThread;
}
// f can return false to suppress regular printing
// call print_raw within f to actually print something
static AutoCloseable tempInterceptPrint(F1 f) {
return tempSetThreadLocal(print_byThread(), f);
}
static ArrayList emptyList() {
return new ArrayList();
//ret Collections.emptyList();
}
static ArrayList emptyList(int capacity) {
return new ArrayList(max(0, capacity));
}
// Try to match capacity
static ArrayList emptyList(Iterable l) {
return l instanceof Collection ? emptyList(((Collection) l).size()) : emptyList();
}
static ArrayList emptyList(Object[] l) {
return emptyList(l(l));
}
// get correct type at once
static ArrayList emptyList(Class c) {
return new ArrayList();
}
static List ll(A... a) {
ArrayList l = new ArrayList(a.length);
if (a != null) for (A x : a) l.add(x);
return l;
}
static Object call_withVarargs(Object o, String method, Object... args) { try {
if (o == null) return null;
if (o instanceof Class) {
Class c = (Class) o;
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findStaticMethod(method, args);
if (me != null)
return invokeMethod(me, null, args);
// try varargs
List methods = cache.cache.get(method);
if (methods != null) methodSearch: for (Method m : methods) {
{ if (!(m.isVarArgs())) continue; }
{ if (!(isStaticMethod(m))) continue; }
Object[] newArgs = massageArgsForVarArgsCall(m, args);
if (newArgs != null)
return invokeMethod(m, null, newArgs);
}
throw fail("Method " + c.getName() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found");
} else {
Class c = o.getClass();
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findMethod(method, args);
if (me != null)
return invokeMethod(me, o, args);
// try varargs
List methods = cache.cache.get(method);
if (methods != null) methodSearch: for (Method m : methods) {
{ if (!(m.isVarArgs())) continue; }
Object[] newArgs = massageArgsForVarArgsCall(m, args);
if (newArgs != null)
return invokeMethod(m, o, newArgs);
}
throw fail("Method " + c.getName() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found");
}
} catch (Exception __e) { throw rethrow(__e); } }
static List _registerDangerousWeakMap_preList;
static A _registerDangerousWeakMap(A map) {
return _registerDangerousWeakMap(map, null);
}
static A _registerDangerousWeakMap(A map, Object init) {
callF(init, map);
if (init instanceof String) {
final String f = (String) init;
init = new VF1() { public void get(Map map) { try { callMC(f, map) ; } catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "callMC(f, map)"; }};
}
if (javax() == null) {
// We're in class init
if (_registerDangerousWeakMap_preList == null) _registerDangerousWeakMap_preList = synchroList();
_registerDangerousWeakMap_preList.add(pair(map, init));
return map;
}
call(javax(), "_registerDangerousWeakMap", map, init);
return map;
}
static void _onLoad_registerDangerousWeakMap() {
assertNotNull(javax());
if (_registerDangerousWeakMap_preList == null) return;
for (Pair p : _registerDangerousWeakMap_preList)
_registerDangerousWeakMap(p.a, p.b);
_registerDangerousWeakMap_preList = null;
}
static Map synchroMap() {
return synchroHashMap();
}
static Map synchroMap(Map map) {
return Collections.synchronizedMap(map);
}
static Throwable getExceptionCause(Throwable e) {
Throwable c = e.getCause();
return c != null ? c : e;
}
static String joinWithSpace(Iterable c) {
return join(" ", c);
}
static String joinWithSpace(String... c) {
return join(" ", c);
}
static List classNames(Collection l) {
return getClassNames(l);
}
static List classNames(Object[] l) {
return getClassNames(Arrays.asList(l));
}
static boolean isInstanceX(Class type, Object arg) {
if (type == boolean.class) return arg instanceof Boolean;
if (type == int.class) return arg instanceof Integer;
if (type == long.class) return arg instanceof Long;
if (type == float.class) return arg instanceof Float;
if (type == short.class) return arg instanceof Short;
if (type == char.class) return arg instanceof Character;
if (type == byte.class) return arg instanceof Byte;
if (type == double.class) return arg instanceof Double;
return type.isInstance(arg);
}
static Class __javax;
static Class getJavaX() { try {
return __javax;
} catch (Exception __e) { throw rethrow(__e); } }
static void __setJavaX(Class j) {
__javax = j;
_onJavaXSet();
}
static boolean endsWithLetterOrDigit(String s) {
return s != null && s.length() > 0 && Character.isLetterOrDigit(s.charAt(s.length()-1));
}
static Object getOpt(Object o, String field) {
return getOpt_cached(o, field);
}
static Object getOpt(String field, Object o) {
return getOpt_cached(o, field);
}
static Object getOpt_raw(Object o, String field) { try {
Field f = getOpt_findField(o.getClass(), field);
if (f == null) return null;
makeAccessible(f);
return f.get(o);
} catch (Exception __e) { throw rethrow(__e); } }
// access of static fields is not yet optimized
static Object getOpt(Class c, String field) { try {
if (c == null) return null;
Field f = getOpt_findStaticField(c, field);
if (f == null) return null;
makeAccessible(f);
return f.get(null);
} catch (Exception __e) { throw rethrow(__e); } }
static Field getOpt_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static A or(A a, A b) {
return a != null ? a : b;
}
static int indexOf(List l, A a, int startIndex) {
if (l == null) return -1;
int n = l(l);
for (int i = startIndex; i < n; i++)
if (eq(l.get(i), a))
return i;
return -1;
}
static int indexOf(List l, int startIndex, A a) {
return indexOf(l, a, startIndex);
}
static int indexOf(List l, A a) {
if (l == null) return -1;
return l.indexOf(a);
}
static int indexOf(String a, String b) {
return a == null || b == null ? -1 : a.indexOf(b);
}
static int indexOf(String a, String b, int i) {
return a == null || b == null ? -1 : a.indexOf(b, i);
}
static int indexOf(String a, char b) {
return a == null ? -1 : a.indexOf(b);
}
static int indexOf(String a, int i, char b) {
return indexOf(a, b, i);
}
static int indexOf(String a, char b, int i) {
return a == null ? -1 : a.indexOf(b, i);
}
static int indexOf(String a, int i, String b) {
return a == null || b == null ? -1 : a.indexOf(b, i);
}
static int indexOf(A[] x, A a) {
int n = l(x);
for (int i = 0; i < n; i++)
if (eq(x[i], a))
return i;
return -1;
}
static int indexOf(Iterable l, A a) {
if (l == null) return -1;
int i = 0;
for (A x : l) {
if (eq(x, a))
return i;
i++;
}
return -1;
}
static void rotateStringBuffer(StringBuffer buf, int max) { try {
if (buf == null) return;
synchronized(buf) {
if (buf.length() <= max) return;
try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
buf.trimToSize();
}
} catch (Exception __e) { throw rethrow(__e); } }
static void rotateStringBuilder(StringBuilder buf, int max) { try {
if (buf == null) return;
synchronized(buf) {
if (buf.length() <= max) return;
try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
buf.trimToSize();
}
} catch (Exception __e) { throw rethrow(__e); } }
static PersistableThrowable persistableThrowable(Throwable e) {
return e == null ? null : new PersistableThrowable(e);
}
static boolean startsWithOneOf(String s, String... l) {
for (String x : l) if (startsWith(s, x)) return true; return false;
}
static boolean startsWithOneOf(String s, Matches m, String... l) {
for (String x : l) if (startsWith(s, x, m)) return true; return false;
}
static boolean isAGIBlueDomain(String domain) {
return domainIsUnder(domain, theAGIBlueDomain());
}
static String hostNameFromURL(String url) { try {
return empty(url) ? null : new URL(url).getHost();
} catch (Exception __e) { throw rethrow(__e); } }
static String getType(Object o) {
return getClassName(o);
}
static long getFileSize(String path) {
return path == null ? 0 : new File(path).length();
}
static long getFileSize(File f) {
return f == null ? 0 : f.length();
}
// TODO: JDK 17!! ?? No! Yes? Yes!!
static Object collectionMutex(List l) {
return l;
}
static Object collectionMutex(Object o) {
if (o instanceof List) return o;
// TODO: actually use our own maps so we can get the mutex properly
String c = className(o);
return o;
}
static Map newWeakHashMap() {
return _registerWeakMap(synchroMap(new WeakHashMap()));
}
static void newPing() {
var tl = newPing_actionTL();
Runnable action = tl == null ? null : tl.get();
{ if (action != null) action.run(); }
}
static boolean isTrue(Object o) {
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
if (o == null) return false;
if (o instanceof ThreadLocal) // TODO: remove this
return isTrue(((ThreadLocal) o).get());
throw fail(getClassName(o));
}
static boolean isTrue(Boolean b) {
return b != null && b.booleanValue();
}
static void failIfUnlicensed() {
assertTrue("license off", licensed());
}
static Thread currentThread() {
return Thread.currentThread();
}
static Object callFunction(Object f, Object... args) {
return callF(f, args);
}
static Throwable _storeException_value;
static void _storeException(Throwable e) {
_storeException_value = e;
}
static Map vm_generalMap_map;
static Map vm_generalMap() {
if (vm_generalMap_map == null)
vm_generalMap_map = (Map) get(javax(), "generalMap");
return vm_generalMap_map;
}
static Object vm_generalMap_get(Object key) {
return vm_generalMap().get(key);
}
static Object vm_generalMap_put(Object key, Object value) {
return mapPutOrRemove(vm_generalMap(), key, value);
}
static Set syncIdentityHashSet() {
return (Set) synchronizedSet(identityHashSet());
}
static Map syncHashMap() {
return synchroHashMap();
}
static IMeta initIMeta(Object o) {
if (o == null) return null;
if (o instanceof IMeta) return ((IMeta) o);
if (o instanceof JComponent) return initMetaOfJComponent((JComponent) o);
if (o instanceof BufferedImage) return optCast(IMeta.class, ((BufferedImage) o).getProperty("meta"));
return null;
}
static String joinNempties(String sep, Object... strings) {
return joinStrings(sep, strings);
}
static String joinNempties(String sep, Iterable strings) {
return joinStrings(sep, strings);
}
static int identityHashCode(Object o) {
return System.identityHashCode(o);
}
static IMeta toIMeta(Object o) {
if (o == null) return null;
if (o instanceof IMeta) return ((IMeta) o);
if (o instanceof JComponent) return initMetaOfJComponent((JComponent) o);
if (o instanceof BufferedImage) return optCast(IMeta.class, ((BufferedImage) o).getProperty("meta"));
return null;
}
static List synchroList() {
return synchroList(new ArrayList ());
}
static List synchroList(List l) {
return Collections.synchronizedList(l);
}
static void pcallFAll(Collection l, Object... args) {
if (l != null) for (Object f : cloneList(l)) pcallF(f, args);
}
static void pcallFAll(Iterator it, Object... args) {
while (it.hasNext()) pcallF(it.next(), args);
}
static Runnable toRunnable(final Object o) {
if (o instanceof Runnable) return (Runnable) o;
if (o instanceof String) throw fail("callF_legacy");
return new Runnable() { public void run() { try { callF(o) ;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(o)"; }};
}
static List> _threadInheritInfo_retrievers = synchroList();
static void _threadInheritInfo(Object info) {
if (info == null) return;
pcallFAll(_threadInheritInfo_retrievers, (Map) info);
}
static AutoCloseable tempSetThreadLocal(final ThreadLocal tl, A a) {
if (tl == null) return null;
final A prev = setThreadLocal(tl, a);
return new AutoCloseable() { public String toString() { return "tl.set(prev);"; } public void close() throws Exception { tl.set(prev); }};
}
static int max(int a, int b) { return Math.max(a, b); }
static int max(int a, int b, int c) { return max(max(a, b), c); }
static long max(int a, long b) { return Math.max((long) a, b); }
static long max(long a, long b) { return Math.max(a, b); }
static double max(int a, double b) { return Math.max((double) a, b); }
static float max(float a, float b) { return Math.max(a, b); }
static double max(double a, double b) { return Math.max(a, b); }
static int max(Collection c) {
int x = Integer.MIN_VALUE;
for (int i : c) x = max(x, i);
return x;
}
static double max(double[] c) {
if (c.length == 0) return Double.MIN_VALUE;
double x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static float max(float[] c) {
if (c.length == 0) return Float.MAX_VALUE;
float x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static byte max(byte[] c) {
byte x = -128;
for (byte d : c) if (d > x) x = d;
return x;
}
static short max(short[] c) {
short x = -0x8000;
for (short d : c) if (d > x) x = d;
return x;
}
static int max(int[] c) {
int x = Integer.MIN_VALUE;
for (int d : c) if (d > x) x = d;
return x;
}
static > A max(A a, A b) {
return cmp(a, b) >= 0 ? a : b;
}
static final Map callOpt_cache = newDangerousWeakHashMap();
static Object callOpt_cached(Object o, String methodName, Object... args) { try {
if (o == null) return null;
if (o instanceof Class) {
Class c = (Class) o;
_MethodCache cache = callOpt_getCache(c);
// TODO: (super-rare) case where method exists static and non-static
// with different args
Method me = cache.findMethod(methodName, args);
if (me == null || (me.getModifiers() & Modifier.STATIC) == 0) return null;
return invokeMethod(me, null, args);
} else {
Class c = o.getClass();
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findMethod(methodName, args);
if (me == null) return null;
return invokeMethod(me, o, args);
}
} catch (Exception __e) { throw rethrow(__e); } }
// no longer synchronizes! (see #1102990)
static _MethodCache callOpt_getCache(Class c) {
_MethodCache cache = callOpt_cache.get(c);
if (cache == null)
callOpt_cache.put(c, cache = new _MethodCache(c));
return cache;
}
static boolean isStaticMethod(Method m) {
return methodIsStatic(m);
}
static Object[] massageArgsForVarArgsCall(Method m, Object[] args) {
Class>[] types = m.getParameterTypes();
int n = types.length-1, nArgs = args.length;
if (nArgs < n) return null;
for (int i = 0; i < n; i++)
if (!argumentCompatibleWithType(args[i], types[i]))
return null;
Class varArgType = types[n].getComponentType();
for (int i = n; i < nArgs; i++)
if (!argumentCompatibleWithType(args[i], varArgType))
return null;
Object[] newArgs = new Object[n+1];
arraycopy(args, 0, newArgs, 0, n);
Object[] varArgs = arrayOfType(varArgType, nArgs-n);
arraycopy(args, n, varArgs, 0, nArgs-n);
newArgs[n] = varArgs;
return newArgs;
}
static String joinWithComma(Collection c) {
return join(", ", c);
}
static String joinWithComma(Object... c) {
return join(", ", c);
}
static String joinWithComma(String... c) {
return join(", ", c);
}
static String joinWithComma(Pair p) {
return p == null ? "" : joinWithComma(str(p.a), str(p.b));
}
static HashMap> callMC_cache = new HashMap();
static String callMC_key;
static Method callMC_value;
// varargs assignment fixer for a single string array argument
static Object callMC(String method, String[] arg) {
return callMC(method, new Object[] {arg});
}
static Object callMC(String method, Object... args) { try {
Method me;
if (callMC_cache == null) callMC_cache = new HashMap(); // initializer time workaround
synchronized(callMC_cache) {
me = method == callMC_key ? callMC_value : null;
}
if (me != null) try {
return invokeMethod(me, null, args);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e);
}
List m;
synchronized(callMC_cache) {
m = callMC_cache.get(method);
}
if (m == null) {
if (callMC_cache.isEmpty()) {
callMC_makeCache();
m = callMC_cache.get(method);
}
if (m == null) throw fail("Method named " + method + " not found in main");
}
int n = m.size();
if (n == 1) {
me = m.get(0);
synchronized(callMC_cache) {
callMC_key = method;
callMC_value = me;
}
try {
return invokeMethod(me, null, args);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e);
}
}
for (int i = 0; i < n; i++) {
me = m.get(i);
if (call_checkArgs(me, args, false))
return invokeMethod(me, null, args);
}
throw fail("No method called " + method + " with arguments (" + joinWithComma(getClasses(args)) + ") found in main");
} catch (Exception __e) { throw rethrow(__e); } }
static void callMC_makeCache() {
synchronized(callMC_cache) {
callMC_cache.clear();
Class _c = (Class) mc(), c = _c;
while (c != null) {
for (Method m : c.getDeclaredMethods())
if ((m.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) {
makeAccessible(m);
multiMapPut(callMC_cache, m.getName(), m);
}
c = c.getSuperclass();
}
}
}
static Pair pair(A a, B b) {
return new Pair(a, b);
}
static Pair pair(A a) {
return new Pair(a, a);
}
static A assertNotNull(A a) {
assertTrue(a != null);
return a;
}
static A assertNotNull(String msg, A a) {
assertTrue(msg, a != null);
return a;
}
static Map synchroHashMap() {
return synchronizedMap(new HashMap());
}
public static String join(String glue, Iterable strings) {
if (strings == null) return "";
if (strings instanceof Collection) {
if (((Collection) strings).size() == 1) return str(first((Collection) strings));
}
StringBuilder buf = new StringBuilder();
Iterator i = strings.iterator();
if (i.hasNext()) {
buf.append(i.next());
while (i.hasNext())
buf.append(glue).append(i.next());
}
return buf.toString();
}
public static String join(String glue, String... strings) {
return join(glue, Arrays.asList(strings));
}
public static String join(String glue, Object... strings) {
return join(glue, Arrays.asList(strings));
}
static String join(Iterable strings) {
return join("", strings);
}
static String join(Iterable strings, String glue) {
return join(glue, strings);
}
public static String join(String[] strings) {
return join("", strings);
}
static String join(String glue, Pair p) {
return p == null ? "" : str(p.a) + glue + str(p.b);
}
static List getClassNames(Collection l) {
List out = new ArrayList();
if (l != null) for (Object o : l)
out.add(o == null ? null : getClassName(o));
return out;
}
static void _onJavaXSet() {}
//static final Map> getOpt_cache = newDangerousWeakHashMap(f getOpt_special_init);
static class getOpt_Map extends WeakHashMap {
getOpt_Map() {
if (getOpt_special == null) getOpt_special = new HashMap();
clear();
}
public void clear() {
super.clear();
//print("getOpt clear");
put(Class.class, getOpt_special);
put(String.class, getOpt_special);
}
}
static final Map> getOpt_cache = _registerDangerousWeakMap(synchroMap(new getOpt_Map()));
//static final Map> getOpt_cache = _registerWeakMap(synchroMap(new getOpt_Map));
static HashMap getOpt_special; // just a marker
/*static void getOpt_special_init(Map map) {
map.put(Class.class, getOpt_special);
map.put(S.class, getOpt_special);
}*/
static Map getOpt_getFieldMap(Object o) {
Class c = _getClass(o);
HashMap map = getOpt_cache.get(c);
if (map == null)
map = getOpt_makeCache(c);
return map;
}
static Object getOpt_cached(Object o, String field) { try {
if (o == null) return null;
Map map = getOpt_getFieldMap(o);
if (map == getOpt_special) {
if (o instanceof Class)
return getOpt((Class) o, field);
/*if (o instanceof S)
ret getOpt(getBot((S) o), field);*/
if (o instanceof Map)
return ((Map) o).get(field);
}
Field f = map.get(field);
if (f != null) return f.get(o);
if (o instanceof DynamicObject)
return syncMapGet2(((DynamicObject) o).fieldValues, field);
return null;
} catch (Exception __e) { throw rethrow(__e); } }
// used internally - we are in synchronized block
static HashMap getOpt_makeCache(Class c) {
HashMap map;
if (isSubtypeOf(c, Map.class))
map = getOpt_special;
else {
map = new HashMap();
if (!reflection_classesNotToScan().contains(c.getName())) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields()) {
makeAccessible(f);
String name = f.getName();
if (!map.containsKey(name))
map.put(name, f);
}
_c = _c.getSuperclass();
} while (_c != null);
}
}
if (getOpt_cache != null) getOpt_cache.put(c, map);
return map;
}
static boolean startsWith(String a, String b) {
return a != null && a.startsWith(unnull(b));
}
static boolean startsWith(String a, char c) {
return nemptyString(a) && a.charAt(0) == c;
}
static boolean startsWith(String a, String b, Matches m) {
if (!startsWith(a, b)) return false;
if (m != null) m.m = new String[] {substring(a, strL(b))};
return true;
}
static boolean startsWith(List a, List b) {
if (a == null || listL(b) > listL(a)) return false;
for (int i = 0; i < listL(b); i++)
if (neq(a.get(i), b.get(i)))
return false;
return true;
}
static boolean domainIsUnder(String domain, String mainDomain) {
return eqic(domain, mainDomain) || ewic(domain, "." + mainDomain);
}
static String theAGIBlueDomain() {
return "agi.blue";
}
static String className(Object o) {
return getClassName(o);
}
static List _registerWeakMap_preList;
static A _registerWeakMap(A map) {
if (javax() == null) {
// We're in class init
if (_registerWeakMap_preList == null) _registerWeakMap_preList = synchroList();
_registerWeakMap_preList.add(map);
return map;
}
try {
call(javax(), "_registerWeakMap", map);
} catch (Throwable e) {
printException(e);
print("Upgrade JavaX!!");
}
return map;
}
static void _onLoad_registerWeakMap() {
assertNotNull(javax());
if (_registerWeakMap_preList == null) return;
for (Object o : _registerWeakMap_preList)
_registerWeakMap(o);
_registerWeakMap_preList = null;
}
static x30_pkg.x30_util.BetterThreadLocal newPing_actionTL;
static x30_pkg.x30_util.BetterThreadLocal newPing_actionTL() {
if (newPing_actionTL == null)
newPing_actionTL = vm_generalMap_getOrCreate("newPing_actionTL",
() -> {
Runnable value = (Runnable) (callF_gen(vm_generalMap_get("newPing_valueForNewThread")));
var tl = new x30_pkg.x30_util.BetterThreadLocal();
tl.set(value);
return tl;
});
return newPing_actionTL;
}
static void assertTrue(Object o) {
if (!(eq(o, true) /*|| isTrue(pcallF(o))*/))
throw fail(str(o));
}
static boolean assertTrue(String msg, boolean b) {
if (!b)
throw fail(msg);
return b;
}
static boolean assertTrue(boolean b) {
if (!b)
throw fail("oops");
return b;
}
static volatile boolean licensed_yes = true;
static boolean licensed() {
if (!licensed_yes) return false;
ping_okInCleanUp();
return true;
}
static void licensed_off() {
licensed_yes = false;
}
static B mapPutOrRemove(Map map, A key, B value) {
if (map != null && key != null)
if (value != null) return map.put(key, value);
else return map.remove(key);
return null;
}
static Set synchronizedSet() {
return synchroHashSet();
}
static Set synchronizedSet(Set set) {
return Collections.synchronizedSet(set);
}
static Set identityHashSet() {
return Collections.newSetFromMap(new IdentityHashMap());
}
static IMeta initMetaOfJComponent(JComponent c) {
if (c == null) return null;
IMeta meta = (IMeta) (c.getClientProperty(IMeta.class));
if (meta == null)
c.putClientProperty(IMeta.class, meta = new Meta());
return meta;
}
static A optCast(Class c, Object o) {
return isInstance(c, o) ? (A) o : null;
}
static String joinStrings(String sep, Object... strings) {
return joinStrings(sep, Arrays.asList(strings));
}
static String joinStrings(String sep, Iterable strings) {
StringBuilder buf = new StringBuilder();
for (Object o : unnull(strings)) {
String s = strOrNull(o);
if (nempty(s)) {
if (nempty(buf)) buf.append(sep);
buf.append(s);
}
}
return str(buf);
}
static Object pcallF(Object f, Object... args) {
return pcallFunction(f, args);
}
static A pcallF(F0 f) {
try { return f == null ? null : f.get(); } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static B pcallF(F1 f, A a) {
try { return f == null ? null : f.get(a); } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static void pcallF(VF1 f, A a) {
try {
{ if (f != null) f.get(a); }
} catch (Throwable __e) { printStackTrace(__e); }
}
static Object pcallF(Runnable r) {
try { { if (r != null) r.run(); } } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static A pcallF(IF0 f) {
try { return f == null ? null : f.get(); } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static B pcallF(IF1 f, A a) {
try { return f == null ? null : f.get(a); } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static A setThreadLocal(ThreadLocal tl, A value) {
if (tl == null) return null;
A old = tl.get();
tl.set(value);
return old;
}
static int cmp(Number a, Number b) {
return a == null ? b == null ? 0 : -1 : cmp(a.doubleValue(), b.doubleValue());
}
static int cmp(double a, double b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(int a, int b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(long a, long b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(Object a, Object b) {
if (a == null) return b == null ? 0 : -1;
if (b == null) return 1;
return ((Comparable) a).compareTo(b);
}
static boolean methodIsStatic(Method m) {
return (m.getModifiers() & Modifier.STATIC) != 0;
}
static boolean argumentCompatibleWithType(Object arg, Class type) {
return arg == null ? !type.isPrimitive() : isInstanceX(type, arg);
}
static void arraycopy(Object[] a, Object[] b) {
if (a != null && b != null)
arraycopy(a, 0, b, 0, Math.min(a.length, b.length));
}
static void arraycopy(Object src, int srcPos, int destPos, int n) { arraycopy(src, srcPos, src, destPos, n); }
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int n) {
if (n != 0)
System.arraycopy(src, srcPos, dest, destPos, n);
}
static A[] arrayOfType(Class type, int n) {
return makeArray(type, n);
}
static A[] arrayOfType(int n, Class type) {
return arrayOfType(type, n);
}
static List getClasses(Object[] array) {
List l = emptyList(l(array));
for (Object o : array) l.add(_getClass(o));
return l;
}
static void multiMapPut(Map > map, A a, B b) {
List l = map.get(a);
if (l == null)
map.put(a, l = new ArrayList());
l.add(b);
}
static void multiMapPut(MultiMap mm, A key, B value) {
if (mm != null && key != null && value != null) mm.put(key, value);
}
static Map synchronizedMap() {
return synchroMap();
}
static Map synchronizedMap(Map map) {
return synchroMap(map);
}
static Object first(Object list) {
return first((Iterable) list);
}
static A first(List list) {
return empty(list) ? null : list.get(0);
}
static A first(A[] bla) {
return bla == null || bla.length == 0 ? null : bla[0];
}
static Pair first(Map map) {
return mapEntryToPair(first(entrySet(map)));
}
static Pair first(MultiMap mm) {
if (mm == null) return null;
var e = first(mm.data.entrySet());
if (e == null) return null;
return pair(e.getKey(), first(e.getValue()));
}
static A first(IterableIterator i) {
return first((Iterator ) i);
}
static A first(Iterator i) {
return i == null || !i.hasNext() ? null : i.next();
}
static A first(Iterable i) {
if (i == null) return null;
Iterator it = i.iterator();
return it.hasNext() ? it.next() : null;
}
static Character first(String s) { return empty(s) ? null : s.charAt(0); }
static Character first(CharSequence s) { return empty(s) ? null : s.charAt(0); }
static A first(Pair p) {
return p == null ? null : p.a;
}
static A first(T3 t) {
return t == null ? null : t.a;
}
static Byte first(byte[] l) {
return empty(l) ? null : l[0];
}
static A first(A[] l, IF1 pred) {
return firstThat(l, pred);
}
static A first(Iterable l, IF1 pred) {
return firstThat(l, pred);
}
static A first(IF1 pred, Iterable l) {
return firstThat(pred, l);
}
static A first(AppendableChain a) {
return a == null ? null : a.element;
}
static void clear(Collection c) {
if (c != null) c.clear();
}
static void clear(Map map) {
if (map != null) map.clear();
}
static void put(Map map, A a, B b) {
if (map != null) map.put(a, b);
}
static void put(List l, int i, A a) {
if (l != null && i >= 0 && i < l(l)) l.set(i, a);
}
static Class> _getClass(String name) {
try {
return Class.forName(name);
} catch (ClassNotFoundException e) {
return null; // could optimize this
}
}
static Class _getClass(Object o) {
return o == null ? null
: o instanceof Class ? (Class) o : o.getClass();
}
static Class _getClass(Object realm, String name) {
try {
return classLoaderForObject(realm).loadClass(classNameToVM(name));
} catch (ClassNotFoundException e) {
return null; // could optimize this
}
}
static B syncMapGet2(Map map, A a) {
if (map == null) return null;
synchronized(collectionMutex(map)) {
return map.get(a);
}
}
static B syncMapGet2(A a, Map map) {
return syncMapGet2(map, a);
}
static boolean isSubtypeOf(Class a, Class b) {
return a != null && b != null && b.isAssignableFrom(a); // << always hated that method, let's replace it!
}
static Set reflection_classesNotToScan_value = litset(
"jdk.internal.loader.URLClassPath"
);
static Set reflection_classesNotToScan() {
return reflection_classesNotToScan_value;
}
static String unnull(String s) {
return s == null ? "" : s;
}
static Collection unnull(Collection l) {
return l == null ? emptyList() : l;
}
static List unnull(List l) { return l == null ? emptyList() : l; }
static int[] unnull(int[] l) { return l == null ? emptyIntArray() : l; }
static char[] unnull(char[] l) { return l == null ? emptyCharArray() : l; }
static double[] unnull(double[] l) { return l == null ? emptyDoubleArray() : l; }
static Map unnull(Map l) {
return l == null ? emptyMap() : l;
}
static Iterable unnull(Iterable i) {
return i == null ? emptyList() : i;
}
static A[] unnull(A[] a) {
return a == null ? (A[]) emptyObjectArray() : a;
}
static BitSet unnull(BitSet b) {
return b == null ? new BitSet() : b;
}
static Pt unnull(Pt p) {
return p == null ? new Pt() : p;
}
//ifclass Symbol
static Symbol unnull(Symbol s) {
return s == null ? emptySymbol() : s;
}
//endif
static Pair unnull(Pair p) {
return p != null ? p : new Pair(null, null);
}
static int unnull(Integer i) { return i == null ? 0 : i; }
static long unnull(Long l) { return l == null ? 0L : l; }
static double unnull(Double l) { return l == null ? 0.0 : l; }
static boolean nemptyString(String s) {
return s != null && s.length() > 0;
}
static int listL(Collection l) {
return l == null ? 0 : l.size();
}
static boolean neq(Object a, Object b) {
return !eq(a, b);
}
static boolean eqic(String a, String b) {
if ((a == null) != (b == null)) return false;
if (a == null) return true;
return a.equalsIgnoreCase(b);
}
static boolean eqic(Symbol a, Symbol b) {
return eq(a, b);
}
static boolean eqic(Symbol a, String b) {
return eqic(asString(a), b);
}
static boolean eqic(char a, char b) {
if (a == b) return true;
char u1 = Character.toUpperCase(a);
char u2 = Character.toUpperCase(b);
if (u1 == u2) return true;
return Character.toLowerCase(u1) == Character.toLowerCase(u2);
}
static boolean ewic(String a, String b) {
return endsWithIgnoreCase(a, b);
}
static boolean ewic(String a, String b, Matches m) {
return endsWithIgnoreCase(a, b, m);
}
static A printException(A e) {
printStackTrace(e);
return e;
}
static A vm_generalMap_getOrCreate(Object key, F0 create) {
return vm_generalMap_getOrCreate(key, f0ToIF0(create));
}
static A vm_generalMap_getOrCreate(Object key, IF0 create) {
Map generalMap = vm_generalMap();
if (generalMap == null) return null; // must be x30 init
synchronized(generalMap) { // should switch to locks here
A a = (A) (vm_generalMap_get(key));
if (a == null)
vm_generalMap_put(key, a = create == null ? null : create.get());
return a;
}
}
static A callF_gen(F0 f) {
return f == null ? null : f.get();
}
static B callF_gen(F1 f, A a) {
return f == null ? null : f.get(a);
}
static A callF_gen(IF0 f) {
return f == null ? null : f.get();
}
static B callF_gen(IF1 f, A a) {
return f == null ? null : f.get(a);
}
static B callF_gen(A a, IF1 f) {
return f == null ? null : f.get(a);
}
static C callF_gen(IF2 f, A a, B b) {
return f == null ? null : f.get(a, b);
}
static void callF_gen(VF1 f, A a) {
{ if (f != null) f.get(a); }
}
static void callF_gen(A a, IVF1 f) {
{ if (f != null) f.get(a); }
}
static void callF_gen(IVF1 f, A a) {
{ if (f != null) f.get(a); }
}
static Object callF_gen(Runnable r) { { if (r != null) r.run(); } return null; }
static Object callF_gen(Object f, Object... args) {
return callF(f, args);
}
static Set synchroHashSet() {
return synchronizedSet(new HashSet ());
}
static boolean isInstance(Class type, Object arg) {
return type.isInstance(arg);
}
static String strOrNull(Object o) {
return o == null ? null : str(o);
}
static boolean nempty(Collection c) {
return !empty(c);
}
static boolean nempty(CharSequence s) {
return !empty(s);
}
static boolean nempty(Object[] o) { return !empty(o); }
static boolean nempty(byte[] o) { return !empty(o); }
static boolean nempty(int[] o) { return !empty(o); }
static boolean nempty(BitSet bs) { return !empty(bs); }
static boolean nempty(Map m) {
return !empty(m);
}
static boolean nempty(Iterator i) {
return i != null && i.hasNext();
}
static boolean nempty(MultiMap mm) { return mm != null && !mm.isEmpty(); }
static boolean nempty(Object o) { return !empty(o); }
static boolean nempty(IntRange r) { return !empty(r); }
static boolean nempty(Rect r) { return r != null && r.w != 0 && r.h != 0; }
static boolean nempty(MultiSet ms) { return ms != null && !ms.isEmpty(); }
static Object pcallFunction(Object f, Object... args) {
try { return callFunction(f, args); } catch (Throwable __e) { printStackTrace(__e); }
return null;
}
static A[] makeArray(Class type, int n) {
return (A[]) Array.newInstance(type, n);
}
static Pair mapEntryToPair(Map.Entry e) {
return e == null ? null : pair(e.getKey(), e.getValue());
}
static Set> entrySet(Map map) {
return _entrySet(map);
}
static A firstThat(Iterable l, IF1 pred) {
for (A a : unnullForIteration(l))
if (pred.get(a))
return a;
return null;
}
static A firstThat(A[] l, IF1 pred) {
for (A a : unnullForIteration(l))
if (pred.get(a))
return a;
return null;
}
static A firstThat(IF1 pred, Iterable l) {
return firstThat(l, pred);
}
static A firstThat(IF1 pred, A[] l) {
return firstThat(l, pred);
}
static ClassLoader classLoaderForObject(Object o) {
if (o instanceof ClassLoader) return ((ClassLoader) o);
if (o == null) return null;
return _getClass(o).getClassLoader();
}
// Note: This is actually broken. Inner classes must stay with a $ separator
static String classNameToVM(String name) {
return name.replace(".", "$");
}
static HashSet litset(A... items) {
return lithashset(items);
}
static int[] emptyIntArray_a = new int[0];
static int[] emptyIntArray() { return emptyIntArray_a; }
static char[] emptyCharArray = new char[0];
static char[] emptyCharArray() { return emptyCharArray; }
static double[] emptyDoubleArray = new double[0];
static double[] emptyDoubleArray() { return emptyDoubleArray; }
static Map emptyMap() {
return new HashMap();
}
static Object[] emptyObjectArray_a = new Object[0];
static Object[] emptyObjectArray() { return emptyObjectArray_a; }
static Symbol emptySymbol_value;
static Symbol emptySymbol() {
if (emptySymbol_value == null) emptySymbol_value = symbol("");
return emptySymbol_value;
}
static String asString(Object o) {
return o == null ? null : o.toString();
}
static boolean endsWithIgnoreCase(String a, String b) {
int la = l(a), lb = l(b);
return la >= lb && regionMatchesIC(a, la-lb, b, 0, lb);
}
static boolean endsWithIgnoreCase(String a, String b, Matches m) {
if (!endsWithIgnoreCase(a, b)) return false;
if (m != null)
m.m = new String[] { substring(a, 0, l(a)-l(b)) };
return true;
}
static IF0 f0ToIF0(F0 f) {
return f == null ? null : () -> f.get();
}
static Set> _entrySet(Map map) {
return map == null ? Collections.EMPTY_SET : map.entrySet();
}
static String unnullForIteration(String s) {
return s == null ? "" : s;
}
static Collection unnullForIteration(Collection l) {
return l == null ? immutableEmptyList() : l;
}
static List unnullForIteration(List l) { return l == null ? immutableEmptyList() : l; }
static int[] unnullForIteration(int[] l) { return l == null ? emptyIntArray() : l; }
static char[] unnullForIteration(char[] l) { return l == null ? emptyCharArray() : l; }
static double[] unnullForIteration(double[] l) { return l == null ? emptyDoubleArray() : l; }
static short[] unnullForIteration(short[] l) { return l == null ? emptyShortArray() : l; }
static Map unnullForIteration(Map l) {
return l == null ? immutableEmptyMap() : l;
}
static Iterable unnullForIteration(Iterable i) {
return i == null ? immutableEmptyList() : i;
}
static A[] unnullForIteration(A[] a) {
return a == null ? (A[]) emptyObjectArray() : a;
}
static BitSet unnullForIteration(BitSet b) {
return b == null ? new BitSet() : b;
}
static Pt unnullForIteration(Pt p) {
return p == null ? new Pt() : p;
}
//ifclass Symbol
static Symbol unnullForIteration(Symbol s) {
return s == null ? emptySymbol() : s;
}
//endif
static Pair unnullForIteration(Pair p) {
return p != null ? p : new Pair(null, null);
}
static long unnullForIteration(Long l) { return l == null ? 0L : l; }
static HashSet lithashset(A... items) {
HashSet set = new HashSet();
for (A a : items) set.add(a);
return set;
}
static WeakHasherMap symbol_map = new WeakHasherMap(new Hasher() {
public int hashCode(Symbol symbol) { return symbol.text.hashCode(); }
public boolean equals(Symbol a, Symbol b) {
if (a == null) return b == null;
return b != null && eq(a.text, b.text);
}
});
static Symbol symbol(String s) {
if (s == null) return null;
synchronized(symbol_map) {
// TODO: avoid object creation by passing the string to findKey
Symbol symbol = new Symbol(s, true);
Symbol existingSymbol = symbol_map.findKey(symbol);
if (existingSymbol == null)
symbol_map.put(existingSymbol = symbol, true);
return existingSymbol;
}
}
static Symbol symbol(CharSequence s) {
if (s == null) return null;
if (s instanceof Symbol) return (Symbol) s;
if (s instanceof String) return symbol((String) s);
return symbol(str(s));
}
static Symbol symbol(Object o) {
return symbol((CharSequence) o);
}
static boolean regionMatchesIC(String a, int offsetA, String b, int offsetB, int len) {
return a != null && a.regionMatches(true, offsetA, b, offsetB, len);
}
static List immutableEmptyList() {
return Collections.emptyList();
}
static short[] emptyShortArray = new short[0];
static short[] emptyShortArray() { return emptyShortArray; }
static Map immutableEmptyMap() {
return Collections.emptyMap();
}
interface IVarWithNotify extends IVar , IF0WithChangeListeners {
default IVarWithNotify onChange(IVF1 r) {
if (r == null) return this;
onChange(() -> r.get(get()));
return this;
}
default IVarWithNotify onChangeAndNow(IVF1 r) {
if (r == null) return this;
onChangeAndNow(() -> r.get(get()));
return this;
}
}
// immutable, has strong refs
// Do not run in a synchronized block - it goes wrong in the presence
// of elaborate classloaders (like in Gazelle BEA)
// see #1102990 and #1102991
final static class _MethodCache {
final Class c;
final HashMap> cache = new HashMap();
_MethodCache(Class c) {
this.c = c; _init(); }
void _init() {
Class _c = c;
java.lang.Module myModule = getClass().getModule();
boolean anyHiddenClasses = false;
while (_c != null) {
boolean exported = classIsExportedTo(_c, myModule);
if (!exported)
anyHiddenClasses = true;
else
for (Method m : _c.getDeclaredMethods())
if ((anyHiddenClasses || !isAbstract(m))
&& !reflection_isForbiddenMethod(m))
multiMapPut(cache, m.getName(), makeAccessible(m));
_c = _c.getSuperclass();
}
// add default methods - this might lead to a duplication
// because the overridden method is also added, but it's not
// a problem except for minimal performance loss.
// If any classes in the hierarchy were inaccessible, we add
// all interface methods (see test_callForbiddenMethodByReflection for a test)
for (Class intf : allInterfacesImplementedBy(c))
for (Method m : intf.getDeclaredMethods())
if ((anyHiddenClasses || m.isDefault()) && !reflection_isForbiddenMethod(m))
multiMapPut(cache, m.getName(), makeAccessible(m));
}
// Returns only matching methods
Method findMethod(String method, Object[] args) { try {
List m = cache.get(method);
if (m == null) return null;
int n = m.size();
for (int i = 0; i < n; i++) {
Method me = m.get(i);
if (call_checkArgs(me, args, false))
return me;
}
return null;
} catch (Exception __e) { throw rethrow(__e); } }
Method findStaticMethod(String method, Object[] args) { try {
List m = cache.get(method);
if (m == null) return null;
int n = m.size();
for (int i = 0; i < n; i++) {
Method me = m.get(i);
if (isStaticMethod(me) && call_checkArgs(me, args, false))
return me;
}
return null;
} catch (Exception __e) { throw rethrow(__e); } }
}
static abstract class VF1 implements IVF1 {
public abstract void get(A a);
}
// Meta - a "minimal" approach to adding meta-level to Java objects
static class Meta implements IMeta {
// Meta - a "minimal" approach to adding meta-level to Java objects
// (implementing the interface IMeta)
// We allocate one extra field for each Java object to make it
// reasoning-compatible (reasoning-compatible = extensible with
// fields of any name at runtime).
//
// We couldn't go for 0 extra fields (meta values must be linked
// directly from the object) and there are no half fields in
// Java... so there you go.
//
// Also, if you don't use any meta data, you are probably not
// reasoning about anything. The point of reasoning in JavaX is
// to attach information to objects directly used in the program.
// Possible information contained in the meta field:
// Origin, destination, security level, sender, cost center,
// purpose, list of reifications, ...
// So here it is. THE FIELD YOU HAVE BEEN WAITING FOR!
// [We also have IMeta to retrofit foreign classes (rare but
// probably useful).]
//////////////////////
// The "meta" field //
//////////////////////
// Generic meta value of any kind, but the typical case is it's a
// Map with extra field values for the object etc.
// "meta" is volatile to avoid synchronization; but you can also synchronize on
// _tempMetaMutex() which is usually the object itself. Collections
// and maps are exempt from using the collections's monitor as the meta
// mutex because their monitor tends to be held for long operations
// (e.g. cloneList). For those we use a substantially more complex
// algorithm using a weakMap. Probably overkill. I may reconsider.
volatile Object meta;
// The meta field is not transient, thus by default it will be
// persisted like anything else unless you customize your object
// to suppress or modulate this.
// ...and the interface methods
public void _setMeta(Object meta) { this.meta = meta; }
public Object _getMeta() { return meta; }
// MOST functions are implemented in IMeta (default implementations)
// Scaffolding convenience functions
final boolean scaffolding(){ return scaffoldingEnabled(); }
boolean scaffoldingEnabled() { return main.scaffoldingEnabled(this); }
boolean scaffoldingEnabled(Object o) { return main.scaffoldingEnabled(o); }
}
static class Matches {
String[] m;
Matches() {}
Matches(String... m) {
this.m = m;}
String get(int i) { return i < m.length ? m[i] : null; }
String unq(int i) { return unquote(get(i)); }
String tlc(int i) { return unq(i).toLowerCase(); }
boolean bool(int i) { return "true".equals(unq(i)); }
String rest() { return m[m.length-1]; } // for matchStart
int psi(int i) { return Integer.parseInt(unq(i)); }
public String toString() { return "Matches(" + joinWithComma(quoteAll(asList(m))) + ")"; }
public int hashCode() { return _hashCode(toList(m)); }
public boolean equals(Object o) { return o instanceof Matches && arraysEqual(m, ((Matches) o).m); }
}
// for the version with MasterSymbol (used WAY back in "Smart Bot"!) see #1010608
static class Symbol implements CharSequence {
String text;
Symbol() {}
Symbol(String text, boolean dummy) {
this.text = text;} // weird signature to prevent accidental calling
public int hashCode() { return _hashCode(text); }
public String toString() { return text; }
public boolean equals(Object o) {
return this == o;
}
// implementation of CharSequence methods
public int length() { return text.length(); }
public char charAt(int index) { return text.charAt(index); }
public CharSequence subSequence(int start, int end) {
return text.substring(start, end);
}
}
static class Var implements IVar , ISetter {
Var() {}
Var(A v) {
this.v = v;}
A v; // you can access this directly if you use one thread
public synchronized void set(A a) {
if (v != a) {
v = a;
notifyAll();
}
}
public synchronized A get() { return v; }
public synchronized boolean has() { return v != null; }
public void clear() { set(null); }
public String toString() { return str(this.get()); }
}
static interface IMeta {
// see class "Meta" for the bla bla
public void _setMeta(Object meta);
public Object _getMeta();
default public IAutoCloseableF0 _tempMetaMutex() {
return new IAutoCloseableF0() {
public Object get() { return IMeta.this; }
public void close() {}
};
}
// actually query another object
default public Object getMeta(Object obj, Object key){ return metaGet(obj, key); }
default public Object metaGet(Object obj, Object key) {
// call global function
return metaMapGet(obj, key);
}
default public Object metaGet(String key, Object obj) {
// call global function
return metaMapGet(obj, key);
}
default public Object getMeta(Object key){ return metaGet(key); }
default public Object metaGet(Object key) {
if (key == null) return null;
Object meta = _getMeta();
if (meta instanceof Map) return ((Map) meta).get(key);
return null;
}
default public void metaSet(IMeta obj, Object key, Object value){ metaPut(obj, key, value); }
default public void metaPut(IMeta obj, Object key, Object value) {
// call global function
metaMapPut(obj, key, value);
}
default public void metaSet(Object key, Object value){ metaPut(key, value); }
default public void metaPut(Object key, Object value) {
if (key == null) return;
Map map = convertObjectMetaToMap(this);
syncMapPutOrRemove(map, key, value);
}
}
// Some of the functions are dependent on the concepts field,
// others are global.
static class G22Utils {
final public G22Utils setBackgroundProcessesUI(BackgroundProcessesUI backgroundProcessesUI){ return backgroundProcessesUI(backgroundProcessesUI); }
public G22Utils backgroundProcessesUI(BackgroundProcessesUI backgroundProcessesUI) { this.backgroundProcessesUI = backgroundProcessesUI; return this; } final public BackgroundProcessesUI getBackgroundProcessesUI(){ return backgroundProcessesUI(); }
public BackgroundProcessesUI backgroundProcessesUI() { return backgroundProcessesUI; }
BackgroundProcessesUI backgroundProcessesUI;
final public G22Utils setModule(Enterable module){ return module(module); }
public G22Utils module(Enterable module) { this.module = module; return this; } final public Enterable getModule(){ return module(); }
public Enterable module() { return module; }
Enterable module;
final public G22Utils setMasterStuff(G22MasterStuff masterStuff){ return masterStuff(masterStuff); }
public G22Utils masterStuff(G22MasterStuff masterStuff) { this.masterStuff = masterStuff; return this; } final public G22MasterStuff getMasterStuff(){ return masterStuff(); }
public G22MasterStuff masterStuff() { return masterStuff; }
G22MasterStuff masterStuff;
final public G22Utils setConcepts(Concepts concepts){ return concepts(concepts); }
public G22Utils concepts(Concepts concepts) { this.concepts = concepts; return this; } final public Concepts getConcepts(){ return concepts(); }
public Concepts concepts() { return concepts; }
Concepts concepts;
final public CombinedStringifier getStringifier(){ return stringifier(); }
public CombinedStringifier stringifier() { return stringifier; }
CombinedStringifier stringifier = new CombinedStringifier(
o -> o instanceof BufferedImage ? "Image (" + ((BufferedImage) o).getWidth() + "*" + ((BufferedImage) o).getHeight() + " px)" : null
);
ImageSurface stdImageSurface() {
var is = pixelatedImageSurface().setAutoZoomToDisplay(true).repaintInThread(false);
is.specialPurposed = true;
new ImageSurface_PositionToolTip(is);
return is;
}
ImageSurface stdImageSurface(MakesBufferedImage img) { return stdImageSurface(toBufferedImage(img)); }
ImageSurface stdImageSurface(BufferedImage img) {
var is = stdImageSurface();
is.setImage(img);
return is;
}
String stringify(Object o) { return stringifier.toString(o); }
transient Set> onSettingUpParser;
public G22Utils onSettingUpParser(IVF1 f) { onSettingUpParser = createOrAddToSyncLinkedHashSet(onSettingUpParser, f); return this; }
public G22Utils removeSettingUpParserListener(IVF1 f) { main.remove(onSettingUpParser, f); return this; }
public void settingUpParser(GazelleV_LeftArrowScriptParser parser) { pcallFAll(onSettingUpParser, parser); }
GazelleV_LeftArrowScriptParser leftArrowParser() {
GazelleV_LeftArrowScriptParser parser = new GazelleV_LeftArrowScriptParser();
parser.g22utils(this);
settingUpParser(parser);
return parser;
}
void basicParserTest() {
var parser = leftArrowParser();
print("classContainerPrefixes" , parser.classContainerPrefixes());
assertEquals(pair(1, 2), parser.parse("new Pair 1 2").get());
}
File byteCodePath() {
return assertNotNull(getBytecodePathForClass(this));
}
ClassNameResolver classNameResolver_cache;
ClassNameResolver classNameResolver() { if (classNameResolver_cache == null) classNameResolver_cache = classNameResolver_load(); return classNameResolver_cache;}
ClassNameResolver classNameResolver_load() {
return new ClassNameResolver().byteCodePath(byteCodePath()).init();
}
File databasesMotherDir() {
return javaxDataDir("Gazelle-22");
}
AutoCloseable enter() { return module == null ? null : module.enter(); }
String defaultDBName() { return "Default"; }
File lastOpenedDBsFile() {
return newFile(databasesMotherDir(), "Last Opened");
}
File autoUpdateFile() {
return newFile(databasesMotherDir(), "Auto-Update");
}
boolean autoUpdateEnabled() {
return fileExists(autoUpdateFile());
}
void setAutoUpdate(boolean b) {
createOrRemoveFile(autoUpdateFile(), b);
}
List dbsToOpen() {
List dbNames = new ArrayList();
for (String name : tlft(loadTextFile(lastOpenedDBsFile())))
if (fileExists(newFile(databasesMotherDir(), name)))
dbNames.add(name);
if (empty(dbNames)) dbNames.add(defaultDBName());
return dbNames;
}
void setOpenDBs(Collection dbDirs) {
List dbNames = new ArrayList();
for (File dbDir : dbDirs)
if (sameFile(databasesMotherDir(), dirOfFile(dbDir)))
dbNames.add(fileName(dbDir));
saveTextFile(lastOpenedDBsFile(), lines(dbNames));
}
Map scriptToMap(G22LeftArrowScript c) {
return litorderedmap(
"Description" , str(c),
"Status" , renderScriptStatus(c),
"LoC" , renderScriptLoC(c));
}
String renderScriptStatus(G22LeftArrowScript c) {
return or2_rev("Empty", joinNemptiesWithSpacedPlus(
c.isClearForAutoRun() ? "Clear for auto-run" : null,
c.isSavedDistinctFromAutoRunVersion() ? "Saved (not cleared)" : null,
c.isEditing() ? "Editing" : null
));
}
String renderScriptLoC(G22LeftArrowScript c) {
return n2(intMax(mapLL(__53 -> linesOfCode_javaTok(__53),
c.editingText,
c.text,
c.codeForAutoRun())));
}
// e.g. for an image file
List labelsForFile(File file) {
if (file == null) return null;
File labelsFile = appendToFileName(file, ".labels");
List labels = tlft(loadTextFile(labelsFile));
return map(__54 -> getLabel(__54), labels);
}
File labelsFile(File file) {
if (file == null) return null;
return appendToFileName(file, ".labels");
}
void setLabelsForFile(File file, List labels) {
List list = map(labels, label -> label.name);
File f = labelsFile(file);
saveTextFile(f, lines(list));
print("Saved " + nLabels(list) + " (" + joinWithComma(list) + ") to " + f);
}
G22Label getLabel(String name) {
if (empty(name)) return null;
if (containsNewLine(name)) throw fail("No newlines in label names allowed: " + name);
return uniqCI(concepts, G22Label.class, "name", name);
}
File dbDir() { return conceptsDir(concepts); }
File fileInDbDir(String name) { return newFile(dbDir(), name); }
class GazelleDB implements IFieldsToList{
String name;
File dir;
GazelleDB() {}
GazelleDB(String name, File dir) {
this.dir = dir;
this.name = name;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + name + ", " + dir + ")"; }
public boolean equals(Object o) {
if (!(o instanceof GazelleDB)) return false;
GazelleDB __0 = (GazelleDB) o;
return eq(name, __0.name) && eq(dir, __0.dir);
}
public int hashCode() {
int h = 1669530526;
h = boostHashCombine(h, _hashCode(name));
h = boostHashCombine(h, _hashCode(dir));
return h;
}
public Object[] _fieldsToList() { return new Object[] {name, dir}; }
Boolean loaded_cache;
boolean loaded() { if (loaded_cache == null) loaded_cache = loaded_load(); return loaded_cache;}
Boolean loaded_load() {
return containsFile(masterStuff.openConceptDirs(), dir);
}
File conceptsFile() { return conceptsFileIn(dir); }
}
List gazelleDBs() {
List dbs = new ArrayList();
for (File dir : listDirsContainingFileNamed(databasesMotherDir(),
"concepts.structure.gz"))
dbs.add(new GazelleDB(fileName(dir), dir));
return dbs;
}
RSyntaxTextAreaWithSearch newSyntaxTextArea() { return newSyntaxTextArea(null); }
RSyntaxTextAreaWithSearch newSyntaxTextArea(IF1 wrapStatusLabel) {
RSyntaxTextAreaWithSearch ta = new RSyntaxTextAreaWithSearch(wrapStatusLabel);
ta.textArea().setHighlightCurrentLine(false);
ta.menuLessOperation();
return ta;
}
File projectStoryTextFile() { return newFile(dbDir(), "story.txt"); }
}
static class MultiMap {
Map > data = new HashMap >();
int fullSize;
MultiMap() {}
MultiMap(boolean useTreeMap) { if (useTreeMap) data = new TreeMap(); }
MultiMap(MultiMap map) { putAll(map); }
MultiMap(Map > data) {
this.data = data;}
void put(A key, B value) { synchronized(data) {
List list = data.get(key);
if (list == null)
data.put(key, list = _makeEmptyList());
list.add(value);
++fullSize;
}}
void add(A key, B value) { put(key, value); }
void addAll(A key, Collection values) { putAll(key, values); }
void addAllIfNotThere(A key, Collection values) { synchronized(data) {
for (B value : values)
setPut(key, value);
}}
void setPut(A key, B value) { synchronized(data) {
if (!containsPair(key, value))
put(key, value);
}}
boolean containsPair(A key, B value) { synchronized(data) {
return get(key).contains(value);
}}
void putAll(Collection keys, B value) { synchronized(data) {
for (A key : unnullForIteration(keys))
put(key, value);
}}
void putAll(A key, Collection values) { synchronized(data) {
if (nempty(values)) getActual(key).addAll(values);
}}
void putAll(Iterable> pairs) { synchronized(data) {
for (Pair p : unnullForIteration(pairs))
put(p.a, p.b);
}}
void removeAll(A key, Collection values) { synchronized(data) {
for (B value : values)
remove(key, value);
}}
List get(A key) { synchronized(data) {
List list = data.get(key);
return list == null ? Collections. emptyList() : list;
}}
List getOpt(A key) { synchronized(data) {
return data.get(key);
}}
List getAndClear(A key) { synchronized(data) {
List l = cloneList(data.get(key));
remove(key);
return l;
}}
// returns actual mutable live list
// creates the list if not there
List getActual(A key) { synchronized(data) {
List list = data.get(key);
if (list == null)
data.put(key, list = _makeEmptyList());
return list;
}}
void clean(A key) { synchronized(data) {
List list = data.get(key);
if (list != null && list.isEmpty()) {
fullSize -= l(list);
data.remove(key);
}
}}
Set keySet() { synchronized(data) {
return data.keySet();
}}
Set keys() { synchronized(data) {
return data.keySet();
}}
void remove(A key) { synchronized(data) {
fullSize -= l(this.getOpt(key));
data.remove(key);
}}
final void remove(Pair p){ removePair(p); }
void removePair(Pair p) {
if (p != null) remove(p.a, p.b);
}
void remove(A key, B value) { synchronized(data) {
List list = data.get(key);
if (list != null) {
if (list.remove(value))
fullSize--;
if (list.isEmpty())
data.remove(key);
}
}}
void clear() { synchronized(data) {
data.clear();
}}
boolean containsKey(A key) { synchronized(data) {
return data.containsKey(key);
}}
B getFirst(A key) { synchronized(data) {
List list = get(key);
return list.isEmpty() ? null : list.get(0);
}}
void addAll(MultiMap map) { putAll(map); }
void putAll(MultiMap map) { synchronized(data) {
for (A key : map.keySet())
putAll(key, map.get(key));
}}
void putAll(Map map) { synchronized(data) {
if (map != null) for (Map.Entry e : map.entrySet())
put(e.getKey(), e.getValue());
}}
final int keyCount(){ return keysSize(); }
int keysSize() { synchronized(data) { return l(data); }}
// full size - note: expensive operation
final int fullSize(){ return size(); }
int size() { synchronized(data) {
return fullSize;
}}
// expensive operation
List reverseGet(B b) { synchronized(data) {
List l = new ArrayList();
for (A key : data.keySet())
if (data.get(key).contains(b))
l.add(key);
return l;
}}
Map > asMap() { synchronized(data) {
return cloneMap(data);
}}
boolean isEmpty() { synchronized(data) { return data.isEmpty(); }}
// override in subclasses
List _makeEmptyList() {
return new ArrayList();
}
// returns live lists
Collection> allLists() {
synchronized(data) {
return new ArrayList(data.values());
}
}
Collection> values() { return allLists(); }
List allValues() {
return concatLists(data.values());
}
Object mutex() { return data; }
public String toString() { return "mm" + str(data); }
}
/*
* @(#)WeakHashMap.java 1.5 98/09/30
*
* Copyright 1998 by Sun Microsystems, Inc.,
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Sun Microsystems, Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Sun.
*/
// From https://github.com/mernst/plume-lib/blob/df0bfafc3c16848d88f4ea0ef3c8bf3367ae085e/java/src/plume/WeakHasherMap.java
static final class WeakHasherMap extends AbstractMap implements Map {
private Hasher hasher = null;
/*@Pure*/
private boolean keyEquals(Object k1, Object k2) {
return (hasher==null ? k1.equals(k2)
: hasher.equals(k1, k2));
}
/*@Pure*/
private int keyHashCode(Object k1) {
return (hasher==null ? k1.hashCode()
: hasher.hashCode(k1));
}
// The WeakKey class can't be static because it depends on the hasher.
// That in turn means that its methods can't be static.
// However, I need to be able to call the methods such as create() that
// were static in the original version of this code.
// This finesses that.
private /*@Nullable*/ WeakKey WeakKeyCreate(K k) {
if (k == null) return null;
else return new WeakKey(k);
}
private /*@Nullable*/ WeakKey WeakKeyCreate(K k, ReferenceQueue super K> q) {
if (k == null) return null;
else return new WeakKey(k, q);
}
// Cannot be a static class: uses keyHashCode() and keyEquals()
private final class WeakKey extends WeakReference {
private int hash; /* Hashcode of key, stored here since the key
may be tossed by the GC */
private WeakKey(K k) {
super(k);
hash = keyHashCode(k);
}
private /*@Nullable*/ WeakKey create(K k) {
if (k == null) return null;
else return new WeakKey(k);
}
private WeakKey(K k, ReferenceQueue super K> q) {
super(k, q);
hash = keyHashCode(k);
}
private /*@Nullable*/ WeakKey create(K k, ReferenceQueue super K> q) {
if (k == null) return null;
else return new WeakKey(k, q);
}
/* A WeakKey is equal to another WeakKey iff they both refer to objects
that are, in turn, equal according to their own equals methods */
/*@Pure*/
@Override
public boolean equals(/*@Nullable*/ Object o) {
if (o == null) return false; // never happens
if (this == o) return true;
// This test is illegal because WeakKey is a generic type,
// so use the getClass hack below instead.
// if (!(o instanceof WeakKey)) return false;
if (!(o.getClass().equals(WeakKey.class))) return false;
Object t = this.get();
@SuppressWarnings("unchecked")
Object u = ((WeakKey)o).get();
if ((t == null) || (u == null)) return false;
if (t == u) return true;
return keyEquals(t, u);
}
/*@Pure*/
@Override
public int hashCode() {
return hash;
}
}
/* Hash table mapping WeakKeys to values */
private HashMap hash;
/* Reference queue for cleared WeakKeys */
private ReferenceQueue super K> queue = new ReferenceQueue();
/* Remove all invalidated entries from the map, that is, remove all entries
whose keys have been discarded. This method should be invoked once by
each public mutator in this class. We don't invoke this method in
public accessors because that can lead to surprising
ConcurrentModificationExceptions. */
@SuppressWarnings("unchecked")
private void processQueue() {
WeakKey wk;
while ((wk = (WeakKey)queue.poll()) != null) { // unchecked cast
hash.remove(wk);
}
}
/* -- Constructors -- */
/**
* Constructs a new, empty WeakHashMap with the given
* initial capacity and the given load factor.
*
* @param initialCapacity the initial capacity of the
* WeakHashMap
*
* @param loadFactor the load factor of the WeakHashMap
*
* @throws IllegalArgumentException If the initial capacity is less than
* zero, or if the load factor is
* nonpositive
*/
public WeakHasherMap(int initialCapacity, float loadFactor) {
hash = new HashMap(initialCapacity, loadFactor);
}
/**
* Constructs a new, empty WeakHashMap with the given
* initial capacity and the default load factor, which is
* 0.75.
*
* @param initialCapacity the initial capacity of the
* WeakHashMap
*
* @throws IllegalArgumentException If the initial capacity is less than
* zero
*/
public WeakHasherMap(int initialCapacity) {
hash = new HashMap(initialCapacity);
}
/**
* Constructs a new, empty WeakHashMap with the default
* capacity and the default load factor, which is 0.75.
*/
public WeakHasherMap() {
hash = new HashMap();
}
/**
* Constructs a new, empty WeakHashMap with the default
* capacity and the default load factor, which is 0.75.
* The WeakHashMap uses the specified hasher for hashing
* keys and comparing them for equality.
* @param h the Hasher to use when hashing values for this map
*/
public WeakHasherMap(Hasher h) {
hash = new HashMap();
hasher = h;
}
/* -- Simple queries -- */
/**
* Returns the number of key-value mappings in this map.
* Note: In contrast to most implementations of the
* Map interface, the time required by this operation is
* linear in the size of the map.
*/
/*@Pure*/
@Override
public int size() {
return entrySet().size();
}
/**
* Returns true if this map contains no key-value mappings.
*/
/*@Pure*/
@Override
public boolean isEmpty() {
return entrySet().isEmpty();
}
/**
* Returns true if this map contains a mapping for the
* specified key.
*
* @param key the key whose presence in this map is to be tested
*/
/*@Pure*/
@Override
public boolean containsKey(Object key) {
@SuppressWarnings("unchecked")
K kkey = (K) key;
return hash.containsKey(WeakKeyCreate(kkey));
}
/* -- Lookup and modification operations -- */
/**
* Returns the value to which this map maps the specified key.
* If this map does not contain a value for this key, then return
* null.
*
* @param key the key whose associated value, if any, is to be returned
*/
/*@Pure*/
@Override
public /*@Nullable*/ V get(Object key) { // type of argument is Object, not K
@SuppressWarnings("unchecked")
K kkey = (K) key;
return hash.get(WeakKeyCreate(kkey));
}
/**
* Updates this map so that the given key maps to the given
* value. If the map previously contained a mapping for
* key then that mapping is replaced and the previous value is
* returned.
*
* @param key the key that is to be mapped to the given
* value
* @param value the value to which the given key is to be
* mapped
*
* @return the previous value to which this key was mapped, or
* null if if there was no mapping for the key
*/
@Override
public V put(K key, V value) {
processQueue();
return hash.put(WeakKeyCreate(key, queue), value);
}
/**
* Removes the mapping for the given key from this map, if
* present.
*
* @param key the key whose mapping is to be removed
*
* @return the value to which this key was mapped, or null if
* there was no mapping for the key
*/
@Override
public V remove(Object key) { // type of argument is Object, not K
processQueue();
@SuppressWarnings("unchecked")
K kkey = (K) key;
return hash.remove(WeakKeyCreate(kkey));
}
/**
* Removes all mappings from this map.
*/
@Override
public void clear() {
processQueue();
hash.clear();
}
/* -- Views -- */
/* Internal class for entries */
// This can't be static, again because of dependence on hasher.
@SuppressWarnings("TypeParameterShadowing")
private final class Entry implements Map.Entry {
private Map.Entry ent;
private K key; /* Strong reference to key, so that the GC
will leave it alone as long as this Entry
exists */
Entry(Map.Entry ent, K key) {
this.ent = ent;
this.key = key;
}
/*@Pure*/
@Override
public K getKey() {
return key;
}
/*@Pure*/
@Override
public V getValue() {
return ent.getValue();
}
@Override
public V setValue(V value) {
return ent.setValue(value);
}
/*@Pure*/
private boolean keyvalEquals(K o1, K o2) {
return (o1 == null) ? (o2 == null) : keyEquals(o1, o2);
}
/*@Pure*/
private boolean valEquals(V o1, V o2) {
return (o1 == null) ? (o2 == null) : o1.equals(o2);
}
/*@Pure*/
@SuppressWarnings("NonOverridingEquals")
public boolean equals(Map.Entry e /* Object o*/) {
// if (! (o instanceof Map.Entry)) return false;
// Map.Entry e = (Map.Entry)o;
return (keyvalEquals(key, e.getKey())
&& valEquals(getValue(), e.getValue()));
}
/*@Pure*/
@Override
public int hashCode() {
V v;
return (((key == null) ? 0 : keyHashCode(key))
^ (((v = getValue()) == null) ? 0 : v.hashCode()));
}
}
/* Internal class for entry sets */
private final class EntrySet extends AbstractSet> {
Set> hashEntrySet = hash.entrySet();
@Override
public Iterator> iterator() {
return new Iterator>() {
Iterator> hashIterator = hashEntrySet.iterator();
Map.Entry next = null;
@Override
public boolean hasNext() {
while (hashIterator.hasNext()) {
Map.Entry ent = hashIterator.next();
WeakKey wk = ent.getKey();
K k = null;
if ((wk != null) && ((k = wk.get()) == null)) {
/* Weak key has been cleared by GC */
continue;
}
next = new Entry(ent, k);
return true;
}
return false;
}
@Override
public Map.Entry next() {
if ((next == null) && !hasNext())
throw new NoSuchElementException();
Map.Entry e = next;
next = null;
return e;
}
@Override
public void remove() {
hashIterator.remove();
}
};
}
/*@Pure*/
@Override
public boolean isEmpty() {
return !(iterator().hasNext());
}
/*@Pure*/
@Override
public int size() {
int j = 0;
for (Iterator> i = iterator(); i.hasNext(); i.next()) j++;
return j;
}
@Override
public boolean remove(Object o) {
processQueue();
if (!(o instanceof Map.Entry,?>)) return false;
@SuppressWarnings("unchecked")
Map.Entry e = (Map.Entry)o; // unchecked cast
Object ev = e.getValue();
WeakKey wk = WeakKeyCreate(e.getKey());
Object hv = hash.get(wk);
if ((hv == null)
? ((ev == null) && hash.containsKey(wk)) : hv.equals(ev)) {
hash.remove(wk);
return true;
}
return false;
}
/*@Pure*/
@Override
public int hashCode() {
int h = 0;
for (Iterator> i = hashEntrySet.iterator(); i.hasNext(); ) {
Map.Entry ent = i.next();
WeakKey wk = ent.getKey();
Object v;
if (wk == null) continue;
h += (wk.hashCode()
^ (((v = ent.getValue()) == null) ? 0 : v.hashCode()));
}
return h;
}
}
private /*@Nullable*/ Set> entrySet = null;
/**
* Returns a Set view of the mappings in this map.
*/
/*@SideEffectFree*/
@Override
public Set> entrySet() {
if (entrySet == null) entrySet = new EntrySet();
return entrySet;
}
// find matching key
K findKey(Object key) {
processQueue();
K kkey = (K) key;
// TODO: use replacement for HashMap to avoid reflection
WeakKey wkey = WeakKeyCreate(kkey);
WeakKey found = hashMap_findKey(hash, wkey);
return found == null ? null : found.get();
}
}
static class SingleComponentPanel extends JPanel {
SingleComponentPanel() { super(new BorderLayout()); }
SingleComponentPanel(Component component) {
this();
if (component != null) setComponent(component);
}
void set(Swingable component) {
set(wrap(component));
}
final void set(Component component){ setComponent(component); }
void setComponent(Component component) {
{ swing(() -> {
if (getComponent() == component) return;
removeAll();
if (component != null)
add(BorderLayout.CENTER, wrap(component));
_revalidate(SingleComponentPanel.this);
}); }
}
// Sometimes we need this?
void setComponentAndRevalidateParent(Component component) {
setComponent(component);
_revalidate(_getParent(this));
}
final void clear(){ noComponent(); }
void noComponent() { setComponent(null); }
Component getComponent() {
return swing( () -> getComponentCount() == 0 ? null : getComponent(0));
}
boolean isEmpty() { return getComponent() == null; }
}
static class TypedVirtualVar extends VirtualVar {
Class type;
TypedVirtualVar(Class type, IF0 getter, IVF1 setter) {
this.setter = setter;
this.getter = getter;
this.type = type;}
public Class getType() { return type; }
}
static class Fail extends RuntimeException implements IFieldsToList{
Object[] objects;
Fail() {}
Fail(Object... objects) {
this.objects = objects;}public Object[] _fieldsToList() { return new Object[] {objects}; }
Fail(Throwable cause, Object... objects) {
super(cause);
this.objects = objects;
}
public String toString() { return joinNemptiesWithColon("Fail", commaCombine(getCause(), objects)); }
}
static class Pair implements Comparable> {
A a;
B b;
Pair() {}
Pair(A a, B b) {
this.b = b;
this.a = a;}
public int hashCode() {
return hashCodeFor(a) + 2*hashCodeFor(b);
}
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Pair)) return false;
Pair t = (Pair) o;
return eq(a, t.a) && eq(b, t.b);
}
public String toString() {
return "<" + a + ", " + b + ">";
}
public int compareTo(Pair p) {
if (p == null) return 1;
int i = ((Comparable ) a).compareTo(p.a);
if (i != 0) return i;
return ((Comparable) b).compareTo(p.b);
}
}
static abstract class F0 {
abstract A get();
}
static abstract class F1 {
abstract B get(A a);
}
// you still need to implement hasNext() and next()
static abstract class IterableIterator implements Iterator , Iterable {
public Iterator iterator() {
return this;
}
public void remove() {
unsupportedOperation();
}
}
public static interface IF0 {
A get();
}
static interface Hasher {
int hashCode(A a);
boolean equals(A a, A b);
}
static interface IFieldsToList {
Object[] _fieldsToList();
}
static interface IF1 {
B get(A a);
}
static class JTextFileEditor implements Swingable , IFieldsToList{
File file;
JTextFileEditor() {}
JTextFileEditor(File file) {
this.file = file;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + file + ")"; }public Object[] _fieldsToList() { return new Object[] {file}; }
final public JTextFileEditor setAutoSave(boolean autoSave){ return autoSave(autoSave); }
public JTextFileEditor autoSave(boolean autoSave) { this.autoSave = autoSave; return this; } final public boolean getAutoSave(){ return autoSave(); }
public boolean autoSave() { return autoSave; }
boolean autoSave = false;
final public JTextArea getTextArea(){ return textArea(); }
public JTextArea textArea() { return textArea; }
JTextArea textArea;
JButton btnReload, btnSave;
JLabel lblChanged;
volatile String fileContents, savedText;
FileWatchService fileWatcher;
Q q = startQ();
RSTOverQ rstLoad = rstWithPreDelay(0.5, q, new Runnable() { public void run() { try { _load();
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_load();"; }});
RSTOverQ rstSave;
public transient JComponent visualize_cache;
public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache;}
public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); }
JComponent visualize_impl() {
assertNotNull(file);
rstSave = rstWithPreDelay(autoSave ? 0.5 : 0.0, q, new Runnable() { public void run() { try { _save();
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_save();"; }});
savedText = fileContents = loadTextFile(file);
textArea = makeTextArea();
setText(savedText);
onChange(textArea, () -> {
updateButtons();
if (autoSave) rstSave.get();
});
bindToComponent(textArea, () -> {
fileWatcher = new FileWatchService();
fileWatcher.addNonRecursiveListener(dirOfFile(file),
f -> { if (sameFile(f, file)) rstLoad.get(); });
rstLoad.get();
}, () -> { { cleanUp(fileWatcher); fileWatcher = null; } });
return northAndCenter(
withSideMargin(centerAndEastWithMargin(
new JFilePathLabel(file).iconOnTheLeft(true).visualize(),
jline(
autoSave
? (lblChanged = jlabel())
: (btnSave = disableButton(jbutton("Save", rstSave))),
btnReload = jbutton("Reload", new Runnable() { public void run() { try { reload();
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "reload();"; }})
))),
withMargin(textArea)
);
}
void updateButtons() {
boolean changed = !eq(savedText, getText(textArea));
setEnabled(btnSave, changed);
setEnabled(btnReload, !eq(fileContents, savedText));
main.setText(lblChanged, changed ? "*" : "");
}
void _save() {
saveTextFileVerbose(file, savedText = getText(textArea));
}
void reload() {
savedText = fileContents;
setText(savedText);
updateButtons();
}
void _load() {
print("Loading " + file);
fileContents = loadTextFile(file);
updateButtons();
}
transient IF0 makeTextArea;
JTextArea makeTextArea() { return makeTextArea != null ? makeTextArea.get() : makeTextArea_base(); }
final JTextArea makeTextArea_fallback(IF0 _f) { return _f != null ? _f.get() : makeTextArea_base(); }
JTextArea makeTextArea_base() {
return wordWrapTypeWriterTextArea();
}
void setText(String text) {
main.setText(textArea(), text);
}
}
static class PersistableThrowable extends DynamicObject {
String className;
String msg;
String stacktrace;
PersistableThrowable() {}
PersistableThrowable(Throwable e) {
if (e == null)
className = "Crazy Null Error";
else {
className = getClassName(e).replace('/', '.');
msg = e.getMessage();
stacktrace = getStackTrace_noRecord(e);
}
}
public String toString() {
return nempty(msg) ? className + ": " + msg : className;
}
RuntimeException asRuntimeException() {
return new Fail(this);
}
}
static interface IVF1 {
void get(A a);
}
static interface Swingable {
JComponent visualize();
}
interface Enterable {
AutoCloseable enter();
}
static class BackgroundProcessesUI {
Set processes = setWithNotify(syncLinkedHashSet(), () -> updateCount());
SimpleLiveValue lvCount = new SimpleLiveValue(Integer.class, 0);
class Entry implements AutoCloseable , IFieldsToList{
String name;
Entry() {}
Entry(String name) {
this.name = name;}
public boolean equals(Object o) {
if (!(o instanceof Entry)) return false;
Entry __0 = (Entry) o;
return eq(name, __0.name);
}
public int hashCode() {
int h = 67115090;
h = boostHashCombine(h, _hashCode(name));
return h;
}
public Object[] _fieldsToList() { return new Object[] {name}; }
final public Entry setMenuItem(JMenuItem menuItem){ return menuItem(menuItem); }
public Entry menuItem(JMenuItem menuItem) { this.menuItem = menuItem; return this; } final public JMenuItem getMenuItem(){ return menuItem(); }
public JMenuItem menuItem() { return menuItem; }
JMenuItem menuItem;
public String toString() { return name; }
public void close() { try { processes.remove(this); } catch (Exception __e) { throw rethrow(__e); } }
}
JLabel shortLabel() {
var lbl = bindToolTipToTransformedLiveValue(
n -> makeToolTip(), lvCount,
simpleTransformedLiveValueLabel(n -> n2(n), lvCount));
onMouseDown_anyButton(lbl, e -> {
var l = cloneList(processes);
// make sure title is displayed fully
JPopupMenu menu = new JPopupMenu();/* {
public Dimension getMinimumSize() {
TitledBorder border = optCast TitledBorder(getBorder());
_print(+border);
ret maxDimension(super.getMinimumSize(), border?.getMinimumSize(this));
}
};*/
int n = componentCount(menu);
for (Entry a : l)
addMenuItem(menu, processToMenuItem(a));
if (componentCount(menu) != n) {
var border = jRaisedSectionBorder("Background Processes");
setBorder(menu, border);
showPopupMenu(menu, e);
var size = menu.getSize();
var borderSize = dimensionPlus(10 /* hack */, 0, border.getMinimumSize(menu));
printVars("size", size, "borderSize", borderSize);
menu.setPopupSize(maxDimension(size, borderSize));
}
});
return lbl;
}
void add(Entry process) {
processes.add(process);
}
void remove(Entry process) {
processes.remove(process);
}
void addOrRemove(boolean add, Entry process) {
if (add) add(process); else remove(process);
}
Entry tempAdd(String name) {
return tempAdd(new Entry(or2(name, "Unnamed process")));
}
Entry tempAdd(Entry process) {
if (process == null) return null;
processes.add(process);
return process;
}
void updateCount() {
lvCount.set(l(processes));
}
String makeToolTip() {
var l = cloneList(processes);
return empty(l) ? "No background processes"
: n2(l, "background process", "background processes")
+ ": " + joinWithComma(processes);
}
transient IF1 processToMenuItem;
JMenuItem processToMenuItem(Entry process) { return processToMenuItem != null ? processToMenuItem.get(process) : processToMenuItem_base(process); }
final JMenuItem processToMenuItem_fallback(IF1 _f, Entry process) { return _f != null ? _f.get(process) : processToMenuItem_base(process); }
JMenuItem processToMenuItem_base(Entry process) {
return process.getMenuItem();
}
}
static interface ISetter {
void set(A a);
}
interface IF0WithChangeListeners extends IF0 , IHasChangeListeners {}
// takes ~70 ms to set up, do it only once if possible
static class ClassNameResolver {
final public ClassNameResolver setByteCodePath(File byteCodePath){ return byteCodePath(byteCodePath); }
public ClassNameResolver byteCodePath(File byteCodePath) { this.byteCodePath = byteCodePath; return this; } final public File getByteCodePath(){ return byteCodePath(); }
public File byteCodePath() { return byteCodePath; }
File byteCodePath = byteCodePathForClass(getClass());
List importedPackages = itemPlusList("java.lang",
endingWith_dropSuffix(standardImports(), ".*"));
Set allFullyQualifiedClassNames_cache;
Set allFullyQualifiedClassNames() { if (allFullyQualifiedClassNames_cache == null) allFullyQualifiedClassNames_cache = allFullyQualifiedClassNames_load(); return allFullyQualifiedClassNames_cache;}
Set allFullyQualifiedClassNames_load() {
Set set = new HashSet();
assertNotNull(byteCodePath);
set.addAll(classNamesInJarOrDir(byteCodePath));
printVars("ClassNameResolver", "byteCodePath", byteCodePath, "classesFound" , l(set));
set.addAll(classNamesInLoadedJigsawModules());
return set;
}
ClassNameResolver init() { allFullyQualifiedClassNames(); return this; }
String findClass(String name) {
for (String pkg : importedPackages) {
String fullName = pkg + "." + name;
if (allFullyQualifiedClassNames().contains(fullName))
return fullName;
}
return null;
}
void printMe() {
printVars("ClassNameResolver", "byteCodePath", byteCodePath);
print("importedPackages", importedPackages);
}
}
static class RSTOverQ implements Runnable {
boolean _isTransient() { return true; }
Runnable runnable;
Q q = startQ();
F0 enter; // optional ownership marker, e.g. for DynModules
boolean trigger, running;
RSTOverQ(Runnable runnable) {
this.runnable = runnable;}
RSTOverQ(Runnable runnable, Q q) {
this.q = q;
this.runnable = runnable; assertNotNull(q); }
RSTOverQ(Q q, Runnable runnable) { this(runnable, q); }
void trigger() { go(); }
synchronized void go() {
if (trigger) return;
trigger = true;
q.add(new Runnable() { public void run() { try { _run();
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_run();"; }});
}
public void run() { go(); }
void get() { go(); } // so you can use the ! syntax
synchronized boolean running() { return running; }
void _run() {
synchronized(this) {
if (!trigger)
return;
running = true;
trigger = false;
}
try {
AutoCloseable __1 = callF(enter); try {
pcallF(runnable);
} finally { _close(__1); }} finally {
synchronized(this) {
running = false;
}
}
}
synchronized boolean triggered() { return trigger; }
void waitUntilDone() {
while (running()) sleep(1);
}
String stats() { return renderVars("trigger", trigger, "running", running, "q", q, "runnable", runnable); }
}
static interface IAutoCloseableF0 extends IF0 , AutoCloseable {}
static class ImageSurface extends Surface {
BufferedImage image;
double zoomX = 1, zoomY = 1, zoomFactor = 1.5;
private Rectangle selection;
List tools = new ArrayList();
// use overlays now
Object overlay; // voidfunc(Graphics2D)
List overlays = syncL();
Runnable onSelectionChange;
final public ImageSurface setVerbose(boolean verbose){ return verbose(verbose); }
public ImageSurface verbose(boolean verbose) { this.verbose = verbose; return this; } final public boolean getVerbose(){ return verbose(); }
public boolean verbose() { return verbose; }
boolean verbose = false;
boolean noMinimumSize = true;
String titleForUpload;
Object onZoom;
boolean specialPurposed = false; // true = don't show image changing commands in popup menu
final public ImageSurface setZoomable(boolean zoomable){ return zoomable(zoomable); }
public ImageSurface zoomable(boolean zoomable) { this.zoomable = zoomable; return this; } final public boolean getZoomable(){ return zoomable(); }
public boolean zoomable() { return zoomable; }
boolean zoomable = true;
boolean noAlpha = false; // set to true to speed up drawing if you don't use alpha
Object interpolationMode = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
Object onNewImage;
BufferedImage imageToDraw; // if you want to draw a different image
File file; // where image was loaded from
boolean autoZoomToDisplay = false; // only works 100% when not in scrollpane
final public ImageSurface setRepaintInThread(boolean repaintInThread){ return repaintInThread(repaintInThread); }
public ImageSurface repaintInThread(boolean repaintInThread) { this.repaintInThread = repaintInThread; return this; } final public boolean getRepaintInThread(){ return repaintInThread(); }
public boolean repaintInThread() { return repaintInThread; }
boolean repaintInThread = false; // after setImage, repaint in same thread
BoolVar showingVar;
Pt mousePosition;
transient Set onMousePositionChanged;
public ImageSurface onMousePositionChanged(Runnable r) { onMousePositionChanged = createOrAddToSyncLinkedHashSet(onMousePositionChanged, r); return this; }
public ImageSurface removeMousePositionChangedListener(Runnable r) { main.remove(onMousePositionChanged, r); return this; }
public void mousePositionChanged() { pcallFAll(onMousePositionChanged); }
public ImageSurface() {
this(dummyImage());
}
static BufferedImage dummyImage() {
return whiteImage(1);
}
ImageSurface(MakesBufferedImage image) {
this(image != null ? image.getBufferedImage() : dummyImage());
}
ImageSurface(BufferedImage image) {
setImage(image);
clearSurface = false;
onResize(this, () -> performAutoZoom());
bindToComponent(this, () -> performAutoZoom(), null);
componentPopupMenu2(this, ImageSurface_popupMenuMaker());
new ImageSurfaceSelector(this);
jHandleFileDrop(this, new VF1() { public void get(File f) { try { setImage(loadBufferedImage(f)) ; } catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "setImage(loadBufferedImage(f))"; }});
imageSurfaceOnHover(this, p -> {
mousePosition = p;
mousePositionChanged();
});
}
public ImageSurface(RGBImage image, double zoom) {
this(image);
setZoom(zoom);
}
// point is already in image coordinates
protected void fillPopupMenu(JPopupMenu menu, final Point point) {
if (zoomable) {
JMenuItem miZoomReset = new JMenuItem("Zoom 100%");
miZoomReset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
setZoom(1.0);
centerPoint(point);
}
});
menu.add(miZoomReset);
JMenuItem miZoomIn = new JMenuItem("Zoom in");
miZoomIn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
zoomIn(zoomFactor);
centerPoint(point);
}
});
menu.add(miZoomIn);
JMenuItem miZoomOut = new JMenuItem("Zoom out");
miZoomOut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
zoomOut(zoomFactor);
centerPoint(point);
}
});
menu.add(miZoomOut);
/*JMenuItem miZoomToWindow = new JMenuItem("Zoom to window");
miZoomToWindow.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
zoomToDisplaySize();
}
});
menu.add(miZoomToWindow);*/
menu.add(jCheckBoxMenuItem_dyn(/*"Auto-zoom to window"*/"Zoom to window",
() -> autoZoomToDisplay,
b -> { setAutoZoomToDisplay(b); }));
addMenuItem(menu, "Show full screen", new Runnable() { public void run() { try { showFullScreen() ;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showFullScreen()"; }});
addMenuItem(menu, "Point: " + point.x + "," + point.y + " (image: " + w() + "*" + h() + ")", null);
menu.addSeparator();
}
if (!specialPurposed)
addMenuItem(menu, "Load image...", new Runnable() { public void run() { try { selectFile("Load image",
new VF1() { public void get(File f) { try { setImage(loadImage2(f)) ; } catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "setImage(loadImage2(f))"; }}) ;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "selectFile(\"Load image\",\r\n new VF1() { public void get(File f) c..."; }});
addMenuItem(menu, "Save image...", new Runnable() { public void run() { try { saveImage() ;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "saveImage()"; }});
addMenuItem(menu, "Upload image...", new Runnable() { public void run() { try { uploadTheImage() ;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "uploadTheImage()"; }});
addMenuItem(menu, "Copy image to clipboard", new Runnable() { public void run() { try { copyImageToClipboard(getImage()) ;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "copyImageToClipboard(getImage())"; }});
if (!specialPurposed) {
addMenuItem(menu, "Paste image from clipboard", new Runnable() { public void run() { try { loadFromClipboard() ;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "loadFromClipboard()"; }});
addMenuItem(menu, "Load image snippet...", new Runnable() { public void run() { try {
selectImageSnippet(new VF1() { public void get(String imageID) { try {
setImage(loadImage2(imageID))
; } catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "setImage(loadImage2(imageID))"; }});
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "selectImageSnippet(new VF1() { public void get(String imageID) ctex {..."; }});
}
if (selection != null)
addMenuItem(menu, "Crop", new Runnable() { public void run() { try { crop() ;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "crop()"; }});
if (!specialPurposed)
addMenuItem(menu, "No image", new Runnable() { public void run() { try { noImage() ;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "noImage()"; }});
}
void noImage() { setImage((BufferedImage) null); }
void crop() {
if (selection == null) return;
BufferedImage img = cloneClipBufferedImage(getImage(), selection);
selection = null;
setImage(img);
}
void loadFromClipboard() {
BufferedImage img = getImageFromClipboard();
if (img != null)
setImage(img);
}
void saveImage() {
var image = getImage();
JFileChooser fileChooser = new JFileChooser(getProgramDir());
if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
try {
main.saveImage(image, file = fileChooser.getSelectedFile());
} catch (Throwable e) {
popup(e);
}
}
}
void drawImageItself(int w, int h, Graphics2D g) {
int iw = getZoomedWidth(), ih = getZoomedHeight();
if (interpolationMode == RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR || zoomX >= 1 || zoomY >= 1) {
// faster
g.drawImage(image, 0, 0, iw, ih, null);
} else
g.drawImage(resizeImage(image, iw, ih), 0, 0, null); // smoother
}
public void render(int w, int h, Graphics2D g) {
if (verbose) _print("render");
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolationMode);
g.setColor(Color.white);
BufferedImage image = or(imageToDraw, this.image);
if (!hasImage())
g.fillRect(0, 0, w, h);
else {
boolean alpha = !noAlpha && hasTransparency(image);
if (alpha) g.fillRect(0, 0, w, h);
drawImageItself(w, h, g);
int iw = getZoomedWidth(), ih = getZoomedHeight();
if (!alpha) {
g.fillRect(iw, 0, w-iw, h);
g.fillRect(0, ih, iw, h-ih);
}
}
if (overlay != null) {
if (verbose) _print("render overlay");
pcallF(overlay, g);
}
for (var overlay : cloneList(overlays)) { try {
overlay.drawOn(g);
} catch (Throwable __e) { printStackTrace(__e); }}
if (selection != null) {
if (verbose) _print("render selection");
// drawRect is inclusive, selection is exclusive, so... whatever, tests show it's cool.
drawSelectionRect(g, selection, Color.green, Color.white);
}
}
public void drawSelectionRect(Graphics2D g, Rectangle selection, Color green, Color white) {
drawSelectionRect(g, selection, green, white, zoomX, zoomY);
}
public void drawSelectionRect(Graphics2D g, Rectangle selection, Color green, Color white, double zoomX, double zoomY) {
g.setColor(green);
int top = (int) (selection.y * zoomY);
int bottom = (int) ((selection.y+selection.height) * zoomY);
int left = (int) (selection.x * zoomX);
int right = (int) ((selection.x+selection.width) * zoomX);
g.drawRect(left-1, top-1, right-left+1, bottom-top+1);
g.setColor(white);
g.drawRect(left - 2, top - 2, right - left + 3, bottom - top + 3);
}
public ImageSurface setZoom(double zoom) {
setZoom(zoom, zoom);
return this;
}
public void setZoom(double zoomX, double zoomY) {
autoZoomToDisplay = false;
setZoom_dontChangeAutoZoom(zoomX, zoomY);
}
public void setZoom_dontChangeAutoZoom(double zoomX) { setZoom_dontChangeAutoZoom(zoomX, zoomX); }
public void setZoom_dontChangeAutoZoom(double zoomX, double zoomY) {
if (this.zoomX == zoomX && this.zoomY == zoomY) return;
if (verbose) _print("Setting zoom");
this.zoomX = zoomX;
this.zoomY = zoomY;
revalidateMe();
repaint();
centerPoint(new Point(getImage().getWidth()/2, getImage().getHeight()/2));
pcallF(onZoom);
}
public Dimension getMinimumSize() {
if (metaGet("scaffolding") != null) scaffoldCalled(this, "getMinimumSize");
if (noMinimumSize) return new Dimension(1, 1);
int w = getZoomedWidth();
int h = getZoomedHeight();
Dimension min = super.getMinimumSize();
return printIfScaffoldingEnabled(this, new Dimension(Math.max(w, min.width), Math.max(h, min.height)));
}
int getZoomedHeight() {
return (int) (h() * zoomY);
}
int getZoomedWidth() {
return (int) (w() * zoomX);
}
boolean isShowing_quick() {
if (showingVar == null) { swing(() -> {
if (showingVar == null) showingVar = componentShowingVar(ImageSurface.this);
}); }
return showingVar.get();
}
public void setImageIfShowing_thisThread(MakesBufferedImage image) { setImageIfShowing_thisThread(toBufferedImage(image)); }
public void setImageIfShowing_thisThread(BufferedImage image) {
if (isShowing_quick())
setImage_thisThread(image);
}
public void setImage(MakesBufferedImage image) { swing(() -> {
setImage_thisThread(image);
}); }
public void setImage(BufferedImage img) { swing(() -> {
setImage_thisThread(img);
}); }
public void setImage_thisThread(MakesBufferedImage img) { setImage_thisThread(toBufferedImage(img)); }
public void setImage_thisThread(BufferedImage img) {
BufferedImage newImage = img != null ? img : dummyImage();
BufferedImage oldImage = image;
image = newImage;
if (verbose) print("Old image size:" + imageSize(oldImage) + ", new image size: " + imageSize(newImage));
boolean sameSize = !imagesHaveSameSize(oldImage, newImage);
if (!sameSize) {
if (verbose) _print("New image size");
revalidateMe();
}
quickRepaint();
pcallF(onNewImage);
if (!sameSize && autoZoomToDisplay) zoomToDisplaySize();
}
void setImageAndZoomToDisplay(BufferedImage img) {
setImage(img);
zoomToDisplaySize();
}
public BufferedImage getImage() {
return image;
}
public double getZoomX() {
return zoomX;
}
public double getZoomY() {
return zoomY;
}
public Dimension getPreferredSize() {
if (metaGet("scaffolding") != null) scaffoldCalled(this, "getPreferredSize");
return printIfScaffoldingEnabled(this, new Dimension(getZoomedWidth(), getZoomedHeight()));
}
/** returns a scrollpane with the scroll-mode prevent-garbage-drawing fix applied */
public JScrollPane makeScrollPane() {
JScrollPane scrollPane = new JScrollPane(this);
scrollPane.getViewport().setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
return scrollPane;
}
public void zoomToWindow() { zoomToDisplaySize(); }
public void zoomToDisplaySize() { swing(() -> {
if (!hasImage()) return;
Dimension display = getDisplaySize();
if (display.width == 0 || display.height == 0) return;
int w = w(), h = h();
double xRatio = (display.width-5)/(double) w;
double yRatio = (display.height-5)/(double) h;
if (scaffoldingEnabled(this))
printVars("zoomToDisplaySize", "display", display, "w", w, "h", h, "xRatio", xRatio, "yRatio", yRatio);
setZoom_dontChangeAutoZoom(min(xRatio, yRatio));
revalidateMe();
}); }
/** tricky magic to get parent scroll pane */
private Dimension getDisplaySize() {
if (metaGet("scaffolding") != null) scaffoldCalled(this, "getDisplaySize");
Container c = getParent();
while (c != null) {
if (c instanceof JScrollPane)
return c.getSize();
c = c.getParent();
}
return getSize();
}
public void setSelection(Rect r) {
setSelection(toRectangle(r));
}
public void setSelection(Rectangle r) {
if (neq(selection, r)) {
selection = r;
pcallF(onSelectionChange);
quickRepaint();
}
}
public Rectangle getSelection() {
return selection;
}
public RGBImage getRGBImage() {
return new RGBImage(getImage());
}
// p is in image coordinates
void centerPoint(Point p) {
JScrollPane sp = enclosingScrollPane(this);
if (sp == null) return;
p = new Point((int) (p.x*getZoomX()), (int) (p.y*getZoomY()));
final JViewport viewport = sp.getViewport();
Dimension viewSize = viewport.getExtentSize();
//_print("centerPoint " + p);
int x = max(0, p.x-viewSize.width/2);
int y = max(0, p.y-viewSize.height/2);
//_print("centerPoint " + p + " => " + x + "/" + y);
p = new Point(x,y);
//_print("centerPoint " + p);
final Point _p = p;
awtLater(new Runnable() { public void run() { try {
viewport.setViewPosition(_p);
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "viewport.setViewPosition(_p);"; }});
}
Pt pointFromEvent(MouseEvent e) {
return pointFromComponentCoordinates(new Pt(e.getX(), e.getY()));
}
Pt pointFromComponentCoordinates(Pt p) {
return new Pt((int) (p.x/zoomX), (int) (p.y/zoomY));
}
Pt pointToComponentCoordinates(double x, double y) {
return new Pt((int) (x*zoomX), (int) (y*zoomY));
}
void uploadTheImage() {
call(hotwire(/*#1007313*/"#1016427"), "go", getImage(), titleForUpload);
}
void showFullScreen() {
showFullScreenImageSurface(getImage());
}
void zoomIn(double f) { setZoom(getZoomX()*f, getZoomY()*f); }
void zoomOut(double f) { setZoom(getZoomX()/f, getZoomY()/f); }
ImageSurface setFile(File f) { file = f; return this; }
void setOverlay(IVF1 overlay) {
this.overlay = overlay;
}
boolean hasImage() { return image != null; }
public int w() { return image.getWidth(); }
public int h() { return image.getHeight(); }
void setPixelated(boolean b) {
assertTrue(b);
imageSurface_pixelated(this);
}
ImageSurface setAutoZoomToDisplay(boolean b) {
if (autoZoomToDisplay = b)
zoomToDisplaySize();
return this;
}
void quickRepaint() {
if (repaintInThread)
paintImmediately(0, 0, getWidth(), getHeight());
else
repaint();
}
void setTool(ImageSurfaceMouseHandler tool) { swing(() -> {
removeAllTools();
addTool(tool);
}); }
boolean hasTool(AutoCloseable tool) {
return swing(() -> tools.contains(tool));
}
void addTool(ImageSurfaceMouseHandler tool) { swing(() -> {
if (!tools.contains(tool))
tool.register(this);
}); }
void removeTool(AutoCloseable tool) { swing(() -> {
if (tools.contains(tool)) {
close(tool);
tools.remove(tool);
}
}); }
void removeAllTools() {
closeAllAndClear(tools);
}
void performAutoZoom() {
if (autoZoomToDisplay) zoomToDisplaySize();
}
void revalidateMe() {
revalidateIncludingFullCenterContainer(this);
}
void addOverlay(G2Drawable overlay) {
overlays.add(overlay);
repaint();
}
void clearOverlays() {
if (nempty(overlays)) {
overlays.clear();
repaint();
}
}
void loadImage(File f) {
setImage(loadImage2(f));
}
JComponent visualize() {
return jscroll_center_borderless(this);
}
A print(A a) { return print("", a); }
A print(String msg, A a) { return _print(msg, a); }
} // end of ImageSurface
// static function allows garbage collection
static VF2 ImageSurface_popupMenuMaker() {
return new VF2() { public void get(ImageSurface is, JPopupMenu menu) { try {
Point p = is.pointFromEvent(componentPopupMenu_mouseEvent.get()).getPoint();
is.fillPopupMenu(menu, p);
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "Point p = is.pointFromEvent(componentPopupMenu_mouseEvent.get()).getPoint();\r..."; }};
}
static class CombinedStringifier implements IStringifier {
CopyOnWriteArrayList> stringifiers = new CopyOnWriteArrayList();
IStringifier defaultStringifier = new Stringifier_ToString();
CombinedStringifier(IPartialStringifier ... stringifiers) {
addAll(this.stringifiers, stringifiers);
}
public String toString(A o) {
for (var stringifier : stringifiers) {
String s = stringifier.toStringOpt(o);
if (s != null) return s;
}
return defaultStringifier.toString(o);
}
public String toString() {
return formatFunctionCall("CombinedStringifier",
listPlus((List) stringifiers, defaultStringifier)
);
}
}
static interface MakesBufferedImage extends WidthAndHeight {
BufferedImage getBufferedImage();
public default void drawAt(Graphics2D g, int x, int y) {
g.drawImage(getBufferedImage(), x, y, null);
}
}
/* e.g.
overlay <- ScreenOverlay
bounds <- rightScreenBounds
overlay bounds bounds
overlay show
Can separate commands with ";" also.
For how to define functions in a script see #1033988.
Note: LeftArrowScriptAutoCompleter uses a lot of this class's internals
*/
static class GazelleV_LeftArrowScriptParser extends SimpleLeftToRightParser {
final public GazelleV_LeftArrowScriptParser setG22utils(G22Utils g22utils){ return g22utils(g22utils); }
public GazelleV_LeftArrowScriptParser g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils(){ return g22utils(); }
public G22Utils g22utils() { return g22utils; }
G22Utils g22utils = new G22Utils();
List functionContainers = new ArrayList();
LinkedHashMap knownVars = new LinkedHashMap();
BuildingScript currentReturnableScript;
boolean inParens = false;
// object can be a class
static class MethodOnObject implements IFieldsToList{
static final String _fieldOrder = "object method";
Object object;
String method;
MethodOnObject() {}
MethodOnObject(Object object, String method) {
this.method = method;
this.object = object;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + object + ", " + method + ")"; }
public boolean equals(Object o) {
if (!(o instanceof MethodOnObject)) return false;
MethodOnObject __3 = (MethodOnObject) o;
return eq(object, __3.object) && eq(method, __3.method);
}
public int hashCode() {
int h = 791808543;
h = boostHashCombine(h, _hashCode(object));
h = boostHashCombine(h, _hashCode(method));
return h;
}
public Object[] _fieldsToList() { return new Object[] {object, method}; }
}
class BuildingScript {
boolean returnable = false;
GazelleV_LeftArrowScript.Script script = new GazelleV_LeftArrowScript.Script();
List steps = new ArrayList();
Map functionDefs = new HashMap();
BuildingScript(boolean returnable) {
this.returnable = returnable;}
void add(GazelleV_LeftArrowScript.Evaluable step) { if (step != null) steps.add(step); }
GazelleV_LeftArrowScript.Evaluable get() {
// if the last command is a return from THIS script,
// convert into a simple expression
var lastStep = last(steps);
if (lastStep instanceof GazelleV_LeftArrowScript.ReturnFromScript)
if (((GazelleV_LeftArrowScript.ReturnFromScript) lastStep).script == script)
replaceLast(steps, ((GazelleV_LeftArrowScript.ReturnFromScript) lastStep).value);
// if the script is only step, is not returnable
// and defines no functions, replace it with its only step
if (!returnable && l(steps) == 1 && empty(functionDefs))
return first(steps);
// make and return actual script
script.functionDefs = functionDefs;
script.steps = toTypedArray(GazelleV_LeftArrowScript.Evaluable.class, steps);
return script;
}
String toStringLong() { return pnlToLines(steps); }
public String toString() { return formatRecordVars("BuildingScript", "script", script, "returnable", returnable); }
}
GazelleV_LeftArrowScript.Script parse(String text) {
setText(text);
return (GazelleV_LeftArrowScript.Script) parseScript(true);
}
// if returnable is true, it's always a Script
GazelleV_LeftArrowScript.Evaluable parseScript(boolean returnable) {
BuildingScript script = new BuildingScript(returnable);
var lastReturnableScript = currentReturnableScript;
if (returnable) currentReturnableScript = script;
try {
parseScript_2(script);
var builtScript = script.get();
currentReturnableScript = lastReturnableScript;
return builtScript;
} catch (Throwable e) {
if (scaffoldingEnabled()) print("Parsed so far:\n" + script);
throw rethrowAndAppendToMessage(e, squareBracketed(str(lineAndColumn())));
}
}
void parseScript_2(BuildingScript script) {
while (mainLoop()) {
if (is(";")) { next(); continue; }
if (is("}")) break;
String t = token();
//print("First token of command: " + t);
if (is("def"))
{ parseFunctionDefinition(); continue; }
if (is("param")) {
consume();
String var = assertIdentifier(tpp());
knownVars.put(var, new LASValueDescriptor());
continue;
}
if (is("return")) {
consume();
var expr = parseExpr();
{ script.add(new GazelleV_LeftArrowScript.ReturnFromScript(currentReturnableScript.script, expr)); continue; }
}
if (scaffoldingEnabled()) print("next tokens: " + quote(token(1)) + " " + quote(token(2)));
if (isIdentifier(t) && eq(token(1), "<") && eq(token(2), "-")) {
if (scaffoldingEnabled()) print("Found assignment");
next(3);
knownVars.put(t, new LASValueDescriptor());
script.add(new GazelleV_LeftArrowScript.Assignment(t, parseExpr()));
} else
script.add(parseExpr());
}
}
GazelleV_LeftArrowScript.Evaluable parseOptionalInnerExpression() {
if (scaffoldingEnabled()) printVars("parseOptionalInnerExpression", "token", token());
if (atCmdEnd() || is("{")) return null;
return parseInnerExpr();
}
GazelleV_LeftArrowScript.Evaluable _const(Object o) { return new GazelleV_LeftArrowScript.Const(o); }
GazelleV_LeftArrowScript.Evaluable parseInnerExpr() { return parseExpr(true); }
GazelleV_LeftArrowScript.Evaluable parseExpr() { return parseExpr(false); }
GazelleV_LeftArrowScript.Evaluable parseExpr(boolean inner) {
if (atEnd()) return null;
String t = token();
if (scaffoldingEnabled()) printVars("parseExpr", "token" , t);
if (is(";")) return null; // empty command
// int or double literal
if (is("-") && empty(nextSpace()) && startsWithDigit(token(1))
|| startsWithDigit(t)) {
t = consumeMultiTokenLiteral();
if (isInteger(t)) return _const(parseInt(t));
if (endsWith(t, "f")) return _const(parseFloat(t));
return _const(parseDouble(t));
}
if (isQuoted(t)) {
consume();
return _const(unquote(t));
}
if (isIdentifier(t)) {
if (is("while"))
return parseWhileLoop();
if (is("for"))
return parseForEach();
if (is("if"))
return parseIfStatement();
consume();
if (scaffoldingEnabled()) print("Consumed identifier " + t + ", next token: " + token() + ", inner: " + inner);
return parseExprStartingWithIdentifier(t, inner);
}
// nested expression
if (eq(t, "(")) {
boolean inParensOld = inParens;
inParens = true;
consume();
//print("Consumed opening parens (level " + parenLevels + ")");
var e = parseExpr();
//print("Consuming closing parens for expr: " + e + " (closing paren level " + parenLevels + ")");
consume(")");
inParens = inParensOld;
return inner ? e : parseCall(e);
}
throw fail("Identifier, literal or opening parentheses expected (got: " + quote(t));
}
// t is last consumed token (the identifier the expression starts with)
GazelleV_LeftArrowScript.Evaluable parseExprStartingWithIdentifier(String t, boolean inner) {
if (eq(t, "true")) return _const(true);
if (eq(t, "false")) return _const(false);
if (eq(t, "null")) return _const(null);
if (eq(t, "new")) {
String className = assertIdentifier(tpp());
Object o = findExternalObject(className);
if (o instanceof Class)
return new GazelleV_LeftArrowScript.NewObject(((Class) o), parseArguments());
throw fail("Class not found: " + className);
}
var type = knownVars.get(t);
if (type != null) {
var e = new GazelleV_LeftArrowScript.GetVar(t).returnType(type);
if (scaffoldingEnabled()) print("Found var acccess: " + e + ", " + (!inner ? "Checking for call" : "Returning expression"));
return inner ? e : parseCall(e);
}
if (!inner) {
var fdef = currentReturnableScript.functionDefs.get(t);
if (fdef != null)
return new GazelleV_LeftArrowScript.CallFunction(fdef, parseArguments());
}
if (eq(t, "_context"))
return new GazelleV_LeftArrowScript.GetVarContext();
Object o = findExternalObject(t);
if (o == null)
throw fail("Unknown object: " + t);
else if (inner)
return _const(o);
else if (o instanceof Class) {
/*if (atCmdEnd())
ret new Toolbox.NewObject(o);*/
/* old object creation syntax (e.g. Pair new a b)
if (is("new")) {
next();
ret new Toolbox.NewObject(o, parseArguments());
} else*/ if (isIdentifier()) {
String name = tpp();
// look for method first
if (hasMethodNamed(((Class) o), name))
return new GazelleV_LeftArrowScript.CallMethod(_const((Class) o), name, parseArguments());
// look for field second
var field = getField(((Class) o), name);
if (field != null) {
assertCmdEnd();
return new GazelleV_LeftArrowScript.GetStaticField(field);
}
throw fail(name + " not found in " + ((Class) o) + " (looked for method or field)");
} else
throw fail("Method name expected: " + token());
} else if (o instanceof MethodOnObject) {
if (inner) throw fail("Can't call methods in arguments");
return new GazelleV_LeftArrowScript.CallMethod(_const(((MethodOnObject) o).object), ((MethodOnObject) o).method, parseArguments());
} else
return parseCall(_const(o));
}
List parseArguments() {
//ret collectWhileNotNull(-> parseOptionalInnerExpression());
List l = new ArrayList();
try {
while (true) {
GazelleV_LeftArrowScript.Evaluable a = parseOptionalInnerExpression();
if (a == null) break;
l.add(a);
}
return l;
} catch (Throwable _e) {
if (scaffoldingEnabled()) print("Arguments parsed so far: " + l);
throw rethrow(_e); }
}
String consumeMultiTokenLiteral() {
return consumeUntilSpaceOr(() -> atCmdEnd());
}
boolean atCmdEnd() {
return
!inParens && atEndOrLineBreak()
|| is(";") || is("}") || is(")");
}
void assertCmdEnd() { if (!atCmdEnd()) throw fail("Expected end of command"); }
GazelleV_LeftArrowScript.Evaluable parseCall(GazelleV_LeftArrowScript.Evaluable target) {
if (atCmdEnd() || !isIdentifier()) return target;
var start = ptr();
String methodName = tpp();
var args = parseArguments();
if (nempty(args))
return new GazelleV_LeftArrowScript.CallMethod(target, methodName, args);
else
return src(start, new GazelleV_LeftArrowScript.CallMethodOrGetField(target, methodName));
}
A src(ListAndIndex start, A a) {
if (a instanceof IHasTokenRangeWithSrc)
((IHasTokenRangeWithSrc) a).setTokenRangeWithSrc(new TokenRangeWithSrc(start, ptr()));
return a;
}
// can return MethodOnObject
transient IF1 findExternalObject;
Object findExternalObject(String name) { return findExternalObject != null ? findExternalObject.get(name) : findExternalObject_base(name); }
final Object findExternalObject_fallback(IF1 _f, String name) { return _f != null ? _f.get(name) : findExternalObject_base(name); }
Object findExternalObject_base(String name) { try {
//try object findClassThroughDefaultClassFinder(name);
//try object findClassInStandardImports(name);
String fullName = globalClassNames().get(name);
if (fullName != null)
return Class.forName(fullName);
for (var container : unnullForIteration(functionContainers))
if (hasMethodNamed(container, name))
return new MethodOnObject(container, name);
return null;
} catch (Exception __e) { throw rethrow(__e); } }
GazelleV_LeftArrowScriptParser allowTheWorld() { return allowTheWorld(mc()); }
GazelleV_LeftArrowScriptParser allowTheWorld(Object... functionContainers) {
for (Object o : unnullForIteration(reversed(functionContainers)))
if (!contains(this.functionContainers, o)) {
this.functionContainers.add(0, o);
globalClassNames_cache = null; // recalculate
}
return this;
}
void printFunctionDefs(GazelleV_LeftArrowScript.Script script) {
if (scaffoldingEnabled()) print(values(script.functionDefs));
}
void parseFunctionDefinition() {
consume("def");
String functionName = assertIdentifier(tpp());
List args = new ArrayList();
while (isIdentifier())
args.add(tpp());
AutoCloseable __1 = tempMapPutAll(knownVars, mapWithSingleValue(args, new LASValueDescriptor())); try {
var functionBody = parseCurlyBlock(true);
currentReturnableScript.functionDefs.put(functionName,
new GazelleV_LeftArrowScript.FunctionDef(functionName, args, functionBody));
} finally { _close(__1); }}
GazelleV_LeftArrowScript.Evaluable parseCurlyBlock(boolean returnable) {
//print(+knownVars);
consume("{");
boolean inParensOld = inParens;
inParens = false;
var script = parseScript(returnable);
consume("}");
inParens = inParensOld;
return script;
}
GazelleV_LeftArrowScript.Evaluable parseWhileLoop() {
consume("while");
var condition = parseExpr();
var body = parseCurlyBlock(false);
return new GazelleV_LeftArrowScript.While(condition, body);
}
GazelleV_LeftArrowScript.Evaluable parseForEach() {
consume("for");
String var = assertIdentifier(tpp());
if (scaffoldingEnabled()) print("for var", var);
consume("in");
var collection = parseExpr();
if (scaffoldingEnabled()) print("collection", collection);
AutoCloseable __2 = tempMapPut(knownVars, var, new LASValueDescriptor()); try {
var body = parseCurlyBlock(false);
return new GazelleV_LeftArrowScript.ForEach(collection, var, body);
} finally { _close(__2); }}
GazelleV_LeftArrowScript.Evaluable parseIfStatement() {
consume("if");
var condition = parseExpr();
var body = parseCurlyBlock(false);
GazelleV_LeftArrowScript.Evaluable elseBranch = null;
if (is("else")) {
consume();
if (is("if"))
elseBranch = parseIfStatement();
else
elseBranch = parseCurlyBlock(false);
}
return new GazelleV_LeftArrowScript.IfThen(condition, body, elseBranch);
}
// declare an external variable with optional type info
void addVar(String var) { addVar(var, new LASValueDescriptor()); }
void addVar(String var, LASValueDescriptor type) { knownVars.put(var, type); }
void addVar(String var, Class type, boolean canBeNull) { addVar(var, new LASValueDescriptor.NonExact(type, canBeNull)); }
// short name to full name
Map globalClassNames_cache;
Map globalClassNames() { if (globalClassNames_cache == null) globalClassNames_cache = globalClassNames_load(); return globalClassNames_cache;}
Map globalClassNames_load() {
var packages = mapToTreeSet(importedPackages(), pkg -> pkg + ".");
// add inner classes of function containers
var classContainers = classContainerPrefixes();
Map out = new HashMap();
for (var className : g22utils.classNameResolver().allFullyQualifiedClassNames()) {
if (isAnonymousClassName(className)) continue;
if (!contains(className, '$')) {
String pkg = longestPrefixInTreeSet(className, packages);
if (pkg != null) {
String shortName = dropPrefix(pkg, className);
if (!shortName.contains("."))
out.put(shortName, className);
}
}
String container = longestPrefixInTreeSet(className, classContainers);
if (container != null)
out.put(dropPrefix(container, className), className);
}
return out;
}
transient IF0> importedPackages;
Collection importedPackages() { return importedPackages != null ? importedPackages.get() : importedPackages_base(); }
final Collection importedPackages_fallback(IF0> _f) { return _f != null ? _f.get() : importedPackages_base(); }
Collection importedPackages_base() {
return itemPlus("java.lang", standardImports_fullyImportedPackages());
}
TreeSet classContainerPrefixes() {
return mapToTreeSet(functionContainers, fc -> className(fc) + "$");
}
}
static class G22LeftArrowScript extends ConceptWithChangeListeners {
static final String _fieldOrder = "description text clearedForAutoRun editingText runCount lastResultByMode compileResultForAutoRun compileResultForSaved";
public transient FieldVar varDescription_cache;
public FieldVar varDescription() { if (varDescription_cache == null) varDescription_cache = varDescription_load(); return varDescription_cache;}
public FieldVar varDescription_load() {
return new FieldVar(this, "description", () -> description(), description -> description(description)); }
final public G22LeftArrowScript setDescription(String description){ return description(description); }
public G22LeftArrowScript description(String description) { if (!eq(this.description, description)) { this.description = description; change(); } return this; }
final public String getDescription(){ return description(); }
public String description() { return description; }
String description;
// the script (last "saved" version)
public transient FieldVar varText_cache;
public FieldVar varText() { if (varText_cache == null) varText_cache = varText_load(); return varText_cache;}
public FieldVar varText_load() {
return new FieldVar(this, "text", () -> text(), text -> text(text)); }
final public G22LeftArrowScript setText(String text){ return text(text); }
public G22LeftArrowScript text(String text) { if (!eq(this.text, text)) { this.text = text; change(); } return this; }
final public String getText(){ return text(); }
public String text() { return text; }
String text;
// the latest code that has been cleared to auto-run (if any)
public transient FieldVar> varClearedForAutoRun_cache;
public FieldVar> varClearedForAutoRun() { if (varClearedForAutoRun_cache == null) varClearedForAutoRun_cache = varClearedForAutoRun_load(); return varClearedForAutoRun_cache;}
public FieldVar> varClearedForAutoRun_load() {
return new FieldVar>(this, "clearedForAutoRun", () -> clearedForAutoRun(), clearedForAutoRun -> clearedForAutoRun(clearedForAutoRun)); }
final public G22LeftArrowScript setClearedForAutoRun(ClearForAutoRun clearedForAutoRun){ return clearedForAutoRun(clearedForAutoRun); }
public G22LeftArrowScript clearedForAutoRun(ClearForAutoRun clearedForAutoRun) { if (!eq(this.clearedForAutoRun, clearedForAutoRun)) { this.clearedForAutoRun = clearedForAutoRun; change(); } return this; }
final public ClearForAutoRun getClearedForAutoRun(){ return clearedForAutoRun(); }
public ClearForAutoRun clearedForAutoRun() { return clearedForAutoRun; }
ClearForAutoRun clearedForAutoRun;
// text currently being modified in an editor (or null)
// Note that "" doesn't count as null.
public transient FieldVar varEditingText_cache;
public FieldVar varEditingText() { if (varEditingText_cache == null) varEditingText_cache = varEditingText_load(); return varEditingText_cache;}
public FieldVar varEditingText_load() {
return new FieldVar(this, "editingText", () -> editingText(), editingText -> editingText(editingText)); }
final public G22LeftArrowScript setEditingText(String editingText){ return editingText(editingText); }
public G22LeftArrowScript editingText(String editingText) { if (!eq(this.editingText, editingText)) { this.editingText = editingText; change(); } return this; }
final public String getEditingText(){ return editingText(); }
public String editingText() { return editingText; }
String editingText;
// run stats
long runCount;
// info about last result (or error) of script run by mode
Map>> lastResultByMode;
@Override void _doneLoading2() {
//print("_doneLoading " + this);
cMigrateField(this, "code", "text");
}
String myType() { return dropPrefix("G22", shortClassName(this)); }
public String toString() { return or2(description, myType() + " " + id); }
void initEditingText() {
editingText(unnull(or(editingText, text)));
}
void receiveEditingText(String text) {
printVars_shorten("receiveEditingText", "text", text);
editingText(text);
}
String stableText() { return text; }
final void save(){ completeEdit(); }
void completeEdit() {
String t = editingText;
printVars_shorten("completeEdit", "t", t);
if (t != null) {
setTextWithHistory(t);
printVars_shorten("completeEdit", "editingText", editingText);
}
}
void setTextWithHistory(String text) {
if (eq(this.text, text)) return;
text(text);
saveTextToHistory();
}
String textForEditing() {
initEditingText();
return editingText;
}
File historyFile() {
return fileInConceptsDir("History/" + shortDynName(this) + id + ".history");
}
void saveTextToHistory() {
saveFieldToHistory("text", text);
}
void saveFieldToHistory(String field, String value) {
File historyFile = historyFile();
if (historyFile == null) return;
String contents = value == null ? " empty" : " (" + nLines(value) + ", " + nChars(value) + "):\n" +
indentx(value) + "\n" +
"\n";
appendToTextFile(historyFile,
"\n===\n" +
"Concept ID: " + id + "\n" +
"Date: " + dateWithMSUTC() + "\n" +
firstToUpper(field) + contents +
"===" + "\n");
}
boolean isSaved() { return text != null; }
boolean isSavedDistinctFromAutoRunVersion() { return isSaved() && !eq(text, codeForAutoRun()); }
boolean isEditing() { return editedText() != null; }
boolean isClearForAutoRun() { return clearedForAutoRun != null; }
String editedText() { return eq(editingText, text) ? null : editingText; }
String codeForAutoRun() { return getVar(clearedForAutoRun()); }
void clearForAutoRun() {
if (!isSaved()) return;
String text = text();
saveFieldToHistory("Auto-runnable code", text);
clearedForAutoRun(new ClearForAutoRun(text));
}
void forgetAutoRunCode() {
if (!isClearForAutoRun()) return;
saveFieldToHistory("Auto-runnable code", null);
clearedForAutoRun(null);
compileResultForAutoRun = null;
}
GazelleV_LeftArrowScriptParser makeParser() { return g22utils(_concepts).leftArrowParser(); }
LASCompileResult newCompileResult() { return new LASCompileResult(); }
transient LASCompileResult compileResultForAutoRun;
LASCompileResult compileForAutoRun() {
String code = codeForAutoRun();
if (code == null) return null;
var cr = compileResultForAutoRun;
if (cr != null && eq(cr.script, code))
return cr;
cr = newCompileResult();
cr.script(code);
var g22utils = assertNotNull("g22utils", g22utils(_concepts()));
var parser = makeParser();
cr.parser(parser);
cr.compile();
return compileResultForAutoRun = cr;
}
transient LASCompileResult compileResultForSaved;
LASCompileResult compileSaved() {
String code = stableText();
if (code == null) return null;
var cr = compileResultForSaved;
if (cr != null && eq(cr.script, code))
return cr;
cr = newCompileResult();
cr.script(code);
var g22utils = assertNotNull("g22utils", g22utils(_concepts()));
var parser = makeParser();
cr.parser(parser);
cr.compile();
return compileResultForSaved = cr;
}
}
static class RSyntaxTextAreaWithSearch implements SearchListener, Swingable {
JPanel panel;
final public RSyntaxTextArea getTextArea(){ return textArea(); }
public RSyntaxTextArea textArea() { return textArea; }
RSyntaxTextArea textArea;
CollapsibleSectionPanel csp;
FindDialog findDialog;
ReplaceDialog replaceDialog;
FindToolBar findToolBar;
ReplaceToolBar replaceToolBar;
StatusBar statusBar;
RSyntaxTextAreaWithSearch() { init(); }
RSyntaxTextAreaWithSearch(IF1 wrapStatusLabel) {
this.wrapStatusLabel = wrapStatusLabel; init(); }
RSyntaxTextAreaWithSearch(String text) { init(); setText(text); }
public JComponent visualize() { return panel; }
void init() { swing(() -> {
rsyntaxTextArea_fixNumPad();
initSearchDialogs();
panel = new JPanel(new BorderLayout());
csp = new CollapsibleSectionPanel();
panel.add(csp);
textArea = javaxSyntaxTextArea();
RTextScrollPane sp = new RTextScrollPane(textArea);
csp.add(sp);
ErrorStrip errorStrip = new ErrorStrip(textArea);
panel.add(errorStrip, BorderLayout.LINE_END);
statusBar = new StatusBar();
panel.add(statusBar, BorderLayout.SOUTH);
}); }
transient IF1 wrapStatusLabel;
JComponent wrapStatusLabel(JComponent label) { return wrapStatusLabel != null ? wrapStatusLabel.get(label) : wrapStatusLabel_base(label); }
final JComponent wrapStatusLabel_fallback(IF1 _f, JComponent label) { return _f != null ? _f.get(label) : wrapStatusLabel_base(label); }
JComponent wrapStatusLabel_base(JComponent label) { return label; }
void addItem(Action a, ButtonGroup bg, JMenu menu) {
JRadioButtonMenuItem item = new JRadioButtonMenuItem(a);
bg.add(item);
menu.add(item);
}
// register keystrokes if we don't have a menu bar
void menuLessOperation() { swing(() -> {
//print("menuLessOperation");
var mb = createMenuBar();
for (var menu : getMenus(mb))
for (var menuItem : getMenuItems(menu)) {
var ks = menuItem.getAccelerator();
//printVars(+ks, +menuItem);
if (ks != null) {
var action = menuItem.getAction();
//print("Registering keystroke: " + ks + " => " + action);
textArea.getInputMap().put(ks, action);
}
}
}); }
JMenuBar createMenuBar() {
JMenuBar mb = new JMenuBar();
JMenu menu = new JMenu("Search");
menu.add(new JMenuItem(new ShowFindDialogAction()));
menu.add(new JMenuItem(new ShowReplaceDialogAction()));
menu.add(new JMenuItem(new GoToLineAction()));
menu.addSeparator();
int ctrl = getToolkit().getMenuShortcutKeyMask();
int shift = InputEvent.SHIFT_MASK;
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_F, ctrl|shift);
Action a = csp.addBottomComponent(ks, findToolBar);
a.putValue(Action.NAME, "Show Find Search Bar");
menu.add(new JMenuItem(a));
ks = KeyStroke.getKeyStroke(KeyEvent.VK_H, ctrl|shift);
a = csp.addBottomComponent(ks, replaceToolBar);
a.putValue(Action.NAME, "Show Replace Search Bar");
menu.add(new JMenuItem(a));
mb.add(menu);
return mb;
}
public String getSelectedText() {
return textArea.getSelectedText();
}
/**
* Creates our Find and Replace dialogs.
*/
public void initSearchDialogs() {
findDialog = new FindDialog((java.awt.Dialog) null, this);
replaceDialog = new ReplaceDialog((java.awt.Dialog) null, this);
// This ties the properties of the two dialogs together (match case,
// regex, etc.).
SearchContext context = findDialog.getSearchContext();
replaceDialog.setSearchContext(context);
// Create tool bars and tie their search contexts together also.
findToolBar = new FindToolBar(this);
findToolBar.setSearchContext(context);
replaceToolBar = new ReplaceToolBar(this);
replaceToolBar.setSearchContext(context);
}
/**
* Listens for events from our search dialogs and actually does the dirty
* work.
*/
@Override
public void searchEvent(SearchEvent e) {
SearchEvent.Type type = e.getType();
SearchContext context = e.getSearchContext();
SearchResult result = null;
switch (type) {
default: // Prevent FindBugs warning later
case MARK_ALL:
result = SearchEngine.markAll(textArea, context);
break;
case FIND:
result = SearchEngine.find(textArea, context);
if (!result.wasFound())
{
//Try to wrap the result...
Caret c = textArea.getCaret();
int pos = c.getDot();
if (context.getSearchForward())
{
c.setDot(0);
}
else
{
c.setDot(textArea.getDocument().getLength());
}
result = SearchEngine.find(textArea, context);
if (!result.wasFound())
{
c.setDot(pos);
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
}
}
break;
case REPLACE:
result = SearchEngine.replace(textArea, context);
if (!result.wasFound()) {
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
}
break;
case REPLACE_ALL:
result = SearchEngine.replaceAll(textArea, context);
JOptionPane.showMessageDialog(null, result.getCount() +
" occurrences replaced.");
break;
}
String text = null;
if (result.wasFound()) {
text = "Text found; occurrences marked: " + result.getMarkedCount();
}
else if (type==SearchEvent.Type.MARK_ALL) {
if (result.getMarkedCount()>0) {
text = "Occurrences marked: " + result.getMarkedCount();
}
else {
text = "";
}
}
else {
text = "Text not found";
}
setStatus(text);
}
class GoToLineAction extends AbstractAction {
GoToLineAction() {
super("Go To Line...");
int c = getToolkit().getMenuShortcutKeyMask();
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_L, c));
}
public void actionPerformed(ActionEvent e) {
findDialog.setVisible(false);
replaceDialog.setVisible(false);
GoToDialog dialog = new GoToDialog((java.awt.Dialog) null);
dialog.setMaxLineNumberAllowed(textArea.getLineCount());
showDialogOnSameScreen(dialog, panel);
int line = dialog.getLineNumber();
if (line>0) {
try {
textArea.setCaretPosition(textArea.getLineStartOffset(line-1));
} catch (BadLocationException ble) { // Never happens
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
ble.printStackTrace();
}
}
}
}
class ShowFindDialogAction extends AbstractAction {
ShowFindDialogAction() {
super("Find...");
int c = getToolkit().getMenuShortcutKeyMask();
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F, c));
}
public void actionPerformed(ActionEvent e) {
replaceDialog.setVisible(false);
showDialogOnSameScreen(findDialog, panel);
}
}
class ShowReplaceDialogAction extends AbstractAction {
ShowReplaceDialogAction() {
super("Replace...");
int c = getToolkit().getMenuShortcutKeyMask();
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_H, c));
}
public void actionPerformed(ActionEvent e) {
findDialog.setVisible(false);
showDialogOnSameScreen(replaceDialog, panel);
}
}
class StatusBar extends JPanel {
JLabel label;
StatusBar() {
label = new JLabel(" ");
setLayout(new BorderLayout());
add(wrapStatusLabel(label), BorderLayout.CENTER);
add(new JLabel(new SizeGripIcon()), BorderLayout.EAST);
}
public void setText(String label) {
main.setText(this.label, label);
}
}
void setStatus(String text) {
statusBar.setText(text);
}
void setText(String text) {
main.setText(textArea, text);
}
String getText() {
return main.getText(textArea);
}
void setEditorFont(final Font font) { swing(() -> {
SyntaxScheme ss = textArea.getSyntaxScheme();
ss = (SyntaxScheme) ss.clone();
for (int i = 0; i < ss.getStyleCount(); i++)
if (ss.getStyle(i) != null)
ss.getStyle(i).font = font;
textArea.setSyntaxScheme(ss);
textArea.setFont(font);
}); }
Font getEditorFont() {
return swing(new F0