private Expression FinishDictOrSetValue()

in src/Parsing/Impl/Parser.cs [4055:4222]


        private Expression FinishDictOrSetValue() {
            string startWhiteSpace = _tokenWhiteSpace, finishWhiteSpace;
            var oStart = GetStart();
            var oEnd = GetEnd();

            List<SliceExpression> dictMembers = null;
            List<Expression> setMembers = null;
            var itemWhiteSpace = MakeWhiteSpaceList();
            var prevAllow = _allowIncomplete;
            var reportedError = false;
            var ateTerminator = false;
            bool hasSequenceUnpack = false, hasDictUnpack = false;
            try {
                _allowIncomplete = true;
                while (true) {
                    if (MaybeEat(TokenKind.RightBrace)) { // empty dict literal
                        finishWhiteSpace = _tokenWhiteSpace;
                        ateTerminator = true;
                        break;
                    }

                    bool isSequenceUnpack = false, isDictUnpack = false;
                    var first = false;
                    var e1 = ParseExpression();
                    if (e1 is StarredExpression s) {
                        if (s.StarCount == 1) {
                            isSequenceUnpack = true;
                            hasSequenceUnpack = true;
                        } else if (s.StarCount == 2) {
                            isDictUnpack = true;
                            hasDictUnpack = true;
                        }
                    }

                    if (MaybeEat(TokenKind.Colon)) { // dict literal
                        var colonWhiteSpace = _tokenWhiteSpace;
                        if (setMembers == null && dictMembers == null) {
                            dictMembers = new List<SliceExpression>();
                            first = true;
                        }
                        var e2 = ParseExpression();

                        if (!reportedError) {
                            if (setMembers != null || hasSequenceUnpack || isSequenceUnpack || isDictUnpack) {
                                ReportSyntaxError(e1.StartIndex, e2.EndIndex, Resources.InvalidSyntaxErrorMsg);//Invalid Syntax
                                reportedError = true;
                            }
                        }


                        var se = new SliceExpression(e1, e2, null, false);
                        if (_verbatim) {
                            AddPreceedingWhiteSpace(se, colonWhiteSpace);
                        }
                        se.SetLoc(e1.StartIndex, e2.EndIndex);

                        if (PeekTokenForOrAsyncFor) {
                            if (!first || (!_stubFile && _langVersion < PythonLanguageVersion.V27)) {
                                ReportSyntaxError(Resources.InvalidSyntaxErrorMsg);//Invalid Syntax
                            }

                            var dictComp = FinishDictComp(se, out ateTerminator);
                            if (_verbatim) {
                                AddPreceedingWhiteSpace(dictComp, startWhiteSpace);
                                AddSecondPreceedingWhiteSpace(dictComp, _tokenWhiteSpace);
                                if (!ateTerminator) {
                                    AddErrorMissingCloseGrouping(dictComp);
                                }
                            }
                            dictComp.SetLoc(oStart, GetEnd());
                            return dictComp;
                        }

                        if (dictMembers != null) {
                            dictMembers.Add(se);
                        } else {
                            setMembers.Add(se);
                        }
                    } else { // set literal or dict unpack
                        if (!_stubFile && _langVersion < PythonLanguageVersion.V27 && !reportedError) {
                            ReportSyntaxError(e1.StartIndex, e1.EndIndex, Resources.SetLiteralsRequirePython2dot7ErrorMsg);//invalid syntax, set literals require Python 2.7 or later.
                            reportedError = true;
                        }

                        if (isDictUnpack && hasDictUnpack) {
                            // **{}, we don't have a colon and a value...
                            if (setMembers != null && !reportedError) {
                                ReportSyntaxError(e1.StartIndex, e1.EndIndex, Resources.InvalidSyntaxErrorMsg);//Invalid Syntax
                                reportedError = true;
                            }

                            if (dictMembers == null) {
                                dictMembers = new List<SliceExpression>();
                            }
                            dictMembers.Add(new DictValueOnlyExpression(e1));
                        } else {
                            if (dictMembers != null) {
                                if (!reportedError) {
                                    ReportSyntaxError(e1.StartIndex, e1.EndIndex, Resources.InvalidSyntaxErrorMsg);//Invalid Syntax
                                    reportedError = true;
                                }
                            } else if (setMembers == null) {
                                setMembers = new List<Expression>();
                                first = true;
                            }

                            if (PeekTokenForOrAsyncFor) {
                                if (!first) {
                                    ReportSyntaxError(Resources.InvalidSyntaxErrorMsg);//invalid syntax
                                }
                                var setComp = FinishSetComp(e1, out ateTerminator);
                                if (_verbatim) {
                                    AddPreceedingWhiteSpace(setComp, startWhiteSpace);
                                    AddSecondPreceedingWhiteSpace(setComp, _tokenWhiteSpace);
                                    if (!ateTerminator) {
                                        AddErrorMissingCloseGrouping(setComp);
                                    }
                                }
                                setComp.SetLoc(oStart, GetEnd());
                                return setComp;
                            }

                            // error recovery
                            if (setMembers != null) {
                                setMembers.Add(e1);
                            } else {
                                var slice = new DictKeyOnlyExpression(e1);
                                slice.SetLoc(e1.IndexSpan);
                                if (_verbatim) {
                                    AddErrorIsIncompleteNode(slice);
                                }
                                dictMembers.Add(slice);
                            }
                        }
                    }

                    if (!MaybeEat(TokenKind.Comma)) {
                        ateTerminator = Eat(TokenKind.RightBrace);
                        finishWhiteSpace = _tokenWhiteSpace;
                        break;
                    }
                    if (itemWhiteSpace != null) {
                        itemWhiteSpace.Add(_tokenWhiteSpace);
                    }
                }
            } finally {
                _allowIncomplete = prevAllow;
            }


            Expression ret;
            if (dictMembers != null || setMembers == null) {
                var expressions = dictMembers != null ? ImmutableArray<SliceExpression>.Create(dictMembers) : ImmutableArray<SliceExpression>.Empty;
                ret = new DictionaryExpression(expressions);
            } else {
                ret = new SetExpression(ImmutableArray<Expression>.Create(setMembers));
            }
            ret.SetLoc(oStart, GetEnd());
            if (_verbatim) {
                AddPreceedingWhiteSpace(ret, startWhiteSpace);
                AddSecondPreceedingWhiteSpace(ret, finishWhiteSpace);
                AddListWhiteSpace(ret, itemWhiteSpace.ToArray());
                if (!ateTerminator) {
                    AddErrorMissingCloseGrouping(ret);
                }
            }
            return ret;
        }