All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.walkmod.javalang.compiler.actions.RemoveUnusedSymbolsAction Maven / Gradle / Ivy

There is a newer version: 2.3.7
Show newest version
/*
 * Copyright (C) 2015 Raquel Pau and Albert Coroleu.
 * 
 * Walkmod is free software: you can redistribute it and/or modify it under the terms of the GNU
 * Lesser General Public License as published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * 
 * Walkmod is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License along with Walkmod. If
 * not, see .
 */
package org.walkmod.javalang.compiler.actions;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.walkmod.javalang.ast.ImportDeclaration;
import org.walkmod.javalang.ast.Node;
import org.walkmod.javalang.ast.body.FieldDeclaration;
import org.walkmod.javalang.ast.body.MethodDeclaration;
import org.walkmod.javalang.ast.body.ModifierSet;
import org.walkmod.javalang.ast.body.TypeDeclaration;
import org.walkmod.javalang.ast.body.VariableDeclarator;
import org.walkmod.javalang.ast.expr.Expression;
import org.walkmod.javalang.ast.expr.LiteralExpr;
import org.walkmod.javalang.ast.expr.NameExpr;
import org.walkmod.javalang.ast.expr.VariableDeclarationExpr;
import org.walkmod.javalang.compiler.symbols.ReferenceType;
import org.walkmod.javalang.compiler.symbols.Symbol;
import org.walkmod.javalang.compiler.symbols.SymbolAction;
import org.walkmod.javalang.compiler.symbols.SymbolTable;

public class RemoveUnusedSymbolsAction extends SymbolAction {

    private List siblings;

    public RemoveUnusedSymbolsAction(List container) {
        this.siblings = container;
    }

    @Override
    public void doPop(Symbol symbol, SymbolTable table) {

        Node n = symbol.getLocation();
        if (n != null) {
            Map attrs = symbol.getAttributes();

            Object reads = attrs.get(ReferencesCounterAction.READS);

            Object writes = attrs.get(ReferencesCounterAction.WRITES);

            if (reads == null && writes == null) {
                if (n instanceof MethodDeclaration) {
                    removeMethod(symbol, table);
                } else if (n instanceof VariableDeclarator) {
                    Node parentNode = n.getParentNode();
                    if (parentNode != null) {
                        if (parentNode instanceof FieldDeclaration) {
                            removeField(symbol, table, (FieldDeclaration) parentNode);
                        } else {
                            removeVariable(symbol, table, (VariableDeclarationExpr) parentNode);
                        }
                    }

                } else if (n instanceof TypeDeclaration) {
                    Symbol thisSymbol = table.findSymbol("this", ReferenceType.VARIABLE);
                    if (symbol.getReferenceType().equals(ReferenceType.TYPE) && thisSymbol != null
                            && !thisSymbol.getType().equals(symbol.getType())) {
                        removeType(symbol, table);
                    }
                } else if (n instanceof ImportDeclaration) {
                    removeImport(symbol, table);
                }
            }
        }
    }

    public List getSiblings() {
        return siblings;
    }

    public void removeImport(Symbol symbol, SymbolTable table) {
        ImportDeclaration id = (ImportDeclaration) symbol.getLocation();
        if (id.isAsterisk() || id.isStatic()) {

            String type = id.getName().toString();
            if (!id.isAsterisk()) {
                int pos = type.lastIndexOf('.');
                type = type.substring(0, pos);
            }
            List> symbols = table.findSymbolsByType(type, ReferenceType.TYPE);
            boolean used = false;
            List> staticElems = null;
            if (id.isStatic()) {
                staticElems = table.findSymbolsByLocation(id);
            }
            Iterator> it = symbols.iterator();
            while (it.hasNext() && !used) {
                Symbol candidate = it.next();

                if (id.isStatic()) {

                    Iterator> itStatic = staticElems.iterator();
                    while (itStatic.hasNext() && !used) {
                        Symbol staticElem = itStatic.next();

                        ReferenceType rt = staticElem.getReferenceType();
                        if (rt.equals(ReferenceType.METHOD) || rt.equals(ReferenceType.VARIABLE)) {
                            Map attrs = staticElem.getAttributes();
                            Object reads = attrs.get(ReferencesCounterAction.READS);
                            Object writes = attrs.get(ReferencesCounterAction.WRITES);
                            used = (reads != null || writes != null);
                        }

                    }

                    if (!used) {
                        Map attrs = candidate.getAttributes();
                        Object reads = attrs.get(ReferencesCounterAction.READS);
                        used = (reads != null);
                    }
                }
            }
            if (!used) {
                remove(id);
            }
        } else {
            String type = id.getName().toString();
            // internal classes
            List> symbols = table.findSymbolsByType(type, ReferenceType.TYPE);
            boolean used = false;
            Iterator> it = symbols.iterator();
            while (it.hasNext() && !used) {
                Symbol next = it.next();
                Map attrs = next.getAttributes();
                Object reads = attrs.get(ReferencesCounterAction.READS);
                Object writes = attrs.get(ReferencesCounterAction.WRITES);
                used = (reads != null || writes != null);
            }
            if (!used) {
                remove(id);
            }
        }
    }

    private void remove(Object o) {
        Iterator it = siblings.iterator();
        boolean removed = false;
        while (it.hasNext() && !removed) {
            Node aux = it.next();
            if (aux == o) { // yes, by reference
                it.remove();
                removed = true;
            }
        }
    }

    public void removeMethod(Symbol symbol, SymbolTable table) {
        MethodDeclaration md = (MethodDeclaration) symbol.getLocation();

        int modifiers = md.getModifiers();
        if (ModifierSet.isPrivate(modifiers)) {
            remove(md);
        }
    }

    public void removeType(Symbol symbol, SymbolTable table) {
        TypeDeclaration td = (TypeDeclaration) symbol.getLocation();
        int modifiers = td.getModifiers();
        if (ModifierSet.isPrivate(modifiers)) {
            remove(td);
        }
    }

    public void removeVariable(Symbol symbol, SymbolTable table, VariableDeclarationExpr vd) {

        List vds = vd.getVars();
        if (vds.size() == 1) {
            Expression init = vds.get(0).getInit();
            if (isReadOnlyExpression(init)) {
                remove(vd.getParentNode());
            }
        } else {
            Iterator it = vds.iterator();
            boolean finish = false;
            while (it.hasNext() && !finish) {
                VariableDeclarator current = it.next();
                if (current.getId().getName().equals(symbol.getName())) {
                    if (isReadOnlyExpression(current.getInit())) {
                        finish = true;
                        it.remove();
                    }
                }
            }
        }
    }

    private boolean isReadOnlyExpression(Expression init) {
        return (init == null || init instanceof LiteralExpr || init instanceof NameExpr);
    }

    public void removeField(Symbol symbol, SymbolTable table, FieldDeclaration fd) {

        int modifiers = fd.getModifiers();
        if (ModifierSet.isPrivate(modifiers)) {
            List vds = fd.getVariables();
            if (vds != null) {
                Iterator it = vds.iterator();
                while (it.hasNext()) {
                    VariableDeclarator vd = it.next();
                    if (vd.getId().getName().equals(symbol.getName())) {
                        Expression init = vd.getInit();
                        if (isReadOnlyExpression(init)) {
                            if (vds.size() == 1) {
                                remove(fd);
                            } else {
                                it.remove();
                            }
                        }
                    }
                }
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy