Skip to content

chore: Use latest LS with the URL encoding fixes #1811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 16, 2023
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
2 changes: 1 addition & 1 deletion arduino-ide-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
"version": "14.0.0"
},
"languageServer": {
"version": "0.7.2"
"version": "0.7.4"
}
}
}
68 changes: 0 additions & 68 deletions arduino-ide-extension/src/browser/arduino-workspace-resolver.ts

This file was deleted.

11 changes: 11 additions & 0 deletions arduino-ide-extension/src/node/arduino-ide-backend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ import { MessagingContribution } from './theia/core/messaging-contribution';
import { MessagingService } from '@theia/core/lib/node/messaging/messaging-service';
import { HostedPluginReader } from './theia/plugin-ext/plugin-reader';
import { HostedPluginReader as TheiaHostedPluginReader } from '@theia/plugin-ext/lib/hosted/node/plugin-reader';
import { PluginDeployer } from '@theia/plugin-ext/lib/common/plugin-protocol';
import {
LocalDirectoryPluginDeployerResolverWithFallback,
PluginDeployer_GH_12064,
} from './theia/plugin-ext/plugin-deployer';

export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(BackendApplication).toSelf().inSingletonScope();
Expand Down Expand Up @@ -392,6 +397,12 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
// https://github.com/arduino/arduino-ide/pull/1706#pullrequestreview-1195595080
bind(HostedPluginReader).toSelf().inSingletonScope();
rebind(TheiaHostedPluginReader).toService(HostedPluginReader);

// https://github.com/eclipse-theia/theia/issues/12064
bind(LocalDirectoryPluginDeployerResolverWithFallback)
.toSelf()
.inSingletonScope();
rebind(PluginDeployer).to(PluginDeployer_GH_12064).inSingletonScope();
});

function bindChildLogger(bind: interfaces.Bind, name: string): void {
Expand Down
100 changes: 100 additions & 0 deletions arduino-ide-extension/src/node/theia/plugin-ext/plugin-deployer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { URI } from '@theia/core/lib/common/uri';
import {
inject,
injectable,
postConstruct,
} from '@theia/core/shared/inversify';
import {
PluginDeployerResolver,
PluginDeployerResolverContext,
} from '@theia/plugin-ext/lib/common/plugin-protocol';
import { PluginDeployerImpl } from '@theia/plugin-ext/lib/main/node/plugin-deployer-impl';
import { LocalDirectoryPluginDeployerResolver } from '@theia/plugin-ext/lib/main/node/resolvers/local-directory-plugin-deployer-resolver';
import { constants, promises as fs } from 'fs';
import { isAbsolute, resolve } from 'path';

@injectable()
export class LocalDirectoryPluginDeployerResolverWithFallback extends LocalDirectoryPluginDeployerResolver {
override async resolve(
pluginResolverContext: PluginDeployerResolverContext
): Promise<void> {
const origin = pluginResolverContext.getOriginId();
// The original implementation must not run when there is a hash in the path. Otherwise, it can resolve an undesired directory.
// Consider app under c:\Users\username\Desktop\# here is my app\
// Then the flawed logic will incorrectly find c:\Users\username\Desktop location after stripping the rest of the path after the hash.
// The implementation which provides a workaround for the hash in the path assumes that the original Theia logic is correct, when no hash present in the URI path.
let localPath: string | null;
if (origin.includes('#')) {
localPath = await resolveLocalPluginPathFallback(
pluginResolverContext,
this.supportedScheme
);
} else {
localPath = await this.originalResolveLocalPluginPath(
pluginResolverContext,
this.supportedScheme
);
}
if (localPath) {
await this.resolveFromLocalPath(pluginResolverContext, localPath);
}
}

private async originalResolveLocalPluginPath(
context: PluginDeployerResolverContext,
scheme: string
): Promise<string | null> {
const object = <Record<string, unknown>>this;
if (
'resolveLocalPluginPath' in object &&
typeof object['resolveLocalPluginPath'] === 'function'
) {
return object['resolveLocalPluginPath'](context, scheme);
}
return null;
}
}

async function resolveLocalPluginPathFallback(
context: PluginDeployerResolverContext,
scheme: string
): Promise<string | null> {
const uri = new URI(context.getOriginId());
if (uri.scheme === scheme) {
const unencodedRawUri = uri.toString(true);
let fsPath = unencodedRawUri.substring(`${scheme}:`.length);
if (!isAbsolute(fsPath)) {
fsPath = resolve(process.cwd(), fsPath);
}
try {
await fs.access(fsPath, constants.R_OK);
return fsPath;
} catch {
console.warn(
`The local plugin referenced by ${context.getOriginId()} does not exist.`
);
}
}
return null;
}

@injectable()
export class PluginDeployer_GH_12064 extends PluginDeployerImpl {
@inject(LocalDirectoryPluginDeployerResolverWithFallback)
private readonly pluginResolver: LocalDirectoryPluginDeployerResolverWithFallback;

@postConstruct()
protected adjustPluginResolvers(): void {
const pluginResolvers = <PluginDeployerResolver[]>(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(this as any).pluginResolvers
);
const index = pluginResolvers.findIndex(
(pluginResolver) =>
pluginResolver instanceof LocalDirectoryPluginDeployerResolver
);
if (index >= 0) {
pluginResolvers.splice(index, 1, this.pluginResolver);
}
}
}