private static bool DoTypesMatch(IType type, UnityTypeSpec typeSpec) { // TODO: Replace with Equals(type, typeSpec.AsIType) if this gets more complex // This handles the types we currently have to deal with - scalars, simple arrays and simple generics. This // method is called frequently, so use KnownTypesCache to mitigate creating too many instances of IType for // the type spec if (typeSpec.IsArray != type is IArrayType) { return(false); } // This doesn't handle an array of generic types, but that's ok if (type is IArrayType arrayType) { return(Equals(arrayType.ElementType.GetTypeElement()?.GetClrName(), typeSpec.ClrTypeName)); } var typeElement = type.GetTypeElement(); if (typeElement == null) { return(false); } if (Equals(typeElement.GetClrName(), typeSpec.ClrTypeName)) { // Now check generics if (typeElement.TypeParameters.Count != typeSpec.TypeParameters.Length) { return(false); } if (typeSpec.TypeParameters.Length > 0) { var substitution = (type as IDeclaredType)?.GetSubstitution(); if (substitution == null) { return(false); } var i = 0; foreach (var typeParameter in substitution.Domain) { var typeParameterType = substitution[typeParameter]; if (!Equals(typeParameterType.GetTypeElement()?.GetClrName(), typeSpec.TypeParameters[i])) { return(false); } i++; } } return(true); } return(false); }
public UnityEventFunctionParameter([NotNull] string name, [NotNull] UnityTypeSpec typeSpec, [CanBeNull] string description, bool isByRef, bool isOptional, string justification) { Name = name; TypeSpec = typeSpec; Description = description; IsByRef = isByRef; IsOptional = isOptional; Justification = justification; }
private static object GetTypeObject(UnityTypeSpec typeSpec, KnownTypesCache knownTypesCache, IPsiModule module) { if (typeSpec.TypeParameters.Length == 0) { var keyword = CSharpTypeFactory.GetTypeKeyword(typeSpec.ClrTypeName); if (keyword != null) { return(keyword); } } return(typeSpec.AsIType(knownTypesCache, module)); }
public UnityEventFunction([NotNull] string name, [NotNull] IClrTypeName typeName, [NotNull] UnityTypeSpec returnType, bool isStatic, bool canBeCoroutine, string description, bool undocumented, Version minimumVersion, Version maximumVersion, [NotNull] params UnityEventFunctionParameter[] parameters) { Description = description; Undocumented = undocumented; IsStatic = isStatic; CanBeCoroutine = canBeCoroutine; myMinimumVersion = minimumVersion; myMaximumVersion = maximumVersion; Name = name; TypeName = typeName; ReturnType = returnType; Parameters = parameters.Length > 0 ? parameters : EmptyArray <UnityEventFunctionParameter> .Instance; }
private UnityTypeSpec GetInternedTypeSpec(string typeName, bool isArray) { // Note that the typeName might be a closed generic type, which is not a valid IClrTypeName, but is a good key var key = typeName + (isArray ? "[]" : string.Empty); if (!myTypeSpecs.TryGetValue(key, out var typeSpec)) { // Note that this means the serialised name needs to be a CLR type name, not a C# name. So System.String // instead of `string` and `System.Collections.Generic.List`1[[System.String]]` instead of List<string>. // Also note that IClrTypeName does not handle closed generics, so we need to strip the type parameters. if (typeName.Contains('`')) { // We don't handle nested generics var match = Regex.Match(typeName, @"^(?<outer>.*`(?<count>\d+))\[\[(?<parameters>.*)\]\]$"); if (match.Success) { var outer = match.Groups["outer"]; var parameters = match.Groups["parameters"]; var @params = parameters.Value.Split(','); var typeNames = new IClrTypeName[@params.Length]; for (var i = 0; i < @params.Length; i++) { typeNames[i] = GetInternedClrTypeName(@params[i]); } var outerTypeName = GetInternedClrTypeName(outer.Value); typeSpec = new UnityTypeSpec(outerTypeName, isArray, typeNames); myTypeSpecs.Add(key, typeSpec); } else { // We control the data coming in, so we'll only see this at dev time throw new InvalidDataException("Unhandled formatting for CLR type name"); } } else { var clrTypeName = GetInternedClrTypeName(typeName); typeSpec = new UnityTypeSpec(clrTypeName, isArray); myTypeSpecs.Add(key, typeSpec); } } return(typeSpec); }