View | Details | Raw Unified | Return to bug 235783
Collapse All | Expand All

(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetAllocationExpression.java (-3 / +52 lines)
Lines 13-18 Link Here
13
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
13
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
14
import org.eclipse.jdt.internal.compiler.ast.CastExpression;
14
import org.eclipse.jdt.internal.compiler.ast.CastExpression;
15
import org.eclipse.jdt.internal.compiler.ast.Expression;
15
import org.eclipse.jdt.internal.compiler.ast.Expression;
16
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
17
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
18
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
19
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
16
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
20
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
17
import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
21
import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
18
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
22
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
Lines 119-124 Link Here
119
	// Propagate the type checking to the arguments, and check if the constructor is defined.
123
	// Propagate the type checking to the arguments, and check if the constructor is defined.
120
	this.constant = Constant.NotAConstant;
124
	this.constant = Constant.NotAConstant;
121
	this.resolvedType = this.type.resolveType(scope, true /* check bounds*/); // will check for null after args are resolved
125
	this.resolvedType = this.type.resolveType(scope, true /* check bounds*/); // will check for null after args are resolved
126
	checkParameterizedAllocation: {
127
		if (this.type instanceof ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
128
			ReferenceBinding currentType = (ReferenceBinding)this.resolvedType;
129
			if (currentType == null) return currentType;
130
			do {
131
				// isStatic() is answering true for toplevel types
132
				if ((currentType.modifiers & ClassFileConstants.AccStatic) != 0) break checkParameterizedAllocation;
133
				if (currentType.isRawType()) break checkParameterizedAllocation;
134
			} while ((currentType = currentType.enclosingType())!= null);
135
			ParameterizedQualifiedTypeReference qRef = (ParameterizedQualifiedTypeReference) this.type;
136
			for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
137
				if (qRef.typeArguments[i] != null) {
138
					scope.problemReporter().illegalQualifiedParameterizedTypeAllocation(this.type, this.resolvedType);
139
					break;
140
				}
141
			}
142
		}
143
	}
144
145
	// resolve type arguments (for generic constructor call)
146
	if (this.typeArguments != null) {
147
		int length = this.typeArguments.length;
148
		boolean argHasError = scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5;
149
		this.genericTypeArguments = new TypeBinding[length];
150
		for (int i = 0; i < length; i++) {
151
			TypeReference typeReference = this.typeArguments[i];
152
			if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
153
				argHasError = true;
154
			}
155
			if (argHasError && typeReference instanceof Wildcard) {
156
				scope.problemReporter().illegalUsageOfWildcard(typeReference);
157
			}
158
		}
159
		if (argHasError) {
160
			if (this.arguments != null) { // still attempt to resolve arguments
161
				for (int i = 0, max = this.arguments.length; i < max; i++) {
162
					this.arguments[i].resolveType(scope);
163
				}
164
			}
165
			return null;
166
		}
167
	}
122
168
123
	// buffering the arguments' types
169
	// buffering the arguments' types
124
	boolean argsContainCast = false;
170
	boolean argsContainCast = false;
Lines 204-211 Link Here
204
	}
250
	}
205
	if (this.arguments != null) {
251
	if (this.arguments != null) {
206
		for (int i = 0; i < this.arguments.length; i++) {
252
		for (int i = 0; i < this.arguments.length; i++) {
207
		    TypeBinding parameterType = this.binding.parameters[i];
253
			TypeBinding parameterType = this.binding.parameters[i];
208
		    TypeBinding argumentType = argumentTypes[i];
254
			TypeBinding argumentType = argumentTypes[i];
209
			this.arguments[i].computeConversion(scope, parameterType, argumentType);
255
			this.arguments[i].computeConversion(scope, parameterType, argumentType);
210
			if (argumentType.needsUncheckedConversion(parameterType)) {
256
			if (argumentType.needsUncheckedConversion(parameterType)) {
211
				scope.problemReporter().unsafeTypeConversion(this.arguments[i], argumentType, parameterType);
257
				scope.problemReporter().unsafeTypeConversion(this.arguments[i], argumentType, parameterType);
Lines 216-222 Link Here
216
		}
262
		}
217
	}
263
	}
218
	if (allocatedType.isRawType() && this.binding.hasSubstitutedParameters()) {
264
	if (allocatedType.isRawType() && this.binding.hasSubstitutedParameters()) {
219
	    scope.problemReporter().unsafeRawInvocation(this, this.binding);
265
		scope.problemReporter().unsafeRawInvocation(this, this.binding);
266
	}
267
	if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
268
		scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
220
	}
269
	}
221
	return allocatedType;
270
	return allocatedType;
222
}
271
}
(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetParser.java (+116 lines)
Lines 84-89 Link Here
84
		this.astLengthPtr--;
84
		this.astLengthPtr--;
85
	}
