Beispiel #1
0
        public static void ExtractModifiers(Context cx, TextWriter trapFile, IEntity key, ISymbol symbol)
        {
            bool interfaceDefinition = symbol.ContainingType != null &&
                                       symbol.ContainingType.Kind == SymbolKind.NamedType &&
                                       symbol.ContainingType.TypeKind == TypeKind.Interface;

            HasAccessibility(cx, trapFile, key, symbol.DeclaredAccessibility);
            if (symbol.Kind == SymbolKind.ErrorType)
            {
                trapFile.has_modifiers(key, Modifier.Create(cx, Accessibility.Public));
            }

            if (symbol.IsAbstract && (symbol.Kind != SymbolKind.NamedType || ((INamedTypeSymbol)symbol).TypeKind != TypeKind.Interface) && !interfaceDefinition)
            {
                HasModifier(cx, trapFile, key, "abstract");
            }

            if (symbol.IsSealed)
            {
                HasModifier(cx, trapFile, key, "sealed");
            }

            bool fromSource = symbol.DeclaringSyntaxReferences.Length > 0;

            if (symbol.IsStatic && !(symbol.Kind == SymbolKind.Field && ((IFieldSymbol)symbol).IsConst && !fromSource))
            {
                HasModifier(cx, trapFile, key, "static");
            }

            if (symbol.IsVirtual)
            {
                HasModifier(cx, trapFile, key, "virtual");
            }

            // For some reason, method in interfaces are "virtual", not "abstract"
            if (symbol.IsAbstract && interfaceDefinition)
            {
                HasModifier(cx, trapFile, key, "virtual");
            }

            if (symbol.Kind == SymbolKind.Field && ((IFieldSymbol)symbol).IsReadOnly)
            {
                HasModifier(cx, trapFile, key, "readonly");
            }

            if (symbol.IsOverride)
            {
                HasModifier(cx, trapFile, key, "override");
            }

            if (symbol.Kind == SymbolKind.Method && ((IMethodSymbol)symbol).IsAsync)
            {
                HasModifier(cx, trapFile, key, "async");
            }

            if (symbol.IsExtern)
            {
                HasModifier(cx, trapFile, key, "extern");
            }

            foreach (var modifier in symbol.GetSourceLevelModifiers())
            {
                HasModifier(cx, trapFile, key, modifier);
            }

            if (symbol.Kind == SymbolKind.NamedType)
            {
                INamedTypeSymbol nt = symbol as INamedTypeSymbol;
                if (nt is null)
                {
                    throw new InternalError(symbol, "Symbol kind is inconsistent with its type");
                }

                if (nt.TypeKind == TypeKind.Struct)
                {
                    if (nt.IsReadOnly)
                    {
                        HasModifier(cx, trapFile, key, "readonly");
                    }
                    if (nt.IsRefLikeType)
                    {
                        HasModifier(cx, trapFile, key, "ref");
                    }
                }
            }
        }
