private BoundExpression SelectField(SimpleNameSyntax node, BoundExpression receiver, string name, DiagnosticBag diagnostics) { var receiverType = receiver.Type as NamedTypeSymbol; if ((object)receiverType == null || !receiverType.IsAnonymousType) { // We only construct transparent query variables using anonymous types, so if we're trying to navigate through // some other type, we must have some query API where the types don't match up as expected. var info = new CSDiagnosticInfo(ErrorCode.ERR_UnsupportedTransparentIdentifierAccess, name, receiver.ExpressionSymbol ?? receiverType); if (receiver.Type?.IsErrorType() != true) { Error(diagnostics, info, node); } return(new BoundBadExpression( node, LookupResultKind.Empty, ImmutableArray.Create <Symbol>(receiver.ExpressionSymbol), ImmutableArray.Create(receiver), new ExtendedErrorTypeSymbol(this.Compilation, "", 0, info))); } LookupResult lookupResult = LookupResult.GetInstance(); LookupOptions options = LookupOptions.MustBeInstance; HashSet <DiagnosticInfo> useSiteDiagnostics = null; LookupMembersWithFallback(lookupResult, receiver.Type, name, 0, ref useSiteDiagnostics, basesBeingResolved: null, options: options); diagnostics.Add(node, useSiteDiagnostics); var result = BindMemberOfType(node, node, name, 0, indexed: false, receiver, default(SeparatedSyntaxList <TypeSyntax>), default(ImmutableArray <TypeSymbolWithAnnotations>), lookupResult, BoundMethodGroupFlags.None, diagnostics); lookupResult.Free(); return(result); }
internal override void LookupSymbolsInSingleBinder( LookupResult result, string name, int arity, ConsList <TypeSymbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { Debug.Assert(result.IsClear); if (IsSubmissionClass) { this.LookupMembersInternal(result, _container, name, arity, basesBeingResolved, options, originalBinder, diagnose, ref useSiteDiagnostics); return; } var imports = GetImports(basesBeingResolved); // first lookup members of the namespace if ((options & LookupOptions.NamespaceAliasesOnly) == 0 && _container != null) { this.LookupMembersInternal(result, _container, name, arity, basesBeingResolved, options, originalBinder, diagnose, ref useSiteDiagnostics); if (result.IsMultiViable) { // symbols cannot conflict with using alias names if (arity == 0 && imports.IsUsingAlias(name, originalBinder.IsSemanticModelBinder)) { CSDiagnosticInfo diagInfo = new CSDiagnosticInfo(ErrorCode.ERR_ConflictAliasAndMember, name, _container); var error = new ExtendedErrorTypeSymbol((NamespaceOrTypeSymbol)null, name, arity, diagInfo, unreported: true); result.SetFrom(LookupResult.Good(error)); // force lookup to be done w/ error symbol as result } return; } } // next try using aliases or symbols in imported namespaces imports.LookupSymbol(originalBinder, result, name, arity, basesBeingResolved, options, diagnose, ref useSiteDiagnostics); }
internal static CSDiagnosticInfo Add(this DiagnosticBag diagnostics, ErrorCode code, Location location, ImmutableArray <Symbol> symbols, params object[] args) { var info = new CSDiagnosticInfo(code, args, symbols, ImmutableArray <Location> .Empty); var diag = new CSDiagnostic(info, location); diagnostics.Add(diag); return(info); }
/// <summary> /// Add a diagnostic to the bag. /// </summary> /// <param name="diagnostics"></param> /// <param name="code"></param> /// <param name="location"></param> /// <param name="args"></param> /// <returns></returns> internal static CSDiagnosticInfo Add(this DiagnosticBag diagnostics, ErrorCode code, Location location, params object[] args) { var info = new CSDiagnosticInfo(code, args); var diag = new CSDiagnostic(info, location); diagnostics.Add(diag); return(info); }
/// <summary> /// Reports an error if the await expression did not occur in an async context. /// </summary> /// <returns>True if the expression contains errors.</returns> private bool ReportBadAwaitWithoutAsync(Location location, DiagnosticBag diagnostics) { DiagnosticInfo info = null; var containingMemberOrLambda = this.ContainingMemberOrLambda; if ((object)containingMemberOrLambda != null) { switch (containingMemberOrLambda.Kind) { case SymbolKind.Field: if (containingMemberOrLambda.ContainingType.IsScriptClass) { if (((FieldSymbol)containingMemberOrLambda).IsStatic) { info = new CSDiagnosticInfo(ErrorCode.ERR_BadAwaitInStaticVariableInitializer); } else { return(false); } } break; case SymbolKind.Method: var method = (MethodSymbol)containingMemberOrLambda; if (method.IsAsync) { return(false); } if (method.MethodKind == MethodKind.AnonymousFunction) { info = method.IsImplicitlyDeclared ? // The await expression occurred in a query expression: new CSDiagnosticInfo(ErrorCode.ERR_BadAwaitInQuery) : new CSDiagnosticInfo(ErrorCode.ERR_BadAwaitWithoutAsyncLambda, ((LambdaSymbol)method).MessageID.Localize()); } else { info = method.ReturnsVoid ? new CSDiagnosticInfo(ErrorCode.ERR_BadAwaitWithoutVoidAsyncMethod) : new CSDiagnosticInfo(ErrorCode.ERR_BadAwaitWithoutAsyncMethod, method.ReturnType.TypeSymbol); } break; } } if (info == null) { info = new CSDiagnosticInfo(ErrorCode.ERR_BadAwaitWithoutAsync); } Error(diagnostics, info, location); return(true); }
public override Diagnostic CreateDiagnostic(int code, Location location, params object[] args) { var info = new CSDiagnosticInfo((ErrorCode)code, args, ImmutableArray <Symbol> .Empty, ImmutableArray <Location> .Empty); return(new CSDiagnostic(info, location)); }
/// <summary> /// This method handles duplicate types in a few different ways: /// - for types before C# 7, the first candidate is returned with a warning /// - for types after C# 7, the type is considered missing /// - in both cases, when BinderFlags.IgnoreCorLibraryDuplicatedTypes is set, any duplicate coming from corlib will be ignored (ie not count as a duplicate) /// </summary> internal NamedTypeSymbol GetWellKnownType(WellKnownType type) { Debug.Assert(type.IsValid()); bool ignoreCorLibraryDuplicatedTypes = this.Options.TopLevelBinderFlags.Includes(BinderFlags.IgnoreCorLibraryDuplicatedTypes); int index = (int)type - (int)WellKnownType.First; if (_lazyWellKnownTypes == null || (object)_lazyWellKnownTypes[index] == null) { if (_lazyWellKnownTypes == null) { Interlocked.CompareExchange(ref _lazyWellKnownTypes, new NamedTypeSymbol[(int)WellKnownTypes.Count], null); } string mdName = type.GetMetadataName(); var warnings = DiagnosticBag.GetInstance(); NamedTypeSymbol result; (AssemblySymbol, AssemblySymbol)conflicts = default; if (IsTypeMissing(type)) { result = null; } else { // well-known types introduced before CSharp7 allow lookup ambiguity and report a warning DiagnosticBag legacyWarnings = (type <= WellKnownType.CSharp7Sentinel) ? warnings : null; result = this.Assembly.GetTypeByMetadataName( mdName, includeReferences: true, useCLSCompliantNameArityEncoding: true, isWellKnownType: true, conflicts: out conflicts, warnings: legacyWarnings, ignoreCorLibraryDuplicatedTypes: ignoreCorLibraryDuplicatedTypes); } if ((object)result == null) { // TODO: should GetTypeByMetadataName rather return a missing symbol? MetadataTypeName emittedName = MetadataTypeName.FromFullName(mdName, useCLSCompliantNameArityEncoding: true); if (type.IsValueTupleType()) { CSDiagnosticInfo errorInfo; if (conflicts.Item1 is null) { Debug.Assert(conflicts.Item2 is null); errorInfo = new CSDiagnosticInfo(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, emittedName.FullName); } else { errorInfo = new CSDiagnosticInfo(ErrorCode.ERR_PredefinedValueTupleTypeAmbiguous3, emittedName.FullName, conflicts.Item1, conflicts.Item2); } result = new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(this.Assembly.Modules[0], ref emittedName, errorInfo, type); } else { result = new MissingMetadataTypeSymbol.TopLevel(this.Assembly.Modules[0], ref emittedName, type); } } if ((object)Interlocked.CompareExchange(ref _lazyWellKnownTypes[index], result, null) != null) { Debug.Assert( TypeSymbol.Equals(result, _lazyWellKnownTypes[index], TypeCompareKind.ConsiderEverything2) || (_lazyWellKnownTypes[index].IsErrorType() && result.IsErrorType()) ); } else { AdditionalCodegenWarnings.AddRange(warnings); } warnings.Free(); } return(_lazyWellKnownTypes[index]); }