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

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java (-8 / +21 lines)
Lines 149-155 Link Here
149
	this.fPackage = packageBinding;
149
	this.fPackage = packageBinding;
150
	this.fileName = binaryType.getFileName();
150
	this.fileName = binaryType.getFileName();
151
151
152
	char[] typeSignature = environment.globalOptions.originalSourceLevel >= ClassFileConstants.JDK1_5 ? binaryType.getGenericSignature() : null;
152
	/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, even in a 1.4 project, we
153
	   must internalize type variables and observe any parameterization of super class
154
	   and/or super interfaces in order to be able to detect overriding in the presence
155
	   of generics.
156
	 */
157
	char[] typeSignature = binaryType.getGenericSignature();
153
	this.typeVariables = typeSignature != null && typeSignature.length > 0 && typeSignature[0] == '<'
158
	this.typeVariables = typeSignature != null && typeSignature.length > 0 && typeSignature[0] == '<'
154
		? null // is initialized in cachePartsFrom (called from LookupEnvironment.createBinaryTypeFrom())... must set to null so isGenericType() answers true
159
		? null // is initialized in cachePartsFrom (called from LookupEnvironment.createBinaryTypeFrom())... must set to null so isGenericType() answers true
155
		: Binding.NO_TYPE_VARIABLES;
160
		: Binding.NO_TYPE_VARIABLES;
Lines 261-271 Link Here
261
		}
266
		}
262
267
263
		long sourceLevel = this.environment.globalOptions.originalSourceLevel;
268
		long sourceLevel = this.environment.globalOptions.originalSourceLevel;
264
		char[] typeSignature = null;
269
		/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, even in a 1.4 project, we
265
		if (sourceLevel >= ClassFileConstants.JDK1_5) {
270
		   must internalize type variables and observe any parameterization of super class
266
			typeSignature = binaryType.getGenericSignature();
271
		   and/or super interfaces in order to be able to detect overriding in the presence
267
			this.tagBits |= binaryType.getTagBits();
272
		   of generics.
268
		}
273
		 */
274
		char[] typeSignature = binaryType.getGenericSignature(); // use generic signature even in 1.4
275
		this.tagBits |= binaryType.getTagBits();
276
		
269
		char[][][] missingTypeNames = binaryType.getMissingTypeNames();
277
		char[][][] missingTypeNames = binaryType.getMissingTypeNames();
