diff --git a/Import/GacUICompiler.cpp b/Import/GacUICompiler.cpp index 330a1452..8828f391 100644 --- a/Import/GacUICompiler.cpp +++ b/Import/GacUICompiler.cpp @@ -739,7 +739,8 @@ GuiDefaultInstanceLoader block->statements.Add(stat); } break; - default:; + default: + errors.Add(L"Precompile: Property \"" + prop.ToString() + L"\" of type \"" + typeInfo.typeName.ToString() + L"\" is not assignable."); } } } @@ -1541,69 +1542,40 @@ Instance Type Resolver (Instance) compiled->context = nullptr;\ }\ +#define DELETE_ASSEMBLY(PATH)\ + if (auto compiled = context.targetFolder->GetValueByPath(PATH).Cast())\ + {\ + compiled->context = nullptr;\ + compiled->assembly = nullptr;\ + }\ + void PerResourcePrecompile(Ptr resource, GuiResourcePrecompileContext& context, collections::List& errors)override { switch (context.passIndex) { - case Instance_CollectInstanceTypes: - { - if (auto obj = resource->GetContent().Cast()) - { - Ptr ibRecord; - - vint index = context.additionalProperties.Keys().IndexOf(this); - if (index == -1) - { - ibRecord = new types::InstanceBaseRecord; - context.additionalProperties.Add(this, ibRecord); - } - else - { - ibRecord = context.additionalProperties.Values()[index].Cast(); - } - - if (auto source = FindInstanceLoadingSource(obj, obj->instance.Obj())) - { - if (auto td = GetInstanceLoaderManager()->GetTypeDescriptorForType(source.typeName)) - { - IGuiInstanceLoader::TypeInfo typeInfo; - typeInfo.typeName = source.typeName; - typeInfo.typeDescriptor = td; - - auto key = GlobalStringKey::Get(obj->className); - index = ibRecord->instanceBases.Keys().IndexOf(key); - if (index == -1) - { - ibRecord->instanceBases.Add(key, typeInfo); - } - else - { - errors.Add(L"Precompile: Found multiple definition for \"" + obj->className + L"\"."); - } - } - } - } - } - break; case Instance_GenerateTemporaryClass: + ENSURE_ASSEMBLY_EXISTS(Path_TemporaryClass) + case Instance_CollectInstanceTypes: { if (auto obj = resource->GetContent().Cast()) { obj->ApplyStyles(context.resolver, errors); - auto ibRecord = context.additionalProperties[this].Cast(); - if (auto module = Workflow_GenerateInstanceClass(obj, ibRecord, *(types::ResolvingResult*)nullptr, errors, true)) + if (auto module = Workflow_GenerateInstanceClass(obj, *(types::ResolvingResult*)nullptr, errors, context.passIndex)) { AddModule(context, Path_TemporaryClass, module, GuiInstanceCompiledWorkflow::TemporaryClass); } - auto record = context.targetFolder->GetValueByPath(L"ClassNameRecord").Cast(); - if (!record) + if (context.passIndex == Instance_CollectInstanceTypes) { - record = MakePtr(); - context.targetFolder->CreateValueByPath(L"ClassNameRecord", L"ClassNameRecord", record); + auto record = context.targetFolder->GetValueByPath(L"ClassNameRecord").Cast(); + if (!record) + { + record = MakePtr(); + context.targetFolder->CreateValueByPath(L"ClassNameRecord", L"ClassNameRecord", record); + } + record->classNames.Add(obj->className); } - record->classNames.Add(obj->className); } } break; @@ -1632,7 +1604,7 @@ Instance Type Resolver (Instance) if (index != -1) { auto resolvingResult = context.additionalProperties.Values()[index].Cast(); - if (auto module = Workflow_GenerateInstanceClass(obj, nullptr, *resolvingResult.Obj(), errors, false)) + if (auto module = Workflow_GenerateInstanceClass(obj, *resolvingResult.Obj(), errors, context.passIndex)) { AddModule(context, Path_InstanceClass, module, GuiInstanceCompiledWorkflow::InstanceClass); } @@ -1645,43 +1617,35 @@ Instance Type Resolver (Instance) void PerPassPrecompile(GuiResourcePrecompileContext& context, collections::List& errors)override { + WString path; switch (context.passIndex) { case Instance_ValidateDependency: + path = Path_TemporaryClass; break; case Instance_CompileTemporaryClass: - case Instance_CompileInstanceCtor: - case Instance_CompileInstanceClass: - { - WString path; - if (context.passIndex == Instance_CompileTemporaryClass) - { - path = Path_TemporaryClass; - } - else if (context.passIndex == Instance_CompileInstanceCtor) - { - path = Path_InstanceCtor; - } - else if (context.passIndex == Instance_CompileInstanceClass) - { - UNLOAD_ASSEMBLY(Path_InstanceCtor) - UNLOAD_ASSEMBLY(Path_TemporaryClass) - path = Path_InstanceClass; - } - else - { - return; - } - - if (auto compiled = context.targetFolder->GetValueByPath(path).Cast()) - { - Workflow_GenerateAssembly(compiled, path, errors); - } - } + DELETE_ASSEMBLY(Path_TemporaryClass) + path = Path_TemporaryClass; break; + case Instance_CompileInstanceCtor: + path = Path_InstanceCtor; + break; + case Instance_CompileInstanceClass: + UNLOAD_ASSEMBLY(Path_InstanceCtor) + UNLOAD_ASSEMBLY(Path_TemporaryClass) + path = Path_InstanceClass; + break; + default: + return; + } + + if (auto compiled = context.targetFolder->GetValueByPath(path).Cast()) + { + Workflow_GenerateAssembly(compiled, path, errors); } } +#undef DELETE_ASSEMBLY #undef UNLOAD_ASSEMBLY #undef ENSURE_ASSEMBLY_EXISTS @@ -6372,7 +6336,7 @@ namespace vl FindInstanceLoadingSource ***********************************************************************/ - InstanceLoadingSource FindInstanceLoadingSource(Ptr context, GuiConstructorRepr* ctor, Ptr ibRecord) + InstanceLoadingSource FindInstanceLoadingSource(Ptr context, GuiConstructorRepr* ctor) { vint index = context->namespaces.Keys().IndexOf(ctor->typeNamespace); if (index != -1) @@ -6385,18 +6349,6 @@ FindInstanceLoadingSource { return InstanceLoadingSource(loader, fullName); } - else if (ibRecord) - { - index = ibRecord->instanceBases.Keys().IndexOf(fullName); - if (index != -1) - { - auto baseFullName = ibRecord->instanceBases.Values()[index]; - if (auto baseLoader = GetInstanceLoaderManager()->GetLoader(baseFullName.typeName)) - { - return InstanceLoadingSource(baseLoader, baseFullName.typeName); - } - } - } } } return InstanceLoadingSource(); @@ -6485,14 +6437,12 @@ WorkflowEventNamesVisitor public: Ptr context; Ptr instanceClass; - Ptr ibRecord; types::ErrorList& errors; IGuiInstanceLoader::TypeInfo resolvedTypeInfo; - WorkflowEventNamesVisitor(Ptr _context, Ptr _instanceClass, Ptr _ibRecord, types::ErrorList& _errors) + WorkflowEventNamesVisitor(Ptr _context, Ptr _instanceClass, types::ErrorList& _errors) :context(_context) , instanceClass(_instanceClass) - , ibRecord(_ibRecord) , errors(_errors) { } @@ -6507,74 +6457,60 @@ WorkflowEventNamesVisitor { if (setter->binding == GlobalStringKey::_Set) { - auto valueRepr = setter->values[0].Cast(); - if (valueRepr && valueRepr->eventHandlers.Count() > 0) + auto prop = repr->setters.Keys()[index]; + IGuiInstanceLoader::PropertyInfo propertyInfo(resolvedTypeInfo, prop); + auto errorPrefix = L"Precompile: Property \"" + propertyInfo.propertyName.ToString() + L"\" of type \"" + resolvedTypeInfo.typeName.ToString() + L"\""; + + auto loader = GetInstanceLoaderManager()->GetLoader(resolvedTypeInfo.typeName); + auto currentLoader = loader; + IGuiInstanceLoader::TypeInfo propTypeInfo; + + while (currentLoader) { - auto prop = repr->setters.Keys()[index]; - IGuiInstanceLoader::PropertyInfo propertyInfo(resolvedTypeInfo, prop); - auto errorPrefix = L"Precompile: Property \"" + propertyInfo.propertyName.ToString() + L"\" of type \"" + resolvedTypeInfo.typeName.ToString() + L"\""; - - auto loader = GetInstanceLoaderManager()->GetLoader(resolvedTypeInfo.typeName); - auto currentLoader = loader; - IGuiInstanceLoader::TypeInfo propTypeInfo; - - while (currentLoader) + if (auto propertyTypeInfo = currentLoader->GetPropertyType(propertyInfo)) { - if (auto propertyTypeInfo = currentLoader->GetPropertyType(propertyInfo)) + if (propertyTypeInfo->support == GuiInstancePropertyInfo::NotSupport) { - if (propertyTypeInfo->support == GuiInstancePropertyInfo::NotSupport) + errors.Add(errorPrefix + L" is not supported."); + goto SKIP_SET; + } + else + { + if (propertyTypeInfo->support == GuiInstancePropertyInfo::SupportSet) { - errors.Add(errorPrefix + L" is not supported."); - goto SKIP_SET; + propTypeInfo.typeDescriptor = propertyTypeInfo->acceptableTypes[0]; + propTypeInfo.typeName = GlobalStringKey::Get(propTypeInfo.typeDescriptor->GetTypeName()); } else { - if (propertyTypeInfo->support == GuiInstancePropertyInfo::SupportSet) - { - propTypeInfo.typeDescriptor = propertyTypeInfo->acceptableTypes[0]; - propTypeInfo.typeName = GlobalStringKey::Get(propTypeInfo.typeDescriptor->GetTypeName()); - } - else - { - errors.Add(errorPrefix + L" does not support the \"-set\" binding."); - goto SKIP_SET; - } - } - - if (!propertyTypeInfo->tryParent) - { - break; + errors.Add(errorPrefix + L" does not support the \"-set\" binding."); + goto SKIP_SET; } } - currentLoader = GetInstanceLoaderManager()->GetParentLoader(currentLoader); - } - if (propTypeInfo.typeDescriptor) - { - auto oldTypeInfo = resolvedTypeInfo; - resolvedTypeInfo = propTypeInfo; - FOREACH(Ptr, value, setter->values) + if (!propertyTypeInfo->tryParent) { - value->Accept(this); + break; } - resolvedTypeInfo = oldTypeInfo; } - else - { - errors.Add(errorPrefix + L" does not exist."); - } - SKIP_SET:; + currentLoader = GetInstanceLoaderManager()->GetParentLoader(currentLoader); } - else + + if (propTypeInfo.typeDescriptor) { auto oldTypeInfo = resolvedTypeInfo; - resolvedTypeInfo = IGuiInstanceLoader::TypeInfo(); + resolvedTypeInfo = propTypeInfo; FOREACH(Ptr, value, setter->values) { value->Accept(this); } resolvedTypeInfo = oldTypeInfo; } + else + { + errors.Add(errorPrefix + L" does not exist."); + } + SKIP_SET:; } else { @@ -6623,51 +6559,41 @@ WorkflowEventNamesVisitor void Visit(GuiConstructorRepr* repr)override { - if (repr->eventHandlers.Count() > 0) + IGuiInstanceLoader::TypeInfo reprTypeInfo; + + if (repr == context->instance.Obj()) { - IGuiInstanceLoader::TypeInfo reprTypeInfo; + auto fullName = GlobalStringKey::Get(context->className); + if (auto reprTd = GetInstanceLoaderManager()->GetTypeDescriptorForType(fullName)) + { + reprTypeInfo.typeName = fullName; + reprTypeInfo.typeDescriptor = reprTd; + } + } - if (repr == context->instance.Obj()) - { - auto fullName = GlobalStringKey::Get(context->className); - if (auto reprTd = GetInstanceLoaderManager()->GetTypeDescriptorForType(fullName)) - { - reprTypeInfo.typeName = fullName; - reprTypeInfo.typeDescriptor = reprTd; - } - } + if (!reprTypeInfo.typeDescriptor) + { + auto source = FindInstanceLoadingSource(context, repr); + reprTypeInfo.typeName = source.typeName; + reprTypeInfo.typeDescriptor = GetInstanceLoaderManager()->GetTypeDescriptorForType(source.typeName); + } - if (!reprTypeInfo.typeDescriptor) - { - auto source = FindInstanceLoadingSource(context, repr, ibRecord); - reprTypeInfo.typeName = source.typeName; - reprTypeInfo.typeDescriptor = GetInstanceLoaderManager()->GetTypeDescriptorForType(source.typeName); - } - - if (reprTypeInfo.typeDescriptor) - { - auto oldTypeInfo = resolvedTypeInfo; - resolvedTypeInfo = reprTypeInfo; - Visit((GuiAttSetterRepr*)repr); - resolvedTypeInfo = oldTypeInfo; - } - else - { - errors.Add( - L"Precompile: Failed to find type \"" + - (repr->typeNamespace == GlobalStringKey::Empty - ? repr->typeName.ToString() - : repr->typeNamespace.ToString() + L":" + repr->typeName.ToString() - ) + - L"\"."); - } + if (reprTypeInfo.typeDescriptor) + { + auto oldTypeInfo = resolvedTypeInfo; + resolvedTypeInfo = reprTypeInfo; + Visit((GuiAttSetterRepr*)repr); + resolvedTypeInfo = oldTypeInfo; } else { - auto oldTypeInfo = resolvedTypeInfo; - resolvedTypeInfo = IGuiInstanceLoader::TypeInfo(); - Visit((GuiAttSetterRepr*)repr); - resolvedTypeInfo = oldTypeInfo; + errors.Add( + L"Precompile: Failed to find type \"" + + (repr->typeNamespace == GlobalStringKey::Empty + ? repr->typeName.ToString() + : repr->typeNamespace.ToString() + L":" + repr->typeName.ToString() + ) + + L"\"."); } } }; @@ -6676,8 +6602,26 @@ WorkflowEventNamesVisitor Workflow_GenerateInstanceClass ***********************************************************************/ - Ptr Workflow_GenerateInstanceClass(Ptr context, Ptr ibRecord, types::ResolvingResult& resolvingResult, types::ErrorList& errors, bool beforePrecompile) + Ptr Workflow_GenerateInstanceClass(Ptr context, types::ResolvingResult& resolvingResult, types::ErrorList& errors, vint passIndex) { + bool beforePrecompile = false; + bool needEventHandler = false; + switch (passIndex) + { + case IGuiResourceTypeResolver_Precompile::Instance_CollectInstanceTypes: + beforePrecompile = true; + needEventHandler = false; + break; + case IGuiResourceTypeResolver_Precompile::Instance_GenerateTemporaryClass: + beforePrecompile = true; + needEventHandler = true; + break; + case IGuiResourceTypeResolver_Precompile::Instance_GenerateInstanceClass: + beforePrecompile = false; + needEventHandler = true; + break; + } + auto source = FindInstanceLoadingSource(context, context->instance.Obj()); auto baseTd = GetInstanceLoaderManager()->GetTypeDescriptorForType(source.typeName); if (!baseTd) @@ -7132,8 +7076,9 @@ Workflow_GenerateInstanceClass } } + if (needEventHandler) { - WorkflowEventNamesVisitor visitor(context, instanceClass, ibRecord, errors); + WorkflowEventNamesVisitor visitor(context, instanceClass, errors); context->instance->Accept(&visitor); } addDecl(ctor); @@ -7930,12 +7875,16 @@ WorkflowGenerateBindingVisitor FOREACH_INDEXER(Ptr, setter, index, repr->setters.Values()) { auto propertyName = repr->setters.Keys()[index]; + if (propertyName.ToString() == L"EmbeddedButton") + { + int a = 0; + } if (setter->binding != GlobalStringKey::Empty && setter->binding != GlobalStringKey::_Set) { if (auto binder = GetInstanceLoaderManager()->GetInstanceBinder(setter->binding)) { auto propertyResolving = resolvingResult.propertyResolvings[setter->values[0].Obj()]; - if (propertyResolving.info->scope != GuiInstancePropertyInfo::Constructor) + if (propertyResolving.info->scope == GuiInstancePropertyInfo::Property) { WString expressionCode = setter->values[0].Cast()->text; auto instancePropertyInfo = reprTypeInfo.typeDescriptor->GetPropertyByName(propertyName.ToString(), true); diff --git a/Import/GacUICompiler.h b/Import/GacUICompiler.h index b3f60455..603f6618 100644 --- a/Import/GacUICompiler.h +++ b/Import/GacUICompiler.h @@ -759,13 +759,6 @@ namespace vl typedef collections::Dictionary PropertyResolvingMap; typedef collections::List ErrorList; - struct InstanceBaseRecord : public Object, public Description - { - typedef GlobalStringKey Key; - typedef IGuiInstanceLoader::TypeInfo Value; - collections::Dictionary instanceBases; - }; - struct ResolvingResult : public Object, public Description { Ptr moduleForValidate; @@ -845,10 +838,10 @@ WorkflowCompiler (Compile) } }; - extern InstanceLoadingSource FindInstanceLoadingSource(Ptr context, GuiConstructorRepr* ctor, Ptr ibRecord = nullptr); + extern InstanceLoadingSource FindInstanceLoadingSource(Ptr context, GuiConstructorRepr* ctor); extern bool Workflow_ValidateStatement(Ptr context, types::ResolvingResult& resolvingResult, description::ITypeDescriptor* rootTypeDescriptor, types::ErrorList& errors, const WString& code, Ptr statement); extern Ptr Workflow_PrecompileInstanceContext(Ptr context, types::ResolvingResult& resolvingResult, types::ErrorList& errors); - extern Ptr Workflow_GenerateInstanceClass(Ptr context, Ptr ibRecord, types::ResolvingResult& resolvingResult, types::ErrorList& errors, bool beforePrecompile); + extern Ptr Workflow_GenerateInstanceClass(Ptr context, types::ResolvingResult& resolvingResult, types::ErrorList& errors, vint passIndex); } } diff --git a/Tools/GacGen.exe b/Tools/GacGen.exe index 59d74329..66d447ae 100644 Binary files a/Tools/GacGen.exe and b/Tools/GacGen.exe differ diff --git a/Tutorial/GacUI_ControlTemplate/UIRes/BlackSkin.bin b/Tutorial/GacUI_ControlTemplate/UIRes/BlackSkin.bin index 90d89b02..4f76b80f 100644 Binary files a/Tutorial/GacUI_ControlTemplate/UIRes/BlackSkin.bin and b/Tutorial/GacUI_ControlTemplate/UIRes/BlackSkin.bin differ diff --git a/Tutorial/GacUI_Controls/UIRes/ContainersAndButtons.bin b/Tutorial/GacUI_Controls/UIRes/ContainersAndButtons.bin index 42b6042e..dfd6b464 100644 Binary files a/Tutorial/GacUI_Controls/UIRes/ContainersAndButtons.bin and b/Tutorial/GacUI_Controls/UIRes/ContainersAndButtons.bin differ diff --git a/Tutorial/GacUI_Controls/UIRes/TextEditor.bin b/Tutorial/GacUI_Controls/UIRes/TextEditor.bin index 96b5fcdb..8be1a945 100644 Binary files a/Tutorial/GacUI_Controls/UIRes/TextEditor.bin and b/Tutorial/GacUI_Controls/UIRes/TextEditor.bin differ diff --git a/Tutorial/GacUI_HelloWorlds/UIRes/CppXml.bin b/Tutorial/GacUI_HelloWorlds/UIRes/CppXml.bin index d3887465..dda381c5 100644 Binary files a/Tutorial/GacUI_HelloWorlds/UIRes/CppXml.bin and b/Tutorial/GacUI_HelloWorlds/UIRes/CppXml.bin differ diff --git a/Tutorial/GacUI_HelloWorlds/UIRes/MVVM.bin b/Tutorial/GacUI_HelloWorlds/UIRes/MVVM.bin index 96385349..ea423f50 100644 Binary files a/Tutorial/GacUI_HelloWorlds/UIRes/MVVM.bin and b/Tutorial/GacUI_HelloWorlds/UIRes/MVVM.bin differ diff --git a/Tutorial/GacUI_Layout/UIRes/Alignment.bin b/Tutorial/GacUI_Layout/UIRes/Alignment.bin index 910206cb..57b4c639 100644 Binary files a/Tutorial/GacUI_Layout/UIRes/Alignment.bin and b/Tutorial/GacUI_Layout/UIRes/Alignment.bin differ diff --git a/Tutorial/GacUI_Layout/UIRes/Flow.bin b/Tutorial/GacUI_Layout/UIRes/Flow.bin index 332f1f87..7f117461 100644 Binary files a/Tutorial/GacUI_Layout/UIRes/Flow.bin and b/Tutorial/GacUI_Layout/UIRes/Flow.bin differ diff --git a/Tutorial/GacUI_Layout/UIRes/RichTextEmbedding.bin b/Tutorial/GacUI_Layout/UIRes/RichTextEmbedding.bin index 507c10ed..eb6a7b83 100644 Binary files a/Tutorial/GacUI_Layout/UIRes/RichTextEmbedding.bin and b/Tutorial/GacUI_Layout/UIRes/RichTextEmbedding.bin differ diff --git a/Tutorial/GacUI_Layout/UIRes/Stack.bin b/Tutorial/GacUI_Layout/UIRes/Stack.bin index 35695731..e7a82209 100644 Binary files a/Tutorial/GacUI_Layout/UIRes/Stack.bin and b/Tutorial/GacUI_Layout/UIRes/Stack.bin differ diff --git a/Tutorial/GacUI_Layout/UIRes/Table.bin b/Tutorial/GacUI_Layout/UIRes/Table.bin index 40e83c3b..615bca82 100644 Binary files a/Tutorial/GacUI_Layout/UIRes/Table.bin and b/Tutorial/GacUI_Layout/UIRes/Table.bin differ