View | Details | Raw Unified | Return to bug 88395 | Differences between
and this patch

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ClassFile.java (-5 / +114 lines)
Lines 1237-1242 Link Here
1237
						// generate a method info to define <enum>#valueOf(String)
1237
						// generate a method info to define <enum>#valueOf(String)
1238
						addSyntheticEnumValueOfMethod(syntheticMethod);
1238
						addSyntheticEnumValueOfMethod(syntheticMethod);
1239
						break;
1239
						break;
1240
					case SyntheticMethodBinding.SwitchTable :
1241
						// generate a method info to define the switch table synthetic method
1242
						addSyntheticSwitchTable(syntheticMethod);
1240
				}
1243
				}
1241
			}
1244
			}
1242
		}
1245
		}
Lines 1316-1321 Link Here
1316
			
1319
			
1317
	}
1320
	}
1318
1321
1322
	public void addSyntheticSwitchTable(SyntheticMethodBinding methodBinding) {
1323
		generateMethodInfoHeader(methodBinding);
1324
		// We know that we won't get more than 1 attribute: the code attribute 
1325
		contents[contentsOffset++] = 0;
1326
		contents[contentsOffset++] = 2;
1327
		// Code attribute
1328
		int codeAttributeOffset = contentsOffset;
1329
		generateCodeAttributeHeader();
1330
		codeStream.init(this);
1331
		codeStream.generateSyntheticBodyForSwitchTable(methodBinding);
1332
		completeCodeAttributeForSyntheticMethod(
1333
			true,
1334
			methodBinding,
1335
			codeAttributeOffset,
1336
			((SourceTypeBinding) methodBinding.declaringClass)
1337
				.scope
1338
				.referenceCompilationUnit()
1339
				.compilationResult
1340
				.lineSeparatorPositions);
1341
		// add the synthetic attribute
1342
		int syntheticAttributeNameIndex =
1343
			constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
1344
		contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
1345
		contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
1346
		// the length of a synthetic attribute is equals to 0
1347
		contents[contentsOffset++] = 0;
1348
		contents[contentsOffset++] = 0;
1349
		contents[contentsOffset++] = 0;
1350
		contents[contentsOffset++] = 0;
1351
	}
1319
	/**
1352
	/**
1320
	 * INTERNAL USE-ONLY
1353
	 * INTERNAL USE-ONLY
1321
	 *  Generate the bytes for a synthetic method that implements Enum#values() for a given enum type
1354
	 *  Generate the bytes for a synthetic method that implements Enum#values() for a given enum type
Lines 2575-2580 Link Here
2575
		SyntheticMethodBinding binding,
2608
		SyntheticMethodBinding binding,
2576
		int codeAttributeOffset,
2609
		int codeAttributeOffset,
2577
		int[] startLineIndexes) {
2610
		int[] startLineIndexes) {
2611
		
2612
		this.completeCodeAttributeForSyntheticMethod(
2613
				false,
2614
				binding,
2615
				codeAttributeOffset,
2616
				startLineIndexes);
2617
	}
2618
2619
	/**
2620
	 * INTERNAL USE-ONLY
2621
	 * That method completes the creation of the code attribute by setting
2622
	 * - the attribute_length
2623
	 * - max_stack
2624
	 * - max_locals
2625
	 * - code_length
2626
	 * - exception table
2627
	 * - and debug attributes if necessary.
2628
	 *
2629
	 * @param binding org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
2630
	 * @param codeAttributeOffset <CODE>int</CODE>
2631
	 */
2632
	public void completeCodeAttributeForSyntheticMethod(
2633
		boolean hasExceptionHandlers,
2634
		SyntheticMethodBinding binding,
2635
		int codeAttributeOffset,
2636
		int[] startLineIndexes) {
2578
		// reinitialize the contents with the byte modified by the code stream
2637
		// reinitialize the contents with the byte modified by the code stream
2579
		this.contents = codeStream.bCodeStream;
2638
		this.contents = codeStream.bCodeStream;
2580
		int localContentsOffset = codeStream.classFileOffset;
2639
		int localContentsOffset = codeStream.classFileOffset;
Lines 2596-2605 Link Here
2596
		if ((localContentsOffset + 40) >= this.contents.length) {
2655
		if ((localContentsOffset + 40) >= this.contents.length) {
2597
			resizeContents(40);
2656
			resizeContents(40);
2598
		}
2657
		}
2599
		// there is no exception table, so we need to offset by 2 the current offset and move 
2658
		
2600
		// on the attribute generation
2659
		if (hasExceptionHandlers) {
2601
		contents[localContentsOffset++] = 0;
2660
			// write the exception table
2602
		contents[localContentsOffset++] = 0;
2661
			int exceptionHandlersNumber = codeStream.exceptionHandlersCounter;
2662
			ExceptionLabel[] exceptionHandlers = codeStream.exceptionHandlers;
2663
			int exSize = exceptionHandlersNumber * 8 + 2;
2664
			if (exSize + localContentsOffset >= this.contents.length) {
2665
				resizeContents(exSize);
2666
			}
2667
			// there is no exception table, so we need to offset by 2 the current offset and move 
2668
			// on the attribute generation
2669
			this.contents[localContentsOffset++] = (byte) (exceptionHandlersNumber >> 8);
2670
			this.contents[localContentsOffset++] = (byte) exceptionHandlersNumber;
2671
			for (int i = 0, max = codeStream.exceptionHandlersIndex; i < max; i++) {
2672
				ExceptionLabel exceptionHandler = exceptionHandlers[i];
2673
				if (exceptionHandler != null) {
2674
					int start = exceptionHandler.start;
2675
					this.contents[localContentsOffset++] = (byte) (start >> 8);
2676
					this.contents[localContentsOffset++] = (byte) start;
2677
					int end = exceptionHandler.end;
2678
					this.contents[localContentsOffset++] = (byte) (end >> 8);
2679
					this.contents[localContentsOffset++] = (byte) end;
2680
					int handlerPC = exceptionHandler.position;
2681
					this.contents[localContentsOffset++] = (byte) (handlerPC >> 8);
2682
					this.contents[localContentsOffset++] = (byte) handlerPC;
2683
					if (exceptionHandler.exceptionType == null) {
2684
						// any exception handler
2685
						this.contents[localContentsOffset++] = 0;
2686
						this.contents[localContentsOffset++] = 0;
2687
					} else {
2688
						int nameIndex;
2689
						switch(exceptionHandler.exceptionType.id) {
2690
							case T_null :
2691
								/* represents ClassNotFoundException, see class literal access*/
2692
								nameIndex = constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
2693
								break;
2694
							case T_long :
2695
								/* represents NoSuchFieldError, see switch table generation*/
2696
								nameIndex = constantPool.literalIndexForType(ConstantPool.JavaLangNoSuchFieldErrorConstantPoolName);
2697
								break;
2698
							default:
2699
								nameIndex = constantPool.literalIndexForType(exceptionHandler.exceptionType.constantPoolName());
2700
						}
2701
						this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
2702
						this.contents[localContentsOffset++] = (byte) nameIndex;
2703
					}
2704
				}
2705
			}
2706
		} else {
2707
			// there is no exception table, so we need to offset by 2 the current offset and move 
2708
			// on the attribute generation
2709
			contents[localContentsOffset++] = 0;
2710
			contents[localContentsOffset++] = 0;
2711
		}
2603
		// debug attributes
2712
		// debug attributes
2604
		int codeAttributeAttributeOffset = localContentsOffset;
2713
		int codeAttributeAttributeOffset = localContentsOffset;
2605
		int attributeNumber = 0;
2714
		int attributeNumber = 0;
Lines 2769-2775 Link Here
2769
		contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
2878
		contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
2770
		contentsOffset = localContentsOffset;
2879
		contentsOffset = localContentsOffset;
2771
	}
2880
	}
2772
2881
	
2773
	/**
2882
	/**
2774
	 * INTERNAL USE-ONLY
2883
	 * INTERNAL USE-ONLY
2775
	 * Complete the creation of a method info by setting up the number of attributes at the right offset.
2884
	 * Complete the creation of a method info by setting up the number of attributes at the right offset.
(-)compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java (-6 / +30 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.ast;
11
package org.eclipse.jdt.internal.compiler.ast;
12
12
13
import java.util.HashMap;
14
13
import org.eclipse.jdt.internal.compiler.ASTVisitor;
15
import org.eclipse.jdt.internal.compiler.ASTVisitor;
14
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
16
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
15
import org.eclipse.jdt.internal.compiler.codegen.*;
17
import org.eclipse.jdt.internal.compiler.codegen.*;
Lines 32-37 Link Here
32
	public int caseCount;
34
	public int caseCount;
33
	int[] constants;
35
	int[] constants;
34
	
36
	
37
	public HashMap synthetics; // use for switch on enums types
38
	
35
	// for local variables table attributes
39
	// for local variables table attributes
36
	int preSwitchInitStateIndex = -1;
40
	int preSwitchInitStateIndex = -1;
37
	int mergedInitStateIndex = -1;
41
	int mergedInitStateIndex = -1;
Lines 75-80 Link Here
75
				}
79
				}
76
			}
80
			}
77
	
81
	
82
			final TypeBinding resolvedTypeBinding = this.expression.resolvedType;
83
			if (caseCount > 0 && resolvedTypeBinding.isEnum()) {
84
				final SourceTypeBinding sourceTypeBinding = this.scope.classScope().referenceContext.binding;
85
				if (this.synthetics == null) {
86
					this.synthetics = new HashMap(2);
87
				}
88
				this.synthetics.put(resolvedTypeBinding, sourceTypeBinding.addSyntheticMethodForSwitchEnum(resolvedTypeBinding));
89
			}
78
			// if no default case, then record it may jump over the block directly to the end
90
			// if no default case, then record it may jump over the block directly to the end
79
			if (defaultCase == null) {
91
			if (defaultCase == null) {
80
				// only retain the potential initializations
92
				// only retain the potential initializations
Lines 120-127 Link Here
120
			if (defaultCase != null) {
132
			if (defaultCase != null) {
121
				defaultCase.targetLabel = defaultLabel;
133
				defaultCase.targetLabel = defaultLabel;
122
			}
134
			}
123
			// generate expression testes
135
124
			expression.generateCode(currentScope, codeStream, needSwitch);
136
			final TypeBinding resolvedType = this.expression.resolvedType;
137
			if (resolvedType.isEnum()) {
138
				if (needSwitch) {
139
					// go through the translation table
140
					codeStream.invokestatic((SyntheticMethodBinding) this.synthetics.get(resolvedType));
141
					expression.generateCode(currentScope, codeStream, true);
142
					// get enum constant ordinal()
143
					codeStream.invokeEnumOrdinal(resolvedType.constantPoolName());
144
					codeStream.iaload();
145
				} else {
146
					// no need to go through the translation table
147
					expression.generateCode(currentScope, codeStream, false);
148
				}
149
			} else {
150
				// generate expression
151
				expression.generateCode(currentScope, codeStream, needSwitch); // value required (switch without cases)
152
			}
125
			// generate the appropriate switch table/lookup bytecode
153
			// generate the appropriate switch table/lookup bytecode
126
			if (needSwitch) {
154
			if (needSwitch) {
127
				int[] sortedIndexes = new int[this.caseCount];
155
				int[] sortedIndexes = new int[this.caseCount];
Lines 133-142 Link Here
133
				System.arraycopy(this.constants, 0, (localKeysCopy = new int[this.caseCount]), 0, this.caseCount);
161
				System.arraycopy(this.constants, 0, (localKeysCopy = new int[this.caseCount]), 0, this.caseCount);
134
				CodeStream.sort(localKeysCopy, 0, this.caseCount - 1, sortedIndexes);
162
				CodeStream.sort(localKeysCopy, 0, this.caseCount - 1, sortedIndexes);
135
163
136
				// for enum constants, actually switch on constant ordinal()
137
				if (this.expression.resolvedType.isEnum()) {
138
					codeStream.invokeEnumOrdinal(this.expression.resolvedType.constantPoolName());
139
				}
140
				int max = localKeysCopy[this.caseCount - 1];
164
				int max = localKeysCopy[this.caseCount - 1];
141
				int min = localKeysCopy[0];
165
				int min = localKeysCopy[0];
142
				if ((long) (caseCount * 2.5) > ((long) max - (long) min)) {
166
				if ((long) (caseCount * 2.5) > ((long) max - (long) min)) {
(-)compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java (+48 lines)
Lines 10-20 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.codegen;
11
package org.eclipse.jdt.internal.compiler.codegen;
12
12
13
import org.eclipse.jdt.core.compiler.CharOperation;
13
import org.eclipse.jdt.internal.compiler.*;
14
import org.eclipse.jdt.internal.compiler.*;
14
15
15
import org.eclipse.jdt.internal.compiler.impl.*;
16
import org.eclipse.jdt.internal.compiler.impl.*;
16
import org.eclipse.jdt.internal.compiler.ast.*;
17
import org.eclipse.jdt.internal.compiler.ast.*;
17
import org.eclipse.jdt.internal.compiler.classfmt.*;
18
import org.eclipse.jdt.internal.compiler.classfmt.*;
19
import org.eclipse.jdt.internal.compiler.env.IConstants;
18
import org.eclipse.jdt.internal.compiler.flow.*;
20
import org.eclipse.jdt.internal.compiler.flow.*;
19
import org.eclipse.jdt.internal.compiler.lookup.*;
21
import org.eclipse.jdt.internal.compiler.lookup.*;
20
22
Lines 1998-2003 Link Here
1998
	this.invokeJavaLangIllegalArgumentExceptionStringConstructor();
2000
	this.invokeJavaLangIllegalArgumentExceptionStringConstructor();
1999
	this.athrow();
2001
	this.athrow();
2000
}
2002
}
2003
public void generateSyntheticBodyForSwitchTable(SyntheticMethodBinding methodBinding) {
2004
	ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
2005
	initializeMaxLocals(methodBinding);
2006
	final Label nullLabel = new Label(this);
2007
	FieldBinding syntheticFieldBinding = methodBinding.targetReadField;
2008
2009
	this.getstatic(syntheticFieldBinding);
2010
	this.dup();
2011
	this.ifnonnull(nullLabel);
2012
	this.pop();
2013
	ReferenceBinding enumBinding = (ReferenceBinding) methodBinding.targetEnumType;
2014
	char[] signature = "()".toCharArray(); //$NON-NLS-1$
2015
	ArrayBinding arrayBinding = scope.createArrayType(enumBinding, 1);
2016
	signature = CharOperation.concat(signature, arrayBinding.constantPoolName());
2017
	this.invoke(OPC_invokestatic, 0, 1, enumBinding.constantPoolName(), TypeConstants.VALUES, signature);
2018
	this.arraylength();
2019
	this.newarray(INT_ARRAY);
2020
	this.putstatic(syntheticFieldBinding);
2021
	final FieldBinding[] fields = enumBinding.fields();
2022
	if (fields != null) {
2023
		for (int i = 0, max = fields.length; i < max; i++) {
2024
			FieldBinding fieldBinding = fields[i];
2025
			if ((fieldBinding.getAccessFlags() & IConstants.AccEnum) != 0) {
2026
				final Label endLabel = new Label(this);
2027
				final ExceptionLabel anyExceptionHandler = new ExceptionLabel(this, BaseTypes.LongBinding /* represents NoSuchFieldError*/);
2028
				this.getstatic(syntheticFieldBinding);
2029
				this.getstatic(fieldBinding);
2030
				this.invokeEnumOrdinal(enumBinding.constantPoolName());
2031
				this.generateInlinedValue(fieldBinding.id);
2032
				this.iastore();
2033
				anyExceptionHandler.placeEnd();
2034
				this.goto_(endLabel);
2035
				// Generate the body of the exception handler
2036
				final int saveStackSize = stackDepth;
2037
				stackDepth = 1;
2038
				anyExceptionHandler.place();
2039
				this.pop(); // we don't use it so we can pop it
2040
				stackDepth = saveStackSize;
2041
				endLabel.place();				
2042
			}
2043
		}
2044
	}
2045
	this.getstatic(syntheticFieldBinding);
2046
	nullLabel.place();
2047
	areturn();
2048
}
2001
public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) {
2049
public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) {
2002
	initializeMaxLocals(accessBinding);
2050
	initializeMaxLocals(accessBinding);
2003
	FieldBinding fieldBinding = accessBinding.targetReadField;
2051
	FieldBinding fieldBinding = accessBinding.targetReadField;
(-)compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java (+1 lines)
Lines 150-155 Link Here
150
	public static final char[] JavaLangIntegerConstantPoolName = "java/lang/Integer".toCharArray(); //$NON-NLS-1$
150
	public static final char[] JavaLangIntegerConstantPoolName = "java/lang/Integer".toCharArray(); //$NON-NLS-1$
151
	public static final char[] JavaLangLongConstantPoolName = "java/lang/Long".toCharArray(); //$NON-NLS-1$
151
	public static final char[] JavaLangLongConstantPoolName = "java/lang/Long".toCharArray(); //$NON-NLS-1$
152
	public static final char[] JavaLangNoClassDefFoundErrorConstantPoolName = "java/lang/NoClassDefFoundError".toCharArray(); //$NON-NLS-1$
152
	public static final char[] JavaLangNoClassDefFoundErrorConstantPoolName = "java/lang/NoClassDefFoundError".toCharArray(); //$NON-NLS-1$
153
	public static final char[] JavaLangNoSuchFieldErrorConstantPoolName = "java/lang/NoSuchFieldError".toCharArray(); //$NON-NLS-1$
153
	public static final char[] JavaLangObjectConstantPoolName = "java/lang/Object".toCharArray(); //$NON-NLS-1$
154
	public static final char[] JavaLangObjectConstantPoolName = "java/lang/Object".toCharArray(); //$NON-NLS-1$
154
	public static final char[] JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME = "java/lang/reflect/AccessibleObject".toCharArray(); //$NON-NLS-1$
155
	public static final char[] JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME = "java/lang/reflect/AccessibleObject".toCharArray(); //$NON-NLS-1$
155
	public static final char[] JAVALANGREFLECTARRAY_CONSTANTPOOLNAME = "java/lang/reflect/Array".toCharArray(); //$NON-NLS-1$
156
	public static final char[] JAVALANGREFLECTARRAY_CONSTANTPOOLNAME = "java/lang/reflect/Array".toCharArray(); //$NON-NLS-1$
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java (+72 lines)
Lines 369-374 Link Here
369
	}
