Пример #1
0
        static CodeAttributeArgumentCollection _ParseCustomAttributeArguments(_PC pc)
        {
            var result = new CodeAttributeArgumentCollection();

            if (ST.lparen != pc.SymbolId)
            {
                return(result);
            }
            if (!pc.Advance())
            {
                throw new ArgumentException("Unterminated argument list", "input");
            }
            var named = false;

            while (ST.rparen != pc.SymbolId)
            {
                var arg = new CodeAttributeArgument();
                if (ST.identifier == pc.SymbolId)
                {
                    var s   = pc.Value;
                    var pc2 = pc.GetLookAhead();
                    pc2.EnsureStarted();
                    pc2.Advance();
                    _SkipComments(pc2);
                    if (ST.eq == pc2.SymbolId)
                    {
                        pc.Advance();
                        _SkipComments(pc);
                        pc.Advance();
                        arg.Name  = s;
                        arg.Value = _ParseExpression(pc);
                        result.Add(arg);
                        named = true;
                        continue;
                    }
                }
                if (named)
                {
                    throw new ArgumentException("Named custom attribute arguments must follow the unnamed arguments.", "input");
                }
                var exp = _ParseExpression(pc);
                _SkipComments(pc);
                arg.Value = exp;
                result.Add(arg);
                if (ST.comma == pc.SymbolId)
                {
                    if (!pc.Advance())
                    {
                        throw new ArgumentException("Unterminated argument list.", "input");
                    }
                }
            }
            if (ST.rparen != pc.SymbolId)
            {
                throw new ArgumentException("Unterminated argument list.", "input");
            }
            pc.Advance();
            return(result);
        }
Пример #2
0
        static CodeCompileUnit _ParseCompileUnit(_PC pc)
        {
            var l      = pc.Line;
            var c      = pc.Column;
            var p      = pc.Position;
            var result = new CodeCompileUnit().Mark(l, c, p);
            var ns     = new CodeNamespace().Mark(l, c, p);

            result.Namespaces.Add(ns);
            while (ST.directive == pc.SymbolId || ST.lineComment == pc.SymbolId || ST.blockComment == pc.SymbolId)
            {
                switch (pc.SymbolId)
                {
                case ST.directive:
                    var d = _ParseDirective(pc) as CodeDirective;
                    if (null != d)
                    {
                        result.StartDirectives.Add(d);
                    }
                    break;

                case ST.blockComment:
                    ns.Comments.Add(_ParseCommentStatement(pc));
                    break;

                case ST.lineComment:
                    ns.Comments.Add(_ParseCommentStatement(pc, true));
                    break;
                }
            }
            while (ST.usingKeyword == pc.SymbolId)
            {
                while (ST.directive == pc.SymbolId || ST.lineComment == pc.SymbolId || ST.blockComment == pc.SymbolId)
                {
                    pc.Advance(false);
                }
                var l2 = pc.Line;
                var c2 = pc.Column;
                var p2 = pc.Position;
                pc.Advance();
                var nsi = new CodeNamespaceImport(_ParseNamespaceName(pc)).SetLoc(l2, c2, p2);
                if (ST.semi != pc.SymbolId)
                {
                    pc.Error("Expecting ; in using declaration");
                }
                pc.Advance(false);
                ns.Imports.Add(nsi);
            }
            while (ST.lbracket == pc.SymbolId)
            {
                var pc2 = pc.GetLookAhead(true);
                pc2.Advance();
                if (ST.assemblyKeyword != pc2.SymbolId)
                {
                    break;
                }
                result.AssemblyCustomAttributes.AddRange(_ParseAttributeGroup(pc, false).Value);
            }
            while (!pc.IsEnded)
            {
                var            startDirs = new CodeDirectiveCollection();
                var            comments  = new CodeCommentStatementCollection();
                CodeLinePragma lp        = null;
                while (ST.directive == pc.SymbolId || ST.lineComment == pc.SymbolId || ST.blockComment == pc.SymbolId)
                {
                    switch (pc.SymbolId)
                    {
                    case ST.directive:
                        var d   = _ParseDirective(pc);
                        var llp = d as CodeLinePragma;
                        if (null != llp)
                        {
                            lp = llp;
                        }
                        else if (null != d)
                        {
                            startDirs.Add(d as CodeDirective);
                        }
                        break;

                    case ST.blockComment:
                        comments.Add(_ParseCommentStatement(pc));
                        break;

                    case ST.lineComment:
                        comments.Add(_ParseCommentStatement(pc, true));
                        break;
                    }
                }
                if (ST.namespaceKeyword == pc.SymbolId)
                {
                    var nns = _ParseNamespace(pc);
                    nns.Comments.AddRange(comments);
                    result.Namespaces.Add(nns);
                }
                else
                {
                    var t = _ParseTypeDecl(pc, false, pc.Line, pc.Column, pc.Position, null);
                    t.Comments.AddRange(comments);
                    t.StartDirectives.AddRange(startDirs);
                    t.LinePragma = lp;
                    ns.Types.Add(t);
                }
            }
            return(result);
        }
