/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Literal.cs
162 строки
8 KB
AlekseyTs
Null annotate ArgumentNames. (#70739)
09 ноя 2023, 17:24
Не верифицирован
09 ноя 2023, 17:24
5e2cf6d
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Immutable; using System.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp { internal partial class LocalRewriter { public override BoundNode VisitLiteral(BoundLiteral node) { Debug.Assert(node.ConstantValueOpt is { }); return MakeLiteral(node.Syntax, node.ConstantValueOpt, node.Type, oldNodeOpt: node); } private BoundExpression MakeLiteral(SyntaxNode syntax, ConstantValue constantValue, TypeSymbol? type, BoundLiteral? oldNodeOpt = null) { Debug.Assert(constantValue != null); if (constantValue.IsDecimal) { // Rewrite decimal literal Debug.Assert(type is { SpecialType: SpecialType.System_Decimal }); return MakeDecimalLiteral(syntax, constantValue); } else if (constantValue.IsDateTime) { // C# does not support DateTime constants but VB does; we might have obtained a // DateTime constant by calling a method with an optional parameter with a DateTime // for its default value. Debug.Assert(type is { SpecialType: SpecialType.System_DateTime }); return MakeDateTimeLiteral(syntax, constantValue); } else if (oldNodeOpt != null) { return oldNodeOpt.Update(constantValue, type); } else { return new BoundLiteral(syntax, constantValue, type, hasErrors: constantValue.IsBad); } } private BoundExpression MakeDecimalLiteral(SyntaxNode syntax, ConstantValue constantValue) { Debug.Assert(constantValue != null); Debug.Assert(constantValue.IsDecimal); var value = constantValue.DecimalValue; bool isNegative; byte scale; uint low, mid, high; value.GetBits(out isNegative, out scale, out low, out mid, out high); var arguments = new ArrayBuilder<BoundExpression>(); SpecialMember member; // check if we can call a simpler constructor, or use a predefined constant if (scale == 0 && int.MinValue <= value && value <= int.MaxValue) { // If we are building static constructor of System.Decimal, accessing static fields // would be bad. var curMethod = _factory.CurrentFunction; Debug.Assert(curMethod is { }); if ((curMethod.MethodKind != MethodKind.SharedConstructor || curMethod.ContainingType.SpecialType != SpecialType.System_Decimal) && !_inExpressionLambda) { Symbol? useField = null; if (value == decimal.Zero) { useField = _compilation.GetSpecialTypeMember(SpecialMember.System_Decimal__Zero); } else if (value == decimal.One) { useField = _compilation.GetSpecialTypeMember(SpecialMember.System_Decimal__One); } else if (value == decimal.MinusOne) { useField = _compilation.GetSpecialTypeMember(SpecialMember.System_Decimal__MinusOne); } if (useField is { HasUseSiteError: false, ContainingType: { HasUseSiteError: false } }) { var fieldSymbol = (FieldSymbol)useField; return new BoundFieldAccess(syntax, null, fieldSymbol, constantValue); } } //new decimal(int); member = SpecialMember.System_Decimal__CtorInt32; arguments.Add(new BoundLiteral(syntax, ConstantValue.Create((int)value), _compilation.GetSpecialType(SpecialType.System_Int32))); } else if (scale == 0 && uint.MinValue <= value && value <= uint.MaxValue) { //new decimal(uint); member = SpecialMember.System_Decimal__CtorUInt32; arguments.Add(new BoundLiteral(syntax, ConstantValue.Create((uint)value), _compilation.GetSpecialType(SpecialType.System_UInt32))); } else if (scale == 0 && long.MinValue <= value && value <= long.MaxValue) { //new decimal(long); member = SpecialMember.System_Decimal__CtorInt64; arguments.Add(new BoundLiteral(syntax, ConstantValue.Create((long)value), _compilation.GetSpecialType(SpecialType.System_Int64))); } else if (scale == 0 && ulong.MinValue <= value && value <= ulong.MaxValue) { //new decimal(ulong); member = SpecialMember.System_Decimal__CtorUInt64; arguments.Add(new BoundLiteral(syntax, ConstantValue.Create((ulong)value), _compilation.GetSpecialType(SpecialType.System_UInt64))); } else { //new decimal(int low, int mid, int high, bool isNegative, byte scale); member = SpecialMember.System_Decimal__CtorInt32Int32Int32BooleanByte; arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(low), _compilation.GetSpecialType(SpecialType.System_Int32))); arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(mid), _compilation.GetSpecialType(SpecialType.System_Int32))); arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(high), _compilation.GetSpecialType(SpecialType.System_Int32))); arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(isNegative), _compilation.GetSpecialType(SpecialType.System_Boolean))); arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(scale), _compilation.GetSpecialType(SpecialType.System_Byte))); } var ctor = (MethodSymbol)_compilation.Assembly.GetSpecialTypeMember(member); Debug.Assert((object)ctor != null); Debug.Assert(ctor.ContainingType.SpecialType == SpecialType.System_Decimal); return new BoundObjectCreationExpression( syntax, ctor, arguments.ToImmutableAndFree(), argumentNamesOpt: default(ImmutableArray<string?>), argumentRefKindsOpt: default(ImmutableArray<RefKind>), expanded: false, argsToParamsOpt: default(ImmutableArray<int>), defaultArguments: default(BitVector), constantValueOpt: constantValue, initializerExpressionOpt: null, type: ctor.ContainingType); } private BoundExpression MakeDateTimeLiteral(SyntaxNode syntax, ConstantValue constantValue) { Debug.Assert(constantValue != null); Debug.Assert(constantValue.IsDateTime); var arguments = new ArrayBuilder<BoundExpression>(); arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(constantValue.DateTimeValue.Ticks), _compilation.GetSpecialType(SpecialType.System_Int64))); var ctor = (MethodSymbol)_compilation.Assembly.GetSpecialTypeMember(SpecialMember.System_DateTime__CtorInt64); Debug.Assert((object)ctor != null); Debug.Assert(ctor.ContainingType.SpecialType == SpecialType.System_DateTime); // This is not a constant from C#'s perspective, so do not mark it as one. return new BoundObjectCreationExpression( syntax, ctor, arguments.ToImmutableAndFree(), argumentNamesOpt: default(ImmutableArray<string?>), argumentRefKindsOpt: default(ImmutableArray<RefKind>), expanded: false, argsToParamsOpt: default(ImmutableArray<int>), defaultArguments: default(BitVector), constantValueOpt: ConstantValue.NotAvailable, initializerExpressionOpt: null, type: ctor.ContainingType); } } }