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

SourcePositions are incorrect in some cases #1953

Closed
pvojtechovsky opened this issue Apr 7, 2018 · 18 comments
Closed

SourcePositions are incorrect in some cases #1953

pvojtechovsky opened this issue Apr 7, 2018 · 18 comments

Comments

@pvojtechovsky
Copy link
Collaborator

In the PR #1950 I added check for consistency of source position start/end offsets:

class BodyHolderSourcePositionImpl
	public BodyHolderSourcePositionImpl(...) {
		super(...);
		checkArgsAreAscending(declarationSourceStart, modifierSourceStart, modifierSourceEnd + 1, sourceStart, sourceEnd + 1, bodyStart, bodyEnd + 1, declarationSourceEnd + 1);
...
}
...
protected static void checkArgsAreAscending(int...values) {
	int last = -1;
	for (int value : values) {
		if (value < 0) {
			throw new SpoonException("SourcePosition value must not be negative");
		}
		if (last > value) {
			throw new SpoonException("SourcePosition values must be ascending or equal");
		}
		last = value;
	}
}

It is needed for sniper mode (source code refactored by spoon has minimum differences comparing to origin source code).

But this SourcePosition consistency check causes that many tests fail now.

@tdurieux
Copy link
Collaborator

tdurieux commented Apr 7, 2018

I think it is mostly due to PartialSourcePositionImpl that have negative values.
That is used in CompilationUnitFactory.getOrCreate(...)

@tdurieux
Copy link
Collaborator

tdurieux commented Apr 7, 2018

I tried to fix some of the issues, I have now only 10 tests that do not succeed.
But I found this case that I think we will not be able to fix:

@GlobalAnnotation
public @Deprecated final @TypeAnnotation Void m() {
}

Because getModifierSourceStart and getModifierSourceEnd mean nothing in this case, because there is the annotation between them. Should we move the position of the modifiers in CtExtendedModifier?

@monperrus
Copy link
Collaborator

monperrus commented Apr 7, 2018 via email

@monperrus
Copy link
Collaborator

monperrus commented Apr 7, 2018 via email

@pvojtechovsky
Copy link
Collaborator Author

Source position section of modifiers already contains annotations in other cases ... and I am OK with that personally. Only the name of this section is confusing. Otherwise it is OK. The types behaves same. E.g this one:

public @Deprecated class Xxx {}

And many thanks Thomas for fixing that! I have to learn to create more issues ... and not to do it on my own.... looks like we are not only 3 on github ;-))

@tdurieux
Copy link
Collaborator

I made all the test pass.
But I still need to make nice PRs and some test.
I added the position on each modifier.

I put in modifiersSourceStart and modifiersSourceEnd the min and the max position of the modifiers.
What do you think?
I think it can be some issue with there are different annotation or comments between modifiers. Like in this example where the modifiersSourceStart and modifiersSourceEnd will content public @Deprecated final and not @GlobalAnnotation public @Deprecated final @TypeAnnotation

@GlobalAnnotation
public @Deprecated final @TypeAnnotation Void m() {
}

@pvojtechovsky
Copy link
Collaborator Author

I put in modifiersSourceStart and modifiersSourceEnd the min and the max position of the modifiers.
What do you think?

You cannot avoid mixing of modifiers and annotations, so may be the solution is simply to document that source fragment of modifiers contains all modifiers including all annotations and keep the code as it is. I think that is good solution and it is backward compatible because it already behaves like that on other places.

@tdurieux
Copy link
Collaborator

The issue is that for the moment, it doesn't not include all the modifiers

@pvojtechovsky
Copy link
Collaborator Author

The issue is that for the moment, it doesn't not include all the modifiers

Can I debug it somewhere? Which test, which branch?

@tdurieux
Copy link
Collaborator

Sorry I meant annotations.

But currently with this code the modifier final is not inluded in the interval.

@GlobalAnnotation
public @Deprecated final Void m() {
}

@pvojtechovsky
Copy link
Collaborator Author

Thanks for explanation. I understand.
I would like if "@GlobalAnnotation\npublic @deprecated final" would be included in the interval of modifiers. OK ?

@tdurieux
Copy link
Collaborator

Do you mean that you would prefer to include all the annotations in the interval?

Even in this case @annot public void m(){}?

@pvojtechovsky
Copy link
Collaborator Author

Do you mean that you would prefer to include all the annotations in the interval?

yes exactly. Even in that case. It already behaves like this. It fits to needs of #1927

@pvojtechovsky
Copy link
Collaborator Author

I have checked the code and I was wrong. I have found the PositionBuilder code which tries to search for place where annotations ends and modifiers start. So Spoon actually tries to separated annotations and modifiers (of type and method) into different source fragments.

So my sentences in the comments above: "It already behaves like this." are wrong.

But I still think that we cannot separate annotations and modifiers, because they can be mixed in arbitrary order, so the only reliable solution is to have them in one one shared "modifiers" source interval. May be we can rename getModifiersStart/End to getModifiersAndAnnotationsStart/End ... so it is clear what is inside.

@tdurieux
Copy link
Collaborator

I think it is the same with comments :/

@pvojtechovsky
Copy link
Collaborator Author

yes and no. Comments are special. They behaves like a whitespace in source code.

Note:

  • comments can be everywhere - it is clear that comments are everywhere, so all algorithms which wants to handle them must count with that
  • annotations can be only in source fragment modifiers - so we have to document it in SourcePosition and adapt the code little bit...

@monperrus
Copy link
Collaborator

can we close this issue (the title is not really focused)?

@pvojtechovsky
Copy link
Collaborator Author

ok, I agree to close it. There are still probably some Source position problems, but it makes sense to create individual issues for them. I will do so in next days after checking the state of sniper mode and related failing tests

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

No branches or pull requests

3 participants