public void Construct(NamedTypeSymbol functype, Action<CodeGenerator> binder_builder) { var callsitetype = _factory.CallSite_T.Construct(functype); // TODO: check if it wasn't constructed already _target.SetContainingType((SubstitutedNamedTypeSymbol)callsitetype); _fld.SetFieldType(callsitetype); _callsite_create = (MethodSymbol)_factory.CallSite_T_Create.SymbolAsMember(callsitetype); // create callsite // static .cctor { var cctor = _factory.CctorBuilder; // fld = CallSite<T>.Create( <BINDER> ) var fldPlace = this.Place; fldPlace.EmitStorePrepare(cctor); var cctor_cg = new CodeGenerator(cctor, _factory._cg.Module, _factory._cg.Diagnostics, _factory._cg.DeclaringCompilation.Options.OptimizationLevel, false, _factory._container, null, null); binder_builder(cctor_cg); cctor.EmitCall(_factory._cg.Module, _factory._cg.Diagnostics, ILOpCode.Call, this.CallSite_Create); fldPlace.EmitStore(cctor); // } }
internal SourceAttributeData( SyntaxReference applicationNode, NamedTypeSymbol attributeClass, MethodSymbol attributeConstructor, ImmutableArray<TypedConstant> constructorArguments, ImmutableArray<int> constructorArgumentsSourceIndices, ImmutableArray<KeyValuePair<string, TypedConstant>> namedArguments, bool hasErrors, bool isConditionallyOmitted) { Debug.Assert(!isConditionallyOmitted || (object)attributeClass != null && attributeClass.IsConditional); Debug.Assert(!constructorArguments.IsDefault); Debug.Assert(!namedArguments.IsDefault); Debug.Assert(constructorArgumentsSourceIndices.IsDefault || constructorArgumentsSourceIndices.Any() && constructorArgumentsSourceIndices.Length == constructorArguments.Length); _attributeClass = attributeClass; _attributeConstructor = attributeConstructor; _constructorArguments = constructorArguments; _constructorArgumentsSourceIndices = constructorArgumentsSourceIndices; _namedArguments = namedArguments; _isConditionallyOmitted = isConditionallyOmitted; _hasErrors = hasErrors; _applicationNode = applicationNode; }
void EmitInvoke(MethodSymbol invoke, Emit.PEModuleBuilder module) { if (invoke == null) { return; } module.SetMethodBody(invoke, MethodGenerator.GenerateMethodBody(module, invoke, il => { var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), OptimizationLevel.Release, false, this, new ParamPlace(invoke.Parameters[0]), new ArgPlace(this, 0)); //var __invoke = (MethodSymbol)GetMembers(Pchp.Syntax.Name.SpecialMethodNames.Invoke.Value).Single(s => s is MethodSymbol); // TODO: call __invoke() directly // context.Call<T>(T, TypeMethods.MagicMethods, params PhpValue[]) var call_t = cg.CoreTypes.Context.Symbol.GetMembers("Call") .OfType<MethodSymbol>() .Where(s => s.Arity == 1 && s.ParameterCount == 3 && s.Parameters[2].IsParams) .Single() .Construct(this); // return context.Call<T>(this, __invoke, args) cg.EmitLoadContext(); cg.EmitThis(); cg.Builder.EmitIntConstant((int)Core.Reflection.TypeMethods.MagicMethods.__invoke); cg.Builder.EmitLoadArgumentOpcode(2); cg.EmitCall(ILOpCode.Call, call_t); cg.EmitRet(invoke.ReturnType); }, null, DiagnosticBag.GetInstance(), false)); }
internal ConstructedMethodSymbol(MethodSymbol constructedFrom, ImmutableArray<TypeSymbol> typeArguments) : base(containingSymbol: constructedFrom.ContainingType, map: new TypeMap(constructedFrom.ContainingType, ((MethodSymbol)constructedFrom.OriginalDefinition).TypeParameters, typeArguments.SelectAsArray(TypeMap.TypeSymbolAsTypeWithModifiers)), originalDefinition: (MethodSymbol)constructedFrom.OriginalDefinition, constructedFrom: constructedFrom) { _typeArguments = typeArguments; }
protected SynthesizedContainer(string name, MethodSymbol topLevelMethod) { Debug.Assert(name != null); Debug.Assert(topLevelMethod != null); _name = name; _typeMap = TypeMap.Empty.WithAlphaRename(topLevelMethod, this, out _typeParameters); }
public SynthesizedPropertySymbol(NamedTypeSymbol containing, string name, bool isStatic, TypeSymbol type, Accessibility accessibility, MethodSymbol getter, MethodSymbol setter) { _containing = containing; _name = name; _accessibility = accessibility; _setMethod = setter; _getMethod = getter; _type = type; _isStatic = isStatic; }
public SpecialParameterSymbol(MethodSymbol symbol, object type, string name, int index) { Debug.Assert(type is TypeSymbol || type is CoreType); Contract.ThrowIfNull(symbol); Contract.ThrowIfNull(type); _symbol = symbol; _type = type; _name = name; _index = index; }
internal RetargetingAttributeData( SyntaxReference applicationNode, NamedTypeSymbol attributeClass, MethodSymbol attributeConstructor, ImmutableArray<TypedConstant> constructorArguments, ImmutableArray<int> constructorArgumentsSourceIndices, ImmutableArray<KeyValuePair<string, TypedConstant>> namedArguments, bool hasErrors, bool isConditionallyOmitted) : base(applicationNode, attributeClass, attributeConstructor, constructorArguments, constructorArgumentsSourceIndices, namedArguments, hasErrors, isConditionallyOmitted) { }
internal SourceAttributeData(SyntaxReference applicationNode, NamedTypeSymbol attributeClass, MethodSymbol attributeConstructor, bool hasErrors) : this( applicationNode, attributeClass, attributeConstructor, constructorArguments: ImmutableArray<TypedConstant>.Empty, constructorArgumentsSourceIndices: default(ImmutableArray<int>), namedArguments: ImmutableArray<KeyValuePair<string, TypedConstant>>.Empty, hasErrors: hasErrors, isConditionallyOmitted: false) { }
// constructor for dynamic call-site delegate: public SynthesizedDelegateSymbol( NamespaceOrTypeSymbol containingSymbol, string name, TypeSymbol objectType, TypeSymbol intPtrType, TypeSymbol voidReturnTypeOpt, int parameterCount, BitVector byRefParameters) : base(name, parameterCount, returnsVoid: (object)voidReturnTypeOpt != null) { _containingSymbol = containingSymbol; _constructor = new DelegateConstructor(this, objectType, intPtrType); _invoke = new InvokeMethod(this, byRefParameters, voidReturnTypeOpt); }
static bool IsAccessible(MethodSymbol method, TypeSymbol classCtx) { if (method.DeclaredAccessibility == Accessibility.Private) { return (method.ContainingType == classCtx); } else if (method.DeclaredAccessibility == Accessibility.Protected) { return classCtx != null && ( method.ContainingType.IsEqualToOrDerivedFrom(classCtx) || classCtx.IsEqualToOrDerivedFrom(method.ContainingType)); } return true; }
internal SynthesizedAttributeData(MethodSymbol ctor, ImmutableArray<TypedConstant> arguments, ImmutableArray<KeyValuePair<String, TypedConstant>> namedArguments) : base( applicationNode: null, attributeClass: (NamedTypeSymbol)ctor.ContainingType, attributeConstructor: ctor, constructorArguments: arguments, constructorArgumentsSourceIndices: default(ImmutableArray<int>), namedArguments: namedArguments, hasErrors: false, isConditionallyOmitted: false) { Debug.Assert((object)ctor != null); Debug.Assert(!arguments.IsDefault); Debug.Assert(!namedArguments.IsDefault); // Frequently empty though. }
protected SubstitutedMethodSymbol(NamedTypeSymbol containingSymbol, TypeMap map, MethodSymbol originalDefinition, MethodSymbol constructedFrom) { Debug.Assert(originalDefinition.IsDefinition); _containingType = containingSymbol; this.originalDefinition = originalDefinition; _inputMap = map; if ((object)constructedFrom != null) { _constructedFrom = constructedFrom; Debug.Assert(ReferenceEquals(constructedFrom.ConstructedFrom, constructedFrom)); _lazyTypeParameters = constructedFrom.TypeParameters; _lazyMap = map; } else { _constructedFrom = this; } }
/// <summary> /// Creates ghost stub that calls current method. /// </summary> protected void CreateGhostOverload(PEModuleBuilder module, DiagnosticBag diagnostic, TypeSymbol ghostreturn, IEnumerable<ParameterSymbol> ghostparams, MethodSymbol explicitOverride = null) { var ghost = new SynthesizedMethodSymbol( this.ContainingType, this.Name, this.IsStatic, explicitOverride != null, ghostreturn, this.DeclaredAccessibility) { ExplicitOverride = explicitOverride, }; ghost.SetParameters(ghostparams.Select(p => new SynthesizedParameterSymbol(ghost, p.Type, p.Ordinal, p.RefKind, p.Name)).ToArray()); // save method symbol to module module.SynthesizedManager.AddMethod(this.ContainingType, ghost); // generate method body GenerateGhostBody(module, diagnostic, ghost); }
public SynthesizedParameterSymbol( MethodSymbol container, TypeSymbol type, int ordinal, RefKind refKind, string name = "", ImmutableArray<CustomModifier> customModifiers = default(ImmutableArray<CustomModifier>), ushort countOfCustomModifiersPrecedingByRef = 0, ConstantValue explicitDefaultConstantValue = null) { Debug.Assert((object)type != null); Debug.Assert(name != null); Debug.Assert(ordinal >= 0); _container = container; _type = type; _ordinal = ordinal; _refKind = refKind; _name = name; _customModifiers = customModifiers.NullToEmpty(); _countOfCustomModifiersPrecedingByRef = countOfCustomModifiersPrecedingByRef; _explicitDefaultConstantValue = explicitDefaultConstantValue; }
private int _hashCode; // computed on demand internal SubstitutedMethodSymbol(SubstitutedNamedTypeSymbol containingSymbol, MethodSymbol originalDefinition) : this(containingSymbol, containingSymbol.TypeSubstitution, originalDefinition, constructedFrom: null) { }
public static bool IsParams(this MethodSymbol method) { return(method.ParameterCount != 0 && method.Parameters[method.ParameterCount - 1].IsParams); }
public static bool IsErrorMethod(this MethodSymbol method) => method == null || method is IErrorMethodSymbol;
public MethodReference(MethodSymbol underlyingMethod) { Debug.Assert((object)underlyingMethod != null); this.UnderlyingMethod = underlyingMethod; }
public static TypeSymbol[] ParametersType(this MethodSymbol method) { return(method.Parameters.Select(p => p.Type).ToArray()); }
internal override void Generate(CodeGenerator cg) { Debug.Assert(this.Enumeree != null); // get the enumerator, // bind actual MoveNext() and CurrentValue and CurrentKey // Template: using( // a) enumerator = enumeree.GetEnumerator() // b) enumerator = Operators.GetEnumerator(enumeree) // ) ... cg.EmitSequencePoint(this.Enumeree.PhpSyntax); var enumereeType = cg.Emit(this.Enumeree); Debug.Assert(enumereeType.SpecialType != SpecialType.System_Void); var getEnumeratorMethod = enumereeType.LookupMember<MethodSymbol>(WellKnownMemberNames.GetEnumeratorMethodName); TypeSymbol enumeratorType; if (enumereeType.IsOfType(cg.CoreTypes.PhpArray)) { cg.Builder.EmitBoolConstant(_aliasedValues); // PhpArray.GetForeachtEnumerator(bool) enumeratorType = cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.PhpArray.GetForeachEnumerator_Boolean); // TODO: IPhpArray } // TODO: IPhpEnumerable // TODO: IPhpArray // TODO: Iterator else if (getEnumeratorMethod != null && getEnumeratorMethod.ParameterCount == 0 && enumereeType.IsReferenceType) { // enumeree.GetEnumerator() enumeratorType = cg.EmitCall(getEnumeratorMethod.IsVirtual ? ILOpCode.Callvirt : ILOpCode.Call, getEnumeratorMethod); } else { cg.EmitConvertToPhpValue(enumereeType, 0); cg.Builder.EmitBoolConstant(_aliasedValues); cg.EmitCallerRuntimeTypeHandle(); // Operators.GetForeachEnumerator(PhpValue, bool, RuntimeTypeHandle) enumeratorType = cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.GetForeachEnumerator_PhpValue_Bool_RuntimeTypeHandle); } // _current = enumeratorType.LookupMember<PropertySymbol>(WellKnownMemberNames.CurrentPropertyName); // TODO: Err if no Current _currentValue = enumeratorType.LookupMember<PropertySymbol>(_aliasedValues ? "CurrentValueAliased" : "CurrentValue"); _currentKey = enumeratorType.LookupMember<PropertySymbol>("CurrentKey"); _disposeMethod = enumeratorType.LookupMember<MethodSymbol>("Dispose", m => m.ParameterCount == 0 && !m.IsStatic); // _enumeratorLoc = cg.GetTemporaryLocal(enumeratorType); cg.Builder.EmitLocalStore(_enumeratorLoc); // bind methods _moveNextMethod = enumeratorType.LookupMember<MethodSymbol>(WellKnownMemberNames.MoveNextMethodName); // TODO: Err if there is no MoveNext() Debug.Assert(_moveNextMethod.ReturnType.SpecialType == SpecialType.System_Boolean); Debug.Assert(_moveNextMethod.IsStatic == false); if (_disposeMethod != null) { /* Template: try { body } finally { enumerator.Dispose } */ // try { cg.Builder.AssertStackEmpty(); cg.Builder.OpenLocalScope(ScopeType.TryCatchFinally); cg.Builder.OpenLocalScope(ScopeType.Try); // EmitBody(cg); // } cg.Builder.CloseLocalScope(); // /Try // finally { cg.Builder.OpenLocalScope(ScopeType.Finally); // enumerator.Dispose() & cleanup EmitDisposeAndClean(cg); // } cg.Builder.CloseLocalScope(); // /Finally cg.Builder.CloseLocalScope(); // /TryCatchFinally } else { EmitBody(cg); EmitDisposeAndClean(cg); } }
//internal static ImmutableArray<TypeParameterSymbol> GetMemberTypeParameters(this Symbol symbol) //{ // switch (symbol.Kind) // { // case SymbolKind.Method: // return ((MethodSymbol)symbol).TypeParameters; // case SymbolKind.NamedType: // case SymbolKind.ErrorType: // return ((NamedTypeSymbol)symbol).TypeParameters; // case SymbolKind.Field: // case SymbolKind.Property: // case SymbolKind.Event: // return ImmutableArray<TypeParameterSymbol>.Empty; // default: // throw ExceptionUtilities.UnexpectedValue(symbol.Kind); // } //} //internal static ImmutableArray<TypeSymbol> GetMemberTypeArgumentsNoUseSiteDiagnostics(this Symbol symbol) //{ // switch (symbol.Kind) // { // case SymbolKind.Method: // return ((MethodSymbol)symbol).TypeArguments; // case SymbolKind.NamedType: // case SymbolKind.ErrorType: // return ((NamedTypeSymbol)symbol).TypeArgumentsNoUseSiteDiagnostics; // case SymbolKind.Field: // case SymbolKind.Property: // case SymbolKind.Event: // return ImmutableArray<TypeSymbol>.Empty; // default: // throw ExceptionUtilities.UnexpectedValue(symbol.Kind); // } //} /// <summary> /// NOTE: every struct has a public parameterless constructor either used-defined or default one /// </summary> internal static bool IsParameterlessConstructor(this MethodSymbol method) { return(method.MethodKind == MethodKind.Constructor && method.ParameterCount == 0); }
/// <summary> /// Determines whether <paramref name="method"/> can override <paramref name="basemethod"/>. /// </summary> /// <param name="method">Source method.</param> /// <param name="basemethod">Overriden method.</param> public static bool CanBeOverride(SourceMethodSymbol method, MethodSymbol basemethod) { return IsAllowedCost(OverrideCost(method, basemethod)); }
public SpecializedGenericMethodInstanceReference(MethodSymbol underlyingMethod) : base(underlyingMethod) { Debug.Assert(PEModuleBuilder.IsGenericType(underlyingMethod.ContainingType) && underlyingMethod.ContainingType.IsDefinition); _genericMethod = new SpecializedMethodReference(underlyingMethod); }
//internal static ISet<PropertySymbol> GetPropertiesForExplicitlyImplementedAccessor(MethodSymbol accessor) //{ // return GetSymbolsForExplicitlyImplementedAccessor<PropertySymbol>(accessor); //} //internal static ISet<EventSymbol> GetEventsForExplicitlyImplementedAccessor(MethodSymbol accessor) //{ // return GetSymbolsForExplicitlyImplementedAccessor<EventSymbol>(accessor); //} //// CONSIDER: the 99% case is a very small set. A list might be more efficient in such cases. //private static ISet<T> GetSymbolsForExplicitlyImplementedAccessor<T>(MethodSymbol accessor) where T : Symbol //{ // if ((object)accessor == null) // { // return SpecializedCollections.EmptySet<T>(); // } // ImmutableArray<MethodSymbol> implementedAccessors = accessor.ExplicitInterfaceImplementations; // if (implementedAccessors.Length == 0) // { // return SpecializedCollections.EmptySet<T>(); // } // var symbolsForExplicitlyImplementedAccessors = new HashSet<T>(); // foreach (var implementedAccessor in implementedAccessors) // { // var associatedProperty = implementedAccessor.AssociatedSymbol as T; // if ((object)associatedProperty != null) // { // symbolsForExplicitlyImplementedAccessors.Add(associatedProperty); // } // } // return symbolsForExplicitlyImplementedAccessors; //} // Properties and events from metadata do not have explicit accessibility. Instead, // the accessibility reported for the PEPropertySymbol or PEEventSymbol is the most // restrictive level that is no more restrictive than the getter/adder and setter/remover. internal static Accessibility GetDeclaredAccessibilityFromAccessors(MethodSymbol accessor1, MethodSymbol accessor2) { if ((object)accessor1 == null) { return(((object)accessor2 == null) ? Accessibility.NotApplicable : accessor2.DeclaredAccessibility); } else if ((object)accessor2 == null) { return(accessor1.DeclaredAccessibility); } return(GetDeclaredAccessibilityFromAccessors(accessor1.DeclaredAccessibility, accessor2.DeclaredAccessibility)); }
internal TypeMap WithAlphaRename(MethodSymbol oldOwner, Symbol newOwner, out ImmutableArray<TypeParameterSymbol> newTypeParameters) { Debug.Assert(object.ReferenceEquals(oldOwner.ConstructedFrom, oldOwner)); return WithAlphaRename(oldOwner.OriginalDefinition.TypeParameters, newOwner, out newTypeParameters); }
//internal override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder<SynthesizedAttributeData> attributes) //{ // // Emit [Dynamic] on synthesized parameter symbols when the original parameter was dynamic // // in order to facilitate debugging. In the case the necessary attributes are missing // // this is a no-op. Emitting an error here, or when the original parameter was bound, would // // adversely effect the compilation or potentially change overload resolution. // var compilation = this.DeclaringCompilation; // if (Type.ContainsDynamic() && compilation.HasDynamicEmitAttributes()) // { // var boolType = compilation.GetSpecialType(SpecialType.System_Boolean); // var diagnostic = boolType.GetUseSiteDiagnostic(); // if ((diagnostic == null) || (diagnostic.Severity != DiagnosticSeverity.Error)) // { // AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.Type, this.CustomModifiers.Length, this.RefKind)); // } // } //} /// <summary> /// For each parameter of a source method, construct a corresponding synthesized parameter /// for a destination method. /// </summary> /// <param name="sourceMethod">Has parameters.</param> /// <param name="destinationMethod">Needs parameters.</param> /// <returns>Synthesized parameters to add to destination method.</returns> internal static ImmutableArray<ParameterSymbol> DeriveParameters(MethodSymbol sourceMethod, MethodSymbol destinationMethod) { var builder = ArrayBuilder<ParameterSymbol>.GetInstance(); foreach (var oldParam in sourceMethod.Parameters) { //same properties as the old one, just change the owner builder.Add(new SynthesizedParameterSymbol(destinationMethod, oldParam.Type, oldParam.Ordinal, oldParam.RefKind, oldParam.Name, oldParam.CustomModifiers, oldParam.CountOfCustomModifiersPrecedingByRef)); } return builder.ToImmutableAndFree(); }
public static bool IsMissingMethod(this MethodSymbol method) => (method == null) || (method is IErrorMethodSymbol && ((IErrorMethodSymbol)method).ErrorKind == ErrorMethodKind.Missing);
//public static bool IsIndexedPropertyAccessor(this MethodSymbol methodSymbol) //{ // var propertyOrEvent = methodSymbol.AssociatedSymbol; // return ((object)propertyOrEvent != null) && propertyOrEvent.IsIndexedProperty(); //} public static bool IsOperator(this MethodSymbol methodSymbol) { return(methodSymbol.MethodKind == MethodKind.UserDefinedOperator || methodSymbol.MethodKind == MethodKind.Conversion); }
public GenericMethodInstanceReference(MethodSymbol underlyingMethod) : base(underlyingMethod) { }
//internal static bool HasUnsafeParameter(this Symbol member) //{ // foreach (TypeSymbol parameterType in member.GetParameterTypes()) // { // if (parameterType.IsUnsafe()) // { // return true; // } // } // return false; //} public static bool IsAccessor(this MethodSymbol methodSymbol) { return((object)methodSymbol.AssociatedSymbol != null); }
/// <summary> /// Checks whether signatures of two methods match exactly so one can override the second. /// </summary> public static bool SignaturesMatch(this MethodSymbol a, MethodSymbol b) { Contract.ThrowIfNull(a); Contract.ThrowIfNull(b); if (a.ReturnType != b.ReturnType) { return false; } var ps1 = a.Parameters; var ps2 = b.Parameters; if (ps1.Length != ps2.Length) { return false; } for (int i = 0; i < ps1.Length; i++) { var p1 = ps1[i]; var p2 = ps2[i]; if (p1.Type != p2.Type || p1.RefKind != p2.RefKind) { return false; } } // return true; }
void EmitDisposeAndClean(CodeGenerator cg) { // enumerator.Dispose() if (_disposeMethod != null) { // TODO: if (enumerator != null) if (_enumeratorLoc.Type.IsValueType) cg.Builder.EmitLocalAddress(_enumeratorLoc); else cg.Builder.EmitLocalLoad(_enumeratorLoc); cg.EmitCall(_disposeMethod.IsVirtual ? ILOpCode.Callvirt : ILOpCode.Call, _disposeMethod) .Expect(SpecialType.System_Void); } //// enumerator = null; //if (!_enumeratorLoc.Type.IsValueType) //{ // cg.Builder.EmitNullConstant(); // cg.Builder.EmitLocalStore(_enumeratorLoc); //} // cg.ReturnTemporaryLocal(_enumeratorLoc); _enumeratorLoc = null; // unbind _moveNextMethod = null; _disposeMethod = null; _currentValue = null; _currentKey = null; _current = null; }
void EmitPhpCtor(MethodSymbol ctor, Emit.PEModuleBuilder module) { if (ctor == null) return; // static class Debug.Assert(ctor.MethodKind == MethodKind.Constructor); module.SetMethodBody(ctor, MethodGenerator.GenerateMethodBody(module, ctor, il => { Debug.Assert(SpecialParameterSymbol.IsContextParameter(ctor.Parameters[0])); var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), OptimizationLevel.Release, false, this, new ParamPlace(ctor.Parameters[0]), new ArgPlace(this, 0)); // call .phpnew var phpnew = this.InitializeInstanceMethod; cg.EmitPop(cg.EmitThisCall(phpnew, ctor)); // call __construct var phpctor = this.ResolvePhpCtor(true); cg.EmitPop(cg.EmitThisCall(phpctor, ctor)); Debug.Assert(ctor.ReturnsVoid); cg.EmitRet(ctor.ReturnType); }, null, DiagnosticBag.GetInstance(), false)); }
/// <summary> /// Calculates override cost, i.e. whether the override is possible and its value. /// In case of more possible overrides, the one with better cost is selected. /// </summary> /// <param name="method">Source method.</param> /// <param name="basemethod">A hypothetical base method.</param> /// <returns></returns> public static ConversionCost OverrideCost(SourceMethodSymbol method, MethodSymbol basemethod) { Contract.ThrowIfNull(method); Contract.ThrowIfNull(basemethod); // if (method.IsStatic || basemethod.IsStatic || basemethod.IsSealed || (!basemethod.IsVirtual && !basemethod.IsAbstract) || // not abstract or virtual method.Name.EqualsOrdinalIgnoreCase(basemethod.Name) == false || method.DeclaredAccessibility == Accessibility.Private || basemethod.DeclaredAccessibility == Accessibility.Private) { return ConversionCost.NoConversion; } if (method.ReturnType != basemethod.ReturnType) { return ConversionCost.ImplicitCast; } // var ps = method.Parameters; var psbase = basemethod.Parameters; // var result = ConversionCost.Pass; // NOTE: there shouldn't be any implicit parameters (Context and LateBoundType are known from this instance) for (int i = 0; i < ps.Length; i++) { if (i < psbase.Length) { var p = ps[i]; var pbase = psbase[i]; if (p.Type != pbase.Type) { if (p.Type.IsOfType(pbase.Type)) { result |= ConversionCost.ImplicitCast; } else { result |= ConversionCost.NoConversion; } } } else { result |= ConversionCost.TooManyArgs; } } // if (ps.Length < psbase.Length) { result |= ConversionCost.MissingArgs; } // return result; }
void ResolveBaseCtorAndParameters() { if (!_parameters.IsDefaultOrEmpty) return; // var phpctor = this.PhpCtor; // this tells us what parameters are provided to resolve base .ctor that can be called var basephpnew = (this.ContainingType.BaseType as IPhpTypeSymbol)?.InitializeInstanceMethod; // base..phpnew() to be called if provided var basectors = (basephpnew != null) ? ImmutableArray.Create(basephpnew) : this.ContainingType.BaseType.InstanceConstructors .Where(c => c.DeclaredAccessibility != Accessibility.Private) .OrderByDescending(c => c.ParameterCount) // longest ctors first .AsImmutable(); // Context <ctx> var ps = new List<ParameterSymbol>(1) { new SpecialParameterSymbol(this, DeclaringCompilation.CoreTypes.Context, SpecialParameterSymbol.ContextName, 0) // Context <ctx> }; var givenparams = (phpctor != null) ? phpctor.Parameters.Where(p => !p.IsImplicitlyDeclared).ToArray() : EmptyArray<ParameterSymbol>.Instance; // find best matching basector foreach (var c in basectors) { var calledparams = c.Parameters.Where(p => !p.IsImplicitlyDeclared).ToArray(); if (CanBePassedTo(givenparams, calledparams)) { // we have found base constructor with most parameters we can call with given parameters _lazyBaseCtor = c; break; } } if (_lazyBaseCtor == null) { throw new InvalidOperationException("Base .ctor cannot be resolved with provided constructor."); } // Debug.Assert(SpecialParameterSymbol.IsContextParameter(ps[0])); Debug.Assert(_lazyBaseCtor != null && !_lazyBaseCtor.IsStatic); foreach (var p in _lazyBaseCtor.Parameters) { if (SpecialParameterSymbol.IsContextParameter(p)) continue; ps.Add(new SynthesizedParameterSymbol(this, p.Type, ps.Count, p.RefKind, p.Name, explicitDefaultConstantValue: p.ExplicitDefaultConstantValue)); } // _parameters = ps.AsImmutable(); }
internal SubstitutedParameterSymbol(MethodSymbol containingSymbol, TypeMap map, ParameterSymbol originalParameter) : this((Symbol)containingSymbol, map, originalParameter) { }
internal virtual TypeSymbol EmitDirectCall(CodeGenerator cg, ILOpCode opcode, MethodSymbol method) { // TODO: emit check the routine is declared // <ctx>.AssertFunctionDeclared var arguments = _arguments.Select(a => a.Value).ToImmutableArray(); return cg.EmitCall(opcode, method, this.Instance, arguments); }
//internal override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder<SynthesizedAttributeData> attributes) //{ // // Emit [Dynamic] on synthesized parameter symbols when the original parameter was dynamic // // in order to facilitate debugging. In the case the necessary attributes are missing // // this is a no-op. Emitting an error here, or when the original parameter was bound, would // // adversely effect the compilation or potentially change overload resolution. // var compilation = this.DeclaringCompilation; // if (Type.ContainsDynamic() && compilation.HasDynamicEmitAttributes()) // { // var boolType = compilation.GetSpecialType(SpecialType.System_Boolean); // var diagnostic = boolType.GetUseSiteDiagnostic(); // if ((diagnostic == null) || (diagnostic.Severity != DiagnosticSeverity.Error)) // { // AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.Type, this.CustomModifiers.Length, this.RefKind)); // } // } //} /// <summary> /// For each parameter of a source method, construct a corresponding synthesized parameter /// for a destination method. /// </summary> /// <param name="sourceMethod">Has parameters.</param> /// <param name="destinationMethod">Needs parameters.</param> /// <returns>Synthesized parameters to add to destination method.</returns> internal static ImmutableArray <ParameterSymbol> DeriveParameters(MethodSymbol sourceMethod, MethodSymbol destinationMethod) { var builder = ArrayBuilder <ParameterSymbol> .GetInstance(); foreach (var oldParam in sourceMethod.Parameters) { //same properties as the old one, just change the owner builder.Add(new SynthesizedParameterSymbol(destinationMethod, oldParam.Type, oldParam.Ordinal, oldParam.RefKind, oldParam.Name, false, oldParam.CustomModifiers, oldParam.CountOfCustomModifiersPrecedingByRef)); } return(builder.ToImmutableAndFree()); }