Produced by Araxis Merge on 9/25/2018 2:13:06 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.
# | Location | File | Last Modified |
---|---|---|---|
1 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\com\sun\tools\javac\comp | Attr.java | Mon Jan 22 14:47:06 2018 UTC |
2 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\com\sun\tools\javac\comp | Attr.java | Wed Sep 12 16:49:24 2018 UTC |
Description | Between Files 1 and 2 |
|
---|---|---|
Text Blocks | Lines | |
Unchanged | 6 | 9700 |
Changed | 5 | 10 |
Inserted | 0 | 0 |
Removed | 0 | 0 |
Whitespace | |
---|---|
Character case | Differences in character case are significant |
Line endings | Differences in line endings (CR and LF characters) are ignored |
CR/LF characters | Not shown in the comparison detail |
No regular expressions were active.
1 | /* | |
2 | * Copyrig ht (c) 199 9, 2016, O racle and/ or its aff iliates. A ll rights reserved. | |
3 | * DO NOT ALTER OR R EMOVE COPY RIGHT NOTI CES OR THI S FILE HEA DER. | |
4 | * | |
5 | * This co de is free software; you can r edistribut e it and/o r modify i t | |
6 | * under t he terms o f the GNU General Pu blic Licen se version 2 only, a s | |
7 | * publish ed by the Free Softw are Founda tion. Ora cle design ates this | |
8 | * particu lar file a s subject to the "Cl asspath" e xception a s provided | |
9 | * by Orac le in the LICENSE fi le that ac companied this code. | |
10 | * | |
11 | * This co de is dist ributed in the hope that it wi ll be usef ul, but WI THOUT | |
12 | * ANY WAR RANTY; wit hout even the implie d warranty of MERCHA NTABILITY or | |
13 | * FITNESS FOR A PAR TICULAR PU RPOSE. Se e the GNU General Pu blic Licen se | |
14 | * version 2 for mor e details (a copy is included in the LIC ENSE file that | |
15 | * accompa nied this code). | |
16 | * | |
17 | * You sho uld have r eceived a copy of th e GNU Gene ral Public License v ersion | |
18 | * 2 along with this work; if not, write to the Fr ee Softwar e Foundati on, | |
19 | * Inc., 5 1 Franklin St, Fifth Floor, Bo ston, MA 0 2110-1301 USA. | |
20 | * | |
21 | * Please contact Or acle, 500 Oracle Par kway, Redw ood Shores , CA 94065 USA | |
22 | * or visi t www.orac le.com if you need a dditional informatio n or have any | |
23 | * questio ns. | |
24 | */ | |
25 | ||
26 | package co m.sun.tool s.javac.co mp; | |
27 | ||
28 | import jav a.util.*; | |
29 | ||
30 | import jav ax.lang.mo del.elemen t.ElementK ind; | |
31 | import jav ax.tools.J avaFileObj ect; | |
32 | ||
33 | import com .sun.sourc e.tree.Ide ntifierTre e; | |
34 | import com .sun.sourc e.tree.Mem berReferen ceTree.Ref erenceMode ; | |
35 | import com .sun.sourc e.tree.Mem berSelectT ree; | |
36 | import com .sun.sourc e.tree.Tre eVisitor; | |
37 | import com .sun.sourc e.util.Sim pleTreeVis itor; | |
38 | import com .sun.tools .javac.cod e.*; | |
39 | import com .sun.tools .javac.cod e.Lint.Lin tCategory; | |
40 | import com .sun.tools .javac.cod e.Symbol.* ; | |
41 | import com .sun.tools .javac.cod e.Type.*; | |
42 | import com .sun.tools .javac.com p.Check.Ch eckContext ; | |
43 | import com .sun.tools .javac.com p.Deferred Attr.AttrM ode; | |
44 | import com .sun.tools .javac.com p.Infer.In ferenceCon text; | |
45 | import com .sun.tools .javac.com p.Infer.Fr eeTypeList ener; | |
46 | import com .sun.tools .javac.jvm .*; | |
47 | import com .sun.tools .javac.tre e.*; | |
48 | import com .sun.tools .javac.tre e.JCTree.* ; | |
49 | import com .sun.tools .javac.tre e.JCTree.J CPolyExpre ssion.*; | |
50 | import com .sun.tools .javac.uti l.*; | |
51 | import com .sun.tools .javac.uti l.JCDiagno stic.Diagn osticPosit ion; | |
52 | import com .sun.tools .javac.uti l.List; | |
53 | import sta tic com.su n.tools.ja vac.code.F lags.*; | |
54 | import sta tic com.su n.tools.ja vac.code.F lags.ANNOT ATION; | |
55 | import sta tic com.su n.tools.ja vac.code.F lags.BLOCK ; | |
56 | import sta tic com.su n.tools.ja vac.code.K inds.*; | |
57 | import sta tic com.su n.tools.ja vac.code.K inds.ERRON EOUS; | |
58 | import sta tic com.su n.tools.ja vac.code.T ypeTag.*; | |
59 | import sta tic com.su n.tools.ja vac.code.T ypeTag.WIL DCARD; | |
60 | import sta tic com.su n.tools.ja vac.tree.J CTree.Tag. *; | |
61 | ||
62 | /** This i s the main context-d ependent a nalysis ph ase in GJC . It | |
63 | * encomp asses name resolutio n, type ch ecking and constant folding as | |
64 | * subtas ks. Some s ubtasks in volve auxi liary clas ses. | |
65 | * @see C heck | |
66 | * @see R esolve | |
67 | * @see C onstFold | |
68 | * @see I nfer | |
69 | * | |
70 | * <p><b> This is NO T part of any suppor ted API. | |
71 | * If you write cod e that dep ends on th is, you do so at you r own risk . | |
72 | * This c ode and it s internal interface s are subj ect to cha nge or | |
73 | * deleti on without notice.</ b> | |
74 | */ | |
75 | public cla ss Attr ex tends JCTr ee.Visitor { | |
76 | protec ted static final Con text.Key<A ttr> attrK ey = | |
77 | ne w Context. Key<Attr>( ); | |
78 | ||
79 | final Names name s; | |
80 | final Log log; | |
81 | final Symtab sym s; | |
82 | final Resolve rs ; | |
83 | final Infer infe r; | |
84 | final DeferredAt tr deferre dAttr; | |
85 | final Check chk; | |
86 | final Flow flow; | |
87 | final MemberEnte r memberEn ter; | |
88 | final TreeMaker make; | |
89 | final ConstFold cfolder; | |
90 | final Enter ente r; | |
91 | final Target tar get; | |
92 | final Types type s; | |
93 | final JCDiagnost ic.Factory diags; | |
94 | final Annotate a nnotate; | |
95 | final TypeAnnota tions type Annotation s; | |
96 | final DeferredLi ntHandler deferredLi ntHandler; | |
97 | final TypeEnvs t ypeEnvs; | |
98 | ||
99 | public static At tr instanc e(Context context) { | |
100 | At tr instanc e = contex t.get(attr Key); | |
101 | if (instance == null) | |
102 | instance = new Att r(context) ; | |
103 | re turn insta nce; | |
104 | } | |
105 | ||
106 | protec ted Attr(C ontext con text) { | |
107 | co ntext.put( attrKey, t his); | |
108 | ||
109 | na mes = Name s.instance (context); | |
110 | lo g = Log.in stance(con text); | |
111 | sy ms = Symta b.instance (context); | |
112 | rs = Resolve .instance( context); | |
113 | ch k = Check. instance(c ontext); | |
114 | fl ow = Flow. instance(c ontext); | |
115 | me mberEnter = MemberEn ter.instan ce(context ); | |
116 | ma ke = TreeM aker.insta nce(contex t); | |
117 | en ter = Ente r.instance (context); | |
118 | in fer = Infe r.instance (context); | |
119 | de ferredAttr = Deferre dAttr.inst ance(conte xt); | |
120 | cf older = Co nstFold.in stance(con text); | |
121 | ta rget = Tar get.instan ce(context ); | |
122 | ty pes = Type s.instance (context); | |
123 | di ags = JCDi agnostic.F actory.ins tance(cont ext); | |
124 | an notate = A nnotate.in stance(con text); | |
125 | ty peAnnotati ons = Type Annotation s.instance (context); | |
126 | de ferredLint Handler = DeferredLi ntHandler. instance(c ontext); | |
127 | ty peEnvs = T ypeEnvs.in stance(con text); | |
128 | ||
129 | Op tions opti ons = Opti ons.instan ce(context ); | |
130 | ||
131 | So urce sourc e = Source .instance( context); | |
132 | al lowGeneric s = source .allowGene rics(); | |
133 | al lowVarargs = source. allowVarar gs(); | |
134 | al lowEnums = source.al lowEnums() ; | |
135 | al lowBoxing = source.a llowBoxing (); | |
136 | al lowCovaria ntReturns = source.a llowCovari antReturns (); | |
137 | al lowAnonOut erThis = s ource.allo wAnonOuter This(); | |
138 | al lowStrings InSwitch = source.al lowStrings InSwitch() ; | |
139 | al lowPoly = source.all owPoly(); | |
140 | al lowTypeAnn os = sourc e.allowTyp eAnnotatio ns(); | |
141 | al lowLambda = source.a llowLambda (); | |
142 | al lowDefault Methods = source.all owDefaultM ethods(); | |
143 | al lowStaticI nterfaceMe thods = so urce.allow StaticInte rfaceMetho ds(); | |
144 | so urceName = source.na me; | |
145 | re lax = (opt ions.isSet ("-retrofi t") || | |
146 | opt ions.isSet ("-relax") ); | |
147 | fi ndDiamonds = options .get("find Diamond") != null && | |
148 | sou rce.allowD iamond(); | |
149 | us eBeforeDec larationWa rning = op tions.isSe t("useBefo reDeclarat ionWarning "); | |
150 | id entifyLamb daCandidat e = option s.getBoole an("identi fyLambdaCa ndidate", false); | |
151 | ||
152 | st atInfo = n ew ResultI nfo(NIL, T ype.noType ); | |
153 | va rInfo = ne w ResultIn fo(VAR, Ty pe.noType) ; | |
154 | un knownExprI nfo = new ResultInfo (VAL, Type .noType); | |
155 | un knownAnyPo lyInfo = n ew ResultI nfo(VAL, I nfer.anyPo ly); | |
156 | un knownTypeI nfo = new ResultInfo (TYP, Type .noType); | |
157 | un knownTypeE xprInfo = new Result Info(Kinds .TYP | Kin ds.VAL, Ty pe.noType) ; | |
158 | re coveryInfo = new Rec overyInfo( deferredAt tr.emptyDe ferredAttr Context); | |
159 | ||
160 | no CheckTree = make.at( -1).Skip() ; | |
161 | } | |
162 | ||
163 | /** Sw itch: rela x some con straints f or retrofi t mode. | |
164 | */ | |
165 | boolea n relax; | |
166 | ||
167 | /** Sw itch: supp ort target -typing in ference | |
168 | */ | |
169 | boolea n allowPol y; | |
170 | ||
171 | /** Sw itch: supp ort type a nnotations . | |
172 | */ | |
173 | boolea n allowTyp eAnnos; | |
174 | ||
175 | /** Sw itch: supp ort generi cs? | |
176 | */ | |
177 | boolea n allowGen erics; | |
178 | ||
179 | /** Sw itch: allo w variable -arity met hods. | |
180 | */ | |
181 | boolea n allowVar args; | |
182 | ||
183 | /** Sw itch: supp ort enums? | |
184 | */ | |
185 | boolea n allowEnu ms; | |
186 | ||
187 | /** Sw itch: supp ort boxing and unbox ing? | |
188 | */ | |
189 | boolea n allowBox ing; | |
190 | ||
191 | /** Sw itch: supp ort covari ant result types? | |
192 | */ | |
193 | boolea n allowCov ariantRetu rns; | |
194 | ||
195 | /** Sw itch: supp ort lambda expressio ns ? | |
196 | */ | |
197 | boolea n allowLam bda; | |
198 | ||
199 | /** Sw itch: supp ort defaul t methods ? | |
200 | */ | |
201 | boolea n allowDef aultMethod s; | |
202 | ||
203 | /** Sw itch: stat ic interfa ce methods enabled? | |
204 | */ | |
205 | boolea n allowSta ticInterfa ceMethods; | |
206 | ||
207 | /** Sw itch: allo w referenc es to surr ounding ob ject from anonymous | |
208 | * obj ects durin g construc tor call? | |
209 | */ | |
210 | boolea n allowAno nOuterThis ; | |
211 | ||
212 | /** Sw itch: gene rates a wa rning if d iamond can be safely applied | |
213 | * to a given n ew express ion | |
214 | */ | |
215 | boolea n findDiam onds; | |
216 | ||
217 | /** | |
218 | * Int ernally en ables/disa bles diamo nd finder feature | |
219 | */ | |
220 | static final boo lean allow DiamondFin der = true ; | |
221 | ||
222 | /** | |
223 | * Swi tch: warn about use of variabl e before d eclaration ? | |
224 | * RFE : 6425594 | |
225 | */ | |
226 | boolea n useBefor eDeclarati onWarning; | |
227 | ||
228 | /** | |
229 | * Swi tch: gener ate warnin gs wheneve r an anony mous inner class tha t is conve rtible | |
230 | * to a lambda e xpression is found | |
231 | */ | |
232 | boolea n identify LambdaCand idate; | |
233 | ||
234 | /** | |
235 | * Swi tch: allow strings i n switch? | |
236 | */ | |
237 | boolea n allowStr ingsInSwit ch; | |
238 | ||
239 | /** | |
240 | * Swi tch: name of source level; use d for erro r reportin g. | |
241 | */ | |
242 | String sourceNam e; | |
243 | ||
244 | /** Ch eck kind a nd type of given tre e against protokind and protot ype. | |
245 | * If check suc ceeds, sto re type in tree and return it. | |
246 | * If check fai ls, store errType in tree and return it. | |
247 | * No checks ar e performe d if the p rototype i s a method type. | |
248 | * It is not ne cessary in this case since we know that kind and t ype | |
249 | * ar e correct. | |
250 | * | |
251 | * @p aram tree The tr ee whose k ind and ty pe is chec ked | |
252 | * @p aram found The co mputed typ e of the t ree | |
253 | * @p aram ownki nd The co mputed kin d of the t ree | |
254 | * @p aram resul tInfo The expected result of the tree | |
255 | */ | |
256 | Type c heck(final JCTree tr ee, final Type found , final in t ownkind, final Res ultInfo re sultInfo) { | |
257 | In ferenceCon text infer enceContex t = result Info.check Context.in ferenceCon text(); | |
258 | Ty pe owntype ; | |
259 | bo olean shou ldCheck = !found.has Tag(ERROR) && | |
260 | !res ultInfo.pt .hasTag(ME THOD) && | |
261 | !res ultInfo.pt .hasTag(FO RALL); | |
262 | if (shouldCh eck && (ow nkind & ~r esultInfo. pkind) != 0) { | |
263 | log.erro r(tree.pos (), "unexp ected.type ", | |
264 | kindNa mes(result Info.pkind ), | |
265 | kindNa me(ownkind )); | |
266 | owntype = types.cr eateErrorT ype(found) ; | |
267 | } else if (a llowPoly & & inferenc eContext.f ree(found) ) { | |
268 | //delay the check if there a re inferen ce variabl es in the found type | |
269 | //this m eans we ar e dealing with a par tially inf erred poly expressio n | |
270 | owntype = shouldCh eck ? resu ltInfo.pt : found; | |
271 | inferenc eContext.a ddFreeType Listener(L ist.of(fou nd, result Info.pt), new FreeTy peListener () { | |
272 | @Override | |
273 | public voi d typesInf erred(Infe renceConte xt inferen ceContext) { | |
274 | Result Info pendi ngResult = | |
275 | resultIn fo.dup(inf erenceCont ext.asInst Type(resul tInfo.pt)) ; | |
276 | check( tree, infe renceConte xt.asInstT ype(found) , ownkind, pendingRe sult); | |
277 | } | |
278 | }); | |
279 | } else { | |
280 | owntype = shouldCh eck ? | |
281 | resultIn fo.check(t ree, found ) : | |
282 | found; | |
283 | } | |
284 | if (tree != noCheckTre e) { | |
285 | tree.typ e = owntyp e; | |
286 | } | |
287 | re turn ownty pe; | |
288 | } | |
289 | ||
290 | /** Is given bla nk final v ariable as signable, i.e. in a scope wher e it | |
291 | * ma y be assig ned to eve n though i t is final ? | |
292 | * @p aram v The blan k final va riable. | |
293 | * @p aram env The curr ent enviro nment. | |
294 | */ | |
295 | boolea n isAssign ableAsBlan kFinal(Var Symbol v, Env<AttrCo ntext> env ) { | |
296 | Sy mbol owner = env.inf o.scope.ow ner; | |
297 | // owner refers to the innerm ost variab le, method or | |
298 | // initia lizer bloc k declarat ion at thi s point. | |
299 | re turn | |
300 | v.owner == owner | |
301 | || | |
302 | ((owner. name == na mes.init | | // i. e. we are in a const ructor | |
303 | owner. kind == VA R || // i. e. we are in a varia ble initia lizer | |
304 | (owner .flags() & BLOCK) != 0) // i. e. we are in an init ializer bl ock | |
305 | && | |
306 | v.owner == owner. owner | |
307 | && | |
308 | ((v.fla gs() & STA TIC) != 0) == Resolv e.isStatic (env)); | |
309 | } | |
310 | ||
311 | /** Ch eck that v ariable ca n be assig ned to. | |
312 | * @p aram pos The curr ent source code posi tion. | |
313 | * @p aram v The assi gned varai ble | |
314 | * @p aram base If the v ariable is referred to in a Se lect, the part | |
315 | * to the l eft of the `.', null otherwise . | |
316 | * @p aram env The curr ent enviro nment. | |
317 | */ | |
318 | void c heckAssign able(Diagn osticPosit ion pos, V arSymbol v , JCTree b ase, Env<A ttrContext > env) { | |
319 | if ((v.flags () & FINAL ) != 0 && | |
320 | ((v.flag s() & HASI NIT) != 0 | |
321 | || | |
322 | !((base == null | | | |
323 | (base .hasTag(ID ENT) && Tr eeInfo.nam e(base) == names._th is)) && | |
324 | isAss ignableAsB lankFinal( v, env)))) { | |
325 | if (v.is ResourceVa riable()) { //TWR re source | |
326 | log. error(pos, "try.reso urce.may.n ot.be.assi gned", v); | |
327 | } else { | |
328 | log. error(pos, "cant.ass ign.val.to .final.var ", v); | |
329 | } | |
330 | } | |
331 | } | |
332 | ||
333 | /** Do es tree re present a static ref erence to an identif ier? | |
334 | * It is assume d that tre e is eithe r a SELECT or an IDE NT. | |
335 | * We have to w eed out se lects from non-type names here . | |
336 | * @p aram tree The can didate tre e. | |
337 | */ | |
338 | boolea n isStatic Reference( JCTree tre e) { | |
339 | if (tree.has Tag(SELECT )) { | |
340 | Symbol l sym = Tree Info.symbo l(((JCFiel dAccess) t ree).selec ted); | |
341 | if (lsym == null | | lsym.kin d != TYP) { | |
342 | retu rn false; | |
343 | } | |
344 | } | |
345 | re turn true; | |
346 | } | |
347 | ||
348 | /** Is this symb ol a type? | |
349 | */ | |
350 | static boolean i sType(Symb ol sym) { | |
351 | re turn sym ! = null && sym.kind = = TYP; | |
352 | } | |
353 | ||
354 | /** Th e current `this' sym bol. | |
355 | * @p aram env The curr ent enviro nment. | |
356 | */ | |
357 | Symbol thisSym(D iagnosticP osition po s, Env<Att rContext> env) { | |
358 | re turn rs.re solveSelf( pos, env, env.enclCl ass.sym, n ames._this ); | |
359 | } | |
360 | ||
361 | /** At tribute a parsed ide ntifier. | |
362 | * @pa ram tree P arsed iden tifier nam e | |
363 | * @pa ram topLev el The top level to u se | |
364 | */ | |
365 | public Symbol at tribIdent( JCTree tre e, JCCompi lationUnit topLevel) { | |
366 | En v<AttrCont ext> local Env = ente r.topLevel Env(topLev el); | |
367 | lo calEnv.enc lClass = m ake.ClassD ef(make.Mo difiers(0) , | |
368 | syms.er rSymbol.na me, | |
369 | null, n ull, null, null); | |
370 | lo calEnv.enc lClass.sym = syms.er rSymbol; | |
371 | re turn tree. accept(ide ntAttribut er, localE nv); | |
372 | } | |
373 | // whe re | |
374 | pr ivate Tree Visitor<Sy mbol,Env<A ttrContext >> identAt tributer = new Ident Attributer (); | |
375 | pr ivate clas s IdentAtt ributer ex tends Simp leTreeVisi tor<Symbol ,Env<AttrC ontext>> { | |
376 | @Overrid e | |
377 | public S ymbol visi tMemberSel ect(Member SelectTree node, Env <AttrConte xt> env) { | |
378 | Symb ol site = visit(node .getExpres sion(), en v); | |
379 | if ( site.kind == ERR || site.kind == ABSENT_ TYP) | |
380 | return sit e; | |
381 | Name name = (N ame)node.g etIdentifi er(); | |
382 | if ( site.kind == PCK) { | |
383 | env.toplev el.packge = (Package Symbol)sit e; | |
384 | return rs. findIdentI nPackage(e nv, (TypeS ymbol)site , name, TY P | PCK); | |
385 | } el se { | |
386 | env.enclCl ass.sym = (ClassSymb ol)site; | |
387 | return rs. findMember Type(env, site.asTyp e(), name, (TypeSymb ol)site); | |
388 | } | |
389 | } | |
390 | ||
391 | @Overrid e | |
392 | public S ymbol visi tIdentifie r(Identifi erTree nod e, Env<Att rContext> env) { | |
393 | retu rn rs.find Ident(env, (Name)nod e.getName( ), TYP | P CK); | |
394 | } | |
395 | } | |
396 | ||
397 | public Type coer ce(Type et ype, Type ttype) { | |
398 | re turn cfold er.coerce( etype, tty pe); | |
399 | } | |
400 | ||
401 | public Type attr ibType(JCT ree node, TypeSymbol sym) { | |
402 | En v<AttrCont ext> env = typeEnvs. get(sym); | |
403 | En v<AttrCont ext> local Env = env. dup(node, env.info.d up()); | |
404 | re turn attri bTree(node , localEnv , unknownT ypeInfo); | |
405 | } | |
406 | ||
407 | public Type attr ibImportQu alifier(JC Import tre e, Env<Att rContext> env) { | |
408 | // Attribute qualifyin g package or class. | |
409 | JC FieldAcces s s = (JCF ieldAccess )tree.qual id; | |
410 | re turn attri bTree(s.se lected, | |
411 | env, | |
412 | new Res ultInfo(tr ee.staticI mport ? TY P : (TYP | PCK), | |
413 | Type.no Type)); | |
414 | } | |
415 | ||
416 | public Env<AttrC ontext> at tribExprTo Tree(JCTre e expr, En v<AttrCont ext> env, JCTree tre e) { | |
417 | br eakTree = tree; | |
418 | Ja vaFileObje ct prev = log.useSou rce(env.to plevel.sou rcefile); | |
419 | tr y { | |
420 | attribEx pr(expr, e nv); | |
421 | } catch (Bre akAttr b) { | |
422 | return b .env; | |
423 | } catch (Ass ertionErro r ae) { | |
424 | if (ae.g etCause() instanceof BreakAttr ) { | |
425 | retu rn ((Break Attr)(ae.g etCause()) ).env; | |
426 | } else { | |
427 | thro w ae; | |
428 | } | |
429 | } finally { | |
430 | breakTre e = null; | |
431 | log.useS ource(prev ); | |
432 | } | |
433 | re turn env; | |
434 | } | |
435 | ||
436 | public Env<AttrC ontext> at tribStatTo Tree(JCTre e stmt, En v<AttrCont ext> env, JCTree tre e) { | |
437 | br eakTree = tree; | |
438 | Ja vaFileObje ct prev = log.useSou rce(env.to plevel.sou rcefile); | |
439 | tr y { | |
440 | attribSt at(stmt, e nv); | |
441 | } catch (Bre akAttr b) { | |
442 | return b .env; | |
443 | } catch (Ass ertionErro r ae) { | |
444 | if (ae.g etCause() instanceof BreakAttr ) { | |
445 | retu rn ((Break Attr)(ae.g etCause()) ).env; | |
446 | } else { | |
447 | thro w ae; | |
448 | } | |
449 | } finally { | |
450 | breakTre e = null; | |
451 | log.useS ource(prev ); | |
452 | } | |
453 | re turn env; | |
454 | } | |
455 | ||
456 | privat e JCTree b reakTree = null; | |
457 | ||
458 | privat e static c lass Break Attr exten ds Runtime Exception { | |
459 | st atic final long seri alVersionU ID = -6924 7711304054 46405L; | |
460 | pr ivate Env< AttrContex t> env; | |
461 | pr ivate Brea kAttr(Env< AttrContex t> env) { | |
462 | this.env = env; | |
463 | } | |
464 | } | |
465 | ||
466 | class ResultInfo { | |
467 | fi nal int pk ind; | |
468 | fi nal Type p t; | |
469 | fi nal CheckC ontext che ckContext; | |
470 | ||
471 | Re sultInfo(i nt pkind, Type pt) { | |
472 | this(pki nd, pt, ch k.basicHan dler); | |
473 | } | |
474 | ||
475 | pr otected Re sultInfo(i nt pkind, Type pt, C heckContex t checkCon text) { | |
476 | this.pki nd = pkind ; | |
477 | this.pt = pt; | |
478 | this.che ckContext = checkCon text; | |
479 | } | |
480 | ||
481 | pr otected Ty pe check(f inal Diagn osticPosit ion pos, f inal Type found) { | |
482 | return c hk.checkTy pe(pos, fo und, pt, c heckContex t); | |
483 | } | |
484 | ||
485 | pr otected Re sultInfo d up(Type ne wPt) { | |
486 | return n ew ResultI nfo(pkind, newPt, ch eckContext ); | |
487 | } | |
488 | ||
489 | pr otected Re sultInfo d up(CheckCo ntext newC ontext) { | |
490 | return n ew ResultI nfo(pkind, pt, newCo ntext); | |
491 | } | |
492 | ||
493 | pr otected Re sultInfo d up(Type ne wPt, Check Context ne wContext) { | |
494 | return n ew ResultI nfo(pkind, newPt, ne wContext); | |
495 | } | |
496 | ||
497 | @O verride | |
498 | pu blic Strin g toString () { | |
499 | if (pt ! = null) { | |
500 | retu rn pt.toSt ring(); | |
501 | } else { | |
502 | retu rn ""; | |
503 | } | |
504 | } | |
505 | } | |
506 | ||
507 | class RecoveryIn fo extends ResultInf o { | |
508 | ||
509 | pu blic Recov eryInfo(fi nal Deferr edAttr.Def erredAttrC ontext def erredAttrC ontext) { | |
510 | super(Ki nds.VAL, T ype.recove ryType, ne w Check.Ne stedCheckC ontext(chk .basicHand ler) { | |
511 | @Ove rride | |
512 | publ ic Deferre dAttr.Defe rredAttrCo ntext defe rredAttrCo ntext() { | |
513 | return def erredAttrC ontext; | |
514 | } | |
515 | @Ove rride | |
516 | publ ic boolean compatibl e(Type fou nd, Type r eq, Warner warn) { | |
517 | return tru e; | |
518 | } | |
519 | @Ove rride | |
520 | publ ic void re port(Diagn osticPosit ion pos, J CDiagnosti c details) { | |
521 | chk.basicH andler.rep ort(pos, d etails); | |
522 | } | |
523 | }); | |
524 | } | |
525 | } | |
526 | ||
527 | final ResultInfo statInfo; | |
528 | final ResultInfo varInfo; | |
529 | final ResultInfo unknownAn yPolyInfo; | |
530 | final ResultInfo unknownEx prInfo; | |
531 | final ResultInfo unknownTy peInfo; | |
532 | final ResultInfo unknownTy peExprInfo ; | |
533 | final ResultInfo recoveryI nfo; | |
534 | ||
535 | Type p t() { | |
536 | re turn resul tInfo.pt; | |
537 | } | |
538 | ||
539 | int pk ind() { | |
540 | re turn resul tInfo.pkin d; | |
541 | } | |
542 | ||
543 | /* ******* ********** ********** ********** ********** ********** ********** ***** | |
544 | * Visitor methods | |
545 | ********* ********** ********** ********** ********** ********** ********** ****/ | |
546 | ||
547 | /** Vi sitor argu ment: the current en vironment. | |
548 | */ | |
549 | Env<At trContext> env; | |
550 | ||
551 | /** Vi sitor argu ment: the currently expected a ttribution result. | |
552 | */ | |
553 | Result Info resul tInfo; | |
554 | ||
555 | /** Vi sitor resu lt: the co mputed typ e. | |
556 | */ | |
557 | Type r esult; | |
558 | ||
559 | /** Sy nthetic tr ee to be u sed during 'fake' ch ecks. | |
560 | */ | |
561 | JCTree noCheckTr ee; | |
562 | ||
563 | /** Vi sitor meth od: attrib ute a tree , catching any compl etion fail ure | |
564 | * ex ceptions. Return the tree's ty pe. | |
565 | * | |
566 | * @p aram tree The tre e to be vi sited. | |
567 | * @p aram env The env ironment v isitor arg ument. | |
568 | * @p aram resul tInfo Th e result i nfo visito r argument . | |
569 | */ | |
570 | Type a ttribTree( JCTree tre e, Env<Att rContext> env, Resul tInfo resu ltInfo) { | |
571 | En v<AttrCont ext> prevE nv = this. env; | |
572 | Re sultInfo p revResult = this.res ultInfo; | |
573 | tr y { | |
574 | this.env = env; | |
575 | this.res ultInfo = resultInfo ; | |
576 | tree.acc ept(this); | |
577 | if (tree == breakT ree && | |
578 | resultInfo .checkCont ext.deferr edAttrCont ext().mode == AttrMo de.CHECK) { | |
579 | thro w new Brea kAttr(copy Env(env)); | |
580 | } | |
581 | return r esult; | |
582 | } catch (Com pletionFai lure ex) { | |
583 | tree.typ e = syms.e rrType; | |
584 | return c hk.complet ionError(t ree.pos(), ex); | |
585 | } finally { | |
586 | this.env = prevEnv ; | |
587 | this.res ultInfo = prevResult ; | |
588 | } | |
589 | } | |
590 | ||
591 | Env<At trContext> copyEnv(E nv<AttrCon text> env) { | |
592 | En v<AttrCont ext> newEn v = | |
593 | env. dup(env.tr ee, env.in fo.dup(cop yScope(env .info.scop e))); | |
594 | if (newEnv.o uter != nu ll) { | |
595 | newEnv.o uter = cop yEnv(newEn v.outer); | |
596 | } | |
597 | re turn newEn v; | |
598 | } | |
599 | ||
600 | Scope copyScope( Scope sc) { | |
601 | Sc ope newSco pe = new S cope(sc.ow ner); | |
602 | Li st<Symbol> elemsList = List.ni l(); | |
603 | wh ile (sc != null) { | |
604 | for (Sco pe.Entry e = sc.elem s ; e != n ull ; e = e.sibling) { | |
605 | elem sList = el emsList.pr epend(e.sy m); | |
606 | } | |
607 | sc = sc. next; | |
608 | } | |
609 | fo r (Symbol s : elemsL ist) { | |
610 | newScope .enter(s); | |
611 | } | |
612 | re turn newSc ope; | |
613 | } | |
614 | ||
615 | /** De rived visi tor method : attribut e an expre ssion tree . | |
616 | */ | |
617 | public Type attr ibExpr(JCT ree tree, Env<AttrCo ntext> env , Type pt) { | |
618 | re turn attri bTree(tree , env, new ResultInf o(VAL, !pt .hasTag(ER ROR) ? pt : Type.noT ype)); | |
619 | } | |
620 | ||
621 | /** De rived visi tor method : attribut e an expre ssion tree with | |
622 | * no constrain ts on the computed t ype. | |
623 | */ | |
624 | public Type attr ibExpr(JCT ree tree, Env<AttrCo ntext> env ) { | |
625 | re turn attri bTree(tree , env, unk nownExprIn fo); | |
626 | } | |
627 | ||
628 | /** De rived visi tor method : attribut e a type t ree. | |
629 | */ | |
630 | public Type attr ibType(JCT ree tree, Env<AttrCo ntext> env ) { | |
631 | Ty pe result = attribTy pe(tree, e nv, Type.n oType); | |
632 | re turn resul t; | |
633 | } | |
634 | ||
635 | /** De rived visi tor method : attribut e a type t ree. | |
636 | */ | |
637 | Type a ttribType( JCTree tre e, Env<Att rContext> env, Type pt) { | |
638 | Ty pe result = attribTr ee(tree, e nv, new Re sultInfo(T YP, pt)); | |
639 | re turn resul t; | |
640 | } | |
641 | ||
642 | /** De rived visi tor method : attribut e a statem ent or def inition tr ee. | |
643 | */ | |
644 | public Type attr ibStat(JCT ree tree, Env<AttrCo ntext> env ) { | |
645 | re turn attri bTree(tree , env, sta tInfo); | |
646 | } | |
647 | ||
648 | /** At tribute a list of ex pressions, returning a list of types. | |
649 | */ | |
650 | List<T ype> attri bExprs(Lis t<JCExpres sion> tree s, Env<Att rContext> env, Type pt) { | |
651 | Li stBuffer<T ype> ts = new ListBu ffer<Type> (); | |
652 | fo r (List<JC Expression > l = tree s; l.nonEm pty(); l = l.tail) | |
653 | ts.appen d(attribEx pr(l.head, env, pt)) ; | |
654 | re turn ts.to List(); | |
655 | } | |
656 | ||
657 | /** At tribute a list of st atements, returning nothing. | |
658 | */ | |
659 | <T ext ends JCTre e> void at tribStats( List<T> tr ees, Env<A ttrContext > env) { | |
660 | fo r (List<T> l = trees ; l.nonEmp ty(); l = l.tail) | |
661 | attribSt at(l.head, env); | |
662 | } | |
663 | ||
664 | /** At tribute th e argument s in a met hod call, returning the method kind. | |
665 | */ | |
666 | int at tribArgs(i nt initial Kind, List <JCExpress ion> trees , Env<Attr Context> e nv, ListBu ffer<Type> argtypes) { | |
667 | in t kind = i nitialKind ; | |
668 | fo r (JCExpre ssion arg : trees) { | |
669 | Type arg type; | |
670 | if (allo wPoly && d eferredAtt r.isDeferr ed(env, ar g)) { | |
671 | argt ype = defe rredAttr.n ew Deferre dType(arg, env); | |
672 | kind |= POLY; | |
673 | } else { | |
674 | argt ype = chk. checkNonVo id(arg, at tribTree(a rg, env, u nknownAnyP olyInfo)); | |
675 | } | |
676 | argtypes .append(ar gtype); | |
677 | } | |
678 | re turn kind; | |
679 | } | |
680 | ||
681 | /** At tribute a type argum ent list, returning a list of types. | |
682 | * Ca ller is re sponsible for callin g checkRef Types. | |
683 | */ | |
684 | List<T ype> attri bAnyTypes( List<JCExp ression> t rees, Env< AttrContex t> env) { | |
685 | Li stBuffer<T ype> argty pes = new ListBuffer <Type>(); | |
686 | fo r (List<JC Expression > l = tree s; l.nonEm pty(); l = l.tail) | |
687 | argtypes .append(at tribType(l .head, env )); | |
688 | re turn argty pes.toList (); | |
689 | } | |
690 | ||
691 | /** At tribute a type argum ent list, returning a list of types. | |
692 | * Ch eck that a ll the typ es are ref erences. | |
693 | */ | |
694 | List<T ype> attri bTypes(Lis t<JCExpres sion> tree s, Env<Att rContext> env) { | |
695 | Li st<Type> t ypes = att ribAnyType s(trees, e nv); | |
696 | re turn chk.c heckRefTyp es(trees, types); | |
697 | } | |
698 | ||
699 | /** | |
700 | * Att ribute typ e variable s (of gene ric classe s or metho ds). | |
701 | * Com pound type s are attr ibuted lat er in attr ibBounds. | |
702 | * @pa ram typara ms the typ e variable s to enter | |
703 | * @pa ram env the cur rent envir onment | |
704 | */ | |
705 | void a ttribTypeV ariables(L ist<JCType Parameter> typarams, Env<AttrC ontext> en v) { | |
706 | fo r (JCTypeP arameter t var : typa rams) { | |
707 | TypeVar a = (TypeV ar)tvar.ty pe; | |
708 | a.tsym.f lags_field |= UNATTR IBUTED; | |
709 | a.bound = Type.noT ype; | |
710 | if (!tva r.bounds.i sEmpty()) { | |
711 | List <Type> bou nds = List .of(attrib Type(tvar. bounds.hea d, env)); | |
712 | for (JCExpress ion bound : tvar.bou nds.tail) | |
713 | bounds = b ounds.prep end(attrib Type(bound , env)); | |
714 | type s.setBound s(a, bound s.reverse( )); | |
715 | } else { | |
716 | // i f no bound s are give n, assume a single b ound of | |
717 | // j ava.lang.O bject. | |
718 | type s.setBound s(a, List. of(syms.ob jectType)) ; | |
719 | } | |
720 | a.tsym.f lags_field &= ~UNATT RIBUTED; | |
721 | } | |
722 | fo r (JCTypeP arameter t var : typa rams) { | |
723 | chk.chec kNonCyclic (tvar.pos( ), (TypeVa r)tvar.typ e); | |
724 | } | |
725 | } | |
726 | ||
727 | /** | |
728 | * Att ribute the type refe rences in a list of annotation s. | |
729 | */ | |
730 | void a ttribAnnot ationTypes (List<JCAn notation> annotation s, | |
731 | Env<AttrC ontext> en v) { | |
732 | fo r (List<JC Annotation > al = ann otations; al.nonEmpt y(); al = al.tail) { | |
733 | JCAnnota tion a = a l.head; | |
734 | attribTy pe(a.annot ationType, env); | |
735 | } | |
736 | } | |
737 | ||
738 | /** | |
739 | * Att ribute a " lazy const ant value" . | |
740 | * @p aram env The env for t he const v alue | |
741 | * @p aram initi alizer The initializ er for the const val ue | |
742 | * @p aram type The expected type, or n ull | |
743 | * @s ee VarSymb ol#setLazy ConstValue | |
744 | */ | |
745 | public Object at tribLazyCo nstantValu e(Env<Attr Context> e nv, | |
746 | JC VariableDe cl variabl e, | |
747 | Ty pe type) { | |
748 | ||
749 | Di agnosticPo sition pre vLintPos | |
750 | = de ferredLint Handler.se tPos(varia ble.pos()) ; | |
751 | ||
752 | tr y { | |
753 | // Use n ull as sym bol to not attach th e type ann otation to any symbo l. | |
754 | // The i nitializer will late r also be visited an d then we' ll attach | |
755 | // to th e symbol. | |
756 | // This prevents h aving mult iple type annotation s, just be cause of | |
757 | // lazy constant v alue evalu ation. | |
758 | memberEn ter.typeAn notate(var iable.init , env, nul l, variabl e.pos()); | |
759 | annotate .flush(); | |
760 | Type ity pe = attri bExpr(vari able.init, env, type ); | |
761 | if (ityp e.constVal ue() != nu ll) { | |
762 | retu rn coerce( itype, typ e).constVa lue(); | |
763 | } else { | |
764 | retu rn null; | |
765 | } | |
766 | } finally { | |
767 | deferred LintHandle r.setPos(p revLintPos ); | |
768 | } | |
769 | } | |
770 | ||
771 | /** At tribute ty pe referen ce in an ` extends' o r `impleme nts' claus e. | |
772 | * Su pertypes o f anonymou s inner cl asses are usually al ready attr ibuted. | |
773 | * | |
774 | * @p aram tree The tre e making u p the type reference . | |
775 | * @p aram env The env ironment c urrent at the refere nce. | |
776 | * @p aram class Expected true if only a cl ass is exp ected here . | |
777 | * @p aram inter faceExpect ed true if only an i nterface i s expected here. | |
778 | */ | |
779 | Type a ttribBase( JCTree tre e, | |
780 | Env<AttrCo ntext> env , | |
781 | boolean cl assExpecte d, | |
782 | boolean in terfaceExp ected, | |
783 | boolean ch eckExtensi ble) { | |
784 | Ty pe t = tre e.type != null ? | |
785 | tree.typ e : | |
786 | attribTy pe(tree, e nv); | |
787 | re turn check Base(t, tr ee, env, c lassExpect ed, interf aceExpecte d, checkEx tensible); | |
788 | } | |
789 | Type c heckBase(T ype t, | |
790 | J CTree tree , | |
791 | E nv<AttrCon text> env, | |
792 | b oolean cla ssExpected , | |
793 | b oolean int erfaceExpe cted, | |
794 | b oolean che ckExtensib le) { | |
795 | if (t.tsym.i sAnonymous ()) { | |
796 | log.erro r(tree.pos (), "cant. inherit.fr om.anon"); | |
797 | return t ypes.creat eErrorType (t); | |
798 | } | |
799 | if (t.isErro neous()) | |
800 | return t ; | |
801 | if (t.hasTag (TYPEVAR) && !classE xpected && !interfac eExpected) { | |
802 | // check that type variable is already visible | |
803 | if (t.ge tUpperBoun d() == nul l) { | |
804 | log. error(tree .pos(), "i llegal.for ward.ref") ; | |
805 | retu rn types.c reateError Type(t); | |
806 | } | |
807 | } else { | |
808 | t = chk. checkClass Type(tree. pos(), t, checkExten sible|!all owGenerics ); | |
809 | } | |
810 | if (interfac eExpected && (t.tsym .flags() & INTERFACE ) == 0) { | |
811 | log.erro r(tree.pos (), "intf. expected.h ere"); | |
812 | // retur n errType is necessa ry since o therwise t here might | |
813 | // be un detected c ycles whic h cause at tribution to loop | |
814 | return t ypes.creat eErrorType (t); | |
815 | } else if (c heckExtens ible && | |
816 | c lassExpect ed && | |
817 | ( t.tsym.fla gs() & INT ERFACE) != 0) { | |
818 | log.erro r(tree.pos (), "no.in tf.expecte d.here"); | |
819 | return t ypes.creat eErrorType (t); | |
820 | } | |
821 | if (checkExt ensible && | |
822 | ((t.tsym .flags() & FINAL) != 0)) { | |
823 | log.erro r(tree.pos (), | |
824 | "cant.in herit.from .final", t .tsym); | |
825 | } | |
826 | ch k.checkNon Cyclic(tre e.pos(), t ); | |
827 | re turn t; | |
828 | } | |
829 | ||
830 | Type a ttribIdent AsEnumType (Env<AttrC ontext> en v, JCIdent id) { | |
831 | As sert.check ((env.encl Class.sym. flags() & ENUM) != 0 ); | |
832 | id .type = en v.info.sco pe.owner.t ype; | |
833 | id .sym = env .info.scop e.owner; | |
834 | re turn id.ty pe; | |
835 | } | |
836 | ||
837 | public void visi tClassDef( JCClassDec l tree) { | |
838 | // Local and anonymous classes h ave not be en entered yet, so w e need to | |
839 | // do it now . | |
840 | if ((env.inf o.scope.ow ner.kind & (VAR | MT H)) != 0) { | |
841 | enter.cl assEnter(t ree, env); | |
842 | } else { | |
843 | // If th is class d eclaration is part o f a class level anno tation, | |
844 | // as in @MyAnno(n ew Object( ) {}) clas s MyClass {}, enter it in | |
845 | // order to simpli fy later s teps and a llow for s ensible er ror | |
846 | // messa ges. | |
847 | if (env. tree.hasTa g(NEWCLASS ) && TreeI nfo.isInAn notation(e nv, tree)) | |
848 | ente r.classEnt er(tree, e nv); | |
849 | } | |
850 | ||
851 | Cl assSymbol c = tree.s ym; | |
852 | if (c == nul l) { | |
853 | // exit in case so mething dr astic went wrong dur ing enter. | |
854 | result = null; | |
855 | } else { | |
856 | // make sure class has been completed: | |
857 | c.comple te(); | |
858 | ||
859 | // If th is class a ppears as an anonymo us class | |
860 | // in a superclass construct or call wh ere | |
861 | // no ex plicit out er instanc e is given , | |
862 | // disab le implici t outer in stance fro m being pa ssed. | |
863 | // (This would be an illegal access to "this bef ore super" ). | |
864 | if (env. info.isSel fCall && | |
865 | env. tree.hasTa g(NEWCLASS ) && | |
866 | ((JC NewClass) env.tree). encl == nu ll) | |
867 | { | |
868 | c.fl ags_field |= NOOUTER THIS; | |
869 | } | |
870 | attribCl ass(tree.p os(), c); | |
871 | result = tree.type = c.type; | |
872 | } | |
873 | } | |
874 | ||
875 | public void visi tMethodDef (JCMethodD ecl tree) { | |
876 | Me thodSymbol m = tree. sym; | |
877 | bo olean isDe faultMetho d = (m.fla gs() & DEF AULT) != 0 ; | |
878 | ||
879 | Li nt lint = env.info.l int.augmen t(m); | |
880 | Li nt prevLin t = chk.se tLint(lint ); | |
881 | Me thodSymbol prevMetho d = chk.se tMethod(m) ; | |
882 | tr y { | |
883 | deferred LintHandle r.flush(tr ee.pos()); | |
884 | chk.chec kDeprecate dAnnotatio n(tree.pos (), m); | |
885 | ||
886 | ||
887 | // Creat e a new en vironment with local scope | |
888 | // for a ttributing the metho d. | |
889 | Env<Attr Context> l ocalEnv = memberEnte r.methodEn v(tree, en v); | |
890 | localEnv .info.lint = lint; | |
891 | ||
892 | attribSt ats(tree.t yparams, l ocalEnv); | |
893 | ||
894 | // If we override any other methods, c heck that we do so p roperly. | |
895 | // JLS ? ?? | |
896 | if (m.is Static()) { | |
897 | chk. checkHideC lashes(tre e.pos(), e nv.enclCla ss.type, m ); | |
898 | } else { | |
899 | chk. checkOverr ideClashes (tree.pos( ), env.enc lClass.typ e, m); | |
900 | } | |
901 | chk.chec kOverride( tree, m); | |
902 | ||
903 | if (isDe faultMetho d && types .overrides ObjectMeth od(m.enclC lass(), m) ) { | |
904 | log. error(tree , "default .overrides .object.me mber", m.n ame, Kinds .kindName( m.location ()), m.loc ation()); | |
905 | } | |
906 | ||
907 | // Enter all type parameters into the local meth od scope. | |
908 | for (Lis t<JCTypePa rameter> l = tree.ty params; l. nonEmpty() ; l = l.ta il) | |
909 | loca lEnv.info. scope.ente rIfAbsent( l.head.typ e.tsym); | |
910 | ||
911 | ClassSym bol owner = env.encl Class.sym; | |
912 | if ((own er.flags() & ANNOTAT ION) != 0 && | |
913 | tree .params.no nEmpty()) | |
914 | log. error(tree .params.he ad.pos(), | |
915 | "int f.annotati on.members .cant.have .params"); | |
916 | ||
917 | // Attri bute all v alue param eters. | |
918 | for (Lis t<JCVariab leDecl> l = tree.par ams; l.non Empty(); l = l.tail) { | |
919 | attr ibStat(l.h ead, local Env); | |
920 | } | |
921 | ||
922 | chk.chec kVarargsMe thodDecl(l ocalEnv, t ree); | |
923 | ||
924 | // Check that type parameter s are well -formed. | |
925 | chk.vali date(tree. typarams, localEnv); | |
926 | ||
927 | // Check that resu lt type is well-form ed. | |
928 | if (tree .restype ! = null && !tree.rest ype.type.h asTag(VOID )) | |
929 | chk. validate(t ree.restyp e, localEn v); | |
930 | ||
931 | // Check that rece iver type is well-fo rmed. | |
932 | if (tree .recvparam != null) { | |
933 | // U se a new e nvironment to check the receiv er paramet er. | |
934 | // O therwise I get "migh t not have been init ialized" e rrors. | |
935 | // I s there a better way ? | |
936 | Env< AttrContex t> newEnv = memberEn ter.method Env(tree, env); | |
937 | attr ibType(tre e.recvpara m, newEnv) ; | |
938 | chk. validate(t ree.recvpa ram, newEn v); | |
939 | } | |
940 | ||
941 | // annot ation meth od checks | |
942 | if ((own er.flags() & ANNOTAT ION) != 0) { | |
943 | // a nnotation method can not have t hrows clau se | |
944 | if ( tree.throw n.nonEmpty ()) { | |
945 | log.error( tree.throw n.head.pos (), | |
946 | "t hrows.not. allowed.in .intf.anno tation"); | |
947 | } | |
948 | // a nnotation method can not declar e type-par ameters | |
949 | if ( tree.typar ams.nonEmp ty()) { | |
950 | log.error( tree.typar ams.head.p os(), | |
951 | "i ntf.annota tion.membe rs.cant.ha ve.type.pa rams"); | |
952 | } | |
953 | // v alidate an notation m ethod's re turn type (could be an annotat ion type) | |
954 | chk. validateAn notationTy pe(tree.re stype); | |
955 | // e nsure that annotatio n method d oes not cl ash with m embers of Object/Ann otation | |
956 | chk. validateAn notationMe thod(tree. pos(), m); | |
957 | } | |
958 | ||
959 | for (Lis t<JCExpres sion> l = tree.throw n; l.nonEm pty(); l = l.tail) | |
960 | chk. checkType( l.head.pos (), l.head .type, sym s.throwabl eType); | |
961 | ||
962 | if (tree .body == n ull) { | |
963 | // E mpty bodie s are only allowed f or | |
964 | // a bstract, n ative, or interface methods, o r for meth ods | |
965 | // i n a retrof it signatu re class. | |
966 | if ( isDefaultM ethod || ( tree.sym.f lags() & ( ABSTRACT | NATIVE)) == 0 && | |
967 | !relax) | |
968 | log.error( tree.pos() , "missing .meth.body .or.decl.a bstract"); | |
969 | if ( tree.defau ltValue != null) { | |
970 | if ((owner .flags() & ANNOTATIO N) == 0) | |
971 | log.er ror(tree.p os(), | |
972 | "defau lt.allowed .in.intf.a nnotation. member"); | |
973 | } | |
974 | } else i f ((tree.s ym.flags() & ABSTRAC T) != 0 && !isDefaul tMethod) { | |
975 | if ( (owner.fla gs() & INT ERFACE) != 0) { | |
976 | log.error( tree.body. pos(), "in tf.meth.ca nt.have.bo dy"); | |
977 | } el se { | |
978 | log.error( tree.pos() , "abstrac t.meth.can t.have.bod y"); | |
979 | } | |
980 | } else i f ((tree.m ods.flags & NATIVE) != 0) { | |
981 | log. error(tree .pos(), "n ative.meth .cant.have .body"); | |
982 | } else { | |
983 | // A dd an impl icit super () call un less an ex plicit cal l to | |
984 | // s uper(...) or this(.. .) is give n | |
985 | // o r we are c ompiling c lass java. lang.Objec t. | |
986 | if ( tree.name == names.i nit && own er.type != syms.obje ctType) { | |
987 | JCBlock bo dy = tree. body; | |
988 | if (body.s tats.isEmp ty() || | |
989 | !TreeI nfo.isSelf Call(body. stats.head )) { | |
990 | body.s tats = bod y.stats. | |
991 | pr epend(memb erEnter.Su perCall(ma ke.at(body .pos), | |
992 | Li st.<Type>n il(), | |
993 | Li st.<JCVari ableDecl>n il(), | |
994 | fa lse)); | |
995 | } else if ((env.encl Class.sym. flags() & ENUM) != 0 && | |
996 | (tree.mod s.flags & GENERATEDC ONSTR) == 0 && | |
997 | TreeInfo. isSuperCal l(body.sta ts.head)) { | |
998 | // enu m construc tors are n ot allowed to call s uper | |
999 | // dir ectly, so make sure there aren 't any sup er calls | |
1000 | // in enum const ructors, e xcept in t he compile r | |
1001 | // gen erated one . | |
1002 | log.er ror(tree.b ody.stats. head.pos() , | |
1003 | "call. to.super.n ot.allowed .in.enum.c tor", | |
1004 | env.en clClass.sy m); | |
1005 | } | |
1006 | } | |
1007 | ||
1008 | // A ttribute a ll type an notations in the bod y | |
1009 | memb erEnter.ty peAnnotate (tree.body , localEnv , m, null) ; | |
1010 | anno tate.flush (); | |
1011 | ||
1012 | // A ttribute m ethod body . | |
1013 | attr ibStat(tre e.body, lo calEnv); | |
1014 | } | |
1015 | ||
1016 | localEnv .info.scop e.leave(); | |
1017 | result = tree.type = m.type; | |
1018 | } | |
1019 | fi nally { | |
1020 | chk.setL int(prevLi nt); | |
1021 | chk.setM ethod(prev Method); | |
1022 | } | |
1023 | } | |
1024 | ||
1025 | public void visi tVarDef(JC VariableDe cl tree) { | |
1026 | // Local var iables hav e not been entered y et, so we need to do it now: | |
1027 | if (env.info .scope.own er.kind == MTH) { | |
1028 | if (tree .sym != nu ll) { | |
1029 | // p arameters have alrea dy been en tered | |
1030 | env. info.scope .enter(tre e.sym); | |
1031 | } else { | |
1032 | try { | |
1033 | annotate.e nterStart( ); | |
1034 | memberEnte r.memberEn ter(tree, env); | |
1035 | } fi nally { | |
1036 | annotate.e nterDone() ; | |
1037 | } | |
1038 | } | |
1039 | } else { | |
1040 | if (tree .init != n ull) { | |
1041 | // F ield initi alizer exp ression ne ed to be e ntered. | |
1042 | memb erEnter.ty peAnnotate (tree.init , env, tre e.sym, tre e.pos()); | |
1043 | anno tate.flush (); | |
1044 | } | |
1045 | } | |
1046 | ||
1047 | Va rSymbol v = tree.sym ; | |
1048 | Li nt lint = env.info.l int.augmen t(v); | |
1049 | Li nt prevLin t = chk.se tLint(lint ); | |
1050 | ||
1051 | // Check tha t the vari able's dec lared type is well-f ormed. | |
1052 | bo olean isIm plicitLamb daParamete r = env.tr ee.hasTag( LAMBDA) && | |
1053 | ((JC Lambda)env .tree).par amKind == JCLambda.P arameterKi nd.IMPLICI T && | |
1054 | (tre e.sym.flag s() & PARA METER) != 0; | |
1055 | ch k.validate (tree.vart ype, env, !isImplici tLambdaPar ameter); | |
1056 | ||
1057 | tr y { | |
1058 | v.getCon stValue(); // ensure compile-t ime consta nt initial izer is ev aluated | |
1059 | deferred LintHandle r.flush(tr ee.pos()); | |
1060 | chk.chec kDeprecate dAnnotatio n(tree.pos (), v); | |
1061 | ||
1062 | if (tree .init != n ull) { | |
1063 | if ( (v.flags_f ield & FIN AL) == 0 | | | |
1064 | !memberEnt er.needsLa zyConstVal ue(tree.in it)) { | |
1065 | // Not a c ompile-tim e constant | |
1066 | // Attribu te initial izer in a new enviro nment | |
1067 | // with th e declared variable as owner. | |
1068 | // Check t hat initia lizer conf orms to va riable's d eclared ty pe. | |
1069 | Env<AttrCo ntext> ini tEnv = mem berEnter.i nitEnv(tre e, env); | |
1070 | initEnv.in fo.lint = lint; | |
1071 | // In orde r to catch self-refe rences, we set the v ariable's | |
1072 | // declara tion posit ion to max imal possi ble value, effective ly | |
1073 | // marking the varia ble as und efined. | |
1074 | initEnv.in fo.enclVar = v; | |
1075 | attribExpr (tree.init , initEnv, v.type); | |
1076 | } | |
1077 | } | |
1078 | result = tree.type = v.type; | |
1079 | } | |
1080 | fi nally { | |
1081 | chk.setL int(prevLi nt); | |
1082 | } | |
1083 | } | |
1084 | ||
1085 | public void visi tSkip(JCSk ip tree) { | |
1086 | re sult = nul l; | |
1087 | } | |
1088 | ||
1089 | public void visi tBlock(JCB lock tree) { | |
1090 | if (env.info .scope.own er.kind == TYP) { | |
1091 | // Block is a stat ic or inst ance initi alizer; | |
1092 | // let t he owner o f the envi ronment be a freshly | |
1093 | // creat ed BLOCK-m ethod. | |
1094 | Env<Attr Context> l ocalEnv = | |
1095 | env. dup(tree, env.info.d up(env.inf o.scope.du pUnshared( ))); | |
1096 | localEnv .info.scop e.owner = | |
1097 | new MethodSymb ol(tree.fl ags | BLOC K | | |
1098 | env.info.s cope.owner .flags() & STRICTFP, names.emp ty, null, | |
1099 | env.info.s cope.owner ); | |
1100 | if ((tre e.flags & STATIC) != 0) localE nv.info.st aticLevel+ +; | |
1101 | ||
1102 | // Attri bute all t ype annota tions in t he block | |
1103 | memberEn ter.typeAn notate(tre e, localEn v, localEn v.info.sco pe.owner, null); | |
1104 | annotate .flush(); | |
1105 | ||
1106 | { | |
1107 | // S tore init and clinit type anno tations wi th the Cla ssSymbol | |
1108 | // t o allow ou tput in Ge n.normaliz eDefs. | |
1109 | Clas sSymbol cs = (ClassS ymbol)env. info.scope .owner; | |
1110 | List <Attribute .TypeCompo und> tas = localEnv. info.scope .owner.get RawTypeAtt ributes(); | |
1111 | if ( (tree.flag s & STATIC ) != 0) { | |
1112 | cs.appendC lassInitTy peAttribut es(tas); | |
1113 | } el se { | |
1114 | cs.appendI nitTypeAtt ributes(ta s); | |
1115 | } | |
1116 | } | |
1117 | ||
1118 | attribSt ats(tree.s tats, loca lEnv); | |
1119 | } else { | |
1120 | // Creat e a new lo cal enviro nment with a local s cope. | |
1121 | Env<Attr Context> l ocalEnv = | |
1122 | env. dup(tree, env.info.d up(env.inf o.scope.du p())); | |
1123 | try { | |
1124 | attr ibStats(tr ee.stats, localEnv); | |
1125 | } finall y { | |
1126 | loca lEnv.info. scope.leav e(); | |
1127 | } | |
1128 | } | |
1129 | re sult = nul l; | |
1130 | } | |
1131 | ||
1132 | public void visi tDoLoop(JC DoWhileLoo p tree) { | |
1133 | at tribStat(t ree.body, env.dup(tr ee)); | |
1134 | at tribExpr(t ree.cond, env, syms. booleanTyp e); | |
1135 | re sult = nul l; | |
1136 | } | |
1137 | ||
1138 | public void visi tWhileLoop (JCWhileLo op tree) { | |
1139 | at tribExpr(t ree.cond, env, syms. booleanTyp e); | |
1140 | at tribStat(t ree.body, env.dup(tr ee)); | |
1141 | re sult = nul l; | |
1142 | } | |
1143 | ||
1144 | public void visi tForLoop(J CForLoop t ree) { | |
1145 | En v<AttrCont ext> loopE nv = | |
1146 | env.dup( env.tree, env.info.d up(env.inf o.scope.du p())); | |
1147 | tr y { | |
1148 | attribSt ats(tree.i nit, loopE nv); | |
1149 | if (tree .cond != n ull) attri bExpr(tree .cond, loo pEnv, syms .booleanTy pe); | |
1150 | loopEnv. tree = tre e; // befo re, we wer e not in l oop! | |
1151 | attribSt ats(tree.s tep, loopE nv); | |
1152 | attribSt at(tree.bo dy, loopEn v); | |
1153 | result = null; | |
1154 | } | |
1155 | fi nally { | |
1156 | loopEnv. info.scope .leave(); | |
1157 | } | |
1158 | } | |
1159 | ||
1160 | public void visi tForeachLo op(JCEnhan cedForLoop tree) { | |
1161 | En v<AttrCont ext> loopE nv = | |
1162 | env.dup( env.tree, env.info.d up(env.inf o.scope.du p())); | |
1163 | tr y { | |
1164 | //the Fo rmal Param eter of a for-each l oop is not in the sc ope when | |
1165 | //attrib uting the for-each e xpression; we mimick this by a ttributing | |
1166 | //the fo r-each exp ression fi rst (again st origina l scope). | |
1167 | Type exp rType = ty pes.cvarUp perBound(a ttribExpr( tree.expr, loopEnv)) ; | |
1168 | attribSt at(tree.va r, loopEnv ); | |
1169 | chk.chec kNonVoid(t ree.pos(), exprType) ; | |
1170 | Type ele mtype = ty pes.elemty pe(exprTyp e); // per haps expr is an arra y? | |
1171 | if (elem type == nu ll) { | |
1172 | // o r perhaps expr imple ments Iter able<T>? | |
1173 | Type base = ty pes.asSupe r(exprType , syms.ite rableType. tsym); | |
1174 | if ( base == nu ll) { | |
1175 | log.error( tree.expr. pos(), | |
1176 | "f oreach.not .applicabl e.to.type" , | |
1177 | ex prType, | |
1178 | di ags.fragme nt("type.r eq.array.o r.iterable ")); | |
1179 | elemtype = types.cre ateErrorTy pe(exprTyp e); | |
1180 | } el se { | |
1181 | List<Type> iterableP arams = ba se.allpara ms(); | |
1182 | elemtype = iterableP arams.isEm pty() | |
1183 | ? syms .objectTyp e | |
1184 | : type s.wildUppe rBound(ite rableParam s.head); | |
1185 | } | |
1186 | } | |
1187 | chk.chec kType(tree .expr.pos( ), elemtyp e, tree.va r.sym.type ); | |
1188 | loopEnv. tree = tre e; // befo re, we wer e not in l oop! | |
1189 | attribSt at(tree.bo dy, loopEn v); | |
1190 | result = null; | |
1191 | } | |
1192 | fi nally { | |
1193 | loopEnv. info.scope .leave(); | |
1194 | } | |
1195 | } | |
1196 | ||
1197 | public void visi tLabelled( JCLabeledS tatement t ree) { | |
1198 | // Check tha t label is not used in an encl osing stat ement | |
1199 | En v<AttrCont ext> env1 = env; | |
1200 | wh ile (env1 != null && !env1.tre e.hasTag(C LASSDEF)) { | |
1201 | if (env1 .tree.hasT ag(LABELLE D) && | |
1202 | ((JC LabeledSta tement) en v1.tree).l abel == tr ee.label) { | |
1203 | log. error(tree .pos(), "l abel.alrea dy.in.use" , | |
1204 | tree .label); | |
1205 | brea k; | |
1206 | } | |
1207 | env1 = e nv1.next; | |
1208 | } | |
1209 | ||
1210 | at tribStat(t ree.body, env.dup(tr ee)); | |
1211 | re sult = nul l; | |
1212 | } | |
1213 | ||
1214 | public void visi tSwitch(JC Switch tre e) { | |
1215 | Ty pe seltype = attribE xpr(tree.s elector, e nv); | |
1216 | ||
1217 | En v<AttrCont ext> switc hEnv = | |
1218 | env.dup( tree, env. info.dup(e nv.info.sc ope.dup()) ); | |
1219 | ||
1220 | tr y { | |
1221 | ||
1222 | boolean enumSwitch = | |
1223 | allo wEnums && | |
1224 | (sel type.tsym. flags() & Flags.ENUM ) != 0; | |
1225 | boolean stringSwit ch = false ; | |
1226 | if (type s.isSameTy pe(seltype , syms.str ingType)) { | |
1227 | if ( allowStrin gsInSwitch ) { | |
1228 | stringSwit ch = true; | |
1229 | } el se { | |
1230 | log.error( tree.selec tor.pos(), "string.s witch.not. supported. in.source" , sourceNa me); | |
1231 | } | |
1232 | } | |
1233 | if (!enu mSwitch && !stringSw itch) | |
1234 | selt ype = chk. checkType( tree.selec tor.pos(), seltype, syms.intTy pe); | |
1235 | ||
1236 | // Attri bute all c ases and | |
1237 | // check that ther e are no d uplicate c ase labels or defaul t clauses. | |
1238 | Set<Obje ct> labels = new Has hSet<Objec t>(); // T he set of case label s. | |
1239 | boolean hasDefault = false; // Is there a d efault lab el? | |
1240 | for (Lis t<JCCase> l = tree.c ases; l.no nEmpty(); l = l.tail ) { | |
1241 | JCCa se c = l.h ead; | |
1242 | Env< AttrContex t> caseEnv = | |
1243 | switchEnv. dup(c, env .info.dup( switchEnv. info.scope .dup())); | |
1244 | try { | |
1245 | if (c.pat != null) { | |
1246 | if (en umSwitch) { | |
1247 | Sy mbol sym = enumConst ant(c.pat, seltype); | |
1248 | if (sym == n ull) { | |
1249 | log.erro r(c.pat.po s(), "enum .label.mus t.be.unqua lified.enu m"); | |
1250 | } else if (! labels.add (sym)) { | |
1251 | log.erro r(c.pos(), "duplicat e.case.lab el"); | |
1252 | } | |
1253 | } else { | |
1254 | Ty pe pattype = attribE xpr(c.pat, switchEnv , seltype) ; | |
1255 | if (!pattype .hasTag(ER ROR)) { | |
1256 | if (patt ype.constV alue() == null) { | |
1257 | log. error(c.pa t.pos(), | |
1258 | (str ingSwitch ? "string. const.req" : "const. expr.req") ); | |
1259 | } else i f (labels. contains(p attype.con stValue()) ) { | |
1260 | log. error(c.po s(), "dupl icate.case .label"); | |
1261 | } else { | |
1262 | labe ls.add(pat type.const Value()); | |
1263 | } | |
1264 | } | |
1265 | } | |
1266 | } else if (hasDefaul t) { | |
1267 | log.er ror(c.pos( ), "duplic ate.defaul t.label"); | |
1268 | } else { | |
1269 | hasDef ault = tru e; | |
1270 | } | |
1271 | attribStat s(c.stats, caseEnv); | |
1272 | } fi nally { | |
1273 | caseEnv.in fo.scope.l eave(); | |
1274 | addVars(c. stats, swi tchEnv.inf o.scope); | |
1275 | } | |
1276 | } | |
1277 | ||
1278 | result = null; | |
1279 | } | |
1280 | fi nally { | |
1281 | switchEn v.info.sco pe.leave() ; | |
1282 | } | |
1283 | } | |
1284 | // whe re | |
1285 | /* * Add any variables defined in stats to the switch scope. */ | |
1286 | pr ivate stat ic void ad dVars(List <JCStateme nt> stats, Scope swi tchScope) { | |
1287 | for (;st ats.nonEmp ty(); stat s = stats. tail) { | |
1288 | JCTr ee stat = stats.head ; | |
1289 | if (stat.h asTag(
|
|
1290 | switchScop e.enter((( JCVariable Decl) stat ).sym); | |
1291 | } | |
1292 | } | |
1293 | // whe re | |
1294 | /** Re turn the s elected en umeration constant s ymbol, or null. */ | |
1295 | privat e Symbol e numConstan t(JCTree t ree, Type enumType) { | |
1296 | if (!tree.ha sTag(IDENT )) { | |
1297 | log.erro r(tree.pos (), "enum. label.must .be.unqual ified.enum "); | |
1298 | return s yms.errSym bol; | |
1299 | } | |
1300 | JC Ident iden t = (JCIde nt)tree; | |
1301 | Na me name = ident.name ; | |
1302 | fo r (Scope.E ntry e = e numType.ts ym.members ().lookup( name); | |
1303 | e.scope != null; e = e.next ()) { | |
1304 | if (e.sy m.kind == VAR) { | |
1305 | Symb ol s = ide nt.sym = e .sym; | |
1306 | ((Va rSymbol)s) .getConstV alue(); // ensure in itializer is evaluat ed | |
1307 | iden t.type = s .type; | |
1308 | retu rn ((s.fla gs_field & Flags.ENU M) == 0) | |
1309 | ? null : s ; | |
1310 | } | |
1311 | } | |
1312 | re turn null; | |
1313 | } | |
1314 | ||
1315 | public void visi tSynchroni zed(JCSync hronized t ree) { | |
1316 | ch k.checkRef Type(tree. pos(), att ribExpr(tr ee.lock, e nv)); | |
1317 | at tribStat(t ree.body, env); | |
1318 | re sult = nul l; | |
1319 | } | |
1320 | ||
1321 | public void visi tTry(JCTry tree) { | |
1322 | // Create a new local environmen t with a l ocal | |
1323 | En v<AttrCont ext> local Env = env. dup(tree, env.info.d up(env.inf o.scope.du p())); | |
1324 | tr y { | |
1325 | boolean isTryWithR esource = tree.resou rces.nonEm pty(); | |
1326 | // Creat e a nested environme nt for att ributing t he try blo ck if need ed | |
1327 | Env<Attr Context> t ryEnv = is TryWithRes ource ? | |
1328 | env. dup(tree, localEnv.i nfo.dup(lo calEnv.inf o.scope.du p())) : | |
1329 | loca lEnv; | |
1330 | try { | |
1331 | // A ttribute r esource de clarations | |
1332 | for (JCTree re source : t ree.resour ces) { | |
1333 | CheckConte xt twrCont ext = new Check.Nest edCheckCon text(resul tInfo.chec kContext) { | |
1334 | @Overr ide | |
1335 | public void repo rt(Diagnos ticPositio n pos, JCD iagnostic details) { | |
1336 | ch k.basicHan dler.repor t(pos, dia gs.fragmen t("try.not .applicabl e.to.type" , details) ); | |
1337 | } | |
1338 | }; | |
1339 | ResultInfo twrResult = new Res ultInfo(VA L, syms.au toCloseabl eType, twr Context); | |
1340 | if (resour ce.hasTag(
|
|
1341 | attrib Stat(resou rce, tryEn v); | |
1342 | twrRes ult.check( resource, resource.t ype); | |
1343 | ||
1344 | //chec k that res ource type cannot th row Interr uptedExcep tion | |
1345 | checkA utoCloseab le(resourc e.pos(), l ocalEnv, r esource.ty pe); | |
1346 | ||
1347 | VarSym bol var = ((JCVariab leDecl) re source).sy m; | |
1348 | var.se tData(Elem entKind.RE SOURCE_VAR IABLE); | |
1349 | } else { | |
1350 | attrib Tree(resou rce, tryEn v, twrResu lt); | |
1351 | } | |
1352 | } | |
1353 | // A ttribute b ody | |
1354 | attr ibStat(tre e.body, tr yEnv); | |
1355 | } finall y { | |
1356 | if ( isTryWithR esource) | |
1357 | tryEnv.inf o.scope.le ave(); | |
1358 | } | |
1359 | ||
1360 | // Attri bute catch clauses | |
1361 | for (Lis t<JCCatch> l = tree. catchers; l.nonEmpty (); l = l. tail) { | |
1362 | JCCa tch c = l. head; | |
1363 | Env< AttrContex t> catchEn v = | |
1364 | localEnv.d up(c, loca lEnv.info. dup(localE nv.info.sc ope.dup()) ); | |
1365 | try { | |
1366 | Type ctype = attribS tat(c.para m, catchEn v); | |
1367 | if (TreeIn fo.isMulti Catch(c)) { | |
1368 | //mult i-catch pa rameter is implicitl y marked a s final | |
1369 | c.para m.sym.flag s_field |= FINAL | U NION; | |
1370 | } | |
1371 | if (c.para m.sym.kind == Kinds. VAR) { | |
1372 | c.para m.sym.setD ata(Elemen tKind.EXCE PTION_PARA METER); | |
1373 | } | |
1374 | chk.checkT ype(c.para m.vartype. pos(), | |
1375 | chk.ch eckClassTy pe(c.param .vartype.p os(), ctyp e), | |
1376 | syms.t hrowableTy pe); | |
1377 | attribStat (c.body, c atchEnv); | |
1378 | } fi nally { | |
1379 | catchEnv.i nfo.scope. leave(); | |
1380 | } | |
1381 | } | |
1382 | ||
1383 | // Attri bute final izer | |
1384 | if (tree .finalizer != null) attribStat (tree.fina lizer, loc alEnv); | |
1385 | result = null; | |
1386 | } | |
1387 | fi nally { | |
1388 | localEnv .info.scop e.leave(); | |
1389 | } | |
1390 | } | |
1391 | ||
1392 | void c heckAutoCl oseable(Di agnosticPo sition pos , Env<Attr Context> e nv, Type r esource) { | |
1393 | if (!resourc e.isErrone ous() && | |
1394 | types.as Super(reso urce, syms .autoClose ableType.t sym) != nu ll && | |
1395 | !types.i sSameType( resource, syms.autoC loseableTy pe)) { // Don't emit warning f or AutoClo seable its elf | |
1396 | Symbol c lose = sym s.noSymbol ; | |
1397 | Log.Diag nosticHand ler discar dHandler = new Log.D iscardDiag nosticHand ler(log); | |
1398 | try { | |
1399 | clos e = rs.res olveQualif iedMethod( pos, | |
1400 | env, | |
1401 | resour ce, | |
1402 | names. close, | |
1403 | List.< Type>nil() , | |
1404 | List.< Type>nil() ); | |
1405 | } | |
1406 | finally { | |
1407 | log. popDiagnos ticHandler (discardHa ndler); | |
1408 | } | |
1409 | if (clos e.kind == MTH && | |
1410 | close.over rides(syms .autoClose ableClose, resource. tsym, type s, true) & & | |
1411 | chk.isHand led(syms.i nterrupted ExceptionT ype, types .memberTyp e(resource , close).g etThrownTy pes()) && | |
1412 | env.info.l int.isEnab led(LintCa tegory.TRY )) { | |
1413 | log. warning(Li ntCategory .TRY, pos, "try.reso urce.throw s.interrup ted.exc", resource); | |
1414 | } | |
1415 | } | |
1416 | } | |
1417 | ||
1418 | public void visi tCondition al(JCCondi tional tre e) { | |
1419 | Ty pe condtyp e = attrib Expr(tree. cond, env, syms.bool eanType); | |
1420 | ||
1421 | tr ee.polyKin d = (!allo wPoly || | |
1422 | pt() .hasTag(NO NE) && pt( ) != Type. recoveryTy pe || | |
1423 | isBo oleanOrNum eric(env, tree)) ? | |
1424 | Poly Kind.STAND ALONE : Po lyKind.POL Y; | |
1425 | ||
1426 | if (tree.pol yKind == P olyKind.PO LY && resu ltInfo.pt. hasTag(VOI D)) { | |
1427 | //cannot get here (i.e. it m eans we ar e returnin g from voi d method - which is already an error) | |
1428 | resultIn fo.checkCo ntext.repo rt(tree, d iags.fragm ent("condi tional.tar get.cant.b e.void")); | |
1429 | result = tree.type = types.c reateError Type(resul tInfo.pt); | |
1430 | return; | |
1431 | } | |
1432 | ||
1433 | Re sultInfo c ondInfo = tree.polyK ind == Pol yKind.STAN DALONE ? | |
1434 | unkn ownExprInf o : | |
1435 | resu ltInfo.dup (new Check .NestedChe ckContext( resultInfo .checkCont ext) { | |
1436 | //this wil l use encl osing chec k context to check c ompatibili ty of | |
1437 | //subexpre ssion agai nst target type; if we are in a method c heck conte xt, | |
1438 | //dependin g on wheth er boxing is allowed , we could have inco mpatibilit ies | |
1439 | @Override | |
1440 | public voi d report(D iagnosticP osition po s, JCDiagn ostic deta ils) { | |
1441 | enclos ingContext .report(po s, diags.f ragment("i ncompatibl e.type.in. conditiona l", detail s)); | |
1442 | } | |
1443 | }); | |
1444 | ||
1445 | Ty pe truetyp e = attrib Tree(tree. truepart, env, condI nfo); | |
1446 | Ty pe falsety pe = attri bTree(tree .falsepart , env, con dInfo); | |
1447 | ||
1448 | Ty pe owntype = (tree.p olyKind == PolyKind. STANDALONE ) ? condTy pe(tree, t ruetype, f alsetype) : pt(); | |
1449 | if (condtype .constValu e() != nul l && | |
1450 | true type.const Value() != null && | |
1451 | fals etype.cons tValue() ! = null && | |
1452 | !own type.hasTa g(NONE)) { | |
1453 | //consta nt folding | |
1454 | owntype = cfolder. coerce(con dtype.isTr ue() ? tru etype : fa lsetype, o wntype); | |
1455 | } | |
1456 | re sult = che ck(tree, o wntype, VA L, resultI nfo); | |
1457 | } | |
1458 | //wher e | |
1459 | pr ivate bool ean isBool eanOrNumer ic(Env<Att rContext> env, JCExp ression tr ee) { | |
1460 | switch ( tree.getTa g()) { | |
1461 | case LITERAL: return ((J CLiteral)t ree).typet ag.isSubRa ngeOf(DOUB LE) || | |
1462 | ((JCLitera l)tree).ty petag == B OOLEAN || | |
1463 | ((JCLitera l)tree).ty petag == B OT; | |
1464 | case LAMBDA: c ase REFERE NCE: retur n false; | |
1465 | case PARENS: r eturn isBo oleanOrNum eric(env, ((JCParens )tree).exp r); | |
1466 | case CONDEXPR: | |
1467 | JCConditio nal condTr ee = (JCCo nditional) tree; | |
1468 | return isB ooleanOrNu meric(env, condTree. truepart) && | |
1469 | is BooleanOrN umeric(env , condTree .falsepart ); | |
1470 | case APPLY: | |
1471 | JCMethodIn vocation s peculative MethodTree = | |
1472 | (J CMethodInv ocation)de ferredAttr .attribSpe culative(t ree, env, unknownExp rInfo); | |
1473 | Type ownty pe = TreeI nfo.symbol (speculati veMethodTr ee.meth).t ype.getRet urnType(); | |
1474 | return typ es.unboxed TypeOrType (owntype). isPrimitiv e(); | |
1475 | case NEWCLASS: | |
1476 | JCExpressi on classNa me = | |
1477 | re moveClassP arams.tran slate(((JC NewClass)t ree).clazz ); | |
1478 | JCExpressi on specula tiveNewCla ssTree = | |
1479 | (J CExpressio n)deferred Attr.attri bSpeculati ve(classNa me, env, u nknownType Info); | |
1480 | return typ es.unboxed TypeOrType (speculati veNewClass Tree.type) .isPrimiti ve(); | |
1481 | defa ult: | |
1482 | Type specu lativeType = deferre dAttr.attr ibSpeculat ive(tree, env, unkno wnExprInfo ).type; | |
1483 | speculativ eType = ty pes.unboxe dTypeOrTyp e(speculat iveType); | |
1484 | return spe culativeTy pe.isPrimi tive(); | |
1485 | } | |
1486 | } | |
1487 | // where | |
1488 | TreeTran slator rem oveClassPa rams = new TreeTrans lator() { | |
1489 | @Ove rride | |
1490 | publ ic void vi sitTypeApp ly(JCTypeA pply tree) { | |
1491 | result = t ranslate(t ree.clazz) ; | |
1492 | } | |
1493 | }; | |
1494 | ||
1495 | /* * Compute the type o f a condit ional expr ession, af ter | |
1496 | * checking that it e xists. Se e JLS 15.2 5. Does no t take int o | |
1497 | * account the specia l case whe re conditi on and bot h arms | |
1498 | * are cons tants. | |
1499 | * | |
1500 | * @param p os Th e source p osition to be used f or error | |
1501 | * di agnostics. | |
1502 | * @param t hentype Th e type of the expres sion's the n-part. | |
1503 | * @param e lsetype Th e type of the expres sion's els e-part. | |
1504 | * / | |
1505 | pr ivate Type condType( Diagnostic Position p os, | |
1506 | Type then type, Type elsetype) { | |
1507 | // If sa me type, t hat is the result | |
1508 | if (type s.isSameTy pe(thentyp e, elsetyp e)) | |
1509 | retu rn thentyp e.baseType (); | |
1510 | ||
1511 | Type the nUnboxed = (!allowBo xing || th entype.isP rimitive() ) | |
1512 | ? th entype : t ypes.unbox edType(the ntype); | |
1513 | Type els eUnboxed = (!allowBo xing || el setype.isP rimitive() ) | |
1514 | ? el setype : t ypes.unbox edType(els etype); | |
1515 | ||
1516 | // Other wise, if b oth arms c an be conv erted to a numeric | |
1517 | // type, return th e least nu meric type that fits both arms | |
1518 | // (i.e. return la rger of th e two, or return int if one | |
1519 | // arm i s short, t he other i s char). | |
1520 | if (then Unboxed.is Primitive( ) && elseU nboxed.isP rimitive() ) { | |
1521 | // I f one arm has an int eger subra nge type ( i.e., byte , | |
1522 | // s hort, or c har), and the other is an inte ger consta nt | |
1523 | // t hat fits i nto the su brange, re turn the s ubrange ty pe. | |
1524 | if ( thenUnboxe d.getTag() .isStrictS ubRangeOf( INT) && | |
1525 | elseUnboxe d.hasTag(I NT) && | |
1526 | types.isAs signable(e lseUnboxed , thenUnbo xed)) { | |
1527 | return the nUnboxed.b aseType(); | |
1528 | } | |
1529 | if ( elseUnboxe d.getTag() .isStrictS ubRangeOf( INT) && | |
1530 | thenUnboxe d.hasTag(I NT) && | |
1531 | types.isAs signable(t henUnboxed , elseUnbo xed)) { | |
1532 | return els eUnboxed.b aseType(); | |
1533 | } | |
1534 | ||
1535 | for (TypeTag t ag : primi tiveTags) { | |
1536 | Type candi date = sym s.typeOfTa g[tag.ordi nal()]; | |
1537 | if (types. isSubtype( thenUnboxe d, candida te) && | |
1538 | types. isSubtype( elseUnboxe d, candida te)) { | |
1539 | return candidate ; | |
1540 | } | |
1541 | } | |
1542 | } | |
1543 | ||
1544 | // Those were all the cases that could result in a primiti ve | |
1545 | if (allo wBoxing) { | |
1546 | if ( thentype.i sPrimitive ()) | |
1547 | thentype = types.box edClass(th entype).ty pe; | |
1548 | if ( elsetype.i sPrimitive ()) | |
1549 | elsetype = types.box edClass(el setype).ty pe; | |
1550 | } | |
1551 | ||
1552 | if (type s.isSubtyp e(thentype , elsetype )) | |
1553 | retu rn elsetyp e.baseType (); | |
1554 | if (type s.isSubtyp e(elsetype , thentype )) | |
1555 | retu rn thentyp e.baseType (); | |
1556 | ||
1557 | if (!all owBoxing | | thentype .hasTag(VO ID) || els etype.hasT ag(VOID)) { | |
1558 | log. error(pos, "neither. conditiona l.subtype" , | |
1559 | then type, else type); | |
1560 | retu rn thentyp e.baseType (); | |
1561 | } | |
1562 | ||
1563 | // both are known to be refe rence type s. The re sult is | |
1564 | // lub(t hentype,el setype). T his cannot fail, as it will | |
1565 | // alway s be possi ble to inf er "Object " if nothi ng better. | |
1566 | return t ypes.lub(t hentype.ba seType(), elsetype.b aseType()) ; | |
1567 | } | |
1568 | ||
1569 | final static Typ eTag[] pri mitiveTags = new Typ eTag[]{ | |
1570 | BY TE, | |
1571 | CH AR, | |
1572 | SH ORT, | |
1573 | IN T, | |
1574 | LO NG, | |
1575 | FL OAT, | |
1576 | DO UBLE, | |
1577 | BO OLEAN, | |
1578 | }; | |
1579 | ||
1580 | public void visi tIf(JCIf t ree) { | |
1581 | at tribExpr(t ree.cond, env, syms. booleanTyp e); | |
1582 | at tribStat(t ree.thenpa rt, env); | |
1583 | if (tree.els epart != n ull) | |
1584 | attribSt at(tree.el separt, en v); | |
1585 | ch k.checkEmp tyIf(tree) ; | |
1586 | re sult = nul l; | |
1587 | } | |
1588 | ||
1589 | public void visi tExec(JCEx pressionSt atement tr ee) { | |
1590 | // a fresh en vironment is require d for 292 inference to work pr operly --- | |
1591 | // see Infer. instantiat ePolymorph icSignatur eInstance( ) | |
1592 | En v<AttrCont ext> local Env = env. dup(tree); | |
1593 | at tribExpr(t ree.expr, localEnv); | |
1594 | re sult = nul l; | |
1595 | } | |
1596 | ||
1597 | public void visi tBreak(JCB reak tree) { | |
1598 | tr ee.target = findJump Target(tre e.pos(), t ree.getTag (), tree.l abel, env) ; | |
1599 | re sult = nul l; | |
1600 | } | |
1601 | ||
1602 | public void visi tContinue( JCContinue tree) { | |
1603 | tr ee.target = findJump Target(tre e.pos(), t ree.getTag (), tree.l abel, env) ; | |
1604 | re sult = nul l; | |
1605 | } | |
1606 | //wher e | |
1607 | /* * Return t he target of a break or contin ue stateme nt, if it exists, | |
1608 | * report a n error if not. | |
1609 | * Note: Th e target o f a labell ed break o r continue is the | |
1610 | * (non-lab elled) sta tement tre e referred to by the label, | |
1611 | * not the tree repre senting th e labelled statement itself. | |
1612 | * | |
1613 | * @param p os The position to be used for error diagnosti cs | |
1614 | * @param t ag The tag of th e jump sta tement. Th is is eith er | |
1615 | * Tre e.BREAK or Tree.CONT INUE. | |
1616 | * @param l abel The label of the jump s tatement, or null if no | |
1617 | * lab el is give n. | |
1618 | * @param e nv The environme nt current at the ju mp stateme nt. | |
1619 | * / | |
1620 | pr ivate JCTr ee findJum pTarget(Di agnosticPo sition pos , | |
1621 | JCTr ee.Tag tag , | |
1622 | Name label, | |
1623 | Env< AttrContex t> env) { | |
1624 | // Searc h environm ents outwa rds from t he point o f jump. | |
1625 | Env<Attr Context> e nv1 = env; | |
1626 | LOOP: | |
1627 | while (e nv1 != nul l) { | |
1628 | swit ch (env1.t ree.getTag ()) { | |
1629 | case LABEL LED: | |
1630 | JCLabe ledStateme nt labelle d = (JCLab eledStatem ent)env1.t ree; | |
1631 | if (la bel == lab elled.labe l) { | |
1632 | // If jump i s a contin ue, check that targe t is a loo p. | |
1633 | if (tag == C ONTINUE) { | |
1634 | if (!lab elled.body .hasTag(DO LOOP) && | |
1635 | !labelled. body.hasTa g(WHILELOO P) && | |
1636 | !labelled. body.hasTa g(FORLOOP) && | |
1637 | !labelled. body.hasTa g(FOREACHL OOP)) | |
1638 | log. error(pos, "not.loop .label", l abel); | |
1639 | // Found labelled statement target, no w go inwar ds | |
1640 | // to ne xt non-lab elled tree . | |
1641 | return T reeInfo.re ferencedSt atement(la belled); | |
1642 | } else { | |
1643 | return l abelled; | |
1644 | } | |
1645 | } | |
1646 | break; | |
1647 | case DOLOO P: | |
1648 | case WHILE LOOP: | |
1649 | case FORLO OP: | |
1650 | case FOREA CHLOOP: | |
1651 | if (la bel == nul l) return env1.tree; | |
1652 | break; | |
1653 | case SWITC H: | |
1654 | if (la bel == nul l && tag = = BREAK) r eturn env1 .tree; | |
1655 | break; | |
1656 | case LAMBD A: | |
1657 | case METHO DDEF: | |
1658 | case CLASS DEF: | |
1659 | break LOOP; | |
1660 | default: | |
1661 | } | |
1662 | env1 = env1.ne xt; | |
1663 | } | |
1664 | if (labe l != null) | |
1665 | log. error(pos, "undef.la bel", labe l); | |
1666 | else if (tag == CO NTINUE) | |
1667 | log. error(pos, "cont.out side.loop" ); | |
1668 | else | |
1669 | log. error(pos, "break.ou tside.swit ch.loop"); | |
1670 | return n ull; | |
1671 | } | |
1672 | ||
1673 | public void visi tReturn(JC Return tre e) { | |
1674 | // Check tha t there is an enclos ing method which is | |
1675 | // nested wi thin than the enclos ing class. | |
1676 | if (env.info .returnRes ult == nul l) { | |
1677 | log.erro r(tree.pos (), "ret.o utside.met h"); | |
1678 | } else { | |
1679 | // Attri bute retur n expressi on, if it exists, an d check th at | |
1680 | // it co nforms to result typ e of enclo sing metho d. | |
1681 | if (tree .expr != n ull) { | |
1682 | if ( env.info.r eturnResul t.pt.hasTa g(VOID)) { | |
1683 | env.info.r eturnResul t.checkCon text.repor t(tree.exp r.pos(), | |
1684 | diags.frag ment("unex pected.ret .val")); | |
1685 | } | |
1686 | attr ibTree(tre e.expr, en v, env.inf o.returnRe sult); | |
1687 | } else i f (!env.in fo.returnR esult.pt.h asTag(VOID ) && | |
1688 | !env.info. returnResu lt.pt.hasT ag(NONE)) { | |
1689 | env. info.retur nResult.ch eckContext .report(tr ee.pos(), | |
1690 | diags.frag ment("miss ing.ret.va l")); | |
1691 | } | |
1692 | } | |
1693 | re sult = nul l; | |
1694 | } | |
1695 | ||
1696 | public void visi tThrow(JCT hrow tree) { | |
1697 | Ty pe owntype = attribE xpr(tree.e xpr, env, allowPoly ? Type.noT ype : syms .throwable Type); | |
1698 | if (allowPol y) { | |
1699 | chk.chec kType(tree , owntype, syms.thro wableType) ; | |
1700 | } | |
1701 | re sult = nul l; | |
1702 | } | |
1703 | ||
1704 | public void visi tAssert(JC Assert tre e) { | |
1705 | at tribExpr(t ree.cond, env, syms. booleanTyp e); | |
1706 | if (tree.det ail != nul l) { | |
1707 | chk.chec kNonVoid(t ree.detail .pos(), at tribExpr(t ree.detail , env)); | |
1708 | } | |
1709 | re sult = nul l; | |
1710 | } | |
1711 | ||
1712 | /** V isitor met hod for me thod invoc ations. | |
1713 | * NO TE: The me thod part of an appl ication wi ll have in its type field | |
1714 | * the re turn type of the met hod, not t he method' s type its elf! | |
1715 | */ | |
1716 | public void visi tApply(JCM ethodInvoc ation tree ) { | |
1717 | // The local environme nt of a me thod appli cation is | |
1718 | // a new env ironment n ested in t he current one. | |
1719 | En v<AttrCont ext> local Env = env. dup(tree, env.info.d up()); | |
1720 | ||
1721 | // The types of the ac tual metho d argument s. | |
1722 | Li st<Type> a rgtypes; | |
1723 | ||
1724 | // The types of the ac tual metho d type arg uments. | |
1725 | Li st<Type> t ypeargtype s = null; | |
1726 | ||
1727 | Na me methNam e = TreeIn fo.name(tr ee.meth); | |
1728 | ||
1729 | bo olean isCo nstructorC all = | |
1730 | methName == names. _this || m ethName == names._su per; | |
1731 | ||
1732 | Li stBuffer<T ype> argty pesBuf = n ew ListBuf fer<>(); | |
1733 | if (isConstr uctorCall) { | |
1734 | // We ar e seeing a ...this(. ..) or ... super(...) call. | |
1735 | // Check that this is the fi rst statem ent in a c onstructor . | |
1736 | if (chec kFirstCons tructorSta t(tree, en v)) { | |
1737 | ||
1738 | // R ecord the fact | |
1739 | // t hat this i s a constr uctor call (using is SelfCall). | |
1740 | loca lEnv.info. isSelfCall = true; | |
1741 | ||
1742 | // A ttribute a rguments, yielding l ist of arg ument type s. | |
1743 | int kind = att ribArgs(MT H, tree.ar gs, localE nv, argtyp esBuf); | |
1744 | argt ypes = arg typesBuf.t oList(); | |
1745 | type argtypes = attribTyp es(tree.ty peargs, lo calEnv); | |
1746 | ||
1747 | // V ariable `s ite' point s to the c lass in wh ich the ca lled | |
1748 | // c onstructor is define d. | |
1749 | Type site = en v.enclClas s.sym.type ; | |
1750 | if ( methName = = names._s uper) { | |
1751 | if (site = = syms.obj ectType) { | |
1752 | log.er ror(tree.m eth.pos(), "no.super class", si te); | |
1753 | site = types.cre ateErrorTy pe(syms.ob jectType); | |
1754 | } else { | |
1755 | site = types.sup ertype(sit e); | |
1756 | } | |
1757 | } | |
1758 | ||
1759 | if ( site.hasTa g(CLASS)) { | |
1760 | Type encl = site.get EnclosingT ype(); | |
1761 | while (enc l != null && encl.ha sTag(TYPEV AR)) | |
1762 | encl = encl.getU pperBound( ); | |
1763 | if (encl.h asTag(CLAS S)) { | |
1764 | // we are callin g a nested class | |
1765 | ||
1766 | if (tr ee.meth.ha sTag(SELEC T)) { | |
1767 | JC Tree quali fier = ((J CFieldAcce ss) tree.m eth).selec ted; | |
1768 | ||
1769 | // We are se eing a pre fixed call , of the f orm | |
1770 | // <expr >.super(.. .). | |
1771 | // Check tha t the pref ix express ion confor ms | |
1772 | // to the ou ter instan ce type of the class . | |
1773 | ch k.checkRef Type(quali fier.pos() , | |
1774 | attri bExpr(qual ifier, loc alEnv, | |
1775 | encl )); | |
1776 | } else if (methN ame == nam es._super) { | |
1777 | // qualifier omitted; check for existence | |
1778 | // of an app ropriate i mplicit qu alifier. | |
1779 | rs .resolveIm plicitThis (tree.meth .pos(), | |
1780 | localEnv, site, tru e); | |
1781 | } | |
1782 | } else if (tree.meth .hasTag(SE LECT)) { | |
1783 | log.er ror(tree.m eth.pos(), "illegal. qual.not.i cls", | |
1784 | site.t sym); | |
1785 | } | |
1786 | ||
1787 | // if we'r e calling a java.lan g.Enum con structor, | |
1788 | // prefix the implic it String and int pa rameters | |
1789 | if (site.t sym == sym s.enumSym && allowEn ums) | |
1790 | argtyp es = argty pes.prepen d(syms.int Type).prep end(syms.s tringType) ; | |
1791 | ||
1792 | // Resolve the calle d construc tor under the assump tion | |
1793 | // that we are refer ring to a superclass instance of the | |
1794 | // current instance (JLS ???). | |
1795 | boolean se lectSuperP rev = loca lEnv.info. selectSupe r; | |
1796 | localEnv.i nfo.select Super = tr ue; | |
1797 | localEnv.i nfo.pendin gResolutio nPhase = n ull; | |
1798 | Symbol sym = rs.reso lveConstru ctor( | |
1799 | tree.m eth.pos(), localEnv, site, arg types, typ eargtypes) ; | |
1800 | localEnv.i nfo.select Super = se lectSuperP rev; | |
1801 | ||
1802 | // Set met hod symbol to resolv ed constru ctor... | |
1803 | TreeInfo.s etSymbol(t ree.meth, sym); | |
1804 | ||
1805 | // ...and check that it is leg al in the current co ntext. | |
1806 | // (this w ill also s et the tre e's type) | |
1807 | Type mpt = newMethod Template(r esultInfo. pt, argtyp es, typear gtypes); | |
1808 | checkId(tr ee.meth, s ite, sym, localEnv, new Result Info(kind, mpt)); | |
1809 | } | |
1810 | // O therwise, `site' is an error t ype and we do nothin g | |
1811 | } | |
1812 | result = tree.type = syms.vo idType; | |
1813 | } else { | |
1814 | // Other wise, we a re seeing a regular method cal l. | |
1815 | // Attri bute the a rguments, yielding l ist of arg ument type s, ... | |
1816 | int kind = attribA rgs(VAL, t ree.args, localEnv, argtypesBu f); | |
1817 | argtypes = argtype sBuf.toLis t(); | |
1818 | typeargt ypes = att ribAnyType s(tree.typ eargs, loc alEnv); | |
1819 | ||
1820 | // ... a nd attribu te the met hod using as a proto type a met hodtype | |
1821 | // whose formal ar gument typ es is exac tly the li st of actu al | |
1822 | // argum ents (this will also set the m ethod symb ol). | |
1823 | Type mpt = newMeth odTemplate (resultInf o.pt, argt ypes, type argtypes); | |
1824 | localEnv .info.pend ingResolut ionPhase = null; | |
1825 | Type mty pe = attri bTree(tree .meth, loc alEnv, new ResultInf o(kind, mp t, resultI nfo.checkC ontext)); | |
1826 | ||
1827 | // Compu te the res ult type. | |
1828 | Type res type = mty pe.getRetu rnType(); | |
1829 | if (rest ype.hasTag (WILDCARD) ) | |
1830 | thro w new Asse rtionError (mtype); | |
1831 | ||
1832 | Type qua lifier = ( tree.meth. hasTag(SEL ECT)) | |
1833 | ? ((JCFiel dAccess) t ree.meth). selected.t ype | |
1834 | : env.encl Class.sym. type; | |
1835 | restype = adjustMe thodReturn Type(quali fier, meth Name, argt ypes, rest ype); | |
1836 | ||
1837 | chk.chec kRefTypes( tree.typea rgs, typea rgtypes); | |
1838 | ||
1839 | // Check that valu e of resul ting type is admissi ble in the | |
1840 | // curre nt context . Also, c apture the return ty pe | |
1841 | result = check(tre e, capture (restype), VAL, resu ltInfo); | |
1842 | } | |
1843 | ch k.validate (tree.type args, loca lEnv); | |
1844 | } | |
1845 | //wher e | |
1846 | Ty pe adjustM ethodRetur nType(Type qualifier Type, Name methodNam e, List<Ty pe> argtyp es, Type r estype) { | |
1847 | if (allo wCovariant Returns && | |
1848 | methodName == names. clone && | |
1849 | type s.isArray( qualifierT ype)) { | |
1850 | // a s a specia l case, ar ray.clone( ) has a re sult that is | |
1851 | // t he same as static ty pe of the array bein g cloned | |
1852 | retu rn qualifi erType; | |
1853 | } else i f (allowGe nerics && | |
1854 | methodName == names. getClass & & | |
1855 | argtypes.i sEmpty()) { | |
1856 | // a s a specia l case, x. getClass() has type Class<? ex tends |X|> | |
1857 | retu rn new Cla ssType(res type.getEn closingTyp e(), | |
1858 | List.<Type >of(new Wi ldcardType (types.era sure(quali fierType), | |
1859 | BoundKi nd.EXTENDS , | |
1860 | syms.bo undClass)) , | |
1861 | restype.ts ym); | |
1862 | } else { | |
1863 | retu rn restype ; | |
1864 | } | |
1865 | } | |
1866 | ||
1867 | /* * Check th at given a pplication node appe ars as fir st stateme nt | |
1868 | * in a con structor c all. | |
1869 | * @param t ree The applicatio n node | |
1870 | * @param e nv The environmen t current at the app lication. | |
1871 | * / | |
1872 | bo olean chec kFirstCons tructorSta t(JCMethod Invocation tree, Env <AttrConte xt> env) { | |
1873 | JCMethod Decl enclM ethod = en v.enclMeth od; | |
1874 | if (encl Method != null && en clMethod.n ame == nam es.init) { | |
1875 | JCBl ock body = enclMetho d.body; | |
1876 | if ( body.stats .head.hasT ag(EXEC) & & | |
1877 | ((JCExpres sionStatem ent) body. stats.head ).expr == tree) | |
1878 | return tru e; | |
1879 | } | |
1880 | log.erro r(tree.pos (),"call.m ust.be.fir st.stmt.in .ctor", | |
1881 | TreeInfo .name(tree .meth)); | |
1882 | return f alse; | |
1883 | } | |
1884 | ||
1885 | /* * Obtain a method ty pe with gi ven argume nt types. | |
1886 | * / | |
1887 | Ty pe newMeth odTemplate (Type rest ype, List< Type> argt ypes, List <Type> typ eargtypes) { | |
1888 | MethodTy pe mt = ne w MethodTy pe(argtype s, restype , List.<Ty pe>nil(), syms.metho dClass); | |
1889 | return ( typeargtyp es == null ) ? mt : ( Type)new F orAll(type argtypes, mt); | |
1890 | } | |
1891 | ||
1892 | public void visi tNewClass( final JCNe wClass tre e) { | |
1893 | Ty pe owntype = types.c reateError Type(tree. type); | |
1894 | ||
1895 | // The local environme nt of a cl ass creati on is | |
1896 | // a new env ironment n ested in t he current one. | |
1897 | En v<AttrCont ext> local Env = env. dup(tree, env.info.d up()); | |
1898 | ||
1899 | // The anony mous inner class def inition of the new e xpression, | |
1900 | // if one is defined b y it. | |
1901 | JC ClassDecl cdef = tre e.def; | |
1902 | ||
1903 | // If enclos ing class is given, attribute it, and | |
1904 | // complete class name to be ful ly qualifi ed | |
1905 | JC Expression clazz = t ree.clazz; // Class field foll owing new | |
1906 | JC Expression clazzid; // Identi fier in cl ass field | |
1907 | JC AnnotatedT ype annocl azzid; // Annota ted type e nclosing c lazzid | |
1908 | an noclazzid = null; | |
1909 | ||
1910 | if (clazz.ha sTag(TYPEA PPLY)) { | |
1911 | clazzid = ((JCType Apply) cla zz).clazz; | |
1912 | if (claz zid.hasTag (ANNOTATED _TYPE)) { | |
1913 | anno clazzid = (JCAnnotat edType) cl azzid; | |
1914 | claz zid = anno clazzid.un derlyingTy pe; | |
1915 | } | |
1916 | } else { | |
1917 | if (claz z.hasTag(A NNOTATED_T YPE)) { | |
1918 | anno clazzid = (JCAnnotat edType) cl azz; | |
1919 | claz zid = anno clazzid.un derlyingTy pe; | |
1920 | } else { | |
1921 | claz zid = claz z; | |
1922 | } | |
1923 | } | |
1924 | ||
1925 | JC Expression clazzid1 = clazzid; // The sa me in full y qualifie d form | |
1926 | ||
1927 | if (tree.enc l != null) { | |
1928 | // We ar e seeing a qualified new, of t he form | |
1929 | // <e xpr>.new C <...> (.. .) ... | |
1930 | // In th is case, w e let claz z stand fo r the name of the | |
1931 | // alloc ated class C prefixe d with the type of t he qualifi er | |
1932 | // expre ssion, so that we ca n | |
1933 | // resol ve it with standard techniques later. I. e., if | |
1934 | // <expr > has type T, then < expr>.new C <...> (. ..) | |
1935 | // yield s a clazz T.C. | |
1936 | Type enc ltype = ch k.checkRef Type(tree. encl.pos() , | |
1937 | attri bExpr(tree .encl, env )); | |
1938 | // TODO 308: in <e xpr>.new C , do we al so want to add the t ype annota tions | |
1939 | // from expr to th e combined type, or not? Yes, do this. | |
1940 | clazzid1 = make.at (clazz.pos ).Select(m ake.Type(e ncltype), | |
1941 | ( (JCIdent) clazzid).n ame); | |
1942 | ||
1943 | EndPosTa ble endPos Table = th is.env.top level.endP ositions; | |
1944 | endPosTa ble.storeE nd(clazzid 1, tree.ge tEndPositi on(endPosT able)); | |
1945 | if (claz z.hasTag(A NNOTATED_T YPE)) { | |
1946 | JCAn notatedTyp e annoType = (JCAnno tatedType) clazz; | |
1947 | List <JCAnnotat ion> annos = annoTyp e.annotati ons; | |
1948 | ||
1949 | if ( annoType.u nderlyingT ype.hasTag (TYPEAPPLY )) { | |
1950 | clazzid1 = make.at(t ree.pos). | |
1951 | TypeAp ply(clazzi d1, | |
1952 | ((JCTy peApply) c lazz).argu ments); | |
1953 | } | |
1954 | ||
1955 | claz zid1 = mak e.at(tree. pos). | |
1956 | AnnotatedT ype(annos, clazzid1) ; | |
1957 | } else i f (clazz.h asTag(TYPE APPLY)) { | |
1958 | claz zid1 = mak e.at(tree. pos). | |
1959 | TypeApply( clazzid1, | |
1960 | ((JCTypeAp ply) clazz ).argument s); | |
1961 | } | |
1962 | ||
1963 | clazz = clazzid1; | |
1964 | } | |
1965 | ||
1966 | // Attribute clazz exp ression an d store | |
1967 | // symbol + type back into the a ttributed tree. | |
1968 | Ty pe clazzty pe = TreeI nfo.isEnum Init(env.t ree) ? | |
1969 | attribId entAsEnumT ype(env, ( JCIdent)cl azz) : | |
1970 | attribTy pe(clazz, env); | |
1971 | ||
1972 | cl azztype = chk.checkD iamond(tre e, clazzty pe); | |
1973 | ch k.validate (clazz, lo calEnv); | |
1974 | if (tree.enc l != null) { | |
1975 | // We ha ve to work in this c ase to sto re | |
1976 | // symbo l + type b ack into t he attribu ted tree. | |
1977 | tree.cla zz.type = clazztype; | |
1978 | TreeInfo .setSymbol (clazzid, TreeInfo.s ymbol(claz zid1)); | |
1979 | clazzid. type = ((J CIdent) cl azzid).sym .type; | |
1980 | if (anno clazzid != null) { | |
1981 | anno clazzid.ty pe = clazz id.type; | |
1982 | } | |
1983 | if (!cla zztype.isE rroneous() ) { | |
1984 | if ( cdef != nu ll && claz ztype.tsym .isInterfa ce()) { | |
1985 | log.error( tree.encl. pos(), "an on.class.i mpl.intf.n o.qual.for .new"); | |
1986 | } el se if (cla zztype.tsy m.isStatic ()) { | |
1987 | log.error( tree.encl. pos(), "qu alified.ne w.of.stati c.class", clazztype. tsym); | |
1988 | } | |
1989 | } | |
1990 | } else if (! clazztype. tsym.isInt erface() & & | |
1991 | c lazztype.g etEnclosin gType().ha sTag(CLASS )) { | |
1992 | // Check for the e xistence o f an aprop os outer i nstance | |
1993 | rs.resol veImplicit This(tree. pos(), env , clazztyp e); | |
1994 | } | |
1995 | ||
1996 | // Attribute construct or argumen ts. | |
1997 | Li stBuffer<T ype> argty pesBuf = n ew ListBuf fer<>(); | |
1998 | in t pkind = attribArgs (VAL, tree .args, loc alEnv, arg typesBuf); | |
1999 | Li st<Type> a rgtypes = argtypesBu f.toList() ; | |
2000 | Li st<Type> t ypeargtype s = attrib Types(tree .typeargs, localEnv) ; | |
2001 | ||
2002 | // If we hav e made no mistakes i n the clas s type... | |
2003 | if (clazztyp e.hasTag(C LASS)) { | |
2004 | // Enums may not b e instanti ated excep t implicit ly | |
2005 | if (allo wEnums && | |
2006 | (cla zztype.tsy m.flags_fi eld&Flags. ENUM) != 0 && | |
2007 | (!env.tree .hasTag(
|
|
2008 | ((( JCVariable Decl) env. tree).mods .flags&Fla gs.ENUM) = = 0 || | |
2009 | ((J CVariableD ecl) env.t ree).init != tree)) | |
2010 | log. error(tree .pos(), "e num.cant.b e.instanti ated"); | |
2011 | // Check that clas s is not a bstract | |
2012 | if (cdef == null & & | |
2013 | (cla zztype.tsy m.flags() & (ABSTRAC T | INTERF ACE)) != 0 ) { | |
2014 | log. error(tree .pos(), "a bstract.ca nt.be.inst antiated", | |
2015 | claz ztype.tsym ); | |
2016 | } else i f (cdef != null && c lazztype.t sym.isInte rface()) { | |
2017 | // C heck that no constru ctor argum ents are g iven to | |
2018 | // a nonymous c lasses imp lementing an interfa ce | |
2019 | if ( !argtypes. isEmpty()) | |
2020 | log.error( tree.args. head.pos() , "anon.cl ass.impl.i ntf.no.arg s"); | |
2021 | ||
2022 | if ( !typeargty pes.isEmpt y()) | |
2023 | log.error( tree.typea rgs.head.p os(), "ano n.class.im pl.intf.no .typeargs" ); | |
2024 | ||
2025 | // E rror recov ery: prete nd no argu ments were supplied. | |
2026 | argt ypes = Lis t.nil(); | |
2027 | type argtypes = List.nil( ); | |
2028 | } else i f (TreeInf o.isDiamon d(tree)) { | |
2029 | Clas sType site = new Cla ssType(cla zztype.get EnclosingT ype(), | |
2030 | cl azztype.ts ym.type.ge tTypeArgum ents(), | |
2031 | cl azztype.ts ym); | |
2032 | ||
2033 | Env< AttrContex t> diamond Env = loca lEnv.dup(t ree); | |
2034 | diam ondEnv.inf o.selectSu per = cdef != null; | |
2035 | diam ondEnv.inf o.pendingR esolutionP hase = nul l; | |
2036 | ||
2037 | //if the type of the ins tance crea tion expre ssion is a class typ e | |
2038 | //ap ply method resolutio n inferenc e (JLS 15. 12.2.7). T he return type | |
2039 | //of the resol ved constr uctor will be a part ially inst antiated t ype | |
2040 | Symb ol constru ctor = rs. resolveDia mond(tree. pos(), | |
2041 | di amondEnv, | |
2042 | si te, | |
2043 | ar gtypes, | |
2044 | ty peargtypes ); | |
2045 | tree .construct or = const ructor.bas eSymbol(); | |
2046 | ||
2047 | fina l TypeSymb ol csym = clazztype. tsym; | |
2048 | Resu ltInfo dia mondResult = new Res ultInfo(pk ind, newMe thodTempla te(resultI nfo.pt, ar gtypes, ty peargtypes ), new Che ck.NestedC heckContex t(resultIn fo.checkCo ntext) { | |
2049 | @Override | |
2050 | public voi d report(D iagnosticP osition _u nused, JCD iagnostic details) { | |
2051 | enclos ingContext .report(tr ee.clazz, | |
2052 | diags.fr agment("ca nt.apply.d iamond.1", diags.fra gment("dia mond", csy m), detail s)); | |
2053 | } | |
2054 | }); | |
2055 | Type construct orType = t ree.constr uctorType = types.cr eateErrorT ype(clazzt ype); | |
2056 | cons tructorTyp e = checkI d(noCheckT ree, site, | |
2057 | constr uctor, | |
2058 | diamon dEnv, | |
2059 | diamon dResult); | |
2060 | ||
2061 | tree .clazz.typ e = types. createErro rType(claz ztype); | |
2062 | if ( !construct orType.isE rroneous() ) { | |
2063 | tree.clazz .type = cl azztype = constructo rType.getR eturnType( ); | |
2064 | tree.const ructorType = types.c reateMetho dTypeWithR eturn(cons tructorTyp e, syms.vo idType); | |
2065 | } | |
2066 | claz ztype = ch k.checkCla ssType(tre e.clazz, t ree.clazz. type, true ); | |
2067 | } | |
2068 | ||
2069 | // Resol ve the cal led constr uctor unde r the assu mption | |
2070 | // that we are ref erring to a supercla ss instanc e of the | |
2071 | // curre nt instanc e (JLS ??? ). | |
2072 | else { | |
2073 | //th e followin g code alt ers some o f the fiel ds in the current | |
2074 | //At trContext - hence, t he current context m ust be dup 'ed in | |
2075 | //or der to avo id downstr eam failur es | |
2076 | Env< AttrContex t> rsEnv = localEnv. dup(tree); | |
2077 | rsEn v.info.sel ectSuper = cdef != n ull; | |
2078 | rsEn v.info.pen dingResolu tionPhase = null; | |
2079 | tree .construct or = rs.re solveConst ructor( | |
2080 | tree.pos() , rsEnv, c lazztype, argtypes, typeargtyp es); | |
2081 | if ( cdef == nu ll) { //do not check twice! | |
2082 | tree.const ructorType = checkId (noCheckTr ee, | |
2083 | cl azztype, | |
2084 | tr ee.constru ctor, | |
2085 | rs Env, | |
2086 | ne w ResultIn fo(pkind, newMethodT emplate(sy ms.voidTyp e, argtype s, typearg types))); | |
2087 | if (rsEnv. info.lastR esolveVara rgs()) | |
2088 | Assert .check(tre e.construc torType.is Erroneous( ) || tree. varargsEle ment != nu ll); | |
2089 | } | |
2090 | if ( cdef == nu ll && | |
2091 | !clazz type.isErr oneous() & & | |
2092 | clazzt ype.getTyp eArguments ().nonEmpt y() && | |
2093 | findDi amonds) { | |
2094 | findDiamon d(localEnv , tree, cl azztype); | |
2095 | } | |
2096 | } | |
2097 | ||
2098 | if (cdef != null) { | |
2099 | // W e are seei ng an anon ymous clas s instance creation. | |
2100 | // I n this cas e, the cla ss instanc e creation | |
2101 | // e xpression | |
2102 | // | |
2103 | // E.new <t ypeargs1>C <typargs2> (args) { . .. } | |
2104 | // | |
2105 | // i s represen ted intern ally as | |
2106 | // | |
2107 | // E . new <typeargs1 >C<typargs 2>(args) ( class <em pty-name> { ... } ) . | |
2108 | // | |
2109 | // T his expres sion is th en *transf ormed* as follows: | |
2110 | // | |
2111 | // ( 1) add a S TATIC flag to the cl ass defini tion | |
2112 | // if the current en vironment is static | |
2113 | // ( 2) add an extends or implement s clause | |
2114 | // ( 3) add a c onstructor . | |
2115 | // | |
2116 | // F or instanc e, if C is a class, and ET is the type o f E, | |
2117 | // t he express ion | |
2118 | // | |
2119 | // E.new <t ypeargs1>C <typargs2> (args) { . .. } | |
2120 | // | |
2121 | // i s translat ed to (whe re X is a fresh name and typar ams is the | |
2122 | // p arameter l ist of the super con structor): | |
2123 | // | |
2124 | // new <type args1>X(<* nullchk*>E , args) wh ere | |
2125 | // X exten ds C<typar gs2> { | |
2126 | // <typa rams> X(ET e, args) { | |
2127 | // e.< typeargs1> super(args ) | |
2128 | // } | |
2129 | // ... | |
2130 | // } | |
2131 | if ( Resolve.is Static(env )) cdef.mo ds.flags | = STATIC; | |
2132 | ||
2133 | if ( clazztype. tsym.isInt erface()) { | |
2134 | cdef.imple menting = List.of(cl azz); | |
2135 | } el se { | |
2136 | cdef.exten ding = cla zz; | |
2137 | } | |
2138 | ||
2139 | if ( resultInfo .checkCont ext.deferr edAttrCont ext().mode == Deferr edAttr.Att rMode.CHEC K && | |
2140 | isSerializ able(clazz type)) { | |
2141 | localEnv.i nfo.isSeri alizable = true; | |
2142 | } | |
2143 | ||
2144 | attr ibStat(cde f, localEn v); | |
2145 | ||
2146 | chec kLambdaCan didate(tre e, cdef.sy m, clazzty pe); | |
2147 | ||
2148 | // I f an outer instance is given, | |
2149 | // p refix it t o the cons tructor ar guments | |
2150 | // a nd delete it from th e new expr ession | |
2151 | if ( tree.encl != null && !clazztyp e.tsym.isI nterface() ) { | |
2152 | tree.args = tree.arg s.prepend( makeNullCh eck(tree.e ncl)); | |
2153 | argtypes = argtypes. prepend(tr ee.encl.ty pe); | |
2154 | tree.encl = null; | |
2155 | } | |
2156 | ||
2157 | // R eassign cl azztype an d recomput e construc tor. | |
2158 | claz ztype = cd ef.sym.typ e; | |
2159 | Symb ol sym = t ree.constr uctor = rs .resolveCo nstructor( | |
2160 | tree.pos() , localEnv , clazztyp e, argtype s, typearg types); | |
2161 | Asse rt.check(s ym.kind < AMBIGUOUS) ; | |
2162 | tree .construct or = sym; | |
2163 | tree .construct orType = c heckId(noC heckTree, | |
2164 | clazztype, | |
2165 | tree.const ructor, | |
2166 | localEnv, | |
2167 | new Result Info(pkind , newMetho dTemplate( syms.voidT ype, argty pes, typea rgtypes))) ; | |
2168 | } | |
2169 | ||
2170 | if (tree .construct or != null && tree.c onstructor .kind == M TH) | |
2171 | ownt ype = claz ztype; | |
2172 | } | |
2173 | re sult = che ck(tree, o wntype, VA L, resultI nfo); | |
2174 | In ferenceCon text infer enceContex t = result Info.check Context.in ferenceCon text(); | |
2175 | if (tree.con structorTy pe != null && infere nceContext .free(tree .construct orType)) { | |
2176 | //we nee d to wait for infere nce to fin ish and th en replace inference vars in t he constru ctor type | |
2177 | inferenc eContext.a ddFreeType Listener(L ist.of(tre e.construc torType), | |
2178 | new FreeTy peListener () { | |
2179 | @Overr ide | |
2180 | public void type sInferred( InferenceC ontext ins tantiatedC ontext) { | |
2181 | tr ee.constru ctorType = instantia tedContext .asInstTyp e(tree.con structorTy pe); | |
2182 | } | |
2183 | }); | |
2184 | } | |
2185 | ch k.validate (tree.type args, loca lEnv); | |
2186 | } | |
2187 | //wher e | |
2188 | vo id findDia mond(Env<A ttrContext > env, JCN ewClass tr ee, Type c lazztype) { | |
2189 | JCTypeAp ply ta = ( JCTypeAppl y)tree.cla zz; | |
2190 | List<JCE xpression> prevTypea rgs = ta.a rguments; | |
2191 | try { | |
2192 | //cr eate a 'fa ke' diamon d AST node by removi ng type-ar gument tre es | |
2193 | ta.a rguments = List.nil( ); | |
2194 | Resu ltInfo fin dDiamondRe sult = new ResultInf o(VAL, | |
2195 | result Info.check Context.in ferenceCon text().fre e(resultIn fo.pt) ? T ype.noType : pt()); | |
2196 | Type inferred = deferred Attr.attri bSpeculati ve(tree, e nv, findDi amondResul t).type; | |
2197 | Type polyPt = allowPoly ? | |
2198 | syms.o bjectType : | |
2199 | clazzt ype; | |
2200 | if ( !inferred. isErroneou s() && | |
2201 | (allowPoly && pt() = = Infer.an yPoly ? | |
2202 | types. isSameType (inferred, clazztype ) : | |
2203 | types. isAssignab le(inferre d, pt().ha sTag(NONE) ? polyPt : pt(), ty pes.noWarn ings))) { | |
2204 | String key = types.i sSameType( clazztype, inferred) ? | |
2205 | "diamo nd.redunda nt.args" : | |
2206 | "diamo nd.redunda nt.args.1" ; | |
2207 | log.warnin g(tree.cla zz.pos(), key, clazz type, infe rred); | |
2208 | } | |
2209 | } finall y { | |
2210 | ta.a rguments = prevTypea rgs; | |
2211 | } | |
2212 | } | |
2213 | ||
2214 | private void check LambdaCand idate(JCNe wClass tre e, ClassSy mbol csym, Type claz ztype) { | |
2215 | if ( allowLambd a && | |
2216 | identi fyLambdaCa ndidate && | |
2217 | clazzt ype.hasTag (CLASS) && | |
2218 | !pt(). hasTag(NON E) && | |
2219 | types. isFunction alInterfac e(clazztyp e.tsym)) { | |
2220 | Symbol des criptor = types.find Descriptor Symbol(cla zztype.tsy m); | |
2221 | int count = 0; | |
2222 | boolean fo und = fals e; | |
2223 | for (Symbo l sym : cs ym.members ().getElem ents()) { | |
2224 | if ((s ym.flags() & SYNTHET IC) != 0 | | | |
2225 | sym.isCo nstructor( )) continu e; | |
2226 | count+ +; | |
2227 | if (sy m.kind != MTH || | |
2228 | !sym.nam e.equals(d escriptor. name)) con tinue; | |
2229 | Type m type = typ es.memberT ype(clazzt ype, sym); | |
2230 | if (ty pes.overri deEquivale nt(mtype, types.memb erType(cla zztype, de scriptor)) ) { | |
2231 | fo und = true ; | |
2232 | } | |
2233 | } | |
2234 | if (found && count = = 1) { | |
2235 | log.no te(tree.de f, "potent ial.lambda .found"); | |
2236 | } | |
2237 | } | |
2238 | } | |
2239 | ||
2240 | /** Ma ke an attr ibuted nul l check tr ee. | |
2241 | */ | |
2242 | public JCExpress ion makeNu llCheck(JC Expression arg) { | |
2243 | // optimizat ion: X.thi s is never null; ski p null che ck | |
2244 | Na me name = TreeInfo.n ame(arg); | |
2245 | if (name == names._thi s || name == names._ super) ret urn arg; | |
2246 | ||
2247 | JC Tree.Tag o ptag = NUL LCHK; | |
2248 | JC Unary tree = make.at (arg.pos). Unary(opta g, arg); | |
2249 | tr ee.operato r = syms.n ullcheck; | |
2250 | tr ee.type = arg.type; | |
2251 | re turn tree; | |
2252 | } | |
2253 | ||
2254 | public void visi tNewArray( JCNewArray tree) { | |
2255 | Ty pe owntype = types.c reateError Type(tree. type); | |
2256 | En v<AttrCont ext> local Env = env. dup(tree); | |
2257 | Ty pe elemtyp e; | |
2258 | if (tree.ele mtype != n ull) { | |
2259 | elemtype = attribT ype(tree.e lemtype, l ocalEnv); | |
2260 | chk.vali date(tree. elemtype, localEnv); | |
2261 | owntype = elemtype ; | |
2262 | for (Lis t<JCExpres sion> l = tree.dims; l.nonEmpt y(); l = l .tail) { | |
2263 | attr ibExpr(l.h ead, local Env, syms. intType); | |
2264 | ownt ype = new ArrayType( owntype, s yms.arrayC lass); | |
2265 | } | |
2266 | } else { | |
2267 | // we ar e seeing a n untyped aggregate { ... } | |
2268 | // this is allowed only if t he prototy pe is an a rray | |
2269 | if (pt() .hasTag(AR RAY)) { | |
2270 | elem type = typ es.elemtyp e(pt()); | |
2271 | } else { | |
2272 | if ( !pt().hasT ag(ERROR)) { | |
2273 | log.error( tree.pos() , "illegal .initializ er.for.typ e", | |
2274 | pt()); | |
2275 | } | |
2276 | elem type = typ es.createE rrorType(p t()); | |
2277 | } | |
2278 | } | |
2279 | if (tree.ele ms != null ) { | |
2280 | attribEx prs(tree.e lems, loca lEnv, elem type); | |
2281 | owntype = new Arra yType(elem type, syms .arrayClas s); | |
2282 | } | |
2283 | if (!types.i sReifiable (elemtype) ) | |
2284 | log.erro r(tree.pos (), "gener ic.array.c reation"); | |
2285 | re sult = che ck(tree, o wntype, VA L, resultI nfo); | |
2286 | } | |
2287 | ||
2288 | /* | |
2289 | * A l ambda expr ession can only be a ttributed when a tar get-type i s availabl e. | |
2290 | * In addition, if the tar get-type i s that of a function al interfa ce whose | |
2291 | * des criptor co ntains inf erence var iables in argument p osition th e lambda e xpression | |
2292 | * is 'stuck' (s ee Deferre dAttr). | |
2293 | */ | |
2294 | @Overr ide | |
2295 | public void visi tLambda(fi nal JCLamb da that) { | |
2296 | if (pt().isE rroneous() || (pt(). hasTag(NON E) && pt() != Type.r ecoveryTyp e)) { | |
2297 | if (pt() .hasTag(NO NE)) { | |
2298 | //la mbda only allowed in assignmen t or metho d invocati on/cast co ntext | |
2299 | log. error(that .pos(), "u nexpected. lambda"); | |
2300 | } | |
2301 | result = that.type = types.c reateError Type(pt()) ; | |
2302 | return; | |
2303 | } | |
2304 | // create an environmen t for attr ibution of the lambd a expressi on | |
2305 | fi nal Env<At trContext> localEnv = lambdaEn v(that, en v); | |
2306 | bo olean need sRecovery = | |
2307 | resu ltInfo.che ckContext. deferredAt trContext( ).mode == DeferredAt tr.AttrMod e.CHECK; | |
2308 | tr y { | |
2309 | Type cur rentTarget = pt(); | |
2310 | if (need sRecovery && isSeria lizable(cu rrentTarge t)) { | |
2311 | loca lEnv.info. isSerializ able = tru e; | |
2312 | } | |
2313 | List<Typ e> explici tParamType s = null; | |
2314 | if (that .paramKind == JCLamb da.Paramet erKind.EXP LICIT) { | |
2315 | //at tribute la mbda param eters | |
2316 | attr ibStats(th at.params, localEnv) ; | |
2317 | expl icitParamT ypes = Tre eInfo.type s(that.par ams); | |
2318 | } | |
2319 | ||
2320 | Type lam bdaType; | |
2321 | if (pt() != Type.r ecoveryTyp e) { | |
2322 | /* W e need to adjust the target. I f the targ et is an | |
2323 | * i ntersectio n type, fo r example: SAM & I1 & I2 ... | |
2324 | * t he target will be up dated to S AM | |
2325 | */ | |
2326 | curr entTarget = targetCh ecker.visi t(currentT arget, tha t); | |
2327 | if ( explicitPa ramTypes ! = null) { | |
2328 | currentTar get = infe r.instanti ateFunctio nalInterfa ce(that, | |
2329 | cu rrentTarge t, explici tParamType s, resultI nfo.checkC ontext); | |
2330 | } | |
2331 | curr entTarget = types.re moveWildca rds(curren tTarget); | |
2332 | lamb daType = t ypes.findD escriptorT ype(curren tTarget); | |
2333 | } else { | |
2334 | curr entTarget = Type.rec overyType; | |
2335 | lamb daType = f allbackDes criptorTyp e(that); | |
2336 | } | |
2337 | ||
2338 | setFunct ionalInfo( localEnv, that, pt() , lambdaTy pe, curren tTarget, r esultInfo. checkConte xt); | |
2339 | ||
2340 | if (lamb daType.has Tag(FORALL )) { | |
2341 | //la mbda expre ssion targ et desc ca nnot be a generic me thod | |
2342 | resu ltInfo.che ckContext. report(tha t, diags.f ragment("i nvalid.gen eric.lambd a.target", | |
2343 | lambda Type, kind Name(curre ntTarget.t sym), curr entTarget. tsym)); | |
2344 | resu lt = that. type = typ es.createE rrorType(p t()); | |
2345 | retu rn; | |
2346 | } | |
2347 | ||
2348 | if (that .paramKind == JCLamb da.Paramet erKind.IMP LICIT) { | |
2349 | //ad d param ty pe info in the AST | |
2350 | List <Type> act uals = lam bdaType.ge tParameter Types(); | |
2351 | List <JCVariabl eDecl> par ams = that .params; | |
2352 | ||
2353 | bool ean arityM ismatch = false; | |
2354 | ||
2355 | whil e (params. nonEmpty() ) { | |
2356 | if (actual s.isEmpty( )) { | |
2357 | //not enough act uals to pe rform lamb da paramet er inferen ce | |
2358 | arityM ismatch = true; | |
2359 | } | |
2360 | //reset pr eviously s et info | |
2361 | Type argTy pe = arity Mismatch ? | |
2362 | sy ms.errType : | |
2363 | ac tuals.head ; | |
2364 | params.hea d.vartype = make.at( params.hea d).Type(ar gType); | |
2365 | params.hea d.sym = nu ll; | |
2366 | actuals = actuals.is Empty() ? | |
2367 | ac tuals : | |
2368 | ac tuals.tail ; | |
2369 | params = p arams.tail ; | |
2370 | } | |
2371 | ||
2372 | //at tribute la mbda param eters | |
2373 | attr ibStats(th at.params, localEnv) ; | |
2374 | ||
2375 | if ( arityMisma tch) { | |
2376 | resultInfo .checkCont ext.report (that, dia gs.fragmen t("incompa tible.arg. types.in.l ambda")); | |
2377 | result = that.ty pe = types .createErr orType(cur rentTarget ); | |
2378 | return ; | |
2379 | } | |
2380 | } | |
2381 | ||
2382 | //from t his point on, no rec overy is n eeded; if we are in assignment context | |
2383 | //we wil l be able to attribu te the who le lambda body, rega rdless of errors; | |
2384 | //if we are in a ' check' met hod contex t, and the lambda is not compa tible | |
2385 | //with t he target- type, it w ill be rec overed any way in Att r.checkId | |
2386 | needsRec overy = fa lse; | |
2387 | ||
2388 | Function alReturnCo ntext func Context = that.getBo dyKind() = = JCLambda .BodyKind. EXPRESSION ? | |
2389 | new Expres sionLambda ReturnCont ext((JCExp ression)th at.getBody (), result Info.check Context) : | |
2390 | new Functi onalReturn Context(re sultInfo.c heckContex t); | |
2391 | ||
2392 | ResultIn fo bodyRes ultInfo = lambdaType .getReturn Type() == Type.recov eryType ? | |
2393 | reco veryInfo : | |
2394 | new ResultInfo (VAL, lamb daType.get ReturnType (), funcCo ntext); | |
2395 | localEnv .info.retu rnResult = bodyResul tInfo; | |
2396 | ||
2397 | if (that .getBodyKi nd() == JC Lambda.Bod yKind.EXPR ESSION) { | |
2398 | attr ibTree(tha t.getBody( ), localEn v, bodyRes ultInfo); | |
2399 | } else { | |
2400 | JCBl ock body = (JCBlock) that.body; | |
2401 | attr ibStats(bo dy.stats, localEnv); | |
2402 | } | |
2403 | ||
2404 | result = check(tha t, current Target, VA L, resultI nfo); | |
2405 | ||
2406 | boolean isSpeculat iveRound = | |
2407 | resultInfo .checkCont ext.deferr edAttrCont ext().mode == Deferr edAttr.Att rMode.SPEC ULATIVE; | |
2408 | ||
2409 | preFlow( that); | |
2410 | flow.ana lyzeLambda (env, that , make, is Speculativ eRound); | |
2411 | ||
2412 | that.typ e = curren tTarget; / /avoids re covery at this stage | |
2413 | checkLam bdaCompati ble(that, lambdaType , resultIn fo.checkCo ntext); | |
2414 | ||
2415 | if (!isS peculative Round) { | |
2416 | //ad d thrown t ypes as bo unds to th e thrown t ypes free variables if needed: | |
2417 | if ( resultInfo .checkCont ext.infere nceContext ().free(la mbdaType.g etThrownTy pes())) { | |
2418 | List<Type> inferredT hrownTypes = flow.an alyzeLambd aThrownTyp es(env, th at, make); | |
2419 | List<Type> thrownTyp es = resul tInfo.chec kContext.i nferenceCo ntext().as UndetVars( lambdaType .getThrown Types()); | |
2420 | ||
2421 | chk.unhand led(inferr edThrownTy pes, throw nTypes); | |
2422 | } | |
2423 | ||
2424 | chec kAccessibl eTypes(tha t, localEn v, resultI nfo.checkC ontext.inf erenceCont ext(), lam bdaType, c urrentTarg et); | |
2425 | } | |
2426 | result = check(tha t, current Target, VA L, resultI nfo); | |
2427 | } catch (Typ es.Functio nDescripto rLookupErr or ex) { | |
2428 | JCDiagno stic cause = ex.getD iagnostic( ); | |
2429 | resultIn fo.checkCo ntext.repo rt(that, c ause); | |
2430 | result = that.type = types.c reateError Type(pt()) ; | |
2431 | return; | |
2432 | } finally { | |
2433 | localEnv .info.scop e.leave(); | |
2434 | if (need sRecovery) { | |
2435 | attr ibTree(tha t, env, re coveryInfo ); | |
2436 | } | |
2437 | } | |
2438 | } | |
2439 | //wher e | |
2440 | vo id preFlow (JCLambda tree) { | |
2441 | new Post AttrAnalyz er() { | |
2442 | @Ove rride | |
2443 | publ ic void sc an(JCTree tree) { | |
2444 | if (tree = = null || | |
2445 | (t ree.type ! = null && | |
2446 | tr ee.type == Type.stuc kType)) { | |
2447 | //don' t touch st uck expres sions! | |
2448 | return ; | |
2449 | } | |
2450 | super.scan (tree); | |
2451 | } | |
2452 | }.scan(t ree); | |
2453 | } | |
2454 | ||
2455 | Ty pes.MapVis itor<Diagn osticPosit ion> targe tChecker = new Types .MapVisito r<Diagnost icPosition >() { | |
2456 | ||
2457 | @Overrid e | |
2458 | public T ype visitC lassType(C lassType t , Diagnost icPosition pos) { | |
2459 | retu rn t.isInt ersection( ) ? | |
2460 | visitI ntersectio nClassType ((Intersec tionClassT ype)t, pos ) : t; | |
2461 | } | |
2462 | ||
2463 | public T ype visitI ntersectio nClassType (Intersect ionClassTy pe ict, Di agnosticPo sition pos ) { | |
2464 | Symb ol desc = types.find Descriptor Symbol(mak eNotionalI nterface(i ct)); | |
2465 | Type target = null; | |
2466 | for (Type boun d : ict.ge tExplicitC omponents( )) { | |
2467 | TypeSymbol boundSym = bound.ts ym; | |
2468 | if (types. isFunction alInterfac e(boundSym ) && | |
2469 | ty pes.findDe scriptorSy mbol(bound Sym) == de sc) { | |
2470 | target = bound; | |
2471 | } else if (!boundSym .isInterfa ce() || (b oundSym.fl ags() & AN NOTATION) != 0) { | |
2472 | //boun d must be an interfa ce | |
2473 | report Intersecti onError(po s, "not.an .intf.comp onent", bo undSym); | |
2474 | } | |
2475 | } | |
2476 | retu rn target != null ? | |
2477 | target : | |
2478 | ict.ge tExplicitC omponents( ).head; // error reco very | |
2479 | } | |
2480 | ||
2481 | private TypeSymbol makeNotio nalInterfa ce(Interse ctionClass Type ict) { | |
2482 | List Buffer<Typ e> targs = new ListB uffer<>(); | |
2483 | List Buffer<Typ e> superty pes = new ListBuffer <>(); | |
2484 | for (Type i : ict.interf aces_field ) { | |
2485 | if (i.isPa rameterize d()) { | |
2486 | targs. appendList (i.tsym.ty pe.allpara ms()); | |
2487 | } | |
2488 | supertypes .append(i. tsym.type) ; | |
2489 | } | |
2490 | Inte rsectionCl assType no tionalIntf = types.m akeInterse ctionType( supertypes .toList()) ; | |
2491 | noti onalIntf.a llparams_f ield = tar gs.toList( ); | |
2492 | noti onalIntf.t sym.flags_ field |= I NTERFACE; | |
2493 | retu rn notiona lIntf.tsym ; | |
2494 | } | |
2495 | ||
2496 | private void repor tIntersect ionError(D iagnosticP osition po s, String key, Objec t... args) { | |
2497 | resu ltInfo.che ckContext. report(pos , diags.fr agment("ba d.intersec tion.targe t.for.func tional.exp r", | |
2498 | diags. fragment(k ey, args)) ); | |
2499 | } | |
2500 | }; | |
2501 | ||
2502 | pr ivate Type fallbackD escriptorT ype(JCExpr ession tre e) { | |
2503 | switch ( tree.getTa g()) { | |
2504 | case LAMBDA: | |
2505 | JCLambda l ambda = (J CLambda)tr ee; | |
2506 | List<Type> argtypes = List.nil (); | |
2507 | for (JCVar iableDecl param : la mbda.param s) { | |
2508 | argtyp es = param .vartype ! = null ? | |
2509 | argtypes .append(pa ram.vartyp e.type) : | |
2510 | argtypes .append(sy ms.errType ); | |
2511 | } | |
2512 | return new MethodTyp e(argtypes , Type.rec overyType, | |
2513 | Li st.of(syms .throwable Type), sym s.methodCl ass); | |
2514 | case REFERENCE : | |
2515 | return new MethodTyp e(List.<Ty pe>nil(), Type.recov eryType, | |
2516 | Li st.of(syms .throwable Type), sym s.methodCl ass); | |
2517 | defa ult: | |
2518 | Assert.err or("Cannot get here! "); | |
2519 | } | |
2520 | return n ull; | |
2521 | } | |
2522 | ||
2523 | pr ivate void checkAcce ssibleType s(final Di agnosticPo sition pos , final En v<AttrCont ext> env, | |
2524 | fina l Inferenc eContext i nferenceCo ntext, fin al Type... ts) { | |
2525 | checkAcc essibleTyp es(pos, en v, inferen ceContext, List.from (ts)); | |
2526 | } | |
2527 | ||
2528 | pr ivate void checkAcce ssibleType s(final Di agnosticPo sition pos , final En v<AttrCont ext> env, | |
2529 | fina l Inferenc eContext i nferenceCo ntext, fin al List<Ty pe> ts) { | |
2530 | if (infe renceConte xt.free(ts )) { | |
2531 | infe renceConte xt.addFree TypeListen er(ts, new FreeTypeL istener() { | |
2532 | @Override | |
2533 | public voi d typesInf erred(Infe renceConte xt inferen ceContext) { | |
2534 | checkA ccessibleT ypes(pos, env, infer enceContex t, inferen ceContext. asInstType s(ts)); | |
2535 | } | |
2536 | }); | |
2537 | } else { | |
2538 | for (Type t : ts) { | |
2539 | rs.checkAc cessibleTy pe(env, t) ; | |
2540 | } | |
2541 | } | |
2542 | } | |
2543 | ||
2544 | /* * | |
2545 | * Lambda/me thod refer ence have a special check cont ext that e nsures | |
2546 | * that i.e. a lambda return typ e is compa tible with the expec ted | |
2547 | * type acco rding to b oth the in herited co ntext and the assign ment | |
2548 | * context. | |
2549 | * / | |
2550 | cl ass Functi onalReturn Context ex tends Chec k.NestedCh eckContext { | |
2551 | ||
2552 | Function alReturnCo ntext(Chec kContext e nclosingCo ntext) { | |
2553 | supe r(enclosin gContext); | |
2554 | } | |
2555 | ||
2556 | @Overrid e | |
2557 | public b oolean com patible(Ty pe found, Type req, Warner war n) { | |
2558 | //re turn type must be co mpatible i n both cur rent conte xt and ass ignment co ntext | |
2559 | retu rn chk.bas icHandler. compatible (found, in ferenceCon text().asU ndetVar(re q), warn); | |
2560 | } | |
2561 | ||
2562 | @Overrid e | |
2563 | public v oid report (Diagnosti cPosition pos, JCDia gnostic de tails) { | |
2564 | encl osingConte xt.report( pos, diags .fragment( "incompati ble.ret.ty pe.in.lamb da", detai ls)); | |
2565 | } | |
2566 | } | |
2567 | ||
2568 | cl ass Expres sionLambda ReturnCont ext extend s Function alReturnCo ntext { | |
2569 | ||
2570 | JCExpres sion expr; | |
2571 | ||
2572 | Expressi onLambdaRe turnContex t(JCExpres sion expr, CheckCont ext enclos ingContext ) { | |
2573 | supe r(enclosin gContext); | |
2574 | this .expr = ex pr; | |
2575 | } | |
2576 | ||
2577 | @Overrid e | |
2578 | public b oolean com patible(Ty pe found, Type req, Warner war n) { | |
2579 | //a void retur n is compa tible with an expres sion state ment lambd a | |
2580 | retu rn TreeInf o.isExpres sionStatem ent(expr) && req.has Tag(VOID) || | |
2581 | super. compatible (found, re q, warn); | |
2582 | } | |
2583 | } | |
2584 | ||
2585 | /* * | |
2586 | * Lambda com patibility . Check th at given r eturn type s, thrown types, par ameter typ es | |
2587 | * are compat ible with the expect ed functio nal interf ace descri ptor. This means tha t: | |
2588 | * (i) parame ter types must be id entical to those of the target descripto r; (ii) re turn | |
2589 | * types must be compat ible with the return type of t he expecte d descript or. | |
2590 | */ | |
2591 | pr ivate void checkLamb daCompatib le(JCLambd a tree, Ty pe descrip tor, Check Context ch eckContext ) { | |
2592 | Type ret urnType = checkConte xt.inferen ceContext( ).asUndetV ar(descrip tor.getRet urnType()) ; | |
2593 | ||
2594 | //return values ha ve already been chec ked - but if lambda has no ret urn | |
2595 | //values , we must ensure tha t void/val ue compati bility is correct; | |
2596 | //this a mounts at checking t hat, if a lambda bod y can comp lete norma lly, | |
2597 | //the de scriptor's return ty pe must be void | |
2598 | if (tree .getBodyKi nd() == JC Lambda.Bod yKind.STAT EMENT && t ree.canCom pleteNorma lly && | |
2599 | !returnTyp e.hasTag(V OID) && re turnType ! = Type.rec overyType) { | |
2600 | chec kContext.r eport(tree , diags.fr agment("in compatible .ret.type. in.lambda" , | |
2601 | diags. fragment(" missing.re t.val", re turnType)) ); | |
2602 | } | |
2603 | ||
2604 | List<Typ e> argType s = checkC ontext.inf erenceCont ext().asUn detVars(de scriptor.g etParamete rTypes()); | |
2605 | if (!typ es.isSameT ypes(argTy pes, TreeI nfo.types( tree.param s))) { | |
2606 | chec kContext.r eport(tree , diags.fr agment("in compatible .arg.types .in.lambda ")); | |
2607 | } | |
2608 | } | |
2609 | ||
2610 | /* Map to ho ld 'fake' clinit met hods. If a lambda is used to i nitialize a | |
2611 | * static fi eld and th at lambda has type a nnotations , these an notations will | |
2612 | * also be s tored at t hese fake clinit met hods. | |
2613 | * | |
2614 | * LambdaToM ethod also use fake clinit met hods so th ey can be reused. | |
2615 | * Also as L TM is a ph ase subseq uent to at tribution, the metho ds from | |
2616 | * clinits c an be safe ly removed by LTM to save memo ry. | |
2617 | * / | |
2618 | pr ivate Map< ClassSymbo l, MethodS ymbol> cli nits = new HashMap<> (); | |
2619 | ||
2620 | pu blic Metho dSymbol re moveClinit (ClassSymb ol sym) { | |
2621 | return c linits.rem ove(sym); | |
2622 | } | |
2623 | ||
2624 | /* This meth od returns an enviro nment to b e used to attribute a lambda | |
2625 | * expressio n. | |
2626 | * | |
2627 | * The owner of this e nvironment is a meth od symbol. If the cu rrent owne r | |
2628 | * is not a method, fo r example if the lam bda is use d to initi alize | |
2629 | * a field, then if th e field is : | |
2630 | * | |
2631 | * - an inst ance field , we use t he first c onstructor . | |
2632 | * - a stati c field, w e create a fake clin it method. | |
2633 | * / | |
2634 | pu blic Env<A ttrContext > lambdaEn v(JCLambda that, Env <AttrConte xt> env) { | |
2635 | Env<Attr Context> l ambdaEnv; | |
2636 | Symbol o wner = env .info.scop e.owner; | |
2637 | if (owne r.kind == VAR && own er.owner.k ind == TYP ) { | |
2638 | //fi eld initia lizer | |
2639 | lamb daEnv = en v.dup(that , env.info .dup(env.i nfo.scope. dupUnshare d())); | |
2640 | Clas sSymbol en clClass = owner.encl Class(); | |
2641 | /* i f the fiel d isn't st atic, then we can ge t the firs t construc tor | |
2642 | * a nd use it as the own er of the environmen t. This is what | |
2643 | * L TM code is doing to look for t ype annota tions so w e are fine . | |
2644 | */ | |
2645 | if ( (owner.fla gs() & STA TIC) == 0) { | |
2646 | for (Symbo l s : encl Class.memb ers_field. getElement sByName(na mes.init)) { | |
2647 | lambda Env.info.s cope.owner = s; | |
2648 | break; | |
2649 | } | |
2650 | } el se { | |
2651 | /* if the field is s tatic then we need t o create a fake clin it | |
2652 | * method, this meth od can lat er be reus ed by LTM. | |
2653 | */ | |
2654 | MethodSymb ol clinit = clinits. get(enclCl ass); | |
2655 | if (clinit == null) { | |
2656 | Type c linitType = new Meth odType(Lis t.<Type>ni l(), | |
2657 | syms.voi dType, Lis t.<Type>ni l(), syms. methodClas s); | |
2658 | clinit = new Met hodSymbol( STATIC | S YNTHETIC | PRIVATE, | |
2659 | names.cl init, clin itType, en clClass); | |
2660 | clinit .params = List.<VarS ymbol>nil( ); | |
2661 | clinit s.put(encl Class, cli nit); | |
2662 | } | |
2663 | lambdaEnv. info.scope .owner = c linit; | |
2664 | } | |
2665 | } else { | |
2666 | lamb daEnv = en v.dup(that , env.info .dup(env.i nfo.scope. dup())); | |
2667 | } | |
2668 | return l ambdaEnv; | |
2669 | } | |
2670 | ||
2671 | @Overr ide | |
2672 | public void visi tReference (final JCM emberRefer ence that) { | |
2673 | if (pt().isE rroneous() || (pt(). hasTag(NON E) && pt() != Type.r ecoveryTyp e)) { | |
2674 | if (pt() .hasTag(NO NE)) { | |
2675 | //me thod refer ence only allowed in assignmen t or metho d invocati on/cast co ntext | |
2676 | log. error(that .pos(), "u nexpected. mref"); | |
2677 | } | |
2678 | result = that.type = types.c reateError Type(pt()) ; | |
2679 | return; | |
2680 | } | |
2681 | fi nal Env<At trContext> localEnv = env.dup( that); | |
2682 | tr y { | |
2683 | //attrib ute member reference qualifier - if this is a cons tructor | |
2684 | //refere nce, the e xpected ki nd must be a type | |
2685 | Type exp rType = at tribTree(t hat.expr, env, membe rReference QualifierR esult(that )); | |
2686 | ||
2687 | if (that .getMode() == JCMemb erReferenc e.Referenc eMode.NEW) { | |
2688 | expr Type = chk .checkCons tructorRef Type(that. expr, expr Type); | |
2689 | if ( !exprType. isErroneou s() && | |
2690 | exprType.i sRaw() && | |
2691 | that.typea rgs != nul l) { | |
2692 | log.error( that.expr. pos(), "in valid.mref ", Kinds.k indName(th at.getMode ()), | |
2693 | diags. fragment(" mref.infer .and.expli cit.params ")); | |
2694 | exprType = types.cre ateErrorTy pe(exprTyp e); | |
2695 | } | |
2696 | } | |
2697 | ||
2698 | if (expr Type.isErr oneous()) { | |
2699 | //if the quali fier expre ssion cont ains probl ems, | |
2700 | //gi ve up attr ibution of method re ference | |
2701 | resu lt = that. type = exp rType; | |
2702 | retu rn; | |
2703 | } | |
2704 | ||
2705 | if (Tree Info.isSta ticSelecto r(that.exp r, names)) { | |
2706 | //if the quali fier is a type, vali date it; r aw warning check is | |
2707 | //om itted as w e don't kn ow at this stage as to whether this is a | |
2708 | //ra w selector (because of inferen ce) | |
2709 | chk. validate(t hat.expr, env, false ); | |
2710 | } | |
2711 | ||
2712 | //attrib type-argu ments | |
2713 | List<Typ e> typearg types = Li st.nil(); | |
2714 | if (that .typeargs != null) { | |
2715 | type argtypes = attribTyp es(that.ty peargs, lo calEnv); | |
2716 | } | |
2717 | ||
2718 | Type des c; | |
2719 | Type cur rentTarget = pt(); | |
2720 | boolean isTargetSe rializable = | |
2721 | resultInfo .checkCont ext.deferr edAttrCont ext().mode == Deferr edAttr.Att rMode.CHEC K && | |
2722 | isSerializ able(curre ntTarget); | |
2723 | if (curr entTarget != Type.re coveryType ) { | |
2724 | curr entTarget = types.re moveWildca rds(target Checker.vi sit(curren tTarget, t hat)); | |
2725 | desc = types.f indDescrip torType(cu rrentTarge t); | |
2726 | } else { | |
2727 | curr entTarget = Type.rec overyType; | |
2728 | desc = fallbac kDescripto rType(that ); | |
2729 | } | |
2730 | ||
2731 | setFunct ionalInfo( localEnv, that, pt() , desc, cu rrentTarge t, resultI nfo.checkC ontext); | |
2732 | List<Typ e> argtype s = desc.g etParamete rTypes(); | |
2733 | Resolve. MethodChec k referenc eCheck = r s.resolveM ethodCheck ; | |
2734 | ||
2735 | if (resu ltInfo.che ckContext. inferenceC ontext().f ree(argtyp es)) { | |
2736 | refe renceCheck = rs.new MethodRefe renceCheck (resultInf o.checkCon text.infer enceContex t()); | |
2737 | } | |
2738 | ||
2739 | Pair<Sym bol, Resol ve.Referen ceLookupHe lper> refR esult = nu ll; | |
2740 | List<Typ e> saved_u ndet = res ultInfo.ch eckContext .inference Context(). save(); | |
2741 | try { | |
2742 | refR esult = rs .resolveMe mberRefere nce(localE nv, that, that.expr. type, | |
2743 | that.n ame, argty pes, typea rgtypes, r eferenceCh eck, | |
2744 | result Info.check Context.in ferenceCon text(), | |
2745 | result Info.check Context.de ferredAttr Context(). mode); | |
2746 | } finall y { | |
2747 | resu ltInfo.che ckContext. inferenceC ontext().r ollback(sa ved_undet) ; | |
2748 | } | |
2749 | ||
2750 | Symbol r efSym = re fResult.fs t; | |
2751 | Resolve. ReferenceL ookupHelpe r lookupHe lper = ref Result.snd ; | |
2752 | ||
2753 | if (refS ym.kind != MTH) { | |
2754 | bool ean target Error; | |
2755 | swit ch (refSym .kind) { | |
2756 | case ABSEN T_MTH: | |
2757 | target Error = fa lse; | |
2758 | break; | |
2759 | case WRONG _MTH: | |
2760 | case WRONG _MTHS: | |
2761 | case AMBIG UOUS: | |
2762 | case HIDDE N: | |
2763 | case STATI CERR: | |
2764 | case MISSI NG_ENCL: | |
2765 | case WRONG _STATICNES S: | |
2766 | target Error = tr ue; | |
2767 | break; | |
2768 | default: | |
2769 | Assert .error("un expected r esult kind " + refSy m.kind); | |
2770 | target Error = fa lse; | |
2771 | } | |
2772 | ||
2773 | JCDi agnostic d etailsDiag = ((Resol ve.Resolve Error)refS ym.baseSym bol()).get Diagnostic (JCDiagnos tic.Diagno sticType.F RAGMENT, | |
2774 | that, ex prType.tsy m, exprTyp e, that.na me, argtyp es, typear gtypes); | |
2775 | ||
2776 | JCDi agnostic.D iagnosticT ype diagKi nd = targe tError ? | |
2777 | JCDiag nostic.Dia gnosticTyp e.FRAGMENT : JCDiagn ostic.Diag nosticType .ERROR; | |
2778 | ||
2779 | JCDi agnostic d iag = diag s.create(d iagKind, l og.current Source(), that, | |
2780 | "inval id.mref", Kinds.kind Name(that. getMode()) , detailsD iag); | |
2781 | ||
2782 | if ( targetErro r && curre ntTarget = = Type.rec overyType) { | |
2783 | //a target error doe sn't make sense duri ng recover y stage | |
2784 | //as we do n't know w hat actual parameter types are | |
2785 | result = t hat.type = currentTa rget; | |
2786 | return; | |
2787 | } el se { | |
2788 | if (target Error) { | |
2789 | result Info.check Context.re port(that, diag); | |
2790 | } else { | |
2791 | log.re port(diag) ; | |
2792 | } | |
2793 | result = t hat.type = types.cre ateErrorTy pe(current Target); | |
2794 | return; | |
2795 | } | |
2796 | } | |
2797 | ||
2798 | that.sym = refSym. baseSymbol (); | |
2799 | that.kin d = lookup Helper.ref erenceKind (that.sym) ; | |
2800 | that.own erAccessib le = rs.is Accessible (localEnv, that.sym. enclClass( )); | |
2801 | ||
2802 | if (desc .getReturn Type() == Type.recov eryType) { | |
2803 | // s top here | |
2804 | resu lt = that. type = cur rentTarget ; | |
2805 | retu rn; | |
2806 | } | |
2807 | ||
2808 | if (resu ltInfo.che ckContext. deferredAt trContext( ).mode == AttrMode.C HECK) { | |
2809 | ||
2810 | if ( that.getMo de() == Re ferenceMod e.INVOKE & & | |
2811 | TreeIn fo.isStati cSelector( that.expr, names) && | |
2812 | that.k ind.isUnbo und() && | |
2813 | !desc. getParamet erTypes(). head.isPar ameterized ()) { | |
2814 | chk.checkR aw(that.ex pr, localE nv); | |
2815 | } | |
2816 | ||
2817 | if ( that.sym.i sStatic() && TreeInf o.isStatic Selector(t hat.expr, names) && | |
2818 | exprTy pe.getType Arguments( ).nonEmpty ()) { | |
2819 | //static r ef with cl ass type-a rgs | |
2820 | log.error( that.expr. pos(), "in valid.mref ", Kinds.k indName(th at.getMode ()), | |
2821 | di ags.fragme nt("static .mref.with .targs")); | |
2822 | result = t hat.type = types.cre ateErrorTy pe(current Target); | |
2823 | return; | |
2824 | } | |
2825 | ||
2826 | if ( that.sym.i sStatic() && !TreeIn fo.isStati cSelector( that.expr, names) && | |
2827 | !that. kind.isUnb ound()) { | |
2828 | //no stati c bound mr efs | |
2829 | log.error( that.expr. pos(), "in valid.mref ", Kinds.k indName(th at.getMode ()), | |
2830 | di ags.fragme nt("static .bound.mre f")); | |
2831 | result = t hat.type = types.cre ateErrorTy pe(current Target); | |
2832 | return; | |
2833 | } | |
2834 | ||
2835 | if ( !refSym.is Static() & & that.kin d == JCMem berReferen ce.Referen ceKind.SUP ER) { | |
2836 | // Check t hat super- qualified symbols ar e not abst ract (JLS) | |
2837 | rs.checkNo nAbstract( that.pos() , that.sym ); | |
2838 | } | |
2839 | ||
2840 | if ( isTargetSe rializable ) { | |
2841 | chk.checkE lemAccessF romSeriali zableLambd a(that); | |
2842 | } | |
2843 | } | |
2844 | ||
2845 | ResultIn fo checkIn fo = | |
2846 | resultInfo .dup(newMe thodTempla te( | |
2847 | desc.g etReturnTy pe().hasTa g(VOID) ? Type.noTyp e : desc.g etReturnTy pe(), | |
2848 | that.k ind.isUnbo und() ? ar gtypes.tai l : argtyp es, typear gtypes), | |
2849 | new Fu nctionalRe turnContex t(resultIn fo.checkCo ntext)); | |
2850 | ||
2851 | Type ref Type = che ckId(noChe ckTree, lo okupHelper .site, ref Sym, local Env, check Info); | |
2852 | ||
2853 | if (that .kind.isUn bound() && | |
2854 | resultInfo .checkCont ext.infere nceContext ().free(ar gtypes.hea d)) { | |
2855 | //re -generate inference constraint s for unbo und receiv er | |
2856 | if ( !types.isS ubtype(res ultInfo.ch eckContext .inference Context(). asUndetVar (argtypes. head), exp rType)) { | |
2857 | //cannot h appen as t his has al ready been checked - we just n eed | |
2858 | //to regen erate the inference constraint s, as that has been lost | |
2859 | //as a res ult of the call to i nferenceCo ntext.save () | |
2860 | Assert.err or("Can't get here") ; | |
2861 | } | |
2862 | } | |
2863 | ||
2864 | if (!ref Type.isErr oneous()) { | |
2865 | refT ype = type s.createMe thodTypeWi thReturn(r efType, | |
2866 | adjust MethodRetu rnType(loo kupHelper. site, that .name, che ckInfo.pt. getParamet erTypes(), refType.g etReturnTy pe())); | |
2867 | } | |
2868 | ||
2869 | //go ahe ad with st andard met hod refere nce compat ibility ch eck - note that para m check | |
2870 | //is a n o-op (as t his has be en taken c are during method ap plicabilit y) | |
2871 | boolean isSpeculat iveRound = | |
2872 | resultInfo .checkCont ext.deferr edAttrCont ext().mode == Deferr edAttr.Att rMode.SPEC ULATIVE; | |
2873 | ||
2874 | that.typ e = curren tTarget; / /avoids re covery at this stage | |
2875 | checkRef erenceComp atible(tha t, desc, r efType, re sultInfo.c heckContex t, isSpecu lativeRoun d); | |
2876 | if (!isS peculative Round) { | |
2877 | chec kAccessibl eTypes(tha t, localEn v, resultI nfo.checkC ontext.inf erenceCont ext(), des c, current Target); | |
2878 | } | |
2879 | result = check(tha t, current Target, VA L, resultI nfo); | |
2880 | } catch (Typ es.Functio nDescripto rLookupErr or ex) { | |
2881 | JCDiagno stic cause = ex.getD iagnostic( ); | |
2882 | resultIn fo.checkCo ntext.repo rt(that, c ause); | |
2883 | result = that.type = types.c reateError Type(pt()) ; | |
2884 | return; | |
2885 | } | |
2886 | } | |
2887 | //wher e | |
2888 | Re sultInfo m emberRefer enceQualif ierResult( JCMemberRe ference tr ee) { | |
2889 | //if thi s is a con structor r eference, the expect ed kind mu st be a ty pe | |
2890 | return n ew ResultI nfo(tree.g etMode() = = Referenc eMode.INVO KE ? VAL | TYP : TYP , Type.noT ype); | |
2891 | } | |
2892 | ||
2893 | ||
2894 | @Suppr essWarning s("fallthr ough") | |
2895 | void c heckRefere nceCompati ble(JCMemb erReferenc e tree, Ty pe descrip tor, Type refType, C heckContex t checkCon text, bool ean specul ativeAttr) { | |
2896 | Ty pe returnT ype = chec kContext.i nferenceCo ntext().as UndetVar(d escriptor. getReturnT ype()); | |
2897 | ||
2898 | Ty pe resType ; | |
2899 | sw itch (tree .getMode() ) { | |
2900 | case NEW : | |
2901 | if ( !tree.expr .type.isRa w()) { | |
2902 | resType = tree.expr. type; | |
2903 | break; | |
2904 | } | |
2905 | default: | |
2906 | resT ype = refT ype.getRet urnType(); | |
2907 | } | |
2908 | ||
2909 | Ty pe incompa tibleRetur nType = re sType; | |
2910 | ||
2911 | if (returnTy pe.hasTag( VOID)) { | |
2912 | incompat ibleReturn Type = nul l; | |
2913 | } | |
2914 | ||
2915 | if (!returnT ype.hasTag (VOID) && !resType.h asTag(VOID )) { | |
2916 | if (resT ype.isErro neous() || | |
2917 | new Functi onalReturn Context(ch eckContext ).compatib le(resType , returnTy pe, types. noWarnings )) { | |
2918 | inco mpatibleRe turnType = null; | |
2919 | } | |
2920 | } | |
2921 | ||
2922 | if (incompat ibleReturn Type != nu ll) { | |
2923 | checkCon text.repor t(tree, di ags.fragme nt("incomp atible.ret .type.in.m ref", | |
2924 | diags.frag ment("inco nvertible. types", re sType, des criptor.ge tReturnTyp e()))); | |
2925 | } | |
2926 | ||
2927 | if (!specula tiveAttr) { | |
2928 | List<Typ e> thrownT ypes = che ckContext. inferenceC ontext().a sUndetVars (descripto r.getThrow nTypes()); | |
2929 | if (chk. unhandled( refType.ge tThrownTyp es(), thro wnTypes).n onEmpty()) { | |
2930 | log. error(tree , "incompa tible.thro wn.types.i n.mref", r efType.get ThrownType s()); | |
2931 | } | |
2932 | } | |
2933 | } | |
2934 | ||
2935 | /** | |
2936 | * Set functiona l type inf o on the u nderlying AST. Note: as the ta rget descr iptor | |
2937 | * mig ht contain inference variables , we might need to r egister an hook in t he | |
2938 | * cur rent infer ence conte xt. | |
2939 | */ | |
2940 | privat e void set Functional Info(final Env<AttrC ontext> en v, final J CFunctiona lExpressio n fExpr, | |
2941 | final Ty pe pt, fin al Type de scriptorTy pe, final Type prima ryTarget, final Chec kContext c heckContex t) { | |
2942 | if (checkCon text.infer enceContex t().free(d escriptorT ype)) { | |
2943 | checkCon text.infer enceContex t().addFre eTypeListe ner(List.o f(pt, desc riptorType ), new Fre eTypeListe ner() { | |
2944 | publ ic void ty pesInferre d(Inferenc eContext i nferenceCo ntext) { | |
2945 | setFunctio nalInfo(en v, fExpr, pt, infere nceContext .asInstTyp e(descript orType), | |
2946 | in ferenceCon text.asIns tType(prim aryTarget) , checkCon text); | |
2947 | } | |
2948 | }); | |
2949 | } else { | |
2950 | ListBuff er<Type> t argets = n ew ListBuf fer<>(); | |
2951 | if (pt.h asTag(CLAS S)) { | |
2952 | if ( pt.isCompo und()) { | |
2953 | targets.ap pend(types .removeWil dcards(pri maryTarget )); //this goes firs t | |
2954 | for (Type t : ((Inte rsectionCl assType)pt ()).interf aces_field ) { | |
2955 | if (t != primary Target) { | |
2956 | ta rgets.appe nd(types.r emoveWildc ards(t)); | |
2957 | } | |
2958 | } | |
2959 | } el se { | |
2960 | targets.ap pend(types .removeWil dcards(pri maryTarget )); | |
2961 | } | |
2962 | } | |
2963 | fExpr.ta rgets = ta rgets.toLi st(); | |
2964 | if (chec kContext.d eferredAtt rContext() .mode == D eferredAtt r.AttrMode .CHECK && | |
2965 | pt != Type .recoveryT ype) { | |
2966 | //ch eck that f unctional interface class is w ell-formed | |
2967 | try { | |
2968 | /* Types.m akeFunctio nalInterfa ceClass() may throw an excepti on | |
2969 | * when it 's execute d post-inf erence. Se e the list ener code | |
2970 | * above. | |
2971 | */ | |
2972 | ClassSymbo l csym = t ypes.makeF unctionalI nterfaceCl ass(env, | |
2973 | na mes.empty, List.of(f Expr.targe ts.head), ABSTRACT); | |
2974 | if (csym ! = null) { | |
2975 | chk.ch eckImpleme ntations(e nv.tree, c sym, csym) ; | |
2976 | } | |
2977 | } ca tch (Types .FunctionD escriptorL ookupError ex) { | |
2978 | JCDiagnost ic cause = ex.getDia gnostic(); | |
2979 | resultInfo .checkCont ext.report (env.tree, cause); | |
2980 | } | |
2981 | } | |
2982 | } | |
2983 | } | |
2984 | ||
2985 | public void visi tParens(JC Parens tre e) { | |
2986 | Ty pe owntype = attribT ree(tree.e xpr, env, resultInfo ); | |
2987 | re sult = che ck(tree, o wntype, pk ind(), res ultInfo); | |
2988 | Sy mbol sym = TreeInfo. symbol(tre e); | |
2989 | if (sym != n ull && (sy m.kind&(TY P|PCK)) != 0) | |
2990 | log.erro r(tree.pos (), "illeg al.start.o f.type"); | |
2991 | } | |
2992 | ||
2993 | public void visi tAssign(JC Assign tre e) { | |
2994 | Ty pe owntype = attribT ree(tree.l hs, env.du p(tree), v arInfo); | |
2995 | Ty pe capture dType = ca pture(ownt ype); | |
2996 | at tribExpr(t ree.rhs, e nv, owntyp e); | |
2997 | re sult = che ck(tree, c apturedTyp e, VAL, re sultInfo); | |
2998 | } | |
2999 | ||
3000 | public void visi tAssignop( JCAssignOp tree) { | |
3001 | // Attribute arguments . | |
3002 | Ty pe owntype = attribT ree(tree.l hs, env, v arInfo); | |
3003 | Ty pe operand = attribE xpr(tree.r hs, env); | |
3004 | // Find oper ator. | |
3005 | Sy mbol opera tor = tree .operator = rs.resol veBinaryOp erator( | |
3006 | tree.pos (), tree.g etTag().no AssignOp() , env, | |
3007 | owntype, operand); | |
3008 | ||
3009 | if (operator .kind == M TH && | |
3010 | !own type.isErr oneous() & & | |
3011 | !ope rand.isErr oneous()) { | |
3012 | chk.chec kOperator( tree.pos() , | |
3013 | (OperatorS ymbol)oper ator, | |
3014 | tree.getTa g().noAssi gnOp(), | |
3015 | owntype, | |
3016 | operand); | |
3017 | chk.chec kDivZero(t ree.rhs.po s(), opera tor, opera nd); | |
3018 | chk.chec kCastable( tree.rhs.p os(), | |
3019 | operator.t ype.getRet urnType(), | |
3020 | owntype); | |
3021 | } | |
3022 | re sult = che ck(tree, o wntype, VA L, resultI nfo); | |
3023 | } | |
3024 | ||
3025 | public void visi tUnary(JCU nary tree) { | |
3026 | // Attribute arguments . | |
3027 | Ty pe argtype = (tree.g etTag().is IncOrDecUn aryOp()) | |
3028 | ? attrib Tree(tree. arg, env, varInfo) | |
3029 | : chk.ch eckNonVoid (tree.arg. pos(), att ribExpr(tr ee.arg, en v)); | |
3030 | ||
3031 | // Find oper ator. | |
3032 | Sy mbol opera tor = tree .operator = | |
3033 | rs.resol veUnaryOpe rator(tree .pos(), tr ee.getTag( ), env, ar gtype); | |
3034 | ||
3035 | Ty pe owntype = types.c reateError Type(tree. type); | |
3036 | if (operator .kind == M TH && | |
3037 | !arg type.isErr oneous()) { | |
3038 | owntype = (tree.ge tTag().isI ncOrDecUna ryOp()) | |
3039 | ? tr ee.arg.typ e | |
3040 | : op erator.typ e.getRetur nType(); | |
3041 | int opc = ((Operat orSymbol)o perator).o pcode; | |
3042 | ||
3043 | // If th e argument is consta nt, fold i t. | |
3044 | if (argt ype.constV alue() != null) { | |
3045 | Type ctype = c folder.fol d1(opc, ar gtype); | |
3046 | if ( ctype != n ull) { | |
3047 | owntype = cfolder.co erce(ctype , owntype) ; | |
3048 | } | |
3049 | } | |
3050 | } | |
3051 | re sult = che ck(tree, o wntype, VA L, resultI nfo); | |
3052 | } | |
3053 | ||
3054 | public void visi tBinary(JC Binary tre e) { | |
3055 | // Attribute arguments . | |
3056 | Ty pe left = chk.checkN onVoid(tre e.lhs.pos( ), attribE xpr(tree.l hs, env)); | |
3057 | Ty pe right = chk.check NonVoid(tr ee.lhs.pos (), attrib Expr(tree. rhs, env)) ; | |
3058 | ||
3059 | // Find oper ator. | |
3060 | Sy mbol opera tor = tree .operator = | |
3061 | rs.resol veBinaryOp erator(tre e.pos(), t ree.getTag (), env, l eft, right ); | |
3062 | ||
3063 | Ty pe owntype = types.c reateError Type(tree. type); | |
3064 | if (operator .kind == M TH && | |
3065 | !lef t.isErrone ous() && | |
3066 | !rig ht.isErron eous()) { | |
3067 | owntype = operator .type.getR eturnType( ); | |
3068 | // This will figur e out when unboxing can happen and | |
3069 | // choos e the righ t comparis on operato r. | |
3070 | int opc = chk.chec kOperator( tree.lhs.p os(), | |
3071 | (OperatorS ymbol)oper ator, | |
3072 | tree.getTa g(), | |
3073 | left, | |
3074 | right); | |
3075 | ||
3076 | // If bo th argumen ts are con stants, fo ld them. | |
3077 | if (left .constValu e() != nul l && right .constValu e() != nul l) { | |
3078 | Type ctype = c folder.fol d2(opc, le ft, right) ; | |
3079 | if ( ctype != n ull) { | |
3080 | owntype = cfolder.co erce(ctype , owntype) ; | |
3081 | } | |
3082 | } | |
3083 | ||
3084 | // Check that argu ment types of a refe rence ==, != are | |
3085 | // casta ble to eac h other, ( JLS 15.21) . Note: u nboxing | |
3086 | // compa risons wil l not have an acmp* opc at thi s point. | |
3087 | if ((opc == ByteCo des.if_acm peq || opc == ByteCo des.if_acm pne)) { | |
3088 | if ( !types.isE qualityCom parable(le ft, right, | |
3089 | ne w Warner(t ree.pos()) )) { | |
3090 | log.error( tree.pos() , "incompa rable.type s", left, right); | |
3091 | } | |
3092 | } | |
3093 | ||
3094 | chk.chec kDivZero(t ree.rhs.po s(), opera tor, right ); | |
3095 | } | |
3096 | re sult = che ck(tree, o wntype, VA L, resultI nfo); | |
3097 | } | |
3098 | ||
3099 | public void visi tTypeCast( final JCTy peCast tre e) { | |
3100 | Ty pe clazzty pe = attri bType(tree .clazz, en v); | |
3101 | ch k.validate (tree.claz z, env, fa lse); | |
3102 | // a fresh en vironment is require d for 292 inference to work pr operly --- | |
3103 | // see Infer. instantiat ePolymorph icSignatur eInstance( ) | |
3104 | En v<AttrCont ext> local Env = env. dup(tree); | |
3105 | // should we propagate the target type? | |
3106 | fi nal Result Info castI nfo; | |
3107 | JC Expression expr = Tr eeInfo.ski pParens(tr ee.expr); | |
3108 | bo olean isPo ly = allow Poly && (e xpr.hasTag (LAMBDA) | | expr.has Tag(REFERE NCE)); | |
3109 | if (isPoly) { | |
3110 | //expres sion is a poly - we need to pr opagate ta rget type info | |
3111 | castInfo = new Res ultInfo(VA L, clazzty pe, new Ch eck.Nested CheckConte xt(resultI nfo.checkC ontext) { | |
3112 | @Ove rride | |
3113 | publ ic boolean compatibl e(Type fou nd, Type r eq, Warner warn) { | |
3114 | return typ es.isCasta ble(found, req, warn ); | |
3115 | } | |
3116 | }); | |
3117 | } else { | |
3118 | //standa lone cast - target-t ype info i s not prop agated | |
3119 | castInfo = unknown ExprInfo; | |
3120 | } | |
3121 | Ty pe exprtyp e = attrib Tree(tree. expr, loca lEnv, cast Info); | |
3122 | Ty pe owntype = isPoly ? clazztyp e : chk.ch eckCastabl e(tree.exp r.pos(), e xprtype, c lazztype); | |
3123 | if (exprtype .constValu e() != nul l) | |
3124 | owntype = cfolder. coerce(exp rtype, own type); | |
3125 | re sult = che ck(tree, c apture(own type), VAL , resultIn fo); | |
3126 | if (!isPoly) | |
3127 | chk.chec kRedundant Cast(local Env, tree) ; | |
3128 | } | |
3129 | ||
3130 | public void visi tTypeTest( JCInstance Of tree) { | |
3131 | Ty pe exprtyp e = chk.ch eckNullOrR efType( | |
3132 | tree.exp r.pos(), a ttribExpr( tree.expr, env)); | |
3133 | Ty pe clazzty pe = attri bType(tree .clazz, en v); | |
3134 | if (!clazzty pe.hasTag( TYPEVAR)) { | |
3135 | clazztyp e = chk.ch eckClassOr ArrayType( tree.clazz .pos(), cl azztype); | |
3136 | } | |
3137 | if (!clazzty pe.isErron eous() && !types.isR eifiable(c lazztype)) { | |
3138 | log.erro r(tree.cla zz.pos(), "illegal.g eneric.typ e.for.inst of"); | |
3139 | clazztyp e = types. createErro rType(claz ztype); | |
3140 | } | |
3141 | ch k.validate (tree.claz z, env, fa lse); | |
3142 | ch k.checkCas table(tree .expr.pos( ), exprtyp e, clazzty pe); | |
3143 | re sult = che ck(tree, s yms.boolea nType, VAL , resultIn fo); | |
3144 | } | |
3145 | ||
3146 | public void visi tIndexed(J CArrayAcce ss tree) { | |
3147 | Ty pe owntype = types.c reateError Type(tree. type); | |
3148 | Ty pe atype = attribExp r(tree.ind exed, env) ; | |
3149 | at tribExpr(t ree.index, env, syms .intType); | |
3150 | if (types.is Array(atyp e)) | |
3151 | owntype = types.el emtype(aty pe); | |
3152 | el se if (!at ype.hasTag (ERROR)) | |
3153 | log.erro r(tree.pos (), "array .req.but.f ound", aty pe); | |
3154 | if ((pkind() & VAR) == 0) owntyp e = captur e(owntype) ; | |
3155 | re sult = che ck(tree, o wntype, VA R, resultI nfo); | |
3156 | } | |
3157 | ||
3158 | public void visi tIdent(JCI dent tree) { | |
3159 | Sy mbol sym; | |
3160 | ||
3161 | // Find symb ol | |
3162 | if (pt().has Tag(METHOD ) || pt(). hasTag(FOR ALL)) { | |
3163 | // If we are looki ng for a m ethod, the prototype `pt' will be a | |
3164 | // metho d type wit h the type of the ca ll's argum ents as pa rameters. | |
3165 | env.info .pendingRe solutionPh ase = null ; | |
3166 | sym = rs .resolveMe thod(tree. pos(), env , tree.nam e, pt().ge tParameter Types(), p t().getTyp eArguments ()); | |
3167 | } else if (t ree.sym != null && t ree.sym.ki nd != VAR) { | |
3168 | sym = tr ee.sym; | |
3169 | } else { | |
3170 | sym = rs .resolveId ent(tree.p os(), env, tree.name , pkind()) ; | |
3171 | } | |
3172 | tr ee.sym = s ym; | |
3173 | ||
3174 | // (1) Also find the e nvironment current f or the cla ss where | |
3175 | // sym i s defined (`symEnv') . | |
3176 | // Only for pre-tiger versions ( 1.4 and ea rlier): | |
3177 | // (2) Also determine whether we access sy mbol out o f an anony mous | |
3178 | // class in a this or super call. Thi s is illeg al for ins tance | |
3179 | // membe rs since s uch classe s don't ca rry a this $n link. | |
3180 | // (`noO uterThisPa th'). | |
3181 | En v<AttrCont ext> symEn v = env; | |
3182 | bo olean noOu terThisPat h = false; | |
3183 | if (env.encl Class.sym. owner.kind != PCK && // we are in an inn er class | |
3184 | (sym.kin d & (VAR | MTH | TYP )) != 0 && | |
3185 | sym.owne r.kind == TYP && | |
3186 | tree.nam e != names ._this && tree.name != names._ super) { | |
3187 | ||
3188 | // Find environmen t in which identifie r is defin ed. | |
3189 | while (s ymEnv.oute r != null && | |
3190 | ! sym.isMemb erOf(symEn v.enclClas s.sym, typ es)) { | |
3191 | if ( (symEnv.en clClass.sy m.flags() & NOOUTERT HIS) != 0) | |
3192 | noOuterThi sPath = !a llowAnonOu terThis; | |
3193 | symE nv = symEn v.outer; | |
3194 | } | |
3195 | } | |
3196 | ||
3197 | // If symbol is a vari able, ... | |
3198 | if (sym.kind == VAR) { | |
3199 | VarSymbo l v = (Var Symbol)sym ; | |
3200 | ||
3201 | // ..., evaluate i ts initial izer, if i t has one, and check for | |
3202 | // illeg al forward reference . | |
3203 | checkIni t(tree, en v, v, fals e); | |
3204 | ||
3205 | // If we are expec ting a var iable (as opposed to a value), check | |
3206 | // that the variab le is assi gnable in the curren t environm ent. | |
3207 | if (pkin d() == VAR ) | |
3208 | chec kAssignabl e(tree.pos (), v, nul l, env); | |
3209 | } | |
3210 | ||
3211 | // In a cons tructor bo dy, | |
3212 | // if symbol is a fiel d or insta nce method , check th at it is | |
3213 | // not acces sed before the super type const ructor is called. | |
3214 | if ((symEnv. info.isSel fCall || n oOuterThis Path) && | |
3215 | (sym.kin d & (VAR | MTH)) != 0 && | |
3216 | sym.owne r.kind == TYP && | |
3217 | (sym.fla gs() & STA TIC) == 0) { | |
3218 | chk.earl yRefError( tree.pos() , sym.kind == VAR ? sym : this Sym(tree.p os(), env) ); | |
3219 | } | |
3220 | En v<AttrCont ext> env1 = env; | |
3221 | if (sym.kind != ERR && sym.kind != TYP && sym.owner != null && sym.owner != env1.e nclClass.s ym) { | |
3222 | // If th e found sy mbol is in accessible , then it is | |
3223 | // acces sed throug h an enclo sing insta nce. Loca te this | |
3224 | // enclo sing insta nce: | |
3225 | while (e nv1.outer != null && !rs.isAcc essible(en v, env1.en clClass.sy m.type, sy m)) | |
3226 | env1 = env1.ou ter; | |
3227 | } | |
3228 | ||
3229 | if (env.info .isSeriali zable) { | |
3230 | chk.chec kElemAcces sFromSeria lizableLam bda(tree); | |
3231 | } | |
3232 | ||
3233 | re sult = che ckId(tree, env1.encl Class.sym. type, sym, env, resu ltInfo); | |
3234 | } | |
3235 | ||
3236 | public void visi tSelect(JC FieldAcces s tree) { | |
3237 | // Determine the expec ted kind o f the qual ifier expr ession. | |
3238 | in t skind = 0; | |
3239 | if (tree.nam e == names ._this || tree.name == names._ super || | |
3240 | tree.nam e == names ._class) | |
3241 | { | |
3242 | skind = TYP; | |
3243 | } else { | |
3244 | if ((pki nd() & PCK ) != 0) sk ind = skin d | PCK; | |
3245 | if ((pki nd() & TYP ) != 0) sk ind = skin d | TYP | PCK; | |
3246 | if ((pki nd() & (VA L | MTH)) != 0) skin d = skind | VAL | TY P; | |
3247 | } | |
3248 | ||
3249 | // Attribute the quali fier expre ssion, and determine its symbo l (if any) . | |
3250 | Ty pe site = attribTree (tree.sele cted, env, new Resul tInfo(skin d, Infer.a nyPoly)); | |
3251 | if ((pkind() & (PCK | TYP)) == 0 ) | |
3252 | site = c apture(sit e); // Cap ture field access | |
3253 | ||
3254 | // don't all ow T.class T[].class , etc | |
3255 | if (skind == TYP) { | |
3256 | Type elt = site; | |
3257 | while (e lt.hasTag( ARRAY)) | |
3258 | elt = ((ArrayT ype)elt.un annotatedT ype()).ele mtype; | |
3259 | if (elt. hasTag(TYP EVAR)) { | |
3260 | log. error(tree .pos(), "t ype.var.ca nt.be.dere f"); | |
3261 | resu lt = tree. type = typ es.createE rrorType(t ree.name, site.tsym, site); | |
3262 | tree .sym = tre e.type.tsy m; | |
3263 | retu rn ; | |
3264 | } | |
3265 | } | |
3266 | ||
3267 | // If qualif ier symbol is a type or `super ', assert `selectSup er' | |
3268 | // for the s election. This is re levant for determini ng whether | |
3269 | // protected symbols a re accessi ble. | |
3270 | Sy mbol sites ym = TreeI nfo.symbol (tree.sele cted); | |
3271 | bo olean sele ctSuperPre v = env.in fo.selectS uper; | |
3272 | en v.info.sel ectSuper = | |
3273 | sitesym != null && | |
3274 | sitesym. name == na mes._super ; | |
3275 | ||
3276 | // Determine the symbo l represen ted by the selection . | |
3277 | en v.info.pen dingResolu tionPhase = null; | |
3278 | Sy mbol sym = selectSym (tree, sit esym, site , env, res ultInfo); | |
3279 | if (sym.kind == VAR && sym.name != names._ super && e nv.info.de faultSuper CallSite ! = null) { | |
3280 | log.erro r(tree.sel ected.pos( ), "not.en cl.class", site.tsym ); | |
3281 | sym = sy ms.errSymb ol; | |
3282 | } | |
3283 | if (sym.exis ts() && !i sType(sym) && (pkind () & (PCK | TYP)) != 0) { | |
3284 | site = c apture(sit e); | |
3285 | sym = se lectSym(tr ee, sitesy m, site, e nv, result Info); | |
3286 | } | |
3287 | bo olean varA rgs = env. info.lastR esolveVara rgs(); | |
3288 | tr ee.sym = s ym; | |
3289 | ||
3290 | if (site.has Tag(TYPEVA R) && !isT ype(sym) & & sym.kind != ERR) { | |
3291 | while (s ite.hasTag (TYPEVAR)) site = si te.getUppe rBound(); | |
3292 | site = c apture(sit e); | |
3293 | } | |
3294 | ||
3295 | // If that s ymbol is a variable, ... | |
3296 | if (sym.kind == VAR) { | |
3297 | VarSymbo l v = (Var Symbol)sym ; | |
3298 | ||
3299 | // ..., evaluate i ts initial izer, if i t has one, and check for | |
3300 | // illeg al forward reference . | |
3301 | checkIni t(tree, en v, v, true ); | |
3302 | ||
3303 | // If we are expec ting a var iable (as opposed to a value), check | |
3304 | // that the variab le is assi gnable in the curren t environm ent. | |
3305 | if (pkin d() == VAR ) | |
3306 | chec kAssignabl e(tree.pos (), v, tre e.selected , env); | |
3307 | } | |
3308 | ||
3309 | if (sitesym != null && | |
3310 | site sym.kind = = VAR && | |
3311 | ((Va rSymbol)si tesym).isR esourceVar iable() && | |
3312 | sym. kind == MT H && | |
3313 | sym. name.equal s(names.cl ose) && | |
3314 | sym. overrides( syms.autoC loseableCl ose, sites ym.type.ts ym, types, true) && | |
3315 | env. info.lint. isEnabled( LintCatego ry.TRY)) { | |
3316 | log.warn ing(LintCa tegory.TRY , tree, "t ry.explici t.close.ca ll"); | |
3317 | } | |
3318 | ||
3319 | // Disallow selecting a type fro m an expre ssion | |
3320 | if (isType(s ym) && (si tesym==nul l || (site sym.kind&( TYP|PCK)) == 0)) { | |
3321 | tree.typ e = check( tree.selec ted, pt(), | |
3322 | sitesym == null ? VA L : sitesy m.kind, ne w ResultIn fo(TYP|PCK , pt())); | |
3323 | } | |
3324 | ||
3325 | if (isType(s itesym)) { | |
3326 | if (sym. name == na mes._this) { | |
3327 | // I f `C' is t he current ly compile d class, c heck that | |
3328 | // C .this' doe s not appe ar in a ca ll to a su per(...) | |
3329 | if ( env.info.i sSelfCall && | |
3330 | site.tsym == env.enc lClass.sym ) { | |
3331 | chk.earlyR efError(tr ee.pos(), sym); | |
3332 | } | |
3333 | } else { | |
3334 | // C heck if ty pe-qualifi ed fields or methods are stati c (JLS) | |
3335 | if ( (sym.flags () & STATI C) == 0 && | |
3336 | !env.next. tree.hasTa g(REFERENC E) && | |
3337 | sym.name ! = names._s uper && | |
3338 | (sym.kind == VAR || sym.kind = = MTH)) { | |
3339 | rs.accessB ase(rs.new StaticErr or(sym), | |
3340 | tree.pos() , site, sy m.name, tr ue); | |
3341 | } | |
3342 | } | |
3343 | if (!all owStaticIn terfaceMet hods && si tesym.isIn terface() && | |
3344 | sym.isStat ic() && sy m.kind == MTH) { | |
3345 | log. error(tree .pos(), "s tatic.intf .method.in voke.not.s upported.i n.source", sourceNam e); | |
3346 | } | |
3347 | } else if (s ym.kind != ERR && (s ym.flags() & STATIC) != 0 && s ym.name != names._cl ass) { | |
3348 | // If th e qualifie d item is not a type and the s elected it em is stat ic, report | |
3349 | // a war ning. Make allowance for the c lass of an array typ e e.g. Obj ect[].clas s) | |
3350 | chk.warn Static(tre e, "static .not.quali fied.by.ty pe", Kinds .kindName( sym.kind), sym.owner ); | |
3351 | } | |
3352 | ||
3353 | // If we are selecting an instan ce member via a `sup er', ... | |
3354 | if (env.info .selectSup er && (sym .flags() & STATIC) = = 0) { | |
3355 | ||
3356 | // Check that supe r-qualifie d symbols are not ab stract (JL S) | |
3357 | rs.check NonAbstrac t(tree.pos (), sym); | |
3358 | ||
3359 | if (site .isRaw()) { | |
3360 | // D etermine a rgument ty pes for si te. | |
3361 | Type site1 = t ypes.asSup er(env.enc lClass.sym .type, sit e.tsym); | |
3362 | if ( site1 != n ull) site = site1; | |
3363 | } | |
3364 | } | |
3365 | ||
3366 | if (env.info .isSeriali zable) { | |
3367 | chk.chec kElemAcces sFromSeria lizableLam bda(tree); | |
3368 | } | |
3369 | ||
3370 | en v.info.sel ectSuper = selectSup erPrev; | |
3371 | re sult = che ckId(tree, site, sym , env, res ultInfo); | |
3372 | } | |
3373 | //wher e | |
3374 | /* * Determin e symbol r eferenced by a Selec t expressi on, | |
3375 | * | |
3376 | * @param t ree The select tre e. | |
3377 | * @param s ite The type of th e selected expressio n, | |
3378 | * @param e nv The current en vironment. | |
3379 | * @param r esultInfo The curren t result. | |
3380 | * / | |
3381 | pr ivate Symb ol selectS ym(JCField Access tre e, | |
3382 | Symbol location, | |
3383 | Type si te, | |
3384 | Env<Att rContext> env, | |
3385 | ResultI nfo result Info) { | |
3386 | Diagnost icPosition pos = tre e.pos(); | |
3387 | Name nam e = tree.n ame; | |
3388 | switch ( site.getTa g()) { | |
3389 | case PAC KAGE: | |
3390 | retu rn rs.acce ssBase( | |
3391 | rs.findIde ntInPackag e(env, sit e.tsym, na me, result Info.pkind ), | |
3392 | pos, locat ion, site, name, tru e); | |
3393 | case ARR AY: | |
3394 | case CLA SS: | |
3395 | if ( resultInfo .pt.hasTag (METHOD) | | resultIn fo.pt.hasT ag(FORALL) ) { | |
3396 | return rs. resolveQua lifiedMeth od( | |
3397 | pos, e nv, locati on, site, name, resu ltInfo.pt. getParamet erTypes(), resultInf o.pt.getTy peArgument s()); | |
3398 | } el se if (nam e == names ._this || name == na mes._super ) { | |
3399 | return rs. resolveSel f(pos, env , site.tsy m, name); | |
3400 | } el se if (nam e == names ._class) { | |
3401 | // In this case, we have alrea dy made su re in | |
3402 | // visitSe lect that qualifier expression is a type . | |
3403 | Type t = s yms.classT ype; | |
3404 | List<Type> typeargs = allowGen erics | |
3405 | ? List .of(types. erasure(si te)) | |
3406 | : List .<Type>nil (); | |
3407 | t = new Cl assType(t. getEnclosi ngType(), typeargs, t.tsym); | |
3408 | return new VarSymbol ( | |
3409 | STATIC | PUBLIC | FINAL, n ames._clas s, t, site .tsym); | |
3410 | } el se { | |
3411 | // We are seeing a p lain ident ifier as s elector. | |
3412 | Symbol sym = rs.find IdentInTyp e(env, sit e, name, r esultInfo. pkind); | |
3413 | if ((resul tInfo.pkin d & ERRONE OUS) == 0) | |
3414 | sym = rs.accessB ase(sym, p os, locati on, site, name, true ); | |
3415 | return sym ; | |
3416 | } | |
3417 | case WIL DCARD: | |
3418 | thro w new Asse rtionError (tree); | |
3419 | case TYP EVAR: | |
3420 | // N ormally, s ite.getUpp erBound() shouldn't be null. | |
3421 | // I t should o nly happen during me mberEnter/ attribBase | |
3422 | // w hen determ ining the super type which *mu st* beac | |
3423 | // d one before attributi ng the typ e variable s. In | |
3424 | // o ther words , we are s eeing this illegal p rogram: | |
3425 | // c lass B<T> extends A< T.foo> {} | |
3426 | Symb ol sym = ( site.getUp perBound() != null) | |
3427 | ? selectSy m(tree, lo cation, ca pture(site .getUpperB ound()), e nv, result Info) | |
3428 | : null; | |
3429 | if ( sym == nul l) { | |
3430 | log.error( pos, "type .var.cant. be.deref") ; | |
3431 | return sym s.errSymbo l; | |
3432 | } el se { | |
3433 | Symbol sym 2 = (sym.f lags() & F lags.PRIVA TE) != 0 ? | |
3434 | rs.new AccessErr or(env, si te, sym) : | |
3435 | sym; | |
3436 | rs.accessB ase(sym2, pos, locat ion, site, name, tru e); | |
3437 | return sym ; | |
3438 | } | |
3439 | case ERR OR: | |
3440 | // p reserve id entifier n ames throu gh errors | |
3441 | retu rn types.c reateError Type(name, site.tsym , site).ts ym; | |
3442 | default: | |
3443 | // T he qualifi er express ion is of a primitiv e type -- only | |
3444 | // . class is a llowed for these. | |
3445 | if ( name == na mes._class ) { | |
3446 | // In this case, we have alrea dy made su re in Sele ct that | |
3447 | // qualifi er express ion is a t ype. | |
3448 | Type t = s yms.classT ype; | |
3449 | Type arg = types.box edClass(si te).type; | |
3450 | t = new Cl assType(t. getEnclosi ngType(), List.of(ar g), t.tsym ); | |
3451 | return new VarSymbol ( | |
3452 | STATIC | PUBLIC | FINAL, n ames._clas s, t, site .tsym); | |
3453 | } el se { | |
3454 | log.error( pos, "cant .deref", s ite); | |
3455 | return sym s.errSymbo l; | |
3456 | } | |
3457 | } | |
3458 | } | |
3459 | ||
3460 | /* * Determin e type of identifier or select expressio n and chec k that | |
3461 | * (1) the referenced symbol is not depre cated | |
3462 | * (2) the symbol's t ype is saf e (@see ch eckSafe) | |
3463 | * (3) if s ymbol is a variable, check tha t its type and kind are | |
3464 | * comp atible wit h the prot otype and protokind. | |
3465 | * (4) if s ymbol is a n instance field of a raw type , | |
3466 | * whic h is being assigned to, issue an uncheck ed warning if its | |
3467 | * type changes u nder erasu re. | |
3468 | * (5) if s ymbol is a n instance method of a raw typ e, issue a n | |
3469 | * unch ecked warn ing if its argument types chan ge under e rasure. | |
3470 | * If check s succeed: | |
3471 | * If sym bol is a c onstant, r eturn its constant t ype | |
3472 | * else i f symbol i s a method , return i ts result type | |
3473 | * otherw ise return its type. | |
3474 | * Otherwis e return e rrType. | |
3475 | * | |
3476 | * @param t ree The syntax tree repr esenting t he identif ier | |
3477 | * @param s ite If this is a select, the type of the sel ected | |
3478 | * expression , otherwis e the type of the cu rrent clas s. | |
3479 | * @param s ym The symbol represent ing the id entifier. | |
3480 | * @param e nv The curren t environm ent. | |
3481 | * @param r esultInfo The exp ected resu lt | |
3482 | * / | |
3483 | Ty pe checkId (JCTree tr ee, | |
3484 | Type site , | |
3485 | Symbol sy m, | |
3486 | Env<AttrC ontext> en v, | |
3487 | ResultInf o resultIn fo) { | |
3488 | return ( resultInfo .pt.hasTag (FORALL) | | resultIn fo.pt.hasT ag(METHOD) ) ? | |
3489 | checkMetho dId(tree, site, sym, env, resu ltInfo) : | |
3490 | checkIdInt ernal(tree , site, sy m, resultI nfo.pt, en v, resultI nfo); | |
3491 | } | |
3492 | ||
3493 | Ty pe checkMe thodId(JCT ree tree, | |
3494 | Type site , | |
3495 | Symbol sy m, | |
3496 | Env<AttrC ontext> en v, | |
3497 | ResultInf o resultIn fo) { | |
3498 | boolean isPolymorh icSignatur e = | |
3499 | (sym .baseSymbo l().flags( ) & SIGNAT URE_POLYMO RPHIC) != 0; | |
3500 | return i sPolymorhi cSignature ? | |
3501 | checkSigPo lyMethodId (tree, sit e, sym, en v, resultI nfo) : | |
3502 | checkMetho dIdInterna l(tree, si te, sym, e nv, result Info); | |
3503 | } | |
3504 | ||
3505 | Ty pe checkSi gPolyMetho dId(JCTree tree, | |
3506 | Type site , | |
3507 | Symbol sy m, | |
3508 | Env<AttrC ontext> en v, | |
3509 | ResultInf o resultIn fo) { | |
3510 | //recove r original symbol fo r signatur e polymorp hic method s | |
3511 | checkMet hodIdInter nal(tree, site, sym. baseSymbol (), env, r esultInfo) ; | |
3512 | env.info .pendingRe solutionPh ase = Reso lve.Method Resolution Phase.BASI C; | |
3513 | return s ym.type; | |
3514 | } | |
3515 | ||
3516 | Ty pe checkMe thodIdInte rnal(JCTre e tree, | |
3517 | Type site , | |
3518 | Symbol sy m, | |
3519 | Env<AttrC ontext> en v, | |
3520 | ResultInf o resultIn fo) { | |
3521 | if ((res ultInfo.pk ind & POLY ) != 0) { | |
3522 | Type pt = resu ltInfo.pt. map(deferr edAttr.new RecoveryD eferredTyp eMap(AttrM ode.SPECUL ATIVE, sym , env.info .pendingRe solutionPh ase)); | |
3523 | Type owntype = checkIdIn ternal(tre e, site, s ym, pt, en v, resultI nfo); | |
3524 | resu ltInfo.pt. map(deferr edAttr.new RecoveryD eferredTyp eMap(AttrM ode.CHECK, sym, env. info.pendi ngResoluti onPhase)); | |
3525 | retu rn owntype ; | |
3526 | } else { | |
3527 | retu rn checkId Internal(t ree, site, sym, resu ltInfo.pt, env, resu ltInfo); | |
3528 | } | |
3529 | } | |
3530 | ||
3531 | Ty pe checkId Internal(J CTree tree , | |
3532 | Type site , | |
3533 | Symbol sy m, | |
3534 | Type pt, | |
3535 | Env<AttrC ontext> en v, | |
3536 | ResultInf o resultIn fo) { | |
3537 | if (pt.i sErroneous ()) { | |
3538 | retu rn types.c reateError Type(site) ; | |
3539 | } | |
3540 | Type own type; // T he compute d type of this ident ifier occu rrence. | |
3541 | switch ( sym.kind) { | |
3542 | case TYP : | |
3543 | // F or types, the comput ed type eq uals the s ymbol's ty pe, | |
3544 | // e xcept for two situat ions: | |
3545 | ownt ype = sym. type; | |
3546 | if ( owntype.ha sTag(CLASS )) { | |
3547 | chk.checkF orBadAuxil iaryClassA ccess(tree .pos(), en v, (ClassS ymbol)sym) ; | |
3548 | Type ownOu ter = ownt ype.getEnc losingType (); | |
3549 | ||
3550 | // (a) If the symbol 's type is parameter ized, eras e it | |
3551 | // because no type p arameters were given . | |
3552 | // We reco ver generi c outer ty pe later i n visitTyp eApply. | |
3553 | if (owntyp e.tsym.typ e.getTypeA rguments() .nonEmpty( )) { | |
3554 | owntyp e = types. erasure(ow ntype); | |
3555 | } | |
3556 | ||
3557 | // (b) If the symbol 's type is an inner class, the n | |
3558 | // we have to interp ret its ou ter type a s a superc lass | |
3559 | // of the site type. Example: | |
3560 | // | |
3561 | // class T ree<A> { c lass Visit or { ... } } | |
3562 | // class P ointTree e xtends Tre e<Point> { ... } | |
3563 | // ...Poin tTree.Visi tor... | |
3564 | // | |
3565 | // Then th e type of the last e xpression above is | |
3566 | // Tree<Po int>.Visit or. | |
3567 | else if (o wnOuter.ha sTag(CLASS ) && site != ownOute r) { | |
3568 | Type n ormOuter = site; | |
3569 | if (no rmOuter.ha sTag(CLASS )) { | |
3570 | no rmOuter = types.asEn closingSup er(site, o wnOuter.ts ym); | |
3571 | } | |
3572 | if (no rmOuter == null) // perhaps fr om an impo rt | |
3573 | no rmOuter = types.eras ure(ownOut er); | |
3574 | if (no rmOuter != ownOuter) | |
3575 | ow ntype = ne w ClassTyp e( | |
3576 | normOute r, List.<T ype>nil(), owntype.t sym); | |
3577 | } | |
3578 | } | |
3579 | brea k; | |
3580 | case VAR : | |
3581 | VarS ymbol v = (VarSymbol )sym; | |
3582 | // T est (4): i f symbol i s an insta nce field of a raw t ype, | |
3583 | // w hich is be ing assign ed to, iss ue an unch ecked warn ing if | |
3584 | // i ts type ch anges unde r erasure. | |
3585 | if ( allowGener ics && | |
3586 | resultInfo .pkind == VAR && | |
3587 | v.owner.ki nd == TYP && | |
3588 | (v.flags() & STATIC) == 0 && | |
3589 | (site.hasT ag(CLASS) || site.ha sTag(TYPEV AR))) { | |
3590 | Type s = t ypes.asOut erSuper(si te, v.owne r); | |
3591 | if (s != n ull && | |
3592 | s.isRa w() && | |
3593 | !types .isSameTyp e(v.type, v.erasure( types))) { | |
3594 | chk.wa rnUnchecke d(tree.pos (), | |
3595 | "uncheck ed.assign. to.var", | |
3596 | v, s); | |
3597 | } | |
3598 | } | |
3599 | // T he compute d type of a variable is the ty pe of the | |
3600 | // v ariable sy mbol, take n as a mem ber of the site type . | |
3601 | ownt ype = (sym .owner.kin d == TYP & & | |
3602 | sym .name != n ames._this && sym.na me != name s._super) | |
3603 | ? types.me mberType(s ite, sym) | |
3604 | : sym.type ; | |
3605 | ||
3606 | // I f the vari able is a constant, record con stant valu e in | |
3607 | // c omputed ty pe. | |
3608 | if ( v.getConst Value() != null && i sStaticRef erence(tre e)) | |
3609 | owntype = owntype.co nstType(v. getConstVa lue()); | |
3610 | ||
3611 | if ( resultInfo .pkind == VAL) { | |
3612 | owntype = capture(ow ntype); // capture " names as e xpressions " | |
3613 | } | |
3614 | brea k; | |
3615 | case MTH : { | |
3616 | ownt ype = chec kMethod(si te, sym, | |
3617 | new Re sultInfo(r esultInfo. pkind, res ultInfo.pt .getReturn Type(), re sultInfo.c heckContex t), | |
3618 | env, T reeInfo.ar gs(env.tre e), result Info.pt.ge tParameter Types(), | |
3619 | result Info.pt.ge tTypeArgum ents()); | |
3620 | brea k; | |
3621 | } | |
3622 | case PCK : case ERR : | |
3623 | ownt ype = sym. type; | |
3624 | brea k; | |
3625 | default: | |
3626 | thro w new Asse rtionError ("unexpect ed kind: " + sym.kin d + | |
3627 | " in tree " + tree) ; | |
3628 | } | |
3629 | ||
3630 | // Test (1): emit a `depreca tion' warn ing if sym bol is dep recated. | |
3631 | // (for constructo rs, the er ror was gi ven when t he constru ctor was | |
3632 | // resol ved) | |
3633 | ||
3634 | if (sym. name != na mes.init) { | |
3635 | chk. checkDepre cated(tree .pos(), en v.info.sco pe.owner, sym); | |
3636 | chk. checkSunAP I(tree.pos (), sym); | |
3637 | chk. checkProfi le(tree.po s(), sym); | |
3638 | } | |
3639 | ||
3640 | // Test (3): if sy mbol is a variable, check that its type and | |
3641 | // kind are compat ible with the protot ype and pr otokind. | |
3642 | return c heck(tree, owntype, sym.kind, resultInfo ); | |
3643 | } | |
3644 | ||
3645 | /* * Check th at variabl e is initi alized and evaluate the variab le's | |
3646 | * initiali zer, if no t yet done . Also che ck that va riable is not | |
3647 | * referenc ed before it is defi ned. | |
3648 | * @param t ree The tree maki ng up the variable r eference. | |
3649 | * @param e nv The current e nvironment . | |
3650 | * @param v The variable' s symbol. | |
3651 | * / | |
3652 | pr ivate void checkInit (JCTree tr ee, | |
3653 | Env<AttrC ontext> en v, | |
3654 | VarSymbol v, | |
3655 | boolean o nlyWarning ) { | |
3656 | // System.e rr.println (v + " " + ((v.flags () & STATI C) != 0) + " " + | |
3657 | // tree.pos + " " + v. pos + " " + | |
3658 | // Resolve.i sStatic(en v));//DEBU G | |
3659 | ||
3660 | // A for ward refer ence is di agnosed if the decla ration pos ition | |
3661 | // of th e variable is greate r than the current t ree positi on | |
3662 | // and t he tree an d variable definitio n occur in the same class | |
3663 | // defin ition. No te that wr ites don't count as references . | |
3664 | // This check appl ies only t o class an d instance | |
3665 | // varia bles. Loc al variabl es follow different scope rule s, | |
3666 | // and a re subject to defini te assignm ent checki ng. | |
3667 | if ((env .info.encl Var == v | | v.pos > tree.pos) && | |
3668 | v.ow ner.kind = = TYP && | |
3669 | encl osingInitE nv(env) != null && | |
3670 | v.ow ner == env .info.scop e.owner.en clClass() && | |
3671 | ((v. flags() & STATIC) != 0) == Res olve.isSta tic(env) & & | |
3672 | (!en v.tree.has Tag(ASSIGN ) || | |
3673 | Tre eInfo.skip Parens(((J CAssign) e nv.tree).l hs) != tre e)) { | |
3674 | Stri ng suffix = (env.inf o.enclVar == v) ? | |
3675 | "self.re f" : "forw ard.ref"; | |
3676 | if ( !onlyWarni ng || isSt aticEnumFi eld(v)) { | |
3677 | log.error( tree.pos() , "illegal ." + suffi x); | |
3678 | } el se if (use BeforeDecl arationWar ning) { | |
3679 | log.warnin g(tree.pos (), suffix , v); | |
3680 | } | |
3681 | } | |
3682 | ||
3683 | v.getCon stValue(); // ensure initializ er is eval uated | |
3684 | ||
3685 | checkEnu mInitializ er(tree, e nv, v); | |
3686 | } | |
3687 | ||
3688 | /* * | |
3689 | * Returns t he enclosi ng init en vironment associated with this env (if a ny). An in it env | |
3690 | * can be ei ther a fie ld declara tion env o r a static /instance initialize r env. | |
3691 | * / | |
3692 | En v<AttrCont ext> enclo singInitEn v(Env<Attr Context> e nv) { | |
3693 | while (t rue) { | |
3694 | swit ch (env.tr ee.getTag( )) { | |
3695 | case
|
|
3696 | JCVari ableDecl v decl = (JC VariableDe cl)env.tre e; | |
3697 | if (vd ecl.sym.ow ner.kind = = TYP) { | |
3698 | // field | |
3699 | re turn env; | |
3700 | } | |
3701 | break; | |
3702 | case BLOCK : | |
3703 | if (en v.next.tre e.hasTag(C LASSDEF)) { | |
3704 | // instance/s tatic init ializer | |
3705 | re turn env; | |
3706 | } | |
3707 | break; | |
3708 | case METHO DDEF: | |
3709 | case CLASS DEF: | |
3710 | case TOPLE VEL: | |
3711 | return null; | |
3712 | } | |
3713 | Asse rt.checkNo nNull(env. next); | |
3714 | env = env.next ; | |
3715 | } | |
3716 | } | |
3717 | ||
3718 | /* * | |
3719 | * Check for illegal r eferences to static members of enum. In | |
3720 | * an enum t ype, const ructors an d initiali zers may n ot | |
3721 | * reference its stati c members unless the y are cons tant. | |
3722 | * | |
3723 | * @param tr ee The tree makin g up the v ariable re ference. | |
3724 | * @param en v The current en vironment. | |
3725 | * @param v The variable's symbol. | |
3726 | * @jls sec tion 8.9 E nums | |
3727 | * / | |
3728 | pr ivate void checkEnum Initialize r(JCTree t ree, Env<A ttrContext > env, Var Symbol v) { | |
3729 | // JLS: | |
3730 | // | |
3731 | // "It i s a compil e-time err or to refe rence a st atic field | |
3732 | // of an enum type that is n ot a compi le-time co nstant | |
3733 | // (15.2 8) from co nstructors , instance initializ er blocks, | |
3734 | // or in stance var iable init ializer ex pressions of that | |
3735 | // type. It is a c ompile-tim e error fo r the cons tructors, | |
3736 | // insta nce initia lizer bloc ks, or ins tance vari able | |
3737 | // initi alizer exp ressions o f an enum constant e to refer | |
3738 | // to it self or to an enum c onstant of the same type that | |
3739 | // is de clared to the right of e." | |
3740 | if (isSt aticEnumFi eld(v)) { | |
3741 | Clas sSymbol en clClass = env.info.s cope.owner .enclClass (); | |
3742 | ||
3743 | if ( enclClass == null || enclClass .owner == null) | |
3744 | return; | |
3745 | ||
3746 | // S ee if the enclosing class is t he enum (o r a | |
3747 | // s ubclass th ereof) dec laring v. If not, t his | |
3748 | // r eference i s OK. | |
3749 | if ( v.owner != enclClass && !types .isSubtype (enclClass .type, v.o wner.type) ) | |
3750 | return; | |
3751 | ||
3752 | // I f the refe rence isn' t from an initialize r, then | |
3753 | // t he referen ce is OK. | |
3754 | if ( !Resolve.i sInitializ er(env)) | |
3755 | return; | |
3756 | ||
3757 | log. error(tree .pos(), "i llegal.enu m.static.r ef"); | |
3758 | } | |
3759 | } | |
3760 | ||
3761 | /* * Is the g iven symbo l a static , non-cons tant field of an Enu m? | |
3762 | * Note: en um literal s should n ot be rega rded as su ch | |
3763 | * / | |
3764 | pr ivate bool ean isStat icEnumFiel d(VarSymbo l v) { | |
3765 | return F lags.isEnu m(v.owner) && | |
3766 | F lags.isSta tic(v) && | |
3767 | ! Flags.isCo nstant(v) && | |
3768 | v .name != n ames._clas s; | |
3769 | } | |
3770 | ||
3771 | Warner noteWarne r = new Wa rner(); | |
3772 | ||
3773 | /** | |
3774 | * Che ck that me thod argum ents confo rm to its instantiat ion. | |
3775 | **/ | |
3776 | public Type chec kMethod(Ty pe site, | |
3777 | fi nal Symbol sym, | |
3778 | Re sultInfo r esultInfo, | |
3779 | En v<AttrCont ext> env, | |
3780 | fi nal List<J CExpressio n> argtree s, | |
3781 | Li st<Type> a rgtypes, | |
3782 | Li st<Type> t ypeargtype s) { | |
3783 | // Test (5): if symbol is an ins tance meth od of a ra w type, is sue | |
3784 | // an unchec ked warnin g if its a rgument ty pes change under era sure. | |
3785 | if (allowGen erics && | |
3786 | (sym.fla gs() & STA TIC) == 0 && | |
3787 | (site.ha sTag(CLASS ) || site. hasTag(TYP EVAR))) { | |
3788 | Type s = types.asO uterSuper( site, sym. owner); | |
3789 | if (s != null && s .isRaw() & & | |
3790 | !typ es.isSameT ypes(sym.t ype.getPar ameterType s(), | |
3791 | sym.e rasure(typ es).getPar ameterType s())) { | |
3792 | chk. warnUnchec ked(env.tr ee.pos(), | |
3793 | "unche cked.call. mbr.of.raw .type", | |
3794 | sym, s ); | |
3795 | } | |
3796 | } | |
3797 | ||
3798 | if (env.info .defaultSu perCallSit e != null) { | |
3799 | for (Typ e sup : ty pes.interf aces(env.e nclClass.t ype).prepe nd(types.s upertype(( env.enclCl ass.type)) )) { | |
3800 | if ( !sup.tsym. isSubClass (sym.enclC lass(), ty pes) || | |
3801 | types. isSameType (sup, env. info.defau ltSuperCal lSite)) co ntinue; | |
3802 | List <MethodSym bol> icand _sup = | |
3803 | types. interfaceC andidates( sup, (Meth odSymbol)s ym); | |
3804 | if ( icand_sup. nonEmpty() && | |
3805 | icand_ sup.head ! = sym && | |
3806 | icand_ sup.head.o verrides(s ym, icand_ sup.head.e nclClass() , types, t rue)) { | |
3807 | log.error( env.tree.p os(), "ill egal.defau lt.super.c all", env. info.defau ltSuperCal lSite, | |
3808 | diags. fragment(" overridden .default", sym, sup) ); | |
3809 | break; | |
3810 | } | |
3811 | } | |
3812 | env.info .defaultSu perCallSit e = null; | |
3813 | } | |
3814 | ||
3815 | if (sym.isSt atic() && site.isInt erface() & & env.tree .hasTag(AP PLY)) { | |
3816 | JCMethod Invocation app = (JC MethodInvo cation)env .tree; | |
3817 | if (app. meth.hasTa g(SELECT) && | |
3818 | !TreeInfo. isStaticSe lector(((J CFieldAcce ss)app.met h).selecte d, names)) { | |
3819 | log. error(env. tree.pos() , "illegal .static.in tf.meth.ca ll", site) ; | |
3820 | } | |
3821 | } | |
3822 | ||
3823 | // Compute t he identif ier's inst antiated t ype. | |
3824 | // For metho ds, we nee d to compu te the ins tance type by | |
3825 | // Resolve.i nstantiate from the symbol's t ype as wel l as | |
3826 | // any type arguments and value arguments. | |
3827 | no teWarner.c lear(); | |
3828 | tr y { | |
3829 | Type own type = rs. checkMetho d( | |
3830 | env, | |
3831 | site, | |
3832 | sym, | |
3833 | resultInfo , | |
3834 | argtypes, | |
3835 | typeargtyp es, | |
3836 | noteWarner ); | |
3837 | ||
3838 | Deferred Attr.Defer redTypeMap checkDefe rredMap = | |
3839 | defe rredAttr.n ew Deferre dTypeMap(D eferredAtt r.AttrMode .CHECK, sy m, env.inf o.pendingR esolutionP hase); | |
3840 | ||
3841 | argtypes = Type.ma p(argtypes , checkDef erredMap); | |
3842 | ||
3843 | if (note Warner.has NonSilentL int(LintCa tegory.UNC HECKED)) { | |
3844 | chk. warnUnchec ked(env.tr ee.pos(), | |
3845 | "unche cked.meth. invocation .applied", | |
3846 | kindNa me(sym), | |
3847 | sym.na me, | |
3848 | rs.met hodArgumen ts(sym.typ e.getParam eterTypes( )), | |
3849 | rs.met hodArgumen ts(Type.ma p(argtypes , checkDef erredMap)) , | |
3850 | kindNa me(sym.loc ation()), | |
3851 | sym.lo cation()); | |
3852 | ownty pe = new M ethodType( owntype.ge tParameter Types(), | |
3853 | types.e rasure(own type.getRe turnType() ), | |
3854 | types.e rasure(own type.getTh rownTypes( )), | |
3855 | syms.me thodClass) ; | |
3856 | } | |
3857 | ||
3858 | return c hk.checkMe thod(ownty pe, sym, e nv, argtre es, argtyp es, env.in fo.lastRes olveVararg s(), | |
3859 | resultInfo .checkCont ext.infere nceContext ()); | |
3860 | } catch (Inf er.Inferen ceExceptio n ex) { | |
3861 | //invali d target t ype - prop agate exce ption outw ards or re port error | |
3862 | //depend ing on the current c heck conte xt | |
3863 | resultIn fo.checkCo ntext.repo rt(env.tre e.pos(), e x.getDiagn ostic()); | |
3864 | return t ypes.creat eErrorType (site); | |
3865 | } catch (Res olve.Inapp licableMet hodExcepti on ex) { | |
3866 | final JC Diagnostic diag = ex .getDiagno stic(); | |
3867 | Resolve. Inapplicab leSymbolEr ror errSym = rs.new Inapplicab leSymbolEr ror(null) { | |
3868 | @Ove rride | |
3869 | prot ected Pair <Symbol, J CDiagnosti c> errCand idate() { | |
3870 | return new Pair<Symb ol, JCDiag nostic>(sy m, diag); | |
3871 | } | |
3872 | }; | |
3873 | List<Typ e> argtype s2 = Type. map(argtyp es, | |
3874 | rs.new Res olveDeferr edRecovery Map(AttrMo de.CHECK, sym, env.i nfo.pendin gResolutio nPhase)); | |
3875 | JCDiagno stic errDi ag = errSy m.getDiagn ostic(JCDi agnostic.D iagnosticT ype.ERROR, | |
3876 | env.tree, sym, site, sym.name, argtypes2 , typeargt ypes); | |
3877 | log.repo rt(errDiag ); | |
3878 | return t ypes.creat eErrorType (site); | |
3879 | } | |
3880 | } | |
3881 | ||
3882 | public void visi tLiteral(J CLiteral t ree) { | |
3883 | re sult = che ck( | |
3884 | tree, li tType(tree .typetag). constType( tree.value ), VAL, re sultInfo); | |
3885 | } | |
3886 | //wher e | |
3887 | /** Re turn the t ype of a l iteral wit h given ty pe tag. | |
3888 | */ | |
3889 | Type l itType(Typ eTag tag) { | |
3890 | re turn (tag == CLASS) ? syms.str ingType : syms.typeO fTag[tag.o rdinal()]; | |
3891 | } | |
3892 | ||
3893 | public void visi tTypeIdent (JCPrimiti veTypeTree tree) { | |
3894 | re sult = che ck(tree, s yms.typeOf Tag[tree.t ypetag.ord inal()], T YP, result Info); | |
3895 | } | |
3896 | ||
3897 | public void visi tTypeArray (JCArrayTy peTree tre e) { | |
3898 | Ty pe etype = attribTyp e(tree.ele mtype, env ); | |
3899 | Ty pe type = new ArrayT ype(etype, syms.arra yClass); | |
3900 | re sult = che ck(tree, t ype, TYP, resultInfo ); | |
3901 | } | |
3902 | ||
3903 | /** Vi sitor meth od for par ameterized types. | |
3904 | * Bo und checki ng is left until lat er, since types are attributed | |
3905 | * be fore super type struc ture is co mpletely k nown | |
3906 | */ | |
3907 | public void visi tTypeApply (JCTypeApp ly tree) { | |
3908 | Ty pe owntype = types.c reateError Type(tree. type); | |
3909 | ||
3910 | // Attribute functor p art of app lication a nd make su re it's a class. | |
3911 | Ty pe clazzty pe = chk.c heckClassT ype(tree.c lazz.pos() , attribTy pe(tree.cl azz, env)) ; | |
3912 | ||
3913 | // Attribute type para meters | |
3914 | Li st<Type> a ctuals = a ttribTypes (tree.argu ments, env ); | |
3915 | ||
3916 | if (clazztyp e.hasTag(C LASS)) { | |
3917 | List<Typ e> formals = clazzty pe.tsym.ty pe.getType Arguments( ); | |
3918 | if (actu als.isEmpt y()) //dia mond | |
3919 | actu als = form als; | |
3920 | ||
3921 | if (actu als.length () == form als.length ()) { | |
3922 | List <Type> a = actuals; | |
3923 | List <Type> f = formals; | |
3924 | whil e (a.nonEm pty()) { | |
3925 | a.head = a .head.with TypeVar(f. head); | |
3926 | a = a.tail ; | |
3927 | f = f.tail ; | |
3928 | } | |
3929 | // C ompute the proper ge neric oute r | |
3930 | Type clazzOute r = clazzt ype.getEnc losingType (); | |
3931 | if ( clazzOuter .hasTag(CL ASS)) { | |
3932 | Type site; | |
3933 | JCExpressi on clazz = TreeInfo. typeIn(tre e.clazz); | |
3934 | if (clazz. hasTag(IDE NT)) { | |
3935 | site = env.enclC lass.sym.t ype; | |
3936 | } else if (clazz.has Tag(SELECT )) { | |
3937 | site = ((JCField Access) cl azz).selec ted.type; | |
3938 | } else thr ow new Ass ertionErro r(""+tree) ; | |
3939 | if (clazzO uter.hasTa g(CLASS) & & site != clazzOuter ) { | |
3940 | if (si te.hasTag( CLASS)) | |
3941 | si te = types .asOuterSu per(site, clazzOuter .tsym); | |
3942 | if (si te == null ) | |
3943 | si te = types .erasure(c lazzOuter) ; | |
3944 | clazzO uter = sit e; | |
3945 | } | |
3946 | } | |
3947 | ownt ype = new ClassType( clazzOuter , actuals, clazztype .tsym); | |
3948 | } else { | |
3949 | if ( formals.le ngth() != 0) { | |
3950 | log.error( tree.pos() , "wrong.n umber.type .args", | |
3951 | Integer.to String(for mals.lengt h())); | |
3952 | } el se { | |
3953 | log.error( tree.pos() , "type.do esnt.take. params", c lazztype.t sym); | |
3954 | } | |
3955 | ownt ype = type s.createEr rorType(tr ee.type); | |
3956 | } | |
3957 | } | |
3958 | re sult = che ck(tree, o wntype, TY P, resultI nfo); | |
3959 | } | |
3960 | ||
3961 | public void visi tTypeUnion (JCTypeUni on tree) { | |
3962 | Li stBuffer<T ype> multi catchTypes = new Lis tBuffer<>( ); | |
3963 | Li stBuffer<T ype> all_m ulticatchT ypes = nul l; // lazy , only if needed | |
3964 | fo r (JCExpre ssion type Tree : tre e.alternat ives) { | |
3965 | Type cty pe = attri bType(type Tree, env) ; | |
3966 | ctype = chk.checkT ype(typeTr ee.pos(), | |
3967 | chk. checkClass Type(typeT ree.pos(), ctype), | |
3968 | syms .throwable Type); | |
3969 | if (!cty pe.isErron eous()) { | |
3970 | //ch eck that a lternative s of a uni on type ar e pairwise | |
3971 | //un related w. r.t. subty ping | |
3972 | if ( chk.inters ects(ctype , multica tchTypes.t oList())) { | |
3973 | for (Type t : multic atchTypes) { | |
3974 | boolea n sub = ty pes.isSubt ype(ctype, t); | |
3975 | boolea n sup = ty pes.isSubt ype(t, cty pe); | |
3976 | if (su b || sup) { | |
3977 | // assume 'a' <: 'b' | |
3978 | Ty pe a = sub ? ctype : t; | |
3979 | Ty pe b = sub ? t : cty pe; | |
3980 | lo g.error(ty peTree.pos (), "multi catch.type s.must.be. disjoint", a, b); | |
3981 | } | |
3982 | } | |
3983 | } | |
3984 | mult icatchType s.append(c type); | |
3985 | if ( all_multic atchTypes != null) | |
3986 | all_multic atchTypes. append(cty pe); | |
3987 | } else { | |
3988 | if ( all_multic atchTypes == null) { | |
3989 | all_multic atchTypes = new List Buffer<>() ; | |
3990 | all_multic atchTypes. appendList (multicatc hTypes); | |
3991 | } | |
3992 | all_ multicatch Types.appe nd(ctype); | |
3993 | } | |
3994 | } | |
3995 | Ty pe t = che ck(noCheck Tree, type s.lub(mult icatchType s.toList() ), TYP, re sultInfo); | |
3996 | if (t.hasTag (CLASS)) { | |
3997 | List<Typ e> alterna tives = | |
3998 | ((al l_multicat chTypes == null) ? m ulticatchT ypes : all _multicatc hTypes).to List(); | |
3999 | t = new UnionClass Type((Clas sType) t, alternativ es); | |
4000 | } | |
4001 | tr ee.type = result = t ; | |
4002 | } | |
4003 | ||
4004 | public void visi tTypeInter section(JC TypeInters ection tre e) { | |
4005 | at tribTypes( tree.bound s, env); | |
4006 | tr ee.type = result = c heckInters ection(tre e, tree.bo unds); | |
4007 | } | |
4008 | ||
4009 | public void visi tTypeParam eter(JCTyp eParameter tree) { | |
4010 | Ty peVar type Var = (Typ eVar) tree .type; | |
4011 | ||
4012 | if (tree.ann otations ! = null && tree.annot ations.non Empty()) { | |
4013 | annotate Type(tree, tree.anno tations); | |
4014 | } | |
4015 | ||
4016 | if (!typeVar .bound.isE rroneous() ) { | |
4017 | //fixup type-param eter bound computed in 'attrib TypeVariab les' | |
4018 | typeVar. bound = ch eckInterse ction(tree , tree.bou nds); | |
4019 | } | |
4020 | } | |
4021 | ||
4022 | Type c heckInters ection(JCT ree tree, List<JCExp ression> b ounds) { | |
4023 | Se t<Type> bo undSet = n ew HashSet <Type>(); | |
4024 | if (bounds.n onEmpty()) { | |
4025 | // accep t class or interface or typeva r as first bound. | |
4026 | bounds.h ead.type = checkBase (bounds.he ad.type, b ounds.head , env, fal se, false, false); | |
4027 | boundSet .add(types .erasure(b ounds.head .type)); | |
4028 | if (boun ds.head.ty pe.isErron eous()) { | |
4029 | retu rn bounds. head.type; | |
4030 | } | |
4031 | else if (bounds.he ad.type.ha sTag(TYPEV AR)) { | |
4032 | // i f first bo und was a typevar, d o not acce pt further bounds. | |
4033 | if ( bounds.tai l.nonEmpty ()) { | |
4034 | log.error( bounds.tai l.head.pos (), | |
4035 | "type.var. may.not.be .followed. by.other.b ounds"); | |
4036 | return bou nds.head.t ype; | |
4037 | } | |
4038 | } else { | |
4039 | // i f first bo und was a class or i nterface, accept onl y interfac es | |
4040 | // a s further bounds. | |
4041 | for (JCExpress ion bound : bounds.t ail) { | |
4042 | bound.type = checkBa se(bound.t ype, bound , env, fal se, true, false); | |
4043 | if (bound. type.isErr oneous()) { | |
4044 | bounds = List.of (bound); | |
4045 | } | |
4046 | else if (b ound.type. hasTag(CLA SS)) { | |
4047 | chk.ch eckNotRepe ated(bound .pos(), ty pes.erasur e(bound.ty pe), bound Set); | |
4048 | } | |
4049 | } | |
4050 | } | |
4051 | } | |
4052 | ||
4053 | if (bounds.l ength() == 0) { | |
4054 | return s yms.object Type; | |
4055 | } else if (b ounds.leng th() == 1) { | |
4056 | return b ounds.head .type; | |
4057 | } else { | |
4058 | Type own type = typ es.makeInt ersectionT ype(TreeIn fo.types(b ounds)); | |
4059 | // ... t he variabl e's bound is a class type flag ged COMPOU ND | |
4060 | // (see comment fo r TypeVar. bound). | |
4061 | // In th is case, g enerate a class tree that repr esents the | |
4062 | // bound class, .. . | |
4063 | JCExpres sion exten ding; | |
4064 | List<JCE xpression> implement ing; | |
4065 | if (!bou nds.head.t ype.isInte rface()) { | |
4066 | exte nding = bo unds.head; | |
4067 | impl ementing = bounds.ta il; | |
4068 | } else { | |
4069 | exte nding = nu ll; | |
4070 | impl ementing = bounds; | |
4071 | } | |
4072 | JCClassD ecl cd = m ake.at(tre e).ClassDe f( | |
4073 | make .Modifiers (PUBLIC | ABSTRACT), | |
4074 | name s.empty, L ist.<JCTyp eParameter >nil(), | |
4075 | exte nding, imp lementing, List.<JCT ree>nil()) ; | |
4076 | ||
4077 | ClassSym bol c = (C lassSymbol )owntype.t sym; | |
4078 | Assert.c heck((c.fl ags() & CO MPOUND) != 0); | |
4079 | cd.sym = c; | |
4080 | c.source file = env .toplevel. sourcefile ; | |
4081 | ||
4082 | // ... a nd attribu te the bou nd class | |
4083 | c.flags_ field |= U NATTRIBUTE D; | |
4084 | Env<Attr Context> c env = ente r.classEnv (cd, env); | |
4085 | typeEnvs .put(c, ce nv); | |
4086 | attribCl ass(c); | |
4087 | return o wntype; | |
4088 | } | |
4089 | } | |
4090 | ||
4091 | public void visi tWildcard( JCWildcard tree) { | |
4092 | // - System.e rr.println ("visitWil dcard("+tr ee+");");/ /DEBUG | |
4093 | Ty pe type = (tree.kind .kind == B oundKind.U NBOUND) | |
4094 | ? syms.o bjectType | |
4095 | : attrib Type(tree. inner, env ); | |
4096 | re sult = che ck(tree, n ew Wildcar dType(chk. checkRefTy pe(tree.po s(), type) , | |
4097 | tree .kind.kind , | |
4098 | syms .boundClas s), | |
4099 | TYP, re sultInfo); | |
4100 | } | |
4101 | ||
4102 | public void visi tAnnotatio n(JCAnnota tion tree) { | |
4103 | As sert.error ("should b e handled in Annotat e"); | |
4104 | } | |
4105 | ||
4106 | public void visi tAnnotated Type(JCAnn otatedType tree) { | |
4107 | Ty pe underly ingType = attribType (tree.getU nderlyingT ype(), env ); | |
4108 | th is.attribA nnotationT ypes(tree. annotation s, env); | |
4109 | an notateType (tree, tre e.annotati ons); | |
4110 | re sult = tre e.type = u nderlyingT ype; | |
4111 | } | |
4112 | ||
4113 | /** | |
4114 | * App ly the ann otations t o the part icular typ e. | |
4115 | */ | |
4116 | public void anno tateType(f inal JCTre e tree, fi nal List<J CAnnotatio n> annotat ions) { | |
4117 | an notate.typ eAnnotatio n(new Anno tate.Worke r() { | |
4118 | @Overrid e | |
4119 | public S tring toSt ring() { | |
4120 | retu rn "annota te " + ann otations + " onto " + tree; | |
4121 | } | |
4122 | @Overrid e | |
4123 | public v oid run() { | |
4124 | List <Attribute .TypeCompo und> compo unds = fro mAnnotatio ns(annotat ions); | |
4125 | if ( annotation s.size() = = compound s.size()) { | |
4126 | // All ann otations w ere succes sfully con verted int o compound s | |
4127 | tree.type = tree.typ e.unannota tedType(). annotatedT ype(compou nds); | |
4128 | } | |
4129 | } | |
4130 | }) ; | |
4131 | } | |
4132 | ||
4133 | privat e static L ist<Attrib ute.TypeCo mpound> fr omAnnotati ons(List<J CAnnotatio n> annotat ions) { | |
4134 | if (annotati ons.isEmpt y()) { | |
4135 | return L ist.nil(); | |
4136 | } | |
4137 | ||
4138 | Li stBuffer<A ttribute.T ypeCompoun d> buf = n ew ListBuf fer<>(); | |
4139 | fo r (JCAnnot ation anno : annotat ions) { | |
4140 | if (anno .attribute != null) { | |
4141 | // T ODO: this null-check is only n eeded for an obscure | |
4142 | // o rdering is sue, where annotate. flush is c alled when | |
4143 | // t he attribu te is not set yet. F or an exam ple failur e | |
4144 | // t ry the ref erenceinfo s/NestedTy pes.java t est. | |
4145 | // A ny better solutions? | |
4146 | buf. append((At tribute.Ty peCompound ) anno.att ribute); | |
4147 | } | |
4148 | // Event ually we w ill want t o throw an exception here, but | |
4149 | // we ca n't do tha t just yet , because it gets tr iggered | |
4150 | // when attempting to attach an annota tion that isn't | |
4151 | // defin ed. | |
4152 | } | |
4153 | re turn buf.t oList(); | |
4154 | } | |
4155 | ||
4156 | public void visi tErroneous (JCErroneo us tree) { | |
4157 | if (tree.err s != null) | |
4158 | for (JCT ree err : tree.errs) | |
4159 | attr ibTree(err , env, new ResultInf o(ERR, pt( ))); | |
4160 | re sult = tre e.type = s yms.errTyp e; | |
4161 | } | |
4162 | ||
4163 | /** De fault visi tor method for all o ther trees . | |
4164 | */ | |
4165 | public void visi tTree(JCTr ee tree) { | |
4166 | th row new As sertionErr or(); | |
4167 | } | |
4168 | ||
4169 | /** | |
4170 | * Att ribute an env for ei ther a top level tre e or class declarati on. | |
4171 | */ | |
4172 | public void attr ib(Env<Att rContext> env) { | |
4173 | if (env.tree .hasTag(TO PLEVEL)) | |
4174 | attribTo pLevel(env ); | |
4175 | el se | |
4176 | attribCl ass(env.tr ee.pos(), env.enclCl ass.sym); | |
4177 | } | |
4178 | ||
4179 | /** | |
4180 | * Att ribute a t op level t ree. These trees are encounter ed when th e | |
4181 | * pac kage decla ration has annotatio ns. | |
4182 | */ | |
4183 | public void attr ibTopLevel (Env<AttrC ontext> en v) { | |
4184 | JC Compilatio nUnit topl evel = env .toplevel; | |
4185 | tr y { | |
4186 | annotate .flush(); | |
4187 | } catch (Com pletionFai lure ex) { | |
4188 | chk.comp letionErro r(toplevel .pos(), ex ); | |
4189 | } | |
4190 | } | |
4191 | ||
4192 | /** Ma in method: attribute class def inition as sociated w ith given class symb ol. | |
4193 | * re porting co mpletion f ailures at the given position. | |
4194 | * @p aram pos T he source position a t which co mpletion e rrors are to be | |
4195 | * r eported. | |
4196 | * @p aram c T he class s ymbol whos e definiti on will be attribute d. | |
4197 | */ | |
4198 | public void attr ibClass(Di agnosticPo sition pos , ClassSym bol c) { | |
4199 | tr y { | |
4200 | annotate .flush(); | |
4201 | attribCl ass(c); | |
4202 | } catch (Com pletionFai lure ex) { | |
4203 | chk.comp letionErro r(pos, ex) ; | |
4204 | } | |
4205 | } | |
4206 | ||
4207 | /** At tribute cl ass defini tion assoc iated with given cla ss symbol. | |
4208 | * @p aram c T he class s ymbol whos e definiti on will be attribute d. | |
4209 | */ | |
4210 | void a ttribClass (ClassSymb ol c) thro ws Complet ionFailure { | |
4211 | if (c.type.h asTag(ERRO R)) return ; | |
4212 | ||
4213 | // Check for cycles in the inher itance gra ph, which can arise from | |
4214 | // ill-forme d class fi les. | |
4215 | ch k.checkNon Cyclic(nul l, c.type) ; | |
4216 | ||
4217 | Ty pe st = ty pes.supert ype(c.type ); | |
4218 | if ((c.flags _field & F lags.COMPO UND) == 0) { | |
4219 | // First , attribut e supercla ss. | |
4220 | if (st.h asTag(CLAS S)) | |
4221 | attr ibClass((C lassSymbol )st.tsym); | |
4222 | ||
4223 | // Next attribute owner, if it is a cl ass. | |
4224 | if (c.ow ner.kind = = TYP && c .owner.typ e.hasTag(C LASS)) | |
4225 | attr ibClass((C lassSymbol )c.owner); | |
4226 | } | |
4227 | ||
4228 | // The previ ous operat ions might have attr ibuted the current c lass | |
4229 | // if there was a cycl e. So we t est first whether th e class is still | |
4230 | // UNATTRIBU TED. | |
4231 | if ((c.flags _field & U NATTRIBUTE D) != 0) { | |
4232 | c.flags_ field &= ~ UNATTRIBUT ED; | |
4233 | ||
4234 | // Get e nvironment current a t the poin t of class definitio n. | |
4235 | Env<Attr Context> e nv = typeE nvs.get(c) ; | |
4236 | ||
4237 | // The i nfo.lint f ield in th e envs sto red in typ eEnvs is d eliberatel y uninitia lized, | |
4238 | // becau se the ann otations w ere not av ailable at the time the env wa s created. Therefore , | |
4239 | // we lo ok up the environmen t chain fo r the firs t enclosin g environm ent for wh ich the | |
4240 | // lint value is s et. Typica lly, this is the par ent env, b ut might b e further if there | |
4241 | // are a ny envs cr eated as a result of TypeParam eter nodes . | |
4242 | Env<Attr Context> l intEnv = e nv; | |
4243 | while (l intEnv.inf o.lint == null) | |
4244 | lint Env = lint Env.next; | |
4245 | ||
4246 | // Havin g found th e enclosin g lint val ue, we can initializ e the lint value for this clas s | |
4247 | env.info .lint = li ntEnv.info .lint.augm ent(c); | |
4248 | ||
4249 | Lint pre vLint = ch k.setLint( env.info.l int); | |
4250 | JavaFile Object pre v = log.us eSource(c. sourcefile ); | |
4251 | ResultIn fo prevRet urnRes = e nv.info.re turnResult ; | |
4252 | ||
4253 | try { | |
4254 | defe rredLintHa ndler.flus h(env.tree ); | |
4255 | env. info.retur nResult = null; | |
4256 | // j ava.lang.E num may no t be subcl assed by a non-enum | |
4257 | if ( st.tsym == syms.enum Sym && | |
4258 | ((c.flags_ field & (F lags.ENUM| Flags.COMP OUND)) == 0)) | |
4259 | log.error( env.tree.p os(), "enu m.no.subcl assing"); | |
4260 | ||
4261 | // E nums may n ot be exte nded by so urce-level classes | |
4262 | if ( st.tsym != null && | |
4263 | ((st.tsym. flags_fiel d & Flags. ENUM) != 0 ) && | |
4264 | ((c.flags_ field & (F lags.ENUM | Flags.CO MPOUND)) = = 0)) { | |
4265 | log.error( env.tree.p os(), "enu m.types.no t.extensib le"); | |
4266 | } | |
4267 | ||
4268 | if ( isSerializ able(c.typ e)) { | |
4269 | env.info.i sSerializa ble = true ; | |
4270 | } | |
4271 | ||
4272 | attr ibClassBod y(env, c); | |
4273 | ||
4274 | chk. checkDepre catedAnnot ation(env. tree.pos() , c); | |
4275 | chk. checkClass OverrideEq ualsAndHas hIfNeeded( env.tree.p os(), c); | |
4276 | chk. checkFunct ionalInter face((JCCl assDecl) e nv.tree, c ); | |
4277 | } finall y { | |
4278 | env. info.retur nResult = prevReturn Res; | |
4279 | log. useSource( prev); | |
4280 | chk. setLint(pr evLint); | |
4281 | } | |
4282 | ||
4283 | } | |
4284 | } | |
4285 | ||
4286 | public void visi tImport(JC Import tre e) { | |
4287 | // nothing t o do | |
4288 | } | |
4289 | ||
4290 | /** Fi nish the a ttribution of a clas s. */ | |
4291 | privat e void att ribClassBo dy(Env<Att rContext> env, Class Symbol c) { | |
4292 | JC ClassDecl tree = (JC ClassDecl) env.tree; | |
4293 | As sert.check (c == tree .sym); | |
4294 | ||
4295 | // Validate type param eters, sup ertype and interface s. | |
4296 | at tribStats( tree.typar ams, env); | |
4297 | if (!c.isAno nymous()) { | |
4298 | //alread y checked if anonymo us | |
4299 | chk.vali date(tree. typarams, env); | |
4300 | chk.vali date(tree. extending, env); | |
4301 | chk.vali date(tree. implementi ng, env); | |
4302 | } | |
4303 | ||
4304 | c. markAbstra ctIfNeeded (types); | |
4305 | ||
4306 | // If this i s a non-ab stract cla ss, check that it ha s no abstr act | |
4307 | // methods o r unimplem ented meth ods of an implemente d interfac e. | |
4308 | if ((c.flags () & (ABST RACT | INT ERFACE)) = = 0) { | |
4309 | if (!rel ax) | |
4310 | chk. checkAllDe fined(tree .pos(), c) ; | |
4311 | } | |
4312 | ||
4313 | if ((c.flags () & ANNOT ATION) != 0) { | |
4314 | if (tree .implement ing.nonEmp ty()) | |
4315 | log. error(tree .implement ing.head.p os(), | |
4316 | "can t.extend.i ntf.annota tion"); | |
4317 | if (tree .typarams. nonEmpty() ) | |
4318 | log. error(tree .typarams. head.pos() , | |
4319 | "int f.annotati on.cant.ha ve.type.pa rams"); | |
4320 | ||
4321 | // If th is annotat ion has a @Repeatabl e, validat e | |
4322 | Attribut e.Compound repeatabl e = c.attr ibute(syms .repeatabl eType.tsym ); | |
4323 | if (repe atable != null) { | |
4324 | // g et diagnos tic positi on for err or reporti ng | |
4325 | Diag nosticPosi tion cbPos = getDiag nosticPosi tion(tree, repeatabl e.type); | |
4326 | Asse rt.checkNo nNull(cbPo s); | |
4327 | ||
4328 | chk. validateRe peatable(c , repeatab le, cbPos) ; | |
4329 | } | |
4330 | } else { | |
4331 | // Check that all extended c lasses and interface s | |
4332 | // are c ompatible (i.e. no t wo define methods wi th same ar guments | |
4333 | // yet d ifferent r eturn type s). (JLS 8.4.6.3) | |
4334 | chk.chec kCompatibl eSupertype s(tree.pos (), c.type ); | |
4335 | if (allo wDefaultMe thods) { | |
4336 | chk. checkDefau ltMethodCl ashes(tree .pos(), c. type); | |
4337 | } | |
4338 | } | |
4339 | ||
4340 | // Check tha t class do es not imp ort the sa me paramet erized int erface | |
4341 | // with two different argument l ists. | |
4342 | ch k.checkCla ssBounds(t ree.pos(), c.type); | |
4343 | ||
4344 | tr ee.type = c.type; | |
4345 | ||
4346 | fo r (List<JC TypeParame ter> l = t ree.typara ms; | |
4347 | l.nonEm pty(); l = l.tail) { | |
4348 | Assert. checkNonNu ll(env.inf o.scope.lo okup(l.hea d.name).sc ope); | |
4349 | } | |
4350 | ||
4351 | // Check tha t a generi c class do esn't exte nd Throwab le | |
4352 | if (!c.type. allparams( ).isEmpty( ) && types .isSubtype (c.type, s yms.throwa bleType)) | |
4353 | log.erro r(tree.ext ending.pos (), "gener ic.throwab le"); | |
4354 | ||
4355 | // Check tha t all meth ods which implement some | |
4356 | // method co nform to t he method they imple ment. | |
4357 | ch k.checkImp lementatio ns(tree); | |
4358 | ||
4359 | // check that a resourc e implemen ting AutoC loseable c annot thro w Interrup tedExcepti on | |
4360 | ch eckAutoClo seable(tre e.pos(), e nv, c.type ); | |
4361 | ||
4362 | fo r (List<JC Tree> l = tree.defs; l.nonEmpt y(); l = l .tail) { | |
4363 | // Attri bute decla ration | |
4364 | attribSt at(l.head, env); | |
4365 | // Check that decl arations i n inner cl asses are not static (JLS 8.1. 2) | |
4366 | // Make an excepti on for sta tic consta nts. | |
4367 | if (c.ow ner.kind ! = PCK && | |
4368 | ((c. flags() & STATIC) == 0 || c.na me == name s.empty) & & | |
4369 | (Tre eInfo.flag s(l.head) & (STATIC | INTERFAC E)) != 0) { | |
4370 | Symb ol sym = n ull; | |
4371 | if (l.head .hasTag(
|
|
4372 | if ( sym == nul l || | |
4373 | sym.kind ! = VAR || | |
4374 | ((VarSymbo l) sym).ge tConstValu e() == nul l) | |
4375 | log.error( l.head.pos (), "icls. cant.have. static.dec l", c); | |
4376 | } | |
4377 | } | |
4378 | ||
4379 | // Check for cycles am ong non-in itial cons tructors. | |
4380 | ch k.checkCyc licConstru ctors(tree ); | |
4381 | ||
4382 | // Check for cycles am ong annota tion eleme nts. | |
4383 | ch k.checkNon CyclicElem ents(tree) ; | |
4384 | ||
4385 | // Check for proper us e of seria lVersionUI D | |
4386 | if (env.info .lint.isEn abled(Lint Category.S ERIAL) && | |
4387 | isSerial izable(c.t ype) && | |
4388 | (c.flags () & Flags .ENUM) == 0 && | |
4389 | checkFor Serial(c)) { | |
4390 | checkSer ialVersion UID(tree, c); | |
4391 | } | |
4392 | if (allowTyp eAnnos) { | |
4393 | // Corre ctly organ ize the po stions of the type a nnotations | |
4394 | typeAnno tations.or ganizeType Annotation sBodies(tr ee); | |
4395 | ||
4396 | // Check type anno tations ap plicabilit y rules | |
4397 | validate TypeAnnota tions(tree , false); | |
4398 | } | |
4399 | } | |
4400 | // where | |
4401 | bo olean chec kForSerial (ClassSymb ol c) { | |
4402 | if ((c.f lags() & A BSTRACT) = = 0) { | |
4403 | retu rn true; | |
4404 | } else { | |
4405 | retu rn c.membe rs().anyMa tch(anyNon AbstractOr DefaultMet hod); | |
4406 | } | |
4407 | } | |
4408 | ||
4409 | pu blic stati c final Fi lter<Symbo l> anyNonA bstractOrD efaultMeth od = new F ilter<Symb ol>() { | |
4410 | @Overrid e | |
4411 | public b oolean acc epts(Symbo l s) { | |
4412 | retu rn s.kind == Kinds.M TH && | |
4413 | (s.flag s() & (DEF AULT | ABS TRACT)) != ABSTRACT; | |
4414 | } | |
4415 | }; | |
4416 | ||
4417 | /* * get a di agnostic p osition fo r an attri bute of Ty pe t, or n ull if att ribute mis sing */ | |
4418 | pr ivate Diag nosticPosi tion getDi agnosticPo sition(JCC lassDecl t ree, Type t) { | |
4419 | for(List <JCAnnotat ion> al = tree.mods. annotation s; !al.isE mpty(); al = al.tail ) { | |
4420 | if ( types.isSa meType(al. head.annot ationType. type, t)) | |
4421 | return al. head.pos() ; | |
4422 | } | |
4423 | ||
4424 | return n ull; | |
4425 | } | |
4426 | ||
4427 | /* * check if a type is a subtype of Serial izable, if that is a vailable. */ | |
4428 | bo olean isSe rializable (Type t) { | |
4429 | try { | |
4430 | syms .serializa bleType.co mplete(); | |
4431 | } | |
4432 | catch (C ompletionF ailure e) { | |
4433 | retu rn false; | |
4434 | } | |
4435 | return t ypes.isSub type(t, sy ms.seriali zableType) ; | |
4436 | } | |
4437 | ||
4438 | /* * Check th at an appr opriate se rialVersio nUID membe r is defin ed. */ | |
4439 | pr ivate void checkSeri alVersionU ID(JCClass Decl tree, ClassSymb ol c) { | |
4440 | ||
4441 | // check for prese nce of ser ialVersion UID | |
4442 | Scope.En try e = c. members(). lookup(nam es.serialV ersionUID) ; | |
4443 | while (e .scope != null && e. sym.kind ! = VAR) e = e.next(); | |
4444 | if (e.sc ope == nul l) { | |
4445 | log. warning(Li ntCategory .SERIAL, | |
4446 | tree.p os(), "mis sing.SVUID ", c); | |
4447 | retu rn; | |
4448 | } | |
4449 | ||
4450 | // check that it i s static f inal | |
4451 | VarSymbo l svuid = (VarSymbol )e.sym; | |
4452 | if ((svu id.flags() & (STATIC | FINAL)) != | |
4453 | (STA TIC | FINA L)) | |
4454 | log. warning(Li ntCategory .SERIAL, | |
4455 | TreeIn fo.diagnos ticPositio nFor(svuid , tree), " improper.S VUID", c); | |
4456 | ||
4457 | // check that it i s long | |
4458 | else if (!svuid.ty pe.hasTag( LONG)) | |
4459 | log. warning(Li ntCategory .SERIAL, | |
4460 | TreeIn fo.diagnos ticPositio nFor(svuid , tree), " long.SVUID ", c); | |
4461 | ||
4462 | // check constant | |
4463 | else if (svuid.get ConstValue () == null ) | |
4464 | log. warning(Li ntCategory .SERIAL, | |
4465 | TreeIn fo.diagnos ticPositio nFor(svuid , tree), " constant.S VUID", c); | |
4466 | } | |
4467 | ||
4468 | privat e Type cap ture(Type type) { | |
4469 | re turn types .capture(t ype); | |
4470 | } | |
4471 | ||
4472 | public void vali dateTypeAn notations( JCTree tre e, boolean sigOnly) { | |
4473 | tr ee.accept( new TypeAn notationsV alidator(s igOnly)); | |
4474 | } | |
4475 | //wher e | |
4476 | privat e final cl ass TypeAn notationsV alidator e xtends Tre eScanner { | |
4477 | ||
4478 | pr ivate fina l boolean sigOnly; | |
4479 | pu blic TypeA nnotations Validator( boolean si gOnly) { | |
4480 | this.sig Only = sig Only; | |
4481 | } | |
4482 | ||
4483 | pu blic void visitAnnot ation(JCAn notation t ree) { | |
4484 | chk.vali dateTypeAn notation(t ree, false ); | |
4485 | super.vi sitAnnotat ion(tree); | |
4486 | } | |
4487 | pu blic void visitAnnot atedType(J CAnnotated Type tree) { | |
4488 | if (!tre e.underlyi ngType.typ e.isErrone ous()) { | |
4489 | supe r.visitAnn otatedType (tree); | |
4490 | } | |
4491 | } | |
4492 | pu blic void visitTypeP arameter(J CTypeParam eter tree) { | |
4493 | chk.vali dateTypeAn notations( tree.annot ations, tr ue); | |
4494 | scan(tre e.bounds); | |
4495 | // Don't call supe r. | |
4496 | // This is needed because ab ove we cal l validate TypeAnnota tion with | |
4497 | // false , which wo uld forbid annotatio ns on type parameter s. | |
4498 | // super .visitType Parameter( tree); | |
4499 | } | |
4500 | pu blic void visitMetho dDef(JCMet hodDecl tr ee) { | |
4501 | if (tree .recvparam != null & & | |
4502 | !tree.recv param.vart ype.type.i sErroneous ()) { | |
4503 | chec kForDeclar ationAnnot ations(tre e.recvpara m.mods.ann otations, | |
4504 | tree.r ecvparam.v artype.typ e.tsym); | |
4505 | } | |
4506 | if (tree .restype ! = null && tree.resty pe.type != null) { | |
4507 | vali dateAnnota tedType(tr ee.restype , tree.res type.type) ; | |
4508 | } | |
4509 | if (sigO nly) { | |
4510 | scan (tree.mods ); | |
4511 | scan (tree.rest ype); | |
4512 | scan (tree.typa rams); | |
4513 | scan (tree.recv param); | |
4514 | scan (tree.para ms); | |
4515 | scan (tree.thro wn); | |
4516 | } else { | |
4517 | scan (tree.defa ultValue); | |
4518 | scan (tree.body ); | |
4519 | } | |
4520 | } | |
4521 | pu blic void visitVarDe f(final JC VariableDe cl tree) { | |
4522 | if (tree .sym != nu ll && tree .sym.type != null) | |
4523 | vali dateAnnota tedType(tr ee.vartype , tree.sym .type); | |
4524 | scan(tre e.mods); | |
4525 | scan(tre e.vartype) ; | |
4526 | if (!sig Only) { | |
4527 | scan (tree.init ); | |
4528 | } | |
4529 | } | |
4530 | pu blic void visitTypeC ast(JCType Cast tree) { | |
4531 | if (tree .clazz != null && tr ee.clazz.t ype != nul l) | |
4532 | vali dateAnnota tedType(tr ee.clazz, tree.clazz .type); | |
4533 | super.vi sitTypeCas t(tree); | |
4534 | } | |
4535 | pu blic void visitTypeT est(JCInst anceOf tre e) { | |
4536 | if (tree .clazz != null && tr ee.clazz.t ype != nul l) | |
4537 | vali dateAnnota tedType(tr ee.clazz, tree.clazz .type); | |
4538 | super.vi sitTypeTes t(tree); | |
4539 | } | |
4540 | pu blic void visitNewCl ass(JCNewC lass tree) { | |
4541 | if (tree .clazz != null && tr ee.clazz.t ype != nul l) { | |
4542 | if ( tree.clazz .hasTag(AN NOTATED_TY PE)) { | |
4543 | checkForDe clarationA nnotations (((JCAnnot atedType) tree.clazz ).annotati ons, | |
4544 | tr ee.clazz.t ype.tsym); | |
4545 | } | |
4546 | if ( tree.def ! = null) { | |
4547 | checkForDe clarationA nnotations (tree.def. mods.annot ations, tr ee.clazz.t ype.tsym); | |
4548 | } | |
4549 | ||
4550 | vali dateAnnota tedType(tr ee.clazz, tree.clazz .type); | |
4551 | } | |
4552 | super.vi sitNewClas s(tree); | |
4553 | } | |
4554 | pu blic void visitNewAr ray(JCNewA rray tree) { | |
4555 | if (tree .elemtype != null && tree.elem type.type != null) { | |
4556 | if ( tree.elemt ype.hasTag (ANNOTATED _TYPE)) { | |
4557 | checkForDe clarationA nnotations (((JCAnnot atedType) tree.elemt ype).annot ations, | |
4558 | tr ee.elemtyp e.type.tsy m); | |
4559 | } | |
4560 | vali dateAnnota tedType(tr ee.elemtyp e, tree.el emtype.typ e); | |
4561 | } | |
4562 | super.vi sitNewArra y(tree); | |
4563 | } | |
4564 | pu blic void visitClass Def(JCClas sDecl tree ) { | |
4565 | if (sigO nly) { | |
4566 | scan (tree.mods ); | |
4567 | scan (tree.typa rams); | |
4568 | scan (tree.exte nding); | |
4569 | scan (tree.impl ementing); | |
4570 | } | |
4571 | for (JCT ree member : tree.de fs) { | |
4572 | if ( member.has Tag(Tag.CL ASSDEF)) { | |
4573 | continue; | |
4574 | } | |
4575 | scan (member); | |
4576 | } | |
4577 | } | |
4578 | pu blic void visitBlock (JCBlock t ree) { | |
4579 | if (!sig Only) { | |
4580 | scan (tree.stat s); | |
4581 | } | |
4582 | } | |
4583 | ||
4584 | /* I would w ant to mod el this af ter | |
4585 | * com.sun.t ools.javac .comp.Chec k.Validato r.visitSel ectInterna l(JCFieldA ccess) | |
4586 | * and overr ide visitS elect and visitTypeA pply. | |
4587 | * However, we only se t the anno tated type in the to p-level ty pe | |
4588 | * of the sy mbol. | |
4589 | * Therefore , we need to overrid e each ind ividual lo cation whe re a type | |
4590 | * can occur . | |
4591 | * / | |
4592 | pr ivate void validateA nnotatedTy pe(final J CTree errt ree, final Type type ) { | |
4593 | // Syste m.out.prin tln("Attr. validateAn notatedTyp e: " + err tree + " t ype: " + t ype); | |
4594 | ||
4595 | if (type .isPrimiti veOrVoid() ) { | |
4596 | retu rn; | |
4597 | } | |
4598 | ||
4599 | JCTree e nclTr = er rtree; | |
4600 | Type enc lTy = type ; | |
4601 | ||
4602 | boolean repeat = t rue; | |
4603 | while (r epeat) { | |
4604 | if ( enclTr.has Tag(TYPEAP PLY)) { | |
4605 | List<Type> tyargs = enclTy.get TypeArgume nts(); | |
4606 | List<JCExp ression> t rargs = (( JCTypeAppl y)enclTr). getTypeArg uments(); | |
4607 | if (trargs .length() > 0) { | |
4608 | // Not hing to do for diamo nds | |
4609 | if (ty args.lengt h() == tra rgs.length ()) { | |
4610 | fo r (int i = 0; i < ty args.lengt h(); ++i) { | |
4611 | validate AnnotatedT ype(trargs .get(i), t yargs.get( i)); | |
4612 | } | |
4613 | } | |
4614 | // If the length s don't ma tch, it's either a d iamond | |
4615 | // or some neste d type tha t redundan tly provid es | |
4616 | // typ e argument s in the t ree. | |
4617 | } | |
4618 | ||
4619 | // Look at the clazz part of a generic t ype | |
4620 | enclTr = ( (JCTree.JC TypeApply) enclTr).cl azz; | |
4621 | } | |
4622 | ||
4623 | if ( enclTr.has Tag(SELECT )) { | |
4624 | enclTr = ( (JCTree.JC FieldAcces s)enclTr). getExpress ion(); | |
4625 | if (enclTy != null & & | |
4626 | !e nclTy.hasT ag(NONE)) { | |
4627 | enclTy = enclTy. getEnclosi ngType(); | |
4628 | } | |
4629 | } el se if (enc lTr.hasTag (ANNOTATED _TYPE)) { | |
4630 | JCAnnotate dType at = (JCTree.J CAnnotated Type) encl Tr; | |
4631 | if (enclTy == null | | | |
4632 | en clTy.hasTa g(NONE)) { | |
4633 | if (at .getAnnota tions().si ze() == 1) { | |
4634 | lo g.error(at .underlyin gType.pos( ), "cant.t ype.annota te.scoping .1", at.ge tAnnotatio ns().head. attribute) ; | |
4635 | } else { | |
4636 | Li stBuffer<A ttribute.C ompound> c omps = new ListBuffe r<Attribut e.Compound >(); | |
4637 | fo r (JCAnnot ation an : at.getAnn otations() ) { | |
4638 | comps.ad d(an.attri bute); | |
4639 | } | |
4640 | lo g.error(at .underlyin gType.pos( ), "cant.t ype.annota te.scoping ", comps.t oList()); | |
4641 | } | |
4642 | repeat = false; | |
4643 | } | |
4644 | enclTr = a t.underlyi ngType; | |
4645 | // enclTy doesn't ne ed to be c hanged | |
4646 | } el se if (enc lTr.hasTag (IDENT)) { | |
4647 | repeat = f alse; | |
4648 | } el se if (enc lTr.hasTag (JCTree.Ta g.WILDCARD )) { | |
4649 | JCWildcard wc = (JCW ildcard) e nclTr; | |
4650 | if (wc.get Kind() == JCTree.Kin d.EXTENDS_ WILDCARD) { | |
4651 | valida teAnnotate dType(wc.g etBound(), ((Wildcar dType)encl Ty.unannot atedType() ).getExten dsBound()) ; | |
4652 | } else if (wc.getKin d() == JCT ree.Kind.S UPER_WILDC ARD) { | |
4653 | valida teAnnotate dType(wc.g etBound(), ((Wildcar dType)encl Ty.unannot atedType() ).getSuper Bound()); | |
4654 | } else { | |
4655 | // Not hing to do for UNBOU ND | |
4656 | } | |
4657 | repeat = f alse; | |
4658 | } el se if (enc lTr.hasTag (TYPEARRAY )) { | |
4659 | JCArrayTyp eTree art = (JCArray TypeTree) enclTr; | |
4660 | validateAn notatedTyp e(art.getT ype(), ((A rrayType)e nclTy.unan notatedTyp e()).getCo mponentTyp e()); | |
4661 | repeat = f alse; | |
4662 | } el se if (enc lTr.hasTag (TYPEUNION )) { | |
4663 | JCTypeUnio n ut = (JC TypeUnion) enclTr; | |
4664 | for (JCTre e t : ut.g etTypeAlte rnatives() ) { | |
4665 | valida teAnnotate dType(t, t .type); | |
4666 | } | |
4667 | repeat = f alse; | |
4668 | } el se if (enc lTr.hasTag (TYPEINTER SECTION)) { | |
4669 | JCTypeInte rsection i t = (JCTyp eIntersect ion) enclT r; | |
4670 | for (JCTre e t : it.g etBounds() ) { | |
4671 | valida teAnnotate dType(t, t .type); | |
4672 | } | |
4673 | repeat = f alse; | |
4674 | } el se if (enc lTr.getKin d() == JCT ree.Kind.P RIMITIVE_T YPE || | |
4675 | enc lTr.getKin d() == JCT ree.Kind.E RRONEOUS) { | |
4676 | repeat = f alse; | |
4677 | } el se { | |
4678 | Assert.err or("Unexpe cted tree: " + enclT r + " with kind: " + enclTr.ge tKind() + | |
4679 | " within: "+ errtree + " with ki nd: " + er rtree.getK ind()); | |
4680 | } | |
4681 | } | |
4682 | } | |
4683 | ||
4684 | pr ivate void checkForD eclaration Annotation s(List<? e xtends JCA nnotation> annotatio ns, | |
4685 | Symb ol sym) { | |
4686 | // Ensur e that no declaratio n annotati ons are pr esent. | |
4687 | // Note that a tre e type mig ht be an A nnotatedTy pe with | |
4688 | // empty annotatio ns, if onl y declarat ion annota tions were given. | |
4689 | // This method wil l raise an error for such a ty pe. | |
4690 | for (JCA nnotation ai : annot ations) { | |
4691 | if ( !ai.type.i sErroneous () && | |
4692 | typeAn notations. annotation Type(ai.at tribute, s ym) == Typ eAnnotatio ns.Annotat ionType.DE CLARATION) { | |
4693 | log.error( ai.pos(), "annotatio n.type.not .applicabl e"); | |
4694 | } | |
4695 | } | |
4696 | } | |
4697 | }; | |
4698 | ||
4699 | // <ed itor-fold desc="post -attributi on visitor "> | |
4700 | ||
4701 | /** | |
4702 | * Han dle missin g types/sy mbols in a n AST. Thi s routine is useful when | |
4703 | * the compiler has encoun tered some errors (w hich might have ende d up | |
4704 | * ter minating a ttribution abruptly) ; if the c ompiler is used in f ail-over | |
4705 | * mod e (e.g. by an IDE) a nd the AST contains semantic e rrors, thi s routine | |
4706 | * pre vents NPE to be prog agated dur ing subseq uent compi lation ste ps. | |
4707 | */ | |
4708 | public void post Attr(JCTre e tree) { | |
4709 | ne w PostAttr Analyzer() .scan(tree ); | |
4710 | } | |
4711 | ||
4712 | class PostAttrAn alyzer ext ends TreeS canner { | |
4713 | ||
4714 | pr ivate void initTypeI fNeeded(JC Tree that) { | |
4715 | if (that .type == n ull) { | |
4716 | if ( that.hasTa g(METHODDE F)) { | |
4717 | that.type = dummyMet hodType((J CMethodDec l)that); | |
4718 | } el se { | |
4719 | that.type = syms.unk nownType; | |
4720 | } | |
4721 | } | |
4722 | } | |
4723 | ||
4724 | /* Construct a dummy m ethod type . If we ha ve a metho d declarat ion, | |
4725 | * and the d eclared re turn type is void, t hen use th at return type | |
4726 | * instead o f UNKNOWN to avoid s purious er ror messag es in lamb da | |
4727 | * bodies (s ee:JDK-804 1704). | |
4728 | * / | |
4729 | pr ivate Type dummyMeth odType(JCM ethodDecl md) { | |
4730 | Type res type = sym s.unknownT ype; | |
4731 | if (md ! = null && md.restype .hasTag(TY PEIDENT)) { | |
4732 | JCPr imitiveTyp eTree prim = (JCPrim itiveTypeT ree)md.res type; | |
4733 | if ( prim.typet ag == VOID ) | |
4734 | restype = syms.voidT ype; | |
4735 | } | |
4736 | return n ew MethodT ype(List.< Type>nil() , restype, | |
4737 | List.< Type>nil() , syms.met hodClass); | |
4738 | } | |
4739 | pr ivate Type dummyMeth odType() { | |
4740 | return d ummyMethod Type(null) ; | |
4741 | } | |
4742 | ||
4743 | @O verride | |
4744 | pu blic void scan(JCTre e tree) { | |
4745 | if (tree == null) return; | |
4746 | if (tree instanceo f JCExpres sion) { | |
4747 | init TypeIfNeed ed(tree); | |
4748 | } | |
4749 | super.sc an(tree); | |
4750 | } | |
4751 | ||
4752 | @O verride | |
4753 | pu blic void visitIdent (JCIdent t hat) { | |
4754 | if (that .sym == nu ll) { | |
4755 | that .sym = sym s.unknownS ymbol; | |
4756 | } | |
4757 | } | |
4758 | ||
4759 | @O verride | |
4760 | pu blic void visitSelec t(JCFieldA ccess that ) { | |
4761 | if (that .sym == nu ll) { | |
4762 | that .sym = sym s.unknownS ymbol; | |
4763 | } | |
4764 | super.vi sitSelect( that); | |
4765 | } | |
4766 | ||
4767 | @O verride | |
4768 | pu blic void visitClass Def(JCClas sDecl that ) { | |
4769 | initType IfNeeded(t hat); | |
4770 | if (that .sym == nu ll) { | |
4771 | that .sym = new ClassSymb ol(0, that .name, tha t.type, sy ms.noSymbo l); | |
4772 | } | |
4773 | super.vi sitClassDe f(that); | |
4774 | } | |
4775 | ||
4776 | @O verride | |
4777 | pu blic void visitMetho dDef(JCMet hodDecl th at) { | |
4778 | initType IfNeeded(t hat); | |
4779 | if (that .sym == nu ll) { | |
4780 | that .sym = new MethodSym bol(0, tha t.name, th at.type, s yms.noSymb ol); | |
4781 | } | |
4782 | super.vi sitMethodD ef(that); | |
4783 | } | |
4784 | ||
4785 | @O verride | |
4786 | pu blic void visitVarDe f(JCVariab leDecl tha t) { | |
4787 | initType IfNeeded(t hat); | |
4788 | if (that .sym == nu ll) { | |
4789 | that .sym = new VarSymbol (0, that.n ame, that. type, syms .noSymbol) ; | |
4790 | that .sym.adr = 0; | |
4791 | } | |
4792 | super.vi sitVarDef( that); | |
4793 | } | |
4794 | ||
4795 | @O verride | |
4796 | pu blic void visitNewCl ass(JCNewC lass that) { | |
4797 | if (that .construct or == null ) { | |
4798 | that .construct or = new M ethodSymbo l(0, names .init, | |
4799 | dummyM ethodType( ), syms.no Symbol); | |
4800 | } | |
4801 | if (that .construct orType == null) { | |
4802 | that .construct orType = s yms.unknow nType; | |
4803 | } | |
4804 | super.vi sitNewClas s(that); | |
4805 | } | |
4806 | ||
4807 | @O verride | |
4808 | pu blic void visitAssig nop(JCAssi gnOp that) { | |
4809 | if (that .operator == null) { | |
4810 | that .operator = new Oper atorSymbol (names.emp ty, dummyM ethodType( ), | |
4811 | -1, sy ms.noSymbo l); | |
4812 | } | |
4813 | super.vi sitAssigno p(that); | |
4814 | } | |
4815 | ||
4816 | @O verride | |
4817 | pu blic void visitBinar y(JCBinary that) { | |
4818 | if (that .operator == null) { | |
4819 | that .operator = new Oper atorSymbol (names.emp ty, dummyM ethodType( ), | |
4820 | -1, sy ms.noSymbo l); | |
4821 | } | |
4822 | super.vi sitBinary( that); | |
4823 | } | |
4824 | ||
4825 | @O verride | |
4826 | pu blic void visitUnary (JCUnary t hat) { | |
4827 | if (that .operator == null) { | |
4828 | that .operator = new Oper atorSymbol (names.emp ty, dummyM ethodType( ), | |
4829 | -1, sy ms.noSymbo l); | |
4830 | } | |
4831 | super.vi sitUnary(t hat); | |
4832 | } | |
4833 | ||
4834 | @O verride | |
4835 | pu blic void visitLambd a(JCLambda that) { | |
4836 | super.vi sitLambda( that); | |
4837 | if (that .targets = = null) { | |
4838 | that .targets = List.nil( ); | |
4839 | } | |
4840 | } | |
4841 | ||
4842 | @O verride | |
4843 | pu blic void visitRefer ence(JCMem berReferen ce that) { | |
4844 | super.vi sitReferen ce(that); | |
4845 | if (that .sym == nu ll) { | |
4846 | that .sym = new MethodSym bol(0, nam es.empty, dummyMetho dType(), | |
4847 | syms.n oSymbol); | |
4848 | } | |
4849 | if (that .targets = = null) { | |
4850 | that .targets = List.nil( ); | |
4851 | } | |
4852 | } | |
4853 | } | |
4854 | // </e ditor-fold > | |
4855 | } |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.