mirror of
https://github.com/github/codeql.git
synced 2025-12-17 17:23:36 +01:00
68 lines
2.6 KiB
C#
68 lines
2.6 KiB
C#
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.CSharp;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Semmle.Extraction.CSharp.Populators;
|
|
using System.Linq;
|
|
|
|
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
|
{
|
|
static class Name
|
|
{
|
|
public static Expression Create(ExpressionNodeInfo info)
|
|
{
|
|
var symbolInfo = info.Context.GetSymbolInfo(info.Node);
|
|
|
|
var target = symbolInfo.Symbol;
|
|
|
|
if (target == null && symbolInfo.CandidateReason == CandidateReason.OverloadResolutionFailure)
|
|
{
|
|
// The expression is probably a cast
|
|
target = info.Context.GetSymbolInfo((CSharpSyntaxNode)info.Node.Parent).Symbol;
|
|
}
|
|
|
|
if (target == null && (symbolInfo.CandidateReason == CandidateReason.Ambiguous || symbolInfo.CandidateReason == CandidateReason.MemberGroup))
|
|
{
|
|
// Pick one at random - they probably resolve to the same ID
|
|
target = symbolInfo.CandidateSymbols.First();
|
|
}
|
|
|
|
if (target == null)
|
|
{
|
|
info.Context.ModelError(info.Node, "Failed to resolve name");
|
|
return new Unknown(info);
|
|
}
|
|
|
|
// There is a very strange bug in Microsoft.CodeAnalysis whereby
|
|
// target.Kind throws System.InvalidOperationException for Discard symbols.
|
|
// So, short-circuit that test here.
|
|
// Ideally this would be another case in the switch statement below.
|
|
if (target is IDiscardSymbol)
|
|
return new Discard(info);
|
|
|
|
switch (target.Kind)
|
|
{
|
|
case SymbolKind.TypeParameter:
|
|
case SymbolKind.NamedType:
|
|
case SymbolKind.DynamicType:
|
|
return TypeAccess.Create(info);
|
|
|
|
case SymbolKind.Property:
|
|
case SymbolKind.Field:
|
|
case SymbolKind.Event:
|
|
case SymbolKind.Method:
|
|
return Access.Create(info, target, true, info.Context.CreateEntity(target));
|
|
|
|
case SymbolKind.Local:
|
|
case SymbolKind.RangeVariable:
|
|
return Access.Create(info, target, false, LocalVariable.GetAlreadyCreated(info.Context, target));
|
|
|
|
case SymbolKind.Parameter:
|
|
return Access.Create(info, target, false, Parameter.GetAlreadyCreated(info.Context, (IParameterSymbol)target));
|
|
|
|
default:
|
|
throw new InternalError(info.Node, "Unhandled identifier kind '{0}'", target.Kind);
|
|
}
|
|
}
|
|
}
|
|
}
|