85
	}
86
}
86
}
87
protected void consumeClassInstanceCreationExpressionWithTypeArguments() {
88
	// ClassInstanceCreationExpression ::= 'new' TypeArguments ClassType '(' ArgumentListopt ')' ClassBodyopt
89
	AllocationExpression alloc;
90
	int length;
91
	if (((length = this.astLengthStack[this.astLengthPtr--]) == 1)
92
		&& (this.astStack[this.astPtr] == null)) {
93
		//NO ClassBody
94
		this.astPtr--;
95
		alloc = new CodeSnippetAllocationExpression(this.evaluationContext);
96
		alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
97
98
		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
99
			this.expressionPtr -= length;
100
			System.arraycopy(
101
				this.expressionStack,
102
				this.expressionPtr + 1,
103
				alloc.arguments = new Expression[length],
104
				0,
105
				length);
106
		}
107
		alloc.type = getTypeReference(0);
108
109
		length = this.genericsLengthStack[this.genericsLengthPtr--];
110
		this.genericsPtr -= length;
111
		System.arraycopy(this.genericsStack, this.genericsPtr + 1, alloc.typeArguments = new TypeReference[length], 0, length);
112
		this.intPtr--;
113
114
		//the default constructor with the correct number of argument
115
		//will be created and added by the TC (see createsInternalConstructorWithBinding)
116
		alloc.sourceStart = this.intStack[this.intPtr--];
117
		pushOnExpressionStack(alloc);
118
	} else {
119
		dispatchDeclarationInto(length);
120
		TypeDeclaration anonymousTypeDeclaration = (TypeDeclaration)this.astStack[this.astPtr];
121
		anonymousTypeDeclaration.declarationSourceEnd = this.endStatementPosition;
122
		anonymousTypeDeclaration.bodyEnd = this.endStatementPosition;
123
		if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) {
124
			anonymousTypeDeclaration.bits |= ASTNode.UndocumentedEmptyBlock;
125
		}
126
		this.astPtr--;
127
		this.astLengthPtr--;
128
129
		QualifiedAllocationExpression allocationExpression = anonymousTypeDeclaration.allocation;
130
		if (allocationExpression != null) {
131
			allocationExpression.sourceEnd = this.endStatementPosition;
132
			// handle type arguments
133
			length = this.genericsLengthStack[this.genericsLengthPtr--];
134
			this.genericsPtr -= length;
135
			System.arraycopy(this.genericsStack, this.genericsPtr + 1, allocationExpression.typeArguments = new TypeReference[length], 0, length);
136
			allocationExpression.sourceStart = this.intStack[this.intPtr--];
137
		}
138
	}
139
}
87
protected void consumeClassDeclaration() {
140
protected void consumeClassDeclaration() {
88
	super.consumeClassDeclaration();
141
	super.consumeClassDeclaration();
89
	/* recovery */
142
	/* recovery */
Lines 370-376 Link Here
370
		super.consumeMethodInvocationName();
423
		super.consumeMethodInvocationName();
371
	}
424
	}
372
}
425
}
426
protected void consumeMethodInvocationNameWithTypeArguments() {
427
	// MethodInvocation ::= Name '.' TypeArguments 'Identifier' '(' ArgumentListopt ')'
428
429
	// when the name is only an identifier...we have a message send to "this" (implicit)
430
	if (this.scanner.startPosition >= this.codeSnippetStart
431
			&& this.scanner.startPosition <= this.codeSnippetEnd + 1 + this.lineSeparatorLength // 14838
432
			&& isTopLevelType()) {
373
433
434
	
435
		MessageSend m = newMessageSendWithTypeArguments();
436
		m.sourceEnd = this.rParenPos;
437
		m.sourceStart =
438
			(int) ((m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr]) >>> 32);
439
		m.selector = this.identifierStack[this.identifierPtr--];
440
		this.identifierLengthPtr--;
441
	
442
		// handle type arguments
443
		int length = this.genericsLengthStack[this.genericsLengthPtr--];
444
		this.genericsPtr -= length;
445
		System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments = new TypeReference[length], 0, length);
446
		this.intPtr--;
447
	
448
		m.receiver = getUnspecifiedReference();
449
		m.sourceStart = m.receiver.sourceStart;
450
		pushOnExpressionStack(m);
451
	} else {
452
		super.consumeMethodInvocationNameWithTypeArguments();
453
	}
