Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Code formatting using shell script

I know this is silly but I can't overcome my curiosity. Is it possible to write a shell script to format a piece of java code?

For example, if a user writes in a code:

    public class Super{
    public static void main(String[] args){
    System.out.println("Hello world");
    int a=0;
    if(a==100)
    {
    System.out.println("Hello world");
    }
    else
    {
    System.out.println("Hello world with else");
    }
    }
}

I would like to write a shell script which would make the code like this.

 public class Super
 {
  public static void main(String[] args)
  {
   System.out.println("Hello world");
   int a=0;
   if(a==100){
    System.out.println("Hello world");
   }
   else{
    System.out.println("Hello world with else");
   }
}

To be precise, we should change the formatting of flower brackets. If it is try/catch or control structures we should change it to same line and if it is function/method/class it should come in next line.I have little knowledge about sed and awk which can do this task so easily. Also I know this can be done using eclipse.

like image 735
Harish Avatar asked Jul 16 '09 14:07

Harish


People also ask

How do I format Java code?

Go to Source | Format Document or press Ctrl+Shift+F.

How do I format a shell file?

There are two ways to format your code: Automatically format on save (requires enabling in Packages → Format Shell → Toggle Format on Save) Run the command Format Shell: Format to invoke shfmt manually.

What is shell script in Java?

Shell Scripting is an open-source operating system. Our Shell Scripting tutorial includes all topics of Scripting executing scripting, loops, scripting parameters, shift through parameters, sourcing, getopts, case, eval, let etc.


2 Answers

Well, I've had some free time on my hands, so I decided to relive my good old linux days :]

After reading a bit about awk and sed, I've decided that it might be better to use both, as it is easier to add indentation in awk and parse strings in sed.

Here is the ~/sed_script that formats the source file:

    # delete indentation
    s/^ \+//g

    # format lines with class
    s/^\(.\+class.\+\) *\({.*\)$/\1\n\2/g

    # format lines with methods
    s/^\(public\|private\)\( \+static\)\?\( \+void\)\? \+\(.\+(.*)\) *\({.*\)$/\1\2\3 \4\n\5/g

    # format lines with other structures
    /^\(if\|else\|for\|while\|case\|do\|try\)\([^{]*\)$/,+1 {   # get lines not containing '{'
                                                            # along with the next line
      /.*{.*/ d             # delete the next line with '{'
      s/\([^{]*\)/\1 {/g    # and add '{' to the first line
    }

And here is the ~/awk_script that adds indentation:

    BEGIN { depth = 0 }
    /}/   { depth = depth - 1 }
          {
              getPrefix(depth)
              print prefix $0
          }
    /{/   { depth = depth + 1 }

          function getPrefix(depth) {
              prefix = ""
              for (i = 0; i < depth; i++) { prefix = prefix "    "}
              return prefix
          }

And you use them like that:

    > sed -f ~/sed_script ~/file_to_format > ~/.tmp_sed
    > awk -f ~/awk_script ~/.tmp_sed

It is far from proper formatting tool, but I hope it will do OK as a sample script for reference :] Good luck with your learning.

like image 196
Kirill Strizhak Avatar answered Sep 30 '22 13:09

Kirill Strizhak


A quick, flawed attempt, but one that works on your sample input:

BEGIN {depth = 0;}
/{$/  {depth = depth + 1}
/^}/  {depth = depth - 1}
      {prefix = ""; for (i = 0; i < depth; i++) { prefix = prefix "  "} print prefix $0 ; }

This is an awk script: place it in a file and do

awk -f awk_script_file source_file

Obvious flaws with this include:

  • It doesn't catch braceless places where you'd like indentation like

    if (foo)
      bar();
    
  • It will modify the indent depth based on braces in comments and string literals

  • It won't detect { braces followed by comments
like image 32
Sbodd Avatar answered Sep 30 '22 15:09

Sbodd