270
		if (typeSignature == null) {
278
		if (typeSignature == null) {
271
			char[] superclassName = binaryType.getSuperclassName();
279
			char[] superclassName = binaryType.getSuperclassName();
Lines 412-418 Link Here
412
	TypeBinding returnType = null;
420
	TypeBinding returnType = null;
413
421
414
	final boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5;
422
	final boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5;
415
	char[] methodSignature = use15specifics ? method.getGenericSignature() : null;
423
	/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, Since a 1.4 project can have a 1.5
424
	   type as a super type and the 1.5 type could be generic, we must internalize usages of type
425
	   variables properly in order to be able to apply substitutions and thus be able to detect
426
	   overriding in the presence of generics. Seeing the erased form is not good enough.
427
	 */
428
	char[] methodSignature = method.getGenericSignature(); // always use generic signature, even in 1.4
416
	if (methodSignature == null) { // no generics
429
	if (methodSignature == null) { // no generics
417
		char[] methodDescriptor = method.getMethodDescriptor();   // of the form (I[Ljava/jang/String;)V
430
		char[] methodDescriptor = method.getMethodDescriptor();   // of the form (I[Ljava/jang/String;)V
418
		int numOfParams = 0;
431
		int numOfParams = 0;
Lines 476-482 Link Here
476
	} else {
489
	} else {
477
		methodModifiers |= ExtraCompilerModifiers.AccGenericSignature;
490
		methodModifiers |= ExtraCompilerModifiers.AccGenericSignature;
478
		// MethodTypeSignature = ParameterPart(optional) '(' TypeSignatures ')' return_typeSignature ['^' TypeSignature (optional)]
491
		// MethodTypeSignature = ParameterPart(optional) '(' TypeSignatures ')' return_typeSignature ['^' TypeSignature (optional)]
479
		SignatureWrapper wrapper = new SignatureWrapper(methodSignature);
492
		SignatureWrapper wrapper = new SignatureWrapper(methodSignature, use15specifics);
480
		if (wrapper.signature[wrapper.start] == '<') {
493
		if (wrapper.signature[wrapper.start] == '<') {
481
			// <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)TA;
494
			// <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)TA;
482
			// ParameterPart = '<' ParameterSignature(s) '>'
495
			// ParameterPart = '<' ParameterSignature(s) '>'
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java (-2 / +1 lines)
Lines 385-392 Link Here
385
	    SourceTypeBinding sourceType = this.referenceContext.binding;
385
	    SourceTypeBinding sourceType = this.referenceContext.binding;
386
		TypeParameter[] typeParameters = this.referenceContext.typeParameters;
386
		TypeParameter[] typeParameters = this.referenceContext.typeParameters;
387
387
388
	    // do not construct type variables if source < 1.5
388
		if (typeParameters == null || typeParameters.length == 0) {
389
		if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) {
390
		    sourceType.typeVariables = Binding.NO_TYPE_VARIABLES;
389
		    sourceType.typeVariables = Binding.NO_TYPE_VARIABLES;
391
		    return;
390
		    return;
392
		}
391
		}
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java (-3 / +6 lines)
Lines 1322-1330 Link Here
1322
}
1322
}
1323
1323
1324
public MethodVerifier newMethodVerifier() {
1324
public MethodVerifier newMethodVerifier() {
1325
	return this.globalOptions.sourceLevel < ClassFileConstants.JDK1_5
1325
	/* Always use MethodVerifier15. Even in a 1.4 project, we must internalize type variables and
1326
		? new MethodVerifier(this)
1326
	   observe any parameterization of super class and/or super interfaces in order to be able to
1327
		: new MethodVerifier15(this); // covariance only if sourceLevel is >= 1.5
1327
	   detect overriding in the presence of generics.
1328
	   See https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850
1329
	 */
1330
	return new MethodVerifier15(this);
1328
}
1331
}
1329
1332
1330
public void releaseClassFiles(org.eclipse.jdt.internal.compiler.ClassFile[] classFiles) {
1333
public void releaseClassFiles(org.eclipse.jdt.internal.compiler.ClassFile[] classFiles) {
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java (-1 / +6 lines)
Lines 11-16 Link Here
11
package org.eclipse.jdt.internal.compiler.lookup;
11
package org.eclipse.jdt.internal.compiler.lookup;
12
12
13
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
13
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
14
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
14
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
15
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
15
import org.eclipse.jdt.internal.compiler.util.SimpleSet;
16
import org.eclipse.jdt.internal.compiler.util.SimpleSet;
16
17
Lines 80-86 Link Here
80
}
81
}
81
boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two) {
82
boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two) {
82
	if (one.returnType == two.returnType) return true;
83
	if (one.returnType == two.returnType) return true;
83
	return areReturnTypesCompatible0(one, two);
84
	if (this.type.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
85
		return areReturnTypesCompatible0(one, two);
86
	} else {
87
		return areTypesEqual(one.returnType.erasure(), two.returnType.erasure());
88
	}
84
}
89
}
85
boolean areTypesEqual(TypeBinding one, TypeBinding two) {
90
boolean areTypesEqual(TypeBinding one, TypeBinding two) {
86
	if (one == two) return true;
91
	if (one == two) return true;
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java (-1 / +1 lines)
Lines 705-711 Link Here
705
705
706
	public TypeVariableBinding[] createTypeVariables(TypeParameter[] typeParameters, Binding declaringElement) {
706
	public TypeVariableBinding[] createTypeVariables(TypeParameter[] typeParameters, Binding declaringElement) {
707
		// do not construct type variables if source < 1.5
707
		// do not construct type variables if source < 1.5
708
		if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5)
708
		if (typeParameters == null || typeParameters.length == 0)
709
			return Binding.NO_TYPE_VARIABLES;
709
			return Binding.NO_TYPE_VARIABLES;
710
710
711
		PackageBinding unitPackage = compilationUnitScope().fPackage;
711
		PackageBinding unitPackage = compilationUnitScope().fPackage;
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java (-3 / +32 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 17-27 Link Here
17
	public int start;
17
	public int start;
18
	public int end;
18
	public int end;
19
	public int bracket;
19
	public int bracket;
20
	private boolean use15specifics;
20
21
21
	public SignatureWrapper(char[] signature) {
22
	public SignatureWrapper(char[] signature, boolean use15specifics) {
22
		this.signature = signature;
23
		this.signature = signature;
23
		this.start = 0;
24
		this.start = 0;
24
		this.end = this.bracket = -1;
25
		this.end = this.bracket = -1;
26
		this.use15specifics = use15specifics;
27
	}
28
	public SignatureWrapper(char [] signature) {
29
		this(signature, true);
25
	}
30
	}
26
	public boolean atEnd() {
31
	public boolean atEnd() {
27
		return this.start < 0 || this.start >= this.signature.length;
32
		return this.start < 0 || this.start >= this.signature.length;
Lines 46-54 Link Here
46
				this.end = this.start;
51
				this.end = this.start;
47
		}
52
		}
48
53
49
		this.start = this.end + 1; // skip ';'
54
		if (this.use15specifics || this.end != this.bracket) {
55
			this.start = this.end + 1; // skip ';'
56
		} else {
57
			this.start = skipAngleContents(this.end) + 1;  // skip <<>*>;
58
			this.bracket = -1;
59
		}
50
		return this.end;
60
		return this.end;
51
	}
61
	}
62
	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, do not expose generics if we shouldn't
63
	public int skipAngleContents(int i) {
64
		if (this.signature[i] != '<') {
65
			return i;
66
		}
67
		int depth = 0, length = this.signature.length;
68
		for (++i; i < length; i++) {
69
			switch(this.signature[i]) {
70
				case '<' :
71
					depth++;
72
					break;
73
				case '>' :
74
					if (--depth < 0)
75
						return i + 1;
76
					break;
77
			}
78
		}
79
		return i;
80
	}
52
	public char[] nextWord() {
81
	public char[] nextWord() {
53
		this.end = CharOperation.indexOf(';', this.signature, this.start);
82
		this.end = CharOperation.indexOf(';', this.signature, this.start);
54
		if (this.bracket <= this.start) // already know it if its > start
83
		if (this.bracket <= this.start) // already know it if its > start
(-)compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java (+3 lines)
Lines 7083-7088 Link Here
7083
    }
7083
    }
7084
}
7084
}
7085
public void unsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod, SourceTypeBinding type) {
7085
public void unsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod, SourceTypeBinding type) {
7086
	if (this.options.sourceLevel < ClassFileConstants.JDK1_5) {
7087
		return;
7088
	}
7086
	int severity = computeSeverity(IProblem.UnsafeReturnTypeOverride);
7089
	int severity = computeSeverity(IProblem.UnsafeReturnTypeOverride);
7087
	if (severity == ProblemSeverities.Ignore) return;
7090
	if (severity == ProblemSeverities.Ignore) return;
7088
	int start = type.sourceStart();
7091
	int start = type.sourceStart();
(-)model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java (-28 / +29 lines)
Lines 291-311 Link Here
291
		int start = methodInfo.getNameSourceStart();
291
		int start = methodInfo.getNameSourceStart();
292
		int end = methodInfo.getNameSourceEnd();
292
		int end = methodInfo.getNameSourceEnd();
293
293
294
		// convert 1.5 specific constructs only if compliance is 1.5 or above
294
		/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, Even when this type is being constructed
295
		   on behalf of a 1.4 project we must internalize type variables properly in order to be able to
296
		   recognize usages of them in the method signature, to apply substitutions and thus to be able to
297
		   detect overriding in the presence of generics. If we simply drop them, when the method signature
298
		   refers to the type parameter, we won't know it should be bound to the type parameter and perform
299
		   incorrect lookup and may mistakenly end up with missing types
300
		 */
295
		TypeParameter[] typeParams = null;
301
		TypeParameter[] typeParams = null;
296
		// Digest type parameters if compliance level of current project or its prerequisite is >= 1.5
302
		char[][] typeParameterNames = methodInfo.getTypeParameterNames();
297
		// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633 && https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259
303
		if (typeParameterNames != null) {
298
		if (this.has1_5Compliance || this.problemReporter.options.complianceLevel >= ClassFileConstants.JDK1_5) {
304
			int parameterCount = typeParameterNames.length;
299
			/* convert type parameters */
305
			if (parameterCount > 0) { // method's type parameters must be null if no type parameter
300
			char[][] typeParameterNames = methodInfo.getTypeParameterNames();
306
				char[][][] typeParameterBounds = methodInfo.getTypeParameterBounds();
301
			if (typeParameterNames != null) {
307
				typeParams = new TypeParameter[parameterCount];
302
				int parameterCount = typeParameterNames.length;
308
				for (int i = 0; i < parameterCount; i++) {
303
				if (parameterCount > 0) { // method's type parameters must be null if no type parameter
309
					typeParams[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end);
304
					char[][][] typeParameterBounds = methodInfo.getTypeParameterBounds();
305
					typeParams = new TypeParameter[parameterCount];
306
					for (int i = 0; i < parameterCount; i++) {
307
						typeParams[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end);
308
					}
309
				}
310
				}
310
			}
311
			}
311
		}
312
		}
Lines 465-488 Link Here
465
			/* convert annotations */
466
			/* convert annotations */
466
			type.annotations = convertAnnotations(typeHandle);
467
			type.annotations = convertAnnotations(typeHandle);
467
		}
