Le modèle de développement classique pour toute application implique une bonne documentation sur l'interface utilisateur et l'API, ainsi que, si nécessaire, une bonne couverture du code source avec des commentaires. Dans ce cas, la finalisation du système commence par une étude de la documentation, puis le code est directement modifié et, enfin, toutes les informations nécessaires sont mises à jour.
Cependant, l'un des problèmes de cette approche est qu'elle augmente considérablement le coût et ralentit le processus de développement. Et si tout cela ne l'est pas? Ensuite, l'EDI vient à la rescousse, grâce à laquelle vous pouvez étudier la logique actuelle en utilisant du code nu.
Lorsque nous avons développé la
plate- forme
lsFusion avec un langage intégré, nous avions plusieurs options. Soit réinventer la roue, et écrire à partir de zéro votre propre IDE, comme 1C l'a fait à un moment donné, ou implémenter un plug-in pour un existant. Nous sommes allés dans la deuxième voie, et dans cet article, je vais montrer ce qui s'est passé.
Puisque la plate-forme elle-même a été développée en Java, nous avions deux options principales: Eclipse ou IDEA. Nous avons opté pour la dernière option et n'avons pas échoué. Lorsque nous avons pris la décision, IDEA n'était toujours pas assez populaire, mais depuis lors, ils ont émergé en tant que leaders sur le marché, et Eclipse est tranquillement derrière.
Il n'a pas fallu beaucoup de temps pour développer le
plugin lui-même, car il était possible d'utiliser le code utilisé directement lors de l'exécution de la plate-forme de nombreuses manières. Ainsi, avec un effort minimal, nous avons obtenu un IDE très puissant, à bien des égards, nettement supérieur en fonctionnalités à l'IDE de nombreuses autres plates-formes ERP (natives et basées sur Eclipse).
Le rôle de l'IDE dans le développement est difficile à surestimer. Malgré le fait que de nombreux développeurs utilisent encore vim et pensent que cela devrait l'être. Cette position a droit à la vie si une personne développe et soutient davantage ce code. Cependant, dans les grands projets où un grand nombre de personnes sont impliquées, leur interchangeabilité est très importante. Les employés tombent malades, partent en vacances et finissent par partir. En outre, la charge sur les différents projets est inégale et il est parfois nécessaire de connecter plus de personnes à l'un d'entre eux afin de respecter les délais. À de tels moments, vous devez connecter de nouvelles personnes aux améliorations, qui doivent rapidement comprendre comment le programme fonctionne actuellement et apporter les modifications nécessaires. Et voici l'IDE.
Tout d'abord, nous avions besoin des éléments suivants de l'IDE:
- Prise en charge de la syntaxe . Mise en évidence des mots clés, substitution automatique, mise en évidence des erreurs.
- La navigation Accédez à l'annonce, recherchez les utilisations, recherchez par chaîne de texte, fichier ou nom, etc.
- Analyse . La hiérarchie des classes et des appels, ainsi que les propriétés et actions de la classe.
- Refactoring Renommer des classes, des propriétés et des actions.
- Visualisation des formulaires . Pour afficher au développeur la conception actuelle d'une certaine forme.
- Métaprogrammation . La possibilité de générer du code basé sur des métacodes à la volée .
- Débogueur La possibilité de définir des points d'arrêt (y compris les conditions), déboguer la logique impérative, regarder les montres.
- Injection de langue . Navigation, refactorisation, substitution automatique et mise en évidence de la syntaxe lsFusion lorsqu'ils sont utilisés dans d'autres langages - Java et JasperReports XML.
Comme nous avons utilisé le schéma standard intégré à IDEA pour le plug-in, le résultat de l'utilisation de la logique dans lsFusion s'est avéré presque identique au développement en Java. Les mêmes éléments de menu, touches de raccourci, débogage transparent, qui peuvent passer du code lsFusion à Java et vice versa, etc.
Voici quelques exemples simples pour montrer comment cela fonctionne dans la pratique.
Prise en charge de la syntaxe
Le plugin peut remplacer des mots clés valides, des propriétés possibles, détecter automatiquement diverses erreurs:

La navigation
Prenez la logique de
l' exemple de
gestion des matériaux . Supposons que nous devons voir où la propriété Price est déclarée. Pour ce faire, vous devez placer le pointeur de la souris sur l'en-tête de la colonne dont nous avons besoin en tant qu'utilisateur avec des droits d'administrateur:

Dans la fenêtre qui apparaît, vous pouvez immédiatement voir dans quel module cette propriété est créée (expédition), quel numéro de ligne s'y trouve (37), la table dans laquelle elle est stockée (_auto_Shipment_ShipmentDetail) et un certain nombre d'autres informations.
Pour accéder directement à la déclaration de propriété, vous devez lancer la recherche de fichiers et saisir Shipment dans la boîte de dialogue qui s'affiche:


Ensuite, en utilisant Navigate - Line / Column, accédez à la 37e ligne, où nous voyons la déclaration de propriété:

En appuyant sur CTRL + ALT + F7, alors que le curseur se trouve sur la propriété souhaitée, vous pouvez trouver rapidement toutes ses utilisations pour tous les projets:

Dans ce cas, la première utilisation du prix consiste à calculer le montant par ligne. Les deux derniers ajoutent aux formulaires appropriés.
Si nécessaire, vous pouvez activer la recherche uniquement par enregistrement dans cette propriété, si vous supprimez l'option correspondante:

Seule l'entrée de cette propriété restera alors dans la liste. Pour savoir quelle valeur spécifique y est écrite, vous devez déplacer le curseur sur salePrice et cliquer sur Aller à la déclaration ou aux utilisations. Ensuite, revenez dans Navigation - Retour et allez à la déclaration de la propriété de l'élément:

Pour résumer, nous avons trouvé où cette propriété dont nous avions besoin a été déclarée, dans quels cas elle est utilisée et quand l'enregistrement y va. Sur la vidéo, j'ai fait toutes les actions avec la souris, bien que dans la pratique, seul le clavier soit utilisé. Cette technique vous permet de déterminer rapidement la logique système actuellement implémentée et d'y apporter des modifications, en ayant une compréhension complète de ce à quoi cela conduira.
Refactoring
Il existe souvent des situations où vous devez modifier le nom d'une propriété, d'une classe, d'un formulaire ou de tout autre élément du système. Pour effectuer une telle action, vous devez vous tenir sur cet élément et cliquer sur Refactor - Rename:

Renommer un élément change automatiquement le code source dans tous les endroits où il est utilisé. De plus, si le fichier migration.script est créé, les entrées correspondantes y seront ajoutées. Le serveur doit connaître les changements de nom afin, par exemple, de migrer automatiquement les données d'une colonne à une autre. Sinon, il est impossible de distinguer le changement de nom de la création d'une nouvelle propriété avec un nom différent.
Analyse
Avant d'effectuer une refactorisation, il est souvent nécessaire de savoir «ce qui se passe» et «qui sont toutes ces personnes».
Pour ce faire, IDEA, presque prêt à l'emploi, vous permet de visualiser la structure de la classe sélectionnée (propriétés et actions disponibles pour cette classe):

De plus, si vous avez besoin d'avoir une idée générale de ce qui se passe, IDEA vous permet de construire différentes hiérarchies:
- héritage de la classe sélectionnée
- Utilisations de l'élément sélectionné (par exemple, propriétés ou formulaires)

