private ParameterSymbol MakeParameterSymbol(int ordinal, string name, ParameterSymbol sourceParameter) { return(new SynthesizedParameterSymbol(this, sourceParameter.Type, ordinal, sourceParameter.RefKind, name, sourceParameter.CustomModifiers)); }
internal EEMethodSymbol( EENamedTypeSymbol container, string name, Location location, MethodSymbol sourceMethod, ImmutableArray <LocalSymbol> sourceLocals, ImmutableArray <LocalSymbol> sourceLocalsForBinding, ImmutableDictionary <string, DisplayClassVariable> sourceDisplayClassVariables, GenerateMethodBody generateMethodBody) { Debug.Assert(sourceMethod.IsDefinition); Debug.Assert(sourceMethod.ContainingSymbol == container.SubstitutedSourceType.OriginalDefinition); Debug.Assert(sourceLocals.All(l => l.ContainingSymbol == sourceMethod)); _container = container; _name = name; _locations = ImmutableArray.Create(location); // What we want is to map all original type parameters to the corresponding new type parameters // (since the old ones have the wrong owners). Unfortunately, we have a circular dependency: // 1) Each new type parameter requires the entire map in order to be able to construct its constraint list. // 2) The map cannot be constructed until all new type parameters exist. // Our solution is to pass each new type parameter a lazy reference to the type map. We then // initialize the map as soon as the new type parameters are available - and before they are // handed out - so that there is never a period where they can require the type map and find // it uninitialized. var sourceMethodTypeParameters = sourceMethod.TypeParameters; var allSourceTypeParameters = container.SourceTypeParameters.Concat(sourceMethodTypeParameters); var getTypeMap = new Func <TypeMap>(() => this.TypeMap); _typeParameters = sourceMethodTypeParameters.SelectAsArray( (tp, i, arg) => (TypeParameterSymbol) new EETypeParameterSymbol(this, tp, i, getTypeMap), (object)null); _allTypeParameters = container.TypeParameters.Concat(_typeParameters); this.TypeMap = new TypeMap(allSourceTypeParameters, _allTypeParameters); EENamedTypeSymbol.VerifyTypeParameters(this, _typeParameters); var substitutedSourceType = container.SubstitutedSourceType; this.SubstitutedSourceMethod = sourceMethod.AsMember(substitutedSourceType); if (sourceMethod.Arity > 0) { this.SubstitutedSourceMethod = this.SubstitutedSourceMethod.Construct(_typeParameters.As <TypeSymbol>()); } TypeParameterChecker.Check(this.SubstitutedSourceMethod, _allTypeParameters); // Create a map from original parameter to target parameter. var parameterBuilder = ArrayBuilder <ParameterSymbol> .GetInstance(); var substitutedSourceThisParameter = this.SubstitutedSourceMethod.ThisParameter; var substitutedSourceHasThisParameter = (object)substitutedSourceThisParameter != null; if (substitutedSourceHasThisParameter) { _thisParameter = MakeParameterSymbol(0, GeneratedNames.ThisProxyFieldName(), substitutedSourceThisParameter); Debug.Assert(_thisParameter.Type == this.SubstitutedSourceMethod.ContainingType); parameterBuilder.Add(_thisParameter); } var ordinalOffset = (substitutedSourceHasThisParameter ? 1 : 0); foreach (var substitutedSourceParameter in this.SubstitutedSourceMethod.Parameters) { var ordinal = substitutedSourceParameter.Ordinal + ordinalOffset; Debug.Assert(ordinal == parameterBuilder.Count); var parameter = MakeParameterSymbol(ordinal, substitutedSourceParameter.Name, substitutedSourceParameter); parameterBuilder.Add(parameter); } _parameters = parameterBuilder.ToImmutableAndFree(); var localsBuilder = ArrayBuilder <LocalSymbol> .GetInstance(); var localsMap = PooledDictionary <LocalSymbol, LocalSymbol> .GetInstance(); foreach (var sourceLocal in sourceLocals) { var local = sourceLocal.ToOtherMethod(this, this.TypeMap); localsMap.Add(sourceLocal, local); localsBuilder.Add(local); } this.Locals = localsBuilder.ToImmutableAndFree(); localsBuilder = ArrayBuilder <LocalSymbol> .GetInstance(); foreach (var sourceLocal in sourceLocalsForBinding) { LocalSymbol local; if (!localsMap.TryGetValue(sourceLocal, out local)) { local = sourceLocal.ToOtherMethod(this, this.TypeMap); localsMap.Add(sourceLocal, local); } localsBuilder.Add(local); } this.LocalsForBinding = localsBuilder.ToImmutableAndFree(); // Create a map from variable name to display class field. var displayClassVariables = PooledDictionary <string, DisplayClassVariable> .GetInstance(); foreach (var pair in sourceDisplayClassVariables) { var variable = pair.Value; var displayClassInstanceFromLocal = variable.DisplayClassInstance as DisplayClassInstanceFromLocal; var displayClassInstance = (displayClassInstanceFromLocal == null) ? (DisplayClassInstance) new DisplayClassInstanceFromThis(_parameters[0]) : new DisplayClassInstanceFromLocal((EELocalSymbol)localsMap[displayClassInstanceFromLocal.Local]); variable = variable.SubstituteFields(displayClassInstance, this.TypeMap); displayClassVariables.Add(pair.Key, variable); } _displayClassVariables = displayClassVariables.ToImmutableDictionary(); displayClassVariables.Free(); localsMap.Free(); _generateMethodBody = generateMethodBody; }
internal static BoundBlock ConstructFieldLikeEventAccessorBody_Regular( SourceEventSymbol eventSymbol, bool isAddMethod, CSharpCompilation compilation, BindingDiagnosticBag diagnostics ) { CSharpSyntaxNode syntax = eventSymbol.CSharpSyntaxNode; TypeSymbol delegateType = eventSymbol.Type; MethodSymbol accessor = isAddMethod ? eventSymbol.AddMethod : eventSymbol.RemoveMethod; ParameterSymbol thisParameter = accessor.ThisParameter; TypeSymbol boolType = compilation.GetSpecialType(SpecialType.System_Boolean); SpecialMember updateMethodId = isAddMethod ? SpecialMember.System_Delegate__Combine : SpecialMember.System_Delegate__Remove; MethodSymbol updateMethod = (MethodSymbol)compilation.GetSpecialTypeMember( updateMethodId ); BoundStatement @return = new BoundReturnStatement( syntax, refKind: RefKind.None, expressionOpt: null ) { WasCompilerGenerated = true }; if (updateMethod == null) { MemberDescriptor memberDescriptor = SpecialMembers.GetDescriptor(updateMethodId); diagnostics.Add( new CSDiagnostic( new CSDiagnosticInfo( ErrorCode.ERR_MissingPredefinedMember, memberDescriptor.DeclaringTypeMetadataName, memberDescriptor.Name ), syntax.Location ) ); return(BoundBlock.SynthesizedNoLocals(syntax, @return)); } Binder.ReportUseSite(updateMethod, diagnostics, syntax); BoundThisReference fieldReceiver = eventSymbol.IsStatic ? null : new BoundThisReference(syntax, thisParameter.Type) { WasCompilerGenerated = true }; BoundFieldAccess boundBackingField = new BoundFieldAccess( syntax, receiver: fieldReceiver, fieldSymbol: eventSymbol.AssociatedField, constantValueOpt: null ) { WasCompilerGenerated = true }; BoundParameter boundParameter = new BoundParameter( syntax, parameterSymbol: accessor.Parameters[0] ) { WasCompilerGenerated = true }; BoundExpression delegateUpdate; MethodSymbol compareExchangeMethod = (MethodSymbol)compilation.GetWellKnownTypeMember( WellKnownMember.System_Threading_Interlocked__CompareExchange_T ); if ((object)compareExchangeMethod == null) { // (DelegateType)Delegate.Combine(_event, value) delegateUpdate = BoundConversion.SynthesizedNonUserDefined( syntax, operand: BoundCall.Synthesized( syntax, receiverOpt: null, method: updateMethod, arguments: ImmutableArray.Create <BoundExpression>( boundBackingField, boundParameter ) ), conversion: Conversion.ExplicitReference, type: delegateType ); // _event = (DelegateType)Delegate.Combine(_event, value); BoundStatement eventUpdate = new BoundExpressionStatement( syntax, expression: new BoundAssignmentOperator( syntax, left: boundBackingField, right: delegateUpdate, type: delegateType ) { WasCompilerGenerated = true } ) { WasCompilerGenerated = true }; return(BoundBlock.SynthesizedNoLocals( syntax, statements: ImmutableArray.Create <BoundStatement>(eventUpdate, @return) )); } compareExchangeMethod = compareExchangeMethod.Construct( ImmutableArray.Create <TypeSymbol>(delegateType) ); Binder.ReportUseSite(compareExchangeMethod, diagnostics, syntax); GeneratedLabelSymbol loopLabel = new GeneratedLabelSymbol("loop"); const int numTemps = 3; LocalSymbol[] tmps = new LocalSymbol[numTemps]; BoundLocal[] boundTmps = new BoundLocal[numTemps]; for (int i = 0; i < numTemps; i++) { tmps[i] = new SynthesizedLocal( accessor, TypeWithAnnotations.Create(delegateType), SynthesizedLocalKind.LoweringTemp ); boundTmps[i] = new BoundLocal(syntax, tmps[i], null, delegateType) { WasCompilerGenerated = true }; } // tmp0 = _event; BoundStatement tmp0Init = new BoundExpressionStatement( syntax, expression: new BoundAssignmentOperator( syntax, left: boundTmps[0], right: boundBackingField, type: delegateType ) { WasCompilerGenerated = true } ) { WasCompilerGenerated = true }; // LOOP: BoundStatement loopStart = new BoundLabelStatement(syntax, label: loopLabel) { WasCompilerGenerated = true }; // tmp1 = tmp0; BoundStatement tmp1Update = new BoundExpressionStatement( syntax, expression: new BoundAssignmentOperator( syntax, left: boundTmps[1], right: boundTmps[0], type: delegateType ) { WasCompilerGenerated = true } ) { WasCompilerGenerated = true }; // (DelegateType)Delegate.Combine(tmp1, value) delegateUpdate = BoundConversion.SynthesizedNonUserDefined( syntax, operand: BoundCall.Synthesized( syntax, receiverOpt: null, method: updateMethod, arguments: ImmutableArray.Create <BoundExpression>(boundTmps[1], boundParameter) ), conversion: Conversion.ExplicitReference, type: delegateType ); // tmp2 = (DelegateType)Delegate.Combine(tmp1, value); BoundStatement tmp2Update = new BoundExpressionStatement( syntax, expression: new BoundAssignmentOperator( syntax, left: boundTmps[2], right: delegateUpdate, type: delegateType ) { WasCompilerGenerated = true } ) { WasCompilerGenerated = true }; // Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1) BoundExpression compareExchange = BoundCall.Synthesized( syntax, receiverOpt: null, method: compareExchangeMethod, arguments: ImmutableArray.Create <BoundExpression>( boundBackingField, boundTmps[2], boundTmps[1] ) ); // tmp0 = Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1); BoundStatement tmp0Update = new BoundExpressionStatement( syntax, expression: new BoundAssignmentOperator( syntax, left: boundTmps[0], right: compareExchange, type: delegateType ) { WasCompilerGenerated = true } ) { WasCompilerGenerated = true }; // tmp0 == tmp1 // i.e. exit when they are equal, jump to start otherwise BoundExpression loopExitCondition = new BoundBinaryOperator( syntax, operatorKind: BinaryOperatorKind.ObjectEqual, left: boundTmps[0], right: boundTmps[1], constantValueOpt: null, methodOpt: null, resultKind: LookupResultKind.Viable, type: boolType ) { WasCompilerGenerated = true }; // branchfalse (tmp0 == tmp1) LOOP BoundStatement loopEnd = new BoundConditionalGoto( syntax, condition: loopExitCondition, jumpIfTrue: false, label: loopLabel ) { WasCompilerGenerated = true }; return(new BoundBlock( syntax, locals: tmps.AsImmutable(), statements: ImmutableArray.Create <BoundStatement>( tmp0Init, loopStart, tmp1Update, tmp2Update, tmp0Update, loopEnd, @return ) ) { WasCompilerGenerated = true }); }
public override Symbol VisitParameter(ParameterSymbol parameter) { // Should never reach here. Should be matched as a result of matching the container. throw ExceptionUtilities.Unreachable; }
public RetargetingPropertyParameterSymbol(RetargetingPropertySymbol retargetingProperty, ParameterSymbol underlyingParameter) : base(underlyingParameter) { Debug.Assert((object)retargetingProperty != null); _retargetingProperty = retargetingProperty; }
protected ProblemCollection CheckParameter([NotNull] Parameter parameter) { var symbol = new ParameterSymbol(parameter); return CheckSymbol(symbol); }
/// <summary> /// Called when visiting a <see cref="ParameterSymbol" />; Override this with specific /// implementation; Calling default <see cref="DefaultVisit" /> if it's not overridden /// </summary> /// <param name="symbol">The visited symbol</param> /// <param name="argument">Additional argument</param> /// <returns></returns> public virtual TResult VisitParameter(ParameterSymbol symbol, TArgument argument) { return(DefaultVisit(symbol, argument)); }
protected RetargetingParameterSymbol(ParameterSymbol underlyingParameter) { Debug.Assert(!(underlyingParameter is RetargetingParameterSymbol)); this.underlyingParameter = underlyingParameter; }
private static void GenerateEvent(ScriptGenerator generator, string typeName, EventSymbol eventSymbol) { ScriptTextWriter writer = generator.Writer; ParameterSymbol valueParameter = eventSymbol.Parameters[0]; string eventName = eventSymbol.GeneratedName; string fieldName = eventName; if (eventSymbol.DefaultImplementation) { fieldName = "__" + Utility.CreateCamelCaseName(eventSymbol.Name); Debug.Assert(eventSymbol.Parent.Type == SymbolType.Class); Symbol fieldSymbol = ((ClassSymbol)eventSymbol.Parent).GetMember(fieldName); Debug.Assert((fieldSymbol != null) && (fieldSymbol.Type == SymbolType.Field)); fieldName = fieldSymbol.GeneratedName; } string fieldReference; if ((eventSymbol.Visibility & MemberVisibility.Static) == 0) { fieldReference = "this."; } else { fieldReference = typeName + "."; } fieldReference += fieldName; bool instanceMember = true; if ((eventSymbol.Visibility & MemberVisibility.Static) != 0) { instanceMember = false; writer.Write(typeName); writer.Write("."); } writer.Write("add_"); writer.Write(eventName); if (instanceMember) { writer.Write(": "); } else { writer.Write(" = "); } writer.Write("function("); writer.Write(valueParameter.GeneratedName); writer.WriteLine(") {"); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, eventSymbol); } if (eventSymbol.DefaultImplementation) { writer.Write(fieldReference); writer.Write(" = ss.bindAdd("); writer.Write(fieldReference); writer.Write(", "); writer.Write(valueParameter.GeneratedName); writer.WriteLine(");"); } else { CodeGenerator.GenerateScript(generator, eventSymbol, /* add */ true); } writer.Indent--; writer.Write("}"); if (instanceMember == false) { writer.WriteLine(";"); } if (instanceMember) { writer.WriteLine(","); } else { writer.Write(typeName); writer.Write("."); } writer.Write("remove_"); writer.Write(eventName); if (instanceMember) { writer.Write(": "); } else { writer.Write(" = "); } writer.Write("function("); writer.Write(valueParameter.GeneratedName); writer.WriteLine(") {"); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, eventSymbol); } if (eventSymbol.DefaultImplementation) { writer.Write(fieldReference); writer.Write(" = ss.bindSub("); writer.Write(fieldReference); writer.Write(", "); writer.Write(valueParameter.GeneratedName); writer.WriteLine(");"); } else { CodeGenerator.GenerateScript(generator, eventSymbol, /* add */ false); } writer.Indent--; writer.Write("}"); if (instanceMember == false) { writer.WriteLine(";"); } }
private static void GenerateIndexer(ScriptGenerator generator, string typeName, PropertySymbol indexerSymbol) { if (indexerSymbol.IsAbstract) { return; } Debug.Assert((indexerSymbol.Visibility & MemberVisibility.Static) == 0); ScriptTextWriter writer = generator.Writer; writer.Write("get_"); writer.Write(indexerSymbol.GeneratedName); writer.Write(": function("); for (int i = 0; i < indexerSymbol.Parameters.Count - 1; i++) { ParameterSymbol parameterSymbol = indexerSymbol.Parameters[i]; if (i > 0) { writer.Write(", "); } writer.Write(parameterSymbol.GeneratedName); } writer.WriteLine(") {"); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, indexerSymbol); } CodeGenerator.GenerateScript(generator, (IndexerSymbol)indexerSymbol, /* getter */ true); writer.Indent--; writer.Write("}"); if (indexerSymbol.IsReadOnly == false) { writer.WriteLine(","); writer.Write("set_"); writer.Write(indexerSymbol.GeneratedName); writer.Write(": function("); for (int i = 0; i < indexerSymbol.Parameters.Count; i++) { ParameterSymbol parameterSymbol = indexerSymbol.Parameters[i]; if (i > 0) { writer.Write(", "); } writer.Write(parameterSymbol.GeneratedName); } writer.WriteLine(") {"); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, indexerSymbol); } CodeGenerator.GenerateScript(generator, (IndexerSymbol)indexerSymbol, /* getter */ false); writer.Write("return "); writer.Write(indexerSymbol.Parameters[indexerSymbol.Parameters.Count - 1].GeneratedName); writer.WriteLine(";"); writer.Indent--; writer.Write("}"); } }
protected override void EnterParameter(ParameterSymbol parameter) { // parameters are NOT intitially assigned here - if that is a problem, then // the parameters must be captured. MakeSlot(parameter); }
public override Symbol VisitParameter(ParameterSymbol parameter) { // Should never reach here. Should be matched as a result of matching the container. throw new InvalidOperationException(); }
internal bool DeriveUseSiteDiagnosticFromParameter(ref DiagnosticInfo result, ParameterSymbol param) { return(DeriveUseSiteDiagnosticFromType(ref result, param.Type) || DeriveUseSiteDiagnosticFromCustomModifiers(ref result, param.CustomModifiers)); }
protected virtual void ReportUnassignedOutParameter(ParameterSymbol parameter, SyntaxNode node, Location location) { if (Diagnostics != null) { if (location == null) { location = new SourceLocation(tree, node); } Diagnostics.Add(ErrorCode.ERR_ParamUnassigned, location, parameter.Name); } }
private void LoadSignature() { var moduleSymbol = _containingType.ContainingPEModule; SignatureHeader signatureHeader; BadImageFormatException mrEx; ParamInfo <TypeSymbol>[] paramInfo = new MetadataDecoder(moduleSymbol, this).GetSignatureForMethod(_handle, out signatureHeader, out mrEx); bool makeBad = (mrEx != null); // If method is not generic, let's assign empty list for type parameters if (!signatureHeader.IsGeneric && _lazyTypeParameters.IsDefault) { ImmutableInterlocked.InterlockedCompareExchange(ref _lazyTypeParameters, ImmutableArray <TypeParameterSymbol> .Empty, default(ImmutableArray <TypeParameterSymbol>)); } int count = paramInfo.Length - 1; ImmutableArray <ParameterSymbol> @params; bool isBadParameter; if (count > 0) { ParameterSymbol[] parameterCreation = new ParameterSymbol[count]; for (int i = 0; i < count; i++) { parameterCreation[i] = new PEParameterSymbol(moduleSymbol, this, i, paramInfo[i + 1], out isBadParameter); if (isBadParameter) { makeBad = true; } } @params = parameterCreation.AsImmutableOrNull(); } else { @params = ImmutableArray <ParameterSymbol> .Empty; } // paramInfo[0] contains information about return "parameter" Debug.Assert(!paramInfo[0].IsByRef); // Dynamify object type if necessary paramInfo[0].Type = paramInfo[0].Type.AsDynamicIfNoPia(_containingType); var returnParam = new PEParameterSymbol(moduleSymbol, this, 0, paramInfo[0], out isBadParameter); if (makeBad || isBadParameter) { var old = Interlocked.CompareExchange(ref _lazyUseSiteDiagnostic, new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this), CSDiagnosticInfo.EmptyErrorInfo); Debug.Assert((object)old == (object)CSDiagnosticInfo.EmptyErrorInfo || ((object)old != null && old.Code == (int)ErrorCode.ERR_BindToBogus && old.Arguments.Length == 1 && old.Arguments[0] == (object)this)); } var signature = new SignatureData(signatureHeader, @params, returnParam); Interlocked.CompareExchange(ref _lazySignature, signature, null); }
private void LoadSignature() { var moduleSymbol = this.containingType.ContainingPEModule; byte callingConvention; BadImageFormatException mrEx; MetadataDecoder.ParamInfo[] paramInfo = new MetadataDecoder(moduleSymbol, this).GetSignatureForMethod(this.handle, out callingConvention, out mrEx); bool makeBad = (mrEx != null); // If method is not generic, let's assign empty list for type parameters if (!SignatureHeader.IsGeneric(callingConvention) && lazyTypeParameters.IsDefault) { ImmutableInterlocked.InterlockedCompareExchange(ref lazyTypeParameters, ImmutableArray<TypeParameterSymbol>.Empty, default(ImmutableArray<TypeParameterSymbol>)); } int count = paramInfo.Length - 1; ImmutableArray<ParameterSymbol> @params; bool isBadParameter; if (count > 0) { ParameterSymbol[] parameterCreation = new ParameterSymbol[count]; for (int i = 0; i < count; i++) { parameterCreation[i] = new PEParameterSymbol(moduleSymbol, this, i, paramInfo[i + 1], out isBadParameter); if (isBadParameter) { makeBad = true; } } @params = parameterCreation.AsImmutableOrNull(); } else { @params = ImmutableArray<ParameterSymbol>.Empty; } // paramInfo[0] contains information about return "parameter" Debug.Assert(!paramInfo[0].IsByRef); // Dynamify object type if necessary paramInfo[0].Type = paramInfo[0].Type.AsDynamicIfNoPia(this.containingType); var returnParam = new PEParameterSymbol(moduleSymbol, this, 0, paramInfo[0], out isBadParameter); if (makeBad || isBadParameter) { var old = Interlocked.CompareExchange(ref lazyUseSiteDiagnostic, new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this), CSDiagnosticInfo.EmptyErrorInfo); Debug.Assert((object)old == (object)CSDiagnosticInfo.EmptyErrorInfo || ((object)old != null && old.Code == (int)ErrorCode.ERR_BindToBogus && old.Arguments.Length == 1 && old.Arguments[0] == (object)this)); } var signature = new SignatureData(callingConvention, @params, returnParam); Interlocked.CompareExchange(ref lazySignature, signature, null); }
public RetargetingMethodParameterSymbol(RetargetingMethodSymbol retargetingMethod, ParameterSymbol underlyingParameter) : base(underlyingParameter) { Debug.Assert((object)retargetingMethod != null); _retargetingMethod = retargetingMethod; }
protected internal override object VisitParameter(ParameterSymbol symbol, ArrayBuilder<SymbolDescriptionPart> builder) { //decorations are handled by methods and properties (for consistency with type parameters) builder.Add(new SymbolDescriptionPart { Kind = SymbolDescriptionPartKind.Identifier, Text = symbol.Name, }); return null; }
public RetargetingPropertyParameterSymbol(RetargetingPropertySymbol retargetingProperty, ParameterSymbol underlyingParameter) : base(underlyingParameter) { Debug.Assert((object)retargetingProperty != null); _retargetingProperty = retargetingProperty; }
private static void AppendParameterSymbolInfo(this ICollection<SymbolMarkupToken> markup, ParameterSymbol symbol) { markup.AppendType(symbol.ValueType); markup.AppendSpace(); markup.AppendParameterName(symbol.Name); }
protected RetargetingParameterSymbol(ParameterSymbol underlyingParameter) : base(underlyingParameter) { Debug.Assert(!(underlyingParameter is RetargetingParameterSymbol)); }
private static ImmutableArray<ParameterSymbol> GetParameters( PEModuleSymbol moduleSymbol, PEPropertySymbol property, MetadataDecoder.ParamInfo[] propertyParams, MetadataDecoder.ParamInfo[] accessorParams, out bool anyParameterIsBad) { anyParameterIsBad = false; // First parameter is the property type. if (propertyParams.Length < 2) { return ImmutableArray<ParameterSymbol>.Empty; } var numAccessorParams = accessorParams.Length; var parameters = new ParameterSymbol[propertyParams.Length - 1]; for (int i = 1; i < propertyParams.Length; i++) // from 1 to skip property/return type { // NOTE: this is a best guess at the Dev10 behavior. The actual behavior is // in the unmanaged helper code that Dev10 uses to load the metadata. var propertyParam = propertyParams[i]; var paramHandle = i < numAccessorParams ? accessorParams[i].Handle : propertyParam.Handle; var ordinal = i - 1; bool isBad; parameters[ordinal] = new PEParameterSymbol(moduleSymbol, property, ordinal, paramHandle, propertyParam, out isBad); if (isBad) { anyParameterIsBad = true; } } return parameters.AsImmutableOrNull(); }
private void EmitParameter(ParameterSymbol parameterSymbol) { // local function bool IsSecure(SyntaxBase?value) => value is BooleanLiteralSyntax boolLiteral && boolLiteral.Value; if (!(SyntaxHelper.TryGetPrimitiveType(parameterSymbol.DeclaringParameter) is TypeSymbol primitiveType)) { // this should have been caught by the type checker long ago throw new ArgumentException($"Unable to find primitive type for parameter {parameterSymbol.Name}"); } writer.WriteStartObject(); if (parameterSymbol.DeclaringParameter.Decorators.Any()) { var parameterType = SyntaxFactory.CreateStringLiteral(primitiveType.Name); var parameterObject = SyntaxFactory.CreateObject(SyntaxFactory.CreateObjectProperty("type", parameterType).AsEnumerable()); if (parameterSymbol.Modifier is ParameterDefaultValueSyntax defaultValueSyntax) { parameterObject.MergeProperty("defaultValue", defaultValueSyntax.DefaultValue); } foreach (var decoratorSyntax in parameterSymbol.DeclaringParameter.Decorators.Reverse()) { var symbol = this.context.SemanticModel.GetSymbolInfo(decoratorSyntax.Expression); if (symbol is FunctionSymbol decoratorSymbol) { var argumentTypes = decoratorSyntax.Arguments .Select(argument => this.context.SemanticModel.TypeManager.GetTypeInfo(argument)) .ToArray(); // There should be exact one matching decorator since there's no errors. Decorator decorator = this.context.SemanticModel.Root.ImportedNamespaces .SelectMany(ns => ns.Value.Type.DecoratorResolver.GetMatches(decoratorSymbol, argumentTypes)) .Single(); parameterObject = decorator.Evaluate(decoratorSyntax, primitiveType, parameterObject); } } foreach (var property in parameterObject.Properties) { if (property.TryGetKeyText() is string propertyName) { this.emitter.EmitProperty(propertyName, property.Value); } } } else { // TODO: remove this before the 0.3 release. switch (parameterSymbol.Modifier) { case null: this.emitter.EmitProperty("type", GetTemplateTypeName(primitiveType, secure: false)); break; case ParameterDefaultValueSyntax defaultValueSyntax: this.emitter.EmitProperty("type", GetTemplateTypeName(primitiveType, secure: false)); this.emitter.EmitProperty("defaultValue", defaultValueSyntax.DefaultValue); break; case ObjectSyntax modifierSyntax: // this would throw on duplicate properties in the object node - we are relying on emitter checking for errors at the beginning var properties = modifierSyntax.ToKnownPropertyValueDictionary(); this.emitter.EmitProperty("type", GetTemplateTypeName(primitiveType, IsSecure(properties.TryGetValue("secure")))); // relying on validation here as well (not all of the properties are valid in all contexts) foreach (string modifierPropertyName in ParameterModifierPropertiesToEmitDirectly) { this.emitter.EmitOptionalPropertyExpression(modifierPropertyName, properties.TryGetValue(modifierPropertyName)); } this.emitter.EmitOptionalPropertyExpression("defaultValue", properties.TryGetValue(LanguageConstants.ParameterDefaultPropertyName)); this.emitter.EmitOptionalPropertyExpression("allowedValues", properties.TryGetValue(LanguageConstants.ParameterAllowedPropertyName)); break; } } writer.WriteEndObject(); }
public EmbeddedParameter(EmbeddedTypesManager.CommonEmbeddedMember containingPropertyOrMethod, ParameterSymbol underlyingParameter) : base(containingPropertyOrMethod, underlyingParameter) { Debug.Assert(underlyingParameter.IsDefinition); }
public void Test1() { var assemblies = MetadataTestHelpers.GetSymbolsForReferences(new[] { TestReferences.SymbolsTests.CustomModifiers.Modifiers.dll, TestReferences.NetFx.v4_0_21006.mscorlib }); var modifiersModule = assemblies[0].Modules[0]; var modifiers = modifiersModule.GlobalNamespace.GetTypeMembers("Modifiers").Single(); FieldSymbol f0 = modifiers.GetMembers("F0").OfType <FieldSymbol>().Single(); Assert.Equal(1, f0.TypeWithAnnotations.CustomModifiers.Length); var f0Mod = f0.TypeWithAnnotations.CustomModifiers[0]; Assert.True(f0Mod.IsOptional); Assert.Equal("System.Runtime.CompilerServices.IsConst", f0Mod.Modifier.ToTestDisplayString()); MethodSymbol m1 = modifiers.GetMembers("F1").OfType <MethodSymbol>().Single(); ParameterSymbol p1 = m1.Parameters[0]; ParameterSymbol p2 = modifiers.GetMembers("F2").OfType <MethodSymbol>().Single().Parameters[0]; ParameterSymbol p4 = modifiers.GetMembers("F4").OfType <MethodSymbol>().Single().Parameters[0]; MethodSymbol m5 = modifiers.GetMembers("F5").OfType <MethodSymbol>().Single(); ParameterSymbol p5 = m5.Parameters[0]; ParameterSymbol p6 = modifiers.GetMembers("F6").OfType <MethodSymbol>().Single().Parameters[0]; MethodSymbol m7 = modifiers.GetMembers("F7").OfType <MethodSymbol>().Single(); Assert.Equal(0, m1.ReturnTypeWithAnnotations.CustomModifiers.Length); Assert.Equal(1, p1.TypeWithAnnotations.CustomModifiers.Length); var p1Mod = p1.TypeWithAnnotations.CustomModifiers[0]; Assert.True(p1Mod.IsOptional); Assert.Equal("System.Runtime.CompilerServices.IsConst", p1Mod.Modifier.ToTestDisplayString()); Assert.Equal(2, p2.TypeWithAnnotations.CustomModifiers.Length); foreach (var p2Mod in p2.TypeWithAnnotations.CustomModifiers) { Assert.True(p2Mod.IsOptional); Assert.Equal("System.Runtime.CompilerServices.IsConst", p2Mod.Modifier.ToTestDisplayString()); } Assert.Equal(SymbolKind.ErrorType, p4.Type.Kind); Assert.True(m5.ReturnsVoid); Assert.Equal(1, m5.ReturnTypeWithAnnotations.CustomModifiers.Length); var m5Mod = m5.ReturnTypeWithAnnotations.CustomModifiers[0]; Assert.True(m5Mod.IsOptional); Assert.Equal("System.Runtime.CompilerServices.IsConst", m5Mod.Modifier.ToTestDisplayString()); Assert.Equal(0, p5.TypeWithAnnotations.CustomModifiers.Length); ArrayTypeSymbol p5Type = (ArrayTypeSymbol)p5.Type; Assert.Equal("System.Int32", p5Type.ElementType.ToTestDisplayString()); Assert.Equal(1, p5Type.ElementTypeWithAnnotations.CustomModifiers.Length); var p5TypeMod = p5Type.ElementTypeWithAnnotations.CustomModifiers[0]; Assert.True(p5TypeMod.IsOptional); Assert.Equal("System.Runtime.CompilerServices.IsConst", p5TypeMod.Modifier.ToTestDisplayString()); Assert.Equal(0, p6.TypeWithAnnotations.CustomModifiers.Length); PointerTypeSymbol p6Type = (PointerTypeSymbol)p6.Type; Assert.Equal("System.Int32", p6Type.PointedAtType.ToTestDisplayString()); Assert.Equal(1, p6Type.PointedAtTypeWithAnnotations.CustomModifiers.Length); var p6TypeMod = p6Type.PointedAtTypeWithAnnotations.CustomModifiers[0]; Assert.True(p6TypeMod.IsOptional); Assert.Equal("System.Runtime.CompilerServices.IsConst", p6TypeMod.Modifier.ToTestDisplayString()); Assert.False(m7.ReturnsVoid); Assert.Equal(1, m7.ReturnTypeWithAnnotations.CustomModifiers.Length); var m7Mod = m7.ReturnTypeWithAnnotations.CustomModifiers[0]; Assert.True(m7Mod.IsOptional); Assert.Equal("System.Runtime.CompilerServices.IsConst", m7Mod.Modifier.ToTestDisplayString()); }
private bool FlowsOut(ParameterSymbol param) { return((object)param != null && param.RefKind != RefKind.None && !param.IsImplicitlyDeclared && !RegionContains(param.Locations[0].SourceSpan)); }
/// <summary> /// </summary> /// <param name="paramDef"> /// </param> internal MetadataParameterAdapter(ParameterSymbol paramDef) { this.paramDef = paramDef; }
internal override bool TryGetThisParameter(out ParameterSymbol thisParameter) { thisParameter = null; return(true); }
/// <summary> /// Creates a SemanticModel for a parameter default value. /// </summary> internal static InitializerSemanticModel Create(CSharpCompilation compilation, ParameterSyntax syntax, ParameterSymbol parameterSymbol, Binder rootBinder) { return(new InitializerSemanticModel(compilation, syntax, parameterSymbol, rootBinder)); }
public ParameterDefinition(Module moduleBeingBuilt, ParameterSymbol underlyingParameter) : base(moduleBeingBuilt, underlyingParameter) { }
protected override void ReportUnassignedOutParameter(ParameterSymbol parameter, SyntaxNode node, Location location) { _result.Add(parameter); base.ReportUnassignedOutParameter(parameter, node, location); }
internal sealed override bool TryGetThisParameter(out ParameterSymbol thisParameter) { thisParameter = lazyThisParameter; if ((object)thisParameter != null || IsStatic) { return true; } Interlocked.CompareExchange(ref lazyThisParameter, new ThisParameterSymbol(this), null); thisParameter = lazyThisParameter; return true; }
public BoundParameter(CSharpSyntaxNode syntax, ParameterSymbol parameterSymbol, bool hasErrors = false) : this(syntax, parameterSymbol, parameterSymbol.Type, hasErrors) { }
private static bool ParametersMatch(ParameterSymbol candidateParam, TypeMap candidateMethodTypeMap, ref ParamInfo<TypeSymbol> targetParam) { Debug.Assert(candidateMethodTypeMap != null); // This could be combined into a single return statement with a more complicated expression, but that would // be harder to debug. if ((candidateParam.RefKind != RefKind.None) != targetParam.IsByRef) { return false; } // CONSIDER: Do we want to add special handling for error types? Right now, we expect they'll just fail to match. var substituted = new TypeWithModifiers(candidateParam.Type, candidateParam.CustomModifiers).SubstituteType(candidateMethodTypeMap); if (substituted.Type != targetParam.Type) { return false; } if (!CustomModifiersMatch(substituted.CustomModifiers, targetParam.CustomModifiers) || !CustomModifiersMatch(candidateMethodTypeMap.SubstituteCustomModifiers(candidateParam.RefCustomModifiers), targetParam.RefCustomModifiers)) { return false; } return true; }
public BoundParameter(CSharpSyntaxNode syntax, ParameterSymbol parameterSymbol) : this(syntax, parameterSymbol, parameterSymbol.Type) { }
private static void AppendParameterSymbolInfo(this ICollection<SymbolMarkupToken> markup, ParameterSymbol symbol, bool includeInfo) { if (includeInfo) { markup.AppendPlainText("(parameter)"); markup.AppendSpace(); } if (symbol.Direction == ParameterDirection.Inout) { markup.AppendKeyword("inout"); markup.AppendSpace(); } else if (symbol.Direction == ParameterDirection.Out) { markup.AppendKeyword("out"); markup.AppendSpace(); } markup.AppendType(symbol.ValueType, false); markup.AppendSpace(); markup.AppendParameterName(symbol.Name); }
/// <summary> /// Creates a SemanticModel for a parameter default value. /// </summary> internal static InitializerSemanticModel Create(SyntaxTreeSemanticModel containingSemanticModel, ParameterSyntax syntax, ParameterSymbol parameterSymbol, Binder rootBinder) { Debug.Assert(containingSemanticModel != null); return(new InitializerSemanticModel(syntax, parameterSymbol, rootBinder, containingSemanticModel)); }
public RetargetingMethodParameterSymbol(RetargetingMethodSymbol retargetingMethod, ParameterSymbol underlyingParameter) : base(underlyingParameter) { Debug.Assert((object)retargetingMethod != null); _retargetingMethod = retargetingMethod; }
internal override bool TryGetThisParameter(out ParameterSymbol thisParameter) { thisParameter = IsStatic ? null : _uncommonFields?._lazyThisParameter ?? InterlockedOperations.Initialize(ref AccessUncommonFields()._lazyThisParameter, new ThisParameterSymbol(this)); return(true); }
protected RetargetingParameterSymbol(ParameterSymbol underlyingParameter) : base(underlyingParameter) { Debug.Assert(!(underlyingParameter is RetargetingParameterSymbol)); }
public ParameterTypeInformation(ParameterSymbol underlyingParameter) { Debug.Assert((object)underlyingParameter != null); _underlyingParameter = underlyingParameter; }
internal Microsoft.Cci.IParameterTypeInformation Translate(ParameterSymbol param, bool needDeclaration) { System.Diagnostics.Debug.Assert(ReferenceEquals(param, param.OriginalDefinition) || !param.Equals(param.OriginalDefinition)); if (!ReferenceEquals(param, param.OriginalDefinition)) { return param; } else if (!needDeclaration) { Symbol container = param.ContainingSymbol; bool containerIsGeneric = false; if (container.Kind == SymbolKind.Method) { if (((MethodSymbol)container).IsGeneric) { containerIsGeneric = true; } else { containerIsGeneric = IsGenericType(container.ContainingType); } } else { containerIsGeneric = IsGenericType(container.ContainingType); } if (containerIsGeneric) { object reference; Microsoft.Cci.IParameterTypeInformation paramRef; if (genericInstanceMap.TryGetValue(param, out reference)) { return (Microsoft.Cci.IParameterTypeInformation)reference; } paramRef = new ParameterTypeInformation(param); genericInstanceMap.Add(param, paramRef); return paramRef; } } return param; }
private ParameterSymbol MakeParameterSymbol(int ordinal, string name, ParameterSymbol sourceParameter) { return(SynthesizedParameterSymbol.Create(this, sourceParameter.TypeWithAnnotations, ordinal, sourceParameter.RefKind, name, sourceParameter.RefCustomModifiers)); }
private static Symbol SymbolFromClangCursor(ClangCursor cursor) { var result = new Symbol(); switch (cursor.Kind) { case NClang.CursorKind.CXXAccessSpecifier: result.Name = "(Access Specifier) " + cursor.CxxAccessSpecifier; break; default: result.Name = cursor.Spelling; break; } result.Kind = (CursorKind)cursor.Kind; result.BriefComment = cursor.BriefCommentText; result.TypeDescription = cursor.CursorType?.Spelling; result.EnumDescription = cursor.EnumConstantDeclValue.ToString(); result.Definition = cursor.Definition.DisplayName; result.Linkage = (LinkageKind)cursor.Linkage; result.IsBuiltInType = IsBuiltInType(cursor.CursorType); result.SymbolType = cursor.CursorType?.Spelling.Replace(" &", "&").Replace(" *", "*") + " "; result.ResultType = cursor.ResultType?.Spelling; result.Arguments = new List<ParameterSymbol>(); result.Access = (AccessType)cursor.CxxAccessSpecifier; result.IsVariadic = cursor.IsVariadic; switch (result.Kind) { case CursorKind.FunctionDeclaration: case CursorKind.CXXMethod: case CursorKind.Constructor: case CursorKind.Destructor: for (var i = 0; i < cursor.ArgumentCount; i++) { var argument = cursor.GetArgument(i); var arg = new ParameterSymbol(); arg.IsBuiltInType = IsBuiltInType(argument.CursorType); arg.Name = argument.Spelling; arg.TypeDescription = argument.CursorType.Spelling; result.Arguments.Add(arg); } if (cursor.IsVariadic) { result.Arguments.Last().Name += ", "; result.Arguments.Add(new ParameterSymbol { Name = "... variadic" }); } if (cursor.ParsedComment.FullCommentAsXml != null) { var documentation = XDocument.Parse(cursor.ParsedComment.FullCommentAsXml); var function = documentation.Element("Function"); var parameters = function.Element("Parameters"); if (parameters != null) { var arguments = parameters.Elements("Parameter"); foreach (var argument in arguments) { var isVarArgs = argument.Element("IsVarArg"); var discussion = argument.Element("Discussion"); var paragraph = discussion.Element("Para"); if (isVarArgs != null) { result.Arguments.Last().Comment = paragraph.Value; } else { var inx = argument.Element("Index"); if (inx != null) // This happens when documentation for an argument was left in, but the argument no longer exists. { var index = int.Parse(inx.Value); result.Arguments[index].Comment = paragraph.Value; } } } } } if (result.Arguments.Count == 0) { result.Arguments.Add(new ParameterSymbol { Name = "void" }); } break; } return result; }
protected BoundExpression LowerEvaluation(BoundDagEvaluation evaluation) { BoundExpression input = _tempAllocator.GetTemp(evaluation.Input); switch (evaluation) { case BoundDagFieldEvaluation f: { FieldSymbol field = f.Field; var outputTemp = new BoundDagTemp(f.Syntax, field.Type, f); BoundExpression output = _tempAllocator.GetTemp(outputTemp); BoundExpression access = _localRewriter.MakeFieldAccess(f.Syntax, input, field, null, LookupResultKind.Viable, field.Type); access.WasCompilerGenerated = true; return(_factory.AssignmentExpression(output, access)); } case BoundDagPropertyEvaluation p: { PropertySymbol property = p.Property; var outputTemp = new BoundDagTemp(p.Syntax, property.Type, p); BoundExpression output = _tempAllocator.GetTemp(outputTemp); return(_factory.AssignmentExpression(output, _localRewriter.MakePropertyAccess(_factory.Syntax, input, property, LookupResultKind.Viable, property.Type, isLeftOfAssignment: false))); } case BoundDagDeconstructEvaluation d: { MethodSymbol method = d.DeconstructMethod; var refKindBuilder = ArrayBuilder <RefKind> .GetInstance(); var argBuilder = ArrayBuilder <BoundExpression> .GetInstance(); BoundExpression receiver; void addArg(RefKind refKind, BoundExpression expression) { refKindBuilder.Add(refKind); argBuilder.Add(expression); } Debug.Assert(method.Name == WellKnownMemberNames.DeconstructMethodName); int extensionExtra; if (method.IsStatic) { Debug.Assert(method.IsExtensionMethod); receiver = _factory.Type(method.ContainingType); addArg(method.ParameterRefKinds[0], input); extensionExtra = 1; } else { receiver = input; extensionExtra = 0; } for (int i = extensionExtra; i < method.ParameterCount; i++) { ParameterSymbol parameter = method.Parameters[i]; Debug.Assert(parameter.RefKind == RefKind.Out); var outputTemp = new BoundDagTemp(d.Syntax, parameter.Type, d, i - extensionExtra); addArg(RefKind.Out, _tempAllocator.GetTemp(outputTemp)); } return(_factory.Call(receiver, method, refKindBuilder.ToImmutableAndFree(), argBuilder.ToImmutableAndFree())); } case BoundDagTypeEvaluation t: { TypeSymbol inputType = input.Type; Debug.Assert(inputType is { }); if (inputType.IsDynamic()) { // Avoid using dynamic conversions for pattern-matching. inputType = _factory.SpecialType(SpecialType.System_Object); input = _factory.Convert(inputType, input); } TypeSymbol type = t.Type; var outputTemp = new BoundDagTemp(t.Syntax, type, t); BoundExpression output = _tempAllocator.GetTemp(outputTemp); CompoundUseSiteInfo <AssemblySymbol> useSiteInfo = _localRewriter.GetNewCompoundUseSiteInfo(); Conversion conversion = _factory.Compilation.Conversions.ClassifyBuiltInConversion(inputType, output.Type, ref useSiteInfo); _localRewriter._diagnostics.Add(t.Syntax, useSiteInfo); BoundExpression evaluated; if (conversion.Exists) { if (conversion.Kind == ConversionKind.ExplicitNullable && inputType.GetNullableUnderlyingType().Equals(output.Type, TypeCompareKind.AllIgnoreOptions) && _localRewriter.TryGetNullableMethod(t.Syntax, inputType, SpecialMember.System_Nullable_T_GetValueOrDefault, out MethodSymbol getValueOrDefault)) { // As a special case, since the null test has already been done we can use Nullable<T>.GetValueOrDefault evaluated = _factory.Call(input, getValueOrDefault); } else { evaluated = _factory.Convert(type, input, conversion); } } else { evaluated = _factory.As(input, type); } return(_factory.AssignmentExpression(output, evaluated)); }
internal override bool TryGetThisParameter(out ParameterSymbol thisParameter) { thisParameter = IsStatic ? null : _uncommonFields?._lazyThisParameter ?? InterlockedOperations.Initialize(ref AccessUncommonFields()._lazyThisParameter, new ThisParameterSymbol(this)); return true; }
protected virtual BoundStatement InitializeParameterField(MethodSymbol getEnumeratorMethod, ParameterSymbol parameter, BoundExpression resultParameter, BoundExpression parameterProxy) { Debug.Assert(!method.IsIterator || !method.IsAsync); // an override handles async-iterators // result.parameter = this.parameterProxy; return(F.Assignment(resultParameter, parameterProxy)); }