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

review 1: Change local variable name refactoring #1005

Merged
merged 6 commits into from Mar 22, 2017

Conversation

Projects
None yet
4 participants
@pvojtechovsky
Collaborator

pvojtechovsky commented Nov 24, 2016

This code is not tested and may be even wrong somewhere. I will work on it, because I will need such refactoring in my project.

Just have a short look at class Refactoring, please. Whether you want such methods in Spoon or it is out of it's scope.

What about checking of validity of such refactoring requests? For example if I have

class A and B in package P and I decide to rename class A to B

then the class B will be twice in the model. Do you have some preferences how to report such invalid requests?
A) to throw exception
B) to call some listener and silently skip the operation
C) ?
I am just sure that in all cases the validity should be checked before the model is modified.

@monperrus

This comment has been minimized.

Show comment
Hide comment
@monperrus

monperrus Nov 24, 2016

Collaborator

Just have a short look at class Refactoring, please.

that's a very useful contribution

Do you have some preferences how to report such invalid requests?

an exception.

we also need strong tests.

Collaborator

monperrus commented Nov 24, 2016

Just have a short look at class Refactoring, please.

that's a very useful contribution

Do you have some preferences how to report such invalid requests?

an exception.

we also need strong tests.

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Nov 28, 2016

Collaborator

we also need strong tests.

I like the idea of usage of complex thirdparty library (like guava), with good jUnit tests, as a test environment.

The test would look like this:

  1. rename all local variables to v1, v2, ... vN.
  2. rename all method parameters to v1,v2,...vN
  3. rename all fields to to v1,v2,...vN
  4. rename all classes to v1,v2...vN
    The renaming should detect conflict if name vX is already used in current context and throw exception, then test will try name v(X+1) as long as v(X+Y) is usable name.
    Then we print the refactored model and run the refactored tests on it too. If it pass, then it is OK
    ... but may be it is too complex task, so it will never pass :-) ... we will see

I came with this idea, hoping that I can avoid writing small jUnit test for each refactoring feature. But now I see these small tests are useful when detecting where is the problem in the code.

So the best will be combination of small tests at beginning and at the end that thirparty library refactoring test, which founds the most tricky things.

Collaborator

pvojtechovsky commented Nov 28, 2016

we also need strong tests.

I like the idea of usage of complex thirdparty library (like guava), with good jUnit tests, as a test environment.

The test would look like this:

  1. rename all local variables to v1, v2, ... vN.
  2. rename all method parameters to v1,v2,...vN
  3. rename all fields to to v1,v2,...vN
  4. rename all classes to v1,v2...vN
    The renaming should detect conflict if name vX is already used in current context and throw exception, then test will try name v(X+1) as long as v(X+Y) is usable name.
    Then we print the refactored model and run the refactored tests on it too. If it pass, then it is OK
    ... but may be it is too complex task, so it will never pass :-) ... we will see

I came with this idea, hoping that I can avoid writing small jUnit test for each refactoring feature. But now I see these small tests are useful when detecting where is the problem in the code.

So the best will be combination of small tests at beginning and at the end that thirparty library refactoring test, which founds the most tricky things.

@monperrus

This comment has been minimized.

Show comment
Hide comment
@monperrus

monperrus Nov 29, 2016

Collaborator
Collaborator

monperrus commented Nov 29, 2016

@monperrus monperrus changed the title from New refactoring methods - rename of CtVariable based elements to WIP New refactoring methods - rename of CtVariable based elements Jan 11, 2017

@monperrus monperrus changed the title from WIP New refactoring methods - rename of CtVariable based elements to WIP[test missing] New refactoring methods - rename of CtVariable based elements Jan 11, 2017

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Jan 12, 2017

Collaborator

The refactoring request validity checks are missing.

These checks can be quite tricky. For example rename of local variable should check

  • if there is another local variable with same name defined in visibility scope of that local variable
  • if there is method parameter with same name in current method
  • if there is catch parameter with same name in current catch block

Do you think that we should continue with refactoring functions, which are implemented as static methods of one class? I have feeling like it would be better to have one class for each refactoring. The API might be like this:

interface CtRefactoring {
  boolean isValid();
  void refactor() throws SpoonInvalidRequest;
}

And sometime there are probably some refactorings which cannot be done without temporary inconsistency in the model, so then we should be able to switch OFF the validation check.

I have implemented nothing yet, so I welcome your suggestions. It is easy to accept any design if there is no code yet. ;-)

Collaborator

pvojtechovsky commented Jan 12, 2017

The refactoring request validity checks are missing.

These checks can be quite tricky. For example rename of local variable should check

  • if there is another local variable with same name defined in visibility scope of that local variable
  • if there is method parameter with same name in current method
  • if there is catch parameter with same name in current catch block

Do you think that we should continue with refactoring functions, which are implemented as static methods of one class? I have feeling like it would be better to have one class for each refactoring. The API might be like this:

interface CtRefactoring {
  boolean isValid();
  void refactor() throws SpoonInvalidRequest;
}

And sometime there are probably some refactorings which cannot be done without temporary inconsistency in the model, so then we should be able to switch OFF the validation check.

I have implemented nothing yet, so I welcome your suggestions. It is easy to accept any design if there is no code yet. ;-)

@monperrus

This comment has been minimized.

Show comment
Hide comment
@monperrus

monperrus Jan 13, 2017

Collaborator
Collaborator

monperrus commented Jan 13, 2017

@pvojtechovsky pvojtechovsky changed the title from WIP[test missing] New refactoring methods - rename of CtVariable based elements to POC Change local variable name refactoring Jan 17, 2017

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Jan 17, 2017

Collaborator

It is POC of Refactoring class, which does rename of local variable.
Usage:

CtLocalVariable target = ...
ChangeLocalVariableName rename = new ChangeLocalVariableName();
rename.setTarget(target);
rename.setNewName("someName");
if(rename.getIssues().size()>0) {
 ... handle conflicts, etc...
}
rename.refactor();

I will add fluent API or a constructor of course. But please give me feedback mainly to

  • Refactor interface
  • Issue interface
  • VariableScopeQuery and VariableReferenceQuery - the nearly finished queries, which can be used for many purposes - they will be used by other future refactorings too ...
  • anything else, what seems to be relevant from your point of view

Please ignore other classes, which comes from other PRs or are obsolete ... I will clean it after your feedback about API

Collaborator

pvojtechovsky commented Jan 17, 2017

It is POC of Refactoring class, which does rename of local variable.
Usage:

CtLocalVariable target = ...
ChangeLocalVariableName rename = new ChangeLocalVariableName();
rename.setTarget(target);
rename.setNewName("someName");
if(rename.getIssues().size()>0) {
 ... handle conflicts, etc...
}
rename.refactor();

I will add fluent API or a constructor of course. But please give me feedback mainly to

  • Refactor interface
  • Issue interface
  • VariableScopeQuery and VariableReferenceQuery - the nearly finished queries, which can be used for many purposes - they will be used by other future refactorings too ...
  • anything else, what seems to be relevant from your point of view

Please ignore other classes, which comes from other PRs or are obsolete ... I will clean it after your feedback about API

@monperrus

This comment has been minimized.

Show comment
Hide comment
@monperrus

monperrus Jan 18, 2017

Collaborator

Hi Pavel,

This is very interesting but this already contains a lot of different things to be discussed, they may be split in several PRs (hence in several separate discussions, one after the other).

According to your long-term plan, what do you prefer to discuss and merge first? maybe VariableScopeQuery?

Collaborator

monperrus commented Jan 18, 2017

Hi Pavel,

This is very interesting but this already contains a lot of different things to be discussed, they may be split in several PRs (hence in several separate discussions, one after the other).

According to your long-term plan, what do you prefer to discuss and merge first? maybe VariableScopeQuery?

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Jan 18, 2017

Collaborator

Hi Martin,

I am aware that there is a lot of things, many baby steps, some of them may be in wrong direction... I develop it this way as a prototype to see what code/structures I need to implement refactoring algorithms in short, efficient and maintainable way. And note, I do not need VariableScopeQuery or VariableReferenceQuery. I need refactorings, which are based on these queries. So I started with refactorings and as a side effect there are VariableScopeQuery and VariableReferenceQuery.

first topic for discussion: VariableScopeQuery?

It is good topic for discussion, because it is one of the core components of that refactorings. So yes, let's discuss it first. I am just not sure if it makes sense to make a PR only for that, because VariableScopeQuery is not much usable on it's own. The better is combination with VariableReferenceQuery. These two are tightly coupled. If you agree then we can move discussion to #1114, which contains only these two queries.

Collaborator

pvojtechovsky commented Jan 18, 2017

Hi Martin,

I am aware that there is a lot of things, many baby steps, some of them may be in wrong direction... I develop it this way as a prototype to see what code/structures I need to implement refactoring algorithms in short, efficient and maintainable way. And note, I do not need VariableScopeQuery or VariableReferenceQuery. I need refactorings, which are based on these queries. So I started with refactorings and as a side effect there are VariableScopeQuery and VariableReferenceQuery.

first topic for discussion: VariableScopeQuery?

It is good topic for discussion, because it is one of the core components of that refactorings. So yes, let's discuss it first. I am just not sure if it makes sense to make a PR only for that, because VariableScopeQuery is not much usable on it's own. The better is combination with VariableReferenceQuery. These two are tightly coupled. If you agree then we can move discussion to #1114, which contains only these two queries.

@monperrus

This comment has been minimized.

Show comment
Hide comment
@monperrus

monperrus Jan 18, 2017

Collaborator

If you agree then we can move discussion to #1114, which contains only these two queries.

OK

Collaborator

monperrus commented Jan 18, 2017

If you agree then we can move discussion to #1114, which contains only these two queries.

OK

@pvojtechovsky pvojtechovsky changed the title from POC Change local variable name refactoring to WiP: Change local variable name refactoring Jan 30, 2017

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Feb 7, 2017

Collaborator

During implementation of local variable rename refactoring, class ChangeLocalVariableName, I have found that I need to extend CtQuery. I need:

  • to know when query enter/exit an element during filterChildren on any query step level
  • to be able to skip processing of children of current element
  • to be able to skip processing of siblings and children of current elements

I will prepare another PR for that soon. Do you have any preference/ideas how to do it? You can influence the solution before it is implemented - so less effort is needed.

If you want to see context where I need it, then have a look at ChangeLocalVariableName#detectNameConflicts of this PR. There are comments which explains the situation.
This PR depends on PR #1154, so look there for classes, which are missing here.

Collaborator

pvojtechovsky commented Feb 7, 2017

