/// <summary> /// Reads an unsafe type expression. /// </summary> /// <param name="type">The type expression.</param> /// <param name="previousPrecedence">The precedence of the previous expression.</param> /// <param name="parentReference">The parent code unit.</param> /// <returns>Returns the expression.</returns> private UnsafeAccessExpression GetUnsafeTypeExpression(Expression type, ExpressionPrecedence previousPrecedence, Reference<ICodePart> parentReference) { Param.Ignore(type); Param.AssertNotNull(previousPrecedence, "previousPrecedence"); Param.AssertNotNull(parentReference, "parentReference"); UnsafeAccessExpression expression = null; if (CheckPrecedence(previousPrecedence, ExpressionPrecedence.Unary)) { // Get the operator symbol. Symbol symbol = this.GetNextSymbol(parentReference); var expressionReference = new Reference<ICodePart>(); OperatorType operatorType; UnsafeAccessExpression.Operator unsafeOperatorType; if (symbol.SymbolType == SymbolType.LogicalAnd) { operatorType = OperatorType.AddressOf; unsafeOperatorType = UnsafeAccessExpression.Operator.AddressOf; } else if (symbol.SymbolType == SymbolType.Multiplication) { operatorType = OperatorType.Dereference; unsafeOperatorType = UnsafeAccessExpression.Operator.Dereference; } else { Debug.Fail("Unexpected operator type."); throw new InvalidOperationException(); } // Create a token for the operator symbol. this.symbols.Advance(); OperatorSymbol token = new OperatorSymbol( symbol.Text, OperatorCategory.Reference, operatorType, symbol.Location, expressionReference, this.symbols.Generated); this.tokens.Add(token); // Create the partial token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, type.Tokens.First, this.tokens.Last); // Create and return the expression. expression = new UnsafeAccessExpression(partialTokens, unsafeOperatorType, type); expressionReference.Target = expression; } return expression; }
/// <summary> /// Reads an unsafe access expression. /// </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 expression.</returns> private UnsafeAccessExpression GetUnsafeAccessExpression(Reference<ICodePart> parentReference, bool unsafeCode) { Param.AssertNotNull(parentReference, "parentReference"); Param.Assert(unsafeCode == true, "unsafeCode", "Un unsafe access must reside in an unsafe code block."); // Get the operator symbol. Symbol symbol = this.GetNextSymbol(parentReference); var expressionReference = new Reference<ICodePart>(); OperatorType operatorType; UnsafeAccessExpression.Operator unsafeOperatorType; if (symbol.SymbolType == SymbolType.LogicalAnd) { operatorType = OperatorType.AddressOf; unsafeOperatorType = UnsafeAccessExpression.Operator.AddressOf; } else if (symbol.SymbolType == SymbolType.Multiplication) { operatorType = OperatorType.Dereference; unsafeOperatorType = UnsafeAccessExpression.Operator.Dereference; } else { Debug.Fail("Unexpected operator type."); throw new InvalidOperationException(); } // Create a token for the operator symbol. this.symbols.Advance(); OperatorSymbol token = new OperatorSymbol( symbol.Text, OperatorCategory.Reference, operatorType, symbol.Location, expressionReference, this.symbols.Generated); Node<CsToken> tokenNode = this.tokens.InsertLast(token); // Get the expression being accessed. Expression innerExpression = this.GetNextExpression(ExpressionPrecedence.Unary, expressionReference, unsafeCode); if (innerExpression == null || innerExpression.Tokens.First == null) { throw new SyntaxException(this.document.SourceCode, symbol.LineNumber); } // Create the partial token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, tokenNode, this.tokens.Last); // Create and return the expression. var expression = new UnsafeAccessExpression(partialTokens, unsafeOperatorType, innerExpression); expressionReference.Target = expression; return expression; }