Beispiel #2
0
        protected void PopulateType(TextWriter trapFile, bool constructUnderlyingTupleType = false)
        {
            PopulateMetadataHandle(trapFile);
            PopulateAttributes();

            trapFile.Write("types(");
            trapFile.WriteColumn(this);
            trapFile.Write(',');
            trapFile.WriteColumn((int)GetClassType(Context, symbol, constructUnderlyingTupleType));
            trapFile.Write(",\"");
            symbol.BuildDisplayName(Context, trapFile, constructUnderlyingTupleType);
            trapFile.WriteLine("\")");

            // Visit base types
            var baseTypes = new List <Type>();

            if (symbol.GetNonObjectBaseType(Context) is INamedTypeSymbol @base)
            {
                var baseKey = Create(Context, @base);
                trapFile.extend(this, baseKey.TypeRef);
                if (symbol.TypeKind != TypeKind.Struct)
                {
                    baseTypes.Add(baseKey);
                }
            }

            if (!(base.symbol is IArrayTypeSymbol))
            {
                foreach (var t in base.symbol.Interfaces.Select(i => Create(Context, i)))
                {
                    trapFile.implement(this, t.TypeRef);
                    baseTypes.Add(t);
                }
            }

            var containingType = ContainingType;

            if (containingType != null && symbol.Kind != SymbolKind.TypeParameter)
            {
                var originalDefinition = symbol.TypeKind == TypeKind.Error ? this : Create(Context, symbol.OriginalDefinition);
                trapFile.nested_types(this, containingType, originalDefinition);
            }
            else if (symbol.ContainingNamespace != null)
            {
                trapFile.parent_namespace(this, Namespace.Create(Context, symbol.ContainingNamespace));
            }

            if (symbol is IArrayTypeSymbol array)
            {
                // They are in the namespace of the original object
                var elementType = array.ElementType;
                var ns          = elementType.TypeKind == TypeKind.TypeParameter ? Context.Compilation.GlobalNamespace : elementType.ContainingNamespace;
                if (ns != null)
                {
                    trapFile.parent_namespace(this, Namespace.Create(Context, ns));
                }
            }

            if (symbol is IPointerTypeSymbol pointer)
            {
                var elementType = pointer.PointedAtType;
                var ns          = elementType.TypeKind == TypeKind.TypeParameter ? Context.Compilation.GlobalNamespace : elementType.ContainingNamespace;

                if (ns != null)
                {
                    trapFile.parent_namespace(this, Namespace.Create(Context, ns));
                }
            }

            if (symbol.BaseType != null && symbol.BaseType.SpecialType == SpecialType.System_MulticastDelegate)
            {
                // This is a delegate.
                // The method "Invoke" has the return type.
                var invokeMethod = ((INamedTypeSymbol)symbol).DelegateInvokeMethod;
                ExtractParametersForDelegateLikeType(trapFile, invokeMethod,
                                                     t => trapFile.delegate_return_type(this, t));
            }

            if (symbol is IFunctionPointerTypeSymbol functionPointer)
            {
                ExtractParametersForDelegateLikeType(trapFile, functionPointer.Signature,
                                                     t => trapFile.function_pointer_return_type(this, t));
            }

            Modifier.ExtractModifiers(Context, trapFile, this, symbol);

            if (IsSourceDeclaration && symbol.FromSource())
            {
                var declSyntaxReferences = symbol.DeclaringSyntaxReferences.Select(d => d.GetSyntax()).ToArray();

                var baseLists = declSyntaxReferences.OfType <ClassDeclarationSyntax>().Select(c => c.BaseList);
                baseLists = baseLists.Concat(declSyntaxReferences.OfType <InterfaceDeclarationSyntax>().Select(c => c.BaseList));
                baseLists = baseLists.Concat(declSyntaxReferences.OfType <StructDeclarationSyntax>().Select(c => c.BaseList));

                baseLists
                .Where(bl => bl != null)
                .SelectMany(bl => bl.Types)
                .Zip(
                    baseTypes.Where(bt => bt.symbol.SpecialType != SpecialType.System_Object),
                    (s, t) => TypeMention.Create(Context, s.Type, this, t))
                .Enumerate();
            }
        }