During implementation of local variable rename refactoring, class ChangeLocalVariableName, I have found that I need to extend CtQuery. I need:

  • to know when query enter/exit an element during filterChildren on any query step level
  • to be able to skip processing of children of current element
  • to be able to skip processing of siblings and children of current elements

I will prepare another PR for that soon. Do you have any preference/ideas how to do it? You can influence the solution before it is implemented - so less effort is needed.

If you want to see context where I need it, then have a look at ChangeLocalVariableName#detectNameConflicts of this PR. There are comments which explains the situation.
This PR depends on PR #1154, so look there for classes, which are missing here.

@monperrus

This comment has been minimized.

Show comment
Hide comment
@monperrus

monperrus Feb 8, 2017

Collaborator
Collaborator

monperrus commented Feb 8, 2017

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Feb 16, 2017

Collaborator

I am testing ChangeLocalVariableName refactoring method using ChangeVariableNameTest. OK, there are still some todos, but I stuck on one thing. The testing algorithm is like this:

  1. take one method from VariableRename class and search for TryRename annotation.
  2. For each found annotation try to rename assigned variable to all new names defined in TryRename annotation. The prefix "-" in the annotation, means that rename to this name should be not possible.
  3. If the rename is possible and passes then the test does following extra steps (see ChangeVariableNameTest#printModelAndTestConsistency)
  4. print the refactored model
  5. compile refactored model
  6. create new class loader and load the class from the refactored model
  7. create instance of that refactored class = call constructor, whose implementation will run all the methods of that class and will check that all assertions are still passing.

The problem is that step 7) does not work. I have no idea why class loader loads some other implementation of the class ...
... it must be so, because otherwise the assertions should fail, because the rename of "var1" to "var2" in this method

	void nestedClassMethodWithShadowVar() {
		@TryRename({"var2", "var3"})
		int var1 = 2; //<--------- the "var1" is renamed to "var2"
		new Runnable() {
			@TryRename({"var1", "var3"})
			int var2 = 3;
			@Override
			public void run() {
				@TryRename({"-var1", "var2"})
				int var3 = 1;
				assertTrue(var1 == 2); //<-----------this reference is renamed too
				//this var1 shadows above defined var1. It can be renamed
				@TryRename({"var2", "-var3"})
				int var1 = 4;
				assertTrue(var1 == 4);
				assertTrue(var2 == 3);
				assertTrue(var3 == 1);
			}
		}.run();
		assertTrue(var1 == 2);
	}

by mistake passes (and it should not pass), and pretty printer produces this valid java code:

    void nestedClassMethodWithShadowVar() {
        @spoon.test.refactoring.testclasses.TryRename(value = { "var2" , "var3" })
        int var2 = 2; //<!----------- is renamed to "var2" - OK
        new java.lang.Runnable() {
            @spoon.test.refactoring.testclasses.TryRename(value = { "var1" , "var3" })
            int var2 = 3;

            @java.lang.Override
            public void run() {
                @spoon.test.refactoring.testclasses.TryRename(value = { "-var1" , "var2" })
                int var3 = 1;
                org.junit.Assert.assertTrue((var2 == 2)); //<-------- is renamed to var2, 
//but the value should be 3, because it is no more local variable reference, but it is now the reference to the class field, 
//which shadows origin local variable! So it should fail here!!!
                @spoon.test.refactoring.testclasses.TryRename(value = { "var2" , "-var3" })
                int var1 = 4;
                org.junit.Assert.assertTrue((var1 == 4));
                org.junit.Assert.assertTrue(((var2) == 3));
                org.junit.Assert.assertTrue((var3 == 1));
            }
        }.run();
        org.junit.Assert.assertTrue((var2 == 2));
    }

