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

Add Swift programming language #2734

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c706436
initial edits for Swift language support
atacan Jan 18, 2025
c3a0c3c
additional scope features
atacan Jan 18, 2025
37c03d1
replace `collectionKey` with `key.mapPair`
atacan Jan 18, 2025
e01350e
remove the Swift-specific type scopes since they're not in the standa…
atacan Jan 18, 2025
1110787
ensure proper alignment between the scope support map and the tree-si…
atacan Jan 18, 2025
3a54328
wip
atacan Jan 18, 2025
e9323fe
swift MDX
atacan Jan 18, 2025
3f4506c
deleted
atacan Jan 18, 2025
1655be7
start from scratch
atacan Jan 18, 2025
e6b91c8
Add Swift grammar rules and declarations to swift.scm
atacan Jan 18, 2025
231064a
start small
atacan Jan 18, 2025
8a0ddd2
make the function work
atacan Jan 18, 2025
f2d8d64
swift.scm by adding class and protocol declarations.
atacan Jan 18, 2025
31d4d2a
full support not-support list
atacan Jan 18, 2025
dbda618
Enhance swift.scm by adding support for import, property, typealias, …
atacan Jan 18, 2025
a568661
Add support for ternary expressions and enhance comment handling in s…
atacan Jan 18, 2025
df4ac3d
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Jan 18, 2025
53ec6d1
Add support for switch statements and enhance if/guard statement hand…
atacan Jan 18, 2025
1cc4244
wrong folder?
atacan Jan 19, 2025
93437b6
swift playground
atacan Jan 19, 2025
5a7de2e
Add support for protocol declarations and enhance argument handling i…
atacan Jan 19, 2025
4e7087c
Merge branch 'main' into add-swift
AndreasArvidsson Feb 22, 2025
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
175 changes: 175 additions & 0 deletions data/playground/swift.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
// Source: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/guidedtour/

print("Hello, world!")
// Prints "Hello, world!"

var myVariable = 42
myVariable = 50
let myConstant = 42

let apples = 3
let oranges = 5

let quotation = """
Even though there's whitespace to the left,
the actual lines aren't indented.
Except for this line.
Double quotes (") can appear without being escaped.

I still have \(apples + oranges) pieces of fruit.
"""

var fruits = ["strawberries", "limes", "tangerines"]
fruits[1] = "grapes"

var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"

let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
if score > 50 {
teamScore += 3
}
else {
teamScore += 1
}
}

let vegetable = "red pepper"
switch vegetable {
case "celery":
print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":
print("That would make a good tea sandwich.")
case let x where x.hasSuffix("pepper"):
print("Is it a spicy \(x)?")
default:
print("Everything tastes good in soup.")
}
// Prints "Is it a spicy red pepper?"

@discardableResult
func greet(person: String, day: String) -> String {
"Hello \(person), today is \(day)."
}
greet(person: "Bob", day: "Tuesday")

func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
var min = scores[0]
var max = scores[0]
var sum = 0

for score in scores {
if score > max {
max = score
}
else if score < min {
min = score
}
sum += score
}

return (min, max, sum)
}
let statistics = calculateStatistics(scores: [5, 3, 100, 3, 9])
print(statistics.sum)

class NamedShape {
var numberOfSides: Int = 0
var name: String

init(name: String) {
self.name = name
}

func simpleDescription() -> String {
"A shape with \(numberOfSides) sides."
}
}

class Square: NamedShape {
var sideLength: Double

init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 4
}

func area() -> Double {
sideLength * sideLength
}

override func simpleDescription() -> String {
"A square with sides of length \(sideLength)."
}
}

let test = Square(sideLength: 5.2, name: "my test square")
_ = test.area()
_ = test.simpleDescription()

enum Rank: Int {
case ace = 1
case two, three, four, five, six, seven, eight, nine, ten
case jack, queen, king

func simpleDescription() -> String {
switch self {
case .ace:
return "ace"
case .jack:
return "jack"
case .queen:
return "queen"
case .king:
return "king"
default:
return String(self.rawValue)
}
}
}
let ace = Rank.ace

func fetchUserID(from server: String) async -> Int {
if server == "primary" {
return 97
}
return 501
}

Task {
await fetchUserID(from: "primary")
}

protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
}

var fridgeIsOpen = false
let fridgeContent = ["milk", "eggs", "leftovers"]

func fridgeContains(_ food: String) -> Bool {
fridgeIsOpen = true
defer {
fridgeIsOpen = false
}

let result = fridgeContent.contains(food)
return result
}

if fridgeContains("banana") {
print("Found a banana")
}
print(fridgeIsOpen)
// Prints "false"

let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ import { scalaScopeSupport } from "./scala";
import { scmScopeSupport } from "./scm";
import type { LanguageScopeSupportFacetMap } from "./scopeSupportFacets.types";
import { scssScopeSupport } from "./scss";
import { swiftScopeSupport } from "./swift";
import { talonScopeSupport } from "./talon";
import { typescriptScopeSupport } from "./typescript";
import { typescriptreactScopeSupport } from "./typescriptreact";
@@ -56,6 +57,7 @@ export const languageScopeSupport: StringRecord<LanguageScopeSupportFacetMap> =
scala: scalaScopeSupport,
scm: scmScopeSupport,
scss: scssScopeSupport,
swift: swiftScopeSupport,
talon: talonScopeSupport,
typescript: typescriptScopeSupport,
typescriptreact: typescriptreactScopeSupport,
188 changes: 188 additions & 0 deletions packages/common/src/scopeSupportFacets/swift.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import type { LanguageScopeSupportFacetMap } from "./scopeSupportFacets.types";
import { ScopeSupportFacetLevel } from "./scopeSupportFacets.types";

