public NamespaceType(string name, IEnumerable <TypeProperty> properties, FunctionResolver methodResolver, DecoratorResolver decoratorResolver) : base(name) { this.Properties = properties.ToImmutableDictionary(property => property.Name, LanguageConstants.IdentifierComparer); this.MethodResolver = methodResolver; this.DecoratorResolver = decoratorResolver; }
public NamedObjectType(string name, TypeSymbolValidationFlags validationFlags, IEnumerable <TypeProperty> properties, ITypeReference?additionalPropertiesType, TypePropertyFlags additionalPropertiesFlags = TypePropertyFlags.None, IEnumerable <FunctionOverload>?functions = null) : base(name) { this.ValidationFlags = validationFlags; this.Properties = properties.ToImmutableDictionary(property => property.Name, LanguageConstants.IdentifierComparer); this.MethodResolver = FunctionResolver.Create(functions); this.AdditionalPropertiesType = additionalPropertiesType; this.AdditionalPropertiesFlags = additionalPropertiesFlags; }
public IEnumerable <Decorator> GetMatches(FunctionSymbol symbol, IList <TypeSymbol> argumentTypes) { foreach (var overload in FunctionResolver.GetMatches(symbol, argumentTypes, out var _, out var _)) { var decorator = this.TryGetDecorator(overload); if (decorator != null) { yield return(decorator); } } }
public IEnumerable <Decorator> GetMatches(FunctionSymbol symbol, IList <TypeSymbol> argumentTypes) { if (!functionSymbols.Contains(symbol)) { yield break; } foreach (var overload in FunctionResolver.GetMatches(symbol, argumentTypes, out var _, out var _)) { this.decoratorsByOverloads.TryGetValue(overload, out Decorator? decorator); if (decorator != null) { yield return(decorator); } } }
public DecoratorResolver(IEnumerable <Decorator> decorators) { this.decoratorsByOverloads = decorators.ToImmutableDictionary(decorator => decorator.Overload, decorator => decorator); this.functionResolver = new FunctionResolver(decoratorsByOverloads.Keys); }
public DecoratorResolver(IEnumerable <Decorator> decorators) { this.decoratorsByOverloads = decorators.ToImmutableDictionary(decorator => decorator.Overload, decorator => decorator); this.functionResolver = FunctionResolver.Create(decoratorsByOverloads.Keys); this.functionSymbols = functionResolver.GetKnownFunctions().Values.ToImmutableHashSet(); }
private TypeSymbol GetFunctionSymbolType( FunctionCallSyntax syntax, FunctionSymbol function, ImmutableArray <FunctionArgumentSyntax> argumentSyntaxes, IList <TypeSymbol> argumentTypes, IList <ErrorDiagnostic> errors) { // Recover argument type errors so we can continue type checking for the parent function call. var recoveredArgumentTypes = argumentTypes .Select(t => t.TypeKind == TypeKind.Error ? LanguageConstants.Any : t) .ToList(); var matches = FunctionResolver.GetMatches( function, recoveredArgumentTypes, out IList <ArgumentCountMismatch> countMismatches, out IList <ArgumentTypeMismatch> typeMismatches).ToList(); if (matches.Count == 0) { if (typeMismatches.Any()) { if (typeMismatches.Count > 1 && typeMismatches.Skip(1).All(tm => tm.ArgumentIndex == typeMismatches[0].ArgumentIndex)) { // All type mismatches are equally good (or bad). var parameterTypes = typeMismatches.Select(tm => tm.ParameterType).ToList(); var argumentType = typeMismatches[0].ArgumentType; var signatures = typeMismatches.Select(tm => tm.Source.TypeSignature).ToList(); var argumentSyntax = argumentSyntaxes[typeMismatches[0].ArgumentIndex]; errors.Add(DiagnosticBuilder.ForPosition(argumentSyntax).CannotResolveFunctionOverload(signatures, argumentType, parameterTypes)); } else { // Choose the type mismatch that has the largest index as the best one. var(_, argumentIndex, argumentType, parameterType) = typeMismatches.OrderBy(tm => tm.ArgumentIndex).Last(); errors.Add(DiagnosticBuilder.ForPosition(argumentSyntaxes[argumentIndex]).ArgumentTypeMismatch(argumentType, parameterType)); } } else { // Argument type mismatch wins over count mismatch. Handle count mismatch only when there's no type mismatch. var(actualCount, mininumArgumentCount, maximumArgumentCount) = countMismatches.Aggregate(ArgumentCountMismatch.Reduce); var argumentsSpan = TextSpan.Between(syntax.OpenParen, syntax.CloseParen); errors.Add(DiagnosticBuilder.ForPosition(argumentsSpan).ArgumentCountMismatch(actualCount, mininumArgumentCount, maximumArgumentCount)); } } if (errors.Any()) { return(new ErrorTypeSymbol(errors)); } if (matches.Count == 1) { // we have an exact match or a single ambiguous match // return its type return(matches.Single().ReturnType); } // function arguments are ambiguous (due to "any" type) // technically, the correct behavior would be to return a union of all possible types // unfortunately our language lacks a good type checking construct // and we also don't want users to have to use the converter functions to work around it // instead, we will return the "any" type to short circuit the type checking for those cases return(LanguageConstants.Any); }
public ObjectType(string name, TypeSymbolValidationFlags validationFlags, IEnumerable <TypeProperty> properties, ITypeReference?additionalPropertiesType, TypePropertyFlags additionalPropertiesFlags, FunctionResolver methodResolver) : base(name) { this.ValidationFlags = validationFlags; this.Properties = properties.ToImmutableDictionary(property => property.Name, LanguageConstants.IdentifierComparer); this.MethodResolver = methodResolver; this.AdditionalPropertiesType = additionalPropertiesType; this.AdditionalPropertiesFlags = additionalPropertiesFlags; }
public ObjectType(string name) : base(name) { AdditionalPropertiesType = LanguageConstants.Any; MethodResolver = new FunctionResolver(this, null); }