1 /* |
1 /* |
2 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
54 import java.util.Map; |
54 import java.util.Map; |
55 import java.util.Set; |
55 import java.util.Set; |
56 import java.util.WeakHashMap; |
56 import java.util.WeakHashMap; |
57 import java.util.function.Function; |
57 import java.util.function.Function; |
58 |
58 |
|
59 import com.sun.source.tree.MemberReferenceTree; |
|
60 import com.sun.tools.javac.tree.JCTree.JCMemberReference.OverloadKind; |
|
61 |
59 import static com.sun.tools.javac.code.TypeTag.*; |
62 import static com.sun.tools.javac.code.TypeTag.*; |
60 import static com.sun.tools.javac.tree.JCTree.Tag.*; |
63 import static com.sun.tools.javac.tree.JCTree.Tag.*; |
61 |
64 |
62 /** |
65 /** |
63 * This is an helper class that is used to perform deferred type-analysis. |
66 * This is an helper class that is used to perform deferred type-analysis. |
146 return make.at(t.pos).NewClass(encl, typeargs, clazz, args, def); |
149 return make.at(t.pos).NewClass(encl, typeargs, clazz, args, def); |
147 } else { |
150 } else { |
148 return super.visitNewClass(node, p); |
151 return super.visitNewClass(node, p); |
149 } |
152 } |
150 } |
153 } |
|
154 |
|
155 @Override @DefinedBy(Api.COMPILER_TREE) |
|
156 public JCTree visitMemberReference(MemberReferenceTree node, Void p) { |
|
157 JCMemberReference t = (JCMemberReference) node; |
|
158 JCExpression expr = copy(t.expr, p); |
|
159 List<JCExpression> typeargs = copy(t.typeargs, p); |
|
160 /** once the value for overloadKind is determined for a copy, it can be safely forwarded to |
|
161 * the copied tree, we want to profit from that |
|
162 */ |
|
163 JCMemberReference result = new JCMemberReference(t.mode, t.name, expr, typeargs) { |
|
164 @Override |
|
165 public void setOverloadKind(OverloadKind overloadKind) { |
|
166 super.setOverloadKind(overloadKind); |
|
167 if (t.getOverloadKind() == null) { |
|
168 t.setOverloadKind(overloadKind); |
|
169 } |
|
170 } |
|
171 }; |
|
172 result.pos = t.pos; |
|
173 return result; |
|
174 } |
151 }; |
175 }; |
152 deferredCopier = new TypeMapping<Void> () { |
176 deferredCopier = new TypeMapping<Void> () { |
153 @Override |
177 @Override |
154 public Type visitType(Type t, Void v) { |
178 public Type visitType(Type t, Void v) { |
155 if (t.hasTag(DEFERRED)) { |
179 if (t.hasTag(DEFERRED)) { |
444 * restored after type-checking. All diagnostics (but critical ones) are |
468 * restored after type-checking. All diagnostics (but critical ones) are |
445 * disabled during speculative type-checking. |
469 * disabled during speculative type-checking. |
446 */ |
470 */ |
447 JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) { |
471 JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) { |
448 return attribSpeculative(tree, env, resultInfo, treeCopier, |
472 return attribSpeculative(tree, env, resultInfo, treeCopier, |
449 (newTree)->new DeferredAttrDiagHandler(log, newTree)); |
473 (newTree)->new DeferredAttrDiagHandler(log, newTree), null); |
|
474 } |
|
475 |
|
476 JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, LocalCacheContext localCache) { |
|
477 return attribSpeculative(tree, env, resultInfo, treeCopier, |
|
478 (newTree)->new DeferredAttrDiagHandler(log, newTree), localCache); |
450 } |
479 } |
451 |
480 |
452 <Z> JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, TreeCopier<Z> deferredCopier, |
481 <Z> JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, TreeCopier<Z> deferredCopier, |
453 Function<JCTree, DeferredDiagnosticHandler> diagHandlerCreator) { |
482 Function<JCTree, DeferredDiagnosticHandler> diagHandlerCreator, |
|
483 LocalCacheContext localCache) { |
454 final JCTree newTree = deferredCopier.copy(tree); |
484 final JCTree newTree = deferredCopier.copy(tree); |
455 Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner))); |
485 Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner))); |
456 speculativeEnv.info.isSpeculative = true; |
486 speculativeEnv.info.isSpeculative = true; |
457 Log.DeferredDiagnosticHandler deferredDiagnosticHandler = diagHandlerCreator.apply(newTree); |
487 Log.DeferredDiagnosticHandler deferredDiagnosticHandler = diagHandlerCreator.apply(newTree); |
458 try { |
488 try { |
459 attr.attribTree(newTree, speculativeEnv, resultInfo); |
489 attr.attribTree(newTree, speculativeEnv, resultInfo); |
460 return newTree; |
490 return newTree; |
461 } finally { |
491 } finally { |
462 new UnenterScanner(env.toplevel.modle).scan(newTree); |
492 new UnenterScanner(env.toplevel.modle).scan(newTree); |
463 log.popDiagnosticHandler(deferredDiagnosticHandler); |
493 log.popDiagnosticHandler(deferredDiagnosticHandler); |
|
494 if (localCache != null) { |
|
495 localCache.leave(); |
|
496 } |
464 } |
497 } |
465 } |
498 } |
466 //where |
499 //where |
467 |
500 |
468 class UnenterScanner extends TreeScanner { |
501 class UnenterScanner extends TreeScanner { |
845 //do nothing |
878 //do nothing |
846 } |
879 } |
847 |
880 |
848 @Override |
881 @Override |
849 public void visitReference(JCMemberReference tree) { |
882 public void visitReference(JCMemberReference tree) { |
|
883 Assert.checkNonNull(tree.getOverloadKind()); |
850 Check.CheckContext checkContext = resultInfo.checkContext; |
884 Check.CheckContext checkContext = resultInfo.checkContext; |
851 Type pt = resultInfo.pt; |
885 Type pt = resultInfo.pt; |
852 if (!inferenceContext.inferencevars.contains(pt)) { |
886 if (!inferenceContext.inferencevars.contains(pt)) { |
853 try { |
887 try { |
854 types.findDescriptorType(pt); |
888 types.findDescriptorType(pt); |
855 } catch (Types.FunctionDescriptorLookupError ex) { |
889 } catch (Types.FunctionDescriptorLookupError ex) { |
856 checkContext.report(null, ex.getDiagnostic()); |
890 checkContext.report(null, ex.getDiagnostic()); |
857 } |
891 } |
858 Env<AttrContext> localEnv = env.dup(tree); |
892 Env<AttrContext> localEnv = env.dup(tree); |
859 JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv, |
893 JCExpression exprTree; |
860 attr.memberReferenceQualifierResult(tree)); |
894 exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv, |
|
895 attr.memberReferenceQualifierResult(tree), argumentAttr.withLocalCacheContext()); |
861 ListBuffer<Type> argtypes = new ListBuffer<>(); |
896 ListBuffer<Type> argtypes = new ListBuffer<>(); |
862 for (Type t : types.findDescriptorType(pt).getParameterTypes()) { |
897 for (Type t : types.findDescriptorType(pt).getParameterTypes()) { |
863 argtypes.append(Type.noType); |
898 argtypes.append(Type.noType); |
864 } |
899 } |
865 JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree); |
900 JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree); |
1123 } |
1158 } |
1124 |
1159 |
1125 Type descType = types.findDescriptorType(pt); |
1160 Type descType = types.findDescriptorType(pt); |
1126 List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes()); |
1161 List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes()); |
1127 if (freeArgVars.nonEmpty() && |
1162 if (freeArgVars.nonEmpty() && |
1128 tree.overloadKind == JCMemberReference.OverloadKind.OVERLOADED) { |
1163 tree.getOverloadKind() == JCMemberReference.OverloadKind.OVERLOADED) { |
1129 stuckVars.addAll(freeArgVars); |
1164 stuckVars.addAll(freeArgVars); |
1130 depVars.addAll(inferenceContext.freeVarsIn(descType.getReturnType())); |
1165 depVars.addAll(inferenceContext.freeVarsIn(descType.getReturnType())); |
1131 } |
1166 } |
1132 } |
1167 } |
1133 |
1168 |