Esempio n. 1
0
        /// <summary>
        /// Reads the next variable declaration 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>
        /// <param name="variables">
        /// Returns the list of variables defined in the statement.
        /// </param>
        /// <returns>
        /// Returns the statement.
        /// </returns>
        private VariableDeclarationStatement ParseVariableDeclarationStatement(Reference<ICodePart> parentReference, bool unsafeCode, VariableCollection variables)
        {
            Param.AssertNotNull(parentReference, "parentReference");
            Param.Ignore(unsafeCode);
            Param.Ignore(variables);

            bool constant = false;

            // Get the first symbol and make sure it is an unknown word or a const.
            Symbol symbol = this.GetNextSymbol(parentReference);

            CsToken firstToken = null;
            Node<CsToken> firstTokenNode = null;

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

            if (symbol.SymbolType == SymbolType.Const)
            {
                constant = true;

                firstToken = new CsToken(symbol.Text, CsTokenType.Const, symbol.Location, statementReference, this.symbols.Generated);
                firstTokenNode = this.tokens.InsertLast(this.GetToken(CsTokenType.Const, SymbolType.Const, statementReference));

                symbol = this.GetNextSymbol(statementReference);
            }

            if (symbol.SymbolType != SymbolType.Other)
            {
                throw this.CreateSyntaxException();
            }

            // Get the expression representing the type.
            LiteralExpression type = this.GetTypeTokenExpression(statementReference, unsafeCode, true);
            if (type == null || type.Tokens.First == null)
            {
                throw new SyntaxException(this.document.SourceCode, firstToken.LineNumber);
            }

            if (firstTokenNode == null)
            {
                firstTokenNode = type.Tokens.First;
            }

            // Get the rest of the declaration.
            VariableDeclarationExpression expression = this.GetVariableDeclarationExpression(type, ExpressionPrecedence.None, unsafeCode);

            // Get the closing semicolon.
            this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, statementReference));

            // Add each of the variables defined in this statement to the variable list being returned.
            if (variables != null)
            {
                VariableModifiers modifiers = constant ? VariableModifiers.Const : VariableModifiers.None;
                foreach (VariableDeclaratorExpression declarator in expression.Declarators)
                {
                    Variable variable = new Variable(
                        expression.Type, 
                        declarator.Identifier.Token.Text, 
                        modifiers, 
                        CodeLocation.Join(expression.Type.Location, declarator.Identifier.Token.Location), 
                        statementReference, 
                        expression.Tokens.First.Value.Generated || declarator.Identifier.Token.Generated);

                    // There might already be a variable in this scope with the same name. This can happen
                    // in valid situation when there are ifdef's surrounding portions of the code.
                    // Just accept the first variable and ignore others.
                    if (!variables.Contains(declarator.Identifier.Token.Text))
                    {
                        variables.Add(variable);
                    }
                }
            }

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

            VariableDeclarationStatement statement = new VariableDeclarationStatement(partialTokens, constant, expression);
            statementReference.Target = statement;

            return statement;
        }
        /// <summary>
        /// The save.
        /// </summary>
        /// <param name="localVariable">
        /// The local variable.
        /// </param>
        private void Save(VariableDeclarationStatement localVariable)
        {
            var storesaveVariablesMode = this.saveVariablesMode;

            if (localVariable.Constant)
            {
                // must be static for C++ as well
                if (storesaveVariablesMode == SaveVariablesMode.DefaultSourceInitializers)
                {
                    this.cppWriter.Write("const ");
                }
                else
                {
                    this.cppWriter.Write("const static ");
                }
            }

            this.Save(localVariable.InnerExpression);

            this.saveVariablesMode = storesaveVariablesMode;
        }