but execution of that code does not fail on AssertionError, but it should fail :-(

Any idea why my test class loader does not load classes compiled from refactored code?

Collaborator

pvojtechovsky commented Feb 16, 2017

I am testing ChangeLocalVariableName refactoring method using ChangeVariableNameTest. OK, there are still some todos, but I stuck on one thing. The testing algorithm is like this:

  1. take one method from VariableRename class and search for TryRename annotation.
  2. For each found annotation try to rename assigned variable to all new names defined in TryRename annotation. The prefix "-" in the annotation, means that rename to this name should be not possible.
  3. If the rename is possible and passes then the test does following extra steps (see ChangeVariableNameTest#printModelAndTestConsistency)
  4. print the refactored model
  5. compile refactored model
  6. create new class loader and load the class from the refactored model
  7. create instance of that refactored class = call constructor, whose implementation will run all the methods of that class and will check that all assertions are still passing.

The problem is that step 7) does not work. I have no idea why class loader loads some other implementation of the class ...
... it must be so, because otherwise the assertions should fail, because the rename of "var1" to "var2" in this method

	void nestedClassMethodWithShadowVar() {
		@TryRename({"var2", "var3"})
		int var1 = 2; //<--------- the "var1" is renamed to "var2"
		new Runnable() {
			@TryRename({"var1", "var3"})
			int var2 = 3;
			@Override
			public void run() {
				@TryRename({"-var1", "var2"})
				int var3 = 1;
				assertTrue(var1 == 2); //<-----------this reference is renamed too
				//this var1 shadows above defined var1. It can be renamed
				@TryRename({"var2", "-var3"})
				int var1 = 4;
				assertTrue(var1 == 4);
				assertTrue(var2 == 3);
				assertTrue(var3 == 1);
			}
		}.run();
		assertTrue(var1 == 2);
	}

by mistake passes (and it should not pass), and pretty printer produces this valid java code:

    void nestedClassMethodWithShadowVar() {
        @spoon.test.refactoring.testclasses.TryRename(value = { "var2" , "var3" })
        int var2 = 2; //<!----------- is renamed to "var2" - OK
        new java.lang.Runnable() {
            @spoon.test.refactoring.testclasses.TryRename(value = { "var1" , "var3" })
            int var2 = 3;

            @java.lang.Override
            public void run() {
                @spoon.test.refactoring.testclasses.TryRename(value = { "-var1" , "var2" })
                int var3 = 1;
                org.junit.Assert.assertTrue((var2 == 2)); //<-------- is renamed to var2, 
//but the value should be 3, because it is no more local variable reference, but it is now the reference to the class field, 
//which shadows origin local variable! So it should fail here!!!
                @spoon.test.refactoring.testclasses.TryRename(value = { "var2" , "-var3" })
                int var1 = 4;
                org.junit.Assert.assertTrue((var1 == 4));
                org.junit.Assert.assertTrue(((var2) == 3));
                org.junit.Assert.assertTrue((var3 == 1));
            }
        }.run();
        org.junit.Assert.assertTrue((var2 == 2));
    }

but execution of that code does not fail on AssertionError, but it should fail :-(

Any idea why my test class loader does not load classes compiled from refactored code?

@tdurieux

This comment has been minimized.

Show comment
Hide comment
@tdurieux

tdurieux Feb 16, 2017

Collaborator

I could be wrong (I did not read all your changes).
It seams that you compile the original files not the model : https://github.com/INRIA/spoon/pull/1005/files#diff-617f2b7a84783b10a9bd2ed77f0fe739R135

Change: SpoonModelBuilder.InputType.FILES to SpoonModelBuilder.InputType.CTTYPES

Collaborator

tdurieux commented Feb 16, 2017

I could be wrong (I did not read all your changes).
It seams that you compile the original files not the model : https://github.com/INRIA/spoon/pull/1005/files#diff-617f2b7a84783b10a9bd2ed77f0fe739R135

Change: SpoonModelBuilder.InputType.FILES to SpoonModelBuilder.InputType.CTTYPES

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Feb 18, 2017

Collaborator

@tdurieux thanks! It really compiled origin not refactored sources. Now the test fails as expected :-)

This PR is still not finished. There are several bugs ... working on it.

Collaborator

pvojtechovsky commented Feb 18, 2017

@tdurieux thanks! It really compiled origin not refactored sources. Now the test fails as expected :-)

This PR is still not finished. There are several bugs ... working on it.

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Feb 20, 2017

Collaborator

Looks like my local variable rename tests passed. Now we have to pass through all the changes to have it in acceptable form in main branch.
I will make some smaller PRs from this one later ...

Collaborator

pvojtechovsky commented Feb 20, 2017

Looks like my local variable rename tests passed. Now we have to pass through all the changes to have it in acceptable form in main branch.
I will make some smaller PRs from this one later ...

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Feb 21, 2017

Collaborator

This PR contains #1193, #1194 too

This PR contains working code, which can safely refactor name of local variables. It detects name conflicts and shadowing of variables. In such case the refactoring throws exception, before invalid change would be done, so the model stays consistent.

I would like to discuss here these topics:

  • name refactoring object: ChangeLocalVariableName ... it needs better name
  • before the refactoring is processed it detects whether requested change is possible (will not cause change in behavior or compilation errors). If problem is found then it's description is added to collection of issues. List<Issue> Refactor#getIssues(). The question is whether we will collect such issues and what issue types we will support?
  • any other improvements You see.
Collaborator

pvojtechovsky commented Feb 21, 2017

This PR contains #1193, #1194 too

This PR contains working code, which can safely refactor name of local variables. It detects name conflicts and shadowing of variables. In such case the refactoring throws exception, before invalid change would be done, so the model stays consistent.

I would like to discuss here these topics:

  • name refactoring object: ChangeLocalVariableName ... it needs better name
  • before the refactoring is processed it detects whether requested change is possible (will not cause change in behavior or compilation errors). If problem is found then it's description is added to collection of issues. List<Issue> Refactor#getIssues(). The question is whether we will collect such issues and what issue types we will support?
  • any other improvements You see.

@pvojtechovsky pvojtechovsky changed the title from WiP: Change local variable name refactoring to review 2: Change local variable name refactoring Mar 14, 2017

@spoon-bot

This comment has been minimized.

Show comment
Hide comment
@spoon-bot

spoon-bot Mar 15, 2017

Collaborator

Revapi Analysis results

Old API: fr.inria.gforge.spoon:spoon-core:jar:5.6.0-20170315.164827-83

New API: fr.inria.gforge.spoon:spoon-core:jar:5.6.0-SNAPSHOT

Detected changes: 8.

Change 1

Name Element
Old class spoon.reflect.visitor.filter.CatchVariableReferenceFunction
New class spoon.reflect.visitor.filter.CatchVariableReferenceFunction
Code java.class.nonFinalClassInheritsFromNewClass
Description Non-final class now inherits from 'spoon.reflect.visitor.filter.LocalVariableReferenceFunction'.
Breaking source: potentially_breaking, binary: potentially_breaking

Change 1

Name Element
Old class spoon.reflect.visitor.filter.CatchVariableReferenceFunction
New class spoon.reflect.visitor.filter.CatchVariableReferenceFunction
Code java.class.noLongerImplementsInterface
Description Class no longer implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.code.CtCatchVariable<?>>'.
Breaking source: breaking, binary: breaking

