Question

Bonjour,

Arrière-plan:

J'utilise Checkstyle 4.4.2 avec un module de vérificateur RegExp pour détecter les cas où le nom de fichier dans les en-têtes source java ne correspond pas au nom de fichier de la classe ou de l'interface dans laquelle ils résident. Cela peut arriver lorsqu'un développeur copie un en-tête d'une classe à une autre sans modifier le " Fichier: " tag.

L'expression régulière utilisée dans le vérificateur RexExp a traversé de nombreuses incarnations et (bien que ce soit peut-être excessif à ce stade) ressemble à ceci:

File: (\w+)\.java\n(?:.*\n)*?(?:[\w|\s]*?(?: class | interface )\1)

La forme de base des fichiers que je vérifie (bien que très simplifiée) ressemble à ceci

/*
 *
 *  Copyright 2009
 *  ...
 *  File: Bar.java
 *  ... 
 */
package foo
... 
import ..
...
/**
 * ...
 */
public class Bar
{...} 

Le problème:

Lorsque aucune correspondance n'est trouvée , (c'est-à-dire lorsqu'un en-tête contenant "Fichier: Bar.java" est copié dans le fichier Bat.java), je reçois une erreur StackOverflowError sur de très longs fichiers (mon cas de test est @ 1300 lignes).

J'ai expérimenté plusieurs testeurs d'expression régulière visuels et je peux voir que, dans le cas non correspondant lorsque le moteur des expressions rationnelles passe la ligne contenant la classe ou le nom de l'interface, recommence la recherche sur la ligne suivante et effectue un retour en arrière, ce qui provoque probablement l'erreur StackOverflowError

La question:

Comment empêcher StackOverflowError en modifiant l'expression régulière

Existe-t-il un moyen de modifier mon expression régulière de telle sorte que, dans le casse correspondante (c'est-à-dire lorsqu'un en-tête contenant "File: Bar.java" soit copié dans le fichier Bat.java) que la correspondance s’arrêterait dès qu’elle examinera la ligne contenant le nom de l’interface ou de la classe et s’apercevra que " \ 1 " ne correspond pas au premier groupe.

Si cela est possible, est-il possible de minimiser la recherche et la correspondance qui ont lieu après avoir examiné la ligne contenant l'interface ou la classe, minimisant ainsi le traitement et (espérons-le) l'erreur StackOverflow?

Était-ce utile?

La solution

Essayez

File: (\w+)\.java\n.*^[\w \t]+(?:class|interface) \1

en mode de correspondance de points. Justification:

[\ w \ s] (le | n'appartient pas là) correspond à tout, y compris les sauts de ligne. Il en résulte beaucoup de retours en arrière dans les lignes que la partie précédente de la regex avait égalées.

Si vous laissez le point gourmand tout engloutir jusqu'à la fin du fichier (rapide), puis effectuez un retour arrière jusqu'à ce que vous trouviez une ligne commençant par des mots ou des espaces / tabulations (mais pas de nouvelles lignes), puis classe ou interface et \ 1, cela ne nécessite pas autant d'espace de pile.

Une solution différente et probablement encore meilleure serait de scinder le problème en plusieurs parties.

Correspond d'abord à la partie Fichier: (\ w +) \. java . Effectuez ensuite une deuxième recherche avec ^ [\ w \ t] + (?: class | interface) plus le \ 1 correspondance de la première recherche sur le même fichier.

Autres conseils

Suivi:

J'ai intégré la suggestion de Tim Pietzcher ci-dessus et sa solution gloutonne a effectivement échoué plus rapidement et sans erreur StackOverflowError lorsqu'aucune correspondance n'a été trouvée. Toutefois, dans le cas positif, l'erreur StackOverflowError existait toujours.

J'ai jeté un œil au code source RegexpCheck.java . Le modèle de classes est construit en mode multiligne de sorte que les expressions ^ et $ correspondent juste après ou juste avant, respectivement, un terminateur de ligne ou la fin de la séquence d'entrée. Ensuite, il lit l'intégralité du fichier de classe dans une chaîne et effectue une recherche récursive du modèle (voir findMatch ()). C'est sans aucun doute la source de l'exception StackOverflowException.

À la fin, je n’ai pas réussi à le faire fonctionner (et j’ai abandonné). Depuis que Maven 2 a publié le maven-checkstyle-plugin-2.4 / Checkstyle 5.0 il ya environ 6 semaines, nous avons décidé de mettre à jour nos outils. Cela ne résoudra peut-être pas le problème StackOverflowError, mais cela me donnera quelque chose d’autre sur lequel travailler jusqu’à ce que quelqu'un décide que nous devons poursuivre ce travail à nouveau.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top