Beispiel #3
0
        public override void Populate(TextWriter trapFile)
        {
            PopulateMetadataHandle(trapFile);
            PopulateAttributes();
            ContainingType.PopulateGenerics();
            PopulateNullability(trapFile, symbol.GetAnnotatedType());

            Field unboundFieldKey = Field.Create(Context, symbol.OriginalDefinition);

            trapFile.fields(this, (symbol.IsConst ? 2 : 1), symbol.Name, ContainingType, Type.Type.TypeRef, unboundFieldKey);

            PopulateModifiers(trapFile);

            if (symbol.IsVolatile)
            {
                Modifier.HasModifier(Context, trapFile, this, "volatile");
            }

            if (symbol.IsConst)
            {
                Modifier.HasModifier(Context, trapFile, this, "const");

                if (symbol.HasConstantValue)
                {
                    trapFile.constant_value(this, Expression.ValueAsString(symbol.ConstantValue));
                }
            }

            foreach (var l in Locations)
            {
                trapFile.field_location(this, l);
            }

            if (!IsSourceDeclaration || !symbol.FromSource())
            {
                return;
            }

            Context.BindComments(this, Location.symbol);

            int child = 0;

            foreach (var initializer in
                     symbol.DeclaringSyntaxReferences.
                     Select(n => n.GetSyntax()).
                     OfType <VariableDeclaratorSyntax>().
                     Where(n => n.Initializer != null))
            {
                Context.PopulateLater(() =>
                {
                    var loc = Context.Create(initializer.GetLocation());
                    var simpleAssignExpr = new Expression(new ExpressionInfo(Context, Type, loc, ExprKind.SIMPLE_ASSIGN, this, child++, false, null));
                    Expression.CreateFromNode(new ExpressionNodeInfo(Context, initializer.Initializer.Value, simpleAssignExpr, 0));
                    var access = new Expression(new ExpressionInfo(Context, Type, Location, ExprKind.FIELD_ACCESS, simpleAssignExpr, 1, false, null));
                    trapFile.expr_access(access, this);
                    if (!symbol.IsStatic)
                    {
                        This.CreateImplicit(Context, Entities.Type.Create(Context, symbol.ContainingType), Location, access, -1);
                    }
                });
            }

            foreach (var initializer in symbol.DeclaringSyntaxReferences.
                     Select(n => n.GetSyntax()).
                     OfType <EnumMemberDeclarationSyntax>().
                     Where(n => n.EqualsValue != null))
            {
                // Mark fields that have explicit initializers.
                var expr = new Expression(new ExpressionInfo(Context, Type, Context.Create(initializer.EqualsValue.Value.FixedLocation()), Kinds.ExprKind.FIELD_ACCESS, this, child++, false, null));
                trapFile.expr_access(expr, this);
            }

            if (IsSourceDeclaration)
            {
                foreach (var syntax in symbol.DeclaringSyntaxReferences.
                         Select(d => d.GetSyntax()).OfType <VariableDeclaratorSyntax>().
                         Select(d => d.Parent).OfType <VariableDeclarationSyntax>())
                {
                    TypeMention.Create(Context, syntax.Type, this, Type);
                }
            }
        }
Beispiel #4
0
 public static void HasModifier(Context cx, TextWriter trapFile, IEntity target, string modifier)
 {
     trapFile.has_modifiers(target, Modifier.Create(cx, modifier));
 }
Beispiel #5
0
        public override void Populate(TextWriter trapFile)
        {
            PopulateMetadataHandle(trapFile);
            PopulateAttributes();
            ContainingType.PopulateGenerics();
            PopulateNullability(trapFile, symbol.GetAnnotatedType());

            var unboundFieldKey = Field.Create(Context, symbol.OriginalDefinition);

            trapFile.fields(this, (symbol.IsConst ? 2 : 1), symbol.Name, ContainingType, Type.Type.TypeRef, unboundFieldKey);

            PopulateModifiers(trapFile);

            if (symbol.IsVolatile)
            {
                Modifier.HasModifier(Context, trapFile, this, "volatile");
            }

            if (symbol.IsConst)
            {
                Modifier.HasModifier(Context, trapFile, this, "const");

                if (symbol.HasConstantValue)
                {
                    trapFile.constant_value(this, Expression.ValueAsString(symbol.ConstantValue));
                }
            }

            foreach (var l in Locations)
            {
                trapFile.field_location(this, l);
            }

            if (!IsSourceDeclaration || !symbol.FromSource())
            {
                return;
            }

            Context.BindComments(this, Location.symbol);

            var child = 0;

            foreach (var initializer in symbol.DeclaringSyntaxReferences
                     .Select(n => n.GetSyntax())
                     .OfType <VariableDeclaratorSyntax>()
                     .Where(n => n.Initializer != null))
            {
                Context.PopulateLater(() =>
                {
                    var loc = Context.Create(initializer.GetLocation());

                    var fieldAccess = AddInitializerAssignment(trapFile, initializer.Initializer.Value, loc, null, ref child);

                    if (!symbol.IsStatic)
                    {
                        This.CreateImplicit(Context, Entities.Type.Create(Context, symbol.ContainingType), Location, fieldAccess, -1);
                    }
                });
            }

            foreach (var initializer in symbol.DeclaringSyntaxReferences
                     .Select(n => n.GetSyntax())
                     .OfType <EnumMemberDeclarationSyntax>()
                     .Where(n => n.EqualsValue != null))
            {
                // Mark fields that have explicit initializers.
                var constValue = symbol.HasConstantValue
                    ? Expression.ValueAsString(symbol.ConstantValue)
                    : null;

                var loc = Context.Create(initializer.GetLocation());

                AddInitializerAssignment(trapFile, initializer.EqualsValue.Value, loc, constValue, ref child);
            }

            if (IsSourceDeclaration)
            {
                foreach (var syntax in symbol.DeclaringSyntaxReferences
                         .Select(d => d.GetSyntax())
                         .OfType <VariableDeclaratorSyntax>()
                         .Select(d => d.Parent)
                         .OfType <VariableDeclarationSyntax>())
                {
                    TypeMention.Create(Context, syntax.Type, this, Type);
                }
            }
        }
