1 /*******************************************************************************
2  * Copyright (c) 2000, 2014 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *     Stephan Herrmann - Contributions for
11  *     						bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
12  *     						bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
13  *     						bug 349326 - [1.7] new warning for missing try-with-resources
14  * 							bug 186342 - [compiler][null] Using annotations for null checking
15  *							bug 358903 - Filter practically unimportant resource leak warnings
16  *							bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
17  *							bug 370639 - [compiler][resource] restore the default for resource leak warnings
18  *							bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
19  *							bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
20  *							bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
21  *							Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations
22  *							Bug 417295 - [1.8[[null] Massage type annotated null analysis to gel well with deep encoded type bindings.
23  *							Bug 400874 - [1.8][compiler] Inference infrastructure should evolve to meet JLS8 18.x (Part G of JSR335 spec)
24  *							Bug 424727 - [compiler][null] NullPointerException in nullAnnotationUnsupportedLocation(ProblemReporter.java:5708)
25  *							Bug 424710 - [1.8][compiler] CCE in SingleNameReference.localVariableBinding
26  *							Bug 425152 - [1.8] [compiler] Lambda Expression not resolved but flow analyzed leading to NPE.
27  *							Bug 424205 - [1.8] Cannot infer type for diamond type with lambda on method invocation
28  *							Bug 424415 - [1.8][compiler] Eventual resolution of ReferenceExpression is not seen to be happening.
29  *							Bug 426366 - [1.8][compiler] Type inference doesn't handle multiple candidate target types in outer overload context
30  *							Bug 426290 - [1.8][compiler] Inference + overloading => wrong method resolution ?
31  *							Bug 426764 - [1.8] Presence of conditional expression as method argument confuses compiler
32  *							Bug 424930 - [1.8][compiler] Regression: "Cannot infer type arguments" error from compiler.
33  *							Bug 427483 - [Java 8] Variables in lambdas sometimes can't be resolved
34  *							Bug 427438 - [1.8][compiler] NPE at org.eclipse.jdt.internal.compiler.ast.ConditionalExpression.generateCode(ConditionalExpression.java:280)
35  *							Bug 426996 - [1.8][inference] try to avoid method Expression.unresolve()?
36  *							Bug 428352 - [1.8][compiler] Resolution errors don't always surface
37  *							Bug 429203 - [1.8][compiler] NPE in AllocationExpression.binding
38  *							Bug 429430 - [1.8] Lambdas and method reference infer wrong exception type with generics (RuntimeException instead of IOException)
39  *							Bug 434297 - [1.8] NPE in LamdaExpression.analyseCode with lamda expression nested in a conditional expression
40  *     Jesper S Moller <jesper@selskabet.org> - Contributions for
41  *							bug 378674 - "The method can be declared as static" is wrong
42  *     Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
43  *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
44  *                          Bug 409245 - [1.8][compiler] Type annotations dropped when call is routed through a synthetic bridge method
45  *     Till Brychcy - Contributions for
46  *     						bug 413460 - NonNullByDefault is not inherited to Constructors when accessed via Class File
47  *******************************************************************************/
48 package org.eclipse.jdt.internal.compiler.ast;
49 
50 import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.*;
51 
52 import org.eclipse.jdt.core.compiler.IProblem;
53 import org.eclipse.jdt.internal.compiler.ASTVisitor;
54 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
55 import org.eclipse.jdt.internal.compiler.codegen.*;
56 import org.eclipse.jdt.internal.compiler.flow.*;
57 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
58 import org.eclipse.jdt.internal.compiler.impl.Constant;
59 import org.eclipse.jdt.internal.compiler.lookup.*;
60 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
61 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
62 
63 public class AllocationExpression extends Expression implements Invocation {
64 
65 	public TypeReference type;
66 	public Expression[] arguments;
67 	public MethodBinding binding;							// exact binding resulting from lookup
68 	MethodBinding syntheticAccessor;						// synthetic accessor for inner-emulation
69 	public TypeReference[] typeArguments;
70 	public TypeBinding[] genericTypeArguments;
71 	public FieldDeclaration enumConstant; // for enum constant initializations
72 	protected TypeBinding typeExpected;	  // for <> inference
73 	public boolean inferredReturnType;
74 
75 	public FakedTrackingVariable closeTracker;	// when allocation a Closeable store a pre-liminary tracking variable here
76 	private ExpressionContext expressionContext = VANILLA_CONTEXT;
77 
78 	 // hold on to this context from invocation applicability inference until invocation type inference (per method candidate):
79 	private SimpleLookupTable/*<PMB,IC18>*/ inferenceContexts;
80 	protected InnerInferenceHelper innerInferenceHelper;
81 	public boolean argumentsHaveErrors;
82 
83 	/** Record to keep state between different parts of resolution. */
84 	ResolutionState suspendedResolutionState;
85 	class ResolutionState {
86 		BlockScope scope;
87 		boolean isDiamond;
88 		boolean diamondNeedsDeferring;
89 		boolean argsContainCast;
90 		boolean cannotInferDiamond; // request the an error be reported in due time
91 		TypeBinding[] argumentTypes;
92 		boolean hasReportedError;
93 
ResolutionState(BlockScope scope, boolean isDiamond, boolean diamonNeedsDeferring, boolean argsContainCast, TypeBinding[] argumentTypes)94 		ResolutionState(BlockScope scope, boolean isDiamond, boolean diamonNeedsDeferring,
95 				boolean argsContainCast, TypeBinding[] argumentTypes)
96 		{
97 			this.scope = scope;
98 			this.isDiamond = isDiamond;
99 			this.diamondNeedsDeferring = diamonNeedsDeferring;
100 			this.argsContainCast = argsContainCast;
101 			this.argumentTypes = argumentTypes;
102 		}
103 	}
104 
analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo)105 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
106 	// check captured variables are initialized in current context (26134)
107 	checkCapturedLocalInitializationIfNecessary((ReferenceBinding)this.binding.declaringClass.erasure(), currentScope, flowInfo);
108 
109 	// process arguments
110 	if (this.arguments != null) {
111 		boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
112 		boolean hasResourceWrapperType = analyseResources
113 				&& this.resolvedType instanceof ReferenceBinding
114 				&& ((ReferenceBinding)this.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable);
115 		for (int i = 0, count = this.arguments.length; i < count; i++) {
116 			flowInfo =
117 				this.arguments[i]
118 					.analyseCode(currentScope, flowContext, flowInfo)
119 					.unconditionalInits();
120 			// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
121 			if (analyseResources && !hasResourceWrapperType) { // allocation of wrapped closeables is analyzed specially
122 				flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, flowContext, false);
123 			}
124 			this.arguments[i].checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
125 		}
126 		analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
127 	}
128 
129 	// record some dependency information for exception types
130 	ReferenceBinding[] thrownExceptions;
131 	if (((thrownExceptions = this.binding.thrownExceptions).length) != 0) {
132 		if ((this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null) {
133 			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
134 			thrownExceptions = currentScope.environment().convertToRawTypes(this.binding.thrownExceptions, true, true);
135 		}
136 		// check exception handling
137 		flowContext.checkExceptionHandlers(
138 			thrownExceptions,
139 			this,
140 			flowInfo.unconditionalCopy(),
141 			currentScope);
142 	}
143 
144 	// after having analysed exceptions above start tracking newly allocated resource:
145 	if (currentScope.compilerOptions().analyseResourceLeaks && FakedTrackingVariable.isAnyCloseable(this.resolvedType))
146 		FakedTrackingVariable.analyseCloseableAllocation(currentScope, flowInfo, this);
147 
148 	if (this.binding.declaringClass.isMemberType() && !this.binding.declaringClass.isStatic()) {
149 		// allocating a non-static member type without an enclosing instance of parent type
150 		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=335845
151 		currentScope.tagAsAccessingEnclosingInstanceStateOf(this.binding.declaringClass.enclosingType(), false /* type variable access */);
152 		// Reviewed for https://bugs.eclipse.org/bugs/show_bug.cgi?id=378674 :
153 		// The corresponding problem (when called from static) is not produced until during code generation
154 	}
155 	manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
156 	manageSyntheticAccessIfNecessary(currentScope, flowInfo);
157 
158 	// account for possible exceptions thrown by the constructor
159 	flowContext.recordAbruptExit(); // TODO whitelist of ctors that cannot throw any exc.??
160 
161 	return flowInfo;
162 }
163 
checkCapturedLocalInitializationIfNecessary(ReferenceBinding checkedType, BlockScope currentScope, FlowInfo flowInfo)164 public void checkCapturedLocalInitializationIfNecessary(ReferenceBinding checkedType, BlockScope currentScope, FlowInfo flowInfo) {
165 	if (((checkedType.tagBits & ( TagBits.AnonymousTypeMask|TagBits.LocalTypeMask)) == TagBits.LocalTypeMask)
166 			&& !currentScope.isDefinedInType(checkedType)) { // only check external allocations
167 		NestedTypeBinding nestedType = (NestedTypeBinding) checkedType;
168 		SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables();
169 		if (syntheticArguments != null)
170 			for (int i = 0, count = syntheticArguments.length; i < count; i++){
171 				SyntheticArgumentBinding syntheticArgument = syntheticArguments[i];
172 				LocalVariableBinding targetLocal;
173 				if ((targetLocal = syntheticArgument.actualOuterLocalVariable) == null) continue;
174 				if (targetLocal.declaration != null && !flowInfo.isDefinitelyAssigned(targetLocal)){
175 					currentScope.problemReporter().uninitializedLocalVariable(targetLocal, this);
176 				}
177 			}
178 	}
179 }
180 
enclosingInstance()181 public Expression enclosingInstance() {
182 	return null;
183 }
184 
generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired)185 public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
186 	if (!valueRequired)
187 		currentScope.problemReporter().unusedObjectAllocation(this);
188 
189 	int pc = codeStream.position;
190 	MethodBinding codegenBinding = this.binding.original();
191 	ReferenceBinding allocatedType = codegenBinding.declaringClass;
192 
193 	codeStream.new_(this.type, allocatedType);
194 	boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
195 	if (valueRequired || isUnboxing) {
196 		codeStream.dup();
197 	}
198 	// better highlight for allocation: display the type individually
199 	if (this.type != null) { // null for enum constant body
200 		codeStream.recordPositionsFrom(pc, this.type.sourceStart);
201 	} else {
202 		// push enum constant name and ordinal
203 		codeStream.ldc(String.valueOf(this.enumConstant.name));
204 		codeStream.generateInlinedValue(this.enumConstant.binding.id);
205 	}
206 
207 	// handling innerclass instance allocation - enclosing instance arguments
208 	if (allocatedType.isNestedType()) {
209 		codeStream.generateSyntheticEnclosingInstanceValues(
210 			currentScope,
211 			allocatedType,
212 			enclosingInstance(),
213 			this);
214 	}
215 	// generate the arguments for constructor
216 	generateArguments(this.binding, this.arguments, currentScope, codeStream);
217 	// handling innerclass instance allocation - outer local arguments
218 	if (allocatedType.isNestedType()) {
219 		codeStream.generateSyntheticOuterArgumentValues(
220 			currentScope,
221 			allocatedType,
222 			this);
223 	}
224 	// invoke constructor
225 	if (this.syntheticAccessor == null) {
226 		codeStream.invoke(Opcodes.OPC_invokespecial, codegenBinding, null /* default declaringClass */, this.typeArguments);
227 	} else {
228 		// synthetic accessor got some extra arguments appended to its signature, which need values
229 		for (int i = 0,
230 			max = this.syntheticAccessor.parameters.length - codegenBinding.parameters.length;
231 			i < max;
232 			i++) {
233 			codeStream.aconst_null();
234 		}
235 		codeStream.invoke(Opcodes.OPC_invokespecial, this.syntheticAccessor, null /* default declaringClass */, this.typeArguments);
236 	}
237 	if (valueRequired) {
238 		codeStream.generateImplicitConversion(this.implicitConversion);
239 	} else if (isUnboxing) {
240 		// conversion only generated if unboxing
241 		codeStream.generateImplicitConversion(this.implicitConversion);
242 		switch (postConversionType(currentScope).id) {
243 			case T_long :
244 			case T_double :
245 				codeStream.pop2();
246 				break;
247 			default :
248 				codeStream.pop();
249 		}
250 	}
251 	codeStream.recordPositionsFrom(pc, this.sourceStart);
252 }
253 
254 /**
255  * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
256  */
genericTypeArguments()257 public TypeBinding[] genericTypeArguments() {
258 	return this.genericTypeArguments;
259 }
260 
isSuperAccess()261 public boolean isSuperAccess() {
262 	return false;
263 }
264 
isTypeAccess()265 public boolean isTypeAccess() {
266 	return true;
267 }
268 
269 /* Inner emulation consists in either recording a dependency
270  * link only, or performing one level of propagation.
271  *
272  * Dependency mechanism is used whenever dealing with source target
273  * types, since by the time we reach them, we might not yet know their
274  * exact need.
275  */
manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo)276 public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
277 	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
278 	ReferenceBinding allocatedTypeErasure = (ReferenceBinding) this.binding.declaringClass.erasure();
279 
280 	// perform some emulation work in case there is some and we are inside a local type only
281 	if (allocatedTypeErasure.isNestedType()
282 		&& (currentScope.enclosingSourceType().isLocalType() || currentScope.isLambdaScope())) {
283 
284 		if (allocatedTypeErasure.isLocalType()) {
285 			((LocalTypeBinding) allocatedTypeErasure).addInnerEmulationDependent(currentScope, false);
286 			// request cascade of accesses
287 		} else {
288 			// locally propagate, since we already now the desired shape for sure
289 			currentScope.propagateInnerEmulation(allocatedTypeErasure, false);
290 			// request cascade of accesses
291 		}
292 	}
293 }
294 
manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo)295 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
296 	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
297 	// if constructor from parameterized type got found, use the original constructor at codegen time
298 	MethodBinding codegenBinding = this.binding.original();
299 
300 	ReferenceBinding declaringClass;
301 	if (codegenBinding.isPrivate() && TypeBinding.notEquals(currentScope.enclosingSourceType(), (declaringClass = codegenBinding.declaringClass))) {
302 
303 		// from 1.4 on, local type constructor can lose their private flag to ease emulation
304 		if ((declaringClass.tagBits & TagBits.IsLocalType) != 0 && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
305 			// constructor will not be dumped as private, no emulation required thus
306 			codegenBinding.tagBits |= TagBits.ClearPrivateModifier;
307 		} else {
308 			this.syntheticAccessor = ((SourceTypeBinding) declaringClass).addSyntheticMethod(codegenBinding, isSuperAccess());
309 			currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
310 		}
311 	}
312 }
313 
printExpression(int indent, StringBuffer output)314 public StringBuffer printExpression(int indent, StringBuffer output) {
315 	if (this.type != null) { // type null for enum constant initializations
316 		output.append("new "); //$NON-NLS-1$
317 	}
318 	if (this.typeArguments != null) {
319 		output.append('<');
320 		int max = this.typeArguments.length - 1;
321 		for (int j = 0; j < max; j++) {
322 			this.typeArguments[j].print(0, output);
323 			output.append(", ");//$NON-NLS-1$
324 		}
325 		this.typeArguments[max].print(0, output);
326 		output.append('>');
327 	}
328 	if (this.type != null) { // type null for enum constant initializations
329 		this.type.printExpression(0, output);
330 	}
331 	output.append('(');
332 	if (this.arguments != null) {
333 		for (int i = 0; i < this.arguments.length; i++) {
334 			if (i > 0) output.append(", "); //$NON-NLS-1$
335 			this.arguments[i].printExpression(0, output);
336 		}
337 	}
338 	return output.append(')');
339 }
340 
resolveType(BlockScope scope)341 public TypeBinding resolveType(BlockScope scope) {
342 	// Propagate the type checking to the arguments, and check if the constructor is defined.
343 	final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
344 	final CompilerOptions compilerOptions = scope.compilerOptions();
345 	boolean diamondNeedsDeferring = false;
346 	long sourceLevel = compilerOptions.sourceLevel;
347 	if (this.constant != Constant.NotAConstant) {
348 		this.constant = Constant.NotAConstant;
349 		if (this.type == null) {
350 			// initialization of an enum constant
351 			this.resolvedType = scope.enclosingReceiverType();
352 		} else {
353 			this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
354 			if (isDiamond && this.typeExpected == null && this.expressionContext == INVOCATION_CONTEXT && sourceLevel >= ClassFileConstants.JDK1_8) {
355 				if (this.resolvedType != null && this.resolvedType.isValidBinding())
356 					diamondNeedsDeferring = true;
357 			}
358 		}
359 	} else {
360 		this.resolvedType = this.type.resolvedType;
361 	}
362 
363 	if (this.type != null) {
364 		checkIllegalNullAnnotation(scope, this.resolvedType);
365 		checkParameterizedAllocation: {
366 			if (this.type instanceof ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
367 				ReferenceBinding currentType = (ReferenceBinding)this.resolvedType;
368 				if (currentType == null) return currentType;
369 				do {
370 					// isStatic() is answering true for toplevel types
371 					if ((currentType.modifiers & ClassFileConstants.AccStatic) != 0) break checkParameterizedAllocation;
372 					if (currentType.isRawType()) break checkParameterizedAllocation;
373 				} while ((currentType = currentType.enclosingType())!= null);
374 				ParameterizedQualifiedTypeReference qRef = (ParameterizedQualifiedTypeReference) this.type;
375 				for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
376 					if (qRef.typeArguments[i] != null) {
377 						scope.problemReporter().illegalQualifiedParameterizedTypeAllocation(this.type, this.resolvedType);
378 						break;
379 					}
380 				}
381 			}
382 		}
383 	}
384 	// will check for null after args are resolved
385 
386 	// resolve type arguments (for generic constructor call)
387 	if (this.typeArguments != null) {
388 		int length = this.typeArguments.length;
389 		this.argumentsHaveErrors = sourceLevel < ClassFileConstants.JDK1_5;
390 		this.genericTypeArguments = new TypeBinding[length];
391 		for (int i = 0; i < length; i++) {
392 			TypeReference typeReference = this.typeArguments[i];
393 			if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
394 				this.argumentsHaveErrors = true;
395 			}
396 			if (this.argumentsHaveErrors && typeReference instanceof Wildcard) {
397 				scope.problemReporter().illegalUsageOfWildcard(typeReference);
398 			}
399 		}
400 		if (isDiamond) {
401 			scope.problemReporter().diamondNotWithExplicitTypeArguments(this.typeArguments);
402 			return null;
403 		}
404 		if (this.argumentsHaveErrors) {
405 			if (this.arguments != null) { // still attempt to resolve arguments
406 				for (int i = 0, max = this.arguments.length; i < max; i++) {
407 					this.arguments[i].resolveType(scope);
408 				}
409 			}
410 			return null;
411 		}
412 	}
413 
414 	// buffering the arguments' types
415 	boolean argsContainCast = false;
416 	TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
417 	if (this.arguments != null) {
418 		this.argumentsHaveErrors = false;
419 		int length = this.arguments.length;
420 		argumentTypes = new TypeBinding[length];
421 		for (int i = 0; i < length; i++) {
422 			Expression argument = this.arguments[i];
423 			if (argument instanceof CastExpression) {
424 				argument.bits |= DisableUnnecessaryCastCheck; // will check later on
425 				argsContainCast = true;
426 			}
427 			argument.setExpressionContext(INVOCATION_CONTEXT);
428 			if (this.arguments[i].resolvedType != null)
429 				scope.problemReporter().genericInferenceError("Argument was unexpectedly found resolved", this); //$NON-NLS-1$
430 			if ((argumentTypes[i] = argument.resolveType(scope)) == null) {
431 				this.argumentsHaveErrors = true;
432 			}
433 			if (sourceLevel >= ClassFileConstants.JDK1_8 && (argument.isPolyExpression() || ((argument instanceof Invocation) && ((Invocation) argument).usesInference()))) {
434 				if (this.innerInferenceHelper == null)
435 					this.innerInferenceHelper = new InnerInferenceHelper();
436 			}
437 		}
438 		if (this.argumentsHaveErrors) {
439 			/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=345359, if arguments have errors, completely bail out in the <> case.
440 			   No meaningful type resolution is possible since inference of the elided types is fully tied to argument types. Do
441 			   not return the partially resolved type.
442 			 */
443 			if (isDiamond) {
444 				return null; // not the partially cooked this.resolvedType
445 			}
446 			if (this.resolvedType instanceof ReferenceBinding) {
447 				// record a best guess, for clients who need hint about possible constructor match
448 				TypeBinding[] pseudoArgs = new TypeBinding[length];
449 				for (int i = length; --i >= 0;) {
450 					pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
451 				}
452 				this.binding = scope.findMethod((ReferenceBinding) this.resolvedType, TypeConstants.INIT, pseudoArgs, this, false);
453 				if (this.binding != null && !this.binding.isValidBinding()) {
454 					MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
455 					// record the closest match, for clients who may still need hint about possible method match
456 					if (closestMatch != null) {
457 						if (closestMatch.original().typeVariables != Binding.NO_TYPE_VARIABLES) { // generic method
458 							// shouldn't return generic method outside its context, rather convert it to raw method (175409)
459 							closestMatch = scope.environment().createParameterizedGenericMethod(closestMatch.original(), (RawTypeBinding)null);
460 						}
461 						this.binding = closestMatch;
462 						MethodBinding closestMatchOriginal = closestMatch.original();
463 						if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
464 							// ignore cases where method is used from within inside itself (e.g. direct recursions)
465 							closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
466 						}
467 					}
468 				}
469 			}
470 			return this.resolvedType;
471 		}
472 	}
473 	if (this.resolvedType == null || !this.resolvedType.isValidBinding()) {
474 		return null;
475 	}
476 
477 	// null type denotes fake allocation for enum constant inits
478 	if (this.type != null && !this.resolvedType.canBeInstantiated()) {
479 		scope.problemReporter().cannotInstantiate(this.type, this.resolvedType);
480 		return this.resolvedType;
481 	}
482 	ResolutionState state = new ResolutionState(scope, isDiamond, diamondNeedsDeferring, argsContainCast, argumentTypes);
483 	if (diamondNeedsDeferring) {
484 		this.suspendedResolutionState = state; // resolving to be continued later (via binding(TypeBinding targetType)).
485 		return new PolyTypeBinding(this);
486 	}
487 
488 	if (!resolvePart2(state))
489 		return null;
490 	return resolvePart3(state);
491 }
492 
493 /** Second part of resolving that may happen multiple times during overload resolution. */
494 boolean resolvePart2(ResolutionState state) {
495 	// TODO: all information persisted during this method may need to be stored per targetType?
496 	if (state.isDiamond) {
497 		ReferenceBinding genericType = ((ParameterizedTypeBinding) this.resolvedType).genericType();
498 		TypeBinding [] inferredTypes = inferElidedTypes((ParameterizedTypeBinding) this.resolvedType, this.resolvedType.enclosingType(), state.argumentTypes, state.scope);
499 		if (inferredTypes == null) {
500 			if (!state.diamondNeedsDeferring) {
501 				state.scope.problemReporter().cannotInferElidedTypes(this);
502 				state.hasReportedError = true;
503 				this.resolvedType = null;
504 			} else {
505 				state.cannotInferDiamond = true; // defer reporting
506 			}
507 			return false;
508 		}
509 		this.resolvedType = this.type.resolvedType = state.scope.environment().createParameterizedType(genericType, inferredTypes, ((ParameterizedTypeBinding) this.resolvedType).enclosingType());
510 		state.cannotInferDiamond = false;
511  	}
512 	ReferenceBinding receiverType = (ReferenceBinding) this.resolvedType;
513 	this.binding = findConstructorBinding(state.scope, this, receiverType, state.argumentTypes);
514 	return true;
515 }
516 
517 /** Final part of resolving (once): check and report various error conditions. */
518 TypeBinding resolvePart3(ResolutionState state) {
519 	if (this.suspendedResolutionState != null && this.suspendedResolutionState.hasReportedError)
520 		return this.resolvedType;
521 	this.suspendedResolutionState = null;
522 	if (state.cannotInferDiamond) {
523 		state.scope.problemReporter().cannotInferElidedTypes(this);
524 		return this.resolvedType = null;
525 	}
526 	ReferenceBinding allocationType = (ReferenceBinding) this.resolvedType;
527 	if (!this.binding.isValidBinding()) {
528 		if (this.binding.declaringClass == null) {
529 			this.binding.declaringClass = allocationType;
530 		}
531 		if (this.type != null && !this.type.resolvedType.isValidBinding()) {
532 			return null;
533 		}
534 		state.scope.problemReporter().invalidConstructor(this, this.binding);
535 		return this.resolvedType;
536 	}
537 	if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
538 		state.scope.problemReporter().missingTypeInConstructor(this, this.binding);
539 	}
540 	if (isMethodUseDeprecated(this.binding, state.scope, true)) {
541 		state.scope.problemReporter().deprecatedMethod(this.binding, this);
542 	}
543 	if (checkInvocationArguments(state.scope, null, allocationType, this.binding, this.arguments, state.argumentTypes, state.argsContainCast, this)) {
544 		this.bits |= ASTNode.Unchecked;
545 	}
546 	if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
547 		state.scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
548 	}
549 	if (!state.isDiamond && this.resolvedType.isParameterizedTypeWithActualArguments()) {
550  		checkTypeArgumentRedundancy((ParameterizedTypeBinding) this.resolvedType, this.resolvedType.enclosingType(), state.argumentTypes, state.scope);
551  	}
552 	CompilerOptions compilerOptions = state.scope.compilerOptions();
553 	if (compilerOptions.isAnnotationBasedNullAnalysisEnabled && (this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
554 		new ImplicitNullAnnotationVerifier(state.scope.environment(), compilerOptions.inheritNullAnnotations)
555 				.checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, state.scope);
556 	}
557 	recordExceptionsForEnclosingLambda(state.scope, this.binding.thrownExceptions);
558 	return allocationType;
559 }
560 
561 /**
562  * Check if 'allocationType' illegally has a top-level null annotation.
563  */
564 void checkIllegalNullAnnotation(BlockScope scope, TypeBinding allocationType) {
565 	if (allocationType != null) {
566 		// only check top-level null annotation (annots on details are OK):
567 		long nullTagBits = allocationType.tagBits & TagBits.AnnotationNullMASK;
568 		if (nullTagBits != 0) {
569 			Annotation annotation = this.type.findAnnotation(nullTagBits);
570 			if (annotation != null)
571 				scope.problemReporter().nullAnnotationUnsupportedLocation(annotation);
572 		}
573 	}
574 }
575 
576 public TypeBinding[] inferElidedTypes(ParameterizedTypeBinding allocationType, ReferenceBinding enclosingType, TypeBinding[] argumentTypes, final BlockScope scope) {
577 	/* Given the allocation type and the arguments to the constructor, see if we can synthesize a generic static factory
578 	   method that would, given the argument types and the invocation site, manufacture a parameterized object of type allocationType.
579 	   If we are successful then by design and construction, the parameterization of the return type of the factory method is identical
580 	   to the types elided in the <>.
581 	 */
582 	MethodBinding factory = scope.getStaticFactory(allocationType, enclosingType, argumentTypes, this);
583 	if (factory instanceof ParameterizedGenericMethodBinding && factory.isValidBinding()) {
584 		ParameterizedGenericMethodBinding genericFactory = (ParameterizedGenericMethodBinding) factory;
585 		this.inferredReturnType = genericFactory.inferredReturnType;
586 		// this is our last chance to inspect the result of the inference that is connected to the throw-away factory binding
587 		InferenceContext18 infCtx18 = getInferenceContext(genericFactory);
588 		if (infCtx18 != null && infCtx18.stepCompleted == InferenceContext18.BINDINGS_UPDATED) {
589 			// refresh argumentTypes from updated bindings in arguments:
590 			// (this shouldn't be strictly necessary, as FunctionExpression.isCompatibleWith() should give the same result,
591 			//  but it's probably be a good idea to avoid the necessity to call isCompatibleWith() in the first place).
592 			for (int i = 0; i < argumentTypes.length; i++) {
593 				if (argumentTypes[i] instanceof PolyTypeBinding)
594 					argumentTypes[i] = this.arguments[i].resolvedType;
595 			}
596 		}
597 		return ((ParameterizedTypeBinding)factory.returnType).arguments;
598 	}
599 	return null;
600 }
601 
602 public void checkTypeArgumentRedundancy(ParameterizedTypeBinding allocationType, ReferenceBinding enclosingType, TypeBinding[] argumentTypes, final BlockScope scope) {
603 	if ((scope.problemReporter().computeSeverity(IProblem.RedundantSpecificationOfTypeArguments) == ProblemSeverities.Ignore) || scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_7) return;
604 	if (allocationType.arguments == null) return;  // raw binding
605 	if (this.genericTypeArguments != null) return; // diamond can't occur with explicit type args for constructor
606 	if (this.type == null) return;
607 	if (argumentTypes == Binding.NO_PARAMETERS && this.typeExpected instanceof ParameterizedTypeBinding) {
608 		ParameterizedTypeBinding expected = (ParameterizedTypeBinding) this.typeExpected;
609 		if (expected.arguments != null && allocationType.arguments.length == expected.arguments.length) {
610 			// check the case when no ctor takes no params and inference uses the expected type directly
611 			// eg. X<String> x = new X<String>()
612 			int i;
613 			for (i = 0; i < allocationType.arguments.length; i++) {
614 				if (TypeBinding.notEquals(allocationType.arguments[i], expected.arguments[i]))
615 					break;
616 			}
617 			if (i == allocationType.arguments.length) {
618 				scope.problemReporter().redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
619 				return;
620 			}
621 		}
622 	}
623 	TypeBinding [] inferredTypes;
624 	int previousBits = this.type.bits;
625 	try {
626 		// checking for redundant type parameters must fake a diamond,
627 		// so we infer the same results as we would get with a diamond in source code:
628 		this.type.bits |= IsDiamond;
629 		inferredTypes = inferElidedTypes(allocationType, enclosingType, argumentTypes, scope);
630 	} finally {
631 		// reset effects of inference
632 		this.type.bits = previousBits;
633 	}
634 	if (inferredTypes == null) {
635 		return;
636 	}
637 	for (int i = 0; i < inferredTypes.length; i++) {
638 		if (TypeBinding.notEquals(inferredTypes[i], allocationType.arguments[i]))
639 			return;
640 	}
641 	scope.problemReporter().redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
642 }
643 
644 public void setActualReceiverType(ReferenceBinding receiverType) {
645 	// ignored
646 }
647 
648 public void setDepth(int i) {
649 	// ignored
650 }
651 
652 public void setFieldIndex(int i) {
653 	// ignored
654 }
655 
656 public void traverse(ASTVisitor visitor, BlockScope scope) {
657 	if (visitor.visit(this, scope)) {
658 		if (this.typeArguments != null) {
659 			for (int i = 0, typeArgumentsLength = this.typeArguments.length; i < typeArgumentsLength; i++) {
660 				this.typeArguments[i].traverse(visitor, scope);
661 			}
662 		}
663 		if (this.type != null) { // enum constant scenario
664 			this.type.traverse(visitor, scope);
665 		}
666 		if (this.arguments != null) {
667 			for (int i = 0, argumentsLength = this.arguments.length; i < argumentsLength; i++)
668 				this.arguments[i].traverse(visitor, scope);
669 		}
670 	}
671 	visitor.endVisit(this, scope);
672 }
673 /**
674  * @see org.eclipse.jdt.internal.compiler.ast.Expression#setExpectedType(org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
675  */
676 public void setExpectedType(TypeBinding expectedType) {
677 	this.typeExpected = expectedType;
678 }
679 
680 public void setExpressionContext(ExpressionContext context) {
681 	this.expressionContext = context;
682 }
683 
684 public boolean isPolyExpression() {
685 	return isPolyExpression(this.binding);
686 }
687 public boolean isPolyExpression(MethodBinding method) {
688 	return (this.expressionContext == ASSIGNMENT_CONTEXT || this.expressionContext == INVOCATION_CONTEXT) &&
689 			this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
690 }
691 
692 /**
693  * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#invocationTargetType()
694  */
695 public TypeBinding invocationTargetType() {
696 	return this.typeExpected;
697 }
698 
699 public boolean statementExpression() {
700 	return true;
701 }
702 
703 //-- interface Invocation: --
704 public MethodBinding binding(TypeBinding targetType, boolean reportErrors, Scope scope) {
705 	if (this.suspendedResolutionState != null && targetType != null) {
706 		setExpectedType(targetType);
707 		if (!resolvePart2(this.suspendedResolutionState)) {
708 			if (reportErrors && !this.suspendedResolutionState.hasReportedError) {
709 				if (this.suspendedResolutionState.cannotInferDiamond)
710 					scope.problemReporter().cannotInferElidedTypes(this);
711 				else
712 					scope.problemReporter().genericInferenceError("constructor is unexpectedly unresolved", this); //$NON-NLS-1$
713 				this.suspendedResolutionState.hasReportedError = true;
714 			}
715 			return null;
716 		}
717 	}
718 	if (reportErrors && this.binding != null && !this.binding.isValidBinding()) {
719 		if (this.binding.declaringClass == null)
720 			this.binding.declaringClass = (ReferenceBinding) this.resolvedType;
721 		if (this.suspendedResolutionState != null) {
722 			scope.problemReporter().invalidConstructor(this, this.binding);
723 			this.suspendedResolutionState.hasReportedError = true;
724 		}
725 	}
726 	return this.binding;
727 }
728 public TypeBinding checkAgainstFinalTargetType(TypeBinding targetType, Scope scope) {
729 	this.typeExpected = targetType;
730 	boolean needsUpdate = this.binding == null || 																// not yet resolved
731 			(this.resolvedType != null && targetType != null && !this.resolvedType.isCompatibleWith(targetType));	// previous attempt was wrong
732 	if (needsUpdate && this.suspendedResolutionState != null && !this.suspendedResolutionState.hasReportedError) {
733 		// Attempt to resolve half resolved diamond
734 		resolvePart2(this.suspendedResolutionState);
735 	}
736 	// confer MessageSend.checkAgainstFinalTargetType(,,):
737 	if (this.binding instanceof ParameterizedGenericMethodBinding) {
738 		InferenceContext18 ctx = getInferenceContext((ParameterizedMethodBinding) this.binding);
739 		if (ctx != null && ctx.stepCompleted < InferenceContext18.TYPE_INFERRED) {
740 			this.typeExpected = targetType;
741 			MethodBinding updatedBinding = ctx.inferInvocationType(this, (ParameterizedGenericMethodBinding) this.binding);
742 			if (updateBindings(updatedBinding, targetType)) {
743 				ASTNode.resolvePolyExpressionArguments(this, updatedBinding, scope);
744 			}
745 		}
746 	}
747 	if (this.suspendedResolutionState != null) {
748 		return resolvePart3(this.suspendedResolutionState);
749 	}
750 	return this.resolvedType;
751 }
752 public Expression[] arguments() {
753 	return this.arguments;
754 }
755 
756 public boolean updateBindings(MethodBinding updatedBinding, TypeBinding targetType) {
757 	boolean hasUpdate = this.binding != updatedBinding;
758 	if (this.inferenceContexts != null && this.binding.original() == updatedBinding.original()) {
759 		InferenceContext18 ctx = (InferenceContext18)this.inferenceContexts.get(this.binding);
760 		if (ctx != null && updatedBinding instanceof ParameterizedGenericMethodBinding) {
761 			this.inferenceContexts.put(updatedBinding, ctx);
762 			// solution may have come from an outer inference, mark now that this (inner) is done (but not deep inners):
763 			hasUpdate |= ctx.registerSolution(targetType, updatedBinding);
764 		}
765 	}
766 	this.binding = updatedBinding;
767 	this.resolvedType = updatedBinding.declaringClass;
768 	return hasUpdate;
769 }
770 public void registerInferenceContext(ParameterizedGenericMethodBinding method, InferenceContext18 infCtx18) {
771 	if (this.inferenceContexts == null)
772 		this.inferenceContexts = new SimpleLookupTable();
773 	this.inferenceContexts.put(method, infCtx18);
774 	MethodBinding original = method.original();
775 	if (original instanceof SyntheticFactoryMethodBinding) {
776 		SyntheticFactoryMethodBinding synthOriginal = (SyntheticFactoryMethodBinding)original;
777 		ParameterizedMethodBinding parameterizedCtor = synthOriginal.applyTypeArgumentsOnConstructor(method.typeArguments);
778 		this.inferenceContexts.put(parameterizedCtor, infCtx18);
779 	}
780 }
781 public boolean usesInference() {
782 	return (this.binding instanceof ParameterizedGenericMethodBinding)
783 			&& getInferenceContext((ParameterizedGenericMethodBinding) this.binding) != null;
784 }
785 public InferenceContext18 getInferenceContext(ParameterizedMethodBinding method) {
786 	if (this.inferenceContexts == null)
787 		return null;
788 	return (InferenceContext18) this.inferenceContexts.get(method);
789 }
790 public boolean innersNeedUpdate() {
791 	return this.innerInferenceHelper != null;
792 }
793 public void innerUpdateDone() {
794 	this.innerInferenceHelper = null;
795 }
796 public InnerInferenceHelper innerInferenceHelper() {
797 	return this.innerInferenceHelper;
798 }
799 
800 //-- interface InvocationSite: --
801 public ExpressionContext getExpressionContext() {
802 	return this.expressionContext;
803 }
804 public InferenceContext18 freshInferenceContext(Scope scope) {
805 	return new InferenceContext18(scope, this.arguments, this);
806 }
807 }
808