/// <summary> /// Initializes a new instance of the TypeofExpression class. /// </summary> /// <param name="proxy">Proxy object for the expression.</param> /// <param name="type">The type literal to get the type of.</param> internal TypeofExpression(CodeUnitProxy proxy, LiteralExpression type) : base(proxy, ExpressionType.Typeof) { Param.AssertNotNull(proxy, "proxy"); Param.AssertNotNull(type, "type"); this.type.Value = CodeParser.ExtractTypeTokenFromLiteralExpression(type); }
/// <summary> /// Initializes a new instance of the LabelStatement class. /// </summary> /// <param name="proxy">Proxy object for the statement.</param> /// <param name="identifier">The label identifier.</param> internal LabelStatement(CodeUnitProxy proxy, LiteralExpression identifier) : base(proxy, StatementType.Label) { Param.AssertNotNull(proxy, "proxy"); Param.AssertNotNull(identifier, "identifier"); this.identifier.Value = identifier; }
/// <summary> /// Initializes a new instance of the CastExpression class. /// </summary> /// <param name="proxy">Proxy object for the expression.</param> /// <param name="type">The cast type.</param> /// <param name="castedExpression">The expression being casted.</param> internal CastExpression(CodeUnitProxy proxy, LiteralExpression type, Expression castedExpression) : base(proxy, ExpressionType.Cast) { Param.AssertNotNull(proxy, "proxy"); Param.AssertNotNull(type, "type"); Param.AssertNotNull(castedExpression, "castedExpression"); this.type.Value = CodeParser.ExtractTypeTokenFromLiteralExpression(type); this.castedExpression.Value = castedExpression; }
/// <summary> /// Initializes a new instance of the VariableDeclaratorExpression class. /// </summary> /// <param name="proxy">Proxy object for the expression.</param> /// <param name="identifier">The identifier name of the variable.</param> /// <param name="initializer">The initialization expression for the variable.</param> internal VariableDeclaratorExpression(CodeUnitProxy proxy, LiteralExpression identifier, Expression initializer) : base(proxy, ExpressionType.VariableDeclarator) { Param.AssertNotNull(proxy, "proxy"); Param.AssertNotNull(identifier, "identifier"); Param.Ignore(initializer); this.identifier.Value = identifier; this.initializer.Value = initializer; }
/// <summary> /// Initializes a new instance of the AttributeExpression class. /// </summary> /// <param name="proxy">Proxy object for the expression.</param> /// <param name="target">The attribute target, if any.</param> /// <param name="initialization">The attribute initialization call.</param> internal AttributeExpression(CodeUnitProxy proxy, LiteralExpression target, Expression initialization) : base(proxy, ExpressionType.Attribute) { Param.AssertNotNull(proxy, "proxy"); Param.Ignore(target); Param.AssertNotNull(initialization, "initialization"); this.target.Value = target; this.initialization.Value = initialization; }
/// <summary> /// Initializes a new instance of the AsExpression class. /// </summary> /// <param name="proxy">Proxy object for the expression.</param> /// <param name="value">The value to convert.</param> /// <param name="type">The type of the conversion.</param> internal AsExpression(CodeUnitProxy proxy, Expression value, LiteralExpression type) : base(proxy, ExpressionType.As) { Param.AssertNotNull(proxy, "proxy"); Param.AssertNotNull(value, "value"); Param.AssertNotNull(type, "type"); this.value.Value = value; this.type.Value = CodeParser.ExtractTypeTokenFromLiteralExpression(type); }
/// <summary> /// Initializes a new instance of the VariableDeclarationExpression class. /// </summary> /// <param name="proxy">Proxy object for the expression.</param> /// <param name="type">The type of the variable or variables being declared.</param> /// <param name="declarators">The collection of declarators on the expression.</param> internal VariableDeclarationExpression(CodeUnitProxy proxy, LiteralExpression type, ICollection<VariableDeclaratorExpression> declarators = null) : base(proxy, ExpressionType.VariableDeclaration) { Param.AssertNotNull(proxy, "proxy"); Param.AssertNotNull(type, "type"); Param.Ignore(declarators); this.type.Value = CodeParser.ExtractTypeTokenFromLiteralExpression(type); if (declarators != null && declarators.Count > 0) { this.declarators.Value = new List<VariableDeclaratorExpression>(declarators); } }
/// <summary> /// Initializes a new instance of the ChildAccessExpression class. /// </summary> /// <param name="proxy">Proxy object for the expression.</param> /// <param name="type">The type of operation being performed.</param> /// <param name="leftHandSide">The left side of the operation.</param> /// <param name="rightHandSide">The member being accessed.</param> internal ChildAccessExpression( CodeUnitProxy proxy, ExpressionType type, Expression leftHandSide, LiteralExpression rightHandSide) : base(proxy, (int)type) { Param.AssertNotNull(proxy, "proxy"); Param.Ignore(type); Param.AssertNotNull(leftHandSide, "leftHandSide"); Param.AssertNotNull(rightHandSide, "rightHandSide"); this.leftHandSide.Value = leftHandSide; this.rightHandSide.Value = rightHandSide; }
/// <summary> /// Reads an expression starting with an unknown word. /// </summary> /// <param name="parentProxy">Represents the parent item.</param> /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param> /// <returns>Returns the expression.</returns> private LiteralExpression GetLiteralExpression(CodeUnitProxy parentProxy, bool unsafeCode) { Param.AssertNotNull(parentProxy, "parentProxy"); Param.Ignore(unsafeCode); // Get the first symbol. this.AdvanceToNextCodeSymbol(parentProxy); Symbol symbol = this.PeekNextSymbol(); var expressionProxy = new CodeUnitProxy(this.document); // First, check if this is a generic. Token literalToken = null; int temp; bool generic = false; if (symbol.SymbolType == SymbolType.Other && this.HasTypeSignature(1, false, out temp, out generic) && generic) { literalToken = this.GetGenericToken(expressionProxy, unsafeCode); } if (literalToken == null) { // This is not a generic. Just convert the symbol to a token. literalToken = this.GetToken(expressionProxy, TokenType.Literal, SymbolType.Other); } // Create a literal expression from this token. var literal = new LiteralExpression(expressionProxy, literalToken); parentProxy.Children.Add(literal); return literal; }
/// <summary> /// Gets a token representing a type identifier. /// </summary> /// <param name="parentProxy">Represents the parent item.</param> /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param> /// <param name="includeArrayBrackets">Indicates whether to include array brackets in the type token.</param> /// <param name="isExpression">Indicates whether this type token comes at the end of an 'is' expression.</param> /// <returns>Returns the token.</returns> private LiteralExpression GetTypeTokenExpression(CodeUnitProxy parentProxy, bool unsafeCode, bool includeArrayBrackets, bool isExpression) { Param.AssertNotNull(parentProxy, "parentProxy"); Param.Ignore(unsafeCode); Param.Ignore(includeArrayBrackets); Param.Ignore(isExpression); this.AdvanceToNextCodeSymbol(parentProxy); var expressionProxy = new CodeUnitProxy(this.document); TypeToken token = this.GetTypeToken(expressionProxy, unsafeCode, includeArrayBrackets, isExpression); // Create and return the literal expression. var expression = new LiteralExpression(expressionProxy, token); parentProxy.Children.Add(expression); return expression; }
/// <summary> /// Parses and returns a constructor. /// </summary> /// <param name="elementProxy">Proxy for the element being created.</param> /// <param name="parent">The parent of the element.</param> /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param> /// <param name="generated">Indicates whether the code is marked as generated code.</param> /// <param name="attributes">The attributes on the element.</param> /// <returns>Returns the element.</returns> private Constructor GetConstructor(CodeUnitProxy elementProxy, Element parent, bool unsafeCode, bool generated, ICollection<Attribute> attributes) { Param.AssertNotNull(elementProxy, "elementProxy"); Param.AssertNotNull(parent, "parent"); Param.Ignore(unsafeCode); Param.Ignore(generated); Param.Ignore(attributes); // Get the modifiers and access. AccessModifierType accessModifier = AccessModifierType.Private; Dictionary<TokenType, Token> modifiers = this.GetElementModifiers(elementProxy, ref accessModifier, ConstructorModifiers); unsafeCode |= modifiers.ContainsKey(TokenType.Unsafe); // Get the name of the constructor. Token name = this.GetElementNameToken(elementProxy, unsafeCode); // Get the parameter list. this.GetParameterList(elementProxy, unsafeCode, SymbolType.OpenParenthesis); // Get the constructor initializer if there is one. ConstructorInitializerStatement constructorInitializerStatement = null; Symbol symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Colon) { this.GetToken(elementProxy, TokenType.BaseColon, SymbolType.Colon); var constructorInitializerStatementProxy = new CodeUnitProxy(this.document); var constructorInitializerExpressionProxy = new CodeUnitProxy(this.document); // The next symbol must be the keyword base or this. symbol = this.PeekNextSymbol(); if (symbol.SymbolType != SymbolType.This && symbol.SymbolType != SymbolType.Base) { throw this.CreateSyntaxException(); } var initializerNameExpressionProxy = new CodeUnitProxy(this.document); Token initializerNameToken = this.GetToken(initializerNameExpressionProxy, TokenType.Literal, symbol.SymbolType); // Get the name expression. var initializerNameExpression = new LiteralExpression(initializerNameExpressionProxy, initializerNameToken); constructorInitializerExpressionProxy.Children.Add(initializerNameExpression); // Get the initializer expression. var constructorInitializerExpression = this.GetMethodInvocationExpression(constructorInitializerExpressionProxy, initializerNameExpression, ExpressionPrecedence.None, unsafeCode); constructorInitializerStatementProxy.Children.Add(constructorInitializerExpression); // Create the constructor initializer statement constructorInitializerStatement = new ConstructorInitializerStatement(constructorInitializerStatementProxy, constructorInitializerExpression); elementProxy.Children.Add(constructorInitializerStatement); } var constructor = new Constructor(elementProxy, name.Text, attributes, unsafeCode); // If the constructor is extern, it will not have a body. if (modifiers.ContainsKey(TokenType.Extern)) { // Get the closing semicolon. this.GetToken(elementProxy, TokenType.Semicolon, SymbolType.Semicolon); } else { // Get the body. this.ParseStatementContainer(elementProxy, constructor, true, unsafeCode); } return constructor; }
/// <summary> /// Parses and returns a field. /// </summary> /// <param name="elementProxy">Proxy for the element being created.</param> /// <param name="parent">The parent of the element.</param> /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param> /// <param name="generated">Indicates whether the code is marked as generated code.</param> /// <param name="attributes">The attributes on the element.</param> /// <returns>Returns the element.</returns> private Field GetField(CodeUnitProxy elementProxy, Element parent, bool unsafeCode, bool generated, ICollection<Attribute> attributes) { Param.AssertNotNull(elementProxy, "elementProxy"); Param.AssertNotNull(parent, "parent"); Param.Ignore(unsafeCode); Param.Ignore(generated); Param.Ignore(attributes); // Get the modifiers and access. AccessModifierType accessModifier = AccessModifierType.Private; Dictionary<TokenType, Token> modifiers = this.GetElementModifiers(elementProxy, ref accessModifier, FieldModifiers); unsafeCode |= modifiers.ContainsKey(TokenType.Unsafe); var declarationExpressionProxy = new CodeUnitProxy(this.document); // Get the field type. var fieldTypeExpressionProxy = new CodeUnitProxy(this.document); TypeToken fieldType = this.GetTypeToken(fieldTypeExpressionProxy, unsafeCode, true); var fieldTypeExpression = new LiteralExpression(fieldTypeExpressionProxy, fieldType); declarationExpressionProxy.Children.Add(fieldTypeExpression); // Get all of the variable declarators. string firstFieldName = this.GetFieldDeclarators(declarationExpressionProxy, unsafeCode, fieldType); if (string.IsNullOrWhiteSpace(firstFieldName)) { throw this.CreateSyntaxException(); } var variableDeclarationStatementProxy = new CodeUnitProxy(this.document); var declarationExpression = new VariableDeclarationExpression(declarationExpressionProxy, fieldTypeExpression); variableDeclarationStatementProxy.Children.Add(declarationExpression); var variableDeclarationStatement = new VariableDeclarationStatement(variableDeclarationStatementProxy, declarationExpression); elementProxy.Children.Add(variableDeclarationStatement); var field = new Field(elementProxy, firstFieldName, attributes, fieldType, unsafeCode); // Get the trailing semicolon. this.GetToken(elementProxy, TokenType.Semicolon, SymbolType.Semicolon); return field; }
/// <summary> /// Creates a new token and adds it to a new literal expression. /// </summary> /// <param name="parentProxy">Represents the parent item.</param> /// <param name="symbolType">The type of the symbol.</param> /// <param name="tokenType">The type of the token.</param> /// <returns>Returns the literal expression.</returns> private LiteralExpression CreateLiteralExpression(CodeUnitProxy parentProxy, SymbolType symbolType, TokenType tokenType) { Param.AssertNotNull(parentProxy, "parentProxy"); Param.Ignore(symbolType, tokenType); this.AdvanceToNextCodeSymbol(parentProxy); var expressionProxy = new CodeUnitProxy(this.document); Token token = this.GetToken(expressionProxy, tokenType, symbolType); var expression = new LiteralExpression(expressionProxy, token); parentProxy.Children.Add(expression); return expression; }
/// <summary> /// Reads the next goto-statement from the file and returns it. /// </summary> /// <param name="parentProxy">Represents the parent item.</param> /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param> /// <returns>Returns the statement.</returns> private GotoStatement GetGotoStatement(CodeUnitProxy parentProxy, bool unsafeCode) { Param.Ignore(unsafeCode); Param.AssertNotNull(parentProxy, "parentProxy"); var statementProxy = new CodeUnitProxy(this.document); // Move past the goto keyword. this.GetToken(statementProxy, TokenType.Goto, SymbolType.Goto); // Get the next symbol. Symbol symbol = this.PeekNextSymbol(); Expression identifier = null; if (symbol.SymbolType == SymbolType.Default) { CodeUnitProxy identifierProxy = new CodeUnitProxy(this.document); Token token = this.GetToken(identifierProxy, TokenType.Literal, SymbolType.Default); identifier = new LiteralExpression(identifierProxy, token); statementProxy.Children.Add(identifier); } else if (symbol.SymbolType == SymbolType.Case) { this.GetToken(statementProxy, TokenType.Literal, SymbolType.Case); identifier = this.GetNextExpression(statementProxy, ExpressionPrecedence.None, unsafeCode); } else { identifier = this.GetNextExpression(statementProxy, ExpressionPrecedence.None, unsafeCode); } // Get the closing semicolon. this.GetToken(statementProxy, TokenType.Semicolon, SymbolType.Semicolon); // Create and return the goto-statement. var statement = new GotoStatement(statementProxy, identifier); parentProxy.Children.Add(statement); return statement; }
/// <summary> /// Parses and returns the declarators for an event. /// </summary> /// <param name="parentProxy">Represents the parent item.</param> /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param> /// <param name="eventHandlerType">The event type.</param> /// <returns>Returns the name of the first event.</returns> private string GetEventDeclarators(CodeUnitProxy parentProxy, bool unsafeCode, TypeToken eventHandlerType) { Param.AssertNotNull(parentProxy, "parentProxy"); Param.Ignore(unsafeCode); Param.AssertNotNull(eventHandlerType, "eventHandlerType"); string firstEventName = null; Symbol symbol = this.PeekNextSymbol(); while (symbol.SymbolType != SymbolType.Semicolon && symbol.SymbolType != SymbolType.OpenCurlyBracket) { this.AdvanceToNextCodeSymbol(parentProxy); var declaratorProxy = new CodeUnitProxy(this.document); // Get the identifier. var identifierExpressionProxy = new CodeUnitProxy(this.document); Token identifier = this.GetElementNameToken(identifierExpressionProxy, unsafeCode, true); if (firstEventName == null) { firstEventName = identifier.Text; } var identifierExpression = new LiteralExpression(identifierExpressionProxy, identifier); declaratorProxy.Children.Add(identifierExpression); Expression initialization = null; // Check whether there is an equals sign. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Equals) { this.GetOperatorSymbolToken(declaratorProxy, OperatorType.Equals); initialization = this.GetNextExpression(declaratorProxy, ExpressionPrecedence.None, unsafeCode); if (initialization == null) { throw this.CreateSyntaxException(); } } var declaratorExpression = new EventDeclaratorExpression(declaratorProxy, identifierExpression, initialization); parentProxy.Children.Add(declaratorExpression); // If the next symbol is a comma, continue. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Comma) { this.GetToken(parentProxy, TokenType.Comma, SymbolType.Comma); symbol = this.PeekNextSymbol(); } } return firstEventName; }
/// <summary> /// Parses and returns a event. /// </summary> /// <param name="elementProxy">Proxy for the element being created.</param> /// <param name="parent">The parent of the element.</param> /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param> /// <param name="generated">Indicates whether the code is marked as generated code.</param> /// <param name="attributes">The attributes on the element.</param> /// <returns>Returns the element.</returns> private Event GetEvent(CodeUnitProxy elementProxy, Element parent, bool unsafeCode, bool generated, ICollection<Attribute> attributes) { Param.AssertNotNull(elementProxy, "elementProxy"); Param.AssertNotNull(parent, "parent"); Param.Ignore(unsafeCode); Param.Ignore(generated); Param.Ignore(attributes); // Get the modifiers and access. AccessModifierType accessModifier = AccessModifierType.Private; // Events within interfaces always have the access of the parent interface. Interface parentInterface = parent as Interface; if (parentInterface != null) { accessModifier = parentInterface.AccessModifierType; } // Get declared modifiers. Dictionary<TokenType, Token> modifiers = this.GetElementModifiers(elementProxy, ref accessModifier, EventModifiers); unsafeCode |= modifiers.ContainsKey(TokenType.Unsafe); // Get the event keyword. this.GetToken(elementProxy, TokenType.Event, SymbolType.Event); // Get the event type. var eventHandlerTypeExpressionProxy = new CodeUnitProxy(this.document); TypeToken eventHandlerType = this.GetTypeToken(eventHandlerTypeExpressionProxy, unsafeCode, true); var eventHandlerTypeExpression = new LiteralExpression(eventHandlerTypeExpressionProxy, eventHandlerType); elementProxy.Children.Add(eventHandlerTypeExpression); // Get all of the event declarators. string firstEventName = this.GetEventDeclarators(elementProxy, unsafeCode, eventHandlerType); if (string.IsNullOrWhiteSpace(firstEventName)) { throw this.CreateSyntaxException(); } Event @event = new Event(elementProxy, firstEventName, attributes, eventHandlerType, unsafeCode); Symbol symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Semicolon) { this.GetToken(elementProxy, TokenType.Semicolon, SymbolType.Semicolon); } else { // Parse the body of the event. this.ParseElementContainer(elementProxy, @event, unsafeCode); } return @event; }
/// <summary> /// Extracts a TypeToken from the literal expression, assuming that one exists. /// </summary> /// <param name="literal">The literal expression.</param> /// <returns>Returns the type token.</returns> internal static TypeToken ExtractTypeTokenFromLiteralExpression(LiteralExpression literal) { Param.AssertNotNull(literal, "literal"); TypeToken type = literal.Token as TypeToken; if (type == null) { throw new SyntaxException(literal.Document, literal.LineNumber, Strings.LiteralExpressionDoesNotContainTypeToken); } return type; }
/// <summary> /// Reads an expression starting with an unknown word. /// </summary> /// <param name="parentProxy">Proxy object for the parent item.</param> /// <returns>Returns the expression.</returns> private LiteralExpression GetConditionalPreprocessorConstantExpression(CodeUnitProxy parentProxy) { Param.AssertNotNull(parentProxy, "parentProxy"); this.AdvanceToNextConditionalDirectiveCodeSymbol(parentProxy); var expressionProxy = new CodeUnitProxy(this.document); // Get the first symbol. Symbol symbol = this.symbols.Peek(1); CsLanguageService.Debug.Assert(symbol != null && symbol.SymbolType == SymbolType.Other, "Expected a text symbol"); // Convert the symbol to a token. this.symbols.Advance(); var literalToken = new LiteralToken(this.document, symbol.Text, symbol.Location, this.symbols.Generated); expressionProxy.Children.Add(literalToken); // Create a literal expression from this token. var literalExpression = new LiteralExpression(expressionProxy, literalToken); parentProxy.Children.Add(literalExpression); return literalExpression; }
/// <summary> /// Parses and returns the declarators for a field. /// </summary> /// <param name="parentProxy">Represents the parent item.</param> /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param> /// <param name="fieldType">The field type.</param> /// <returns>Returns the name of the first field.</returns> private string GetFieldDeclarators(CodeUnitProxy parentProxy, bool unsafeCode, TypeToken fieldType) { Param.AssertNotNull(parentProxy, "parentProxy"); Param.Ignore(unsafeCode); Param.AssertNotNull(fieldType, "fieldType"); string firstFieldName = null; Symbol symbol = this.PeekNextSymbol(); while (symbol.SymbolType != SymbolType.Semicolon) { this.AdvanceToNextCodeSymbol(parentProxy); var declaratorProxy = new CodeUnitProxy(this.document); // Get the identifier. var identifierExpressionProxy = new CodeUnitProxy(this.document); Token identifier = this.GetElementNameToken(identifierExpressionProxy, unsafeCode, true); var identifierExpression = new LiteralExpression(identifierExpressionProxy, identifier); declaratorProxy.Children.Add(identifierExpression); if (firstFieldName == null) { firstFieldName = identifier.Text; } Expression initialization = null; // Check whether there is an equals sign. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Equals) { this.GetOperatorSymbolToken(declaratorProxy, OperatorType.Equals); // Get the expression after the equals sign. If the expression starts with an // opening curly bracket, then this is an initialization expression or an // anonymous type initialization expression. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.OpenCurlyBracket) { // Determine whether this is an array or an anonymous type. if (fieldType.Text == "var" || ( fieldType.Text != "Array" && fieldType.Text != "System.Array" && !fieldType.Text.Contains("["))) { initialization = this.GetAnonymousTypeInitializerExpression(declaratorProxy, unsafeCode); } else { initialization = this.GetArrayInitializerExpression(declaratorProxy, unsafeCode); } } else { initialization = this.GetNextExpression(declaratorProxy, ExpressionPrecedence.None, unsafeCode); } if (initialization == null) { throw this.CreateSyntaxException(); } } var declaratorExpression = new VariableDeclaratorExpression(declaratorProxy, identifierExpression, initialization); parentProxy.Children.Add(declaratorExpression); // If the next symbol is a comma, continue. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Comma) { this.GetToken(parentProxy, TokenType.Comma, SymbolType.Comma); symbol = this.PeekNextSymbol(); } } // Return the declarators as a read-only collection. return firstFieldName; }