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

Re-add local variable type hints #5457

Draft
wants to merge 11 commits into
base: dev/feature
Choose a base branch
from
Draft

Conversation

TheLimeGlass
Copy link
Collaborator

@TheLimeGlass TheLimeGlass commented Feb 17, 2023

Description

Re-adds local variable type hints. This allows Skript to understand local variable types in some circumstances, and provide warnings so the user knows nothing will happen. Like setting a variable to a string and then attempting to teleport the player to the string should produce a warning.

Also made calling functions with local variables of the wrong type error #1229

Considering this breaking change I guess, since some users may not know their scripts aren't working.

Examples of proper warning now:

test "type hints":
	set {_string} to "empty"
	set helmet of last spawned zombie to 1 of {_string}
	# {_string} still a string
	add stone to {_string} # Fails and does nothing
	# {_string} still a string
	set helmet of last spawned zombie to 1 of {_string}
	# {_string} still a string

	set {_timespan} to a second
	set helmet of last spawned zombie to 1 of {_timespan}
[Skript] Line 3: (..\..\..\..\..\src\test\skript\tests\misc\type-hints.sk)
     Variable '{_string}' is of type 'text', not a 'item stack, item type or entity type'
     Line: set helmet of last spawned zombie to 1 of {_string}

 [Skript] Line 7: (..\..\..\..\..\src\test\skript\tests\misc\type-hints.sk)
     Variable '{_string}' is of type 'text', not a 'item stack, item type or entity type'
     Line: set helmet of last spawned zombie to 1 of {_string}

 [Skript] Line 11: (..\..\..\..\..\src\test\skript\tests\misc\type-hints.sk)
     Variable '{_timespan}' is of type 'time span', not a 'item stack, item type or entity type'
     Line: set helmet of last spawned zombie to 1 of {_timespan}

Notes:

  • I think the issues bensku had in the past was the clearing of the type hints, which would cause either a race condition or just be the incorrect type.
  • The test currently produces warnings as it should. There currently isn't a way to test against proper warnings, so i'll also need to do that in a new pull request soon.
  • No, I do not think this feature should be configurable via the config.sk, if a type is not the correct type it will not work in general, so why hide the warning. What are you doing? (I added this to EffSuppressWarnings so it can technically be accessed for users, it's more added for the test runner though)
  • Addons can use the following if they wish to disable this warning because they're doing witch craft:
getParser().getCurrentScript().suppressWarning(ScriptWarning.LOCAL_VARIABLE_TYPE);

Target Minecraft Versions: any
Requirements: none
Related Issues: #1229, #3864 and #5060

@TheLimeGlass TheLimeGlass added bug An issue that needs to be fixed. Alternatively, a PR fixing an issue. variables Related to variables and/or storing them. labels Feb 17, 2023
@TheLimeGlass TheLimeGlass marked this pull request as draft February 17, 2023 12:02
@TheLimeGlass TheLimeGlass marked this pull request as ready for review February 17, 2023 13:57
@TheLimeGlass
Copy link
Collaborator Author

TheLimeGlass commented Feb 17, 2023

Also fixed #1229

@TheLimeGlass TheLimeGlass added the breaking changes Pull or feature requests that contain breaking changes (API, syntax, etc.) label Feb 17, 2023
Copy link
Member

@APickledWalrus APickledWalrus left a comment

Choose a reason for hiding this comment

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

Looking excellent 👍

src/main/java/ch/njol/skript/lang/Variable.java Outdated Show resolved Hide resolved
Copy link
Contributor

@kiip1 kiip1 left a comment

Choose a reason for hiding this comment

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

Looks good

);
}

private static final int CONFLICT = 1, INSTANCE = 2, CONJUNCTION = 3, START_EXPR = 4;
private static final int CONFLICT = 1, INSTANCE = 2, CONJUNCTION = 3, START_EXPR = 4, LOCAL_TYPES = 5;
Copy link
Contributor

Choose a reason for hiding this comment

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

Time for this to become an enum I guess

Copy link
Member

Choose a reason for hiding this comment

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

Yeah we could just use a switch statement to assign the ScriptWarning value based on the parse mark

Copy link
Contributor

@kiip1 kiip1 Feb 17, 2023

Choose a reason for hiding this comment

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

Or some ordinal like:

