[Request:Rearranger] Getter/Setter

Hi,

I often use "getter" like

public List getMyList(){
return Collections.unmodifiableList( myList );
}


Could u treat those "getters" as getters and not as "other method"?

Thanks

13 comments
Comment actions Permalink

Yes, I could.

Alain was pretty adamant about treating methods as "getters" only if they did a simple return of the field in the method name, and "setters" only if they only set the variable. He gave me code to actually check the logic of the methods to make sure that these methods do the strict accessor/mutator functions and nothing else.

However, others seem to like the looser definition of a getter being anything starting with "get" (or "is", etc) plus field name, and setter being "set" plus field name. What the method actually does is immaterial.

Would it be satisfactory if I added a way to choose which definition of getter/setter you want? And is the looser definition acceptable to you?

-Dave

0
Comment actions Permalink

yes, i think the "looser" definition is acceptable for me.

But i would prefer some sort of "template-matching".

e.g.
Getters are for me:
+ "simple" Getters
+ "return Collections.unmodifiable$field.type$( $field$ );


0
Comment actions Permalink

One more point:

I want the following order (shorted):

all static public methods
all public methods
all Getters/Setters
equals()
hashCode()

I tried to declare that order. But the equals() and hashCode() method are moved to those public methods...
Didn´t find a way to avoid that. It seems that the Reearanger is going from top to bottom and place the method at the first match...

Any ideas?

0
Comment actions Permalink

Johannes,

You are correct; Rearranger moves items based on their first match.

In the example you gave, equals() and hashCode() would match the rule "all public methods."

For the moment, your best option is to modify the rule for "all public methods" to set "Name does not match" option to "equals|hashCode" (or whatever regular expression matches those canonical methods you want excluded). Thus the rule becomes "all public methods whose names do not match 'equals|hashCode'".

AlainR asked me long ago to add a special checkbox for canonical methods (equals, hashCode, toString). I think I will implement this as another method type (besides constructor, getter/setter, and other.) Then you'll be able to specify a rule "all non-canonical public methods" with a couple of checkboxes, and no regular expressions.

Thank you very much for your suggestions.

-Dave

0
Comment actions Permalink

Let me think that over.

The template-matching idea would be somewhat difficult to design. The code to inspect a method relies on the internal program structure information (Psi) tree, not on text matching. This is nice in one way because comments and spacing are not an issue. But it makes it harder to match a text-based template. On the other hand, it doesn't really do a full analysis of the method's behavior; for example

is just a little more verbose but does exactly the same thing as your more succinct version of the method. Yet the current accessor method analyzer would reject it, because it isn't a simple return statement followed by the variable name.

I could maybe split the difference and offer three definitions for a getter:
1) strict: method contains only "return ]]>"
2) relaxed: method contains one "return" statement
3) name: method conforms to getter naming scheme and returns a value

Thoughts, anyone?

-Dave

0
Comment actions Permalink

Ok that "|" made it ;) Thanks a lot...

What about implementing some sort of emphasis when u sort the methods?

So those all-catching rules get a very low emphasis, but e.g. the name-fitting rules get a higher one.
In that case the "equals"-Method would get the following emphases:

Rule Emphasis Score
all public methods: 1 1
name-matching: 5 5


On a second run you could sort the methods according the highest score.


0
Comment actions Permalink

