Pergunta

Olá,

Antecedentes:

Eu estou usando Checkstyle 4.4.2 com um módulo verificador RegExp para detectar quando o nome do arquivo em cabeçalhos de origem fora java não coincidir com o nome da classe ou interface em que residem arquivo. Isso pode acontecer quando um desenvolvedor de cópias de um cabeçalho de uma classe para outra e não modifica o "arquivo:". Tag

O uso de expressões regulares no verificador RexExp passou por muitas encarnações e (embora seja possivelmente um exagero neste momento) parece com isso:

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

A forma básica de arquivos que eu estou verificando (embora muito simplificada) se parece com isso

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

O Problema:

Quando nenhuma correspondência for encontrada , (ou seja, quando um cabeçalho contendo "File: Bar.java" é copiado para arquivo Bat.java) eu receber uma StackOverflowError em arquivos muito longos (meu caso de teste é @ 1300 linhas).

Eu experimentei com vários testadores de expressão regular visuais e pode ver que no caso de não-casamento quando o motor regex passa a linha que contém o nome da classe ou interface que começa a procurar novamente na próxima linha e faz algum retrocesso que provavelmente faz com que o StackOverflowError

A Pergunta:

Como evitar a StackOverflowError modificando a expressão regular

Existe alguma maneira de modificar a minha expressão regular tal que no caso de não-casamento (ou seja, quando um cabeçalho contendo "File: Bar.java" é copiado para arquivo Bat.java) que a correspondência iria parar uma vez que examina a linha que contém o nome da interface ou classe e vê que "\ 1" não coincide com o primeiro grupo.

Como alternativa, se isso pode ser feito, é é possível minimizar a pesquisa e correspondência que ocorre depois que examina a linha que contém o interface ou classe de processamento minimizando, assim, e (espero) o erro StackOverflow?

Foi útil?

Solução

Tente

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

no ponto-jogos-all modo. Justificativa:

[\w\s] (a | não pertence lá) corresponde a qualquer coisa, incluindo as quebras de linha. Isso resulta em um monte de retrocesso de volta para as linhas que a parte anterior do regex tinha correspondido.

Se você deixar o ponto gananciosos devorar tudo até o final do arquivo (rápida) e, em seguida, recuar até encontrar uma linha que começa com palavras ou espaços / abas (mas sem novas linhas) e depois class ou interface e \ 1, em seguida, que não requer tanto espaço pilha.

Um diferente, e provavelmente melhor solução ainda seria dividir o problema em partes.

Primeiro coincidir com a parte File: (\w+)\.java. Em seguida, faça uma segunda pesquisa com ^[\w \t]+(?:class|interface) mais o jogo \1 da primeira pesquisa sobre o mesmo arquivo.

Outras dicas

Siga-se:

I ligado a sugestão de Tim Pietzcher acima e sua solução ganancioso, de fato, falhar mais rápido e sem StackOverflowError quando nenhuma correspondência foi encontrada. No entanto, no caso positivo, o StackOverflowError ainda ocorrido.

Eu levei um olhar para o código-fonte RegexpCheck.java . O padrão de classes é construído de modo tal que as várias linhas expressões ^ e $ jogo apenas depois ou imediatamente antes de, respectivamente, um terminal de linha ou o fim da sequência de entrada. Em seguida, ele lê o arquivo de classe inteira em uma corda e faz uma pesquisa recursiva para o padrão (veja findMatch ()). Essa é, sem dúvida, a fonte do StackOverflowException.

No final, eu não fazê-lo funcionar (e desistiu) Desde Maven 2 lançado do Maven-checkstyle plugin-2.4 / 5.0 Checkstyle cerca de 6 semanas atrás nós decidimos atualizar nossas ferramentas. Isto pode não resolver o problema StackOverflowError, mas vai me dar alguma coisa para o trabalho em até que alguém decide que precisamos perseguir isso novamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top