Skip to content
This repository has been archived by the owner on Jun 22, 2024. It is now read-only.

Commit

Permalink
Fixed an issue preventing autocompletion to work reliably on Linux, f…
Browse files Browse the repository at this point in the history
…ixes #54
  • Loading branch information
vknabel committed Sep 8, 2019
1 parent 4cedc92 commit 9adcb8d
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 34 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 2.8.1

- Fixed an issue preventing autocompletion to work reliably on Linux, fixes [#54](https://github.com/vknabel/vscode-swift-development-environment/issues/54)
- Installation instructions now correctly link `/usr/lib/libsourcekitdInProc.so`, noticed by [@kennethz3](https://github.com/kennethz3)
- Support quoted arguments in settings, fixed by [@haifengkao](https://github.com/haifengkao)

## 2.8.0

- Now LSP-mode `sourcekite` supports `sourcekit-lsp.toolchainPath` after updating to [[email protected]](https://github.com/vknabel/sourcekite/releases/tag/0.6.0)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ sourcekit-lsp is easier to install and will be updated more frequently. On the o
# Ensure you have libcurl4-openssl-dev installed (not pre-installed)
# $ apt-get update && apt-get install libcurl4-openssl-dev
# Ensure LD_LIBRARY_PATH contains /your/swift/usr/lib
# And have $ sudo ln -s /your/swift/usr/lib/libsourcekitdInProc.so /usr/lib/sourcekitdInProc
# And have $ sudo ln -s /your/swift/usr/lib/libsourcekitdInProc.so /usr/lib/libsourcekitdInProc.so
$ make install PREFIX=/usr/local

# For macOS
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"url": "https://github.com/vknabel"
},
"license": "Apache-2.0",
"version": "2.8.0",
"version": "2.8.1",
"publisher": "vknabel",
"icon": "icons/icon.png",
"galleryBanner": {
Expand Down
10 changes: 8 additions & 2 deletions src/clientMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ function currentServerOptions(context: ExtensionContext) {
path.join("out/src/server", "server.js")
);
// The debug options for the server
const debugOptions = { execArgv: ["--nolazy", "--inspect=6004"] };
const debugOptions = {
execArgv: ["--nolazy", "--inspect=6004"],
...process.env
};

// If the extension is launched in debug mode then the debug server options are used
// Otherwise the run options are used
Expand All @@ -76,7 +79,10 @@ function currentServerOptions(context: ExtensionContext) {
.getConfiguration("swift")
.get("languageServerPath", "/usr/local/bin/LanguageServer");

const run: Executable = { command: executableCommand };
const run: Executable = {
command: executableCommand,
options: process.env
};
const debug: Executable = run;
const serverOptions: ServerOptions = {
run: run,
Expand Down
28 changes: 2 additions & 26 deletions src/server/packages/available-packages.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as path from "path";
import { descriptionPackage } from "./description-package";
import { Package, Target } from "../package";
import { Package } from "../package";
import { swiftFilePackage } from "./swift-file-package";
import { debugYamlPackage } from "./debug-yaml-package";
import { configPackage } from "./config-package";
import { flatteningTargetsWithUniqueSources } from "./package-helpers";

export const availablePackages: Package = async fromPath => {
const [
Expand All @@ -24,27 +24,3 @@ export const availablePackages: Package = async fromPath => {
swiftFileTargets
);
};

function flatteningTargetsWithUniqueSources(...targets: Target[][]) {
return targets.reduce(
(current, next) => [...current, ...removingDuplicateSources(next, current)],
[]
);
}

function removingDuplicateSources(
fromTargets: Target[],
uniqueTargets: Target[]
): Target[] {
return fromTargets.map(target => {
const swiftFilesWithoutTargets = Array.from(target.sources).filter(
source =>
uniqueTargets.findIndex(desc =>
desc.sources.has(
path.relative(desc.path, path.resolve(target.path, source))
)
) === -1
);
return { ...target, sources: new Set(swiftFilesWithoutTargets) };
});
}
136 changes: 136 additions & 0 deletions src/server/packages/package-helpers.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import {
removingDuplicateSources,
flatteningTargetsWithUniqueSources
} from "./package-helpers";
import { Target } from "../package";

const uniqueTarget: Target = {
name: "Unique",
path: "Sources/Unique",
sources: new Set(["Hello.swift", "main.swift"]),
compilerArguments: []
};

const unrelatedTarget: Target = {
name: "UnrelatedTarget",
path: "Sources/UnrelatedTarget",
sources: new Set(["Unrelated.swift"]),
compilerArguments: []
};

describe("package helpers", () => {
describe("removingDuplicateSources", () => {
it("does not emit unique targets", () => {
const emittedTargets = removingDuplicateSources([], [uniqueTarget]);
expect(emittedTargets).toHaveLength(0);
});

it("unrelated source sets will be kept", () => {
const emittedTargets = removingDuplicateSources(
[unrelatedTarget],
[uniqueTarget]
);
expect(emittedTargets).toEqual([unrelatedTarget]);
});

it("unrelated source sets with differing paths will be kept for same file names", () => {
const unrelatedTargetWithSameFileNames: Target = {
...unrelatedTarget,
sources: uniqueTarget.sources
};

const emittedTargets = removingDuplicateSources(
[unrelatedTargetWithSameFileNames],
[uniqueTarget]
);
expect(emittedTargets).toEqual([unrelatedTargetWithSameFileNames]);
});

it("source sets with same paths but different file names are kept", () => {
const samePathTargetWithDifferentSources = {
...unrelatedTarget,
path: uniqueTarget.path
};
const emittedTargets = removingDuplicateSources(
[samePathTargetWithDifferentSources],
[uniqueTarget]
);
expect(emittedTargets).toEqual([samePathTargetWithDifferentSources]);
});

it("source sets with different paths but same files will be deuplicated", () => {
const differentPathTargetWithSameSources = {
...unrelatedTarget,
path: "./",
sources: new Set(
Array(uniqueTarget.sources.values()).map(
sourceFile => `${uniqueTarget.path}/${sourceFile}`
)
)
};
const emittedTargets = removingDuplicateSources(
[differentPathTargetWithSameSources],
[uniqueTarget]
);
expect(emittedTargets).toEqual([differentPathTargetWithSameSources]);
});
});

describe("flatteningTargetsWithUniqueSources", () => {
it("bug: configs did not override global paths", () => {
// see https://github.com/vknabel/vscode-swift-development-environment/issues/55
const emittedTargets = flatteningTargetsWithUniqueSources(
[
{
name: "HiModuleFromConfigs",
path: "/Users/vknabel/Desktop/AutocompleteIos/Sources/Hi",
sources: new Set(["Hi.swift"]),
compilerArguments: []
}
],
[
{
name: "HiModuleFromDebugYaml",
path: "/Users/vknabel/Desktop/AutocompleteIos",
sources: new Set([
"/Users/vknabel/Desktop/AutocompleteIos/Sources/Hi/Hi.swift"
]),
compilerArguments: []
}
],
[
{
name: "AutocompleteIos",
path: "/Users/vknabel/Desktop/AutocompleteIos",
sources: new Set([
"/Users/vknabel/Desktop/AutocompleteIos/Package.swift"
]),
compilerArguments: []
}
]
);
expect(emittedTargets).toEqual([
{
name: "HiModuleFromConfigs",
path: "/Users/vknabel/Desktop/AutocompleteIos/Sources/Hi",
sources: new Set(["Hi.swift"]),
compilerArguments: []
},
{
name: "HiModuleFromDebugYaml",
path: "/Users/vknabel/Desktop/AutocompleteIos",
sources: new Set([]),
compilerArguments: []
},
{
name: "AutocompleteIos",
path: "/Users/vknabel/Desktop/AutocompleteIos",
sources: new Set([
"/Users/vknabel/Desktop/AutocompleteIos/Package.swift"
]),
compilerArguments: []
}
]);
});
});
});
39 changes: 39 additions & 0 deletions src/server/packages/package-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Target } from "../package";
import * as path from "path";

export function flatteningTargetsWithUniqueSources(
...targets: Target[][]
): Target[] {
return targets.reduce(
(current, next) => [
...current,
...removingDuplicateSources(next, current.map(normalizedTarget))
],
[]
);
}

export function removingDuplicateSources(
fromTargets: Target[],
uniqueTargets: Target[]
): Target[] {
return fromTargets.map(target => {
const swiftFilesWithoutTargets = Array.from(target.sources).filter(
source =>
uniqueTargets.findIndex(desc =>
desc.sources.has(path.resolve(target.path, source))
) === -1
);
return { ...target, sources: new Set(swiftFilesWithoutTargets) };
});
}

function normalizedTarget(target: Target): Target {
return {
...target,
sources: mapSet(target.sources, source => path.resolve(target.path, source))
};
}
function mapSet<T, R>(set: Set<T>, transform: (element: T) => R): Set<R> {
return new Set(Array.from(set.values()).map(element => transform(element)));
}
9 changes: 5 additions & 4 deletions src/server/sourcekites.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ function restartSourcekite() {
}

function createSkProtocolProcess() {
const env = { TOOLCHAIN_DIR: Current.config.toolchainPath };
const env = {
...process.env,
TOOLCHAIN_DIR: Current.config.toolchainPath || process.env["TOOLCHAIN_DIR"]
};
if (server.skProtocolProcessAsShellCmd) {
const volumes = Current.config.workspacePaths.map(
path => `-v '${path}:${path}'`
Expand All @@ -44,9 +47,7 @@ function createSkProtocolProcess() {
function initializeSKProtocolProcess() {
Current.log(
"sourcekite",
`***sourcekite initializing with skProtocolProcess at [${
server.skProtocolPath
}]`
`***sourcekite initializing with skProtocolProcess at [${server.skProtocolPath}]`
);

const pathSourcekite = Current.config.sourcekitePath;
Expand Down

0 comments on commit 9adcb8d

Please sign in to comment.