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

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/model/SignatureTests.java (+15 lines)
Lines 505-510 Link Here
505
505
506
}
506
}
507
/**
507
/**
508
 * @bug 155003: [model] Missing exception types / wrong signature?
509
 * @test Ensure that thrown exceptions are well decoded when added at the end of the signature
510
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=155003"
511
 */
512
public void testGetThrownExceptions_Bug155003() throws JavaModelException {
513
	String methodSig = "()Ljava.lang.Object;^Ljava.lang.InstantiationException;^Ljava.lang.IllegalAccessException;";
514
	assertStringsEqual("Signature#Bug155003#1 is not correct",
515
		"Ljava.lang.InstantiationException;\nLjava.lang.IllegalAccessException;\n",
516
		Signature.getThrownExceptionTypes(methodSig));
517
	methodSig = "()V"; // no change when no thrown exceptions
518
	assertStringsEqual("Signature#Bug155003#2 is not correct",
519
		"",
520
		Signature.getThrownExceptionTypes(methodSig));
521
}
522
/**
508
 * @see Signature
523
 * @see Signature
509
 * @since 3.0
524
 * @since 3.0
510
 */
525
 */
(-)src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java (+77 lines)
Lines 7321-7324 Link Here
7321
    	assertTrue("Not assignement compatible", typeBinding.isAssignmentCompatible(typeBinding2));
7321
    	assertTrue("Not assignement compatible", typeBinding.isAssignmentCompatible(typeBinding2));
7322
    	assertTrue("Not assignement compatible", typeBinding.isAssignmentCompatible(collectionTypeBinding));
7322
    	assertTrue("Not assignement compatible", typeBinding.isAssignmentCompatible(collectionTypeBinding));
7323
	}
7323
	}
7324
7325
	/**
7326
	 * @bug 155003: [model] Missing exception types / wrong signature?
7327
	 * @test Ensure that thrown exceptions are added in method unique key (not in signature)
7328
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=155003"
7329
	 */
7330
	public void testBug155003() throws CoreException {
7331
		workingCopies = new ICompilationUnit[1];
7332
		workingCopies[0] = getWorkingCopy("/Converter15/src/Test.java",
7333
			"public class Test {\n" + 
7334
			"    public void foo() throws InstantiationException, IllegalAccessException {\n" + 
7335
			"    }\n" + 
7336
			"    void test() throws InstantiationException, IllegalAccessException {\n" + 
7337
			"    	foo();\n" + 
7338
			"    }\n" + 
7339
			"}",
7340
			true // compute problems => resolve bindings
7341
		);
7342
7343
		// Get 'test' method statements
7344
		CompilationUnit unit = (CompilationUnit) buildAST(this.workingCopies[0]);
7345
		ASTNode method = getASTNode(unit, 0, 1);
7346
		assertEquals("Expecting method", method.getNodeType(), ASTNode.METHOD_DECLARATION);
7347
		MethodDeclaration bar = (MethodDeclaration) method;
7348
		Block body = bar.getBody();
7349
		List statements = body.statements();
7350
		
7351
		// Verify statement binding
7352
		ASTNode node = (ASTNode) statements.get(0);
7353
		assertEquals("Expecting expression statement", node.getNodeType(), ASTNode.EXPRESSION_STATEMENT);
7354
	   	assertBindingEquals(
7355
			"LTest;.foo()V^Ljava/lang/InstantiationException;^Ljava/lang/IllegalAccessException;",
7356
	   		resolveBinding(((ExpressionStatement)node).getExpression())
7357
	   	);
7358
	}