Beispiel #6
0
        public override void Populate()
        {
            ExtractMetadataHandle();
            ExtractAttributes();
            ContainingType.ExtractGenerics();

            Field unboundFieldKey = Field.Create(Context, symbol.OriginalDefinition);

            Context.Emit(Tuples.fields(this, (symbol.IsConst ? 2 : 1), symbol.Name, ContainingType, Type.TypeRef, unboundFieldKey));

            ExtractModifiers();

            if (symbol.IsVolatile)
            {
                Modifier.HasModifier(Context, this, "volatile");
            }

            if (symbol.IsConst)
            {
                Modifier.HasModifier(Context, this, "const");

                if (symbol.HasConstantValue)
                {
                    Context.Emit(Tuples.constant_value(this, Expression.ValueAsString(symbol.ConstantValue)));
                }
            }

            foreach (var l in Locations)
            {
                Context.Emit(Tuples.field_location(this, l));
            }

            if (!IsSourceDeclaration || !symbol.FromSource())
            {
                return;
            }

            Context.BindComments(this, Location.symbol);

            int child = 0;

            foreach (var initializer in
                     symbol.DeclaringSyntaxReferences.
                     Select(n => n.GetSyntax()).
                     OfType <VariableDeclaratorSyntax>().
                     Where(n => n.Initializer != null))
            {
                Context.PopulateLater(() =>
                {
                    Expression.CreateFromNode(new ExpressionNodeInfo(Context, initializer.Initializer.Value, this, child++));
                });
            }

            foreach (var initializer in symbol.DeclaringSyntaxReferences.
                     Select(n => n.GetSyntax()).
                     OfType <EnumMemberDeclarationSyntax>().
                     Where(n => n.EqualsValue != null))
            {
                // Mark fields that have explicit initializers.
                var expr = new Expression(new ExpressionInfo(Context, Type, Context.Create(initializer.EqualsValue.Value.FixedLocation()), Kinds.ExprKind.FIELD_ACCESS, this, child++, false, null));
                Context.Emit(Tuples.expr_access(expr, this));
            }

            if (IsSourceDeclaration)
            {
                foreach (var syntax in symbol.DeclaringSyntaxReferences.
                         Select(d => d.GetSyntax()).OfType <VariableDeclaratorSyntax>().
                         Select(d => d.Parent).OfType <VariableDeclarationSyntax>())
                {
                    TypeMention.Create(Context, syntax.Type, this, Type);
                }
            }
        }
