mirror of
https://github.com/SSCLI/sscli_20021101
synced 2026-06-08 12:28:57 +00:00
9fa3874800
Moved the original file to the archive subfolder.
483 lines
22 KiB
C#
483 lines
22 KiB
C#
// ==++==
|
|
//
|
|
//
|
|
// Copyright (c) 2002 Microsoft Corporation. All rights reserved.
|
|
//
|
|
// The use and distribution terms for this software are contained in the file
|
|
// named license.txt, which can be found in the root of this distribution.
|
|
// By using this software in any fashion, you are agreeing to be bound by the
|
|
// terms of this license.
|
|
//
|
|
// You must not remove this notice, or any other, from this software.
|
|
//
|
|
//
|
|
// ==--==
|
|
namespace Microsoft.JScript
|
|
{
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Configuration.Assemblies;
|
|
using System.Globalization;
|
|
using System.Reflection;
|
|
using System.Reflection.Emit;
|
|
using System.Security.Permissions;
|
|
|
|
internal sealed class CustomAttribute : AST{
|
|
private AST ctor;
|
|
private ASTList args;
|
|
private AST target; //indicates what kind of member the custom attribute is being applied to
|
|
internal Object type; // will contain either the Type or ClassScope for the custom attribute type
|
|
private ArrayList positionalArgValues;
|
|
private ArrayList namedArgFields;
|
|
private ArrayList namedArgFieldValues;
|
|
private ArrayList namedArgProperties;
|
|
private ArrayList namedArgPropertyValues;
|
|
internal bool raiseToPropertyLevel;
|
|
|
|
internal CustomAttribute(Context context, AST func, ASTList args)
|
|
: base(context) {
|
|
this.ctor = func;
|
|
this.args = args;
|
|
this.target = null;
|
|
this.type = null;
|
|
this.positionalArgValues = new ArrayList();
|
|
this.namedArgFields = new ArrayList();
|
|
this.namedArgFieldValues = new ArrayList();
|
|
this.namedArgProperties = new ArrayList();
|
|
this.namedArgPropertyValues = new ArrayList();
|
|
this.raiseToPropertyLevel = false;
|
|
}
|
|
|
|
//Check that custom attribute is applicable to its target
|
|
private bool CheckIfTargetOK(Object caType){
|
|
if (caType == null) return false;
|
|
AttributeTargets validOn = (AttributeTargets)0;
|
|
Type caTypeT = caType as Type;
|
|
if (caTypeT != null){
|
|
Object[] usage = caTypeT.GetCustomAttributes(typeof(AttributeUsageAttribute), true);
|
|
validOn = ((AttributeUsageAttribute)usage[0]).ValidOn;
|
|
}else
|
|
validOn = ((ClassScope)caType).owner.validOn;
|
|
Object target = this.target;
|
|
Class c = target as Class;
|
|
if (c != null){
|
|
if (c.isInterface){
|
|
if ((validOn & AttributeTargets.Interface) != 0) return true;
|
|
}else if (c is EnumDeclaration){
|
|
if ((validOn & AttributeTargets.Enum) != 0) return true;
|
|
}else if ((validOn & AttributeTargets.Class) != 0){
|
|
if (caTypeT == typeof(AttributeUsageAttribute)){
|
|
//This is an attribute that describes a new attribute class
|
|
//Set the validOn field of Class so that it becomes easier to check the usage of the new attribute
|
|
if (this.positionalArgValues.Count > 0){
|
|
Object par0 = this.positionalArgValues[0];
|
|
if (par0 is AttributeTargets) c.validOn = (AttributeTargets)par0;
|
|
}
|
|
for (int i = 0, n = this.namedArgProperties.Count; i < n; i++){
|
|
PropertyInfo prop = this.namedArgProperties[i] as PropertyInfo;
|
|
if (prop.Name == "AllowMultiple") c.allowMultiple = (bool)this.namedArgPropertyValues[i];
|
|
}
|
|
}
|
|
return true;
|
|
}else if (caTypeT.FullName == "System.NonSerializedAttribute"){
|
|
c.attributes &= ~TypeAttributes.Serializable;
|
|
return false;
|
|
}
|
|
this.context.HandleError(JSError.InvalidCustomAttributeTarget, CustomAttribute.GetTypeName(caType));
|
|
return false;
|
|
}
|
|
FunctionDeclaration fDecl = target as FunctionDeclaration;
|
|
if (fDecl != null){
|
|
if ((validOn & AttributeTargets.Property) != 0 && fDecl.enclosingProperty != null){
|
|
if (fDecl.enclosingProperty.getter == null || ((JSFieldMethod)fDecl.enclosingProperty.getter).func == fDecl.func){
|
|
this.raiseToPropertyLevel = true; return true;
|
|
}else{
|
|
this.context.HandleError(JSError.PropertyLevelAttributesMustBeOnGetter);
|
|
return false;
|
|
}
|
|
}
|
|
if ((validOn & AttributeTargets.Method) != 0 && fDecl.isMethod) return true;
|
|
if ((validOn & AttributeTargets.Constructor) != 0 && fDecl.func.isConstructor) return true;
|
|
this.context.HandleError(JSError.InvalidCustomAttributeTarget, CustomAttribute.GetTypeName(caType));
|
|
return false;
|
|
}
|
|
if (target is VariableDeclaration || target is Constant){
|
|
if ((validOn & AttributeTargets.Field) != 0) return true;
|
|
this.context.HandleError(JSError.InvalidCustomAttributeTarget, CustomAttribute.GetTypeName(caType));
|
|
return false;
|
|
}
|
|
if (target is AssemblyCustomAttributeList && (validOn & AttributeTargets.Assembly) != 0) return true;
|
|
if (target == null && (validOn & AttributeTargets.Parameter) != 0) return true;
|
|
this.context.HandleError(JSError.InvalidCustomAttributeTarget, CustomAttribute.GetTypeName(caType));
|
|
return false;
|
|
}
|
|
|
|
private static ushort DaysSince2000(){
|
|
return (ushort)(DateTime.Now - new DateTime(2000, 1, 1)).Days;
|
|
}
|
|
|
|
internal override Object Evaluate(){
|
|
ConstructorInfo c = (ConstructorInfo)((Binding)this.ctor).member;
|
|
ParameterInfo[] pars = c.GetParameters();
|
|
int pn = pars.Length;
|
|
for (int i = positionalArgValues.Count; i < pn; i++) positionalArgValues.Add(Convert.CoerceT(null, pars[i].ParameterType));
|
|
Object[] pArgVals = new Object[pn]; positionalArgValues.CopyTo(0, pArgVals, 0, pn);
|
|
Object ca = c.Invoke(BindingFlags.ExactBinding, null, pArgVals, null);
|
|
for (int i = 0, n = this.namedArgProperties.Count; i < n; i++){
|
|
JSProperty prop = this.namedArgProperties[i] as JSProperty;
|
|
if (prop != null)
|
|
prop.SetValue(ca, Convert.Coerce(this.namedArgPropertyValues[i], prop.PropertyIR()), null);
|
|
else
|
|
((PropertyInfo)this.namedArgProperties[i]).SetValue(ca, this.namedArgPropertyValues[i], null);
|
|
}
|
|
for (int i = 0, n = this.namedArgFields.Count; i < n; i++){
|
|
JSVariableField field = this.namedArgFields[i] as JSVariableField;
|
|
if (field != null)
|
|
field.SetValue(ca, Convert.Coerce(this.namedArgFieldValues[i], field.GetInferredType(null)));
|
|
else
|
|
((FieldInfo)this.namedArgFields[i]).SetValue(ca, this.namedArgFieldValues[i]);
|
|
}
|
|
return ca;
|
|
}
|
|
|
|
internal CLSComplianceSpec GetCLSComplianceValue(){
|
|
Debug.Assert(this.type == Typeob.CLSCompliantAttribute);
|
|
return ((bool)this.positionalArgValues[0]) ? CLSComplianceSpec.CLSCompliant : CLSComplianceSpec.NonCLSCompliant;
|
|
}
|
|
|
|
private void ConvertClassScopesAndEnumWrappers(ArrayList vals){
|
|
for (int i = 0, n = vals.Count; i < n; i++){
|
|
ClassScope csc = vals[i] as ClassScope;
|
|
if (csc != null){ vals[i] = csc.GetTypeBuilder(); continue;}
|
|
EnumWrapper wrapper = vals[i] as EnumWrapper;
|
|
if (wrapper != null) vals[i] = wrapper.ToNumericValue();
|
|
}
|
|
}
|
|
|
|
private void ConvertFieldAndPropertyInfos(ArrayList vals){
|
|
for (int i = 0, n = vals.Count; i < n; i++){
|
|
JSField jsfld = vals[i] as JSField;
|
|
if (jsfld != null){ vals[i] = jsfld.GetMetaData(); continue;}
|
|
JSProperty jsprop = vals[i] as JSProperty;
|
|
if (jsprop != null){ vals[i] = jsprop.metaData; continue;}
|
|
}
|
|
}
|
|
|
|
internal CustomAttributeBuilder GetCustomAttribute(){
|
|
ConstructorInfo c = (ConstructorInfo)((Binding)this.ctor).member;
|
|
ParameterInfo[] pars = c.GetParameters();
|
|
int pn = pars.Length;
|
|
if (c is JSConstructor)
|
|
c = ((JSConstructor)c).GetConstructorInfo(compilerGlobals);
|
|
this.ConvertClassScopesAndEnumWrappers(this.positionalArgValues);
|
|
this.ConvertClassScopesAndEnumWrappers(this.namedArgPropertyValues);
|
|
this.ConvertClassScopesAndEnumWrappers(this.namedArgFieldValues);
|
|
this.ConvertFieldAndPropertyInfos(this.namedArgProperties);
|
|
this.ConvertFieldAndPropertyInfos(this.namedArgFields);
|
|
for (int i = positionalArgValues.Count; i < pn; i++) positionalArgValues.Add(Convert.CoerceT(null, pars[i].ParameterType));
|
|
Object[] pArgVals = new Object[pn]; positionalArgValues.CopyTo(0, pArgVals, 0, pn);
|
|
PropertyInfo[] nArgProps = new PropertyInfo[namedArgProperties.Count]; namedArgProperties.CopyTo(nArgProps);
|
|
Object[] nArgPVals = new Object[namedArgPropertyValues.Count]; namedArgPropertyValues.CopyTo(nArgPVals);
|
|
FieldInfo[] nArgFields = new FieldInfo[namedArgFields.Count]; namedArgFields.CopyTo(nArgFields);
|
|
Object[] nArgFVals = new Object[namedArgFieldValues.Count]; namedArgFieldValues.CopyTo(nArgFVals);
|
|
return new CustomAttributeBuilder(c, pArgVals, nArgProps, nArgPVals, nArgFields, nArgFVals);
|
|
}
|
|
|
|
internal Object GetTypeIfAttributeHasToBeUnique(){
|
|
Type t = this.type as Type;
|
|
if (t != null){
|
|
Object[] custAttrs = t.GetCustomAttributes(typeof(AttributeUsageAttribute), false);
|
|
if (custAttrs.Length > 0 && !((AttributeUsageAttribute)custAttrs[0]).AllowMultiple) return t;
|
|
return null;
|
|
}
|
|
if (!((ClassScope)this.type).owner.allowMultiple) return this.type;
|
|
return null;
|
|
}
|
|
|
|
private static String GetTypeName(Object t){
|
|
Type ty = t as Type;
|
|
if (ty != null) return ty.FullName;
|
|
return ((ClassScope)t).GetFullName();
|
|
}
|
|
|
|
internal bool IsExpandoAttribute(){ //Use only before partial evaluation has been done
|
|
Lookup id = this.ctor as Lookup;
|
|
return id != null && id.Name == "expando";
|
|
}
|
|
internal override AST PartiallyEvaluate(){
|
|
this.ctor = this.ctor.PartiallyEvaluateAsCallable();
|
|
|
|
//first weed out assignment expressions and use them as property initializers
|
|
ASTList positionalArgs = new ASTList(this.args.context);
|
|
ASTList namedArgs = new ASTList(this.args.context);
|
|
for (int i = 0, m = this.args.count; i < m; i++){
|
|
AST arg = this.args[i];
|
|
Assign assign = arg as Assign;
|
|
if (assign != null){
|
|
assign.rhside = assign.rhside.PartiallyEvaluate();
|
|
namedArgs.Append(assign);
|
|
}else
|
|
positionalArgs.Append(arg.PartiallyEvaluate());
|
|
}
|
|
|
|
int n = positionalArgs.count;
|
|
IReflect[] argIRs = new IReflect[n];
|
|
for (int i = 0; i < n; i++){
|
|
AST arg = positionalArgs[i];
|
|
// only accept ConstantWrappers
|
|
if (arg is ConstantWrapper){
|
|
Object argument = arg.Evaluate();
|
|
if ((argIRs[i] = CustomAttribute.TypeOfArgument(argument)) != null){
|
|
this.positionalArgValues.Add(argument);
|
|
continue;
|
|
}
|
|
}else if (arg is ArrayLiteral && ((ArrayLiteral)arg).IsOkToUseInCustomAttribute()){
|
|
argIRs[i] = Typeob.ArrayObject;
|
|
this.positionalArgValues.Add(arg.Evaluate());
|
|
continue;
|
|
}
|
|
arg.context.HandleError(JSError.InvalidCustomAttributeArgument);
|
|
return null; // the custom attribute is not good and it will be ignored
|
|
}
|
|
|
|
//Get the custom attribute and the appropriate constructor (under the covers)
|
|
this.type = this.ctor.ResolveCustomAttribute(positionalArgs, argIRs, this.target);
|
|
if (this.type == null) return null;
|
|
if (Convert.IsPromotableTo((IReflect)this.type, typeof(CodeAccessSecurityAttribute))){
|
|
this.context.HandleError(JSError.CannotUseStaticSecurityAttribute);
|
|
return null;
|
|
}
|
|
|
|
|
|
//Coerce the positional arguments to the right type and supply default values for optional parameters
|
|
ConstructorInfo c = (ConstructorInfo)((Binding)this.ctor).member;
|
|
ParameterInfo[] parameters = c.GetParameters();
|
|
int j = 0;
|
|
int len = this.positionalArgValues.Count;
|
|
foreach (ParameterInfo p in parameters){
|
|
IReflect ir = p is ParameterDeclaration ? ((ParameterDeclaration)p).ParameterIReflect : p.ParameterType;
|
|
if (j < len ){
|
|
Object value = this.positionalArgValues[j];
|
|
this.positionalArgValues[j] = Convert.Coerce(value, ir, value is ArrayObject);
|
|
j++;
|
|
}else{
|
|
Object value;
|
|
if (p.DefaultValue == System.Convert.DBNull){
|
|
value = Convert.Coerce(null, ir);
|
|
}else
|
|
value = p.DefaultValue;
|
|
this.positionalArgValues.Add(value);
|
|
}
|
|
}
|
|
|
|
//Check validity of property/field initializers
|
|
for (int i = 0, m = namedArgs.count; i < m; i++){
|
|
Assign assign = (Assign)namedArgs[i];
|
|
if (assign.lhside is Lookup &&
|
|
(assign.rhside is ConstantWrapper ||
|
|
(assign.rhside is ArrayLiteral && ((ArrayLiteral)assign.rhside).IsOkToUseInCustomAttribute()))){
|
|
Object value = assign.rhside.Evaluate();
|
|
IReflect argType = null;
|
|
if (value is ArrayObject || ((argType = CustomAttribute.TypeOfArgument(value)) != null && argType != Typeob.Object)){
|
|
String name = ((Lookup)assign.lhside).Name;
|
|
MemberInfo [] members = ((IReflect)this.type).GetMember(name, BindingFlags.Public|BindingFlags.Instance);
|
|
if (members == null || members.Length == 0){
|
|
assign.context.HandleError(JSError.NoSuchMember);
|
|
return null;
|
|
}
|
|
if (members.Length == 1){
|
|
MemberInfo member = members[0];
|
|
if (member is FieldInfo){
|
|
FieldInfo fieldInfo = (FieldInfo)member;
|
|
if (!fieldInfo.IsLiteral && !fieldInfo.IsInitOnly){
|
|
try{
|
|
IReflect ir = fieldInfo is JSVariableField ? ((JSVariableField)fieldInfo).GetInferredType(null) : fieldInfo.FieldType;
|
|
value = Convert.Coerce(value, ir, value is ArrayObject);
|
|
this.namedArgFields.Add(member);
|
|
this.namedArgFieldValues.Add(value);
|
|
continue;
|
|
}catch(JScriptException){
|
|
assign.rhside.context.HandleError(JSError.TypeMismatch);
|
|
return null; // the custom attribute is not good and it will be ignored
|
|
}
|
|
}
|
|
}else if (member is PropertyInfo){
|
|
PropertyInfo propertyInfo = (PropertyInfo)member;
|
|
MethodInfo setMethodInfo = JSProperty.GetSetMethod(propertyInfo, false);
|
|
if (setMethodInfo != null){
|
|
ParameterInfo [] paramInfo = setMethodInfo.GetParameters();
|
|
if (paramInfo != null && paramInfo.Length == 1){
|
|
try{
|
|
IReflect ir = paramInfo[0] is ParameterDeclaration ? ((ParameterDeclaration)paramInfo[0]).ParameterIReflect : paramInfo[0].ParameterType;
|
|
value = Convert.Coerce(value, ir, value is ArrayObject);
|
|
this.namedArgProperties.Add(member);
|
|
this.namedArgPropertyValues.Add(value);
|
|
}catch(JScriptException){
|
|
assign.rhside.context.HandleError(JSError.TypeMismatch);
|
|
return null; // the custom attribute is not good and it will be ignored
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
assign.context.HandleError(JSError.InvalidCustomAttributeArgument);
|
|
return null;
|
|
}
|
|
|
|
if (!this.CheckIfTargetOK(this.type))
|
|
return null; //Ignore attribute
|
|
|
|
//Consume and discard assembly name attributes
|
|
try{
|
|
Type ty = this.type as Type;
|
|
if (ty != null && this.target is AssemblyCustomAttributeList){
|
|
if (ty.FullName == "System.Reflection.AssemblyAlgorithmIdAttribute"){
|
|
if (this.positionalArgValues.Count > 0)
|
|
this.Engine.Globals.assemblyHashAlgorithm = (AssemblyHashAlgorithm)Convert.CoerceT(this.positionalArgValues[0], typeof(AssemblyHashAlgorithm));
|
|
return null;
|
|
}
|
|
if (ty.FullName == "System.Reflection.AssemblyCultureAttribute"){
|
|
if (this.positionalArgValues.Count > 0){
|
|
String cultureId = Convert.ToString(this.positionalArgValues[0]);
|
|
if (this.Engine.PEFileKind != PEFileKinds.Dll && cultureId.Length > 0){
|
|
this.context.HandleError(JSError.ExecutablesCannotBeLocalized);
|
|
return null;
|
|
}
|
|
this.Engine.Globals.assemblyCulture = new CultureInfo(cultureId);
|
|
}
|
|
return null;
|
|
}
|
|
if (ty.FullName == "System.Reflection.AssemblyDelaySignAttribute"){
|
|
if (this.positionalArgValues.Count > 0)
|
|
this.Engine.Globals.assemblyDelaySign = Convert.ToBoolean(this.positionalArgValues[0], false);
|
|
return null;
|
|
}
|
|
if (ty.FullName == "System.Reflection.AssemblyFlagsAttribute"){
|
|
if (this.positionalArgValues.Count > 0)
|
|
this.Engine.Globals.assemblyFlags = (AssemblyFlags)(uint)Convert.CoerceT(this.positionalArgValues[0], typeof(uint));
|
|
return null;
|
|
}
|
|
if (ty.FullName == "System.Reflection.AssemblyKeyFileAttribute"){
|
|
if (this.positionalArgValues.Count > 0){
|
|
this.Engine.Globals.assemblyKeyFileName = Convert.ToString(this.positionalArgValues[0]);
|
|
if (this.Engine.Globals.assemblyKeyFileName != null && this.Engine.Globals.assemblyKeyFileName.Length == 0)
|
|
this.Engine.Globals.assemblyKeyFileName = null;
|
|
}
|
|
return null;
|
|
}
|
|
if (ty.FullName == "System.Reflection.AssemblyKeyNameAttribute"){
|
|
if (this.positionalArgValues.Count > 0){
|
|
this.Engine.Globals.assemblyKeyName = Convert.ToString(this.positionalArgValues[0]);
|
|
if (this.Engine.Globals.assemblyKeyName != null && this.Engine.Globals.assemblyKeyName.Length == 0)
|
|
this.Engine.Globals.assemblyKeyName = null;
|
|
}
|
|
return null;
|
|
}
|
|
if (ty.FullName == "System.Reflection.AssemblyVersionAttribute"){
|
|
if (this.positionalArgValues.Count > 0)
|
|
this.Engine.Globals.assemblyVersion = this.ParseVersion(Convert.ToString(this.positionalArgValues[0]));
|
|
return null;
|
|
}
|
|
if (ty.FullName == "System.CLSCompliantAttribute"){
|
|
this.Engine.isCLSCompliant = this.args == null || this.args.count == 0 || Convert.ToBoolean(this.positionalArgValues[0], false);
|
|
return this;
|
|
}
|
|
}
|
|
}catch(ArgumentException){
|
|
this.context.HandleError(JSError.InvalidCall);
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
private Version ParseVersion(String vString){
|
|
ushort major = 1;
|
|
ushort minor = 0;
|
|
ushort build = 0;
|
|
ushort revision = 0;
|
|
try{
|
|
int n = vString.Length;
|
|
int i = vString.IndexOf('.', 0);
|
|
if (i < 0) throw new Exception();
|
|
major = UInt16.Parse(vString.Substring(0, i), CultureInfo.InvariantCulture);
|
|
int j = vString.IndexOf('.', i+1);
|
|
if (j < i+1)
|
|
minor = UInt16.Parse(vString.Substring(i+1, n-i-1), CultureInfo.InvariantCulture);
|
|
else{
|
|
minor = UInt16.Parse(vString.Substring(i+1, j-i-1), CultureInfo.InvariantCulture);
|
|
if (vString[j+1] == '*'){
|
|
build = CustomAttribute.DaysSince2000();
|
|
revision = CustomAttribute.SecondsSinceMidnight();
|
|
}else{
|
|
int k = vString.IndexOf('.', j+1);
|
|
if (k < j+1)
|
|
build = UInt16.Parse(vString.Substring(j+1, n-j-1), CultureInfo.InvariantCulture);
|
|
else{
|
|
build = UInt16.Parse(vString.Substring(j+1, k-j-1), CultureInfo.InvariantCulture);
|
|
if (vString[k+1] == '*')
|
|
revision = CustomAttribute.SecondsSinceMidnight();
|
|
else
|
|
revision = UInt16.Parse(vString.Substring(k+1, n-k-1), CultureInfo.InvariantCulture);
|
|
}
|
|
}
|
|
}
|
|
}catch(Exception){
|
|
this.args[0].context.HandleError(JSError.NotValidVersionString);
|
|
}
|
|
return new Version(major, minor, build, revision);
|
|
}
|
|
|
|
private static ushort SecondsSinceMidnight(){
|
|
TimeSpan sinceMidnight = DateTime.Now - DateTime.Today;
|
|
return (ushort)((sinceMidnight.Hours*60*60+sinceMidnight.Minutes*60+sinceMidnight.Seconds)/2);
|
|
}
|
|
|
|
internal void SetTarget(AST target){
|
|
this.target = target;
|
|
}
|
|
|
|
internal override void TranslateToIL(ILGenerator il, Type rtype){
|
|
}
|
|
|
|
internal override void TranslateToILInitializer(ILGenerator il){
|
|
}
|
|
|
|
internal static IReflect TypeOfArgument(Object argument){
|
|
if (argument is Enum)
|
|
return argument.GetType();
|
|
else if (argument is EnumWrapper)
|
|
return ((EnumWrapper)argument).type;
|
|
else{
|
|
switch (Convert.GetTypeCode(argument)){
|
|
case TypeCode.Empty:
|
|
case TypeCode.DBNull: return Typeob.Object;
|
|
case TypeCode.Boolean: return Typeob.Boolean;
|
|
case TypeCode.Char: return Typeob.Char;
|
|
case TypeCode.Byte: return Typeob.Byte;
|
|
case TypeCode.UInt16: return Typeob.UInt16;
|
|
case TypeCode.UInt32: return Typeob.UInt32;
|
|
case TypeCode.UInt64: return Typeob.UInt64;
|
|
case TypeCode.SByte: return Typeob.SByte;
|
|
case TypeCode.Int16: return Typeob.Int16;
|
|
case TypeCode.Int32: return Typeob.Int32;
|
|
case TypeCode.Int64: return Typeob.Int64;
|
|
case TypeCode.Single: return Typeob.Single;
|
|
case TypeCode.Double: return Typeob.Double;
|
|
case TypeCode.Object:
|
|
if (argument is Type) return Typeob.Type;
|
|
if (argument is ClassScope) return Typeob.Type;
|
|
break;
|
|
case TypeCode.String: return Typeob.String;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|