public TypeWithAnnotations ToTypeWithAnnotations( CSharpCompilation compilation, bool asAnnotatedType = false ) { if (Type?.IsTypeParameterDisallowingAnnotationInCSharp8() == true) { var type = TypeWithAnnotations.Create(Type, NullableAnnotation.NotAnnotated); return(State == NullableFlowState.MaybeDefault ? type.SetIsAnnotated(compilation) : type); } NullableAnnotation annotation = asAnnotatedType ? ( Type?.IsValueType == true ? NullableAnnotation.NotAnnotated : NullableAnnotation.Annotated ) : ( State.IsNotNull() || Type?.CanContainNull() == false ? NullableAnnotation.NotAnnotated : NullableAnnotation.Annotated ); return(TypeWithAnnotations.Create(this.Type, annotation)); }
private TypeWithState(TypeSymbol?type, NullableFlowState state) { Debug.Assert(state == NullableFlowState.NotNull || type?.CanContainNull() != false); Debug.Assert(state != NullableFlowState.MaybeDefault || type is null || type.IsTypeParameterDisallowingAnnotationInCSharp8()); Type = type; State = state; }
public TypeWithAnnotations ToTypeWithAnnotations() { NullableAnnotation annotation = this.State.IsNotNull() || Type?.CanContainNull() == false || Type?.IsTypeParameterDisallowingAnnotation() == true ? NullableAnnotation.NotAnnotated : NullableAnnotation.Annotated; return(TypeWithAnnotations.Create(this.Type, annotation)); }
/// <summary> /// Create a fresh decision tree for the given input expression of the given type. /// </summary> public static DecisionTree Create(BoundExpression expression, TypeSymbol type, Symbol enclosingSymbol) { Debug.Assert(expression.Type == type); LocalSymbol temp = null; if (expression.ConstantValue == null) { // Unless it is a constant, the decision tree acts on a copy of the input expression. // We create a temp to represent that copy. Lowering will assign into this temp. temp = new SynthesizedLocal(enclosingSymbol as MethodSymbol, type, SynthesizedLocalKind.PatternMatching, expression.Syntax, false, RefKind.None); expression = new BoundLocal(expression.Syntax, temp, null, type); } if (type.CanContainNull() || type.SpecialType == SpecialType.None) { // We need the ByType decision tree to separate null from non-null values. // Note that, for the purpose of the decision tree (and subsumption), we // ignore the fact that the input may be a constant, and therefore always // or never null. return(new ByType(expression, type, temp)); } else { // If it is a (e.g. builtin) value type, we can switch on its (constant) values. return(new ByValue(expression, type, temp)); } }
public static TypeWithState Create(TypeSymbol?type, NullableFlowState defaultState) { if (defaultState == NullableFlowState.MaybeDefault && (type is null || type.IsTypeParameterDisallowingAnnotationInCSharp8())) { Debug.Assert(type?.IsNullableTypeOrTypeParameter() != true); return(new TypeWithState(type, defaultState)); } var state = defaultState != NullableFlowState.NotNull && type?.CanContainNull() != false ? NullableFlowState.MaybeNull : NullableFlowState.NotNull; return(new TypeWithState(type, state)); }
public static TypeWithState ForType(TypeSymbol type) => new TypeWithState(type, type?.CanContainNull() == true ? NullableFlowState.MaybeNull : NullableFlowState.NotNull);
private TypeWithState(TypeSymbol type, NullableFlowState state) { Debug.Assert(state == NullableFlowState.NotNull || type?.CanContainNull() != false); Type = type; State = state; }
public static TypeWithState Create(TypeSymbol type, NullableFlowState defaultState) { var state = defaultState == NullableFlowState.MaybeNull && type?.CanContainNull() != false ? NullableFlowState.MaybeNull : NullableFlowState.NotNull; return(new TypeWithState(type, state)); }
public static TypeWithState ForType(TypeSymbol type) { var state = type?.CanContainNull() != false ? NullableFlowState.MaybeNull : NullableFlowState.NotNull; return(new TypeWithState(type, state)); }