Beispiel #7
0
        protected void PopulateType(TextWriter trapFile)
        {
            PopulateMetadataHandle(trapFile);
            PopulateAttributes();

            trapFile.Write("types(");
            trapFile.WriteColumn(this);
            trapFile.Write(',');
            trapFile.WriteColumn((int)GetClassType(Context, symbol));
            trapFile.Write(",\"");
            symbol.BuildDisplayName(Context, trapFile);
            trapFile.WriteLine("\")");

            // Visit base types
            var baseTypes = new List <Type>();

            if (symbol.BaseType != null)
            {
                Type baseKey = Create(Context, symbol.BaseType);
                trapFile.extend(this, baseKey.TypeRef);
                if (symbol.TypeKind != TypeKind.Struct)
                {
                    baseTypes.Add(baseKey);
                }
            }

            if (symbol.TypeKind == TypeKind.Interface)
            {
                trapFile.extend(this, Create(Context, Context.Compilation.ObjectType));
            }

            if (!(base.symbol is IArrayTypeSymbol))
            {
                foreach (var t in base.symbol.Interfaces.Select(i => Create(Context, i)))
                {
                    trapFile.implement(this, t.TypeRef);
                    baseTypes.Add(t);
                }
            }

            var containingType = ContainingType;

            if (containingType != null && symbol.Kind != SymbolKind.TypeParameter)
            {
                Type originalDefinition = symbol.TypeKind == TypeKind.Error ? this : Create(Context, symbol.OriginalDefinition);
                trapFile.nested_types(this, containingType, originalDefinition);
            }
            else if (symbol.ContainingNamespace != null)
            {
                trapFile.parent_namespace(this, Namespace.Create(Context, symbol.ContainingNamespace));
            }

            if (symbol is IArrayTypeSymbol)
            {
                // They are in the namespace of the original object
                ITypeSymbol      elementType = ((IArrayTypeSymbol)symbol).ElementType;
                INamespaceSymbol ns          = elementType.TypeKind == TypeKind.TypeParameter ? Context.Compilation.GlobalNamespace : elementType.ContainingNamespace;
                if (ns != null)
                {
                    trapFile.parent_namespace(this, Namespace.Create(Context, ns));
                }
            }

            if (symbol is IPointerTypeSymbol)
            {
                ITypeSymbol      elementType = ((IPointerTypeSymbol)symbol).PointedAtType;
                INamespaceSymbol ns          = elementType.TypeKind == TypeKind.TypeParameter ? Context.Compilation.GlobalNamespace : elementType.ContainingNamespace;

                if (ns != null)
                {
                    trapFile.parent_namespace(this, Namespace.Create(Context, ns));
                }
            }

            if (symbol.BaseType != null && symbol.BaseType.SpecialType == SpecialType.System_MulticastDelegate)
            {
                // This is a delegate.
                // The method "Invoke" has the return type.
                var invokeMethod = ((INamedTypeSymbol)symbol).DelegateInvokeMethod;

                // Copy the parameters from the "Invoke" method to the delegate type
                for (var i = 0; i < invokeMethod.Parameters.Length; ++i)
                {
                    var param               = invokeMethod.Parameters[i];
                    var originalParam       = invokeMethod.OriginalDefinition.Parameters[i];
                    var originalParamEntity = SymbolEqualityComparer.Default.Equals(param, originalParam) ? null :
                                              DelegateTypeParameter.Create(Context, originalParam, Create(Context, ((INamedTypeSymbol)symbol).OriginalDefinition));
                    DelegateTypeParameter.Create(Context, param, this, originalParamEntity);
                }

                var returnKey = Create(Context, invokeMethod.ReturnType);
                trapFile.delegate_return_type(this, returnKey.TypeRef);
                if (invokeMethod.ReturnsByRef)
                {
                    trapFile.type_annotation(this, Kinds.TypeAnnotation.Ref);
                }
                if (invokeMethod.ReturnsByRefReadonly)
                {
                    trapFile.type_annotation(this, Kinds.TypeAnnotation.ReadonlyRef);
                }
            }

            Modifier.ExtractModifiers(Context, trapFile, this, symbol);

            if (IsSourceDeclaration && symbol.FromSource())
            {
                var declSyntaxReferences = symbol.DeclaringSyntaxReferences.Select(d => d.GetSyntax()).ToArray();

                var baseLists = declSyntaxReferences.OfType <ClassDeclarationSyntax>().Select(c => c.BaseList);
                baseLists = baseLists.Concat(declSyntaxReferences.OfType <InterfaceDeclarationSyntax>().Select(c => c.BaseList));
                baseLists = baseLists.Concat(declSyntaxReferences.OfType <StructDeclarationSyntax>().Select(c => c.BaseList));

                baseLists.
                Where(bl => bl != null).
                SelectMany(bl => bl.Types).
                Zip(baseTypes.Where(bt => bt.symbol.SpecialType != SpecialType.System_Object),
                    (s, t) => TypeMention.Create(Context, s.Type, this, t)).
                Enumerate();
            }
        }
