public void SetUp() { compilation = new SimpleCompilation(TypeSystemLoaderTests.TestAssembly, TypeSystemLoaderTests.Mscorlib, TypeSystemLoaderTests.SystemCore); conversions = new CSharpConversions(compilation); }
public override void VisitForeachStatement(ForeachStatement foreachStatement) { base.VisitForeachStatement(foreachStatement); var rr = ctx.Resolve(foreachStatement) as ForEachResolveResult; if (rr == null) { return; } if (rr.ElementType.Kind == TypeKind.Unknown) { return; } if (ReflectionHelper.GetTypeCode(rr.ElementType) == TypeCode.Object) { return; } if (conversions == null) { conversions = CSharpConversions.Get(ctx.Compilation); } Conversion c = conversions.ImplicitConversion(rr.ElementType, rr.ElementVariable.Type); if (c.IsValid) { return; } var csResolver = ctx.GetResolverStateBefore(foreachStatement); var builder = new TypeSystemAstBuilder(csResolver); AstType elementType = builder.ConvertType(rr.ElementType); AstType variableType = foreachStatement.VariableType; string text = ctx.TranslateString("Collection element type '{0}' is not implicitly convertible to '{1}'"); AddIssue(variableType, string.Format(text, elementType.GetText(), variableType.GetText())); }
public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions) { if (this.Parameters.Count != parameterTypes.Length) { return(Conversion.None); } for (int i = 0; i < parameterTypes.Length; ++i) { if (!parameterTypes[i].Equals(this.Parameters[i].Type)) { if (IsImplicitlyTyped) { // it's possible that different parameter types also lead to a valid conversion return(LambdaConversion.Instance); } else { return(Conversion.None); } } } if (returnType.Equals(this.ReturnType)) { return(LambdaConversion.Instance); } else { return(Conversion.None); } }
internal TypeInference(ICompilation compilation, CSharpConversions conversions) { Debug.Assert(compilation != null); Debug.Assert(conversions != null); this.compilation = compilation; this.conversions = conversions; }
public void Run(AstNode rootNode, TransformContext context) { this.context = context; this.conversions = CSharpConversions.Get(context.TypeSystem); InitializeContext(rootNode.Annotation <UsingScope>()); rootNode.AcceptVisitor(this); }
public TypeInference(ICompilation compilation) { if (compilation == null) throw new ArgumentNullException("compilation"); this.compilation = compilation; this.conversions = CSharpConversions.Get(compilation); }
public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions) { // Anonymous method expressions without parameter lists are applicable to any parameter list. if (HasParameterList) { if (this.Parameters.Count != parameterTypes.Length) { return(Conversion.None); } for (int i = 0; i < parameterTypes.Length; ++i) { if (!conversions.IdentityConversion(parameterTypes[i], this.Parameters[i].Type)) { if (IsImplicitlyTyped) { // it's possible that different parameter types also lead to a valid conversion return(LambdaConversion.Instance); } else { return(Conversion.None); } } } } if (conversions.IdentityConversion(this.ReturnType, returnType) || conversions.ImplicitConversion(this.InferredReturnType, returnType).IsValid) { return(LambdaConversion.Instance); } else { return(Conversion.None); } }
public override void VisitForeachStatement(ForeachStatement foreachStatement) { base.VisitForeachStatement(foreachStatement); var rr = ctx.Resolve(foreachStatement) as ForEachResolveResult; if (rr == null) return; if (rr.ElementType.Kind == TypeKind.Unknown) return; if (ReflectionHelper.GetTypeCode(rr.ElementType) == TypeCode.Object) return; if (conversions == null) { conversions = CSharpConversions.Get(ctx.Compilation); } Conversion c = conversions.ImplicitConversion(rr.ElementType, rr.ElementVariable.Type); if (c.IsValid) return; var csResolver = ctx.GetResolverStateBefore(foreachStatement); var builder = new TypeSystemAstBuilder(csResolver); AstType elementType = builder.ConvertType(rr.ElementType); AstType variableType = foreachStatement.VariableType; string issueText = ctx.TranslateString("Collection element type '{0}' is not implicitly convertible to '{1}'"); string fixText = ctx.TranslateString("Use type '{0}'"); AddIssue(variableType, string.Format(issueText, elementType.GetText(), variableType.GetText()), new CodeAction(string.Format(fixText, elementType.GetText()), script => script.Replace(variableType, elementType))); }
/// <remarks> /// See $7.10.10 of C# 4 Spec for details. /// </remarks> Value Visit(TypeIsResolveResult result) { var importedType = NullableType.GetUnderlyingType(Import(result.TargetType)); var val = Convert(result.Input); var conversions = CSharpConversions.Get(debuggerTypeSystem); bool evalResult = false; if (!val.IsNull) { IType inputType = NullableType.GetUnderlyingType(val.Type); if (inputType.Equals(importedType)) { evalResult = true; } else if (conversions.IsImplicitReferenceConversion(inputType, importedType)) { evalResult = true; } else if (conversions.IsBoxingConversion(inputType, importedType)) { evalResult = true; } } return(Eval.CreateValue(evalThread, evalResult)); }
public OverloadResolution(ICompilation compilation, ResolveResult[] arguments, string[] argumentNames = null, IType[] typeArguments = null, CSharpConversions conversions = null) { if (compilation == null) { throw new ArgumentNullException("compilation"); } if (arguments == null) { throw new ArgumentNullException("arguments"); } if (argumentNames == null) { argumentNames = new string[arguments.Length]; } else if (argumentNames.Length != arguments.Length) { throw new ArgumentException("argumentsNames.Length must be equal to arguments.Length"); } this.compilation = compilation; this.arguments = arguments; this.argumentNames = argumentNames; // keep explicitlyGivenTypeArguments==null when no type arguments were specified if (typeArguments != null && typeArguments.Length > 0) { this.explicitlyGivenTypeArguments = typeArguments; } this.conversions = conversions ?? CSharpConversions.Get(compilation); this.AllowExpandingParams = true; this.AllowOptionalParameters = true; }
public CSharpResolver(ICompilation compilation) { if (compilation == null) throw new ArgumentNullException("compilation"); this.compilation = compilation; this.conversions = CSharpConversions.Get(compilation); this.context = new CSharpTypeResolveContext(compilation.MainAssembly); }
public TypeInference(ICompilation compilation) { if (compilation == null) { throw new ArgumentNullException("compilation"); } this.compilation = compilation; this.conversions = CSharpConversions.Get(compilation); }
public CSharpResolver(CSharpTypeResolveContext context) { if (context == null) throw new ArgumentNullException("context"); this.compilation = context.Compilation; this.conversions = CSharpConversions.Get(compilation); this.context = context; if (context.CurrentTypeDefinition != null) currentTypeDefinitionCache = new TypeDefinitionCache(context.CurrentTypeDefinition); }
private CSharpResolver(ICompilation compilation, CSharpConversions conversions, CSharpTypeResolveContext context, bool checkForOverflow, bool isWithinLambdaExpression, TypeDefinitionCache currentTypeDefinitionCache, ImmutableStack<IVariable> localVariableStack, ObjectInitializerContext objectInitializerStack) { this.compilation = compilation; this.conversions = conversions; this.context = context; this.checkForOverflow = checkForOverflow; this.isWithinLambdaExpression = isWithinLambdaExpression; this.currentTypeDefinitionCache = currentTypeDefinitionCache; this.localVariableStack = localVariableStack; this.objectInitializerStack = objectInitializerStack; }
internal MetadataContext(HackedSimpleCompilation compilation, EmitSettings settings) { this.hackedCompilation = compilation; Settings = settings ?? new EmitSettings(); CSharpConversions = CSharpConversions.Get(compilation); moduleMap = compilation.Modules.ToDictionary(m => new ModuleSignature(m.Name)); Modules = moduleMap.Keys.ToImmutableArray(); MainModule = Modules[0]; mutableModule = (VirtualModule)moduleMap[MainModule]; Debug.Assert(MainModule.Name == this.Compilation.MainModule.Name); }
/// <summary> /// Validates whether the given type argument satisfies the constraints for the given type parameter. /// </summary> /// <param name="typeParameter">The type parameter.</param> /// <param name="typeArgument">The type argument.</param> /// <param name="substitution">The substitution that defines how type parameters are replaced with type arguments. /// The substitution is used to check constraints that depend on other type parameters (or recursively on the same type parameter). /// May be null if no substitution should be used.</param> /// <returns>True if the constraints are satisfied; false otherwise.</returns> public static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution = null) { if (typeParameter == null) { throw new ArgumentNullException("typeParameter"); } if (typeArgument == null) { throw new ArgumentNullException("typeArgument"); } return(ValidateConstraints(typeParameter, typeArgument, substitution, CSharpConversions.Get(typeParameter.Owner.Compilation))); }
public CSharpResolver(ICompilation compilation) { if (compilation == null) throw new ArgumentNullException("compilation"); this.compilation = compilation; this.conversions = CSharpConversions.Get(compilation); this.context = new CSharpTypeResolveContext(compilation.MainAssembly); var pc = compilation.MainAssembly.UnresolvedAssembly as CSharpProjectContent; if (pc != null) { this.checkForOverflow = pc.CompilerSettings.CheckForOverflow; } }
public SupportsIndexingCriterion(IType returnType, IEnumerable<IType> argumentTypes, CSharpConversions conversions, bool isWriteAccess = false) { if (returnType == null) throw new ArgumentNullException("returnType"); if (argumentTypes == null) throw new ArgumentNullException("argumentTypes"); if (conversions == null) throw new ArgumentNullException("conversions"); this.returnType = returnType; this.argumentTypes = argumentTypes.ToList(); this.conversions = conversions; this.isWriteAccess = isWriteAccess; }
private ExpressionWithResolveResult HandleImplicitConversion(IMethod method, TranslatedExpression argument) { var conversions = CSharpConversions.Get(expressionBuilder.compilation); IType targetType = method.ReturnType; var conv = conversions.ImplicitConversion(argument.Type, targetType); if (!(conv.IsUserDefined && conv.Method.Equals(method))) { // implicit conversion to targetType isn't directly possible, so first insert a cast to the argument type argument = argument.ConvertTo(method.Parameters[0].Type, expressionBuilder); conv = conversions.ImplicitConversion(argument.Type, targetType); } return(new CastExpression(expressionBuilder.ConvertType(targetType), argument.Expression) .WithRR(new ConversionResolveResult(targetType, argument.ResolveResult, conv))); }
public SupportsIndexingCriterion(IType returnType, IEnumerable <IType> argumentTypes, CSharpConversions conversions, bool isWriteAccess = false) { if (returnType == null) { throw new ArgumentNullException("returnType"); } if (argumentTypes == null) { throw new ArgumentNullException("argumentTypes"); } if (conversions == null) { throw new ArgumentNullException("conversions"); } this.returnType = returnType; this.argumentTypes = argumentTypes.ToList(); this.conversions = conversions; this.isWriteAccess = isWriteAccess; }
public OverloadResolution(ICompilation compilation, ResolveResult[] arguments, string[] argumentNames = null, IType[] typeArguments = null, CSharpConversions conversions = null) { if (compilation == null) throw new ArgumentNullException("compilation"); if (arguments == null) throw new ArgumentNullException("arguments"); if (argumentNames == null) argumentNames = new string[arguments.Length]; else if (argumentNames.Length != arguments.Length) throw new ArgumentException("argumentsNames.Length must be equal to arguments.Length"); this.compilation = compilation; this.arguments = arguments; this.argumentNames = argumentNames; // keep explicitlyGivenTypeArguments==null when no type arguments were specified if (typeArguments != null && typeArguments.Length > 0) this.explicitlyGivenTypeArguments = typeArguments; this.conversions = conversions ?? CSharpConversions.Get(compilation); this.AllowExpandingParams = true; this.AllowOptionalParameters = true; }
public override void VisitIsExpression(IsExpression isExpression) { base.VisitIsExpression(isExpression); var conversions = CSharpConversions.Get(ctx.Compilation); var exprType = ctx.Resolve(isExpression.Expression).Type; var providedType = ctx.ResolveType(isExpression.Type); if (exprType.Kind == TypeKind.Unknown || providedType.Kind == TypeKind.Unknown) { return; } if (IsValidReferenceOrBoxingConversion(exprType, providedType)) { return; } var exprTP = exprType as ITypeParameter; var providedTP = providedType as ITypeParameter; if (exprTP != null) { if (IsValidReferenceOrBoxingConversion(exprTP.EffectiveBaseClass, providedType) && exprTP.EffectiveInterfaceSet.All(i => IsValidReferenceOrBoxingConversion(i, providedType))) { return; } } if (providedTP != null) { if (IsValidReferenceOrBoxingConversion(exprType, providedTP.EffectiveBaseClass)) { return; } } AddIssue(isExpression, ctx.TranslateString("Given expression is never of the provided type")); }
public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions) { return(conversions.ImplicitConversion(inferredReturnType, returnType)); }
public ConstraintValidatingSubstitution(IReadOnlyList <IType> classTypeArguments, IReadOnlyList <IType> methodTypeArguments, OverloadResolution overloadResolution) : base(classTypeArguments, methodTypeArguments) { this.conversions = overloadResolution.conversions; }
internal static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution, CSharpConversions conversions) { switch (typeArgument.Kind) { // void, null, and pointers cannot be used as type arguments case TypeKind.Void: case TypeKind.Null: case TypeKind.Pointer: return false; } if (typeParameter.HasReferenceTypeConstraint) { if (typeArgument.IsReferenceType != true) return false; } if (typeParameter.HasValueTypeConstraint) { if (!NullableType.IsNonNullableValueType(typeArgument)) return false; } if (typeParameter.HasDefaultConstructorConstraint) { ITypeDefinition def = typeArgument.GetDefinition(); if (def != null && def.IsAbstract) return false; var ctors = typeArgument.GetConstructors( m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public, GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions ); if (!ctors.Any()) return false; } foreach (IType constraintType in typeParameter.DirectBaseTypes) { IType c = constraintType; if (substitution != null) c = c.AcceptVisitor(substitution); if (!conversions.IsConstraintConvertible(typeArgument, c)) return false; } return true; }
public ConstraintValidatingSubstitution(IList<IType> classTypeArguments, IList<IType> methodTypeArguments, OverloadResolution overloadResolution) : base(classTypeArguments, methodTypeArguments) { this.conversions = overloadResolution.conversions; }
public override void VisitIndexerExpression(IndexerExpression indexerExpression) { base.VisitIndexerExpression(indexerExpression); var localResolveResult = context.Resolve(indexerExpression.Target) as LocalResolveResult; if (localResolveResult == null) { return; } var resolveResult = context.Resolve(indexerExpression); if (localResolveResult == null) { return; } var parent = indexerExpression.Parent; while (parent is ParenthesizedExpression) { parent = parent.Parent; } if (parent is DirectionExpression) { // The only types which are indexable and where the indexing expression // results in a variable is an actual array type AddCriterion(localResolveResult.Variable, new IsArrayTypeCriterion()); } else if (resolveResult is ArrayAccessResolveResult) { var arrayResolveResult = (ArrayAccessResolveResult)resolveResult; var arrayType = arrayResolveResult.Array.Type as ArrayType; if (arrayType != null) { var parameterTypes = arrayResolveResult.Indexes.Select(index => index.Type); var criterion = new SupportsIndexingCriterion(arrayType.ElementType, parameterTypes, CSharpConversions.Get(context.Compilation)); AddCriterion(localResolveResult.Variable, criterion); } } else if (resolveResult is CSharpInvocationResolveResult) { var invocationResolveResult = (CSharpInvocationResolveResult)resolveResult; var parameterTypes = invocationResolveResult.Arguments.Select(arg => arg.Type); var criterion = new SupportsIndexingCriterion(invocationResolveResult.Member.ReturnType, parameterTypes, CSharpConversions.Get(context.Compilation)); AddCriterion(localResolveResult.Variable, criterion); } }
public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions) { return conversions.ImplicitConversion(inferredReturnType, returnType); }
/// <summary> /// Gets whether the lambda body is valid for the given parameter types and return type. /// </summary> /// <returns> /// Produces a conversion with <see cref="Conversion.IsAnonymousFunctionConversion"/>=<c>true</c> if the lambda is valid; /// otherwise returns <see cref="Conversion.None"/>. /// </returns> public abstract Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions);
static bool IsEligibleExtensionMethod(ICompilation compilation, CSharpConversions conversions, IType targetType, IMethod method, bool useTypeInference, out IType[] outInferredTypes) { outInferredTypes = null; if (targetType == null) return true; if (method.Parameters.Count == 0) return false; IType thisParameterType = method.Parameters[0].Type; if (useTypeInference && method.TypeParameters.Count > 0) { // We need to infer type arguments from targetType: TypeInference ti = new TypeInference(compilation, conversions); ResolveResult[] arguments = { new ResolveResult(targetType) }; IType[] parameterTypes = { method.Parameters[0].Type }; bool success; var inferredTypes = ti.InferTypeArguments(method.TypeParameters, arguments, parameterTypes, out success); var substitution = new TypeParameterSubstitution(null, inferredTypes); // Validate that the types that could be inferred (aren't unknown) satisfy the constraints: bool hasInferredTypes = false; for (int i = 0; i < inferredTypes.Length; i++) { if (inferredTypes[i].Kind != TypeKind.Unknown && inferredTypes[i].Kind != TypeKind.UnboundTypeArgument) { hasInferredTypes = true; if (!OverloadResolution.ValidateConstraints(method.TypeParameters[i], inferredTypes[i], substitution, conversions)) return false; } else { inferredTypes[i] = method.TypeParameters[i]; // do not substitute types that could not be inferred } } if (hasInferredTypes) outInferredTypes = inferredTypes; thisParameterType = thisParameterType.AcceptVisitor(substitution); } Conversion c = conversions.ImplicitConversion(targetType, thisParameterType); return c.IsValid && (c.IsIdentityConversion || c.IsReferenceConversion || c.IsBoxingConversion); }
public override void SetUp() { base.SetUp(); conversions = new CSharpConversions(compilation); }
void AssertDoesNotMatch(IType candidateType, IType elementType, bool isWriteAccess, params IType[] indexTypes) { var criterion = new SupportsIndexingCriterion(elementType, indexTypes, CSharpConversions.Get(compilation), isWriteAccess); Assert.IsFalse(criterion.SatisfiedBy(candidateType)); }
public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions) { Assert.AreEqual(expectedParameterTypes, parameterTypes); return conversions.ImplicitConversion(inferredReturnType, returnType); }
internal static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution, CSharpConversions conversions) { switch (typeArgument.Kind) // void, null, and pointers cannot be used as type arguments { case TypeKind.Void: case TypeKind.Null: case TypeKind.Pointer: return(false); } if (typeParameter.HasReferenceTypeConstraint) { if (typeArgument.IsReferenceType != true) { return(false); } } if (typeParameter.HasValueTypeConstraint) { if (!NullableType.IsNonNullableValueType(typeArgument)) { return(false); } } if (typeParameter.HasDefaultConstructorConstraint) { ITypeDefinition def = typeArgument.GetDefinition(); if (def != null && def.IsAbstract) { return(false); } var ctors = typeArgument.GetConstructors( m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public, GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions ); if (!ctors.Any()) { return(false); } } foreach (IType constraintType in typeParameter.DirectBaseTypes) { IType c = constraintType; if (substitution != null) { c = c.AcceptVisitor(substitution); } if (!conversions.IsConstraintConvertible(typeArgument, c)) { return(false); } } return(true); }
public GatherVisitor(BaseRefactoringContext ctx) : base(ctx) { conversions = CSharpConversions.Get(ctx.Compilation); }
public OverloadResolution PerformOverloadResolution(ICompilation compilation, ResolveResult[] arguments, string[] argumentNames = null, bool allowExtensionMethods = true, bool allowExpandingParams = true, bool allowOptionalParameters = true, bool checkForOverflow = false, CSharpConversions conversions = null) { Log.WriteLine("Performing overload resolution for " + this); Log.WriteCollection(" Arguments: ", arguments); var typeArgumentArray = this.TypeArguments.ToArray(); OverloadResolution or = new OverloadResolution(compilation, arguments, argumentNames, typeArgumentArray, conversions); or.AllowExpandingParams = allowExpandingParams; or.AllowOptionalParameters = allowOptionalParameters; or.CheckForOverflow = checkForOverflow; or.AddMethodLists(methodLists); if (allowExtensionMethods && !or.FoundApplicableCandidate) { // No applicable match found, so let's try extension methods. var extensionMethods = this.GetExtensionMethods(); if (extensionMethods.Any()) { Log.WriteLine("No candidate is applicable, trying {0} extension methods groups...", extensionMethods.Count()); ResolveResult[] extArguments = new ResolveResult[arguments.Length + 1]; extArguments[0] = new ResolveResult(this.TargetType); arguments.CopyTo(extArguments, 1); string[] extArgumentNames = null; if (argumentNames != null) { extArgumentNames = new string[argumentNames.Length + 1]; argumentNames.CopyTo(extArgumentNames, 1); } var extOr = new OverloadResolution(compilation, extArguments, extArgumentNames, typeArgumentArray, conversions); extOr.AllowExpandingParams = allowExpandingParams; extOr.AllowOptionalParameters = allowOptionalParameters; extOr.IsExtensionMethodInvocation = true; extOr.CheckForOverflow = checkForOverflow; foreach (var g in extensionMethods) { foreach (var method in g) { Log.Indent(); OverloadResolutionErrors errors = extOr.AddCandidate(method); Log.Unindent(); or.LogCandidateAddingResult(" Extension", method, errors); } if (extOr.FoundApplicableCandidate) { break; } } // For the lack of a better comparison function (the one within OverloadResolution // cannot be used as it depends on the argument set): if (extOr.FoundApplicableCandidate || or.BestCandidate == null) { // Consider an extension method result better than the normal result only // if it's applicable; or if there is no normal result. or = extOr; } } } Log.WriteLine("Overload resolution finished, best candidate is {0}.", or.GetBestCandidateWithSubstitutedTypeArguments()); return(or); }
public GatherVisitor (BaseRefactoringContext ctx) : base (ctx) { conversions = CSharpConversions.Get(ctx.Compilation); }
public void SetUp() { compilation = new SimpleCompilation(CecilLoaderTests.Mscorlib); conversions = new CSharpConversions(compilation); }