Skip to content

Commit ad67700

Browse files
joderskyretronym
authored andcommitted
Javadoc: fix problems in community build
- fix initialization NPE in doc headers - fix assertion errors for java fields - ignore comments when deciding where to put interface methods - consider DocDefs when checking for constructors
1 parent 4e822d7 commit ad67700

File tree

6 files changed

+317
-11
lines changed

6 files changed

+317
-11
lines changed

src/compiler/scala/tools/nsc/ast/TreeInfo.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,12 @@ abstract class TreeInfo extends scala.reflect.internal.TreeInfo {
9797
case DocDef(_, definition) => isPureDef(definition)
9898
case _ => super.isPureDef(tree)
9999
}
100+
101+
override def firstConstructor(stats: List[Tree]): Tree = {
102+
def unwrap(stat: Tree): Tree = stat match {
103+
case DocDef(_, defn) => unwrap(defn)
104+
case tree => tree
105+
}
106+
super.firstConstructor(stats map unwrap)
107+
}
100108
}

src/compiler/scala/tools/nsc/javac/JavaParsers.scala

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,8 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
117117
atPos(pkg.pos) { PackageDef(pkg, stats) }
118118

119119
def makeTemplate(parents: List[Tree], stats: List[Tree]) =
120-
Template(
121-
parents,
122-
noSelfType,
123-
if (treeInfo.firstConstructor(stats) == EmptyTree) makeConstructor(List()) :: stats
124-
else stats)
120+
Template(parents, noSelfType, if (treeInfo.firstConstructor(stats) == EmptyTree)
121+
makeConstructor(Nil) :: stats else stats)
125122

126123
def makeSyntheticParam(count: Int, tpt: Tree): ValDef =
127124
makeParam(nme.syntheticParamName(count), tpt)
@@ -586,7 +583,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
586583
case CLASS | ENUM | INTERFACE | AT =>
587584
typeDecl(if (definesInterface(parentToken)) mods | Flags.STATIC else mods)
588585
case _ =>
589-
joinComment(termDecl(mods, parentToken))
586+
termDecl(mods, parentToken)
590587
}
591588

