Vineflower / vineflower

Modern Java decompiler aiming to be as accurate as possible, with an emphasis on output quality. Fork of the Fernflower decompiler.
https://vineflower.org/
Apache License 2.0
1.25k stars 88 forks source link

"Variable is already defined in the scope" error #258

Open zsrv opened 1 year ago

zsrv commented 1 year ago

Version: Quiltflower 1.10.0 (commit 1736a2c41f7a5cade89b1f3aa602b30778644920)

Original code:

import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;

public class Example {
    public static Transformer newTransformer() {
        return null;
    }

    public String myMethod() {
        Source source = null;
        try {
            if (source == null) {
                String string = null;
                return string;
            }
            StringWriter stringWriter = new StringWriter();
            StreamResult streamResult = new StreamResult(stringWriter);
            newTransformer().transform(source, streamResult);
            String string = stringWriter.getBuffer().toString();
            return string;
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
        finally {
            if (source != null) {
                System.out.println(".");
            }
        }
    }
}

Quiltflower output:

import java.io.StringWriter;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.stream.StreamResult;

public class Example {
   public static Transformer newTransformer() {
      return null;
   }

   public String myMethod() {
      Source source = null;

      String streamResult;
      try {
         if (source != null) {
            StringWriter stringWriter = new StringWriter();
            StreamResult streamResult = new StreamResult(stringWriter);
            newTransformer().transform(source, streamResult);
            return stringWriter.getBuffer().toString();
         }

         String string = null;
         streamResult = string;
      } catch (Exception var9) {
         throw new RuntimeException(var9);
      } finally {
         if (source != null) {
            System.out.println(".");
         }
      }

      return streamResult;
   }
}

The output results in this error:

Variable 'streamResult' is already defined in the scope
jaskarth commented 1 year ago

Thanks for the helpful bug report and reproducer! Here is an interim fix: 2ce18b7 The issue seems to be related to variables being re-defined using values from the LVT when they aren't supposed to, which needs a deeper look into.