use of org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding in project bazel-jdt-java-toolchain by salesforce.
the class LambdaExpression method addSyntheticArgument.
public void addSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) {
if (this.original != this || this.binding == null)
// Do not bother tracking outer locals for clones created during overload resolution.
return;
SyntheticArgumentBinding syntheticLocal = null;
int newSlot = this.outerLocalVariables.length;
for (int i = 0; i < newSlot; i++) {
if (this.outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable)
return;
}
System.arraycopy(this.outerLocalVariables, 0, this.outerLocalVariables = new SyntheticArgumentBinding[newSlot + 1], 0, newSlot);
this.outerLocalVariables[newSlot] = syntheticLocal = new SyntheticArgumentBinding(actualOuterLocalVariable);
// may need adjusting later if we need to generate an instance method for the lambda.
syntheticLocal.resolvedPosition = this.outerLocalVariablesSlotSize;
syntheticLocal.declaringScope = this.scope;
int parameterCount = this.binding.parameters.length;
TypeBinding[] newParameters = new TypeBinding[parameterCount + 1];
newParameters[newSlot] = actualOuterLocalVariable.type;
for (int i = 0, j = 0; i < parameterCount; i++, j++) {
if (i == newSlot)
j++;
newParameters[j] = this.binding.parameters[i];
}
this.binding.parameters = newParameters;
switch(syntheticLocal.type.id) {
case TypeIds.T_long:
case TypeIds.T_double:
this.outerLocalVariablesSlotSize += 2;
break;
default:
this.outerLocalVariablesSlotSize++;
break;
}
}
use of org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding in project bazel-jdt-java-toolchain by salesforce.
the class LambdaExpression method generateCode.
@Override
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
if (this.shouldCaptureInstance) {
this.binding.modifiers &= ~ClassFileConstants.AccStatic;
} else {
this.binding.modifiers |= ClassFileConstants.AccStatic;
}
SourceTypeBinding sourceType = currentScope.enclosingSourceType();
boolean firstSpill = !(this.binding instanceof SyntheticMethodBinding);
this.binding = sourceType.addSyntheticMethod(this);
int pc = codeStream.position;
StringBuilder signature = new StringBuilder();
signature.append('(');
if (this.shouldCaptureInstance) {
codeStream.aload_0();
signature.append(sourceType.signature());
}
for (int i = 0, length = this.outerLocalVariables == null ? 0 : this.outerLocalVariables.length; i < length; i++) {
SyntheticArgumentBinding syntheticArgument = this.outerLocalVariables[i];
if (this.shouldCaptureInstance && firstSpill) {
// finally block handling results in extra spills, avoid side effect.
syntheticArgument.resolvedPosition++;
}
signature.append(syntheticArgument.type.signature());
LocalVariableBinding capturedOuterLocal = syntheticArgument.actualOuterLocalVariable;
VariableBinding[] path = currentScope.getEmulationPath(capturedOuterLocal);
codeStream.generateOuterAccess(path, this, capturedOuterLocal, currentScope);
}
signature.append(')');
if (this.expectedType instanceof IntersectionTypeBinding18) {
signature.append(((IntersectionTypeBinding18) this.expectedType).getSAMType(currentScope).signature());
} else {
signature.append(this.expectedType.signature());
}
int invokeDynamicNumber = codeStream.classFile.recordBootstrapMethod(this);
codeStream.invokeDynamic(invokeDynamicNumber, (this.shouldCaptureInstance ? 1 : 0) + this.outerLocalVariablesSlotSize, 1, this.descriptor.selector, signature.toString().toCharArray(), this.resolvedType.id, this.resolvedType);
if (!valueRequired)
codeStream.pop();
codeStream.recordPositionsFrom(pc, this.sourceStart);
}
use of org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding in project bazel-jdt-java-toolchain by salesforce.
the class ReferenceExpression method generateImplicitLambda.
public void generateImplicitLambda(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
ReferenceExpression copy = copy();
int argc = this.descriptor.parameters.length;
LambdaExpression implicitLambda = new LambdaExpression(this.compilationResult, false, (this.binding.modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0);
Argument[] arguments = new Argument[argc];
for (int i = 0; i < argc; i++) arguments[i] = new Argument(CharOperation.append(ImplicitArgName, Integer.toString(i).toCharArray()), 0, null, 0, true);
implicitLambda.setArguments(arguments);
implicitLambda.setExpressionContext(this.expressionContext);
implicitLambda.setExpectedType(this.expectedType);
int parameterShift = this.receiverPrecedesParameters ? 1 : 0;
Expression[] argv = new SingleNameReference[argc - parameterShift];
for (int i = 0, length = argv.length; i < length; i++) {
char[] name = CharOperation.append(ImplicitArgName, Integer.toString((i + parameterShift)).toCharArray());
argv[i] = new SingleNameReference(name, 0);
}
boolean generateSecretReceiverVariable = shouldGenerateSecretReceiverVariable();
if (isMethodReference()) {
if (generateSecretReceiverVariable) {
this.lhs.generateCode(currentScope, codeStream, true);
codeStream.store(this.receiverVariable, false);
codeStream.addVariable(this.receiverVariable);
}
MessageSend message = new MessageSend();
message.selector = this.selector;
Expression receiver = generateSecretReceiverVariable ? new SingleNameReference(this.receiverVariable.name, 0) : copy.lhs;
message.receiver = this.receiverPrecedesParameters ? new SingleNameReference(CharOperation.append(ImplicitArgName, Integer.toString(0).toCharArray()), 0) : receiver;
message.typeArguments = copy.typeArguments;
message.arguments = argv;
implicitLambda.setBody(message);
} else if (isArrayConstructorReference()) {
// We don't care for annotations, source positions etc. They are immaterial, just drop.
ArrayAllocationExpression arrayAllocationExpression = new ArrayAllocationExpression();
arrayAllocationExpression.dimensions = new Expression[] { argv[0] };
if (this.lhs instanceof ArrayTypeReference) {
ArrayTypeReference arrayTypeReference = (ArrayTypeReference) this.lhs;
arrayAllocationExpression.type = arrayTypeReference.dimensions == 1 ? new SingleTypeReference(arrayTypeReference.token, 0L) : new ArrayTypeReference(arrayTypeReference.token, arrayTypeReference.dimensions - 1, 0L);
} else {
ArrayQualifiedTypeReference arrayQualifiedTypeReference = (ArrayQualifiedTypeReference) this.lhs;
arrayAllocationExpression.type = arrayQualifiedTypeReference.dimensions == 1 ? new QualifiedTypeReference(arrayQualifiedTypeReference.tokens, arrayQualifiedTypeReference.sourcePositions) : new ArrayQualifiedTypeReference(arrayQualifiedTypeReference.tokens, arrayQualifiedTypeReference.dimensions - 1, arrayQualifiedTypeReference.sourcePositions);
}
implicitLambda.setBody(arrayAllocationExpression);
} else {
AllocationExpression allocation = new AllocationExpression();
if (this.lhs instanceof TypeReference) {
allocation.type = (TypeReference) this.lhs;
} else if (this.lhs instanceof SingleNameReference) {
allocation.type = new SingleTypeReference(((SingleNameReference) this.lhs).token, 0);
} else if (this.lhs instanceof QualifiedNameReference) {
allocation.type = new QualifiedTypeReference(((QualifiedNameReference) this.lhs).tokens, new long[((QualifiedNameReference) this.lhs).tokens.length]);
} else {
// $NON-NLS-1$
throw new IllegalStateException("Unexpected node type");
}
allocation.typeArguments = copy.typeArguments;
allocation.arguments = argv;
implicitLambda.setBody(allocation);
}
// Process the lambda, taking care not to double report diagnostics. Don't expect any from resolve, Any from code generation should surface, but not those from flow analysis.
BlockScope lambdaScope = this.receiverVariable != null ? this.receiverVariable.declaringScope : currentScope;
IErrorHandlingPolicy oldPolicy = lambdaScope.problemReporter().switchErrorHandlingPolicy(silentErrorHandlingPolicy);
try {
implicitLambda.resolveType(lambdaScope, true);
implicitLambda.analyseCode(lambdaScope, new FieldInitsFakingFlowContext(null, this, Binding.NO_EXCEPTIONS, null, lambdaScope, FlowInfo.DEAD_END), UnconditionalFlowInfo.fakeInitializedFlowInfo(lambdaScope.outerMostMethodScope().analysisIndex, lambdaScope.referenceType().maxFieldCount));
} finally {
lambdaScope.problemReporter().switchErrorHandlingPolicy(oldPolicy);
}
SyntheticArgumentBinding[] outerLocals = this.receiverType.syntheticOuterLocalVariables();
for (int i = 0, length = outerLocals == null ? 0 : outerLocals.length; i < length; i++) implicitLambda.addSyntheticArgument(outerLocals[i].actualOuterLocalVariable);
implicitLambda.generateCode(lambdaScope, codeStream, valueRequired);
if (generateSecretReceiverVariable) {
codeStream.removeVariable(this.receiverVariable);
}
}
use of org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding in project bazel-jdt-java-toolchain by salesforce.
the class ClassFile method initializeDefaultLocals.
private void initializeDefaultLocals(StackMapFrame frame, MethodBinding methodBinding, int maxLocals, int codeLength) {
if (maxLocals != 0) {
int resolvedPosition = 0;
// take into account enum constructor synthetic name+ordinal
final boolean isConstructor = methodBinding.isConstructor();
if (isConstructor || !methodBinding.isStatic()) {
LocalVariableBinding localVariableBinding = new LocalVariableBinding(ConstantPool.This, methodBinding.declaringClass, 0, false);
localVariableBinding.resolvedPosition = 0;
this.codeStream.record(localVariableBinding);
localVariableBinding.recordInitializationStartPC(0);
localVariableBinding.recordInitializationEndPC(codeLength);
frame.putLocal(resolvedPosition, new VerificationTypeInfo(isConstructor ? VerificationTypeInfo.ITEM_UNINITIALIZED_THIS : VerificationTypeInfo.ITEM_OBJECT, methodBinding.declaringClass));
resolvedPosition++;
}
if (isConstructor) {
if (methodBinding.declaringClass.isEnum()) {
// $NON-NLS-1$
LocalVariableBinding localVariableBinding = new LocalVariableBinding(" name".toCharArray(), this.referenceBinding.scope.getJavaLangString(), 0, false);
localVariableBinding.resolvedPosition = resolvedPosition;
this.codeStream.record(localVariableBinding);
localVariableBinding.recordInitializationStartPC(0);
localVariableBinding.recordInitializationEndPC(codeLength);
frame.putLocal(resolvedPosition, new VerificationTypeInfo(this.referenceBinding.scope.getJavaLangString()));
resolvedPosition++;
// $NON-NLS-1$
localVariableBinding = new LocalVariableBinding(" ordinal".toCharArray(), TypeBinding.INT, 0, false);
localVariableBinding.resolvedPosition = resolvedPosition;
this.codeStream.record(localVariableBinding);
localVariableBinding.recordInitializationStartPC(0);
localVariableBinding.recordInitializationEndPC(codeLength);
frame.putLocal(resolvedPosition, new VerificationTypeInfo(TypeBinding.INT));
resolvedPosition++;
}
// take into account the synthetic parameters
if (methodBinding.declaringClass.isNestedType()) {
ReferenceBinding[] enclosingInstanceTypes;
if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
// an enclosingInstanceType can only be a reference
// binding. It cannot be
// LongBinding or DoubleBinding
// $NON-NLS-1$
LocalVariableBinding localVariableBinding = new LocalVariableBinding((" enclosingType" + i).toCharArray(), enclosingInstanceTypes[i], 0, false);
localVariableBinding.resolvedPosition = resolvedPosition;
this.codeStream.record(localVariableBinding);
localVariableBinding.recordInitializationStartPC(0);
localVariableBinding.recordInitializationEndPC(codeLength);
frame.putLocal(resolvedPosition, new VerificationTypeInfo(enclosingInstanceTypes[i]));
resolvedPosition++;
}
}
TypeBinding[] arguments;
if ((arguments = methodBinding.parameters) != null) {
for (int i = 0, max = arguments.length; i < max; i++) {
final TypeBinding typeBinding = arguments[i];
frame.putLocal(resolvedPosition, new VerificationTypeInfo(typeBinding));
switch(typeBinding.id) {
case TypeIds.T_double:
case TypeIds.T_long:
resolvedPosition += 2;
break;
default:
resolvedPosition++;
}
}
}
SyntheticArgumentBinding[] syntheticArguments;
if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) {
for (int i = 0, max = syntheticArguments.length; i < max; i++) {
final TypeBinding typeBinding = syntheticArguments[i].type;
// $NON-NLS-1$
LocalVariableBinding localVariableBinding = new LocalVariableBinding((" synthetic" + i).toCharArray(), typeBinding, 0, false);
localVariableBinding.resolvedPosition = resolvedPosition;
this.codeStream.record(localVariableBinding);
localVariableBinding.recordInitializationStartPC(0);
localVariableBinding.recordInitializationEndPC(codeLength);
frame.putLocal(resolvedPosition, new VerificationTypeInfo(typeBinding));
switch(typeBinding.id) {
case TypeIds.T_double:
case TypeIds.T_long:
resolvedPosition += 2;
break;
default:
resolvedPosition++;
}
}
}
} else {
TypeBinding[] arguments;
if ((arguments = methodBinding.parameters) != null) {
for (int i = 0, max = arguments.length; i < max; i++) {
final TypeBinding typeBinding = arguments[i];
frame.putLocal(resolvedPosition, new VerificationTypeInfo(typeBinding));
switch(typeBinding.id) {
case TypeIds.T_double:
case TypeIds.T_long:
resolvedPosition += 2;
break;
default:
resolvedPosition++;
}
}
}
}
} else {
TypeBinding[] arguments;
if ((arguments = methodBinding.parameters) != null) {
for (int i = 0, max = arguments.length; i < max; i++) {
final TypeBinding typeBinding = arguments[i];
// For the branching complexities in the generated $deserializeLambda$ we need the local variable
// $NON-NLS-1$
LocalVariableBinding localVariableBinding = new LocalVariableBinding((" synthetic" + i).toCharArray(), typeBinding, 0, true);
localVariableBinding.resolvedPosition = i;
this.codeStream.record(localVariableBinding);
localVariableBinding.recordInitializationStartPC(0);
localVariableBinding.recordInitializationEndPC(codeLength);
frame.putLocal(resolvedPosition, new VerificationTypeInfo(typeBinding));
switch(typeBinding.id) {
case TypeIds.T_double:
case TypeIds.T_long:
resolvedPosition += 2;
break;
default:
resolvedPosition++;
}
}
}
}
}
}
use of org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding in project bazel-jdt-java-toolchain by salesforce.
the class ClassFile method generateMethodParameters.
/**
* @param binding the given method binding
* @return the number of attributes created while dumping he method's parameters in the .class file (0 or 1)
*/
private int generateMethodParameters(final MethodBinding binding) {
if (binding.sourceLambda() != null)
return 0;
int initialContentsOffset = this.contentsOffset;
// count of actual parameters
int length = 0;
AbstractMethodDeclaration methodDeclaration = binding.sourceMethod();
boolean isConstructor = binding.isConstructor();
TypeBinding[] targetParameters = binding.parameters;
ReferenceBinding declaringClass = binding.declaringClass;
if (declaringClass.isEnum()) {
if (isConstructor) {
// insert String name,int ordinal
length = writeArgumentName(ConstantPool.EnumName, ClassFileConstants.AccSynthetic, length);
length = writeArgumentName(ConstantPool.EnumOrdinal, ClassFileConstants.AccSynthetic, length);
} else if (binding instanceof SyntheticMethodBinding && CharOperation.equals(ConstantPool.ValueOf, binding.selector)) {
// insert String name
length = writeArgumentName(ConstantPool.Name, ClassFileConstants.AccMandated, length);
// Override "unknown" synthetics below
targetParameters = Binding.NO_PARAMETERS;
}
}
boolean needSynthetics = isConstructor && declaringClass.isNestedType();
if (needSynthetics) {
// Take into account the synthetic argument names
// This tracks JLS8, paragraph 8.8.9
boolean anonymousWithLocalSuper = declaringClass.isAnonymousType() && declaringClass.superclass().isLocalType();
boolean anonymousWithNestedSuper = declaringClass.isAnonymousType() && declaringClass.superclass().isNestedType();
boolean isImplicitlyDeclared = ((!declaringClass.isPrivate()) || declaringClass.isAnonymousType()) && !anonymousWithLocalSuper;
ReferenceBinding[] syntheticArgumentTypes = declaringClass.syntheticEnclosingInstanceTypes();
if (syntheticArgumentTypes != null) {
for (int i = 0, count = syntheticArgumentTypes.length; i < count; i++) {
// This behaviour tracks JLS 15.9.5.1
// This covers that the parameter ending up in a nested class must be mandated "on the way in", even if it
// isn't the first. The practical relevance of this is questionable, since the constructor call will be
// generated by the same constructor.
boolean couldForwardToMandated = anonymousWithNestedSuper ? declaringClass.superclass().enclosingType().equals(syntheticArgumentTypes[i]) : true;
int modifier = couldForwardToMandated && isImplicitlyDeclared ? ClassFileConstants.AccMandated : ClassFileConstants.AccSynthetic;
char[] name = CharOperation.concat(TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX, // cannot use depth, can be identical
String.valueOf(i).toCharArray());
length = writeArgumentName(name, modifier | ClassFileConstants.AccFinal, length);
}
}
if (binding instanceof SyntheticMethodBinding) {
targetParameters = ((SyntheticMethodBinding) binding).targetMethod.parameters;
methodDeclaration = ((SyntheticMethodBinding) binding).targetMethod.sourceMethod();
}
}
if (targetParameters != Binding.NO_PARAMETERS) {
Argument[] arguments = null;
if (methodDeclaration != null && methodDeclaration.arguments != null) {
arguments = methodDeclaration.arguments;
}
for (int i = 0, max = targetParameters.length, argumentsLength = arguments != null ? arguments.length : 0; i < max; i++) {
if (argumentsLength > i && arguments[i] != null) {
Argument argument = arguments[i];
length = writeArgumentName(argument.name, argument.binding.modifiers, length);
} else {
length = writeArgumentName(null, ClassFileConstants.AccSynthetic, length);
}
}
}
if (needSynthetics) {
SyntheticArgumentBinding[] syntheticOuterArguments = declaringClass.syntheticOuterLocalVariables();
int count = syntheticOuterArguments == null ? 0 : syntheticOuterArguments.length;
for (int i = 0; i < count; i++) {
length = writeArgumentName(syntheticOuterArguments[i].name, syntheticOuterArguments[i].modifiers | ClassFileConstants.AccSynthetic, length);
}
// move the extra padding arguments of the synthetic constructor invocation to the end
for (int i = targetParameters.length, extraLength = binding.parameters.length; i < extraLength; i++) {
TypeBinding parameter = binding.parameters[i];
length = writeArgumentName(parameter.constantPoolName(), ClassFileConstants.AccSynthetic, length);
}
}
if (length > 0) {
// so we actually output the parameter
// u1 for count, u2+u2 per parameter
int attributeLength = 1 + 4 * length;
if (this.contentsOffset + 6 + attributeLength >= this.contents.length) {
resizeContents(6 + attributeLength);
}
int methodParametersNameIndex = this.constantPool.literalIndex(AttributeNamesConstants.MethodParametersName);
this.contents[initialContentsOffset++] = (byte) (methodParametersNameIndex >> 8);
this.contents[initialContentsOffset++] = (byte) methodParametersNameIndex;
this.contents[initialContentsOffset++] = (byte) (attributeLength >> 24);
this.contents[initialContentsOffset++] = (byte) (attributeLength >> 16);
this.contents[initialContentsOffset++] = (byte) (attributeLength >> 8);
this.contents[initialContentsOffset++] = (byte) attributeLength;
this.contents[initialContentsOffset++] = (byte) length;
return 1;
} else {
return 0;
}
}
Aggregations