aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/ftbsc/lll/proxies/AbstractProxy.java
blob: ff320f0bfbbe190e0bab148acb6cb8e04d1a1361 (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
150
151
152
153
154
155
156
package ftbsc.lll.proxies;

import java.lang.reflect.Modifier;
import org.objectweb.asm.Type;

/**
 * Abstract proxy class, implementing common aspects.
 * @since 0.3.0
 */
public abstract class AbstractProxy {

   /**
    * Which type of proxy this is.
    */
   public final ProxyType proxyType;

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

   /**
    * The descriptor for this element.
    */
   public final String descriptor;

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

   /**
    * The modifiers of the member, as a packed int
    * @see 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 descriptor the descriptor for the element
    * @param modifiers the modifiers, as a packed int
    * @param parent the FQN of the parent class
    * @param proxyType the {@link ProxyType} being represented here
    */
   protected AbstractProxy(String name, String descriptor, int modifiers, QualifiableProxy parent, ProxyType proxyType) {
      this.name = name;
      this.descriptor = descriptor;
      this.modifiers = modifiers;
      this.parent = parent;
      this.proxyType = proxyType;
   }

   /**
    * 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.descriptor.equals(this.descriptor);
      } 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 descriptor of the element.
       */
      protected String descriptor;

      /**
       * 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;
      }

      /**
       * 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) {
         this.descriptor = descriptor;
         return this;
      }

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

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