Skip to content

Commit

Permalink
Add Filesystem API to jars
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthurm1 committed Apr 27, 2022
1 parent c1d4ed5 commit b01aa0f
Show file tree
Hide file tree
Showing 5 changed files with 321 additions and 92 deletions.
39 changes: 20 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@
{
"id": "java",
"extensions": [
".cfr"
".cfr",
".class"
]
},
{
Expand Down Expand Up @@ -563,31 +564,31 @@
"commandPalette": [
{
"command": "metals.show-tasty",
"when": "metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.tasty || metals:enabled && resourceExtname==.tasty-decoded"
"when": "metals:enabled && resourceScheme != metalsfs && resourceExtname==.scala || metals:enabled && resourceExtname==.tasty-decoded"
},
{
"command": "metals.show-cfr",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.class || metals:enabled && resourceExtname==.cfr"
"when": "metals:enabled && resourceScheme != metalsfs && resourceExtname==.java || metals:enabled && resourceScheme != metalsfs && resourceExtname==.scala || metals:enabled && resourceExtname==.cfr"
},
{
"command": "metals.show-javap",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.class || metals:enabled && resourceExtname==.javap"
"when": "metals:enabled && resourceScheme != metalsfs && resourceExtname==.java || metals:enabled && resourceScheme != metalsfs && resourceExtname==.scala || metals:enabled && resourceScheme == metalsfs && resourceExtname==.class || metals:enabled && resourceExtname==.javap"
},
{
"command": "metals.show-javap-verbose",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.class || metals:enabled && resourceExtname==.javap-verbose"
"when": "metals:enabled && resourceScheme != metalsfs && resourceExtname==.java || metals:enabled && resourceScheme != metalsfs && resourceExtname==.scala || metals:enabled && resourceScheme == metalsfs && resourceExtname==.class || metals:enabled && resourceExtname==.javap-verbose"
},
{
"command": "metals.show-semanticdb-compact",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.semanticdb || metals:enabled && resourceExtname==.semanticdb-compact"
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceScheme == metalsfs && resourceExtname==.class || metals:enabled && resourceExtname==.semanticdb-compact"
},
{
"command": "metals.show-semanticdb-detailed",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.semanticdb || metals:enabled && resourceExtname==.semanticdb-detailed"
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceScheme == metalsfs && resourceExtname==.class || metals:enabled && resourceExtname==.semanticdb-detailed"
},
{
"command": "metals.show-semanticdb-proto",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.semanticdb || metals:enabled && resourceExtname==.semanticdb-proto"
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceScheme == metalsfs && resourceExtname==.class || metals:enabled && resourceExtname==.semanticdb-proto"
},
{
"command": "metals.reveal-active-file",
Expand Down Expand Up @@ -647,11 +648,11 @@
},
{
"command": "metals.new-scala-file",
"when": "metals:enabled"
"when": "metals:enabled && resourceScheme != metalsfs"
},
{
"command": "metals.new-java-file",
"when": "metals:enabled"
"when": "metals:enabled && resourceScheme != metalsfs"
},
{
"command": "metals.new-scala-project",
Expand Down Expand Up @@ -685,12 +686,12 @@
"explorer/context": [
{
"command": "metals.new-scala-file",
"when": "metals:enabled",
"when": "metals:enabled && resourceScheme != metalsfs",
"group": "navigation@1"
},
{
"command": "metals.new-java-file",
"when": "metals:enabled",
"when": "metals:enabled && resourceScheme != metalsfs",
"group": "navigation@2"
},
{
Expand All @@ -702,37 +703,37 @@
"metals.analyze": [
{
"command": "metals.show-tasty",
"when": "metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.tasty || metals:enabled && resourceExtname==.tasty-decoded",
"when": "metals:enabled && resourceScheme != metalsfs && resourceExtname==.scala || metals:enabled && resourceExtname==.tasty || metals:enabled && resourceExtname==.tasty-decoded",
"group": "metals-1@1"
},
{
"command": "metals.show-cfr",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.class",
"when": "metals:enabled && resourceScheme != metalsfs && resourceExtname==.java || metals:enabled && resourceScheme != metalsfs && resourceExtname==.scala || metals:enabled && resourceScheme != metalsfs && resourceExtname==.class",
"group": "metals-2@1"
},
{
"command": "metals.show-javap",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.class",
"when": "metals:enabled && resourceScheme != metalsfs && resourceExtname==.java || metals:enabled && resourceScheme != metalsfs && resourceExtname==.scala || metals:enabled && resourceExtname==.class",
"group": "metals-3@1"
},
{
"command": "metals.show-javap-verbose",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.class",
"when": "metals:enabled && resourceScheme != metalsfs && resourceExtname==.java || metals:enabled && resourceScheme != metalsfs && resourceExtname==.scala || metals:enabled && resourceExtname==.class",
"group": "metals-3@2"
},
{
"command": "metals.show-semanticdb-compact",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.semanticdb",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceScheme == metalsfs && resourceExtname==.class || metals:enabled && resource ~= ///.metals//readonly/// && resourceExtname==.class || metals:enabled && resourceExtname==.semanticdb",
"group": "metals-4@1"
},
{
"command": "metals.show-semanticdb-detailed",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.semanticdb",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceScheme == metalsfs && resourceExtname==.class || metals:enabled && resource ~= ///.metals//readonly/// && resourceExtname==.class || metals:enabled && resourceExtname==.semanticdb",
"group": "metals-4@2"
},
{
"command": "metals.show-semanticdb-proto",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceExtname==.semanticdb",
"when": "metals:enabled && resourceExtname==.java || metals:enabled && resourceExtname==.scala || metals:enabled && resourceScheme == metalsfs && resourceExtname==.class || metals:enabled && resource ~= ///.metals//readonly/// && resourceExtname==.class || metals:enabled && resourceExtname==.semanticdb",
"group": "metals-4@3"
}
],
Expand Down
163 changes: 104 additions & 59 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
ProviderResult,
Hover,
TextDocument,
FileSystemProvider,
} from "vscode";
import {
LanguageClient,
Expand Down Expand Up @@ -79,7 +80,11 @@ import {
startFindInFilesProvider,
} from "./findInFiles";
import * as ext from "./hoverExtension";
import { decodeAndShowFile, MetalsFileProvider } from "./metalsContentProvider";
import {
decodeAndShowFile,
DecodeExtension,
MetalsFileProvider,
} from "./metalsContentProvider";
import {
getJavaHomeFromConfig,
getTextDocumentPositionParams,
Expand All @@ -91,6 +96,7 @@ import * as workbenchCommands from "./workbenchCommands";
import { getServerVersion } from "./getServerVersion";
import { getCoursierMirrorPath } from "./mirrors";
import { DoctorProvider } from "./doctor";
import MetalsFileSystemProvider from "./metalsFileSystemProvider";

const outputChannel = window.createOutputChannel("Metals");
const openSettingsAction = "Open settings";
Expand Down Expand Up @@ -373,8 +379,8 @@ function launchMetals(
documentSelector: [
{ scheme: "file", language: "scala" },
{ scheme: "file", language: "java" },
{ scheme: "jar", language: "scala" },
{ scheme: "jar", language: "java" },
{ scheme: "metalsfs", language: "scala" },
{ scheme: "metalsfs", language: "java" },
],
synchronize: {
configurationSection: "metals",
Expand Down Expand Up @@ -449,6 +455,18 @@ function launchMetals(
);
}

function registerFileSystemProvider(
scheme: string,
provider: FileSystemProvider
) {
context.subscriptions.push(
workspace.registerFileSystemProvider(scheme, provider, {
isCaseSensitive: true,
isReadonly: true,
})
);
}

function registerTextDocumentContentProvider(
scheme: string,
provider: TextDocumentContentProvider
Expand All @@ -461,50 +479,21 @@ function launchMetals(
const metalsFileProvider = new MetalsFileProvider(client);

registerTextDocumentContentProvider("metalsDecode", metalsFileProvider);
registerTextDocumentContentProvider("jar", metalsFileProvider);

registerCommand("metals.show-cfr", async (uri: Uri) => {
await decodeAndShowFile(client, metalsFileProvider, uri, "cfr");
});

registerCommand("metals.show-javap-verbose", async (uri: Uri) => {
await decodeAndShowFile(client, metalsFileProvider, uri, "javap-verbose");
});

registerCommand("metals.show-javap", async (uri: Uri) => {
await decodeAndShowFile(client, metalsFileProvider, uri, "javap");
});

registerCommand("metals.show-semanticdb-compact", async (uri: Uri) => {
await decodeAndShowFile(
client,
metalsFileProvider,
uri,
"semanticdb-compact"
);
});

registerCommand("metals.show-semanticdb-detailed", async (uri: Uri) => {
await decodeAndShowFile(
client,
metalsFileProvider,
uri,
"semanticdb-detailed"
);
});

registerCommand("metals.show-semanticdb-proto", async (uri: Uri) => {
await decodeAndShowFile(
client,
metalsFileProvider,
uri,
"semanticdb-proto"
);
});

registerCommand("metals.show-tasty", async (uri: Uri) => {
await decodeAndShowFile(client, metalsFileProvider, uri, "tasty-decoded");
});
const decodeCommands: [string, DecodeExtension][] = [
["cfr", "cfr"],
["javap-verbose", "javap-verbose"],
["javap", "javap"],
["semanticdb-compact", "semanticdb-compact"],
["semanticdb-detailed", "semanticdb-detailed"],
["semanticdb-proto", "semanticdb-proto"],
["tasty", "tasty-decoded"],
];
decodeCommands.forEach((command) =>
registerCommand(`metals.show-${command[0]}`, async (uri: Uri) => {
await decodeAndShowFile(client, metalsFileProvider, uri, command[1]);
})
);

registerCommand(
"metals.restartServer",
Expand Down Expand Up @@ -647,7 +636,7 @@ function launchMetals(
codeLensRefresher
);
languages.registerCodeLensProvider(
{ scheme: "jar", language: "scala" },
{ scheme: "metalsfs", language: "scala" },
codeLensRefresher
);

Expand Down Expand Up @@ -714,6 +703,67 @@ function launchMetals(
case ClientCommands.ReloadDoctor:
doctorProvider.reloadOrRefreshDoctor(params);
break;
case "metals-create-library-filesystem": {
const uri = params.arguments && params.arguments[0];
if (typeof uri === "string") {
const librariesURI = Uri.parse(uri);
// filesystem is persistent across VSCode sessions so may already exist
const libraryFolderName = "Metals - Libraries";
const newLibraryFolder = {
uri: librariesURI,
name: libraryFolderName,
};
const folderByUri = workspace.getWorkspaceFolder(librariesURI);
if (folderByUri && folderByUri.name != libraryFolderName) {
// wrong name on libraries folder
workspace.updateWorkspaceFolders(
folderByUri.index,
1,
newLibraryFolder
);
} else {
const folderByName = workspace.workspaceFolders?.find(
(folder) => folder.name == libraryFolderName
);
if (
folderByName &&
folderByName.uri.toString != librariesURI.toString
) {
if (folderByUri) {
// too many libraries folders
workspace.updateWorkspaceFolders(folderByName.index, 1);
} else {
// wrong root on libraries folder
workspace.updateWorkspaceFolders(
folderByName.index,
1,
newLibraryFolder
);
}
} else if (!folderByUri) {
// missing libraries folder
const workspaceCount = workspace.workspaceFolders?.length;
if (workspaceCount)
workspace.updateWorkspaceFolders(
workspaceCount,
0,
newLibraryFolder
);
}
}

const metalsFileSystemProvider = new MetalsFileSystemProvider(
client,
librariesURI
);
registerFileSystemProvider(
librariesURI.scheme,
metalsFileSystemProvider
);
metalsFileSystemProvider.reinitialiseURI(librariesURI);
}
break;
}
case ClientCommands.FocusDiagnostics:
commands.executeCommand(ClientCommands.FocusDiagnostics);
break;
Expand Down Expand Up @@ -873,7 +923,7 @@ function launchMetals(
registerCommand("metals.reveal-active-file", () => {
if (treeViews) {
const editor = window.visibleTextEditors.find((e) =>
isSupportedLanguage(e.document.languageId)
isSupportedDocument(e.document)
);
if (editor) {
const params = getTextDocumentPositionParams(editor);
Expand Down Expand Up @@ -950,7 +1000,6 @@ function launchMetals(
client,
findInFilesProvider,
findInFilesView,
metalsFileProvider,
outputChannel
)
);
Expand Down Expand Up @@ -996,7 +1045,7 @@ function launchMetals(
);

window.onDidChangeActiveTextEditor((editor) => {
if (editor && isSupportedLanguage(editor.document.languageId)) {
if (editor && isSupportedDocument(editor.document)) {
client.sendNotification(
MetalsDidFocus.type,
editor.document.uri.toString()
Expand Down Expand Up @@ -1252,15 +1301,11 @@ function detectLaunchConfigurationChanges() {
);
}

function isSupportedLanguage(languageId: TextDocument["languageId"]): boolean {
switch (languageId) {
case "scala":
case "sc":
case "java":
return true;
default:
return false;
}
function isSupportedDocument(textDocument: TextDocument): boolean {
return (
["metalsfs", "file"].includes(textDocument.uri.scheme) &&
["scala", "sc", "java"].includes(textDocument.languageId)
);
}

// NOTE(gabro): we would normally use the `configurationDefaults` contribution point in the
Expand Down
Loading

0 comments on commit b01aa0f

Please sign in to comment.