private ClassType defineClasses( Collection<OutputFileObject> classes, EvaluationContext context, DebugProcess process, ClassLoaderReference classLoader) throws EvaluateException, InvalidTypeException, ClassNotLoadedException { VirtualMachineProxyImpl proxy = (VirtualMachineProxyImpl) process.getVirtualMachineProxy(); for (OutputFileObject cls : classes) { if (cls.getName().contains(GEN_CLASS_NAME)) { Method defineMethod = ((ClassType) classLoader.referenceType()) .concreteMethodByName("defineClass", "(Ljava/lang/String;[BII)Ljava/lang/Class;"); byte[] bytes = changeSuperToMagicAccessor(cls.toByteArray()); ArrayList<Value> args = new ArrayList<Value>(); StringReference name = proxy.mirrorOf(cls.myOrigName); keep(name, context); args.add(name); args.add(mirrorOf(bytes, context, process)); args.add(proxy.mirrorOf(0)); args.add(proxy.mirrorOf(bytes.length)); process.invokeMethod(context, classLoader, defineMethod, args); } } return (ClassType) process.findClass(context, getGenClassQName(), classLoader); }
// Used in compiling to mark out "dirty" areas of the code; ie, comments and string literals. // These dirty areas don't get their syntax highlighted or any special treatment. // @returns: pairs of integers that represent dirty boundaries. private ArrayList<Integer> getDirty(String code) { ArrayList<Integer> dirtyBounds = new ArrayList<>(); // Handles string literals int j = -1; while (true) { j = code.indexOf("\"", j + 1); if (j < 0) break; // Ignore escaped characters if (!code.substring(j - 1, j).equals("\\")) dirtyBounds.add(j); } // End of line comments j = -1; while (true) { j = code.indexOf("//", j + 1); if (j < 0) break; dirtyBounds.add(j); // If there's no newline, then the comment lasts for the length of the code dirtyBounds.add( code.indexOf("\n", j + 1) == -1 ? code.length() : code.indexOf("\n", j + 1)); } // Block comments (and javadoc comments) j = -1; while (true) { j = code.indexOf("/*", j + 1); if (j < 0) break; dirtyBounds.add(j); dirtyBounds.add(code.indexOf("*/", j + 1)); } return dirtyBounds; }
// A helper method to check if a given position is dirty or not. private boolean isDirty(ArrayList<Integer> dirty, int position) { for (int k = 0; k < dirty.size(); k += 2) if (position > dirty.get(k) && position < dirty.get(k + 1)) return true; return false; }