Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .vscode-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const launchArgs = [
"--disable-gpu",
"--disable-gpu-sandbox",
"--disable-chromium-sandbox",
"--disable-extension=vscode.git",
"--no-xshm",
];
if (dataDir) {
Expand Down
3 changes: 2 additions & 1 deletion scripts/soundness.sh
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@ EOF
\( \! -path './assets/*' -a \
\( \! -path './coverage/*' -a \
\( \! -path './.husky/*' -a \
\( \! -path './src/typings/*' -a \
\( "${matching_files[@]}" \) \
\) \) \) \) \) \) \)
\) \) \) \) \) \) \) \) \)
} | while read -r line; do
if [[ "$(replace_acceptable_years < "$line" | head -n "$expected_lines" | shasum)" != "$expected_sha" ]]; then
printf "\033[0;31mmissing headers in file '%s'!\033[0m\n" "$line"
Expand Down
6 changes: 5 additions & 1 deletion src/BackgroundCompilation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export class BackgroundCompilation implements vscode.Disposable {
private workspaceFileWatcher?: vscode.FileSystemWatcher;
private configurationEventDisposable?: vscode.Disposable;
private disposables: vscode.Disposable[] = [];
private _disposed = false;

constructor(private folderContext: FolderContext) {
// We only want to configure the file watcher if background compilation is enabled.
Expand Down Expand Up @@ -59,7 +60,9 @@ export class BackgroundCompilation implements vscode.Disposable {
this.workspaceFileWatcher.onDidChange(
debounce(
() => {
void this.runTask();
if (!this._disposed) {
void this.runTask();
}
},
100 /* 10 times per second */,
{ trailing: true }
Expand All @@ -73,6 +76,7 @@ export class BackgroundCompilation implements vscode.Disposable {
}

dispose() {
this._disposed = true;
this.configurationEventDisposable?.dispose();
this.disposables.forEach(disposable => disposable.dispose());
}
Expand Down
1 change: 1 addition & 0 deletions src/FolderContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export class FolderContext implements vscode.Disposable {
this.packageWatcher.dispose();
this.testExplorer?.dispose();
this.backgroundCompilation.dispose();
this.taskQueue.dispose();
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/PackageWatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ export class PackageWatcher {
watcher.onDidDelete(async () => await this.handleWorkspaceStateChange());

if (await fileExists(uri.fsPath)) {
// TODO: Remove this
this.logger.info("Loading initial workspace-state.json");
await this.handleWorkspaceStateChange();
}

Expand Down Expand Up @@ -193,6 +195,10 @@ export class PackageWatcher {
*/
private async handleWorkspaceStateChange() {
await this.folderContext.reloadWorkspaceState();
// TODO: Remove this
this.logger.info(
`Package watcher state updated workspace-state.json: ${JSON.stringify(this.folderContext.swiftPackage.workspaceState, null, 2)}`
);
await this.folderContext.fireEvent(FolderOperation.workspaceStateUpdated);
}
}
3 changes: 2 additions & 1 deletion src/SwiftPackage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@ export class SwiftPackage {
readonly folder: vscode.Uri,
private contentsPromise: Promise<SwiftPackageState>,
public resolved: PackageResolved | undefined,
private workspaceState: WorkspaceState | undefined
// TODO: Make private again
public workspaceState: WorkspaceState | undefined
) {}

/**
Expand Down
6 changes: 5 additions & 1 deletion src/WorkspaceContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { SwiftTaskProvider } from "./tasks/SwiftTaskProvider";
import { TaskManager } from "./tasks/TaskManager";
import { BuildFlags } from "./toolchain/BuildFlags";
import { SwiftToolchain } from "./toolchain/toolchain";
import { ProjectPanelProvider } from "./ui/ProjectPanelProvider";
import { StatusItem } from "./ui/StatusItem";
import { SwiftBuildStatus } from "./ui/SwiftBuildStatus";
import { isExcluded, isPathInsidePath } from "./utilities/filesystem";
Expand All @@ -60,6 +61,7 @@ export class WorkspaceContext implements vscode.Disposable {
public commentCompletionProvider: CommentCompletionProviders;
public documentation: DocumentationManager;
public testRunManager: TestRunManager;
public projectPanel: ProjectPanelProvider;
private lastFocusUri: vscode.Uri | undefined;
private initialisationFinished = false;

Expand Down Expand Up @@ -102,6 +104,7 @@ export class WorkspaceContext implements vscode.Disposable {
this.documentation = new DocumentationManager(extensionContext, this);
this.currentDocument = null;
this.commentCompletionProvider = new CommentCompletionProviders();
this.projectPanel = new ProjectPanelProvider(this);

const onChangeConfig = vscode.workspace.onDidChangeConfiguration(async event => {
// Clear build path cache when build-related configurations change
Expand Down Expand Up @@ -225,6 +228,7 @@ export class WorkspaceContext implements vscode.Disposable {
this.logger,
this.statusItem,
this.buildStatus,
this.projectPanel,
];
this.lastFocusUri = vscode.window.activeTextEditor?.document.uri;

Expand Down Expand Up @@ -463,7 +467,7 @@ export class WorkspaceContext implements vscode.Disposable {
// find context with root folder
const index = this.folders.findIndex(context => context.folder.fsPath === folder.fsPath);
if (index !== -1) {
this.logger.warn(`Adding package folder ${folder} twice`);
this.logger.warn(`Adding package folder ${folder} twice: ${Error().stack}`);
return this.folders[index];
}
const folderContext = await FolderContext.create(folder, workspaceFolder, this);
Expand Down
9 changes: 9 additions & 0 deletions src/commands/dependencies/useLocal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,21 @@ export async function useLocalDependency(
currentFolder.toolchain
);

ctx.logger.debug(
`Placing dependency "${identifier}" in "editing" state with task: ${task.definition}`
);

const success = await executeTaskWithUI(
task,
`Use local version of ${identifier}`,
currentFolder,
true
);

ctx.logger.debug(
`Finished placing dependency "${identifier}" in "editing" state, success: ${success}`
);

if (success) {
await ctx.fireEvent(currentFolder, FolderOperation.resolvedUpdated);
}
Expand Down
11 changes: 11 additions & 0 deletions src/debugger/buildConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ export class TestingConfigurationFactory {
if (xcTestPath === undefined) {
return null;
}
const toolchain = this.ctx.toolchain;
return {
...baseConfig,
program: path.join(xcTestPath, "xctest"),
Expand All @@ -450,6 +451,16 @@ export class TestingConfigurationFactory {
env: {
...this.testEnv,
...this.sanitizerRuntimeEnvironment,
...(toolchain.swiftVersion.isGreaterThanOrEqual(
new Version(6, 2, 0)
)
? {
// Starting in 6.2 we need to provide libTesting.dylib for xctests
DYLD_FRAMEWORK_PATH:
toolchain.swiftTestingFrameworkPath(),
DYLD_LIBRARY_PATH: toolchain.swiftTestingLibraryPath(),
}
: {}),
SWIFT_TESTING_ENABLED: "0",
},
};
Expand Down
13 changes: 6 additions & 7 deletions src/debugger/debugAdapterFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ export class LLDBDebugConfigurationProvider implements vscode.DebugConfiguration
return undefined;
}
}
if (!(await this.promptForCodeLldbSettings(toolchain))) {
return undefined;
}

await this.promptForCodeLldbSettingsIfRequired(toolchain);

// Rename lldb-dap's "terminateCommands" to "preTerminateCommands" for CodeLLDB
if ("terminateCommands" in launchConfig) {
launchConfig["preTerminateCommands"] = launchConfig["terminateCommands"];
Expand Down Expand Up @@ -203,23 +203,23 @@ export class LLDBDebugConfigurationProvider implements vscode.DebugConfiguration
}
}

async promptForCodeLldbSettings(toolchain: SwiftToolchain): Promise<boolean> {
async promptForCodeLldbSettingsIfRequired(toolchain: SwiftToolchain) {
const libLldbPathResult = await getLLDBLibPath(toolchain);
if (!libLldbPathResult.success) {
const errorMessage = `Error: ${getErrorDescription(libLldbPathResult.failure)}`;
void vscode.window.showWarningMessage(
`Failed to setup CodeLLDB for debugging of Swift code. Debugging may produce unexpected results. ${errorMessage}`
);
this.logger.error(`Failed to setup CodeLLDB: ${errorMessage}`);
return true;
return;
}
const libLldbPath = libLldbPathResult.success;
const lldbConfig = vscode.workspace.getConfiguration("lldb");
if (
lldbConfig.get<string>("library") === libLldbPath &&
lldbConfig.get<string>("launch.expressions") === "native"
) {
return true;
return;
}
let userSelection: "Global" | "Workspace" | "Run Anyway" | undefined = undefined;
switch (configuration.debugger.setupCodeLLDB) {
Expand Down Expand Up @@ -272,7 +272,6 @@ export class LLDBDebugConfigurationProvider implements vscode.DebugConfiguration
);
break;
}
return true;
}

private convertEnvironmentVariables(map: { [key: string]: string }): string[] {
Expand Down
8 changes: 3 additions & 5 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import { SelectedXcodeWatcher } from "./toolchain/SelectedXcodeWatcher";
import { checkForSwiftlyInstallation } from "./toolchain/swiftly";
import { SwiftToolchain } from "./toolchain/toolchain";
import { LanguageStatusItems } from "./ui/LanguageStatusItems";
import { ProjectPanelProvider } from "./ui/ProjectPanelProvider";
import { getReadOnlyDocumentProvider } from "./ui/ReadOnlyDocumentProvider";
import { showToolchainError } from "./ui/ToolchainSelection";
import { checkAndWarnAboutWindowsSymlinks } from "./ui/win32";
Expand Down Expand Up @@ -144,14 +143,13 @@ export async function activate(context: vscode.ExtensionContext): Promise<Api> {
);

// project panel provider
const projectPanelProvider = new ProjectPanelProvider(workspaceContext);
const dependenciesView = vscode.window.createTreeView("projectPanel", {
treeDataProvider: projectPanelProvider,
treeDataProvider: workspaceContext.projectPanel,
showCollapseAll: true,
});
projectPanelProvider.observeFolders(dependenciesView);
workspaceContext.projectPanel.observeFolders(dependenciesView);

context.subscriptions.push(dependenciesView, projectPanelProvider);
context.subscriptions.push(dependenciesView);

// observer that will resolve package and build launch configurations
context.subscriptions.push(workspaceContext.onDidChangeFolders(handleFolderEvent(logger)));
Expand Down
28 changes: 17 additions & 11 deletions src/sourcekit-lsp/LanguageClientManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -517,11 +517,13 @@ export class LanguageClientManager implements vscode.Disposable {
this.logMessage(client, params as SourceKitLogMessageParams);
});

// start client
this.clientReadyPromise = client
.start()
.then(() => runningPromise)
.then(() => {
// Create and save the client ready promise
this.clientReadyPromise = (async () => {
try {
// start client
await client.start();
await runningPromise;

// Now that we've started up correctly, start the error handler to auto-restart
// if sourcekit-lsp crashes during normal operation.
errorHandler.enable();
Expand All @@ -546,15 +548,19 @@ export class LanguageClientManager implements vscode.Disposable {
this.subscriptions.push(this.didChangeActiveDocument);
}
} catch {
// do nothing
// do nothing, the experimental capability is not supported
}
} catch (reason) {
this.folderContext.workspaceContext.logger.error(
`Error starting SourceKit-LSP: ${reason}`
);
if (this.languageClient?.state === State.Running) {
await this.languageClient?.stop();
}
})
.catch(reason => {
this.folderContext.workspaceContext.logger.error(reason);
void this.languageClient?.stop();
this.languageClient = undefined;
throw reason;
});
}
})();

this.languageClient = client;
this.cancellationToken = new vscode.CancellationTokenSource();
Expand Down
7 changes: 6 additions & 1 deletion src/tasks/TaskQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ class QueuedOperation {
*
* Queue swift task operations to be executed serially
*/
export class TaskQueue {
export class TaskQueue implements vscode.Disposable {
queue: QueuedOperation[];
activeOperation?: QueuedOperation;
workspaceContext: WorkspaceContext;
Expand All @@ -176,6 +176,11 @@ export class TaskQueue {
this.disabled = false;
}

dispose() {
this.queue = [];
this.activeOperation = undefined;
}

/**
* Add operation to queue
* @param operation Operation to queue
Expand Down
20 changes: 16 additions & 4 deletions src/toolchain/toolchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ export class SwiftToolchain {
);
const toolchainPath = await this.getToolchainPath(swiftFolderPath, folder, logger);
const targetInfo = await this.getSwiftTargetInfo(
this._getToolchainExecutable(toolchainPath, "swift")
this._getToolchainExecutable(toolchainPath, "swift"),
logger
);
const swiftVersion = this.getSwiftVersion(targetInfo);
const [runtimePath, defaultSDK] = await Promise.all([
Expand Down Expand Up @@ -872,24 +873,35 @@ export class SwiftToolchain {
}

/** @returns swift target info */
private static async getSwiftTargetInfo(swiftExecutable: string): Promise<SwiftTargetInfo> {
private static async getSwiftTargetInfo(
swiftExecutable: string,
logger?: SwiftLogger
): Promise<SwiftTargetInfo> {
try {
try {
const { stdout } = await execSwift(["-print-target-info"], { swiftExecutable });
const targetInfo = JSON.parse(stdout.trimEnd()) as SwiftTargetInfo;
if (!targetInfo.target) {
logger?.warn(
`No target found in toolchain, targetInfo was: ${JSON.stringify(targetInfo)}`
);
}

if (targetInfo.compilerVersion) {
return targetInfo;
}
} catch {
} catch (error) {
// hit error while running `swift -print-target-info`. We are possibly running
// a version of swift 5.3 or older
logger?.warn(`Error while running 'swift -print-target-info': ${error}`);
}
const { stdout } = await execSwift(["--version"], { swiftExecutable });
return {
compilerVersion: stdout.split(lineBreakRegex, 1)[0],
paths: { runtimeLibraryPaths: [""] },
};
} catch {
} catch (error) {
logger?.warn(`Error while running 'swift --version': ${error}`);
throw Error(
"Failed to get swift version from either '-print-target-info' or '--version'."
);
Expand Down
Loading