Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 346454 | Differences between
and this patch

Collapse All | Expand All

(-)codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java (-1 / +16 lines)
Lines 5003-5009 Link Here
5003
		int relevance) {
5003
		int relevance) {
5004
5004
5005
		// No visibility checks can be performed without the scope & invocationSite
5005
		// No visibility checks can be performed without the scope & invocationSite
5006
		MethodBinding[] methods = currentType.availableMethods();
5006
		MethodBinding[] methods = null;
5007
		if (currentType instanceof ParameterizedTypeBinding && invocationSite instanceof CompletionOnQualifiedAllocationExpression) {
5008
			CompletionOnQualifiedAllocationExpression alloc = (CompletionOnQualifiedAllocationExpression) invocationSite;
5009
			if ((alloc.bits & ASTNode.IsDiamond) != 0) {
5010
				// inference failed. So don't substitute type arguments. Just return the unsubstituted methods
5011
				// and let the user decide what to substitute.
5012
				ParameterizedTypeBinding binding = (ParameterizedTypeBinding) currentType;
5013
				ReferenceBinding originalGenericType = binding.genericType();
5014
				if (originalGenericType != null)
5015
					methods = originalGenericType.methods();
5016
			} else {
5017
				methods = currentType.availableMethods();
5018
			}
5019
		} else {
5020
			methods = currentType.availableMethods();
5021
		}
5007
		if(methods != null) {
5022
		if(methods != null) {
5008
			int minArgLength = argTypes == null ? 0 : argTypes.length;
5023
			int minArgLength = argTypes == null ? 0 : argTypes.length;
5009
			next : for (int f = methods.length; --f >= 0;) {
5024
			next : for (int f = methods.length; --f >= 0;) {
(-)codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedAllocationExpression.java (-5 / +37 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 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 39-62 Link Here
39
39
40
public class CompletionOnQualifiedAllocationExpression extends QualifiedAllocationExpression {
40
public class CompletionOnQualifiedAllocationExpression extends QualifiedAllocationExpression {
41
public TypeBinding resolveType(BlockScope scope) {
41
public TypeBinding resolveType(BlockScope scope) {
42
	TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
42
	if (this.arguments != null) {
43
	if (this.arguments != null) {
43
		int argsLength = this.arguments.length;
44
		int argsLength = this.arguments.length;
44
		for (int a = argsLength; --a >= 0;)
45
		int length = this.arguments.length;
45
			this.arguments[a].resolveType(scope);
46
		argumentTypes = new TypeBinding[length];
47
		for (int a = argsLength; --a >= 0;) {
48
			argumentTypes[a] = this.arguments[a].resolveType(scope);
49
		}
46
	}
50
	}
47
51
	final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
48
	if (this.enclosingInstance != null) {
52
	if (this.enclosingInstance != null) {
49
		TypeBinding enclosingType = this.enclosingInstance.resolveType(scope);
53
		TypeBinding enclosingType = this.enclosingInstance.resolveType(scope);
54
		if (enclosingType == null) {
55
			// try to propose something even if enclosing type cannot be resolved.
56
			// Eg.: new Test<>().new Test<>(#cursor#
57
			if (this.enclosingInstance instanceof AllocationExpression) {
58
				TypeReference enclosingInstanceType = ((AllocationExpression) this.enclosingInstance).type;
59
				if (enclosingInstanceType != null) {
60
					enclosingType = enclosingInstanceType.resolvedType;
61
				}
62
			}
63
		}
50
		if (enclosingType == null || !(enclosingType instanceof ReferenceBinding)) {
64
		if (enclosingType == null || !(enclosingType instanceof ReferenceBinding)) {
51
			throw new CompletionNodeFound();
65
			throw new CompletionNodeFound();
52
		}
66
		}
53
		this.resolvedType = ((SingleTypeReference) this.type).resolveTypeEnclosing(scope, (ReferenceBinding) enclosingType);
67
		this.resolvedType = ((SingleTypeReference) this.type).resolveTypeEnclosing(scope, (ReferenceBinding) enclosingType);
68
		if (isDiamond && (this.resolvedType instanceof ParameterizedTypeBinding)) {
69
			TypeBinding [] inferredTypes = inferElidedTypes(((ParameterizedTypeBinding) this.resolvedType).genericType(), null, argumentTypes, scope);
70
			if (inferredTypes != null) {
71
				this.resolvedType = this.type.resolvedType = scope.environment().createParameterizedType(((ParameterizedTypeBinding) this.resolvedType).genericType(), inferredTypes, ((ParameterizedTypeBinding) this.resolvedType).enclosingType());
72
			} else {
73
				// inference failed. Resolved type will be of the form Test<>
74
				this.bits |= ASTNode.IsDiamond;
75
			}
76
	 	}
54
		if (!(this.resolvedType instanceof ReferenceBinding))
77
		if (!(this.resolvedType instanceof ReferenceBinding))
55
			throw new CompletionNodeFound(); // no need to continue if its an array or base type
78
			throw new CompletionNodeFound(); // no need to continue if its an array or base type
56
		if (this.resolvedType.isInterface()) // handle the anonymous class definition case
79
		if (this.resolvedType.isInterface()) // handle the anonymous class definition case
57
			this.resolvedType = scope.getJavaLangObject();
80
			this.resolvedType = scope.getJavaLangObject();
58
	} else {
81
	} else {
59
		this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
82
	 	this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
83
	 	if (isDiamond && (this.resolvedType instanceof ParameterizedTypeBinding)) {
84
			TypeBinding [] inferredTypes = inferElidedTypes(((ParameterizedTypeBinding) this.resolvedType).genericType(), null, argumentTypes, scope);
85
			if (inferredTypes != null) {
86
				this.resolvedType = this.type.resolvedType = scope.environment().createParameterizedType(((ParameterizedTypeBinding) this.resolvedType).genericType(), inferredTypes, ((ParameterizedTypeBinding) this.resolvedType).enclosingType());
87
			} else {
88
				// inference failed. Resolved type will be of the form Test<>
89
				this.bits |= ASTNode.IsDiamond;
90
			}
91
	 	}
60
		if (!(this.resolvedType instanceof ReferenceBinding))
92
		if (!(this.resolvedType instanceof ReferenceBinding))
61
			throw new CompletionNodeFound(); // no need to continue if its an array or base type
93
			throw new CompletionNodeFound(); // no need to continue if its an array or base type
62
	}
94
	}
(-)codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java (-1 / +12 lines)
Lines 2614-2619 Link Here
2614
		this.listLength++;
2614
		this.listLength++;
2615
	}
2615
	}
2616
}
2616
}
2617
protected void consumeGenericTypeWithDiamond() {
2618
	super.consumeGenericTypeWithDiamond();
2619
	// we need to pop the <> of the diamond from the stack.
2620
	// This is not required in usual case when the type argument isn't elided
2621
	// since the < and > get popped while parsing the type argument. 
2622
	popElement(K_BINARY_OPERATOR); // pop >
2623
	popElement(K_BINARY_OPERATOR); // pop <
2624
}
2617
protected void consumeStatementFor() {
2625
protected void consumeStatementFor() {
2618
	super.consumeStatementFor();
2626
	super.consumeStatementFor();
2619
2627
Lines 4366-4372 Link Here
4366
4374
4367
protected TypeReference getTypeReferenceForGenericType(int dim,	int identifierLength, int numberOfIdentifiers) {
4375
protected TypeReference getTypeReferenceForGenericType(int dim,	int identifierLength, int numberOfIdentifiers) {
4368
	TypeReference ref = super.getTypeReferenceForGenericType(dim, identifierLength, numberOfIdentifiers);
4376
	TypeReference ref = super.getTypeReferenceForGenericType(dim, identifierLength, numberOfIdentifiers);
4369
4377
	// in completion case we might have encountered the assist node before really parsing
4378
	// the complete class instance creation, and so a separate check for diamond is needed here.
4379
	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=346454
4380
	checkForDiamond(ref);
4370
	if(this.assistNode != null) {
4381
	if(this.assistNode != null) {
4371
		if (identifierLength == 1 && numberOfIdentifiers == 1) {
4382
		if (identifierLength == 1 && numberOfIdentifiers == 1) {
4372
			ParameterizedSingleTypeReference singleRef = (ParameterizedSingleTypeReference) ref;
4383
			ParameterizedSingleTypeReference singleRef = (ParameterizedSingleTypeReference) ref;
(-)codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java (-1 / +1 lines)
Lines 989-995 Link Here
989
	int currentIdentifiersLength = identifierLength;
989
	int currentIdentifiersLength = identifierLength;
990
	while (index > 0) {
990
	while (index > 0) {
991
		int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
991
		int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
992
		if (currentTypeArgumentsLength != 0) {
992
		if (currentTypeArgumentsLength > 0) {
993
			this.genericsPtr -= currentTypeArgumentsLength;
993
			this.genericsPtr -= currentTypeArgumentsLength;
994
			System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments[index - 1] = new TypeReference[currentTypeArgumentsLength], 0, currentTypeArgumentsLength);
994
			System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments[index - 1] = new TypeReference[currentTypeArgumentsLength], 0, currentTypeArgumentsLength);
995
		}
995
		}
(-)src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest.java (+76 lines)
Lines 8868-8871 Link Here
8868
		expectedReplacedSource,
8868
		expectedReplacedSource,
8869
		testName);
8869
		testName);
8870
}
8870
}
8871
8872
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=346454
8873
public void testBug346454(){
8874
	if (this.complianceLevel < ClassFileConstants.JDK1_7)
8875
		return;
8876
	String str =
8877
		"public class Test<T> {\n" +
8878
		"	public void foo() {\n" +
8879
		"      Test<String> t = new Test<>()\n" +
8880
		"   }" +
8881
		"}\n";
8882
8883
	String testName = "<complete after diamond type>";
8884
	String completeBehind = "new Test<>(";
8885
	String expectedCompletionNodeToString = "<CompleteOnAllocationExpression:new Test<>()>";
8886
	String completionIdentifier = "";
8887
	String expectedReplacedSource = "";
8888
	String expectedUnitDisplayString =			
8889
		"public class Test<T> {\n" + 
8890
		"  public Test() {\n" + 
8891
		"  }\n" + 
8892
		"  public void foo() {\n" + 
8893
		"    Test<String> t = <CompleteOnAllocationExpression:new Test<>()>;\n" + 
8894
		"  }\n" + 
8895
		"}\n";
8896
8897
	int cursorLocation = str.indexOf(completeBehind) + completeBehind.length() - 1;
8898
	checkMethodParse(
8899
		str.toCharArray(),
8900
		cursorLocation,
8901
		expectedCompletionNodeToString,
8902
		expectedUnitDisplayString,
8903
		completionIdentifier,
8904
		expectedReplacedSource,
8905
		testName);
8906
}
8907
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=346454
8908
public void testBug346454b(){
8909
	if (this.complianceLevel < ClassFileConstants.JDK1_7)
8910
		return;
8911
	String str =
8912
		"public class Test<T> {\n" +
8913
		"	public class T2<Z>{}\n" +
8914
		"	public void foo() {\n" +
8915
		"      Test<String>.T2<String> t = new Test<>().new T2<>()\n" +
8916
		"   }" +
8917
		"}\n";
8918
8919
	String testName = "<complete after diamond type>";
8920
	String completeBehind = "new Test<>().new T2<>(";
8921
	String expectedCompletionNodeToString = "<CompleteOnQualifiedAllocationExpression:new Test<>().new T2<>()>";
8922
	String completionIdentifier = "";
8923
	String expectedReplacedSource = "";
8924
	String expectedUnitDisplayString =			
8925
		"public class Test<T> {\n" + 
8926
		"  public class T2<Z> {\n" + 
8927
		"    public T2() {\n" + 
8928
		"    }\n" + 
8929
		"  }\n" + 
8930
		"  public Test() {\n" + 
8931
		"  }\n" + 
8932
		"  public void foo() {\n" + 
8933
		"    Test<String>.T2<String> t = <CompleteOnQualifiedAllocationExpression:new Test<>().new T2<>()>;\n" + 
8934
		"  }\n" + 
8935
		"}\n";
8936
8937
	int cursorLocation = str.indexOf(completeBehind) + completeBehind.length() - 1;
8938
	checkMethodParse(
8939
		str.toCharArray(),
8940
		cursorLocation,
8941
		expectedCompletionNodeToString,
8942
		expectedUnitDisplayString,
8943
		completionIdentifier,
8944
		expectedReplacedSource,
8945
		testName);
8946
}
8871
}
8947
}

Return to bug 346454