Beispiel #8
0
 public static void HasModifier(Context cx, IEntity target, string modifier)
 {
     cx.Emit(Tuples.has_modifiers(target, Modifier.Create(cx, modifier)));
 }
Beispiel #9
0
        public static void ExtractModifiers(Context cx, IEntity key, ISymbol symbol)
        {
            bool interfaceDefinition = symbol.ContainingType != null &&
                                       symbol.ContainingType.Kind == SymbolKind.NamedType &&
                                       symbol.ContainingType.TypeKind == TypeKind.Interface;

            Modifier.HasAccessibility(cx, key, symbol.DeclaredAccessibility);
            if (symbol.Kind == SymbolKind.ErrorType)
            {
                cx.Emit(Tuples.has_modifiers(key, Modifier.Create(cx, Accessibility.Public)));
            }

            if (symbol.IsAbstract && (symbol.Kind != SymbolKind.NamedType || ((INamedTypeSymbol)symbol).TypeKind != TypeKind.Interface) && !interfaceDefinition)
            {
                Modifier.HasModifier(cx, key, "abstract");
            }

            if (symbol.IsSealed)
            {
                HasModifier(cx, key, "sealed");
            }

            bool fromSource = symbol.DeclaringSyntaxReferences.Length > 0;

            if (symbol.IsStatic && !(symbol.Kind == SymbolKind.Field && ((IFieldSymbol)symbol).IsConst && !fromSource))
            {
                HasModifier(cx, key, "static");
            }

            if (symbol.IsVirtual)
            {
                HasModifier(cx, key, "virtual");
            }

            // For some reason, method in interfaces are "virtual", not "abstract"
            if (symbol.IsAbstract && interfaceDefinition)
            {
                HasModifier(cx, key, "virtual");
            }

            if (symbol.Kind == SymbolKind.Field && ((IFieldSymbol)symbol).IsReadOnly)
            {
                HasModifier(cx, key, "readonly");
            }

            if (symbol.IsOverride)
            {
                HasModifier(cx, key, "override");
            }

            if (symbol.Kind == SymbolKind.Method && ((IMethodSymbol)symbol).IsAsync)
            {
                HasModifier(cx, key, "async");
            }

            if (symbol.IsExtern)
            {
                HasModifier(cx, key, "extern");
            }

            foreach (var modifier in symbol.GetSourceLevelModifiers())
            {
                HasModifier(cx, key, modifier);
            }

            if (symbol.Kind == SymbolKind.NamedType)
            {
                INamedTypeSymbol nt = symbol as INamedTypeSymbol;
                if (nt is null)
                {
                    throw new InternalError(symbol, "Symbol kind is inconsistent with its type");
                }

                if (nt.TypeKind == TypeKind.Struct)
                {
                    // Sadly, these properties are internal so cannot be accessed directly.
                    // This seems to be a deficiency in the model.
                    var readonlyProperty = nt.GetType().GetProperty("IsReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);

                    bool isReadOnly      = (bool)readonlyProperty.GetValue(nt);
                    bool isByRefLikeType = nt.IsRefLikeType;

                    if (isReadOnly)
                    {
                        HasModifier(cx, key, "readonly");
                    }
                    if (isByRefLikeType)
                    {
                        HasModifier(cx, key, "ref");
                    }
                }
            }
        }