private static NameReference createNameRef(TypeBinding typeBinding, ASTNode source) { long p = ((long) source.sourceStart << 32) | source.sourceEnd; char[] pkg = typeBinding.qualifiedPackageName(); char[] basename = typeBinding.qualifiedSourceName(); StringBuilder sb = new StringBuilder(); if (pkg != null) sb.append(pkg); if (sb.length() > 0) sb.append("."); sb.append(basename); String tName = sb.toString(); if (tName.indexOf('.') == -1) { return new SingleNameReference(basename, p); } else { char[][] sources; String[] in = tName.split("\\."); sources = new char[in.length][]; for (int i = 0; i < in.length; i++) sources[i] = in[i].toCharArray(); long[] poss = new long[in.length]; Arrays.fill(poss, p); return new QualifiedNameReference(sources, poss, source.sourceStart, source.sourceEnd); } }
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; } }
public MemberValuePair convert(org.eclipse.jdt.internal.compiler.ast.MemberValuePair memberValuePair) { final MemberValuePair pair = new MemberValuePair(this.ast); final SimpleName simpleName = new SimpleName(this.ast); simpleName.internalSetIdentifier(new String(memberValuePair.name)); int start = memberValuePair.sourceStart; int end = memberValuePair.sourceEnd; simpleName.setSourceRange(start, end - start + 1); pair.setName(simpleName); final Expression value = convert(memberValuePair.value); pair.setValue(value); start = memberValuePair.sourceStart; end = value.getStartPosition() + value.getLength() - 1; pair.setSourceRange(start, end - start + 1); if (memberValuePair.value instanceof SingleNameReference && ((SingleNameReference)memberValuePair.value).token == RecoveryScanner.FAKE_IDENTIFIER) { pair.setFlags(pair.getFlags() | ASTNode.RECOVERED); } if (this.resolveBindings) { recordNodes(simpleName, memberValuePair); recordNodes(pair, memberValuePair); } return pair; }
public void unqualifiedFieldAccess(NameReference reference, FieldBinding field) { int sourceStart = reference.sourceStart; int sourceEnd = reference.sourceEnd; if (reference instanceof SingleNameReference) { int numberOfParens = (reference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens != 0) { sourceStart = retrieveStartingPositionAfterOpeningParenthesis(sourceStart, sourceEnd, numberOfParens); sourceEnd = retrieveEndingPositionAfterOpeningParenthesis(sourceStart, sourceEnd, numberOfParens); } else { sourceStart = nodeSourceStart(field, reference); sourceEnd = nodeSourceEnd(field, reference); } } else { sourceStart = nodeSourceStart(field, reference); sourceEnd = nodeSourceEnd(field, reference); } this.handle( IProblem.UnqualifiedFieldAccess, new String[] {new String(field.declaringClass.readableName()), new String(field.name)}, new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)}, sourceStart, sourceEnd); }
public void nullityMismatch(Expression expression, TypeBinding providedType, TypeBinding requiredType, int nullStatus, char[][] annotationName) { if ((nullStatus & FlowInfo.NULL) != 0) { nullityMismatchIsNull(expression, requiredType, annotationName); return; } if ((nullStatus & FlowInfo.POTENTIALLY_NULL) != 0) { if (expression instanceof SingleNameReference) { SingleNameReference snr = (SingleNameReference) expression; if (snr.binding instanceof LocalVariableBinding) { if (((LocalVariableBinding)snr.binding).isNullable()) { nullityMismatchSpecdNullable(expression, requiredType, annotationName); return; } } } nullityMismatchPotentiallyNull(expression, requiredType, annotationName); return; } nullityMismatchIsUnknown(expression, providedType, requiredType, annotationName); }
@Override public void endVisit(SingleNameReference x, BlockScope scope) { try { JExpression result = resolveNameReference(x, scope); if (result == null) { push(null); return; } if (x.genericCast != null) { JType castType = typeMap.get(x.genericCast); result = maybeCast(castType, result); } push(result); } catch (Throwable e) { throw translateException(x, e); } }
/** * 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; }
/** * Returns the actual value of the given Literal or Literal-like node. */ public static Object calculateValue(Expression e) { if (e instanceof Literal) { ((Literal)e).computeConstant(); switch (e.constant.typeID()) { case TypeIds.T_int: return e.constant.intValue(); case TypeIds.T_byte: return e.constant.byteValue(); case TypeIds.T_short: return e.constant.shortValue(); case TypeIds.T_char: return e.constant.charValue(); case TypeIds.T_float: return e.constant.floatValue(); case TypeIds.T_double: return e.constant.doubleValue(); case TypeIds.T_boolean: return e.constant.booleanValue(); case TypeIds.T_long: return e.constant.longValue(); case TypeIds.T_JavaLangString: return e.constant.stringValue(); default: return null; } } else if (e instanceof ClassLiteralAccess) { return Eclipse.toQualifiedName(((ClassLiteralAccess)e).type.getTypeName()); } else if (e instanceof SingleNameReference) { return new String(((SingleNameReference)e).token); } else if (e instanceof QualifiedNameReference) { String qName = Eclipse.toQualifiedName(((QualifiedNameReference)e).tokens); int idx = qName.lastIndexOf('.'); return idx == -1 ? qName : qName.substring(idx+1); } return null; }
static Expression createFieldAccessor(EclipseNode field, FieldAccess fieldAccess, ASTNode source) { int pS = source == null ? 0 : source.sourceStart, pE = source == null ? 0 : source.sourceEnd; long p = (long)pS << 32 | pE; boolean lookForGetter = lookForGetter(field, fieldAccess); GetterMethod getter = lookForGetter ? findGetter(field) : null; if (getter == null) { FieldDeclaration fieldDecl = (FieldDeclaration)field.get(); FieldReference ref = new FieldReference(fieldDecl.name, p); if ((fieldDecl.modifiers & ClassFileConstants.AccStatic) != 0) { EclipseNode containerNode = field.up(); if (containerNode != null && containerNode.get() instanceof TypeDeclaration) { ref.receiver = new SingleNameReference(((TypeDeclaration)containerNode.get()).name, p); } else { Expression smallRef = new FieldReference(field.getName().toCharArray(), p); if (source != null) setGeneratedBy(smallRef, source); return smallRef; } } else { ref.receiver = new ThisReference(pS, pE); } if (source != null) { setGeneratedBy(ref, source); setGeneratedBy(ref.receiver, source); } return ref; } MessageSend call = new MessageSend(); setGeneratedBy(call, source); call.sourceStart = pS; call.statementEnd = call.sourceEnd = pE; call.receiver = new ThisReference(pS, pE); setGeneratedBy(call.receiver, source); call.selector = getter.name; return call; }
private void doAssignmentCheck0(EclipseNode node, Statement statement, char[] varName) { if (statement instanceof Assignment) doAssignmentCheck0(node, ((Assignment)statement).expression, varName); else if (statement instanceof LocalDeclaration) doAssignmentCheck0(node, ((LocalDeclaration)statement).initialization, varName); else if (statement instanceof CastExpression) doAssignmentCheck0(node, ((CastExpression)statement).expression, varName); else if (statement instanceof SingleNameReference) { if (Arrays.equals(((SingleNameReference)statement).token, varName)) { EclipseNode problemNode = node.getNodeFor(statement); if (problemNode != null) problemNode.addWarning( "You're assigning an auto-cleanup variable to something else. This is a bad idea."); } } }
void generateSingularMethod(TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) { LombokImmutableList<String> suffixes = getArgumentSuffixes(); char[][] names = new char[suffixes.size()][]; for (int i = 0; i < suffixes.size(); i++) { String s = suffixes.get(i); char[] n = data.getSingularName(); names[i] = s.isEmpty() ? n : s.toCharArray(); } 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)); FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L); thisDotField.receiver = new ThisReference(0, 0); MessageSend thisDotFieldDotAdd = new MessageSend(); thisDotFieldDotAdd.arguments = new Expression[suffixes.size()]; for (int i = 0; i < suffixes.size(); i++) { thisDotFieldDotAdd.arguments[i] = new SingleNameReference(names[i], 0L); } thisDotFieldDotAdd.receiver = thisDotField; thisDotFieldDotAdd.selector = getAddMethodName().toCharArray(); statements.add(thisDotFieldDotAdd); if (returnStatement != null) statements.add(returnStatement); md.statements = statements.toArray(new Statement[statements.size()]); md.arguments = new Argument[suffixes.size()]; for (int i = 0; i < suffixes.size(); i++) { TypeReference tr = cloneParamType(i, data.getTypeArgs(), builderType); md.arguments[i] = new Argument(names[i], 0, tr, 0); } md.returnType = returnType; md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName(getAddMethodName(), new String(data.getSingularName())).toCharArray(); data.setGeneratedByRecursive(md); injectMethod(builderType, md); }
void generateSingularMethod(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, false)); FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L); thisDotField.receiver = new ThisReference(0, 0); MessageSend thisDotFieldDotAdd = new MessageSend(); thisDotFieldDotAdd.arguments = new Expression[] {new SingleNameReference(data.getSingularName(), 0L)}; thisDotFieldDotAdd.receiver = thisDotField; thisDotFieldDotAdd.selector = "add".toCharArray(); statements.add(thisDotFieldDotAdd); if (returnStatement != null) statements.add(returnStatement); md.statements = statements.toArray(new Statement[statements.size()]); TypeReference paramType = cloneParamType(0, data.getTypeArgs(), builderType); Argument param = new Argument(data.getSingularName(), 0, paramType, 0); md.arguments = new Argument[] {param}; md.returnType = returnType; md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray(); data.setGeneratedByRecursive(md); injectMethod(builderType, md); }
void generatePluralMethod(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, false)); FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L); thisDotField.receiver = new ThisReference(0, 0); MessageSend thisDotFieldDotAddAll = new MessageSend(); thisDotFieldDotAddAll.arguments = new Expression[] {new SingleNameReference(data.getPluralName(), 0L)}; thisDotFieldDotAddAll.receiver = thisDotField; thisDotFieldDotAddAll.selector = "addAll".toCharArray(); statements.add(thisDotFieldDotAddAll); if (returnStatement != null) statements.add(returnStatement); md.statements = statements.toArray(new Statement[statements.size()]); TypeReference paramType = new QualifiedTypeReference(TypeConstants.JAVA_UTIL_COLLECTION, NULL_POSS); paramType = addTypeArgs(1, true, builderType, paramType, data.getTypeArgs()); Argument param = new Argument(data.getPluralName(), 0, paramType, 0); md.arguments = new Argument[] {param}; md.returnType = returnType; md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray(); data.setGeneratedByRecursive(md); injectMethod(builderType, md); }
/** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SingleNameReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(SingleNameReference singleNameReference, BlockScope scope) { final int numberOfParens = (singleNameReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(singleNameReference, numberOfParens); } this.scribe.printNextToken(SINGLETYPEREFERENCE_EXPECTEDTOKENS); if (numberOfParens > 0) { manageClosingParenthesizedExpression(singleNameReference, numberOfParens); } return false; }
protected SingleNameReference newSingleNameReference(char[] source, long positions) { SingleNameReference ref = this.singleNameReference; ref.token = source; ref.sourceStart = (int) (positions >>> 32); ref.sourceEnd = (int) positions; return ref; }
public Name convert(org.eclipse.jdt.internal.compiler.ast.NameReference reference) { if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) { return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) reference); } else { return convert((org.eclipse.jdt.internal.compiler.ast.SingleNameReference) reference); } }
public SimpleName convert(org.eclipse.jdt.internal.compiler.ast.SingleNameReference nameReference) { final SimpleName name = new SimpleName(this.ast); name.internalSetIdentifier(new String(nameReference.token)); if (this.resolveBindings) { recordNodes(name, nameReference); } name.setSourceRange(nameReference.sourceStart, nameReference.sourceEnd - nameReference.sourceStart + 1); return name; }
static Expression createFieldAccessor(EclipseNode field, FieldAccess fieldAccess, ASTNode source) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; boolean lookForGetter = lookForGetter(field, fieldAccess); GetterMethod getter = lookForGetter ? findGetter(field) : null; if (getter == null) { FieldDeclaration fieldDecl = (FieldDeclaration)field.get(); FieldReference ref = new FieldReference(fieldDecl.name, p); if ((fieldDecl.modifiers & ClassFileConstants.AccStatic) != 0) { EclipseNode containerNode = field.up(); if (containerNode != null && containerNode.get() instanceof TypeDeclaration) { ref.receiver = new SingleNameReference(((TypeDeclaration)containerNode.get()).name, p); } else { Expression smallRef = new FieldReference(field.getName().toCharArray(), p); setGeneratedBy(smallRef, source); return smallRef; } } else { ref.receiver = new ThisReference(pS, pE); } setGeneratedBy(ref, source); setGeneratedBy(ref.receiver, source); return ref; } MessageSend call = new MessageSend(); setGeneratedBy(call, source); call.sourceStart = pS; call.statementEnd = call.sourceEnd = pE; call.receiver = new ThisReference(pS, pE); setGeneratedBy(call.receiver, source); call.selector = getter.name; return call; }
private static MethodDeclaration createGetReferencedKeyMethod(ASTNode source, String relatedFieldName, boolean isOneToOne, TypeReference baseType, TypeReference referenceType, CompilationResult compResult) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; MethodDeclaration getReferencedKey = new MethodDeclaration(compResult); setGeneratedBy(getReferencedKey, source); getReferencedKey.modifiers = ClassFileConstants.AccPublic; getReferencedKey.annotations = new Annotation[] { makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source) }; getReferencedKey.returnType = createTypeReference(Long.class, p); setGeneratedBy(getReferencedKey.returnType, source); getReferencedKey.returnType.sourceStart = pS; getReferencedKey.returnType.sourceEnd = pE; getReferencedKey.arguments = new Argument[] { new Argument("item".toCharArray(), 0, (isOneToOne ? baseType : referenceType), ClassFileConstants.AccFinal) }; setGeneratedBy(getReferencedKey.arguments[0], source); getReferencedKey.arguments[0].sourceStart = pS; getReferencedKey.arguments[0].sourceEnd = pE; getReferencedKey.selector = "getReferencedKey".toCharArray(); getReferencedKey.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; getReferencedKey.bodyStart = getReferencedKey.declarationSourceStart = getReferencedKey.sourceStart = source.sourceStart; getReferencedKey.bodyEnd = getReferencedKey.declarationSourceEnd = getReferencedKey.sourceEnd = source.sourceEnd; MessageSend getRelatedFieldName = new MessageSend(); setGeneratedBy(getRelatedFieldName, source); getRelatedFieldName.sourceStart = pS; getRelatedFieldName.sourceEnd = pE; getRelatedFieldName.receiver = new SingleNameReference("item".toCharArray(), p); setGeneratedBy(getRelatedFieldName.receiver, source); getRelatedFieldName.receiver.sourceStart = pS; getRelatedFieldName.receiver.sourceEnd = pE; getRelatedFieldName.selector = ("get" + toProperCase(relatedFieldName)).toCharArray(); ReturnStatement returnStatement = new ReturnStatement(getRelatedFieldName, pS, pE); setGeneratedBy(returnStatement, source); getReferencedKey.statements = new Statement[] { returnStatement }; return getReferencedKey; }
public MethodDeclaration createStaticConstructor(AccessLevel level, String name, EclipseNode type, Collection<EclipseNode> fields, ASTNode source) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long) pS << 32 | pE; MethodDeclaration constructor = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult); constructor.modifiers = toEclipseModifier(level) | ClassFileConstants.AccStatic; TypeDeclaration typeDecl = (TypeDeclaration) type.get(); constructor.returnType = EclipseHandlerUtil.namePlusTypeParamsToTypeReference(typeDecl.name, typeDecl.typeParameters, p); constructor.annotations = null; constructor.selector = name.toCharArray(); constructor.thrownExceptions = null; constructor.typeParameters = copyTypeParams(((TypeDeclaration) type.get()).typeParameters, source); constructor.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = source.sourceStart; constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = source.sourceEnd; List<Argument> params = new ArrayList<Argument>(); List<Expression> assigns = new ArrayList<Expression>(); AllocationExpression statement = new AllocationExpression(); statement.sourceStart = pS; statement.sourceEnd = pE; statement.type = copyType(constructor.returnType, source); for (EclipseNode fieldNode : fields) { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); long fieldPos = (((long) field.sourceStart) << 32) | field.sourceEnd; SingleNameReference nameRef = new SingleNameReference(field.name, fieldPos); assigns.add(nameRef); Argument parameter = new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL); parameter.annotations = copyAnnotations(source, findAnnotations(field, NON_NULL_PATTERN), findAnnotations(field, NULLABLE_PATTERN)); params.add(parameter); } statement.arguments = assigns.isEmpty() ? null : assigns.toArray(new Expression[assigns.size()]); constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[params.size()]); constructor.statements = new Statement[] { new ReturnStatement(statement, (int) (p >> 32), (int)p) }; constructor.traverse(new SetGeneratedByVisitor(source), typeDecl.scope); return constructor; }
static MethodDeclaration createSetter(TypeDeclaration parent, EclipseNode fieldNode, String name, boolean shouldReturnThis, int modifier, EclipseNode sourceNode, List<Annotation> onMethod, List<Annotation> onParam) { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); ASTNode source = sourceNode.get(); int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; MethodDeclaration method = new MethodDeclaration(parent.compilationResult); method.modifiers = modifier; if (shouldReturnThis) { method.returnType = cloneSelfType(fieldNode, source); } if (method.returnType == null) { method.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0); method.returnType.sourceStart = pS; method.returnType.sourceEnd = pE; shouldReturnThis = false; } 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; Expression fieldRef = createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source); NameReference fieldNameRef = new SingleNameReference(field.name, p); Assignment assignment = new Assignment(fieldRef, fieldNameRef, (int)p); assignment.sourceStart = pS; assignment.sourceEnd = assignment.statementEnd = 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) { statements.add(assignment); } else { Statement nullCheck = generateNullCheck(field, sourceNode); if (nullCheck != null) statements.add(nullCheck); statements.add(assignment); } if (shouldReturnThis) { ThisReference thisRef = new ThisReference(pS, pE); ReturnStatement returnThis = new ReturnStatement(thisRef, pS, pE); statements.add(returnThis); } 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; }
/** * 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; }
private MethodDeclaration generateToBuilderMethod(String methodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, List<BuilderFieldData> builderFields, boolean fluent, ASTNode source) { // return new ThingieBuilder<A, B>().setA(this.a).setB(this.b); int pS = source.sourceStart, pE = source.sourceEnd; long p = (long) pS << 32 | pE; MethodDeclaration out = new MethodDeclaration( ((CompilationUnitDeclaration) type.top().get()).compilationResult); out.selector = methodName.toCharArray(); out.modifiers = ClassFileConstants.AccPublic; out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; out.returnType = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p); AllocationExpression invoke = new AllocationExpression(); invoke.type = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p); Expression receiver = invoke; for (BuilderFieldData bfd : builderFields) { char[] setterName = fluent ? bfd.name : HandlerUtil.buildAccessorName("set", new String(bfd.name)).toCharArray(); MessageSend ms = new MessageSend(); if (bfd.obtainVia == null || !bfd.obtainVia.field().isEmpty()) { char[] fieldName = bfd.obtainVia == null ? bfd.rawName : bfd.obtainVia.field().toCharArray(); FieldReference fr = new FieldReference(fieldName, 0); fr.receiver = new ThisReference(0, 0); ms.arguments = new Expression[] {fr}; } else { String obtainName = bfd.obtainVia.method(); boolean obtainIsStatic = bfd.obtainVia.isStatic(); MessageSend obtainExpr = new MessageSend(); obtainExpr.receiver = obtainIsStatic ? new SingleNameReference(type.getName().toCharArray(), 0) : new ThisReference(0, 0); obtainExpr.selector = obtainName.toCharArray(); if (obtainIsStatic) obtainExpr.arguments = new Expression[] {new ThisReference(0, 0)}; ms.arguments = new Expression[] {obtainExpr}; } ms.receiver = receiver; ms.selector = setterName; receiver = ms; } out.statements = new Statement[] {new ReturnStatement(receiver, pS, pE)}; out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope); return out; }