Skip to content

Commit

Permalink
[Swift APIView] Migrate from SwiftAST to SwiftSyntax (#4789)
Browse files Browse the repository at this point in the history
* Progress converting SwiftAST to SwiftSyntax.

* Progress.

* Remove old files. Improve syntax.

* Update logic.

* Progress.

* Progress.

* Precedence groups and operator progress.

* Progress on enabling additional syntax.

* Fix protocol member filtering.

* Progress on enums.

* Fix missing member declarations in classes and structs.

* Fix function display.

* Fixes for enums cases.

* Various fixes.

* Eliminate SharedLogger.fail statements in favor of SharedLogger.warn

* Add extension support.

* Tweaks and removing defaulted cases.

* Extension fixes

* Group extensions with the same definitionIds together.

* Fix navigation for outside extensions.

* Duplicate definition fix.

* Fix issue with navigation.

* Code review feeback.
  • Loading branch information
tjprescott authored Jan 13, 2023
1 parent d401782 commit b4ae814
Show file tree
Hide file tree
Showing 64 changed files with 1,294 additions and 3,628 deletions.
4 changes: 4 additions & 0 deletions src/swift/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Release History

## Version 0.2.0 (Unreleased)
- Switch from SwiftAST dependency to SwiftSyntax.
- Overhaul to how extensions are displayed.

## Version 0.1.4 (Unreleased)
- Allow attributes inside function signatures.

Expand Down
4 changes: 2 additions & 2 deletions src/swift/SwiftAPIView/SwiftAPIView.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 0.1.4;
MARKETING_VERSION = 0.2.0;
PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.SwiftAPIView;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand All @@ -311,7 +311,7 @@
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 0.1.4;
MARKETING_VERSION = 0.2.0;
PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.SwiftAPIView;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@
argument = "--source=/Users/travisprescott/repos/azure-sdk-for-ios/sdk/communication/AzureCommunicationChat/Source"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "--source=/Users/travisprescott/Documents/AzureCommunicationCalling.xcframework"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "--source=/Users/travisprescott/repos/communication-ui-library-ios/AzureCommunicationUI"
isEnabled = "NO">
Expand All @@ -64,12 +68,12 @@
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "--package-name=SwiftAPIViewTests"
argument = "--package-name=AzureCommunicationCallingTEST"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "--source=/Users/travisprescott/repos/azure-sdk-tools/src/swift/SwiftAPIViewTests/Sources"
isEnabled = "YES">
isEnabled = "NO">
</CommandLineArgument>
</CommandLineArguments>
<LocationScenarioReference
Expand Down
40 changes: 24 additions & 16 deletions src/swift/SwiftAPIViewCore/Sources/APIViewManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@
//
// --------------------------------------------------------------------------

import AST
import Foundation
import OrderedCollections
import Parser
import Source
import SwiftSyntax
import SwiftSyntaxParser
import SourceKittenFramework


Expand Down Expand Up @@ -59,18 +58,21 @@ public class APIViewConfiguration {
}

/// Handles the generation of APIView JSON files.
public class APIViewManager {
public class APIViewManager: SyntaxVisitor {

// MARK: Properties

var config = APIViewConfiguration()

var mode: APIViewManagerMode

var statements = OrderedDictionary<Int, CodeBlockItemSyntax.Item>()

// MARK: Initializer

public init(mode: APIViewManagerMode = .commandLine) {
self.mode = mode
super.init(viewMode: .all)
}

// MARK: Methods
Expand Down Expand Up @@ -116,9 +118,9 @@ public class APIViewManager {
}

/// Handles automatic processing of swiftinterface file, if supplied
func process(filePath: String) throws -> SourceFile {
func process(filePath: String) throws -> String {
if filePath.hasSuffix("swift") || filePath.hasSuffix("swifttxt") || filePath.hasSuffix("swiftinterface") {
return try SourceReader.read(at: filePath)
return try String(contentsOfFile: filePath)
}
if filePath.hasSuffix("h") {
let args = [String]()
Expand All @@ -136,7 +138,7 @@ public class APIViewManager {
let tempUrl = sourceDir.appendingPathComponent(tempFilename)
try sourceCode.write(to: tempUrl, atomically: true, encoding: .utf8)
defer { try! FileManager.default.removeItem(at: tempUrl) }
return try SourceReader.read(at: tempUrl.path)
return try String(contentsOfFile: tempUrl.path)
}
}
throw ToolError.client("Unsupported file type: \(filePath)")
Expand Down Expand Up @@ -197,7 +199,6 @@ public class APIViewManager {
SharedLogger.fail("\(sourceUrl.path) does not exist.")
}

var statements = OrderedDictionary<Int, Statement>()
var filePaths = [String]()
if isDir.boolValue {
packageName = config.packageName ?? extractPackageName(from: sourceUrl)
Expand All @@ -210,15 +211,11 @@ public class APIViewManager {
}
for filePath in filePaths {
do {
let sourceFile = try process(filePath: filePath)
let topLevelDecl = try Parser(source: sourceFile).parse()

// hash top-level statement text to eliminate duplicates
topLevelDecl.statements.forEach { statement in
statements[statement.description.hash] = statement
}
let source = try process(filePath: filePath)
let rootNode = try SyntaxParser.parse(source: source);
self.walk(rootNode)
} catch let error {
SharedLogger.warn(error.localizedDescription)
SharedLogger.warn("\(error)")
}
}
// Ensure that package name and version can be resolved
Expand All @@ -239,4 +236,15 @@ public class APIViewManager {
let apiView = APIViewModel(name: apiViewName, packageName: packageName!, versionString: packageVersion!, statements: Array(statements.values))
return apiView
}

// MARK: SyntaxVisitor

public override func visit(_ node: SourceFileSyntax) -> SyntaxVisitorContinueKind {
for statement in node.statements {
let tokens = Array(statement.item.tokens(viewMode: .all))
statements[tokens.hashValue] = statement.item
}
return .skipChildren
}
}

This file was deleted.

This file was deleted.

Loading

0 comments on commit b4ae814

Please sign in to comment.