private void AddTypeParameters(TypeSyntax typeSyntax, MultiDictionary <string, TypeParameterSymbol> map) { switch (typeSyntax.Kind()) { case SyntaxKind.AliasQualifiedName: AddTypeParameters(((AliasQualifiedNameSyntax)typeSyntax).Name, map); break; case SyntaxKind.QualifiedName: // NOTE: Dev11 does not warn about duplication, it just matches parameter types to the // *last* type parameter with the same name. That's why we're iterating backwards. QualifiedNameSyntax qualifiedNameSyntax = (QualifiedNameSyntax)typeSyntax; AddTypeParameters(qualifiedNameSyntax.Right, map); AddTypeParameters(qualifiedNameSyntax.Left, map); break; case SyntaxKind.GenericName: AddTypeParameters((GenericNameSyntax)typeSyntax, map); break; case SyntaxKind.IdentifierName: case SyntaxKind.PredefinedType: break; default: throw ExceptionUtilities.UnexpectedValue(typeSyntax.Kind()); } }
private bool CompareTypes(TypeSyntax oldType, TypeSyntax newType) { // Type nodes can be NULL for ctor/dtor/operators ... if (oldType == null || newType == null) { return(oldType == newType); } if (oldType.Kind() != newType.Kind()) { return(false); } switch (oldType.Kind()) { case SyntaxKind.PredefinedType: var oldPredefinedType = (PredefinedTypeSyntax)oldType; var newPredefinedType = (PredefinedTypeSyntax)newType; return(oldPredefinedType.Keyword.RawKind == newPredefinedType.Keyword.RawKind); case SyntaxKind.ArrayType: var oldArrayType = (ArrayTypeSyntax)oldType; var newArrayType = (ArrayTypeSyntax)newType; return(oldArrayType.RankSpecifiers.Count == newArrayType.RankSpecifiers.Count && CompareTypes(oldArrayType.ElementType, newArrayType.ElementType)); case SyntaxKind.PointerType: var oldPointerType = (PointerTypeSyntax)oldType; var newPointerType = (PointerTypeSyntax)newType; return(CompareTypes(oldPointerType.ElementType, newPointerType.ElementType)); case SyntaxKind.NullableType: var oldNullableType = (NullableTypeSyntax)oldType; var newNullableType = (NullableTypeSyntax)newType; return(CompareTypes( oldNullableType.ElementType, newNullableType.ElementType )); case SyntaxKind.IdentifierName: case SyntaxKind.QualifiedName: case SyntaxKind.AliasQualifiedName: case SyntaxKind.GenericName: var oldName = (NameSyntax)oldType; var newName = (NameSyntax)newType; return(CompareNames(oldName, newName)); } Debug.Fail("Unknown kind: " + oldType.Kind()); return(false); }
private TypeNode ParseType(TypeSyntax type) { TypeNode kType; switch (type.Kind()) { case SyntaxKind.PredefinedType: kType = ParsePredefinedType(type as PredefinedTypeSyntax); break; default: throw new KeyNotFoundException($"couldn't find member with name '{type.Kind()}'"); } return(kType); }
public static SourceLocalSymbol MakeDeconstructionLocal( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax closestTypeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind, SyntaxNode deconstruction ) { Debug.Assert(closestTypeSyntax != null); Debug.Assert(nodeBinder != null); Debug.Assert(closestTypeSyntax.Kind() != SyntaxKind.RefType); return(closestTypeSyntax.IsVar ? new DeconstructionLocalSymbol( containingSymbol, scopeBinder, nodeBinder, closestTypeSyntax, identifierToken, kind, deconstruction ) : new SourceLocalSymbol( containingSymbol, scopeBinder, false, closestTypeSyntax, identifierToken, kind )); }
private static TypeSyntax NarrowIntegerType(TypeSyntax type) { if ((type.Kind() == SyntaxKind.PredefinedType) && (((PredefinedTypeSyntax)type).Keyword.Kind() == SyntaxKind.ULongKeyword)) { type = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.UIntKeyword)).WithTrailingTrivia(SyntaxFactory.Space); } else if ((type.Kind() == SyntaxKind.PredefinedType) && (((PredefinedTypeSyntax)type).Keyword.Kind() == SyntaxKind.LongKeyword)) { type = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)).WithTrailingTrivia(SyntaxFactory.Space); } else { throw new ArgumentException(); } return type; }
void Populate() { switch (Syntax.Kind()) { case SyntaxKind.ArrayType: var ats = (ArrayTypeSyntax)Syntax; var at = (ArrayType)Type; Emit(Loc ?? Syntax.GetLocation(), Parent, Type); Create(cx, ats.ElementType, this, at.ElementType); return; case SyntaxKind.NullableType: var nts = (NullableTypeSyntax)Syntax; var nt = (NamedType)Type; Emit(Loc ?? Syntax.GetLocation(), Parent, Type); Create(cx, nts.ElementType, this, nt.TypeArguments[0]); return; case SyntaxKind.TupleType: var tts = (TupleTypeSyntax)Syntax; var tt = (TupleType)Type; Emit(Loc ?? Syntax.GetLocation(), Parent, Type); tts.Elements.Zip(tt.TupleElements, (s, t) => Create(cx, s.Type, this, t.Type)).Enumerate(); return; case SyntaxKind.PointerType: var pts = (PointerTypeSyntax)Syntax; var pt = (PointerType)Type; Emit(Loc ?? Syntax.GetLocation(), Parent, Type); Create(cx, pts.ElementType, this, pt.PointedAtType); return; case SyntaxKind.GenericName: var gns = (GenericNameSyntax)Syntax; Emit(Loc ?? gns.Identifier.GetLocation(), Parent, Type); cx.PopulateLater(() => gns.TypeArgumentList.Arguments.Zip(Type.TypeMentions, (s, t) => Create(cx, s, this, t)).Enumerate()); return; case SyntaxKind.QualifiedName: if (Type.ContainingType == null) { // namespace qualifier Emit(Loc ?? Syntax.GetLocation(), Parent, Type); } else { // Type qualifier var qns = (QualifiedNameSyntax)Syntax; var right = Create(cx, qns.Right, Parent, Type); Create(cx, qns.Left, right, Type.ContainingType); } return; default: Emit(Loc ?? Syntax.GetLocation(), Parent, Type); return; } }
internal static TypeSyntax SkipRef(this TypeSyntax syntax) { if (syntax.Kind() == SyntaxKind.RefType) { syntax = ((RefTypeSyntax)syntax).Type; } return(syntax); }
internal static TypeSyntax SkipRef(this TypeSyntax syntax, out RefKind refKind) { refKind = RefKind.None; if (syntax.Kind() == SyntaxKind.RefType) { refKind = RefKind.Ref; syntax = ((RefTypeSyntax)syntax).Type; } return(syntax); }
protected void FilterType(TypeSyntax syntax) { if (syntax.Kind() == SyntaxKind.PredefinedType) { return; } SymbolInfo symbolInfo = this.SemanticModel.GetSymbolInfo(syntax, new CancellationToken()); if (symbolInfo.Symbol != null && symbolInfo.Symbol.Kind == SymbolKind.NamedType) { this.FilterTypeSymbol((ITypeSymbol)symbolInfo.Symbol); } }
private string ResolvePredefinedAndArrayTypes(TypeSyntax type) { switch (type.Kind()) { case SyntaxKind.PredefinedType: return(Context.TypeResolver.ResolvePredefinedType(Context.GetTypeInfo(type).Type.Name)); case SyntaxKind.ArrayType: return(ResolveType(type.DescendantNodes().OfType <TypeSyntax>().Single()) + ".MakeArrayType()"); case SyntaxKind.PointerType: return(ResolveType(type.DescendantNodes().OfType <TypeSyntax>().Single()) + ".MakePointerType()"); } return(null); }
private static TypeSyntax GetReplacementName(TypeSyntax symbolNameSyntax, TypeSyntax nameSyntax) { switch (nameSyntax.Kind()) { case SyntaxKind.GenericName: return(GetReplacementGenericName(symbolNameSyntax, (GenericNameSyntax)nameSyntax)); case SyntaxKind.QualifiedName: return(GetReplacementQualifiedName((QualifiedNameSyntax)symbolNameSyntax, (QualifiedNameSyntax)nameSyntax)); default: return(symbolNameSyntax); } }
internal static TypeSyntax SkipRef(this TypeSyntax syntax, out RefKind refKind) { if (syntax.Kind() == SyntaxKind.RefType) { var refType = (RefTypeSyntax)syntax; refKind = refType.ReadOnlyKeyword.Kind() == SyntaxKind.ReadOnlyKeyword ? RefKind.RefReadOnly : RefKind.Ref; return(refType.Type); } refKind = RefKind.None; return(syntax); }
private static void CheckType(SyntaxNodeAnalysisContext context, TypeSyntax typeSyntax, Location reportLocation = null) { switch (typeSyntax.Kind()) { case SyntaxKindEx.TupleType: CheckTupleType(context, (TupleTypeSyntaxWrapper)typeSyntax, reportLocation); break; case SyntaxKind.QualifiedName: CheckType(context, ((QualifiedNameSyntax)typeSyntax).Right, reportLocation ?? typeSyntax.GetLocation()); break; case SyntaxKind.GenericName: CheckGenericName(context, (GenericNameSyntax)typeSyntax, reportLocation); break; } }
private static void AppendTypeName(StringBuilder builder, TypeSyntax type) { if (type is NameSyntax name) { AppendName(builder, name); } else { switch (type.Kind()) { case SyntaxKind.PredefinedType: builder.Append(((PredefinedTypeSyntax)type).Keyword.ValueText); break; case SyntaxKind.ArrayType: var arrayType = (ArrayTypeSyntax)type; AppendTypeName(builder, arrayType.ElementType); var specifiers = arrayType.RankSpecifiers; for (int i = 0; i < specifiers.Count; i++) { builder.Append('['); var specifier = specifiers[i]; if (specifier.Rank > 1) { builder.Append(',', specifier.Rank - 1); } builder.Append(']'); } break; case SyntaxKind.PointerType: AppendTypeName(builder, ((PointerTypeSyntax)type).ElementType); builder.Append('*'); break; case SyntaxKind.NullableType: AppendTypeName(builder, ((NullableTypeSyntax)type).ElementType); builder.Append('?'); break; } } }
private static void CheckType(SyntaxNodeAnalysisContext context, TypeSyntax typeSyntax) { switch (typeSyntax.Kind()) { case SyntaxKindEx.TupleType: CheckTupleType(context, (TupleTypeSyntaxWrapper)typeSyntax); break; case SyntaxKind.QualifiedName: CheckType(context, ((QualifiedNameSyntax)typeSyntax).Right); break; case SyntaxKind.GenericName: CheckGenericName(context, (GenericNameSyntax)typeSyntax); break; } }
public static SourceLocalSymbol MakeDeconstructionLocal( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax closestTypeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind, SyntaxNode deconstruction) { Debug.Assert(closestTypeSyntax != null); Debug.Assert(nodeBinder != null); Debug.Assert(closestTypeSyntax.Kind() != SyntaxKind.RefType); // https://github.com/dotnet/roslyn/issues/62039: Allow 'scoped' modifier. return(closestTypeSyntax.IsVar ? new DeconstructionLocalSymbol(containingSymbol, scopeBinder, nodeBinder, closestTypeSyntax, identifierToken, kind, deconstruction) : new SourceLocalSymbol(containingSymbol, scopeBinder, false, closestTypeSyntax, identifierToken, kind, hasScopedModifier: false)); }
// // Primary wideners // private static TypeSyntax WidenType(TypeSyntax type) { switch (type.Kind()) { default: throw new ArgumentException(); case SyntaxKind.PredefinedType: if (((PredefinedTypeSyntax)type).Keyword.Kind() == SyntaxKind.IntKeyword) { type = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.LongKeyword)).WithTrailingTrivia(SyntaxFactory.Space); } else if (((PredefinedTypeSyntax)type).Keyword.Kind() == SyntaxKind.UIntKeyword) { type = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ULongKeyword)).WithTrailingTrivia(SyntaxFactory.Space); } else { throw new ArgumentException(); } break; case SyntaxKind.GenericName: GenericNameSyntax genericType = (GenericNameSyntax)type; type = genericType.WithIdentifier( SyntaxFactory.Identifier(genericType.Identifier.Text + LongAppendText) .WithTriviaFrom(genericType.Identifier)); break; case SyntaxKind.IdentifierName: IdentifierNameSyntax identifierType = (IdentifierNameSyntax)type; type = identifierType.WithIdentifier( SyntaxFactory.Identifier(identifierType.Identifier.Text + LongAppendText) .WithTriviaFrom(identifierType.Identifier)); break; case SyntaxKind.ArrayType: ArrayTypeSyntax arrayType = (ArrayTypeSyntax)type; type = arrayType.WithElementType(WidenType(arrayType.ElementType)); break; } return(type); }
private static bool IsNotNullableReplacable(this NameSyntax name, TypeSyntax reducedName) { var isNotNullableReplacable = false; // var isLeftSideOfDot = name.IsLeftSideOfDot(); // var isRightSideOfDot = name.IsRightSideOfDot(); if (reducedName.Kind() == SyntaxKind.NullableType) { if (((NullableTypeSyntax)reducedName).ElementType.Kind() == SyntaxKind.OmittedTypeArgument) { isNotNullableReplacable = true; } else { isNotNullableReplacable = name.IsLeftSideOfDot() || name.IsRightSideOfDot(); } } return(isNotNullableReplacable); }
internal static RefKind GetRefKind(this TypeSyntax syntax) { var refKind = RefKind.None; if (syntax != null && syntax.Kind() == SyntaxKind.RefType) { var refType = (RefTypeSyntax)syntax; switch (refType.RefKindKeyword.Kind()) { case SyntaxKind.RefKeyword: refKind = RefKind.Ref; break; case SyntaxKind.InKeyword: refKind = RefKind.In; break; case SyntaxKind.OutKeyword: refKind = RefKind.Out; break; default: throw ExceptionUtilities.UnexpectedValue(refType.RefKindKeyword); } if (refType.LetKeyword.Kind() == SyntaxKind.LetKeyword) { if (refKind == RefKind.Ref) { refKind = RefKind.RefReadOnly; // LetRef } else { // error } } } return(refKind); }
/// <summary> /// Return true if the method is async, and a resultType if the asyn method expect a result /// </summary> /// <param name="method"></param> /// <param name="resultType"></param> /// <returns></returns> private static bool IsAsyncMethod(TypeSyntax method, out string[] resultType) { bool isAsync = false; resultType = null; if (method is QualifiedNameSyntax) { return(IsAsyncMethod(((QualifiedNameSyntax)method).Right, out resultType)); } if (method is IdentifierNameSyntax) { string typeIdentifier = ((IdentifierNameSyntax)method).Identifier.ToString(); //If returning Task if (typeIdentifier.Equals("Task", StringComparison.OrdinalIgnoreCase)) { isAsync = true; } } else if (method is GenericNameSyntax) { //If returning Task<> if (method.Kind() == SyntaxKind.GenericName) { string typeIdentifier = ((GenericNameSyntax)method).Identifier.ToString(); //If returning Task if (typeIdentifier.Equals("Task", StringComparison.OrdinalIgnoreCase)) { isAsync = true; resultType = ((GenericNameSyntax)method).TypeArgumentList.Arguments.Select(p => p.ToString()).ToArray(); } } } return(isAsync); }
protected EqualsValueClauseSyntax GetDefault(GraphQLValue defaultValue, TypeSyntax type) { switch (defaultValue?.Kind) { case ASTNodeKind.IntValue: return(SyntaxFactory.EqualsValueClause( SyntaxFactory.LiteralExpression( SyntaxKind.NumericLiteralExpression, SyntaxFactory.ParseToken(((GraphQLScalarValue)defaultValue).Value)))); case ASTNodeKind.FloatValue: return(SyntaxFactory.EqualsValueClause( SyntaxFactory.LiteralExpression( SyntaxKind.NumericLiteralExpression, SyntaxFactory.ParseToken($"{((GraphQLScalarValue)defaultValue).Value}f")))); case ASTNodeKind.StringValue: return(SyntaxFactory.EqualsValueClause( SyntaxFactory.LiteralExpression( SyntaxKind.StringLiteralExpression, SyntaxFactory.ParseToken($"\"{((GraphQLScalarValue)defaultValue).Value}\""))));; case ASTNodeKind.BooleanValue: return(((GraphQLScalarValue)defaultValue).Value.ToLower() == "true" ? SyntaxFactory.EqualsValueClause(SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression)) : SyntaxFactory.EqualsValueClause(SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression))); case ASTNodeKind.EnumValue: return(SyntaxFactory.EqualsValueClause(SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, type.Kind() == SyntaxKind.NullableType ? ((NullableTypeSyntax)type).ElementType : type, SyntaxFactory.IdentifierName(((GraphQLScalarValue)defaultValue).Value)))); } ; return(SyntaxFactory.EqualsValueClause(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression))); }
private static TypeSyntax UnwrapType(TypeSyntax type) { while (true) { switch (type.Kind()) { case SyntaxKind.ArrayType: type = ((ArrayTypeSyntax)type).ElementType; break; case SyntaxKind.PointerType: type = ((PointerTypeSyntax)type).ElementType; break; case SyntaxKind.NullableType: type = ((NullableTypeSyntax)type).ElementType; break; default: return(type); } } }
protected override void VisitType(TypeSyntax node) { switch (node.Kind()) { case SyntaxKind.ArrayType: { VisitArrayType((ArrayTypeSyntax)node); break; } case SyntaxKind.AliasQualifiedName: case SyntaxKind.GenericName: case SyntaxKind.IdentifierName: case SyntaxKind.NullableType: case SyntaxKind.OmittedTypeArgument: case SyntaxKind.PointerType: case SyntaxKind.PredefinedType: case SyntaxKind.QualifiedName: case SyntaxKind.RefType: case SyntaxKind.TupleType: { if (IsAnyTypeParameter) { base.VisitType(node); } break; } default: { base.VisitType(node); break; } } }
private static void ExpandTypeName(TypeSyntax type, StringBuilder builder) { switch (type.Kind()) { case SyntaxKind.AliasQualifiedName: var alias = (AliasQualifiedNameSyntax)type; builder.Append(alias.Alias.Identifier.ValueText); break; case SyntaxKind.ArrayType: var array = (ArrayTypeSyntax)type; ExpandTypeName(array.ElementType, builder); for (int i = 0; i < array.RankSpecifiers.Count; i++) { var rankSpecifier = array.RankSpecifiers[i]; builder.Append(rankSpecifier.OpenBracketToken.Text); for (int j = 1; j < rankSpecifier.Sizes.Count; j++) { builder.Append(','); } builder.Append(rankSpecifier.CloseBracketToken.Text); } break; case SyntaxKind.GenericName: var generic = (GenericNameSyntax)type; builder.Append(generic.Identifier.ValueText); if (generic.TypeArgumentList != null) { var arguments = generic.TypeArgumentList.Arguments; builder.Append(generic.TypeArgumentList.LessThanToken.Text); for (int i = 0; i < arguments.Count; i++) { if (i != 0) { builder.Append(','); } ExpandTypeName(arguments[i], builder); } builder.Append(generic.TypeArgumentList.GreaterThanToken.Text); } break; case SyntaxKind.IdentifierName: var identifierName = (IdentifierNameSyntax)type; builder.Append(identifierName.Identifier.ValueText); break; case SyntaxKind.NullableType: var nullable = (NullableTypeSyntax)type; ExpandTypeName(nullable.ElementType, builder); builder.Append(nullable.QuestionToken.Text); break; case SyntaxKind.OmittedTypeArgument: // do nothing since it was omitted, but don't reach the default block break; case SyntaxKind.PointerType: var pointer = (PointerTypeSyntax)type; ExpandTypeName(pointer.ElementType, builder); builder.Append(pointer.AsteriskToken.Text); break; case SyntaxKind.PredefinedType: var predefined = (PredefinedTypeSyntax)type; builder.Append(predefined.Keyword.Text); break; case SyntaxKind.QualifiedName: var qualified = (QualifiedNameSyntax)type; ExpandTypeName(qualified.Left, builder); builder.Append(qualified.DotToken.Text); ExpandTypeName(qualified.Right, builder); break; default: Debug.Assert(false, "Unexpected type syntax " + type.Kind()); break; } }
static bool TypeIsPointerType(TypeSyntax type) { return(type != null && type.Kind() == SyntaxKind.PointerType); }
/// <summary> /// Maps a type into another. /// </summary> /// <param name="originalType">The original type.</param> /// <returns>The new type, or the original type if no mapping is possible.</returns> public static string MapType(this TypeSyntax originalTypeSyntax) { // ArrayTypeSyntax // NameSyntax //NullableTypeSyntax //OmittedTypeArgumentSyntax //PointerTypeSyntax //PredefinedTypeSyntax //RefTypeSyntax //TupleTypeSyntax string originalType = null; switch (originalTypeSyntax.Kind()) { case SyntaxKind.PredefinedType: var predefinedSyntaxNode = originalTypeSyntax as PredefinedTypeSyntax; originalType = predefinedSyntaxNode.Keyword.Text; break; case SyntaxKind.GenericName: var genericNameSyntaxNode = originalTypeSyntax as GenericNameSyntax; originalType = genericNameSyntaxNode.Identifier.ValueText; break; case SyntaxKind.IdentifierName: var simpleNameSyntaxNode = originalTypeSyntax as SimpleNameSyntax; originalType = simpleNameSyntaxNode.Identifier.ValueText; break; case SyntaxKind.ArrayType: var arrayTypeSyntaxNode = originalTypeSyntax as ArrayTypeSyntax; originalType = arrayTypeSyntaxNode.ElementType.MapType(); break; case SyntaxKind.NullableType: var nullableTypeSyntaxNode = originalTypeSyntax as NullableTypeSyntax; originalType = nullableTypeSyntaxNode.ElementType.MapType(); break; case SyntaxKind.QualifiedName: var qualifiedNameSyntaxNode = originalTypeSyntax as QualifiedNameSyntax; originalType = qualifiedNameSyntaxNode.Right.MapType(); //TODO should we handle the left? or leave it up to TypeScript cleanup? break; case SyntaxKind.RefType: case SyntaxKind.TupleType: default: throw new NotImplementedException(); //break; } if (IsVoid(originalType)) { originalType = Lexems.VoidReturnType; } if (IsString(originalType)) { originalType = Lexems.StringType; } if (IsInt(originalType)) { originalType = Lexems.NumberType; } if (IsDouble(originalType)) { originalType = Lexems.NumberType; } if (IsFloat(originalType)) { originalType = Lexems.NumberType; } if (IsBool(originalType)) { originalType = Lexems.BooleanType; } if (IsKnockoutObservable(originalType)) { originalType = "KnockoutObservable"; } if (IsKnockoutObservableArray(originalType)) { originalType = "KnockoutObservableArray"; } if (IsKnockoutComputedObservable(originalType)) { originalType = "KnockoutComputed"; } if (IsObject(originalType)) { originalType = Lexems.AnyType; } switch (originalTypeSyntax.Kind()) { case SyntaxKind.GenericName: var genericNameSyntaxNode = originalTypeSyntax as GenericNameSyntax; originalType = originalType + SyntaxUtility.ToAngleBracketEnclosedList(genericNameSyntaxNode.TypeArgumentList.Arguments.Select(unit => unit.MapType())); break; case SyntaxKind.ArrayType: var arrayTypeSyntaxNode = originalTypeSyntax as ArrayTypeSyntax; originalType = originalType + "[]"; break; case SyntaxKind.NullableType: var nullableTypeSyntaxNode = originalTypeSyntax as NullableTypeSyntax; originalType = originalType + "|null"; break; default: break; } return(originalType); }
protected override void Populate(TextWriter trapFile) { switch (syntax.Kind()) { case SyntaxKind.ArrayType: case SyntaxKind.PointerType: Emit(trapFile, loc ?? syntax.GetLocation(), parent, type); Create(Context, GetArrayElementType(syntax), this, GetArrayElementType(type)); return; case SyntaxKind.NullableType: var nts = (NullableTypeSyntax)syntax; if (type is NamedType nt) { if (!nt.Symbol.IsReferenceType) { Emit(trapFile, loc ?? syntax.GetLocation(), parent, type); Create(Context, nts.ElementType, this, nt.TypeArguments[0]); } else { Create(Context, nts.ElementType, parent, type); } } else if (type is ArrayType) { Create(Context, nts.ElementType, parent, type); } return; case SyntaxKind.TupleType: var tts = (TupleTypeSyntax)syntax; var tt = (TupleType)type; Emit(trapFile, loc ?? syntax.GetLocation(), parent, type); foreach (var(s, t) in tts.Elements.Zip(tt.TupleElements, (s, t) => (s, t?.Type))) { if (t is not null) { Create(Context, s.Type, this, t); } } return; case SyntaxKind.GenericName: Emit(trapFile, loc ?? syntax.GetLocation(), parent, type); Context.PopulateLater(() => ((GenericNameSyntax)syntax) .TypeArgumentList .Arguments .Zip(type.TypeMentions, (s, t) => Create(Context, s, this, t)).Enumerate()); return; case SyntaxKind.QualifiedName: var qns = (QualifiedNameSyntax)syntax; var right = Create(Context, qns.Right, parent, type); if (type.ContainingType is not null) { // Type qualifier Create(Context, qns.Left, right, type.ContainingType); } return; default: Emit(trapFile, loc ?? syntax.GetLocation(), parent, type); return; } }
protected override void Populate(TextWriter trapFile) { switch (Syntax.Kind()) { case SyntaxKind.ArrayType: Emit(trapFile, Loc ?? Syntax.GetLocation(), Parent, Type); Create(cx, GetElementType(Syntax), this, GetElementType(Type)); return; case SyntaxKind.NullableType: var nts = (NullableTypeSyntax)Syntax; if (Type is NamedType nt) { Emit(trapFile, Loc ?? Syntax.GetLocation(), Parent, Type); Create(cx, nts.ElementType, this, nt.symbol.IsReferenceType ? nt : nt.TypeArguments[0]); } else if (Type is ArrayType array) { Create(cx, nts.ElementType, Parent, array); } return; case SyntaxKind.TupleType: var tts = (TupleTypeSyntax)Syntax; var tt = (TupleType)Type; Emit(trapFile, Loc ?? Syntax.GetLocation(), Parent, Type); tts.Elements.Zip(tt.TupleElements, (s, t) => Create(cx, s.Type, this, t.Type)).Enumerate(); return; case SyntaxKind.PointerType: var pts = (PointerTypeSyntax)Syntax; var pt = (PointerType)Type; Emit(trapFile, Loc ?? Syntax.GetLocation(), Parent, Type); Create(cx, pts.ElementType, this, pt.PointedAtType); return; case SyntaxKind.GenericName: var gns = (GenericNameSyntax)Syntax; Emit(trapFile, Loc ?? gns.Identifier.GetLocation(), Parent, Type); cx.PopulateLater(() => gns.TypeArgumentList.Arguments.Zip(Type.TypeMentions, (s, t) => Create(cx, s, this, t)).Enumerate()); return; case SyntaxKind.QualifiedName: if (Type.ContainingType == null) { // namespace qualifier Emit(trapFile, Loc ?? Syntax.GetLocation(), Parent, Type); } else { // Type qualifier var qns = (QualifiedNameSyntax)Syntax; var right = Create(cx, qns.Right, Parent, Type); Create(cx, qns.Left, right, Type.ContainingType); } return; default: Emit(trapFile, Loc ?? Syntax.GetLocation(), Parent, Type); return; } }
internal Type(TypeSyntax typeDeclaration) { Name = typeDeclaration.ToString(); IsDefault = typeDeclaration.Kind().Equals(SyntaxKind.PredefinedType); }