public override TypeWithNode VisitMethodDeclaration(MethodDeclarationSyntax node) { var outerMethodReturnType = currentMethodReturnType; try { var symbol = semanticModel.GetDeclaredSymbol(node); if (symbol != null) { CreateOverrideEdge(symbol, symbol.OverriddenMethod); currentMethodReturnType = typeSystem.GetSymbolType(symbol); } else { currentMethodReturnType = typeSystem.VoidType; } if (node.Body != null || node.ExpressionBody != null) { return(HandleAsOperation(node)); } else { return(typeSystem.VoidType); } } finally { currentMethodReturnType = outerMethodReturnType; } }
/// <summary> /// Creates a new TypeWithNode /// /// newType must be the result of applying the substitution to this.Type. /// </summary> internal TypeWithNode WithSubstitution(ITypeSymbol newType, TypeSubstitution subst, TypeSystem.Builder?tsBuilder) { if (this.Type is ITypeParameterSymbol tp) { var substituted = subst[tp.TypeParameterKind, tp.FullOrdinal()]; Debug.Assert(SymbolEqualityComparer.Default.Equals(substituted.Type, newType)); if (tsBuilder != null) { var newNode = tsBuilder.Join(substituted.Node, this.Node, new EdgeLabel()); return(substituted.WithNode(newNode)); } else { return(substituted); } } else if (this.Type is INamedTypeSymbol thisNamedTypeSymbol && newType is INamedTypeSymbol newNamedTypeSymbol) { Debug.Assert(SymbolEqualityComparer.Default.Equals(thisNamedTypeSymbol.OriginalDefinition, newNamedTypeSymbol.OriginalDefinition)); Debug.Assert(newNamedTypeSymbol.FullArity() == this.TypeArguments.Count); TypeWithNode[] newTypeArgs = new TypeWithNode[this.TypeArguments.Count]; var newNamedTypeSymbolTypeArguments = newNamedTypeSymbol.FullTypeArguments().ToList(); for (int i = 0; i < newTypeArgs.Length; i++) { newTypeArgs[i] = this.TypeArguments[i].WithSubstitution(newNamedTypeSymbolTypeArguments[i], subst, tsBuilder); } return(new TypeWithNode(newType, this.Node, newTypeArgs)); }
internal IDisposable SaveCurrentMethod() { var outerMethod = currentMethod; var outerMethodReturnType = currentMethodReturnType; return(new CallbackOnDispose(delegate { currentMethod = outerMethod; currentMethodReturnType = outerMethodReturnType; })); }
internal TypeWithNode ExtractTaskReturnType(TypeWithNode taskType) { // See also: EffectiveReturnType() extension method if (taskType.TypeArguments.Count == 0) { return(typeSystem.VoidType); } else { return(taskType.TypeArguments.Single()); } }
public override TypeWithNode VisitEventDeclaration(EventDeclarationSyntax node) { node.ExplicitInterfaceSpecifier?.Accept(this); using var outerMethod = SaveCurrentMethod(); var symbol = semanticModel.GetDeclaredSymbol(node); if (symbol != null) { CreateOverrideEdge(symbol, symbol.OverriddenEvent); currentMethodReturnType = typeSystem.GetSymbolType(symbol); } else { currentMethodReturnType = typeSystem.VoidType; } currentMethod = null; node.AccessorList?.Accept(this); return(typeSystem.VoidType); }
public override TypeWithNode VisitArrayType(ArrayTypeSyntax node) { var elementType = node.ElementType.Accept(this); // Handle nested arrays foreach (var rank in node.RankSpecifiers.Skip(1).Reverse()) { // Trying to insert `?` for nested arrays will be tricky, // because `int[,][]` with nullable nested arrays has to turn into `int[]?[,]` // So for now, just handle nested arrays as oblivious. var nestedArrayType = elementType.Type != null?semanticModel.Compilation.CreateArrayTypeSymbol(elementType.Type) : null; elementType = new TypeWithNode(nestedArrayType, typeSystem.ObliviousNode, new[] { elementType }); } var arrayType = elementType.Type != null?semanticModel.Compilation.CreateArrayTypeSymbol(elementType.Type) : null; var nullNode = CanBeMadeNullableSyntax(node) ? mapping[node] : typeSystem.ObliviousNode; return(new TypeWithNode(arrayType, nullNode, new[] { elementType })); }
public override TypeWithNode VisitConstructorDeclaration(ConstructorDeclarationSyntax node) { var outerMethodReturnType = currentMethodReturnType; try { currentMethodReturnType = typeSystem.VoidType; var operation = semanticModel.GetOperation(node, cancellationToken); if (operation == null) { throw new NotSupportedException($"Could not get operation for {node}"); } if (node.Initializer?.ThisOrBaseKeyword.Kind() != SyntaxKind.ThisKeyword) { HashSet <ISymbol> initializedSymbols = new HashSet <ISymbol>(); foreach (var assgn in operation.DescendantsAndSelf().OfType <ISimpleAssignmentOperation>()) { if (assgn.Target is IFieldReferenceOperation fieldRef) { initializedSymbols.Add(fieldRef.Field); } else if (assgn.Target is IPropertyReferenceOperation propertyRef) { initializedSymbols.Add(propertyRef.Property); } else if (assgn.Target is IEventReferenceOperation eventRef) { initializedSymbols.Add(eventRef.Event); } } if (node.Parent is TypeDeclarationSyntax typeSyntax) { bool isStatic = node.Modifiers.Any(SyntaxKind.StaticKeyword); MarkFieldsAndPropertiesAsNullable(typeSyntax.Members, isStatic, initializedSymbols, node.GetLocation()); } } return(operation.Accept(operationVisitor, new EdgeBuildingContext())); } finally { currentMethodReturnType = outerMethodReturnType; } }
private TypeWithNode HandleMethodDeclaration(BaseMethodDeclarationSyntax node) { using var outerMethod = SaveCurrentMethod(); currentMethod = semanticModel.GetDeclaredSymbol(node); if (currentMethod != null) { CreateOverrideEdge(currentMethod, currentMethod.OverriddenMethod); currentMethodReturnType = GetMethodReturnSymbol(currentMethod); } else { currentMethodReturnType = typeSystem.VoidType; } if (node.Body != null || node.ExpressionBody != null) { return(HandleAsOperation(node)); } else { return(typeSystem.VoidType); } }
public override TypeWithNode VisitIndexerDeclaration(IndexerDeclarationSyntax node) { var outerMethodReturnType = currentMethodReturnType; try { var symbol = semanticModel.GetDeclaredSymbol(node); if (symbol != null) { CreateOverrideEdge(symbol, symbol.OverriddenProperty); currentMethodReturnType = typeSystem.GetSymbolType(symbol); } else { currentMethodReturnType = typeSystem.VoidType; } node.AccessorList?.Accept(this); node.ExpressionBody?.Accept(this); return(typeSystem.VoidType); } finally { currentMethodReturnType = outerMethodReturnType; } }