summaryrefslogtreecommitdiff
path: root/src/main/java/ftbsc/lll/proxies/AbstractProxy.java
blob: 93eaec85947d0cc712bdd57fd8855f468bbd2be6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package ftbsc.lll.proxies;

import org.objectweb.asm.Type;

/**
 * Abstract proxy class, implementing common aspects
 * of {@link MethodProxy} and {@link FieldProxy}.
 * @since 0.3.0
 */
public abstract class AbstractProxy {

   /**
    * The name of the corresponding element.
    */
   public final String name;

   /**
    * The {@link Type} corresponding to this element.
    */
   public final Type type;

   /**
    * The fully qualified name (i.e. java.lang.String) of
    * the parent class.
    */
   public final QualifiableProxy parent;

   /**
    * The modifiers of the element, as a packed int.
    * @see java.lang.reflect.Modifier
    */
   public final int modifiers;

   /**
    * The private constructor, should be called by all classes extending this in theirs.
    * @param name the name of the element
    * @param type the {@link Type} for the element
    * @param modifiers the modifiers, as a packed int
    * @param parent the FQN of the parent class
    */
   protected AbstractProxy(String name, Type type, int modifiers, QualifiableProxy parent) {
      this.name = name;
      this.type = type;
      this.modifiers = modifiers;
      this.parent = parent;
   }

   /**
    * Indicates whether the given object is a proxy for the same element as this.
    * @param obj the object to perform
    * @return true if it's equal
    */
   @Override
   public boolean equals(Object obj) {
      if(obj instanceof AbstractProxy) {
         AbstractProxy p = (AbstractProxy) obj;
         return p.parent.equals(this.parent)
            && p.name.equals(this.name)
            && p.modifiers == this.modifiers
            && p.type.equals(this.type);
      } else return false;
   }

   /**
    * A Builder for the generic proxy.
    * @param <T> the type of proxy
    */
   public abstract static class Builder<T extends AbstractProxy> {

      /**
       * The name of the element.
       */
      protected String name;

      /**
       * The modifiers of the element, as a packed int.
       */
      protected int modifiers;

      /**
       * The fully qualified name of the parent.
       */
      protected QualifiableProxy parent;

      /**
       * The {@link Type} corresponding to the element.
       */
      protected Type type;

      /**
       * The constructor.
       * @param name the name of the element
       */
      protected Builder(String name) {
         this.name = name;
         this.modifiers = 0;
      }

      /**
       * @param newModifier the modifier to add
       * @return the current state of the builder
       */
      public Builder<T> addModifier(int newModifier) {
         this.modifiers |= newModifier;
         return this;
      }

      /**
       * @param newModifier the new modifier value
       * @return the current state of the builder
       */
      public Builder<T> setModifiers(int newModifier) {
         this.modifiers = newModifier;
         return this;
      }

      /**
       * @param parent the {@link QualifiableProxy} representing the parent
       * @return the current state of the builder
       */
      public Builder<T> setParent(QualifiableProxy parent) {
         this.parent = parent;
         return this;
      }

      /**
       * @param type the {@link Type} corresponding to the element
       * @return the current state of the builder
       */
      public Builder<T> setType(Type type) {
         this.type = type;
         return this;
      }

      /**
       * Sets {@link Type} for this element from the descriptor, passed as a {@link String}.
       * @param descriptor the descriptor passed as a {@link String}
       * @return the builder's state after the change
       */
      public Builder<T> setDescriptor(String descriptor) {
         return this.setType(Type.getType(descriptor));
      }

      /**
       * @return the built proxy object
       */
      public abstract T build();
   }
}