-
-
Notifications
You must be signed in to change notification settings - Fork 390
Meta-syntax and annotations. #6571
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
base: dev/feature
Are you sure you want to change the base?
Conversation
In regards to only the sections/structures seeing their annotations and their contents being blind to them, I think it would be nice to provide a standard way to access the annotations of a parent section/structure, so you can suppress warnings in a block instead of on every line that needs it. |
I like annotations, but the meta syntax is Essentially a WrapperExpression. See that class for reference. I don't want to add two variants of the same functionality, unless it does more than modify expressions inside the pattern. |
This can probably done by attaching it to the context, but I don't really know enough about what the sectioncontext is/does to do that reliably myself. I'll wait for Walrus's input. |
1cb2c8b
to
3c5cc56
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little concerned how we will document what annotations exist, but looks great api wise
src/main/java/ch/njol/skript/test/runner/CondHasAnnotations.java
Outdated
Show resolved
Hide resolved
src/main/java/ch/njol/skript/test/runner/CondHasAnnotations.java
Outdated
Show resolved
Hide resolved
src/main/java/ch/njol/skript/test/runner/StructHasAnnotations.java
Outdated
Show resolved
Hide resolved
src/main/java/org/skriptlang/skript/lang/script/Annotation.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm honestly still a little unsure about this feature, but here's my thoughts on the code itself
src/main/java/ch/njol/skript/test/runner/StructHasAnnotations.java
Outdated
Show resolved
Hide resolved
src/main/java/ch/njol/skript/test/runner/StructHasAnnotations.java
Outdated
Show resolved
Hide resolved
src/main/java/ch/njol/skript/test/runner/StructHasAnnotations.java
Outdated
Show resolved
Hide resolved
@@ -175,10 +181,17 @@ protected void loadOptionalCode(SectionNode sectionNode) { | |||
|
|||
@Nullable | |||
public static Section parse(String expr, @Nullable String defaultError, SectionNode sectionNode, List<TriggerItem> triggerItems) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the goal of the changes for this method? It doesn't actually seem to do anything, as the resetting of annotations occurs before the SkriptParser is invoked. That is, nothing happens between saving them and resetting them.
*/ | ||
public interface Annotation extends CharSequence { | ||
|
||
static @NotNull Annotation create(String text) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like @Contract("_ -> new")
public String subSequence(int start, int end) { | ||
if (start == 0) | ||
return '@' + value.substring(0, end + 1); | ||
return value.substring(start + 1, end + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think there needs to be subtraction here rather than addition for start
. I also think you want to leave end
as-is. If for some annotation @hello
, if I do annotation.subSequence(0, 2)
, that should give @h
, but it would currently give @he
(end
should be exclusive)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review got posted early 😔
This is looking better 🙂
src/main/java/org/skriptlang/skript/lang/structure/Structure.java
Outdated
Show resolved
Hide resolved
Co-authored-by: sovdee <10354869+sovdeeth@users.noreply.github.com>
Co-authored-by: Patrick Miller <apickledwalrus@gmail.com>
Co-authored-by: Patrick Miller <apickledwalrus@gmail.com>
Co-authored-by: Patrick Miller <apickledwalrus@gmail.com>
222ff22
to
cd6135d
Compare
Summary
This defines the concept of syntax that only affects other syntax (rather than actually having its own function.)
This also adds an 'annotation': a metadata note visible at parse-time to the upcoming line of code.
(Drafted based on this internal discussion.)
Meta-syntax
This adds an interface for meta-syntax elements.
Meta syntax is syntax that (only) affects other syntax, (e.g. things that do something at parsing time, syntax that modifies another syntax inside it, etc.) but doesn't really do anything by itself.
We don't really have many examples in Skript right now: we usually prefer to add optional flag patterns to the end of syntax
[with [my cool option[s]]]
.You could say that a lot of entries in structures are meta-syntax since they're modifying what the structure is doing rather than actually doing something on their own.
Meta-syntax can be a powerful tool, for example:
Annotations
Annotations are a kind of meta-syntax, they don't do anything functional by themselves at all (they're basically a comment) but they're also visible to upcoming code, which might do something special based on them.
In most languages that have the concept, annotations are used to include metadata for self-reflection, compiler (parsing/interpreting in our case) instructions, debugging and the like.
Annotation Format
Annotations start with the
@
character (similar to Java). I felt that having some character was important to help users differentiate them from code (in the same way that#
marks the beginning of a comment). As annotations are essentially a (visible) comment, it makes sense that they're quite similar.@suppress warnings @case sensitive variables broadcast "hello!"
There's no verification or rules for what follows the
@
: it won't error if a user writes something random (@foo bar
), but it won't have any impact either. I decided to be very relaxed about verification and leave it up to the thing that requires the annotation.Annotation Placement
An @annotation is a piece of metadata attached to code. By itself, it does nothing. There are no errors or penalties for writing a bogus or unknown annotation (in this case it acts like a comment does).
An annotation is visible to (and only to) the line of code it is placed before:
If multiple annotations are placed before a line of code then all will be visible to that line.
Annotations are visible to every element within the line, and are discarded after the line has been parsed.
Annotations placed on a section header line are visible only to the section header.
Annotations placed at the root level before a structure are visible only in that structure's initialisation.
Entries (like triggers) are typically handled in the structure's
load
method, so a structure would have to keep a copy of annotations and make them available here if intended.Annotations don't have native support at the entry-level (since the definition of entries depends entirely on the structure).
It is up to elements within a line how to (or whether to) interact with annotations. Some may have a global effect on any syntax (e. g. suppressing a warning, changing parsing order) whereas others might be relevant ONLY to one syntax.
Annotation-checking API
Most annotation usage will simply be checking is-present.
Annotations can be checked from the parser instance.
They can be checked for presence by:
parserInstance.hasAnnotation(annotation)
parserInstance.hasAnnotation(text)
parserInstance.hasAnnotationMatching(pattern)
parserInstance.hasAnnotationMatching(pattern)
Annotation instances can also be fetched by pattern.
This is useful if an annotation is designed to include some kind of data input. This uses skript pattern matching.
In this case, the pattern match result AND the annotation instance are returned together as a
Match
if present.Any matching annotation can be fetched with
parserInstance.getAnnotationMatching(text/pattern)
, which returns a nullable match.All matching annotations can be fetched with
parserInstance.getAnnotationsMatching(text/pattern)
, which returns a non-null array of (potentially zero) non-null matches.Example Use-cases
This is actually included in this PR as a test dummy currently,
I don't know if it'll stay in after draft, it should probably be more comprehensive.
set {x} to snowball
- item? entity type? event entity?)We don't intend this to be overused -- it should be kept for cases where it's unreasonable (or somehow bad) to build in regular support for something, or where it should be a meta-control toggle rather than a real syntax.
Target Minecraft Versions: any
Requirements: none
Related Issues: requires #6551