1 11 package org.eclipse.jdt.internal.compiler.lookup; 12 13 import org.eclipse.jdt.core.compiler.CharOperation; 14 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; 15 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; 16 17 public class SyntheticAccessMethodBinding extends MethodBinding { 18 19 public FieldBinding targetReadField; public FieldBinding targetWriteField; public MethodBinding targetMethod; 23 public int accessType; 24 25 public final static int FieldReadAccess = 1; public final static int FieldWriteAccess = 2; public final static int MethodAccess = 3; public final static int ConstructorAccess = 4; public final static int SuperMethodAccess = 5; 31 final static char[] AccessMethodPrefix = { 'a', 'c', 'c', 'e', 's', 's', '$' }; 32 33 public int sourceStart = 0; public int index; 36 public SyntheticAccessMethodBinding(FieldBinding targetField, boolean isReadAccess, ReferenceBinding declaringClass) { 37 38 this.modifiers = AccDefault | AccStatic | AccSynthetic; 39 SourceTypeBinding declaringSourceType = (SourceTypeBinding) declaringClass; 40 SyntheticAccessMethodBinding[] knownAccessMethods = declaringSourceType.syntheticAccessMethods(); 41 int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length; 42 this.index = methodId; 43 this.selector = CharOperation.concat(AccessMethodPrefix, String.valueOf(methodId).toCharArray()); 44 if (isReadAccess) { 45 this.returnType = targetField.type; 46 if (targetField.isStatic()) { 47 this.parameters = NoParameters; 48 } else { 49 this.parameters = new TypeBinding[1]; 50 this.parameters[0] = declaringSourceType; 51 } 52 this.targetReadField = targetField; 53 this.accessType = FieldReadAccess; 54 } else { 55 this.returnType = VoidBinding; 56 if (targetField.isStatic()) { 57 this.parameters = new TypeBinding[1]; 58 this.parameters[0] = targetField.type; 59 } else { 60 this.parameters = new TypeBinding[2]; 61 this.parameters[0] = declaringSourceType; 62 this.parameters[1] = targetField.type; 63 } 64 this.targetWriteField = targetField; 65 this.accessType = FieldWriteAccess; 66 } 67 this.thrownExceptions = NoExceptions; 68 this.declaringClass = declaringSourceType; 69 70 boolean needRename; 72 do { 73 check : { 74 needRename = false; 75 MethodBinding[] methods = declaringSourceType.methods; 77 for (int i = 0, length = methods.length; i < length; i++) { 78 if (CharOperation.equals(this.selector, methods[i].selector) && this.areParametersEqual(methods[i])) { 79 needRename = true; 80 break check; 81 } 82 } 83 if (knownAccessMethods != null) { 85 for (int i = 0, length = knownAccessMethods.length; i < length; i++) { 86 if (knownAccessMethods[i] == null) continue; 87 if (CharOperation.equals(this.selector, knownAccessMethods[i].selector) && this.areParametersEqual(methods[i])) { 88 needRename = true; 89 break check; 90 } 91 } 92 } 93 } 94 if (needRename) { this.setSelector(CharOperation.concat(AccessMethodPrefix, String.valueOf(++methodId).toCharArray())); 96 } 97 } while (needRename); 98 99 FieldDeclaration[] fieldDecls = declaringSourceType.scope.referenceContext.fields; 101 if (fieldDecls != null) { 102 for (int i = 0, max = fieldDecls.length; i < max; i++) { 103 if (fieldDecls[i].binding == targetField) { 104 this.sourceStart = fieldDecls[i].sourceStart; 105 return; 106 } 107 } 108 } 109 110 124 this.sourceStart = declaringSourceType.scope.referenceContext.sourceStart; } 128 129 public SyntheticAccessMethodBinding(MethodBinding targetMethod, boolean isSuperAccess, ReferenceBinding receiverType) { 130 131 if (targetMethod.isConstructor()) { 132 this.initializeConstructorAccessor(targetMethod); 133 } else { 134 this.initializeMethodAccessor(targetMethod, isSuperAccess, receiverType); 135 } 136 } 137 138 142 public void initializeConstructorAccessor(MethodBinding accessedConstructor) { 143 144 this.targetMethod = accessedConstructor; 145 this.modifiers = AccDefault | AccSynthetic; 146 SourceTypeBinding sourceType = (SourceTypeBinding) accessedConstructor.declaringClass; 147 SyntheticAccessMethodBinding[] knownAccessMethods = 148 sourceType.syntheticAccessMethods(); 149 this.index = knownAccessMethods == null ? 0 : knownAccessMethods.length; 150 151 this.selector = accessedConstructor.selector; 152 this.returnType = accessedConstructor.returnType; 153 this.accessType = ConstructorAccess; 154 this.parameters = new TypeBinding[accessedConstructor.parameters.length + 1]; 155 System.arraycopy( 156 accessedConstructor.parameters, 157 0, 158 this.parameters, 159 0, 160 accessedConstructor.parameters.length); 161 parameters[accessedConstructor.parameters.length] = 162 accessedConstructor.declaringClass; 163 this.thrownExceptions = accessedConstructor.thrownExceptions; 164 this.declaringClass = sourceType; 165 166 boolean needRename; 168 do { 169 check : { 170 needRename = false; 171 MethodBinding[] methods = sourceType.methods; 173 for (int i = 0, length = methods.length; i < length; i++) { 174 if (CharOperation.equals(this.selector, methods[i].selector) 175 && this.areParametersEqual(methods[i])) { 176 needRename = true; 177 break check; 178 } 179 } 180 if (knownAccessMethods != null) { 182 for (int i = 0, length = knownAccessMethods.length; i < length; i++) { 183 if (knownAccessMethods[i] == null) 184 continue; 185 if (CharOperation.equals(this.selector, knownAccessMethods[i].selector) 186 && this.areParametersEqual(knownAccessMethods[i])) { 187 needRename = true; 188 break check; 189 } 190 } 191 } 192 } 193 if (needRename) { int length = this.parameters.length; 195 System.arraycopy( 196 this.parameters, 197 0, 198 this.parameters = new TypeBinding[length + 1], 199 0, 200 length); 201 this.parameters[length] = this.declaringClass; 202 } 203 } while (needRename); 204 205 AbstractMethodDeclaration[] methodDecls = 207 sourceType.scope.referenceContext.methods; 208 if (methodDecls != null) { 209 for (int i = 0, length = methodDecls.length; i < length; i++) { 210 if (methodDecls[i].binding == accessedConstructor) { 211 this.sourceStart = methodDecls[i].sourceStart; 212 return; 213 } 214 } 215 } 216 } 217 218 221 public void initializeMethodAccessor(MethodBinding accessedMethod, boolean isSuperAccess, ReferenceBinding receiverType) { 222 223 this.targetMethod = accessedMethod; 224 this.modifiers = AccDefault | AccStatic | AccSynthetic; 225 SourceTypeBinding declaringSourceType = (SourceTypeBinding) receiverType; 226 SyntheticAccessMethodBinding[] knownAccessMethods = declaringSourceType.syntheticAccessMethods(); 227 int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length; 228 this.index = methodId; 229 230 this.selector = CharOperation.concat(AccessMethodPrefix, String.valueOf(methodId).toCharArray()); 231 this.returnType = accessedMethod.returnType; 232 this.accessType = isSuperAccess ? SuperMethodAccess : MethodAccess; 233 234 if (accessedMethod.isStatic()) { 235 this.parameters = accessedMethod.parameters; 236 } else { 237 this.parameters = new TypeBinding[accessedMethod.parameters.length + 1]; 238 this.parameters[0] = declaringSourceType; 239 System.arraycopy(accessedMethod.parameters, 0, this.parameters, 1, accessedMethod.parameters.length); 240 } 241 this.thrownExceptions = accessedMethod.thrownExceptions; 242 this.declaringClass = declaringSourceType; 243 244 boolean needRename; 246 do { 247 check : { 248 needRename = false; 249 MethodBinding[] methods = declaringSourceType.methods; 251 for (int i = 0, length = methods.length; i < length; i++) { 252 if (CharOperation.equals(this.selector, methods[i].selector) && this.areParametersEqual(methods[i])) { 253 needRename = true; 254 break check; 255 } 256 } 257 if (knownAccessMethods != null) { 259 for (int i = 0, length = knownAccessMethods.length; i < length; i++) { 260 if (knownAccessMethods[i] == null) continue; 261 if (CharOperation.equals(this.selector, knownAccessMethods[i].selector) && this.areParametersEqual(knownAccessMethods[i])) { 262 needRename = true; 263 break check; 264 } 265 } 266 } 267 } 268 if (needRename) { this.setSelector(CharOperation.concat(AccessMethodPrefix, String.valueOf(++methodId).toCharArray())); 270 } 271 } while (needRename); 272 273 AbstractMethodDeclaration[] methodDecls = declaringSourceType.scope.referenceContext.methods; 275 if (methodDecls != null) { 276 for (int i = 0, length = methodDecls.length; i < length; i++) { 277 if (methodDecls[i].binding == accessedMethod) { 278 this.sourceStart = methodDecls[i].sourceStart; 279 return; 280 } 281 } 282 } 283 } 284 285 protected boolean isConstructorRelated() { 286 return accessType == ConstructorAccess; 287 } 288 } 289 | Popular Tags |