Emacs enum indentation - java

I'm having a problem with Emacs's indentation of Java enums. While it indents the first member OK, it wants to give all of the rest of the static enum members an additional level of indentation. It looks like this:
class MyClass {
public enum MyEnum {
ONE(1), //good
TWO(2), // not good!
THREE(3),
FOUR(4);
private final int value;
}
}
When I run C-c C-s on the line that opens the enum, it gives me ((inclass 1) (topmost-intro 1)), which doesn't seem quite right -- it seems like it should be giving brace-list-open. When I run it on the first enum member, it gives me ((defun-block-intro 21)), which is definitely not right. Every subsequent member gives (statement-cont 50).
I'm in java-mode and I'm using the java style of indentation. Does anyone know what the problem might be?

The problem is that Emacs doesn't support Java language features added in 1.5 or later. You will also have problems with generics, for instance.
EDIT: Amazingly, searching Google for "java enum site:debbugs.gnu.org" gives no results. I suggest filing a bug.

The same problem existed in csharp-mode until last week. The way I fixed it was to add a new matcher in the c-basic-matchers-after setting for the csharp language. The new matcher looks like this:
;; Case 2: declaration of enum with or without an explicit base type
,#(when t
`((,(byte-compile
`(lambda (limit)
(let ((parse-sexp-lookup-properties
(cc-eval-when-compile
(boundp 'parse-sexp-lookup-properties))))
(while (re-search-forward
,(concat csharp-enum-decl-re
"[ \t\n\r\f\v]*"
"{")
limit t)
(unless
(progn
(goto-char (match-beginning 0))
(c-skip-comments-and-strings limit))
(progn
(save-match-data
(goto-char (match-end 0))
(c-put-char-property (1- (point))
'c-type
'c-decl-id-start)
(c-forward-syntactic-ws))
(save-match-data
(c-font-lock-declarators limit t nil))
(goto-char (match-end 0))
)
)))
nil))
)))
where csharp-enum-decl-re is defined as
(defconst csharp-enum-decl-re
(concat
"\\<enum[ \t\n\r\f\v]+"
"\\([[:alpha:]_][[:alnum:]_]*\\)"
"[ \t\n\r\f\v]*"
"\\(:[ \t\n\r\f\v]*"
"\\("
(c-make-keywords-re nil
(list "sbyte" "byte" "short" "ushort" "int" "uint" "long" "ulong"))
"\\)"
"\\)?")
"Regex that captures an enum declaration in C#"
)
What this does is set a text property on the brace-open after an enum declaration line. That text property tells cc-mode to indent the contents of the brace list differently. As a "brace list". Setting that property gets brace-list-open on the following line.
Maybe something similar will work for you.
You could customize the matchers for java yourself, with something like this, and If you open a bug, you could submit this as a suggested fix.
In C#, enums can derive from any integer type. so,
public enum MyEnumType : uint
{
ONE = 1,
TWO,
THREE,
}
I think that in Java there is no such possibility. If so, the Java regex would be much simpler than the regex I used for C#.
Whoops! It just occurred to me, that with Java's simpler syntax, there is also the possibility that you can turn on brace-lists, just by setting the enum keyword in the right language constant. If that's so, then the solution for you could be as simple as:
(c-lang-defconst c-inexpr-brace-list-kwds
java '("enum"))
This didn't work for C# because of its more complex syntax.
EDIT - no that didn't work. It's more complicated than that.

The CVS version of CC-mode does indeed contain the necessary fixes, as Nathaniel Flath mentioned earlier. It is easy to install. Just check it out from here (let's say, into ~/.emacs.d/cc-mode), byte-compile, as explained in readme, and add to load path by adding (add-to-list 'load-path "~/.emacs.d/cc-mode") to your ~/.emacs.d/init.el. Then enum indentation works like a charm !

You can try using JDEE - I heard that they were planning to include some Java 6 support. Or if you're more adventurous you could try out malabar-mode, which claims to be a better java mode than JDEE. Funny enough the last commit in malabar(from a day ago) has the following message - "Fix enum constant indentation" :-)

Related

How to abbreviate "number of <items>" in source code?

I'm new to learning Java and I'm bad at English but I try my best to write good, understandable source code.
I want to make variables to save the "number of cars" or "number of items". How do I abbreviate "number of ..." without using symbols like # that don't work in a source code?
Thanks
You have several choices to do that
numberOfItems (verbose, but clear in meaning)
numItems (it's ok)
itemCount (probably, the best — what I'd have used)
items (shortest, but can't know if it is an integer or a list of items)
I try my best to write good, understandable source code
Then my best advice would be not to abbreviate variable names.
Just go with numberOfCars.
Why?
I know you've probably seen a lot of programs where people use one-letter variables or stuff like numCars.
Abbreviating your variables make your code less clear for others (including you in 6 months).
We all have great text editors with auto-completion on variables, use that.

Finding Object in Array of Arrays based in Sub-Object condition

I need to find a object in java based in the property of its many subojects.
What I currently have is ugly as hell and I'm sure there's a more efficient way to do so.
Probably with a library like hamcrest, or maybe directly with Java (my knowledge in Java is not the best).
This is what I have so far:
private HotelResult findHotelResult(List<HotelResult> hotelResultsList, HotelSelection hotelSelection) {
for (HotelResult hotelResult : hotelResultsList)
for (RoomOption roomOption : hotelResult.getRoomOptions())
for (RoomTypeIds roomTypeIds : roomOption.getRoomTypeIds())
for (RoomRateIds roomRateIds : roomTypeIds.getRoomRateIds())
if ( roomRateIds.getId().equals(hotelSelection.getResultId()) )
return hotelResult;
(...)
}
Thank you in advance.
Try this if you are using Java 8 o higher...
private HotelResult findHotelResult(List<HotelResult> hotelResultsList, HotelSelection hotelSelection) {
Optional<HotelResult> found = hotelResultsList.stream().filter((r) -> {
Optional<RoomRateIds> optId = r.getRoomOptions().stream().flatMap(o -> o.getRoomTypeIds().stream())
.flatMap(rate -> rate.getRoomRateIds().stream())
.filter(id -> id.getId().equals(hotelSelection.getResultId())).findFirst();
return optId.isPresent();
}).findFirst();
return found.orElse(null);
}
There is no more efficient way of doing so, at least not without re-organizing your data model from what it currently is into something completely different.
There is nothing wrong with nice, cleanly laid out nested loops, making very clear what is happening. You could perhaps replace them with a sequence of forEach( ...forEach( ... forEach( ... ) ) ) but then you will have an undecipherable tangle of parentheses to deal with, the purpose of the code will be less clear, debugging the code will become next to impossible, and performance will suffer.
The only thing that could be improved in the code that you have shown us would be to either get rid of the unnecessary blank lines, or get rid of the egyptian-style curly braces, or both, since every single curly brace in that code is unnecessary.
That, alone, might make the code look less as if it could use some improvement. Since it doesn't.

BigDecimal notation eclipse plugin or nice external tool

I need to make a lot of operations using BigDecimal, and I found having to express
Double a = b - c * d; //natural way
as
BigDecimal a = b.subtract(c.multiply(d))//BigDecimal way
is not only ugly, but a source of mistakes and communication problems between me and business analysts. They were perfectly able to read code with Doubles, but now they can't.
Of course a perfect solution will be java support for operator overloading, but since this not going to happen, I'm looking for an eclipse plugin or even an external tool that make an automatic conversion from "natural way" to "bigdecimal way".
I'm not trying to preprocess source code or dynamic translation or any complex thing, I just want something I can input text and get text, and keep the "natural way" as a comment in source code.
P.S.: I've found this incredible smart hack but I don't want to start doing bytecode manipulation. Maybe I can use that to create a Natural2BigDecimal translator, but I don't want to reinvent the wheel if someone has already done such a tool.
I don't want to switch to Scala/Groovy/JavaScript and I also can't, company rules forbid anything but java in server side code.
"I'm not trying to preprocess source code ... I just want something I can input [bigDecimal arithmetic expression] text".
Half of solving a problem is recognizing the problem for what it is. You exactly want something to preprocess your BigDecimal expressions to produce legal Java.
You have only two basic choices:
A stand-alone "domain specific language" and DSL compiler that accepts "standard" expressions and converts them directly to Java code. (This is one kind of preprocessor). This leaves you with the problem of keeping all the expression fragments around, and somehow knowing where to put them in the Java code.
A tool that reads the Java source text, finds such expressions, and converts them to BigDecimal in the text. I'd suggest something that let you code the expressions outside the actual code and inserted the translation.
Perhaps (stolen from another answer):
// BigDecimal a = b - c * d;
BigDecimal a = b.subtract( c.multiply( d ) );
with the meaning "compile the big decimal expression in the comment into its java equivalent, and replace the following statement with that translation.
To implement the second idea, you need a program transformation system, which can apply source-to-source rewriting rules to transforms (generate as a special case of transform) the code. This is just a preprocessor that is organized to be customizable to your needs.
Our DMS Software Reengineering Toolkit with its Java Front End could do this. You need a full Java parser to do that transformation part; you'll want name and type resolution so that you can parse/check the proposed expression for sanity.
While I agree that the as-is Java notation is ugly, and your proposal would make it prettier, my personal opinion is this isn't worth the effort. You end up with a dependency on a complex tool (yes, DMS is complex: manipulating code isn't easy) for a rather marginal gain.
If you and your team wrote thousands of these formulas, or the writers of such formulas were Java-naive it might make sense. In that case,
I'd go further, and simply insist you write the standard expression format where you need it. You could customize the Java Front End to detect when the operand types were of decimal type, and do the rewriting for you. Then you simply run this preprocessor before every Java compilation step.
I agree, it's very cumbersome! I use proper documentation (comments before each equation) as the best "solution" to this.
// a = b - c * d;
BigDecimal a = b.subtract( c.multiply( d ) )
You might go the route of an expression evaluator. There is a decent (albeit paid) one at http://www.singularsys.com/jep. Antlr has a rudimentary grammar that also does expression evaluation (tho I am not sure how it would perform) at http://www.antlr.org/wiki/display/ANTLR3/Expression+evaluator.
Neither would give you the compile-time safety you would have with true operators. You could also write the various algorithm-based classes in something like Scala, which does support operator overloading out of the box and would interoperate seamlessly with your other Java classes.

Java-Mode Argument Indenting in Emacs

My java-mode in emacs wants to indent function arguments like this:
someLongFunctionName(
argumentNumberOne,
argumentNumberTwo,
argumentNumberThree,
argumentNumberFour
);
There are two problems here. Firstly, it wants to line up the start of the arguments with the end of the function name. Secondly, it wants to treat the the closet paren as if it were an argument, and thus lines it up with all other arguments. I don't like either of those behaviors.
I would much rather it indent my code like this:
someLongFunctionName(
argumentNumberOne,
argumentNumberTwo,
argumentNumberThree,
argumentNumberFour
);
c-mode does a much better job of this by default, and I would like to carry over the behavior to java-mode if possible.
I still need to learn how the emacs indentation engine works, and at the moment I don't honestly really even know that much lisp. Those two learning exercises are definitely on my plate, but at the moment a quick copy-paste solution would be pretty awesome.
Try this
(defun my-indent-setup ()
(c-set-offset 'arglist-intro '+))
(add-hook 'java-mode-hook 'my-indent-setup)
From http://www.emacswiki.org/emacs/IndentingC

Can I Define Exceptions to Eclipse cleanup rules?

Most often the cleanup rules (Preferences > Java > Code Style > Clean Up) in Eclipse work perfectly and create nice-looking code.
But sometimes, especially with comments and concatenated string snippets (like inline SQL queries), the cleanup just messes things up, and destroys my formatting.
Is there a way to say to Eclipse "Don't touch this block of text! I have formatted it just the way I like, and you would make it just less readable"?
I assume you do not really mean ‘Clean Up’, but the ‘Format source code’ option hidden within. It is configured in Preferences > Java > Code Style > Formatter. And, indeed, there is an option called ‘On/Off Tags’. Sadly, it’s off by default. You would now write it like so:
// #formatter:off
StringBuilder sql = new StringBuilder()
.append("SELECT whatever \n")
.append("FROM some_table");
// #formatter:on
It may well be possible that the accepted answer was correct at the time of writing, however, this was introduced in Eclipse 3.5, if I’m not mistaken.
I have experienced the same problem, and while I don't have a solution, I can tell you how I work around the problem.
Because of how formatting works, I deliberately avoid lines of code that are excessively long. In general, when I keep lines short, it makes better decisions as to how to format the code. This can even work with SQL statements, for example:
public static final String SELECT_SOMETHING = "SELECT"
+ "OBJECTID, THIS, THAT, THEOTHER, THING"
+ " FROM DBNAME.DBSCHEMA.TABLE_T"
+ " WHERE ID = ?";
This statement formats reasonably, because where possible items were split apart and concatenated together. When I don't do this, I get unpredictable results:
public static final String SELECT_SOMETHING = "SELECT OBJECTID, SOMETHING FROM DBNAME.DBSCHEMA.TABLE_T WHERE ID = ?";
For comments, I place them all on a single line when possible, and allow it to word wrap when it does the formatting.
Also, it is possible to change the style using the code formatter to make things work better for your coding style. You may want everyone on the team to use the same format, just to avoid conflicts. Because it is easier to compare changes with other developers, or prior versions using your source control tool, even if it makes parts of your code less readable, using the formatter has still been to my advantage.
Still, I understand your frustration when the formatter makes bad decisions!
Feeling iffy about replying to my own question, but there's a workaround I currently do (note: I have these cleanup rules as a save-action):
Save (with Ctrl/Cmd-S, don't know if it matters how you save) the code, and let Eclipse mess up your formatting. Then just press Ctrl/Cmd-Z to undo, and immediately re-save. The format reverts back to its original format and seems to be saved as intended.
For SQL statements in code, you can put a single-line comment character at the end of each line. Then the formatter can't reformat it. It's uglier than not having to do it, but it's prettier than if Eclipse formats it.
StringBuffer sql = new StringBuffer() //
.append("SELECT whatever \n") //
.append("FROM some_table");
No. (To the best of my knowledge, and I have had the same problem and have looked many times hard and long...)
(for Javadoc comments only)
If I have a block of text that formatted just the way I like, I enclose them by the <pre></pre> tags.
if you don't want a field to become final (i.i: because you want to change it while debugging), you just assign it to itself on the constructor. This would get an eclipse warning, but your field will stay non-final.

Categories

Resources