Skip to content

Conversation

@natebosch
Copy link
Member

@natebosch natebosch commented Dec 2, 2025

Closes #2567

The error when there is a compilation failure due to a missing main is
less direct than it could be and exposes details of wrapping the test
suite in another library. Add an explicit check for a function declared
with that name when parsing metadata before attempting any compiles.

Add a check to parseMetadata that throws a FormatException if there
is no function declared directly in the library named main. This will
prevent some previously working designs such as exposing a main in a
part or with export, but we do not expect those designs are used in
practice.

Closes #2567

The error when there is a compilation failure due to a missing `main` is
not very clear. Add an explicit check for a definition with that name
when parsing metadata.

This does not handle cases where the definition is not a method, but
those cases should be more rare than omitting main.
_annotations = directives.isEmpty ? [] : directives.first.metadata;
_languageVersionComment = result.unit.languageVersionToken?.value();
_hasMain = result.unit.declarations.any(
(d) => d is NamedCompilationUnitMember && d.name.toString() == 'main',
Copy link
Member Author

Choose a reason for hiding this comment

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

@scheglov - I'm pretty sure toString() is not what I'm meant to be using, but stringValue was null and I didn't see a better route to getting this name. Is there a better option here?

Copy link
Contributor

Choose a reason for hiding this comment

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

If says main, meaning probably a top-level function?
If so, you want FunctionDeclaration and its Token get name.

Copy link
Member Author

Choose a reason for hiding this comment

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

and its Token get name.

What way should I go from the Token instance to a String? Is the .toString() considered a reliable mechanism to get exactly 'main'?

@github-actions
Copy link

github-actions bot commented Dec 2, 2025

PR Health

Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

This check can be disabled by tagging the PR with skip-changelog-check.

@natebosch
Copy link
Member Author

If this doesn't break anything internally I think it might be the lowest cost approach.

@jakemac53 WDYT about the limitations checking for "correct" definitions of main, and only checking whether one exists? Do you think that's sufficient or should I make it more in depth?

_annotations = directives.isEmpty ? [] : directives.first.metadata;
_languageVersionComment = result.unit.languageVersionToken?.value();
_hasMain = result.unit.declarations.any(
(d) => d is FunctionDeclaration && d.name.toString() == 'main',
Copy link
Contributor

Choose a reason for hiding this comment

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

d.name.lexeme

@jakemac53
Copy link
Contributor

Yeah I think this is the best solution, the edge cases should be very rare and can be worked around.

Ultimately if some use case does come up it wouldn't be very difficult to actually add support for manually crawling exports as well.

@jakemac53
Copy link
Contributor

Will need changelog and such but lgtm

@natebosch natebosch marked this pull request as ready for review December 2, 2025 19:51
@natebosch natebosch requested a review from a team as a code owner December 2, 2025 19:51
@natebosch
Copy link
Member Author

Hmm, I think I'd be fine with updating tests in this repo to use an explicitly forwarding main, but there are also some internal flutter testing use cases that seem to rely on test suites without direct definitions of main (which now that I think about it is unsurprising since flutter also has atypical patterns for main under lib/).

I'll see if I can gauge how wide the impact would be.

@natebosch
Copy link
Member Author

We currently allow a _test.dart file to be independent of the precompiled output for that test. We parse the file for metadata as if it was the same content though. Precompiling and then changing the content isn't a supported workflow so I think it's OK to require that the _test.dart file stay well-formed with a main defined even after it's been precompiled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing main under _test.dart file

3 participants