Change 2

Name Element
Old class spoon.reflect.visitor.filter.FieldReferenceFunction
New class spoon.reflect.visitor.filter.FieldReferenceFunction
Code java.class.noLongerImplementsInterface
Description Class no longer implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtField<?>>'.
Breaking source: breaking, binary: breaking

Change 2

Name Element
Old class spoon.reflect.visitor.filter.FieldReferenceFunction
New class spoon.reflect.visitor.filter.FieldReferenceFunction
Code java.class.nowImplementsInterface
Description Class now implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtElement>'.
Breaking source: non_breaking, binary: non_breaking

Change 2

Name Element
Old class spoon.reflect.visitor.filter.FieldReferenceFunction
New class spoon.reflect.visitor.filter.FieldReferenceFunction
Code java.class.superTypeTypeParametersChanged
Description Super type's type parameters changed from 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtField<?>>' to 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtElement>'.
Breaking source: potentially_breaking, binary: potentially_breaking

Change 3

Name Element
Old class spoon.reflect.visitor.filter.LocalVariableReferenceFunction
New class spoon.reflect.visitor.filter.LocalVariableReferenceFunction
Code java.class.noLongerImplementsInterface
Description Class no longer implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.code.CtLocalVariable<?>>'.
Breaking source: breaking, binary: breaking

Change 3

Name Element
Old class spoon.reflect.visitor.filter.LocalVariableReferenceFunction
New class spoon.reflect.visitor.filter.LocalVariableReferenceFunction
Code java.class.nowImplementsInterface
Description Class now implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtElement>'.
Breaking source: non_breaking, binary: non_breaking

Change 3

Name Element
Old class spoon.reflect.visitor.filter.LocalVariableReferenceFunction
New class spoon.reflect.visitor.filter.LocalVariableReferenceFunction
Code java.class.superTypeTypeParametersChanged
Description Super type's type parameters changed from 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.code.CtLocalVariable<?>>' to 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtElement>'.
Breaking source: potentially_breaking, binary: potentially_breaking

Change 4

Name Element
Old class spoon.reflect.visitor.filter.ParameterReferenceFunction
New class spoon.reflect.visitor.filter.ParameterReferenceFunction
Code java.class.nonFinalClassInheritsFromNewClass
Description Non-final class now inherits from 'spoon.reflect.visitor.filter.LocalVariableReferenceFunction'.
Breaking source: potentially_breaking, binary: potentially_breaking

Change 4

Name Element
Old class spoon.reflect.visitor.filter.ParameterReferenceFunction
New class spoon.reflect.visitor.filter.ParameterReferenceFunction
Code java.class.noLongerImplementsInterface
Description Class no longer implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtParameter<?>>'.
Breaking source: breaking, binary: breaking

Change 5

Name Element
Old class spoon.reflect.visitor.filter.VariableReferenceFunction
New class spoon.reflect.visitor.filter.VariableReferenceFunction
Code java.class.noLongerImplementsInterface
Description Class no longer implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtVariable<?>>'.
Breaking source: breaking, binary: breaking

Change 5

Name Element
Old class spoon.reflect.visitor.filter.VariableReferenceFunction
New class spoon.reflect.visitor.filter.VariableReferenceFunction
Code java.class.nowImplementsInterface
Description Class now implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtElement>'.
Breaking source: non_breaking, binary: non_breaking

Change 5

Name Element
Old class spoon.reflect.visitor.filter.VariableReferenceFunction
New class spoon.reflect.visitor.filter.VariableReferenceFunction
Code java.class.superTypeTypeParametersChanged
Description Super type's type parameters changed from 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtVariable<?>>' to 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtElement>'.
Breaking source: potentially_breaking, binary: potentially_breaking

Change 6

Name Element
Old parameter void spoon.reflect.visitor.filter.FieldReferenceFunction::apply(===spoon.reflect.declaration.CtField<?>===, spoon.reflect.visitor.chain.CtConsumer<java.lang.Object>)
New parameter void spoon.reflect.visitor.filter.FieldReferenceFunction::apply(===spoon.reflect.declaration.CtElement===, spoon.reflect.visitor.chain.CtConsumer<java.lang.Object>)
Code java.method.parameterTypeChanged
Description The type of the parameter changed from 'spoon.reflect.declaration.CtField<?>' to 'spoon.reflect.declaration.CtElement'.
Breaking source: potentially_breaking, binary: breaking

Change 7

Name Element
Old parameter void spoon.reflect.visitor.filter.LocalVariableReferenceFunction::apply(===spoon.reflect.code.CtLocalVariable<?>===, spoon.reflect.visitor.chain.CtConsumer<java.lang.Object>)
New parameter void spoon.reflect.visitor.filter.LocalVariableReferenceFunction::apply(===spoon.reflect.declaration.CtElement===, spoon.reflect.visitor.chain.CtConsumer<java.lang.Object>)
Code java.method.parameterTypeChanged
Description The type of the parameter changed from 'spoon.reflect.code.CtLocalVariable<?>' to 'spoon.reflect.declaration.CtElement'.
Breaking source: potentially_breaking, binary: breaking

Change 8

Name Element
Old parameter void spoon.reflect.visitor.filter.VariableReferenceFunction::apply(===spoon.reflect.declaration.CtVariable<?>===, spoon.reflect.visitor.chain.CtConsumer<java.lang.Object>)
New parameter void spoon.reflect.visitor.filter.VariableReferenceFunction::apply(===spoon.reflect.declaration.CtElement===, spoon.reflect.visitor.chain.CtConsumer<java.lang.Object>)
Code java.method.parameterTypeChanged
Description The type of the parameter changed from 'spoon.reflect.declaration.CtVariable<?>' to 'spoon.reflect.declaration.CtElement'.
Breaking source: potentially_breaking, binary: breaking
Collaborator

spoon-bot commented Mar 15, 2017

Revapi Analysis results

Old API: fr.inria.gforge.spoon:spoon-core:jar:5.6.0-20170315.164827-83

New API: fr.inria.gforge.spoon:spoon-core:jar:5.6.0-SNAPSHOT

Detected changes: 8.

Change 1

Name Element
Old class spoon.reflect.visitor.filter.CatchVariableReferenceFunction
New class spoon.reflect.visitor.filter.CatchVariableReferenceFunction
Code java.class.nonFinalClassInheritsFromNewClass
Description Non-final class now inherits from 'spoon.reflect.visitor.filter.LocalVariableReferenceFunction'.
Breaking source: potentially_breaking, binary: potentially_breaking

Change 1

Name Element
Old class spoon.reflect.visitor.filter.CatchVariableReferenceFunction
New class spoon.reflect.visitor.filter.CatchVariableReferenceFunction
Code java.class.noLongerImplementsInterface
Description Class no longer implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.code.CtCatchVariable<?>>'.
Breaking source: breaking, binary: breaking

Change 2

Name Element
Old class spoon.reflect.visitor.filter.FieldReferenceFunction
New class spoon.reflect.visitor.filter.FieldReferenceFunction
Code java.class.noLongerImplementsInterface
Description Class no longer implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtField<?>>'.
Breaking source: breaking, binary: breaking

Change 2

Name Element
Old class spoon.reflect.visitor.filter.FieldReferenceFunction
New class spoon.reflect.visitor.filter.FieldReferenceFunction
Code java.class.nowImplementsInterface
Description Class now implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtElement>'.
Breaking source: non_breaking, binary: non_breaking

Change 2

Name Element
Old class spoon.reflect.visitor.filter.FieldReferenceFunction
New class spoon.reflect.visitor.filter.FieldReferenceFunction
Code java.class.superTypeTypeParametersChanged
Description Super type's type parameters changed from 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtField<?>>' to 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtElement>'.
Breaking source: potentially_breaking, binary: potentially_breaking

Change 3

Name Element
Old class spoon.reflect.visitor.filter.LocalVariableReferenceFunction
New class spoon.reflect.visitor.filter.LocalVariableReferenceFunction
Code java.class.noLongerImplementsInterface
Description Class no longer implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.code.CtLocalVariable<?>>'.
Breaking source: breaking, binary: breaking

Change 3

Name Element
Old class spoon.reflect.visitor.filter.LocalVariableReferenceFunction
New class spoon.reflect.visitor.filter.LocalVariableReferenceFunction
Code java.class.nowImplementsInterface
Description Class now implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtElement>'.
Breaking source: non_breaking, binary: non_breaking

Change 3

Name Element
Old class spoon.reflect.visitor.filter.LocalVariableReferenceFunction
New class spoon.reflect.visitor.filter.LocalVariableReferenceFunction
Code java.class.superTypeTypeParametersChanged
Description Super type's type parameters changed from 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.code.CtLocalVariable<?>>' to 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtElement>'.
Breaking source: potentially_breaking, binary: potentially_breaking

Change 4

Name Element
Old class spoon.reflect.visitor.filter.ParameterReferenceFunction
New class spoon.reflect.visitor.filter.ParameterReferenceFunction
Code java.class.nonFinalClassInheritsFromNewClass
Description Non-final class now inherits from 'spoon.reflect.visitor.filter.LocalVariableReferenceFunction'.
Breaking source: potentially_breaking, binary: potentially_breaking

Change 4

Name Element
Old class spoon.reflect.visitor.filter.ParameterReferenceFunction
New class spoon.reflect.visitor.filter.ParameterReferenceFunction
Code java.class.noLongerImplementsInterface
Description Class no longer implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtParameter<?>>'.
Breaking source: breaking, binary: breaking

Change 5

Name Element
Old class spoon.reflect.visitor.filter.VariableReferenceFunction
New class spoon.reflect.visitor.filter.VariableReferenceFunction
Code java.class.noLongerImplementsInterface
Description Class no longer implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtVariable<?>>'.
Breaking source: breaking, binary: breaking

Change 5

Name Element
Old class spoon.reflect.visitor.filter.VariableReferenceFunction
New class spoon.reflect.visitor.filter.VariableReferenceFunction
Code java.class.nowImplementsInterface
Description Class now implements interface 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtElement>'.
Breaking source: non_breaking, binary: non_breaking

Change 5

Name Element
Old class spoon.reflect.visitor.filter.VariableReferenceFunction
New class spoon.reflect.visitor.filter.VariableReferenceFunction
Code java.class.superTypeTypeParametersChanged
Description Super type's type parameters changed from 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtVariable<?>>' to 'spoon.reflect.visitor.chain.CtConsumableFunction<spoon.reflect.declaration.CtElement>'.
Breaking source: potentially_breaking, binary: potentially_breaking

Change 6

