Skip to content

Commit

Permalink
NPE in org.eclipse.jdt.internal.compiler.ast.MessageSend.analyseCode (#…
Browse files Browse the repository at this point in the history
…1626)

fixes #1621
  • Loading branch information
stephan-herrmann authored Nov 26, 2023
1 parent 47bb602 commit c13b03c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,20 @@ public boolean kosherDescriptor(Scope currentScope, MethodBinding sam, boolean s
return super.kosherDescriptor(currentScope, sam, shouldChatter);
}

public void resolveWithPatternVariablesInScope(LocalVariableBinding[] patternVariablesInScope, BlockScope blockScope, boolean skipKosherCheck) {
if (patternVariablesInScope != null) {
for (LocalVariableBinding local : patternVariablesInScope) {
local.modifiers &= ~ExtraCompilerModifiers.AccPatternVariable;
}
this.resolveType(blockScope, skipKosherCheck);
for (LocalVariableBinding local : patternVariablesInScope) {
local.modifiers |= ExtraCompilerModifiers.AccPatternVariable;
}
} else {
resolveType(blockScope, skipKosherCheck);
}
}

/* This code is arranged so that we can continue with as much analysis as possible while avoiding
* mine fields that would result in a slew of spurious messages. This method is a merger of:
* @see org.eclipse.jdt.internal.compiler.lookup.MethodScope.createMethod(AbstractMethodDeclaration)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ public void generateImplicitLambda(BlockScope currentScope, CodeStream codeStrea
argv[i] = new SingleNameReference(name, 0);
}
boolean generateSecretReceiverVariable = shouldGenerateSecretReceiverVariable();
LocalVariableBinding[] patternVariablesInScope = null;
if (isMethodReference()) {
if (generateSecretReceiverVariable) {
this.lhs.generateCode(currentScope, codeStream, true);
Expand All @@ -219,6 +220,13 @@ public void generateImplicitLambda(BlockScope currentScope, CodeStream codeStrea
MessageSend message = new MessageSend();
message.selector = this.selector;
Expression receiver = generateSecretReceiverVariable ? new SingleNameReference(this.receiverVariable.name, 0) : copy.lhs;
if (this.lhs instanceof NameReference nr
&& nr.binding instanceof LocalVariableBinding receiverLocal
&& receiverLocal.isValidBinding()
&& (receiverLocal.modifiers & ExtraCompilerModifiers.AccPatternVariable) != 0) {
// what was in scope during initial resolve must be in scope during resolve of synthetic AST, too:
patternVariablesInScope = new LocalVariableBinding[] { receiverLocal };
}
message.receiver = this.receiverPrecedesParameters ?
new SingleNameReference(CharOperation.append(ImplicitArgName, Integer.toString(0).toCharArray()), 0) : receiver;
message.typeArguments = copy.typeArguments;
Expand Down Expand Up @@ -259,7 +267,7 @@ public void generateImplicitLambda(BlockScope currentScope, CodeStream codeStrea
BlockScope lambdaScope = this.receiverVariable != null ? this.receiverVariable.declaringScope : currentScope;
IErrorHandlingPolicy oldPolicy = lambdaScope.problemReporter().switchErrorHandlingPolicy(silentErrorHandlingPolicy);
try {
implicitLambda.resolveType(lambdaScope, true);
implicitLambda.resolveWithPatternVariablesInScope(patternVariablesInScope, lambdaScope, true);
implicitLambda.analyseCode(lambdaScope,
new FieldInitsFakingFlowContext(null, this, Binding.NO_EXCEPTIONS, null, lambdaScope, FlowInfo.DEAD_END),
UnconditionalFlowInfo.fakeInitializedFlowInfo(implicitLambda.firstLocalLocal, lambdaScope.referenceType().maxFieldCount));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,34 @@ public void testGH1076() {
"Syntax error, modifiers are not allowed here\n" +
"----------\n");
}

public void testGH1621() {
runConformTest(
new String[] {
"ConsumerEndpointSpec.java",
"""
import java.util.function.Consumer;
public class ConsumerEndpointSpec {
public void setNotPropagatedHeaders(String... headers) {
for (String s: headers) System.out.print(s);
}
void foo(Object h) {
if (h instanceof ConsumerEndpointSpec producingMessageHandler) {
acceptIfNotEmpty(new String[] {"OK"}, producingMessageHandler::setNotPropagatedHeaders);
}
}
public <T> void acceptIfNotEmpty(T[] value, Consumer<T[]> consumer) {
consumer.accept(value);
}
public static void main(String... args) {
ConsumerEndpointSpec obj = new ConsumerEndpointSpec();
obj.foo(obj);
}
}
"""
},
"OK",
getCompilerOptions());
}
}

0 comments on commit c13b03c

Please sign in to comment.