blob: a3c08640650cf7611022a5248cb356db51863045 [file] [log] [blame]
Stephan Herrmann7b7062f2010-04-01 19:56:59 +00001/*******************************************************************************
Stephan Herrmann34106802019-02-02 13:45:17 +01002 * Copyright (c) 2000, 2019 IBM Corporation and others.
Stephan Herrmannaa0c80c2018-09-08 22:11:53 +02003 *
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
Stephan Herrmann7b7062f2010-04-01 19:56:59 +00006 * which accompanies this distribution, and is available at
Stephan Herrmannaa0c80c2018-09-08 22:11:53 +02007 * https://www.eclipse.org/legal/epl-2.0/
8 *
9 * SPDX-License-Identifier: EPL-2.0
Stephan Herrmanna441c702018-10-14 17:51:04 +020010 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000011 * Contributors:
12 * IBM Corporation - initial API and implementation
Stephan Herrmannaa1e2842011-12-10 00:30:58 +010013 * Fraunhofer FIRST - extended API and implementation
14 * Technical University Berlin - extended API and implementation
15 * Stephan Herrmann - Contributions for
Stephan Herrmann66cc2b62010-09-26 15:38:59 +000016 * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
17 * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
Stephan Herrmann6dcbb382011-10-25 16:30:31 +000018 * bug 349326 - [1.7] new warning for missing try-with-resources
Stephan Herrmannaa1e2842011-12-10 00:30:58 +010019 * bug 186342 - [compiler][null] Using annotations for null checking
Stephan Herrmann2c38ab42012-01-28 20:42:28 +010020 * bug 358903 - Filter practically unimportant resource leak warnings
Stephan Herrmann6cecadb2012-02-26 01:08:39 +010021 * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
22 * bug 370639 - [compiler][resource] restore the default for resource leak warnings
Stephan Herrmann1a8ea8f2012-09-18 15:10:52 +020023 * bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
24 * bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
Stephan Herrmannc7600d82013-04-28 22:48:05 +020025 * bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
Stephan Herrmann4388de02013-12-30 10:43:45 +010026 * Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations
Stephan Herrmann5d5b2c32014-01-02 00:10:41 +010027 * Bug 417295 - [1.8[[null] Massage type annotated null analysis to gel well with deep encoded type bindings.
Stephan Herrmannc1c48622014-01-04 23:19:31 +010028 * Bug 400874 - [1.8][compiler] Inference infrastructure should evolve to meet JLS8 18.x (Part G of JSR335 spec)
Stephan Herrmannddef2c12014-01-05 18:18:25 +010029 * Bug 424727 - [compiler][null] NullPointerException in nullAnnotationUnsupportedLocation(ProblemReporter.java:5708)
Stephan Herrmann78721b12014-02-12 00:01:46 +010030 * Bug 424710 - [1.8][compiler] CCE in SingleNameReference.localVariableBinding
31 * Bug 425152 - [1.8] [compiler] Lambda Expression not resolved but flow analyzed leading to NPE.
32 * Bug 424205 - [1.8] Cannot infer type for diamond type with lambda on method invocation
33 * Bug 424415 - [1.8][compiler] Eventual resolution of ReferenceExpression is not seen to be happening.
34 * Bug 426366 - [1.8][compiler] Type inference doesn't handle multiple candidate target types in outer overload context
35 * Bug 426290 - [1.8][compiler] Inference + overloading => wrong method resolution ?
Stephan Herrmann4d079452014-03-27 18:01:49 +010036 * Bug 426764 - [1.8] Presence of conditional expression as method argument confuses compiler
37 * Bug 424930 - [1.8][compiler] Regression: "Cannot infer type arguments" error from compiler.
38 * Bug 427483 - [Java 8] Variables in lambdas sometimes can't be resolved
39 * Bug 427438 - [1.8][compiler] NPE at org.eclipse.jdt.internal.compiler.ast.ConditionalExpression.generateCode(ConditionalExpression.java:280)
Stephan Herrmann14e866b2014-03-28 20:26:29 +010040 * Bug 426996 - [1.8][inference] try to avoid method Expression.unresolve()?
41 * Bug 428352 - [1.8][compiler] Resolution errors don't always surface
Stephan Herrmann2671e412014-03-29 00:36:47 +010042 * Bug 429203 - [1.8][compiler] NPE in AllocationExpression.binding
Stephan Herrmanne2399432014-03-29 13:02:22 +010043 * Bug 429430 - [1.8] Lambdas and method reference infer wrong exception type with generics (RuntimeException instead of IOException)
Stephan Herrmannbc9c6682014-05-15 22:48:38 +020044 * Bug 434297 - [1.8] NPE in LamdaExpression.analyseCode with lamda expression nested in a conditional expression
Stephan Herrmann32fd38b2014-12-13 15:26:29 +010045 * Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
Stephan Herrmann075533e2015-04-28 17:54:14 +020046 * Bug 448709 - [1.8][null] ensure we don't infer types that violate null constraints on a type parameter's bound
Stephan Herrmannc7600d82013-04-28 22:48:05 +020047 * Jesper S Moller <jesper@selskabet.org> - Contributions for
48 * bug 378674 - "The method can be declared as static" is wrong
Stephan Herrmann5d5b2c32014-01-02 00:10:41 +010049 * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
Stephan Herrmann64791942013-12-28 21:28:24 +010050 * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
51 * Bug 409245 - [1.8][compiler] Type annotations dropped when call is routed through a synthetic bridge method
Stephan Herrmann4c6c5002013-09-12 23:09:47 +020052 * Till Brychcy - Contributions for
53 * bug 413460 - NonNullByDefault is not inherited to Constructors when accessed via Class File
Stephan Herrmann210dc3a2015-08-13 22:46:42 +020054 * Lars Vogel <Lars.Vogel@vogella.com> - Contributions for
55 * Bug 473178
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000056 *******************************************************************************/
57package org.eclipse.jdt.internal.compiler.ast;
58
Stephan Herrmann4d079452014-03-27 18:01:49 +010059import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.*;
60
Stephan Herrmanne6a1a642014-11-15 14:33:08 +010061import java.util.HashMap;
62
Stephan Herrmann44109d32011-08-02 14:34:26 +000063import org.eclipse.jdt.core.compiler.IProblem;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000064import org.eclipse.jdt.internal.compiler.ASTVisitor;
65import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
66import org.eclipse.jdt.internal.compiler.codegen.*;
67import org.eclipse.jdt.internal.compiler.flow.*;
Stephan Herrmann4c6c5002013-09-12 23:09:47 +020068import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
Stephan Herrmann794deee2014-04-18 21:18:19 +020069import org.eclipse.jdt.internal.compiler.impl.CompilerOptions.WeavingScheme;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000070import org.eclipse.jdt.internal.compiler.impl.Constant;
71import org.eclipse.jdt.internal.compiler.lookup.*;
Stephan Herrmann44109d32011-08-02 14:34:26 +000072import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
Stephan Herrmanna28db532014-01-05 14:59:05 +010073import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
Stephan Herrmann20fb5ac2014-04-03 23:32:36 +020074import org.eclipse.objectteams.otdt.internal.core.compiler.ast.ConstructorDecapsulationException;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000075import org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies;
76import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
77import org.eclipse.objectteams.otdt.internal.core.compiler.control.StateMemento;
78import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.AnchorMapping;
79import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.DependentTypeBinding;
80import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.ITeamAnchor;
81import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
82import org.eclipse.objectteams.otdt.internal.core.compiler.model.RoleModel;
83import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance.CopyInheritance;
84import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstGenerator;
85import org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator;
86import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer;
87
88/**
89 * OTDT changes:
90 *
91 * What: wrap resolved type if role, may need to instantiate parameters of constructor call.
92 * Why: this expression can be seen as a variant of MessageSend
93 * (invokes the constructor and returns a value).
94 *
95 * What: replace "new Role()" statements with a call to the creation method.
96 * Why: do it during resolve, because only now we will find the role if it is in a role file.
97 *
98 * What: record need to check duplicate roles
99 * if this expression creates a role using the lifting constructor
100 * See: Class comment in MethodBinding
101 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000102 */
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100103public class AllocationExpression extends Expression implements IPolyExpression, Invocation {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000104
105 public TypeReference type;
106 public Expression[] arguments;
107 public MethodBinding binding; // exact binding resulting from lookup
108 MethodBinding syntheticAccessor; // synthetic accessor for inner-emulation
109 public TypeReference[] typeArguments;
110 public TypeBinding[] genericTypeArguments;
111 public FieldDeclaration enumConstant; // for enum constant initializations
Stephan Herrmann44109d32011-08-02 14:34:26 +0000112 protected TypeBinding typeExpected; // for <> inference
113 public boolean inferredReturnType;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000114
Stephan Herrmann2c38ab42012-01-28 20:42:28 +0100115 public FakedTrackingVariable closeTracker; // when allocation a Closeable store a pre-liminary tracking variable here
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100116 public ExpressionContext expressionContext = VANILLA_CONTEXT;
Stephan Herrmanna28db532014-01-05 14:59:05 +0100117
118 // hold on to this context from invocation applicability inference until invocation type inference (per method candidate):
Stephan Herrmann4d079452014-03-27 18:01:49 +0100119 private SimpleLookupTable/*<PMB,IC18>*/ inferenceContexts;
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100120 public HashMap<TypeBinding, MethodBinding> solutionsPerTargetType;
Stephan Herrmann32fd38b2014-12-13 15:26:29 +0100121 private InferenceContext18 outerInferenceContext; // resolving within the context of an outer (lambda) inference?
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100122 public boolean argsContainCast;
Stephan Herrmann4194d172014-11-11 21:35:54 +0100123 public TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100124 public boolean argumentsHaveErrors = false;
125
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000126//{ObjectTeams: alternate AST in case the creation needs to be redirected through a creator call:
127 private MessageSend roleCreatorCall = null;
128 private NameReference valueParam; // if allocation type has value parameter: synthesized argument for ctor call
Stephan Herrmannf3b56c22014-01-03 20:39:26 +0100129 public boolean isGenerated;
130 @Override
131 public boolean isGenerated() {
132 return this.isGenerated;
133 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000134// SH}
135
Stephan Herrmanne4721882018-01-25 20:43:01 +0100136@Override
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000137public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
138//{ObjectTeams: redirect?
139 if (this.roleCreatorCall != null)
140 return this.roleCreatorCall.analyseCode(currentScope, flowContext, flowInfo);
141// SH}
142 // check captured variables are initialized in current context (26134)
143 checkCapturedLocalInitializationIfNecessary((ReferenceBinding)this.binding.declaringClass.erasure(), currentScope, flowInfo);
144
145 // process arguments
146 if (this.arguments != null) {
Stephan Herrmann6cecadb2012-02-26 01:08:39 +0100147 boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
148 boolean hasResourceWrapperType = analyseResources
149 && this.resolvedType instanceof ReferenceBinding
Stephan Herrmann2c38ab42012-01-28 20:42:28 +0100150 && ((ReferenceBinding)this.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000151 for (int i = 0, count = this.arguments.length; i < count; i++) {
152 flowInfo =
153 this.arguments[i]
154 .analyseCode(currentScope, flowContext, flowInfo)
155 .unconditionalInits();
Stephan Herrmann2c38ab42012-01-28 20:42:28 +0100156 // if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
Stephan Herrmann6cecadb2012-02-26 01:08:39 +0100157 if (analyseResources && !hasResourceWrapperType) { // allocation of wrapped closeables is analyzed specially
Stephan Herrmann1a8ea8f2012-09-18 15:10:52 +0200158 flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, flowContext, false);
Stephan Herrmann2c38ab42012-01-28 20:42:28 +0100159 }
Stephan Herrmannc7600d82013-04-28 22:48:05 +0200160 this.arguments[i].checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
Stephan Herrmann4194d172014-11-11 21:35:54 +0100161 }
Stephan Herrmannaa1e2842011-12-10 00:30:58 +0100162 analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000163 }
Stephan Herrmann2c38ab42012-01-28 20:42:28 +0100164
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000165 // record some dependency information for exception types
166 ReferenceBinding[] thrownExceptions;
167 if (((thrownExceptions = this.binding.thrownExceptions).length) != 0) {
168 if ((this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null) {
169 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
170 thrownExceptions = currentScope.environment().convertToRawTypes(this.binding.thrownExceptions, true, true);
171 }
172 // check exception handling
173 flowContext.checkExceptionHandlers(
174 thrownExceptions,
175 this,
176 flowInfo.unconditionalCopy(),
177 currentScope);
178 }
Stephan Herrmann6cecadb2012-02-26 01:08:39 +0100179
180 // after having analysed exceptions above start tracking newly allocated resource:
Stephan Herrmann942dbe92012-04-12 20:50:07 +0200181 if (currentScope.compilerOptions().analyseResourceLeaks && FakedTrackingVariable.isAnyCloseable(this.resolvedType))
Stephan Herrmann6cecadb2012-02-26 01:08:39 +0100182 FakedTrackingVariable.analyseCloseableAllocation(currentScope, flowInfo, this);
183
Stephan Herrmannf94f0622016-04-26 18:20:41 +0200184 ReferenceBinding declaringClass = this.binding.declaringClass;
185 MethodScope methodScope = currentScope.methodScope();
186 if ((declaringClass.isMemberType() && !declaringClass.isStatic()) ||
187 (declaringClass.isLocalType() && !methodScope.isStatic && methodScope.isLambdaScope())) {
Stephan Herrmanna1bf6562011-03-01 21:59:07 +0000188 // allocating a non-static member type without an enclosing instance of parent type
189 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=335845
Stephan Herrmann529142e2013-09-06 01:04:51 +0200190 currentScope.tagAsAccessingEnclosingInstanceStateOf(this.binding.declaringClass.enclosingType(), false /* type variable access */);
Stephan Herrmannc7600d82013-04-28 22:48:05 +0200191 // Reviewed for https://bugs.eclipse.org/bugs/show_bug.cgi?id=378674 :
192 // The corresponding problem (when called from static) is not produced until during code generation
Stephan Herrmanna1bf6562011-03-01 21:59:07 +0000193 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000194 manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
195 manageSyntheticAccessIfNecessary(currentScope, flowInfo);
196
Stephan Herrmann1a8ea8f2012-09-18 15:10:52 +0200197 // account for possible exceptions thrown by the constructor
198 flowContext.recordAbruptExit(); // TODO whitelist of ctors that cannot throw any exc.??
199
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000200 return flowInfo;
201}
202
203public void checkCapturedLocalInitializationIfNecessary(ReferenceBinding checkedType, BlockScope currentScope, FlowInfo flowInfo) {
204 if (((checkedType.tagBits & ( TagBits.AnonymousTypeMask|TagBits.LocalTypeMask)) == TagBits.LocalTypeMask)
205 && !currentScope.isDefinedInType(checkedType)) { // only check external allocations
206 NestedTypeBinding nestedType = (NestedTypeBinding) checkedType;
207 SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables();
208 if (syntheticArguments != null)
209 for (int i = 0, count = syntheticArguments.length; i < count; i++){
210 SyntheticArgumentBinding syntheticArgument = syntheticArguments[i];
211 LocalVariableBinding targetLocal;
212 if ((targetLocal = syntheticArgument.actualOuterLocalVariable) == null) continue;
213 if (targetLocal.declaration != null && !flowInfo.isDefinitelyAssigned(targetLocal)){
Stephan Herrmannd0fe0622018-07-26 19:10:48 +0200214 currentScope.problemReporter().uninitializedLocalVariable(targetLocal, this, currentScope);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000215 }
216 }
217 }
218}
219
220public Expression enclosingInstance() {
221 return null;
222}
223
Stephan Herrmanne4721882018-01-25 20:43:01 +0100224@Override
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000225public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
Stephan Herrmannd1a89d72015-12-08 19:38:48 +0100226 cleanUpInferenceContexts();
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000227 if (!valueRequired)
228 currentScope.problemReporter().unusedObjectAllocation(this);
Stephan Herrmannd1a89d72015-12-08 19:38:48 +0100229
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000230//{ObjectTeams: redirect?
231 if (this.roleCreatorCall != null) {
232 this.roleCreatorCall.generateCode(currentScope, codeStream, valueRequired);
233 return;
234 }
235// SH}
236 int pc = codeStream.position;
237 MethodBinding codegenBinding = this.binding.original();
238 ReferenceBinding allocatedType = codegenBinding.declaringClass;
239
Stephan Herrmannbd1255d2013-09-05 23:25:05 +0200240 codeStream.new_(this.type, allocatedType);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000241 boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
242 if (valueRequired || isUnboxing) {
243 codeStream.dup();
244 }
245 // better highlight for allocation: display the type individually
246 if (this.type != null) { // null for enum constant body
247 codeStream.recordPositionsFrom(pc, this.type.sourceStart);
248 } else {
249 // push enum constant name and ordinal
250 codeStream.ldc(String.valueOf(this.enumConstant.name));
251 codeStream.generateInlinedValue(this.enumConstant.binding.id);
252 }
253
254 // handling innerclass instance allocation - enclosing instance arguments
255 if (allocatedType.isNestedType()) {
256 codeStream.generateSyntheticEnclosingInstanceValues(
257 currentScope,
258 allocatedType,
259 enclosingInstance(),
260 this);
261 }
262//{ObjectTeams: pass value parameter:
263 if (this.valueParam != null)
264 this.valueParam.generateCode(currentScope, codeStream, true);
265// SH}
266 // generate the arguments for constructor
267 generateArguments(this.binding, this.arguments, currentScope, codeStream);
268 // handling innerclass instance allocation - outer local arguments
269 if (allocatedType.isNestedType()) {
270 codeStream.generateSyntheticOuterArgumentValues(
271 currentScope,
272 allocatedType,
273 this);
274 }
275 // invoke constructor
276 if (this.syntheticAccessor == null) {
Stephan Herrmannbd1255d2013-09-05 23:25:05 +0200277 codeStream.invoke(Opcodes.OPC_invokespecial, codegenBinding, null /* default declaringClass */, this.typeArguments);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000278 } else {
279 // synthetic accessor got some extra arguments appended to its signature, which need values
280 for (int i = 0,
281 max = this.syntheticAccessor.parameters.length - codegenBinding.parameters.length;
282 i < max;
283 i++) {
284 codeStream.aconst_null();
285 }
Stephan Herrmann64791942013-12-28 21:28:24 +0100286 codeStream.invoke(Opcodes.OPC_invokespecial, this.syntheticAccessor, null /* default declaringClass */, this.typeArguments);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000287 }
288 if (valueRequired) {
289 codeStream.generateImplicitConversion(this.implicitConversion);
290 } else if (isUnboxing) {
291 // conversion only generated if unboxing
292 codeStream.generateImplicitConversion(this.implicitConversion);
293 switch (postConversionType(currentScope).id) {
294 case T_long :
295 case T_double :
296 codeStream.pop2();
297 break;
298 default :
299 codeStream.pop();
300 }
301 }
302 codeStream.recordPositionsFrom(pc, this.sourceStart);
303}
304
305/**
306 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
307 */
Stephan Herrmanne4721882018-01-25 20:43:01 +0100308@Override
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000309public TypeBinding[] genericTypeArguments() {
310 return this.genericTypeArguments;
311}
312
Stephan Herrmanne4721882018-01-25 20:43:01 +0100313@Override
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000314public boolean isSuperAccess() {
315//{ObjectTeams: within a creation method fake visibility:
316 if (isGenerated())
317 return true;
318// SH}
319 return false;
320}
321
Stephan Herrmanne4721882018-01-25 20:43:01 +0100322@Override
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000323public boolean isTypeAccess() {
324 return true;
325}
326
327/* Inner emulation consists in either recording a dependency
328 * link only, or performing one level of propagation.
329 *
330 * Dependency mechanism is used whenever dealing with source target
331 * types, since by the time we reach them, we might not yet know their
332 * exact need.
333 */
334public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
Stephan Herrmann0e64ff62011-03-10 18:42:36 +0000335 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000336 ReferenceBinding allocatedTypeErasure = (ReferenceBinding) this.binding.declaringClass.erasure();
337
338 // perform some emulation work in case there is some and we are inside a local type only
339 if (allocatedTypeErasure.isNestedType()
Stephan Herrmann14d6b962015-06-09 14:32:46 +0200340 && (currentScope.enclosingSourceType().isLocalType() || currentScope.isLambdaSubscope())) {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000341
342 if (allocatedTypeErasure.isLocalType()) {
343 ((LocalTypeBinding) allocatedTypeErasure).addInnerEmulationDependent(currentScope, false);
344 // request cascade of accesses
345 } else {
346 // locally propagate, since we already now the desired shape for sure
347 currentScope.propagateInnerEmulation(allocatedTypeErasure, false);
348 // request cascade of accesses
349 }
350 }
351}
352
353public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
Stephan Herrmann0e64ff62011-03-10 18:42:36 +0000354 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000355 // if constructor from parameterized type got found, use the original constructor at codegen time
356 MethodBinding codegenBinding = this.binding.original();
357//{ObjectTeams: baseclass decapsulation:
358 if ( codegenBinding.isPrivate()
359 && this.type != null
360 && this.type.getBaseclassDecapsulation().isAllowed())
361 {
362 return; // avoid tweaking below, which might result in CCE if declaringClass is binary.
363 }
364// SH}
365
366 ReferenceBinding declaringClass;
Stephan Herrmanna441c702018-10-14 17:51:04 +0200367 if (codegenBinding.isPrivate() &&
368 !currentScope.enclosingSourceType().isNestmateOf(this.binding.declaringClass) &&
369 TypeBinding.notEquals(currentScope.enclosingSourceType(), (declaringClass = codegenBinding.declaringClass))) {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000370
371 // from 1.4 on, local type constructor can lose their private flag to ease emulation
372 if ((declaringClass.tagBits & TagBits.IsLocalType) != 0 && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
373 // constructor will not be dumped as private, no emulation required thus
374 codegenBinding.tagBits |= TagBits.ClearPrivateModifier;
375 } else {
376 this.syntheticAccessor = ((SourceTypeBinding) declaringClass).addSyntheticMethod(codegenBinding, isSuperAccess());
377 currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
378 }
379 }
380}
381
Stephan Herrmanne4721882018-01-25 20:43:01 +0100382@Override
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000383public StringBuffer printExpression(int indent, StringBuffer output) {
384 if (this.type != null) { // type null for enum constant initializations
385 output.append("new "); //$NON-NLS-1$
386 }
387 if (this.typeArguments != null) {
388 output.append('<');
389 int max = this.typeArguments.length - 1;
390 for (int j = 0; j < max; j++) {
391 this.typeArguments[j].print(0, output);
392 output.append(", ");//$NON-NLS-1$
393 }
394 this.typeArguments[max].print(0, output);
395 output.append('>');
396 }
397 if (this.type != null) { // type null for enum constant initializations
398 this.type.printExpression(0, output);
399 }
400 output.append('(');
401 if (this.arguments != null) {
402 for (int i = 0; i < this.arguments.length; i++) {
403 if (i > 0) output.append(", "); //$NON-NLS-1$
404 this.arguments[i].printExpression(0, output);
405 }
406 }
407 return output.append(')');
408}
409
Stephan Herrmanne4721882018-01-25 20:43:01 +0100410@Override
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000411public TypeBinding resolveType(BlockScope scope) {
412 // Propagate the type checking to the arguments, and check if the constructor is defined.
Stephan Herrmannf087af32014-01-04 01:36:05 +0100413 final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
414 final CompilerOptions compilerOptions = scope.compilerOptions();
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100415 long sourceLevel = compilerOptions.sourceLevel;
Stephan Herrmannf087af32014-01-04 01:36:05 +0100416 if (this.constant != Constant.NotAConstant) {
417 this.constant = Constant.NotAConstant;
418 if (this.type == null) {
419 // initialization of an enum constant
420 this.resolvedType = scope.enclosingReceiverType();
421 } else {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000422//{ObjectTeams: support detection of new path.R():
Stephan Herrmannf087af32014-01-04 01:36:05 +0100423 this.type.bits |= IsAllocationType;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000424// SH}
Stephan Herrmannf087af32014-01-04 01:36:05 +0100425 this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000426 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100427 if (this.type != null) {
428 checkIllegalNullAnnotation(scope, this.resolvedType);
429 checkParameterizedAllocation: {
430 if (this.type instanceof ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
431 ReferenceBinding currentType = (ReferenceBinding)this.resolvedType;
432 if (currentType == null) return currentType;
433 do {
434 // isStatic() is answering true for toplevel types
435 if ((currentType.modifiers & ClassFileConstants.AccStatic) != 0) break checkParameterizedAllocation;
436 if (currentType.isRawType()) break checkParameterizedAllocation;
437 } while ((currentType = currentType.enclosingType())!= null);
438 ParameterizedQualifiedTypeReference qRef = (ParameterizedQualifiedTypeReference) this.type;
439 for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
440 if (qRef.typeArguments[i] != null) {
441 scope.problemReporter().illegalQualifiedParameterizedTypeAllocation(this.type, this.resolvedType);
442 break;
443 }
Stephan Herrmann032b22f2014-01-04 18:29:30 +0100444 }
445 }
446 }
447 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100448 // will check for null after args are resolved
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000449
450//{ObjectTeams: replace role allocations:
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100451 if (!scope.isGeneratedScope()) {
452 // also accept type.resolvedType if a problem was detected during type.resolveType().
453 TypeBinding typeBinding = this.resolvedType;
454 if (typeBinding != null && (typeBinding instanceof ProblemReferenceBinding))
455 typeBinding = ((ProblemReferenceBinding)typeBinding).closestMatch();
456 if ( typeBinding instanceof ReferenceBinding
457 && ((ReferenceBinding)typeBinding).isDirectRole())
458 return resolveAsRoleCreationExpression((ReferenceBinding) typeBinding, scope);
459 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000460// SH}
461
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100462 // resolve type arguments (for generic constructor call)
463 if (this.typeArguments != null) {
464 int length = this.typeArguments.length;
465 this.argumentsHaveErrors = sourceLevel < ClassFileConstants.JDK1_5;
466 this.genericTypeArguments = new TypeBinding[length];
467 for (int i = 0; i < length; i++) {
468 TypeReference typeReference = this.typeArguments[i];
469 if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
470 this.argumentsHaveErrors = true;
471 }
472 if (this.argumentsHaveErrors && typeReference instanceof Wildcard) {
473 scope.problemReporter().illegalUsageOfWildcard(typeReference);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000474 }
475 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100476 if (isDiamond) {
477 scope.problemReporter().diamondNotWithExplicitTypeArguments(this.typeArguments);
478 return null;
479 }
480 if (this.argumentsHaveErrors) {
481 if (this.arguments != null) { // still attempt to resolve arguments
482 for (int i = 0, max = this.arguments.length; i < max; i++) {
483 this.arguments[i].resolveType(scope);
484 }
485 }
486 return null;
487 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000488 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000489
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100490 // buffering the arguments' types
491 if (this.arguments != null) {
492 this.argumentsHaveErrors = false;
493 int length = this.arguments.length;
494 this.argumentTypes = new TypeBinding[length];
495 for (int i = 0; i < length; i++) {
496 Expression argument = this.arguments[i];
497 if (argument instanceof CastExpression) {
498 argument.bits |= DisableUnnecessaryCastCheck; // will check later on
499 this.argsContainCast = true;
500 }
501 argument.setExpressionContext(INVOCATION_CONTEXT);
Stephan Herrmann4fda94b2014-03-29 16:07:55 +0100502//{ObjectTeams: generated arguments can be pre-resolved indeed:
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100503 if (argument.resolvedType != null && argument.isGenerated()) {
504 this.argumentTypes[i] = argument.resolvedType;
505 if (this.argumentTypes[i] == null)
506 this.argumentsHaveErrors = true;
507 } else {
Stephan Herrmann4fda94b2014-03-29 16:07:55 +0100508// orig:
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100509 if (this.arguments[i].resolvedType != null)
510 scope.problemReporter().genericInferenceError("Argument was unexpectedly found resolved", this); //$NON-NLS-1$
511 if ((this.argumentTypes[i] = argument.resolveType(scope)) == null) {
512 this.argumentsHaveErrors = true;
513 }
Stephan Herrmann4fda94b2014-03-29 16:07:55 +0100514// :giro
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100515 }
Stephan Herrmann4fda94b2014-03-29 16:07:55 +0100516// SH}
Stephan Herrmann78721b12014-02-12 00:01:46 +0100517 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100518 if (this.argumentsHaveErrors) {
519 /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=345359, if arguments have errors, completely bail out in the <> case.
Stephan Herrmann44109d32011-08-02 14:34:26 +0000520 No meaningful type resolution is possible since inference of the elided types is fully tied to argument types. Do
521 not return the partially resolved type.
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100522 */
523 if (isDiamond) {
524 return null; // not the partially cooked this.resolvedType
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000525 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100526 if (this.resolvedType instanceof ReferenceBinding) {
527 // record a best guess, for clients who need hint about possible constructor match
528 TypeBinding[] pseudoArgs = new TypeBinding[length];
529 for (int i = length; --i >= 0;) {
530 pseudoArgs[i] = this.argumentTypes[i] == null ? TypeBinding.NULL : this.argumentTypes[i]; // replace args with errors with null type
531 }
532 this.binding = scope.findMethod((ReferenceBinding) this.resolvedType, TypeConstants.INIT, pseudoArgs, this, false);
533 if (this.binding != null && !this.binding.isValidBinding()) {
534 MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
535 // record the closest match, for clients who may still need hint about possible method match
536 if (closestMatch != null) {
537 if (closestMatch.original().typeVariables != Binding.NO_TYPE_VARIABLES) { // generic method
538 // shouldn't return generic method outside its context, rather convert it to raw method (175409)
539 closestMatch = scope.environment().createParameterizedGenericMethod(closestMatch.original(), (RawTypeBinding)null);
540 }
541 this.binding = closestMatch;
542 MethodBinding closestMatchOriginal = closestMatch.original();
543 if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
544 // ignore cases where method is used from within inside itself (e.g. direct recursions)
545 closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
546 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000547 }
548 }
549 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100550 return this.resolvedType;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000551 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100552 }
553 if (this.resolvedType == null || !this.resolvedType.isValidBinding()) {
554 return null;
555 }
556
557 // null type denotes fake allocation for enum constant inits
558 if (this.type != null && !this.resolvedType.canBeInstantiated()) {
559 scope.problemReporter().cannotInstantiate(this.type, this.resolvedType);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000560 return this.resolvedType;
561 }
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100562 }
563 if (isDiamond) {
564 this.binding = inferConstructorOfElidedParameterizedType(scope);
565 if (this.binding == null || !this.binding.isValidBinding()) {
566 scope.problemReporter().cannotInferElidedTypes(this);
567 return this.resolvedType = null;
Stephan Herrmann44109d32011-08-02 14:34:26 +0000568 }
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100569 if (this.typeExpected == null && compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8 && this.expressionContext.definesTargetType()) {
570 return new PolyTypeBinding(this);
571 }
572 this.resolvedType = this.type.resolvedType = this.binding.declaringClass;
Stephan Herrmannfd865ba2017-10-14 19:28:38 +0200573 // 15.9.3 - If the compile-time declaration is applicable by variable arity invocation...
574 if (this.binding.isVarargs()) {
575 TypeBinding lastArg = this.binding.parameters[this.binding.parameters.length - 1].leafComponentType();
576 if (!lastArg.erasure().canBeSeenBy(scope)) {
577 scope.problemReporter().invalidType(this, new ProblemReferenceBinding(new char[][] {lastArg.readableName()}, (ReferenceBinding)lastArg, ProblemReasons.NotVisible));
578 return this.resolvedType = null;
579 }
580 }
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100581 resolvePolyExpressionArguments(this, this.binding, this.argumentTypes, scope);
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100582 } else {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000583//{ObjectTeams: may need to instantiate parameters of constructor
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100584 AnchorMapping anchorMapping = AnchorMapping.setupNewMapping(null, this.arguments, scope);
585 try {
586 // ensure allocation type has methods:
Stephan Herrmannfb991012016-03-19 21:52:20 +0100587 if (this.enumConstant == null)
588 Dependencies.ensureBindingState((ReferenceBinding) this.resolvedType, ITranslationStates.STATE_LENV_DONE_FIELDS_AND_METHODS);
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100589// orig:
590 this.binding = findConstructorBinding(scope, this, (ReferenceBinding) this.resolvedType, this.argumentTypes);
Stephan Herrmann78721b12014-02-12 00:01:46 +0100591//:giro
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100592 } finally {
593 AnchorMapping.removeCurrentMapping(anchorMapping);
594 }
Stephan Herrmann78721b12014-02-12 00:01:46 +0100595// SH}
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100596 }
Stephan Herrmannbd1255d2013-09-05 23:25:05 +0200597 if (!this.binding.isValidBinding()) {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000598//{ObjectTeams: baseclass decapsulation?
599 boolean baseclassDecapsulationAllowed =
600 this.type != null // null happens for enum constants
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100601 && this.type.getBaseclassDecapsulation((ReferenceBinding) this.resolvedType).isAllowed();
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000602 if ( this.binding.problemId() == ProblemReasons.NotVisible
603 && ( baseclassDecapsulationAllowed
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100604 || scope.isGeneratedScope()))
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000605 {
606 this.binding = ((ProblemMethodBinding)this.binding).closestMatch;
607 if (baseclassDecapsulationAllowed) {
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100608 int accessId = scope.enclosingSourceType().roleModel.addInaccessibleBaseMethod(this.binding);
609 scope.problemReporter().decapsulation(this, scope);
610 if (scope.compilerOptions().weavingScheme == WeavingScheme.OTDRE) {
Stephan Herrmann20fb5ac2014-04-03 23:32:36 +0200611 throw new ConstructorDecapsulationException(accessId);
612 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000613 }
614 } else {
615// orig:
616 if (this.binding.declaringClass == null) {
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100617 this.binding.declaringClass = (ReferenceBinding) this.resolvedType;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000618 }
619 if (this.type != null && !this.type.resolvedType.isValidBinding()) {
620 return null;
621 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100622 scope.problemReporter().invalidConstructor(this, this.binding);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000623 return this.resolvedType;
624// :giro
625 }
626// SH}
627 }
628 if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100629 scope.problemReporter().missingTypeInConstructor(this, this.binding);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000630 }
Stephan Herrmannc33eb9f2019-02-24 19:57:37 +0100631 if (isMethodUseDeprecated(this.binding, scope, true, this)) {
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100632 scope.problemReporter().deprecatedMethod(this.binding, this);
Stephan Herrmann4194d172014-11-11 21:35:54 +0100633 }
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100634 if (checkInvocationArguments(scope, null, this.resolvedType, this.binding, this.arguments, this.argumentTypes, this.argsContainCast, this)) {
Stephan Herrmann78721b12014-02-12 00:01:46 +0100635 this.bits |= ASTNode.Unchecked;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000636 }
637 if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100638 scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000639 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100640 if (!isDiamond && this.resolvedType.isParameterizedTypeWithActualArguments()) {
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100641 checkTypeArgumentRedundancy((ParameterizedTypeBinding) this.resolvedType, scope);
Stephan Herrmann44109d32011-08-02 14:34:26 +0000642 }
Stephan Herrmann075533e2015-04-28 17:54:14 +0200643 if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
Stephan Herrmannfd40c0e2017-01-27 23:32:20 +0100644 ImplicitNullAnnotationVerifier.ensureNullnessIsKnown(this.binding, scope);
Stephan Herrmann075533e2015-04-28 17:54:14 +0200645 if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
646 if (this.binding instanceof ParameterizedGenericMethodBinding && this.typeArguments != null) {
647 TypeVariableBinding[] typeVariables = this.binding.original().typeVariables();
648 for (int i = 0; i < this.typeArguments.length; i++)
Stephan Herrmannd1a89d72015-12-08 19:38:48 +0100649 this.typeArguments[i].checkNullConstraints(scope, (ParameterizedGenericMethodBinding) this.binding, typeVariables, i);
Stephan Herrmann075533e2015-04-28 17:54:14 +0200650 }
651 }
Stephan Herrmann4c6c5002013-09-12 23:09:47 +0200652 }
Stephan Herrmann6054d022016-03-19 16:21:11 +0100653 if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8 &&
654 this.binding.getTypeAnnotations() != Binding.NO_ANNOTATIONS) {
655 this.resolvedType = scope.environment().createAnnotatedType(this.resolvedType, this.binding.getTypeAnnotations());
656 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000657//{ObjectTeams: may need to wrap the resolved type
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100658 this.resolvedType = RoleTypeCreator.maybeWrapUnqualifiedRoleType(this.resolvedType, scope, this);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000659 DependentTypeBinding dependentTypeBinding = this.resolvedType.asPlainDependentType();
660 if (dependentTypeBinding != null) {
661 ITeamAnchor[] anchorPath = dependentTypeBinding._teamAnchor.getBestNamePath();
662 int len = anchorPath.length;
663 int prefixLen=0;
664 char[][] tokens;
665 if (anchorPath[0] instanceof FieldBinding && ((FieldBinding)anchorPath[0]).isStatic()) {
666 char[][] qname = TypeAnalyzer.compoundNameOfReferenceType(((FieldBinding)anchorPath[0]).declaringClass, true, false);
667 prefixLen = qname.length;
668 len += prefixLen;
669 tokens = new char[len][];
670 System.arraycopy(qname, 0, tokens, 0, qname.length);
671 } else {
672 tokens = new char[len][];
673 }
674 for (int i=0; i+prefixLen < len; i++)
675 tokens[i+prefixLen] = anchorPath[i].internalName();
676 AstGenerator gen = new AstGenerator(this);
677 if (len > 1)
678 this.valueParam = gen.qualifiedNameReference(tokens);
679 else
680 this.valueParam = gen.singleNameReference(tokens[0]);
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100681 this.valueParam.resolve(scope);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000682 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000683// SH}
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100684 return this.resolvedType;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000685}
686
Stephan Herrmann4388de02013-12-30 10:43:45 +0100687/**
688 * Check if 'allocationType' illegally has a top-level null annotation.
Stephan Herrmann4388de02013-12-30 10:43:45 +0100689 */
Stephan Herrmann5d5b2c32014-01-02 00:10:41 +0100690void checkIllegalNullAnnotation(BlockScope scope, TypeBinding allocationType) {
Stephan Herrmann4388de02013-12-30 10:43:45 +0100691 if (allocationType != null) {
692 // only check top-level null annotation (annots on details are OK):
693 long nullTagBits = allocationType.tagBits & TagBits.AnnotationNullMASK;
694 if (nullTagBits != 0) {
695 Annotation annotation = this.type.findAnnotation(nullTagBits);
Stephan Herrmannddef2c12014-01-05 18:18:25 +0100696 if (annotation != null)
697 scope.problemReporter().nullAnnotationUnsupportedLocation(annotation);
Stephan Herrmann4388de02013-12-30 10:43:45 +0100698 }
699 }
Stephan Herrmann4388de02013-12-30 10:43:45 +0100700}
701
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100702// For allocation expressions, boxing compatibility is same as vanilla compatibility, since java.lang's wrapper types are not generic.
Stephan Herrmanne4721882018-01-25 20:43:01 +0100703@Override
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100704public boolean isBoxingCompatibleWith(TypeBinding targetType, Scope scope) {
705 return isPolyExpression() ? false : isCompatibleWith(scope.boxing(targetType), scope);
706}
707
Stephan Herrmanne4721882018-01-25 20:43:01 +0100708@Override
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100709public boolean isCompatibleWith(TypeBinding targetType, final Scope scope) {
710 if (this.argumentsHaveErrors || this.binding == null || !this.binding.isValidBinding() || targetType == null || scope == null)
711 return false;
712 TypeBinding allocationType = this.resolvedType;
713 if (isPolyExpression()) {
714 TypeBinding originalExpectedType = this.typeExpected;
715 try {
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100716 MethodBinding method = this.solutionsPerTargetType != null ? this.solutionsPerTargetType.get(targetType) : null;
717 if (method == null) {
718 this.typeExpected = targetType;
719 method = inferConstructorOfElidedParameterizedType(scope); // caches result already.
720 if (method == null || !method.isValidBinding())
721 return false;
722 }
723 allocationType = method.declaringClass;
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100724 } finally {
725 this.typeExpected = originalExpectedType;
726 }
727 }
728 return allocationType != null && allocationType.isCompatibleWith(targetType, scope);
729}
730
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100731public MethodBinding inferConstructorOfElidedParameterizedType(final Scope scope) {
732 if (this.typeExpected != null && this.binding != null) {
733 MethodBinding cached = this.solutionsPerTargetType != null ? this.solutionsPerTargetType.get(this.typeExpected) : null;
734 if (cached != null)
735 return cached;
736 }
Stephan Herrmann7c967d32016-08-02 21:34:11 +0200737 boolean[] inferredReturnTypeOut = new boolean[1];
738 MethodBinding constructor = inferDiamondConstructor(scope, this, this.resolvedType, this.argumentTypes, inferredReturnTypeOut);
739 if (constructor != null) {
740 this.inferredReturnType = inferredReturnTypeOut[0];
Stephan Herrmanne2459222014-11-13 16:43:22 +0100741 if (constructor instanceof ParameterizedGenericMethodBinding && scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8) {
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100742 // force an inference context to be established for nested poly allocations (to be able to transfer b2), but avoid tunneling through overload resolution. We know this is the MSMB.
743 if (this.expressionContext == INVOCATION_CONTEXT && this.typeExpected == null)
744 constructor = ParameterizedGenericMethodBinding.computeCompatibleMethod18(constructor.shallowOriginal(), this.argumentTypes, scope, this);
Stephan Herrmanne2459222014-11-13 16:43:22 +0100745 }
Stephan Herrmann34106802019-02-02 13:45:17 +0100746 if (this.typeExpected != null && this.typeExpected.isProperType(true))
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100747 registerResult(this.typeExpected, constructor);
Stephan Herrmann7c967d32016-08-02 21:34:11 +0200748 }
749 return constructor;
750}
751
752public static MethodBinding inferDiamondConstructor(Scope scope, InvocationSite site, TypeBinding type, TypeBinding[] argumentTypes, boolean[] inferredReturnTypeOut) {
753 ReferenceBinding genericType = ((ParameterizedTypeBinding) type).genericType();
754 ReferenceBinding enclosingType = type.enclosingType();
755 ParameterizedTypeBinding allocationType = scope.environment().createParameterizedType(genericType, genericType.typeVariables(), enclosingType);
756
757 // Given the allocation type and the arguments to the constructor, see if we can infer the constructor of the elided parameterized type.
758 MethodBinding factory = scope.getStaticFactory(allocationType, enclosingType, argumentTypes, site);
759 if (factory instanceof ParameterizedGenericMethodBinding && factory.isValidBinding()) {
760 ParameterizedGenericMethodBinding genericFactory = (ParameterizedGenericMethodBinding) factory;
761 inferredReturnTypeOut[0] = genericFactory.inferredReturnType;
762 SyntheticFactoryMethodBinding sfmb = (SyntheticFactoryMethodBinding) factory.original();
763 TypeVariableBinding[] constructorTypeVariables = sfmb.getConstructor().typeVariables();
764 TypeBinding [] constructorTypeArguments = constructorTypeVariables != null ? new TypeBinding[constructorTypeVariables.length] : Binding.NO_TYPES;
765 if (constructorTypeArguments.length > 0)
766 System.arraycopy(((ParameterizedGenericMethodBinding)factory).typeArguments, sfmb.typeVariables().length - constructorTypeArguments.length ,
767 constructorTypeArguments, 0, constructorTypeArguments.length);
Stephan Herrmannfd865ba2017-10-14 19:28:38 +0200768 if (allocationType.isInterface()) {
769 ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) factory.returnType;
770 return new ParameterizedMethodBinding(parameterizedType, sfmb.getConstructor());
771 }
Stephan Herrmanna1dd2df2017-12-05 20:11:07 +0100772 return sfmb.applyTypeArgumentsOnConstructor(((ParameterizedTypeBinding)factory.returnType).arguments, constructorTypeArguments, genericFactory.inferredWithUncheckedConversion, site.invocationTargetType());
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100773 }
774 return null;
775}
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100776public TypeBinding[] inferElidedTypes(final Scope scope) {
Stephan Herrmannfd865ba2017-10-14 19:28:38 +0200777 return inferElidedTypes((ParameterizedTypeBinding) this.resolvedType, scope);
778}
779public TypeBinding[] inferElidedTypes(ParameterizedTypeBinding parameterizedType, final Scope scope) {
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100780
Stephan Herrmannfd865ba2017-10-14 19:28:38 +0200781 ReferenceBinding genericType = parameterizedType.genericType();
782 ReferenceBinding enclosingType = parameterizedType.enclosingType();
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100783 ParameterizedTypeBinding allocationType = scope.environment().createParameterizedType(genericType, genericType.typeVariables(), enclosingType);
784
Stephan Herrmann44109d32011-08-02 14:34:26 +0000785 /* Given the allocation type and the arguments to the constructor, see if we can synthesize a generic static factory
786 method that would, given the argument types and the invocation site, manufacture a parameterized object of type allocationType.
787 If we are successful then by design and construction, the parameterization of the return type of the factory method is identical
788 to the types elided in the <>.
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100789 */
790 MethodBinding factory = scope.getStaticFactory(allocationType, enclosingType, this.argumentTypes, this);
Stephan Herrmann44109d32011-08-02 14:34:26 +0000791 if (factory instanceof ParameterizedGenericMethodBinding && factory.isValidBinding()) {
792 ParameterizedGenericMethodBinding genericFactory = (ParameterizedGenericMethodBinding) factory;
793 this.inferredReturnType = genericFactory.inferredReturnType;
794 return ((ParameterizedTypeBinding)factory.returnType).arguments;
795 }
796 return null;
797}
798
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100799public void checkTypeArgumentRedundancy(ParameterizedTypeBinding allocationType, final BlockScope scope) {
Stephan Herrmann14e866b2014-03-28 20:26:29 +0100800 if ((scope.problemReporter().computeSeverity(IProblem.RedundantSpecificationOfTypeArguments) == ProblemSeverities.Ignore) || scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_7) return;
Stephan Herrmann44109d32011-08-02 14:34:26 +0000801 if (allocationType.arguments == null) return; // raw binding
802 if (this.genericTypeArguments != null) return; // diamond can't occur with explicit type args for constructor
Stephan Herrmannac2aba32014-05-01 14:58:19 +0200803 if (this.type == null) return;
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100804 if (this.argumentTypes == Binding.NO_PARAMETERS && this.typeExpected instanceof ParameterizedTypeBinding) {
Stephan Herrmann44109d32011-08-02 14:34:26 +0000805 ParameterizedTypeBinding expected = (ParameterizedTypeBinding) this.typeExpected;
806 if (expected.arguments != null && allocationType.arguments.length == expected.arguments.length) {
807 // check the case when no ctor takes no params and inference uses the expected type directly
808 // eg. X<String> x = new X<String>()
809 int i;
810 for (i = 0; i < allocationType.arguments.length; i++) {
Stephan Herrmann1bb10072014-01-03 14:36:07 +0100811 if (TypeBinding.notEquals(allocationType.arguments[i], expected.arguments[i]))
Stephan Herrmann44109d32011-08-02 14:34:26 +0000812 break;
813 }
814 if (i == allocationType.arguments.length) {
Stephan Herrmann14e866b2014-03-28 20:26:29 +0100815 scope.problemReporter().redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
Stephan Herrmann44109d32011-08-02 14:34:26 +0000816 return;
817 }
818 }
819 }
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100820 TypeBinding [] inferredTypes;
821 int previousBits = this.type.bits;
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100822 try {
823 // checking for redundant type parameters must fake a diamond,
824 // so we infer the same results as we would get with a diamond in source code:
825 this.type.bits |= IsDiamond;
Stephan Herrmannfd865ba2017-10-14 19:28:38 +0200826 inferredTypes = inferElidedTypes(allocationType, scope);
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100827 } finally {
828 // reset effects of inference
829 this.type.bits = previousBits;
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100830 }
Stephan Herrmann44109d32011-08-02 14:34:26 +0000831 if (inferredTypes == null) {
832 return;
833 }
834 for (int i = 0; i < inferredTypes.length; i++) {
Stephan Herrmann1bb10072014-01-03 14:36:07 +0100835 if (TypeBinding.notEquals(inferredTypes[i], allocationType.arguments[i]))
Stephan Herrmann44109d32011-08-02 14:34:26 +0000836 return;
837 }
Stephan Herrmann14e866b2014-03-28 20:26:29 +0100838 scope.problemReporter().redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
Stephan Herrmann44109d32011-08-02 14:34:26 +0000839}
840
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000841//{ObjectTeams: replace with and resolved role creation expression:
842private TypeBinding resolveAsRoleCreationExpression(ReferenceBinding typeBinding, BlockScope scope) {
843 RoleModel roleModel = typeBinding.roleModel;
844 ReferenceBinding roleClass = roleModel.getClassPartBinding();
845 // creating a role that should not be instantiated (OTJLD 2.4.3)?
846 if (typeBinding.isRole()) {
847 ReferenceBinding subRole = roleClass.roleModel._supercededBy;
848 if (subRole != null)
849 scope.problemReporter().instantiatingSupercededRole(this, subRole);
850 }
851
852 if ( !StateMemento.hasMethodResolveStarted(typeBinding)
853 && roleClass != null)
854 {
855 Dependencies.ensureRoleState(
856 roleClass.roleModel,
857 ITranslationStates.STATE_METHODS_CREATED); // forces creation method to be created
858 }
859
860 if (!RoleTypeBinding.isRoleWithExplicitAnchor(typeBinding)) {
861 ReferenceBinding enclosingType = scope.enclosingReceiverType();
862 if (scope.methodScope().isStatic)
863 enclosingType = enclosingType.enclosingType();
864 ReferenceBinding targetEnclosing = roleClass != null
865 ? roleClass.enclosingType()
866 : roleModel.getTeamModel().getBinding();
Stephan Herrmannb8575932014-01-03 22:34:59 +0100867 while (enclosingType != null && TypeBinding.notEquals(enclosingType.original(), targetEnclosing)) {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000868 enclosingType = enclosingType.enclosingType();
869 }
870 if (enclosingType == null) {
871 // create a dummy binding for error reporting (just need declaringClass):
872 this.binding = new MethodBinding(0, Binding.NO_PARAMETERS, Binding.NO_EXCEPTIONS, typeBinding);
873 scope.problemReporter().noSuchEnclosingInstance(
874 typeBinding.enclosingType(), this, false);
875 return null;
876 }
877 }
878
879 if (roleModel.hasBaseclassProblem()) {
880 scope.methodScope().referenceContext.tagAsHavingErrors();
881 return null; // creator is not generated.
882 }
883
884 this.roleCreatorCall = CopyInheritance.createConstructorMethodInvocationExpression(scope, this);
885 if (this.roleCreatorCall == null)
886 return null;
887
888 this.resolvedType = this.roleCreatorCall.resolveType(scope);
Stephan Herrmann85a866e2011-01-27 00:55:45 +0000889 if (typeBinding.isParameterizedType()) {
890 this.resolvedType = scope.environment().createParameterizedType(
891 (ReferenceBinding)this.resolvedType,
892 ((ParameterizedTypeBinding)typeBinding).arguments,
893 this.resolvedType.enclosingType());
894 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000895
896 // UI needs to find the method in this.binding:
897 MethodBinding origBinding = this.roleCreatorCall.binding;
898 if (origBinding != null && origBinding.model != null && origBinding.model._srcCtor != null)
899 this.binding = origBinding.model._srcCtor;
900 else
901 this.binding = origBinding;
902
903 return this.resolvedType;
904}
905// SH}
906
Stephan Herrmanne4721882018-01-25 20:43:01 +0100907@Override
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000908public void setActualReceiverType(ReferenceBinding receiverType) {
909 // ignored
910}
911
Stephan Herrmanne4721882018-01-25 20:43:01 +0100912@Override
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000913public void setDepth(int i) {
914 // ignored
915}
916
Stephan Herrmanne4721882018-01-25 20:43:01 +0100917@Override
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000918public void setFieldIndex(int i) {
919 // ignored
920}
921
Stephan Herrmanne4721882018-01-25 20:43:01 +0100922@Override
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000923public void traverse(ASTVisitor visitor, BlockScope scope) {
924//{ObjectTeams: alternate ast
925 if (this.roleCreatorCall != null) {
926 this.roleCreatorCall.traverse(visitor, scope);
927 return;
928 }
929// SH}
930
931 if (visitor.visit(this, scope)) {
932 if (this.typeArguments != null) {
933 for (int i = 0, typeArgumentsLength = this.typeArguments.length; i < typeArgumentsLength; i++) {
934 this.typeArguments[i].traverse(visitor, scope);
935 }
936 }
937 if (this.type != null) { // enum constant scenario
938 this.type.traverse(visitor, scope);
939 }
940 if (this.arguments != null) {
941 for (int i = 0, argumentsLength = this.arguments.length; i < argumentsLength; i++)
942 this.arguments[i].traverse(visitor, scope);
943 }
944 }
945 visitor.endVisit(this, scope);
946}
Stephan Herrmann44109d32011-08-02 14:34:26 +0000947/**
948 * @see org.eclipse.jdt.internal.compiler.ast.Expression#setExpectedType(org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
949 */
Stephan Herrmanne4721882018-01-25 20:43:01 +0100950@Override
Stephan Herrmann44109d32011-08-02 14:34:26 +0000951public void setExpectedType(TypeBinding expectedType) {
952 this.typeExpected = expectedType;
953}
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200954
Stephan Herrmanne4721882018-01-25 20:43:01 +0100955@Override
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200956public void setExpressionContext(ExpressionContext context) {
957 this.expressionContext = context;
958}
959
Stephan Herrmanne4721882018-01-25 20:43:01 +0100960@Override
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200961public boolean isPolyExpression() {
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100962 return isPolyExpression(this.binding);
963}
Stephan Herrmanne4721882018-01-25 20:43:01 +0100964@Override
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100965public boolean isPolyExpression(MethodBinding method) {
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200966 return (this.expressionContext == ASSIGNMENT_CONTEXT || this.expressionContext == INVOCATION_CONTEXT) &&
967 this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
968}
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100969
Stephan Herrmann44109d32011-08-02 14:34:26 +0000970/**
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100971 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#invocationTargetType()
Stephan Herrmann44109d32011-08-02 14:34:26 +0000972 */
Stephan Herrmanne4721882018-01-25 20:43:01 +0100973@Override
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100974public TypeBinding invocationTargetType() {
Stephan Herrmann44109d32011-08-02 14:34:26 +0000975 return this.typeExpected;
976}
977
Stephan Herrmanne4721882018-01-25 20:43:01 +0100978@Override
Stephan Herrmann59cd3cc2013-05-01 23:38:47 +0200979public boolean statementExpression() {
Stephan Herrmann075533e2015-04-28 17:54:14 +0200980 return ((this.bits & ASTNode.ParenthesizedMASK) == 0);
Stephan Herrmann59cd3cc2013-05-01 23:38:47 +0200981}
982
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100983//-- interface Invocation: --
Stephan Herrmanne4721882018-01-25 20:43:01 +0100984@Override
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100985public MethodBinding binding() {
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100986 return this.binding;
987}
Stephan Herrmanne4721882018-01-25 20:43:01 +0100988@Override
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100989public Expression[] arguments() {
990 return this.arguments;
991}
Stephan Herrmanna28db532014-01-05 14:59:05 +0100992
Stephan Herrmanne4721882018-01-25 20:43:01 +0100993@Override
Stephan Herrmanna28db532014-01-05 14:59:05 +0100994public void registerInferenceContext(ParameterizedGenericMethodBinding method, InferenceContext18 infCtx18) {
995 if (this.inferenceContexts == null)
996 this.inferenceContexts = new SimpleLookupTable();
997 this.inferenceContexts.put(method, infCtx18);
Stephan Herrmann78721b12014-02-12 00:01:46 +0100998}
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100999
1000@Override
1001public void registerResult(TypeBinding targetType, MethodBinding method) {
1002 if (method != null && method.isConstructor()) { // ignore the factory.
1003 if (this.solutionsPerTargetType == null)
Stephan Herrmann210dc3a2015-08-13 22:46:42 +02001004 this.solutionsPerTargetType = new HashMap<>();
Stephan Herrmanne6a1a642014-11-15 14:33:08 +01001005 this.solutionsPerTargetType.put(targetType, method);
1006 }
1007}
1008
Stephan Herrmanne4721882018-01-25 20:43:01 +01001009@Override
Stephan Herrmann4d079452014-03-27 18:01:49 +01001010public InferenceContext18 getInferenceContext(ParameterizedMethodBinding method) {
Stephan Herrmanna28db532014-01-05 14:59:05 +01001011 if (this.inferenceContexts == null)
1012 return null;
1013 return (InferenceContext18) this.inferenceContexts.get(method);
1014}
Stephan Herrmannd1a89d72015-12-08 19:38:48 +01001015
1016@Override
1017public void cleanUpInferenceContexts() {
1018 if (this.inferenceContexts == null)
1019 return;
1020 for (Object value : this.inferenceContexts.valueTable)
1021 if (value != null)
1022 ((InferenceContext18) value).cleanUp();
1023 this.inferenceContexts = null;
Stephan Herrmann6054d022016-03-19 16:21:11 +01001024 this.outerInferenceContext = null;
1025 this.solutionsPerTargetType = null;
Stephan Herrmannd1a89d72015-12-08 19:38:48 +01001026}
1027
Stephan Herrmannc1c48622014-01-04 23:19:31 +01001028//-- interface InvocationSite: --
Stephan Herrmanne4721882018-01-25 20:43:01 +01001029@Override
Stephan Herrmannc1c48622014-01-04 23:19:31 +01001030public ExpressionContext getExpressionContext() {
1031 return this.expressionContext;
1032}
Stephan Herrmanne4721882018-01-25 20:43:01 +01001033@Override
Stephan Herrmannc1c48622014-01-04 23:19:31 +01001034public InferenceContext18 freshInferenceContext(Scope scope) {
Stephan Herrmann32fd38b2014-12-13 15:26:29 +01001035 return new InferenceContext18(scope, this.arguments, this, this.outerInferenceContext);
Stephan Herrmannc1c48622014-01-04 23:19:31 +01001036}
Stephan Herrmannc33eb9f2019-02-24 19:57:37 +01001037@Override
1038public int nameSourceStart() {
1039 return this.type.sourceStart;
1040}
1041@Override
1042public int nameSourceEnd() {
1043 return this.type.sourceEnd;
1044}
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +01001045}