Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Linting in Swift

Linting in Swift

Linters define and enforce syntactical conventions across codebases. They enable teams of developers to convey shared values to one another, making new contributions easier and more fun to review and existing code easier to build off of. This talk will explore how Swift compiles, how Swift linting works, and the importance and difficulty of sharing programming patterns and techniques across engineering teams.

Tamar Nachmany

May 31, 2016
Tweet

More Decks by Tamar Nachmany

Other Decks in Technology

Transcript

  1. let library = [ Movie(name: "Casablanca", director: "Michael Curtiz"), Song(name:

    "Blue Suede Shoes", artist: “Elvis") ] for item in library {
 if let book = item as! Book { // This will crash at runtime.
 } } Rule: Don’t Allow Force Downcasting (as!)
  2. 1. Why build automated tools for code review?
 2. Where

    do Xcode errors come from?
 3. How does SwiftLint supplement the Swift compiler?
 Let’s explore these questions:
  3. Making sure engineers feel like they are always learning is

    important for retaining talented people.
  4. What information do we need to display this? 1. Error

    location 2. Error cause 3. Fix-it suggestion 4. Severity (error or warning-level issue)
  5. When you enter new code into your project, Xcode sends

    messages to SourceKit.
 SourceKit responds with some info.
  6. SourceKit Response key.diagnostics: [ { key.line: 5, key.column: 9, key.filepath:

    "/Users/SourceKit-Logging.playground", key.severity: source.diagnostic.severity.error, key.description: "'println' has been renamed to 'print'", key.diagnostic_stage: source.diagnostic.stage.swift.sema, key.fixits: [ { key.offset: 0, key.length: 7, key.sourcetext: "print" } ]
  7. What does SwiftLint need to do for this to work?

    • Establish rules • Parse files and assess them based on new rules • Print results in Xcode, the command line, etc
  8. func validateFile(file: File, kind: KindType, dictionary: [String: SourceKitRepresentable]) -> [StyleViolation]

    { // Analyze file as a dictionary of SourceKitRepresentable strings } ASTRule
  9. public func validateFile(file: File) -> [StyleViolation] { return violationRangesInFile(file).map {

    StyleViolation(ruleDescription: self.dynamicType.description, severity: configuration.severity, location: Location(file: file, characterOffset: $0.location)) } } Comma Rule Analyzes the file using regular expressions
  10. public func validateFile(file: File, kind: SwiftDeclarationKind, dictionary: [String: SourceKitRepresentable]) ->

    [StyleViolation] { return file.validateVariableName(dictionary, kind: kind).map { name, offset in if configuration.excluded.contains(name) { return [] } … } Variable Name Length Rule 
 Needs to know the Swift declaration kind
  11. To get set up: • Install SwiftLint locally • Create

    a config file called (.swiftlint.yml) where rules are defined. • A script that runs SwiftLint • A script that runs your script, perhaps in a build phase for your target(s)