Skip to content

Commit 39186ac

Browse files
c-gitshepmaster
andcommitted
Add detection of main under more circumstances
The cases that are intended to be added by this commit are: - Code with no comments but ends in a semicolon before the declaration of `main`. No comments was required to prevent `//` being included to comment out the line. This was done by not allowing `/` as part of the code before the `;` While this is more restrictive than necessary, it didn't seem likely that the code before `main` would include `/` so didn't seem worthwhile to take the performance hit to make the check less restrictive. To prevent long regex scans going multiple lines I also disallowed newlines in the code by including `\n` and `\r` as disallowed characters. The whole point is code on the same line as `main` so this seemed fine and would help prevent unnecessarily matching all lines before main when it doesn't matter. - Allow multiline comments within the arguments area of main that both start and end within the brackets. I'm not expecting a substantial performance cost from this one because this case is near the end of the matching. I used the following test cases ```rust fn main() { // Should work println!("Hello, world!"); } //;fn main() { //Shouldn't work println!("Hello, world!"); } use std; fn main(){ println!("Hello, world!"); } // Should work const fn main() { // Should work println!("Hello, world!"); } /* fn main() {} */ // Shouldn't work fn main(/* comment */) { // Should work // snip } ``` Co-authored-by: Jake Goulding <[email protected]>
1 parent 1b83eff commit 39186ac

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

ui/frontend/selectors/index.spec.ts

+8
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,12 @@ describe('checking for a main function', () => {
5555
test('a function with the substring main does not count', () => {
5656
expect(doMainFunctionSelector('fn mainly()')).toBe(false);
5757
});
58+
59+
test('a main function after other items on the same line', () => {
60+
expect(doMainFunctionSelector('use std; fn main(){ println!("Hello, world!"); }')).toBe(true);
61+
});
62+
63+
test('a main function with a block comment in the argument list', () => {
64+
expect(doMainFunctionSelector('fn main(/* comment */) {')).toBe(true);
65+
});
5866
});

ui/frontend/selectors/index.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,15 @@ export const selectionSelector = (state: State) => state.selection;
2020
const HAS_TESTS_RE = /^\s*#\s*\[\s*test\s*([^"]*)]/m;
2121
export const hasTestsSelector = createSelector(codeSelector, code => !!code.match(HAS_TESTS_RE));
2222

23-
const HAS_MAIN_FUNCTION_RE = /^\s*(pub\s+)?\s*(const\s+)?\s*(async\s+)?\s*fn\s+main\s*\(\s*\)/m;
23+
// https://stackoverflow.com/a/34755045/155423
24+
const HAS_MAIN_FUNCTION_RE = new RegExp(
25+
[
26+
/^([^\n\r\/]*;)?/,
27+
/\s*(pub\s+)?\s*(const\s+)?\s*(async\s+)?\s*/,
28+
/fn\s+main\s*\(\s*(\/\*.*\*\/)?\s*\)/,
29+
].map((r) => r.source).join(''),
30+
'm'
31+
);
2432
export const hasMainFunctionSelector = createSelector(codeSelector, code => !!code.match(HAS_MAIN_FUNCTION_RE));
2533

2634
const CRATE_TYPE_RE = /^\s*#!\s*\[\s*crate_type\s*=\s*"([^"]*)"\s*]/m;

0 commit comments

Comments
 (0)