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

Implement containerSeemsToBeEmptyDomElement (regex free) #691

Merged
merged 6 commits into from
Mar 23, 2025

Conversation

frodi-karlsson
Copy link
Contributor

@frodi-karlsson frodi-karlsson commented Mar 22, 2025

Scouring some discussions I see regex is not favored due to Go not being very fast at it (?) so I assume that's why this function got "!!!"d. With that assumption, it's pretty straight forward to convert the Strada implementation to simple string checks so that's this.

@@ -10826,7 +10826,15 @@ func (c *Checker) isPropertyAccessible(node *ast.Node, isSuper bool, isWrite boo
}

func (c *Checker) containerSeemsToBeEmptyDomElement(containingType *Type) bool {
return false // !!!
if c.compilerOptions.Lib == nil || slices.Contains(c.compilerOptions.Lib, "dom") {
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'm now concerned about this due to #593 (comment) showing that our config parser doesn't actually include "dom" as the output here. Maybe that PR was wrong even though it really seemed right.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see (sort of...), but removing slices.Contains(c.compilerOptions.Lib, "dom") yields no test diff, so I think perhaps this doesn't disprove that comment and this could be wrong

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I ran a quick test showing that comment to also apply for dom, just to be sure

assert.DeepEqual(t, parsedConfigFileContent.CompilerOptions().Lib, []string{"dom"})
        --- parsedConfigFileContent.CompilerOptions().Lib
        +++ →
          []string{
        -       "lib.dom.d.ts",
        +       "dom",
          }

I wouldn't say that test should be included, since we're already testing the same thing in the compiler tsconfig test

Copy link
Member

Choose a reason for hiding this comment

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

If the original code matched only "dom", then I'm just trying to figure out if this means config parsing is still wrong. Not necessarily that your PR was wrong originally.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've revert back to the Strada-like check for now, as a default until we know more there

Copy link
Member

@jakebailey jakebailey Mar 22, 2025

Choose a reason for hiding this comment

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

Okay, yeah, so this code in strada has always been broken.

I modified strada to print compilerOptions.lib when this function is called, and the tests print lines like:

[ 'lib.es2015.d.ts', 'lib.es2017.sharedmemory.d.ts' ]
[ 'lib.es5.d.ts', 'lib.dom.d.ts' ]

So !compilerOptions.lib.includes("dom") is always true. 😆

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Being a bit unsure what to do, I opened an issue here microsoft/TypeScript#61466 and re-implemented the fixed version here

Comment on lines 10836 to 10842
if t.symbol.Name == "EventTarget" || t.symbol.Name == "Node" || t.symbol.Name == "Element" {
return true
}

if !(strings.HasPrefix(t.symbol.Name, "HTML") && strings.HasSuffix(t.symbol.Name, "Element")) {
return false
}
Copy link
Member

Choose a reason for hiding this comment

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

I would probably suggest something like:

name := t.symbol.Name

switch name {
case "EventTarget", "Node", "Element":
	return true
}

name, ok := strings.CutPrefix(name, "HTML")
if !ok {
	return false
}

name, ok := strings.CutSuffix(name, "Element")
if !ok {
	return false
}

// ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TIL the cut functions return an ok! Thanks

Comment on lines 10844 to 10852
isMiddleAlpha := true
for _, r := range t.symbol.Name[4 : len(t.symbol.Name)-7] {
if !('a' <= r && r <= 'z') && !('A' <= r && r <= 'Z') {
isMiddleAlpha = false
break
}
}

return isMiddleAlpha
Copy link
Member

Choose a reason for hiding this comment

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

I'd probably just do:

for _, r := range name {
	if !stringutil.IsASCIILetter(r) {
		return false
	}
}

return true

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just knew there'd be a util somewhere but I searched for 'a' < and not the other way around, thanks again 😄

@jakebailey jakebailey added this pull request to the merge queue Mar 23, 2025
Merged via the queue into microsoft:main with commit c5b95c1 Mar 23, 2025
22 checks passed
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.

2 participants