Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Dynamic pattern/template parameters #1324

Closed
pvojtechovsky opened this issue May 28, 2017 · 2 comments
Closed

Feature request: Dynamic pattern/template parameters #1324

pvojtechovsky opened this issue May 28, 2017 · 2 comments
Labels

Comments

@pvojtechovsky
Copy link
Collaborator

The dynamic template parameters would let us decouple template model and template parameters. It would bring

  • simpler template definition (see Example 1)
  • any part of spoon model might be used as a template model and with appropriate template parameters definition it might be used to generate code (see Example 2)
  • simpler template engine implementation (because template parameters would exist as extra data out of template model, therefore code of substitution engine might be simpler.
  • Template matcher might use template parameters with better parameter matching filters, because template parameter definition would be not limited to annotation parameters, but might contain any java structures, because it would be configured dynamically by java calls at runtime (see Example 3).

Example 1

public class FluentSetterTemplate extends ExtensionTemplate {

	/**
	 * @param propertyName propertyDescription
	 * @return this to support fluent API
	 */
	public FluentSetterTemplate propertyName(ParamType propertyName) {
		request.setPropertyName(propertyName);
		return this;
	}
	
	@Local
	public FluentSetterTemplate(String propertyName, String propertyDescription, CtTypeReference<?> requestType, CtTypeReference<?> paramType) {
		parameter("propertyName").value(lowerCaseFirst(propertyName));
		parameter("PropertyName").value(upperCaseFirst(propertyName));
		parameter("propertyDescription").value(propertyDescription);
		parameter("Request").value(requestType);
		parameter("ParamType").value(paramType);
	}
	
	@Local
	Request request;
	
	@Local
	interface Request {
		void setPropertyName(ParamType prop);
	}
	@Local
	interface ParamType {}
}

Example 2
arbitrary code as a template

//this is example of any class of spoon model, whose method is used as `template model`
public class SomeClass {
...
        Service service;
...
	/**
	 * @param readOnly defines whether document is read only
	 * @return this to support fluent API
	 */
	public SomeClass readOnly (boolean readOnly) {
		service.setReadOnly(readOnly);
		return this;
	}
   ...
}
//this is a template definition, which uses the SomeClass#readOnly method as template model
public class FluentSetterTemplate extends ExtensionTemplate {
	@Local
	public FluentSetterTemplate(String propertyName, String propertyDescription, CtTypeReference<?> requestType, CtTypeReference<?> paramType, CtMethod templateMethod) {
		parameter("readOnly").value(lowerCaseFirst(propertyName));
		parameter("ReadOnlyvalue(upperCaseFirst(propertyName));
		parameter("defines whether document is read only").value(propertyDescription);
		parameter("Service").value(requestType);
		parameter("boolean").value(paramType);
                setTemplateModel(templateMethod);
	}
}

The templates of Example 1 and Example 2 would generate same code.

Example 3
it is same like Example 1, but the extra parameter matching fitler is configured by setFilter - can be helpful to drive template matcher.

public class FluentSetterTemplate extends ExtensionTemplate {

	/**
	 * @param propertyName propertyDescription
	 * @return this to support fluent API
	 */
	public FluentSetterTemplate propertyName(ParamType propertyName) {
		request.setPropertyName(propertyName);
		return this;
	}
	
	@Local
	public FluentSetterTemplate(String propertyName, String propertyDescription, CtTypeReference<?> requestType, CtTypeReference<?> paramType) {
		parameter("propertyName").value(lowerCaseFirst(propertyName));
		parameter("PropertyName").value(upperCaseFirst(propertyName));
		parameter("propertyDescription").value(propertyDescription);
		parameter("Request").value(requestType);
//See the custom parameter matching filter, which is configured dynamically
		parameter("ParamType").value(paramType).setFilter((CtTypeReference tr->{
                     return tr.subTypeOf(factory.createTypeRefarence(AutoClosable.class))
                });
	}
	
	@Local
	Request request;
	
	@Local
	interface Request {
		void setPropertyName(ParamType prop);
	}
	@Local
	interface ParamType {}
}

Notes:

  • the usage of dynamic template parameters would be optional. Legacy TemplateParameter and @Parameter can be still used to define template parameters.
  • The code which creates a template, would always check for TemplateParameter and @Parameter and initialize appropriate dynamic template parameters. Then the template substitution engine, might be simplified, because it will understand only one way for definition of template parameters - dynamic template parameters.

Would you like something like that, or do you see some conceptual/other problem?

@surli surli added the feature label May 29, 2017
@pvojtechovsky
Copy link
Collaborator Author

Will be solved by #1686

@monperrus monperrus changed the title Feature request: Dynamic template parameters Feature request: Dynamic pattern/template parameters Nov 17, 2018
@monperrus
Copy link
Collaborator

FYI:

A Reflexive and Automated Approach to Syntactic Pattern Matching in Code Transformations
https://hal.archives-ouvertes.fr/hal-01851857/document

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants