public JsExpression VisitUnaryExpression(ExpressionSyntax node, ExpressionSyntax expression) { ExpressionType op; switch (node.CSharpKind()) { case SyntaxKind.LogicalNotExpression: op = ExpressionType.Not; break; case SyntaxKind.UnaryMinusExpression: op = ExpressionType.Negate; break; case SyntaxKind.PostDecrementExpression: case SyntaxKind.PostIncrementExpression: throw new Exception("Expression trees cannot contain assignment operators."); default: throw new Exception("Unknown operation: " + node.CSharpKind()); } var makeUnary = GetExpressionMethod("MakeUnary", Context.Instance.ExpressionType, Context.Instance.Expression, Context.Instance.TypeType); var opExpression = idioms.GetEnumValue(Context.Instance.ExpressionType.GetMembers(op.ToString()).OfType <IFieldSymbol>().Single()); var operand = expression.Accept(this); var type = model.GetTypeInfo(node).ConvertedType; return(idioms.InvokeStatic( makeUnary, opExpression, operand, idioms.TypeOf(type))); }
public static TypeSyntax ConstantType(ExpressionSyntax value) { var valueStr = value.ToString(); switch (value.CSharpKind()) { case SyntaxKind.NumericLiteralExpression: { int val; double dval; if (int.TryParse(valueStr, out val)) { return(Compiler.Int); } else if (double.TryParse(valueStr, out dval)) { return(Compiler.Double); } break; } case SyntaxKind.StringLiteralExpression: return(Compiler.String); case SyntaxKind.TrueLiteralExpression: case SyntaxKind.FalseLiteralExpression: return(Compiler.Boolean); } return(SyntaxFactory.ParseTypeName(valueStr)); }
public void ParseExpression() { ExpressionSyntax expression = SyntaxFactory.ParseExpression("1 + 2"); if (expression.CSharpKind() == SyntaxKind.AddExpression) { BinaryExpressionSyntax binaryExpression = (BinaryExpressionSyntax)expression; SyntaxToken operatorToken = binaryExpression.OperatorToken; Assert.AreEqual("+", operatorToken.ToString()); ExpressionSyntax left = binaryExpression.Left; Assert.AreEqual(SyntaxKind.NumericLiteralExpression, left.CSharpKind()); } }
private static bool IsAssignmentOfPropertyValueParameterToBackingField( ExpressionSyntax expression, IFieldSymbol backingField, SemanticModel semanticModel) { if (expression.CSharpKind() != SyntaxKind.SimpleAssignmentExpression) { return(false); } var assignment = (AssignmentExpressionSyntax)expression; return(IsBackingField(assignment.Left, backingField, semanticModel) && IsPropertyValueParameter(assignment.Right, semanticModel)); }
/// <summary> /// Decomposes a name or member access expression into its component parts. /// </summary> /// <param name="expression">The name or member access expression.</param> /// <param name="qualifier">The qualifier (or left-hand-side) of the name expression. This may be null if there is no qualifier.</param> /// <param name="name">The name of the expression.</param> /// <param name="arity">The number of generic type parameters.</param> private static void DecomposeName(ExpressionSyntax expression, out ExpressionSyntax qualifier, out string name, out int arity) { switch (expression.CSharpKind()) { case SyntaxKind.SimpleMemberAccessExpression: case SyntaxKind.PointerMemberAccessExpression: var max = (MemberAccessExpressionSyntax)expression; qualifier = max.Expression; name = max.Name.Identifier.ValueText; arity = max.Name.Arity; break; case SyntaxKind.QualifiedName: var qn = (QualifiedNameSyntax)expression; qualifier = qn.Left; name = qn.Right.Identifier.ValueText; arity = qn.Arity; break; case SyntaxKind.AliasQualifiedName: var aq = (AliasQualifiedNameSyntax)expression; qualifier = aq.Alias; name = aq.Name.Identifier.ValueText; arity = aq.Name.Arity; break; case SyntaxKind.GenericName: var gx = (GenericNameSyntax)expression; qualifier = null; name = gx.Identifier.ValueText; arity = gx.Arity; break; case SyntaxKind.IdentifierName: var nx = (IdentifierNameSyntax)expression; qualifier = null; name = nx.Identifier.ValueText; arity = 0; break; default: qualifier = null; name = null; arity = 0; break; } }
private ExpressionSyntax TryAddTypeArgumentToIdentifierName(ExpressionSyntax newNode, ISymbol symbol) { if (newNode.CSharpKind() == SyntaxKind.IdentifierName && symbol.Kind == SymbolKind.Method) { if (((IMethodSymbol)symbol).TypeArguments.Length != 0) { var typeArguments = ((IMethodSymbol)symbol).TypeArguments; var genericName = SyntaxFactory.GenericName( ((IdentifierNameSyntax)newNode).Identifier, SyntaxFactory.TypeArgumentList( SyntaxFactory.SeparatedList( typeArguments.Select(p => SyntaxFactory.ParseTypeName(p.ToDisplayParts(TypeNameFormatWithGenerics).ToDisplayString()))))) .WithLeadingTrivia(newNode.GetLeadingTrivia()) .WithTrailingTrivia(newNode.GetTrailingTrivia()) .WithAdditionalAnnotations(Simplifier.Annotation); genericName = newNode.CopyAnnotationsTo(genericName); return(genericName); } } return(newNode); }
private static bool WillConflictWithExistingLocal(ExpressionSyntax expression, ExpressionSyntax simplifiedNode) { if (simplifiedNode.CSharpKind() == SyntaxKind.IdentifierName && !SyntaxFacts.IsInNamespaceOrTypeContext(expression)) { var identifierName = (IdentifierNameSyntax)simplifiedNode; var enclosingDeclarationSpace = FindImmediatelyEnclosingLocalVariableDeclarationSpace(expression); var enclosingMemberDeclaration = expression.FirstAncestorOrSelf<MemberDeclarationSyntax>(); if (enclosingDeclarationSpace != null && enclosingMemberDeclaration != null) { var locals = enclosingMemberDeclaration.GetLocalDeclarationMap()[identifierName.Identifier.ValueText]; foreach (var token in locals) { if (token.GetAncestors<SyntaxNode>().Contains(enclosingDeclarationSpace)) { return true; } } } } return false; }
private static bool IsNullableTypeInPointerExpression(ExpressionSyntax expression, ExpressionSyntax simplifiedNode) { // Note: nullable type syntax is not allowed in pointer type syntax if (simplifiedNode.CSharpKind() == SyntaxKind.NullableType && simplifiedNode.DescendantNodes().Any(n => n is PointerTypeSyntax)) { return true; } return false; }
public static TypeSyntax ConstantType(ExpressionSyntax value) { var valueStr = value.ToString(); switch (value.CSharpKind()) { case SyntaxKind.NumericLiteralExpression: { int val; double dval; if (int.TryParse(valueStr, out val)) return Compiler.Int; else if (double.TryParse(valueStr, out dval)) return Compiler.Double; break; } case SyntaxKind.StringLiteralExpression: return Compiler.String; case SyntaxKind.TrueLiteralExpression: case SyntaxKind.FalseLiteralExpression: return Compiler.Boolean; } return SyntaxFactory.ParseTypeName(valueStr); }
private static bool IsAssignmentOfPropertyValueParameterToBackingField( ExpressionSyntax expression, IFieldSymbol backingField, SemanticModel semanticModel) { if (expression.CSharpKind() != SyntaxKind.SimpleAssignmentExpression) { return false; } var assignment = (BinaryExpressionSyntax)expression; return IsBackingField(assignment.Left, backingField, semanticModel) && IsPropertyValueParameter(assignment.Right, semanticModel); }
private ExpressionSyntax FullyQualifyIdentifierName( ISymbol symbol, ExpressionSyntax rewrittenNode, ExpressionSyntax originalNode, bool replaceNode, bool isInsideCref, bool omitLeftHandSide) { Debug.Assert(!replaceNode || rewrittenNode.CSharpKind() == SyntaxKind.IdentifierName); //// TODO: use and expand Generate*Syntax(isymbol) to not depend on symbol display any more. //// See GenerateExpressionSyntax(); var result = rewrittenNode; // only if this symbol has a containing type or namespace there is work for us to do. if (replaceNode || symbol.ContainingType != null || symbol.ContainingNamespace != null) { ImmutableArray <SymbolDisplayPart> displayParts; ExpressionSyntax left = null; // we either need to create an AliasQualifiedName if the symbol is directly contained in the global namespace, // otherwise it a QualifiedName. if (!replaceNode && symbol.ContainingType == null && symbol.ContainingNamespace.IsGlobalNamespace) { return(rewrittenNode.CopyAnnotationsTo( SyntaxFactory.AliasQualifiedName( SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)), (SimpleNameSyntax)rewrittenNode.WithLeadingTrivia(null)) .WithLeadingTrivia(rewrittenNode.GetLeadingTrivia()))); } displayParts = replaceNode ? symbol.ToDisplayParts(TypeNameFormatWithGenerics) : ((ISymbol)symbol.ContainingType ?? (ISymbol)symbol.ContainingNamespace).ToDisplayParts(TypeNameFormatWithGenerics); rewrittenNode = TryAddTypeArgumentToIdentifierName(rewrittenNode, symbol); // Replaces the '<' token with the '{' token since we are inside crefs rewrittenNode = TryReplaceAngleBracesWithCurlyBraces(rewrittenNode, isInsideCref); result = rewrittenNode; if (!omitLeftHandSide) { left = SyntaxFactory.ParseTypeName(displayParts.ToDisplayString()); // Replaces the '<' token with the '{' token since we are inside crefs left = TryReplaceAngleBracesWithCurlyBraces(left, isInsideCref); if (replaceNode) { return(left .WithLeadingTrivia(rewrittenNode.GetLeadingTrivia()) .WithTrailingTrivia(rewrittenNode.GetTrailingTrivia())); } // now create syntax for the combination of left and right syntax, or a simple replacement in case of an identifier var parent = originalNode.Parent; var leadingTrivia = rewrittenNode.GetLeadingTrivia(); rewrittenNode = rewrittenNode.WithLeadingTrivia(null); switch (parent.CSharpKind()) { case SyntaxKind.QualifiedName: var qualifiedParent = (QualifiedNameSyntax)parent; result = rewrittenNode.CopyAnnotationsTo( SyntaxFactory.QualifiedName( (NameSyntax)left, (SimpleNameSyntax)rewrittenNode)); break; case SyntaxKind.SimpleMemberAccessExpression: var memberAccessParent = (MemberAccessExpressionSyntax)parent; result = rewrittenNode.CopyAnnotationsTo( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, left, (SimpleNameSyntax)rewrittenNode)); break; default: Debug.Assert(rewrittenNode is SimpleNameSyntax); if (SyntaxFacts.IsInNamespaceOrTypeContext(originalNode)) { var right = (SimpleNameSyntax)rewrittenNode; result = rewrittenNode.CopyAnnotationsTo(SyntaxFactory.QualifiedName((NameSyntax)left, right.WithAdditionalAnnotations(Simplifier.SpecialTypeAnnotation))); } else if (originalNode.Parent is CrefSyntax) { var right = (SimpleNameSyntax)rewrittenNode; result = rewrittenNode.CopyAnnotationsTo(SyntaxFactory.QualifiedName((NameSyntax)left, right)); } else { result = rewrittenNode.CopyAnnotationsTo( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, left, (SimpleNameSyntax)rewrittenNode)); } break; } result = result.WithLeadingTrivia(leadingTrivia); } } return(result); }
private ExpressionSyntax VisitSimpleName(SimpleNameSyntax rewrittenSimpleName, SimpleNameSyntax originalSimpleName) { cancellationToken.ThrowIfCancellationRequested(); // if this is "var", then do not process further if (originalSimpleName.IsVar) { return(rewrittenSimpleName); } var identifier = rewrittenSimpleName.Identifier; ExpressionSyntax newNode = rewrittenSimpleName; var isInsideCref = originalSimpleName.AncestorsAndSelf(ascendOutOfTrivia: true).Any(n => n is CrefSyntax); //// //// 1. if this identifier is an alias, we'll expand it here and replace the node completely. //// if (!SyntaxFacts.IsAliasQualifier(originalSimpleName)) { var aliasInfo = semanticModel.GetAliasInfo(originalSimpleName, cancellationToken); if (aliasInfo != null) { var aliasTarget = aliasInfo.Target; if (aliasTarget.IsNamespace() && ((INamespaceSymbol)aliasTarget).IsGlobalNamespace) { return(rewrittenSimpleName); } // if the enclosing expression is a typeof expression that already contains open type we cannot // we need to insert an open type as well. var typeOfExpression = originalSimpleName.GetAncestor <TypeOfExpressionSyntax>(); if (typeOfExpression != null && IsTypeOfUnboundGenericType(semanticModel, typeOfExpression)) { aliasTarget = ((INamedTypeSymbol)aliasTarget).ConstructUnboundGenericType(); } // the expanded form replaces the current identifier name. var replacement = FullyQualifyIdentifierName( aliasTarget, newNode, originalSimpleName, replaceNode: true, isInsideCref: isInsideCref, omitLeftHandSide: false) .WithAdditionalAnnotations(Simplifier.Annotation); // We replace the simple name completely, so we can't continue and rename the token // with a RenameLocationAnnotation. // There's also no way of removing annotations, so we just add a DoNotRenameAnnotation. if (replacement.CSharpKind() == SyntaxKind.AliasQualifiedName) { var qualifiedReplacement = (AliasQualifiedNameSyntax)replacement; var newIdentifier = identifier.CopyAnnotationsTo(qualifiedReplacement.Name.Identifier); if (this.annotationForReplacedAliasIdentifier != null) { newIdentifier = newIdentifier.WithAdditionalAnnotations(annotationForReplacedAliasIdentifier); } var aliasAnnotationInfo = AliasAnnotation.Create(aliasInfo.Name); newIdentifier = newIdentifier.WithAdditionalAnnotations(aliasAnnotationInfo); replacement = replacement.ReplaceNode( qualifiedReplacement.Name, qualifiedReplacement.Name.WithIdentifier(newIdentifier)); replacement = newNode.CopyAnnotationsTo(replacement); var firstReplacementToken = replacement.GetFirstToken(true, false, true, true); var firstOriginalToken = originalSimpleName.GetFirstToken(true, false, true, true); SyntaxToken tokenWithLeadingWhitespace; if (TryAddLeadingElasticTriviaIfNecessary(firstReplacementToken, firstOriginalToken, out tokenWithLeadingWhitespace)) { replacement = replacement.ReplaceToken(firstOriginalToken, tokenWithLeadingWhitespace); } replacement = AppendElasticTriviaIfNecessary(replacement, originalSimpleName); return(replacement); } if (replacement.CSharpKind() == SyntaxKind.QualifiedName) { var qualifiedReplacement = (QualifiedNameSyntax)replacement; var newIdentifier = identifier.CopyAnnotationsTo(qualifiedReplacement.Right.Identifier); if (this.annotationForReplacedAliasIdentifier != null) { newIdentifier = newIdentifier.WithAdditionalAnnotations(annotationForReplacedAliasIdentifier); } var aliasAnnotationInfo = AliasAnnotation.Create(aliasInfo.Name); newIdentifier = newIdentifier.WithAdditionalAnnotations(aliasAnnotationInfo); replacement = replacement.ReplaceNode( qualifiedReplacement.Right, qualifiedReplacement.Right.WithIdentifier(newIdentifier)); replacement = newNode.CopyAnnotationsTo(replacement); replacement = AppendElasticTriviaIfNecessary(replacement, originalSimpleName); return(replacement); } throw new NotImplementedException(); } } var symbol = semanticModel.GetSymbolInfo(originalSimpleName.Identifier).Symbol; if (symbol == null) { return(newNode); } var typeArgumentSymbols = TypeArgumentSymbolsPresentInName(originalSimpleName); var omitLeftSideOfExpression = false; // Check to see if the type Arguments in the resultant Symbol is recursively defined. if (IsTypeArgumentDefinedRecursive(symbol, typeArgumentSymbols, enterContainingSymbol: true)) { if (symbol.ContainingSymbol.Equals(symbol.OriginalDefinition.ContainingSymbol) && symbol.Kind == SymbolKind.Method && ((IMethodSymbol)symbol).IsStatic) { if (IsTypeArgumentDefinedRecursive(symbol, typeArgumentSymbols, enterContainingSymbol: false)) { return(newNode); } else { omitLeftSideOfExpression = true; } } else { return(newNode); } } if (IsInvocationWithDynamicArguments(originalSimpleName, semanticModel)) { return(newNode); } //// //// 2. If it's an attribute, make sure the identifier matches the attribute's class name. //// if (originalSimpleName.GetAncestor <AttributeSyntax>() != null) { if (symbol.IsConstructor() && symbol.ContainingType.IsAttribute()) { symbol = symbol.ContainingType; var name = symbol.Name; Debug.Assert(name.StartsWith(originalSimpleName.Identifier.ValueText)); // if the user already used the Attribute suffix in the attribute, we'll maintain it. if (identifier.ValueText == name && name.EndsWith("Attribute")) { identifier = identifier.WithAdditionalAnnotations(SimplificationHelpers.DontSimplifyAnnotation); } identifier = identifier.CopyAnnotationsTo(SyntaxFactory.VerbatimIdentifier(identifier.LeadingTrivia, name, name, identifier.TrailingTrivia)); } } //// //// 3. Always try to escape keyword identifiers //// identifier = TryEscapeIdentifierToken(identifier, originalSimpleName, semanticModel).WithAdditionalAnnotations(Simplifier.Annotation); if (identifier != rewrittenSimpleName.Identifier) { switch (newNode.CSharpKind()) { case SyntaxKind.IdentifierName: case SyntaxKind.GenericName: newNode = ((SimpleNameSyntax)newNode).WithIdentifier(identifier); break; default: throw new NotImplementedException(); } } var parent = originalSimpleName.Parent; // do not complexify further for location where only simple names are allowed if (parent is MemberDeclarationSyntax || originalSimpleName.GetAncestor <NameEqualsSyntax>() != null || (parent is MemberAccessExpressionSyntax && parent.CSharpKind() != SyntaxKind.SimpleMemberAccessExpression) || ((parent.CSharpKind() == SyntaxKind.SimpleMemberAccessExpression || parent.CSharpKind() == SyntaxKind.NameMemberCref) && originalSimpleName.IsRightSideOfDot()) || (parent.CSharpKind() == SyntaxKind.QualifiedName && originalSimpleName.IsRightSideOfQualifiedName()) || (parent.CSharpKind() == SyntaxKind.AliasQualifiedName)) { return(TryAddTypeArgumentToIdentifierName(newNode, symbol)); } //// //// 4. If this is a standalone identifier or the left side of a qualified name or member access try to fully qualify it //// // we need to treat the constructor as type name, so just get the containing type. if (symbol.IsConstructor() && (parent.CSharpKind() == SyntaxKind.ObjectCreationExpression || parent.CSharpKind() == SyntaxKind.NameMemberCref)) { symbol = symbol.ContainingType; } // if it's a namespace or type name, fully qualify it. if (symbol.Kind == SymbolKind.NamedType || symbol.Kind == SymbolKind.Namespace) { var replacement = FullyQualifyIdentifierName( (INamespaceOrTypeSymbol)symbol, newNode, originalSimpleName, replaceNode: false, isInsideCref: isInsideCref, omitLeftHandSide: omitLeftSideOfExpression) .WithAdditionalAnnotations(Simplifier.Annotation); replacement = AppendElasticTriviaIfNecessary(replacement, originalSimpleName); return(replacement); } // if it's a member access, we're fully qualifying the left side and make it a member access. if (symbol.Kind == SymbolKind.Method || symbol.Kind == SymbolKind.Field || symbol.Kind == SymbolKind.Property) { if (symbol.IsStatic || originalSimpleName.IsParentKind(SyntaxKind.NameMemberCref)) { newNode = FullyQualifyIdentifierName( symbol, newNode, originalSimpleName, replaceNode: false, isInsideCref: isInsideCref, omitLeftHandSide: omitLeftSideOfExpression); } else { if (!IsPropertyNameOfObjectInitializer(originalSimpleName)) { ExpressionSyntax left; // Assumption here is, if the enclosing and containing types are different then there is Inheritence relationship if (semanticModel.GetEnclosingNamedType(originalSimpleName.SpanStart, cancellationToken) != symbol.ContainingType) { left = SyntaxFactory.BaseExpression(); } else { left = SyntaxFactory.ThisExpression(); } var identifiersLeadingTrivia = newNode.GetLeadingTrivia(); newNode = TryAddTypeArgumentToIdentifierName(newNode, symbol); newNode = SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, left, (SimpleNameSyntax)newNode.WithLeadingTrivia(null)) .WithLeadingTrivia(identifiersLeadingTrivia); } } } var result = newNode.WithAdditionalAnnotations(Simplifier.Annotation); result = AppendElasticTriviaIfNecessary(result, originalSimpleName); return(result); }
public void FlattenCondition(ExpressionSyntax expr, string prefix, bool ss_jump_if_value, string ss_jump_label, List<FlatStatement> instructions) { if (expr is LiteralExpressionSyntax) { switch (expr.CSharpKind()) { case SyntaxKind.TrueLiteralExpression: if (ss_jump_if_value) instructions.Add(FlatStatement.JMP(FlatOperand.LabelRef(ss_jump_label))); return; case SyntaxKind.FalseLiteralExpression: if (!ss_jump_if_value) instructions.Add(FlatStatement.JMP(FlatOperand.LabelRef(ss_jump_label))); return; } throw new NotImplementedException("literal expression " + expr.CSharpKind().ToString()); } if (expr is BinaryExpressionSyntax) { BinaryExpressionSyntax condition = expr as BinaryExpressionSyntax; switch (condition.CSharpKind()) { case SyntaxKind.LogicalAndExpression: { FlattenCondition(condition.Left, prefix, ss_jump_if_value, ss_jump_label, instructions); // fell through because left side didnt match. check right side FlattenCondition(condition.Right, prefix, ss_jump_if_value, ss_jump_label, instructions); // fell through because right side didnt match either. return; } break; case SyntaxKind.LogicalOrExpression: { string ifEnterLabel = prefix + MakeUniqueLabelPrefix("shortcircuit"); FlattenCondition(condition.Left, prefix, !ss_jump_if_value, ifEnterLabel, instructions); // short circuit if left side matches // fell through because left side didn't match. check right side FlattenCondition(condition.Right, prefix, ss_jump_if_value, ss_jump_label, instructions); instructions.Add(FlatStatement.LABEL(FlatOperand.LabelRef(ifEnterLabel))); return; } break; case SyntaxKind.IsExpression: { FlatOperand fop_result = ResolveExpression(expr, null, instructions); if (ss_jump_if_value) instructions.Add(FlatStatement.JNZ(FlatOperand.LabelRef(ss_jump_label), fop_result)); else instructions.Add(FlatStatement.JZ(FlatOperand.LabelRef(ss_jump_label), fop_result)); } return; } FlatOperand opnd_left = ResolveExpression(condition.Left, null, instructions); FlatOperand opnd_right = ResolveExpression(condition.Right, null, instructions); switch (condition.CSharpKind()) { case SyntaxKind.GreaterThanOrEqualExpression: if (ss_jump_if_value) instructions.Add(FlatStatement.JGE(FlatOperand.LabelRef(ss_jump_label), opnd_left, opnd_right)); else instructions.Add(FlatStatement.JL(FlatOperand.LabelRef(ss_jump_label), opnd_left, opnd_right)); return; case SyntaxKind.GreaterThanExpression: if (ss_jump_if_value) instructions.Add(FlatStatement.JG(FlatOperand.LabelRef(ss_jump_label), opnd_left, opnd_right)); else instructions.Add(FlatStatement.JLE(FlatOperand.LabelRef(ss_jump_label), opnd_left, opnd_right)); return; case SyntaxKind.LessThanExpression: if (ss_jump_if_value) instructions.Add(FlatStatement.JL(FlatOperand.LabelRef(ss_jump_label), opnd_left, opnd_right)); else instructions.Add(FlatStatement.JGE(FlatOperand.LabelRef(ss_jump_label), opnd_left, opnd_right)); return; case SyntaxKind.LessThanOrEqualExpression: if (ss_jump_if_value) instructions.Add(FlatStatement.JLE(FlatOperand.LabelRef(ss_jump_label), opnd_left, opnd_right)); else instructions.Add(FlatStatement.JG(FlatOperand.LabelRef(ss_jump_label), opnd_left, opnd_right)); return; case SyntaxKind.NotEqualsExpression: if (ss_jump_if_value) instructions.Add(FlatStatement.JNE(FlatOperand.LabelRef(ss_jump_label), opnd_left, opnd_right)); else instructions.Add(FlatStatement.JE(FlatOperand.LabelRef(ss_jump_label), opnd_left, opnd_right)); return; case SyntaxKind.EqualsExpression: if (ss_jump_if_value) instructions.Add(FlatStatement.JE(FlatOperand.LabelRef(ss_jump_label), opnd_left, opnd_right)); else instructions.Add(FlatStatement.JNE(FlatOperand.LabelRef(ss_jump_label), opnd_left, opnd_right)); return; default: throw new NotImplementedException("binary expression " + condition.CSharpKind()); } throw new NotImplementedException(); } TypeInfo ti = Model.GetTypeInfo(expr); if (ti.ConvertedType.SpecialType == SpecialType.System_Boolean) { FlatOperand fop_result = ResolveExpression(expr, null, instructions); if (ss_jump_if_value) instructions.Add(FlatStatement.JNZ(FlatOperand.LabelRef(ss_jump_label), fop_result)); else instructions.Add(FlatStatement.JZ(FlatOperand.LabelRef(ss_jump_label), fop_result)); return; } throw new NotImplementedException(); }
private ExpressionSyntax FullyQualifyIdentifierName( ISymbol symbol, ExpressionSyntax rewrittenNode, ExpressionSyntax originalNode, bool replaceNode, bool isInsideCref, bool omitLeftHandSide) { Debug.Assert(!replaceNode || rewrittenNode.CSharpKind() == SyntaxKind.IdentifierName); //// TODO: use and expand Generate*Syntax(isymbol) to not depend on symbol display any more. //// See GenerateExpressionSyntax(); var result = rewrittenNode; // only if this symbol has a containing type or namespace there is work for us to do. if (replaceNode || symbol.ContainingType != null || symbol.ContainingNamespace != null) { ImmutableArray<SymbolDisplayPart> displayParts; ExpressionSyntax left = null; // we either need to create an AliasQualifiedName if the symbol is directly contained in the global namespace, // otherwise it a QualifiedName. if (!replaceNode && symbol.ContainingType == null && symbol.ContainingNamespace.IsGlobalNamespace) { return rewrittenNode.CopyAnnotationsTo( SyntaxFactory.AliasQualifiedName( SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)), (SimpleNameSyntax)rewrittenNode.WithLeadingTrivia(null)) .WithLeadingTrivia(rewrittenNode.GetLeadingTrivia())); } displayParts = replaceNode ? symbol.ToDisplayParts(TypeNameFormatWithGenerics) : ((ISymbol)symbol.ContainingType ?? (ISymbol)symbol.ContainingNamespace).ToDisplayParts(TypeNameFormatWithGenerics); rewrittenNode = TryAddTypeArgumentToIdentifierName(rewrittenNode, symbol); // Replaces the '<' token with the '{' token since we are inside crefs rewrittenNode = TryReplaceAngleBracesWithCurlyBraces(rewrittenNode, isInsideCref); result = rewrittenNode; if (!omitLeftHandSide) { left = SyntaxFactory.ParseTypeName(displayParts.ToDisplayString()); // Replaces the '<' token with the '{' token since we are inside crefs left = TryReplaceAngleBracesWithCurlyBraces(left, isInsideCref); if (replaceNode) { return left .WithLeadingTrivia(rewrittenNode.GetLeadingTrivia()) .WithTrailingTrivia(rewrittenNode.GetTrailingTrivia()); } // now create syntax for the combination of left and right syntax, or a simple replacement in case of an identifier var parent = originalNode.Parent; var leadingTrivia = rewrittenNode.GetLeadingTrivia(); rewrittenNode = rewrittenNode.WithLeadingTrivia(null); switch (parent.CSharpKind()) { case SyntaxKind.QualifiedName: var qualifiedParent = (QualifiedNameSyntax)parent; result = rewrittenNode.CopyAnnotationsTo( SyntaxFactory.QualifiedName( (NameSyntax)left, (SimpleNameSyntax)rewrittenNode)); break; case SyntaxKind.SimpleMemberAccessExpression: var memberAccessParent = (MemberAccessExpressionSyntax)parent; result = rewrittenNode.CopyAnnotationsTo( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, left, (SimpleNameSyntax)rewrittenNode)); break; default: Debug.Assert(rewrittenNode is SimpleNameSyntax); if (SyntaxFacts.IsInNamespaceOrTypeContext(originalNode)) { var right = (SimpleNameSyntax)rewrittenNode; result = rewrittenNode.CopyAnnotationsTo(SyntaxFactory.QualifiedName((NameSyntax)left, right.WithAdditionalAnnotations(Simplifier.SpecialTypeAnnotation))); } else if (originalNode.Parent is CrefSyntax) { var right = (SimpleNameSyntax)rewrittenNode; result = rewrittenNode.CopyAnnotationsTo(SyntaxFactory.QualifiedName((NameSyntax)left, right)); } else { result = rewrittenNode.CopyAnnotationsTo( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, left, (SimpleNameSyntax)rewrittenNode)); } break; } result = result.WithLeadingTrivia(leadingTrivia); } } return result; }
private ExpressionSyntax TryAddTypeArgumentToIdentifierName(ExpressionSyntax newNode, ISymbol symbol) { if (newNode.CSharpKind() == SyntaxKind.IdentifierName && symbol.Kind == SymbolKind.Method) { if (((IMethodSymbol)symbol).TypeArguments.Length != 0) { var typeArguments = ((IMethodSymbol)symbol).TypeArguments; var genericName = SyntaxFactory.GenericName( ((IdentifierNameSyntax)newNode).Identifier, SyntaxFactory.TypeArgumentList( SyntaxFactory.SeparatedList( typeArguments.Select(p => SyntaxFactory.ParseTypeName(p.ToDisplayParts(TypeNameFormatWithGenerics).ToDisplayString()))))) .WithLeadingTrivia(newNode.GetLeadingTrivia()) .WithTrailingTrivia(newNode.GetTrailingTrivia()) .WithAdditionalAnnotations(Simplifier.Annotation); genericName = newNode.CopyAnnotationsTo(genericName); return genericName; } } return newNode; }