I don´t know much about that PSI-stuff - so I can´t help you out :(.

But your idea sounds good:

What is a Getter? (possible criterias - multiple selections possible)
(1) returns just the fieldname
(2) contains just one return-statment (maybe not too usefull!?)
(3) conforms getter naming scheme (get + something else)
(4) conforms strict getter naming scheme (get + existing field name)


I would prefer the following settings for my project:
- other public methods
- (3)
- (2)+(4)
- (1)+(3) -- can be usefull, if the name of the field has changed (deprecated getter)
- (1)+(4)




0
Comment actions Permalink

Interesting idea. Were you thinking that the user would assign the priority? (I think so; any priorities I might assign based on how specific the rule is would probably displease someone sometime.)

That would definitely remove the need for making so many exceptions. Rearranger would consider rules in priority order instead of simply top-to-bottom on the list, matching items as it went and removing those items from consideration by other rules. Rearrangement would take place after all rules of all priorities had been considered.

Rules at the same priority level would still be handled sequentially. So if I made the default priority low (say 1) for every existing rule, the Rearranger would continue to operate as it currently does.

-Dave

0
Comment actions Permalink

Yeah - of course you can´t "guess" the correct priority. Just assign the default value of "10" (should not be the lowest possible) and let the user do the rest...

0
Comment actions Permalink

One more:

addObject( Object o){
objects.add( o );
}
removeObject( Object o){
objects.remove( o );
}


are also something special...



0
Comment actions Permalink

These are perhaps "logical" getters/setters. Would it work to have two rules

to simply select them by name?

Or are you planning to have addObject, addInteger, addBoolean, addMyClass, etc. and want a handier way to specify? I know you could almost do that with a rule

but that wouldn't keep the logical getter and setter together. I suppose that's what you're trying to achieve! :) You need a way to link them.

If the names make these getters unique (as opposed to the function of the method body), you could match them all with a wildcard regex like "add(.*)". Perhaps we need a way to say, "the name of the corresponding setter for this getter is 'remove' + getter field name." What if I added another attribute to the Method rule panel to that effect? Then your rule would be something like
where \1 substitutes the buffered contents of the parenthesized regular expression.

Only drawback I see to this arrangement is that these paired methods (which you probably view as logical getter/setters) won't be grouped with the "real" getters/setters, because they won't match a rule like:

Reicht das aus?

Thanks,
-Dave

0
Comment actions Permalink

Dave,


I'd like the ability to define rule-and-profile-based rearrangement .
I think this
- would allow you to satisfy more specific request like this one, (part
1/, below: method profiles)
- would make the plugin even more useful (part 2/ below: rule-based
rearrangement).


What it is :
In a same project, depending on some conditions, the plugin
would(could) choose to use a different rearrangement rules for
individual classes.


Example 1 : servlets.
-



"If the class is a servlet, put those 3 methods at the top of the class."
doPost (..)
doGet (..)
handle (..)


Example 2 : applications
-


"If the class extends Object, put "main()" at the top of the class.


etc...



I see 2 implementations "challenges" in this request.

1/
- define method "profiles", groups.
Ex: "doPost(..), doGet(..), handle(..)
Ex: standard (strict) accessors
Ex: relaxed accessors
...
I feel this feature would be useful right now, even if you don't
implement the 2nd part (see below).



2/
- rule based rearranging
if (condition on class)
then sort the methods this way.


Alain

0
Comment actions Permalink

Hi Alain,

Interesting suggestion!

I was thinking about different ways it might be implemented. One could specify conditional execution of rules at various levels. (So these aren't necessarily mutually exclusive.)


1) Allow a condition to be specified for each rule. Conditions for class content rules (like field and method rules) might be:
To take your suggestion as an example, the rules would be


2) Allow a condition to be specified for a group of rules; essentially, create a "rule" that is really a conditional IF-statement and contains other rules. This would be more convenient than (1) above if the same condition was going to be applied to multiple rules, but harder to represent/implement with the current user interface.


3) Provide a way to select from a number of Rearranger rulesets based on outer class (or file) attributes. A ruleset is the list of outer class and class member rules, plus all the other configuration options. Today there's only one ruleset and it's used for every rearrangement. Maybe certain Java files, or certain classes, or certain types of classes merit their own ruleset. For example, perhaps you want JUnit tests rearranged one way, servlet classes another, and classes of a certain package another. With this capability, you could rearrange classes of a given module differently from other modules.

I'd have to add a new panel which would allow the user to manage multiple rulesets and specify conditions for each. For simplicity, if a user didn't ever go to this panel, there'd be just one default ruleset that operates on all classes, as it does today.

This (3) capability would also allow you to tailor rearrangement for each class or file when the plugin is enhanced operate on entire directories in the project.

-


You wrote:
+I see 2 implementations "challenges" in this request.

1/
- define method "profiles", groups.
Ex: "doPost(..), doGet(..), handle(..)
Ex: standard (strict) accessors
Ex: relaxed accessors
...
I feel this feature would be useful right now, even if you don't
implement the 2nd part (see below).
+
I'm not sure I understand how this "1/" feature relates to conditionally executing different rules for different classes. This seems to have more to do with which methods a given rule selects; i.e., we've already decided to execute the rule; now we just want to select the "right group" of methods.

You can already specify the first example in a rule

and in the next version of the Rearranger (code mostly done) you can specify the definitions of getter and setter for each rule independently of other rules. And, to make you especially happy (since it's your request from a long time ago! :), I added "canonical" method type so you can match canonical methods with a single checkbox!

So I think that the selection of methods is up to par with your "1/" feature (in the next release of the plugin, I mean.)

-



I'd be interested to know how many people would use conditionals:
-(0) ever
-(1) on a per rule basis
-(2) for a group of rules
-(4) to decide which Rearranger ruleset to apply to a given file
-(3,5,6,7) or combinations of the above

In other words, how granular does the conditional control have to be - per rule, per group of rules, or per file?

It's a fair amount of work; I'd like to have a sense of how useful it would be. Other suggestions for solution are also certainly welcome. Thanks for your feedback.

And Alain, thanks for thinking outside the box and coming up with these ideas!

-Dave

0

Please sign in to leave a comment.