Bâtissons RDCore
This document is available in English
Note
⏳ Les contributions externes sont présentement fermées.
👉 Surveillez l'annonce prochaine d'une CLA et l'ouverture officielle de ce projet open-core.
🚀 Démarrage
- Lisez et signez d'abord l'accord de licence contributeur (CLA) approprié (ça facilitera la suite);
- Prenez connaissance de la feuille de route du projet et sélectionnez un ticket;
- Démarrez un fork du référentiel RDCore sur votre compte GitHub;
- Téléchargez un clone du référentiel sur un poste libre de droits (donc pas sur un poste fourni par votre employeur);
- Ouvrez
RDCore.slnxdans Microsoft Visual Studio Community Edition 2026 (gratuit pour contributions open-source);
- 👉 Alternativement, utilisez les outils CLI
dotnet buildpour compiler la solution.
- Démarrez une nouvelle branche à partir de main, nommée en référence au ticket sélectionné;
- Effectuez et testez vos contributions dans votre branche locale;
- Lorsque tout fonctionne et est prêt pour revue, ouvrez une pull request en y référant le ticket sélectionné;
- 👉 Mentionnez
Closes #suivi du numéro du ticket dans le corps de la pull request. - 👉 Une telle mention dans un commit de votre historique apparaîtra sur l'historique de ce ticket dès que vos commits sont poussés dans votre fork, ce qui signale un travail en cours aux autres contributeurs.
- Une fois votre pull request complétée, détruisez la branche et resynchronisez main pour démarrer un nouveau développement.
- 👉 Le squash merge détruira le détail de l'historique de vos commits dans le référentiel central, ce qui complique rapidement les choses si des commits additionnels s'ajoutent à une branche déjà complétée; un correctif peut être soumis en démarrant une nouvelle branche à partir de main resynchronisé avec le merge commit.
🧩 Créer une extension RDCore
Il suffit de quelques lignes dans votre point d'entrée pour que votre application RDCore soit prise en charge :
public class Program
{
public static async Task<int> Main(string[] args)
{
using var host = new RDCoreConsoleClientHost();
return await host.RunAsync(args);
}
}
Hôte
Avant de pouvoir écrire ces lignes, il faudra définir votre hôte en héritant de RDCoreLanguageClientHost si vous construisez un client :
internal class RDCoreConsoleClientHost() : RDCoreLanguageClientHost<RDCoreConsoleClientApp>()
{
protected override void ConfigureAdditionalExternalServices(IServiceCollection services, IConfiguration configuration)
{
services
.AddSingleton<IAppThemeService, AppThemeService>()
.AddSingleton<IAppThemeLoaderService, AppThemeLoaderService>()
.AddSingleton<IConsoleMessageWriter, DefaultConsoleMessageWriter>()
.AddSingleton<ILoggerProvider, RDCoreConsoleLoggerProvider>()
.AddSingleton<ShowSplashCommand>();
}
}
...ou alors en héritant de RDCoreLanguageServerHost si vous construisez plutôt un serveur :
internal class CoreDiagnosticsAppHost() : RDCoreLanguageServerHost<CoreDiagnosticsApp>()
{
protected override void ConfigureAdditionalExternalServices(IServiceCollection services, IConfiguration configuration)
{
}
}
Application
Dans les deux cas, le rôle de l'hôte est de fournir les services au IServiceCollection de sorte que l'application puisse être instanciée en lui injectant tous les services dont elle a besoin.
Ensuite pour un client on hérite l'application LSP de RDCoreClientApp :
internal class RDCoreConsoleClientApp(
IRDCoreLanguageServerProcess serverProcess,
IHealthCheckService<RDCoreConsoleClientApp> healthCheckService,
ILanguageServerProtocolTransportLayer transportLayer,
ILogger<RDCoreConsoleClientApp> logger)
: RDCoreClientApp(serverProcess, healthCheckService, transportLayer, logger)
{
protected override void ConfigureServices(IServiceCollection services)
{
}
protected override ClientCapabilities ConfigureClientCapabilities(ClientCapabilities capabilities)
{
// TODO
return capabilities;
}
protected override void ConfigureHandlers(IRDCoreLSPHandlerConfigurationBuilder builder)
{
// TODO
}
protected override async Task OnLanguageClientStartedAsync(ILanguageClient client, CancellationToken token)
{
// TODO
}
protected override void Dispose(bool disposing) { }
}
...et pour un serveur on hérite l'application LSP de RDCoreServerApp :
internal class CoreDiagnosticsApp : RDCoreServerApp
{
public CoreDiagnosticsApp(
IServerStateProvider serverStateProvider,
IHealthCheckService<CoreDiagnosticsApp> healthCheckService,
ILanguageServerProtocolTransportLayer transportLayer,
ILogger<CoreDiagnosticsApp> logger)
: base(serverStateProvider, healthCheckService, transportLayer, logger)
{
}
protected override void ConfigureHandlers(IRDCoreLSPHandlerConfigurationBuilder builder)
{
// TODO
}
protected override void RegisterServerCapabilities(ILanguageServer server, ClientCapabilities clientCapabilities)
{
// TODO
}
protected override void Dispose(bool disposing)
{
// TODO
}
}
Dans tous les cas, le rôle de ce niveau d'abstraction est de configurer les capacités (LSP) de l'application et les handlers pour la prise en charge de requêtes et notifications LSP.
Client ou Serveur?
- Une application client est généralement une application de type IDE.
- Une application serveur peut être un serveur de langage satellite ou une extension (plug-in) de la plateforme.
- 🌐LSP 3.17 Specifications
Important
🧩 Les extensions de la plateforme RDCore requièrent un manifest pour permettre leur découverte par l'hôte d'environnement; le schéma de ce manifest est défini par ExtensionInfo; l'hôte d'environnement peut founir des outils de développement (CLI) pour faciliter la création d'un manifest pour une extension en cours de développement.
Capacités
Les extensions de la plateforme RDCore avec un manifest valide qui leur permet d'initier un LSP handshake avec la couche d'orchestration LSP doit fournir des paramètres d'initialisation qui spécifient un jeu complet de capacités définies tant par le protocole (LSP) que définies par l'hôte de l'environnement.
👉 La liste complète et exhaustive des capacités de la plateforme sera documentée à la section RD-VBAL §2.0.2 à mesure que progresse son implémentation.
Note
Les extensions tant de première que de tierces parties distribuées à travers l'infranuagique RDCore PEUVENT utiliser un capability provider qui PEUT valider la disponibilité de certains capacités avancées en requérant une authentification 2FA, la validation d'une inscription active (gratuite ou payante), et la validation d'un build signé avec le build officiel du canal de distribution certifié.
🧩 Extension de la plateforme (SDK et coeur de langage)
Le coeur de langage est conçu pour être étendu à travers des extensions de la plateforme de type serveur, moyennant un échange de capacités donnant accès à des points d'extensions.
Voir RD-VBAL § 1.1 pour les détails et la philosophie d'extension de la plateforme à ce niveau.
ACCUEIL • HOME | ℹ️ BIENVENUE • WELCOME | 🧩 BÂTISSONS • BUILD | RD-VBAL | SDK | 🌐 rubberduckvba.ca