2013-07-28 9 views
6

Nel modulo B ho la documentazione con un collegamento 'A.foo', collegamento al membro foo del modulo A. Nel modulo A importare il modulo B. Haddock lo rende come un collegamento a A.html#t:foo, che punta al tipofoo (che non esiste) non alla funzione foo, che è a A.html#v:foo.Collegamento eglefino alle funzioni nei moduli non importati

  • Perché l'eglefino collega a t: per le variabili che iniziano con una lettera minuscola? È un bug? Per 'A.Foo' posso vedere che potrebbe essere un tipo o un costruttore, quindi ci sono problemi di namespacing. Per foo sembra che una variabile sia almeno la più plausibile.
  • C'è un modo per simulare un collegamento? Sto scrivendo questo in esempi di codice, quindi ho bisogno di renderlo come foo. Ho provato le ancore, ma esse rappresentano il nome del modulo e per i collegamenti ipertestuali diretti non si ha il controllo sul testo visualizzato.
  • Ho considerato un post processore (sostituendo t:[a-z] con v:), ma ciò richiede un Setup.hs personalizzato che causa problemi ed è piuttosto brutto.
  • Impossibile trovare i flag della riga di comando di Haddock per ottenere un comportamento più ragionevole, ad esempio specificando che foo è una variabile.
  • Non riesco ad aggiungere un'importazione di A a B senza introdurre le importazioni circolari, che è vile aggiungerlo solo per la documentazione.

Sto riscontrando questo problema nello Shake documentation, dove ad esempio removeFilesAfter non ottiene il collegamento corretto.

risposta

2

Questo era un Haddock bug #228 e Neil's Haddock bug #253 e la correzione è stata a monte per alcuni mesi. Puoi costruire GHC HEAD e ricostruire la tua documentazione o attendere 7.8 e farlo allora.

4

Posso parzialmente rispondere alla prima domanda (Perché?); non sono sicuro se si tratta di un bug o comportamento desiderato.

Quando l'eglefino risolve i riferimenti in LexParseRn.rename, tenta di cercare l'identificatore nell'ambiente (tramite lookupGRE_RdrName). Questo dovrebbe fallire. Successivamente sembra che cosa significhi medio (utilizzando dataTcOccs from GHC’s RnEnv). Le linee in questione sono:

dataTcOccs :: RdrName -> [RdrName] 
-- Return both the given name and the same name promoted to the TcClsName 
-- namespace. This is useful when we aren't sure which we are looking at. 
dataTcOccs rdr_name 
    [...] 
    | isDataOcc occ || isVarOcc occ 
    = [rdr_name, rdr_name_tc] 
    [...] 
    where 
    occ = rdrNameOcc rdr_name 
    rdr_name_tc = setRdrNameSpace rdr_name tcName 

quindi restituisce il nome interpretato come tutto ciò che era prima (probabilmente un link ad un valore), e quindi interpretato come un costruttore di tipo. Come può un nome normale essere un costruttore di tipi? La mia ipotesi è che questo è stato aggiunto quando TypeOperators è stato riformato in GHC 7.6, che ora condividono lo spazio dei nomi con operatori a livello di valore.

Quindi le corrispondenze di haddock sul risultato: se il primo è un costruttore di tipi, utilizzarlo, altrimenti utilizzare il secondo. Quindi prima era un costruttore di tipi, poi questo è usato. O non lo era, ma deve essere utilizzata la versione modificata generata da dataTcOccs.

Mi sembra che l'eglefino dovrebbe sempre utilizzare la prima opzione qui e il codice è solo una copia fuorviante di come vengono utilizzati più risultati quando possono essere effettivamente risolti.

+1

analisi molto belle, ogni possibilità di inviare una patch upstream? –

+0

So solo * come * il codice funziona in questo modo, non * perché *, potrebbe esserci una buona ragione per questo. Ma suppongo che tu possa aprire una segnalazione di bug e indirizzarla qui in modo che sappiano a quale parte del loro codice hanno bisogno di pensare. –

+0

Ho pile di bug di Haddock aperti (almeno 6 dal mio conteggio) che non hanno mai avuto alcuna risposta - sembra che a loro non importi ... –

Problemi correlati