bool Bind()
        {
            var compilation = _compilation;

            if (_type == null)
            {
                _namedArgs = ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty;

                // TODO: check the attribute can be bound to symbol

                var type = _tref.ResolveRuntimeType(compilation);
                if (type.IsValidType() && compilation.GetWellKnownType(WellKnownType.System_Attribute).IsAssignableFrom(type))
                {
                    // valid CLR attribute
                    // bind strictly

                    // bind arguments
                    if (!TryResolveCtor((NamedTypeSymbol)type, compilation, out _ctor, out _ctorArgs))
                    {
                        throw new InvalidOperationException("no matching .ctor");
                    }

                    // bind named parameters to CLR attribute properties
                    foreach (var arg in _arguments)
                    {
                        if (arg.ParameterName == null)
                        {
                            continue;
                        }

                        var member =
                            (Symbol)type.LookupMember <PropertySymbol>(arg.ParameterName) ??
                            (Symbol)type.LookupMember <FieldSymbol>(arg.ParameterName);

                        if (member != null && TryBindTypedConstant(member.GetTypeOrReturnType(), arg.Value.ConstantValue, out var constant))
                        {
                            _namedArgs = _namedArgs.Add(new KeyValuePair <string, TypedConstant>(arg.ParameterName, constant));
                        }
                        else
                        {
                            throw new InvalidOperationException();
                        }
                    }

                    //
                    _type = (NamedTypeSymbol)type;
                }
                else
                {
                    // store just the metadata
                    _type = compilation.CoreTypes.PhpCustomAtribute ?? throw new InvalidOperationException("PhpCustomAtribute not defined.");
                    _ctor = _type.Constructors.Single(m =>
                                                      m.ParameterCount == 2 &&
                                                      m.Parameters[0].Type.IsStringType() &&
                                                      m.Parameters[1].Type.IsByteArray());

                    //compilation.DeclarationDiagnostics.Add(
                    //    Location.Create(file.SyntaxTree, _tref.Span.ToTextSpan()),
                    //    Errors.ErrorCode.ERR_TypeNameCannotBeResolved,
                    //    _tref.ToString());

                    //type = new MissingMetadataTypeSymbol(_tref.ToString(), 0, false);

                    _ctorArgs = ImmutableArray.Create(
                        compilation.CreateTypedConstant(_tref.ToString()),
                        compilation.CreateTypedConstant(Encoding.UTF8.GetBytes(ArgumentsToJson())));
                }

                // TODO: validate {type} attribute TARGET if any
                //Attribute::TARGET_CLASS
                //Attribute::TARGET_FUNCTION
                //Attribute::TARGET_METHOD
                //Attribute::TARGET_PROPERTY
                //Attribute::TARGET_CLASS_CONSTANT
                //Attribute::TARGET_PARAMETER
                //Attribute::TARGET_ALL
            }

            //
            return(_type != null);
        }
示例#2
0
 public override string ToString() => _targetType.ToString() + "`" + _typeArguments.Length;
示例#3
0
        /// <summary>
        /// Gets string representation of types contained in given type mask.
        /// </summary>
        public string ToString(TypeRefMask mask)
        {
            if (!mask.IsVoid)
            {
                if (mask.IsAnyType)
                {
                    return(TypeRefMask.MixedTypeName);
                }

                //
                var types = new List <string>(1);

                // handle arrays separately
                var arrmask = mask & _isArrayMask;
                if (arrmask != 0)
                {
                    mask &= ~_isArrayMask;
                    IBoundTypeRef elementtype = null;
                    var           elementmask = GetElementType(arrmask);
                    if (elementmask.IsSingleType)
                    {
                        elementtype = GetTypes(elementmask).FirstOrDefault();
                    }

                    if (elementtype != null)
                    {
                        types.Add(elementtype.ToString() + "[]");
                    }
                    else
                    {
                        types.Add(QualifiedName.Array.ToString());
                    }
                }

                //// int|double => number
                //var isNumber = (_isIntMask != 0 && _isDoubleMask != 0 && (mask & IsNumberMask) == IsNumberMask);
                //if (isNumber)
                //    mask &= ~IsNumberMask;

                //if (IsNull(mask))
                //{
                //    mask &= ~_isNullMask;
                //    types.Add(QualifiedName.Null.ToString());
                //}

                //
                types.AddRange(GetTypes(mask).Select(t => t.ToString()));

                //if (isNumber)
                //    types.Add("number");

                //
                if (types.Count != 0)
                {
                    types.Sort();
                    return(string.Join(PHPDocBlock.TypeVarDescTag.TypeNamesSeparator.ToString(), types.Distinct()));
                }
            }

            return(TypeRefMask.VoidTypeName);
        }