Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cleanup to make use of text blocks leaves out many cases #1703

Closed
carstenartur opened this issue Oct 6, 2024 · 8 comments
Closed

cleanup to make use of text blocks leaves out many cases #1703

carstenartur opened this issue Oct 6, 2024 · 8 comments

Comments

@carstenartur
Copy link
Contributor

Many cases are not covered by the cleanup to make use of text blocks

                StringBuilder buf= new StringBuilder();
		buf.append("package test1;\n");
		buf.append("public class E1 {\n");
		buf.append("    FI fi= (Integer i, String[][] s) -> {};\n"); // no varargs
		buf.append("}\n");
		buf.append("interface FI {\n");
		buf.append("    void foo(Integer i, String[]... s);\n");
		buf.append("}\n");
		assertNumberOfProposals(proposals, 2);
		assertCorrectLabels(proposals);

		String expected1= buf.toString();

Many more examples at
#1702

@jjohnstn
Copy link
Contributor

jjohnstn commented Oct 8, 2024

Looking at the examples, there are two situations:

  1. There is a line comment in the append that specifies a particular append line. This cannot be put into a text block and is meaningless if moved. NLS comments are supported if on all lines.
  2. There are calls to indexOf() after the toString() call. The current logic doesn't convert if the buffer is used for other things or other calls to it. It happens that indexOf() is also supported by a String so this could be done.

@carstenartur
Copy link
Contributor Author

Looking at the examples, there are two situations:

  1. There is a line comment in the append that specifies a particular append line. This cannot be put into a text block and is meaningless if moved. NLS comments are supported if on all lines.

So for long sections it would be possible to either have multiple text blocks or use something similar to printf on the resulting block to insert the particular append line. I agree this is no easy addition, maybe not worth it.

  1. There are calls to indexOf() after the toString() call. The current logic doesn't convert if the buffer is used for other things or other calls to it. It happens that indexOf() is also supported by a String so this could be done.

Yes, cool approach.

I closed the PR that shows the use cases. I think it is still visible but not in the list of active prs.

@jjohnstn
Copy link
Contributor

Looking at the examples, there are two situations:

  1. There is a line comment in the append that specifies a particular append line. This cannot be put into a text block and is meaningless if moved. NLS comments are supported if on all lines.

So for long sections it would be possible to either have multiple text blocks or use something similar to printf on the resulting block to insert the particular append line. I agree this is no easy addition, maybe not worth it.

I don't think breaking up the text block is the answer. I don't know how but it might be worth contacting the language standard people to let then know about such a scenario and see if they could put in a line comment equivalent that would be ignored by the text block.

The other way of doing this would be to subsume comments into the text block since in this case we are dealing with code sequences and adding a line comment within the string would be reasonable. Impossible to guess with a cleanup but perhaps could be done as a quick fix so the user could tell you manually they want that.

For example:

    StringBuilder buf = new StringBuilder();
    buf.append("package p;\n");
    buf.append("public class A {\n");
    buf.append("    public void foo() {\n");
    buf.append("        int a = b;\n");  // here is where the compiler error is
    buf.append("    }\n");
    buf.append("}\n");
    String x = buf.toString();

gets converted to:

    String x = """
        package p;
        public class A {
            public void foo() {
                int a = b;  // here is where the compiler error is
            }
        }
        """;
  
  1. There are calls to indexOf() after the toString() call. The current logic doesn't convert if the buffer is used for other things or other calls to it. It happens that indexOf() is also supported by a String so this could be done.

Yes, cool approach.

I closed the PR that shows the use cases. I think it is still visible but not in the list of active prs.

I alread7 have a patch for the indexOf support. I am on vacation but will push it up shortly. If the indexOf() call is in the middle of a bunch of appends it won't convert but it allows the indexOf to be before or after the toString()/implicit toString() call.

jjohnstn added a commit to jjohnstn/eclipse.jdt.ui-1 that referenced this issue Oct 10, 2024
- add new support to StringConcatToTextBlockFixCore to allow
  an indexOf call for StringBuilder/StringBuffer which can also work
  on a String once the conversion is complete (change the variable
  name of the indexOf call appropriately)
- add new tests to StringConcatToTextBlockFixCore
- for eclipse-jdt#1703
@carstenartur
Copy link
Contributor Author

There are some more cases where the cleanup is failing.
Try it on the file
https://github.com/carstenartur/sandbox/blob/main/sandbox_functional_converter_test/src/org/sandbox/jdt/ui/tests/quickfix/Java8CleanUpTest.java
or just look at it right now as it is already the result of a partly fail.
You see that starting with line 772 it did not work.

jjohnstn added a commit that referenced this issue Oct 12, 2024
* Enhance StringBuilder to text block cleanup to support indexOf

- add new support to StringConcatToTextBlockFixCore to allow
  an indexOf call for StringBuilder/StringBuffer which can also work
  on a String once the conversion is complete (change the variable
  name of the indexOf call appropriately)
- add new tests to CleanUpTest15 and AssistQuickFixTest15
- for #1703
@jjohnstn
Copy link
Contributor

Hi @carstenartur It appears that adding the empty string at the end is causing the cleanup to bail (removal of empty strings as last concatenation makes it work). I will make a patch to fix this.

jjohnstn added a commit to jjohnstn/eclipse.jdt.ui-1 that referenced this issue Oct 15, 2024
- add logic to StringConcatToTextBlockFixCore to handle the case where
  empty strings are appended
- modify tests in CleanUpTest15 to add some empty strings to existing
  tests
- for eclipse-jdt#1703
jjohnstn added a commit that referenced this issue Oct 15, 2024
…1717)

- add logic to StringConcatToTextBlockFixCore to handle the case where
  empty strings are appended
- modify tests in CleanUpTest15 to add some empty strings to existing
  tests
- for #1703
@jjohnstn
Copy link
Contributor

Hi @carstenartur let me know if there are other scenarios. It would be preferable to open separate specific issues for them and close this one as it makes it easier for end-users to track if their problem is the same.

@carstenartur
Copy link
Contributor Author

Yes, of course. Let's close this one for being able to distinguish different use cases. There are more issues e.g. a case where the the formatting cleanup makes a sequence of text blocks indent each one a little bit more until the text blocks end up with hundreds of leading spaces. When I come to that point I can create another issue.
Thank you very much so far!

@jjohnstn
Copy link
Contributor

Thanks @carstenartur. I am hoping to get your big explicit encoding feature into M2 this week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants