X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SourceTypeBinding.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SourceTypeBinding.java index 51d892a..266a332 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SourceTypeBinding.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/SourceTypeBinding.java @@ -1,18 +1,19 @@ /******************************************************************************* - * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * Copyright (c) 2000, 2003 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-v05.html - * + * http://www.eclipse.org/legal/cpl-v10.html + * * Contributors: * IBM Corporation - initial API and implementation - ******************************************************************************/ + *******************************************************************************/ package net.sourceforge.phpdt.internal.compiler.lookup; import java.util.Enumeration; import java.util.Hashtable; +import net.sourceforge.phpdt.core.compiler.CharOperation; import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration; import net.sourceforge.phpdt.internal.compiler.ast.Argument; import net.sourceforge.phpdt.internal.compiler.ast.AssertStatement; @@ -21,10 +22,9 @@ import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration; import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration; import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration; import net.sourceforge.phpdt.internal.compiler.ast.TypeReference; -import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions; import net.sourceforge.phpdt.internal.compiler.impl.Constant; import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; -import net.sourceforge.phpdt.internal.compiler.util.CharOperation; + public class SourceTypeBinding extends ReferenceBinding { public ReferenceBinding superclass; @@ -35,13 +35,14 @@ public class SourceTypeBinding extends ReferenceBinding { public ClassScope scope; - // Synthetics are separated into 4 categories: methods, fields, class literals and changed declaring class bindings + // Synthetics are separated into 4 categories: methods, super methods, fields, class literals and changed declaring class bindings public final static int METHOD = 0; public final static int FIELD = 1; public final static int CLASS_LITERAL = 2; public final static int CHANGED_DECLARING_CLASS = 3; - + Hashtable[] synthetics; + protected SourceTypeBinding() { } public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassScope scope) { @@ -52,7 +53,7 @@ public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassSc this.sourceName = scope.referenceContext.name; this.scope = scope; - computeId(); +// computeId(); } private void addDefaultAbstractMethod(MethodBinding abstractMethod) { MethodBinding defaultAbstract = new MethodBinding( @@ -74,7 +75,7 @@ public void addDefaultAbstractMethods() { tagBits |= KnowsDefaultAbstractMethods; if (isClass() && isAbstract()) { - if (fPackage.environment.options.targetJDK >= CompilerOptions.JDK1_2) return; // no longer added for post 1.2 targets +// if (fPackage.environment.options.targetJDK >= CompilerOptions.JDK1_2) return; // no longer added for post 1.2 targets ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][]; int lastPosition = 0; @@ -114,14 +115,14 @@ public FieldBinding addSyntheticField(LocalVariableBinding actualOuterLocalVaria if (synthetics[FIELD] == null) { synthetics[FIELD] = new Hashtable(5); } - + FieldBinding synthField = (FieldBinding) synthetics[FIELD].get(actualOuterLocalVariable); if (synthField == null) { synthField = new SyntheticFieldBinding( - CharOperation.concat(SyntheticArgumentBinding.OuterLocalPrefix, actualOuterLocalVariable.name), - actualOuterLocalVariable.type, - AccPrivate | AccFinal | AccSynthetic, - this, + CharOperation.concat(SyntheticArgumentBinding.OuterLocalPrefix, actualOuterLocalVariable.name), + actualOuterLocalVariable.type, + AccPrivate | AccFinal ,//| AccSynthetic, + this, Constant.NotAConstant, synthetics[FIELD].size()); synthetics[FIELD].put(actualOuterLocalVariable, synthField); @@ -170,7 +171,7 @@ public FieldBinding addSyntheticField(ReferenceBinding enclosingType) { SyntheticArgumentBinding.EnclosingInstancePrefix, String.valueOf(enclosingType.depth()).toCharArray()), enclosingType, - AccPrivate | AccFinal | AccSynthetic, + AccDefault | AccFinal,// | AccSynthetic, this, Constant.NotAConstant, synthetics[FIELD].size()); @@ -187,7 +188,7 @@ public FieldBinding addSyntheticField(ReferenceBinding enclosingType) { break; } } - } + } return synthField; } /* Add a new synthetic field for a class literal access. @@ -209,7 +210,7 @@ public FieldBinding addSyntheticField(TypeBinding targetType, BlockScope blockSc synthField = new SyntheticFieldBinding( ("class$" + synthetics[CLASS_LITERAL].size()).toCharArray(), //$NON-NLS-1$ blockScope.getJavaLangClass(), - AccDefault | AccStatic | AccSynthetic, + AccDefault | AccStatic,// | AccSynthetic, this, Constant.NotAConstant, synthetics[CLASS_LITERAL].size()); @@ -226,7 +227,7 @@ public FieldBinding addSyntheticField(TypeBinding targetType, BlockScope blockSc break; } } - } + } return synthField; } @@ -247,10 +248,10 @@ public FieldBinding addSyntheticField(AssertStatement assertStatement, BlockScop synthField = new SyntheticFieldBinding( "$assertionsDisabled".toCharArray(), //$NON-NLS-1$ BooleanBinding, - AccDefault | AccStatic | AccSynthetic | AccFinal, + AccDefault | AccStatic | AccFinal,//| AccSynthetic | AccFinal, this, Constant.NotAConstant, - 0); + synthetics[FIELD].size()); synthetics[FIELD].put("assertionEmulation", synthField); //$NON-NLS-1$ } // ensure there is not already such a field defined by the user @@ -295,7 +296,7 @@ public SyntheticAccessMethodBinding addSyntheticMethod(FieldBinding targetField, if (accessors == null) { accessMethod = new SyntheticAccessMethodBinding(targetField, isReadAccess, this); synthetics[METHOD].put(targetField, accessors = new SyntheticAccessMethodBinding[2]); - accessors[isReadAccess ? 0 : 1] = accessMethod; + accessors[isReadAccess ? 0 : 1] = accessMethod; } else { if ((accessMethod = accessors[isReadAccess ? 0 : 1]) == null) { accessMethod = new SyntheticAccessMethodBinding(targetField, isReadAccess, this); @@ -305,10 +306,11 @@ public SyntheticAccessMethodBinding addSyntheticMethod(FieldBinding targetField, 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) { +public SyntheticAccessMethodBinding addSyntheticMethod(MethodBinding targetMethod, boolean isSuperAccess) { if (synthetics == null) { synthetics = new Hashtable[4]; @@ -317,10 +319,17 @@ public SyntheticAccessMethodBinding addSyntheticMethod(MethodBinding targetMetho synthetics[METHOD] = new Hashtable(5); } - SyntheticAccessMethodBinding accessMethod = (SyntheticAccessMethodBinding) synthetics[METHOD].get(targetMethod); - if (accessMethod == null) { - accessMethod = new SyntheticAccessMethodBinding(targetMethod, this); - synthetics[METHOD].put(targetMethod, accessMethod); + SyntheticAccessMethodBinding accessMethod = null; + SyntheticAccessMethodBinding[] accessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD].get(targetMethod); + if (accessors == null) { + accessMethod = new SyntheticAccessMethodBinding(targetMethod, isSuperAccess, this); + synthetics[METHOD].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; } @@ -341,7 +350,9 @@ void faultInTypesForFieldsAndMethods() { // NOTE: the type of each field of a source type is resolved when needed public FieldBinding[] fields() { - + if (fields==null) { + fields = new FieldBinding[0]; + } try { int failed = 0; for (int f = 0, max = fields.length; f < max; f++) { @@ -354,7 +365,7 @@ public FieldBinding[] fields() { 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) @@ -375,7 +386,7 @@ public FieldBinding[] fields() { } if (newFields != null){ System.arraycopy(newFields, 0, fields = new FieldBinding[count], 0, count); - } + } throw e; } return fields; @@ -532,7 +543,7 @@ public MethodBinding[] getMethods(char[] selector) { } } } - + if (foundProblem || count > 1) { for (int m = methods.length; --m >= 0;) { MethodBinding method = methods[m]; @@ -563,12 +574,12 @@ public MethodBinding[] getMethods(char[] selector) { } } } - + 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) @@ -604,10 +615,10 @@ public MethodBinding[] getMethods(char[] selector) { } if (newMethods != null){ System.arraycopy(newMethods, 0, methods = new MethodBinding[count], 0, count); - } + } modifiers ^= AccUnresolved; throw e; - } + } return NoMethods; } /* Answer the synthetic field for @@ -615,7 +626,7 @@ public MethodBinding[] getMethods(char[] selector) { */ public FieldBinding getSyntheticField(LocalVariableBinding actualOuterLocalVariable) { - + if (synthetics == null || synthetics[FIELD] == null) return null; return (FieldBinding) synthetics[FIELD].get(actualOuterLocalVariable); } @@ -672,7 +683,7 @@ 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) { @@ -680,7 +691,7 @@ public MethodBinding[] methods() { failed++; } } - + for (int m = methods.length; --m >= 0;) { MethodBinding method = methods[m]; if (method != null) { @@ -710,7 +721,7 @@ public MethodBinding[] methods() { } } } - + if (failed > 0) { int newSize = methods.length - failed; if (newSize == 0) { @@ -723,7 +734,7 @@ public MethodBinding[] methods() { methods = newMethods; } } - + // handle forward references to potential default abstract methods addDefaultAbstractMethods(); } catch(AbortCompilation e){ @@ -740,10 +751,10 @@ public MethodBinding[] methods() { } if (newMethods != null){ System.arraycopy(newMethods, 0, methods = new MethodBinding[count], 0, count); - } + } modifiers ^= AccUnresolved; throw e; - } + } modifiers ^= AccUnresolved; return methods; } @@ -872,7 +883,7 @@ public ReferenceBinding[] superInterfaces() { return superInterfaces; } public SyntheticAccessMethodBinding[] syntheticAccessMethods() { - + if (synthetics == null || synthetics[METHOD] == null || synthetics[METHOD].size() == 0) return null; // difficult to compute size up front because of the embedded arrays so assume there is only 1 @@ -880,22 +891,34 @@ public SyntheticAccessMethodBinding[] syntheticAccessMethods() { SyntheticAccessMethodBinding[] bindings = new SyntheticAccessMethodBinding[1]; Enumeration fieldsOrMethods = synthetics[METHOD].keys(); while (fieldsOrMethods.hasMoreElements()) { + Object fieldOrMethod = fieldsOrMethods.nextElement(); + if (fieldOrMethod instanceof MethodBinding) { - if (index + 1 > bindings.length) - System.arraycopy(bindings, 0, (bindings = new SyntheticAccessMethodBinding[index + 1]), 0, index); - bindings[index++] = (SyntheticAccessMethodBinding) synthetics[METHOD].get(fieldOrMethod); + + SyntheticAccessMethodBinding[] methodAccessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD].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].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]; - if (fieldAccessors[1] != null) - bindings[index++] = fieldAccessors[1]; + if (fieldAccessors[0] != null) + bindings[index++] = fieldAccessors[0]; // read access + if (fieldAccessors[1] != null) + bindings[index++] = fieldAccessors[1]; // write access } } @@ -912,7 +935,7 @@ public SyntheticAccessMethodBinding[] syntheticAccessMethods() { * Answer the collection of synthetic fields to append into the classfile */ public FieldBinding[] syntheticFields() { - + if (synthetics == null) return null; int fieldSize = synthetics[FIELD] == null ? 0 : synthetics[FIELD].size(); @@ -1018,7 +1041,7 @@ void verifyMethods(MethodVerifier verifier) { * or null if one does not exist. */ -public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, BlockScope scope, boolean onlyExactMatch) { +public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, boolean onlyExactMatch) { if (synthetics == null || synthetics[FIELD] == null) return null; FieldBinding field = (FieldBinding) synthetics[FIELD].get(targetEnclosingType); @@ -1028,10 +1051,10 @@ public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, Bloc // 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 enum = synthetics[FIELD].elements(); - while (enum.hasMoreElements()) { - field = (FieldBinding) enum.nextElement(); - if (CharOperation.startsWith(field.name, SyntheticArgumentBinding.EnclosingInstancePrefix) + Enumeration e = synthetics[FIELD].elements(); + while (e.hasMoreElements()) { + field = (FieldBinding) e.nextElement(); + if (CharOperation.prefixEquals(SyntheticArgumentBinding.EnclosingInstancePrefix, field.name) && targetEnclosingType.isSuperclassOf((ReferenceBinding) field.type)) return field; }