Skip to main content
summaryrefslogtreecommitdiffstats
blob: d2474a424e32a3d95dc0b79522bca75e99535740 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Fraunhofer FIRST - extended API and implementation
 *     Technical University Berlin - extended API and implementation
 *     Stephan Herrmann - Contribution for
 *							Bug 400874 - [1.8][compiler] Inference infrastructure should evolve to meet JLS8 18.x (Part G of JSR335 spec)
 *							Bug 433478 - [compiler][null] NPE in ReferenceBinding.isCompatibleWith
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;

import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.AnchorMapping;

/**
 * OTDT change:
 *
 * What: If a closest match is given, replace it with instantiated copy.
 */
public class ProblemMethodBinding extends MethodBinding {

	private int problemReason;
	public MethodBinding closestMatch; // TODO (philippe) should rename into #alternateMatch
	public InferenceContext18 inferenceContext; // inference context may help to coordinate error reporting

public ProblemMethodBinding(char[] selector, TypeBinding[] args, int problemReason) {
	this.selector = selector;
	this.parameters = (args == null || args.length == 0) ? Binding.NO_PARAMETERS : args;
	this.problemReason = problemReason;
	this.thrownExceptions = Binding.NO_EXCEPTIONS;
}
public ProblemMethodBinding(char[] selector, TypeBinding[] args, ReferenceBinding declaringClass, int problemReason) {
	this.selector = selector;
	this.parameters = (args == null || args.length == 0) ? Binding.NO_PARAMETERS : args;
	this.declaringClass = declaringClass;
	this.problemReason = problemReason;
	this.thrownExceptions = Binding.NO_EXCEPTIONS;
}
public ProblemMethodBinding(MethodBinding closestMatch, char[] selector, TypeBinding[] args, int problemReason) {
	this(selector, args, problemReason);
	this.closestMatch = closestMatch;
//{ObjectTeams:
	if (closestMatch != null) {
		// check for need to instantiate parameters;
		TypeBinding[] newParameters = AnchorMapping.instantiateParameters(null, closestMatch.parameters, closestMatch);
		// if instantiating was actually performed, we need a clone to hold the new parameters:
		if (newParameters != closestMatch.parameters) {
			// clone 'closestMatch' depending on its dynamic type:
			MethodBinding clone = getMethodClone(closestMatch);
			if (clone != null) {
				clone.parameters = newParameters;
				this.closestMatch = clone;
			}
		}
	}
// SH}
	if (closestMatch != null && problemReason != ProblemReasons.Ambiguous) {
		this.declaringClass = closestMatch.declaringClass;
		this.returnType = closestMatch.returnType;
		if (problemReason == ProblemReasons.InvocationTypeInferenceFailure || problemReason == ProblemReasons.ContradictoryNullAnnotations) {
			this.thrownExceptions = closestMatch.thrownExceptions;
			this.typeVariables = closestMatch.typeVariables;
			this.modifiers = closestMatch.modifiers;
			this.tagBits = closestMatch.tagBits;
		}
	}
}

//{ObjectTeams: Clone closestMatch before manipulation.
private MethodBinding getMethodClone(MethodBinding givenClosestMatch) {
	if(givenClosestMatch instanceof ParameterizedGenericMethodBinding) {
		ParameterizedGenericMethodBinding pgmb = (ParameterizedGenericMethodBinding)givenClosestMatch;
		MethodBinding clone = new ParameterizedGenericMethodBinding(givenClosestMatch, pgmb.typeArguments, pgmb.environment(), false, false, pgmb.targetType);
		clone.declaringClass = givenClosestMatch.declaringClass;
		return clone;
	} else if(givenClosestMatch instanceof ParameterizedMethodBinding) {
		if (givenClosestMatch.declaringClass instanceof ParameterizedTypeBinding)
			return new ParameterizedMethodBinding((ParameterizedTypeBinding)givenClosestMatch.declaringClass, givenClosestMatch);
		else
			return null;
	} else {
		return new MethodBinding(givenClosestMatch, givenClosestMatch.declaringClass);
	}
}
// SH}

@Override
public MethodBinding computeSubstitutedMethod(MethodBinding method, LookupEnvironment env) {
	return this.closestMatch == null ? this : this.closestMatch.computeSubstitutedMethod(method, env);
}
@Override
public MethodBinding findOriginalInheritedMethod(MethodBinding inheritedMethod) {
	return this.closestMatch == null ? this : this.closestMatch.findOriginalInheritedMethod(inheritedMethod);
}
@Override
public MethodBinding genericMethod() {
	return this.closestMatch == null ? this : this.closestMatch.genericMethod();
}
@Override
public MethodBinding original() {
	return this.closestMatch == null ? this : this.closestMatch.original();
}
@Override
public MethodBinding shallowOriginal() {
	return this.closestMatch == null ? this : this.closestMatch.shallowOriginal();
}
@Override
public MethodBinding tiebreakMethod() {
	return this.closestMatch == null ? this : this.closestMatch.tiebreakMethod();
}
@Override
public boolean hasSubstitutedParameters() {
	if (this.closestMatch != null)
		return this.closestMatch.hasSubstitutedParameters();
	return false;
}
@Override
public boolean isParameterizedGeneric() {
	return this.closestMatch instanceof ParameterizedGenericMethodBinding;
}
/** API
 * Answer the problem id associated with the receiver.
 * NoError if the receiver is a valid binding.
 */
@Override
public final int problemId() {
	return this.problemReason;
}
}

Back to the top