7359
	public void testBug155003_Generic() throws CoreException {
7360
		workingCopies = new ICompilationUnit[1];
7361
		workingCopies[0] = getWorkingCopy("/Converter15/src/X.java",
7362
			"public class X<T> {\n" + 
7363
			"	<U extends Exception> X<T> foo(X<T> x) throws RuntimeException, U {\n" + 
7364
			"		return null;\n" + 
7365
			"	}\n" + 
7366
			"	<K, V> V bar(K key, V value) throws Exception {\n" + 
7367
			"		return value;\n" + 
7368
			"	}\n" + 
7369
			"	void test() throws Exception {\n" + 
7370
			"		foo(this);\n" + 
7371
			"		bar(\"\", \"\");\n" + 
7372
			"	}\n" + 
7373
			"}\n",
7374
			true // compute problems => resolve bindings
7375
		);
7376
7377
		// Get 'test' method statements
7378
		CompilationUnit unit = (CompilationUnit) buildAST(this.workingCopies[0]);
7379
		ASTNode method = getASTNode(unit, 0, 2);
7380
		assertEquals("Expecting method", method.getNodeType(), ASTNode.METHOD_DECLARATION);
7381
		MethodDeclaration bar = (MethodDeclaration) method;
7382
		Block body = bar.getBody();
7383
		List statements = body.statements();
7384
		
7385
		// Verify first statement binding
7386
		ASTNode node = (ASTNode) statements.get(0);
7387
		assertEquals("Expecting expression statement", node.getNodeType(), ASTNode.EXPRESSION_STATEMENT);
7388
	   	assertBindingEquals(
7389
			"LX<LX;:TT;>;.foo<U:Ljava/lang/Exception;>(LX<TT;>;)LX<TT;>;^Ljava/lang/RuntimeException;^TU;%<Ljava/lang/Exception;>",
7390
	   		resolveBinding(((ExpressionStatement)node).getExpression())
7391
	   	);
7392
		
7393
		// Verify second statement binding
7394
		node = (ASTNode) statements.get(1);
7395
		assertEquals("Expecting expression statement", node.getNodeType(), ASTNode.EXPRESSION_STATEMENT);
7396
		assertBindingEquals(
7397
			"LX<LX;:TT;>;.bar<K:Ljava/lang/Object;V:Ljava/lang/Object;>(TK;TV;)TV;^Ljava/lang/Exception;%<Ljava/lang/String;Ljava/lang/String;>",
7398
	   		resolveBinding(((ExpressionStatement)node).getExpression())
7399
		);
7400
	}
7324
}
7401
}
(-)model/org/eclipse/jdt/internal/core/util/BindingKeyParser.java (-9 / +23 lines)
Lines 53-58 Link Here
53
				&& this.source[this.index] == '!';
53
				&& this.source[this.index] == '!';
54
		}
54
		}
55
		
55
		
56
		boolean isAtEnd() {
57
			return this.index >= this.source.length;
58
		}
59
		
56
		boolean isAtFieldOrMethodStart() {
60
		boolean isAtFieldOrMethodStart() {
57
			return 
61
			return 
58
				this.index < this.source.length
62
				this.index < this.source.length
Lines 116-122 Link Here
116
			return this.index < this.source.length && "LIZVCDBFJS[!".indexOf(this.source[this.index]) != -1; //$NON-NLS-1$
120
			return this.index < this.source.length && "LIZVCDBFJS[!".indexOf(this.source[this.index]) != -1; //$NON-NLS-1$
117
		}
121
		}
118
		
122
		
119
		boolean isAtFlagsStart() {
123
		boolean isAtThrownStart() {
120
			return 
124
			return 
121
				this.index < this.source.length
125
				this.index < this.source.length
122
				&& this.source[this.index] == '^';
126
				&& this.source[this.index] == '^';
Lines 325-330 Link Here
325
			}
329
			}
326
		}
330
		}
327
		
331
		
332
		void skipThrownStart() {
333
			while (this.index < this.source.length && this.source[this.index] == '^')
334
				this.index++;
335
		}
336
		
328
		void skipParametersStart() {
337
		void skipParametersStart() {
329
			while (this.index < this.source.length && (this.source[this.index] == '<' || this.source[this.index] == '%'))
338
			while (this.index < this.source.length && (this.source[this.index] == '<' || this.source[this.index] == '%'))
330
				this.index++;
339
				this.index++;
Lines 429-434 Link Here
429
		// default is to do nothing
438
		// default is to do nothing
430
	}
439
	}
