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

net.minecraftforge.gradle.tasks.RemapSourcesTask Maven / Gradle / Ivy

package net.minecraftforge.gradle.tasks;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.minecraftforge.gradle.StringUtils;
import net.minecraftforge.gradle.common.Constants;
import net.minecraftforge.gradle.delayed.DelayedFile;
import net.minecraftforge.gradle.tasks.abstractutil.EditJarTask;

import org.gradle.api.tasks.InputFile;

import au.com.bytecode.opencsv.CSVParser;
import au.com.bytecode.opencsv.CSVReader;

import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.io.Files;

public class RemapSourcesTask extends EditJarTask
{
    @InputFile
    private DelayedFile                            methodsCsv;

    @InputFile
    private DelayedFile                            fieldsCsv;

    @InputFile
    private DelayedFile                            paramsCsv;
    
    private boolean doesJavadocs = false;
    private boolean noJavadocs = false;

    private final Map> methods    = new HashMap>();
    private final Map> fields     = new HashMap>();
    private final Map              params     = new HashMap();

    private static final Pattern                   SRG_FINDER = Pattern.compile("(func_[0-9]+_[a-zA-Z_]+|field_[0-9]+_[a-zA-Z_]+|p_[\\w]+_\\d+_)([^\\w\\$])");
    private static final Pattern                   METHOD     = Pattern.compile("^((?: {4})+|\\t+)(?:[\\w$.\\[\\]]+ )+(func_[0-9]+_[a-zA-Z_]+)\\(");
    private static final Pattern                   FIELD      = Pattern.compile("^((?: {4})+|\\t+)(?:[\\w$.\\[\\]]+ )+(field_[0-9]+_[a-zA-Z_]+) *(?:=|;)");

    @Override
    public void doStuffBefore() throws Throwable
    {
        readCsvFiles();
    }

    @Override
    public String asRead(String text)
    {
        Matcher matcher;
        ArrayList newLines = new ArrayList();
        for (String line : StringUtils.lines(text))
        {
            if (noJavadocs) // noajavadocs? dont bothe with the rest of this crap...
            {
                newLines.add(replaceInLine(line));
                continue;
            }
            
            
            matcher = METHOD.matcher(line);
            if (matcher.find())
            {
                String name = matcher.group(2);

                if (methods.containsKey(name) && methods.get(name).containsKey("name"))
                {
                    String javadoc = methods.get(name).get("javadoc");
                    if (!Strings.isNullOrEmpty(javadoc))
                    {
                        if (doesJavadocs)
                            javadoc = buildJavadoc(matcher.group(1), javadoc, true);
                        else
                            javadoc = matcher.group(1) + "// JAVADOC METHOD $$ " + name;
                        insetAboveAnnotations(newLines, javadoc);
                    }
                }
            }
            else if (line.trim().startsWith("// JAVADOC "))
            {
                Matcher match = SRG_FINDER.matcher(line);
                if (match.find())
                {
                    String indent = line.substring(0, line.indexOf("// JAVADOC"));
                    String name = match.group();
                    if (name.startsWith("func_"))
                    {
                        Map mtd = methods.get(name);
                        if (mtd != null && !Strings.isNullOrEmpty(mtd.get("javadoc")))
                        {
                            line = buildJavadoc(indent, mtd.get("javadoc"), true);
                        }
                    }
                    else if (name.startsWith("field_"))
                    {
                        Map fld = fields.get(name);
                        if (fld != null && !Strings.isNullOrEmpty(fld.get("javadoc")))
                        {
                            line = buildJavadoc(indent, fld.get("javadoc"), true);
                        }
                    }

                    if (line.endsWith(Constants.NEWLINE))
                    {
                        line = line.substring(0, line.length() - Constants.NEWLINE.length());
                    }
                }
            }
            else
            {
                matcher = FIELD.matcher(line);
                if (matcher.find())
                {
                    String name = matcher.group(2);
                    if (fields.containsKey(name))
                    {
                        String javadoc = fields.get(name).get("javadoc");
                        if (!Strings.isNullOrEmpty(javadoc))
                        {
                            if (doesJavadocs)
                                javadoc = buildJavadoc(matcher.group(1), javadoc, false);
                            else
                                javadoc = matcher.group(1) + "// JAVADOC FIELD $$ " + name;
                            insetAboveAnnotations(newLines, javadoc);
                        }
                    }
                }
            }
            newLines.add(replaceInLine(line));
        }

        return Joiner.on(Constants.NEWLINE).join(newLines);
    }
    
    private void insetAboveAnnotations(List list, String line)
    {
        int back = 0;
        while (list.get(list.size() - 1 - back).trim().startsWith("@"))
        {
            back++;
        }
        list.add(list.size() - back, line);
    }
    
    private String replaceInLine(String line)
    {
        // FAR all methods
        StringBuffer buf = new StringBuffer();
        Matcher matcher = SRG_FINDER.matcher(line);
        while (matcher.find())
        {
            String find = matcher.group(1);
            
            if (find.startsWith("p_"))
                find = params.get(find);
            else if (find.startsWith("func_"))
                find = stupidMacro(methods, find);
            else if (find.startsWith("field_"))
                find = stupidMacro(fields, find);
            
            if (find == null)
                find = matcher.group(1);
            
            matcher.appendReplacement(buf, find);
            buf.append(matcher.group(2));
        }
        matcher.appendTail(buf);
        return buf.toString();
    }

