public EnumEntity RegisterEnum(string enumName, NamespaceEntity namespaceEntity) { var namespaceQualifiedId = namespaceEntity.GetNamespaceQualifiedId(enumName); if (Entities.Any(e => e.NamespaceQualifiedId.Equals(namespaceQualifiedId))) { throw new InvalidOperationException($"Enum entity with id '{namespaceQualifiedId}' already exists."); } var entity = new EnumEntity(enumName, namespaceQualifiedId, namespaceEntity); Entities.Add(entity); return(entity); }
public void RegisterNamespaceType(TypeDefinition typeDefinition, NamespaceEntity namespaceEntity) { if (!string.IsNullOrEmpty(typeDefinition.Id)) { entitiesContext.Types.RegisterType(typeDefinition.Id, typeDefinition, namespaceEntity); } else if (!string.IsNullOrEmpty(typeDefinition.Extend)) { entitiesContext.Types.RegisterTypeExtension(typeDefinition.Extend, typeDefinition, namespaceEntity); } else { logger.LogError("Type definition in namespace '{FullName}' must have an ID or extends another type. {TypeDefinition}", namespaceEntity.FullName, JsonSerializer.Serialize(typeDefinition)); } }
public bool ShouldProcess(NamespaceEntity namespaceEntity) { if (registrationOptions.ExcludeNamespaces is not null && registrationOptions.ExcludeNamespaces.Contains(namespaceEntity.FullName)) { logger.LogWarning("Skipped namespace '{FullName}'.", namespaceEntity.FullName); return(false); } if (registrationOptions.IncludeNamespaces is not null && !registrationOptions.IncludeNamespaces.Contains(namespaceEntity.FullName)) { logger.LogError("Namespace '{FullName}' is not recognized.", namespaceEntity.FullName); return(false); } return(true); }
public void RegisterRootApi(IEnumerable <ClassEntity> classEntities) { var namespaceEntity = new NamespaceEntity(null, string.Empty, string.Empty); var typeDefinition = new TypeDefinition() { Description = registrationOptions.RootApiClassDescription, ObjectProperties = classEntities .Where(classEntity => classEntity.NamespaceEntity.Parent is null) .Select(classEntity => { var propertyDefinition = GetPropertyDefinition(classEntity); return(KeyValuePair.Create(classEntity.NamespaceEntity.Name, propertyDefinition)); }).ToDictionary(p => p.Key, p => p.Value) }; var typeEntity = new TypeEntity(registrationOptions.RootApiClassName, registrationOptions.RootApiClassName, namespaceEntity, typeDefinition); rootApiClassEntityRegistrar.RegisterClass(typeEntity); }
override public void Run() { NameResolutionService.Reset(); foreach (Boo.Lang.Compiler.Ast.Module module in CompileUnit.Modules) { foreach (Import import in module.Imports) { IEntity entity = NameResolutionService.ResolveQualifiedName(import.Namespace); if (null == entity) { Errors.Add(CompilerErrorFactory.InvalidNamespace(import)); entity = TypeSystemServices.ErrorEntity; } else { if (!IsValidNamespace(entity)) { Errors.Add(CompilerErrorFactory.NotANamespace(import, entity.FullName)); entity = TypeSystemServices.ErrorEntity; } else { if (null != import.AssemblyReference) { NamespaceEntity nsInfo = entity as NamespaceEntity; if (null != nsInfo) { entity = new AssemblyQualifiedNamespaceEntity(GetBoundAssembly(import.AssemblyReference), nsInfo); } } if (null != import.Alias) { entity = new AliasedNamespace(import.Alias.Name, entity); import.Alias.Entity = entity; } } } _context.TraceInfo("{1}: import reference '{0}' bound to {2}.", import, import.LexicalInfo, entity.Name); import.Entity = entity; } } }
public PropertyDefinition Convert(EventDefinition eventDefinition, NamespaceEntity namespaceEntity) { if (ShouldCreateEventTypeObject(eventDefinition)) { return(new PropertyDefinition() { Type = ObjectType.EventTypeObject, Description = eventDefinition.Description, IsUnsupported = eventDefinition.IsUnsupported, Deprecated = eventDefinition.Deprecated, ObjectFunctions = GetEventFunctions(eventDefinition, namespaceEntity) }); } return(new PropertyDefinition() { Ref = registrationOptions.BaseEventTypeName, Description = eventDefinition.Description, IsUnsupported = eventDefinition.IsUnsupported, Deprecated = eventDefinition.Deprecated }); }
public void RegisterType(string typeId, TypeDefinition typeDefinition, NamespaceEntity namespaceEntity) { var namespaceQualifiedId = namespaceEntity.GetNamespaceQualifiedId(typeId); if (Entities.Any(e => e.NamespaceQualifiedId.Equals(namespaceQualifiedId))) { throw new InvalidOperationException($"Type entity with id '{namespaceQualifiedId}' already exists."); } var entity = new TypeEntity(typeId, namespaceQualifiedId, namespaceEntity, typeDefinition); if (typeExtensions.ContainsKey(namespaceQualifiedId) && typeExtensions.Remove(namespaceQualifiedId, out var extensions)) { // register all the type extensions that was registered before this type foreach (var extension in extensions) { entity.Extensions.Add(extension); } } Entities.Add(entity); }
public ClrTypeInfo GetClrType(TypeReference?typeReference, NamespaceEntity namespaceEntity) { if (typeReference is null) { throw new ArgumentNullException(nameof(typeReference)); } if (typeReference.Type == ObjectType.Array) { var arrayItemType = GetClrType(typeReference.ArrayItems, namespaceEntity); return(arrayItemType.MakeEnumerableType()); } if (typeReference.Type == ObjectType.Null && typeReference.Ref is null && typeReference.TypeChoices is null) { return(GetClrType(typeof(void))); } if (typeReference.Ref is null && typeReference.TypeChoices is not null) { return(GetClrType(typeof(JsonElement))); } if (typeReference.Type == ObjectType.Function) { return(GetFunctionClrType(typeReference, namespaceEntity)); } var typeId = GetTypeId(typeReference, namespaceEntity); if (!clrTypeStore.ContainsKey(typeId)) { throw new InvalidOperationException($"Type id '{typeId}' is not defined in the CLR types store."); } return(clrTypeStore[typeId]); }
public void ProcessTypeDefinition(string className, TypeDefinition typeDefinition, NamespaceEntity namespaceEntity) { Process(new[] { className }, typeDefinition, namespaceEntity); }
public void RegisterTypeExtension(string typeId, TypeDefinition typeDefinition, NamespaceEntity namespaceEntity) { var namespaceQualifiedId = namespaceEntity.GetNamespaceQualifiedId(typeId); var entity = Entities.SingleOrDefault(e => e.NamespaceQualifiedId.Equals(namespaceQualifiedId)); if (entity is null) { // The type to be extended is not yet registered, store the definition in a dictionary first if (typeExtensions.ContainsKey(namespaceQualifiedId)) { typeExtensions[namespaceQualifiedId].Add(typeDefinition); } else { typeExtensions.Add(namespaceQualifiedId, new List <TypeDefinition>() { typeDefinition }); } } else { entity.Extensions.Add(typeDefinition); } }
public ClrPropertyInfo TranslatePropertyDefinition(string propertyName, PropertyDefinition propertyDefinition, NamespaceEntity namespaceEntity, ClrTypeInfo clrTypeInfo) { var propertyType = clrTypeStore.GetClrType(propertyDefinition, namespaceEntity); if (clrTypeInfo.Metadata.TryGetValue(Constants.TypeMetadata.ClassType, out var classType) && (ClassType)classType == ClassType.CombinedCallbackParameterClass && propertyType.FullName == typeof(object).FullName) { propertyType = propertyType.MakeJsonElement(); } if (propertyDefinition.IsOptional && !propertyType.IsNullable) { propertyType = propertyType.MakeNullable(); } clrTypeInfo.AddRequiredNamespaces(propertyType.ReferenceNamespaces); if (propertyName.Equals(clrTypeInfo.CSharpName, StringComparison.OrdinalIgnoreCase)) { // Property name cannot be the same as declaring type, prefer to change the type name instead of the property name clrTypeInfo.CSharpName = $"{clrTypeInfo.CSharpName}Type"; } return(new ClrPropertyInfo() { Name = propertyName, PrivateName = propertyName.ToCamelCase(), PublicName = propertyName.ToCapitalCase(), Description = propertyDefinition.Description, DeclaringType = clrTypeInfo, PropertyType = propertyType, IsConstant = propertyDefinition.IsConstant, ConstantValue = propertyDefinition.ConstantValue, IsObsolete = propertyDefinition.IsDeprecated, ObsoleteMessage = propertyDefinition.Deprecated }); }
private IEnumerable <FunctionDefinition> GetEventFunctions(EventDefinition eventDefinition, NamespaceEntity namespaceEntity) { var functionDefinitions = new List <FunctionDefinition>(); var baseEventTypeEntity = typeEntityRegistrar.GetTypeEntity(registrationOptions.BaseEventTypeName, namespaceEntity); functionDefinitions.AddRange(GetEventFunctionDefinitions(eventDefinition, baseEventTypeEntity, "addListener", false)); functionDefinitions.AddRange(GetEventFunctionDefinitions(eventDefinition, baseEventTypeEntity, "hasListener", true)); functionDefinitions.AddRange(GetEventFunctionDefinitions(eventDefinition, baseEventTypeEntity, "removeListener", true)); return(functionDefinitions); }
public ClassEntity RegisterNamespaceApi(IEnumerable <NamespaceDefinition> namespaceDefinitions, NamespaceEntity namespaceEntity) { var namespaceDefinition = namespaceDefinitions.First(); if (namespaceDefinitions.Count() > 1) { namespaceDefinition = new NamespaceDefinition() { Description = namespaceDefinitions.FirstOrDefault(definition => definition.Description is not null)?.Description, Events = namespaceDefinitions.SelectMany(definition => definition.Events ?? Enumerable.Empty <EventDefinition>()).ToArray(), Functions = namespaceDefinitions.SelectMany(definition => definition.Functions ?? Enumerable.Empty <FunctionDefinition>()).ToArray(), Namespace = namespaceDefinition.Namespace, Permissions = namespaceDefinitions.SelectMany(definition => definition.Permissions ?? Enumerable.Empty <string>()).Distinct().ToArray(), Properties = namespaceDefinitions.SelectMany(definition => definition.Properties ?? Enumerable.Empty <KeyValuePair <string, PropertyDefinition> >()).ToDictionary(propertyDefinitionPair => propertyDefinitionPair.Key, propertyDefinitionPair => propertyDefinitionPair.Value), Source = namespaceDefinition.Source, Types = namespaceDefinitions.SelectMany(definition => definition.Types ?? Enumerable.Empty <TypeDefinition>()).ToArray() }; } var namespaceApiTypeDefinition = namespaceApiToTypeDefinitionConverter.Convert(namespaceDefinition, namespaceEntity); if (namespaceApiTypeDefinition.Id is null) { throw new InvalidOperationException("Namespace Api should have an Id."); } var namespaceQualifiedId = namespaceEntity.GetNamespaceQualifiedId(namespaceApiTypeDefinition.Id); var typeEntity = new TypeEntity(namespaceApiTypeDefinition.Id, namespaceQualifiedId, namespaceEntity, namespaceApiTypeDefinition); return(apiClassEntityRegistrar.RegisterClass(typeEntity)); }
private void Process(IEnumerable <string> nameHierarchy, TypeReference?typeReference, NamespaceEntity namespaceEntity) { if (typeReference is null || typeReference.IsUnsupported) { return; } if (typeReference.Ref is not null) { var typeEntity = typeEntityRegistrar.GetTypeEntity(typeReference.Ref, namespaceEntity); if (typeReferencesProcessed.Add(typeEntity.NamespaceQualifiedId)) { ProcessTypeDefinition(typeEntity.FormattedName, typeEntity.Definition, typeEntity.NamespaceEntity); } return; } TryHandleSingleTypeChoice(typeReference); TryHandleCallbackParametersCombination(nameHierarchy, typeReference); if (typeReference.Ref is null && IsObjectType(typeReference) && ShouldRegisterObjectType(typeReference)) { if (typeReference.Type == ObjectType.EventTypeObject) { nameHierarchy = SetNameSuffix(nameHierarchy, registrationOptions.EventTypeNameSuffix); } if (typesToRegister.ContainsKey(typeReference)) { ThrowIfNameHierarchyDifferent(nameHierarchy, typesToRegister[typeReference].NameHierarchy); return; } typesToRegister.Add(typeReference, new AnonymousTypeEntityRegistrationInfo(nameHierarchy, typeReference, namespaceEntity)); } Process(SetNameSuffix(nameHierarchy, registrationOptions.ArrayItemTypeNameSuffix), typeReference.ArrayItems, namespaceEntity); ProcessFunctionParameters(nameHierarchy, typeReference.FunctionParameters, namespaceEntity); var functionReturnTypeName = typeReference.Type == ObjectType.PropertyGetterFunction ? nameHierarchy : SetNameSuffix(nameHierarchy, registrationOptions.FunctionReturnTypeNameSuffix); Process(functionReturnTypeName, typeReference.FunctionReturns, namespaceEntity); ProcessFunctions(nameHierarchy, typeReference.ObjectFunctions, namespaceEntity); ProcessProperties(nameHierarchy, typeReference.ObjectProperties, namespaceEntity); ProcessTypeChoices(nameHierarchy, typeReference.TypeChoices, namespaceEntity); }
public ClrMethodInfo TranslateFunctionDefinition(FunctionDefinition functionDefinition, NamespaceEntity namespaceEntity, ClrTypeInfo clrTypeInfo) { if (functionDefinition.Name is null) { throw new InvalidOperationException("Function definition should have a name."); } var parameterDefinitions = functionDefinition.FunctionParameters?.ToList() ?? new List <ParameterDefinition>(); var returnDefinition = GetReturnDefinition(functionDefinition, parameterDefinitions); var methodParameters = parameterDefinitions.Select(parameterDefinition => { var clrParameterInfo = TranslateParameterDefinition(parameterDefinition, namespaceEntity); clrTypeInfo.AddRequiredNamespaces(clrParameterInfo.ParameterType.ReferenceNamespaces); return(clrParameterInfo); }).ToArray(); var methodReturnType = GetReturnType(returnDefinition, namespaceEntity); if (methodReturnType is not null) { clrTypeInfo.AddRequiredNamespaces(methodReturnType.ReferenceNamespaces); } var methodInfo = new ClrMethodInfo() { Name = functionDefinition.Name, PublicName = functionDefinition.Name.ToCapitalCase(), Description = functionDefinition.Description, DeclaringType = clrTypeInfo, Parameters = methodParameters, Return = new ClrMethodReturnInfo() { Description = returnDefinition?.Description, HasReturnType = methodReturnType is not null, ReturnType = methodReturnType },
public TypeEntity GetTypeEntity(string typeId, NamespaceEntity namespaceEntity) { return(entitiesContext.Types.GetTypeEntity(typeId, namespaceEntity)); }
public ClassEntity RegisterNamespaceApi(TypeDefinition namespaceApiTypeDefinition, NamespaceEntity namespaceEntity) { if (namespaceApiTypeDefinition.Id is null) { throw new InvalidOperationException("Namespace Api should have an Id."); } var classEntity = entitiesContext.Classes.RegisterClass(ClassEntityType.ApiClass, namespaceApiTypeDefinition.Id, namespaceEntity); classEntity.TypeDefinition = namespaceApiTypeDefinition; classEntity.Description = namespaceApiTypeDefinition.Description; classEntity.BaseClassName = $"{registrationOptions.ApiClassBaseClassName}"; classEntity.ImplementInterface = true; if (namespaceApiTypeDefinition.ObjectEvents is not null) { classEntity.Events.AddRange(namespaceApiTypeDefinition.ObjectEvents); } if (namespaceApiTypeDefinition.ObjectFunctions is not null) { AddFunctionsToClassEntity(namespaceApiTypeDefinition.ObjectFunctions, classEntity); } if (namespaceApiTypeDefinition.ObjectProperties is not null) { AddPropertiesToClassEntity(namespaceApiTypeDefinition.ObjectProperties, classEntity); } return(classEntity); }
public void RegisterNamespaceTypes(IEnumerable <TypeDefinition>?typeDefinitions, NamespaceEntity namespaceEntity) { if (typeDefinitions is null) { return; } foreach (var typeDefinition in typeDefinitions) { RegisterNamespaceType(typeDefinition, namespaceEntity); } }
public bool HasTypeEntity(string typeId, NamespaceEntity namespaceEntity) { return(entitiesContext.Types.HasTypeEntity(typeId, namespaceEntity)); }
public override void OnImport(Boo.Lang.Compiler.Ast.Import import) { INamespace oldns = NameResolutionService.CurrentNamespace; IEntity entity = null; try { NameResolutionService.EnterNamespace(NameResolutionService.CurrentNamespace.ParentNamespace); entity = NameResolutionService.ResolveQualifiedName(import.Namespace); } finally { NameResolutionService.EnterNamespace(oldns); } if (null == entity) { entity = NameResolutionService.ResolveQualifiedName(import.Namespace); } //if 'import X', try 'import X from X' //comment out next if block if this is not wanted if (null == entity && null == import.AssemblyReference) { if (TryAutoAddAssemblyReference(import)) { entity = NameResolutionService.ResolveQualifiedName(import.Namespace); } } if (null == entity) { Errors.Add(CompilerErrorFactory.InvalidNamespace(import)); entity = TypeSystemServices.ErrorEntity; } else { if (!IsValidNamespace(entity)) { Errors.Add(CompilerErrorFactory.NotANamespace(import, entity.FullName)); entity = TypeSystemServices.ErrorEntity; } else { string name = entity.FullName; if (null != import.AssemblyReference) { NamespaceEntity nsInfo = entity as NamespaceEntity; if (null != nsInfo) { entity = new AssemblyQualifiedNamespaceEntity(GetBoundAssembly(import.AssemblyReference), nsInfo); } } if (null != import.Alias) { entity = new AliasedNamespace(import.Alias.Name, entity); import.Alias.Entity = entity; name = entity.Name; //use alias name instead of namespace name } //only add unique namespaces Import cachedImport = nameSpaces[name] as Import; if (cachedImport == null) { nameSpaces[name] = import; } else { //ignore for partial classes in separate files if (cachedImport.LexicalInfo.FileName == import.LexicalInfo.FileName) { Warnings.Add(CompilerWarningFactory.DuplicateNamespace( import, import.Namespace)); } RemoveCurrentNode(); return; } } } _context.TraceInfo("{1}: import reference '{0}' bound to {2}.", import, import.LexicalInfo, entity.FullName); import.Entity = entity; }
private TypeDefinition GetNamespaceApiTypeDefinition(NamespaceDefinition namespaceDefinition, NamespaceEntity namespaceEntity) { var functions = new List <FunctionDefinition>(); var properties = new Dictionary <string, PropertyDefinition>(); if (namespaceDefinition.Functions is not null) { functions.AddRange(namespaceDefinition.Functions); } if (namespaceDefinition.Properties is not null) { foreach (var propertyDefinitionPair in namespaceDefinition.Properties) { var propertyName = propertyDefinitionPair.Key; var propertyDefinition = propertyDefinitionPair.Value; if (propertyDefinition.IsConstant) { properties.Add(propertyName, GetConstantPropertyDefinition(propertyDefinition)); } else { // If this is not a constant property, convert it to a function functions.Add(new FunctionDefinition() { Name = propertyName, Type = ObjectType.PropertyGetterFunction, Async = "true", FunctionReturns = SerializationHelper.DeserializeTo <FunctionReturnDefinition>(propertyDefinition) }); } } } return(new TypeDefinition() { Id = namespaceEntity.FormattedName + registrationOptions.ApiClassNamePostfix, Description = namespaceDefinition.Description, Type = ObjectType.Object, ObjectFunctions = functions.Any() ? functions : null, ObjectProperties = properties.Any() ? properties : null, ObjectEvents = namespaceDefinition.Events }); }
public ClassEntity RegisterClass(ClassType type, string className, TypeDefinition typeDefinition, NamespaceEntity namespaceEntity) { var namespaceQualifiedId = namespaceEntity.GetNamespaceQualifiedId(className); if (Entities.Any(e => e.NamespaceQualifiedId.Equals(namespaceQualifiedId))) { throw new InvalidOperationException($"Class entity with id '{namespaceQualifiedId}' already exists."); } var entity = new ClassEntity(type, className, namespaceQualifiedId, typeDefinition, namespaceEntity); Entities.Add(entity); return(entity); }
private IDictionary <string, PropertyDefinition>?GetNamespaceApiPropertyDefinitions(NamespaceDefinition namespaceDefinition, NamespaceEntity namespaceEntity) { var properties = new Dictionary <string, PropertyDefinition>(); if (namespaceDefinition.Properties is not null) { foreach (var propertyDefinitionPair in namespaceDefinition.Properties) { var propertyName = propertyDefinitionPair.Key; var propertyDefinition = propertyDefinitionPair.Value; if (propertyDefinition.IsConstant) { properties.Add(propertyName, GetConstantPropertyDefinition(propertyDefinition)); } } } if (namespaceDefinition.Events is not null) { foreach (var eventDefinition in namespaceDefinition.Events) { if (eventDefinition.Name is null) { throw new InvalidOperationException("Event definition should have a Name."); } var propertyDefinition = eventDefinitionToPropertyDefinitionConverter.Convert(eventDefinition, namespaceEntity); properties.Add(eventDefinition.Name, propertyDefinition); } } return(properties.Any() ? properties : null); }