Skip to content

Review: refactor: move SpoonMetaModel from src/test to src/main#2016

Merged
monperrus merged 18 commits intoINRIA:masterfrom
pvojtechovsky:refMoveMetamodel
Jun 9, 2018
Merged

Review: refactor: move SpoonMetaModel from src/test to src/main#2016
monperrus merged 18 commits intoINRIA:masterfrom
pvojtechovsky:refMoveMetamodel

Conversation

@pvojtechovsky
Copy link
Copy Markdown
Collaborator

The metamodel in runtime is needed by Pattern matcher.

@monperrus I have some questions:

  • should we somehow merge SpoonMetaModel with spoon.Metamodel ?
  • where to put all other necessary metamodel classes which are actually in spoon.metamodel ?
  • the creation of SpoonMetaModel in runtime needs about 3s. I guess we should lazily create it when somebody needs it and cache it. Where? FactoryImpl#metamodel? Or static variable of spoon.Metamodel or ?

@monperrus
Copy link
Copy Markdown
Collaborator

  • should we somehow merge SpoonMetaModel with spoon.Metamodel ?

Yes.

  • where to put all other necessary metamodel classes which are actually in spoon.metamodel ?

I'm not sure to understand. Which ones?

  • the creation of SpoonMetaModel in runtime needs about 3s. I guess we should lazily create it when somebody needs it and cache it. Where? FactoryImpl#metamodel? Or static variable of spoon.Metamodel or ?

A static singleton seems fine to me.

@pvojtechovsky
Copy link
Copy Markdown
Collaborator Author

@monperrus I need your feedback concerning design. There are several ways how to do it
A) to move typemembers of SpoonMetaModel into Metamodel
the problem is that constructor of MetamodelConcept is package protected. So we have to either make it public or move MetamodelConcept into package spoon
B) to keep SpoonMetaModel as internal class in package spoon.metamodel and just create it and implement delegate methods from Metamodel ... but how to make it internal and keep it accessible for other package?
C) to move Metamodel from spoon to spoon.metamodel
D) to move MetamodelConcept, etc. from spoon.metamodel to spoon
E) ?

@pvojtechovsky pvojtechovsky changed the title refactor: move SpoonMetaModel from src/test to src/main HELP refactor: move SpoonMetaModel from src/test to src/main Jun 1, 2018
@pvojtechovsky
Copy link
Copy Markdown
Collaborator Author

ping @monperrus

@pvojtechovsky
Copy link
Copy Markdown
Collaborator Author

I suggest to move spoon.Metamodel to spoon.metamodel.Metamodel. WDYT?

@pvojtechovsky pvojtechovsky changed the title HELP refactor: move SpoonMetaModel from src/test to src/main WiP: refactor: move SpoonMetaModel from src/test to src/main Jun 3, 2018
@monperrus
Copy link
Copy Markdown
Collaborator

I suggest to move spoon.Metamodel to spoon.metamodel.Metamodel. WDYT?

OK for me.

@pvojtechovsky pvojtechovsky changed the title WiP: refactor: move SpoonMetaModel from src/test to src/main Review: refactor: move SpoonMetaModel from src/test to src/main Jun 4, 2018
@monperrus
Copy link
Copy Markdown
Collaborator

Just passed over the PR and pushed my changes (mostly documentation, several renamings, some refactorings).

This is super meta, I like it!

Two questions:

  • getRootSuperField: I don't understand at all this method, could you explain more in the Javadoc?
  • getRelatedMethods (this was before getOwnMethods): is that correct? is that a good name?

@pvojtechovsky
Copy link
Copy Markdown
Collaborator Author

This is super meta, I like it!

thank you. Me too. It opens new ways how to implement new powerful features in Spoon.

getRelatedMethods/getOwnMethods

For example:
CtClass has no OWN methods which provides access to CtRole#NAME, therefore getRelatedMethods will return empty collection when it is called on CtClass and CtRole#NAME. But if the same method is called on CtNamedElement and CtRole#NAME, then it will return getSimpleName, setSimpleName

So I would prefer getOwnMethods or getDeclaredMethods. Because getRelatedMethods sounds more like (all) related method, not only these which are delcared directly in current concept and are not inherited from super type

@monperrus
Copy link
Copy Markdown
Collaborator

So I would prefer getOwnMethods or getDeclaredMethods

Just renamed it to getDeclaredMethods. I'm still not sure it should be in this class.

Would mmMethod.getDeclaredMethods() be conceptually equivalent to mmMethod.getConcept().getRelatedMethods(mmMethod)?

@pvojtechovsky
Copy link
Copy Markdown
Collaborator Author

Would mmMethod.getDeclaredMethods() be conceptually equivalent to mmMethod.getConcept().getRelatedMethods(mmMethod)?

yes, it would be conceptually equivalent. So API can be changed like this, but the data should be stored same - so we assure that it behaves same

@monperrus
Copy link
Copy Markdown
Collaborator

