public IfStatement generateCompareFloatOrDouble(Expression thisRef, Expression otherRef, char[] floatOrDouble, ASTNode source) { int pS = source.sourceStart, pE = source.sourceEnd; /* if (Float.compare(fieldName, other.fieldName) != 0) return false */ MessageSend floatCompare = new MessageSend(); floatCompare.sourceStart = pS; floatCompare.sourceEnd = pE; setGeneratedBy(floatCompare, source); floatCompare.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.LANG, floatOrDouble); floatCompare.selector = "compare".toCharArray(); floatCompare.arguments = new Expression[] {thisRef, otherRef}; IntLiteral int0 = makeIntLiteral("0".toCharArray(), source); EqualExpression ifFloatCompareIsNot0 = new EqualExpression(floatCompare, int0, OperatorIds.NOT_EQUAL); ifFloatCompareIsNot0.sourceStart = pS; ifFloatCompareIsNot0.sourceEnd = pE; setGeneratedBy(ifFloatCompareIsNot0, source); FalseLiteral falseLiteral = new FalseLiteral(pS, pE); setGeneratedBy(falseLiteral, source); ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE); setGeneratedBy(returnFalse, source); IfStatement ifStatement = new IfStatement(ifFloatCompareIsNot0, returnFalse, pS, pE); setGeneratedBy(ifStatement, source); return ifStatement; }
/** Generates 'this.<em>name</em>.size()' as an expression; if nullGuard is true, it's this.name == null ? 0 : this.name.size(). */ protected Expression getSize(EclipseNode builderType, char[] name, boolean nullGuard) { MessageSend invoke = new MessageSend(); ThisReference thisRef = new ThisReference(0, 0); FieldReference thisDotName = new FieldReference(name, 0L); thisDotName.receiver = thisRef; invoke.receiver = thisDotName; invoke.selector = SIZE_TEXT; if (!nullGuard) return invoke; ThisReference cdnThisRef = new ThisReference(0, 0); FieldReference cdnThisDotName = new FieldReference(name, 0L); cdnThisDotName.receiver = cdnThisRef; NullLiteral nullLiteral = new NullLiteral(0, 0); EqualExpression isNull = new EqualExpression(cdnThisDotName, nullLiteral, OperatorIds.EQUAL_EQUAL); IntLiteral zeroLiteral = makeIntLiteral(new char[] {'0'}, null); ConditionalExpression conditional = new ConditionalExpression(isNull, zeroLiteral, invoke); return conditional; }
public char[] returnVarNameIfNullCheck(Statement stat) { if (!(stat instanceof IfStatement)) return null; /* Check that the if's statement is a throw statement, possibly in a block. */ { Statement then = ((IfStatement) stat).thenStatement; if (then instanceof Block) { Statement[] blockStatements = ((Block) then).statements; if (blockStatements == null || blockStatements.length == 0) return null; then = blockStatements[0]; } if (!(then instanceof ThrowStatement)) return null; } /* Check that the if's conditional is like 'x == null'. Return from this method (don't generate a nullcheck) if 'x' is equal to our own variable's name: There's already a nullcheck here. */ { Expression cond = ((IfStatement) stat).condition; if (!(cond instanceof EqualExpression)) return null; EqualExpression bin = (EqualExpression) cond; int operatorId = ((bin.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT); if (operatorId != OperatorIds.EQUAL_EQUAL) return null; if (!(bin.left instanceof SingleNameReference)) return null; if (!(bin.right instanceof NullLiteral)) return null; return ((SingleNameReference) bin.left).token; } }
private void generateClearMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType) { MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult); md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; md.modifiers = ClassFileConstants.AccPublic; FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L); thisDotField.receiver = new ThisReference(0, 0); FieldReference thisDotField2 = new FieldReference(data.getPluralName(), 0L); thisDotField2.receiver = new ThisReference(0, 0); md.selector = HandlerUtil.buildAccessorName("clear", new String(data.getPluralName())).toCharArray(); MessageSend clearMsg = new MessageSend(); clearMsg.receiver = thisDotField2; clearMsg.selector = "clear".toCharArray(); Statement clearStatement = new IfStatement(new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.NOT_EQUAL), clearMsg, 0, 0); md.statements = returnStatement != null ? new Statement[] {clearStatement, returnStatement} : new Statement[] {clearStatement}; md.returnType = returnType; injectMethod(builderType, md); }
public void notCompatibleTypesError(EqualExpression expression, TypeBinding leftType, TypeBinding rightType) { String leftName = new String(leftType.readableName()); String rightName = new String(rightType.readableName()); String leftShortName = new String(leftType.shortReadableName()); String rightShortName = new String(rightType.shortReadableName()); if (leftShortName.equals(rightShortName)){ leftShortName = leftName; rightShortName = rightName; } this.handle( IProblem.IncompatibleTypesInEqualityOperator, new String[] {leftName, rightName }, new String[] {leftShortName, rightShortName }, expression.sourceStart, expression.sourceEnd); }
@Override public void endVisit(EqualExpression x, BlockScope scope) { JBinaryOperator op; switch ((x.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) { case OperatorIds.EQUAL_EQUAL: op = JBinaryOperator.EQ; break; case OperatorIds.NOT_EQUAL: op = JBinaryOperator.NEQ; break; default: throw translateException(x, new InternalCompilerException( "Unexpected operator for EqualExpression")); } pushBinaryOp(x, op); }
/** * Generates a new statement that checks if the given variable is null, and if so, throws a {@code NullPointerException} with the * variable name as message. */ public static Statement generateNullCheck(AbstractVariableDeclaration variable, ASTNode source) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; if (isPrimitive(variable.type)) return null; AllocationExpression exception = new AllocationExpression(); setGeneratedBy(exception, source); exception.type = new QualifiedTypeReference(fromQualifiedName("java.lang.NullPointerException"), new long[]{p, p, p}); setGeneratedBy(exception.type, source); exception.arguments = new Expression[] { new StringLiteral(variable.name, pS, pE, 0)}; setGeneratedBy(exception.arguments[0], source); ThrowStatement throwStatement = new ThrowStatement(exception, pS, pE); setGeneratedBy(throwStatement, source); SingleNameReference varName = new SingleNameReference(variable.name, p); setGeneratedBy(varName, source); NullLiteral nullLiteral = new NullLiteral(pS, pE); setGeneratedBy(nullLiteral, source); EqualExpression equalExpression = new EqualExpression(varName, nullLiteral, OperatorIds.EQUAL_EQUAL); equalExpression.sourceStart = pS; equalExpression.statementEnd = equalExpression.sourceEnd = pE; setGeneratedBy(equalExpression, source); IfStatement ifStatement = new IfStatement(equalExpression, throwStatement, 0, 0); setGeneratedBy(ifStatement, source); return ifStatement; }
private IfStatement generateCompareFloatOrDouble(Expression thisRef, Expression otherRef, char[] floatOrDouble, ASTNode source) { int pS = source.sourceStart, pE = source.sourceEnd; /* if (Float.compare(fieldName, other.fieldName) != 0) return false */ MessageSend floatCompare = new MessageSend(); floatCompare.sourceStart = pS; floatCompare.sourceEnd = pE; setGeneratedBy(floatCompare, source); floatCompare.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.LANG, floatOrDouble); floatCompare.selector = "compare".toCharArray(); floatCompare.arguments = new Expression[] {thisRef, otherRef}; IntLiteral int0 = makeIntLiteral("0".toCharArray(), source); EqualExpression ifFloatCompareIsNot0 = new EqualExpression(floatCompare, int0, OperatorIds.NOT_EQUAL); ifFloatCompareIsNot0.sourceStart = pS; ifFloatCompareIsNot0.sourceEnd = pE; setGeneratedBy(ifFloatCompareIsNot0, source); FalseLiteral falseLiteral = new FalseLiteral(pS, pE); setGeneratedBy(falseLiteral, source); ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE); setGeneratedBy(returnFalse, source); IfStatement ifStatement = new IfStatement(ifFloatCompareIsNot0, returnFalse, pS, pE); setGeneratedBy(ifStatement, source); return ifStatement; }
protected Statement createConstructBuilderVarIfNeeded(SingularData data, EclipseNode builderType) { FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L); thisDotField.receiver = new ThisReference(0, 0); FieldReference thisDotField2 = new FieldReference(data.getPluralName(), 0L); thisDotField2.receiver = new ThisReference(0, 0); Expression cond = new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.EQUAL_EQUAL); MessageSend createBuilderInvoke = new MessageSend(); char[][] tokenizedName = makeGuavaTypeName(getSimpleTargetTypeName(data), false); createBuilderInvoke.receiver = new QualifiedNameReference(tokenizedName, NULL_POSS, 0, 0); createBuilderInvoke.selector = getBuilderMethodName(data); return new IfStatement(cond, new Assignment(thisDotField2, createBuilderInvoke, 0), 0, 0); }
private void generateClearMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType) { MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult); md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; md.modifiers = ClassFileConstants.AccPublic; String pN = new String(data.getPluralName()); char[] keyFieldName = (pN + "$key").toCharArray(); char[] valueFieldName = (pN + "$value").toCharArray(); FieldReference thisDotField = new FieldReference(keyFieldName, 0L); thisDotField.receiver = new ThisReference(0, 0); FieldReference thisDotField2 = new FieldReference(keyFieldName, 0L); thisDotField2.receiver = new ThisReference(0, 0); FieldReference thisDotField3 = new FieldReference(valueFieldName, 0L); thisDotField3.receiver = new ThisReference(0, 0); md.selector = HandlerUtil.buildAccessorName("clear", new String(data.getPluralName())).toCharArray(); MessageSend clearMsg1 = new MessageSend(); clearMsg1.receiver = thisDotField2; clearMsg1.selector = "clear".toCharArray(); MessageSend clearMsg2 = new MessageSend(); clearMsg2.receiver = thisDotField3; clearMsg2.selector = "clear".toCharArray(); Block clearMsgs = new Block(2); clearMsgs.statements = new Statement[] {clearMsg1, clearMsg2}; Statement clearStatement = new IfStatement(new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.NOT_EQUAL), clearMsgs, 0, 0); md.statements = returnStatement != null ? new Statement[] {clearStatement, returnStatement} : new Statement[] {clearStatement}; md.returnType = returnType; injectMethod(builderType, md); }
/** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.EqualExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(EqualExpression equalExpression, BlockScope scope) { if ((equalExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT == OperatorIds.EQUAL_EQUAL) { return dumpEqualityExpression(equalExpression, TerminalTokens.TokenNameEQUAL_EQUAL, scope); } else { return dumpEqualityExpression(equalExpression, TerminalTokens.TokenNameNOT_EQUAL, scope); } }
protected void consumeEqualityExpression(int op) { // EqualityExpression ::= EqualityExpression '==' RelationalExpression // EqualityExpression ::= EqualityExpression '!=' RelationalExpression //optimize the push/pop this.expressionPtr--; this.expressionLengthPtr--; this.expressionStack[this.expressionPtr] = new EqualExpression( this.expressionStack[this.expressionPtr], this.expressionStack[this.expressionPtr + 1], op); }
protected void consumeEqualityExpressionWithName(int op) { // EqualityExpression ::= Name '==' RelationalExpression // EqualityExpression ::= Name '!=' RelationalExpression pushOnExpressionStack(getUnspecifiedReferenceOptimized()); this.expressionPtr--; this.expressionLengthPtr--; this.expressionStack[this.expressionPtr] = new EqualExpression( this.expressionStack[this.expressionPtr + 1], this.expressionStack[this.expressionPtr], op); }
public void uninternedIdentityComparison(EqualExpression expr, TypeBinding lhs, TypeBinding rhs, CompilationUnitDeclaration unit) { char [] lhsName = lhs.sourceName(); char [] rhsName = rhs.sourceName(); if (CharOperation.equals(lhsName, "VoidTypeBinding".toCharArray()) //$NON-NLS-1$ || CharOperation.equals(lhsName, "NullTypeBinding".toCharArray()) //$NON-NLS-1$ || CharOperation.equals(lhsName, "ProblemReferenceBinding".toCharArray())) //$NON-NLS-1$ return; if (CharOperation.equals(rhsName, "VoidTypeBinding".toCharArray()) //$NON-NLS-1$ || CharOperation.equals(rhsName, "NullTypeBinding".toCharArray()) //$NON-NLS-1$ || CharOperation.equals(rhsName, "ProblemReferenceBinding".toCharArray())) //$NON-NLS-1$ return; boolean[] validIdentityComparisonLines = unit.validIdentityComparisonLines; if (validIdentityComparisonLines != null) { int problemStartPosition = expr.left.sourceStart; int[] lineEnds; int lineNumber = problemStartPosition >= 0 ? Util.getLineNumber(problemStartPosition, lineEnds = unit.compilationResult().getLineSeparatorPositions(), 0, lineEnds.length-1) : 0; if (lineNumber <= validIdentityComparisonLines.length && validIdentityComparisonLines[lineNumber - 1]) return; } this.handle( IProblem.UninternedIdentityComparison, new String[] { new String(lhs.readableName()), new String(rhs.readableName()) }, new String[] { new String(lhs.shortReadableName()), new String(rhs.shortReadableName()) }, expr.sourceStart, expr.sourceEnd); }
/** * Generates a new statement that checks if the given variable is null, and if so, throws a specified exception with the * variable name as message. * * @param exName The name of the exception to throw; normally {@code java.lang.NullPointerException}. */ public static Statement generateNullCheck(AbstractVariableDeclaration variable, EclipseNode sourceNode) { NullCheckExceptionType exceptionType = sourceNode.getAst().readConfiguration(ConfigurationKeys.NON_NULL_EXCEPTION_TYPE); if (exceptionType == null) exceptionType = NullCheckExceptionType.NULL_POINTER_EXCEPTION; ASTNode source = sourceNode.get(); int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; if (isPrimitive(variable.type)) return null; AllocationExpression exception = new AllocationExpression(); setGeneratedBy(exception, source); int partCount = 1; String exceptionTypeStr = exceptionType.getExceptionType(); for (int i = 0; i < exceptionTypeStr.length(); i++) if (exceptionTypeStr.charAt(i) == '.') partCount++; long[] ps = new long[partCount]; Arrays.fill(ps, 0L); exception.type = new QualifiedTypeReference(fromQualifiedName(exceptionTypeStr), ps); setGeneratedBy(exception.type, source); exception.arguments = new Expression[] { new StringLiteral(exceptionType.toExceptionMessage(new String(variable.name)).toCharArray(), pS, pE, 0) }; setGeneratedBy(exception.arguments[0], source); ThrowStatement throwStatement = new ThrowStatement(exception, pS, pE); setGeneratedBy(throwStatement, source); SingleNameReference varName = new SingleNameReference(variable.name, p); setGeneratedBy(varName, source); NullLiteral nullLiteral = new NullLiteral(pS, pE); setGeneratedBy(nullLiteral, source); EqualExpression equalExpression = new EqualExpression(varName, nullLiteral, OperatorIds.EQUAL_EQUAL); equalExpression.sourceStart = pS; equalExpression.statementEnd = equalExpression.sourceEnd = pE; setGeneratedBy(equalExpression, source); Block throwBlock = new Block(0); throwBlock.statements = new Statement[] {throwStatement}; throwBlock.sourceStart = pS; throwBlock.sourceEnd = pE; setGeneratedBy(throwBlock, source); IfStatement ifStatement = new IfStatement(equalExpression, throwBlock, 0, 0); setGeneratedBy(ifStatement, source); return ifStatement; }
public MethodDeclaration createWither(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, EclipseNode sourceNode, List<Annotation> onMethod, List<Annotation> onParam, boolean makeAbstract ) { ASTNode source = sourceNode.get(); if (name == null) return null; FieldDeclaration field = (FieldDeclaration) fieldNode.get(); int pS = source.sourceStart, pE = source.sourceEnd; long p = (long) pS << 32 | pE; MethodDeclaration method = new MethodDeclaration(parent.compilationResult); if (makeAbstract) modifier = modifier | ClassFileConstants.AccAbstract | ExtraCompilerModifiers.AccSemicolonBody; method.modifiers = modifier; method.returnType = cloneSelfType(fieldNode, source); if (method.returnType == null) return null; Annotation[] deprecated = null; if (isFieldDeprecated(fieldNode)) { deprecated = new Annotation[] { generateDeprecatedAnnotation(source) }; } method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated); Argument param = new Argument(field.name, p, copyType(field.type, source), ClassFileConstants.AccFinal); param.sourceStart = pS; param.sourceEnd = pE; method.arguments = new Argument[] { param }; method.selector = name.toCharArray(); method.binding = null; method.thrownExceptions = null; method.typeParameters = null; method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); if (!makeAbstract) { List<Expression> args = new ArrayList<Expression>(); for (EclipseNode child : fieldNode.up().down()) { if (child.getKind() != Kind.FIELD) continue; FieldDeclaration childDecl = (FieldDeclaration) child.get(); // Skip fields that start with $ if (childDecl.name != null && childDecl.name.length > 0 && childDecl.name[0] == '$') continue; long fieldFlags = childDecl.modifiers; // Skip static fields. if ((fieldFlags & ClassFileConstants.AccStatic) != 0) continue; // Skip initialized final fields. if (((fieldFlags & ClassFileConstants.AccFinal) != 0) && childDecl.initialization != null) continue; if (child.get() == fieldNode.get()) { args.add(new SingleNameReference(field.name, p)); } else { args.add(createFieldAccessor(child, FieldAccess.ALWAYS_FIELD, source)); } } AllocationExpression constructorCall = new AllocationExpression(); constructorCall.arguments = args.toArray(new Expression[0]); constructorCall.type = cloneSelfType(fieldNode, source); Expression identityCheck = new EqualExpression( createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source), new SingleNameReference(field.name, p), OperatorIds.EQUAL_EQUAL); ThisReference thisRef = new ThisReference(pS, pE); Expression conditional = new ConditionalExpression(identityCheck, thisRef, constructorCall); Statement returnStatement = new ReturnStatement(conditional, pS, pE); method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; List<Statement> statements = new ArrayList<Statement>(5); if (nonNulls.length > 0) { Statement nullCheck = generateNullCheck(field, sourceNode); if (nullCheck != null) statements.add(nullCheck); } statements.add(returnStatement); method.statements = statements.toArray(new Statement[0]); } param.annotations = copyAnnotations(source, nonNulls, nullables, onParam.toArray(new Annotation[0])); method.traverse(new SetGeneratedByVisitor(source), parent.scope); return method; }
@Override public boolean visit(EqualExpression node, BlockScope scope) { fixPositions(setGeneratedBy(node, source)); return super.visit(node, scope); }
public MethodDeclaration createWither(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, EclipseNode sourceNode, List<Annotation> onMethod, List<Annotation> onParam) { ASTNode source = sourceNode.get(); if (name == null) return null; FieldDeclaration field = (FieldDeclaration) fieldNode.get(); int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; MethodDeclaration method = new MethodDeclaration(parent.compilationResult); method.modifiers = modifier; method.returnType = cloneSelfType(fieldNode, source); if (method.returnType == null) return null; Annotation[] deprecated = null; if (isFieldDeprecated(fieldNode)) { deprecated = new Annotation[] { generateDeprecatedAnnotation(source) }; } method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated); Argument param = new Argument(field.name, p, copyType(field.type, source), Modifier.FINAL); param.sourceStart = pS; param.sourceEnd = pE; method.arguments = new Argument[] { param }; method.selector = name.toCharArray(); method.binding = null; method.thrownExceptions = null; method.typeParameters = null; method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; List<Expression> args = new ArrayList<Expression>(); for (EclipseNode child : fieldNode.up().down()) { if (child.getKind() != Kind.FIELD) continue; FieldDeclaration childDecl = (FieldDeclaration) child.get(); // Skip fields that start with $ if (childDecl.name != null && childDecl.name.length > 0 && childDecl.name[0] == '$') continue; long fieldFlags = childDecl.modifiers; // Skip static fields. if ((fieldFlags & ClassFileConstants.AccStatic) != 0) continue; // Skip initialized final fields. if (((fieldFlags & ClassFileConstants.AccFinal) != 0) && childDecl.initialization != null) continue; if (child.get() == fieldNode.get()) { args.add(new SingleNameReference(field.name, p)); } else { args.add(createFieldAccessor(child, FieldAccess.ALWAYS_FIELD, source)); } } AllocationExpression constructorCall = new AllocationExpression(); constructorCall.arguments = args.toArray(new Expression[0]); constructorCall.type = cloneSelfType(fieldNode, source); Expression identityCheck = new EqualExpression( createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source), new SingleNameReference(field.name, p), OperatorIds.EQUAL_EQUAL); ThisReference thisRef = new ThisReference(pS, pE); Expression conditional = new ConditionalExpression(identityCheck, thisRef, constructorCall); Statement returnStatement = new ReturnStatement(conditional, pS, pE); method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); List<Statement> statements = new ArrayList<Statement>(5); if (nonNulls.length > 0) { Statement nullCheck = generateNullCheck(field, sourceNode); if (nullCheck != null) statements.add(nullCheck); } statements.add(returnStatement); method.statements = statements.toArray(new Statement[0]); param.annotations = copyAnnotations(source, nonNulls, nullables, onParam.toArray(new Annotation[0])); method.traverse(new SetGeneratedByVisitor(source), parent.scope); return method; }
public boolean visit(EqualExpression equalExpression, BlockScope scope) { addRealFragment(equalExpression); return false; }
private MethodDeclaration createWither(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, ASTNode source, List<Annotation> onMethod, List<Annotation> onParam) { if (name == null) return null; FieldDeclaration field = (FieldDeclaration) fieldNode.get(); int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; MethodDeclaration method = new MethodDeclaration(parent.compilationResult); method.modifiers = modifier; method.returnType = cloneSelfType(fieldNode, source); if (method.returnType == null) return null; Annotation[] deprecated = null; if (isFieldDeprecated(fieldNode)) { deprecated = new Annotation[] { generateDeprecatedAnnotation(source) }; } Annotation[] copiedAnnotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated); if (copiedAnnotations.length != 0) { method.annotations = copiedAnnotations; } Argument param = new Argument(field.name, p, copyType(field.type, source), Modifier.FINAL); param.sourceStart = pS; param.sourceEnd = pE; method.arguments = new Argument[] { param }; method.selector = name.toCharArray(); method.binding = null; method.thrownExceptions = null; method.typeParameters = null; method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; List<Expression> args = new ArrayList<Expression>(); for (EclipseNode child : fieldNode.up().down()) { if (child.getKind() != Kind.FIELD) continue; FieldDeclaration childDecl = (FieldDeclaration) child.get(); // Skip fields that start with $ if (childDecl.name != null && childDecl.name.length > 0 && childDecl.name[0] == '$') continue; long fieldFlags = childDecl.modifiers; // Skip static fields. if ((fieldFlags & ClassFileConstants.AccStatic) != 0) continue; // Skip initialized final fields. if (((fieldFlags & ClassFileConstants.AccFinal) != 0) && childDecl.initialization != null) continue; if (child.get() == fieldNode.get()) { args.add(new SingleNameReference(field.name, p)); } else { args.add(createFieldAccessor(child, FieldAccess.ALWAYS_FIELD, source)); } } AllocationExpression constructorCall = new AllocationExpression(); constructorCall.arguments = args.toArray(new Expression[0]); constructorCall.type = cloneSelfType(fieldNode, source); Expression identityCheck = new EqualExpression( createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source), new SingleNameReference(field.name, p), OperatorIds.EQUAL_EQUAL); ThisReference thisRef = new ThisReference(pS, pE); Expression conditional = new ConditionalExpression(identityCheck, thisRef, constructorCall); Statement returnStatement = new ReturnStatement(conditional, pS, pE); method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; Annotation[] nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN); List<Statement> statements = new ArrayList<Statement>(5); if (nonNulls.length > 0) { Statement nullCheck = generateNullCheck(field, source); if (nullCheck != null) statements.add(nullCheck); } statements.add(returnStatement); method.statements = statements.toArray(new Statement[0]); Annotation[] copiedAnnotationsParam = copyAnnotations(source, nonNulls, nullables, onParam.toArray(new Annotation[0])); if (copiedAnnotationsParam.length != 0) param.annotations = copiedAnnotationsParam; method.traverse(new SetGeneratedByVisitor(source), parent.scope); return method; }
@Override public boolean visit(EqualExpression node, BlockScope scope) { setGeneratedBy(node, source); applyOffsetExpression(node); return super.visit(node, scope); }