Skip to content

Suggest to add missing equal token to variable declarations #1770

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

Merged
merged 1 commit into from
Jun 15, 2023

Conversation

whiteio
Copy link
Contributor

@whiteio whiteio commented Jun 12, 2023

When a variable declaration is followed by an expression on the same line, it should be suggested to insert an equal token.

Resolves #1610

@whiteio whiteio requested a review from ahoppen as a code owner June 12, 2023 22:14
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

Thanks @whiteio. I’ve got one question regarding the implementation. Also: Could you add a test case from the example in the issue?

@@ -1405,6 +1407,14 @@ extension Parser {
value: initExpr,
arena: self.arena
)
} else if self.atStartOfExpression() && !isProbablyVarDecl && !self.at(.leftBrace) && !self.currentToken.flags.contains(.isAtStartOfLine) {
Copy link
Member

Choose a reason for hiding this comment

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

Can’t you just inline isProbablyVarDecl here? If you can, you could merge the !self.at(.leftBrace) check into it?

Also, instead of checking self.currentToken.flags.contains(.isAtStartOfLine) it’s nicer to check

self.at(TokenSpec(.identifier, allowAtStartOfLine: false), TokenSpec(.wildcard, allowAtStartOfLine: false))`

Also: What do we need the isProbablyVarDecl check for?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ahoppen Yes I've added in the test case from the example in the issue. isProbablyVarDecl can be inlined, I've inlined it and merged in !self.at(.leftBrace).

self.at(TokenSpec(.identifier, allowAtStartOfLine: false), TokenSpec(.wildcard, allowAtStartOfLine: false))`

Would this also need to include keywords? For example, if I change it to the above it would suggest inserting an '=' if the variable declaration is followed by an initializer on a new line, such as:

struct S {
  let _value: Int
                 ╰─ error: expected '=' in variable
  init() {
  }
}

Also: What do we need the isProbablyVarDecl check for?

I added this in to make sure that the correct fixits are suggested when there are consecutive variable declarations on the same line.

For example, without the isProbablyVarDecl check it would suggest adding an '=' instead of a ';' before 'i' in the following case

let x: Int i = 10

Copy link
Member

@ahoppen ahoppen Jun 14, 2023

Choose a reason for hiding this comment

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

self.at(TokenSpec(.identifier, allowAtStartOfLine: false), TokenSpec(.wildcard, allowAtStartOfLine: false))

I am sorry, I missed that you had a negation in front of self.at. Forget what I said.

I added this in to make sure that the correct fixits are suggested when there are consecutive variable declarations on the same line.

Hmm. But this also means that you don’t generate the diagnostic to add the missing = if you write the following, right?

let x: Int i

I’m not sure if it’s really beneficial to optimize for the case where someone incorrectly writes two variable declarations on the same line. Declaring two variables on the same line isn’t very common in Swift in my experience.

So: My take on this would be to just remove

!self.at(.identifier, .wildcard, .leftBrace), !self.peek().rawTokenKind.is(.colon, .equal, .comma)

entirely. The only thing you might need to keep is !self.at(.leftBrace) so that we parse the upcoming init accessor syntax correctly

struct Foo {
  let x = 1 {
    init {
      
    }
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So: My take on this would be to just remove
!self.at(.identifier, .wildcard, .leftBrace), !self.peek().rawTokenKind.is(.colon, .equal, .comma)

Yes, you're right. I've made your suggested change to remove this, I've added !self.at(.leftBrace) as it's needed for scenarios such as the one you've mentioned. 👍

@whiteio whiteio force-pushed the whiteio/insert-missing-equal branch 2 times, most recently from 8873db7 to 25a81b9 Compare June 14, 2023 17:08
@@ -102,8 +102,7 @@ final class ConsecutiveStatementsTests: XCTestCase {
// Errors
i = j
j = i
let r : Int
i = j
let r : Int i = j
Copy link
Member

Choose a reason for hiding this comment

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

Am I missing something or do you know why we aren’t interesting a = after Int as the Fix-It says?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks like "insert '='" wasn't included in the applyFixits parameter. I've added it in now.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, that makes sense.

@whiteio whiteio force-pushed the whiteio/insert-missing-equal branch from 25a81b9 to f63a3e1 Compare June 14, 2023 17:29
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

Just one more comment, then we’re ready to 🚢

applyFixIts: ["insert '>'", "insert newline", "insert expression"],
applyFixIts: ["insert '>'", "insert expression"],
Copy link
Member

Choose a reason for hiding this comment

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

The idea is that the a test inserts newline and the b test below adds the ;. So, I think you should be able to remove testRecovery7b.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, that's it removed now.

When a variable declaration is followed by an expression on the same line,
it should be suggested to insert an `equal` token
@whiteio whiteio force-pushed the whiteio/insert-missing-equal branch from f63a3e1 to f504798 Compare June 14, 2023 21:04
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

Thank you @whiteio.

@ahoppen
Copy link
Member

ahoppen commented Jun 15, 2023

@swift-ci Please test

@ahoppen ahoppen enabled auto-merge June 15, 2023 04:03
@ahoppen ahoppen merged commit 06a19a4 into swiftlang:main Jun 15, 2023
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.

Bad diagnostic for let foo: [Int] []
2 participants