431
	
440
	
441
	public void consumeException() {
442
		// default is to do nothing
443
	}
444
	
432
	public void consumeField(char[] fieldName) {
445
	public void consumeField(char[] fieldName) {
433
		// default is to do nothing
446
		// default is to do nothing
434
	}
447
	}
Lines 579-585 Link Here
579
		
592
		
580
		consumeType();
593
		consumeType();
581
		this.scanner.skipTypeEnd();
594
		this.scanner.skipTypeEnd();
582
		parseFlags();
583
		
595
		
584
		if (this.scanner.isAtFieldOrMethodStart()) {
596
		if (this.scanner.isAtFieldOrMethodStart()) {
585
			switch (this.scanner.nextToken()) {
597
			switch (this.scanner.nextToken()) {
Lines 704-710 Link Here
704
			parseLocalVariable();
716
			parseLocalVariable();
705
		} else {
717
		} else {
706
		 	consumeLocalVar(varName);
718
		 	consumeLocalVar(varName);
707
			parseFlags();
708
		}
719
		}
709
 	}
720
 	}
710
	
721
	
Lines 713-719 Link Here
713
	 	this.scanner.skipMethodSignature();
724
	 	this.scanner.skipMethodSignature();
714
	 	char[] signature = this.scanner.getTokenSource();
725
	 	char[] signature = this.scanner.getTokenSource();
715
	 	consumeMethod(selector, signature);
726
	 	consumeMethod(selector, signature);
716
		parseFlags();
727
		parseThrownExceptions();
717
		if (this.scanner.isAtParametersStart())
728
		if (this.scanner.isAtParametersStart())
718
			parseParameterizedMethod();
729
			parseParameterizedMethod();
719
	}
730
	}
Lines 743-751 Link Here
743
 		consumeField(fieldName);
754
 		consumeField(fieldName);
744
	}
755
	}
745
	
756
	
746
	private void parseFlags() {
757
	private void parseThrownExceptions() {
747
		if (!this.scanner.isAtFlagsStart() || this.scanner.nextToken() != Scanner.FLAGS) return;
758
		while (this.scanner.isAtThrownStart()) {
748
		consumeModifiers(this.scanner.getTokenSource());
759
			this.scanner.skipThrownStart();
760
			consumeException();
761
			parseFullyQualifiedName();
762
			consumeType();
763
			this.scanner.skipTypeEnd();
764
		}
749
	}
765
	}
750
	
766
	