468
		}
468
		// Digest type parameters if compliance level of current project or its prerequisite is >= 1.5
469
		/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, even in a 1.4 project, we
469
		// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633 && https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259
470
		   must internalize type variables and observe any parameterization of super class
470
		if (this.has1_5Compliance || this.problemReporter.options.complianceLevel >= ClassFileConstants.JDK1_5) {
471
		   and/or super interfaces in order to be able to detect overriding in the presence
471
			/* convert type parameters */
472
		   of generics.
472
			char[][] typeParameterNames = typeInfo.getTypeParameterNames();
473
		 */
473
			if (typeParameterNames.length > 0) {
474
		char[][] typeParameterNames = typeInfo.getTypeParameterNames();
474
				int parameterCount = typeParameterNames.length;
475
		if (typeParameterNames.length > 0) {
475
				char[][][] typeParameterBounds = typeInfo.getTypeParameterBounds();
476
			int parameterCount = typeParameterNames.length;
476
				type.typeParameters = new TypeParameter[parameterCount];
477
			char[][][] typeParameterBounds = typeInfo.getTypeParameterBounds();
477
				for (int i = 0; i < parameterCount; i++) {
478
			type.typeParameters = new TypeParameter[parameterCount];
478
					type.typeParameters[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end);
479
			for (int i = 0; i < parameterCount; i++) {
479
				}
480
				type.typeParameters[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end);
480
			}
481
			}
481
		}
482
		}
