예제 #1
0
        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);
        }
예제 #6
0
        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 }));
        }
예제 #7
0
        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);
     }
 }
예제 #9
0
        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;
            }
        }