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

Scope tests #2053

Merged
merged 76 commits into from
Dec 6, 2023
Merged

Scope tests #2053

merged 76 commits into from
Dec 6, 2023

Conversation

AndreasArvidsson
Copy link
Member

@AndreasArvidsson AndreasArvidsson commented Nov 22, 2023

Started implementing a new scope handler test representation

[Content]
const name = "Hello world";
              ^^^^^^^^^^^^^

Originally I was thinking of doing ^ for each character. That worked fine until @pokey asked the question about empty ranges which we actually has in a few places. So I switch to a multiline representation of [---] where the empty range would be [].

[Content]
 function myFunk() {
[-------------------
 
 }
 -]

I do wonder if we want to start multiline ranges above the source code and end it below. Makes it so the code is actually inside the range endings.

[Content]
[-------------------
 function myFunk() {
 
 }
 -]

Relevant issues
#1524
#2010

Checklist

  • I have added tests
  • I have updated the docs and cheatsheet
  • [-] I have not broken the cheatsheet

@pokey
Copy link
Member

pokey commented Nov 22, 2023

So I switch to a representation of [---] where the empty range would be [].

As discussed in original issue, we'd like to remove the brackets when it's a single-line range. Why not just use the originally suggested format, modulo the notion that we do one range type per section?

I do wonder if we want to start multiline ranges above the source code and end it below. Makes it so the code is actually inside the range endings.

I think that makes sense if there are only two lines, but what happens if there are more lines? Do the middle ones go above or below? I think I'd lean toward consistency

@AndreasArvidsson
Copy link
Member Author

AndreasArvidsson commented Nov 22, 2023

So I switch to a representation of [---] where the empty range would be [].

As discussed in original issue, we'd like to remove the brackets when it's a single-line range. Why not just use the originally suggested format, modulo the notion that we do one range type per section?

It's just a question about how we would represent an empty range?

I do wonder if we want to start multiline ranges above the source code and end it below. Makes it so the code is actually inside the range endings.

I think that makes sense if there are only two lines, but what happens if there are more lines? Do the middle ones go above or below? I think I'd lean toward consistency

the lines outside of the range would not be affected by this.

[Content]
 // before
 function myFunk() {
[-------------------

 }
 -]
 // after

vs

[Content]
 // before
[-------------------
 function myFunk() {

 }
 -]
 // after

@pokey
Copy link
Member

pokey commented Nov 22, 2023

It's just a question about how we would represent an empty range?

By "original format" I mean that specified in the Examples section of the description of #1524, just modified so that

  • we have unmodified document at the top before ---
  • we reproduce document once per range type per target
  • instead of varying the annotation style by range type, we always use the { / ^ style (but note that we drop the { for single-line targets, as per initial spec, in contrast to your suggestion here). I much prefer ^ to -, but I guess if we adopt your other suggestion then the start arrows are pointing the wrong direction 😅

the lines outside of the range would not be affected by this.

no I don't mean lines outside range, I mean lines inside range. But I guess we can just leave out the annotations there because we know the range is contiguous? eg

[content]
[-----------
 if (true) {
     const foo = "bar";
 }
 -]

I think it's an interesting idea, tho I wonder if we drop a bunch of the -'s in this case because they're a bit misleading, because then there's no dashes above or below the other internal lines. Maybe we just drop the -s altogether and just use [ / ] (though I think I might prefer curlies)

I also wonder if there's some ambiguity here as there's no marker distinguishing annotation lines from code lines, and we're no longer following alternation convention

@AndreasArvidsson
Copy link
Member Author

AndreasArvidsson commented Nov 22, 2023

^^^^ for single line and [-- or {--} for multiline sounds reasonable. Would we represent an empty range like [] or {}?

[content]
[-----------
 if (true) {
     const foo = "bar";
 }
 -]

That was what I was thinking. As you said it's a contiguous range. We can of course extend the top line all the way to the right if we think that is a better indicator?

edit: This format also works out quite nicely when we have leading and trailing delimiters with empty lines

[#2 Leading delimiter: Content]
[
 
 aaa
 ]

 
[#2 Trailing delimiter: Content]
 
   [
 aaa
 
 ]

@AndreasArvidsson
Copy link
Member Author

@pokey I have updated the fixture files. [ vs { is something we can discuss further. Does the format look okay otherwise?

Copy link
Member

@pokey pokey left a comment

Choose a reason for hiding this comment

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

Just had a quick look through a few of the fixture files, and left a few comments. Lmk if you want me to review the rest

@AndreasArvidsson
Copy link
Member Author

AndreasArvidsson commented Nov 30, 2023

Do we want iteration scope in these fixtures? Or maybe that should be a separate fixture?

@pokey
Copy link
Member

pokey commented Nov 30, 2023

Hmm. Not sure. Maybe separate fixture? I wonder if iteration scope for each scope should be its own facet. Not a bad idea, to make people think about iteration scope for scopes for which it matters

@AndreasArvidsson
Copy link
Member Author

Yes I was thinking of separate facets. Probably a good idea?

@pokey
Copy link
Member

pokey commented Nov 30, 2023

Yeah let's go with separate facets 👍

@AndreasArvidsson
Copy link
Member Author

@pokey Iterations scope facet and fixtures added


export const htmlSupport: LanguageScopeSupportFacetMap = {
["key.attribute"]: supported,
["tags.element"]: supported,
Copy link
Member

Choose a reason for hiding this comment

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

Why the .element here?

Copy link
Member Author

Choose a reason for hiding this comment

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

We might have tags in another context in the future. I'm just trying to be thorough.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm. I guess it's a bit more future proof, tho feels like following this convention to the letter might result in some awkward names. Idk cc/ @josharian

Copy link
Collaborator

Choose a reason for hiding this comment

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

idk either

how immutable do we need these facets to be? can we lower the cost of mistakes sufficiently that it doesn't matter much?

Copy link
Member Author

Choose a reason for hiding this comment

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

Were gonna have a lot of files with these facets as their name so it's not gonna be that easy to change them, but also definitely not impossible.

Copy link
Member

Choose a reason for hiding this comment

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

I guess a simple rename should handle all the typescript refs, and then we could easily write a script that moves the test fixtures

Copy link
Member Author

Choose a reason for hiding this comment

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

A bit annoying having to do a script, but definitely doable

Copy link
Member

Choose a reason for hiding this comment

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

Update from meet-up: let's go with just tags. It's ok to have the general thing and then sub-facets as well

Comment on lines +4 to +7
[#1 Range] =
[#1 Domain] = 0:0-0:14
0| { value: 123 }
>--------------<
Copy link
Member

Choose a reason for hiding this comment

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

Huh. Technically this iteration scope is not for this facet. Not sure there's much we can do about that tho 🤷‍♂️

Copy link
Member Author

@AndreasArvidsson AndreasArvidsson Dec 1, 2023

Choose a reason for hiding this comment

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

I don't think so. This would be a reason to have more fine grained scopes as well.

Copy link
Member

@pokey pokey Dec 1, 2023

Choose a reason for hiding this comment

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

Yeah fair point. I wonder how many of our facets should really be their own scopes 🤔. I guess nice thing bout facets is it makes it easier for us to switch them to their own scopes later because they're explicitly tagged

Copy link
Member Author

Choose a reason for hiding this comment

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

Probably quite a few.

Copy link
Member Author

@AndreasArvidsson AndreasArvidsson Dec 2, 2023

Choose a reason for hiding this comment

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

I think one indicator that a scope maybe should split is that we have multiple iteration scopes as in the above example. For example all the different types of ways you can do functions in javascript is still the same function scope, but a value in a map pair is not really the same thing as a return statement value and they do have different iteration scopes. This is definitely going to be on a case by case basis, but I think that having multiple iteration scopes for the same scope is a bit of a warning sign.

@AndreasArvidsson AndreasArvidsson linked an issue Dec 5, 2023 that may be closed by this pull request
3 tasks
@pokey pokey removed the to discuss Plan to discuss at meet-up label Dec 5, 2023
@AndreasArvidsson
Copy link
Member Author

@pokey Updated after today's meeting discussion

Copy link
Member

@pokey pokey left a comment

Choose a reason for hiding this comment

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

Couple more minor comments

.pre-commit-config.yaml Outdated Show resolved Hide resolved
packages/common/src/scopeSupportFacets/textual.ts Outdated Show resolved Hide resolved
AndreasArvidsson and others added 3 commits December 6, 2023 02:20
Co-authored-by: Pokey Rule <755842+pokey@users.noreply.github.com>
Copy link
Member

@pokey pokey left a comment

Choose a reason for hiding this comment

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

I find I'm not in love with label and examples fields of facet info. Shall we make them optional and delete them where they're unhelpful? I'm happy to do that as I have opinions about where they're unhelpful 😅

["value.assignment"]: supported,

["key.attribute"]: notApplicable,
["tags"]: notApplicable,
Copy link
Member

Choose a reason for hiding this comment

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

this isn't true. JSX is valid in JS. Shall we just mark it unsupported / leave it undefined for now?

Copy link
Member Author

@AndreasArvidsson AndreasArvidsson Dec 6, 2023

Choose a reason for hiding this comment

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

I was thinking that we should test all jsx under javascriptreact and not javascript. I would leave it undefined if anything. Saying that it's unsupported is not true either.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm. Probably fine for now. At some point we should prob figure out how to automatically run tests for all langs where they're applicable, eg run our js tests in ts, etc. We could maybe make subsets of languages and then define a way to import tests from one language to another. But we can do that in a follow-up

label: "Word",
description: "A single word in a token",
scopeType: "word",
examples: ["foo_bar", "fooBar"],
Copy link
Member

Choose a reason for hiding this comment

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

These examples are pretty misleading. If we're going to take the example thing seriously, we need to figure out a way to demarcate substrings. I do question how useful / ergonomic it is to just drop these examples into strings. The examples from test casees are already there and likely to be far more useful

Copy link
Member Author

Choose a reason for hiding this comment

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

I was thinking examples as a very general guide. If you want details you she'd look at the actual fixtures

label: "Line",
description: "A single line in the document",
scopeType: "line",
examples: ["foo"],
Copy link
Member

Choose a reason for hiding this comment

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

this is unhelpful in the other direction. Really questioning the utility of these examples 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

If you don't like them we can't ditch them

export interface ScopeSupportFacetInfo {
readonly label: string;
readonly description: string;
readonly scopeType: SimpleScopeTypeType;
Copy link
Member

Choose a reason for hiding this comment

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

What's going to happen when we want to test "round"? That's not a simple scope type

Copy link
Member Author

@AndreasArvidsson AndreasArvidsson Dec 6, 2023

Choose a reason for hiding this comment

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

I just copied the interface from your issue. We can make it a scope type instead?

Copy link
Member

Choose a reason for hiding this comment

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

Maybe ok for the time being. I wonder if we create a utility function to make it more ergonomic once we need to support complex scopes.

label: "Attributes key",
description: "Key(LHS) of an attribute",
scopeType: "collectionKey",
examples: ['id="root"'],
Copy link
Member

Choose a reason for hiding this comment

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

As in other examples, this would be more helpful if there were a way to put it in context, but a flat string is not a particularly comfortable way to do that

Copy link
Member Author

Choose a reason for hiding this comment

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

Absolutely.

description: "Iteration of map pair keys",
scopeType: "collectionKey",
isIteration: true,
examples: ["{ value: 0 }"],
Copy link
Member

Choose a reason for hiding this comment

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

This shouldn't include the curly brackets, but then it becomes pretty unclear what's going on here. I guess we could use multiple?

Copy link
Member Author

@AndreasArvidsson AndreasArvidsson Dec 6, 2023

Choose a reason for hiding this comment

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

The examples are not the content range. It's just example of the type of code that would have this facet

examples: ['id="root"'],
},
["key.mapPair"]: {
label: "Map key",
Copy link
Member

Choose a reason for hiding this comment

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

These labels feel kinda useless / arbitrary and a bit redundant with the description. I wonder if we just autogenerate these from the id like we do for human-readable scope types. Ie key.mapPair => "key (map pair)"

Copy link
Member Author

Choose a reason for hiding this comment

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

Sounds good to me

@@ -0,0 +1,82 @@
import { SimpleScopeTypeType } from "../types/command/PartialTargetDescriptor.types";

const scopeSupportFacets = [
Copy link
Member

Choose a reason for hiding this comment

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

I do feel like all of these could be their own fine-grained scope. I wonder if we think about moving in that direction sooner rather than later

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't quite follow what you're suggesting? What exactly do you want to make more fine grained? I definitely prefer them fine grained

Copy link
Member

Choose a reason for hiding this comment

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

Eg key.mapPair, key.attribute, etc could all be their own scopes. I think every facet here should probably just be a new fine-grained scope. Not something to change for this PR just an observation. Makes me question the notion of facets entirely, but they're undoubtedly a step forward so nothing to get in the way of this PR

Copy link
Member Author

Choose a reason for hiding this comment

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

Totally agree

@AndreasArvidsson
Copy link
Member Author

I would be happy to remove label and examples, but I don't think we should make them optional.

@pokey pokey enabled auto-merge December 6, 2023 17:29
@pokey pokey added this pull request to the merge queue Dec 6, 2023
Merged via the queue into main with commit 43cf0da Dec 6, 2023
14 checks passed
@pokey pokey deleted the scope_tests branch December 6, 2023 17:38
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.

New representation for scope handler tests
3 participants