int mark = parseResult.mark;
if (mark < 0 || mark >= Enum.values().length)
	return false;
warning = Enum.values()[mark];

Copy link
Member

Choose a reason for hiding this comment

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

Oh yeah this is already done in init. Could probably store the ScriptWarning we are suppressing and use that for the toString switch instead of the int constants

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I was thinking of making it it's own type. This is user accessable, so making it a ClassInfo is just simplier for us to add new enums in the future.

I wasn't going to address this here, but I guess I can.

Copy link
Member

Choose a reason for hiding this comment

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

We could do that too. You don't have to do it for this PR though

src/main/java/ch/njol/skript/ScriptLoader.java Outdated Show resolved Hide resolved
src/main/java/ch/njol/skript/ScriptLoader.java Outdated Show resolved Hide resolved
src/main/java/ch/njol/skript/variables/TypeHints.java Outdated Show resolved Hide resolved
@TPGamesNL
Copy link
Member

I remember one of the issues of local variable type hints being syntax like do X and store result in {_var}, often used for async computations. Skript doesn't know at parsetime that this variable will be changed, so it will know have the right type hints.

How does this PR deal with that issue?

@TheLimeGlass
Copy link
Collaborator Author

TheLimeGlass commented Feb 17, 2023

I remember one of the issues of local variable type hints being syntax like do X and store result in {_var}, often used for async computations. Skript doesn't know at parsetime that this variable will be changed, so it will know have the right type hints.

How does this PR deal with that issue?

It doesn't, and it's not the end of the world either, it'll act without type hints still.

Maybe a better implementation rather than listening to the set/add would be the listening in on the variable change in Variables.class.

Would be able to add a JUnit async effect test once the JUnit pull request is merged.

@TPGamesNL
Copy link
Member

Listening for acceptsChanges might also not work, I've seen addons use if (expr instanceof Variable) {} before instead of properly checking if the expr can be changed, so they never indicate to Variable that the var will be changed at runtime.

Indeed it's not the end of the world, but it's annoying for a user to get a false positive warning, it may confuse them.

Make sure to also test for code that changes Event (and thus local variables) within a structure, such as sections (newer and older impls of them). Also those that carry over local variables from another event (e.g. spawn section of Skript)

@TheLimeGlass TheLimeGlass requested review from kiip1 and APickledWalrus and removed request for kiip1 February 18, 2023 01:27
@TheLimeGlass
Copy link
Collaborator Author

Listening for acceptsChanges might also not work, I've seen addons use if (expr instanceof Variable) {} before instead of properly checking if the expr can be changed, so they never indicate to Variable that the var will be changed at runtime.

Indeed it's not the end of the world, but it's annoying for a user to get a false positive warning, it may confuse them.

Make sure to also test for code that changes Event (and thus local variables) within a structure, such as sections (newer and older impls of them). Also those that carry over local variables from another event (e.g. spawn section of Skript)

Ok, well I applied type hints when the change method of the variable expression is used. If an addon does not properly use the change method we cannot provide type hints for it. I don't want to be re-parsing a VariableString to check if it's simple in the Variables.setVariable method.

@TheLimeGlass TheLimeGlass removed the request for review from kiip1 March 19, 2023 09:59
@TheLimeGlass
Copy link
Collaborator Author

TheLimeGlass commented Mar 19, 2023

NOTE: It should be failing. I have to update those tests to correct them now.

@TheLimeGlass TheLimeGlass requested a review from kiip1 March 19, 2023 10:05
@TheLimeGlass TheLimeGlass added the 2.8 Targeting a 2.8.X version release label Mar 19, 2023
@TheLimeGlass

This comment was marked as outdated.

@TheLimeGlass TheLimeGlass marked this pull request as draft March 19, 2023 10:09
@TheLimeGlass TheLimeGlass mentioned this pull request Aug 19, 2023
1 task
@TheLimeGlass TheLimeGlass changed the base branch from master to dev/feature October 28, 2023 09:46
@sovdeeth sovdeeth removed the 2.8 Targeting a 2.8.X version release label Dec 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking changes Pull or feature requests that contain breaking changes (API, syntax, etc.) bug An issue that needs to be fixed. Alternatively, a PR fixing an issue. variables Related to variables and/or storing them.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants