Repository: PowerShell/PowerShell
File: src/System.Management.Automation/engine/parser/SemanticChecks.cs (C#)

Code before:
                    break;
            }

            return AstVisitAction.Continue;
        }

        private static bool IsOrderedAttribute(TypeConstraintAst typeConstraint)
            => typeConstraint.TypeName.FullName.Equals(LanguagePrimitives.OrderedAttribute, StringComparison.OrdinalIgnoreCase);

        public override AstVisitAction VisitConvertExpression(ConvertExpressionAst convertExpressionAst)
        {
            if (IsOrderedAttribute(convertExpressionAst.Type))
            {
                if (convertExpressionAst.Child is not HashtableAst)
                {
                    // We allow the ordered attribute only on hashliteral node.
                    // This check covers the following scenario
                    //   $a = [ordered]10
                    _parser.ReportError(convertExpressionAst.Extent,
                        nameof(ParserStrings.OrderedAttributeOnlyOnHashLiteralNode),
                        ParserStrings.OrderedAttributeOnlyOnHashLiteralNode,
                        convertExpressionAst.Type.TypeName.FullName);
                }

                // Skip any further type checks on [ordered],
                // type resolution failure is costly and unnecessary
                return AstVisitAction.Continue;
            }

            Type targetType = convertExpressionAst.Type.TypeName.GetReflectionType();

            if (typeof(PSReference) == targetType)
            {
                // Check for [ref][ref]
                ExpressionAst child = convertExpressionAst.Child;
                bool multipleRefs = false;
                while (true)
                {
                    var childAttrExpr = child as AttributedExpressionAst;
                    if (childAttrExpr != null)
                    {
                        var childConvert = childAttrExpr as ConvertExpressionAst;
                        if (childConvert != null && !IsOrderedAttribute(childConvert.Type) && typeof(PSReference) == childConvert.Type.TypeName.GetReflectionType())
                        {
                            multipleRefs = true;
                            _parser.ReportError(childConvert.Type.Extent,
                                                nameof(ParserStrings.ReferenceNeedsToBeByItselfInTypeSequence),
                                                ParserStrings.ReferenceNeedsToBeByItselfInTypeSequence);
                        }

                        child = childAttrExpr.Child;

Review comment (suggestion):
```suggestion
                // Currently, the type name '[ordered]' is handled specially in PowerShell.
                // When used in a conversion expression, it's only allowed on a hashliteral node, and it's
                // always interpreted as 'System.Collections.Specialized.OrderedDictionary' by the compiler.
                // So, we can return early from here.
```

Code after:
                    break;
            }

            return AstVisitAction.Continue;
        }

        public override AstVisitAction VisitConvertExpression(ConvertExpressionAst convertExpressionAst)
        {
            if (convertExpressionAst.Type.TypeName.FullName.Equals(LanguagePrimitives.OrderedAttribute, StringComparison.OrdinalIgnoreCase))
            {
                if (convertExpressionAst.Child is not HashtableAst)
                {
                    // We allow the ordered attribute only on hashliteral node.
                    // This check covers the following scenario
                    //   $a = [ordered]10
                    _parser.ReportError(convertExpressionAst.Extent,
                        nameof(ParserStrings.OrderedAttributeOnlyOnHashLiteralNode),
                        ParserStrings.OrderedAttributeOnlyOnHashLiteralNode,
                        convertExpressionAst.Type.TypeName.FullName);
                }

                // Currently, the type name '[ordered]' is handled specially in PowerShell.
                // When used in a conversion expression, it's only allowed on a hashliteral node, and it's
                // always interpreted as an initializer for a case-insensitive
                // 'System.Collections.Specialized.OrderedDictionary' by the compiler.
                // So, we can return early from here.
                return AstVisitAction.Continue;
            }

            if (typeof(PSReference) == convertExpressionAst.Type.TypeName.GetReflectionType())
            {
                // Check for [ref][ref]
                ExpressionAst child = convertExpressionAst.Child;
                bool multipleRefs = false;
                while (true)
                {
                    var childAttrExpr = child as AttributedExpressionAst;
                    if (childAttrExpr != null)
                    {
                        var childConvert = childAttrExpr as ConvertExpressionAst;
                        if (childConvert != null && typeof(PSReference) == childConvert.Type.TypeName.GetReflectionType())
                        {
                            multipleRefs = true;
                            _parser.ReportError(childConvert.Type.Extent,
                                                nameof(ParserStrings.ReferenceNeedsToBeByItselfInTypeSequence),
                                                ParserStrings.ReferenceNeedsToBeByItselfInTypeSequence);
                        }

                        child = childAttrExpr.Child;
                        continue;
                    }