private void createSingleFieldSetterMethod(FieldNode fieldNode) { MethodBuilder.createPublicMethod(fieldNode.getName()) .param(fieldNode.getType(), "value") .assignToProperty(fieldNode.getName(), varX("value")) .addTo(annotatedClass); if (fieldNode.getType().equals(ClassHelper.boolean_TYPE)) { MethodBuilder.createPublicMethod(fieldNode.getName()) .callThis(fieldNode.getName(), constX(true)) .addTo(annotatedClass); } }
private void createMapOfSimpleElementsMethods( FieldNode fieldNode, ClassNode keyType, ClassNode valueType) { String methodName = fieldNode.getName(); MethodBuilder.createPublicMethod(methodName) .param(fieldNode.getType(), "values") .callMethod(propX(varX("this"), fieldNode.getName()), "putAll", varX("values")) .addTo(annotatedClass); String singleElementMethod = getElementNameForCollectionField(fieldNode); MethodBuilder.createPublicMethod(singleElementMethod) .param(keyType, "key") .param(valueType, "value") .callMethod(propX(varX("this"), fieldNode.getName()), "put", args("key", "value")) .addTo(annotatedClass); }
private void createListOfSimpleElementsMethods(FieldNode fieldNode, ClassNode elementType) { MethodBuilder.createPublicMethod(fieldNode.getName()) .arrayParam(elementType, "values") .statement(callX(propX(varX("this"), fieldNode.getName()), "addAll", varX("values"))) .addTo(annotatedClass); MethodBuilder.createPublicMethod(fieldNode.getName()) .param(fieldNode.getType(), "values") .statement(callX(propX(varX("this"), fieldNode.getName()), "addAll", varX("values"))) .addTo(annotatedClass); MethodBuilder.createPublicMethod(getElementNameForCollectionField(fieldNode)) .param(elementType, "value") .statement(callX(propX(varX("this"), fieldNode.getName()), "add", varX("value"))) .addTo(annotatedClass); }
private void createValidateMethod() { Validation.Mode mode = getEnumMemberValue( getAnnotation(annotatedClass, VALIDATION_ANNOTATION), "mode", Validation.Mode.class, Validation.Mode.AUTOMATIC); annotatedClass.addField( "$manualValidation", ACC_PRIVATE, ClassHelper.Boolean_TYPE, new ConstantExpression(mode == Validation.Mode.MANUAL)); MethodBuilder.createPublicMethod("manualValidation") .param(Boolean_TYPE, "validation") .assignS(varX("$manualValidation"), varX("validation")) .addTo(annotatedClass); MethodBuilder methodBuilder = MethodBuilder.createPublicMethod(VALIDATE_METHOD); if (ASTHelper.isDSLObject(annotatedClass.getSuperClass())) { methodBuilder.statement(callSuperX(VALIDATE_METHOD)); } BlockStatement block = new BlockStatement(); validateFields(block); validateCustomMethods(block); TryCatchStatement tryCatchStatement = new TryCatchStatement(block, EmptyStatement.INSTANCE); tryCatchStatement.addCatch( new CatchStatement( param(ASSERTION_ERROR_TYPE, "e"), new ThrowStatement( ctorX(VALIDATION_EXCEPTION_TYPE, args(propX(varX("e"), "message"), varX("e")))))); tryCatchStatement.addCatch( new CatchStatement( param(EXCEPTION_TYPE, "e"), new ThrowStatement( ctorX(VALIDATION_EXCEPTION_TYPE, args(propX(varX("e"), "message"), varX("e")))))); methodBuilder.statement(tryCatchStatement).addTo(annotatedClass); }
private void createApplyMethods() { MethodBuilder.createPublicMethod("apply") .returning(newClass(annotatedClass)) .namedParams("values") .delegatingClosureParam(annotatedClass) .applyNamedParams("values") .assignS(propX(varX("closure"), "delegate"), varX("this")) .assignS( propX(varX("closure"), "resolveStrategy"), propX(classX(ClassHelper.CLOSURE_TYPE), "DELEGATE_FIRST")) .callMethod("closure", "call") .doReturn("this") .addTo(annotatedClass); MethodBuilder.createPublicMethod("apply") .returning(newClass(annotatedClass)) .delegatingClosureParam(annotatedClass) .callThis("apply", args(new MapExpression(), varX("closure"))) .doReturn("this") .addTo(annotatedClass); }
private void preventOwnerOverride() { MethodBuilder.createPublicMethod(setterName(ownerField)) .param(OBJECT_TYPE, "value") .statement( ifS( andX( isInstanceOfX(varX("value"), ownerField.getType()), notX(propX(varX("this"), ownerField.getName()))), assignX(propX(varX("this"), ownerField.getName()), varX("value")))) .addTo(annotatedClass); }
private void createFactoryMethods() { if (isAbstract(annotatedClass)) return; MethodBuilder.createPublicMethod("create") .returning(newClass(annotatedClass)) .mod(Opcodes.ACC_STATIC) .namedParams("values") .optionalStringParam("name", keyField) .delegatingClosureParam(annotatedClass) .declareVariable( "result", keyField != null ? ctorX(annotatedClass, args("name")) : ctorX(annotatedClass)) .callMethod("result", "copyFromTemplate") .callMethod("result", "apply", args("values", "closure")) .callValidationOn("result") .doReturn("result") .addTo(annotatedClass); MethodBuilder.createPublicMethod("create") .returning(newClass(annotatedClass)) .mod(Opcodes.ACC_STATIC) .optionalStringParam("name", keyField) .delegatingClosureParam(annotatedClass) .doReturn( callX( annotatedClass, "create", keyField != null ? args(new MapExpression(), varX("name"), varX("closure")) : args(new MapExpression(), varX("closure")))) .addTo(annotatedClass); MethodBuilder.createPublicMethod("createFromScript") .returning(newClass(annotatedClass)) .deprecated() .mod(Opcodes.ACC_STATIC) .classParam("configType", ClassHelper.SCRIPT_TYPE) .doReturn(callX(callX(varX("configType"), "newInstance"), "run")) .addTo(annotatedClass); if (keyField != null) { MethodBuilder.createPublicMethod("createFrom") .returning(newClass(annotatedClass)) .mod(Opcodes.ACC_STATIC) .stringParam("name") .stringParam("text") .declareVariable( "simpleName", callX( callX( callX(callX(varX("name"), "tokenize", args(constX("."))), "first"), "tokenize", args(constX("/"))), "last")) .declareVariable("result", callX(annotatedClass, "create", args("simpleName"))) .declareVariable( "loader", ctorX( ClassHelper.make(GroovyClassLoader.class), args( callX( callX(ClassHelper.make(Thread.class), "currentThread"), "getContextClassLoader")))) .declareVariable("config", ctorX(ClassHelper.make(CompilerConfiguration.class))) .assignS( propX(varX("config"), "scriptBaseClass"), constX(DelegatingScript.class.getName())) .declareVariable("binding", ctorX(ClassHelper.make(Binding.class))) .declareVariable( "shell", ctorX(ClassHelper.make(GroovyShell.class), args("loader", "binding", "config"))) .declareVariable("script", callX(varX("shell"), "parse", args("text"))) .callMethod("script", "setDelegate", args("result")) .callMethod("script", "run") .doReturn("result") .addTo(annotatedClass); MethodBuilder.createPublicMethod("createFromSnippet") .deprecated() .returning(newClass(annotatedClass)) .mod(Opcodes.ACC_STATIC) .stringParam("name") .stringParam("text") .doReturn(callX(annotatedClass, "createFrom", args("name", "text"))) .addTo(annotatedClass); } else { MethodBuilder.createPublicMethod("createFrom") .returning(newClass(annotatedClass)) .mod(Opcodes.ACC_STATIC) .stringParam("text") .declareVariable("result", callX(annotatedClass, "create")) .declareVariable( "loader", ctorX( ClassHelper.make(GroovyClassLoader.class), args( callX( callX(ClassHelper.make(Thread.class), "currentThread"), "getContextClassLoader")))) .declareVariable("config", ctorX(ClassHelper.make(CompilerConfiguration.class))) .assignS( propX(varX("config"), "scriptBaseClass"), constX(DelegatingScript.class.getName())) .declareVariable("binding", ctorX(ClassHelper.make(Binding.class))) .declareVariable( "shell", ctorX(ClassHelper.make(GroovyShell.class), args("loader", "binding", "config"))) .declareVariable("script", callX(varX("shell"), "parse", args("text"))) .callMethod("script", "setDelegate", args("result")) .callMethod("script", "run") .doReturn("result") .addTo(annotatedClass); MethodBuilder.createPublicMethod("createFromSnippet") .deprecated() .returning(newClass(annotatedClass)) .mod(Opcodes.ACC_STATIC) .stringParam("text") .doReturn(callX(annotatedClass, "createFrom", args("text"))) .addTo(annotatedClass); } MethodBuilder.createPublicMethod("createFrom") .returning(newClass(annotatedClass)) .mod(Opcodes.ACC_STATIC) .param(make(File.class), "src") .doReturn( callX( annotatedClass, "createFromSnippet", args(callX(callX(varX("src"), "toURI"), "toURL")))) .addTo(annotatedClass); MethodBuilder.createPublicMethod("createFromSnippet") .deprecated() .returning(newClass(annotatedClass)) .mod(Opcodes.ACC_STATIC) .param(make(File.class), "src") .doReturn(callX(annotatedClass, "createFrom", args("src"))) .addTo(annotatedClass); MethodBuilder.createPublicMethod("createFrom") .returning(newClass(annotatedClass)) .mod(Opcodes.ACC_STATIC) .param(make(URL.class), "src") .declareVariable("text", propX(varX("src"), "text")) .doReturn( callX( annotatedClass, "createFromSnippet", keyField != null ? args(propX(varX("src"), "path"), varX("text")) : args("text"))) .addTo(annotatedClass); MethodBuilder.createPublicMethod("createFromSnippet") .deprecated() .returning(newClass(annotatedClass)) .mod(Opcodes.ACC_STATIC) .param(make(URL.class), "src") .doReturn(callX(annotatedClass, "createFrom", args("src"))) .addTo(annotatedClass); }
private void createSingleDSLObjectClosureMethod(FieldNode fieldNode) { String methodName = fieldNode.getName(); ClassNode targetFieldType = fieldNode.getType(); FieldNode targetTypeKeyField = getKeyField(targetFieldType); String targetOwnerFieldName = getOwnerFieldName(targetFieldType); if (!ASTHelper.isAbstract(targetFieldType)) { MethodBuilder.createPublicMethod(methodName) .returning(targetFieldType) .namedParams("values") .optionalStringParam("key", targetTypeKeyField) .delegatingClosureParam(targetFieldType) .declareVariable( "created", callX(classX(targetFieldType), "newInstance", optionalKeyArg(targetTypeKeyField))) .callMethod("created", "copyFromTemplate") .optionalAssignThisToPropertyS("created", targetOwnerFieldName, targetOwnerFieldName) .assignToProperty( fieldNode.getName(), callX(varX("created"), "apply", args("values", "closure"))) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); MethodBuilder.createPublicMethod(methodName) .returning(targetFieldType) .optionalStringParam("key", targetTypeKeyField) .delegatingClosureParam(targetFieldType) .declareVariable( "created", callX(classX(targetFieldType), "newInstance", optionalKeyArg(targetTypeKeyField))) .callMethod("created", "copyFromTemplate") .optionalAssignThisToPropertyS("created", targetOwnerFieldName, targetOwnerFieldName) .assignToProperty(fieldNode.getName(), callX(varX("created"), "apply", varX("closure"))) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); } if (!isFinal(targetFieldType)) { MethodBuilder.createPublicMethod(methodName) .returning(targetFieldType) .namedParams("values") .classParam("typeToCreate", targetFieldType) .optionalStringParam("key", targetTypeKeyField) .delegatingClosureParam(targetFieldType) .declareVariable( "created", callX(varX("typeToCreate"), "newInstance", optionalKeyArg(targetTypeKeyField))) .callMethod("created", "copyFromTemplate") .optionalAssignThisToPropertyS("created", targetOwnerFieldName, targetOwnerFieldName) .assignToProperty( fieldNode.getName(), callX(varX("created"), "apply", args("values", "closure"))) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); MethodBuilder.createPublicMethod(methodName) .returning(targetFieldType) .classParam("typeToCreate", targetFieldType) .optionalStringParam("key", targetTypeKeyField) .delegatingClosureParam(targetFieldType) .declareVariable( "created", callX(varX("typeToCreate"), "newInstance", optionalKeyArg(targetTypeKeyField))) .callMethod("created", "copyFromTemplate") .optionalAssignThisToPropertyS("created", targetOwnerFieldName, targetOwnerFieldName) .assignToProperty(fieldNode.getName(), callX(varX("created"), "apply", varX("closure"))) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); } }
private void createMapOfDSLObjectMethods( FieldNode fieldNode, ClassNode keyType, ClassNode elementType) { if (getKeyField(elementType) == null) { addCompileError( String.format( "Value type of map %s (%s) has no key field", fieldNode.getName(), elementType.getName()), fieldNode); return; } MethodBuilder.createPublicMethod(fieldNode.getName()) .closureParam("closure") .assignS(propX(varX("closure"), "delegate"), varX("this")) .assignS( propX(varX("closure"), "resolveStrategy"), propX(classX(ClassHelper.CLOSURE_TYPE), "DELEGATE_FIRST")) .callMethod("closure", "call") .addTo(annotatedClass); String methodName = getElementNameForCollectionField(fieldNode); String targetOwner = getOwnerFieldName(elementType); if (!ASTHelper.isAbstract(elementType)) { MethodBuilder.createPublicMethod(methodName) .returning(elementType) .namedParams("values") .param(keyType, "key") .delegatingClosureParam(elementType) .declareVariable("created", callX(classX(elementType), "newInstance", args("key"))) .callMethod("created", "copyFromTemplate") .optionalAssignThisToPropertyS("created", targetOwner, targetOwner) .callMethod(fieldNode.getName(), "put", args(varX("key"), varX("created"))) .callMethod("created", "apply", args("values", "closure")) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); MethodBuilder.createPublicMethod(methodName) .returning(elementType) .param(keyType, "key") .delegatingClosureParam(elementType) .declareVariable("created", callX(classX(elementType), "newInstance", args("key"))) .callMethod("created", "copyFromTemplate") .optionalAssignThisToPropertyS("created", targetOwner, targetOwner) .callMethod(fieldNode.getName(), "put", args(varX("key"), varX("created"))) .callMethod("created", "apply", varX("closure")) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); } if (!isFinal(elementType)) { MethodBuilder.createPublicMethod(methodName) .returning(elementType) .namedParams("values") .classParam("typeToCreate", elementType) .param(keyType, "key") .delegatingClosureParam(elementType) .declareVariable("created", callX(varX("typeToCreate"), "newInstance", args("key"))) .callMethod("created", "copyFromTemplate") .callMethod(fieldNode.getName(), "put", args(varX("key"), varX("created"))) .optionalAssignThisToPropertyS("created", targetOwner, targetOwner) .callMethod("created", "apply", args("values", "closure")) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); MethodBuilder.createPublicMethod(methodName) .returning(elementType) .classParam("typeToCreate", elementType) .param(keyType, "key") .delegatingClosureParam(elementType) .declareVariable("created", callX(varX("typeToCreate"), "newInstance", args("key"))) .callMethod("created", "copyFromTemplate") .callMethod(fieldNode.getName(), "put", args(varX("key"), varX("created"))) .optionalAssignThisToPropertyS("created", targetOwner, targetOwner) .callMethod("created", "apply", varX("closure")) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); } //noinspection ConstantConditions MethodBuilder.createPublicMethod(methodName) .param(elementType, "value") .callMethod( fieldNode.getName(), "put", args(propX(varX("value"), getKeyField(elementType).getName()), varX("value"))) .optionalAssignThisToPropertyS("value", targetOwner, targetOwner) .addTo(annotatedClass); }
private void createListOfDSLObjectMethods(FieldNode fieldNode, ClassNode elementType) { String methodName = getElementNameForCollectionField(fieldNode); FieldNode fieldKey = getKeyField(elementType); String targetOwner = getOwnerFieldName(elementType); MethodBuilder.createPublicMethod(fieldNode.getName()) .closureParam("closure") .assignS(propX(varX("closure"), "delegate"), varX("this")) .assignS( propX(varX("closure"), "resolveStrategy"), propX(classX(ClassHelper.CLOSURE_TYPE), "DELEGATE_FIRST")) .callMethod("closure", "call") .addTo(annotatedClass); if (!ASTHelper.isAbstract(elementType)) { MethodBuilder.createPublicMethod(methodName) .returning(elementType) .namedParams("values") .optionalStringParam("key", fieldKey) .delegatingClosureParam(elementType) .declareVariable( "created", callX(classX(elementType), "newInstance", optionalKeyArg(fieldKey))) .callMethod("created", "copyFromTemplate") .optionalAssignThisToPropertyS("created", targetOwner, targetOwner) .callMethod( fieldNode.getName(), "add", callX(varX("created"), "apply", args("values", "closure"))) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); MethodBuilder.createPublicMethod(methodName) .returning(elementType) .optionalStringParam("key", fieldKey) .delegatingClosureParam(elementType) .declareVariable( "created", callX(classX(elementType), "newInstance", optionalKeyArg(fieldKey))) .callMethod("created", "copyFromTemplate") .optionalAssignThisToPropertyS("created", targetOwner, targetOwner) .callMethod(fieldNode.getName(), "add", callX(varX("created"), "apply", varX("closure"))) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); } if (!isFinal(elementType)) { MethodBuilder.createPublicMethod(methodName) .returning(elementType) .namedParams("values") .classParam("typeToCreate", elementType) .optionalStringParam("key", fieldKey) .delegatingClosureParam(elementType) .declareVariable( "created", callX(varX("typeToCreate"), "newInstance", optionalKeyArg(fieldKey))) .callMethod("created", "copyFromTemplate") .optionalAssignThisToPropertyS("created", targetOwner, targetOwner) .callMethod( fieldNode.getName(), "add", callX(varX("created"), "apply", args("values", "closure"))) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); MethodBuilder.createPublicMethod(methodName) .returning(elementType) .classParam("typeToCreate", elementType) .optionalStringParam("key", fieldKey) .delegatingClosureParam(elementType) .declareVariable( "created", callX(varX("typeToCreate"), "newInstance", optionalKeyArg(fieldKey))) .callMethod("created", "copyFromTemplate") .optionalAssignThisToPropertyS("created", targetOwner, targetOwner) .callMethod(fieldNode.getName(), "add", callX(varX("created"), "apply", varX("closure"))) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); } MethodBuilder.createPublicMethod(methodName) .param(elementType, "value") .callMethod(fieldNode.getName(), "add", varX("value")) .optionalAssignThisToPropertyS("value", targetOwner, targetOwner) .addTo(annotatedClass); }