use of org.eclipse.jdt.internal.compiler.ast.ThisReference in project lombok by rzwitserloot.
the class EclipseJavaUtilMapSingularizer method generateSingularMethod.
private void generateSingularMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = ClassFileConstants.AccPublic;
List<Statement> statements = new ArrayList<Statement>();
statements.add(createConstructBuilderVarIfNeeded(data, builderType, true));
String sN = new String(data.getSingularName());
String pN = new String(data.getPluralName());
char[] keyParamName = (sN + "Key").toCharArray();
char[] valueParamName = (sN + "Value").toCharArray();
char[] keyFieldName = (pN + "$key").toCharArray();
char[] valueFieldName = (pN + "$value").toCharArray();
/* this.pluralname$key.add(singularnameKey); */
{
FieldReference thisDotKeyField = new FieldReference(keyFieldName, 0L);
thisDotKeyField.receiver = new ThisReference(0, 0);
MessageSend thisDotKeyFieldDotAdd = new MessageSend();
thisDotKeyFieldDotAdd.arguments = new Expression[] { new SingleNameReference(keyParamName, 0L) };
thisDotKeyFieldDotAdd.receiver = thisDotKeyField;
thisDotKeyFieldDotAdd.selector = "add".toCharArray();
statements.add(thisDotKeyFieldDotAdd);
}
/* this.pluralname$value.add(singularnameValue); */
{
FieldReference thisDotValueField = new FieldReference(valueFieldName, 0L);
thisDotValueField.receiver = new ThisReference(0, 0);
MessageSend thisDotValueFieldDotAdd = new MessageSend();
thisDotValueFieldDotAdd.arguments = new Expression[] { new SingleNameReference(valueParamName, 0L) };
thisDotValueFieldDotAdd.receiver = thisDotValueField;
thisDotValueFieldDotAdd.selector = "add".toCharArray();
statements.add(thisDotValueFieldDotAdd);
}
if (returnStatement != null)
statements.add(returnStatement);
md.statements = statements.toArray(new Statement[statements.size()]);
TypeReference keyParamType = cloneParamType(0, data.getTypeArgs(), builderType);
Argument keyParam = new Argument(keyParamName, 0, keyParamType, 0);
TypeReference valueParamType = cloneParamType(1, data.getTypeArgs(), builderType);
Argument valueParam = new Argument(valueParamName, 0, valueParamType, 0);
md.arguments = new Argument[] { keyParam, valueParam };
md.returnType = returnType;
md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName("put", new String(data.getSingularName())).toCharArray();
md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
use of org.eclipse.jdt.internal.compiler.ast.ThisReference in project lombok by rzwitserloot.
the class HandleNonNull method addCompactConstructorIfNeeded.
private EclipseNode addCompactConstructorIfNeeded(EclipseNode typeNode, EclipseNode annotationNode) {
// explicit Compact Constructor has bits set: Bit32, IsCanonicalConstructor (10).
// implicit Compact Constructor has bits set: Bit32, IsCanonicalConstructor (10), and IsImplicit (11).
// explicit constructor with long-form shows up as a normal constructor (Bit32 set, that's all), but the
// implicit CC is then also present and will presumably be stripped out in some later phase.
EclipseNode toRemove = null;
EclipseNode existingCompactConstructor = null;
List<FieldDeclaration> recordComponents = null;
for (EclipseNode child : typeNode.down()) {
if (!(child.get() instanceof ConstructorDeclaration))
continue;
ConstructorDeclaration cd = (ConstructorDeclaration) child.get();
if ((cd.bits & IsCanonicalConstructor) != 0) {
if ((cd.bits & IsImplicit) != 0) {
toRemove = child;
} else {
existingCompactConstructor = child;
}
} else {
if (recordComponents == null)
recordComponents = getRecordComponents(typeNode);
int argLength = cd.arguments == null ? 0 : cd.arguments.length;
int compLength = recordComponents.size();
boolean isCanonical = argLength == compLength;
if (isCanonical)
top: for (int i = 0; i < argLength; i++) {
TypeReference a = recordComponents.get(i).type;
TypeReference b = cd.arguments[i] == null ? null : cd.arguments[i].type;
// technically this won't match e.g. `java.lang.String` to just `String`;
// to use this feature you'll need to use the same way to write it, which seems
// like a fair requirement.
char[][] ta = getRawTypeName(a);
char[][] tb = getRawTypeName(b);
if (ta == null || tb == null || ta.length != tb.length) {
isCanonical = false;
break top;
}
for (int j = 0; j < ta.length; j++) {
if (!Arrays.equals(ta[j], tb[j])) {
isCanonical = false;
break top;
}
}
}
if (isCanonical) {
return null;
}
}
}
if (existingCompactConstructor != null)
return existingCompactConstructor;
int posToInsert = -1;
TypeDeclaration td = (TypeDeclaration) typeNode.get();
if (toRemove != null) {
int idxToRemove = -1;
for (int i = 0; i < td.methods.length; i++) {
if (td.methods[i] == toRemove.get())
idxToRemove = i;
}
if (idxToRemove != -1) {
System.arraycopy(td.methods, idxToRemove + 1, td.methods, idxToRemove, td.methods.length - idxToRemove - 1);
posToInsert = td.methods.length - 1;
typeNode.removeChild(toRemove);
}
}
if (posToInsert == -1) {
AbstractMethodDeclaration[] na = new AbstractMethodDeclaration[td.methods.length + 1];
posToInsert = td.methods.length;
System.arraycopy(td.methods, 0, na, 0, posToInsert);
td.methods = na;
}
ConstructorDeclaration cd = new ConstructorDeclaration(((CompilationUnitDeclaration) typeNode.top().get()).compilationResult);
cd.modifiers = ClassFileConstants.AccPublic;
cd.bits = ASTNode.Bit32 | ECLIPSE_DO_NOT_TOUCH_FLAG | IsCanonicalConstructor;
cd.selector = td.name;
cd.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper);
if (recordComponents == null)
recordComponents = getRecordComponents(typeNode);
cd.arguments = new Argument[recordComponents.size()];
cd.statements = new Statement[recordComponents.size()];
cd.bits = IsCanonicalConstructor;
for (int i = 0; i < cd.arguments.length; i++) {
FieldDeclaration cmp = recordComponents.get(i);
cd.arguments[i] = new Argument(cmp.name, cmp.sourceStart, cmp.type, 0);
cd.arguments[i].bits = ASTNode.IsArgument | ASTNode.IgnoreRawTypeCheck | ASTNode.IsReachable;
FieldReference lhs = new FieldReference(cmp.name, 0);
lhs.receiver = new ThisReference(0, 0);
SingleNameReference rhs = new SingleNameReference(cmp.name, 0);
cd.statements[i] = new Assignment(lhs, rhs, cmp.sourceEnd);
}
setGeneratedBy(cd, annotationNode.get());
for (int i = 0; i < cd.arguments.length; i++) {
FieldDeclaration cmp = recordComponents.get(i);
cd.arguments[i].sourceStart = cmp.sourceStart;
cd.arguments[i].sourceEnd = cmp.sourceStart;
cd.arguments[i].declarationSourceEnd = cmp.sourceStart;
cd.arguments[i].declarationEnd = cmp.sourceStart;
}
td.methods[posToInsert] = cd;
cd.annotations = addSuppressWarningsAll(typeNode, cd, cd.annotations);
cd.annotations = addGenerated(typeNode, cd, cd.annotations);
return typeNode.add(cd, Kind.METHOD);
}
use of org.eclipse.jdt.internal.compiler.ast.ThisReference in project lombok by rzwitserloot.
the class HandleSuperBuilder method generateCleanMethod.
private MethodDeclaration generateCleanMethod(BuilderJob job) {
List<Statement> statements = new ArrayList<Statement>();
for (BuilderFieldData bfd : job.builderFields) {
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
bfd.singularData.getSingularizer().appendCleaningCode(bfd.singularData, job.builderType, statements);
}
}
FieldReference thisUnclean = new FieldReference(CLEAN_FIELD_NAME, 0);
thisUnclean.receiver = new ThisReference(0, 0);
statements.add(new Assignment(thisUnclean, new FalseLiteral(0, 0), 0));
MethodDeclaration decl = job.createNewMethodDeclaration();
// new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
decl.selector = CLEAN_METHOD_NAME;
decl.modifiers = ClassFileConstants.AccPrivate;
decl.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
decl.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0);
decl.statements = statements.toArray(new Statement[0]);
decl.traverse(new SetGeneratedByVisitor(job.source), (ClassScope) null);
return decl;
}
use of org.eclipse.jdt.internal.compiler.ast.ThisReference in project lombok by rzwitserloot.
the class HandleSuperBuilder method generateSelfMethod.
private MethodDeclaration generateSelfMethod(BuilderJob job) {
MethodDeclaration out = job.createNewMethodDeclaration();
out.selector = SELF_METHOD_NAME;
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
out.modifiers = ClassFileConstants.AccProtected;
Annotation overrideAnn = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, job.builderType.get());
Annotation sefAnn = job.checkerFramework.generatePure() ? generateNamedAnnotation(job.builderType.get(), CheckerFrameworkVersion.NAME__PURE) : null;
if (sefAnn != null)
out.annotations = new Annotation[] { overrideAnn, sefAnn };
else
out.annotations = new Annotation[] { overrideAnn };
out.returnType = namePlusTypeParamsToTypeReference(job.builderType, job.typeParams, job.getPos());
addCheckerFrameworkReturnsReceiver(out.returnType, job.parentType.get(), job.checkerFramework);
out.statements = new Statement[] { new ReturnStatement(new ThisReference(0, 0), 0, 0) };
return out;
}
use of org.eclipse.jdt.internal.compiler.ast.ThisReference in project lombok by rzwitserloot.
the class HandleEqualsAndHashCode method createHashCode.
public MethodDeclaration createHashCode(EclipseNode type, Collection<Included<EclipseNode, EqualsAndHashCode.Include>> members, boolean callSuper, boolean cacheHashCode, ASTNode source, FieldAccess fieldAccess) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
MethodDeclaration method = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
setGeneratedBy(method, source);
method.modifiers = toEclipseModifier(AccessLevel.PUBLIC);
method.returnType = TypeReference.baseTypeReference(TypeIds.T_int, 0);
setGeneratedBy(method.returnType, source);
Annotation overrideAnnotation = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source);
CheckerFrameworkVersion checkerFramework = getCheckerFrameworkVersion(type);
if (cacheHashCode && checkerFramework.generatePure()) {
method.annotations = new Annotation[] { overrideAnnotation, generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__PURE) };
} else if (checkerFramework.generateSideEffectFree()) {
method.annotations = new Annotation[] { overrideAnnotation, generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE) };
} else {
method.annotations = new Annotation[] { overrideAnnotation };
}
method.selector = "hashCode".toCharArray();
method.thrownExceptions = null;
method.typeParameters = null;
method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart;
method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd;
method.arguments = null;
List<Statement> statements = new ArrayList<Statement>();
boolean isEmpty = true;
for (Included<EclipseNode, EqualsAndHashCode.Include> member : members) {
TypeReference fType = getFieldType(member.getNode(), fieldAccess);
if (fType.getLastToken() != null) {
isEmpty = false;
break;
}
}
/* if (this.$hashCodeCache != 0) return this.$hashCodeCache; */
{
if (cacheHashCode) {
FieldReference hashCodeCacheRef = new FieldReference(HASH_CODE_CACHE_NAME_ARR, p);
hashCodeCacheRef.receiver = new ThisReference(pS, pE);
setGeneratedBy(hashCodeCacheRef, source);
setGeneratedBy(hashCodeCacheRef.receiver, source);
EqualExpression cacheNotZero = new EqualExpression(hashCodeCacheRef, makeIntLiteral("0".toCharArray(), source), OperatorIds.NOT_EQUAL);
setGeneratedBy(cacheNotZero, source);
ReturnStatement returnCache = new ReturnStatement(hashCodeCacheRef, pS, pE);
setGeneratedBy(returnCache, source);
IfStatement ifStatement = new IfStatement(cacheNotZero, returnCache, pS, pE);
setGeneratedBy(ifStatement, source);
statements.add(ifStatement);
}
}
/* final int PRIME = X; */
{
/* Without members, PRIME isn't used, as that would trigger a 'local variable not used' warning. */
if (!isEmpty) {
LocalDeclaration primeDecl = new LocalDeclaration(PRIME, pS, pE);
setGeneratedBy(primeDecl, source);
primeDecl.modifiers |= Modifier.FINAL;
primeDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0);
primeDecl.type.sourceStart = pS;
primeDecl.type.sourceEnd = pE;
setGeneratedBy(primeDecl.type, source);
primeDecl.initialization = makeIntLiteral(String.valueOf(HandlerUtil.primeForHashcode()).toCharArray(), source);
statements.add(primeDecl);
}
}
/* int result = ... */
{
LocalDeclaration resultDecl = new LocalDeclaration(RESULT, pS, pE);
setGeneratedBy(resultDecl, source);
final Expression init;
if (callSuper) {
/* ... super.hashCode(); */
MessageSend callToSuper = new MessageSend();
setGeneratedBy(callToSuper, source);
callToSuper.sourceStart = pS;
callToSuper.sourceEnd = pE;
callToSuper.receiver = new SuperReference(pS, pE);
setGeneratedBy(callToSuper.receiver, source);
callToSuper.selector = "hashCode".toCharArray();
init = callToSuper;
} else {
/* ... 1; */
init = makeIntLiteral("1".toCharArray(), source);
}
resultDecl.initialization = init;
resultDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0);
resultDecl.type.sourceStart = pS;
resultDecl.type.sourceEnd = pE;
if (isEmpty && !cacheHashCode)
resultDecl.modifiers |= Modifier.FINAL;
setGeneratedBy(resultDecl.type, source);
statements.add(resultDecl);
}
for (Included<EclipseNode, EqualsAndHashCode.Include> member : members) {
EclipseNode memberNode = member.getNode();
boolean isMethod = memberNode.getKind() == Kind.METHOD;
TypeReference fType = getFieldType(memberNode, fieldAccess);
char[] dollarFieldName = ((isMethod ? "$$" : "$") + memberNode.getName()).toCharArray();
char[] token = fType.getLastToken();
Expression fieldAccessor = isMethod ? createMethodAccessor(memberNode, source) : createFieldAccessor(memberNode, fieldAccess, source);
if (fType.dimensions() == 0 && token != null) {
if (Arrays.equals(TypeConstants.BOOLEAN, token)) {
/* booleanField ? X : Y */
IntLiteral intTrue = makeIntLiteral(String.valueOf(HandlerUtil.primeForTrue()).toCharArray(), source);
IntLiteral intFalse = makeIntLiteral(String.valueOf(HandlerUtil.primeForFalse()).toCharArray(), source);
ConditionalExpression intForBool = new ConditionalExpression(fieldAccessor, intTrue, intFalse);
setGeneratedBy(intForBool, source);
statements.add(createResultCalculation(source, intForBool));
} else if (Arrays.equals(TypeConstants.LONG, token)) {
/* (int)(ref >>> 32 ^ ref) */
statements.add(createLocalDeclaration(source, dollarFieldName, TypeReference.baseTypeReference(TypeIds.T_long, 0), fieldAccessor));
SingleNameReference copy1 = new SingleNameReference(dollarFieldName, p);
setGeneratedBy(copy1, source);
SingleNameReference copy2 = new SingleNameReference(dollarFieldName, p);
setGeneratedBy(copy2, source);
statements.add(createResultCalculation(source, longToIntForHashCode(copy1, copy2, source)));
} else if (Arrays.equals(TypeConstants.FLOAT, token)) {
/* Float.floatToIntBits(fieldName) */
MessageSend floatToIntBits = new MessageSend();
floatToIntBits.sourceStart = pS;
floatToIntBits.sourceEnd = pE;
setGeneratedBy(floatToIntBits, source);
floatToIntBits.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_FLOAT);
floatToIntBits.selector = FLOAT_TO_INT_BITS;
floatToIntBits.arguments = new Expression[] { fieldAccessor };
statements.add(createResultCalculation(source, floatToIntBits));
} else if (Arrays.equals(TypeConstants.DOUBLE, token)) {
/* longToIntForHashCode(Double.doubleToLongBits(fieldName)) */
MessageSend doubleToLongBits = new MessageSend();
doubleToLongBits.sourceStart = pS;
doubleToLongBits.sourceEnd = pE;
setGeneratedBy(doubleToLongBits, source);
doubleToLongBits.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_DOUBLE);
doubleToLongBits.selector = DOUBLE_TO_LONG_BITS;
doubleToLongBits.arguments = new Expression[] { fieldAccessor };
statements.add(createLocalDeclaration(source, dollarFieldName, TypeReference.baseTypeReference(TypeIds.T_long, 0), doubleToLongBits));
SingleNameReference copy1 = new SingleNameReference(dollarFieldName, p);
setGeneratedBy(copy1, source);
SingleNameReference copy2 = new SingleNameReference(dollarFieldName, p);
setGeneratedBy(copy2, source);
statements.add(createResultCalculation(source, longToIntForHashCode(copy1, copy2, source)));
} else if (BUILT_IN_TYPES.contains(new String(token))) {
statements.add(createResultCalculation(source, fieldAccessor));
} else /* objects */
{
/* final java.lang.Object $fieldName = this.fieldName; */
/* $fieldName == null ? NULL_PRIME : $fieldName.hashCode() */
statements.add(createLocalDeclaration(source, dollarFieldName, generateQualifiedTypeRef(source, TypeConstants.JAVA_LANG_OBJECT), fieldAccessor));
SingleNameReference copy1 = new SingleNameReference(dollarFieldName, p);
setGeneratedBy(copy1, source);
SingleNameReference copy2 = new SingleNameReference(dollarFieldName, p);
setGeneratedBy(copy2, source);
MessageSend hashCodeCall = new MessageSend();
hashCodeCall.sourceStart = pS;
hashCodeCall.sourceEnd = pE;
setGeneratedBy(hashCodeCall, source);
hashCodeCall.receiver = copy1;
hashCodeCall.selector = HASH_CODE;
NullLiteral nullLiteral = new NullLiteral(pS, pE);
setGeneratedBy(nullLiteral, source);
EqualExpression objIsNull = new EqualExpression(copy2, nullLiteral, OperatorIds.EQUAL_EQUAL);
setGeneratedBy(objIsNull, source);
IntLiteral intMagic = makeIntLiteral(String.valueOf(HandlerUtil.primeForNull()).toCharArray(), source);
ConditionalExpression nullOrHashCode = new ConditionalExpression(objIsNull, intMagic, hashCodeCall);
nullOrHashCode.sourceStart = pS;
nullOrHashCode.sourceEnd = pE;
setGeneratedBy(nullOrHashCode, source);
statements.add(createResultCalculation(source, nullOrHashCode));
}
} else if (fType.dimensions() > 0 && token != null) {
/* Arrays.deepHashCode(array) //just hashCode for simple arrays */
MessageSend arraysHashCodeCall = new MessageSend();
arraysHashCodeCall.sourceStart = pS;
arraysHashCodeCall.sourceEnd = pE;
setGeneratedBy(arraysHashCodeCall, source);
arraysHashCodeCall.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray());
if (fType.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token))) {
arraysHashCodeCall.selector = "deepHashCode".toCharArray();
} else {
arraysHashCodeCall.selector = "hashCode".toCharArray();
}
arraysHashCodeCall.arguments = new Expression[] { fieldAccessor };
statements.add(createResultCalculation(source, arraysHashCodeCall));
}
}
/*
* if (result == 0) result = Integer.MIN_VALUE;
* this.$hashCodeCache = result;
*
*/
{
if (cacheHashCode) {
SingleNameReference resultRef = new SingleNameReference(RESULT, p);
setGeneratedBy(resultRef, source);
EqualExpression resultIsZero = new EqualExpression(resultRef, makeIntLiteral("0".toCharArray(), source), OperatorIds.EQUAL_EQUAL);
setGeneratedBy(resultIsZero, source);
resultRef = new SingleNameReference(RESULT, p);
setGeneratedBy(resultRef, source);
FieldReference integerMinValue = new FieldReference("MIN_VALUE".toCharArray(), p);
integerMinValue.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_INTEGER);
setGeneratedBy(integerMinValue, source);
Assignment newResult = new Assignment(resultRef, integerMinValue, pE);
newResult.sourceStart = pS;
newResult.statementEnd = newResult.sourceEnd = pE;
setGeneratedBy(newResult, source);
IfStatement ifStatement = new IfStatement(resultIsZero, newResult, pS, pE);
setGeneratedBy(ifStatement, source);
statements.add(ifStatement);
FieldReference hashCodeCacheRef = new FieldReference(HASH_CODE_CACHE_NAME_ARR, p);
hashCodeCacheRef.receiver = new ThisReference(pS, pE);
setGeneratedBy(hashCodeCacheRef, source);
setGeneratedBy(hashCodeCacheRef.receiver, source);
resultRef = new SingleNameReference(RESULT, p);
setGeneratedBy(resultRef, source);
Assignment cacheResult = new Assignment(hashCodeCacheRef, resultRef, pE);
cacheResult.sourceStart = pS;
cacheResult.statementEnd = cacheResult.sourceEnd = pE;
setGeneratedBy(cacheResult, source);
statements.add(cacheResult);
}
}
/* return result; */
{
SingleNameReference resultRef = new SingleNameReference(RESULT, p);
setGeneratedBy(resultRef, source);
ReturnStatement returnStatement = new ReturnStatement(resultRef, pS, pE);
setGeneratedBy(returnStatement, source);
statements.add(returnStatement);
}
method.statements = statements.toArray(new Statement[0]);
return method;
}
Aggregations