/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java

https://github.com/iamsteveholmes/kotlin · Java · 229 lines · 174 code · 37 blank · 18 comment · 12 complexity · 4156813c704b7d5f1c9983911e3084e9 MD5 · raw file

  1. /*
  2. * Copyright 2010-2012 JetBrains s.r.o.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.jetbrains.jet.lang.resolve.calls.model;
  17. import com.google.common.collect.Maps;
  18. import com.intellij.util.Function;
  19. import org.jetbrains.annotations.NotNull;
  20. import org.jetbrains.annotations.Nullable;
  21. import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
  22. import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
  23. import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
  24. import org.jetbrains.jet.lang.resolve.*;
  25. import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind;
  26. import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate;
  27. import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus;
  28. import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
  29. import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
  30. import org.jetbrains.jet.lang.types.JetType;
  31. import org.jetbrains.jet.lang.types.TypeSubstitutor;
  32. import java.util.ArrayList;
  33. import java.util.List;
  34. import java.util.Map;
  35. import static org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus.UNKNOWN_STATUS;
  36. /**
  37. * @author abreslav
  38. */
  39. public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedCallWithTrace<D> {
  40. public static final Function<ResolvedCallWithTrace<? extends CallableDescriptor>, CallableDescriptor> MAP_TO_CANDIDATE = new Function<ResolvedCallWithTrace<? extends CallableDescriptor>, CallableDescriptor>() {
  41. @Override
  42. public CallableDescriptor fun(ResolvedCallWithTrace<? extends CallableDescriptor> resolvedCall) {
  43. return resolvedCall.getCandidateDescriptor();
  44. }
  45. };
  46. public static final Function<ResolvedCallWithTrace<? extends CallableDescriptor>, CallableDescriptor> MAP_TO_RESULT = new Function<ResolvedCallWithTrace<? extends CallableDescriptor>, CallableDescriptor>() {
  47. @Override
  48. public CallableDescriptor fun(ResolvedCallWithTrace<? extends CallableDescriptor> resolvedCall) {
  49. return resolvedCall.getResultingDescriptor();
  50. }
  51. };
  52. @NotNull
  53. public static <D extends CallableDescriptor> ResolvedCallImpl<D> create(@NotNull ResolutionCandidate<D> candidate, @NotNull DelegatingBindingTrace trace) {
  54. return new ResolvedCallImpl<D>(candidate, trace);
  55. }
  56. private final D candidateDescriptor;
  57. private D resultingDescriptor; // Probably substituted
  58. private final ReceiverValue thisObject; // receiver object of a method
  59. private final ReceiverValue receiverArgument; // receiver of an extension function
  60. private final ExplicitReceiverKind explicitReceiverKind;
  61. private final boolean isSafeCall;
  62. private final Map<TypeParameterDescriptor, JetType> typeArguments = Maps.newLinkedHashMap();
  63. private final Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = Maps.newLinkedHashMap();
  64. private boolean someArgumentHasNoType = false;
  65. private final DelegatingBindingTrace trace;
  66. private ResolutionStatus status = UNKNOWN_STATUS;
  67. private boolean hasUnknownTypeParameters = false;
  68. private ConstraintSystem constraintSystem = null;
  69. private ResolvedCallImpl(@NotNull ResolutionCandidate<D> candidate, @NotNull DelegatingBindingTrace trace) {
  70. this.candidateDescriptor = candidate.getDescriptor();
  71. this.thisObject = candidate.getThisObject();
  72. this.receiverArgument = candidate.getReceiverArgument();
  73. this.explicitReceiverKind = candidate.getExplicitReceiverKind();
  74. this.isSafeCall = candidate.isSafeCall();
  75. this.trace = trace;
  76. }
  77. @Override
  78. @NotNull
  79. public ResolutionStatus getStatus() {
  80. return status;
  81. }
  82. public void addStatus(@NotNull ResolutionStatus status) {
  83. this.status = this.status.combine(status);
  84. }
  85. @Override
  86. public boolean hasUnknownTypeParameters() {
  87. return hasUnknownTypeParameters;
  88. }
  89. public void setHasUnknownTypeParameters(boolean hasUnknownTypeParameters) {
  90. this.hasUnknownTypeParameters = hasUnknownTypeParameters;
  91. }
  92. @Override
  93. @NotNull
  94. public DelegatingBindingTrace getTrace() {
  95. return trace;
  96. }
  97. @Override
  98. @NotNull
  99. public D getCandidateDescriptor() {
  100. return candidateDescriptor;
  101. }
  102. @Override
  103. @NotNull
  104. public D getResultingDescriptor() {
  105. return resultingDescriptor == null ? candidateDescriptor : resultingDescriptor;
  106. }
  107. public void setResultingSubstitutor(@NotNull TypeSubstitutor substitutor) {
  108. resultingDescriptor = (D) candidateDescriptor.substitute(substitutor);
  109. assert resultingDescriptor != null : candidateDescriptor;
  110. Map<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
  111. for (ValueParameterDescriptor valueParameterDescriptor : resultingDescriptor.getValueParameters()) {
  112. parameterMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor);
  113. }
  114. Map<ValueParameterDescriptor, ResolvedValueArgument> originalValueArguments = Maps.newHashMap(valueArguments);
  115. valueArguments.clear();
  116. for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : originalValueArguments.entrySet()) {
  117. ValueParameterDescriptor substitutedVersion = parameterMap.get(entry.getKey().getOriginal());
  118. assert substitutedVersion != null : entry.getKey();
  119. valueArguments.put(substitutedVersion, entry.getValue());
  120. }
  121. }
  122. public void recordTypeArgument(@NotNull TypeParameterDescriptor typeParameter, @NotNull JetType typeArgument) {
  123. assert !typeArguments.containsKey(typeParameter) : typeParameter + " -> " + typeArgument;
  124. typeArguments.put(typeParameter, typeArgument);
  125. }
  126. public void setConstraintSystem(@NotNull ConstraintSystem constraintSystem) {
  127. this.constraintSystem = constraintSystem;
  128. }
  129. @Nullable
  130. public ConstraintSystem getConstraintSystem() {
  131. return constraintSystem;
  132. }
  133. public void recordValueArgument(@NotNull ValueParameterDescriptor valueParameter, @NotNull ResolvedValueArgument valueArgument) {
  134. assert !valueArguments.containsKey(valueParameter) : valueParameter + " -> " + valueArgument;
  135. valueArguments.put(valueParameter, valueArgument);
  136. }
  137. @Override
  138. @NotNull
  139. public ReceiverValue getReceiverArgument() {
  140. return receiverArgument;
  141. }
  142. @Override
  143. @NotNull
  144. public ReceiverValue getThisObject() {
  145. return thisObject;
  146. }
  147. @Override
  148. @NotNull
  149. public ExplicitReceiverKind getExplicitReceiverKind() {
  150. return explicitReceiverKind;
  151. }
  152. @Override
  153. @NotNull
  154. public Map<ValueParameterDescriptor, ResolvedValueArgument> getValueArguments() {
  155. return valueArguments;
  156. }
  157. @NotNull
  158. @Override
  159. public List<ResolvedValueArgument> getValueArgumentsByIndex() {
  160. List<ResolvedValueArgument> arguments = new ArrayList<ResolvedValueArgument>(candidateDescriptor.getValueParameters().size());
  161. for (int i = 0; i < candidateDescriptor.getValueParameters().size(); ++i) {
  162. arguments.add(null);
  163. }
  164. for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : valueArguments.entrySet()) {
  165. if (arguments.set(entry.getKey().getIndex(), entry.getValue()) != null) {
  166. throw new IllegalStateException();
  167. }
  168. }
  169. for (Object o : arguments) {
  170. if (o == null) {
  171. throw new IllegalStateException();
  172. }
  173. }
  174. return arguments;
  175. }
  176. public void argumentHasNoType() {
  177. this.someArgumentHasNoType = true;
  178. }
  179. @Override
  180. public boolean isDirty() {
  181. return someArgumentHasNoType;
  182. }
  183. @NotNull
  184. @Override
  185. public Map<TypeParameterDescriptor, JetType> getTypeArguments() {
  186. return typeArguments;
  187. }
  188. @Override
  189. public boolean isSafeCall() {
  190. return isSafeCall;
  191. }
  192. }