Name Element
Old parameter void spoon.reflect.visitor.filter.FieldReferenceFunction::apply(===spoon.reflect.declaration.CtField<?>===, spoon.reflect.visitor.chain.CtConsumer<java.lang.Object>)
New parameter void spoon.reflect.visitor.filter.FieldReferenceFunction::apply(===spoon.reflect.declaration.CtElement===, spoon.reflect.visitor.chain.CtConsumer<java.lang.Object>)
Code java.method.parameterTypeChanged
Description The type of the parameter changed from 'spoon.reflect.declaration.CtField<?>' to 'spoon.reflect.declaration.CtElement'.
Breaking source: potentially_breaking, binary: breaking

Change 7

Name Element
Old parameter void spoon.reflect.visitor.filter.LocalVariableReferenceFunction::apply(===spoon.reflect.code.CtLocalVariable<?>===, spoon.reflect.visitor.chain.CtConsumer<java.lang.Object>)
New parameter void spoon.reflect.visitor.filter.LocalVariableReferenceFunction::apply(===spoon.reflect.declaration.CtElement===, spoon.reflect.visitor.chain.CtConsumer<java.lang.Object>)
Code java.method.parameterTypeChanged
Description The type of the parameter changed from 'spoon.reflect.code.CtLocalVariable<?>' to 'spoon.reflect.declaration.CtElement'.
Breaking source: potentially_breaking, binary: breaking

Change 8

Name Element
Old parameter void spoon.reflect.visitor.filter.VariableReferenceFunction::apply(===spoon.reflect.declaration.CtVariable<?>===, spoon.reflect.visitor.chain.CtConsumer<java.lang.Object>)
New parameter void spoon.reflect.visitor.filter.VariableReferenceFunction::apply(===spoon.reflect.declaration.CtElement===, spoon.reflect.visitor.chain.CtConsumer<java.lang.Object>)
Code java.method.parameterTypeChanged
Description The type of the parameter changed from 'spoon.reflect.declaration.CtVariable<?>' to 'spoon.reflect.declaration.CtElement'.
Breaking source: potentially_breaking, binary: breaking

@pvojtechovsky pvojtechovsky changed the title from review 2: Change local variable name refactoring to review 1: Change local variable name refactoring Mar 17, 2017

@monperrus

This comment has been minimized.

Show comment
Hide comment
@monperrus

monperrus Mar 17, 2017

Collaborator

rebase to have a cleaner diff?

Collaborator

monperrus commented Mar 17, 2017

rebase to have a cleaner diff?

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Mar 17, 2017

Collaborator

Here you are :-)

Collaborator

pvojtechovsky commented Mar 17, 2017

Here you are :-)

@monperrus

Thanks for this brand-new feature, which looks promising.

I've tried to understand the design and usage from the tests and the interface documentation.

Here is a first set of comments.

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Mar 19, 2017

Collaborator

Your ides/change suggestions were implemented. Please review

Collaborator

pvojtechovsky commented Mar 19, 2017

Your ides/change suggestions were implemented. Please review

@monperrus

a second set of comments.

I'm really impressed by the test :-)

@monperrus

This comment has been minimized.

Show comment
Hide comment
@monperrus

monperrus Mar 21, 2017

Collaborator
Collaborator

monperrus commented Mar 21, 2017

@monperrus

This comment has been minimized.

Show comment
Hide comment
@monperrus

monperrus Mar 21, 2017

Collaborator
Collaborator

monperrus commented Mar 21, 2017

@monperrus

This comment has been minimized.

Show comment
Hide comment
@monperrus

monperrus Mar 21, 2017

Collaborator
Collaborator

monperrus commented Mar 21, 2017

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Mar 21, 2017

Collaborator

CtRefactor#setTarget

I would prefer to keep CtRefactor as it is. I can imagine refactoring methods, which has no target at all. And how would rename refactoring work on array of target elements?

The problem with that is that the interface cannot be understood without knowing concrete
implementations, which is an issue

But CtRefactor is very abstract. It is more like marker interface, which collects all the future refactoring implementations. I guess the only think which can be "understood" here is that "client can run refactoring after s/he configures it by refactoring specific methods"

I understand that Spoon is interface based, so I have added new interface, where setTarget fits better. What about this one?

public interface CtRenameRefactoring<T extends CtNamedElement> extends CtRefactoring {
	CtRenameRefactoring<T> setTarget(T target);
	CtRenameRefactoring<T> setNewName(String newName);
}

add Refactoring#renameLocalVariable ...

I have added

public static void changeLocalVariableName(CtLocalVariable<?> localVariable, String name)

whose name and parameters fits more to the existing method

public static void changeTypeName(final CtType<?> type, String name)

What about rename of RenameLocalVariableRefactor to
A) CtRenameLocalVariableRefactor
B) CtRenameLocalVariableRefactoring' because it is based on CtRefactoring` interface now.

Collaborator

pvojtechovsky commented Mar 21, 2017

CtRefactor#setTarget

I would prefer to keep CtRefactor as it is. I can imagine refactoring methods, which has no target at all. And how would rename refactoring work on array of target elements?

The problem with that is that the interface cannot be understood without knowing concrete
implementations, which is an issue

But CtRefactor is very abstract. It is more like marker interface, which collects all the future refactoring implementations. I guess the only think which can be "understood" here is that "client can run refactoring after s/he configures it by refactoring specific methods"

