Skip to content

Commit

Permalink
[24] don't request access to enclosing class if it's never used (#3390)
Browse files Browse the repository at this point in the history
* [24] don't request access to enclosing class if it's never used

Fixes after re-opening:
+ essentially revert previous change
+ replace with specific detection wrt local type alloc in static context

Fixes #3194

* [24] don't request access to enclosing class if it's never used

+ additional test

Fixes #3194
  • Loading branch information
stephan-herrmann authored Dec 17, 2024
1 parent 5018236 commit da91237
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
* This is an implementation of an early-draft specification developed under the Java
* Community Process (JCP) and is made available for testing and evaluation purposes
* only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
* IBM Corporation - added the following constants
Expand Down Expand Up @@ -2759,6 +2763,11 @@ public interface IProblem {
*/
int ConstructorCallNotAllowedHere = PreviewRelated + 2031;

/**
* @since 3.40
*/
int AllocatingLocalInStaticContext = TypeRelated + 2032;

/**
* @since 3.40
* @noreference preview feature
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
* This is an implementation of an early-draft specification developed under the Java
* Community Process (JCP) and is made available for testing and evaluation purposes
* only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
* Stephan Herrmann - Contributions for
Expand Down Expand Up @@ -363,6 +367,11 @@ public TypeBinding resolveType(BlockScope scope) {
} else {
this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
}
if (this.resolvedType instanceof LocalTypeBinding local && this.enumConstant == null) {
MethodScope enclosingMethodScope = local.scope.enclosingMethodScope();
if (enclosingMethodScope != null && !enclosingMethodScope.isStatic && scope.isInStaticContext())
scope.problemReporter().allocationInStaticContext(this, local);
}
if (this.type != null) {
checkIllegalNullAnnotation(scope, this.resolvedType);
checkParameterizedAllocation: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
* This is an implementation of an early-draft specification developed under the Java
* Community Process (JCP) and is made available for testing and evaluation purposes
* only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
* Jesper S Moller - Contributions for
Expand Down Expand Up @@ -718,6 +722,12 @@ enclosing instance of this (8.1.3)", we will actually implement this check in co
if (isMethodReference) {
someMethod = scope.getMethod(this.receiverType, this.selector, descriptorParameters, this);
} else {
if (this.receiverType instanceof LocalTypeBinding local) {
MethodScope enclosingMethodScope = local.scope.enclosingMethodScope();
if (enclosingMethodScope != null && !enclosingMethodScope.isStatic && scope.isInStaticContext()) {
scope.problemReporter().allocationInStaticContext(this, local);
}
}
if (argumentsTypeElided() && this.receiverType.isRawType()) {
boolean[] inferredReturnType = new boolean[1];
someMethod = AllocationExpression.inferDiamondConstructor(scope, this, this.receiverType, this.descriptor.parameters, inferredReturnType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
* This is an implementation of an early-draft specification developed under the Java
* Community Process (JCP) and is made available for testing and evaluation purposes
* only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
* Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
Expand Down Expand Up @@ -921,22 +925,18 @@ public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo f
if ((this.bits & Binding.FIELD) != 0) {
FieldBinding fieldBinding = (FieldBinding) this.binding;
FieldBinding codegenField = fieldBinding.original();
if ((this.bits & ASTNode.DepthMASK) != 0) {
if ((codegenField.isPrivate() // private access
&& !currentScope.enclosingSourceType().isNestmateOf(codegenField.declaringClass))
|| (codegenField.isProtected() // implicit protected access
&& codegenField.declaringClass.getPackage() != currentScope.enclosingSourceType().getPackage())) {
if (this.syntheticAccessors == null)
this.syntheticAccessors = new MethodBinding[2];
this.syntheticAccessors[isReadAccess ? SingleNameReference.READ : SingleNameReference.WRITE] =
((SourceTypeBinding) currentScope.enclosingSourceType().
enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT)).addSyntheticMethod(codegenField, isReadAccess, false /* not super access */);
currentScope.problemReporter().needToEmulateFieldAccess(codegenField, this, isReadAccess);
return;
}
if (!codegenField.isStatic() && currentScope.enclosingSourceType() instanceof NestedTypeBinding nestedType) {
nestedType.requestEnclosingInstancePathTo(codegenField.declaringClass);
}
if (((this.bits & ASTNode.DepthMASK) != 0)
&& ((codegenField.isPrivate() // private access
&& !currentScope.enclosingSourceType().isNestmateOf(codegenField.declaringClass) )
|| (codegenField.isProtected() // implicit protected access
&& codegenField.declaringClass.getPackage() != currentScope.enclosingSourceType().getPackage()))) {
if (this.syntheticAccessors == null)
this.syntheticAccessors = new MethodBinding[2];
this.syntheticAccessors[isReadAccess ? SingleNameReference.READ : SingleNameReference.WRITE] =
((SourceTypeBinding)currentScope.enclosingSourceType().
enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT)).addSyntheticMethod(codegenField, isReadAccess, false /*not super access*/);
currentScope.problemReporter().needToEmulateFieldAccess(codegenField, this, isReadAccess);
return;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
* This is an implementation of an early-draft specification developed under the Java
* Community Process (JCP) and is made available for testing and evaluation purposes
* only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
* Stephan Herrmann - Contributions for
Expand Down Expand Up @@ -1072,14 +1076,9 @@ public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, Fl
outerScope = outerScope.enclosingInstanceScope();
earlySeen = methodScope.isInsideEarlyConstructionContext(nestedType.enclosingType(), false);
}
if (JavaFeature.FLEXIBLE_CONSTRUCTOR_BODIES.isSupported(currentScope.compilerOptions())
&& nestedType.enclosingInstances != null) // only if access to enclosing instance has already been requested
{
if (JavaFeature.FLEXIBLE_CONSTRUCTOR_BODIES.isSupported(currentScope.compilerOptions())) {
// JEP 482: this is the central location for organizing synthetic arguments and fields
// to serve far outer instances even in inner early construction context.
// Only SingleNameReference.manageSyntheticAccessIfNecessary() may add more synth outers later on
// (using NestedTypeBinding.requestEnclosingInstancePathTo()).
//
// Locations MethodBinding.computeSignature() and BlockScope.getEmulationPath() will faithfully
// use the information generated here, to decide about signature and call sequence.
while (outerScope != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,27 +126,14 @@ public SyntheticArgumentBinding addSyntheticArgumentAndField(ReferenceBinding ta
if (!isPrototype()) throw new IllegalStateException();
if (this.scope.isInsideEarlyConstructionContext(targetEnclosingType, false))
return null;
return doAddSyntheticArgumentAndField(targetEnclosingType);
}

private SyntheticArgumentBinding doAddSyntheticArgumentAndField(ReferenceBinding targetEnclosingType) {
SyntheticArgumentBinding synthLocal = addSyntheticArgument(targetEnclosingType);
if (synthLocal == null)
return null;
if (synthLocal == null) return null;

if (synthLocal.matchingField == null)
synthLocal.matchingField = addSyntheticFieldForInnerclass(targetEnclosingType);
return synthLocal;
}

public void requestEnclosingInstancePathTo(ReferenceBinding targetEnclosingClass) {
if (isCompatibleWith(targetEnclosingClass))
return;
if (getSyntheticField(targetEnclosingClass, false) == null)
doAddSyntheticArgumentAndField(targetEnclosingClass);
if (this.enclosingType instanceof NestedTypeBinding nestedType)
nestedType.requestEnclosingInstancePathTo(targetEnclosingClass);
}

/* Answer the receiver's enclosing type... null if the receiver is a top level type.
*/
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
* This is an implementation of an early-draft specification developed under the Java
* Community Process (JCP) and is made available for testing and evaluation purposes
* only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
* Stephan Herrmann - Contributions for
Expand Down Expand Up @@ -5797,6 +5801,11 @@ public List<ClassScope> collectClassesBeingInitialized() {
return list;
}

public boolean isInStaticContext() {
MethodScope methodScope = methodScope();
return methodScope != null && methodScope.isStatic;
}

public void include(LocalVariableBinding[] bindings) {
// `this` is assumed to be populated with bindings.
if (bindings != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
* This is an implementation of an early-draft specification developed under the Java
* Community Process (JCP) and is made available for testing and evaluation purposes
* only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
* Benjamin Muskalla - Contribution for bug 239066
Expand Down Expand Up @@ -12425,6 +12429,15 @@ public void allocationInEarlyConstructionContext(Expression expr, TypeBinding al
expr.sourceStart,
expr.sourceEnd);
}
public void allocationInStaticContext(ASTNode location, LocalTypeBinding allocatedType) {
this.handle(
IProblem.AllocatingLocalInStaticContext,
new String[] { String.valueOf(allocatedType.readableName()) },
new String[] { String.valueOf(allocatedType.shortReadableName()) },
location.sourceStart,
location.sourceEnd);
}

public void fieldReadInEarlyConstructionContext(char[] token, int sourceStart, int sourceEnd) {
String[] arguments = new String[] {String.valueOf(token)};
this.handle(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,7 @@
2029 = Cannot assign field ''{0}'' from class ''{1}'' in an early construction context
2030 = Cannot assign field ''{0}'' in an early construction context, because it has an initializer
2031 = Constructor call is not allowed here
2032 = Cannot instantiate local class ''{0}'' in a static context

# JEP 455 Primitive Types in Patterns, instanceof, and switch (Preview)
2100 = Case constants in a switch on ''{0}'' must have type ''{1}''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ class ProblemAttributes {
expectedProblemAttributes.put("AbstractMethodMustBeImplementedOverConcreteMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("AbstractMethodsInConcreteClass", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("AbstractServiceImplementation", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("AllocatingLocalInStaticContext", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("AmbiguousConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("AmbiguousConstructorInDefaultConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("AmbiguousConstructorInImplicitConstructorCall", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
Expand Down Expand Up @@ -1480,6 +1481,7 @@ class ProblemAttributes {
expectedProblemAttributes.put("AbstractMethodMustBeImplementedOverConcreteMethod", SKIP);
expectedProblemAttributes.put("AbstractMethodsInConcreteClass", SKIP);
expectedProblemAttributes.put("AbstractServiceImplementation", SKIP);
expectedProblemAttributes.put("AllocatingLocalInStaticContext", SKIP);
expectedProblemAttributes.put("AmbiguousConstructor", SKIP);
expectedProblemAttributes.put("AmbiguousConstructorInDefaultConstructor", SKIP);
expectedProblemAttributes.put("AmbiguousConstructorInImplicitConstructorCall", SKIP);
Expand Down
Loading

0 comments on commit da91237

Please sign in to comment.