X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Flookup%2FSourceTypeBinding.java;fp=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Flookup%2FSourceTypeBinding.java;h=0000000000000000000000000000000000000000;hb=6f0cd02d46e011bd5599e1b7fefc6159cb811135;hp=e791f1e03e3cc5919f751b404075981b7c9274a4;hpb=622d0e5a4b1b35b6918a516a79a0cc22272a919e;p=org.ibex.tool.git diff --git a/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java deleted file mode 100644 index e791f1e..0000000 --- a/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java +++ /dev/null @@ -1,1068 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.jdt.internal.compiler.lookup; - -import java.util.Enumeration; -import java.util.Hashtable; - -import org.eclipse.jdt.core.compiler.CharOperation; -import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.Argument; -import org.eclipse.jdt.internal.compiler.ast.AssertStatement; -import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; -import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; -import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeReference; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.eclipse.jdt.internal.compiler.impl.Constant; -import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; - -public class SourceTypeBinding extends ReferenceBinding { - public ReferenceBinding superclass; - public ReferenceBinding[] superInterfaces; - public FieldBinding[] fields; - public MethodBinding[] methods; - public ReferenceBinding[] memberTypes; - - public ClassScope scope; - - // Synthetics are separated into 4 categories: methods, super methods, fields, class literals and changed declaring type bindings - public final static int METHOD_EMUL = 0; - public final static int FIELD_EMUL = 1; - public final static int CLASS_LITERAL_EMUL = 2; - public final static int RECEIVER_TYPE_EMUL = 3; - - Hashtable[] synthetics; - -public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassScope scope) { - this.compoundName = compoundName; - this.fPackage = fPackage; - this.fileName = scope.referenceCompilationUnit().getFileName(); - this.modifiers = scope.referenceContext.modifiers; - this.sourceName = scope.referenceContext.name; - this.scope = scope; - - // expect the fields & methods to be initialized correctly later - this.fields = NoFields; - this.methods = NoMethods; - - computeId(); -} -private void addDefaultAbstractMethod(MethodBinding abstractMethod) { - MethodBinding defaultAbstract = new MethodBinding( - abstractMethod.modifiers | AccDefaultAbstract, - abstractMethod.selector, - abstractMethod.returnType, - abstractMethod.parameters, - abstractMethod.thrownExceptions, - this); - - MethodBinding[] temp = new MethodBinding[methods.length + 1]; - System.arraycopy(methods, 0, temp, 0, methods.length); - temp[methods.length] = defaultAbstract; - methods = temp; -} -public void addDefaultAbstractMethods() { - if ((tagBits & KnowsDefaultAbstractMethods) != 0) return; - - tagBits |= KnowsDefaultAbstractMethods; - - if (isClass() && isAbstract()) { - if (fPackage.environment.options.targetJDK >= ClassFileConstants.JDK1_2) return; // no longer added for post 1.2 targets - - ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][]; - int lastPosition = 0; - interfacesToVisit[lastPosition] = superInterfaces(); - - for (int i = 0; i <= lastPosition; i++) { - ReferenceBinding[] interfaces = interfacesToVisit[i]; - for (int j = 0, length = interfaces.length; j < length; j++) { - ReferenceBinding superType = interfaces[j]; - if (superType.isValidBinding()) { - MethodBinding[] superMethods = superType.methods(); - for (int m = superMethods.length; --m >= 0;) { - MethodBinding method = superMethods[m]; - if (!implementsMethod(method)) - addDefaultAbstractMethod(method); - } - - ReferenceBinding[] itsInterfaces = superType.superInterfaces(); - if (itsInterfaces != NoSuperInterfaces) { - if (++lastPosition == interfacesToVisit.length) - System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition); - interfacesToVisit[lastPosition] = itsInterfaces; - } - } - } - } - } -} -/* Add a new synthetic field for . -* Answer the new field or the existing field if one already existed. -*/ - -public FieldBinding addSyntheticField(LocalVariableBinding actualOuterLocalVariable) { - if (synthetics == null) { - synthetics = new Hashtable[4]; - } - if (synthetics[FIELD_EMUL] == null) { - synthetics[FIELD_EMUL] = new Hashtable(5); - } - - FieldBinding synthField = (FieldBinding) synthetics[FIELD_EMUL].get(actualOuterLocalVariable); - if (synthField == null) { - synthField = new SyntheticFieldBinding( - CharOperation.concat(SyntheticArgumentBinding.OuterLocalPrefix, actualOuterLocalVariable.name), - actualOuterLocalVariable.type, - AccPrivate | AccFinal | AccSynthetic, - this, - Constant.NotAConstant, - synthetics[FIELD_EMUL].size()); - synthetics[FIELD_EMUL].put(actualOuterLocalVariable, synthField); - } - - // ensure there is not already such a field defined by the user - boolean needRecheck; - int index = 1; - do { - needRecheck = false; - FieldBinding existingField; - if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) { - TypeDeclaration typeDecl = scope.referenceContext; - for (int i = 0, max = typeDecl.fields.length; i < max; i++) { - FieldDeclaration fieldDecl = typeDecl.fields[i]; - if (fieldDecl.binding == existingField) { - synthField.name = CharOperation.concat( - SyntheticArgumentBinding.OuterLocalPrefix, - actualOuterLocalVariable.name, - ("$" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$ - needRecheck = true; - break; - } - } - } - } while (needRecheck); - return synthField; -} -/* Add a new synthetic field for . -* Answer the new field or the existing field if one already existed. -*/ - -public FieldBinding addSyntheticField(ReferenceBinding enclosingType) { - - if (synthetics == null) { - synthetics = new Hashtable[4]; - } - if (synthetics[FIELD_EMUL] == null) { - synthetics[FIELD_EMUL] = new Hashtable(5); - } - - FieldBinding synthField = (FieldBinding) synthetics[FIELD_EMUL].get(enclosingType); - if (synthField == null) { - synthField = new SyntheticFieldBinding( - CharOperation.concat( - SyntheticArgumentBinding.EnclosingInstancePrefix, - String.valueOf(enclosingType.depth()).toCharArray()), - enclosingType, - AccDefault | AccFinal | AccSynthetic, - this, - Constant.NotAConstant, - synthetics[FIELD_EMUL].size()); - synthetics[FIELD_EMUL].put(enclosingType, synthField); - } - // ensure there is not already such a field defined by the user - FieldBinding existingField; - if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) { - TypeDeclaration typeDecl = scope.referenceContext; - for (int i = 0, max = typeDecl.fields.length; i < max; i++) { - FieldDeclaration fieldDecl = typeDecl.fields[i]; - if (fieldDecl.binding == existingField) { - scope.problemReporter().duplicateFieldInType(this, fieldDecl); - break; - } - } - } - return synthField; -} -/* Add a new synthetic field for a class literal access. -* Answer the new field or the existing field if one already existed. -*/ - -public FieldBinding addSyntheticField(TypeBinding targetType, BlockScope blockScope) { - - if (synthetics == null) { - synthetics = new Hashtable[4]; - } - if (synthetics[CLASS_LITERAL_EMUL] == null) { - synthetics[CLASS_LITERAL_EMUL] = new Hashtable(5); - } - - // use a different table than FIELDS, given there might be a collision between emulation of X.this$0 and X.class. - FieldBinding synthField = (FieldBinding) synthetics[CLASS_LITERAL_EMUL].get(targetType); - if (synthField == null) { - synthField = new SyntheticFieldBinding( - ("class$" + synthetics[CLASS_LITERAL_EMUL].size()).toCharArray(), //$NON-NLS-1$ - blockScope.getJavaLangClass(), - AccDefault | AccStatic | AccSynthetic, - this, - Constant.NotAConstant, - synthetics[CLASS_LITERAL_EMUL].size()); - synthetics[CLASS_LITERAL_EMUL].put(targetType, synthField); - } - // ensure there is not already such a field defined by the user - FieldBinding existingField; - if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) { - TypeDeclaration typeDecl = blockScope.referenceType(); - for (int i = 0, max = typeDecl.fields.length; i < max; i++) { - FieldDeclaration fieldDecl = typeDecl.fields[i]; - if (fieldDecl.binding == existingField) { - blockScope.problemReporter().duplicateFieldInType(this, fieldDecl); - break; - } - } - } - return synthField; -} - -/* Add a new synthetic field for the emulation of the assert statement. -* Answer the new field or the existing field if one already existed. -*/ -public FieldBinding addSyntheticField(AssertStatement assertStatement, BlockScope blockScope) { - - if (synthetics == null) { - synthetics = new Hashtable[4]; - } - if (synthetics[FIELD_EMUL] == null) { - synthetics[FIELD_EMUL] = new Hashtable(5); - } - - FieldBinding synthField = (FieldBinding) synthetics[FIELD_EMUL].get("assertionEmulation"); //$NON-NLS-1$ - if (synthField == null) { - synthField = new SyntheticFieldBinding( - "$assertionsDisabled".toCharArray(), //$NON-NLS-1$ - BooleanBinding, - AccDefault | AccStatic | AccSynthetic | AccFinal, - this, - Constant.NotAConstant, - synthetics[FIELD_EMUL].size()); - synthetics[FIELD_EMUL].put("assertionEmulation", synthField); //$NON-NLS-1$ - } - // ensure there is not already such a field defined by the user - // ensure there is not already such a field defined by the user - boolean needRecheck; - int index = 0; - do { - needRecheck = false; - FieldBinding existingField; - if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) { - TypeDeclaration typeDecl = scope.referenceContext; - for (int i = 0, max = typeDecl.fields.length; i < max; i++) { - FieldDeclaration fieldDecl = typeDecl.fields[i]; - if (fieldDecl.binding == existingField) { - synthField.name = CharOperation.concat( - "$assertionsDisabled".toCharArray(), //$NON-NLS-1$ - ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$ - needRecheck = true; - break; - } - } - } - } while (needRecheck); - return synthField; -} - -/* Add a new synthetic access method for read/write access to . - Answer the new method or the existing method if one already existed. -*/ - -public SyntheticAccessMethodBinding addSyntheticMethod(FieldBinding targetField, boolean isReadAccess) { - - if (synthetics == null) { - synthetics = new Hashtable[4]; - } - if (synthetics[METHOD_EMUL] == null) { - synthetics[METHOD_EMUL] = new Hashtable(5); - } - - SyntheticAccessMethodBinding accessMethod = null; - SyntheticAccessMethodBinding[] accessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD_EMUL].get(targetField); - if (accessors == null) { - accessMethod = new SyntheticAccessMethodBinding(targetField, isReadAccess, this); - synthetics[METHOD_EMUL].put(targetField, accessors = new SyntheticAccessMethodBinding[2]); - accessors[isReadAccess ? 0 : 1] = accessMethod; - } else { - if ((accessMethod = accessors[isReadAccess ? 0 : 1]) == null) { - accessMethod = new SyntheticAccessMethodBinding(targetField, isReadAccess, this); - accessors[isReadAccess ? 0 : 1] = accessMethod; - } - } - return accessMethod; -} -/* Add a new synthetic access method for access to . - * Must distinguish access method used for super access from others (need to use invokespecial bytecode) - Answer the new method or the existing method if one already existed. -*/ - -public SyntheticAccessMethodBinding addSyntheticMethod(MethodBinding targetMethod, boolean isSuperAccess) { - - if (synthetics == null) { - synthetics = new Hashtable[4]; - } - if (synthetics[METHOD_EMUL] == null) { - synthetics[METHOD_EMUL] = new Hashtable(5); - } - - SyntheticAccessMethodBinding accessMethod = null; - SyntheticAccessMethodBinding[] accessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD_EMUL].get(targetMethod); - if (accessors == null) { - accessMethod = new SyntheticAccessMethodBinding(targetMethod, isSuperAccess, this); - synthetics[METHOD_EMUL].put(targetMethod, accessors = new SyntheticAccessMethodBinding[2]); - accessors[isSuperAccess ? 0 : 1] = accessMethod; - } else { - if ((accessMethod = accessors[isSuperAccess ? 0 : 1]) == null) { - accessMethod = new SyntheticAccessMethodBinding(targetMethod, isSuperAccess, this); - accessors[isSuperAccess ? 0 : 1] = accessMethod; - } - } - return accessMethod; -} - -public FieldBinding[] availableFields() { - return fields(); -} -public MethodBinding[] availableMethods() { - return methods(); -} -void faultInTypesForFieldsAndMethods() { - fields(); - methods(); - - for (int i = 0, length = memberTypes.length; i < length; i++) - ((SourceTypeBinding) memberTypes[i]).faultInTypesForFieldsAndMethods(); -} -// NOTE: the type of each field of a source type is resolved when needed - -public FieldBinding[] fields() { - - try { - int failed = 0; - for (int f = 0, max = fields.length; f < max; f++) { - if (resolveTypeFor(fields[f]) == null) { - fields[f] = null; - failed++; - } - } - if (failed > 0) { - int newSize = fields.length - failed; - if (newSize == 0) - return fields = NoFields; - - FieldBinding[] newFields = new FieldBinding[newSize]; - for (int i = 0, n = 0, max = fields.length; i < max; i++) - if (fields[i] != null) - newFields[n++] = fields[i]; - fields = newFields; - } - } catch(AbortCompilation e){ - // ensure null fields are removed - FieldBinding[] newFields = null; - int count = 0; - for (int i = 0, max = fields.length; i < max; i++){ - FieldBinding field = fields[i]; - if (field == null && newFields == null){ - System.arraycopy(fields, 0, newFields = new FieldBinding[max], 0, i); - } else if (newFields != null && field != null) { - newFields[count++] = field; - } - } - if (newFields != null){ - System.arraycopy(newFields, 0, fields = new FieldBinding[count], 0, count); - } - throw e; - } - return fields; -} -public MethodBinding[] getDefaultAbstractMethods() { - int count = 0; - for (int i = methods.length; --i >= 0;) - if (methods[i].isDefaultAbstract()) - count++; - if (count == 0) return NoMethods; - - MethodBinding[] result = new MethodBinding[count]; - count = 0; - for (int i = methods.length; --i >= 0;) - if (methods[i].isDefaultAbstract()) - result[count++] = methods[i]; - return result; -} -// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed - -public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) { - int argCount = argumentTypes.length; - - if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods - nextMethod : for (int m = methods.length; --m >= 0;) { - MethodBinding method = methods[m]; - if (method.selector == ConstructorDeclaration.ConstantPoolName && method.parameters.length == argCount) { - TypeBinding[] toMatch = method.parameters; - for (int p = 0; p < argCount; p++) - if (toMatch[p] != argumentTypes[p]) - continue nextMethod; - return method; - } - } - } else { - MethodBinding[] constructors = getMethods(ConstructorDeclaration.ConstantPoolName); // takes care of duplicates & default abstract methods - nextConstructor : for (int c = constructors.length; --c >= 0;) { - MethodBinding constructor = constructors[c]; - TypeBinding[] toMatch = constructor.parameters; - if (toMatch.length == argCount) { - for (int p = 0; p < argCount; p++) - if (toMatch[p] != argumentTypes[p]) - continue nextConstructor; - return constructor; - } - } - } - return null; -} -// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed -// searches up the hierarchy as long as no potential (but not exact) match was found. - -public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes) { - int argCount = argumentTypes.length; - int selectorLength = selector.length; - boolean foundNothing = true; - - if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods - nextMethod : for (int m = methods.length; --m >= 0;) { - MethodBinding method = methods[m]; - if (method.selector.length == selectorLength && CharOperation.equals(method.selector, selector)) { - foundNothing = false; // inner type lookups must know that a method with this name exists - if (method.parameters.length == argCount) { - TypeBinding[] toMatch = method.parameters; - for (int p = 0; p < argCount; p++) - if (toMatch[p] != argumentTypes[p]) - continue nextMethod; - return method; - } - } - } - } else { - MethodBinding[] matchingMethods = getMethods(selector); // takes care of duplicates & default abstract methods - foundNothing = matchingMethods == NoMethods; - nextMethod : for (int m = matchingMethods.length; --m >= 0;) { - MethodBinding method = matchingMethods[m]; - TypeBinding[] toMatch = method.parameters; - if (toMatch.length == argCount) { - for (int p = 0; p < argCount; p++) - if (toMatch[p] != argumentTypes[p]) - continue nextMethod; - return method; - } - } - } - - if (foundNothing) { - if (isInterface()) { - if (superInterfaces.length == 1) - return superInterfaces[0].getExactMethod(selector, argumentTypes); - } else if (superclass != null) { - return superclass.getExactMethod(selector, argumentTypes); - } - } - return null; -} -// NOTE: the type of a field of a source type is resolved when needed - -public FieldBinding getField(char[] fieldName, boolean needResolve) { - // always resolve anyway on source types - int fieldLength = fieldName.length; - for (int f = fields.length; --f >= 0;) { - FieldBinding field = fields[f]; - if (field.name.length == fieldLength && CharOperation.equals(field.name, fieldName)) { - if (resolveTypeFor(field) != null) - return field; - - int newSize = fields.length - 1; - if (newSize == 0) { - fields = NoFields; - } else { - FieldBinding[] newFields = new FieldBinding[newSize]; - System.arraycopy(fields, 0, newFields, 0, f); - System.arraycopy(fields, f + 1, newFields, f, newSize - f); - fields = newFields; - } - return null; - } - } - return null; -} -// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed - -public MethodBinding[] getMethods(char[] selector) { - // handle forward references to potential default abstract methods - addDefaultAbstractMethods(); - - try{ - int count = 0; - int lastIndex = -1; - int selectorLength = selector.length; - if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods - for (int m = 0, length = methods.length; m < length; m++) { - MethodBinding method = methods[m]; - if (method.selector.length == selectorLength && CharOperation.equals(method.selector, selector)) { - count++; - lastIndex = m; - } - } - } else { - boolean foundProblem = false; - int failed = 0; - for (int m = 0, length = methods.length; m < length; m++) { - MethodBinding method = methods[m]; - if (method.selector.length == selectorLength && CharOperation.equals(method.selector, selector)) { - if (resolveTypesFor(method) == null) { - foundProblem = true; - methods[m] = null; // unable to resolve parameters - failed++; - } else if (method.returnType == null) { - foundProblem = true; - } else { - count++; - lastIndex = m; - } - } - } - - if (foundProblem || count > 1) { - for (int m = methods.length; --m >= 0;) { - MethodBinding method = methods[m]; - if (method != null && method.selector.length == selectorLength && CharOperation.equals(method.selector, selector)) { - AbstractMethodDeclaration methodDecl = null; - for (int i = 0; i < m; i++) { - MethodBinding method2 = methods[i]; - if (method2 != null && CharOperation.equals(method.selector, method2.selector)) { - if (method.areParametersEqual(method2)) { - if (methodDecl == null) { - methodDecl = method.sourceMethod(); // cannot be retrieved after binding is lost - scope.problemReporter().duplicateMethodInType(this, methodDecl); - methodDecl.binding = null; - methods[m] = null; - failed++; - } - scope.problemReporter().duplicateMethodInType(this, method2.sourceMethod()); - method2.sourceMethod().binding = null; - methods[i] = null; - failed++; - } - } - } - if (method.returnType == null && methodDecl == null) { // forget method with invalid return type... was kept to detect possible collisions - method.sourceMethod().binding = null; - methods[m] = null; - failed++; - } - } - } - - if (failed > 0) { - int newSize = methods.length - failed; - if (newSize == 0) - return methods = NoMethods; - - MethodBinding[] newMethods = new MethodBinding[newSize]; - for (int i = 0, n = 0, max = methods.length; i < max; i++) - if (methods[i] != null) - newMethods[n++] = methods[i]; - methods = newMethods; - return getMethods(selector); // try again now that the problem methods have been removed - } - } - } - if (count == 1) - return new MethodBinding[] {methods[lastIndex]}; - if (count > 1) { - MethodBinding[] result = new MethodBinding[count]; - count = 0; - for (int m = 0; m <= lastIndex; m++) { - MethodBinding method = methods[m]; - if (method.selector.length == selectorLength && CharOperation.equals(method.selector, selector)) - result[count++] = method; - } - return result; - } - } catch(AbortCompilation e){ - // ensure null methods are removed - MethodBinding[] newMethods = null; - int count = 0; - for (int i = 0, max = methods.length; i < max; i++){ - MethodBinding method = methods[i]; - if (method == null && newMethods == null){ - System.arraycopy(methods, 0, newMethods = new MethodBinding[max], 0, i); - } else if (newMethods != null && method != null) { - newMethods[count++] = method; - } - } - if (newMethods != null){ - System.arraycopy(newMethods, 0, methods = new MethodBinding[count], 0, count); - } - modifiers ^= AccUnresolved; - throw e; - } - return NoMethods; -} -/* Answer the synthetic field for -* or null if one does not exist. -*/ - -public FieldBinding getSyntheticField(LocalVariableBinding actualOuterLocalVariable) { - - if (synthetics == null || synthetics[FIELD_EMUL] == null) return null; - return (FieldBinding) synthetics[FIELD_EMUL].get(actualOuterLocalVariable); -} -public ReferenceBinding[] memberTypes() { - return this.memberTypes; -} -public FieldBinding getUpdatedFieldBinding(FieldBinding targetField, ReferenceBinding newDeclaringClass) { - - if (this.synthetics == null) { - this.synthetics = new Hashtable[4]; - } - if (this.synthetics[RECEIVER_TYPE_EMUL] == null) { - this.synthetics[RECEIVER_TYPE_EMUL] = new Hashtable(5); - } - - Hashtable fieldMap = (Hashtable) this.synthetics[RECEIVER_TYPE_EMUL].get(targetField); - if (fieldMap == null) { - fieldMap = new Hashtable(5); - this.synthetics[RECEIVER_TYPE_EMUL].put(targetField, fieldMap); - } - FieldBinding updatedField = (FieldBinding) fieldMap.get(newDeclaringClass); - if (updatedField == null){ - updatedField = new FieldBinding(targetField, newDeclaringClass); - fieldMap.put(newDeclaringClass, updatedField); - } - return updatedField; -} - -public MethodBinding getUpdatedMethodBinding(MethodBinding targetMethod, ReferenceBinding newDeclaringClass) { - - if (this.synthetics == null) { - this.synthetics = new Hashtable[4]; - } - if (this.synthetics[RECEIVER_TYPE_EMUL] == null) { - this.synthetics[RECEIVER_TYPE_EMUL] = new Hashtable(5); - } - - - Hashtable methodMap = (Hashtable) synthetics[RECEIVER_TYPE_EMUL].get(targetMethod); - if (methodMap == null) { - methodMap = new Hashtable(5); - this.synthetics[RECEIVER_TYPE_EMUL].put(targetMethod, methodMap); - } - MethodBinding updatedMethod = (MethodBinding) methodMap.get(newDeclaringClass); - if (updatedMethod == null){ - updatedMethod = new MethodBinding(targetMethod, newDeclaringClass); - methodMap.put(newDeclaringClass, updatedMethod); - } - return updatedMethod; -} -public boolean hasMemberTypes() { - return this.memberTypes.length > 0; -} -// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed -public MethodBinding[] methods() { - try { - if ((modifiers & AccUnresolved) == 0) - return methods; - - int failed = 0; - for (int m = 0, max = methods.length; m < max; m++) { - if (resolveTypesFor(methods[m]) == null) { - methods[m] = null; // unable to resolve parameters - failed++; - } - } - - for (int m = methods.length; --m >= 0;) { - MethodBinding method = methods[m]; - if (method != null) { - AbstractMethodDeclaration methodDecl = null; - for (int i = 0; i < m; i++) { - MethodBinding method2 = methods[i]; - if (method2 != null && CharOperation.equals(method.selector, method2.selector)) { - if (method.areParametersEqual(method2)) { - if (methodDecl == null) { - methodDecl = method.sourceMethod(); // cannot be retrieved after binding is lost - scope.problemReporter().duplicateMethodInType(this, methodDecl); - methodDecl.binding = null; - methods[m] = null; - failed++; - } - scope.problemReporter().duplicateMethodInType(this, method2.sourceMethod()); - method2.sourceMethod().binding = null; - methods[i] = null; - failed++; - } - } - } - if (method.returnType == null && methodDecl == null) { // forget method with invalid return type... was kept to detect possible collisions - method.sourceMethod().binding = null; - methods[m] = null; - failed++; - } - } - } - - if (failed > 0) { - int newSize = methods.length - failed; - if (newSize == 0) { - methods = NoMethods; - } else { - MethodBinding[] newMethods = new MethodBinding[newSize]; - for (int m = 0, n = 0, max = methods.length; m < max; m++) - if (methods[m] != null) - newMethods[n++] = methods[m]; - methods = newMethods; - } - } - - // handle forward references to potential default abstract methods - addDefaultAbstractMethods(); - } catch(AbortCompilation e){ - // ensure null methods are removed - MethodBinding[] newMethods = null; - int count = 0; - for (int i = 0, max = methods.length; i < max; i++){ - MethodBinding method = methods[i]; - if (method == null && newMethods == null){ - System.arraycopy(methods, 0, newMethods = new MethodBinding[max], 0, i); - } else if (newMethods != null && method != null) { - newMethods[count++] = method; - } - } - if (newMethods != null){ - System.arraycopy(newMethods, 0, methods = new MethodBinding[count], 0, count); - } - modifiers ^= AccUnresolved; - throw e; - } - modifiers ^= AccUnresolved; - return methods; -} -private FieldBinding resolveTypeFor(FieldBinding field) { - if ((field.modifiers & AccUnresolved) == 0) - return field; - - FieldDeclaration[] fieldDecls = scope.referenceContext.fields; - for (int f = 0, length = fieldDecls.length; f < length; f++) { - if (fieldDecls[f].binding != field) - continue; - - field.type = fieldDecls[f].getTypeBinding(scope); - field.modifiers ^= AccUnresolved; - if (!field.type.isValidBinding()) { - scope.problemReporter().fieldTypeProblem(this, fieldDecls[f], field.type); - //scope.problemReporter().invalidType(fieldDecls[f].type, field.type); - fieldDecls[f].binding = null; - return null; - } - if (field.type == VoidBinding) { - scope.problemReporter().variableTypeCannotBeVoid(fieldDecls[f]); - fieldDecls[f].binding = null; - return null; - } - if (field.type.isArrayType() && ((ArrayBinding) field.type).leafComponentType == VoidBinding) { - scope.problemReporter().variableTypeCannotBeVoidArray(fieldDecls[f]); - fieldDecls[f].binding = null; - return null; - } - return field; - } - return null; // should never reach this point -} -private MethodBinding resolveTypesFor(MethodBinding method) { - if ((method.modifiers & AccUnresolved) == 0) - return method; - - AbstractMethodDeclaration methodDecl = method.sourceMethod(); - TypeReference[] exceptionTypes = methodDecl.thrownExceptions; - if (exceptionTypes != null) { - int size = exceptionTypes.length; - method.thrownExceptions = new ReferenceBinding[size]; - ReferenceBinding throwable = scope.getJavaLangThrowable(); - int count = 0; - ReferenceBinding resolvedExceptionType; - for (int i = 0; i < size; i++) { - resolvedExceptionType = (ReferenceBinding) exceptionTypes[i].getTypeBinding(scope); - if (!resolvedExceptionType.isValidBinding()) { - methodDecl.scope.problemReporter().exceptionTypeProblem(this, methodDecl, exceptionTypes[i], resolvedExceptionType); - //methodDecl.scope.problemReporter().invalidType(exceptionTypes[i], resolvedExceptionType); - continue; - } - if (throwable != resolvedExceptionType && !throwable.isSuperclassOf(resolvedExceptionType)) { - methodDecl.scope.problemReporter().cannotThrowType(this, methodDecl, exceptionTypes[i], resolvedExceptionType); - continue; - } - method.thrownExceptions[count++] = resolvedExceptionType; - } - if (count < size) - System.arraycopy(method.thrownExceptions, 0, method.thrownExceptions = new ReferenceBinding[count], 0, count); - } - - boolean foundArgProblem = false; - Argument[] arguments = methodDecl.arguments; - if (arguments != null) { - int size = arguments.length; - method.parameters = new TypeBinding[size]; - for (int i = 0; i < size; i++) { - Argument arg = arguments[i]; - method.parameters[i] = arg.type.getTypeBinding(scope); - if (!method.parameters[i].isValidBinding()) { - methodDecl.scope.problemReporter().argumentTypeProblem(this, methodDecl, arg, method.parameters[i]); - //methodDecl.scope.problemReporter().invalidType(arg, method.parameters[i]); - foundArgProblem = true; - } else if (method.parameters[i] == VoidBinding) { - methodDecl.scope.problemReporter().argumentTypeCannotBeVoid(this, methodDecl, arg); - foundArgProblem = true; - } else if (method.parameters[i].isArrayType() && ((ArrayBinding) method.parameters[i]).leafComponentType == VoidBinding) { - methodDecl.scope.problemReporter().argumentTypeCannotBeVoidArray(this, methodDecl, arg); - foundArgProblem = true; - } - } - } - - boolean foundReturnTypeProblem = false; - if (!method.isConstructor()) { - TypeReference returnType = ((MethodDeclaration) methodDecl).returnType; - if (returnType == null) { - methodDecl.scope.problemReporter().missingReturnType(methodDecl); - method.returnType = null; - foundReturnTypeProblem = true; - } else { - method.returnType = returnType.getTypeBinding(scope); - if (!method.returnType.isValidBinding()) { - methodDecl.scope.problemReporter().returnTypeProblem(this, (MethodDeclaration) methodDecl, method.returnType); - //methodDecl.scope.problemReporter().invalidType(returnType, method.returnType); - method.returnType = null; - foundReturnTypeProblem = true; - } else if (method.returnType.isArrayType() && ((ArrayBinding) method.returnType).leafComponentType == VoidBinding) { - methodDecl.scope.problemReporter().returnTypeCannotBeVoidArray(this, (MethodDeclaration) methodDecl); - method.returnType = null; - foundReturnTypeProblem = true; - } - } - } - if (foundArgProblem) { - methodDecl.binding = null; - return null; - } - if (foundReturnTypeProblem) - return method; // but its still unresolved with a null return type & is still connected to its method declaration - - method.modifiers ^= AccUnresolved; - return method; -} -public final int sourceEnd() { - return scope.referenceContext.sourceEnd; -} -public final int sourceStart() { - return scope.referenceContext.sourceStart; -} -public ReferenceBinding superclass() { - return superclass; -} -public ReferenceBinding[] superInterfaces() { - return superInterfaces; -} -public SyntheticAccessMethodBinding[] syntheticAccessMethods() { - - if (synthetics == null || synthetics[METHOD_EMUL] == null || synthetics[METHOD_EMUL].size() == 0) return null; - - // difficult to compute size up front because of the embedded arrays so assume there is only 1 - int index = 0; - SyntheticAccessMethodBinding[] bindings = new SyntheticAccessMethodBinding[1]; - Enumeration fieldsOrMethods = synthetics[METHOD_EMUL].keys(); - while (fieldsOrMethods.hasMoreElements()) { - - Object fieldOrMethod = fieldsOrMethods.nextElement(); - - if (fieldOrMethod instanceof MethodBinding) { - - SyntheticAccessMethodBinding[] methodAccessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD_EMUL].get(fieldOrMethod); - int numberOfAccessors = 0; - if (methodAccessors[0] != null) numberOfAccessors++; - if (methodAccessors[1] != null) numberOfAccessors++; - if (index + numberOfAccessors > bindings.length) - System.arraycopy(bindings, 0, (bindings = new SyntheticAccessMethodBinding[index + numberOfAccessors]), 0, index); - if (methodAccessors[0] != null) - bindings[index++] = methodAccessors[0]; // super access - if (methodAccessors[1] != null) - bindings[index++] = methodAccessors[1]; // normal access - - } else { - - SyntheticAccessMethodBinding[] fieldAccessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD_EMUL].get(fieldOrMethod); - int numberOfAccessors = 0; - if (fieldAccessors[0] != null) numberOfAccessors++; - if (fieldAccessors[1] != null) numberOfAccessors++; - if (index + numberOfAccessors > bindings.length) - System.arraycopy(bindings, 0, (bindings = new SyntheticAccessMethodBinding[index + numberOfAccessors]), 0, index); - if (fieldAccessors[0] != null) - bindings[index++] = fieldAccessors[0]; // read access - if (fieldAccessors[1] != null) - bindings[index++] = fieldAccessors[1]; // write access - } - } - - // sort them in according to their own indexes - int length; - SyntheticAccessMethodBinding[] sortedBindings = new SyntheticAccessMethodBinding[length = bindings.length]; - for (int i = 0; i < length; i++){ - SyntheticAccessMethodBinding binding = bindings[i]; - sortedBindings[binding.index] = binding; - } - return sortedBindings; -} -/** - * Answer the collection of synthetic fields to append into the classfile - */ -public FieldBinding[] syntheticFields() { - - if (synthetics == null) return null; - - int fieldSize = synthetics[FIELD_EMUL] == null ? 0 : synthetics[FIELD_EMUL].size(); - int literalSize = synthetics[CLASS_LITERAL_EMUL] == null ? 0 :synthetics[CLASS_LITERAL_EMUL].size(); - int totalSize = fieldSize + literalSize; - if (totalSize == 0) return null; - FieldBinding[] bindings = new FieldBinding[totalSize]; - - // add innerclass synthetics - if (synthetics[FIELD_EMUL] != null){ - Enumeration elements = synthetics[FIELD_EMUL].elements(); - for (int i = 0; i < fieldSize; i++) { - SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements.nextElement(); - bindings[synthBinding.index] = synthBinding; - } - } - // add class literal synthetics - if (synthetics[CLASS_LITERAL_EMUL] != null){ - Enumeration elements = synthetics[CLASS_LITERAL_EMUL].elements(); - for (int i = 0; i < literalSize; i++) { - SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements.nextElement(); - bindings[fieldSize+synthBinding.index] = synthBinding; - } - } - return bindings; -} -public String toString() { - String s = "(id="+(id == NoId ? "NoId" : (""+id) ) +")\n"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-4$ //$NON-NLS-1$ - - if (isDeprecated()) s += "deprecated "; //$NON-NLS-1$ - if (isPublic()) s += "public "; //$NON-NLS-1$ - if (isProtected()) s += "protected "; //$NON-NLS-1$ - if (isPrivate()) s += "private "; //$NON-NLS-1$ - if (isAbstract() && isClass()) s += "abstract "; //$NON-NLS-1$ - if (isStatic() && isNestedType()) s += "static "; //$NON-NLS-1$ - if (isFinal()) s += "final "; //$NON-NLS-1$ - - s += isInterface() ? "interface " : "class "; //$NON-NLS-1$ //$NON-NLS-2$ - s += (compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED TYPE"; //$NON-NLS-1$ - - s += "\n\textends "; //$NON-NLS-1$ - s += (superclass != null) ? superclass.debugName() : "NULL TYPE"; //$NON-NLS-1$ - - if (superInterfaces != null) { - if (superInterfaces != NoSuperInterfaces) { - s += "\n\timplements : "; //$NON-NLS-1$ - for (int i = 0, length = superInterfaces.length; i < length; i++) { - if (i > 0) - s += ", "; //$NON-NLS-1$ - s += (superInterfaces[i] != null) ? superInterfaces[i].debugName() : "NULL TYPE"; //$NON-NLS-1$ - } - } - } else { - s += "NULL SUPERINTERFACES"; //$NON-NLS-1$ - } - - if (enclosingType() != null) { - s += "\n\tenclosing type : "; //$NON-NLS-1$ - s += enclosingType().debugName(); - } - - if (fields != null) { - if (fields != NoFields) { - s += "\n/* fields */"; //$NON-NLS-1$ - for (int i = 0, length = fields.length; i < length; i++) - s += (fields[i] != null) ? "\n" + fields[i].toString() : "\nNULL FIELD"; //$NON-NLS-1$ //$NON-NLS-2$ - } - } else { - s += "NULL FIELDS"; //$NON-NLS-1$ - } - - if (methods != null) { - if (methods != NoMethods) { - s += "\n/* methods */"; //$NON-NLS-1$ - for (int i = 0, length = methods.length; i < length; i++) - s += (methods[i] != null) ? "\n" + methods[i].toString() : "\nNULL METHOD"; //$NON-NLS-1$ //$NON-NLS-2$ - } - } else { - s += "NULL METHODS"; //$NON-NLS-1$ - } - - if (memberTypes != null) { - if (memberTypes != NoMemberTypes) { - s += "\n/* members */"; //$NON-NLS-1$ - for (int i = 0, length = memberTypes.length; i < length; i++) - s += (memberTypes[i] != null) ? "\n" + memberTypes[i].toString() : "\nNULL TYPE"; //$NON-NLS-1$ //$NON-NLS-2$ - } - } else { - s += "NULL MEMBER TYPES"; //$NON-NLS-1$ - } - - s += "\n\n\n"; //$NON-NLS-1$ - return s; -} -void verifyMethods(MethodVerifier verifier) { - verifier.verify(this); - - for (int i = memberTypes.length; --i >= 0;) - ((SourceTypeBinding) memberTypes[i]).verifyMethods(verifier); -} - -/* Answer the synthetic field for -* or null if one does not exist. -*/ - -public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, boolean onlyExactMatch) { - - if (synthetics == null || synthetics[FIELD_EMUL] == null) return null; - FieldBinding field = (FieldBinding) synthetics[FIELD_EMUL].get(targetEnclosingType); - if (field != null) return field; - - // type compatibility : to handle cases such as - // class T { class M{}} - // class S extends T { class N extends M {}} --> need to use S as a default enclosing instance for the super constructor call in N(). - if (!onlyExactMatch){ - Enumeration accessFields = synthetics[FIELD_EMUL].elements(); - while (accessFields.hasMoreElements()) { - field = (FieldBinding) accessFields.nextElement(); - if (CharOperation.prefixEquals(SyntheticArgumentBinding.EnclosingInstancePrefix, field.name) - && targetEnclosingType.isSuperclassOf((ReferenceBinding) field.type)) - return field; - } - } - return null; -} -}