diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs index 1796f50ee6b0669d21ece3c484666bc14513b671..7689cd3ffbe9c3a1d9145042ac2dfb47b18d6ffe 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs @@ -551,7 +551,6 @@ public void AllWellKnownTypes() { switch (wkt) { - case WellKnownType.My_InternalXmlHelper: case WellKnownType.Microsoft_VisualBasic_Embedded: case WellKnownType.Microsoft_VisualBasic_CompilerServices_EmbeddedOperators: // Not applicable in C#. @@ -592,7 +591,6 @@ public void AllWellKnownTypeMembers() case WellKnownMember.Count: // Not a real value; continue; - case WellKnownMember.My_InternalXmlHelper__Value: case WellKnownMember.Microsoft_VisualBasic_Embedded__ctor: case WellKnownMember.Microsoft_VisualBasic_CompilerServices_EmbeddedOperators__CompareStringStringStringBoolean: // C# can't embed VB core. diff --git a/src/Compilers/Core/Portable/WellKnownMember.cs b/src/Compilers/Core/Portable/WellKnownMember.cs index af876db1eebec1d9f2647d74edca227173acfbb3..960d572e9814257b5697b591005be0df1c7da4d6 100644 --- a/src/Compilers/Core/Portable/WellKnownMember.cs +++ b/src/Compilers/Core/Portable/WellKnownMember.cs @@ -306,8 +306,6 @@ internal enum WellKnownMember Microsoft_VisualBasic_Information__VbTypeName, Microsoft_VisualBasic_Interaction__CallByName, - My_InternalXmlHelper__Value, - System_Runtime_CompilerServices_IAsyncStateMachine_MoveNext, System_Runtime_CompilerServices_IAsyncStateMachine_SetStateMachine, diff --git a/src/Compilers/Core/Portable/WellKnownMembers.cs b/src/Compilers/Core/Portable/WellKnownMembers.cs index c2a8b62455781f70fea71f0daa4f9d4a8509cdf9..2c7dd930166f099e56c5904129a859d5268d943f 100644 --- a/src/Compilers/Core/Portable/WellKnownMembers.cs +++ b/src/Compilers/Core/Portable/WellKnownMembers.cs @@ -2220,17 +2220,6 @@ static WellKnownMembers() (byte)SignatureTypeCode.TypeHandle, (byte)WellKnownType.Microsoft_VisualBasic_CallType, (byte)SignatureTypeCode.SZArray, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Object, - // My_InternalXmlHelper__Value - (byte)(MemberFlags.Property | MemberFlags.Static), // Flags - (byte)WellKnownType.My_InternalXmlHelper, // DeclaringTypeId - 0, // Arity - 1, // Method Signature - (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_String, - (byte)SignatureTypeCode.GenericTypeInstance, - (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Collections_Generic_IEnumerable_T, - 1, - (byte)SignatureTypeCode.TypeHandle, (byte)WellKnownType.System_Xml_Linq_XElement, - // System_Runtime_CompilerServices_IAsyncStateMachine_MoveNext (byte)(MemberFlags.Method | MemberFlags.Virtual), // Flags (byte)WellKnownType.System_Runtime_CompilerServices_IAsyncStateMachine, // DeclaringTypeId @@ -2799,7 +2788,6 @@ static WellKnownMembers() "TypeName", // Microsoft_VisualBasic_Information__TypeName "VbTypeName", // Microsoft_VisualBasic_Information__VbTypeName "CallByName", // Microsoft_VisualBasic_Interaction__CallByName - "Value", // My_InternalXmlHelper__Value "MoveNext", // System_Runtime_CompilerServices_IAsyncStateMachine_MoveNext "SetStateMachine", // System_Runtime_CompilerServices_IAsyncStateMachine_SetStateMachine "SetException", // System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetException diff --git a/src/Compilers/Core/Portable/WellKnownTypes.cs b/src/Compilers/Core/Portable/WellKnownTypes.cs index 856e16d9eb596e711e7c0fc19285ce3222749b96..cc925826980f6156a8d5381aba3ec93db2059eb7 100644 --- a/src/Compilers/Core/Portable/WellKnownTypes.cs +++ b/src/Compilers/Core/Portable/WellKnownTypes.cs @@ -101,8 +101,6 @@ internal enum WellKnownType Microsoft_VisualBasic_Information, Microsoft_VisualBasic_Interaction, - My_InternalXmlHelper, - // standard Func delegates - must be ordered by arity System_Func_T, System_Func_T2, @@ -349,8 +347,6 @@ internal static class WellKnownTypes "Microsoft.VisualBasic.Information", "Microsoft.VisualBasic.Interaction", - "My.InternalXmlHelper", - "System.Func`1", "System.Func`2", "System.Func`3", diff --git a/src/Compilers/VisualBasic/Portable/Binding/Binder.vb b/src/Compilers/VisualBasic/Portable/Binding/Binder.vb index e1477c82231e2febc33b80e93a585a912460004b..9f21eef90c857d2818f7e24f6d8a494eaa061abd 100644 --- a/src/Compilers/VisualBasic/Portable/Binding/Binder.vb +++ b/src/Compilers/VisualBasic/Portable/Binding/Binder.vb @@ -3,6 +3,7 @@ Imports System.Collections.Concurrent Imports System.Collections.Generic Imports System.Collections.Immutable +Imports System.Reflection.Metadata Imports System.Runtime.InteropServices Imports System.Threading Imports Microsoft.CodeAnalysis.RuntimeMembers @@ -326,6 +327,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End Get End Property + Friend ReadOnly Property ContainingModule As ModuleSymbol + Get + ' If there's a containing member, it either is or has a containing module. + ' Otherwise, we'll just use the compilation's source module. + Dim containingMember = Me.ContainingMember + Return If(TryCast(containingMember, ModuleSymbol), If(containingMember?.ContainingModule, Me.Compilation.SourceModule)) + End Get + End Property + ''' ''' Tells whether binding is happening in a query context. ''' @@ -452,6 +462,79 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return type.GetUseSiteErrorInfo() End Function + Private Function GetInternalXmlHelperType(syntax As VisualBasicSyntaxNode, diagBag As DiagnosticBag) As NamedTypeSymbol + Dim typeSymbol = GetInternalXmlHelperType() + + Dim useSiteError = GetUseSiteErrorForWellKnownType(typeSymbol) + If useSiteError IsNot Nothing Then + ReportDiagnostic(diagBag, syntax, useSiteError) + End If + + Return typeSymbol + End Function + + Private Function GetInternalXmlHelperType() As NamedTypeSymbol + Const globalMetadataName = "My.InternalXmlHelper" + Dim metadataName = globalMetadataName + + Dim rootNamespace = Me.Compilation.Options.RootNamespace + Dim haveRootNamespace As Boolean = Not String.IsNullOrEmpty(rootNamespace) + If haveRootNamespace Then + metadataName = $"{rootNamespace}.{metadataName}" + End If + + Dim emittedName = MetadataTypeName.FromFullName(metadataName, useCLSCompliantNameArityEncoding:=True) + + Dim containingModule = Me.ContainingModule + Dim typeSymbol = containingModule.LookupTopLevelMetadataType(emittedName) + + ' Roslyn emits the type into the global namespace so we should look there too. + If haveRootNamespace AndAlso TypeOf typeSymbol Is MissingMetadataTypeSymbol Then + Dim globalEmittedName = MetadataTypeName.FromFullName(globalMetadataName, useCLSCompliantNameArityEncoding:=True) + Dim globalTypeSymbol = containingModule.LookupTopLevelMetadataType(globalEmittedName) + If TypeOf globalTypeSymbol IsNot MissingMetadataTypeSymbol Then + typeSymbol = globalTypeSymbol + End If + End If + + Return typeSymbol + End Function + + ''' + ''' WARN: Retrieves the symbol but does not check its viability (accessibility, etc). + ''' + Private Function GetInternalXmlHelperValueExtensionProperty() As PropertySymbol + For Each candidate As Symbol In GetInternalXmlHelperType().GetMembers("Value") + If Not candidate.IsShared OrElse candidate.Kind <> SymbolKind.Property Then + Continue For + End If + + Dim candidateProperty = DirectCast(candidate, PropertySymbol) + If candidateProperty.Type.SpecialType <> SpecialType.System_String OrElse + candidateProperty.TypeCustomModifiers.Length > 0 OrElse + candidateProperty.ParameterCount <> 1 Then + + Continue For + End If + + Dim parameter = candidateProperty.Parameters(0) + If parameter.CustomModifiers.Length > 0 Then + Continue For + End If + + Dim parameterType = parameter.Type + If parameterType.OriginalDefinition.SpecialType <> SpecialType.System_Collections_Generic_IEnumerable_T OrElse + DirectCast(parameterType, NamedTypeSymbol).TypeArgumentsNoUseSiteDiagnostics(0) <> Me.Compilation.GetWellKnownType(WellKnownType.System_Xml_Linq_XElement) Then + Continue For + End If + + ' Only one symbol can match the criteria above, so we don't have to worry about ambiguity. + Return candidateProperty + Next + + Return Nothing + End Function + ''' ''' This is a layer on top of the assembly version that generates a diagnostic if the well-known ''' member isn't found. diff --git a/src/Compilers/VisualBasic/Portable/Binding/Binder_Lookup.vb b/src/Compilers/VisualBasic/Portable/Binding/Binder_Lookup.vb index 1b856615fa6f6221926973ba84ca7fe01f0d9731..458f0ce14a22fd6beff848c6cb755e44b148789a 100644 --- a/src/Compilers/VisualBasic/Portable/Binding/Binder_Lookup.vb +++ b/src/Compilers/VisualBasic/Portable/Binding/Binder_Lookup.vb @@ -153,7 +153,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End If ' Check for external symbols marked with 'Microsoft.VisualBasic.Embedded' attribute - If Me.Compilation.SourceModule IsNot unwrappedSym.ContainingModule AndAlso unwrappedSym.IsHiddenByEmbeddedAttribute() Then + If unwrappedSym.ContainingModule IsNot Me.ContainingModule AndAlso unwrappedSym.IsHiddenByEmbeddedAttribute() Then Return SingleLookupResult.Empty End If @@ -1197,7 +1197,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return End If - Dim symbol = compilation.GetWellKnownTypeMember(WellKnownMember.My_InternalXmlHelper__Value) + Dim symbol = binder.GetInternalXmlHelperValueExtensionProperty() Dim singleResult As SingleLookupResult If symbol Is Nothing Then ' Match the native compiler which reports ERR_XmlFeaturesNotAvailable in this case. diff --git a/src/Compilers/VisualBasic/Portable/Binding/Binder_XmlLiterals.vb b/src/Compilers/VisualBasic/Portable/Binding/Binder_XmlLiterals.vb index 201afeeac5b3b214b696c098dc25fcfc096924a2..5f683b023e1f4c6cb8d16f9700c6feaa9492c5f1 100644 --- a/src/Compilers/VisualBasic/Portable/Binding/Binder_XmlLiterals.vb +++ b/src/Compilers/VisualBasic/Portable/Binding/Binder_XmlLiterals.vb @@ -354,7 +354,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ' Generate method group and arguments for RemoveNamespaceAttributes. removeNamespacesGroup = GetXmlMethodOrPropertyGroup(syntax, - GetWellKnownType(WellKnownType.My_InternalXmlHelper, syntax, diagnostics), + GetInternalXmlHelperType(syntax, diagnostics), StringConstants.XmlRemoveNamespaceAttributesMethodName, Nothing, diagnostics) @@ -423,7 +423,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ImmutableArray.Create(Of BoundExpression)(prefix, [namespace]), diagnostics) Else - Dim type = GetWellKnownType(WellKnownType.My_InternalXmlHelper, syntax, diagnostics) + Dim type = GetInternalXmlHelperType(syntax, diagnostics) Dim group = GetXmlMethodOrPropertyGroup(syntax, type, StringConstants.XmlCreateNamespaceAttributeMethodName, Nothing, diagnostics) objectCreation = BindInvocationExpressionIfGroupNotNothing(syntax, group, ImmutableArray.Create(Of BoundExpression)(prefix, [namespace]), diagnostics) End If @@ -478,7 +478,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ' with embedded expression values since CreateAttribute handles Nothing values. value = BindXmlEmbeddedExpression(DirectCast(valueSyntax, XmlEmbeddedExpressionSyntax), diagnostics) Dim group = GetXmlMethodOrPropertyGroup(valueSyntax, - GetWellKnownType(WellKnownType.My_InternalXmlHelper, syntax, diagnostics), + GetInternalXmlHelperType(syntax, diagnostics), StringConstants.XmlCreateAttributeMethodName, Nothing, diagnostics) @@ -653,7 +653,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Dim useSiteDiagnostics As HashSet(Of DiagnosticInfo) = Nothing If receiverType.IsOrDerivedFrom(xmlType, useSiteDiagnostics) OrElse receiverType.IsCompatibleWithGenericIEnumerableOfType(xmlType, useSiteDiagnostics) Then group = GetXmlMethodOrPropertyGroup(syntax, - GetWellKnownType(WellKnownType.My_InternalXmlHelper, syntax, diagnostics), + GetInternalXmlHelperType(syntax, diagnostics), StringConstants.XmlAttributeValueMethodName, Nothing, diagnostics) diff --git a/src/Compilers/VisualBasic/Portable/Binding/ImportAliasesBinder.vb b/src/Compilers/VisualBasic/Portable/Binding/ImportAliasesBinder.vb index 2233570e64519fb632ea2a1aea20fe1d9ce82f29..7a3f2f077a88710e04cc7613837b87879e34c74e 100644 --- a/src/Compilers/VisualBasic/Portable/Binding/ImportAliasesBinder.vb +++ b/src/Compilers/VisualBasic/Portable/Binding/ImportAliasesBinder.vb @@ -66,6 +66,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End If Next End Sub + + Public Overrides ReadOnly Property ContainingMember As Symbol + Get + Return Me.Compilation.SourceModule + End Get + End Property End Class End Namespace diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/XmlLiteralsTests_UseSiteErrors.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/XmlLiteralsTests_UseSiteErrors.vb index 324070139d3d150eaa553483a47a8d7e827e69dc..8347e4524882594d2c2ac4df3623322010dc3335 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/XmlLiteralsTests_UseSiteErrors.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/XmlLiteralsTests_UseSiteErrors.vb @@ -208,12 +208,9 @@ Namespace System.Xml.Linq Public Class XNamespace End Class End Namespace -Namespace My - Public Module InternalXmlHelper - Public Function RemoveNamespaceAttributes(prefixes As String(), namespaces As XNamespace(), attributes As Object, o As Object) As Object - Return Nothing - End Function - End Module +Namespace Microsoft.VisualBasic.CompilerServices + Public Class StandardModuleAttribute : Inherits System.Attribute + End Class End Namespace ]]> ) @@ -222,11 +219,20 @@ End Namespace /> Private F2 As Object = ="b"/> Private F3 As Object = /> End Class +Namespace My + Public Module InternalXmlHelper + Public Function RemoveNamespaceAttributes(prefixes As String(), namespaces As XNamespace(), attributes As Object, o As Object) As Object + Return Nothing + End Function + End Module +End Namespace ]]> , references:={New VisualBasicCompilationReference(compilation1)}) compilation2.AssertTheseDiagnostics( ) @@ -285,11 +288,20 @@ End Namespace /> Private F2 As Object = ="b"/> Private F3 As Object = /> End Class +Namespace My + Public Module InternalXmlHelper + Public Function RemoveNamespaceAttributes(prefixes As String(), namespaces As XNamespace(), attributes As List(Of XAttribute), o As Object) As Object + Return Nothing + End Function + End Module +End Namespace ]]> , references:={New VisualBasicCompilationReference(compilation1)}) compilation2.AssertTheseDiagnostics( ) @@ -616,9 +622,21 @@ End Namespace +Imports System.Collections.Generic +Imports System.Xml.Linq Class C Shared F As Object = <%= Nothing %> End Class +Namespace My + Public Module InternalXmlHelper + Public Function CreateNamespaceAttribute(name As XName, ns As XNamespace) As XAttribute + Return Nothing + End Function + Public Function RemoveNamespaceAttributes(prefixes As String(), namespaces As XNamespace(), attributes As Object, o As Object) As Object + Return Nothing + End Function + End Module +End Namespace ]]> , references:={New VisualBasicCompilationReference(compilation1)}) compilation2.AssertTheseDiagnostics( ) @@ -728,6 +746,10 @@ Class C Private F2 As Object = F1. Private F3 As Object = F1.@x End Class +Namespace My + Public Module InternalXmlHelper + End Module +End Namespace ]]> , references:={New VisualBasicCompilationReference(compilation1)}) compilation2.AssertTheseDiagnostics( ) @@ -775,6 +797,10 @@ Class C Return x.Value End Function End Class +Namespace My + Public Module InternalXmlHelper + End Module +End Namespace ]]> , references:={New VisualBasicCompilationReference(compilation1)}) compilation2.AssertTheseDiagnostics( ) @@ -820,6 +841,15 @@ Class C Return x.VALUE End Function End Class +Namespace My + Public Module InternalXmlHelper + Public ReadOnly Property Value(x As IEnumerable(Of XElement), y As Object, z As Object) As Object + Get + Return Nothing + End Get + End Property + End Module +End Namespace ]]> , references:={New VisualBasicCompilationReference(compilation1)}) compilation2.AssertTheseDiagnostics( - + + Public Sub EvaluateXmlMemberAccess() Dim source = "Class C @@ -1762,6 +1762,96 @@ End Class" }") End Sub + + + Public Sub InternalXmlHelper_RootNamespace() + Dim source = +"Class C + Shared Sub M(x As System.Xml.Linq.XElement) + Dim y = x.@ + End Sub +End Class" + Dim allReferences = GetAllXmlReferences() + Dim comp = CreateCompilationWithReferences( + MakeSources(source), + options:=TestOptions.DebugDll.WithRootNamespace("Root"), + references:=allReferences) + Dim exeBytes As Byte() = Nothing + Dim pdbBytes As Byte() = Nothing + Dim references As ImmutableArray(Of MetadataReference) = Nothing + comp.EmitAndGetReferences(exeBytes, pdbBytes, references) + Dim runtime = CreateRuntimeInstance( + ExpressionCompilerUtilities.GenerateUniqueName(), + allReferences, + exeBytes, + Nothing) + Dim context = CreateMethodContext(runtime, "Root.C.M") + Dim errorMessage As String = Nothing + Dim testData = New CompilationTestData() + Dim result = context.CompileExpression("x.@a", errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) + Assert.Null(errorMessage) + testData.GetMethodData("<>x.<>m0").VerifyIL( +"{ + // Code size 22 (0x16) + .maxstack 3 + .locals init (String V_0) + IL_0000: ldarg.0 + IL_0001: ldstr ""a"" + IL_0006: ldstr """" + IL_000b: call ""Function System.Xml.Linq.XName.Get(String, String) As System.Xml.Linq.XName"" + IL_0010: call ""Function My.InternalXmlHelper.get_AttributeValue(System.Xml.Linq.XElement, System.Xml.Linq.XName) As String"" + IL_0015: ret +}") + End Sub + + + + Public Sub InternalXmlHelper_AddedModules() + Dim sourceTemplate = +"Class C{0} + Shared Sub M(x As System.Xml.Linq.XElement) + Dim y = x.@ + End Sub +End Class" + Dim xmlReferences = GetAllXmlReferences() + Dim moduleOptions = New VisualBasicCompilationOptions(OutputKind.NetModule, optimizationLevel:=OptimizationLevel.Debug).WithExtendedCustomDebugInformation(True) + + Dim tree1 = VisualBasicSyntaxTree.ParseText(String.Format(sourceTemplate, 1)) + Dim tree2 = VisualBasicSyntaxTree.ParseText(String.Format(sourceTemplate, 2)) + Dim ref1 = CreateCompilationWithReferences(tree1, xmlReferences, moduleOptions, assemblyName:="Module1").EmitToImageReference() + Dim ref2 = CreateCompilationWithReferences(tree2, xmlReferences, moduleOptions, assemblyName:="Module2").EmitToImageReference() + + Dim tree = VisualBasicSyntaxTree.ParseText(String.Format(sourceTemplate, "")) + Dim compReferences = xmlReferences.Concat(ImmutableArray.Create(ref1, ref2)) + Dim comp = CreateCompilationWithReferences(tree, compReferences, TestOptions.DebugDll, assemblyName:="Test") + + Dim exeBytes As Byte() = Nothing + Dim pdbBytes As Byte() = Nothing + Dim references As ImmutableArray(Of MetadataReference) = Nothing + comp.EmitAndGetReferences(exeBytes, pdbBytes, references) + Dim runtime = CreateRuntimeInstance( + ExpressionCompilerUtilities.GenerateUniqueName(), + compReferences, + exeBytes, + Nothing) + Dim context = CreateMethodContext(runtime, "C1.M") ' In Module1 + Dim errorMessage As String = Nothing + Dim testData = New CompilationTestData() + Dim result = context.CompileExpression("x.@a", errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) + Assert.Null(errorMessage) + testData.GetMethodData("<>x.<>m0").VerifyIL( +"{ + // Code size 22 (0x16) + .maxstack 3 + IL_0000: ldarg.0 + IL_0001: ldstr ""a"" + IL_0006: ldstr """" + IL_000b: call ""Function System.Xml.Linq.XName.Get(String, String) As System.Xml.Linq.XName"" + IL_0010: call ""Function My.InternalXmlHelper.get_AttributeValue(System.Xml.Linq.XElement, System.Xml.Linq.XName) As String"" + IL_0015: ret +}") + End Sub + Public Sub AssignByRefParameter() Const source = @@ -3177,8 +3267,8 @@ End Module End Sub - - + + Public Sub ConditionalAccessExpressionType() Dim source = "Class C @@ -3190,6 +3280,7 @@ End Module End Function Private X As System.Xml.Linq.XElement Sub M() + Dim dummy = Me?.X.@a ' Ensure InternalXmlHelper is emitted. End Sub End Class" Dim allReferences = GetAllXmlReferences() @@ -3217,12 +3308,13 @@ End Class" "{ // Code size 25 (0x19) .maxstack 1 - .locals init (Integer? V_0) + .locals init (String V_0, + Integer? V_1) IL_0000: ldarg.0 IL_0001: brtrue.s IL_000d - IL_0003: ldloca.s V_0 + IL_0003: ldloca.s V_1 IL_0005: initobj ""Integer?"" - IL_000b: ldloc.0 + IL_000b: ldloc.1 IL_000c: ret IL_000d: ldarg.0 IL_000e: call ""Function C.F() As Integer"" @@ -3244,6 +3336,7 @@ End Class" "{ // Code size 32 (0x20) .maxstack 3 + .locals init (String V_0) IL_0000: ldarg.0 IL_0001: brtrue.s IL_0005 IL_0003: ldnull @@ -3275,6 +3368,7 @@ End Class" "{ // Code size 17 (0x11) .maxstack 2 + .locals init (String V_0) IL_0000: ldarg.0 IL_0001: callvirt ""Function C.G() As C"" IL_0006: dup