369
	}
370
	return accessMethod;
370
	return accessMethod;
371
}
371
}
372
/*
373
 * Add a synthetic field to handle the cache of the switch translation table for the corresponding enum type 
374
 */
375
public SyntheticFieldBinding addSyntheticFieldForSwitchEnum(char[] fieldName, String key) {
376
	if (synthetics == null)
377
		synthetics = new HashMap[4];
378
	if (synthetics[FIELD_EMUL] == null)
379
		synthetics[FIELD_EMUL] = new HashMap(5);
380
381
	SyntheticFieldBinding synthField = (SyntheticFieldBinding) synthetics[FIELD_EMUL].get(key); //$NON-NLS-1$
382
	if (synthField == null) {
383
		synthField = new SyntheticFieldBinding(
384
			fieldName,
385
			scope.createArrayType(BaseTypes.IntBinding,1),
386
			AccPrivate | AccStatic | AccSynthetic | AccFinal,
387
			this,
388
			Constant.NotAConstant,
389
			synthetics[FIELD_EMUL].size());
390
		synthetics[FIELD_EMUL].put(key, synthField);
391
	}
392
	// ensure there is not already such a field defined by the user
393
	boolean needRecheck;
394
	int index = 0;
395
	do {
396
		needRecheck = false;
397
		FieldBinding existingField;
398
		if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
399
			TypeDeclaration typeDecl = scope.referenceContext;
400
			for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
401
				FieldDeclaration fieldDecl = typeDecl.fields[i];
402
				if (fieldDecl.binding == existingField) {
403
					synthField.name = CharOperation.concat(
404
						TypeConstants.SYNTHETIC_ENUM_VALUES,
405
						("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
406
					needRecheck = true;
407
					break;
408
				}
409
			}
410
		}
411
	} while (needRecheck);
412
	return synthField;
413
}
414
/* Add a new synthetic method the enum type. Selector can either be 'values' or 'valueOf'.
415
 * char[] constants from TypeConstants must be used: TypeConstants.VALUES/VALUEOF
416
*/
417
public SyntheticMethodBinding addSyntheticMethodForSwitchEnum(TypeBinding enumBinding) {
418
	if (synthetics == null)
419
		synthetics = new HashMap[4];
420
	if (synthetics[METHOD_EMUL] == null)
421
		synthetics[METHOD_EMUL] = new HashMap(5);
422
423
	SyntheticMethodBinding accessMethod = null;
424
	char[] selector = CharOperation.concat(TypeConstants.SYNTHETIC_SWITCH_ENUM_TABLE, enumBinding.constantPoolName());
425
	CharOperation.replace(selector, '/', '$');
426
	final String key = new String(selector);
427
	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) synthetics[METHOD_EMUL].get(key);
