Exemplo n.º 1
0
        /// <summary>
        /// Reads the next using-statement from the file and returns it.
        /// </summary>
        /// <param name="parentReference">
        /// The parent code unit.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the code being parsed resides in an unsafe code block.
        /// </param>
        /// <returns>
        /// Returns the statement.
        /// </returns>
        private UsingStatement ParseUsingStatement(Reference<ICodePart> parentReference, bool unsafeCode)
        {
            Param.AssertNotNull(parentReference, "parentReference");
            Param.Ignore(unsafeCode);

            Reference<ICodePart> statementReference = new Reference<ICodePart>();

            // Move past the using keyword.
            CsToken firstToken = this.GetToken(CsTokenType.Using, SymbolType.Using, parentReference, statementReference);
            Node<CsToken> firstTokenNode = this.tokens.InsertLast(firstToken);

            // Get the opening parenthesis.
            Bracket openParenthesis = this.GetBracketToken(CsTokenType.OpenParenthesis, SymbolType.OpenParenthesis, statementReference);
            Node<CsToken> openParenthesisNode = this.tokens.InsertLast(openParenthesis);

            // Get the expression within the parenthesis.
            Expression expression = this.GetNextExpression(ExpressionPrecedence.None, statementReference, unsafeCode, true, false);
            if (expression == null)
            {
                throw this.CreateSyntaxException();
            }

            // Get the closing parenthesis.
            Bracket closeParenthesis = this.GetBracketToken(CsTokenType.CloseParenthesis, SymbolType.CloseParenthesis, statementReference);
            Node<CsToken> closeParenthesisNode = this.tokens.InsertLast(closeParenthesis);

            openParenthesis.MatchingBracketNode = closeParenthesisNode;
            closeParenthesis.MatchingBracketNode = openParenthesisNode;

            // Get the embedded statement.
            Statement childStatement = this.GetNextStatement(statementReference, unsafeCode);
            if (childStatement == null)
            {
                throw this.CreateSyntaxException();
            }

            // Create the token list for the statement.
            CsTokenList partialTokens = new CsTokenList(this.tokens, firstTokenNode, this.tokens.Last);

            // Create the using-statement.
            UsingStatement statement = new UsingStatement(partialTokens, expression);
            statement.EmbeddedStatement = childStatement;
            statementReference.Target = statement;

            // Add the variable if there is one.
            VariableDeclarationExpression variableDeclaration = expression as VariableDeclarationExpression;
            if (variableDeclaration != null)
            {
                foreach (VariableDeclaratorExpression declarator in variableDeclaration.Declarators)
                {
                    Variable variable = new Variable(
                        variableDeclaration.Type, 
                        declarator.Identifier.Token.Text, 
                        VariableModifiers.None, 
                        CodeLocation.Join(variableDeclaration.Type.Location, declarator.Identifier.Token.Location), 
                        statementReference, 
                        variableDeclaration.Type.Generated || declarator.Identifier.Token.Generated);

                    // If there is already a variable in this scope with the same name, ignore this one.
                    if (!statement.Variables.Contains(declarator.Identifier.Token.Text))
                    {
                        statement.Variables.Add(variable);
                    }
                }
            }

            return statement;
        }
        /// <summary>
        /// The save.
        /// </summary>
        /// <param name="usingStatement">
        /// The using statement.
        /// </param>
        private void Save(UsingStatement usingStatement)
        {
            var isLiteral = usingStatement.Resource is LiteralExpression;

            // this.cppWriter.Write("/* using */");
            if (!isLiteral)
            {
                this.cppWriter.WriteLine();
                this.cppWriter.WriteLine("{");
                this.cppWriter.Indent++;

                @switch(usingStatement.Resource);
                this.cppWriter.Write(";");
            }

            this.Save(usingStatement.EmbeddedStatement);

            if (!isLiteral)
            {
                // get disposable interface
                var variableDeclaration = usingStatement.Resource as VariableDeclarationExpression;
                if (variableDeclaration != null)
                {
                    foreach (var varDecl in variableDeclaration.Declarators)
                    {
                        this.cppWriter.Write("dynamic_cast<");
                        this.Save(
                            new TypeResolver("IDisposable", this), this.cppWriter, SavingOptions.UseFullyQualifiedNames);
                        this.cppWriter.Write(">(");
                        this.cppWriter.Write(varDecl.Identifier);
                        this.cppWriter.WriteLine(")->Dispose();");
                    }
                }

                this.cppWriter.Indent--;
                this.cppWriter.WriteLine("}");
            }
        }