Ejemplo n.º 1
0
		/// <summary>
		/// Validates and constructs generic entities out of an ambiguous generic definition entity.
		/// </summary>
		private IEntity ConstructAmbiguousEntity(Node constructionNode, Ambiguous ambiguousDefinition, IType[] typeArguments)
		{
			var checker = new GenericConstructionChecker(typeArguments, constructionNode); 
			var matches = new List<IEntity>(ambiguousDefinition.Entities);
			bool reportErrors = false;
			foreach (Predicate<IEntity> check in checker.Checks)
			{
				matches = matches.Collect(check);

				if (matches.Count == 0)
				{
					Errors.Add(checker.Errors[0]); // only report first error, assuming the rest are superfluous
					return TypeSystemServices.ErrorEntity;
				}

				if (reportErrors)
					checker.ReportErrors(Errors);

				checker.DiscardErrors();

				// We only want full error reporting once we get down to a single candidate
				if (matches.Count == 1)
					reportErrors = true;
			}

			IEntity[] constructedMatches = Array.ConvertAll<IEntity, IEntity>(matches.ToArray(), def => MakeGenericEntity(def, typeArguments));
			return Entities.EntityFromList(constructedMatches);
		}
Ejemplo n.º 2
0
        /// <summary>
        /// Validates and constructs generic entities out of an ambiguous generic definition entity.
        /// </summary>
        private IEntity ConstructAmbiguousEntity(Node constructionNode, Ambiguous ambiguousDefinition, IType[] typeArguments)
        {
            var  checker      = new GenericConstructionChecker(typeArguments, constructionNode);
            var  matches      = new List <IEntity>(ambiguousDefinition.Entities);
            bool reportErrors = false;

            foreach (Predicate <IEntity> check in checker.Checks)
            {
                matches = matches.Collect(check);

                if (matches.Count == 0)
                {
                    Errors.Add(checker.Errors[0]);                     // only report first error, assuming the rest are superfluous
                    return(TypeSystemServices.ErrorEntity);
                }

                if (reportErrors)
                {
                    checker.ReportErrors(Errors);
                }

                checker.DiscardErrors();

                // We only want full error reporting once we get down to a single candidate
                if (matches.Count == 1)
                {
                    reportErrors = true;
                }
            }

            IEntity[] constructedMatches = Array.ConvertAll <IEntity, IEntity>(matches.ToArray(), def => MakeGenericEntity(def, typeArguments));
            return(Entities.EntityFromList(constructedMatches));
        }
Ejemplo n.º 3
0
        // Sometimes, for the purpose of overload resolution, it doesn't matter which overload
        // you pick, because they all take the same callable type and only differ in the rest of
        // the param list
        private IMethod ResolveAmbiguousInvocationContext(Ambiguous entity, int argumentIndex)
        {
            var candidates = entity.Entities
                             .OfType <IMethod>()
                             .Where(m => m.GetParameters().Length > argumentIndex && m.GetParameters()[argumentIndex].Type is ICallableType)
                             .ToArray();

            if (candidates.Length > 0)
            {
                var first = candidates[0];
                if (candidates.Length == 1)
                {
                    return(first);
                }
                var correspondingType = first.GetParameters()[argumentIndex].Type;
                if (candidates.Skip(1).All(m => m.GetParameters()[argumentIndex].Type == correspondingType))
                {
                    return(first);
                }
                var returnType = ((ICallableType)first.GetParameters()[argumentIndex].Type).GetSignature().ReturnType;
                if (candidates.Skip(1).All(m => ((ICallableType)m.GetParameters()[argumentIndex].Type).GetSignature().ReturnType == returnType))
                {
                    _closure["$InferredReturnType"] = returnType;
                }
            }
            AstAnnotations.MarkAmbiguousSignature(MethodInvocationContext);
            AstAnnotations.MarkAmbiguousSignature(_closure);
            return(null);
        }
