internal BinderWithContainingMemberOrLambda(Binder next, BinderFlags flags, Symbol containingMemberOrLambda) : base(next, flags) { Debug.Assert(containingMemberOrLambda != null); _containingMemberOrLambda = containingMemberOrLambda; }
/// <summary> /// Construct context /// </summary> public RegionAnalysisContext(CSharpCompilation compilation, Symbol member, BoundNode boundNode, BoundNode firstInRegion, BoundNode lastInRegion) { this.Compilation = compilation; this.Member = member; this.BoundNode = boundNode; this.FirstInRegion = firstInRegion; this.LastInRegion = lastInRegion; this.Failed = boundNode == null || firstInRegion == null || lastInRegion == null || firstInRegion.Syntax.SpanStart > lastInRegion.Syntax.Span.End; if (!this.Failed && ReferenceEquals(firstInRegion, lastInRegion)) { switch (firstInRegion.Kind) { case BoundKind.NamespaceExpression: case BoundKind.TypeExpression: // Some bound nodes are still considered to be invalid for flow analysis this.Failed = true; break; } } }
internal SubsumptionDiagnosticBuilder(Symbol enclosingSymbol, Conversions conversions, BoundExpression expression) : base(enclosingSymbol, conversions) { _subsumptionTree = DecisionTree.Create(expression, expression.Type, enclosingSymbol); }
internal ExecutableCodeBinder(CSharpSyntaxNode root, Symbol memberSymbol, Binder next, BinderFlags additionalFlags) : base(next, (next.Flags | additionalFlags) & ~BinderFlags.AllClearedAtExecutableCodeBoundary) { this.memberSymbol = memberSymbol; this.root = root; this.owner = memberSymbol as MethodSymbol; }
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.PatternMatchingTemp, expression.Syntax, false, RefKind.None); expression = new BoundLocal(expression.Syntax, temp, null, type); } if (expression.Type.CanBeAssignedNull()) { // 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. // If it isn't a builtin, in practice we will only use the Default part of the // ByValue. return new ByValue(expression, type, temp); } }
private void CheckArguments(ImmutableArray<RefKind> argumentRefKindsOpt, ImmutableArray<BoundExpression> arguments, Symbol method) { if (!argumentRefKindsOpt.IsDefault) { Debug.Assert(arguments.Length == argumentRefKindsOpt.Length); for (int i = 0; i < arguments.Length; i++) { if (argumentRefKindsOpt[i] != RefKind.None) { var argument = arguments[i]; switch (argument.Kind) { case BoundKind.FieldAccess: CheckFieldAddress((BoundFieldAccess)argument, method); break; case BoundKind.Local: var local = (BoundLocal)argument; if (local.Syntax.Kind() == SyntaxKind.DeclarationExpression) { CheckOutDeclaration(local, method); } break; } } } } }
public MethodGroupResolution( MethodGroup methodGroup, Symbol otherSymbol, OverloadResolutionResult<MethodSymbol> overloadResolutionResult, AnalyzedArguments analyzedArguments, LookupResultKind resultKind, ImmutableArray<Diagnostic> diagnostics, bool extensionMethodsOfSameViabilityAreAvailable) { Debug.Assert((methodGroup == null) || (methodGroup.Methods.Count > 0)); Debug.Assert((methodGroup == null) || ((object)otherSymbol == null)); // Methods should be represented in the method group. Debug.Assert(((object)otherSymbol == null) || (otherSymbol.Kind != SymbolKind.Method)); Debug.Assert(resultKind != LookupResultKind.Ambiguous); // HasAnyApplicableMethod is expecting Viable methods. Debug.Assert(!diagnostics.IsDefault); Debug.Assert(!extensionMethodsOfSameViabilityAreAvailable || methodGroup == null || !methodGroup.IsExtensionMethodGroup); this.MethodGroup = methodGroup; this.OtherSymbol = otherSymbol; this.OverloadResolutionResult = overloadResolutionResult; this.AnalyzedArguments = analyzedArguments; this.ResultKind = resultKind; this.Diagnostics = diagnostics; this.ExtensionMethodsOfSameViabilityAreAvailable = extensionMethodsOfSameViabilityAreAvailable; }
protected DecisionTreeBuilder( Symbol enclosingSymbol, Conversions conversions) { this._enclosingSymbol = enclosingSymbol; this._conversions = conversions; }
private static void CheckSymbolKind(Symbol symbol) { switch (symbol.Kind) { case SymbolKind.ErrorType: case SymbolKind.NamedType: case SymbolKind.Event: case SymbolKind.Field: case SymbolKind.Method: case SymbolKind.Property: case SymbolKind.TypeParameter: break; // Can sensibly append location. case SymbolKind.ArrayType: case SymbolKind.PointerType: case SymbolKind.Parameter: break; // Can sensibly append location, after unwrapping. case SymbolKind.DynamicType: break; // Can't sensibly append location, but it should never be ambiguous. case SymbolKind.Namespace: case SymbolKind.Alias: case SymbolKind.Assembly: case SymbolKind.NetModule: case SymbolKind.Label: case SymbolKind.Local: case SymbolKind.RangeVariable: case SymbolKind.Preprocessing: default: throw ExceptionUtilities.UnexpectedValue(symbol.Kind); } }
internal static void Analyze( CSharpCompilation compilation, Symbol member, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion, HashSet<PrefixUnaryExpressionSyntax> unassignedVariableAddressOfSyntaxes, out IEnumerable<Symbol> readInside, out IEnumerable<Symbol> writtenInside, out IEnumerable<Symbol> readOutside, out IEnumerable<Symbol> writtenOutside, out IEnumerable<Symbol> captured, out IEnumerable<Symbol> unsafeAddressTaken) { var walker = new ReadWriteWalker(compilation, member, node, firstInRegion, lastInRegion, unassignedVariableAddressOfSyntaxes); try { bool badRegion = false; walker.Analyze(ref badRegion); if (badRegion) { readInside = writtenInside = readOutside = writtenOutside = captured = unsafeAddressTaken = Enumerable.Empty<Symbol>(); } else { readInside = walker._readInside; writtenInside = walker._writtenInside; readOutside = walker._readOutside; writtenOutside = walker._writtenOutside; captured = walker.GetCaptured(); unsafeAddressTaken = walker.GetUnsafeAddressTaken(); } } finally { walker.Free(); } }
internal ImmutableArray<Symbol> BindCref(CrefSyntax syntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics) { ImmutableArray<Symbol> symbols = BindCrefInternal(syntax, out ambiguityWinner, diagnostics); Debug.Assert(!symbols.IsDefault, "Prefer empty to null."); Debug.Assert((symbols.Length > 1) == ((object)ambiguityWinner != null), "ambiguityWinner should be set iff more than one symbol is returned."); return symbols; }
private ImmutableArray<Symbol> BindQualifiedCref(QualifiedCrefSyntax syntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics) { // NOTE: we won't check whether container is an error type - we'll just let BindMemberCref fail // and report a blanket diagnostic. NamespaceOrTypeSymbol container = BindNamespaceOrTypeSymbolInCref(syntax.Container); return BindMemberCref(syntax.Member, container, out ambiguityWinner, diagnostics); }
public virtual void Visit(Symbol symbol) { if ((object)symbol != null) { symbol.Accept(this); } }
private static string GetCapturedVariableFieldName(Symbol variable, ref int uniqueId) { if (IsThis(variable)) { return GeneratedNames.ThisProxyFieldName(); } var local = variable as LocalSymbol; if ((object)local != null) { if (local.SynthesizedKind == SynthesizedLocalKind.LambdaDisplayClass) { return GeneratedNames.MakeLambdaDisplayLocalName(uniqueId++); } if (local.SynthesizedKind == SynthesizedLocalKind.ExceptionFilterAwaitHoistedExceptionLocal) { return GeneratedNames.MakeHoistedLocalFieldName(local.SynthesizedKind, uniqueId++); } if (local.SynthesizedKind == SynthesizedLocalKind.InstrumentationPayload) { return GeneratedNames.MakeSynthesizedInstrumentationPayloadLocalFieldName(uniqueId++); } } Debug.Assert(variable.Name != null); return variable.Name; }
protected override void ReportUnassigned(Symbol symbol, SyntaxNode node) { if (node.Parent.Kind() == SyntaxKind.AddressOfExpression) { _result.Add((PrefixUnaryExpressionSyntax)node.Parent); } }
private MethodBodySemanticModel(CSharpCompilation compilation, Symbol owner, Binder rootBinder, CSharpSyntaxNode syntax, SyntaxTreeSemanticModel parentSemanticModelOpt = null, int speculatedPosition = 0) : base(compilation, syntax, owner, rootBinder, parentSemanticModelOpt, speculatedPosition) { Debug.Assert((object)owner != null); Debug.Assert(owner.Kind == SymbolKind.Method); Debug.Assert(syntax != null); Debug.Assert(owner.ContainingType.IsScriptClass || syntax.Kind != SyntaxKind.CompilationUnit); }
internal LazyObsoleteDiagnosticInfo(Symbol symbol, Symbol containingSymbol, BinderFlags binderFlags) : base(CSharp.MessageProvider.Instance, (int)ErrorCode.Unknown) { this.symbol = symbol; this.containingSymbol = containingSymbol; this.binderFlags = binderFlags; this.lazyActualObsoleteDiagnostic = null; }
public static LambdaCapturedVariable Create(LambdaFrame frame, Symbol captured, ref int uniqueId) { Debug.Assert(captured is LocalSymbol || captured is ParameterSymbol); string fieldName = GetCapturedVariableFieldName(captured, ref uniqueId); TypeSymbol type = GetCapturedVariableFieldType(frame, captured); return new LambdaCapturedVariable(frame, type, fieldName, IsThis(captured)); }
protected override void ReportUnassigned(Symbol symbol, SyntaxNode node) { // TODO: how to handle fields of structs? if (symbol.Kind != SymbolKind.Field) { _result.Add(symbol); } }
/// <summary> /// Checks if 'symbol' is accessible from within assembly 'within'. /// </summary> public static bool IsSymbolAccessible( Symbol symbol, AssemblySymbol within, ref HashSet<DiagnosticInfo> useSiteDiagnostics) { bool failedThroughTypeCheck; return IsSymbolAccessibleCore(symbol, within, null, out failedThroughTypeCheck, within.DeclaringCompilation, ref useSiteDiagnostics); }
internal AbstractRegionControlFlowPass( CSharpCompilation compilation, Symbol member, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion) : base(compilation, member, node, firstInRegion, lastInRegion) { }
// create a SemanticModel for: // (a) A true field initializer (field = value) of a named type (incl. Enums) OR // (b) A constructor initializer (": this(...)" or ": base(...)") OR // (c) A parameter default value private InitializerSemanticModel(CSharpCompilation compilation, CSharpSyntaxNode syntax, Symbol symbol, Binder rootBinder, SyntaxTreeSemanticModel parentSemanticModelOpt = null, int speculatedPosition = 0) : base(compilation, syntax, symbol, rootBinder, parentSemanticModelOpt, speculatedPosition) { }
internal ExecutableCodeBinder(CSharpSyntaxNode root, Symbol memberSymbol, Binder next, BinderFlags additionalFlags) : base(next, (next.Flags | additionalFlags) & ~BinderFlags.AllClearedAtExecutableCodeBoundary) { Debug.Assert((object)memberSymbol == null || (memberSymbol.Kind != SymbolKind.Local && memberSymbol.Kind != SymbolKind.RangeVariable && memberSymbol.Kind != SymbolKind.Parameter)); _memberSymbol = memberSymbol; _root = root; }
/// <summary> /// Checks if 'symbol' is accessible from within type 'within', with /// an optional qualifier of type "throughTypeOpt". /// </summary> public static bool IsSymbolAccessible( Symbol symbol, NamedTypeSymbol within, ref HashSet<DiagnosticInfo> useSiteDiagnostics, TypeSymbol throughTypeOpt = null) { bool failedThroughTypeCheck; return IsSymbolAccessibleCore(symbol, within, throughTypeOpt, out failedThroughTypeCheck, within.DeclaringCompilation, ref useSiteDiagnostics); }
public SymbolDistinguisher(Compilation compilation, Symbol symbol0, Symbol symbol1) { Debug.Assert(symbol0 != symbol1); CheckSymbolKind(symbol0); CheckSymbolKind(symbol1); _compilation = compilation; _symbol0 = symbol0; _symbol1 = symbol1; }
/// <summary> /// Checks if 'symbol' is accessible from within type 'within', with /// an qualifier of type "throughTypeOpt". Sets "failedThroughTypeCheck" to true /// if it failed the "through type" check. /// </summary> public static bool IsSymbolAccessible( Symbol symbol, NamedTypeSymbol within, TypeSymbol throughTypeOpt, out bool failedThroughTypeCheck, ref HashSet<DiagnosticInfo> useSiteDiagnostics, ConsList<Symbol> basesBeingResolved = null) { return IsSymbolAccessibleCore(symbol, within, throughTypeOpt, out failedThroughTypeCheck, within.DeclaringCompilation, ref useSiteDiagnostics, basesBeingResolved); }
/// <summary> /// Creates a speculative SemanticModel for an initializer node (field initializer, constructor initializer, or parameter default value) /// that did not appear in the original source code. /// </summary> internal static InitializerSemanticModel CreateSpeculative(SyntaxTreeSemanticModel parentSemanticModel, Symbol owner, CSharpSyntaxNode syntax, Binder rootBinder, int position) { Debug.Assert(parentSemanticModel != null); Debug.Assert(syntax != null); Debug.Assert(syntax.IsKind(SyntaxKind.EqualsValueClause) || syntax.IsKind(SyntaxKind.ThisConstructorInitializer) || syntax.IsKind(SyntaxKind.BaseConstructorInitializer)); Debug.Assert(rootBinder != null); Debug.Assert(rootBinder.IsSemanticModelBinder); return new InitializerSemanticModel(parentSemanticModel.Compilation, syntax, owner, rootBinder, parentSemanticModel, position); }
// methodsWithYields will contain all function-declaration-like CSharpSyntaxNodes with yield statements contained within them. // Currently the types of these are restricted to only be whatever the syntax parameter is, plus any LocalFunctionStatementSyntax contained within it. // This may change if the language is extended to allow iterator lambdas, in which case the lambda would also be returned. // (lambdas currently throw a diagnostic in WithLambdaParametersBinder.GetIteratorElementType when a yield is used within them) public static SmallDictionary<SyntaxNode, Binder> BuildMap( Symbol containingMemberOrLambda, SyntaxNode syntax, Binder enclosing, ArrayBuilder<SyntaxNode> methodsWithYields, Func<Binder, SyntaxNode, Binder> rootBinderAdjusterOpt = null) { var builder = new LocalBinderFactory(containingMemberOrLambda, syntax, enclosing, methodsWithYields); StatementSyntax statement; var expressionSyntax = syntax as ExpressionSyntax; if (expressionSyntax != null) { enclosing = new ExpressionVariableBinder(syntax, enclosing); if ((object)rootBinderAdjusterOpt != null) { enclosing = rootBinderAdjusterOpt(enclosing, syntax); } builder.AddToMap(syntax, enclosing); builder.Visit(expressionSyntax, enclosing); } else if (syntax.Kind() != SyntaxKind.Block && (statement = syntax as StatementSyntax) != null) { CSharpSyntaxNode embeddedScopeDesignator; enclosing = builder.GetBinderForPossibleEmbeddedStatement(statement, enclosing, out embeddedScopeDesignator); if ((object)rootBinderAdjusterOpt != null) { enclosing = rootBinderAdjusterOpt(enclosing, embeddedScopeDesignator); } if (embeddedScopeDesignator != null) { builder.AddToMap(embeddedScopeDesignator, enclosing); } builder.Visit(statement, enclosing); } else { if ((object)rootBinderAdjusterOpt != null) { enclosing = rootBinderAdjusterOpt(enclosing, null); } builder.Visit((CSharpSyntaxNode)syntax, enclosing); } // the other place this is possible is in a local function if (builder._sawYield) methodsWithYields.Add(syntax); return builder._map; }
internal override bool EnsureSingleDefinition(Symbol symbol, string name, Location location, DiagnosticBag diagnostics) { ParameterSymbol existingDeclaration; var map = this.definitionMap; if (map != null && map.TryGetValue(name, out existingDeclaration)) { return InMethodBinder.ReportConflictWithParameter(existingDeclaration, symbol, name, location, diagnostics); } return false; }
private LocalBinderFactory(Symbol containingMemberOrLambda, CSharpSyntaxNode root, Binder enclosing, ArrayBuilder<CSharpSyntaxNode> methodsWithYields) { Debug.Assert((object)containingMemberOrLambda != null); Debug.Assert(containingMemberOrLambda.Kind != SymbolKind.Local && containingMemberOrLambda.Kind != SymbolKind.RangeVariable && containingMemberOrLambda.Kind != SymbolKind.Parameter); _map = new SmallDictionary<CSharpSyntaxNode, Binder>(ReferenceEqualityComparer.Instance); _containingMemberOrLambda = containingMemberOrLambda; _enclosing = enclosing; _methodsWithYields = methodsWithYields; _root = root; }
/// <summary> /// Creates a speculative SemanticModel for an initializer node (field initializer, constructor initializer, or parameter default value) /// that did not appear in the original source code. /// </summary> internal static InitializerSemanticModel CreateSpeculative(SyntaxTreeSemanticModel parentSemanticModel, Symbol owner, CSharpSyntaxNode syntax, Binder rootBinder, int position) { Debug.Assert(parentSemanticModel != null); Debug.Assert(syntax != null); Debug.Assert(syntax.IsKind(SyntaxKind.EqualsValueClause)); Debug.Assert(rootBinder != null); Debug.Assert(rootBinder.IsSemanticModelBinder); return(new InitializerSemanticModel(parentSemanticModel.Compilation, syntax, owner, rootBinder, parentSemanticModel, position)); }
internal static bool ReportConflictWithParameter(Symbol parameter, Symbol newSymbol, string name, Location newLocation, DiagnosticBag diagnostics) { var oldLocation = parameter.Locations[0]; #if PATTERNS_FIXED Debug.Assert(oldLocation != newLocation || oldLocation == Location.None || newLocation.SourceTree?.GetRoot().ContainsDiagnostics == true, "same nonempty location refers to different symbols?"); #else if (oldLocation == newLocation) { return(false); } #endif SymbolKind parameterKind = parameter.Kind; // Quirk of the way we represent lambda parameters. SymbolKind newSymbolKind = (object)newSymbol == null ? SymbolKind.Parameter : newSymbol.Kind; if (newSymbolKind == SymbolKind.ErrorType) { return(true); } if (parameterKind == SymbolKind.Parameter) { if (newSymbolKind == SymbolKind.Parameter || newSymbolKind == SymbolKind.Local || (newSymbolKind == SymbolKind.Method && ((MethodSymbol)newSymbol).MethodKind == MethodKind.LocalFunction)) { // A local or parameter named '{0}' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter diagnostics.Add(ErrorCode.ERR_LocalIllegallyOverrides, newLocation, name); return(true); } if (newSymbolKind == SymbolKind.RangeVariable) { // The range variable '{0}' conflicts with a previous declaration of '{0}' diagnostics.Add(ErrorCode.ERR_QueryRangeVariableOverrides, newLocation, name); return(true); } } if (parameterKind == SymbolKind.TypeParameter) { if (newSymbolKind == SymbolKind.Parameter || newSymbolKind == SymbolKind.Local || (newSymbolKind == SymbolKind.Method && ((MethodSymbol)newSymbol).MethodKind == MethodKind.LocalFunction)) { // CS0412: '{0}': a parameter, local variable, or local function cannot have the same name as a method type parameter diagnostics.Add(ErrorCode.ERR_LocalSameNameAsTypeParam, newLocation, name); return(true); } if (newSymbolKind == SymbolKind.TypeParameter) { // Type parameter declaration name conflicts are detected elsewhere return(false); } if (newSymbolKind == SymbolKind.RangeVariable) { // The range variable '{0}' cannot have the same name as a method type parameter diagnostics.Add(ErrorCode.ERR_QueryRangeVariableSameAsTypeParam, newLocation, name); return(true); } } Debug.Assert(false, "what else could be defined in a method?"); return(true); }
private RegionReachableWalker(CSharpCompilation compilation, Symbol member, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion) : base(compilation, member, node, firstInRegion, lastInRegion) { }
/// <summary> /// Checks if 'symbol' is accessible from within 'within', which must be a NamedTypeSymbol /// or an AssemblySymbol. /// /// Note that NamedTypeSymbol, if available, is the type that is associated with the binder /// that found the 'symbol', not the inner-most type that contains the access to the /// 'symbol'. /// /// If 'symbol' is accessed off of an expression then 'throughTypeOpt' is the type of that /// expression. This is needed to properly do protected access checks. Sets /// "failedThroughTypeCheck" to true if this protected check failed. /// /// NOTE(cyrusn): I expect this function to be called a lot. As such, i do not do any memory /// allocations in the function itself (including not making any iterators). This does mean /// that certain helper functions that we'd like to call are inlined in this method to /// prevent the overhead of returning collections or enumerators. /// </summary> private static bool IsSymbolAccessibleCore( Symbol symbol, Symbol within, // must be assembly or named type symbol TypeSymbol throughTypeOpt, out bool failedThroughTypeCheck, CSharpCompilation compilation, ref HashSet <DiagnosticInfo> useSiteDiagnostics, ConsList <Symbol> basesBeingResolved = null) { Debug.Assert((object)symbol != null); Debug.Assert((object)within != null); Debug.Assert(within.IsDefinition); Debug.Assert(within is NamedTypeSymbol || within is AssemblySymbol); failedThroughTypeCheck = false; switch (symbol.Kind) { case SymbolKind.ArrayType: return(IsSymbolAccessibleCore(((ArrayTypeSymbol)symbol).ElementType, within, null, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved)); case SymbolKind.PointerType: return(IsSymbolAccessibleCore(((PointerTypeSymbol)symbol).PointedAtType, within, null, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved)); case SymbolKind.NamedType: return(IsNamedTypeAccessible((NamedTypeSymbol)symbol, within, ref useSiteDiagnostics, basesBeingResolved)); case SymbolKind.ErrorType: // Always assume that error types are accessible. return(true); case SymbolKind.TypeParameter: case SymbolKind.Parameter: case SymbolKind.Local: case SymbolKind.Label: case SymbolKind.Namespace: case SymbolKind.DynamicType: case SymbolKind.Assembly: case SymbolKind.NetModule: case SymbolKind.RangeVariable: // These types of symbols are always accessible (if visible). return(true); case SymbolKind.Method: case SymbolKind.Property: case SymbolKind.Event: case SymbolKind.Field: if (symbol.IsStatic) { // static members aren't accessed "through" an "instance" of any type. So we // null out the "through" instance here. This ensures that we'll understand // accessing protected statics properly. throughTypeOpt = null; } return(IsMemberAccessible(symbol.ContainingType, symbol.DeclaredAccessibility, within, throughTypeOpt, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics)); default: throw ExceptionUtilities.UnexpectedValue(symbol.Kind); } }
public virtual TResult DefaultVisit(Symbol symbol) { return(default(TResult)); }
/// <summary> /// Learn from any constant null patterns appearing in the pattern. /// </summary> /// <param name="inputType">Type type of the input expression (before nullable analysis). /// Used to determine which types can contain null.</param> private void LearnFromAnyNullPatterns( int inputSlot, TypeSymbol inputType, BoundPattern pattern) { if (inputSlot <= 0) return; // https://github.com/dotnet/roslyn/issues/35041 We only need to do this when we're rewriting, so we // can get information for any nodes in the pattern. VisitPatternForRewriting(pattern); switch (pattern) { case BoundConstantPattern cp: bool isExplicitNullCheck = cp.Value.ConstantValue == ConstantValue.Null; if (isExplicitNullCheck) { // Since we're not branching on this null test here, we just infer the top level // nullability. We'll branch on it later. LearnFromNullTest(inputSlot, inputType, ref this.State, markDependentSlotsNotNull: false); } break; case BoundDeclarationPattern _: case BoundDiscardPattern _: case BoundITuplePattern _: break; // nothing to learn case BoundRecursivePattern rp: { if (rp.IsExplicitNotNullTest) { LearnFromNullTest(inputSlot, inputType, ref this.State, markDependentSlotsNotNull: false); } // for positional part: we only learn from tuples (not Deconstruct) if (rp.DeconstructMethod is null && !rp.Deconstruction.IsDefault) { var elements = inputType.TupleElements; for (int i = 0, n = Math.Min(rp.Deconstruction.Length, elements.IsDefault ? 0 : elements.Length); i < n; i++) { BoundSubpattern item = rp.Deconstruction[i]; FieldSymbol element = elements[i]; LearnFromAnyNullPatterns(GetOrCreateSlot(element, inputSlot), element.Type, item.Pattern); } } // for property part if (!rp.Properties.IsDefault) { for (int i = 0, n = rp.Properties.Length; i < n; i++) { BoundSubpattern item = rp.Properties[i]; Symbol symbol = item.Symbol; if (symbol?.ContainingType.Equals(inputType, TypeCompareKind.AllIgnoreOptions) == true) { LearnFromAnyNullPatterns(GetOrCreateSlot(symbol, inputSlot), symbol.GetTypeOrReturnType().Type, item.Pattern); } } } } break; default: throw ExceptionUtilities.UnexpectedValue(pattern); } }
private ImmutableArray <Symbol> ProcessParameterlessCrefMemberLookupResults( ImmutableArray <Symbol> symbols, int arity, MemberCrefSyntax memberSyntax, TypeArgumentListSyntax?typeArgumentListSyntax, out Symbol?ambiguityWinner, DiagnosticBag diagnostics) { // If the syntax indicates arity zero, then we match methods of any arity. // However, if there are both generic and non-generic methods, then the // generic methods should be ignored. if (symbols.Length > 1 && arity == 0) { bool hasNonGenericMethod = false; bool hasGenericMethod = false; foreach (Symbol s in symbols) { if (s.Kind != SymbolKind.Method) { continue; } if (((MethodSymbol)s).Arity == 0) { hasNonGenericMethod = true; } else { hasGenericMethod = true; } if (hasGenericMethod && hasNonGenericMethod) { break; //Nothing else to be learned. } } if (hasNonGenericMethod && hasGenericMethod) { symbols = symbols.WhereAsArray(s => s.Kind != SymbolKind.Method || ((MethodSymbol)s).Arity == 0); } } Debug.Assert(!symbols.IsEmpty); Symbol symbol = symbols[0]; // If there's ambiguity, prefer source symbols. // Logic is similar to ResultSymbol, but separate because the error handling is totally different. if (symbols.Length > 1) { // Size is known, but IndexOfSymbolFromCurrentCompilation expects a builder. ArrayBuilder <Symbol> unwrappedSymbols = ArrayBuilder <Symbol> .GetInstance(symbols.Length); foreach (Symbol wrapped in symbols) { unwrappedSymbols.Add(UnwrapAliasNoDiagnostics(wrapped)); } BestSymbolInfo secondBest; BestSymbolInfo best = GetBestSymbolInfo(unwrappedSymbols, out secondBest); Debug.Assert(!best.IsNone); Debug.Assert(!secondBest.IsNone); unwrappedSymbols.Free(); int symbolIndex = 0; if (best.IsFromCompilation) { symbolIndex = best.Index; symbol = symbols[symbolIndex]; // NOTE: symbols, not unwrappedSymbols. } if (symbol.Kind == SymbolKind.TypeParameter) { CrefSyntax crefSyntax = GetRootCrefSyntax(memberSyntax); diagnostics.Add(ErrorCode.WRN_BadXMLRefTypeVar, crefSyntax.Location, crefSyntax.ToString()); } else if (secondBest.IsFromCompilation == best.IsFromCompilation) { CrefSyntax crefSyntax = GetRootCrefSyntax(memberSyntax); int otherIndex = symbolIndex == 0 ? 1 : 0; diagnostics.Add(ErrorCode.WRN_AmbiguousXMLReference, crefSyntax.Location, crefSyntax.ToString(), symbol, symbols[otherIndex]); ambiguityWinner = ConstructWithCrefTypeParameters(arity, typeArgumentListSyntax, symbol); return(symbols.SelectAsArray(sym => ConstructWithCrefTypeParameters(arity, typeArgumentListSyntax, sym))); } } else if (symbol.Kind == SymbolKind.TypeParameter) { CrefSyntax crefSyntax = GetRootCrefSyntax(memberSyntax); diagnostics.Add(ErrorCode.WRN_BadXMLRefTypeVar, crefSyntax.Location, crefSyntax.ToString()); } ambiguityWinner = null; return(ImmutableArray.Create <Symbol>(ConstructWithCrefTypeParameters(arity, typeArgumentListSyntax, symbol))); }
internal VariablesDeclaredWalker(CSharpCompilation compilation, Symbol member, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion) : base(compilation, member, node, firstInRegion, lastInRegion) { }
private static bool IsNonPublicMemberAccessible( NamedTypeSymbol containingType, // the symbol's containing type Accessibility declaredAccessibility, Symbol within, TypeSymbol throughTypeOpt, out bool failedThroughTypeCheck, CSharpCompilation compilation, ref HashSet <DiagnosticInfo> useSiteDiagnostics, ConsList <Symbol> basesBeingResolved = null) { failedThroughTypeCheck = false; var originalContainingType = containingType.OriginalDefinition; var withinType = within as NamedTypeSymbol; var withinAssembly = (object)withinType != null ? withinType.ContainingAssembly : (AssemblySymbol)within; switch (declaredAccessibility) { case Accessibility.NotApplicable: // TODO(cyrusn): Is this the right thing to do here? Should the caller ever be // asking about the accessibility of a symbol that has "NotApplicable" as its // value? For now, I'm preserving the behavior of the existing code. But perhaps // we should fail here and require the caller to not do this? return(true); case Accessibility.Private: // All expressions in the current submission (top-level or nested in a method or // type) can access previous submission's private top-level members. Previous // submissions are treated like outer classes for the current submission - the // inner class can access private members of the outer class. if (containingType.TypeKind == TypeKind.Submission) { return(true); } // private members never accessible from outside a type. return((object)withinType != null && IsPrivateSymbolAccessible(withinType, originalContainingType)); case Accessibility.Internal: // An internal type is accessible if we're in the same assembly or we have // friend access to the assembly it was defined in. return(withinAssembly.HasInternalAccessTo(containingType.ContainingAssembly)); case Accessibility.ProtectedAndInternal: if (!withinAssembly.HasInternalAccessTo(containingType.ContainingAssembly)) { // We require internal access. If we don't have it, then this symbol is // definitely not accessible to us. return(false); } // We had internal access. Also have to make sure we have protected access. return(IsProtectedSymbolAccessible(withinType, throughTypeOpt, originalContainingType, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved)); case Accessibility.ProtectedOrInternal: if (withinAssembly.HasInternalAccessTo(containingType.ContainingAssembly)) { // If we have internal access to this symbol, then that's sufficient. no // need to do the complicated protected case. return(true); } // We don't have internal access. But if we have protected access then that's // sufficient. return(IsProtectedSymbolAccessible(withinType, throughTypeOpt, originalContainingType, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved)); case Accessibility.Protected: return(IsProtectedSymbolAccessible(withinType, throughTypeOpt, originalContainingType, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved)); default: throw ExceptionUtilities.UnexpectedValue(declaredAccessibility); } }
internal override bool IsAccessible(Symbol symbol, TypeSymbol accessThroughType, out bool failedThroughTypeCheck, ref HashSet <DiagnosticInfo> useSiteDiagnostics, ConsList <Symbol> basesBeingResolved = null) { failedThroughTypeCheck = false; return(this.IsSymbolAccessibleConditional(symbol, Compilation.Assembly, ref useSiteDiagnostics)); }
public virtual TResult Visit(Symbol symbol) { return((object)symbol == null ? default(TResult) : symbol.Accept(this)); }
private ReadWriteWalker(CSharpCompilation compilation, Symbol member, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion, HashSet <PrefixUnaryExpressionSyntax> unassignedVariableAddressOfSyntaxes) : base(compilation, member, node, firstInRegion, lastInRegion, unassignedVariableAddressOfSyntaxes: unassignedVariableAddressOfSyntaxes) { }