Toutes les principales fonctionnalités sont fournies par IDEA automatiquement (avec un minimum de gestes) après la mise en œuvre des annonces des moteurs de recherche. L'ensemble de fonctionnalités suivant a rendu le plugin bricoleur avec un peu plus, mais une partie importante de l'infrastructure a été fournie par IDEA (non sans problèmes, bien sûr, mais plus à ce sujet plus tard).
Visualisation de formulaire
Dans lsFusion, la structure et la conception des formulaires sont définies dans le même code que la logique du domaine à l'aide de constructions spéciales. De plus, différentes parties du formulaire peuvent être déclarées dans différents modules, et lorsque le serveur démarre, elles «fusionnent» ensemble, selon les modules connectés.
Pour voir la conception résultante, vous pouvez bien sûr redémarrer le serveur et regarder le résultat dans le client. Mais le redémarrage du serveur prend un certain temps. Un plugin peut:
- Afficher la conception actuelle et la structure hiérarchique du formulaire dans une fenêtre spéciale
- Rechercher des éléments dans la structure de forme
- Mettre en surbrillance l'élément de forme sélectionné dans la conception
Voici à quoi cela ressemble dans l'IDE:

Lors de la création d'un formulaire, seul le module actif en cours et tout ce dont il dépend sont pris en compte.
Il n'est pas encore possible de modifier visuellement la conception actuelle, car le formulaire est formé de plusieurs blocs de code. Pendant la modification, il est difficile de déterminer clairement à quel endroit vous devez apporter les modifications appropriées. De plus, le même élément peut être modifié dans plusieurs blocs de code, et la plate-forme garantit que si un module dépend d'un autre, ses modifications seront appliquées en dernier. Cependant, à l'avenir, nous prévoyons d'ajouter certaines fonctionnalités pour les changements de conception visuelle.
Métaprogrammation
Parfois, il est nécessaire de créer le même type de code pour diverses tâches. LsFusion possède un mécanisme de métacode qui vous permet de générer du code basé sur un modèle. Dans ce cas, en cas de modification du métacode, le code sera automatiquement mis à jour. En fait, il s'agit d'un copier / coller automatique avec la possibilité de remplacer certains identifiants par des valeurs spécifiées.
Pour activer ce mécanisme, vous devez d'abord l'activer dans le menu. Après cela, l'EDI changera automatiquement le code correspondant.

Au démarrage du serveur, seul le code généré sera utilisé. Les modèles META eux-mêmes ne seront pas pris en compte lors du démarrage du serveur.
Soit dit en passant, la mise en œuvre de la possibilité de métaprogrammation nous a obligés à apporter une autre contribution à l'open source (dans ce cas, Intellij IDEA). Le fait est que dans les ERP, les métacodes sont utilisés très activement et, en conséquence, il est souvent nécessaire de générer du code / supprimer le code généré. Cela conduit à un grand nombre de modifications de fichiers asynchrones, ce qui, à son tour, a conduit à un
bogue très particulier. Le problème est qu'ils ne pouvaient pas être lus dans JetBrains lui-même, donc tout se résumait au fait que nous devions nous-mêmes écrire un
test unitaire non fonctionnel. Bien sûr, cela a pris plusieurs jours, mais nous a indirectement aidé à mettre en œuvre les deux possibilités suivantes.
Débogueur
Lorsque le code n'est pas clair sur ce qui se passe, vous devez vous tourner vers le débogueur. Sur n'importe quelle ligne de logique impérative (actions, événements, restrictions), vous pouvez mettre un point d'arrêt. Dès que l'exécution du serveur atteint ce point, elle sera arrêtée et le contrôle ira au débogueur. En ce moment, vous pouvez regarder des montres et continuer à exécuter ligne par ligne. Sur la gauche, une trace de pile sera affichée, le long de laquelle vous pourrez naviguer comme si vous déboguez une application Java standard.