592589
def makeCompanionObject(cdef: ClassDef, statics: List[Tree]): Tree =
@@ -708,8 +705,15 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
708705
in.nextToken()
709706
} else {
710707
if (in.token == ENUM || definesInterface(in.token)) mods |= Flags.STATIC
711-
val decls = memberDecl(mods, parentToken)
712-
(if (mods.hasStaticFlag || inInterface && !(decls exists (_.isInstanceOf[DefDef])))
708+
val decls = joinComment(memberDecl(mods, parentToken))
709+
710+
def isDefDef(tree: Tree): Boolean = tree match {
711+
case _: DefDef => true
712+
case DocDef(_, defn) => isDefDef(defn)
713+
case _ => false
714+
}
715+
716+
(if (mods.hasStaticFlag || inInterface && !(decls exists isDefDef))
713717
statics
714718
else
715719
members) ++= decls

src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ trait MethodSynthesis {
201201

202202
import AnnotationInfo.{mkFilter => annotationFilter}
203203
def addDerivedTrees(typer: Typer, stat: Tree): List[Tree] = stat match {
204-
case vd @ ValDef(mods, name, tpt, rhs) if deriveAccessors(vd) && !vd.symbol.isModuleVar =>
204+
case vd @ ValDef(mods, name, tpt, rhs) if deriveAccessors(vd) && !vd.symbol.isModuleVar && !vd.symbol.isJava =>
205205
stat.symbol.initialize // needed!
206206

207207
val getter = Getter(vd)

src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,16 @@ abstract class ScaladocSyntaxAnalyzer[G <: Global](val global: G) extends Syntax
216216

217217
class ScaladocJavaUnitScanner(unit: CompilationUnit) extends JavaUnitScanner(unit) {
218218

219-
private val docBuffer: StringBuilder = new StringBuilder
219+
private var docBuffer: StringBuilder = _
220220
private var inDocComment = false
221221
private var docStart: Int = 0
222222
private var lastDoc: DocComment = null
223223

224+
override def init() = {
225+
docBuffer = new StringBuilder
226+
super.init()
227+
}
228+
224229
// get last doc comment
225230
def flushDoc(): DocComment = try lastDoc finally lastDoc = null
226231

test/scaladoc/resources/SI-4826.java

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/**
2+
* A package header
3+
*/
14
package test.scaladoc;
25

36
/**
@@ -6,6 +9,29 @@
69
*/
710
public class JavaComments {
811

12+
/** A field */
13+
public final int x;
14+
/** A field */
15+
protected int y;
16+
/** A field */
17+
private int z;
18+
19+
/**
20+
* Inner class
21+
*/
22+
public class Inner {
23+
/** Inner method */
24+
public void foo() {
25+
}
26+
}
27+
28+
/**
29+
* A typed inner class
30+
* @param <T> some type
31+
*/
32+
public class InnerTyped<T> {
33+
}
34+
935
/**
1036
* Compute the answer to the ultimate question of life, the
1137
* universe, and everything. :marker:
@@ -16,5 +42,268 @@ public int answer(int factor) {
1642
return 42 * factor;
1743
}
1844

45+
/** Private */
46+
private double foo(double value) {
47+
return value;
48+
}
49+
50+
/** Protected */
51+
protected double bar(double value) {
52+
return value;
53+
}
54+
55+
/** No qualifier*/
56+
String noqualifier() {
57+
return "something";
58+
}
59+
60+
/** Void */
61+
public void voidmethod(boolean t) {
62+
}
63+
64+
/**
65+
* Typed parameter
66+
* @param <A> the parameter type
67+
* @param a parameter
68+
* @return something
69+
*/
70+
public <A> void tparams(A a) {
71+
}
72+
73+
/**
74+
* Typed parameter
75+
* @param <A> the return type
76+
* @param <B> the parameter typeA
77+
* @param b parameter
78+
* @return casts B to A
79+
*/
80+
public <A, B extends A> A cast(B b) {
81+
return (B) b;
82+
}
83+
1984
}
2085

86+
// The following snippet is taken from Akka, it mainly tests interfaces
87+
88+
/**
89+
* Class that encapsulates all the Functional Interfaces
90+
* used for creating partial functions.
91+
*
92+
* This is an EXPERIMENTAL feature and is subject to change until it has received more real world testing.
93+
*/
94+
public final class FI {
95+
96+
/** Doc comment on constructor */
97+
private FI() {
98+
}
99+
100+
/**
101+
* Functional interface for an application.
102+
*
103+
* @param <I> the input type, that this Apply will be applied to
104+
* @param <R> the return type, that the results of the application will have
105+
*/
106+
public static interface Apply<I, R> {
107+
/**
108+
* The application to perform.
109+
*
110+
* @param i an instance that the application is performed on
111+
* @return the result of the application
112+
*/
113+
public R apply(I i) throws Exception;
114+
}
115+
116+
/**
117+
* Functional interface for an application.
118+
*
119+
* @param <I1> the first input type, that this Apply will be applied to
120+
* @param <I2> the second input type, that this Apply will be applied to
121+
* @param <R> the return type, that the results of the application will have
122+
*/
123+
public static interface Apply2<I1, I2, R> {
124+
/**
125+
* The application to perform.
126+
*
127+
* @param i1 an instance that the application is performed on
128+
* @param i2 an instance that the application is performed on
129+
* @return the result of the application
130+
*/
131+
public R apply(I1 i1, I2 i2) throws Exception;
132+
}
133+
134+
/**
135+
* Functional interface for a predicate.
136+
*
137+
* @param <T> the type that the predicate will operate on.
138+
*/
139+
public static interface TypedPredicate<T> {
140+
/**
141+
* The predicate to evaluate.
142+
*
143+
* @param t an instance that the predicate is evaluated on.
144+
* @return the result of the predicate
145+
*/
146+
public boolean defined(T t);
147+
}
148+
149+
/**
150+
* Functional interface for a predicate.
151+
*
152+
* @param <T> the type that the predicate will operate on.
153+
* @param <U> the type that the predicate will operate on.
154+
*/
155+
public static interface TypedPredicate2<T, U> {
156+
/**
157+
* The predicate to evaluate.
158+
*
159+
* @param t an instance that the predicate is evaluated on.
160+
* @param u an instance that the predicate is evaluated on.
161+
* @return the result of the predicate
162+
*/
163+
public boolean defined(T t, U u);
164+
}
165+
166+
/**
167+
* Functional interface for an application.
168+
*
169+
* @param <I> the input type, that this Apply will be applied to
170+
*/
171+
public static interface UnitApply<I> {
172+
/**
173+
* The application to perform.
174+
*
175+
* @param i an instance that the application is performed on
176+
*/
177+
public void apply(I i) throws Exception;
178+
}
179+
180+
/**
181+
* Functional interface for an application.
182+
*
183+
* @param <I1> the first input type, that this Apply will be applied to
184+
* @param <I2> the second input type, that this Apply will be applied to
185+
*/
186+
public static interface UnitApply2<I1, I2> {
187+
/**
188+
* The application to perform.
189+
*
190+
* @param i1 an instance that the application is performed on
191+
* @param i2 an instance that the application is performed on
192+
*/
193+
public void apply(I1 i1, I2 i2) throws Exception;
194+
}
195+
196+
/**
197+
* Functional interface for an application.
198+
*
199+
* @param <I1> the first input type, that this Apply will be applied to
200+
* @param <I2> the second input type, that this Apply will be applied to
201+
* @param <I3> the third input type, that this Apply will be applied to
202+
*/
203+
public static interface UnitApply3<I1, I2, I3> {
204+
/**
205+
* The application to perform.
206+
*
207+
* @param i1 an instance that the application is performed on
208+
* @param i2 an instance that the application is performed on
209+
* @param i3 an instance that the application is performed on
210+
*/
211+
public void apply(I1 i1, I2 i2, I3 i3) throws Exception;
212+
}
213+
214+
/**
215+
* Functional interface for an application.
216+
*
217+
* @param <I1> the first input type, that this Apply will be applied to
218+
* @param <I2> the second input type, that this Apply will be applied to
219+
* @param <I3> the third input type, that this Apply will be applied to
220+
* @param <I4> the fourth input type, that this Apply will be applied to
221+
*/
222+
public static interface UnitApply4<I1, I2, I3, I4> {
223+
/**
224+
* The application to perform.
225+
*
226+
* @param i1 an instance that the application is performed on
227+
* @param i2 an instance that the application is performed on
228+
* @param i3 an instance that the application is performed on
229+
* @param i4 an instance that the application is performed on
230+
*/
231+
public void apply(I1 i1, I2 i2, I3 i3, I4 i4) throws Exception;
232+
}
233+
234+
/**
235+
* Functional interface for an application.
236+
*/
237+
public static interface UnitApplyVoid {
238+
/**
239+
* The application to perform.
240+
*/
241+
public void apply() throws Exception;
242+
}
243+
244+
/**
245+
* Package scoped functional interface for a predicate. Used internally to match against arbitrary types.
246+
*/
247+
static interface Predicate {
248+
/**
249+
* The predicate to evaluate.
250+
*
251+
* @param o an instance that the predicate is evaluated on.
252+
* @return the result of the predicate
253+
*/
254+
public boolean defined(Object o);
255+
}
256+
257+
/** comment about */
258+
/** a comment about */
259+
/** a comment */
260+
void foo() {}
261+
262+
/** someone forgot to uncomment */
263+
//void thisMethod() {}
264+
/** and also this */
265+
//void otherMethod() {}
266+
}
267+
268+
/**
269+
* Functional interface for an application.
270+
*
271+
* @param <I1> the first input type, that this Apply will be applied to
272+
* @param <I2> the second input type, that this Apply will be applied to
273+
* @param <I3> the third input type, that this Apply will be applied to
274+
* @param <I4> the fourth input type, that this Apply will be applied to
275+
*/
276+
public interface UnitApply4<I1, I2, I3, I4> {
277+
/**
278+
* The application to perform.
279+
*
280+
* @param i1 an instance that the application is performed on
281+
* @param i2 an instance that the application is performed on
282+
* @param i3 an instance that the application is performed on
283+
* @param i4 an instance that the application is performed on
284+
*/
285+
public void apply(I1 i1, I2 i2, I3 i3, I4 i4) throws Exception;
286+
}
287+
288+
/**
289+
* Functional interface for an application.
290+
*/
291+
public interface UnitApplyVoid {
292+
/**
293+
* The application to perform.
294+
*/
295+
public void apply() throws Exception;
296+
}
297+
298+
/**
299+
* Package scoped functional interface for a predicate. Used internally to match against arbitrary types.
300+
*/
301+
interface Predicate {
302+
/**
303+
* The predicate to evaluate.
304+
*
305+
* @param o an instance that the predicate is evaluated on.
306+
* @return the result of the predicate
307+
*/
308+
public boolean defined(Object o);
309+
}

test/scaladoc/run/SI-4826.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ object Test extends ScaladocModelTest {
1414
}
1515

1616
// no need for special settings
17-
def scaladocSettings = ""
17+
override def scaladocSettings = ""
1818

1919
def testModel(rootPackage: Package) = {
2020
import access._

0 commit comments

Comments
 (0)