454
}
374
protected void consumeMethodInvocationSuper() {
455
protected void consumeMethodInvocationSuper() {
375
	// MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
456
	// MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
376
457
Lines 383-388 Link Here
383
	m.receiver = new CodeSnippetSuperReference(m.sourceStart, this.endPosition);
464
	m.receiver = new CodeSnippetSuperReference(m.sourceStart, this.endPosition);
384
	pushOnExpressionStack(m);
465
	pushOnExpressionStack(m);
385
}
466
}
467
protected void consumeMethodInvocationSuperWithTypeArguments() {
468
	// MethodInvocation ::= 'super' '.' TypeArguments 'Identifier' '(' ArgumentListopt ')'
469
470
	MessageSend m = newMessageSendWithTypeArguments();
471
	this.intPtr--; // start position of the typeArguments
472
	m.sourceEnd = this.rParenPos;
473
	m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr];
474
	m.selector = this.identifierStack[this.identifierPtr--];
475
	this.identifierLengthPtr--;
476
477
	// handle type arguments
478
	int length = this.genericsLengthStack[this.genericsLengthPtr--];
479
	this.genericsPtr -= length;
480
	System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments = new TypeReference[length], 0, length);
481
	m.sourceStart = this.intStack[this.intPtr--]; // start position of the super keyword
482
483
	m.receiver = new CodeSnippetSuperReference(m.sourceStart, this.endPosition);
484
	pushOnExpressionStack(m);
485
}
386
protected void consumePrimaryNoNewArrayThis() {
486
protected void consumePrimaryNoNewArrayThis() {
387
	// PrimaryNoNewArray ::= 'this'
487
	// PrimaryNoNewArray ::= 'this'
388
488
Lines 679-684 Link Here
679
	}
779
	}
680
	return m;
780
	return m;
681
}
781
}
782
protected MessageSend newMessageSendWithTypeArguments() {
783
	// '(' ArgumentListopt ')'
784
	// the arguments are on the expression stack
785
	CodeSnippetMessageSend m = new CodeSnippetMessageSend(this.evaluationContext);
786
	int length;
787
	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
788
		this.expressionPtr -= length;
789
		System.arraycopy(
790
			this.expressionStack,
791
			this.expressionPtr + 1,
792
			m.arguments = new Expression[length],
793
			0,
794
			length);
795
	}
796
	return m;
797
}
682
/**
798
/**
683
 * Records the scanner position if we're parsing a top level type.
799
 * Records the scanner position if we're parsing a top level type.
684
 */
800
 */
(-)src/org/eclipse/jdt/core/tests/eval/DebugEvaluationTest.java (+157 lines)
Lines 2782-2787 Link Here
2782
		removeTempClass("A62");
2782
		removeTempClass("A62");
2783
	}
2783
	}
