blob: 4f3b5a2c1ce07cf463c3831920768fca9e14f974 [file] [log] [blame]
Stephan Herrmann7b7062f2010-04-01 19:56:59 +00001/*******************************************************************************
Stephan Herrmann075533e2015-04-28 17:54:14 +02002 * Copyright (c) 2000, 2015 IBM Corporation and others.
Stephan Herrmann7b7062f2010-04-01 19:56:59 +00003 * 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
Stephan Herrmann44109d32011-08-02 14:34:26 +00007 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +00008 * Contributors:
9 * IBM Corporation - initial API and implementation
Stephan Herrmannaa1e2842011-12-10 00:30:58 +010010 * Fraunhofer FIRST - extended API and implementation
11 * Technical University Berlin - extended API and implementation
12 * Stephan Herrmann - Contributions for
Stephan Herrmann66cc2b62010-09-26 15:38:59 +000013 * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
14 * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
Stephan Herrmann6dcbb382011-10-25 16:30:31 +000015 * bug 349326 - [1.7] new warning for missing try-with-resources
Stephan Herrmannaa1e2842011-12-10 00:30:58 +010016 * bug 186342 - [compiler][null] Using annotations for null checking
Stephan Herrmann2c38ab42012-01-28 20:42:28 +010017 * bug 358903 - Filter practically unimportant resource leak warnings
Stephan Herrmann6cecadb2012-02-26 01:08:39 +010018 * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
19 * bug 370639 - [compiler][resource] restore the default for resource leak warnings
Stephan Herrmann1a8ea8f2012-09-18 15:10:52 +020020 * bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
21 * bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
Stephan Herrmannc7600d82013-04-28 22:48:05 +020022 * bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
Stephan Herrmann4388de02013-12-30 10:43:45 +010023 * Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations
Stephan Herrmann5d5b2c32014-01-02 00:10:41 +010024 * 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 +010025 * 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 +010026 * Bug 424727 - [compiler][null] NullPointerException in nullAnnotationUnsupportedLocation(ProblemReporter.java:5708)
Stephan Herrmann78721b12014-02-12 00:01:46 +010027 * Bug 424710 - [1.8][compiler] CCE in SingleNameReference.localVariableBinding
28 * Bug 425152 - [1.8] [compiler] Lambda Expression not resolved but flow analyzed leading to NPE.
29 * Bug 424205 - [1.8] Cannot infer type for diamond type with lambda on method invocation
30 * Bug 424415 - [1.8][compiler] Eventual resolution of ReferenceExpression is not seen to be happening.
31 * Bug 426366 - [1.8][compiler] Type inference doesn't handle multiple candidate target types in outer overload context
32 * Bug 426290 - [1.8][compiler] Inference + overloading => wrong method resolution ?
Stephan Herrmann4d079452014-03-27 18:01:49 +010033 * Bug 426764 - [1.8] Presence of conditional expression as method argument confuses compiler
34 * Bug 424930 - [1.8][compiler] Regression: "Cannot infer type arguments" error from compiler.
35 * Bug 427483 - [Java 8] Variables in lambdas sometimes can't be resolved
36 * 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 +010037 * Bug 426996 - [1.8][inference] try to avoid method Expression.unresolve()?
38 * Bug 428352 - [1.8][compiler] Resolution errors don't always surface
Stephan Herrmann2671e412014-03-29 00:36:47 +010039 * Bug 429203 - [1.8][compiler] NPE in AllocationExpression.binding
Stephan Herrmanne2399432014-03-29 13:02:22 +010040 * 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 +020041 * Bug 434297 - [1.8] NPE in LamdaExpression.analyseCode with lamda expression nested in a conditional expression
Stephan Herrmann32fd38b2014-12-13 15:26:29 +010042 * Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
Stephan Herrmann075533e2015-04-28 17:54:14 +020043 * 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 +020044 * Jesper S Moller <jesper@selskabet.org> - Contributions for
45 * bug 378674 - "The method can be declared as static" is wrong
Stephan Herrmann5d5b2c32014-01-02 00:10:41 +010046 * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
Stephan Herrmann64791942013-12-28 21:28:24 +010047 * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
48 * Bug 409245 - [1.8][compiler] Type annotations dropped when call is routed through a synthetic bridge method
Stephan Herrmann4c6c5002013-09-12 23:09:47 +020049 * Till Brychcy - Contributions for
50 * bug 413460 - NonNullByDefault is not inherited to Constructors when accessed via Class File
Stephan Herrmann210dc3a2015-08-13 22:46:42 +020051 * Lars Vogel <Lars.Vogel@vogella.com> - Contributions for
52 * Bug 473178
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000053 *******************************************************************************/
54package org.eclipse.jdt.internal.compiler.ast;
55
Stephan Herrmann4d079452014-03-27 18:01:49 +010056import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.*;
57
Stephan Herrmanne6a1a642014-11-15 14:33:08 +010058import java.util.HashMap;
59
Stephan Herrmann44109d32011-08-02 14:34:26 +000060import org.eclipse.jdt.core.compiler.IProblem;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000061import org.eclipse.jdt.internal.compiler.ASTVisitor;
62import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
63import org.eclipse.jdt.internal.compiler.codegen.*;
64import org.eclipse.jdt.internal.compiler.flow.*;
Stephan Herrmann4c6c5002013-09-12 23:09:47 +020065import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
Stephan Herrmann794deee2014-04-18 21:18:19 +020066import org.eclipse.jdt.internal.compiler.impl.CompilerOptions.WeavingScheme;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000067import org.eclipse.jdt.internal.compiler.impl.Constant;
68import org.eclipse.jdt.internal.compiler.lookup.*;
Stephan Herrmann44109d32011-08-02 14:34:26 +000069import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
Stephan Herrmanna28db532014-01-05 14:59:05 +010070import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
Stephan Herrmann20fb5ac2014-04-03 23:32:36 +020071import org.eclipse.objectteams.otdt.internal.core.compiler.ast.ConstructorDecapsulationException;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000072import org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies;
73import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
74import org.eclipse.objectteams.otdt.internal.core.compiler.control.StateMemento;
75import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.AnchorMapping;
76import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.DependentTypeBinding;
77import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.ITeamAnchor;
78import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
79import org.eclipse.objectteams.otdt.internal.core.compiler.model.RoleModel;
80import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance.CopyInheritance;
81import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstGenerator;
82import org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator;
83import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer;
84
85/**
86 * OTDT changes:
87 *
88 * What: wrap resolved type if role, may need to instantiate parameters of constructor call.
89 * Why: this expression can be seen as a variant of MessageSend
90 * (invokes the constructor and returns a value).
91 *
92 * What: replace "new Role()" statements with a call to the creation method.
93 * Why: do it during resolve, because only now we will find the role if it is in a role file.
94 *
95 * What: record need to check duplicate roles
96 * if this expression creates a role using the lifting constructor
97 * See: Class comment in MethodBinding
98 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000099 */
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100100public class AllocationExpression extends Expression implements IPolyExpression, Invocation {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000101
102 public TypeReference type;
103 public Expression[] arguments;
104 public MethodBinding binding; // exact binding resulting from lookup
105 MethodBinding syntheticAccessor; // synthetic accessor for inner-emulation
106 public TypeReference[] typeArguments;
107 public TypeBinding[] genericTypeArguments;
108 public FieldDeclaration enumConstant; // for enum constant initializations
Stephan Herrmann44109d32011-08-02 14:34:26 +0000109 protected TypeBinding typeExpected; // for <> inference
110 public boolean inferredReturnType;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000111
Stephan Herrmann2c38ab42012-01-28 20:42:28 +0100112 public FakedTrackingVariable closeTracker; // when allocation a Closeable store a pre-liminary tracking variable here
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100113 public ExpressionContext expressionContext = VANILLA_CONTEXT;
Stephan Herrmanna28db532014-01-05 14:59:05 +0100114
115 // hold on to this context from invocation applicability inference until invocation type inference (per method candidate):
Stephan Herrmann4d079452014-03-27 18:01:49 +0100116 private SimpleLookupTable/*<PMB,IC18>*/ inferenceContexts;
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100117 public HashMap<TypeBinding, MethodBinding> solutionsPerTargetType;
Stephan Herrmann32fd38b2014-12-13 15:26:29 +0100118 private InferenceContext18 outerInferenceContext; // resolving within the context of an outer (lambda) inference?
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100119 public boolean argsContainCast;
Stephan Herrmann4194d172014-11-11 21:35:54 +0100120 public TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100121 public boolean argumentsHaveErrors = false;
122
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000123//{ObjectTeams: alternate AST in case the creation needs to be redirected through a creator call:
124 private MessageSend roleCreatorCall = null;
125 private NameReference valueParam; // if allocation type has value parameter: synthesized argument for ctor call
Stephan Herrmannf3b56c22014-01-03 20:39:26 +0100126 public boolean isGenerated;
127 @Override
128 public boolean isGenerated() {
129 return this.isGenerated;
130 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000131// SH}
132
133public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
134//{ObjectTeams: redirect?
135 if (this.roleCreatorCall != null)
136 return this.roleCreatorCall.analyseCode(currentScope, flowContext, flowInfo);
137// SH}
138 // check captured variables are initialized in current context (26134)
139 checkCapturedLocalInitializationIfNecessary((ReferenceBinding)this.binding.declaringClass.erasure(), currentScope, flowInfo);
140
141 // process arguments
142 if (this.arguments != null) {
Stephan Herrmann6cecadb2012-02-26 01:08:39 +0100143 boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
144 boolean hasResourceWrapperType = analyseResources
145 && this.resolvedType instanceof ReferenceBinding
Stephan Herrmann2c38ab42012-01-28 20:42:28 +0100146 && ((ReferenceBinding)this.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000147 for (int i = 0, count = this.arguments.length; i < count; i++) {
148 flowInfo =
149 this.arguments[i]
150 .analyseCode(currentScope, flowContext, flowInfo)
151 .unconditionalInits();
Stephan Herrmann2c38ab42012-01-28 20:42:28 +0100152 // 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 +0100153 if (analyseResources && !hasResourceWrapperType) { // allocation of wrapped closeables is analyzed specially
Stephan Herrmann1a8ea8f2012-09-18 15:10:52 +0200154 flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, flowContext, false);
Stephan Herrmann2c38ab42012-01-28 20:42:28 +0100155 }
Stephan Herrmannc7600d82013-04-28 22:48:05 +0200156 this.arguments[i].checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
Stephan Herrmann4194d172014-11-11 21:35:54 +0100157 }
Stephan Herrmannaa1e2842011-12-10 00:30:58 +0100158 analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000159 }
Stephan Herrmann2c38ab42012-01-28 20:42:28 +0100160
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000161 // record some dependency information for exception types
162 ReferenceBinding[] thrownExceptions;
163 if (((thrownExceptions = this.binding.thrownExceptions).length) != 0) {
164 if ((this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null) {
165 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
166 thrownExceptions = currentScope.environment().convertToRawTypes(this.binding.thrownExceptions, true, true);
167 }
168 // check exception handling
169 flowContext.checkExceptionHandlers(
170 thrownExceptions,
171 this,
172 flowInfo.unconditionalCopy(),
173 currentScope);
174 }
Stephan Herrmann6cecadb2012-02-26 01:08:39 +0100175
176 // after having analysed exceptions above start tracking newly allocated resource:
Stephan Herrmann942dbe92012-04-12 20:50:07 +0200177 if (currentScope.compilerOptions().analyseResourceLeaks && FakedTrackingVariable.isAnyCloseable(this.resolvedType))
Stephan Herrmann6cecadb2012-02-26 01:08:39 +0100178 FakedTrackingVariable.analyseCloseableAllocation(currentScope, flowInfo, this);
179
Stephan Herrmanna1bf6562011-03-01 21:59:07 +0000180 if (this.binding.declaringClass.isMemberType() && !this.binding.declaringClass.isStatic()) {
181 // allocating a non-static member type without an enclosing instance of parent type
182 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=335845
Stephan Herrmann529142e2013-09-06 01:04:51 +0200183 currentScope.tagAsAccessingEnclosingInstanceStateOf(this.binding.declaringClass.enclosingType(), false /* type variable access */);
Stephan Herrmannc7600d82013-04-28 22:48:05 +0200184 // Reviewed for https://bugs.eclipse.org/bugs/show_bug.cgi?id=378674 :
185 // The corresponding problem (when called from static) is not produced until during code generation
Stephan Herrmanna1bf6562011-03-01 21:59:07 +0000186 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000187 manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
188 manageSyntheticAccessIfNecessary(currentScope, flowInfo);
189
Stephan Herrmann1a8ea8f2012-09-18 15:10:52 +0200190 // account for possible exceptions thrown by the constructor
191 flowContext.recordAbruptExit(); // TODO whitelist of ctors that cannot throw any exc.??
192
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000193 return flowInfo;
194}
195
196public void checkCapturedLocalInitializationIfNecessary(ReferenceBinding checkedType, BlockScope currentScope, FlowInfo flowInfo) {
197 if (((checkedType.tagBits & ( TagBits.AnonymousTypeMask|TagBits.LocalTypeMask)) == TagBits.LocalTypeMask)
198 && !currentScope.isDefinedInType(checkedType)) { // only check external allocations
199 NestedTypeBinding nestedType = (NestedTypeBinding) checkedType;
200 SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables();
201 if (syntheticArguments != null)
202 for (int i = 0, count = syntheticArguments.length; i < count; i++){
203 SyntheticArgumentBinding syntheticArgument = syntheticArguments[i];
204 LocalVariableBinding targetLocal;
205 if ((targetLocal = syntheticArgument.actualOuterLocalVariable) == null) continue;
206 if (targetLocal.declaration != null && !flowInfo.isDefinitelyAssigned(targetLocal)){
207 currentScope.problemReporter().uninitializedLocalVariable(targetLocal, this);
208 }
209 }
210 }
211}
212
213public Expression enclosingInstance() {
214 return null;
215}
216
217public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
Stephan Herrmannd1a89d72015-12-08 19:38:48 +0100218 cleanUpInferenceContexts();
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000219 if (!valueRequired)
220 currentScope.problemReporter().unusedObjectAllocation(this);
Stephan Herrmannd1a89d72015-12-08 19:38:48 +0100221
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000222//{ObjectTeams: redirect?
223 if (this.roleCreatorCall != null) {
224 this.roleCreatorCall.generateCode(currentScope, codeStream, valueRequired);
225 return;
226 }
227// SH}
228 int pc = codeStream.position;
229 MethodBinding codegenBinding = this.binding.original();
230 ReferenceBinding allocatedType = codegenBinding.declaringClass;
231
Stephan Herrmannbd1255d2013-09-05 23:25:05 +0200232 codeStream.new_(this.type, allocatedType);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000233 boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
234 if (valueRequired || isUnboxing) {
235 codeStream.dup();
236 }
237 // better highlight for allocation: display the type individually
238 if (this.type != null) { // null for enum constant body
239 codeStream.recordPositionsFrom(pc, this.type.sourceStart);
240 } else {
241 // push enum constant name and ordinal
242 codeStream.ldc(String.valueOf(this.enumConstant.name));
243 codeStream.generateInlinedValue(this.enumConstant.binding.id);
244 }
245
246 // handling innerclass instance allocation - enclosing instance arguments
247 if (allocatedType.isNestedType()) {
248 codeStream.generateSyntheticEnclosingInstanceValues(
249 currentScope,
250 allocatedType,
251 enclosingInstance(),
252 this);
253 }
254//{ObjectTeams: pass value parameter:
255 if (this.valueParam != null)
256 this.valueParam.generateCode(currentScope, codeStream, true);
257// SH}
258 // generate the arguments for constructor
259 generateArguments(this.binding, this.arguments, currentScope, codeStream);
260 // handling innerclass instance allocation - outer local arguments
261 if (allocatedType.isNestedType()) {
262 codeStream.generateSyntheticOuterArgumentValues(
263 currentScope,
264 allocatedType,
265 this);
266 }
267 // invoke constructor
268 if (this.syntheticAccessor == null) {
Stephan Herrmannbd1255d2013-09-05 23:25:05 +0200269 codeStream.invoke(Opcodes.OPC_invokespecial, codegenBinding, null /* default declaringClass */, this.typeArguments);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000270 } else {
271 // synthetic accessor got some extra arguments appended to its signature, which need values
272 for (int i = 0,
273 max = this.syntheticAccessor.parameters.length - codegenBinding.parameters.length;
274 i < max;
275 i++) {
276 codeStream.aconst_null();
277 }
Stephan Herrmann64791942013-12-28 21:28:24 +0100278 codeStream.invoke(Opcodes.OPC_invokespecial, this.syntheticAccessor, null /* default declaringClass */, this.typeArguments);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000279 }
280 if (valueRequired) {
281 codeStream.generateImplicitConversion(this.implicitConversion);
282 } else if (isUnboxing) {
283 // conversion only generated if unboxing
284 codeStream.generateImplicitConversion(this.implicitConversion);
285 switch (postConversionType(currentScope).id) {
286 case T_long :
287 case T_double :
288 codeStream.pop2();
289 break;
290 default :
291 codeStream.pop();
292 }
293 }
294 codeStream.recordPositionsFrom(pc, this.sourceStart);
295}
296
297/**
298 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
299 */
300public TypeBinding[] genericTypeArguments() {
301 return this.genericTypeArguments;
302}
303
304public boolean isSuperAccess() {
305//{ObjectTeams: within a creation method fake visibility:
306 if (isGenerated())
307 return true;
308// SH}
309 return false;
310}
311
312public boolean isTypeAccess() {
313 return true;
314}
315
316/* Inner emulation consists in either recording a dependency
317 * link only, or performing one level of propagation.
318 *
319 * Dependency mechanism is used whenever dealing with source target
320 * types, since by the time we reach them, we might not yet know their
321 * exact need.
322 */
323public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
Stephan Herrmann0e64ff62011-03-10 18:42:36 +0000324 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000325 ReferenceBinding allocatedTypeErasure = (ReferenceBinding) this.binding.declaringClass.erasure();
326
327 // perform some emulation work in case there is some and we are inside a local type only
328 if (allocatedTypeErasure.isNestedType()
Stephan Herrmann14d6b962015-06-09 14:32:46 +0200329 && (currentScope.enclosingSourceType().isLocalType() || currentScope.isLambdaSubscope())) {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000330
331 if (allocatedTypeErasure.isLocalType()) {
332 ((LocalTypeBinding) allocatedTypeErasure).addInnerEmulationDependent(currentScope, false);
333 // request cascade of accesses
334 } else {
335 // locally propagate, since we already now the desired shape for sure
336 currentScope.propagateInnerEmulation(allocatedTypeErasure, false);
337 // request cascade of accesses
338 }
339 }
340}
341
342public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
Stephan Herrmann0e64ff62011-03-10 18:42:36 +0000343 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000344 // if constructor from parameterized type got found, use the original constructor at codegen time
345 MethodBinding codegenBinding = this.binding.original();
346//{ObjectTeams: baseclass decapsulation:
347 if ( codegenBinding.isPrivate()
348 && this.type != null
349 && this.type.getBaseclassDecapsulation().isAllowed())
350 {
351 return; // avoid tweaking below, which might result in CCE if declaringClass is binary.
352 }
353// SH}
354
355 ReferenceBinding declaringClass;
Stephan Herrmann1bb10072014-01-03 14:36:07 +0100356 if (codegenBinding.isPrivate() && TypeBinding.notEquals(currentScope.enclosingSourceType(), (declaringClass = codegenBinding.declaringClass))) {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000357
358 // from 1.4 on, local type constructor can lose their private flag to ease emulation
359 if ((declaringClass.tagBits & TagBits.IsLocalType) != 0 && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
360 // constructor will not be dumped as private, no emulation required thus
361 codegenBinding.tagBits |= TagBits.ClearPrivateModifier;
362 } else {
363 this.syntheticAccessor = ((SourceTypeBinding) declaringClass).addSyntheticMethod(codegenBinding, isSuperAccess());
364 currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
365 }
366 }
367}
368
369public StringBuffer printExpression(int indent, StringBuffer output) {
370 if (this.type != null) { // type null for enum constant initializations
371 output.append("new "); //$NON-NLS-1$
372 }
373 if (this.typeArguments != null) {
374 output.append('<');
375 int max = this.typeArguments.length - 1;
376 for (int j = 0; j < max; j++) {
377 this.typeArguments[j].print(0, output);
378 output.append(", ");//$NON-NLS-1$
379 }
380 this.typeArguments[max].print(0, output);
381 output.append('>');
382 }
383 if (this.type != null) { // type null for enum constant initializations
384 this.type.printExpression(0, output);
385 }
386 output.append('(');
387 if (this.arguments != null) {
388 for (int i = 0; i < this.arguments.length; i++) {
389 if (i > 0) output.append(", "); //$NON-NLS-1$
390 this.arguments[i].printExpression(0, output);
391 }
392 }
393 return output.append(')');
394}
395
396public TypeBinding resolveType(BlockScope scope) {
397 // Propagate the type checking to the arguments, and check if the constructor is defined.
Stephan Herrmannf087af32014-01-04 01:36:05 +0100398 final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
399 final CompilerOptions compilerOptions = scope.compilerOptions();
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100400 long sourceLevel = compilerOptions.sourceLevel;
Stephan Herrmannf087af32014-01-04 01:36:05 +0100401 if (this.constant != Constant.NotAConstant) {
402 this.constant = Constant.NotAConstant;
403 if (this.type == null) {
404 // initialization of an enum constant
405 this.resolvedType = scope.enclosingReceiverType();
406 } else {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000407//{ObjectTeams: support detection of new path.R():
Stephan Herrmannf087af32014-01-04 01:36:05 +0100408 this.type.bits |= IsAllocationType;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000409// SH}
Stephan Herrmannf087af32014-01-04 01:36:05 +0100410 this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000411 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100412 if (this.type != null) {
413 checkIllegalNullAnnotation(scope, this.resolvedType);
414 checkParameterizedAllocation: {
415 if (this.type instanceof ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
416 ReferenceBinding currentType = (ReferenceBinding)this.resolvedType;
417 if (currentType == null) return currentType;
418 do {
419 // isStatic() is answering true for toplevel types
420 if ((currentType.modifiers & ClassFileConstants.AccStatic) != 0) break checkParameterizedAllocation;
421 if (currentType.isRawType()) break checkParameterizedAllocation;
422 } while ((currentType = currentType.enclosingType())!= null);
423 ParameterizedQualifiedTypeReference qRef = (ParameterizedQualifiedTypeReference) this.type;
424 for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
425 if (qRef.typeArguments[i] != null) {
426 scope.problemReporter().illegalQualifiedParameterizedTypeAllocation(this.type, this.resolvedType);
427 break;
428 }
Stephan Herrmann032b22f2014-01-04 18:29:30 +0100429 }
430 }
431 }
432 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100433 // will check for null after args are resolved
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000434
435//{ObjectTeams: replace role allocations:
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100436 if (!scope.isGeneratedScope()) {
437 // also accept type.resolvedType if a problem was detected during type.resolveType().
438 TypeBinding typeBinding = this.resolvedType;
439 if (typeBinding != null && (typeBinding instanceof ProblemReferenceBinding))
440 typeBinding = ((ProblemReferenceBinding)typeBinding).closestMatch();
441 if ( typeBinding instanceof ReferenceBinding
442 && ((ReferenceBinding)typeBinding).isDirectRole())
443 return resolveAsRoleCreationExpression((ReferenceBinding) typeBinding, scope);
444 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000445// SH}
446
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100447 // resolve type arguments (for generic constructor call)
448 if (this.typeArguments != null) {
449 int length = this.typeArguments.length;
450 this.argumentsHaveErrors = sourceLevel < ClassFileConstants.JDK1_5;
451 this.genericTypeArguments = new TypeBinding[length];
452 for (int i = 0; i < length; i++) {
453 TypeReference typeReference = this.typeArguments[i];
454 if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
455 this.argumentsHaveErrors = true;
456 }
457 if (this.argumentsHaveErrors && typeReference instanceof Wildcard) {
458 scope.problemReporter().illegalUsageOfWildcard(typeReference);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000459 }
460 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100461 if (isDiamond) {
462 scope.problemReporter().diamondNotWithExplicitTypeArguments(this.typeArguments);
463 return null;
464 }
465 if (this.argumentsHaveErrors) {
466 if (this.arguments != null) { // still attempt to resolve arguments
467 for (int i = 0, max = this.arguments.length; i < max; i++) {
468 this.arguments[i].resolveType(scope);
469 }
470 }
471 return null;
472 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000473 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000474
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100475 // buffering the arguments' types
476 if (this.arguments != null) {
477 this.argumentsHaveErrors = false;
478 int length = this.arguments.length;
479 this.argumentTypes = new TypeBinding[length];
480 for (int i = 0; i < length; i++) {
481 Expression argument = this.arguments[i];
482 if (argument instanceof CastExpression) {
483 argument.bits |= DisableUnnecessaryCastCheck; // will check later on
484 this.argsContainCast = true;
485 }
486 argument.setExpressionContext(INVOCATION_CONTEXT);
Stephan Herrmann4fda94b2014-03-29 16:07:55 +0100487//{ObjectTeams: generated arguments can be pre-resolved indeed:
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100488 if (argument.resolvedType != null && argument.isGenerated()) {
489 this.argumentTypes[i] = argument.resolvedType;
490 if (this.argumentTypes[i] == null)
491 this.argumentsHaveErrors = true;
492 } else {
Stephan Herrmann4fda94b2014-03-29 16:07:55 +0100493// orig:
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100494 if (this.arguments[i].resolvedType != null)
495 scope.problemReporter().genericInferenceError("Argument was unexpectedly found resolved", this); //$NON-NLS-1$
496 if ((this.argumentTypes[i] = argument.resolveType(scope)) == null) {
497 this.argumentsHaveErrors = true;
498 }
Stephan Herrmann4fda94b2014-03-29 16:07:55 +0100499// :giro
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100500 }
Stephan Herrmann4fda94b2014-03-29 16:07:55 +0100501// SH}
Stephan Herrmann78721b12014-02-12 00:01:46 +0100502 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100503 if (this.argumentsHaveErrors) {
504 /* 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 +0000505 No meaningful type resolution is possible since inference of the elided types is fully tied to argument types. Do
506 not return the partially resolved type.
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100507 */
508 if (isDiamond) {
509 return null; // not the partially cooked this.resolvedType
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000510 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100511 if (this.resolvedType instanceof ReferenceBinding) {
512 // record a best guess, for clients who need hint about possible constructor match
513 TypeBinding[] pseudoArgs = new TypeBinding[length];
514 for (int i = length; --i >= 0;) {
515 pseudoArgs[i] = this.argumentTypes[i] == null ? TypeBinding.NULL : this.argumentTypes[i]; // replace args with errors with null type
516 }
517 this.binding = scope.findMethod((ReferenceBinding) this.resolvedType, TypeConstants.INIT, pseudoArgs, this, false);
518 if (this.binding != null && !this.binding.isValidBinding()) {
519 MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
520 // record the closest match, for clients who may still need hint about possible method match
521 if (closestMatch != null) {
522 if (closestMatch.original().typeVariables != Binding.NO_TYPE_VARIABLES) { // generic method
523 // shouldn't return generic method outside its context, rather convert it to raw method (175409)
524 closestMatch = scope.environment().createParameterizedGenericMethod(closestMatch.original(), (RawTypeBinding)null);
525 }
526 this.binding = closestMatch;
527 MethodBinding closestMatchOriginal = closestMatch.original();
528 if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
529 // ignore cases where method is used from within inside itself (e.g. direct recursions)
530 closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
531 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000532 }
533 }
534 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100535 return this.resolvedType;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000536 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100537 }
538 if (this.resolvedType == null || !this.resolvedType.isValidBinding()) {
539 return null;
540 }
541
542 // null type denotes fake allocation for enum constant inits
543 if (this.type != null && !this.resolvedType.canBeInstantiated()) {
544 scope.problemReporter().cannotInstantiate(this.type, this.resolvedType);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000545 return this.resolvedType;
546 }
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100547 }
548 if (isDiamond) {
549 this.binding = inferConstructorOfElidedParameterizedType(scope);
550 if (this.binding == null || !this.binding.isValidBinding()) {
551 scope.problemReporter().cannotInferElidedTypes(this);
552 return this.resolvedType = null;
Stephan Herrmann44109d32011-08-02 14:34:26 +0000553 }
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100554 if (this.typeExpected == null && compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8 && this.expressionContext.definesTargetType()) {
555 return new PolyTypeBinding(this);
556 }
557 this.resolvedType = this.type.resolvedType = this.binding.declaringClass;
558 resolvePolyExpressionArguments(this, this.binding, this.argumentTypes, scope);
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100559 } else {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000560//{ObjectTeams: may need to instantiate parameters of constructor
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100561 AnchorMapping anchorMapping = AnchorMapping.setupNewMapping(null, this.arguments, scope);
562 try {
563 // ensure allocation type has methods:
564 Dependencies.ensureBindingState((ReferenceBinding) this.resolvedType, ITranslationStates.STATE_LENV_DONE_FIELDS_AND_METHODS);
565// orig:
566 this.binding = findConstructorBinding(scope, this, (ReferenceBinding) this.resolvedType, this.argumentTypes);
Stephan Herrmann78721b12014-02-12 00:01:46 +0100567//:giro
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100568 } finally {
569 AnchorMapping.removeCurrentMapping(anchorMapping);
570 }
Stephan Herrmann78721b12014-02-12 00:01:46 +0100571// SH}
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100572 }
Stephan Herrmannbd1255d2013-09-05 23:25:05 +0200573 if (!this.binding.isValidBinding()) {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000574//{ObjectTeams: baseclass decapsulation?
575 boolean baseclassDecapsulationAllowed =
576 this.type != null // null happens for enum constants
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100577 && this.type.getBaseclassDecapsulation((ReferenceBinding) this.resolvedType).isAllowed();
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000578 if ( this.binding.problemId() == ProblemReasons.NotVisible
579 && ( baseclassDecapsulationAllowed
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100580 || scope.isGeneratedScope()))
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000581 {
582 this.binding = ((ProblemMethodBinding)this.binding).closestMatch;
583 if (baseclassDecapsulationAllowed) {
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100584 int accessId = scope.enclosingSourceType().roleModel.addInaccessibleBaseMethod(this.binding);
585 scope.problemReporter().decapsulation(this, scope);
586 if (scope.compilerOptions().weavingScheme == WeavingScheme.OTDRE) {
Stephan Herrmann20fb5ac2014-04-03 23:32:36 +0200587 throw new ConstructorDecapsulationException(accessId);
588 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000589 }
590 } else {
591// orig:
592 if (this.binding.declaringClass == null) {
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100593 this.binding.declaringClass = (ReferenceBinding) this.resolvedType;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000594 }
595 if (this.type != null && !this.type.resolvedType.isValidBinding()) {
596 return null;
597 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100598 scope.problemReporter().invalidConstructor(this, this.binding);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000599 return this.resolvedType;
600// :giro
601 }
602// SH}
603 }
604 if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100605 scope.problemReporter().missingTypeInConstructor(this, this.binding);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000606 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100607 if (isMethodUseDeprecated(this.binding, scope, true)) {
608 scope.problemReporter().deprecatedMethod(this.binding, this);
Stephan Herrmann4194d172014-11-11 21:35:54 +0100609 }
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100610 if (checkInvocationArguments(scope, null, this.resolvedType, this.binding, this.arguments, this.argumentTypes, this.argsContainCast, this)) {
Stephan Herrmann78721b12014-02-12 00:01:46 +0100611 this.bits |= ASTNode.Unchecked;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000612 }
613 if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100614 scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000615 }
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100616 if (!isDiamond && this.resolvedType.isParameterizedTypeWithActualArguments()) {
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100617 checkTypeArgumentRedundancy((ParameterizedTypeBinding) this.resolvedType, scope);
Stephan Herrmann44109d32011-08-02 14:34:26 +0000618 }
Stephan Herrmann075533e2015-04-28 17:54:14 +0200619 if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
620 if ((this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
621 new ImplicitNullAnnotationVerifier(scope.environment(), compilerOptions.inheritNullAnnotations)
622 .checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
623 }
624 if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
625 if (this.binding instanceof ParameterizedGenericMethodBinding && this.typeArguments != null) {
626 TypeVariableBinding[] typeVariables = this.binding.original().typeVariables();
627 for (int i = 0; i < this.typeArguments.length; i++)
Stephan Herrmannd1a89d72015-12-08 19:38:48 +0100628 this.typeArguments[i].checkNullConstraints(scope, (ParameterizedGenericMethodBinding) this.binding, typeVariables, i);
Stephan Herrmann075533e2015-04-28 17:54:14 +0200629 }
630 }
Stephan Herrmann4c6c5002013-09-12 23:09:47 +0200631 }
Stephan Herrmann6054d022016-03-19 16:21:11 +0100632 if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8 &&
633 this.binding.getTypeAnnotations() != Binding.NO_ANNOTATIONS) {
634 this.resolvedType = scope.environment().createAnnotatedType(this.resolvedType, this.binding.getTypeAnnotations());
635 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000636//{ObjectTeams: may need to wrap the resolved type
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100637 this.resolvedType = RoleTypeCreator.maybeWrapUnqualifiedRoleType(this.resolvedType, scope, this);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000638 DependentTypeBinding dependentTypeBinding = this.resolvedType.asPlainDependentType();
639 if (dependentTypeBinding != null) {
640 ITeamAnchor[] anchorPath = dependentTypeBinding._teamAnchor.getBestNamePath();
641 int len = anchorPath.length;
642 int prefixLen=0;
643 char[][] tokens;
644 if (anchorPath[0] instanceof FieldBinding && ((FieldBinding)anchorPath[0]).isStatic()) {
645 char[][] qname = TypeAnalyzer.compoundNameOfReferenceType(((FieldBinding)anchorPath[0]).declaringClass, true, false);
646 prefixLen = qname.length;
647 len += prefixLen;
648 tokens = new char[len][];
649 System.arraycopy(qname, 0, tokens, 0, qname.length);
650 } else {
651 tokens = new char[len][];
652 }
653 for (int i=0; i+prefixLen < len; i++)
654 tokens[i+prefixLen] = anchorPath[i].internalName();
655 AstGenerator gen = new AstGenerator(this);
656 if (len > 1)
657 this.valueParam = gen.qualifiedNameReference(tokens);
658 else
659 this.valueParam = gen.singleNameReference(tokens[0]);
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100660 this.valueParam.resolve(scope);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000661 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000662// SH}
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100663 return this.resolvedType;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000664}
665
Stephan Herrmann4388de02013-12-30 10:43:45 +0100666/**
667 * Check if 'allocationType' illegally has a top-level null annotation.
Stephan Herrmann4388de02013-12-30 10:43:45 +0100668 */
Stephan Herrmann5d5b2c32014-01-02 00:10:41 +0100669void checkIllegalNullAnnotation(BlockScope scope, TypeBinding allocationType) {
Stephan Herrmann4388de02013-12-30 10:43:45 +0100670 if (allocationType != null) {
671 // only check top-level null annotation (annots on details are OK):
672 long nullTagBits = allocationType.tagBits & TagBits.AnnotationNullMASK;
673 if (nullTagBits != 0) {
674 Annotation annotation = this.type.findAnnotation(nullTagBits);
Stephan Herrmannddef2c12014-01-05 18:18:25 +0100675 if (annotation != null)
676 scope.problemReporter().nullAnnotationUnsupportedLocation(annotation);
Stephan Herrmann4388de02013-12-30 10:43:45 +0100677 }
678 }
Stephan Herrmann4388de02013-12-30 10:43:45 +0100679}
680
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100681// For allocation expressions, boxing compatibility is same as vanilla compatibility, since java.lang's wrapper types are not generic.
682public boolean isBoxingCompatibleWith(TypeBinding targetType, Scope scope) {
683 return isPolyExpression() ? false : isCompatibleWith(scope.boxing(targetType), scope);
684}
685
686public boolean isCompatibleWith(TypeBinding targetType, final Scope scope) {
687 if (this.argumentsHaveErrors || this.binding == null || !this.binding.isValidBinding() || targetType == null || scope == null)
688 return false;
689 TypeBinding allocationType = this.resolvedType;
690 if (isPolyExpression()) {
691 TypeBinding originalExpectedType = this.typeExpected;
692 try {
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100693 MethodBinding method = this.solutionsPerTargetType != null ? this.solutionsPerTargetType.get(targetType) : null;
694 if (method == null) {
695 this.typeExpected = targetType;
696 method = inferConstructorOfElidedParameterizedType(scope); // caches result already.
697 if (method == null || !method.isValidBinding())
698 return false;
699 }
700 allocationType = method.declaringClass;
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100701 } finally {
702 this.typeExpected = originalExpectedType;
703 }
704 }
705 return allocationType != null && allocationType.isCompatibleWith(targetType, scope);
706}
707
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100708public MethodBinding inferConstructorOfElidedParameterizedType(final Scope scope) {
709 if (this.typeExpected != null && this.binding != null) {
710 MethodBinding cached = this.solutionsPerTargetType != null ? this.solutionsPerTargetType.get(this.typeExpected) : null;
711 if (cached != null)
712 return cached;
713 }
714 ReferenceBinding genericType = ((ParameterizedTypeBinding) this.resolvedType).genericType();
715 ReferenceBinding enclosingType = this.resolvedType.enclosingType();
716 ParameterizedTypeBinding allocationType = scope.environment().createParameterizedType(genericType, genericType.typeVariables(), enclosingType);
717
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100718 // Given the allocation type and the arguments to the constructor, see if we can infer the constructor of the elided parameterized type.
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100719 MethodBinding factory = scope.getStaticFactory(allocationType, enclosingType, this.argumentTypes, this);
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100720 if (factory instanceof ParameterizedGenericMethodBinding && factory.isValidBinding()) {
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100721 ParameterizedGenericMethodBinding genericFactory = (ParameterizedGenericMethodBinding) factory;
722 this.inferredReturnType = genericFactory.inferredReturnType;
Stephan Herrmanne2459222014-11-13 16:43:22 +0100723 SyntheticFactoryMethodBinding sfmb = (SyntheticFactoryMethodBinding) factory.original();
724 TypeVariableBinding[] constructorTypeVariables = sfmb.getConstructor().typeVariables();
725 TypeBinding [] constructorTypeArguments = constructorTypeVariables != null ? new TypeBinding[constructorTypeVariables.length] : Binding.NO_TYPES;
726 if (constructorTypeArguments.length > 0)
727 System.arraycopy(((ParameterizedGenericMethodBinding)factory).typeArguments, sfmb.typeVariables().length - constructorTypeArguments.length ,
728 constructorTypeArguments, 0, constructorTypeArguments.length);
729 MethodBinding constructor = sfmb.applyTypeArgumentsOnConstructor(((ParameterizedTypeBinding)factory.returnType).arguments, constructorTypeArguments);
730 if (constructor instanceof ParameterizedGenericMethodBinding && scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8) {
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100731 // 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.
732 if (this.expressionContext == INVOCATION_CONTEXT && this.typeExpected == null)
733 constructor = ParameterizedGenericMethodBinding.computeCompatibleMethod18(constructor.shallowOriginal(), this.argumentTypes, scope, this);
Stephan Herrmanne2459222014-11-13 16:43:22 +0100734 }
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100735 if (this.typeExpected != null)
736 registerResult(this.typeExpected, constructor);
Stephan Herrmanne2459222014-11-13 16:43:22 +0100737 return constructor;
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100738 }
739 return null;
740}
741
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100742public TypeBinding[] inferElidedTypes(final Scope scope) {
743
744 ReferenceBinding genericType = ((ParameterizedTypeBinding) this.resolvedType).genericType();
745 ReferenceBinding enclosingType = this.resolvedType.enclosingType();
746 ParameterizedTypeBinding allocationType = scope.environment().createParameterizedType(genericType, genericType.typeVariables(), enclosingType);
747
Stephan Herrmann44109d32011-08-02 14:34:26 +0000748 /* Given the allocation type and the arguments to the constructor, see if we can synthesize a generic static factory
749 method that would, given the argument types and the invocation site, manufacture a parameterized object of type allocationType.
750 If we are successful then by design and construction, the parameterization of the return type of the factory method is identical
751 to the types elided in the <>.
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100752 */
753 MethodBinding factory = scope.getStaticFactory(allocationType, enclosingType, this.argumentTypes, this);
Stephan Herrmann44109d32011-08-02 14:34:26 +0000754 if (factory instanceof ParameterizedGenericMethodBinding && factory.isValidBinding()) {
755 ParameterizedGenericMethodBinding genericFactory = (ParameterizedGenericMethodBinding) factory;
756 this.inferredReturnType = genericFactory.inferredReturnType;
757 return ((ParameterizedTypeBinding)factory.returnType).arguments;
758 }
759 return null;
760}
761
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100762public void checkTypeArgumentRedundancy(ParameterizedTypeBinding allocationType, final BlockScope scope) {
Stephan Herrmann14e866b2014-03-28 20:26:29 +0100763 if ((scope.problemReporter().computeSeverity(IProblem.RedundantSpecificationOfTypeArguments) == ProblemSeverities.Ignore) || scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_7) return;
Stephan Herrmann44109d32011-08-02 14:34:26 +0000764 if (allocationType.arguments == null) return; // raw binding
765 if (this.genericTypeArguments != null) return; // diamond can't occur with explicit type args for constructor
Stephan Herrmannac2aba32014-05-01 14:58:19 +0200766 if (this.type == null) return;
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100767 if (this.argumentTypes == Binding.NO_PARAMETERS && this.typeExpected instanceof ParameterizedTypeBinding) {
Stephan Herrmann44109d32011-08-02 14:34:26 +0000768 ParameterizedTypeBinding expected = (ParameterizedTypeBinding) this.typeExpected;
769 if (expected.arguments != null && allocationType.arguments.length == expected.arguments.length) {
770 // check the case when no ctor takes no params and inference uses the expected type directly
771 // eg. X<String> x = new X<String>()
772 int i;
773 for (i = 0; i < allocationType.arguments.length; i++) {
Stephan Herrmann1bb10072014-01-03 14:36:07 +0100774 if (TypeBinding.notEquals(allocationType.arguments[i], expected.arguments[i]))
Stephan Herrmann44109d32011-08-02 14:34:26 +0000775 break;
776 }
777 if (i == allocationType.arguments.length) {
Stephan Herrmann14e866b2014-03-28 20:26:29 +0100778 scope.problemReporter().redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
Stephan Herrmann44109d32011-08-02 14:34:26 +0000779 return;
780 }
781 }
782 }
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100783 TypeBinding [] inferredTypes;
784 int previousBits = this.type.bits;
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100785 try {
786 // checking for redundant type parameters must fake a diamond,
787 // so we infer the same results as we would get with a diamond in source code:
788 this.type.bits |= IsDiamond;
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100789 inferredTypes = inferElidedTypes(scope);
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100790 } finally {
791 // reset effects of inference
792 this.type.bits = previousBits;
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100793 }
Stephan Herrmann44109d32011-08-02 14:34:26 +0000794 if (inferredTypes == null) {
795 return;
796 }
797 for (int i = 0; i < inferredTypes.length; i++) {
Stephan Herrmann1bb10072014-01-03 14:36:07 +0100798 if (TypeBinding.notEquals(inferredTypes[i], allocationType.arguments[i]))
Stephan Herrmann44109d32011-08-02 14:34:26 +0000799 return;
800 }
Stephan Herrmann14e866b2014-03-28 20:26:29 +0100801 scope.problemReporter().redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
Stephan Herrmann44109d32011-08-02 14:34:26 +0000802}
803
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000804//{ObjectTeams: replace with and resolved role creation expression:
805private TypeBinding resolveAsRoleCreationExpression(ReferenceBinding typeBinding, BlockScope scope) {
806 RoleModel roleModel = typeBinding.roleModel;
807 ReferenceBinding roleClass = roleModel.getClassPartBinding();
808 // creating a role that should not be instantiated (OTJLD 2.4.3)?
809 if (typeBinding.isRole()) {
810 ReferenceBinding subRole = roleClass.roleModel._supercededBy;
811 if (subRole != null)
812 scope.problemReporter().instantiatingSupercededRole(this, subRole);
813 }
814
815 if ( !StateMemento.hasMethodResolveStarted(typeBinding)
816 && roleClass != null)
817 {
818 Dependencies.ensureRoleState(
819 roleClass.roleModel,
820 ITranslationStates.STATE_METHODS_CREATED); // forces creation method to be created
821 }
822
823 if (!RoleTypeBinding.isRoleWithExplicitAnchor(typeBinding)) {
824 ReferenceBinding enclosingType = scope.enclosingReceiverType();
825 if (scope.methodScope().isStatic)
826 enclosingType = enclosingType.enclosingType();
827 ReferenceBinding targetEnclosing = roleClass != null
828 ? roleClass.enclosingType()
829 : roleModel.getTeamModel().getBinding();
Stephan Herrmannb8575932014-01-03 22:34:59 +0100830 while (enclosingType != null && TypeBinding.notEquals(enclosingType.original(), targetEnclosing)) {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000831 enclosingType = enclosingType.enclosingType();
832 }
833 if (enclosingType == null) {
834 // create a dummy binding for error reporting (just need declaringClass):
835 this.binding = new MethodBinding(0, Binding.NO_PARAMETERS, Binding.NO_EXCEPTIONS, typeBinding);
836 scope.problemReporter().noSuchEnclosingInstance(
837 typeBinding.enclosingType(), this, false);
838 return null;
839 }
840 }
841
842 if (roleModel.hasBaseclassProblem()) {
843 scope.methodScope().referenceContext.tagAsHavingErrors();
844 return null; // creator is not generated.
845 }
846
847 this.roleCreatorCall = CopyInheritance.createConstructorMethodInvocationExpression(scope, this);
848 if (this.roleCreatorCall == null)
849 return null;
850
851 this.resolvedType = this.roleCreatorCall.resolveType(scope);
Stephan Herrmann85a866e2011-01-27 00:55:45 +0000852 if (typeBinding.isParameterizedType()) {
853 this.resolvedType = scope.environment().createParameterizedType(
854 (ReferenceBinding)this.resolvedType,
855 ((ParameterizedTypeBinding)typeBinding).arguments,
856 this.resolvedType.enclosingType());
857 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000858
859 // UI needs to find the method in this.binding:
860 MethodBinding origBinding = this.roleCreatorCall.binding;
861 if (origBinding != null && origBinding.model != null && origBinding.model._srcCtor != null)
862 this.binding = origBinding.model._srcCtor;
863 else
864 this.binding = origBinding;
865
866 return this.resolvedType;
867}
868// SH}
869
870public void setActualReceiverType(ReferenceBinding receiverType) {
871 // ignored
872}
873
874public void setDepth(int i) {
875 // ignored
876}
877
878public void setFieldIndex(int i) {
879 // ignored
880}
881
882public void traverse(ASTVisitor visitor, BlockScope scope) {
883//{ObjectTeams: alternate ast
884 if (this.roleCreatorCall != null) {
885 this.roleCreatorCall.traverse(visitor, scope);
886 return;
887 }
888// SH}
889
890 if (visitor.visit(this, scope)) {
891 if (this.typeArguments != null) {
892 for (int i = 0, typeArgumentsLength = this.typeArguments.length; i < typeArgumentsLength; i++) {
893 this.typeArguments[i].traverse(visitor, scope);
894 }
895 }
896 if (this.type != null) { // enum constant scenario
897 this.type.traverse(visitor, scope);
898 }
899 if (this.arguments != null) {
900 for (int i = 0, argumentsLength = this.arguments.length; i < argumentsLength; i++)
901 this.arguments[i].traverse(visitor, scope);
902 }
903 }
904 visitor.endVisit(this, scope);
905}
Stephan Herrmann44109d32011-08-02 14:34:26 +0000906/**
907 * @see org.eclipse.jdt.internal.compiler.ast.Expression#setExpectedType(org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
908 */
909public void setExpectedType(TypeBinding expectedType) {
910 this.typeExpected = expectedType;
911}
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200912
913public void setExpressionContext(ExpressionContext context) {
914 this.expressionContext = context;
915}
916
917public boolean isPolyExpression() {
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100918 return isPolyExpression(this.binding);
919}
920public boolean isPolyExpression(MethodBinding method) {
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200921 return (this.expressionContext == ASSIGNMENT_CONTEXT || this.expressionContext == INVOCATION_CONTEXT) &&
922 this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
923}
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100924
Stephan Herrmann44109d32011-08-02 14:34:26 +0000925/**
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100926 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#invocationTargetType()
Stephan Herrmann44109d32011-08-02 14:34:26 +0000927 */
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100928public TypeBinding invocationTargetType() {
Stephan Herrmann44109d32011-08-02 14:34:26 +0000929 return this.typeExpected;
930}
931
Stephan Herrmann59cd3cc2013-05-01 23:38:47 +0200932public boolean statementExpression() {
Stephan Herrmann075533e2015-04-28 17:54:14 +0200933 return ((this.bits & ASTNode.ParenthesizedMASK) == 0);
Stephan Herrmann59cd3cc2013-05-01 23:38:47 +0200934}
935
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100936//-- interface Invocation: --
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100937public MethodBinding binding() {
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100938 return this.binding;
939}
940public Expression[] arguments() {
941 return this.arguments;
942}
Stephan Herrmanna28db532014-01-05 14:59:05 +0100943
Stephan Herrmanna28db532014-01-05 14:59:05 +0100944public void registerInferenceContext(ParameterizedGenericMethodBinding method, InferenceContext18 infCtx18) {
945 if (this.inferenceContexts == null)
946 this.inferenceContexts = new SimpleLookupTable();
947 this.inferenceContexts.put(method, infCtx18);
Stephan Herrmann78721b12014-02-12 00:01:46 +0100948}
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100949
950@Override
951public void registerResult(TypeBinding targetType, MethodBinding method) {
952 if (method != null && method.isConstructor()) { // ignore the factory.
953 if (this.solutionsPerTargetType == null)
Stephan Herrmann210dc3a2015-08-13 22:46:42 +0200954 this.solutionsPerTargetType = new HashMap<>();
Stephan Herrmanne6a1a642014-11-15 14:33:08 +0100955 this.solutionsPerTargetType.put(targetType, method);
956 }
957}
958
Stephan Herrmann4d079452014-03-27 18:01:49 +0100959public InferenceContext18 getInferenceContext(ParameterizedMethodBinding method) {
Stephan Herrmanna28db532014-01-05 14:59:05 +0100960 if (this.inferenceContexts == null)
961 return null;
962 return (InferenceContext18) this.inferenceContexts.get(method);
963}
Stephan Herrmannd1a89d72015-12-08 19:38:48 +0100964
965@Override
966public void cleanUpInferenceContexts() {
967 if (this.inferenceContexts == null)
968 return;
969 for (Object value : this.inferenceContexts.valueTable)
970 if (value != null)
971 ((InferenceContext18) value).cleanUp();
972 this.inferenceContexts = null;
Stephan Herrmann6054d022016-03-19 16:21:11 +0100973 this.outerInferenceContext = null;
974 this.solutionsPerTargetType = null;
Stephan Herrmannd1a89d72015-12-08 19:38:48 +0100975}
976
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100977//-- interface InvocationSite: --
978public ExpressionContext getExpressionContext() {
979 return this.expressionContext;
980}
981public InferenceContext18 freshInferenceContext(Scope scope) {
Stephan Herrmann32fd38b2014-12-13 15:26:29 +0100982 return new InferenceContext18(scope, this.arguments, this, this.outerInferenceContext);
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100983}
Stephan Herrmann6ffc1f32014-11-13 12:53:41 +0100984}