Recaf icon indicating copy to clipboard operation
Recaf copied to clipboard

JavaParser issues in '< >'

Open CXVUSER opened this issue 3 years ago • 3 comments

parser fails in: private WeakIdentityHashMap<IUnit, Integer> interpreterIds; image image

parser no fails in: private WeakIdentityHashMap<IUnit, Integer interpreterIds;

???

JDK 11.0.6 recaf-3.0.0-SNAPSHOT-3d01eec

CXVUSER avatar Aug 05 '22 10:08 CXVUSER

We can't do anything about that the moment (correct me if I'm wrong), but it is recommended that in cases like that you use assembler mode, which the warning suggests.

xxDark avatar Aug 05 '22 11:08 xxDark

I'd like to have an example class that reproduces this consistently in order to investigate the cause.

Col-E avatar Aug 13 '22 20:08 Col-E

package me.coley.jremapper.ui;

import me.coley.jremapper.util.Logging;
import java.util.Arrays;
import java.util.TreeMap;
import javafx.scene.input.TransferMode;
import me.coley.event.Event;
import me.coley.jremapper.event.ClassOpenEvent;
import javafx.scene.input.Dragboard;
import java.io.File;
import javafx.scene.image.ImageView;
import me.coley.jremapper.util.Icons;
import javafx.scene.control.TreeCell;
import me.coley.jremapper.mapping.CMap;
import me.coley.jremapper.event.MappingChangeEvent;
import java.util.Iterator;
import java.util.zip.ZipEntry;
import java.util.jar.JarEntry;
import java.io.OutputStream;
import java.util.jar.JarOutputStream;
import java.io.FileOutputStream;
import java.util.Map;
import java.util.HashMap;
import me.coley.jremapper.event.SaveJarEvent;
import java.nio.file.Path;
import com.eclipsesource.json.JsonValue;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.nio.file.OpenOption;
import java.nio.charset.StandardCharsets;
import com.eclipsesource.json.WriterConfig;
import me.coley.jremapper.event.SaveMapEvent;
import me.coley.jremapper.mapping.Mappings;
import me.coley.jremapper.event.LoadMapEvent;
import me.coley.event.Listener;
import javafx.scene.control.TreeItem;
import me.coley.jremapper.event.NewInputEvent;
import me.coley.jremapper.util.Threads;
import java.util.Objects;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.DragEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import me.coley.event.Bus;
import me.coley.jremapper.asm.Input;
import javafx.scene.control.TreeView;
import javafx.scene.layout.BorderPane;

public class FilePane extends BorderPane
{
    private final TreeView<String> tree;
    private Input input;
    
    public FilePane() {
        this.tree = new TreeView<String>();
        Bus.subscribe(this);
        this.setCenter(this.tree);
        this.tree.setOnDragOver(this::lambda$new$0);
        this.tree.setOnMouseClicked(this::lambda$new$1);
        this.tree.setOnDragDropped(FilePane::lambda$new$2);
        this.tree.setShowRoot(false);
        this.tree.setCellFactory(this::lambda$new$3);
        Bus.subscribe(this);
        final TreeView<String> tree = this.tree;
        Objects.requireNonNull(tree);
        Threads.runFx(tree::requestFocus);
    }
    
    @Listener
    public void onInputChange(final NewInputEvent input) {
        this.input = input.get();
        this.tree.setRoot(this.getNodesForDirectory(this.input));
    }
    
    @Listener
    public void onLoadMapRequest(final LoadMapEvent load) {
        Mappings.INSTANCE.loadMapping(load.getDestination());
    }
    
    @Listener
    public void onSaveMapRequest(final SaveMapEvent save) {
        final JsonValue value = Mappings.INSTANCE.toMapping();
        try {
            final Path path = save.getDestination().toPath();
            final byte[] content = value.toString(WriterConfig.PRETTY_PRINT).getBytes(StandardCharsets.UTF_8);
            Files.write(path, content, StandardOpenOption.CREATE);
        }
        catch (final Exception e) {
            e.printStackTrace();
        }
    }
    
    @Listener
    public void onSaveJarRequest(final SaveJarEvent save) {
        final Map<String, byte[]> content = new HashMap<String, byte[]>();
        for (Map.Entry<String, byte[]> e : this.input.rawNodeMap.entrySet()) {
            final byte[] clazz = e.getValue();
            final String key = Mappings.INSTANCE.getTransformedName(e.getKey()) + ".class";
            content.put(key, Mappings.INSTANCE.intercept(clazz));
        }
        for (final Map.Entry<String, byte[]> e : this.input.resourceMap.entrySet()) {
            content.put(e.getKey(), e.getValue());
        }
        try (final JarOutputStream output = new JarOutputStream(new FileOutputStream(save.getDestination()))) {
            for (final Map.Entry<String, byte[]> entry : content.entrySet()) {
                output.putNextEntry(new JarEntry(entry.getKey()));
                output.write(entry.getValue());
                output.closeEntry();
            }
        }
        catch (final Exception e2) {
            e2.printStackTrace();
        }
    }
    
    @Listener
    public void onMappingUpdate(final MappingChangeEvent remap) {
        if (remap.getMapping() instanceof CMap) {
            final String original = remap.getMapping().getOriginalName();
            final String current = remap.getMapping().getCurrentName();
            final FileTreeItem item = this.getNode(current);
            final FileTreeItem parent = (FileTreeItem)item.getParent();
            parent.remove(item);
            try {
                this.addToRoot((FileTreeItem)this.tree.getRoot(), remap.getNewName(), original);
            }
            catch (final Exception e) {
                this.tree.setRoot(this.getNodesForDirectory(this.input));
            }
        }
    }
    