Ejemplo n.º 4
0
        private IType GetTypeFromMethodInvocationContext()
        {
            if (MethodInvocationContext == null)
            {
                return(null);
            }

            int argumentIndex = MethodInvocationContext.Arguments.IndexOf(Closure);

            if (argumentIndex == -1 && _asyncParent != null)
            {
                argumentIndex = MethodInvocationContext.Arguments.IndexOf(_asyncParent);
            }

            var entity = MethodInvocationContext.Target.Entity;
            var method = entity as IMethodBase;

            if (method == null)
            {
                if (entity.EntityType == EntityType.Type)
                {
                    var ctors = ((IType)MethodInvocationContext.Target.Entity).GetConstructors().ToArray();
                    if (ctors.Length == 1)
                    {
                        method = ctors[0];
                    }
                    else if (ctors.Length == 0)
                    {
                        return(null);
                    }
                    else
                    {
                        entity = new Ambiguous(ctors);
                    }
                }
                if (entity.EntityType == EntityType.Ambiguous)
                {
                    method = ResolveAmbiguousInvocationContext((Ambiguous)entity, argumentIndex);
                }
                if (method == null)
                {
                    return(null);
                }
            }

            IParameter[] parameters = method.GetParameters();

            if (argumentIndex < parameters.Length)
            {
                return(parameters[argumentIndex].Type);
            }
            if (method.AcceptVarArgs)
            {
                return(parameters[parameters.Length - 1].Type);
            }
            return(null);
        }
Ejemplo n.º 5
0
        private IEntity ResolvePreferringInternalMacros(string macroTypeName)
        {
            IEntity   resolved  = NameResolutionService.ResolveQualifiedName(macroTypeName);
            Ambiguous ambiguous = resolved as Ambiguous;

            if (null != ambiguous && ambiguous.AllEntitiesAre(EntityType.Type))
            {
                return(Entities.PreferInternalEntitiesOverExternalOnes(ambiguous));
            }
            return(resolved);
        }
Ejemplo n.º 6
0
        private Ambiguous NeedsClarification(FieldStepState stepState)
        {
            Ambiguous clarify = null;

            foreach (var clarification in stepState.Clarifications)
            {
                if (clarification.Values.Length > 1)
                {
                    clarify = clarification;
                    break;
                }
            }
            return(clarify);
        }
Ejemplo n.º 7
0
 IEntity ResolveMacroExtensionType(MacroStatement node, Ambiguous extensions)
 {
     if (null == extensions)
     {
         return(null);
     }
     foreach (var entity in extensions.Entities)
     {
         var extensionType = ResolveMacroExtensionType(node, entity as IMethod);
         if (null != extensionType)
         {
             return(extensionType);
         }
     }
     return(null);
 }
Ejemplo n.º 8
0
        public static IEntity PreferInternalEntitiesOverExternalOnes(IEntity entity)
        {
            Ambiguous ambiguous = entity as Ambiguous;

            if (null == ambiguous)
            {
                return(entity);
            }

            bool isAmbiguousBetweenInternalAndExternalEntities = ambiguous.Any(EntityPredicates.IsInternalEntity) &&
                                                                 ambiguous.Any(EntityPredicates.IsNonInternalEntity);

            if (!isAmbiguousBetweenInternalAndExternalEntities)
            {
                return(entity);
            }

            return(EntityFromList(ambiguous.Select(EntityPredicates.IsInternalEntity)));
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Maps a type member involving generic arguments to its constructed counterpart, after substituting
        /// concrete types for generic arguments.
        /// </summary>
        public IEntity Map(IEntity source)
        {
            if (source == null)
            {
                return(null);
            }

            // Map generic source to the constructed owner of this mapping
            if (source == _genericSource)
            {
                return(_constructedOwner);
            }

            Ambiguous ambiguous = source as Ambiguous;

            if (ambiguous != null)
            {
                return(MapAmbiguousEntity(ambiguous));
            }

            IMember member = source as IMember;

            if (member != null)
            {
                return(MapMember(member));
            }

            IType type = source as IType;

            if (type != null)
            {
                return(MapType(type));
            }

            return(source);
        }
Ejemplo n.º 10
0
        private IField <T> ClarifyField(Ambiguous clarify, IRecognize <T> recognizer)
        {
            var field = new FieldClarify(_field);

            foreach (var value in clarify.Values)
            {
                var choice = value as Choice;
                if (choice != null)
                {
                    field.AddDescription(choice.Value,
                                         choice.Description.Description,
                                         choice.Description.Image,
                                         choice.Description.Message);
                    field.AddTerms(choice.Value, choice.Terms.Alternatives);
                }
                else
                {
                    var desc = recognizer.ValueDescription(value);
                    field.AddDescription(value, desc.Description, desc.Image);
                    field.AddTerms(value, recognizer.ValidInputs(value).ToArray());
                }
            }
            return(field);
        }
Ejemplo n.º 11
0
 private IEntity MapAmbiguousEntity(Ambiguous source)
 {
     // Map each individual entity in the ambiguous list
     return(new Ambiguous(Array.ConvertAll <IEntity, IEntity>(source.Entities, Map)));
 }
Ejemplo n.º 12
0
        public async Task <StepResult> ProcessAsync(IDialogContext context, T state, FormState form, IMessageActivity input, IEnumerable <TermMatch> matches)
        {
            var inputText = MessageActivityHelper.GetSanitizedTextInput(input);

            ValidateResult feedback = new ValidateResult();

            feedback.IsValid      = true;
            feedback.Feedback     = null;
            feedback.FeedbackCard = null;
            feedback.Choices      = null;
            FormPrompt prompt         = null;
            FormPrompt feedbackPrompt = null;
            var        iprompt        = _field.Prompt;
            var        fieldState     = (FieldStepState)form.StepState;
            object     response       = null;

            if (fieldState.State == FieldStepStates.SentPrompt)
            {
                // Response to prompt
                var firstMatch = matches.FirstOrDefault();
                if (matches.Count() == 1)
                {
                    response = firstMatch.Value;
                    if (_field.AllowsMultiple && response != null &&
                        (response.GetType() == typeof(string) || !response.GetType().IsIEnumerable()))
                    {
                        response = new List <object>()
                        {
                            response
                        };
                    }
                    feedback = await SetValueAsync(state, response, form);

                    if (!feedback.IsValid && feedback.Choices != null)
                    {
                        var choices = new Ambiguous(inputText.Substring(firstMatch.Start, firstMatch.Length), feedback.Choices);
                        fieldState.State          = FieldStepStates.SentClarify;
                        fieldState.Settled        = new List <object>();
                        fieldState.Clarifications = new List <Ambiguous>()
                        {
                            choices
                        };
                        response = SetValue(state, null);
                        prompt   = ClarifyPrompt((FieldStepState)form.StepState, iprompt.Recognizer, state);
                    }
                }
                else if (matches.Count() > 1)
                {
                    // Check multiple matches for ambiguity
                    var groups = MatchAnalyzer.GroupedMatches(matches);
                    // 1) Could be multiple match groups like for ingredients.
                    // 2) Could be overlapping matches like "onion".
                    // 3) Could be multiple matches where only one is expected.

                    if (!_field.AllowsMultiple)
                    {
                        // Create a single group of all possibilities if only want one value
                        var mergedGroup = groups.SelectMany((group) => group).ToList();
                        groups = new List <List <TermMatch> >()
                        {
                            mergedGroup
                        };
                    }
                    var ambiguous = new List <Ambiguous>();
                    var settled   = new List <object>();
                    foreach (var choices in groups)
                    {
                        if (choices.Count > 1)
                        {
                            var unclearResponses = string.Join(" ", (from choice in choices select inputText.Substring(choice.Start, choice.Length)).Distinct());
                            var values           = from match in choices select match.Value;
                            ambiguous.Add(new Ambiguous(unclearResponses, values));
                        }
                        else
                        {
                            var matchValue = choices.First().Value;
                            if (matchValue != null && matchValue.GetType() != typeof(string) && matchValue.GetType().IsIEnumerable())
                            {
                                foreach (var value in (System.Collections.IEnumerable)matchValue)
                                {
                                    settled.Add(value);
                                }
                            }
                            else
                            {
                                settled.Add(choices.First().Value);
                            }
                        }
                    }
                    if (settled.Count > 1)
                    {
                        // Remove no preference if present
                        settled.Remove(null);
                    }

                    if (ambiguous.Count > 0)
                    {
                        // Need 1 or more clarifications
                        fieldState.State          = FieldStepStates.SentClarify;
                        fieldState.Settled        = settled;
                        fieldState.Clarifications = ambiguous;
                        response = SetValue(state, null);
                        prompt   = ClarifyPrompt((FieldStepState)form.StepState, iprompt.Recognizer, state);
                    }
                    else
                    {
                        if (_field.AllowsMultiple)
                        {
                            response = settled;
                            feedback = await SetValueAsync(state, response, form);
                        }
                        else
                        {
                            Debug.Assert(settled.Count == 1);
                            response = settled.First();
                            feedback = await SetValueAsync(state, response, form);
                        }
                    }
                }
                var unmatched      = MatchAnalyzer.Unmatched(inputText, matches);
                var unmatchedWords = string.Join(" ", unmatched);
                var nonNoise       = Language.NonNoiseWords(Language.WordBreak(unmatchedWords)).ToArray();
                fieldState.Unmatched = null;
                if (_field.Prompt.Annotation.Feedback == FeedbackOptions.Always)
                {
                    fieldState.Unmatched = string.Join(" ", nonNoise);
                }
                else if (_field.Prompt.Annotation.Feedback == FeedbackOptions.Auto &&
                         nonNoise.Any() &&
                         unmatched.Any())
                {
                    fieldState.Unmatched = string.Join(" ", nonNoise);
                }
            }
            else if (fieldState.State == FieldStepStates.SentClarify)
            {
                if (matches.Count() == 1)
                {
                    // Clarified ambiguity
                    var clarify = NeedsClarification(fieldState);
                    fieldState.Settled.Add(matches.First().Value);
                    fieldState.Clarifications.Remove(clarify);
                    if (prompt == null)
                    {
                        // No clarification left, so set the field
                        if (_field.AllowsMultiple)
                        {
                            response = fieldState.Settled;
                            feedback = await SetValueAsync(state, response, form);
                        }
                        else
                        {
                            Debug.Assert(fieldState.Settled.Count == 1);
                            response = fieldState.Settled.First();
                            feedback = await SetValueAsync(state, response, form);
                        }
                        form.SetPhase(StepPhase.Completed);
                    }
                }
            }
            if (form.Phase() == StepPhase.Completed)
            {
                form.StepState = null;
                if (fieldState.Unmatched != null)
                {
                    if (feedback.FeedbackCard != null)
                    {
                        feedbackPrompt = feedback.FeedbackCard;
                    }
                    else if (feedback.Feedback != null)
                    {
                        feedbackPrompt = new FormPrompt {
                            Prompt = feedback.Feedback
                        };
                    }
                    else
                    {
                        if (fieldState.Unmatched != string.Empty)
                        {
                            feedbackPrompt = new Prompter <T>(_field.Template(TemplateUsage.Feedback), _field.Form, null).Prompt(state, _field, fieldState.Unmatched);
                        }
                        else
                        {
                            feedbackPrompt = new Prompter <T>(_field.Template(TemplateUsage.Feedback), _field.Form, null).Prompt(state, _field);
                        }
                    }
                }
            }
            var next = _field.Next(response, state);

            return(new StepResult(feedback.IsValid, next, feedbackPrompt ?? (feedback.FeedbackCard ?? new FormPrompt {
                Prompt = feedback.Feedback
            }), prompt));
        }
Ejemplo n.º 13
0
 private IEntity AmbiguousReference(SimpleTypeReference node, Ambiguous entity)
 {
     CompilerErrors().Add(CompilerErrorFactory.AmbiguousReference(node, node.Name, entity.Entities));
     return(TypeSystemServices.ErrorEntity);
 }
Ejemplo n.º 14
0
        private IPrompt <T> NextClarifyPrompt(T state, FieldStepState stepState, IRecognize <T> recognizer, out Ambiguous clarify)
        {
            IPrompt <T> prompter = null;

            clarify = null;
            foreach (var clarification in stepState.Clarifications)
            {
                if (clarification.Values.Length > 1)
                {
                    clarify = clarification;
                    break;
                }
            }
            if (clarify != null)
            {
                var field = new Field <T>("__clarify__", FieldRole.Value);
                field.Form = _field.Form;
                var template     = _field.Template(TemplateUsage.Clarify);
                var helpTemplate = _field.Template(template.AllowNumbers ? TemplateUsage.EnumOneNumberHelp : TemplateUsage.EnumManyNumberHelp);
                field.SetPrompt(new PromptAttribute(template));
                field.ReplaceTemplate(_field.Template(TemplateUsage.Clarify));
                field.ReplaceTemplate(helpTemplate);
                foreach (var value in clarify.Values)
                {
                    field.AddDescription(value, recognizer.ValueDescription(value));
                    field.AddTerms(value, recognizer.ValidInputs(value).ToArray());
                }
                var choiceRecognizer = new RecognizeEnumeration <T>(field);
                prompter = new Prompter <T>(template, _field.Form, choiceRecognizer);
            }
            return(prompter);
        }
Ejemplo n.º 15
0
		private IEntity MapAmbiguousEntity(Ambiguous source)
		{
			// Map each individual entity in the ambiguous list 
			return new Ambiguous(Array.ConvertAll<IEntity, IEntity>(source.Entities, Map));
		}