Skip to content

Add two more diagnostics #624

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 2 commits into from
Aug 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Sources/SwiftParser/Declarations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,9 @@ extension Parser {
public mutating func parseParameterClause(isClosure: Bool = false) -> RawParameterClauseSyntax {
let (unexpectedBeforeLParen, lparen) = self.expect(.leftParen)
var elements = [RawFunctionParameterSyntax]()
do {
// If we are missing the left parenthesis and the next token doesn't appear to be an argument label, don't parse any parameters.
let shouldSkipParameterParsing = lparen.isMissing && (!currentToken.canBeArgumentLabel || currentToken.isKeyword)
if !shouldSkipParameterParsing {
var keepGoing = true
while !self.at(.eof) && !self.at(.rightParen) && keepGoing {
// Attributes.
Expand Down
22 changes: 22 additions & 0 deletions Sources/SwiftParser/Diagnostics/ParseDiagnosticsGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -158,5 +158,27 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
}
return .visitChildren
}

override public func visit(_ node: ParameterClauseSyntax) -> SyntaxVisitorContinueKind {
if shouldSkip(node) {
return .skipChildren
}
if node.leftParen.presence == .missing && node.parameterList.isEmpty && node.rightParen.presence == .missing {
addDiagnostic(node, .missingFunctionParameterClause)
markNodesAsHandled(node.leftParen.id, node.parameterList.id, node.rightParen.id)
}
return .visitChildren
}

public override func visit(_ node: UnresolvedTernaryExprSyntax) -> SyntaxVisitorContinueKind {
if shouldSkip(node) {
return .skipChildren
}
if node.colonMark.presence == .missing {
addDiagnostic(node.colonMark, .missingColonInTernaryExprDiagnostic)
markNodesAsHandled(node.colonMark.id)
}
return .visitChildren
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ public extension ParserFixIt {
/// Please order the cases in this enum alphabetically by case name.
public enum StaticParserError: String, DiagnosticMessage {
case cStyleForLoop = "C-style for statement has been removed in Swift 3"
case missingColonInTernaryExprDiagnostic = "Expected ':' after '? ...' in ternary expression"
case missingFunctionParameterClause = "Expected argument list in function declaration"
case throwsInReturnPosition = "'throws' may only occur before '->'"

public var message: String { self.rawValue }
Expand Down
28 changes: 28 additions & 0 deletions Tests/SwiftParserTest/DiagnosticTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,32 @@ public class DiagnosticTests: XCTestCase {
expectedFixedSource: "() throws -> Int"
)
}

public func testNoParamsForFunction() throws {
let source = """
class MyClass {
func withoutParameters

func withParameters() {}
}
"""

let classDecl = withParser(source: source) {
Syntax(raw: $0.parseDeclaration().raw).as(ClassDeclSyntax.self)!
}

XCTAssertSingleDiagnostic(in: classDecl, line: 2, column: 25, message: "Expected argument list in function declaration")
}

func testMissingColonInTernary() throws {
let source = """
foo ? 1
"""

let node = withParser(source: source) {
Syntax(raw: $0.parseExpression().raw)
}

XCTAssertSingleDiagnostic(in: node, line: 1, column: 8, message: "Expected ':' after '? ...' in ternary expression")
}
}
36 changes: 36 additions & 0 deletions Tests/SwiftParserTest/RecoveryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -349,4 +349,40 @@ public class RecoveryTests: XCTestCase {
"""
}
}

public func testNoParamsForFunction() throws {
let source = """
class MyClass {
func withoutParameters

func withParameters() {}
}
"""

let classDecl = withParser(source: source) {
Syntax(raw: $0.parseDeclaration().raw)
}
try XCTAssertHasSubstructure(
classDecl,
FunctionDeclSyntax(
attributes: nil,
modifiers: nil,
funcKeyword: .funcKeyword(),
identifier: .identifier("withoutParameters"),
genericParameterClause: nil,
signature: FunctionSignatureSyntax(
input: ParameterClauseSyntax(
leftParen: .leftParenToken(presence: .missing),
parameterList: FunctionParameterListSyntax([]),
rightParen: .rightParenToken(presence: .missing)
),
asyncOrReasyncKeyword: nil,
throwsOrRethrowsKeyword: nil,
output: nil
),
genericWhereClause: nil,
body: nil
)
)
}
}