blob: baf68a0944c055a791ab77e036ed65f7474fccfd [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.RecordComponent;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.TeamAnchor;
public class RecordComponentBinding extends VariableBinding {
public ReferenceBinding declaringRecord;
public BlockScope declaringScope; // back-pointer to its declaring scope
public RecordComponentBinding(ReferenceBinding declaringRecord, RecordComponent declaration, TypeBinding type, int modifiers) {
super(declaration.name, type, modifiers, null);
this.declaringRecord = declaringRecord;
declaration.binding = this;
}
/* API
* Answer the receiver's binding type from Binding.BindingID.
*/
@Override
public final int kind() {
return RECORD_COMPONENT;
}
//{ObjectTeams:
@Override
public boolean isBaseAnchor() {
// TODO Auto-generated method stub
return false;
}
private RecordComponentBinding(ReferenceBinding declaringRecord, char[] name, int modifiers) {
super(name, null, modifiers, null);
this.declaringRecord = declaringRecord;
}
@Override
protected TeamAnchor getClone() {
return new RecordComponentBinding(this.declaringRecord, this.name, this.modifiers);
}
// SH}
/*
* declaringUniqueKey # recordComponentName
* p.X (int first, int second) { } --> Lp/X;#first
*/
@Override
public char[] computeUniqueKey(boolean isLeaf) {
StringBuffer buffer = new StringBuffer();
buffer.append(this.declaringRecord.computeUniqueKey(false/*not a leaf*/));
// variable name
buffer.append('#');
buffer.append(this.name);
int length = buffer.length();
char[] uniqueKey = new char[length];
buffer.getChars(0, length, uniqueKey, 0);
return uniqueKey;
}
/**
* X<T> t --> LX<TT;>;
*/
public char[] genericSignature() {
if ((this.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0) return null;
return this.type.genericTypeSignature();
}
@Override
public AnnotationBinding[] getAnnotations() {
RecordComponentBinding originalRecordComponentBinding = original();
ReferenceBinding declaringRecordBinding = originalRecordComponentBinding.declaringRecord;
if (declaringRecordBinding == null) {
return Binding.NO_ANNOTATIONS;
}
return declaringRecordBinding.retrieveAnnotations(originalRecordComponentBinding);
}
@Override
public long getAnnotationTagBits() {
RecordComponentBinding originalRecordComponentBinding = original();
if ((originalRecordComponentBinding.tagBits & TagBits.AnnotationResolved) == 0 &&
originalRecordComponentBinding.declaringRecord instanceof SourceTypeBinding) {
ClassScope scope = ((SourceTypeBinding) originalRecordComponentBinding.declaringRecord).scope;
if (scope == null) {// should not be true - but safety net
this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
return 0;
}
TypeDeclaration typeDecl = scope.referenceContext;
RecordComponent recordComponent = typeDecl.declarationOf(originalRecordComponentBinding);
if (recordComponent != null) {
ASTNode.resolveAnnotations(typeDecl.initializerScope, recordComponent.annotations, originalRecordComponentBinding);
}
}
return originalRecordComponentBinding.tagBits;
}
public final boolean isDeprecated() {
return (this.modifiers & ClassFileConstants.AccDeprecated) != 0;
}
// TODO: check
public final boolean isPublic() {
return (this.modifiers & ClassFileConstants.AccPublic) != 0;
}
/**
* Returns the original RecordComponent (as opposed to parameterized instances)
*/
public RecordComponentBinding original() {
return this;
}
@Override
public void setAnnotations(AnnotationBinding[] annotations, boolean forceStore) {
this.declaringRecord.storeAnnotations(this, annotations, forceStore);
}
public RecordComponent sourceRecordComponent() {
if (!(this.declaringRecord instanceof SourceTypeBinding))
return null;
SourceTypeBinding sourceType = (SourceTypeBinding) this.declaringRecord;
RecordComponent[] recordComponents = sourceType.scope.referenceContext.recordComponents;
if (recordComponents != null) {
for (int i = recordComponents.length; --i >= 0;)
if (this == recordComponents[i].binding)
return recordComponents[i];
}
return null;
}
}