    private FileTreeItem getNode(final String name) {
        FileTreeItem r = (FileTreeItem)this.tree.getRoot();
        final String[] parts = name.split("/");
        for (int i = 0; i < parts.length; ++i) {
            final String part = parts[i];
            if (i == parts.length - 1) {
                r = r.getFile(part);
            }
            else {
                r = r.getDir(part);
            }
        }
        return r;
    }
    
    private final FileTreeItem getNodesForDirectory(final Input input) {
        final FileTreeItem root = new FileTreeItem("root", null);
        input.names().forEach(this::lambda$getNodesForDirectory$4);
        return root;
    }
    
    private void addToRoot(final FileTreeItem root, final String currentName, final String originalName) {
        FileTreeItem r = root;
        final String[] parts = currentName.split("/");
        for (int i = 0; i < parts.length; ++i) {
            final String part = parts[i];
            if (i == parts.length - 1) {
                r.addFile(part, originalName);
            }
            else if (r.hasDir(part)) {
                r = r.getDir(part);
            }
            else {
                r = r.addDir(part);
            }
        }
    }
    
    private static String trim(final String item) {
        return (item.indexOf("/") > 0) ? item.substring(item.lastIndexOf("/") + 1) : item;
    }
    
    private void lambda$getNodesForDirectory$4(final FileTreeItem root, final String name) {
        this.addToRoot(root, name, name);
    }
    
    private TreeCell lambda$new$3(final TreeView param) {
        return new TreeCell<String>() {
            public void updateItem(final String item, final boolean empty) {
                super.updateItem(item, empty);
                if (empty || item == null) {
                    this.setText(null);
                    this.setGraphic(null);
                }
                else {
                    final boolean cont = FilePane.this.input.hasRawClass(item);
                    final Node fxImage = cont ? Icons.getClass(FilePane.this.input.getClassAccess(item)) : new ImageView(Icons.CL_PACKAGE);
                    this.setGraphic(fxImage);
                    String name = item;
                    if (cont) {
                        final CMap map = Mappings.INSTANCE.getClassMapping(item);
                        if (map != null) {
                            name = map.getCurrentName();
                        }
                        name = FilePane.trim(name);
                        this.setText(name);
                    }
                    final int max = 150;
                    if (name.length() > max) {
                        name = name.substring(0, max);
                    }
                    this.setText(name);
                }
            }
        };
    }
    
    private static void lambda$new$2(final DragEvent e) {
        final Dragboard db = e.getDragboard();
        if (db.hasFiles()) {
            NewInputEvent.call(db.getFiles().get(0));
        }
    }
    
    private void lambda$new$1(final MouseEvent e) {
        if (e.getClickCount() == 2) {
            final FileTreeItem item = this.tree.getSelectionModel().getSelectedItem();
            if (item != null && !item.isDir) {
                Bus.post(new ClassOpenEvent(item.fullPath));
            }
        }
    }
    
    private void lambda$new$0(final DragEvent e) {
        if (e.getGestureSource() != this.tree && e.getDragboard().hasFiles()) {
            e.acceptTransferModes(TransferMode.COPY_OR_MOVE);
        }
        e.consume();
    }
    
    public class FileTreeItem extends TreeItem<String> implements Comparable<String>
    {
        private final Map<String, FileTreeItem> dirs;
        private final Map<String, FileTreeItem> files;
        final boolean isDir;
        final String fullPath;
        
        private FileTreeItem(final String part, final String full) {
            this.dirs = new TreeMap<String, FileTreeItem>();
            this.files = new TreeMap<String, FileTreeItem>();
            this.isDir = (full == null);
            this.fullPath = full;
            this.setValue(this.isDir ? part : full);
        }
        
        FileTreeItem addDir(final String part) {
            final FileTreeItem fti = new FileTreeItem(part, null);
            this.dirs.put(part, fti);
            this.addOrdered(fti);
            return fti;
        }
        
        void addFile(final String part, final String name) {
            final FileTreeItem fti = new FileTreeItem(part, name);
            this.files.put(part, fti);
            this.addOrdered(fti);
        }
        
        private void addOrdered(final FileTreeItem fti) {
            try {
                final int sizeD = this.dirs.size();
                final int sizeF = this.files.size();
                final int size = sizeD + sizeF;
                if (size == 0) {
                    this.getChildren().add(fti);
                    return;
                }
                if (fti.isDir) {
                    final FileTreeItem[] array = this.dirs.values().toArray(new FileTreeItem[0]);
                    int index = Arrays.binarySearch(array, ((TreeItem<Object>)fti).getValue());
                    if (index < 0) {
                        index = index * -1 - 1;
                    }
                    this.getChildren().add(index, fti);
                }
                else {
                    final FileTreeItem[] array = this.files.values().toArray(new FileTreeItem[0]);
                    int index = Arrays.binarySearch(array, ((TreeItem<Object>)fti).getValue());
                    if (index < 0) {
                        index = index * -1 - 1;
                    }
                    this.getChildren().add(sizeD + index, fti);
                }
            }
            catch (final Exception e) {
                Logging.fatal(e);
            }
        }
        
        public void remove(final FileTreeItem item) {
            final String name = FilePane.trim(item.getValue());
            if (item.isDir) {
                this.dirs.remove(name);
            }
            else {
                this.files.remove(name);
            }
            this.getChildren().remove(item);
        }
        
        FileTreeItem getDir(final String name) {
            return this.dirs.get(name);
        }
        
        boolean hasDir(final String name) {
            return this.dirs.containsKey(name);
        }
        
        FileTreeItem getFile(final String name) {
            return this.files.get(name);
        }
        
        @Override
        public int compareTo(final String s) {
            return this.getValue().compareTo(s);
        }
    }
}

CXVUSER avatar Aug 19 '22 04:08 CXVUSER