I understand that Spoon is interface based, so I have added new interface, where setTarget fits better. What about this one?

public interface CtRenameRefactoring<T extends CtNamedElement> extends CtRefactoring {
	CtRenameRefactoring<T> setTarget(T target);
	CtRenameRefactoring<T> setNewName(String newName);
}

add Refactoring#renameLocalVariable ...

I have added

public static void changeLocalVariableName(CtLocalVariable<?> localVariable, String name)

whose name and parameters fits more to the existing method

public static void changeTypeName(final CtType<?> type, String name)

What about rename of RenameLocalVariableRefactor to
A) CtRenameLocalVariableRefactor
B) CtRenameLocalVariableRefactoring' because it is based on CtRefactoring` interface now.

@spoon-bot

This comment has been minimized.

Show comment
Hide comment
@spoon-bot

spoon-bot Mar 21, 2017

Collaborator

Revapi Analysis results

Old API: fr.inria.gforge.spoon:spoon-core:jar:5.7.0-20170321.120037-10

New API: fr.inria.gforge.spoon:spoon-core:jar:5.7.0-SNAPSHOT

Detected changes: 1.

Change 1

Name Element
Old method java.util.List<java.io.File> spoon.reflect.cu.CompilationUnit::getBinaryFiles()
New none
Code java.method.removed
Description Method was removed.
Breaking source: breaking, binary: breaking
Collaborator

spoon-bot commented Mar 21, 2017

Revapi Analysis results

Old API: fr.inria.gforge.spoon:spoon-core:jar:5.7.0-20170321.120037-10

New API: fr.inria.gforge.spoon:spoon-core:jar:5.7.0-SNAPSHOT

Detected changes: 1.

Change 1

Name Element
Old method java.util.List<java.io.File> spoon.reflect.cu.CompilationUnit::getBinaryFiles()
New none
Code java.method.removed
Description Method was removed.
Breaking source: breaking, binary: breaking
@spoon-bot

This comment has been minimized.

Show comment
Hide comment
@spoon-bot

spoon-bot Mar 21, 2017

Collaborator

Revapi Analysis results

Old API: fr.inria.gforge.spoon:spoon-core:jar:5.7.0-20170321.120037-10

New API: fr.inria.gforge.spoon:spoon-core:jar:5.7.0-SNAPSHOT

Detected changes: 1.

Change 1

Name Element
Old method java.util.List<java.io.File> spoon.reflect.cu.CompilationUnit::getBinaryFiles()
New none
Code java.method.removed
Description Method was removed.
Breaking source: breaking, binary: breaking
Collaborator

spoon-bot commented Mar 21, 2017

Revapi Analysis results

Old API: fr.inria.gforge.spoon:spoon-core:jar:5.7.0-20170321.120037-10

New API: fr.inria.gforge.spoon:spoon-core:jar:5.7.0-SNAPSHOT

Detected changes: 1.

Change 1

Name Element
Old method java.util.List<java.io.File> spoon.reflect.cu.CompilationUnit::getBinaryFiles()
New none
Code java.method.removed
Description Method was removed.
Breaking source: breaking, binary: breaking
@monperrus

This comment has been minimized.

Show comment
Hide comment
@monperrus

monperrus Mar 21, 2017

Collaborator
Collaborator

monperrus commented Mar 21, 2017

@spoon-bot

This comment has been minimized.

Show comment
Hide comment
@spoon-bot

spoon-bot Mar 22, 2017

Collaborator

Revapi Analysis results

Old API: fr.inria.gforge.spoon:spoon-core:jar:5.7.0-20170321.234528-11

New API: fr.inria.gforge.spoon:spoon-core:jar:5.7.0-SNAPSHOT

Detected changes: 1.

Change 1

Name Element
Old method java.util.List<java.io.File> spoon.reflect.cu.CompilationUnit::getBinaryFiles()
New none
Code java.method.removed
Description Method was removed.
Breaking source: breaking, binary: breaking
Collaborator

spoon-bot commented Mar 22, 2017

Revapi Analysis results

Old API: fr.inria.gforge.spoon:spoon-core:jar:5.7.0-20170321.234528-11

New API: fr.inria.gforge.spoon:spoon-core:jar:5.7.0-SNAPSHOT

Detected changes: 1.

Change 1

Name Element
Old method java.util.List<java.io.File> spoon.reflect.cu.CompilationUnit::getBinaryFiles()
New none
Code java.method.removed
Description Method was removed.
Breaking source: breaking, binary: breaking

@monperrus monperrus merged commit ae72ad6 into INRIA:master Mar 22, 2017

3 of 4 checks passed

pull_request-INRIA-spoon-master-docker /tmp/tmpncwav55c
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
coverage/coveralls Coverage increased (+0.1%) to 81.162%
Details
pull_request-INRIA-spoon-master-revapi /tmp/tmpphvf8bme
Details
@monperrus

This comment has been minimized.

Show comment
Hide comment
@monperrus

monperrus Mar 22, 2017

Collaborator

thanks!

Collaborator

monperrus commented Mar 22, 2017

thanks!

@pvojtechovsky

This comment has been minimized.

Show comment
Hide comment
@pvojtechovsky

pvojtechovsky Mar 22, 2017

Collaborator

You are welcome ;-)

Collaborator

pvojtechovsky commented Mar 22, 2017

You are welcome ;-)

@pvojtechovsky pvojtechovsky deleted the pvojtechovsky:variableRenameRefactoring branch Mar 22, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment