/** * Add a method that is marked as @Generated. * * @see ClassNode#addMethod(MethodNode) */ public static void addGeneratedMethod(ClassNode cNode, MethodNode mNode) { cNode.addMethod(mNode); markAsGenerated(cNode, mNode); }
/** * Helper method to add a new method to a ClassNode. Depending on the shouldBeSynthetic flag the * call will either be made to ClassNode.addSyntheticMethod() or ClassNode.addMethod(). If a non-synthetic method * is to be added the ACC_SYNTHETIC modifier is removed if it has been accidentally supplied. */ protected MethodNode addMethod(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) { if (shouldBeSynthetic) { return node.addSyntheticMethod(name, modifiers, returnType, parameters, exceptions, code); } else { return node.addMethod(name, modifiers & ~ACC_SYNTHETIC, returnType, parameters, exceptions, code); } }
/** * Adds a synthetic method as part of the compilation process */ public MethodNode addSyntheticMethod(String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) { MethodNode answer = addMethod(name, modifiers|ACC_SYNTHETIC, returnType, parameters, exceptions, code); answer.setSynthetic(true); return answer; }
private MethodNode getOrAddStaticConstructorNode() { MethodNode method = null; List declaredMethods = getDeclaredMethods("<clinit>"); if (declaredMethods.isEmpty()) { method = addMethod("<clinit>", ACC_STATIC, ClassHelper.VOID_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement()); method.setSynthetic(true); } else { method = (MethodNode) declaredMethods.get(0); } return method; }
private void buildCommon(ClassNode buildee, AnnotationNode anno, List<FieldNode> fieldNodes, ClassNode builder) { String prefix = getMemberStringValue(anno, "prefix", ""); String buildMethodName = getMemberStringValue(anno, "buildMethodName", "create"); createBuilderConstructors(builder, buildee, fieldNodes); buildee.getModule().addClass(builder); String builderMethodName = getMemberStringValue(anno, "builderMethodName", "createInitializer"); buildee.addMethod(createBuilderMethod(buildMethodName, builder, fieldNodes.size(), builderMethodName)); for (int i = 0; i < fieldNodes.size(); i++) { builder.addMethod(createBuilderMethodForField(builder, fieldNodes, prefix, i)); } builder.addMethod(createBuildMethod(builder, buildMethodName, fieldNodes)); }
private void addDummyConstructor(ClassNode node) { // constructors should not be treated as errors (they have no real meaning for interfaces anyway) node.addMethod(new MethodNode("<clinit>", ACC_PUBLIC | ACC_STATIC, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)); }
private static void createBuilderFactoryMethod(AnnotationNode anno, ClassNode buildee, ClassNode builder) { buildee.getModule().addClass(builder); buildee.addMethod(createBuilderMethod(anno, builder)); }
public void testDetectsCorrectMethodModifiersInClass() throws Exception { // can't check volatile here as it doubles up with bridge ClassNode node = new ClassNode("zzz", ACC_PUBLIC, ClassHelper.OBJECT_TYPE); node.addMethod(new MethodNode("st", ACC_STRICT, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)); node.addMethod(new MethodNode("na", ACC_NATIVE, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)); node.addMethod(new MethodNode("sy", ACC_SYNCHRONIZED, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)); addDummyConstructor(node); verifier.visitClass(node); checkErrorCount(0); }
private void transplantMethod(Method method) { FeatureMethod feature = (FeatureMethod) method; MethodNode oldAst = feature.getAst(); MethodNode newAst = copyMethod(oldAst, createInternalName(feature)); spec.getAst().addMethod(newAst); feature.setAst(newAst); AstUtil.deleteMethod(spec.getAst(), oldAst); }
private static void renameMethod(ClassNode buildee, MethodNode mNode, String newName) { buildee.addMethod(newName, mNode.getModifiers(), mNode.getReturnType(), mNode.getParameters(), mNode.getExceptions(), mNode.getCode()); buildee.removeMethod(mNode); }
private void checkDetectsDuplicateMethods(int modifiers, String expectedErrorMessage, Parameter[] params) { ClassNode node = new ClassNode("zzz", modifiers, ClassHelper.OBJECT_TYPE); node.addMethod(new MethodNode("xxx", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, params, ClassNode.EMPTY_ARRAY, null)); node.addMethod(new MethodNode("xxx", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, params, ClassNode.EMPTY_ARRAY, null)); verifier.visitClass(node); checkErrorCount(2); checkErrorMessage(expectedErrorMessage); }
@SuppressWarnings("unchecked") private void createDataProcessorMethod() { if (dataProcessorVars.isEmpty()) return; dataProcessorStats.add( new ReturnStatement( new ArrayExpression( ClassHelper.OBJECT_TYPE, (List) dataProcessorVars))); BlockStatement blockStat = new BlockStatement(dataProcessorStats, new VariableScope()); new DataProcessorVariableRewriter().visitBlockStatement(blockStat); whereBlock.getParent().getParent().getAst().addMethod( new MethodNode( InternalIdentifiers.getDataProcessorName(whereBlock.getParent().getAst().getName()), Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE, dataProcessorParams.toArray(new Parameter[dataProcessorParams.size()]), ClassNode.EMPTY_ARRAY, blockStat)); }
private static void createBuildeeMethods(ClassNode buildee, MethodNode mNode, ClassNode builder, List<FieldNode> fields) { ClassNode paramType = makeClassSafeWithGenerics(builder, setGenTypes(fields.size())); List<Expression> argsList = new ArrayList<Expression>(); Parameter initParam = param(paramType, "initializer"); for (FieldNode fieldNode : fields) { argsList.add(propX(varX(initParam), fieldNode.getName())); } String newName = "$" + mNode.getName(); // can't have private and public methods of the same name, so rename original buildee.addMethod(mNode.getName(), PUBLIC_STATIC, mNode.getReturnType(), params(param(paramType, "initializer")), NO_EXCEPTIONS, block(stmt(callX(buildee, newName, args(argsList))))); renameMethod(buildee, mNode, newName); }
public void testDetectsIncorrectMethodModifiersInInterface() throws Exception { // can't check volatile here as it doubles up with bridge ClassNode node = new ClassNode("zzz", ACC_ABSTRACT | ACC_INTERFACE, ClassHelper.OBJECT_TYPE); node.addMethod(new MethodNode("st", ACC_STRICT, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)); node.addMethod(new MethodNode("na", ACC_NATIVE, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)); node.addMethod(new MethodNode("sy", ACC_SYNCHRONIZED, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)); addDummyConstructor(node); verifier.visitClass(node); checkErrorCount(3); checkErrorMessage(EXPECTED_STRICT_METHOD_ERROR_MESSAGE); checkErrorMessage(EXPECTED_NATIVE_METHOD_ERROR_MESSAGE); checkErrorMessage(EXPECTED_SYNCHRONIZED_METHOD_ERROR_MESSAGE); }
private FixtureMethod getSharedInitializerMethod() { if (spec.getSharedInitializerMethod() == null) { // method is private s.t. multiple initializer methods along hierarchy can be called independently MethodNode gMethod = new MethodNode(InternalIdentifiers.SHARED_INITIALIZER_METHOD, Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC, ClassHelper.DYNAMIC_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement()); spec.getAst().addMethod(gMethod); FixtureMethod method = new FixtureMethod(spec, gMethod); method.addBlock(new AnonymousBlock(method)); spec.setSharedInitializerMethod(method); } return spec.getSharedInitializerMethod(); }
public void testDetectsFinalAndStaticMethodsInInterface() throws Exception { ClassNode node = new ClassNode("zzz", ACC_ABSTRACT | ACC_INTERFACE, ClassHelper.OBJECT_TYPE); node.addMethod(new MethodNode("xxx", ACC_PUBLIC | ACC_FINAL, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)); node.addMethod(new MethodNode("yyy", ACC_PUBLIC | ACC_STATIC, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)); addDummyConstructor(node); verifier.visitClass(node); checkErrorCount(2); checkErrorMessage(EXPECTED_INTERFACE_FINAL_METHOD_ERROR_MESSAGE); checkErrorMessage(EXPECTED_INTERFACE_STATIC_METHOD_ERROR_MESSAGE); }
public void buildMethod(BuilderASTTransformation transform, MethodNode mNode, AnnotationNode anno) { if (transform.getMemberValue(anno, "includes") != null || transform.getMemberValue(anno, "excludes") != null) { transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME + " processing: includes/excludes only allowed on classes", anno); } ClassNode buildee = mNode.getDeclaringClass(); ClassNode builder = createBuilder(anno, buildee); createBuilderFactoryMethod(anno, buildee, builder); for (Parameter parameter : mNode.getParameters()) { builder.addField(createFieldCopy(buildee, parameter)); builder.addMethod(createBuilderMethodForProp(builder, new PropertyInfo(parameter.getName(), parameter.getType()), getPrefix(anno))); } builder.addMethod(createBuildMethodForMethod(anno, buildee, mNode, mNode.getParameters())); }
private FixtureMethod getInitializerMethod() { if (spec.getInitializerMethod() == null) { // method is private s.t. multiple initializer methods along hierarchy can be called independently MethodNode gMethod = new MethodNode(InternalIdentifiers.INITIALIZER_METHOD, Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC, ClassHelper.DYNAMIC_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement()); spec.getAst().addMethod(gMethod); FixtureMethod method = new FixtureMethod(spec, gMethod); method.addBlock(new AnonymousBlock(method)); spec.setInitializerMethod(method); } return spec.getInitializerMethod(); }
public void testDetectsIncorrectMemberVisibilityInInterface() throws Exception { ClassNode node = new ClassNode("zzz", ACC_ABSTRACT | ACC_INTERFACE, ClassHelper.OBJECT_TYPE); node.addMethod(new MethodNode("prim", ACC_PRIVATE, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)); node.addMethod(new MethodNode("prom", ACC_PROTECTED, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null)); node.addField("prif", ACC_PRIVATE, ClassHelper.OBJECT_TYPE, null); node.addField("prof", ACC_PROTECTED, ClassHelper.OBJECT_TYPE, null); addDummyConstructor(node); verifier.visitClass(node); checkErrorCount(4); checkErrorMessage(EXPECTED_PROTECTED_FIELD_ERROR_MESSAGE); checkErrorMessage(EXPECTED_PRIVATE_FIELD_ERROR_MESSAGE); checkErrorMessage(EXPECTED_PROTECTED_METHOD_ERROR_MESSAGE); checkErrorMessage(EXPECTED_PRIVATE_METHOD_ERROR_MESSAGE); }
private void createDataProviderMethod(Expression dataProviderExpr, int nextDataVariableIndex) { instanceFieldAccessChecker.check(dataProviderExpr); dataProviderExpr = dataProviderExpr.transformExpression(new DataTablePreviousVariableTransformer()); MethodNode method = new MethodNode( InternalIdentifiers.getDataProviderName(whereBlock.getParent().getAst().getName(), dataProviderCount++), Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE, getPreviousParameters(nextDataVariableIndex), ClassNode.EMPTY_ARRAY, new BlockStatement( Arrays.<Statement>asList( new ReturnStatement( new ExpressionStatement(dataProviderExpr))), new VariableScope())); method.addAnnotation(createDataProviderAnnotation(dataProviderExpr, nextDataVariableIndex)); whereBlock.getParent().getParent().getAst().addMethod(method); }