Skip to content
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: feature: SourcePosition#isValidPosition(), throw exception when accessing invalid position #1964

Merged
merged 8 commits into from
Apr 17, 2018

Conversation

pvojtechovsky
Copy link
Collaborator

@pvojtechovsky pvojtechovsky commented Apr 15, 2018

This is alternative to #1963

  1. introduces new Concept Source
/**
 * This interface represents the origin source of a program element
 */
public interface Source extends Serializable {

	/**
	 * Gets the file for this position.
	 */
	File getFile();

	/**
	 * Gets the compilation unit for this position.
	 */
	CompilationUnit getCompilationUnit();
}
  1. SourcePosition extends Source
  2. CtElement#getPosition() returns null if source position is not known. It is DerivedProperty now.
  3. there is new CtElement#getSource() and setSource(Source)
  4. there is new CtElement#getCompilationUnit() which return not null even for cases when NoSourcePosition was used before.
  5. all CtElements which belongs to one Compilation unit share one SourceImpl (before each had own instance of PartialSourcePositionImpl) - less memory needed
  6. removes NoSourcePosition and PartialSourcePosition.

It is not backward compatible for the code which expected NoSourcePosition or asked getSourceStart() >= 0, ... , but:

  • most of the modified code was incorrect anyway, because such check did not counted with new PartialSourcePosition , ...
  • I think it is now more KISS and client's friendly for future code.

WDYT?

@pvojtechovsky pvojtechovsky changed the title refactor: SourcePosition. Removed (Partial/No)SourcePosition WIP: refactor: SourcePosition. Added Source, Removed (Partial/No)SourcePosition Apr 15, 2018
@pvojtechovsky pvojtechovsky changed the title WIP: refactor: SourcePosition. Added Source, Removed (Partial/No)SourcePosition review: refactor: SourcePosition. Added Source, Removed (Partial/No)SourcePosition Apr 15, 2018
@monperrus
Copy link
Collaborator

  1. CtElement#getPosition() returns null if source position is not known. It is DerivedProperty now.

Returning null is a bad and dangerous practice. I would prefer not to go in this direction.

  1. all CtElements which belongs to one Compilation unit share one SourceImpl (before each had own instance of PartialSourcePositionImpl) - less memory needed

That's good!

  1. there is new CtElement#getSource() and setSource(Source)

What would be the difference with getPosition?

@monperrus
Copy link
Collaborator

Sidenote: when it is no backward-compatible, please avoid prefixing the PR with refactoring. If it is a refactoring, by convention/definition, it does not change the behavior and thus there are no assertion modification or deletion in src/test.

@monperrus monperrus changed the title review: refactor: SourcePosition. Added Source, Removed (Partial/No)SourcePosition review: fix: SourcePosition. Added Source, Removed (Partial/No)SourcePosition Apr 15, 2018
@pvojtechovsky
Copy link
Collaborator Author

Returning null is a bad and dangerous practice. I would prefer not to go in this direction.

What do you suggest? Note that existing approach with NoSourcePosition and PartialSourcePosition has some problem - see problems discussed in #1963

@pvojtechovsky
Copy link
Collaborator Author

there is new CtElement#getSource() and setSource(Source)

What would be the difference with getPosition?

I do not understand, the question. But let's discuss first the alternative for getPosition returns null. It is the main point of this PR, so any change here will completely change whole solution ;-)

@monperrus
Copy link
Collaborator

monperrus commented Apr 15, 2018 via email

@pvojtechovsky
Copy link
Collaborator Author

main problem?

nobody really knows how to correctly ask whether value returned by CtElement#getPosition contains source position or not.

With this PR it is clear
if (element.getPosition() != null) { /*then you can use position*/} else {/*it is not available*/}

But what is correct without this PR???

@monperrus
Copy link
Collaborator

monperrus commented Apr 15, 2018

What you proposed sounds good to me

boolean isValid() {
  return this instanceof NoSourcePosition == false;
}

One method, clear responsibility, encapsulates implementation detail, no null value

@pvojtechovsky
Copy link
Collaborator Author

I have two questions, before I can change this PR:

  1. Do you have better name for that isValid method? May be
  • isPositionValid
  • isStartEndValid
  • ...
    because for example compilation unit and source File are valid always ...
  1. what should return getStart(), ... when isValid() == false ??
    A) -1 like till now
    B) throw exception - like @tdurieux suggests?

I prefer throw exception too. It avoids ugly bugs...

@tdurieux
Copy link
Collaborator

  1. what about isValidPosition?

  2. A prefer the option B

@pvojtechovsky
Copy link
Collaborator Author

Thanks Thomas for your opinion, I agree with you.
@monperrus please give us feedback too because throwing exceptions is not backward compatible ... so will you accept that solution?

@monperrus
Copy link
Collaborator

agree with @tdurieux.

@pvojtechovsky pvojtechovsky changed the title review: fix: SourcePosition. Added Source, Removed (Partial/No)SourcePosition WIP: fix: SourcePosition. Added Source, Removed (Partial/No)SourcePosition Apr 16, 2018
@@ -269,6 +273,16 @@ public void setAutoImport(boolean autoImport) {
this.autoImport = autoImport;
}

private PartialSourcePositionImpl myPartialSourcePosition;
/**
* @return a {@link Source} which points to this {@link CompilationUnit}. It always returns same value to safe memory.
Copy link
Collaborator

Choose a reason for hiding this comment

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

the path to Source is not found during the javadoc generation

@monperrus
Copy link
Collaborator

Looking forward to it, it should fix the regression identified in Casper: https://travis-ci.org/Spirals-Team/casper/builds/367789415

@pvojtechovsky
Copy link
Collaborator Author

So we are three in this cinema ... looking at yellow circle ... and waiting for happy end :-))

@pvojtechovsky pvojtechovsky changed the title WIP: fix: SourcePosition. Added Source, Removed (Partial/No)SourcePosition review: feature: SourcePosition#isValidPosition(), throw exception when accessing invalid position Apr 17, 2018
@spoon-bot
Copy link
Collaborator

API changes: 1 (Detected by Revapi)

Old API: fr.inria.gforge.spoon:spoon-core:jar:6.3.0-20180417.183645-43 / New API: fr.inria.gforge.spoon:spoon-core:jar:6.3.0-SNAPSHOT

Method was added to an interface.
Old none
New method SourcePosition#isValidPosition()
Breaking binary: non_breaking,

@monperrus monperrus merged commit 7f29a81 into INRIA:master Apr 17, 2018
@monperrus
Copy link
Collaborator

thanks for the comprehensive refactoring

@pvojtechovsky pvojtechovsky deleted the refSourcePosition branch April 17, 2018 18:57
@monperrus
Copy link
Collaborator

I confirm that the regression has been fixed

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

Successfully merging this pull request may close these issues.

5 participants