modifiers,
329 | String initialValue) throws IOException {
330 | indent();
331 | emitModifiers(modifiers);
332 | emitCompressedType(type);
333 | out.write(" ");
334 | out.write(name);
335 |
336 | if (initialValue != null) {
337 | out.write(" =");
338 | if (!initialValue.startsWith("\n")) {
339 | out.write(" ");
340 | }
341 |
342 | String[] lines = initialValue.split("\n", -1);
343 | out.write(lines[0]);
344 | for (int i = 1; i < lines.length; i++) {
345 | out.write("\n");
346 | hangingIndent();
347 | out.write(lines[i]);
348 | }
349 | }
350 | out.write(";\n");
351 | return this;
352 | }
353 |
354 | /**
355 | * Emit a method declaration.
356 | *
357 | * A {@code null} return type may be used to indicate a constructor, but
358 | * {@link #beginConstructor(Set, String...)} should be preferred. This behavior may be removed in
359 | * a future release.
360 | *
361 | * @param returnType the method's return type, or null for constructors
362 | * @param name the method name, or the fully qualified class name for constructors.
363 | * @param modifiers the set of modifiers to be applied to the method
364 | * @param parameters alternating parameter types and names.
365 | */
366 | public JavaWriter beginMethod(String returnType, String name, Set modifiers,
367 | String... parameters) throws IOException {
368 | return beginMethod(returnType, name, modifiers, Arrays.asList(parameters), null);
369 | }
370 |
371 | /**
372 | * Emit a method declaration.
373 | *
374 | * A {@code null} return type may be used to indicate a constructor, but
375 | * {@link #beginConstructor(Set, List, List)} should be preferred. This behavior may be removed in
376 | * a future release.
377 | *
378 | * @param returnType the method's return type, or null for constructors.
379 | * @param name the method name, or the fully qualified class name for constructors.
380 | * @param modifiers the set of modifiers to be applied to the method
381 | * @param parameters alternating parameter types and names.
382 | * @param throwsTypes the classes to throw, or null for no throws clause.
383 | */
384 | public JavaWriter beginMethod(String returnType, String name, Set modifiers,
385 | List parameters, List throwsTypes) throws IOException {
386 | indent();
387 | emitModifiers(modifiers);
388 | if (returnType != null) {
389 | emitCompressedType(returnType);
390 | out.write(" ");
391 | out.write(name);
392 | } else {
393 | emitCompressedType(name);
394 | }
395 | out.write("(");
396 | if (parameters != null) {
397 | for (int p = 0; p < parameters.size();) {
398 | if (p != 0) {
399 | out.write(", ");
400 | }
401 | emitCompressedType(parameters.get(p++));
402 | out.write(" ");
403 | emitCompressedType(parameters.get(p++));
404 | }
405 | }
406 | out.write(")");
407 | if (throwsTypes != null && throwsTypes.size() > 0) {
408 | out.write("\n");
409 | indent();
410 | out.write(" throws ");
411 | for (int i = 0; i < throwsTypes.size(); i++) {
412 | if (i != 0) {
413 | out.write(", ");
414 | }
415 | emitCompressedType(throwsTypes.get(i));
416 | }
417 | }
418 | if (modifiers.contains(ABSTRACT) || Scope.INTERFACE_DECLARATION.equals(scopes.peek())) {
419 | out.write(";\n");
420 | scopes.push(Scope.ABSTRACT_METHOD);
421 | } else {
422 | out.write(" {\n");
423 | scopes.push(returnType == null ? Scope.CONSTRUCTOR : Scope.NON_ABSTRACT_METHOD);
424 | }
425 | return this;
426 | }
427 |
428 | public JavaWriter beginConstructor(Set modifiers, String... parameters)
429 | throws IOException {
430 | beginMethod(null, rawType(types.peekFirst()), modifiers, parameters);
431 | return this;
432 | }
433 |
434 | public JavaWriter beginConstructor(Set modifiers,
435 | List parameters, List throwsTypes)
436 | throws IOException {
437 | beginMethod(null, rawType(types.peekFirst()), modifiers, parameters, throwsTypes);
438 | return this;
439 | }
440 |
441 | /** Emits some Javadoc comments with line separated by {@code \n}. */
442 | public JavaWriter emitJavadoc(String javadoc, Object... params) throws IOException {
443 | String formatted = String.format(javadoc, params);
444 |
445 | indent();
446 | out.write("/**\n");
447 | for (String line : formatted.split("\n")) {
448 | indent();
449 | out.write(" *");
450 | if (!line.isEmpty()) {
451 | out.write(" ");
452 | out.write(line);
453 | }
454 | out.write("\n");
455 | }
456 | indent();
457 | out.write(" */\n");
458 | return this;
459 | }
460 |
461 | /** Emits a single line comment. */
462 | public JavaWriter emitSingleLineComment(String comment, Object... args) throws IOException {
463 | indent();
464 | out.write("// ");
465 | out.write(String.format(comment, args));
466 | out.write("\n");
467 | return this;
468 | }
469 |
470 | public JavaWriter emitEmptyLine() throws IOException {
471 | out.write("\n");
472 | return this;
473 | }
474 |
475 | public JavaWriter emitEnumValue(String name) throws IOException {
476 | indent();
477 | out.write(name);
478 | out.write(",\n");
479 | return this;
480 | }
481 |
482 | /**
483 | * A simple switch to emit the proper enum depending if its last causing it to be terminated
484 | * by a semi-colon ({@code ;}).
485 | */
486 | public JavaWriter emitEnumValue(String name, boolean isLast) throws IOException {
487 | return isLast ? emitLastEnumValue(name) : emitEnumValue(name);
488 | }
489 |
490 | private JavaWriter emitLastEnumValue(String name) throws IOException {
491 | indent();
492 | out.write(name);
493 | out.write(";\n");
494 | return this;
495 | }
496 |
497 | /** Emit a list of enum values followed by a semi-colon ({@code ;}). */
498 | public JavaWriter emitEnumValues(Iterable names) throws IOException {
499 | Iterator iterator = names.iterator();
500 |
501 | while (iterator.hasNext()) {
502 | String name = iterator.next();
503 | if (iterator.hasNext()) {
504 | emitEnumValue(name);
505 | } else {
506 | emitLastEnumValue(name);
507 | }
508 | }
509 |
510 | return this;
511 | }
512 |
513 | /** Equivalent to {@code annotation(annotation, emptyMap())}. */
514 | public JavaWriter emitAnnotation(String annotation) throws IOException {
515 | return emitAnnotation(annotation, Collections.emptyMap());
516 | }
517 |
518 | /** Equivalent to {@code annotation(annotationType.getName(), emptyMap())}. */
519 | public JavaWriter emitAnnotation(Class extends Annotation> annotationType) throws IOException {
520 | return emitAnnotation(type(annotationType), Collections.emptyMap());
521 | }
522 |
523 | /**
524 | * Annotates the next element with {@code annotationType} and a {@code value}.
525 | *
526 | * @param value an object used as the default (value) parameter of the annotation. The value will
527 | * be encoded using Object.toString(); use {@link #stringLiteral} for String values. Object
528 | * arrays are written one element per line.
529 | */
530 | public JavaWriter emitAnnotation(Class extends Annotation> annotationType, Object value)
531 | throws IOException {
532 | return emitAnnotation(type(annotationType), value);
533 | }
534 |
535 | /**
536 | * Annotates the next element with {@code annotation} and a {@code value}.
537 | *
538 | * @param value an object used as the default (value) parameter of the annotation. The value will
539 | * be encoded using Object.toString(); use {@link #stringLiteral} for String values. Object
540 | * arrays are written one element per line.
541 | */
542 | public JavaWriter emitAnnotation(String annotation, Object value) throws IOException {
543 | indent();
544 | out.write("@");
545 | emitCompressedType(annotation);
546 | out.write("(");
547 | emitAnnotationValue(value);
548 | out.write(")");
549 | out.write("\n");
550 | return this;
551 | }
552 |
553 | /** Equivalent to {@code annotation(annotationType.getName(), attributes)}. */
554 | public JavaWriter emitAnnotation(Class extends Annotation> annotationType,
555 | Map attributes) throws IOException {
556 | return emitAnnotation(type(annotationType), attributes);
557 | }
558 |
559 | /**
560 | * Annotates the next element with {@code annotation} and {@code attributes}.
561 | *
562 | * @param attributes a map from annotation attribute names to their values. Values are encoded
563 | * using Object.toString(); use {@link #stringLiteral} for String values. Object arrays are
564 | * written one element per line.
565 | */
566 | public JavaWriter emitAnnotation(String annotation, Map attributes)
567 | throws IOException {
568 | indent();
569 | out.write("@");
570 | emitCompressedType(annotation);
571 | switch (attributes.size()) {
572 | case 0:
573 | break;
574 | case 1:
575 | Entry onlyEntry = attributes.entrySet().iterator().next();
576 | out.write("(");
577 | if (!"value".equals(onlyEntry.getKey())) {
578 | out.write(onlyEntry.getKey());
579 | out.write(" = ");
580 | }
581 | emitAnnotationValue(onlyEntry.getValue());
582 | out.write(")");
583 | break;
584 | default:
585 | boolean split = attributes.size() > MAX_SINGLE_LINE_ATTRIBUTES
586 | || containsArray(attributes.values());
587 | out.write("(");
588 | scopes.push(Scope.ANNOTATION_ATTRIBUTE);
589 | String separator = split ? "\n" : "";
590 | for (Map.Entry entry : attributes.entrySet()) {
591 | out.write(separator);
592 | separator = split ? ",\n" : ", ";
593 | if (split) {
594 | indent();
595 | }
596 | out.write(entry.getKey());
597 | out.write(" = ");
598 | Object value = entry.getValue();
599 | emitAnnotationValue(value);
600 | }
601 | popScope(Scope.ANNOTATION_ATTRIBUTE);
602 | if (split) {
603 | out.write("\n");
604 | indent();
605 | }
606 | out.write(")");
607 | break;
608 | }
609 | out.write("\n");
610 | return this;
611 | }
612 |
613 | private boolean containsArray(Collection> values) {
614 | for (Object value : values) {
615 | if (value instanceof Object[]) {
616 | return true;
617 | }
618 | }
619 | return false;
620 | }
621 |
622 | /**
623 | * Writes a single annotation value. If the value is an array, each element in the array will be
624 | * written to its own line.
625 | */
626 | private JavaWriter emitAnnotationValue(Object value) throws IOException {
627 | if (value instanceof Object[]) {
628 | out.write("{");
629 | boolean firstValue = true;
630 | scopes.push(Scope.ANNOTATION_ARRAY_VALUE);
631 | for (Object o : ((Object[]) value)) {
632 | if (firstValue) {
633 | firstValue = false;
634 | out.write("\n");
635 | } else {
636 | out.write(",\n");
637 | }
638 | indent();
639 | out.write(o.toString());
640 | }
641 | popScope(Scope.ANNOTATION_ARRAY_VALUE);
642 | out.write("\n");
643 | indent();
644 | out.write("}");
645 | } else {
646 | out.write(value.toString());
647 | }
648 | return this;
649 | }
650 |
651 | /**
652 | * @param pattern a code pattern like "int i = %s". Newlines will be further indented. Should not
653 | * contain trailing semicolon.
654 | */
655 | public JavaWriter emitStatement(String pattern, Object... args) throws IOException {
656 | checkInMethod();
657 | String[] lines = String.format(pattern, args).split("\n", -1);
658 | indent();
659 | out.write(lines[0]);
660 | for (int i = 1; i < lines.length; i++) {
661 | out.write("\n");
662 | hangingIndent();
663 | out.write(lines[i]);
664 | }
665 | out.write(";\n");
666 | return this;
667 | }
668 |
669 | /**
670 | * @param controlFlow the control flow construct and its code, such as "if (foo == 5)". Shouldn't
671 | * contain braces or newline characters.
672 | */
673 | public JavaWriter beginControlFlow(String controlFlow, Object... args) throws IOException {
674 | checkInMethod();
675 | indent();
676 | out.write(String.format(controlFlow, args));
677 | out.write(" {\n");
678 | scopes.push(Scope.CONTROL_FLOW);
679 | return this;
680 | }
681 |
682 | /**
683 | * @param controlFlow the control flow construct and its code, such as "else if (foo == 10)".
684 | * Shouldn't contain braces or newline characters.
685 | */
686 | public JavaWriter nextControlFlow(String controlFlow, Object... args) throws IOException {
687 | popScope(Scope.CONTROL_FLOW);
688 | indent();
689 | scopes.push(Scope.CONTROL_FLOW);
690 | out.write("} ");
691 | out.write(String.format(controlFlow, args));
692 | out.write(" {\n");
693 | return this;
694 | }
695 |
696 | public JavaWriter endControlFlow() throws IOException {
697 | return endControlFlow(null);
698 | }
699 |
700 | /**
701 | * @param controlFlow the optional control flow construct and its code, such as
702 | * "while(foo == 20)". Only used for "do/while" control flows.
703 | */
704 | public JavaWriter endControlFlow(String controlFlow, Object... args) throws IOException {
705 | popScope(Scope.CONTROL_FLOW);
706 | indent();
707 | if (controlFlow != null) {
708 | out.write("} ");
709 | out.write(String.format(controlFlow, args));
710 | out.write(";\n");
711 | } else {
712 | out.write("}\n");
713 | }
714 | return this;
715 | }
716 |
717 | /** Completes the current method declaration. */
718 | public JavaWriter endMethod() throws IOException {
719 | Scope popped = scopes.pop();
720 | // support calling a constructor a "method" to support the legacy code
721 | if (popped == Scope.NON_ABSTRACT_METHOD || popped == Scope.CONSTRUCTOR) {
722 | indent();
723 | out.write("}\n");
724 | } else if (popped != Scope.ABSTRACT_METHOD) {
725 | throw new IllegalStateException();
726 | }
727 | return this;
728 | }
729 |
730 | /** Completes the current constructor declaration. */
731 | public JavaWriter endConstructor() throws IOException {
732 | popScope(Scope.CONSTRUCTOR);
733 | indent();
734 | out.write("}\n");
735 | return this;
736 | }
737 |
738 | /** Returns the string literal representing {@code data}, including wrapping quotes. */
739 | public static String stringLiteral(String data) {
740 | StringBuilder result = new StringBuilder();
741 | result.append('"');
742 | for (int i = 0; i < data.length(); i++) {
743 | char c = data.charAt(i);
744 | switch (c) {
745 | case '"':
746 | result.append("\\\"");
747 | break;
748 | case '\\':
749 | result.append("\\\\");
750 | break;
751 | case '\b':
752 | result.append("\\b");
753 | break;
754 | case '\t':
755 | result.append("\\t");
756 | break;
757 | case '\n':
758 | result.append("\\n");
759 | break;
760 | case '\f':
761 | result.append("\\f");
762 | break;
763 | case '\r':
764 | result.append("\\r");
765 | break;
766 | default:
767 | if (Character.isISOControl(c)) {
768 | result.append(String.format("\\u%04x", (int) c));
769 | } else {
770 | result.append(c);
771 | }
772 | }
773 | }
774 | result.append('"');
775 | return result.toString();
776 | }
777 |
778 | /** Build a string representation of a type and optionally its generic type arguments. */
779 | public static String type(Class> raw, String... parameters) {
780 | if (parameters.length == 0) {
781 | return raw.getCanonicalName();
782 | }
783 | if (raw.getTypeParameters().length != parameters.length) {
784 | throw new IllegalArgumentException();
785 | }
786 | StringBuilder result = new StringBuilder();
787 | result.append(raw.getCanonicalName());
788 | result.append("<");
789 | result.append(parameters[0]);
790 | for (int i = 1; i < parameters.length; i++) {
791 | result.append(", ");
792 | result.append(parameters[i]);
793 | }
794 | result.append(">");
795 | return result.toString();
796 | }
797 |
798 | /** Build a string representation of the raw type for a (optionally generic) type. */
799 | public static String rawType(String type) {
800 | int lessThanIndex = type.indexOf('<');
801 | if (lessThanIndex != -1) {
802 | return type.substring(0, lessThanIndex);
803 | }
804 | return type;
805 | }
806 |
807 | @Override public void close() throws IOException {
808 | out.close();
809 | }
810 |
811 | /** Emits the modifiers to the writer. */
812 | private void emitModifiers(Set modifiers) throws IOException {
813 | if (modifiers.isEmpty()) {
814 | return;
815 | }
816 | // Use an EnumSet to ensure the proper ordering
817 | if (!(modifiers instanceof EnumSet)) {
818 | modifiers = EnumSet.copyOf(modifiers);
819 | }
820 | for (Modifier modifier : modifiers) {
821 | out.append(modifier.toString()).append(' ');
822 | }
823 | }
824 |
825 | private void indent() throws IOException {
826 | for (int i = 0, count = scopes.size(); i < count; i++) {
827 | out.write(indent);
828 | }
829 | }
830 |
831 | private void hangingIndent() throws IOException {
832 | for (int i = 0, count = scopes.size() + 2; i < count; i++) {
833 | out.write(indent);
834 | }
835 | }
836 |
837 | private static final EnumSet
838 | METHOD_SCOPES = EnumSet.of(Scope.NON_ABSTRACT_METHOD, Scope.CONSTRUCTOR, Scope.CONTROL_FLOW,
839 | Scope.INITIALIZER);
840 |
841 | private void checkInMethod() {
842 | if (!METHOD_SCOPES.contains(scopes.peekFirst())) {
843 | throw new IllegalArgumentException();
844 | }
845 | }
846 |
847 | private void popScope(Scope... expected) {
848 | if (!EnumSet.copyOf(Arrays.asList(expected)).contains(scopes.pop())) {
849 | throw new IllegalStateException();
850 | }
851 | }
852 |
853 | private enum Scope {
854 | TYPE_DECLARATION,
855 | INTERFACE_DECLARATION,
856 | ABSTRACT_METHOD,
857 | NON_ABSTRACT_METHOD,
858 | CONSTRUCTOR,
859 | CONTROL_FLOW,
860 | ANNOTATION_ATTRIBUTE,
861 | ANNOTATION_ARRAY_VALUE,
862 | INITIALIZER
863 | }
864 | }
865 |
--------------------------------------------------------------------------------
/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor:
--------------------------------------------------------------------------------
1 | com.hannesdorfmann.fragmentargs.processor.ArgProcessor
--------------------------------------------------------------------------------
/processor/src/test/java/com/hannesdorfmann/fragmentargs/processor/CompareModifierUtilsTest.java:
--------------------------------------------------------------------------------
1 | package com.hannesdorfmann.fragmentargs.processor;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 | import javax.lang.model.element.Element;
6 | import javax.lang.model.element.Modifier;
7 | import junit.framework.Assert;
8 | import org.junit.Before;
9 | import org.junit.Test;
10 | import org.mockito.Mockito;
11 |
12 | /**
13 | * @author Hannes Dorfmann
14 | */
15 | public class CompareModifierUtilsTest {
16 |
17 | Element a, b;
18 | Set aModifiers, bModifiers;
19 |
20 | @Before
21 | public void init() {
22 | a = Mockito.mock(Element.class);
23 | b = Mockito.mock(Element.class);
24 |
25 | aModifiers = new HashSet();
26 | bModifiers = new HashSet();
27 |
28 | Mockito.doReturn(aModifiers).when(a).getModifiers();
29 | Mockito.doReturn(bModifiers).when(b).getModifiers();
30 | }
31 |
32 | @Test
33 | public void aPublicBnot() {
34 | aModifiers.add(Modifier.PUBLIC);
35 | bModifiers.add(Modifier.PRIVATE);
36 |
37 | Assert.assertEquals(-1, ModifierUtils.compareModifierVisibility(a, b));
38 | }
39 |
40 | @Test
41 | public void aDefaultBnot() {
42 | bModifiers.add(Modifier.PRIVATE);
43 |
44 | Assert.assertEquals(-1, ModifierUtils.compareModifierVisibility(a, b));
45 | }
46 |
47 | @Test
48 | public void aProtectedBnot() {
49 | aModifiers.add(Modifier.PROTECTED);
50 | bModifiers.add(Modifier.PRIVATE);
51 |
52 | Assert.assertEquals(-1, ModifierUtils.compareModifierVisibility(a, b));
53 | }
54 |
55 |
56 | @Test
57 | public void bPublicAnot() {
58 | bModifiers.add(Modifier.PUBLIC);
59 | aModifiers.add(Modifier.PRIVATE);
60 |
61 | Assert.assertEquals(1, ModifierUtils.compareModifierVisibility(a, b));
62 | }
63 |
64 | @Test
65 | public void bDefaultAnot() {
66 | aModifiers.add(Modifier.PRIVATE);
67 |
68 | Assert.assertEquals(1, ModifierUtils.compareModifierVisibility(a, b));
69 | }
70 |
71 | @Test
72 | public void bProtectedAnot() {
73 | aModifiers.add(Modifier.PRIVATE);
74 | bModifiers.add(Modifier.PROTECTED);
75 |
76 | Assert.assertEquals(1, ModifierUtils.compareModifierVisibility(a, b));
77 | }
78 |
79 | @Test
80 | public void samePrivate() {
81 | aModifiers.add(Modifier.PRIVATE);
82 | bModifiers.add(Modifier.PRIVATE);
83 |
84 | Assert.assertEquals(0, ModifierUtils.compareModifierVisibility(a, b));
85 | }
86 |
87 | @Test
88 | public void sameProtected() {
89 | aModifiers.add(Modifier.PRIVATE);
90 | bModifiers.add(Modifier.PRIVATE);
91 |
92 | Assert.assertEquals(0, ModifierUtils.compareModifierVisibility(a, b));
93 | }
94 |
95 | @Test
96 | public void sameDefault() {
97 |
98 | Assert.assertEquals(0, ModifierUtils.compareModifierVisibility(a, b));
99 | }
100 |
101 | @Test
102 | public void samePublic() {
103 | aModifiers.add(Modifier.PUBLIC);
104 | bModifiers.add(Modifier.PUBLIC);
105 |
106 | Assert.assertEquals(0, ModifierUtils.compareModifierVisibility(a, b));
107 | }
108 |
109 |
110 |
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/processor/src/test/java/com/hannesdorfmann/fragmentargs/processor/CompileTest.java:
--------------------------------------------------------------------------------
1 | package com.hannesdorfmann.fragmentargs.processor;
2 |
3 | import com.google.testing.compile.JavaFileObjects;
4 |
5 | import static com.google.common.truth.Truth.assert_;
6 | import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
7 |
8 | public final class CompileTest {
9 |
10 | public static void assertClassCompilesWithoutError(final String classResourceName, final String outputClassResourceName) {
11 | assert_().about(javaSource())
12 | .that(JavaFileObjects.forResource(classResourceName))
13 | .processedWith(new ArgProcessor())
14 | .compilesWithoutError()
15 | .and()
16 | .generatesSources(JavaFileObjects.forResource(outputClassResourceName));
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/processor/src/test/java/com/hannesdorfmann/fragmentargs/processor/InnerClassTest.java:
--------------------------------------------------------------------------------
1 | package com.hannesdorfmann.fragmentargs.processor;
2 |
3 | import org.junit.Test;
4 |
5 | import static com.hannesdorfmann.fragmentargs.processor.CompileTest.assertClassCompilesWithoutError;
6 |
7 | public class InnerClassTest {
8 |
9 | @Test
10 | public void innerClass() {
11 | assertClassCompilesWithoutError("ClassWithInnerClass.java", "ClassWithInnerClassBuilder.java");
12 | }
13 |
14 | @Test
15 | public void innerClassWithProtectedField() {
16 | assertClassCompilesWithoutError("InnerClassWithProtectedField.java", "InnerClassWithProtectedFieldBuilder.java");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/processor/src/test/java/com/hannesdorfmann/fragmentargs/processor/ModifierUtilsDefaultModifierTest.java:
--------------------------------------------------------------------------------
1 | package com.hannesdorfmann.fragmentargs.processor;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 | import javax.lang.model.element.Modifier;
6 | import junit.framework.Assert;
7 | import org.junit.Test;
8 |
9 | /**
10 | * @author Hannes Dorfmann
11 | */
12 | public class ModifierUtilsDefaultModifierTest {
13 |
14 | @Test
15 | public void isDefaultModifier() {
16 |
17 | Set modifiers = new HashSet();
18 | modifiers.add(Modifier.PUBLIC);
19 | Assert.assertFalse(ModifierUtils.isDefaultModifier(modifiers));
20 |
21 | modifiers.clear();
22 | modifiers.add(Modifier.PRIVATE);
23 | Assert.assertFalse(ModifierUtils.isDefaultModifier(modifiers));
24 |
25 | modifiers.clear();
26 | modifiers.add(Modifier.PROTECTED);
27 | Assert.assertFalse(ModifierUtils.isDefaultModifier(modifiers));
28 |
29 |
30 | modifiers.clear();
31 | modifiers.add(Modifier.FINAL);
32 | modifiers.add(Modifier.STATIC);
33 |
34 | Assert.assertTrue(ModifierUtils.isDefaultModifier(modifiers));
35 | }
36 |
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/processor/src/test/java/com/hannesdorfmann/fragmentargs/processor/ProtectedAccessTest.java:
--------------------------------------------------------------------------------
1 | package com.hannesdorfmann.fragmentargs.processor;
2 |
3 | import com.google.testing.compile.JavaFileObjects;
4 |
5 | import org.junit.Test;
6 |
7 | import static com.google.common.truth.Truth.assert_;
8 | import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
9 |
10 | public class ProtectedAccessTest {
11 |
12 | private static final String[] PROCESSOR_OPTIONS
13 | = new String[]{"-AfragmentArgsSupportAnnotations=false"};
14 |
15 | @Test
16 | public void protectedField() {
17 | assert_().about(javaSource())
18 | .that(JavaFileObjects.forResource("ClassWithProtectedField.java"))
19 | .withCompilerOptions(PROCESSOR_OPTIONS)
20 | .processedWith(new ArgProcessor())
21 | .compilesWithoutError();
22 | }
23 |
24 | @Test
25 | public void protectedSetter() {
26 | assert_().about(javaSource())
27 | .that(JavaFileObjects.forResource("ClassWithProtectedSetter.java"))
28 | .withCompilerOptions(PROCESSOR_OPTIONS)
29 | .processedWith(new ArgProcessor())
30 | .compilesWithoutError();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/processor/src/test/resources/ClassWithInnerClass.java:
--------------------------------------------------------------------------------
1 | package com.hannesdorfmann.fragmentargs.processor.test;
2 |
3 | @com.hannesdorfmann.fragmentargs.annotation.FragmentWithArgs
4 | public class ClassWithInnerClass extends android.app.Fragment {
5 |
6 | @com.hannesdorfmann.fragmentargs.annotation.Arg
7 | String arg;
8 |
9 | @com.hannesdorfmann.fragmentargs.annotation.FragmentWithArgs
10 | public static class InnerClass extends android.app.Fragment {
11 |
12 | @com.hannesdorfmann.fragmentargs.annotation.Arg
13 | String arg;
14 | }
15 |
16 | }
--------------------------------------------------------------------------------
/processor/src/test/resources/ClassWithInnerClassBuilder.java:
--------------------------------------------------------------------------------
1 | package com.hannesdorfmann.fragmentargs.processor.test;
2 |
3 | import android.os.Bundle;
4 |
5 | public final class ClassWithInnerClassBuilder {
6 |
7 | private final Bundle mArguments = new Bundle();
8 |
9 | public ClassWithInnerClassBuilder(String arg) {
10 |
11 | mArguments.putString("arg", arg);
12 | }
13 |
14 | public static ClassWithInnerClass newClassWithInnerClass(String arg) {
15 | return new ClassWithInnerClassBuilder(arg).build();
16 | }
17 |
18 | public Bundle buildBundle() {
19 | return new Bundle(mArguments);
20 | }
21 |
22 | public static final void injectArguments(ClassWithInnerClass fragment) {
23 | Bundle args = fragment.getArguments();
24 | if (args == null) {
25 | throw new IllegalStateException("No arguments set. Have you set up this Fragment with the corresponding FragmentArgs Builder? ");
26 | }
27 |
28 | if (!args.containsKey("arg")) {
29 | throw new IllegalStateException("required argument arg is not set");
30 | }
31 | fragment.arg = args.getString("arg");
32 | }
33 |
34 | public ClassWithInnerClass build() {
35 | ClassWithInnerClass fragment = new ClassWithInnerClass();
36 | fragment.setArguments(mArguments);
37 | return fragment;
38 | }
39 | }
--------------------------------------------------------------------------------
/processor/src/test/resources/ClassWithProtectedField.java:
--------------------------------------------------------------------------------
1 | package com.hannesdorfmann.fragmentargs.processor.test;
2 |
3 | @com.hannesdorfmann.fragmentargs.annotation.FragmentWithArgs
4 | public class ClassWithProtectedField extends android.app.Fragment {
5 | @com.hannesdorfmann.fragmentargs.annotation.Arg
6 | protected String protectedArg;
7 | }
--------------------------------------------------------------------------------
/processor/src/test/resources/ClassWithProtectedSetter.java:
--------------------------------------------------------------------------------
1 | package com.hannesdorfmann.fragmentargs.processor.test;
2 |
3 | @com.hannesdorfmann.fragmentargs.annotation.FragmentWithArgs
4 | public class ClassWithProtectedSetter extends android.app.Fragment {
5 | @com.hannesdorfmann.fragmentargs.annotation.Arg
6 | private String privateArg;
7 |
8 | protected void setPrivateArg(String privateArg) {
9 | this.privateArg = privateArg;
10 | }
11 | }
--------------------------------------------------------------------------------
/processor/src/test/resources/InnerClassWithProtectedField.java:
--------------------------------------------------------------------------------
1 | package com.hannesdorfmann.fragmentargs.processor.test;
2 |
3 | @com.hannesdorfmann.fragmentargs.annotation.FragmentWithArgs
4 | public class InnerClassWithProtectedField extends android.app.Fragment {
5 |
6 | @com.hannesdorfmann.fragmentargs.annotation.Arg
7 | protected String arg;
8 |
9 | @com.hannesdorfmann.fragmentargs.annotation.FragmentWithArgs
10 | public static class InnerClass extends android.app.Fragment {
11 |
12 | @com.hannesdorfmann.fragmentargs.annotation.Arg
13 | protected String arg;
14 | }
15 |
16 | }
--------------------------------------------------------------------------------
/processor/src/test/resources/InnerClassWithProtectedFieldBuilder.java:
--------------------------------------------------------------------------------
1 | package com.hannesdorfmann.fragmentargs.processor.test;
2 |
3 | import android.os.Bundle;
4 |
5 | public final class InnerClassWithProtectedFieldBuilder {
6 |
7 | private final Bundle mArguments = new Bundle();
8 |
9 | public InnerClassWithProtectedFieldBuilder(String arg) {
10 |
11 | mArguments.putString("arg", arg);
12 | }
13 |
14 | public static InnerClassWithProtectedField newInnerClassWithProtectedField(String arg) {
15 | return new InnerClassWithProtectedFieldBuilder(arg).build();
16 | }
17 |
18 | public Bundle buildBundle() {
19 | return new Bundle(mArguments);
20 | }
21 |
22 | public static final void injectArguments(InnerClassWithProtectedField fragment) {
23 | Bundle args = fragment.getArguments();
24 | if (args == null) {
25 | throw new IllegalStateException("No arguments set. Have you set up this Fragment with the corresponding FragmentArgs Builder? ");
26 | }
27 |
28 | if (!args.containsKey("arg")) {
29 | throw new IllegalStateException("required argument arg is not set");
30 | }
31 | fragment.arg = args.getString("arg");
32 | }
33 |
34 | public InnerClassWithProtectedField build() {
35 | InnerClassWithProtectedField fragment = new InnerClassWithProtectedField();
36 | fragment.setArguments(mArguments);
37 | return fragment;
38 | }
39 | }
--------------------------------------------------------------------------------