diff --git a/src/Lean/Elab/Declaration.lean b/src/Lean/Elab/Declaration.lean index e5247d0fea..699abf33d7 100644 --- a/src/Lean/Elab/Declaration.lean +++ b/src/Lean/Elab/Declaration.lean @@ -145,19 +145,23 @@ private def inductiveSyntaxToView (modifiers : Modifiers) (decl : Syntax) : Comm let ⟨name, declName, levelNames⟩ ← expandDeclId declId modifiers addDeclarationRanges declName decl let ctors ← decl[4].getArgs.mapM fun ctor => withRef ctor do - -- def ctor := leading_parser " | " >> declModifiers >> ident >> optDeclSig - let ctorModifiers ← elabModifiers ctor[1] + -- def ctor := leading_parser optional docComment >> "\n| " >> declModifiers >> rawIdent >> optDeclSig + let mut ctorModifiers ← elabModifiers ctor[2] + if let some leadingDocComment := ctor[0].getOptional? then + if ctorModifiers.docString?.isSome then + logErrorAt leadingDocComment "duplicate doc string" + ctorModifiers := { ctorModifiers with docString? := TSyntax.getDocString ⟨leadingDocComment⟩ } if ctorModifiers.isPrivate && modifiers.isPrivate then throwError "invalid 'private' constructor in a 'private' inductive datatype" if ctorModifiers.isProtected && modifiers.isPrivate then throwError "invalid 'protected' constructor in a 'private' inductive datatype" checkValidCtorModifier ctorModifiers - let ctorName := ctor.getIdAt 2 + let ctorName := ctor.getIdAt 3 let ctorName := declName ++ ctorName - let ctorName ← withRef ctor[2] <| applyVisibility ctorModifiers.visibility ctorName - let (binders, type?) := expandOptDeclSig ctor[3] + let ctorName ← withRef ctor[3] <| applyVisibility ctorModifiers.visibility ctorName + let (binders, type?) := expandOptDeclSig ctor[4] addDocString' ctorName ctorModifiers.docString? - addAuxDeclarationRanges ctorName ctor ctor[2] + addAuxDeclarationRanges ctorName ctor ctor[3] return { ref := ctor, modifiers := ctorModifiers, declName := ctorName, binders := binders, type? := type? : CtorView } let computedFields ← (decl[5].getOptional?.map (·[1].getArgs) |>.getD #[]).mapM fun cf => withRef cf do return { ref := cf, modifiers := cf[0], fieldId := cf[1].getId, type := ⟨cf[3]⟩, matchAlts := ⟨cf[4]⟩ } diff --git a/src/Lean/Linter/MissingDocs.lean b/src/Lean/Linter/MissingDocs.lean index d730820e6b..16902bed1c 100644 --- a/src/Lean/Linter/MissingDocs.lean +++ b/src/Lean/Linter/MissingDocs.lean @@ -136,9 +136,9 @@ def checkDecl : SimpleHandler := fun stx => do lintDeclHead k rest[1][0] if k == ``«inductive» || k == ``classInductive then for stx in rest[4].getArgs do - let head := stx[1] - if declModifiersPubNoDoc head then - lintField rest[1][0] stx[2] "public constructor" + let head := stx[2] + if stx[0].isNone && declModifiersPubNoDoc head then + lintField rest[1][0] stx[3] "public constructor" unless rest[5].isNone do for stx in rest[5][0][1].getArgs do let head := stx[0] diff --git a/src/Lean/Parser/Command.lean b/src/Lean/Parser/Command.lean index a9a95a1d1e..4fe3e584b7 100644 --- a/src/Lean/Parser/Command.lean +++ b/src/Lean/Parser/Command.lean @@ -77,7 +77,7 @@ def «instance» := leading_parser Term.attrKind >> "instance" >> optNamed def «axiom» := leading_parser "axiom " >> declId >> ppIndent declSig /- As `declSig` starts with a space, "example" does not need a trailing space. -/ def «example» := leading_parser "example" >> ppIndent optDeclSig >> declVal -def ctor := leading_parser "\n| " >> ppIndent (declModifiers true >> rawIdent >> optDeclSig) +def ctor := leading_parser atomic (optional docComment >> "\n| ") >> ppGroup (declModifiers true >> rawIdent >> optDeclSig) def derivingClasses := sepBy1 (group (ident >> optional (" with " >> Term.structInst))) ", " def optDeriving := leading_parser optional (ppLine >> atomic ("deriving " >> notSymbol "instance") >> derivingClasses) def computedField := leading_parser declModifiers true >> ident >> " : " >> termParser >> Term.matchAlts