    private String stupidMacro(Map> map, String key)
    {
        Map s = map.get(key);
        return s == null ? null : s.get("name");
    }

    private void readCsvFiles() throws IOException
    {
        CSVReader reader = getReader(getMethodsCsv());
        for (String[] s : reader.readAll())
        {
            Map temp = new HashMap();
            temp.put("name", s[1]);
            temp.put("javadoc", s[3]);
            methods.put(s[0], temp);
        }

        reader = getReader(getFieldsCsv());
        for (String[] s : reader.readAll())
        {
            Map temp = new HashMap();
            temp.put("name", s[1]);
            temp.put("javadoc", s[3]);
            fields.put(s[0], temp);
        }

        reader = getReader(getParamsCsv());
        for (String[] s : reader.readAll())
        {
            params.put(s[0], s[1]);
        }
    }

    public static CSVReader getReader(File file) throws IOException
    {
        return new CSVReader(Files.newReader(file, Charset.defaultCharset()), CSVParser.DEFAULT_SEPARATOR, CSVParser.DEFAULT_QUOTE_CHARACTER, CSVParser.DEFAULT_ESCAPE_CHARACTER, 1, false);
    }

    private String buildJavadoc(String indent, String javadoc, boolean isMethod)
    {
        StringBuilder builder = new StringBuilder();

        if (javadoc.length() >= 70 || isMethod)
        {
            List list = wrapText(javadoc, 120 - (indent.length() + 3));

            builder.append(indent);
            builder.append("/**");
            builder.append(Constants.NEWLINE);

            for (String line : list)
            {
                builder.append(indent);
                builder.append(" * ");
                builder.append(line);
                builder.append(Constants.NEWLINE);
            }

            builder.append(indent);
            builder.append(" */");
            //builder.append(Constants.NEWLINE);

        }
        // one line
        else
        {
            builder.append(indent);
            builder.append("/** ");
            builder.append(javadoc);
            builder.append(" */");
            //builder.append(Constants.NEWLINE);
        }

        return builder.toString().replace(indent, indent);
    }

    private static List wrapText(String text, int len)
    {
        // return empty array for null text
        if (text == null)
        {
            return new ArrayList();
        }

        // return text if len is zero or less
        if (len <= 0)
        {
            return new ArrayList(Arrays.asList(text));
        }

        // return text if less than length
        if (text.length() <= len)
        {
            return new ArrayList(Arrays.asList(text));
        }

        List lines = new ArrayList();
        StringBuilder line = new StringBuilder();
        StringBuilder word = new StringBuilder();
        int tempNum;

        // each char in array
        for (char c : text.toCharArray())
        {
            // its a wordBreaking character.
            if (c == ' ' || c == ',' || c == '-')
            {
                // add the character to the word
                word.append(c);

                // its a space. set TempNum to 1, otherwise leave it as a wrappable char
                tempNum = Character.isWhitespace(c) ? 1 : 0;

                // subtract tempNum from the length of the word
                if ((line.length() + word.length() - tempNum) > len)
                {
                    lines.add(line.toString());
                    line.delete(0, line.length());
                }

                // new word, add it to the next line and clear the word
                line.append(word);
                word.delete(0, word.length());

            }
            // not a linebreak char
            else
            {
                // add it to the word and move on
                word.append(c);
            }
        }

        // handle any extra chars in current word
        if (word.length() > 0)
        {
            if ((line.length() + word.length()) > len)
            {
                lines.add(line.toString());
                line.delete(0, line.length());
            }
            line.append(word);
        }

        // handle extra line
        if (line.length() > 0)
        {
            lines.add(line.toString());
        }

        List temp = new ArrayList(lines.size());
        for (String s : lines)
        {
            temp.add(s.trim());
        }
        return temp;
    }

    public File getMethodsCsv()
    {
        return methodsCsv.call();
    }

    public void setMethodsCsv(DelayedFile methodsCsv)
    {
        this.methodsCsv = methodsCsv;
    }

    public File getFieldsCsv()
    {
        return fieldsCsv.call();
    }

    public void setFieldsCsv(DelayedFile fieldsCsv)
    {
        this.fieldsCsv = fieldsCsv;
    }

    public File getParamsCsv()
    {
        return paramsCsv.call();
    }

    public void setParamsCsv(DelayedFile paramsCsv)
    {
        this.paramsCsv = paramsCsv;
    }
    
    public boolean doesJavadocs()
    {
        return doesJavadocs;
    }

    public void setDoesJavadocs(boolean javadoc)
    {
        this.doesJavadocs = javadoc;
    }
    
    public void setNoJavadocs()
    {
        noJavadocs = true;
    }

    @Override
    public void doStuffAfter() throws Throwable
    {
    }

    @Override
    public void doStuffMiddle() throws Throwable
    {
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy