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

Limit parameters count #447

Closed
wants to merge 5 commits into from
Closed

Limit parameters count #447

wants to merge 5 commits into from

Conversation

delebedev
Copy link
Contributor

Very early version of #415.
Implementation depends on answer here: jpsim/SourceKitten#151.

return false
}

return key == "source.lang.swift.decl.var.parameter"
Copy link
Collaborator

Choose a reason for hiding this comment

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

You could avoid the hardcoded string literal by doing return SwiftDeclarationKind(rawValue: key) == . VarParameter instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nice, had no idea there were constants for that :)

@jpsim
Copy link
Collaborator

jpsim commented Jan 29, 2016

I'm excited to see you getting started on this! Let me know if you have any questions moving forward.

@delebedev
Copy link
Contributor Author

@jpsim assuming my code example here jpsim/SourceKitten#151 do you think there are "good" ™️ way to extract function parameters from AST?

I'm inclining to simply get function declaration string and parse it manually. Moreover I have to do it anyway because of default parameters (they are not represented in SourceKit AFAIK)

@jpsim
Copy link
Collaborator

jpsim commented Jan 29, 2016

@jpsim assuming my code example here jpsim/SourceKitten#151 (comment) do you think there are "good" way to extract function parameters from AST?

Yeah, it's spot on. You're using an ASTRule and only continuing the validation process when substructures have .VarParameters. 👍

@delebedev
Copy link
Contributor Author

@jpsim but apparently it triggers false positive for this simple snippet:

private func foo(dictionary: [Int: Int]) -> Int {
    dictionary.flatMap { foo in return foo }
    return 1
}

produces 1 level-nested structure which will count foo parameters and return 2 not 1:

  "key.substructure" : [
    {
      "key.kind" : "source.lang.swift.decl.function.free",
      "key.offset" : 22,
      "key.nameoffset" : 27,
      "key.namelength" : 27,
      "key.bodyoffset" : 63,
      "key.bodylength" : 73,
      "key.accessibility" : "source.lang.swift.accessibility.private",
      "key.substructure" : [
        {
          "key.kind" : "source.lang.swift.decl.var.parameter",
          "key.offset" : 31,
          "key.nameoffset" : 0,
          "key.namelength" : 0,
          "key.length" : 10,
          "key.typename" : "[Int: Int]",
          "key.name" : "dictionary"
        },
        {
          "key.kind" : "source.lang.swift.decl.var.parameter",
          "key.offset" : 103,
          "key.nameoffset" : 0,
          "key.namelength" : 0,
          "key.length" : 3,
          "key.typename" : "foo",
          "key.name" : "foo"
        }
      ],
      "key.name" : "foo(_:)",
      "key.length" : 115
    }
  ],
  "key.offset" : 0,
  "key.diagnostic_stage" : "source.diagnostic.stage.swift.parse",
  "key.length" : 138
}

@jpsim
Copy link
Collaborator

jpsim commented Jan 29, 2016

In your example, foo is a parameter. It's a parameter to the closure. If you want to filter just parameters to functions, you can filter .VarParameters that have a key.offset between its enclosing function's key.offset and key.bodyoffset.

In your example, you'd only end up with dictionary as parameters for functions because its key.offset is 17, which falls between its parent function's key.offset of 8 and key.bodyoffset of 49. Whereas foo isn't considered because its key.offset is 71, which is outside the 8..<49 range.

@delebedev
Copy link
Contributor Author

@jpsim thanks for this 👍 I had a feeling I'm missing something

range: Range<Int>) -> Int {

var count = 0
for e in structure {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

usage of for loop is intentional (not very functional 😃) : it allows to return early in case method reached end of current function declaration

@delebedev delebedev changed the title [WIP] Limit parameters count Limit parameters count Jan 31, 2016
@delebedev
Copy link
Contributor Author

@jpsim ready to be reviewed!

let offset = Int(dictionary["key.offset"] as? Int64 ?? 0)
return [StyleViolation(ruleDescription: self.dynamicType.description,
severity: parameter.severity,
location: Location(file: file, characterOffset: offset),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you please use Location(file: file, byteOffset: offset) instead of Location(file: file, characterOffset: offset)?
Because dictionary["key.offset"] is byte offset.

return [StyleViolation(ruleDescription: self.dynamicType.description,
severity: parameter.severity,
location: Location(file: file, byteOffset: offset),
reason: "{Parameters list should have \(config.warning) or less parameters: " +
Copy link
Collaborator

Choose a reason for hiding this comment

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

Typo: {Parameters

@jpsim
Copy link
Collaborator

jpsim commented Jan 31, 2016

The implementation here looks great! I'd like us to really nail down the rule name though.

"Parameters List Length" and "Parameter List Length" seem to be used interchangeably. We're not really measuring the string length here, but rather the number of parameters.

I think "Function Parameter Count" might be a more appropriate name.

Otherwise like I said, the implementation looks spot on (as far as I can tell reveling this from my phone 😉).

@delebedev
Copy link
Contributor Author

@jpsim agreed with naming, changed

@jpsim jpsim mentioned this pull request Jan 31, 2016
@jpsim
Copy link
Collaborator

jpsim commented Jan 31, 2016

Thanks @garnett! I just had a few minor changes to add, so I'll merge in #459.

Really nice work on this! Not too many people have ventured into writing ASTRule based rules so far, so if you learned anything that you think might be useful to add in the contributing.md documentation for others looking to write rules, please let me know!

@jpsim jpsim closed this Jan 31, 2016
@norio-nomura
Copy link
Collaborator

👏

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.

3 participants