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

List possible variables and type names when cannot find reference #166

Closed
kaleidawave opened this issue Jun 20, 2024 · 14 comments · Fixed by #180
Closed

List possible variables and type names when cannot find reference #166

kaleidawave opened this issue Jun 20, 2024 · 14 comments · Fixed by #180
Assignees
Labels
checking Issues around checking enhancement New feature or request good-first-issue PRs welcome 🙏 just-rust No TypeScript / type checking knowledge needed

Comments

@kaleidawave
Copy link
Owner

kaleidawave commented Jun 20, 2024

When a variable name cannot be found an error is raised

For the current this means the somethin will raise a type error

const something = ...
console.log(somethin)

However the current error for this sort of not found reference error is:

error: 
    ┌─ demo.tsx:799:12
    │
799 │     const a = not_found
    │               ^^^^^^^^^ Could not find variable 'not_found' in scope

It would be better for the error to include possible alternatives that are in scope:

error: 
    ┌─ demo.tsx:799:12
    │
799 │     const a = not_found
    │               ^^^^^^^^^ Could not find variable 'not_found' in scope
    │     
    |     Did you mean `found` or `is_found`

I started on this, but didn't finish. You can add the possible fields to the TypeCheckerError::CouldNotFindType, use the levenshtein crate to find similar (aka low distance) names to the specified one and parents_iter().map(|env| env.variables.keys()) to get variable names in the scope (+ named_types for types)

CouldNotFindVariable {
variable: &'a str,
possibles: Vec<&'a str>,
position: SpanWithSource,
},
CouldNotFindType(&'a str, SpanWithSource),

levenshtein = "1"

I would recommend approaching it by

@kaleidawave kaleidawave added enhancement New feature or request checking Issues around checking good-first-issue PRs welcome 🙏 just-rust No TypeScript / type checking knowledge needed labels Jun 20, 2024
@vHugoObject
Copy link
Contributor

Can I take this?

@kaleidawave
Copy link
Owner Author

Sure @vHugoObject, no one has taken it. Have updated the description. LMK if you get stuck on anything!

@vHugoObject
Copy link
Contributor

To be clear, I should create a typescript file with some code where a variable cannot be found and place that example file in checker/examples so that it can be ran with cargo run -p ezno-checker --example run_checker?

@kaleidawave
Copy link
Owner Author

I would first start by creating a function (possibly in a empty project) that is like pub fn get_closest(items: Iterator<Item=&str>, closest_to: &str) -> Option<&str> and satisfies the test assert_eq!(get_closest(["something", "unrelated", "Math"], "somethin"), Some("something"));.

Once that works you can try wiring that into the checker in the place mentioned above.

To test it out, yes copy code above to a file anywhere (e.g. code.ts, doesn't have to be in checker/examples), then you can check that you have implemented it correctly using cargo run -p ezno-checker --example run_checker code.ts

@vHugoObject
Copy link
Contributor

Yes, I understood the first part and I already have the function written. My question was more should I add and commit code.ts to the example folder for other people to use not just me? Also "possibles" is currently expecting a "Vec<&'a str>". Shouldn't that be the return type of get_closest instead of &str?

@kaleidawave
Copy link
Owner Author

Awesome. At the moment there isn't any general example ts files so I probably wouldn't commit the example file. Normally this sort of change would be shown in the specification checking tests but they don't register or check extra/labels in diagnostics so it won't have an effect there.

Yes possibles can be &str. Maybe it should Option<&str> and only match if the has a short distance?

Looking forward to the PR. Once I see the new code I will have a think about testing/examples for the new functionality!

@vHugoObject
Copy link
Contributor

vHugoObject commented Jul 16, 2024

Ok, so "possible" as "Option<&str>" or "possibles" as "Option<Vec<&str>>"? I ask because this is the signature of levenshtein: fn levenshtein(a: &str b: &str) -> usize. So I was just going to do something like items.filter(|item| levenshtein(closest_one, item) < 2).collect::<Vec<&str>>(). Then I could do a match-case based on the length of the list so that the error message would be "Did you mean found", "Did you mean found or is_found" or "Did you mean found,is_found or founder".

@kaleidawave
Copy link
Owner Author

kaleidawave commented Jul 16, 2024

Yep possible: Vec<&str> looks good. Then for the reporting in diagnostics.rs you could match based on slice. I remember doing something in a different project like

match possibles.as_slice() {
  [] => None,
  [a] => format!("did you mean {a}"),
  [a, b] => format!("did you mean {a} or {b}"),
  [a @ .., b] => format!("did you mean {items} or {b}", items = a.join(", ")),
}

@vHugoObject
Copy link
Contributor

So I am able to get variables using env.variables.keys() but env.named_types.keys() returns nothing.

@kaleidawave
Copy link
Owner Author

Hmm? That shouldn't be non empty because it is used in get_type_from_name?

Does it work for the following?

type SomeType = number;
let x: SumType = 2;

@kaleidawave
Copy link
Owner Author

Also just wondering do you want to also add possible suggestions for import not found (which would need changes to get_export) and property not found (using properties_on_type).

@vHugoObject
Copy link
Contributor

Ok, the issue is there is CouldNotFindType and CannotFindType. Now that I added possibles as a field to CannotFindType, potential types are shown when I run a test file with your example. I am not sure when CouldNotFindType is called or what the difference between the two is, but for now both have possibles fields. And yeah, I can go ahead and do import not found and property not found.

@vHugoObject
Copy link
Contributor

"PropertyDoesNotExist" for properties and "CannotOpenFile" for imports?

@kaleidawave
Copy link
Owner Author

Ok, the issue is there is CouldNotFindType and CannotFindType. Now that I added possibles as a field to CannotFindType, potential types are shown when I run a test file with your example. I am not sure when CouldNotFindType is called or what the difference between the two is, but for now both have possibles fields. And yeah, I can go ahead and do import not found and property not found.

Ah yes I found there was two errors for the same thing by mistake, should merge the two into the same variant.

"PropertyDoesNotExist" for properties and "CannotOpenFile" for imports?

Yep, if possible that would be great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
checking Issues around checking enhancement New feature or request good-first-issue PRs welcome 🙏 just-rust No TypeScript / type checking knowledge needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants