Skip to content

Commit

Permalink
Merge branch 'eclipse-jdt:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
carstenartur authored Oct 28, 2024
2 parents 0ab4ca3 + 65db85c commit 5bf2739
Show file tree
Hide file tree
Showing 79 changed files with 3,605 additions and 1,277 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2550,11 +2550,19 @@ public interface IProblem {
int SealedLocalDirectSuperTypeSealed = TypeRelated + 1864;
/** @since 3.28 */
int SealedAnonymousClassCannotExtendSealedType = TypeRelated + 1865;
/** @since 3.28 */
/** @since 3.28
* @deprecated problem no longer generated
*/
int SealedSuperTypeInDifferentPackage = TypeRelated + 1866;
/** @since 3.28 */
/** @since 3.28
* @deprecated problem no longer generated
*/
int SealedSuperTypeDisallowed = TypeRelated + 1867;
/* Java15 errors - end */
/**
* @since 3.40
*/
int FunctionalInterfaceMayNotbeSealed = TypeRelated + 1868;
/* Java17 Sealed types errors - end */

/**
* @since 3.28
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5842,7 +5842,6 @@ private int generateTypeAnnotationAttributeForTypeDeclaration() {
superInterface.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS, i, allTypeAnnotationContexts);
}
}
// TODO: permittedTypes codegen
TypeParameter[] typeParameters = typeDeclaration.typeParameters;
if (typeParameters != null) {
for (int i = 0, max = typeParameters.length; i < max; i++) {
Expand Down Expand Up @@ -6044,7 +6043,7 @@ public void initialize(SourceTypeBinding aType, ClassFile parentClassFile, boole
if (aType.isAnonymousType()) {
ReferenceBinding superClass = aType.superclass;
if (superClass == null || !(superClass.isEnum() && superClass.isSealed()))
accessFlags &= ~ClassFileConstants.AccFinal;
accessFlags &= ~ClassFileConstants.AccFinal;
}
int finalAbstract = ClassFileConstants.AccFinal | ClassFileConstants.AccAbstract;
if ((accessFlags & finalAbstract) == finalAbstract) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
import org.eclipse.jdt.internal.compiler.ast.TypeReference.AnnotationPosition;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.StringConstant;
import org.eclipse.jdt.internal.compiler.lookup.*;

@SuppressWarnings({"rawtypes", "unchecked"})
Expand Down Expand Up @@ -498,6 +500,8 @@ public final boolean isFieldUseDeprecated(FieldBinding field, Scope scope, int f
// inside same unit - no report
if (scope.isDefinedInSameUnit(field.declaringClass)) return false;

if (sinceValueUnreached(field, scope)) return false;

// if context is deprecated, may avoid reporting
if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
return true;
Expand Down Expand Up @@ -548,6 +552,8 @@ public final boolean isMethodUseDeprecated(MethodBinding method, Scope scope,
// inside same unit - no report
if (scope.isDefinedInSameUnit(method.declaringClass)) return false;

if (sinceValueUnreached(method, scope)) return false;

// non explicit use and non explicitly deprecated - no report
if (!isExplicitUse &&
(method.modifiers & ClassFileConstants.AccDeprecated) == 0) {
Expand All @@ -559,6 +565,37 @@ public final boolean isMethodUseDeprecated(MethodBinding method, Scope scope,
return true;
}

private boolean sinceValueUnreached(Binding binding, Scope scope) {
if (binding instanceof TypeBinding typeBinding) {
if (!typeBinding.isReadyForAnnotations()) {
return false;
}
}
AnnotationBinding[] annotations = binding.getAnnotations();
for (AnnotationBinding annotation : annotations) {
if (annotation != null && annotation.getAnnotationType().id == TypeIds.T_JavaLangDeprecated) {
ElementValuePair[] pairs = annotation.getElementValuePairs();
for (ElementValuePair pair : pairs) {
if (CharOperation.equals(pair.getName(), TypeConstants.SINCE)) {
if (pair.getValue() instanceof StringConstant strConstant) {
try {
String value = strConstant.stringValue();
long sinceLevel = CompilerOptions.versionToJdkLevel(value);
long complianceLevel = scope.compilerOptions().complianceLevel;
if (complianceLevel < sinceLevel) {
return true;
}
} catch (NumberFormatException e) {
// do nothing and fall through
}
}
}
}
}
}
return false;
}

public boolean isSuper() {

return false;
Expand Down Expand Up @@ -619,6 +656,8 @@ public final boolean isTypeUseDeprecated(TypeBinding type, Scope scope) {
// inside same unit - no report
if (scope.isDefinedInSameUnit(refType)) return false;

if (sinceValueUnreached(refType, scope)) return false;

// if context is deprecated, may avoid reporting
if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,13 @@ public TypeBinding resolveType(BlockScope scope) {
protected void checkEarlyConstructionContext(BlockScope scope) {
if (JavaFeature.FLEXIBLE_CONSTRUCTOR_BODIES.isSupported(scope.compilerOptions())
&& this.type != null && this.type.resolvedType instanceof ReferenceBinding currentType) {
TypeBinding uninitialized = scope.getMatchingUninitializedType(currentType, !currentType.isLocalType());
// only enclosing types of non-static member types are relevant
if (currentType.isStatic() || currentType.isLocalType())
return;
currentType = currentType.enclosingType();
if (currentType == null)
return;
TypeBinding uninitialized = scope.getMatchingUninitializedType(currentType, true);
if (uninitialized != null)
scope.problemReporter().allocationInEarlyConstructionContext(this, this.resolvedType, uninitialized);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@ private Constant resolveCasePattern(BlockScope scope, TypeBinding caseType, Type
if (type != null) {
constant = IntConstant.fromValue(switchStatement.constantIndex);
switchStatement.caseLabelElements.add(e);
if (e instanceof RecordPattern)
switchStatement.containsRecordPatterns = true;

if (isUnguarded)
switchStatement.caseLabelElementTypes.add(type);
Expand All @@ -379,11 +381,8 @@ private Constant resolveCasePattern(BlockScope scope, TypeBinding caseType, Type
// The following code is copied from InstanceOfExpression#resolve()
// But there are enough differences to warrant a copy
if (!type.isReifiable()) {
if (expressionType != TypeBinding.NULL && !(e instanceof RecordPattern)) {
boolean isLegal = e.checkCastTypesCompatibility(scope, type, expressionType, e, false);
if (!isLegal || (e.bits & ASTNode.UnsafeCast) != 0) {
scope.problemReporter().unsafeCastInInstanceof(e, type, expressionType);
}
if (!e.isApplicable(switchExpressionType, scope, e)) {
return Constant.NotAConstant;
}
} else if (type.isValidBinding()) {
// if not a valid binding, an error has already been reported for unresolved type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.VANILLA_CONTEXT;

import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
Expand Down Expand Up @@ -75,7 +74,6 @@ public class ConditionalExpression extends OperatorExpression implements IPolyEx
private boolean isPolyExpression = false;
private TypeBinding originalValueIfTrueType;
private TypeBinding originalValueIfFalseType;
private boolean use18specifics;

public ConditionalExpression(Expression condition, Expression valueIfTrue, Expression valueIfFalse) {
this.condition = condition;
Expand Down Expand Up @@ -473,17 +471,11 @@ public StringBuilder printExpressionNoParenthesis(int indent, StringBuilder outp
public TypeBinding resolveType(BlockScope scope) {
// JLS3 15.25
LookupEnvironment env = scope.environment();
final long sourceLevel = scope.compilerOptions().sourceLevel;
boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5;
this.use18specifics = sourceLevel >= ClassFileConstants.JDK1_8;

if (this.use18specifics) {
if (this.expressionContext == ASSIGNMENT_CONTEXT || this.expressionContext == INVOCATION_CONTEXT) {
this.valueIfTrue.setExpressionContext(this.expressionContext);
this.valueIfTrue.setExpectedType(this.expectedType);
this.valueIfFalse.setExpressionContext(this.expressionContext);
this.valueIfFalse.setExpectedType(this.expectedType);
}
if (this.expressionContext == ASSIGNMENT_CONTEXT || this.expressionContext == INVOCATION_CONTEXT) {
this.valueIfTrue.setExpressionContext(this.expressionContext);
this.valueIfTrue.setExpectedType(this.expectedType);
this.valueIfFalse.setExpressionContext(this.expressionContext);
this.valueIfFalse.setExpectedType(this.expectedType);
}

if (this.constant != Constant.NotAConstant) {
Expand Down Expand Up @@ -556,7 +548,7 @@ public TypeBinding resolveType(BlockScope scope) {

TypeBinding valueIfTrueType = this.originalValueIfTrueType;
TypeBinding valueIfFalseType = this.originalValueIfFalseType;
if (use15specifics && TypeBinding.notEquals(valueIfTrueType, valueIfFalseType)) {
if (TypeBinding.notEquals(valueIfTrueType, valueIfFalseType)) {
if (valueIfTrueType.isBaseType()) {
if (valueIfFalseType.isBaseType()) {
// bool ? baseType : baseType
Expand Down Expand Up @@ -667,48 +659,27 @@ public TypeBinding resolveType(BlockScope scope) {
}
// Type references (null null is already tested)
if (valueIfTrueType.isBaseType() && valueIfTrueType != TypeBinding.NULL) {
if (use15specifics) {
valueIfTrueType = env.computeBoxingType(valueIfTrueType);
} else {
scope.problemReporter().conditionalArgumentsIncompatibleTypes(this, valueIfTrueType, valueIfFalseType);
return null;
}
valueIfTrueType = env.computeBoxingType(valueIfTrueType);
}
if (valueIfFalseType.isBaseType() && valueIfFalseType != TypeBinding.NULL) {
if (use15specifics) {
valueIfFalseType = env.computeBoxingType(valueIfFalseType);
} else {
scope.problemReporter().conditionalArgumentsIncompatibleTypes(this, valueIfTrueType, valueIfFalseType);
return null;
}
valueIfFalseType = env.computeBoxingType(valueIfFalseType);
}
if (use15specifics) {
// >= 1.5 : LUB(operand types) must exist
TypeBinding commonType = null;
if (valueIfTrueType == TypeBinding.NULL) {
commonType = valueIfFalseType.withoutToplevelNullAnnotation(); // null on other branch invalidates any @NonNull
} else if (valueIfFalseType == TypeBinding.NULL) {
commonType = valueIfTrueType.withoutToplevelNullAnnotation(); // null on other branch invalidates any @NonNull
} else {
commonType = scope.lowerUpperBound(new TypeBinding[] { valueIfTrueType, valueIfFalseType });
}
if (commonType != null) {
this.valueIfTrue.computeConversion(scope, commonType, this.originalValueIfTrueType);
this.valueIfFalse.computeConversion(scope, commonType, this.originalValueIfFalseType);
return this.resolvedType = commonType.capture(scope, this.sourceStart, this.sourceEnd);
}

// >= 1.5 : LUB(operand types) must exist
TypeBinding commonType = null;
if (valueIfTrueType == TypeBinding.NULL) {
commonType = valueIfFalseType.withoutToplevelNullAnnotation(); // null on other branch invalidates any @NonNull
} else if (valueIfFalseType == TypeBinding.NULL) {
commonType = valueIfTrueType.withoutToplevelNullAnnotation(); // null on other branch invalidates any @NonNull
} else {
// < 1.5 : one operand must be convertible to the other
if (valueIfFalseType.isCompatibleWith(valueIfTrueType)) {
this.valueIfTrue.computeConversion(scope, valueIfTrueType, this.originalValueIfTrueType);
this.valueIfFalse.computeConversion(scope, valueIfTrueType, this.originalValueIfFalseType);
return this.resolvedType = valueIfTrueType;
} else if (valueIfTrueType.isCompatibleWith(valueIfFalseType)) {
this.valueIfTrue.computeConversion(scope, valueIfFalseType, this.originalValueIfTrueType);
this.valueIfFalse.computeConversion(scope, valueIfFalseType, this.originalValueIfFalseType);
return this.resolvedType = valueIfFalseType;
}
commonType = scope.lowerUpperBound(new TypeBinding[] { valueIfTrueType, valueIfFalseType });
}
if (commonType != null) {
this.valueIfTrue.computeConversion(scope, commonType, this.originalValueIfTrueType);
this.valueIfFalse.computeConversion(scope, commonType, this.originalValueIfFalseType);
return this.resolvedType = commonType.capture(scope, this.sourceStart, this.sourceEnd);
}

scope.problemReporter().conditionalArgumentsIncompatibleTypes(
this,
valueIfTrueType,
Expand Down Expand Up @@ -816,9 +787,6 @@ public boolean isFunctionalType() {
@Override
public boolean isPolyExpression() throws UnsupportedOperationException {

if (!this.use18specifics)
return false;

if (this.isPolyExpression)
return true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ public void setIsGuarded() {
this.patterns[i].setIsGuarded();
}

@Override
public void setOuterExpressionType(TypeBinding expressionType) {
super.setOuterExpressionType(expressionType);
for (int i = 0; i < this.patternsCount; i++)
this.patterns[i].setOuterExpressionType(expressionType);
}

@Override
public TypeBinding resolveType(BlockScope scope) {
boolean hasError = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ public void setIsEitherOrPattern() {
this.primaryPattern.setIsEitherOrPattern();
}

@Override
public void setOuterExpressionType(TypeBinding expressionType) {
super.setOuterExpressionType(expressionType);
this.primaryPattern.setOuterExpressionType(expressionType);
}

@Override
public boolean coversType(TypeBinding type, Scope scope) {
return isUnguarded() && this.primaryPattern.coversType(type, scope);
Expand Down Expand Up @@ -130,7 +136,7 @@ public void traverse(ASTVisitor visitor, BlockScope scope) {
}

@Override
protected boolean isApplicable(TypeBinding other, BlockScope scope) {
return this.primaryPattern.isApplicable(other, scope);
protected boolean isApplicable(TypeBinding expressionType, BlockScope scope, ASTNode location) {
return this.primaryPattern.isApplicable(expressionType, scope, location);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,13 @@ public TypeBinding resolveType(BlockScope scope) {
if (expressionType == null || checkedType == null)
return null;

if (this.pattern != null) {
if (this.pattern.isApplicable(expressionType, scope, this)) {
checkForPrimitives(scope, checkedType, expressionType);
}
return this.resolvedType = TypeBinding.BOOLEAN;
}

if (!checkedType.isReifiable()) {
CompilerOptions options = scope.compilerOptions();
// Report same as before for older compliances
Expand All @@ -286,25 +293,26 @@ public TypeBinding resolveType(BlockScope scope) {
if (expressionType != TypeBinding.NULL) {
boolean isLegal = checkCastTypesCompatibility(scope, checkedType, expressionType, this.expression, true);
if (!isLegal || (this.bits & ASTNode.UnsafeCast) != 0) {
scope.problemReporter().unsafeCastInInstanceof(this.expression, checkedType, expressionType);
scope.problemReporter().unsafeCastInTestingContext(this.expression, checkedType, expressionType);
} else {
checkRefForPrimitivesAndAddSecretVariable(scope, checkedType, expressionType);
}
}
}
} else if (checkedType.isValidBinding()) {
// if not a valid binding, an error has already been reported for unresolved type
if ((expressionType != TypeBinding.NULL && expressionType.isBaseType()) // disallow autoboxing
|| checkedType.isBaseType()
|| !checkCastTypesCompatibility(scope, checkedType, expressionType, null, true)) {
checkForPrimitives(scope, checkedType, expressionType);
}
checkForPrimitives(scope, checkedType, expressionType);
}

return this.resolvedType = TypeBinding.BOOLEAN;
}

private void checkForPrimitives(BlockScope scope, TypeBinding checkedType, TypeBinding expressionType) {
boolean needToCheck = (expressionType != TypeBinding.NULL && expressionType.isBaseType()) // disallow autoboxing
|| checkedType.isBaseType()
|| !checkCastTypesCompatibility(scope, checkedType, expressionType, null, true);
if (!needToCheck)
return;
PrimitiveConversionRoute route = Pattern.findPrimitiveConversionRoute(checkedType, expressionType, scope);
this.testContextRecord = new TestContextRecord(checkedType, expressionType, route);

Expand Down
Loading

0 comments on commit 5bf2739

Please sign in to comment.