428
	// first add the corresponding synthetic field
429
	if (accessors == null) {
430
		// then create the synthetic method
431
		final SyntheticFieldBinding fieldBinding = this.addSyntheticFieldForSwitchEnum(selector, key);
432
		accessMethod = new SyntheticMethodBinding(fieldBinding, this, enumBinding, selector);
433
		synthetics[METHOD_EMUL].put(key, accessors = new SyntheticMethodBinding[2]);
434
		accessors[0] = accessMethod;		
435
	} else {
436
		if ((accessMethod = accessors[0]) == null) {
437
			final SyntheticFieldBinding fieldBinding = this.addSyntheticFieldForSwitchEnum(selector, key);
438
			accessMethod = new SyntheticMethodBinding(fieldBinding, this, enumBinding, selector);
439
			accessors[0] = accessMethod;
440
		}
441
	}
442
	return accessMethod;
443
}
372
/* Add a new synthetic access method for access to <targetMethod>.
444
/* Add a new synthetic access method for access to <targetMethod>.
373
 * Must distinguish access method used for super access from others (need to use invokespecial bytecode)
445
 * Must distinguish access method used for super access from others (need to use invokespecial bytecode)
374
	Answer the new method or the existing method if one already existed.
446
	Answer the new method or the existing method if one already existed.
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java (-1 / +56 lines)
Lines 18-24 Link Here
18
18
19
	public FieldBinding targetReadField;		// read access to a field
19
	public FieldBinding targetReadField;		// read access to a field
20
	public FieldBinding targetWriteField;		// write access to a field
20
	public FieldBinding targetWriteField;		// write access to a field
21
	public MethodBinding targetMethod;	// method or constructor
21
	public MethodBinding targetMethod;			// method or constructor
22
	public TypeBinding targetEnumType; 			// enum type
22
	
23
	
23
	public int kind;
24
	public int kind;
24
25
Lines 30-35 Link Here
30
	public final static int BridgeMethod = 6; // bridge method
31
	public final static int BridgeMethod = 6; // bridge method
31
	public final static int EnumValues = 7; // enum #values()
32
	public final static int EnumValues = 7; // enum #values()
32
	public final static int EnumValueOf = 8; // enum #valueOf(String)
33
	public final static int EnumValueOf = 8; // enum #valueOf(String)
34
	public final static int SwitchTable = 9; // switch table method
33
35
34
	public int sourceStart = 0; // start position of the matching declaration
36
	public int sourceStart = 0; // start position of the matching declaration
35
	public int index; // used for sorting access methods in the class file
37
	public int index; // used for sorting access methods in the class file
Lines 128-133 Link Here
128
		this.sourceStart = declaringSourceType.scope.referenceContext.sourceStart; // use the target declaring class name position instead
130
		this.sourceStart = declaringSourceType.scope.referenceContext.sourceStart; // use the target declaring class name position instead
129
	}
131
	}
130
132
133
	public SyntheticMethodBinding(FieldBinding targetField, ReferenceBinding declaringClass, TypeBinding enumBinding, char[] selector) {
134
		this.modifiers = AccDefault | AccStatic | AccSynthetic;
135
		this.tagBits |= TagBits.AnnotationResolved;
136
		SourceTypeBinding declaringSourceType = (SourceTypeBinding) declaringClass;
137
		SyntheticMethodBinding[] knownAccessMethods = declaringSourceType.syntheticMethods();
138
		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
139
		this.index = methodId;
140
		this.selector = selector;
141
		this.returnType = declaringSourceType.scope.createArrayType(BaseTypes.IntBinding, 1);
142
		this.parameters = NoParameters;
143
		this.targetReadField = targetField;
144
		this.targetEnumType = enumBinding;
145
		this.kind = SwitchTable;
146
		this.thrownExceptions = NoExceptions;
147
		this.declaringClass = declaringSourceType;
148
  
149
		if (declaringSourceType.isStrictfp()) {
150
			this.modifiers |= AccStrictfp;
151
		}
152
		// check for method collision
153
		boolean needRename;
154
		do {
155
			check : {
156
				needRename = false;
157
				// check for collision with known methods
158
				MethodBinding[] methods = declaringSourceType.methods;
159
				for (int i = 0, length = methods.length; i < length; i++) {
160
					if (CharOperation.equals(this.selector, methods[i].selector) && this.areParametersEqual(methods[i])) {
161
						needRename = true;
162
						break check;
163
					}
164
				}
165
				// check for collision with synthetic accessors
166
				if (knownAccessMethods != null) {
167
					for (int i = 0, length = knownAccessMethods.length; i < length; i++) {
168
						if (knownAccessMethods[i] == null) continue;
169
						if (CharOperation.equals(this.selector, knownAccessMethods[i].selector) && this.areParametersEqual(methods[i])) {
170
							needRename = true;
171
							break check;
172
						}
173
					}
174
				}
175
			}
176
			if (needRename) { // retry with a selector postfixed by a growing methodId
177
				this.setSelector(CharOperation.concat(TypeConstants.SYNTHETIC_ACCESS_METHOD_PREFIX, String.valueOf(++methodId).toCharArray()));
178
			}
179
		} while (needRename);
180
181
		// We now at this point - per construction - it is for sure an enclosing instance, we are going to
182
		// show the target field type declaration location.
183
		this.sourceStart = declaringSourceType.scope.referenceContext.sourceStart; // use the target declaring class name position instead
184
	}
185
	
131
	public SyntheticMethodBinding(MethodBinding targetMethod, boolean isSuperAccess, ReferenceBinding receiverType) {
186
	public SyntheticMethodBinding(MethodBinding targetMethod, boolean isSuperAccess, ReferenceBinding receiverType) {
132
	
187
	
133
		if (targetMethod.isConstructor()) {
188
		if (targetMethod.isConstructor()) {
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java (+1 lines)
Lines 144-149 Link Here
144
	// Synthetics
144
	// Synthetics
145
	char[] INIT = "<init>".toCharArray(); //$NON-NLS-1$
145
	char[] INIT = "<init>".toCharArray(); //$NON-NLS-1$
146
	char[] CLINIT = "<clinit>".toCharArray(); //$NON-NLS-1$
146
	char[] CLINIT = "<clinit>".toCharArray(); //$NON-NLS-1$
147
	char[] SYNTHETIC_SWITCH_ENUM_TABLE = "$SWITCH_TABLE$".toCharArray(); //$NON-NLS-1$
147
	char[] SYNTHETIC_ENUM_VALUES = "ENUM$VALUES".toCharArray(); //$NON-NLS-1$
148
	char[] SYNTHETIC_ENUM_VALUES = "ENUM$VALUES".toCharArray(); //$NON-NLS-1$
148
	char[] SYNTHETIC_ASSERT_DISABLED = "$assertionsDisabled".toCharArray(); //$NON-NLS-1$
149
	char[] SYNTHETIC_ASSERT_DISABLED = "$assertionsDisabled".toCharArray(); //$NON-NLS-1$
149
	char[] SYNTHETIC_CLASS = "class$".toCharArray(); //$NON-NLS-1$
150
	char[] SYNTHETIC_CLASS = "class$".toCharArray(); //$NON-NLS-1$

Return to bug 88395