By working on getDeclaredMethods, I finally got a solution where all tests pass with method getDeclaredMethods / field ownMethods.

Is there something I don't understand? Is there a missing test?

@pvojtechovsky
Copy link
Copy Markdown
Collaborator Author

Is there something I don't understand?

Probably yes. I don't understand your changes - it cannot work. You changed the meaning of members - there is different values now so it fails.

Is there a missing test?

sure. I did not developed that using "Test driven development" rules, so there was a code needed by other tests, which was not directly tested by MetamodelTest.

I will need some time to remember the purpose of own methods, but they are definitely need.

I suggest to rollback the changes related to own methods

@pvojtechovsky
Copy link
Copy Markdown
Collaborator Author

I suggest to rollback your last commit. We can then discuss the state before that commit and I can explain your questions. But your latest changes are too deep and changed a lot.

@pvojtechovsky
Copy link
Copy Markdown
Collaborator Author

Is there a missing test?

CtScannerTest#testScannerCallsAllProperties is not only a test of scanner but also a test of metamodel. I think you agree that CtScanner contains some unique information about spoon model. So "comparing" the CtScanner and Metamodel types and properties is the only test which can check whether all concepts and properties are as expected.

@monperrus
Copy link
Copy Markdown
Collaborator

You're right. I'll rollback.

@monperrus
Copy link
Copy Markdown
Collaborator

Worked on it. The goal was to:

  • remove field MMMethod#superTypes in which was redundant with ownMethods
  • remove a discrepancy: ownMethods also contains other methods from upper in the class put by addSuperField

This has worked well, but for CtScannerTest and ReplaceParametrizedTest.

For handling this, this was the opportunity to simplify two things:

  • simplify isDerived/isUnsettable
  • only consider the interface classes in the metamodel, and not the implementation classes

Now all tests pass!

OK with this?

}

MMMethod getter = mmField.getMethod(MMMethodKind.GET);
System.err.println("---"+getter.getSignature());
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it intentional?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


if(getter.getName().equals("getComments") && leafConcept.getModelInterface().isSubtypeOf(ctRefRef)) {
if(getter.getName().equals("getComments") && leafConcept.getMetamodelInterface().isSubtypeOf(ctRefRef)
) {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the new line before that line intentional?

// contract: CtScanner only calls methods that have a role and the associated getter
if (calledMethods.size() > 0) {
problems.add("CtScanner " + visitMethod.getPosition() + " calls unexpected methods: "+calledMethods);
fail("CtScanner " + visitMethod.getPosition() + " calls unexpected methods: "+calledMethods);
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why that? A) change all to fail or keep all as problems.add(). WDYT?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

mmConcept.getRoleToProperty().forEach((role, mmField) -> {
if (mmField.isUnsettable()) {
//contract: all unsettable fields are derived too
assertTrue("Unsettable field " + mmField + " must be derived too", mmField.isDerived());
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you removed that contract? Is it no more true?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it was hard to understand and debug.

now the contract is much easier: if the method or one of its ancestor contains the Derived annotation (resp Unsettable) it is derived (resp unsettable)

the test has been adapted accordingly

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines was the test you required here #1904
I guess the contract "unsettable implies derived" should be still assert by a test. So I suggest to keep these lines


RoleHandler rh = RoleHandlerHelper.getRoleHandler(o.getClass(), mmField.getRole());
if (mmField.getName().equals("interface")) {
System.out.println("");
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forgot the breakpoint, sorry, removed!

@pvojtechovsky
Copy link
Copy Markdown
Collaborator Author

OK with this?

Yes, I like these simplifications. Thank You Martin 👍

@monperrus
Copy link
Copy Markdown
Collaborator

Then, I'll merge after Travis, and you can proceed with rebasing the Pattern branch afterwards.

@pvojtechovsky
Copy link
Copy Markdown
Collaborator Author

The Travis failed on timeout (downloading some dependencies), so I rebased to trigger next build

@pvojtechovsky
Copy link
Copy Markdown
Collaborator Author

@surli the travis failed on timeout second time. Any idea?

@spoon-bot
Copy link
Copy Markdown
Collaborator

API changes: 1 (Detected by Revapi)

Old API: fr.inria.gforge.spoon:spoon-core:jar:6.3.0-20180608.225255-128 / New API: fr.inria.gforge.spoon:spoon-core:jar:6.3.0-SNAPSHOT

Class was removed.
Old class Metamodel
New none
Breaking binary: breaking

@pvojtechovsky
Copy link
Copy Markdown
Collaborator Author

@monperrus CI finally passed. It is ready for merge

@monperrus monperrus merged commit 1e6e4a4 into INRIA:master Jun 9, 2018
@pvojtechovsky pvojtechovsky deleted the refMoveMetamodel branch June 9, 2018 08:13
@surli surli mentioned this pull request Jun 25, 2018
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

Successfully merging this pull request may close these issues.

3 participants