feat: External Libraries and some toolchain perf tweaks
This commit is contained in:
parent
cac455b460
commit
6514f65980
9 changed files with 253 additions and 9 deletions
|
@ -17,6 +17,11 @@ Changelog structure reference:
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Zig
|
||||
- External Libraries support for zig stdlib
|
||||
|
||||
## [14.1.0]
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2023-2024 FalsePattern
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.falsepattern.zigbrains.common.util;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class Lazy<T> {
|
||||
private T value;
|
||||
|
||||
private final Supplier<T> initializer;
|
||||
|
||||
public T get() {
|
||||
if (value != null)
|
||||
return value;
|
||||
|
||||
synchronized (this) {
|
||||
if (value != null)
|
||||
return value;
|
||||
return value = initializer.get();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettings;
|
|||
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettingsService;
|
||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
||||
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainProvider;
|
||||
import com.falsepattern.zigbrains.project.toolchain.tools.ZigCompilerTool;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
|
@ -114,8 +115,8 @@ public class ZigProjectSettingsPanel implements MyDisposable {
|
|||
() -> {
|
||||
val toolchain = Optional.ofNullable(pathToToolchain).map(ZigToolchainProvider::findToolchain).orElse(null);
|
||||
val zig = Optional.ofNullable(toolchain).map(AbstractZigToolchain::zig).orElse(null);
|
||||
val version = Optional.ofNullable(zig).flatMap(z -> z.queryVersion(Path.of("."))).orElse(null);
|
||||
val stdPath = Optional.ofNullable(zig).flatMap(z -> z.getStdPath(Path.of("."))).orElse(null);
|
||||
val version = Optional.ofNullable(zig).flatMap(ZigCompilerTool::queryVersion).orElse(null);
|
||||
val stdPath = Optional.ofNullable(zig).flatMap(ZigCompilerTool::getStdPath).orElse(null);
|
||||
|
||||
return new Pair<>(version, stdPath);
|
||||
},
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package com.falsepattern.zigbrains.project.toolchain;
|
||||
|
||||
import com.falsepattern.zigbrains.common.util.Lazy;
|
||||
import com.falsepattern.zigbrains.project.toolchain.flavours.AbstractZigToolchainFlavour;
|
||||
import com.falsepattern.zigbrains.project.toolchain.tools.ZigCompilerTool;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
|
@ -31,6 +32,8 @@ import java.util.Objects;
|
|||
public abstract class AbstractZigToolchain {
|
||||
private final Path location;
|
||||
|
||||
private final Lazy<ZigCompilerTool> zig = new Lazy<>(() -> new ZigCompilerTool(this));
|
||||
|
||||
public static @Nullable AbstractZigToolchain suggest() {
|
||||
return suggest(null);
|
||||
}
|
||||
|
@ -46,7 +49,7 @@ public abstract class AbstractZigToolchain {
|
|||
}
|
||||
|
||||
public ZigCompilerTool zig() {
|
||||
return new ZigCompilerTool(this);
|
||||
return zig.get();
|
||||
}
|
||||
|
||||
public abstract int executionTimeoutInMilliseconds();
|
||||
|
|
|
@ -18,17 +18,23 @@ package com.falsepattern.zigbrains.project.toolchain;
|
|||
|
||||
import com.intellij.execution.wsl.WslPath;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
public class LocalZigToolchainProvider implements ZigToolchainProvider{
|
||||
public class LocalZigToolchainProvider implements ZigToolchainProvider {
|
||||
private static final Map<Path, LocalZigToolchain> tcCache = ContainerUtil.createWeakKeyWeakValueMap();
|
||||
@Override
|
||||
public @Nullable AbstractZigToolchain getToolchain(Path homePath) {
|
||||
if (SystemInfo.isWindows && WslPath.isWslUncPath(homePath.toString())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new LocalZigToolchain(homePath);
|
||||
return tcCache.computeIfAbsent(homePath, LocalZigToolchain::new);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright 2023-2024 FalsePattern
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.falsepattern.zigbrains.project.toolchain.stdlib;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.AdditionalLibraryRootsProvider;
|
||||
import com.intellij.openapi.roots.SyntheticLibrary;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public class ZigLibraryRootProvider extends AdditionalLibraryRootsProvider {
|
||||
@Override
|
||||
public @NotNull Collection<SyntheticLibrary> getAdditionalProjectLibraries(@NotNull Project project) {
|
||||
return Collections.singleton(new ZigSyntheticLibrary(project));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright 2023-2024 FalsePattern
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.falsepattern.zigbrains.project.toolchain.stdlib;
|
||||
|
||||
import com.falsepattern.zigbrains.common.util.ApplicationUtil;
|
||||
import com.falsepattern.zigbrains.common.util.PathUtil;
|
||||
import com.falsepattern.zigbrains.project.openapi.components.ZigProjectSettingsService;
|
||||
import com.falsepattern.zigbrains.zig.Icons;
|
||||
import com.falsepattern.zigbrains.zig.parser.ZigFile;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectUtil;
|
||||
import com.intellij.openapi.roots.SyntheticLibrary;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class ZigSyntheticLibrary extends SyntheticLibrary implements ItemPresentation {
|
||||
private final Future<Collection<VirtualFile>> roots;
|
||||
private final Future<String> name;
|
||||
public ZigSyntheticLibrary(Project project) {
|
||||
val service = ZigProjectSettingsService.getInstance(project);
|
||||
val state = service.getState();
|
||||
this.roots = ApplicationManager.getApplication().executeOnPooledThread(() -> {
|
||||
var roots = pathToVFS(state.getExplicitPathToStd());
|
||||
if (roots != null) {
|
||||
return roots;
|
||||
}
|
||||
val toolchain = state.getToolchain();
|
||||
if (toolchain != null) {
|
||||
val stdPath =
|
||||
toolchain.zig().getStdPath().orElse(null);
|
||||
return pathToVFS(stdPath);
|
||||
}
|
||||
return Collections.emptySet();
|
||||
});
|
||||
|
||||
this.name = ApplicationManager.getApplication()
|
||||
.executeOnPooledThread(() -> Optional.ofNullable(state.getToolchain())
|
||||
.flatMap(tc -> tc.zig().queryVersion())
|
||||
.map(version -> "Zig " + version)
|
||||
.orElse("Zig"));
|
||||
}
|
||||
|
||||
private static @Nullable Collection<VirtualFile> pathToVFS(String path) {
|
||||
if (path != null && !path.isEmpty()) {
|
||||
val thePath = PathUtil.pathFromString(path);
|
||||
if (thePath != null) {
|
||||
val file = VfsUtil.findFile(thePath, true);
|
||||
if (file != null) {
|
||||
val children = file.getChildren();
|
||||
if (children != null && children.length > 0)
|
||||
return Arrays.asList(children);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public @NotNull Collection<VirtualFile> getSourceRoots() {
|
||||
try {
|
||||
return roots.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<VirtualFile> getBinaryRoots() {
|
||||
return super.getBinaryRoots();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof ZigSyntheticLibrary other && Objects.equals(roots.get(), other.roots.get());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(roots.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NlsSafe @Nullable String getPresentableText() {
|
||||
try {
|
||||
return name.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
return "Zig";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Icon getIcon(boolean unused) {
|
||||
return Icons.ZIG;
|
||||
}
|
||||
}
|
|
@ -16,20 +16,45 @@
|
|||
|
||||
package com.falsepattern.zigbrains.project.toolchain.tools;
|
||||
|
||||
import com.falsepattern.zigbrains.common.util.Lazy;
|
||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
||||
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainEnvironmentSerializable;
|
||||
import com.google.gson.Gson;
|
||||
import com.intellij.execution.process.ProcessOutput;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
public class ZigCompilerTool extends AbstractZigTool{
|
||||
public static final String TOOL_NAME = "zig";
|
||||
private final Lazy<Optional<String>> version;
|
||||
private final Lazy<Optional<String>> stdPath;
|
||||
|
||||
public ZigCompilerTool(AbstractZigToolchain toolchain) {
|
||||
super(toolchain, TOOL_NAME);
|
||||
val app = ApplicationManager.getApplication();
|
||||
val baseFuture = app.executeOnPooledThread(() -> getEnv(null));
|
||||
version = new Lazy<>(() -> {
|
||||
try {
|
||||
return baseFuture.get().map(ZigToolchainEnvironmentSerializable::version);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
});
|
||||
stdPath = new Lazy<>(() -> {
|
||||
try {
|
||||
return baseFuture.get().map(ZigToolchainEnvironmentSerializable::stdDirectory);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<ZigToolchainEnvironmentSerializable> getEnv(@Nullable Path workingDirectory) {
|
||||
|
@ -39,11 +64,11 @@ public class ZigCompilerTool extends AbstractZigTool{
|
|||
|
||||
}
|
||||
|
||||
public Optional<String> getStdPath(@Nullable Path workingDirectory) {
|
||||
return getEnv(workingDirectory).map(ZigToolchainEnvironmentSerializable::stdDirectory);
|
||||
public Optional<String> getStdPath() {
|
||||
return stdPath.get();
|
||||
}
|
||||
|
||||
public Optional<String> queryVersion(@Nullable Path workingDirectory) {
|
||||
return getEnv(workingDirectory).map(ZigToolchainEnvironmentSerializable::version);
|
||||
public Optional<String> queryVersion() {
|
||||
return version.get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
|
||||
<consoleFilterProvider implementation="com.falsepattern.zigbrains.project.console.ZigConsoleFilterProvider"/>
|
||||
<analyzeStacktraceFilter implementation="com.falsepattern.zigbrains.project.console.ZigSourceFileFilter"/>
|
||||
|
||||
<additionalLibraryRootsProvider implementation="com.falsepattern.zigbrains.project.toolchain.stdlib.ZigLibraryRootProvider"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.falsepattern.zigbrains">
|
||||
|
|
Loading…
Add table
Reference in a new issue