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

Update Swift template to silence warnings about unmodified class reference #3387

Merged
merged 5 commits into from
Dec 26, 2021

Conversation

eneko
Copy link

@eneko eneko commented Dec 3, 2021

When generating language parsers in Swift, the resulting code triggers some warnings due to a variable not being modified in the generated function bodies.

Example generated code:

	@discardableResult
	 internal func typeCondition() throws -> TypeConditionContext {
		var _localctx: TypeConditionContext = TypeConditionContext(_ctx, getState())
		try enterRule(_localctx, 28, GraphQLParser.RULE_typeCondition)
		defer {
	    		try! exitRule()
	    }
		do {
		 	try enterOuterAlt(_localctx, 1)
		 	setState(237)
		 	try match(GraphQLParser.Tokens.ON.rawValue)
		 	setState(238)
		 	try namedType()

		}
		catch ANTLRException.recognition(let re) {
			_localctx.exception = re
			_errHandler.reportError(self, re)
			try _errHandler.recover(self, re)
		}

		return _localctx
	}

Compiler warning

warning: variable '_localctx' was never mutated; consider changing to 'let' constant

Solution

All possible types asignable to `_localctx` are classes that inherit from [`RuleContext`](https://github.com/antlr/antlr4/blob/7da07c73a3dc40d4ed24d90c6ac52702050295b1/runtime/Swift/Sources/Antlr4/RuleContext.swift#L58), which conforms to protocol [`Tree`](https://github.com/antlr/antlr4/blob/7da07c73a3dc40d4ed24d90c6ac52702050295b1/runtime/Swift/Sources/Antlr4/tree/Tree.swift#L11). This protocol conforms to `class`/`AnyObject` which requires any conforming types to be Swift classes (reference types). Because of this, it is safe to use `let` instead of `var` in the generated code.

Class/protocol hierarchy:
ParserRuleContext -> RuleContext -> RuleNode -> ParseTree -> SyntaxTree -> Tree -> AnyObject

This pull requests updates the Swift template to use let instead of var, in order to silence this warning.

Swift template has been updated to break this statements into two. By doing this, we prevent the Swift compiler from raising warnings when the variable is not modified in the generated function body.

The code from the above example would now look like this:

var _localctx: TypeConditionContext 
_localctx = TypeConditionContext(_ctx, getState())

@eneko eneko closed this Dec 3, 2021
@eneko
Copy link
Author

eneko commented Dec 3, 2021

Seems like the assumptions above were incorrect and there are instances where _localctx is override by a new instance, in which cases let wouldn't work.

@eneko
Copy link
Author

eneko commented Dec 3, 2021

Found another way to silence the warnings, see updated PR description.

@eneko eneko reopened this Dec 3, 2021
@parrt parrt added this to the 4.9.4 milestone Dec 26, 2021
@parrt parrt merged commit 13a0add into antlr:master Dec 26, 2021
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.

2 participants