751
	private void parseParameterizedType(char[] typeName, boolean isRaw) {
767
	private void parseParameterizedType(char[] typeName, boolean isRaw) {
Lines 758-764 Link Here
758
	 	this.scanner.skipParametersEnd();
774
	 	this.scanner.skipParametersEnd();
759
		consumeParameterizedType(typeName, isRaw);
775
		consumeParameterizedType(typeName, isRaw);
760
		this.scanner.skipTypeEnd();
776
		this.scanner.skipTypeEnd();
761
		parseFlags();
762
	 	if (this.scanner.isAtMemberTypeStart() && this.scanner.nextToken() == Scanner.TYPE) {
777
	 	if (this.scanner.isAtMemberTypeStart() && this.scanner.nextToken() == Scanner.TYPE) {
763
	 		typeName = this.scanner.getTokenSource();
778
	 		typeName = this.scanner.getTokenSource();
764
			if (this.scanner.isAtParametersStart()) {
779
			if (this.scanner.isAtParametersStart()) {
Lines 773-779 Link Here
773
		this.scanner.skipParametersEnd();
788
		this.scanner.skipParametersEnd();
774
		consumeRawType();
789
		consumeRawType();
775
		this.scanner.skipTypeEnd();
790
		this.scanner.skipTypeEnd();
776
		parseFlags();
777
	 	if (this.scanner.isAtMemberTypeStart() && this.scanner.nextToken() == Scanner.TYPE) {
791
	 	if (this.scanner.isAtMemberTypeStart() && this.scanner.nextToken() == Scanner.TYPE) {
778
	 		char[] typeName = this.scanner.getTokenSource();
792
	 		char[] typeName = this.scanner.getTokenSource();
779
			if (this.scanner.isAtParametersStart()) {
793
			if (this.scanner.isAtParametersStart()) {
(-)model/org/eclipse/jdt/internal/core/util/KeyToSignature.java (+4 lines)
Lines 198-203 Link Here
198
		}
198
		}
199
	}
199
	}
200
	
200
	
201
	public void consumeException() {
202
		this.signature.append('^');
203
	}
204
	
201
	public void consumeFullyQualifiedName(char[] fullyQualifiedName) {
205
	public void consumeFullyQualifiedName(char[] fullyQualifiedName) {
202
		this.typeSigStart = this.signature.length();
206
		this.typeSigStart = this.signature.length();
203
		this.signature.append('L');
207
		this.signature.append('L');
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java (-3 / +31 lines)
Lines 320-329 Link Here
320
	
320
	
321
	// generic signature
321
	// generic signature
322
	char[] sig = genericSignature();
322
	char[] sig = genericSignature();
323
	if (sig == null) sig = signature();
323
	boolean isGeneric = sig != null;
324
	if (!isGeneric) sig = signature();
324
	int signatureLength = sig.length;
325
	int signatureLength = sig.length;
325
	
326
	
326
	char[] uniqueKey = new char[declaringLength + 1 + selectorLength + signatureLength];
327
	// thrown exceptions
328
	int thrownExceptionsLength = this.thrownExceptions.length;
329
	int thrownExceptionsSignatureLength = 0;
330
	char[][] thrownExceptionsSignatures = null;
331
	boolean addThrownExceptions = thrownExceptionsLength > 0 && (!isGeneric || CharOperation.lastIndexOf('^', sig) < 0);
332
	if (addThrownExceptions) {
333
		thrownExceptionsSignatures = new char[thrownExceptionsLength][];
334
		for (int i = 0; i < thrownExceptionsLength; i++) {
335
			if (this.thrownExceptions[i] != null) {
336
				thrownExceptionsSignatures[i] = this.thrownExceptions[i].signature();
337
				thrownExceptionsSignatureLength += thrownExceptionsSignatures[i].length + 1;	// add one char for separator
338
			}
339
		}
340
	}
341
	
342
	char[] uniqueKey = new char[declaringLength + 1 + selectorLength + signatureLength + thrownExceptionsSignatureLength];
327
	int index = 0;
343
	int index = 0;
328
	System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
344
	System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
329
	index = declaringLength;
345
	index = declaringLength;
Lines 331-337 Link Here
331
	System.arraycopy(this.selector, 0, uniqueKey, index, selectorLength);
347
	System.arraycopy(this.selector, 0, uniqueKey, index, selectorLength);
332
	index += selectorLength;
348
	index += selectorLength;
333
	System.arraycopy(sig, 0, uniqueKey, index, signatureLength);
349
	System.arraycopy(sig, 0, uniqueKey, index, signatureLength);
334
	//index += signatureLength;
350
	if (thrownExceptionsSignatureLength > 0) {
351
		index += signatureLength;
352
		for (int i = 0; i < thrownExceptionsLength; i++) {
353
			char[] thrownExceptionSignature = thrownExceptionsSignatures[i];
354
			if (thrownExceptionSignature != null) {
355
				uniqueKey[index++] = '^';
356
				int length = thrownExceptionSignature.length;
357
				System.arraycopy(thrownExceptionSignature, 0, uniqueKey, index, length);
358
				index += length;
359
			}
360
		}
361
	}
362
335
	return uniqueKey;
363
	return uniqueKey;
336
}
364
}
337
/* 
365
/* 

Return to bug 155003