482
483
483
		/* set superclass and superinterfaces */
484
		/* set superclass and superinterfaces */
484
		if (typeInfo.getSuperclassName() != null) {
485
		if (typeInfo.getSuperclassName() != null) {
485
			type.superclass = createTypeReference(typeInfo.getSuperclassName(), start, end);
486
			type.superclass = createTypeReference(typeInfo.getSuperclassName(), start, end, true /* include generics */);
486
			type.superclass.bits |= ASTNode.IsSuperType;
487
			type.superclass.bits |= ASTNode.IsSuperType;
487
		}
488
		}
488
		char[][] interfaceNames = typeInfo.getInterfaceNames();
489
		char[][] interfaceNames = typeInfo.getInterfaceNames();
Lines 490-496 Link Here
490
		if (interfaceCount > 0) {
491
		if (interfaceCount > 0) {
491
			type.superInterfaces = new TypeReference[interfaceCount];
492
			type.superInterfaces = new TypeReference[interfaceCount];
492
			for (int i = 0; i < interfaceCount; i++) {
493
			for (int i = 0; i < interfaceCount; i++) {
493
				type.superInterfaces[i] = createTypeReference(interfaceNames[i], start, end);
494
				type.superInterfaces[i] = createTypeReference(interfaceNames[i], start, end, true /* include generics */);
494
				type.superInterfaces[i].bits |= ASTNode.IsSuperType;
495
				type.superInterfaces[i].bits |= ASTNode.IsSuperType;
495
			}
496
			}
496
		}
497
		}
(-)model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java (-14 / +32 lines)
Lines 107-117 Link Here
107
	protected TypeReference createTypeReference(
107
	protected TypeReference createTypeReference(
108
		char[] typeName,
108
		char[] typeName,
109
		int start,
109
		int start,
110
		int end,
111
		boolean includeGenericsAnyway) {
112
113
		int length = typeName.length;
114
		this.namePos = 0;
115
		return decodeType(typeName, length, start, end, true);
116
	}
117
118
	/*
119
	 * Build a type reference from a readable name, e.g. java.lang.Object[][]
120
	 */
121
	protected TypeReference createTypeReference(
122
		char[] typeName,
123
		int start,
110
		int end) {
124
		int end) {
111
125
112
		int length = typeName.length;
126
		int length = typeName.length;
113
		this.namePos = 0;
127
		this.namePos = 0;
114
		return decodeType(typeName, length, start, end);
128
		return decodeType(typeName, length, start, end, false);
115
	}
129
	}
116
130
117
	/*
131
	/*
Lines 351-357 Link Here
351
		}
365
		}
352
	}
366
	}
353
367
354
	private TypeReference decodeType(char[] typeName, int length, int start, int end) {
368
	private TypeReference decodeType(char[] typeName, int length, int start, int end, boolean includeGenericsAnyway) {
355
		int identCount = 1;
369
		int identCount = 1;
356
		int dim = 0;
370
		int dim = 0;
357
		int nameFragmentStart = this.namePos, nameFragmentEnd = -1;
371
		int nameFragmentStart = this.namePos, nameFragmentEnd = -1;
Lines 373-379 Link Here
373
								}
387
								}
374
								this.namePos += max;
388
								this.namePos += max;
375
								Wildcard result = new Wildcard(Wildcard.SUPER);
389
								Wildcard result = new Wildcard(Wildcard.SUPER);
376
								result.bound = decodeType(typeName, length, start, end);
390
								result.bound = decodeType(typeName, length, start, end, includeGenericsAnyway);
377
								result.sourceStart = start;
391
								result.sourceStart = start;
378
								result.sourceEnd = end;
392
								result.sourceEnd = end;
379
								return result;
393
								return result;
Lines 389-395 Link Here
389
								}
403
								}
390
								this.namePos += max;
404
								this.namePos += max;
391
								Wildcard result = new Wildcard(Wildcard.EXTENDS);
405
								Wildcard result = new Wildcard(Wildcard.EXTENDS);
392
								result.bound = decodeType(typeName, length, start, end);
406
								result.bound = decodeType(typeName, length, start, end, includeGenericsAnyway);
393
								result.sourceStart = start;
407
								result.sourceStart = start;
394
								result.sourceEnd = end;
408
								result.sourceEnd = end;
395
								return result;
409
								return result;
Lines 414-436 Link Here
414
					identCount ++;
428
					identCount ++;
415
					break;
429
					break;
416
				case '<' :
430
				case '<' :
417
					/* We need to convert and preserve 1.5 specific constructs only if compliance is 1.5 or above,
431
					/* We need to convert and preserve 1.5 specific constructs either if compliance is 1.5 or above,
418
					   but in all cases, we must skip over them to see if there are any applicable type fragments
432
					   or the caller has explicitly requested generics to be included. The parameter includeGenericsAnyway
419
					   after the type parameters: i.e we just aren't done having seen a '<' in 1.4 mode. Because of
433
					   should be used by the caller to signal that in the calling context generics information must be 
420
					   the way type signatures are encoded, TypeConverter.decodeType(String, int, int, int) is immune
434
					   internalized even when the requesting project is 1.4. But in all cases, we must skip over them to
435
					   see if there are any applicable type fragments after the type parameters: i.e we just aren't done
436
					   having seen a '<' in 1.4 mode. 
437
					   
438
					   Because of the way type signatures are encoded, TypeConverter.decodeType(String, int, int, int) is immune
421
					   to this problem. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=325633
439
					   to this problem. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=325633
422
					 */
440
					 */
423
					if (this.has1_5Compliance) {
441
					if (this.has1_5Compliance || includeGenericsAnyway) {
424
						if (fragments == null) fragments = new ArrayList(2);
442
						if (fragments == null) fragments = new ArrayList(2);
425
					}
443
					}
426
					nameFragmentEnd = this.namePos-1;
444
					nameFragmentEnd = this.namePos-1;
427
					if (this.has1_5Compliance) {
445
					if (this.has1_5Compliance || includeGenericsAnyway) {
428
						char[][] identifiers = CharOperation.splitOn('.', typeName, nameFragmentStart, this.namePos);
446
						char[][] identifiers = CharOperation.splitOn('.', typeName, nameFragmentStart, this.namePos);
429
						fragments.add(identifiers);
447
						fragments.add(identifiers);
430
					}
448
					}
431
					this.namePos++; // skip '<'
449
					this.namePos++; // skip '<'
432
					TypeReference[] arguments = decodeTypeArguments(typeName, length, start, end); // positionned on '>' at end
450
					TypeReference[] arguments = decodeTypeArguments(typeName, length, start, end, includeGenericsAnyway); // positionned on '>' at end
433
					if (this.has1_5Compliance) {
451
					if (this.has1_5Compliance || includeGenericsAnyway) {
434
						fragments.add(arguments);
452
						fragments.add(arguments);
435
						identCount = 0;
453
						identCount = 0;
436
						nameFragmentStart = -1;
454
						nameFragmentStart = -1;
Lines 519-529 Link Here
519
		}
537
		}
520
	}
538
	}
521
539
522
	private TypeReference[] decodeTypeArguments(char[] typeName, int length, int start, int end) {
540
	private TypeReference[] decodeTypeArguments(char[] typeName, int length, int start, int end, boolean includeGenericsAnyway) {
523
		ArrayList argumentList = new ArrayList(1);
541
		ArrayList argumentList = new ArrayList(1);
524
		int count = 0;
542
		int count = 0;
525
		argumentsLoop: while (this.namePos < length) {
543
		argumentsLoop: while (this.namePos < length) {
526
			TypeReference argument = decodeType(typeName, length, start, end);
544
			TypeReference argument = decodeType(typeName, length, start, end, includeGenericsAnyway);
527
			count++;
545
			count++;
528
			argumentList.add(argument);
546
			argumentList.add(argument);
529
			if (this.namePos >= length) break argumentsLoop;
547
			if (this.namePos >= length) break argumentsLoop;
(-)src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java (-2 / +53 lines)
Lines 11010-11017 Link Here
11010
		"Name clash: The method foo(T) of type Interface<T> has the same erasure as foo(T) of type Base<T> but does not override it\n" + 
11010
		"Name clash: The method foo(T) of type Interface<T> has the same erasure as foo(T) of type Base<T> but does not override it\n" + 
11011
		"----------\n");
11011
		"----------\n");
11012
}
11012
}
11013
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850 
11013
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850 
11014
public void _test213() {
11014
public void test213() {
11015
	Map compilerOptions15 = getCompilerOptions();
11015
	Map compilerOptions15 = getCompilerOptions();
11016
	compilerOptions15.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
11016
	compilerOptions15.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
11017
	compilerOptions15.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
11017
	compilerOptions15.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
Lines 11061-11064 Link Here
11061
		compilerOptions14,
11061
		compilerOptions14,
11062
		null);
11062
		null);
11063
}
11063
}
11064
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850 
11065
public void test213a() {
11066
	Map compilerOptions15 = getCompilerOptions();
11067
	compilerOptions15.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
11068
	compilerOptions15.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
11069
	compilerOptions15.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
11070
	this.runConformTest(
11071
		new String[] {
11072
			"Y.java",
11073
			"public abstract class Y implements I<Y> {\n" + 
11074
			"		public final Y foo(Object o, J<Y, I<Y>> j) {\n" + 
11075
			"			return null;\n" + 
11076
			"		}\n" + 
11077
			"	public final void bar(Object o, J<Y, String> j, Y y) {\n" + 
11078
			"	}\n" + 
11079
			"}",
11080
			"I.java",
11081
			"public interface I<S> {\n" + 
11082
			"	public S foo(Object o, J<S, I<S>> j);\n" + 
11083
			"	public void bar(Object o, J<S, String> j, S s);\n" + 
11084
			"}",
11085
			"J.java",
11086
			"public interface J<S, T> {}"
11087
		},
11088
		"",
11089
		null,
11090
		true,
11091
		null,
11092
		compilerOptions15,
11093
		null);
11094
	
11095
	Map compilerOptions14 = getCompilerOptions();
11096
	compilerOptions14.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_2);
11097
	compilerOptions14.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
11098
	compilerOptions14.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3);
11099
	this.runConformTest(
11100
		new String[] {
11101
			"X.java",
11102
			"public class X {\n" + 
11103
			"	public Object foo() {\n" + 
11104
			"		return new Y() {};\n" + 
11105
			"	}\n" + 
11106
			"}"
11107
		},
11108
		"",
11109
		null,
11110
		false,
11111
		null,
11112
		compilerOptions14,
11113
		null);
11114
}
11064
}
11115
}
(-)src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java (-10 / +15 lines)
Lines 3379-3430 Link Here
3379
				"	^^^^\n" +
3379
				"	^^^^\n" +
3380
				"The method bar1() from the type X refers to the missing type Zork\n" +
3380
				"The method bar1() from the type X refers to the missing type Zork\n" +
3381
				"----------\n" +
3381
				"----------\n" +
3382
				"2. ERROR in X.java (at line 6)\n" +
3382
				"2. ERROR in X.java (at line 5)\n" + 
3383
				"	bar2();\n" + 
3384
				"	^^^^\n" + 
3385
				"The method bar2() from the type X refers to the missing type Zork\n" + 
3386
				"----------\n" + 
3387
				"3. ERROR in X.java (at line 6)\n" +
3383
				"	bar3(null);\n" +
3388
				"	bar3(null);\n" +
3384
				"	^^^^\n" +
3389
				"	^^^^\n" +
3385
				"The method bar3(Zork) from the type X refers to the missing type Zork\n" +
3390
				"The method bar3(Zork) from the type X refers to the missing type Zork\n" +
3386
				"----------\n" +
3391
				"----------\n" +
3387
				"3. ERROR in X.java (at line 7)\n" +
3392
				"4. ERROR in X.java (at line 7)\n" +
3388
				"	bar4(null,null);\n" +
3393
				"	bar4(null,null);\n" +
3389
				"	^^^^\n" +
3394
				"	^^^^\n" +
3390
				"The method bar4(Zork) from the type X refers to the missing type Zork\n" +
3395
				"The method bar4(Zork) from the type X refers to the missing type Zork\n" +
3391
				"----------\n" +
3396
				"----------\n" +
3392
				"4. ERROR in X.java (at line 9)\n" +
3397
				"5. ERROR in X.java (at line 9)\n" +
3393
				"	Zork<String> bar1() {}\n" +
3398
				"	Zork<String> bar1() {}\n" +
3394
				"	^^^^\n" +
3399
				"	^^^^\n" +
3395
				"Zork cannot be resolved to a type\n" +
3400
				"Zork cannot be resolved to a type\n" +
3396
				"----------\n" +
3401
				"----------\n" +
3397
				"5. ERROR in X.java (at line 9)\n" +
3402
				"6. ERROR in X.java (at line 9)\n" +
3398
				"	Zork<String> bar1() {}\n" +
3403
				"	Zork<String> bar1() {}\n" +
3399
				"	     ^^^^^^\n" +
3404
				"	     ^^^^^^\n" +
3400
				"Syntax error, parameterized types are only available if source level is 1.5\n" +
3405
				"Syntax error, parameterized types are only available if source level is 1.5\n" +
3401
				"----------\n" +
3406
				"----------\n" +
3402
				"6. ERROR in X.java (at line 10)\n" +
3407
				"7. ERROR in X.java (at line 10)\n" +
3403
				"	List<Zork> bar2() {}\n" +
3408
				"	List<Zork> bar2() {}\n" +
3404
				"	     ^^^^\n" +
3409
				"	     ^^^^\n" +
3405
				"Syntax error, parameterized types are only available if source level is 1.5\n" +
3410
				"Syntax error, parameterized types are only available if source level is 1.5\n" +
3406
				"----------\n" +
3411
				"----------\n" +
3407
				"7. ERROR in X.java (at line 10)\n" +
3412
				"8. ERROR in X.java (at line 10)\n" +
3408
				"	List<Zork> bar2() {}\n" +
3413
				"	List<Zork> bar2() {}\n" +
3409
				"	     ^^^^\n" +
3414
				"	     ^^^^\n" +
3410
				"Zork cannot be resolved to a type\n" +
3415
				"Zork cannot be resolved to a type\n" +
3411
				"----------\n" +
3416
				"----------\n" +
3412
				"8. ERROR in X.java (at line 11)\n" +
3417
				"9. ERROR in X.java (at line 11)\n" +
3413
				"	void bar3(Zork<String> z) {}\n" +
3418
				"	void bar3(Zork<String> z) {}\n" +
3414
				"	          ^^^^\n" +
3419
				"	          ^^^^\n" +
3415
				"Zork cannot be resolved to a type\n" +
3420
				"Zork cannot be resolved to a type\n" +
3416
				"----------\n" +
3421
				"----------\n" +
3417
				"9. ERROR in X.java (at line 11)\n" +
3422
				"10. ERROR in X.java (at line 11)\n" +
3418
				"	void bar3(Zork<String> z) {}\n" +
3423
				"	void bar3(Zork<String> z) {}\n" +
3419
				"	               ^^^^^^\n" +
3424
				"	               ^^^^^^\n" +
3420
				"Syntax error, parameterized types are only available if source level is 1.5\n" +
3425
				"Syntax error, parameterized types are only available if source level is 1.5\n" +
3421
				"----------\n" +
3426
				"----------\n" +
3422
				"10. ERROR in X.java (at line 12)\n" +
3427
				"11. ERROR in X.java (at line 12)\n" +
3423
				"	void bar4(Zork<String,String> z) {}\n" +
3428
				"	void bar4(Zork<String,String> z) {}\n" +
3424
				"	          ^^^^\n" +
3429
				"	          ^^^^\n" +
3425
				"Zork cannot be resolved to a type\n" +
3430
				"Zork cannot be resolved to a type\n" +
3426
				"----------\n" +
3431
				"----------\n" +
3427
				"11. ERROR in X.java (at line 12)\n" +
3432
				"12. ERROR in X.java (at line 12)\n" +
3428
				"	void bar4(Zork<String,String> z) {}\n" +
3433
				"	void bar4(Zork<String,String> z) {}\n" +
3429
				"	               ^^^^^^^^^^^^^\n" +
3434
				"	               ^^^^^^^^^^^^^\n" +
3430
				"Syntax error, parameterized types are only available if source level is 1.5\n" +
3435
				"Syntax error, parameterized types are only available if source level is 1.5\n" +
(-)src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java (+75 lines)
Lines 4876-4879 Link Here
4876
			deleteProject(project15);
4876
			deleteProject(project15);
4877
	}
4877
	}
4878
}
4878
}
4879
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850
4880
public void testGenericAPIUsageFromA14Project6() throws CoreException {
4881
	IJavaProject project14 = null;
4882
	IJavaProject project15 = null;
4883
	try {
4884
		project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin");
4885
		createFolder("/Reconciler15API/src/p2");
4886
		createFile(
4887
				"/Reconciler15API/src/p2/Y.java",
4888
				"package p2;\n" +
4889
				"public abstract class Y implements I<Y> {\n" +
4890
				"    public final Y foo(Object o, J<Y> j) {\n" +
4891
				"        return null;\n" +
4892
				"    }\n" +
4893
				"    public final void bar(Object o, J<Y> j, Y y) {\n" +
4894
				"    }\n" +
4895
				"}\n" +
4896
				"interface I<S> {\n" +
4897
				"	public S foo(Object o, J<S> j);\n" +
4898
				"	public void bar(Object o, J<S> j, S s);\n" +
4899
				"}\n" +
4900
				"interface J<S> {}\n"
4901
			);
4902
		project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
4903
		project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
4904
		project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
4905
		
4906
		project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin");
4907
		project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4);
4908
		project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
4909
		project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);
4910
		
4911
		IClasspathEntry[] oldClasspath = project14.getRawClasspath();
4912
		int oldLength = oldClasspath.length;
4913
		IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1];
4914
		System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength);
4915
		newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API"));
4916
		project14.setRawClasspath(newClasspath, null);
4917
		
4918
		createFolder("/Reconciler1415/src/p1");
4919
		String source = 
4920
			"package p1;\n" +
4921
			"import p2.Y;\n" +
4922
			"public class X {\n" + 
4923
			"   private int unused = 0;\n" +
4924
			"	public Object foo() {\n" + 
4925
			"		return new Y() {};\n" + 
4926
			"	}\n" + 
4927
			"}";
4928
4929
		createFile(
4930
			"/Reconciler1415/src/p1/X.java",
4931
			source
4932
		);
4933
		
4934
		this.workingCopies = new ICompilationUnit[1];
4935
		char[] sourceChars = source.toCharArray();
4936
		this.problemRequestor.initialize(sourceChars);
4937
		this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null);
4938
		assertProblems(
4939
			"Unexpected problems",
4940
			"----------\n" + 
4941
			"1. WARNING in /Reconciler1415/src/p1/X.java (at line 4)\n" + 
4942
			"	private int unused = 0;\n" + 
4943
			"	            ^^^^^^\n" + 
4944
			"The field X.unused is never read locally\n" + 
4945
			"----------\n"
4946
		);
4947
	} finally {
4948
		if (project14 != null)
4949
			deleteProject(project14);
4950
		if (project15 != null)
4951
			deleteProject(project15);
4952
	}
4953
}
4879
}
4954
}

Return to bug 324850