@return Assembly wrapper. @throws Exception IllegalStateException, cannot find class/method LineParseException, cannot compile bytecode
()
| 50 | * <ul><li>LineParseException, cannot compile bytecode</li></ul> |
| 51 | */ |
| 52 | @Override |
| 53 | public Result call() throws Exception { |
| 54 | if(className == null || className.isEmpty()) |
| 55 | throw new IllegalStateException("No class specified"); |
| 56 | if(!getWorkspace().getPrimary().getClasses().containsKey(className)) |
| 57 | throw new IllegalStateException("No class by the name '" + className + |
| 58 | "' exists in the primary resource"); |
| 59 | int descStart = methodDef.indexOf("("); |
| 60 | if (descStart == -1) |
| 61 | throw new IllegalStateException("Invalid method def '" + methodDef + "'"); |
| 62 | // Get info - need method access |
| 63 | ClassReader reader = getWorkspace().getClassReader(className); |
| 64 | ClassNode node = ClassUtil.getNode(reader, ClassReader.SKIP_FRAMES); |
| 65 | String name = methodDef.substring(0, descStart); |
| 66 | String desc = methodDef.substring(descStart); |
| 67 | MethodNode method = null; |
| 68 | int methodIndex = -1; |
| 69 | for (int i = 0; i < node.methods.size(); i++) { |
| 70 | MethodNode mn = node.methods.get(i); |
| 71 | if(mn.name.equals(name) && mn.desc.equals(desc)) { |
| 72 | method = mn; |
| 73 | methodIndex = i; |
| 74 | break; |
| 75 | } |
| 76 | } |
| 77 | if (method == null) |
| 78 | throw new IllegalStateException("No method '" + methodDef + "' found in '" + className + "'"); |
| 79 | // Assemble method |
| 80 | String code; |
| 81 | try { |
| 82 | code = FileUtils.readFileToString(input, UTF_8); |
| 83 | } catch(IOException ex) { |
| 84 | throw new IllegalStateException("Could not read from '" + input + "'"); |
| 85 | } |
| 86 | ParseResult<RootAST> result = Parse.parse(code); |
| 87 | MethodAssembler assembler = new MethodAssembler(className, getController()); |
| 88 | MethodNode generated = assembler.compile(result); |
| 89 | // Replace method |
| 90 | MethodNode old = node.methods.get(methodIndex); |
| 91 | Comments.removeComments(old); |
| 92 | ClassUtil.copyMethodMetadata(old, generated); |
| 93 | node.methods.set(methodIndex, generated); |
| 94 | //Finalize changes |
| 95 | Workspace workspace = Recaf.getCurrentWorkspace(); |
| 96 | ClassWriter cw = workspace.createWriter(ClassWriter.COMPUTE_FRAMES); |
| 97 | ClassVisitor visitor = cw; |
| 98 | for (ClassVisitorPlugin visitorPlugin : PluginsManager.getInstance() |
| 99 | .ofType(ClassVisitorPlugin.class)) { |
| 100 | visitor = visitorPlugin.intercept(visitor); |
| 101 | } |
| 102 | node.accept(visitor); |
| 103 | byte[] value = cw.toByteArray(); |
| 104 | workspace.getPrimary().getClasses().put(node.name, value); |
| 105 | // Return wrapper |
| 106 | return new Result(node, generated); |
| 107 | } |
| 108 | |
| 109 | /** |
nothing calls this directly
no test coverage detected