22
33import com .axellience .vuegwt .client .Vue ;
44import com .axellience .vuegwt .client .component .VueComponent ;
5+ import com .axellience .vuegwt .client .component .options .CustomizeOptions ;
56import com .axellience .vuegwt .client .component .options .VueComponentOptions ;
67import com .axellience .vuegwt .client .directive .options .VueDirectiveOptions ;
78import com .axellience .vuegwt .client .jsnative .jstypes .JsObject ;
1011import com .axellience .vuegwt .client .vue .VueJsConstructor ;
1112import com .axellience .vuegwt .jsr69 .GenerationNameUtil ;
1213import com .axellience .vuegwt .jsr69 .component .annotations .Component ;
13- import com .axellience .vuegwt .jsr69 .component .annotations .VueCustomizeOptions ;
1414import com .squareup .javapoet .ClassName ;
1515import com .squareup .javapoet .CodeBlock ;
1616import com .squareup .javapoet .MethodSpec ;
1717import com .squareup .javapoet .ParameterizedTypeName ;
18- import com .squareup .javapoet .TypeName ;
1918import com .squareup .javapoet .TypeSpec .Builder ;
2019
2120import javax .annotation .processing .ProcessingEnvironment ;
2221import javax .inject .Inject ;
23- import javax .lang .model .element .ExecutableElement ;
2422import javax .lang .model .element .Modifier ;
2523import javax .lang .model .element .TypeElement ;
26- import javax .lang .model .element .VariableElement ;
2724import javax .lang .model .type .DeclaredType ;
2825import javax .lang .model .type .MirroredTypesException ;
2926import javax .lang .model .type .TypeMirror ;
30- import javax .lang .model .util .ElementFilter ;
3127import javax .lang .model .util .Elements ;
3228import javax .lang .model .util .Types ;
33- import javax .tools .Diagnostic .Kind ;
3429import java .util .LinkedList ;
3530import java .util .List ;
3631import java .util .Optional ;
37- import java .util .stream .Collectors ;
3832import java .util .stream .Stream ;
3933
4034import static com .axellience .vuegwt .client .tools .VueGWTTools .componentToTagName ;
4135import static com .axellience .vuegwt .client .tools .VueGWTTools .directiveToTagName ;
4236import static com .axellience .vuegwt .jsr69 .GenerationNameUtil .*;
43- import static com .axellience .vuegwt .jsr69 .GenerationUtil . hasAnnotation ;
37+ import static com .axellience .vuegwt .jsr69 .component . ComponentGenerationUtil . getComponentCustomizeOptions ;
4438import static com .axellience .vuegwt .jsr69 .component .ComponentGenerationUtil .getComponentLocalComponents ;
4539import static com .axellience .vuegwt .jsr69 .component .ComponentGenerationUtil .getSuperComponentType ;
46- import static com .axellience .vuegwt .jsr69 .component .ComponentGenerationUtil .resolveVariableTypeName ;
4740
4841/**
4942 * Generate {@link VueFactory} from the user {@link VueComponent} classes annotated by {@link
@@ -79,11 +72,12 @@ protected List<CodeBlock> createInitMethod(TypeElement component,
7972 VueComponentOptions .class ,
8073 component .asType (),
8174 componentJsTypeName (component ));
75+ processCustomizeOptions (component , initBuilder , initParametersCall );
8276
8377 // Extend the parent Component
8478 Optional <ClassName > superFactoryType =
8579 getSuperComponentType (component ).map (GenerationNameUtil ::componentFactoryName );
86-
80+
8781 if (superFactoryType .isPresent ())
8882 {
8983 initBuilder .addParameter (superFactoryType .get (), "superFactory" );
@@ -103,7 +97,6 @@ protected List<CodeBlock> createInitMethod(TypeElement component,
10397 registerProvider (component , initBuilder , initParametersCall );
10498 registerLocalComponents (component , initBuilder , initParametersCall );
10599 registerLocalDirectives (componentAnnotation , initBuilder );
106- processCustomizeOptionsMethods (component , initBuilder , initParametersCall );
107100
108101 MethodSpec initMethod = initBuilder .build ();
109102 vueFactoryClassBuilder .addMethod (initMethod );
@@ -221,123 +214,44 @@ private void addGetDirectivesStatement(MethodSpec.Builder injectDependenciesBuil
221214 }
222215
223216 /**
224- * Process all the methods annotated with {@link VueCustomizeOptions}. These methods should be
225- * called when the {@link VueFactory} is created. If they have more parameters than the {@link
226- * VueComponentOptions} those parameters should be injected.
217+ * Process all the {@link CustomizeOptions} from the {@link Component} annotation.
227218 * @param component The {@link VueComponent} we generate for
228219 * @param initBuilder The builder for our {@link VueFactory} init method
229220 * @param staticInitParameters The list of static parameters to pass when calling the init
230221 * method from a static context
231222 */
232- private void processCustomizeOptionsMethods (TypeElement component ,
233- MethodSpec . Builder initBuilder , List <CodeBlock > staticInitParameters )
223+ private void processCustomizeOptions (TypeElement component , MethodSpec . Builder initBuilder ,
224+ List <CodeBlock > staticInitParameters )
234225 {
235- List <ExecutableElement > customizeOptionsMethods = ElementFilter
236- .methodsIn (component .getEnclosedElements ())
237- .stream ()
238- .filter (method -> hasAnnotation (method , VueCustomizeOptions .class ))
239- .peek (this ::validateCustomizeOptionsMethod )
240- .collect (Collectors .toList ());
241-
242- customizeOptionsMethods .forEach (customizeOptionsMethod -> this .processCustomizeOptionsMethod (
243- customizeOptionsMethod ,
226+ getComponentCustomizeOptions (elements ,
227+ component ).forEach (customizeOptions -> this .processCustomizeOptions (customizeOptions ,
244228 initBuilder ,
245- component ,
246229 staticInitParameters ));
247230 }
248231
249232 /**
250- * Process a specific method annotated with {@link VueCustomizeOptions}. This method should be
251- * called when the {@link VueFactory} is created. If it has more parameters than the {@link
252- * VueComponentOptions} those parameters should be injected .
253- * @param customizeOptionsMethod The method we are generating for
233+ * Process the {@link CustomizeOptions} from the {@link Component} annotation. An instance
234+ * of this class should be created with our factory and used to customize our
235+ * {@link VueComponentOptions} before passing them to Vue .
236+ * @param customizeOptions The {@link CustomizeOptions} we are generating for
254237 * @param initBuilder The builder for our {@link VueFactory} init method
255- * @param component The {@link VueComponent} we generate for
256238 * @param staticInitParameters The list of static parameters to pass when calling the init
257239 * method from a static context
258240 */
259- private void processCustomizeOptionsMethod (ExecutableElement customizeOptionsMethod ,
260- MethodSpec .Builder initBuilder , TypeElement component , List <CodeBlock > staticInitParameters )
261- {
262- // Check if has at least one parameter to inject
263- String methodName = customizeOptionsMethod .getSimpleName ().toString ();
264-
265- List <String > parameters = new LinkedList <>();
266- parameters .add ("jsConstructor.getOptions()" );
267-
268- if (customizeOptionsMethod .getParameters ().size () > 1 )
269- {
270- for (int i = 1 ; i < customizeOptionsMethod .getParameters ().size (); i ++)
271- {
272- VariableElement parameter = customizeOptionsMethod .getParameters ().get (i );
273-
274- String parameterName = methodName + "_" + parameter .getSimpleName ().toString ();
275- parameters .add (parameterName );
276- initBuilder .addParameter (resolveVariableTypeName (parameter , messager ),
277- parameterName );
278- staticInitParameters .add (CodeBlock .of ("null" ));
279- }
280- }
281-
282- initBuilder .addStatement ("$T.$L($L)" ,
283- component .asType (),
284- methodName ,
285- String .join (", " , parameters ));
286- }
287-
288- /**
289- * Validate that the {@link VueCustomizeOptions} method is declared correctly.
290- * @param customizeOptionsMethod The method to validate
291- */
292- private void validateCustomizeOptionsMethod (ExecutableElement customizeOptionsMethod )
293- {
294- // Check that the method is static
295- if (!customizeOptionsMethod .getModifiers ().contains (Modifier .STATIC ))
296- {
297- printCustomizeOptionsError ("The method should be static." , customizeOptionsMethod );
298- return ;
299- }
300-
301- // Check that the method is not private
302- if (customizeOptionsMethod .getModifiers ().contains (Modifier .PRIVATE ))
303- {
304- printCustomizeOptionsError (
305- "The method cannot be private, please make it at least package-protected." ,
306- customizeOptionsMethod );
307- return ;
308- }
309-
310- // Check we have at least one parameter
311- if (customizeOptionsMethod .getParameters ().isEmpty ())
312- {
313- printCustomizeOptionsError (
314- "The method should have at least one parameter of type VueComponentOptions." ,
315- customizeOptionsMethod );
316- return ;
317- }
318-
319- // Check first parameter type
320- VariableElement parameter = customizeOptionsMethod .getParameters ().get (0 );
321- TypeName parameterType = TypeName .get (parameter .asType ());
322- if (parameterType instanceof ParameterizedTypeName )
323- parameterType = ((ParameterizedTypeName ) parameterType ).rawType ;
324-
325- if (!parameterType .equals (ClassName .get (VueComponentOptions .class )))
326- {
327- printCustomizeOptionsError ("The method first parameter of type VueComponentOptions." ,
328- customizeOptionsMethod );
329- }
330- }
331-
332- private void printCustomizeOptionsError (String message ,
333- ExecutableElement customizeOptionsMethod )
241+ private void processCustomizeOptions (TypeMirror customizeOptions ,
242+ MethodSpec .Builder initBuilder , List <CodeBlock > staticInitParameters )
334243 {
335- messager .printMessage (Kind .ERROR ,
336- "On method "
337- + customizeOptionsMethod .getSimpleName ()
338- + " annotated with @VueCustomizeOptions in component "
339- + customizeOptionsMethod .getEnclosingElement ().getSimpleName ()
340- + ": "
341- + message );
244+ ClassName customizeOptionsClassName = ((ClassName ) ClassName .get (customizeOptions ));
245+ char c [] = customizeOptionsClassName .simpleName ().toCharArray ();
246+ c [0 ] = Character .toLowerCase (c [0 ]);
247+ String parameterName = new String (c );
248+
249+ initBuilder .addParameter (customizeOptionsClassName , parameterName );
250+ staticInitParameters .add (CodeBlock .of ("new $T()" , customizeOptionsClassName ));
251+
252+ initBuilder .addStatement ("$L.$L($L)" ,
253+ parameterName ,
254+ "customizeOptions" ,
255+ "componentOptions" );
342256 }
343257}
0 commit comments