Пример #3
0
        static CodeNamespace _ParseNamespace(_PC pc)
        {
            var l = pc.Line;
            var c = pc.Column;
            var p = pc.Position;

            var result = new CodeNamespace().Mark(l, c, p);

            while (ST.lineComment == pc.SymbolId || ST.blockComment == pc.SymbolId || ST.directive == pc.SymbolId)
            {
                if (ST.directive != pc.SymbolId)
                {
                    result.Comments.Add(_ParseCommentStatement(pc, true));
                }
            }
            if (ST.namespaceKeyword != pc.SymbolId)
            {
                pc.Error("Expecting namespace");
            }
            pc.Advance();
            result.Name = _ParseNamespaceName(pc);
            if (ST.lbrace != pc.SymbolId)
            {
                pc.Error("Expecing { in namespace declaration");
            }
            pc.Advance(false);
            if (ST.directive == pc.SymbolId || ST.lineComment == pc.SymbolId || ST.blockComment == pc.SymbolId)
            {
                var pc2 = pc.GetLookAhead(true);
                if (ST.usingKeyword == pc2.SymbolId)
                {
                    pc.Advance();
                }
            }
            while (ST.usingKeyword == pc.SymbolId)
            {
                while (ST.directive == pc.SymbolId || ST.lineComment == pc.SymbolId || ST.blockComment == pc.SymbolId)
                {
                    pc.Advance(false);
                }
                var l2 = pc.Line;
                var c2 = pc.Column;
                var p2 = pc.Position;
                pc.Advance();
                var nsi = new CodeNamespaceImport(_ParseNamespaceName(pc)).SetLoc(l2, c2, p2);
                if (ST.semi != pc.SymbolId)
                {
                    pc.Error("Expecting ; in using declaration");
                }
                pc.Advance(false);
                result.Imports.Add(nsi);
            }
            while (ST.rbrace != pc.SymbolId)
            {
                result.Types.Add(_ParseTypeDecl(pc, false, pc.Line, pc.Column, pc.Position, null));
            }
            if (ST.rbrace != pc.SymbolId)
            {
                pc.Error("Unterminated namespace declaration", l, c, p);
            }
            pc.Advance(false);
            return(result);
        }
Пример #4
0
        static CodeStatement _ParseStatement(_PC pc, bool includeComments = false)
        {
            #region Preamble
            CodeLinePragma lp        = null;
            var            startDirs = new CodeDirectiveCollection();
            while (ST.directive == pc.SymbolId)
            {
                var d = _ParseDirective(pc);
                if (null != d)
                {
                    var clp = d as CodeLinePragma;
                    if (null != clp)
                    {
                        lp = clp;
                    }
                    else
                    {
                        startDirs.Add(d as CodeDirective);
                    }
                }
                while (!includeComments && ST.lineComment == pc.SymbolId || ST.blockComment == pc.SymbolId)
                {
                    pc.Advance(false);
                }
            }
            CodeStatement stmt = null;
            if (includeComments && (ST.lineComment == pc.SymbolId || ST.blockComment == pc.SymbolId))
            {
                stmt = _ParseCommentStatement(pc);
                stmt.StartDirectives.AddRange(startDirs);
                if (null != lp)
                {
                    stmt.LinePragma = lp;
                }
            }
            else
            {
                while (ST.lineComment == pc.SymbolId || ST.blockComment == pc.SymbolId)
                {
                    pc.Advance(false);
                }
            }
            #endregion Preamble
            var l = pc.Line;
            var c = pc.Column;
            var p = pc.Position;
            // if we got here we've parsed our start directives and this isn't a comment statement
            if (null == stmt)
            {
                _PC pc2 = null;
                switch (pc.SymbolId)
                {
                case ST.semi:
                    // can't do much with empty statements
                    pc.Advance();
                    stmt = new CodeSnippetStatement().SetLoc(l, c, p);
                    break;

                case ST.gotoKeyword:
                    pc.Advance();
                    if (ST.identifier != pc.SymbolId)
                    {
                        pc.Error("Expecting label identifier in goto statement");
                    }
                    stmt = new CodeGotoStatement(pc.Value).SetLoc(l, c, p);
                    if (ST.semi != pc.SymbolId)
                    {
                        pc.Error("Expecting ; in goto statement");
                    }
                    pc.Advance();
                    break;

                case ST.returnKeyword:
                    pc.Advance();
                    if (ST.semi != pc.SymbolId)
                    {
                        stmt = new CodeMethodReturnStatement(_ParseExpression(pc)).Mark(l, c, p);
                    }
                    else
                    {
                        stmt = new CodeMethodReturnStatement().SetLoc(l, c, p);
                    }
                    if (ST.semi != pc.SymbolId)
                    {
                        pc.Error("Expecting ; in return statement");
                    }
                    pc.Advance();
                    break;

                case ST.throwKeyword:
                    pc.Advance();
                    var expr = _ParseExpression(pc);
                    stmt = new CodeThrowExceptionStatement(expr).Mark(l, c, p);
                    if (ST.semi != pc.SymbolId)
                    {
                        pc.Error("Expecting ; in throw statement");
                    }
                    pc.Advance();
                    break;

                case ST.ifKeyword:
                    stmt = _ParseIfStatement(pc);
                    break;

                case ST.whileKeyword:
                    stmt = _ParseWhileStatement(pc);
                    break;

                case ST.forKeyword:
                    stmt = _ParseForStatement(pc);
                    break;

                case ST.tryKeyword:
                    stmt = _ParseTryCatchFinallyStatement(pc);
                    break;

                case ST.varType:
                    stmt = _ParseVariableDeclarationStatement(pc);
                    break;

                default:
                    // possibly a var decl, a label statement, or an expression statement
                    if (ST.identifier == pc.SymbolId)
                    {
                        pc2 = pc.GetLookAhead(true);
                        pc2.Advance();
                        if (ST.colon == pc2.SymbolId)                                 // label
                        {
                            var lbl = pc2.Value;
                            pc.Advance();
                            stmt = new CodeLabeledStatement(lbl, new CodeSnippetStatement().SetLoc(l, c, p)).SetLoc(l, c, p);
                            pc2  = null;
                            break;
                        }
                    }
                    pc2 = null;
                    pc2 = pc.GetLookAhead(true);
                    pc2.ResetAdvanceCount();
                    var advc = 0;
                    try
                    {
                        // possibly a var decl
                        stmt = _ParseVariableDeclarationStatement(pc2);
                        advc = pc2.AdvanceCount;
                        while (advc > 0)
                        {
                            pc.Advance(false);
                            --advc;
                        }
                        break;
                    }
                    catch (SlangSyntaxException sx)
                    {
                        try
                        {
                            pc.ResetAdvanceCount();
                            expr = _ParseExpression(pc);
                            if (ST.semi != pc.SymbolId)
                            {
                                pc.Error("Expecting ; in expression statement");
                            }
                            pc.Advance();
                            var bo = expr as CodeBinaryOperatorExpression;
                            if (null != bo && CodeBinaryOperatorType.Assign == bo.Operator)
                            {
                                var ur = bo.UserData.Contains("slang:unresolved");
                                stmt = new CodeAssignStatement(bo.Left, bo.Right).Mark(l, c, p, ur);
                            }
                            else
                            {
                                stmt = new CodeExpressionStatement(expr).Mark(l, c, p);
                            }
                            break;
                        }
                        catch (SlangSyntaxException sx2)
                        {
                            if (pc.AdvanceCount > advc)
                            {
                                throw sx2;
                            }
                            throw sx;
                        }
                    }
                }
            }
            #region Post
            stmt.StartDirectives.AddRange(startDirs);
            if (null != lp)
            {
                stmt.LinePragma = lp;
            }

            while (!includeComments && ST.lineComment == pc.SymbolId || ST.blockComment == pc.SymbolId)
            {
                pc.Advance(false);
            }
            while (ST.directive == pc.SymbolId && pc.Value.StartsWith("#end", StringComparison.InvariantCulture))
            {
                stmt.EndDirectives.Add(_ParseDirective(pc) as CodeDirective);
                while (!includeComments && ST.lineComment == pc.SymbolId || ST.blockComment == pc.SymbolId)
                {
                    pc.Advance(false);
                }
            }
            #endregion Post
            return(stmt);
        }
Пример #5
0
        static IList <KeyValuePair <string, CodeAttributeDeclaration> > _ParseCustomAttributeGroup(_PC pc)
        {
            // expects to be on [
            pc.Advance();
            _SkipComments(pc);
            if (pc.IsEnded)
            {
                throw new ArgumentException("Unterminated custom attribute declaration group");
            }
            var result    = new List <KeyValuePair <string, CodeAttributeDeclaration> >();
            var target    = pc.Value;
            var hasTarget = false;
            var pc2       = pc.GetLookAhead();

            pc2.EnsureStarted();
            pc2.Advance();
            _SkipComments(pc2);
            if (ST.colon == pc2.SymbolId)
            {
                hasTarget = true;
                pc.Advance();
                _SkipComments(pc);
                pc.Advance();
                _SkipComments(pc);
                if (pc.IsEnded)
                {
                    throw new ArgumentException("Unterminated custom attribute declaration group", "input");
                }
            }
            while (ST.rbracket != pc.SymbolId)
            {
                var attr = _ParseCustomAttribute(pc);
                _SkipComments(pc);
                if (!hasTarget)
                {
                    result.Add(new KeyValuePair <string, CodeAttributeDeclaration>(null, attr));
                }
                else
                {
                    result.Add(new KeyValuePair <string, CodeAttributeDeclaration>(target, attr));
                }
                if (pc.IsEnded)
                {
                    throw new ArgumentException("Unterminated custom attribute declaration group", "input");
                }
                if (ST.comma == pc.SymbolId)
                {
                    pc.Advance();
                    _SkipComments(pc);
                    if (pc.IsEnded)
                    {
                        throw new ArgumentException("Unterminated custom attribute declaration group", "input");
                    }
                    if (ST.rbracket == pc.SymbolId)
                    {
                        throw new ArgumentException("Unexpected comma found in attribute declaration group", "input");
                    }
                }
            }
            if (ST.rbracket != pc.SymbolId)
            {
                throw new ArgumentException("Invalid custom attribute declaration", "input");
            }
            pc.Advance();
            _SkipComments(pc);
            if (0 == result.Count)
            {
                throw new ArgumentException("Attribute groups must not be empty.", "input");
            }
            return(result);
        }
Пример #6
0
        static KeyValuePair <CodeTypeReference, string> _ParsePrivateImplementationType(_PC pc)
        {
            // i really hate this routine
            _SkipComments(pc);
            CodeTypeReference ptr  = null;
            string            name = null;
            _PC pc2 = pc.GetLookAhead();

            pc2.EnsureStarted();
            try
            {
                ptr = _ParseTypeRef(pc2, true);
            }
            catch { ptr = null; }
            if (ptr != null)
            {
                if (ST.dot == pc2.SymbolId)              // we didn't finish parsing the next field. This is probably what we wanted to begin with so yay
                {
                    _ParseTypeRef(pc);
                    pc.Advance();
                    _SkipComments(pc);
                    if (pc.IsEnded)
                    {
                        throw new ArgumentException("Unterminated private member declaration");
                    }

                    var s = pc.Value;
                    pc.Advance();
                    return(new KeyValuePair <CodeTypeReference, string>(ptr, s));
                }
                // HACK: it will have parsed the name as part of the typeref, so we just trim it off.
                var idx = ptr.BaseType.LastIndexOfAny(new char[] { '.', '+' });
                if (0 > idx)
                {
                    pc.Advance();
                    if (ST.dot != pc.SymbolId)
                    {
                        // the entire thing is the name. There is no private implementation type
                        if (0 < ptr.TypeArguments.Count)
                        {
                            throw new ArgumentException("Missing member name on private member declaration", "input");
                        }
                        return(new KeyValuePair <CodeTypeReference, string>(null, ptr.BaseType));
                    }
                    else                     // this is probably a "this"
                    {
                        pc.Advance();
                        _SkipComments(pc);
                        if (ST.keyword == pc.SymbolId && "this" == pc.Value)
                        {
                            pc.Advance();
                            return(new KeyValuePair <CodeTypeReference, string>(ptr, "this"));
                        }
                        throw new ArgumentException("Illegal private member implementation type.", "input");
                    }
                }
                name         = ptr.BaseType.Substring(idx + 1);
                ptr.BaseType = ptr.BaseType.Substring(0, idx);
                _ParseTypeRef(pc, false);                 // advance
                return(new KeyValuePair <CodeTypeReference, string>(ptr, name));
            }
            var n = pc.Value;

            pc.Advance();
            return(new KeyValuePair <CodeTypeReference, string>(null, n));
            //throw new ArgumentException("Expecting identifier on private member declaration", "input");
        }
        static CodeIterationStatement _ParseForStatement(_PC pc)
        {
            // expects to be on for
            if (!pc.Advance())
            {
                throw new ArgumentException("Unterminated for statement", "input");
            }
            _SkipComments(pc);
            if (ST.lparen != pc.SymbolId || !pc.Advance())
            {
                throw new ArgumentException("Unterminated for statement", "input");
            }
            _SkipComments(pc);
            CodeStatement init = null;

            if (pc.IsEnded)
            {
                throw new ArgumentException("Unterminated for statement", "input");
            }
            if (ST.semi != pc.SymbolId)
            {
                var pc2 = pc.GetLookAhead();
                pc2.EnsureStarted();
                try
                {
                    init = _ParseVariableDeclaration(pc2);
                }
                catch { init = null; }
            }
            if (null != init)
            {
                _ParseVariableDeclaration(pc);
                _SkipComments(pc);
            }
            else
            {
                _SkipComments(pc);
                if (ST.semi != pc.SymbolId)
                {
                    var e   = _ParseExpression(pc);
                    var bbo = e as CodeBinaryOperatorExpression;
                    if (null == e)
                    {
                        throw new NotImplementedException("Expression in init statement was null");
                    }
                    if (null != bbo && CodeBinaryOperatorType.Assign == bbo.Operator)
                    {
                        init = new CodeAssignStatement(bbo.Left, bbo.Right);
                    }
                    else
                    {
                        init = new CodeExpressionStatement(e);
                    }
                    _SkipComments(pc);
                    if (ST.semi != pc.SymbolId)
                    {
                        throw new ArgumentException("Invalid init statement in for statement", "input");
                    }
                    if (pc.IsEnded)
                    {
                        throw new ArgumentException("Unterminated for statement", "input");
                    }
                }
            }
            if (null == init)
            {
                if (ST.semi != pc.SymbolId)
                {
                    throw new ArgumentException("Invalid for statement", "input");
                }
                pc.Advance();
                _SkipComments(pc);
            }
            if (pc.IsEnded)
            {
                throw new ArgumentException("Unterminated for statement", "input");
            }
            CodeExpression test = null;

            if (ST.semi != pc.SymbolId)
            {
                test = _ParseExpression(pc);
                _SkipComments(pc);
                if (ST.semi != pc.SymbolId)
                {
                    throw new ArgumentException("Invalid test expression in for statement", "input");
                }
                if (!pc.Advance())
                {
                    throw new ArgumentException("Unterminated for statement", "input");
                }
            }
            _SkipComments(pc);
            if (pc.IsEnded)
            {
                throw new ArgumentException("Unterminated for statement", "input");
            }
            CodeExpression inc = null;

            if (ST.rparen != pc.SymbolId)
            {
                inc = _ParseExpression(pc);
                _SkipComments(pc);
            }
            if (ST.rparen != pc.SymbolId)
            {
                throw new ArgumentNullException("Invalid incremement statement in for loop");
            }
            if (!pc.Advance())
            {
                throw new ArgumentException("Unterminated for statement", "input");
            }
            _SkipComments(pc);
            if (pc.IsEnded)
            {
                throw new ArgumentException("Unterminated for statement", "input");
            }
            var           bo   = inc as CodeBinaryOperatorExpression;
            CodeStatement incs = null;

            if (null != inc)
            {
                if (null != bo && CodeBinaryOperatorType.Assign == bo.Operator)
                {
                    incs = new CodeAssignStatement(bo.Left, bo.Right);
                }
                else
                {
                    incs = new CodeExpressionStatement(inc);
                }
            }
            if (null == init)
            {
                init = new CodeSnippetStatement();
            }
            if (null == incs)
            {
                incs = new CodeSnippetStatement();
            }
            if (null == test)
            {
                test = new CodeSnippetExpression();
            }
            var result = new CodeIterationStatement(init, test, incs);

            if (ST.lbrace == pc.SymbolId)
            {
                if (!pc.Advance())
                {
                    throw new ArgumentException("Unterminated for statement", "input");
                }
                while (!pc.IsEnded && ST.rbrace != pc.SymbolId)
                {
                    result.Statements.Add(_ParseStatement(pc, true));
                }
                if (ST.rbrace != pc.SymbolId)
                {
                    throw new ArgumentException("Unterminated for statement", "input");
                }
                pc.Advance();
                _SkipComments(pc);
                if (pc.IsEnded)
                {
                    return(result);
                }
            }
            else
            {
                result.Statements.Add(_ParseStatement(pc));
            }

            _SkipComments(pc);
            return(result);
        }
        static CodeStatement _ParseStatement(_PC pc, bool includeComments = false)
        {
            if (includeComments && (ST.lineComment == pc.SymbolId || ST.blockComment == pc.SymbolId))
            {
                return(_ParseCommentStatement(pc));
            }

            _SkipComments(pc);
            var pc2 = pc.GetLookAhead();

            pc2.EnsureStarted();
            CodeVariableDeclarationStatement vs = null;

            try
            {
                vs = _ParseVariableDeclaration(pc2);
            }
            catch { vs = null; }
            if (null != vs)
            {
                // advance
                _ParseVariableDeclaration(pc);
                return(vs);
            }
            pc2 = pc.GetLookAhead();
            pc2.EnsureStarted();
            CodeExpression e;

            try
            {
                e = _ParseExpression(pc2);
            }
            catch { e = null; }
            if (null != e)
            {
                _SkipComments(pc2);
                if (ST.semi == pc2.SymbolId)
                {
                    pc2.Advance();
                    _ParseExpression(pc);
                    _SkipComments(pc);
                    pc.Advance();
                    // c# treats a=1; as an expression-statement using an assign expression, linguistically
                    // so that's how we parsed it. However, CodeDOM has a special case object for this
                    // called CodeAssignStatement. For maximum language portability, we don't want to rely
                    // on assign expressions when we don't have to as they can get weird. So what we do is
                    // whenever we parse one of these we detect it and turn it into an assign statement
                    var bo = e as CodeBinaryOperatorExpression;
                    if (null != bo && CodeBinaryOperatorType.Assign == bo.Operator)
                    {
                        return(new CodeAssignStatement(bo.Left, bo.Right));
                    }
                    return(new CodeExpressionStatement(e));
                }
                else if (ST.addAssign == pc2.SymbolId || ST.subAssign == pc2.SymbolId)
                {
                    bool isAttach = ST.addAssign == pc2.SymbolId;
                    _ParseExpression(pc);
                    _SkipComments(pc);
                    pc.Advance();

                    pc2.Advance();
                    _SkipComments(pc);
                    var le = _ParseExpression(pc);
                    _SkipComments(pc);
                    if (pc.IsEnded)
                    {
                        throw new ArgumentException("Unterminated statement. Expecting ;", "input");
                    }
                    pc.Advance();
                    var v = e as CodeVariableReferenceExpression;
                    CodeEventReferenceExpression er = null;
                    if (null != v)
                    {
                        er = new CodeEventReferenceExpression(null, v.VariableName);
                    }
                    else
                    {
                        var f = e as CodeFieldReferenceExpression;
                        if (null != f)
                        {
                            er = new CodeEventReferenceExpression(f.TargetObject, f.FieldName);
                        }
                    }
                    if (null == er)
                    {
                        throw new ArgumentNullException("The attach/remove target does not refer to a valid event", "input");
                    }
                    er.UserData.Add("slang:unresolved", true);
                    return(isAttach ? new CodeAttachEventStatement(er, le) as CodeStatement : new CodeRemoveEventStatement(er, le));
                }
            }
            switch (pc.SymbolId)
            {
            case ST.keyword:
                switch (pc.Value)
                {
                case "if":
                    return(_ParseIfStatement(pc));

                case "goto":
                    return(_ParseGotoStatement(pc));

                case "for":
                    return(_ParseForStatement(pc));

                case "while":
                    return(_ParseWhileStatement(pc));

                case "return":
                    return(_ParseReturnStatement(pc));

                case "throw":
                    return(_ParseThrowStatement(pc));

                case "try":
                    return(_ParseTryCatchFinallyStatement(pc));

                case "var":
                case "bool":
                case "char":
                case "string":
                case "sbyte":
                case "byte":
                case "short":
                case "ushort":
                case "int":
                case "uint":
                case "long":
                case "ulong":
                case "float":
                case "double":
                case "decimal":
                    return(_ParseVariableDeclaration(pc));

                default:

                    throw new NotSupportedException(string.Format("The keyword {0} is not supported", pc.Value));
                }

            case ST.identifier:                     // we already know it isn't an expression
                var s = pc.Value;
                pc2 = pc.GetLookAhead();
                pc2.EnsureStarted();
                pc2.Advance();
                if (ST.colon == pc2.SymbolId)
                {
                    // CodeDOM for some reason wants us to attach a statement to a label.
                    // we don't like that for a number of reasons so we don't do it.
                    var ls = new CodeLabeledStatement(pc.Value);
                    pc.Advance();
                    _SkipComments(pc);
                    if (pc.IsEnded || ST.colon != pc.SymbolId)
                    {
                        throw new ArgumentException("Unterminated label. Expecting :", "input");
                    }
                    pc.Advance();
                    return(ls);
                }

                throw new NotImplementedException("Not finished");

            default:

                throw new ArgumentException(string.Format("Unexpected token {0} found statement.", pc.Value), "input");
            }
        }
Пример #9
0
        static CodeTypeReference _ParseTypeRef(_PC pc, bool notArrayPart = false, bool once = false)
        {
            _SkipComments(pc);
            if (pc.IsEnded)
            {
                throw new ArgumentException("Expecting a type reference", "input");
            }
            _PC pc2;             // for lookahead
            var isIntrinsic = false;
            var result      = new CodeTypeReference();
            var first       = true;

            while (!pc.IsEnded)
            {
                var s = pc.Value;

                if (first)
                {
                    if (ST.keyword == pc.SymbolId)
                    {
                        s           = _TranslateIntrinsicType(s);
                        isIntrinsic = true;
                    }
                    else if (ST.identifier != pc.SymbolId)
                    {
                        throw new ArgumentException("An identifier was expected", "input");
                    }
                    result.BaseType = s;
                }
                else
                {
                    if (ST.identifier != pc.SymbolId)
                    {
                        throw new ArgumentException("An identifier was expected", "input");
                    }
                    result.BaseType = string.Concat(result.BaseType, "+", s);
                }
                pc.Advance();
                _SkipComments(pc);
                if (pc.IsEnded)
                {
                    return(result);
                }
                if (!first || !isIntrinsic)
                {
                    _SkipComments(pc);
                    while (ST.dot == pc.SymbolId)
                    {
                        // this might be a nested type but we can't know that yet
                        result.UserData["slang:unresolved"] = true;
                        var bt = string.Concat(result.BaseType, ".");
                        pc2 = pc.GetLookAhead();
                        pc2.EnsureStarted();
                        pc2.Advance();
                        _SkipComments(pc2);
                        if (ST.identifier != pc2.SymbolId)
                        {
                            return(result);
                        }
                        pc.Advance();
                        _SkipComments(pc);
                        result.BaseType = string.Concat(bt, pc.Value);
                        if (!pc.Advance())
                        {
                            return(result);
                        }
                    }
                }
                if (ST.lt == pc.SymbolId)                 // generic type parameters follow
                {
                    var c = result.TypeArguments.Count;
                    result = _ParseTypeGenerics(pc, result);
                    // HACK: Microsoft's CodeTypeReference object doesn't handle nested type references properly
                    // in the case of generics so we have to fix it up. We just manually add the type argument count
                    // to the end of a nested type, since it's not done in the CodeTypeReference internals like it
                    // is supposed to be. It works properly however, on the outermost type (first=true) so we don't
                    // touch it until we start nesting
                    // TODO: Frankly, if they ever fix this (they won't) it will break this code (which is why they won't)
                    // but we could check here to see if it has been fixed before we "operate". I didn't bother, but
                    // it would make things more robust in the case of Microsoft ever fixing anything.
                    if (!first && result.TypeArguments.Count > c)
                    {
                        result.BaseType = string.Concat(result.BaseType, "`", result.TypeArguments.Count - c);
                    }
                }
                _SkipComments(pc);
                if (!notArrayPart)
                {
                    if (ST.lbracket == pc.SymbolId)
                    {
                        result = _ParseArrayTypeModifiers(result, pc);
                    }
                    _SkipComments(pc);
                }
                if (once || ST.dot != pc.SymbolId)
                {
                    break;
                }
                pc2 = pc.GetLookAhead();
                pc2.EnsureStarted();
                pc2.Advance();
                _SkipComments(pc2);
                if (ST.identifier != pc2.SymbolId)
                {
                    return(result);
                }
                pc.Advance();
                _SkipComments(pc);
                if (pc.IsEnded)
                {
                    throw new ArgumentException("Unterminated type reference", "input");
                }
                first = false;
            }
            return(result);
        }