Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
238db4f7
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
238db4f7
编写于
10月 07, 2015
作者:
A
AlekseyTs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add support for custom modifiers referencing generic types.
Fixes #5725.
上级
a4e375b9
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
641 addition
and
89 deletion
+641
-89
src/Compilers/CSharp/Portable/Emitter/Model/CustomModifierAdapter.cs
...rs/CSharp/Portable/Emitter/Model/CustomModifierAdapter.cs
+0
-1
src/Compilers/CSharp/Portable/Symbols/AbstractTypeMap.cs
src/Compilers/CSharp/Portable/Symbols/AbstractTypeMap.cs
+42
-1
src/Compilers/CSharp/Portable/Symbols/Symbol.cs
src/Compilers/CSharp/Portable/Symbols/Symbol.cs
+9
-1
src/Compilers/CSharp/Portable/Symbols/TypeWithModifiers.cs
src/Compilers/CSharp/Portable/Symbols/TypeWithModifiers.cs
+4
-3
src/Compilers/CSharp/Test/Symbol/Symbols/CustomModifiersTests.cs
...pilers/CSharp/Test/Symbol/Symbols/CustomModifiersTests.cs
+209
-0
src/Compilers/Core/Portable/MetadataReader/MetadataDecoder.cs
...Compilers/Core/Portable/MetadataReader/MetadataDecoder.cs
+124
-79
src/Compilers/VisualBasic/Portable/Emit/CustomModifierAdapter.vb
...pilers/VisualBasic/Portable/Emit/CustomModifierAdapter.vb
+0
-1
src/Compilers/VisualBasic/Portable/Symbols/TypeSubstitution.vb
...ompilers/VisualBasic/Portable/Symbols/TypeSubstitution.vb
+34
-0
src/Compilers/VisualBasic/Portable/Symbols/TypeWithModifiers.vb
...mpilers/VisualBasic/Portable/Symbols/TypeWithModifiers.vb
+4
-3
src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/CustomModifiersTests.vb
...ualBasic/Test/Symbol/SymbolsTests/CustomModifiersTests.vb
+215
-0
未找到文件。
src/Compilers/CSharp/Portable/Emitter/Model/CustomModifierAdapter.cs
浏览文件 @
238db4f7
...
@@ -15,7 +15,6 @@ bool Cci.ICustomModifier.IsOptional
...
@@ -15,7 +15,6 @@ bool Cci.ICustomModifier.IsOptional
Cci
.
ITypeReference
Cci
.
ICustomModifier
.
GetModifier
(
EmitContext
context
)
Cci
.
ITypeReference
Cci
.
ICustomModifier
.
GetModifier
(
EmitContext
context
)
{
{
Debug
.
Assert
(
this
.
Modifier
.
IsDefinition
);
return
((
PEModuleBuilder
)
context
.
Module
).
Translate
(
this
.
Modifier
,
(
CSharpSyntaxNode
)
context
.
SyntaxNodeOpt
,
context
.
Diagnostics
);
return
((
PEModuleBuilder
)
context
.
Module
).
Translate
(
this
.
Modifier
,
(
CSharpSyntaxNode
)
context
.
SyntaxNodeOpt
,
context
.
Diagnostics
);
}
}
}
}
...
...
src/Compilers/CSharp/Portable/Symbols/AbstractTypeMap.cs
浏览文件 @
238db4f7
...
@@ -145,9 +145,50 @@ internal ImmutableArray<CustomModifier> SubstituteCustomModifiers(TypeSymbol typ
...
@@ -145,9 +145,50 @@ internal ImmutableArray<CustomModifier> SubstituteCustomModifiers(TypeSymbol typ
return
new
TypeWithModifiers
(
type
,
customModifiers
).
SubstituteType
(
this
).
CustomModifiers
;
return
new
TypeWithModifiers
(
type
,
customModifiers
).
SubstituteType
(
this
).
CustomModifiers
;
}
}
return
customModifiers
;
return
SubstituteCustomModifiers
(
customModifiers
)
;
}
}
internal
ImmutableArray
<
CustomModifier
>
SubstituteCustomModifiers
(
ImmutableArray
<
CustomModifier
>
customModifiers
)
{
if
(
customModifiers
.
IsDefaultOrEmpty
)
{
return
customModifiers
;
}
for
(
int
i
=
0
;
i
<
customModifiers
.
Length
;
i
++)
{
var
modifier
=
(
NamedTypeSymbol
)
customModifiers
[
i
].
Modifier
;
var
substituted
=
SubstituteNamedType
(
modifier
);
if
(
modifier
!=
substituted
)
{
var
builder
=
ArrayBuilder
<
CustomModifier
>.
GetInstance
(
customModifiers
.
Length
);
builder
.
AddRange
(
customModifiers
,
i
);
builder
.
Add
(
customModifiers
[
i
].
IsOptional
?
CSharpCustomModifier
.
CreateOptional
(
substituted
)
:
CSharpCustomModifier
.
CreateRequired
(
substituted
));
for
(
i
++;
i
<
customModifiers
.
Length
;
i
++)
{
modifier
=
(
NamedTypeSymbol
)
customModifiers
[
i
].
Modifier
;
substituted
=
SubstituteNamedType
(
modifier
);
if
(
modifier
!=
substituted
)
{
builder
.
Add
(
customModifiers
[
i
].
IsOptional
?
CSharpCustomModifier
.
CreateOptional
(
substituted
)
:
CSharpCustomModifier
.
CreateRequired
(
substituted
));
}
else
{
builder
.
Add
(
customModifiers
[
i
]);
}
}
Debug
.
Assert
(
builder
.
Count
==
customModifiers
.
Length
);
return
builder
.
ToImmutableAndFree
();
}
}
return
customModifiers
;
}
protected
virtual
TypeSymbol
SubstituteDynamicType
()
protected
virtual
TypeSymbol
SubstituteDynamicType
()
{
{
return
DynamicTypeSymbol
.
Instance
;
return
DynamicTypeSymbol
.
Instance
;
...
...
src/Compilers/CSharp/Portable/Symbols/Symbol.cs
浏览文件 @
238db4f7
...
@@ -934,7 +934,15 @@ internal bool DeriveUseSiteDiagnosticFromCustomModifiers(ref DiagnosticInfo resu
...
@@ -934,7 +934,15 @@ internal bool DeriveUseSiteDiagnosticFromCustomModifiers(ref DiagnosticInfo resu
{
{
foreach
(
CustomModifier
modifier
in
customModifiers
)
foreach
(
CustomModifier
modifier
in
customModifiers
)
{
{
if
(
DeriveUseSiteDiagnosticFromType
(
ref
result
,
(
TypeSymbol
)
modifier
.
Modifier
))
var
modifierType
=
(
NamedTypeSymbol
)
modifier
.
Modifier
;
// Unbound generic type is valid as a modifier, let's not report any use site diagnostics because of that.
if
(
modifierType
.
IsUnboundGenericType
)
{
modifierType
=
modifierType
.
OriginalDefinition
;
}
if
(
DeriveUseSiteDiagnosticFromType
(
ref
result
,
modifierType
))
{
{
return
true
;
return
true
;
}
}
...
...
src/Compilers/CSharp/Portable/Symbols/TypeWithModifiers.cs
浏览文件 @
238db4f7
...
@@ -86,14 +86,15 @@ public TypeSymbol AsTypeSymbolOnly()
...
@@ -86,14 +86,15 @@ public TypeSymbol AsTypeSymbolOnly()
public
TypeWithModifiers
SubstituteType
(
AbstractTypeMap
typeMap
)
public
TypeWithModifiers
SubstituteType
(
AbstractTypeMap
typeMap
)
{
{
var
newCustomModifiers
=
typeMap
.
SubstituteCustomModifiers
(
this
.
CustomModifiers
);
var
newTypeWithModifiers
=
typeMap
.
SubstituteType
(
this
.
Type
);
var
newTypeWithModifiers
=
typeMap
.
SubstituteType
(
this
.
Type
);
if
(!
newTypeWithModifiers
.
Is
(
this
.
Type
))
if
(!
newTypeWithModifiers
.
Is
(
this
.
Type
)
||
newCustomModifiers
!=
this
.
CustomModifiers
)
{
{
return
new
TypeWithModifiers
(
newTypeWithModifiers
.
Type
,
this
.
CustomModifiers
.
Concat
(
newTypeWithModifiers
.
CustomModifiers
));
return
new
TypeWithModifiers
(
newTypeWithModifiers
.
Type
,
new
CustomModifiers
.
Concat
(
newTypeWithModifiers
.
CustomModifiers
));
}
}
else
else
{
{
return
this
;
// substitution had no effect on the type
return
this
;
// substitution had no effect on the type
or modifiers
}
}
}
}
}
}
...
...
src/Compilers/CSharp/Test/Symbol/Symbols/CustomModifiersTests.cs
浏览文件 @
238db4f7
...
@@ -1370,5 +1370,214 @@ public override void Test(int [,] c)
...
@@ -1370,5 +1370,214 @@ public override void Test(int [,] c)
CompileAndVerify
(
compilation
,
expectedOutput
:
@"Test
CompileAndVerify
(
compilation
,
expectedOutput
:
@"Test
Overriden"
);
Overriden"
);
}
}
[
ClrOnlyFact
(
ClrOnlyReason
.
Ilasm
),
WorkItem
(
5725
,
"https://github.com/dotnet/roslyn/issues/5725"
)]
public
void
ModifiersWithConstructedType_01
()
{
var
ilSource
=
@"
.class public auto ansi beforefieldinit CL1`1<valuetype .ctor ([mscorlib]System.ValueType) T1>
extends[mscorlib] System.Object
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call instance void[mscorlib] System.Object::.ctor()
IL_0006:
ret
} // end of method CL1`1::.ctor
.method public hidebysig newslot virtual
instance void Test(!T1 modopt(valuetype [mscorlib]System.Nullable`1<!T1>) t1) cil managed
{
// Code size 1 (0x1)
.maxstack 1
IL_0000: ldstr ""Test""
IL_0005: call void [mscorlib]System.Console::WriteLine(string)
IL_000a: ret
} // end of method CL1`1::Test
} // end of class CL1`1
.class public auto ansi beforefieldinit CL2
extends class CL1`1<int32 modopt([mscorlib]System.Runtime.CompilerServices.IsLong)>
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call instance void class CL1`1<int32 modopt([mscorlib]System.Runtime.CompilerServices.IsLong)>::.ctor()
IL_0006: ret
} // end of method CL2::.ctor
} // end of class CL2
"
;
var
source
=
@"
class Test
{
static void Main()
{
var x = new CL2();
x.Test(1);
x = new CL3();
x.Test(1);
}
}
class CL3 : CL2
{
public override void Test(int c)
{
System.Console.WriteLine(""Overriden"");
}
}"
;
var
compilation
=
CreateCompilationWithCustomILSource
(
source
,
ilSource
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
compilation
,
expectedOutput
:
@"Test
Overriden"
);
}
[
ClrOnlyFact
(
ClrOnlyReason
.
Ilasm
),
WorkItem
(
5725
,
"https://github.com/dotnet/roslyn/issues/5725"
)]
public
void
ModifiersWithConstructedType_02
()
{
var
ilSource
=
@"
.class public auto ansi beforefieldinit CL1`1<valuetype .ctor ([mscorlib]System.ValueType) T1>
extends[mscorlib] System.Object
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call instance void[mscorlib] System.Object::.ctor()
IL_0006:
ret
} // end of method CL1`1::.ctor
.method public hidebysig newslot virtual
instance void Test(!T1 modopt(valuetype [mscorlib]System.Nullable`1) t1) cil managed
{
// Code size 1 (0x1)
.maxstack 1
IL_0000: ldstr ""Test""
IL_0005: call void [mscorlib]System.Console::WriteLine(string)
IL_000a: ret
} // end of method CL1`1::Test
} // end of class CL1`1
.class public auto ansi beforefieldinit CL2
extends class CL1`1<int32 modopt([mscorlib]System.Runtime.CompilerServices.IsLong)>
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call instance void class CL1`1<int32 modopt([mscorlib]System.Runtime.CompilerServices.IsLong)>::.ctor()
IL_0006: ret
} // end of method CL2::.ctor
} // end of class CL2
"
;
var
source
=
@"
class Test
{
static void Main()
{
var x = new CL2();
x.Test(1);
x = new CL3();
x.Test(1);
}
}
class CL3 : CL2
{
public override void Test(int c)
{
System.Console.WriteLine(""Overriden"");
}
}"
;
var
compilation
=
CreateCompilationWithCustomILSource
(
source
,
ilSource
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
compilation
,
expectedOutput
:
@"Test
Overriden"
);
}
[
ClrOnlyFact
(
ClrOnlyReason
.
Ilasm
),
WorkItem
(
5725
,
"https://github.com/dotnet/roslyn/issues/5725"
)]
public
void
ModifiersWithConstructedType_03
()
{
var
ilSource
=
@"
.class public auto ansi beforefieldinit CL1`1<valuetype .ctor ([mscorlib]System.ValueType) T1>
extends[mscorlib] System.Object
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call instance void[mscorlib] System.Object::.ctor()
IL_0006:
ret
} // end of method CL1`1::.ctor
.method public hidebysig newslot virtual
instance int32 modopt(CL2) modopt(valuetype [mscorlib]System.Nullable`1<!T1>) modopt(valuetype [mscorlib]System.Nullable`1<!T1>) modopt(CL2) [] Test(!T1 t1) cil managed
{
// Code size 1 (0x1)
.maxstack 1
IL_0000: ldstr ""Test""
IL_0005: call void [mscorlib]System.Console::WriteLine(string)
IL_0006: ldnull
IL_000a: ret
} // end of method CL1`1::Test
} // end of class CL1`1
.class public auto ansi beforefieldinit CL2
extends class CL1`1<int32 modopt([mscorlib]System.Runtime.CompilerServices.IsLong)>
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call instance void class CL1`1<int32 modopt([mscorlib]System.Runtime.CompilerServices.IsLong)>::.ctor()
IL_0006: ret
} // end of method CL2::.ctor
} // end of class CL2
"
;
var
source
=
@"
class Test
{
static void Main()
{
var x = new CL2();
x.Test(1);
x = new CL3();
x.Test(1);
}
}
class CL3 : CL2
{
public override int[] Test(int c)
{
System.Console.WriteLine(""Overriden"");
return null;
}
}"
;
var
compilation
=
CreateCompilationWithCustomILSource
(
source
,
ilSource
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
compilation
,
expectedOutput
:
@"Test
Overriden"
);
}
}
}
}
}
\ No newline at end of file
src/Compilers/Core/Portable/MetadataReader/MetadataDecoder.cs
浏览文件 @
238db4f7
...
@@ -309,56 +309,63 @@ private TypeSymbol DecodeTypeOrThrow(ref BlobReader ppSig, SignatureTypeCode typ
...
@@ -309,56 +309,63 @@ private TypeSymbol DecodeTypeOrThrow(ref BlobReader ppSig, SignatureTypeCode typ
break
;
break
;
case
SignatureTypeCode
.
GenericTypeInstance
:
case
SignatureTypeCode
.
GenericTypeInstance
:
SignatureTypeCode
elementTypeCode
=
ppSig
.
ReadSignatureTypeCode
();
typeSymbol
=
DecodeGenericTypeInstanceOrThrow
(
ref
ppSig
,
out
refersToNoPiaLocalType
);
if
(
elementTypeCode
!=
SignatureTypeCode
.
TypeHandle
)
break
;
{
throw
new
UnsupportedSignatureContent
();
}
EntityHandle
tokenGeneric
=
ppSig
.
ReadTypeHandle
();
default
:
int
argumentCount
;
throw
new
UnsupportedSignatureContent
();
if
(!
ppSig
.
TryReadCompressedInteger
(
out
argumentCount
))
}
{
throw
new
UnsupportedSignatureContent
();
}
TypeSymbol
generic
=
GetTypeOfToken
(
tokenGeneric
,
out
refersToNoPiaLocalType
)
;
return
typeSymbol
;
Debug
.
Assert
(!
refersToNoPiaLocalType
||
generic
.
TypeKind
==
TypeKind
.
Error
);
}
var
argumentsBuilder
=
ArrayBuilder
<
KeyValuePair
<
TypeSymbol
,
ImmutableArray
<
ModifierInfo
<
TypeSymbol
>>>>.
GetInstance
(
argumentCount
);
private
TypeSymbol
DecodeGenericTypeInstanceOrThrow
(
ref
BlobReader
ppSig
,
out
bool
refersToNoPiaLocalType
)
var
argumentRefersToNoPiaLocalTypeBuilder
=
ArrayBuilder
<
bool
>.
GetInstance
(
argumentCount
);
{
SignatureTypeCode
elementTypeCode
=
ppSig
.
ReadSignatureTypeCode
();
if
(
elementTypeCode
!=
SignatureTypeCode
.
TypeHandle
)
{
throw
new
UnsupportedSignatureContent
();
}
for
(
int
argumentIndex
=
0
;
argumentIndex
<
argumentCount
;
argumentIndex
++)
EntityHandle
tokenGeneric
=
ppSig
.
ReadTypeHandle
();
{
int
argumentCount
;
bool
argumentRefersToNoPia
;
if
(!
ppSig
.
TryReadCompressedInteger
(
out
argumentCount
))
modifiers
=
DecodeModifiersOrThrow
(
ref
ppSig
,
out
typeCode
);
{
argumentsBuilder
.
Add
(
KeyValuePair
.
Create
(
DecodeTypeOrThrow
(
ref
ppSig
,
typeCode
,
out
argumentRefersToNoPia
),
modifiers
));
throw
new
UnsupportedSignatureContent
();
argumentRefersToNoPiaLocalTypeBuilder
.
Add
(
argumentRefersToNoPia
);
}
}
// The instantiated type might have a generic parent, in which case some or all of the type
TypeSymbol
generic
=
GetTypeOfToken
(
tokenGeneric
,
out
refersToNoPiaLocalType
);
// arguments might actually be for the parent.
Debug
.
Assert
(!
refersToNoPiaLocalType
||
generic
.
TypeKind
==
TypeKind
.
Error
);
var
arguments
=
argumentsBuilder
.
ToImmutableAndFree
();
var
argumentsBuilder
=
ArrayBuilder
<
KeyValuePair
<
TypeSymbol
,
ImmutableArray
<
ModifierInfo
<
TypeSymbol
>>>>.
GetInstance
(
argumentCount
);
var
argumentRefersToNoPiaLocalType
=
argumentRefersToNoPiaLocalTypeBuilder
.
ToImmutableAndFree
();
var
argumentRefersToNoPiaLocalTypeBuilder
=
ArrayBuilder
<
bool
>.
GetInstance
(
argumentCount
);
typeSymbol
=
SubstituteTypeParameters
(
generic
,
arguments
,
argumentRefersToNoPiaLocalType
);
foreach
(
bool
flag
in
argumentRefersToNoPiaLocalType
)
for
(
int
argumentIndex
=
0
;
argumentIndex
<
argumentCount
;
argumentIndex
++
)
{
{
if
(
flag
)
bool
argumentRefersToNoPia
;
{
SignatureTypeCode
typeCode
;
refersToNoPiaLocalType
=
true
;
ImmutableArray
<
ModifierInfo
<
TypeSymbol
>>
modifiers
=
DecodeModifiersOrThrow
(
ref
ppSig
,
out
typeCode
)
;
break
;
argumentsBuilder
.
Add
(
KeyValuePair
.
Create
(
DecodeTypeOrThrow
(
ref
ppSig
,
typeCode
,
out
argumentRefersToNoPia
),
modifiers
))
;
}
argumentRefersToNoPiaLocalTypeBuilder
.
Add
(
argumentRefersToNoPia
);
}
}
break
;
// The instantiated type might have a generic parent, in which case some or all of the type
// arguments might actually be for the parent.
default
:
var
arguments
=
argumentsBuilder
.
ToImmutableAndFree
();
throw
new
UnsupportedSignatureContent
();
var
argumentRefersToNoPiaLocalType
=
argumentRefersToNoPiaLocalTypeBuilder
.
ToImmutableAndFree
();
TypeSymbol
typeSymbol
=
SubstituteTypeParameters
(
generic
,
arguments
,
argumentRefersToNoPiaLocalType
);
foreach
(
bool
flag
in
argumentRefersToNoPiaLocalType
)
{
if
(
flag
)
{
refersToNoPiaLocalType
=
true
;
break
;
}
}
}
return
typeSymbol
;
return
typeSymbol
;
}
}
/// <exception cref="UnsupportedSignatureContent">If the encoded type is invalid.</exception>
/// <exception cref="UnsupportedSignatureContent">If the encoded type is invalid.</exception>
...
@@ -653,13 +660,7 @@ private ImmutableArray<ModifierInfo<TypeSymbol>> DecodeModifiersOrThrow(ref Blob
...
@@ -653,13 +660,7 @@ private ImmutableArray<ModifierInfo<TypeSymbol>> DecodeModifiersOrThrow(ref Blob
if
(
typeCode
==
SignatureTypeCode
.
OptionalModifier
)
if
(
typeCode
==
SignatureTypeCode
.
OptionalModifier
)
{
{
EntityHandle
token
=
signatureReader
.
ReadTypeHandle
();
ModifierInfo
<
TypeSymbol
>
modifier
=
new
ModifierInfo
<
TypeSymbol
>(
true
,
DecodeModifierTypeOrThrow
(
ref
signatureReader
));
ModifierInfo
<
TypeSymbol
>
modifier
=
new
ModifierInfo
<
TypeSymbol
>(
true
,
GetTypeOfToken
(
token
));
if
(!
IsAcceptableModOptModifier
(
token
,
modifier
.
Modifier
))
{
throw
new
UnsupportedSignatureContent
();
}
if
(
modifiers
==
null
)
if
(
modifiers
==
null
)
{
{
...
@@ -676,48 +677,83 @@ private ImmutableArray<ModifierInfo<TypeSymbol>> DecodeModifiersOrThrow(ref Blob
...
@@ -676,48 +677,83 @@ private ImmutableArray<ModifierInfo<TypeSymbol>> DecodeModifiersOrThrow(ref Blob
return
modifiers
?.
ToImmutableAndFree
()
??
default
(
ImmutableArray
<
ModifierInfo
<
TypeSymbol
>>);
return
modifiers
?.
ToImmutableAndFree
()
??
default
(
ImmutableArray
<
ModifierInfo
<
TypeSymbol
>>);
}
}
/// <summary>
private
TypeSymbol
DecodeModifierTypeOrThrow
(
ref
BlobReader
signatureReader
)
/// According to ECMA spec:
/// The CMOD_OPT or CMOD_REQD is followed by a metadata token that
/// indexes a row in the TypeDef table or the TypeRef table.
/// i.e. No modopt in DecodeType (though it still works in DecodeModifier).
/// </summary>
private
static
bool
IsAcceptableModOptModifier
(
EntityHandle
token
,
TypeSymbol
modifier
)
{
{
EntityHandle
token
=
signatureReader
.
ReadTypeHandle
();
TypeSymbol
type
;
bool
isNoPiaLocalType
;
// According to ECMA spec:
// The CMOD_OPT or CMOD_REQD is followed by a metadata token that
// indexes a row in the TypeDef table or the TypeRef table.
tryAgain
:
switch
(
token
.
Kind
)
switch
(
token
.
Kind
)
{
{
case
HandleKind
.
TypeDefinition
:
case
HandleKind
.
TypeDefinition
:
type
=
GetTypeOfTypeDef
((
TypeDefinitionHandle
)
token
,
out
isNoPiaLocalType
,
isContainingType
:
false
);
// it is valid for a modifier to refer to an unconstructed type, we need to preserve this fact
type
=
SubstituteWithUnboundIfGeneric
(
type
);
break
;
case
HandleKind
.
TypeReference
:
case
HandleKind
.
TypeReference
:
return
true
;
type
=
GetTypeOfTypeRef
((
TypeReferenceHandle
)
token
,
out
isNoPiaLocalType
);
// it is valid for a modifier to refer to an unconstructed type, we need to preserve this fact
type
=
SubstituteWithUnboundIfGeneric
(
type
);
break
;
case
HandleKind
.
TypeSpecification
:
case
HandleKind
.
TypeSpecification
:
// Section 23.2.7 of the CLI spec specifically says that this is not allowed (see comment on method),
// Section 23.2.7 of the CLI spec specifically says that this is not allowed (see comment on method),
// but, apparently, ilasm turns modopt(int32) into a TypeSpec.
// but, apparently, ilasm turns modopt(int32) into a TypeSpec.
if
(
modifier
!=
null
)
// In addition, managed C++ compiler can use constructed generic types as modifiers, for example Nullable<bool>, etc.
// We will support only cases like these even though it looks like CLR allows any types that can be encoded through a TypeSpec.
BlobReader
memoryReader
=
this
.
Module
.
GetTypeSpecificationSignatureReaderOrThrow
((
TypeSpecificationHandle
)
token
);
SignatureTypeCode
typeCode
=
memoryReader
.
ReadSignatureTypeCode
();
bool
refersToNoPiaLocalType
;
switch
(
typeCode
)
{
{
switch
(
modifier
.
SpecialType
)
case
SignatureTypeCode
.
Void
:
{
case
SignatureTypeCode
.
Boolean
:
case
SpecialType
.
System_Void
:
case
SignatureTypeCode
.
SByte
:
case
SpecialType
.
System_Boolean
:
case
SignatureTypeCode
.
Byte
:
case
SpecialType
.
System_SByte
:
case
SignatureTypeCode
.
Int16
:
case
SpecialType
.
System_Byte
:
case
SignatureTypeCode
.
UInt16
:
case
SpecialType
.
System_Int16
:
case
SignatureTypeCode
.
Int32
:
case
SpecialType
.
System_UInt16
:
case
SignatureTypeCode
.
UInt32
:
case
SpecialType
.
System_Int32
:
case
SignatureTypeCode
.
Int64
:
case
SpecialType
.
System_UInt32
:
case
SignatureTypeCode
.
UInt64
:
case
SpecialType
.
System_Int64
:
case
SignatureTypeCode
.
Single
:
case
SpecialType
.
System_UInt64
:
case
SignatureTypeCode
.
Double
:
case
SpecialType
.
System_Single
:
case
SignatureTypeCode
.
Char
:
case
SpecialType
.
System_Double
:
case
SignatureTypeCode
.
String
:
case
SpecialType
.
System_Char
:
case
SignatureTypeCode
.
IntPtr
:
case
SpecialType
.
System_String
:
case
SignatureTypeCode
.
UIntPtr
:
case
SpecialType
.
System_Object
:
case
SignatureTypeCode
.
Object
:
return
true
;
case
SignatureTypeCode
.
TypedReference
:
}
type
=
GetSpecialType
(
typeCode
.
ToSpecialType
());
break
;
case
SignatureTypeCode
.
TypeHandle
:
token
=
memoryReader
.
ReadTypeHandle
();
goto
tryAgain
;
case
SignatureTypeCode
.
GenericTypeInstance
:
type
=
DecodeGenericTypeInstanceOrThrow
(
ref
memoryReader
,
out
refersToNoPiaLocalType
);
break
;
default
:
throw
new
UnsupportedSignatureContent
();
}
}
return
false
;
break
;
default
:
default
:
return
false
;
throw
new
UnsupportedSignatureContent
()
;
}
}
return
type
;
}
}
/// <exception cref="UnsupportedSignatureContent">If the encoded local variable type is invalid.</exception>
/// <exception cref="UnsupportedSignatureContent">If the encoded local variable type is invalid.</exception>
...
@@ -1645,14 +1681,23 @@ protected TypeSymbol DecodeFieldSignature(ref BlobReader signatureReader, out bo
...
@@ -1645,14 +1681,23 @@ protected TypeSymbol DecodeFieldSignature(ref BlobReader signatureReader, out bo
if
(
typeCode
==
SignatureTypeCode
.
OptionalModifier
||
if
(
typeCode
==
SignatureTypeCode
.
OptionalModifier
||
typeCode
==
SignatureTypeCode
.
RequiredModifier
)
typeCode
==
SignatureTypeCode
.
RequiredModifier
)
{
{
EntityHandle
token
=
signatureReader
.
ReadTypeHandle
();
TypeSymbol
type
;
ModifierInfo
<
TypeSymbol
>
modifier
=
new
ModifierInfo
<
TypeSymbol
>((
typeCode
==
SignatureTypeCode
.
OptionalModifier
),
GetTypeOfToken
(
token
));
if
(!
IsAcceptableModOptModifier
(
token
,
modifier
.
Modifier
))
try
{
type
=
DecodeModifierTypeOrThrow
(
ref
signatureReader
);
}
catch
(
BadImageFormatException
mrEx
)
{
return
GetUnsupportedMetadataTypeSymbol
(
mrEx
);
// an exception from metadata reader.
}
catch
(
UnsupportedSignatureContent
)
{
{
return
GetUnsupportedMetadataTypeSymbol
();
// unsupported signature content
return
GetUnsupportedMetadataTypeSymbol
();
// unsupported signature content
}
}
ModifierInfo
<
TypeSymbol
>
modifier
=
new
ModifierInfo
<
TypeSymbol
>((
typeCode
==
SignatureTypeCode
.
OptionalModifier
),
type
);
if
(
IsVolatileModifierType
(
modifier
.
Modifier
))
if
(
IsVolatileModifierType
(
modifier
.
Modifier
))
{
{
isVolatile
=
true
;
isVolatile
=
true
;
...
...
src/Compilers/VisualBasic/Portable/Emit/CustomModifierAdapter.vb
浏览文件 @
238db4f7
...
@@ -15,7 +15,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
...
@@ -15,7 +15,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End
Property
End
Property
Private
Function
CciGetModifier
(
context
As
EmitContext
)
As
Cci
.
ITypeReference
Implements
Cci
.
ICustomModifier
.
GetModifier
Private
Function
CciGetModifier
(
context
As
EmitContext
)
As
Cci
.
ITypeReference
Implements
Cci
.
ICustomModifier
.
GetModifier
Debug
.
Assert
(
Me
.
Modifier
Is
Me
.
Modifier
.
OriginalDefinition
)
Return
DirectCast
(
context
.
Module
,
PEModuleBuilder
).
Translate
(
Me
.
Modifier
,
DirectCast
(
context
.
SyntaxNodeOpt
,
VisualBasicSyntaxNode
),
context
.
Diagnostics
)
Return
DirectCast
(
context
.
Module
,
PEModuleBuilder
).
Translate
(
Me
.
Modifier
,
DirectCast
(
context
.
SyntaxNodeOpt
,
VisualBasicSyntaxNode
),
context
.
Diagnostics
)
End
Function
End
Function
End
Class
End
Class
...
...
src/Compilers/VisualBasic/Portable/Symbols/TypeSubstitution.vb
浏览文件 @
238db4f7
...
@@ -866,6 +866,40 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
...
@@ -866,6 +866,40 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Return
New
TypeWithModifiers
(
type
,
customModifiers
).
InternalSubstituteTypeParameters
(
Me
).
CustomModifiers
Return
New
TypeWithModifiers
(
type
,
customModifiers
).
InternalSubstituteTypeParameters
(
Me
).
CustomModifiers
End
If
End
If
Return
SubstituteCustomModifiers
(
customModifiers
)
End
Function
Function
SubstituteCustomModifiers
(
customModifiers
As
ImmutableArray
(
Of
CustomModifier
))
As
ImmutableArray
(
Of
CustomModifier
)
If
customModifiers
.
IsDefaultOrEmpty
Then
Return
customModifiers
End
If
For
i
As
Integer
=
0
To
customModifiers
.
Length
-
1
Dim
modifier
=
DirectCast
(
customModifiers
(
i
).
Modifier
,
NamedTypeSymbol
)
Dim
substituted
=
DirectCast
(
modifier
.
InternalSubstituteTypeParameters
(
Me
).
AsTypeSymbolOnly
(),
NamedTypeSymbol
)
If
modifier
<>
substituted
Then
Dim
builder
=
ArrayBuilder
(
Of
CustomModifier
).
GetInstance
(
customModifiers
.
Length
)
builder
.
AddRange
(
customModifiers
,
i
)
builder
.
Add
(
If
(
customModifiers
(
i
).
IsOptional
,
VisualBasicCustomModifier
.
CreateOptional
(
substituted
),
VisualBasicCustomModifier
.
CreateRequired
(
substituted
)))
For
j
As
Integer
=
i
+
1
To
customModifiers
.
Length
-
1
modifier
=
DirectCast
(
customModifiers
(
j
).
Modifier
,
NamedTypeSymbol
)
substituted
=
DirectCast
(
modifier
.
InternalSubstituteTypeParameters
(
Me
).
AsTypeSymbolOnly
(),
NamedTypeSymbol
)
If
modifier
<>
substituted
Then
builder
.
Add
(
If
(
customModifiers
(
j
).
IsOptional
,
VisualBasicCustomModifier
.
CreateOptional
(
substituted
),
VisualBasicCustomModifier
.
CreateRequired
(
substituted
)))
Else
builder
.
Add
(
customModifiers
(
j
))
End
If
Next
Debug
.
Assert
(
builder
.
Count
=
customModifiers
.
Length
)
Return
builder
.
ToImmutableAndFree
()
End
If
Next
Return
customModifiers
Return
customModifiers
End
Function
End
Function
...
...
src/Compilers/VisualBasic/Portable/Symbols/TypeWithModifiers.vb
浏览文件 @
238db4f7
...
@@ -66,11 +66,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
...
@@ -66,11 +66,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End
Function
End
Function
Function
InternalSubstituteTypeParameters
(
substitution
As
TypeSubstitution
)
As
TypeWithModifiers
Function
InternalSubstituteTypeParameters
(
substitution
As
TypeSubstitution
)
As
TypeWithModifiers
Dim
newCustomModifiers
=
If
(
substitution
IsNot
Nothing
,
substitution
.
SubstituteCustomModifiers
(
Me
.
CustomModifiers
),
Me
.
CustomModifiers
)
Dim
newTypeWithModifiers
As
TypeWithModifiers
=
Me
.
Type
.
InternalSubstituteTypeParameters
(
substitution
)
Dim
newTypeWithModifiers
As
TypeWithModifiers
=
Me
.
Type
.
InternalSubstituteTypeParameters
(
substitution
)
If
Not
newTypeWithModifiers
.
Is
(
Me
.
Type
)
Then
If
Not
newTypeWithModifiers
.
Is
(
Me
.
Type
)
OrElse
newCustomModifiers
<>
Me
.
CustomModifiers
Then
Return
New
TypeWithModifiers
(
newTypeWithModifiers
.
Type
,
Me
.
CustomModifiers
.
Concat
(
newTypeWithModifiers
.
CustomModifiers
))
Return
New
TypeWithModifiers
(
newTypeWithModifiers
.
Type
,
new
CustomModifiers
.
Concat
(
newTypeWithModifiers
.
CustomModifiers
))
Else
Else
Return
Me
' substitution had no effect on the type
Return
Me
' substitution had no effect on the type
or modifiers
End
If
End
If
End
Function
End
Function
End
Structure
End
Structure
...
...
src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/CustomModifiersTests.vb
浏览文件 @
238db4f7
...
@@ -1318,5 +1318,220 @@ End Class
...
@@ -1318,5 +1318,220 @@ End Class
Overriden"
)
Overriden"
)
End
Sub
End
Sub
<
Fact
,
WorkItem
(
5725
,
"https://github.com/dotnet/roslyn/issues/5725"
)
>
Public
Sub
ModifiersWithConstructedType_01
()
Dim
ilSource
=
<
!
[
CDATA
[
.
class
public
auto
ansi
beforefieldinit
CL1
`
1
<
valuetype
.
ctor
(
[
mscorlib
]
System
.
ValueType
)
T1
>
extends
[
mscorlib
]
System
.
Object
{
.
method
public
hidebysig
specialname
rtspecialname
instance
void
.
ctor
()
cil
managed
{
//
Code
size
7
(
0
x7
)
.
maxstack
1
IL_0000
:
ldarg
.
0
IL_0001
:
call
instance
void
[
mscorlib
]
System
.
Object
::.
ctor
()
IL_0006
:
ret
}
//
end
of
method
CL1
`
1
::.
ctor
.
method
public
hidebysig
newslot
virtual
instance
void
Test
(!
T1
modopt
(
valuetype
[
mscorlib
]
System
.
Nullable
`
1
<
!
T1
>
)
t1
)
cil
managed
{
//
Code
size
1
(
0
x1
)
.
maxstack
1
IL_0000
:
ldstr
"Test"
IL_0005
:
call
void
[
mscorlib
]
System
.
Console
::
WriteLine
(
string
)
IL_000a
:
ret
}
//
end
of
method
CL1
`
1
::
Test
}
//
end
of
class
CL1
`
1
.
class
public
auto
ansi
beforefieldinit
CL2
extends
class
CL1
`
1
<
int32
modopt
(
[
mscorlib
]
System
.
Runtime
.
CompilerServices
.
IsLong
)
>
{
.
method
public
hidebysig
specialname
rtspecialname
instance
void
.
ctor
()
cil
managed
{
//
Code
size
7
(
0
x7
)
.
maxstack
1
IL_0000
:
ldarg
.
0
IL_0001
:
call
instance
void
class
CL1
`
1
<
int32
modopt
(
[
mscorlib
]
System
.
Runtime
.
CompilerServices
.
IsLong
)
>
::.
ctor
()
IL_0006
:
ret
}
//
end
of
method
CL2
::.
ctor
}
//
end
of
class
CL2
]]
>
.
Value
Dim
vbSource
=
<
compilation
>
<
file
name
=
"c.vb"
><
!
[
CDATA
[
Class
Module1
Shared
Sub
Main
()
Dim
x
=
new
CL2
()
x
.
Test
(
1
)
x
=
new
CL3
()
x
.
Test
(
1
)
End
Sub
End
Class
class
CL3
Inherits
CL2
public
overrides
Sub
Test
(
c
As
Integer
)
System
.
Console
.
WriteLine
(
"Overriden"
)
end
Sub
End
Class
]]>
</
file
>
</
compilation
>
Dim
compilation
=
CreateCompilationWithCustomILSource
(
vbSource
,
ilSource
,
options
:
=
TestOptions
.
ReleaseExe
)
CompileAndVerify
(
compilation
,
expectedOutput
:
=
"Test
Overriden"
)
End
Sub
<
Fact
,
WorkItem
(
5725
,
"https://github.com/dotnet/roslyn/issues/5725"
)
>
Public
Sub
ModifiersWithConstructedType_02
()
Dim
ilSource
=
<
!
[
CDATA
[
.
class
public
auto
ansi
beforefieldinit
CL1
`
1
<
valuetype
.
ctor
(
[
mscorlib
]
System
.
ValueType
)
T1
>
extends
[
mscorlib
]
System
.
Object
{
.
method
public
hidebysig
specialname
rtspecialname
instance
void
.
ctor
()
cil
managed
{
//
Code
size
7
(
0
x7
)
.
maxstack
1
IL_0000
:
ldarg
.
0
IL_0001
:
call
instance
void
[
mscorlib
]
System
.
Object
::.
ctor
()
IL_0006
:
ret
}
//
end
of
method
CL1
`
1
::.
ctor
.
method
public
hidebysig
newslot
virtual
instance
void
Test
(!
T1
modopt
(
valuetype
[
mscorlib
]
System
.
Nullable
`
1
)
t1
)
cil
managed
{
//
Code
size
1
(
0
x1
)
.
maxstack
1
IL_0000
:
ldstr
"Test"
IL_0005
:
call
void
[
mscorlib
]
System
.
Console
::
WriteLine
(
string
)
IL_000a
:
ret
}
//
end
of
method
CL1
`
1
::
Test
}
//
end
of
class
CL1
`
1
.
class
public
auto
ansi
beforefieldinit
CL2
extends
class
CL1
`
1
<
int32
modopt
(
[
mscorlib
]
System
.
Runtime
.
CompilerServices
.
IsLong
)
>
{
.
method
public
hidebysig
specialname
rtspecialname
instance
void
.
ctor
()
cil
managed
{
//
Code
size
7
(
0
x7
)
.
maxstack
1
IL_0000
:
ldarg
.
0
IL_0001
:
call
instance
void
class
CL1
`
1
<
int32
modopt
(
[
mscorlib
]
System
.
Runtime
.
CompilerServices
.
IsLong
)
>
::.
ctor
()
IL_0006
:
ret
}
//
end
of
method
CL2
::.
ctor
}
//
end
of
class
CL2
]]
>
.
Value
Dim
vbSource
=
<
compilation
>
<
file
name
=
"c.vb"
><
!
[
CDATA
[
Class
Module1
Shared
Sub
Main
()
Dim
x
=
new
CL2
()
x
.
Test
(
1
)
x
=
new
CL3
()
x
.
Test
(
1
)
End
Sub
End
Class
class
CL3
Inherits
CL2
public
overrides
Sub
Test
(
c
As
Integer
)
System
.
Console
.
WriteLine
(
"Overriden"
)
end
Sub
End
Class
]]>
</
file
>
</
compilation
>
Dim
compilation
=
CreateCompilationWithCustomILSource
(
vbSource
,
ilSource
,
options
:
=
TestOptions
.
ReleaseExe
)
CompileAndVerify
(
compilation
,
expectedOutput
:
=
"Test
Overriden"
)
End
Sub
<
Fact
,
WorkItem
(
5725
,
"https://github.com/dotnet/roslyn/issues/5725"
)
>
Public
Sub
ModifiersWithConstructedType_03
()
Dim
ilSource
=
<
!
[
CDATA
[
.
class
public
auto
ansi
beforefieldinit
CL1
`
1
<
valuetype
.
ctor
(
[
mscorlib
]
System
.
ValueType
)
T1
>
extends
[
mscorlib
]
System
.
Object
{
.
method
public
hidebysig
specialname
rtspecialname
instance
void
.
ctor
()
cil
managed
{
//
Code
size
7
(
0
x7
)
.
maxstack
1
IL_0000
:
ldarg
.
0
IL_0001
:
call
instance
void
[
mscorlib
]
System
.
Object
::.
ctor
()
IL_0006
:
ret
}
//
end
of
method
CL1
`
1
::.
ctor
.
method
public
hidebysig
newslot
virtual
instance
int32
modopt
(
CL2
)
modopt
(
valuetype
[
mscorlib
]
System
.
Nullable
`
1
<
!
T1
>
)
modopt
(
valuetype
[
mscorlib
]
System
.
Nullable
`
1
<
!
T1
>
)
modopt
(
CL2
)
[]
Test
(!
T1
t1
)
cil
managed
{
//
Code
size
1
(
0
x1
)
.
maxstack
1
IL_0000
:
ldstr
"Test"
IL_0005
:
call
void
[
mscorlib
]
System
.
Console
::
WriteLine
(
string
)
IL_0006
:
ldnull
IL_000a
:
ret
}
//
end
of
method
CL1
`
1
::
Test
}
//
end
of
class
CL1
`
1
.
class
public
auto
ansi
beforefieldinit
CL2
extends
class
CL1
`
1
<
int32
modopt
(
[
mscorlib
]
System
.
Runtime
.
CompilerServices
.
IsLong
)
>
{
.
method
public
hidebysig
specialname
rtspecialname
instance
void
.
ctor
()
cil
managed
{
//
Code
size
7
(
0
x7
)
.
maxstack
1
IL_0000
:
ldarg
.
0
IL_0001
:
call
instance
void
class
CL1
`
1
<
int32
modopt
(
[
mscorlib
]
System
.
Runtime
.
CompilerServices
.
IsLong
)
>
::.
ctor
()
IL_0006
:
ret
}
//
end
of
method
CL2
::.
ctor
}
//
end
of
class
CL2
]]
>
.
Value
Dim
vbSource
=
<
compilation
>
<
file
name
=
"c.vb"
><
!
[
CDATA
[
Class
Module1
Shared
Sub
Main
()
Dim
x
=
new
CL2
()
x
.
Test
(
1
)
x
=
new
CL3
()
x
.
Test
(
1
)
End
Sub
End
Class
class
CL3
Inherits
CL2
public
overrides
Function
Test
(
c
As
Integer
)
As
Integer
()
System
.
Console
.
WriteLine
(
"Overriden"
)
return
Nothing
end
Function
End
Class
]]>
</
file
>
</
compilation
>
Dim
compilation
=
CreateCompilationWithCustomILSource
(
vbSource
,
ilSource
,
options
:
=
TestOptions
.
ReleaseExe
)
CompileAndVerify
(
compilation
,
expectedOutput
:
=
"Test
Overriden"
)
End
Sub
End
Class
End
Class
End
Namespace
End
Namespace
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录