const { supported, unsupported, notApplicable } = ScopeSupportFacetLevel;

export const swiftScopeSupport: LanguageScopeSupportFacetMap = {
// Command related
command: notApplicable,

// XML/HTML related
element: notApplicable,
startTag: notApplicable,
endTag: notApplicable,
tags: notApplicable,
attribute: supported, // Swift has attributes like @available, @objc
environment: notApplicable,

// Document structure
section: notApplicable,

// Data structures and control flow
list: supported,
map: supported,
ifStatement: supported,
regularExpression: supported,
switchStatementSubject: supported,
fieldAccess: supported,

// Statements and classes
statement: supported,
"statement.class": supported,
"statement.iteration.document": supported,
"statement.iteration.block": supported,

class: supported,
"class.iteration.document": supported,
"class.iteration.block": supported,
className: supported,
"className.iteration.document": supported,
"className.iteration.block": supported,

// Functions
namedFunction: supported,
"namedFunction.method": supported,
"namedFunction.method.iteration.class": supported,
"namedFunction.constructor": supported, // Swift has initializers
"namedFunction.iteration": supported,
"namedFunction.iteration.document": supported,
anonymousFunction: supported, // Swift has closures
functionName: supported,
"functionName.method": supported,
"functionName.method.iteration.class": supported,
"functionName.constructor": supported,
"functionName.iteration": supported,
"functionName.iteration.document": supported,

// Function calls
functionCall: supported,
"functionCall.constructor": supported,
functionCallee: supported,
"functionCallee.constructor": supported,

// Arguments
"argument.actual": supported,
"argument.actual.iteration": supported,
"argument.actual.method": supported,
"argument.actual.method.iteration": supported,
"argument.actual.constructor": supported,
"argument.actual.constructor.iteration": supported,
"argument.formal": supported,
"argument.formal.iteration": supported,
"argument.formal.method": supported,
"argument.formal.method.iteration": supported,
"argument.formal.constructor": supported,
"argument.formal.constructor.iteration": supported,

// Comments
"comment.line": supported,
"comment.block": supported,

// Strings
"string.singleLine": supported,
"string.multiLine": supported,

// Text fragments
"textFragment.comment.line": supported,
"textFragment.comment.block": supported,
"textFragment.string.singleLine": supported,
"textFragment.string.multiLine": supported,

// Delimiters
disqualifyDelimiter: supported,
pairDelimiter: supported,

// Branches
"branch.if": supported,
"branch.loop": supported,
"branch.if.iteration": supported,
"branch.try": supported,
"branch.try.iteration": supported,
"branch.switchCase": supported,
"branch.switchCase.iteration": supported,
"branch.ternary": supported,

// Collection items
"collectionItem.unenclosed": supported,
"collectionItem.unenclosed.iteration": supported,

// Conditions
"condition.if": supported,
"condition.while": supported,
"condition.doWhile": unsupported, // Swift doesn't have do-while loops
"condition.for": supported,
"condition.ternary": supported,
"condition.switchCase": supported,
"condition.switchCase.iteration": supported,

// Names
"name.assignment": supported,
"name.assignment.pattern": supported,
"name.variable": supported,
"name.variable.pattern": supported,
"name.foreach": supported,
"name.function": supported,
"name.method": supported,
"name.constructor": supported,
"name.class": supported,
"name.field": supported,
"name.resource": unsupported, // Swift doesn't have explicit resource management blocks
"name.resource.iteration": unsupported,
"name.argument.formal": supported,
"name.argument.formal.iteration": supported,
"name.argument.formal.method": supported,
"name.argument.formal.method.iteration": supported,
"name.argument.formal.constructor": supported,
"name.argument.formal.constructor.iteration": supported,
"name.iteration.block": supported,
"name.iteration.document": supported,

// Keys
"key.attribute": supported,
"key.mapPair": supported,
"key.mapPair.iteration": supported,

// Values
"value.assignment": supported,
"value.variable": supported,
"value.variable.pattern": supported,
"value.mapPair": supported,
"value.mapPair.iteration": supported,
"value.foreach": supported,
"value.attribute": supported,
"value.return": supported,
"value.return.lambda": supported,
"value.field": supported,
"value.yield": unsupported, // Swift doesn't have yield statements
"value.resource": unsupported,
"value.resource.iteration": unsupported,
"value.argument.formal": supported,
"value.argument.formal.iteration": supported,
"value.argument.formal.method": supported,
"value.argument.formal.method.iteration": supported,
"value.argument.formal.constructor": supported,
"value.argument.formal.constructor.iteration": supported,
"value.typeAlias": supported,

// Types
"type.variable": supported,
"type.argument.formal": supported,
"type.argument.formal.iteration": supported,
"type.argument.formal.method": supported,
"type.argument.formal.method.iteration": supported,
"type.argument.formal.constructor": supported,
"type.argument.formal.constructor.iteration": supported,
"type.return": supported,
"type.field": supported,
"type.field.iteration": supported,
"type.foreach": supported,
"type.interface": supported, // Swift has protocols which are similar to interfaces
"type.class": supported,
"type.alias": supported,
"type.cast": supported,
"type.typeArgument": supported,
"type.typeArgument.iteration": supported,

// Notebook
notebookCell: notApplicable,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Language from "./Language";

# Swift

<Language languageId="swift"></Language>
Loading