Lorsque vous affichez les valeurs actuelles, vous pouvez accéder à la fois aux objets actuels (par exemple, les envois) et à tout autre objet de la base de données (par exemple, l'article i). Cependant, le développeur lui-même est responsable de l'ajout de données aux montres, dont la lecture prendra beaucoup de temps ou de mémoire et entraînera une baisse des performances.
Vous pouvez également définir des points d'arrêt sur une propriété spécifique. L'exécution s'arrêtera n'importe où lorsqu'un enregistrement lui sera fait:

Ceci est utile lorsque vous devez déterminer quel événement ou action modifie la valeur d'une propriété.
Pour réellement implémenter le débogueur, nous avons en fait utilisé le débogueur Java IDEA existant. Autrement dit, la plate-forme est en cours de débogage en tant qu'application Java ordinaire, mais pour les actions lsFusion, nous créons des méthodes java proxy et remplaçons leur affichage par notre code (si je comprends bien dans IDEA, cela est fait pour prendre en charge Scala et d'autres wrappers sur Java). Et ce fut un moment amusant. À un moment donné, les développeurs d'IDEA ont
rendu privé
le constructeur de leur débogueur Java. Et si la situation avec l'appel de méthodes privées peut toujours être contournée via Reflection, alors comment hériter d'une classe avec un constructeur privé n'est pas clair. Mais juste à ce moment-là, il y a eu une épreuve de force avec un bogue de la section supérieure, et nous avons «décidé de demander aux gens de JetBrains de protéger ce constructeur», ce à quoi ils ont réagi très rapidement (pour lequel, bien sûr, merci beaucoup à eux).
Injection de langue
L'une des fonctionnalités les plus inhabituelles d'IDEA est la possibilité de prendre en charge votre langue dans les constantes de chaîne d'autres langues. Pour ce faire, il suffit d'indiquer à IDEA exactement quelles constantes de chaîne s'appliquent à votre langue, puis IDEA elle-même automatiquement:
- génère un fichier virtuel (ou plusieurs fichiers) avec les préfixes donnés pour chaque constante de chaîne
- crée dans l'éditeur du fichier source pour toutes les constantes une sorte de «fenêtre» dans ce fichier virtuel
- fournit dans ce fichier virtuel la prise en charge de toutes les fonctionnalités du langage «intégré», telles que la mise en évidence des erreurs, le passage à une annonce, la saisie semi-automatique, la recherche d'utilisations et, surtout, la refactorisation. Autrement dit, lorsque vous renommez un élément dans une langue, il est automatiquement renommé dans toutes les constantes de chaîne qui font référence à cet élément dans d'autres langues. Ainsi, vous êtes automatiquement protégé contre les liens rompus.

Ici, dans IDEA, il y avait (et il y a toujours) un petit
bug . Lorsque le fichier virtuel est volumineux, si l'IDEA doit aller au début de la "fenêtre d'implémentation" lorsqu'elle procède à son utilisation, elle va en fait à la fin de la "fenêtre d'implémentation" précédente (c'est-à-dire, par exemple, à l'utilisation précédente de la propriété dans le fichier Java). Il existe bien sûr une solution de contournement simple pour ce bogue qui consiste à créer un fichier virtuel distinct pour chaque chaîne littérale. Mais cette approche ralentit lorsqu'il y a plus de 30 utilisations, donc dans ce cas, vous devez toujours utiliser un grand fichier virtuel (en revanche, quand il y a beaucoup d'utilisations, il n'est pas si difficile de trouver la bonne, c'est-à-dire les suivantes). Nous avons demandé à corriger ce bogue à nouveau dans le cadre de l '«échange de services», et les développeurs JetBrains l'ont en quelque sorte corrigé, mais, comme il s'est avéré plus tard, ce n'était pas le cas (il était toujours visible par le commit, mais nous pensions que ce n'était tout simplement pas à la hauteur l'a compris à la fin). Cependant, nous sommes tous habitués à ce bogue depuis longtemps, car la situation avec l'utilisation de plus de 30 éléments dans un fichier est assez rare.
Conclusion
L'article décrit uniquement les principaux cas d'utilisation. Il a également la possibilité de rechercher des implémentations de propriétés et de classes abstraites, de visualiser les dépendances entre les modules et les propriétés, de générer automatiquement des formulaires basés sur xml / json, et bien plus encore. Et, bien sûr, il y a une intégration intégrée avec les principaux systèmes de contrôle de version de Git et Subversion, ainsi qu'un support pour Maven et Ant.
En suivant la voie du développement du plug-in IDEA, avec peu d'efforts, nous avons obtenu un environnement de développement intégré gratuit très puissant qui dépasse les concurrents IDE à bien des égards.