/// <summary> /// Проверяет, подходит ли фаункция для вызова с указанными параметрами /// </summary> /// <param name="candidate"></param> /// <param name="givenParameterTypes">Типы параметров, указанные пользователем</param> /// <returns></returns> private bool IsSuitableFunction( function_node candidate, type_node[] givenParameterTypes, expression_node patternInstance, location deconstructionLocation, out type_node[] parameterTypes) { parameterTypes = new type_node[givenParameterTypes.Length]; var selfParameter = candidate.is_extension_method ? candidate.parameters.First(IsSelfParameter) : null; Debug.Assert(!candidate.is_extension_method || selfParameter != null, "Couldn't find self parameter in extension method"); var candidateParameterTypes = candidate.is_extension_method ? candidate.parameters.Where(x => !IsSelfParameter(x)).ToArray() : candidate.parameters.ToArray(); if (candidateParameterTypes.Length != givenParameterTypes.Length) { return(false); } // Разрешаем только deconstruct текущего класса, родительские в расчет не берем if (candidate is common_method_node commonMethod && !AreTheSameType(patternInstance.type, commonMethod.cont_type)) { return(false); } var genericDeduceNeeded = candidate.is_extension_method && candidate.is_generic_function; type_node[] deducedGenerics = new type_node[candidate.generic_parameters_count]; if (genericDeduceNeeded) { // Выводим дженерики по self var nils = new List <int>(); var deduceSucceded = generic_convertions.DeduceInstanceTypes(selfParameter.type, patternInstance.type, deducedGenerics, nils); if (!deduceSucceded || deducedGenerics.Contains(null)) { return(false); } } for (int i = 0; i < givenParameterTypes.Length; i++) { var givenParameter = givenParameterTypes[i]; var candidateParameter = candidateParameterTypes[i].type; if (genericDeduceNeeded && (candidateParameter.is_generic_parameter || candidateParameter.is_generic_type_instance)) { candidateParameter = InstantiateParameter(candidateParameter, deducedGenerics); } if (givenParameter != null && !AreTheSameType(candidateParameter, givenParameter)) { return(false); } parameterTypes[i] = candidateParameter; } return(true); }
/// <summary> /// Проверяет, подходит ли фаункция для вызова с указанными параметрами /// </summary> /// <param name="candidate"></param> /// <param name="givenParameterTypes">Типы параметров, указанные пользователем</param> /// <returns></returns> private bool IsSuitableFunction( function_node candidate, type_node[] givenParameterTypes, expression_node patternInstance, location deconstructionLocation, out type_node[] parameterTypes) { parameterTypes = new type_node[givenParameterTypes.Length]; var selfParameter = candidate.is_extension_method ? candidate.parameters.First(IsSelfParameter) : null; Debug.Assert(!candidate.is_extension_method || selfParameter != null, "Couldn't find self parameter in extension method"); var candidateParameterTypes = candidate.is_extension_method ? candidate.parameters.Where(x => !IsSelfParameter(x)).ToArray() : candidate.parameters.ToArray(); if (candidateParameterTypes.Length != givenParameterTypes.Length) { return(false); } var genericDeduceNeeded = candidate.is_extension_method && candidate.is_generic_function; type_node[] deducedGenerics = new type_node[candidate.generic_parameters_count]; if (genericDeduceNeeded) { // Выводим дженерики по self var nils = new List <int>(); var deduceSucceded = generic_convertions.DeduceInstanceTypes(selfParameter.type, patternInstance.type, deducedGenerics, nils); if (!deduceSucceded || deducedGenerics.Contains(null)) { // Проверка на то, что в Deconstruct все дженерики выводятся по self делается в другом месте // TODO Patterns: сделать проверку из коммента выше // TODO Patterns: запретить дженерик методы в классах. Можно использовать только дженерик-типы самого класса в качестве параметров //AddError(deconstructionLocation, "COULDNT_DEDUCE_DECONSTRUCT_GENERIC_TYPE"); return(false); } } for (int i = 0; i < givenParameterTypes.Length; i++) { var givenParameter = givenParameterTypes[i]; var candidateParameter = candidateParameterTypes[i].type; if (genericDeduceNeeded && (candidateParameter.is_generic_parameter || candidateParameter.is_generic_type_instance)) { candidateParameter = InstantiateParameter(candidateParameter, deducedGenerics); } if (givenParameter != null && !AreTheSameType(candidateParameter, givenParameter)) { return(false); } parameterTypes[i] = candidateParameter; } return(true); }