2784
}
2784
}
2785
public void test065() {
2786
	if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
2787
	try {
2788
		String sourceA65 =
2789
			"public class A65<T> {\n"
2790
				+ "\tprivate int i;\n"
2791
				+ "\tpublic <U>A65() {;\n"
2792
				+ "\t}\n"
2793
				+ "\tprivate <U>A65(int i) {;\n"
2794
				+ "\t\tthis.i = i;\n"
2795
				+ "\t}\n"               
2796
				+ "\tpublic void bar() {\n"
2797
				+ "\t}\n"
2798
				+ "}";
2799
		compileAndDeploy15(sourceA65, "A65");
2800
2801
		String userCode = "new <Object>A65<Object>().bar();";
2802
		JDIStackFrame stackFrame =
2803
			new JDIStackFrame(this.jdiVM, this, userCode, "A65", "bar", -1);
2804
2805
		DebugRequestor requestor = new DebugRequestor();
2806
		char[] snippet = "return new <Object>A65<Object>(3).i;".toCharArray();
2807
		try {
2808
			this.context.evaluate(
2809
				snippet,
2810
				stackFrame.localVariableTypeNames(),
2811
				stackFrame.localVariableNames(),
2812
				stackFrame.localVariableModifiers(),
2813
				stackFrame.declaringTypeName(),
2814
				stackFrame.isStatic(),
2815
				stackFrame.isConstructorCall(),
2816
				getEnv(),
2817
				getCompilerOptions(),
2818
				requestor,
2819
				getProblemFactory());
2820
		} catch (InstallException e) {
2821
			assertTrue("No targetException " + e.getMessage(), false);
2822
		}
2823
		assertTrue(
2824
			"Should get one result but got " + (requestor.resultIndex + 1),
2825
			requestor.resultIndex == 0);
2826
		EvaluationResult result = requestor.results[0];
2827
		assertTrue("Code snippet should not have problems", !result.hasProblems());
2828
		assertTrue("Result should have a value", result.hasValue());
2829
		assertEquals("Value", "3".toCharArray(), result.getValueDisplayString());
2830
		assertEquals("Type", "int".toCharArray(), result.getValueTypeName());
2831
	} finally {
2832
		removeTempClass("A65");
2833
	}
2834
}
2835
public void test066() {
2836
	if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
2837
	try {
2838
		String sourceA66 =
2839
			"public class A66 {\n"
2840
				+ "\tprivate int i;\n"
2841
				+ "\tpublic A66() {;\n"
2842
				+ "\t}\n"
2843
				+ "\tprivate <U> int foo(int i) {;\n"
2844
				+ "\t\treturn i;\n"    
2845
				+ "\t}\n"               
2846
				+ "\tpublic void bar() {\n"
2847
				+ "\t}\n"
2848
				+ "}";
2849
		compileAndDeploy15(sourceA66, "A66");
2850
2851
		String userCode = "new A66().bar();";
2852
		JDIStackFrame stackFrame =
2853
			new JDIStackFrame(this.jdiVM, this, userCode, "A66", "bar", -1);
2854
2855
		DebugRequestor requestor = new DebugRequestor();
2856
		char[] snippet = "return this.<Object>foo(3);".toCharArray();
2857
		try {
2858
			this.context.evaluate(
2859
				snippet,
2860
				stackFrame.localVariableTypeNames(),
2861
				stackFrame.localVariableNames(),
2862
				stackFrame.localVariableModifiers(),
2863
				stackFrame.declaringTypeName(),
2864
				stackFrame.isStatic(),
2865
				stackFrame.isConstructorCall(),
2866
				getEnv(),
2867
				getCompilerOptions(),
2868
				requestor,
2869
				getProblemFactory());
2870
		} catch (InstallException e) {
2871
			assertTrue("No targetException " + e.getMessage(), false);
2872
		}
2873
		assertTrue(
2874
			"Should get one result but got " + (requestor.resultIndex + 1),
2875
			requestor.resultIndex == 0);
2876
		EvaluationResult result = requestor.results[0];
2877
		assertTrue("Code snippet should not have problems", !result.hasProblems());
2878
		assertTrue("Result should have a value", result.hasValue());
2879
		assertEquals("Value", "3".toCharArray(), result.getValueDisplayString());
2880
		assertEquals("Type", "int".toCharArray(), result.getValueTypeName());
2881
	} finally {
2882
		removeTempClass("A66");
2883
	}
2884
}
2885
public void test067() {
2886
	if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
2887
	try {
2888
		String sourceA67 =
2889
			"import java.util.List;\n" +
2890
			"public class A67<T> {\n" +
2891
			"	public static String toString(List<?> list) {\n" +
2892
			"		StringBuilder builder = new StringBuilder(\"{\");\n" +
2893
			"		for (Object o : list) {" +
2894
			"			builder.append(o);\n" +
2895
			"		}\n" +
2896
			"		builder.append(\"}\");\n" +
2897
			"		return String.valueOf(builder);\n" +
2898
			"	}\n" +
2899
			"	public void bar() {\n" +
2900
			"	}\n" +
2901
			"}";
2902
		compileAndDeploy15(sourceA67, "A67");
2903
2904
		String userCode = "new A67<Object>().bar();";
2905
		JDIStackFrame stackFrame =
2906
			new JDIStackFrame(this.jdiVM, this, userCode, "A67", "bar", -1);
2907
2908
		DebugRequestor requestor = new DebugRequestor();
2909
		char[] snippet = ("java.util.ArrayList<String> list = new java.util.ArrayList<String>();\n" +
2910
				"list.add(\"Test\");\n" +
2911
				"list.add(\"Hello\");\n" +
2912
				"list.add(\"World\");\n" +
2913
				"return A67.toString(list);").toCharArray();
2914
		try {
2915
			this.context.evaluate(
2916
				snippet,
2917
				stackFrame.localVariableTypeNames(),
2918
				stackFrame.localVariableNames(),
2919
				stackFrame.localVariableModifiers(),
2920
				stackFrame.declaringTypeName(),
2921
				stackFrame.isStatic(),
2922
				stackFrame.isConstructorCall(),
2923
				getEnv(),
2924
				getCompilerOptions(),
2925
				requestor,
2926
				getProblemFactory());
2927
		} catch (InstallException e) {
2928
			assertTrue("No targetException " + e.getMessage(), false);
2929
		}
2930
		assertTrue(
2931
			"Should get one result but got " + (requestor.resultIndex + 1),
2932
			requestor.resultIndex == 0);
2933
		EvaluationResult result = requestor.results[0];
2934
		assertTrue("Code snippet should not have problems", !result.hasProblems());
2935
		assertTrue("Result should have a value", result.hasValue());
2936
		assertEquals("Value", "{TestHelloWorld}".toCharArray(), result.getValueDisplayString());
2937
		assertEquals("Type", "java.lang.String".toCharArray(), result.getValueTypeName());
2938
	} finally {
2939
		removeTempClass("A67");
2940
	}
2941
}
2785
/**
2942
/**
2786
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=178861
2943
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=178861
2787
 */
2944
 */

Return to bug 235783