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); }
public override string ToString() => _targetType.ToString() + "`" + _typeArguments.Length;
/// <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); }