public static string GetComponentName([NotNull] IYamlDocument componentDocument)
        {
            var name = componentDocument.GetUnityObjectPropertyValue(UnityYamlConstants.NameProperty).AsString();

            if (!string.IsNullOrWhiteSpace(name))
            {
                return(name);
            }

            var scriptDocument = componentDocument.GetUnityObjectDocumentFromFileIDProperty(UnityYamlConstants.ScriptProperty);

            name = scriptDocument.GetUnityObjectPropertyValue(UnityYamlConstants.NameProperty).AsString();
            if (!string.IsNullOrWhiteSpace(name))
            {
                return(name);
            }

            var fileID = componentDocument.GetUnityObjectPropertyValue(UnityYamlConstants.ScriptProperty).AsFileID();

            if (fileID != null && fileID.IsExternal && fileID.IsMonoScript)
            {
                var typeElement = GetTypeElementFromScriptAssetGuid(componentDocument.GetSolution(), fileID.guid);
                if (typeElement != null)
                {
                    // TODO: Format like in Unity, by splitting the camel humps
                    return(typeElement.ShortName + " (Script)");
                }
            }

            return(scriptDocument.GetUnityObjectTypeFromRootNode()
                   ?? componentDocument.GetUnityObjectTypeFromRootNode()
                   ?? "Component");
        }
        public static IYamlDocument FindTransformComponentForGameObject([CanBeNull] IYamlDocument gameObjectDocument)
        {
            // GameObject:
            //   m_Component:
            //   - component: {fileID: 1234567890}
            //   - component: {fileID: 1234567890}
            //   - component: {fileID: 1234567890}
            // One of these components is the RectTransform(GUI, 2D) or Transform(3D). Most likely the first, but we can't rely on order
            if (gameObjectDocument?.GetUnityObjectPropertyValue("m_Component") is IBlockSequenceNode components)
            {
                var file = (IYamlFile)gameObjectDocument.GetContainingFile();

                foreach (var componentEntry in components.EntriesEnumerable)
                {
                    // - component: {fileID: 1234567890}
                    var componentNode   = componentEntry.Value as IBlockMappingNode;
                    var componentFileID = componentNode?.EntriesEnumerable.FirstOrDefault()?.Content.Value.AsFileID();
                    if (componentFileID != null && !componentFileID.IsNullReference && !componentFileID.IsExternal)
                    {
                        var component     = file.FindDocumentByAnchor(componentFileID.fileID);
                        var componentName = component.GetUnityObjectTypeFromRootNode();
                        if (componentName != null && (componentName.Equals(UnityYamlConstants.RectTransformComponent) || componentName.Equals(UnityYamlConstants.TransformComponent)))
                        {
                            return(component);
                        }
                    }
                }
            }

            return(null);
        }
        // If we add any more references, add them here, or SWEA's usage count won't pick them up!!
        public static bool CanContainReference([NotNull] IYamlDocument document)
        {
            var buffer = document.Body.GetTextAsBuffer();

            return(UnityEventTargetReferenceFactory.CanContainReference(buffer) ||
                   MonoScriptReferenceFactory.CanContainReference(buffer));
        }
        public static IBlockMappingNode FindRootBlockMapEntries([CanBeNull] this IYamlDocument document)
        {
            // A YAML document is a block mapping node with a single entry. The key is usually the type of the object,
            // while the value is another block mapping node. Those entries are the properties of the Unity object
            var rootBlockMappingNode = document?.Body.BlockNode as IBlockMappingNode;

            return(rootBlockMappingNode?.EntriesEnumerable.FirstOrDefault()?.Content.Value as IBlockMappingNode);
        }
Esempio n. 5
0
        private FileID GetCorrespondingSourceObjectFileId(IYamlDocument document)
        {
            if (myVersion.GetActualVersionForSolution().Major == 2017)
            {
                return(document.GetUnityObjectPropertyValue(UnityYamlConstants.CorrespondingSourceObjectProperty2017)?.AsFileID());
            }

            return(document.GetUnityObjectPropertyValue(UnityYamlConstants.CorrespondingSourceObjectProperty)?.AsFileID() ??
                   document.GetUnityObjectPropertyValue(UnityYamlConstants.CorrespondingSourceObjectProperty2017)?.AsFileID());
        }
Esempio n. 6
0
        private FileID GetPrefabInstanceFileId(IYamlDocument document)
        {
            if (myVersion.GetActualVersionForSolution().Major == 2017)
            {
                return(document.GetUnityObjectPropertyValue(UnityYamlConstants.PrefabInstanceProperty2017)?.AsFileID());
            }

            return(document.GetUnityObjectPropertyValue(UnityYamlConstants.PrefabInstanceProperty)?.AsFileID() ??
                   document.GetUnityObjectPropertyValue(UnityYamlConstants.PrefabInstanceProperty2017)?.AsFileID());
        }
        public static string GetUnityObjectTypeFromRootNode([CanBeNull] this IYamlDocument document)
        {
            // E.g.
            // --- !u!114 &293532596
            // MonoBehaviour:
            //   m_ObjectHideFlags: 0
            // This will return "MonoBehaviour"
            // (Note that !u!114 is the actual type of this object - MonoBehaviour -
            // https://docs.unity3d.com/Manual/ClassIDReference.html)
            var rootBlockMappingNode = document?.Body.BlockNode as IBlockMappingNode;

            return(rootBlockMappingNode?.EntriesEnumerable.FirstOrDefault()?.Key.AsString());
        }
Esempio n. 8
0
        public void ProcessSceneHierarchyFromComponentToRoot(IYamlDocument startComponent, IUnityCachedSceneProcessorConsumer consumer)
        {
            myShellLocks.AssertReadAccessAllowed();

            var sourceFile = startComponent.GetSourceFile();
            var anchor     = UnitySceneDataUtil.GetAnchorFromBuffer(startComponent.GetTextAsBuffer());

            if (sourceFile == null || anchor == null)
            {
                return;
            }

            ProcessSceneHierarchyFromComponentToRoot(sourceFile, new FileID(null, anchor), consumer);
        }
        public static IYamlDocument GetUnityObjectDocumentFromFileIDProperty([CanBeNull] this IYamlDocument document, string key)
        {
            var fileID = document.GetUnityObjectPropertyValue(key).AsFileID();

            if (fileID == null || fileID.IsNullReference || fileID.IsExternal)
            {
                return(null);
            }

            Assertion.AssertNotNull(document, "document != null");
            var file = (IYamlFile)document.GetContainingFile();

            return(file.FindDocumentByAnchor(fileID.fileID));
        }
        public static IYamlDocument GetTransformFromPrefabInstance(IYamlDocument prefabInstanceDocument)
        {
            // Prefab instance stores it's father in modification map
            var prefabModification = GetPrefabModification(prefabInstanceDocument);

            var fileID = prefabModification?.FindMapEntryBySimpleKey(UnityYamlConstants.TransformParentProperty)?.Content.Value.AsFileID();

            if (fileID == null)
            {
                return(null);
            }

            var file = (IYamlFile)prefabInstanceDocument.GetContainingFile();

            return(file.FindDocumentByAnchor(fileID.fileID));
        }
        public static bool CanContainReference([NotNull] IYamlDocument document)
        {
            // This document can only contain a reference if it represents a MonoBehaviour (which includes compiled
            // MonoBehaviours such as Button) and if it has the `m_MethodName` property. So, check the text of the
            // closed chameleon for "!u!114" and "m_MethodName".
            // TODO: Can we improve this?
            // When the chameleon is closed, GetTextAsBuffer returns a ProjectedBuffer over the source file element.
            // When open, it's a bit more expensive, by creating a StringBuffer over the result of GetText, which is
            // calculated by pre-initialising a StringBuilder to the correct length and calling GetText(StringBuilder)
            // on the child nodes.
            // Then we search the buffer, potentially twice. We'll limit the tag searcher to the first 100 characters of
            // the buffer
            var buffer = document.Body.GetTextAsBuffer();

            return(CanContainReference(buffer));
        }
Esempio n. 12
0
        public void ConsumeGameObject(IYamlDocument gameObject, IBlockMappingNode modifications)
        {
            string name = null;

            if (modifications != null)
            {
                var documentId = gameObject.GetFileId();
                name = UnityObjectPsiUtil.GetValueFromModifications(modifications, documentId, UnityYamlConstants.NameProperty);
            }
            if (name == null)
            {
                name = gameObject.GetUnityObjectPropertyValue(UnityYamlConstants.NameProperty).AsString();
            }

            if (name?.Equals(string.Empty) == true)
            {
                name = null;
            }
            NameParts.Add(name ?? "Unknown");
        }
Esempio n. 13
0
        public void ProcessSceneHierarchyFromComponentToRoot(IYamlDocument startComponent, IUnitySceneProcessorConsumer consumer)
        {
            if (startComponent == null)
            {
                return;
            }

            var start = startComponent;

            if (!IsStripped(startComponent)) // start component can be stripped, e.g : prefab's MonoBehavior's function is passed to button event handler
            {
                // Component must be attached to game object
                start = start.GetUnityObjectDocumentFromFileIDProperty(UnityYamlConstants.GameObjectProperty);

                // GameObject could be stripped, if another prefab's gameobject is modified via adding MonoBehaviour
                if (!IsStripped(start))
                {
                    // Each GameObject must have Transform. We will use it to process scene hierarcy
                    start = UnityObjectPsiUtil.FindTransformComponentForGameObject(start);
                }
            }
            ProcessSceneHierarchyFromComponentToRootInner(start, consumer, null);
        }
Esempio n. 14
0
 public void ConsumeGameObject(IYamlDocument gameObject, IBlockMappingNode modifications)
 {
     {
         int rootOrder = -1;
         var transform = UnityObjectPsiUtil.FindTransformComponentForGameObject(gameObject);
         if (modifications != null)
         {
             if (!int.TryParse(UnityObjectPsiUtil.GetValueFromModifications(modifications, transform.GetFileId(), UnityYamlConstants.RootOrderProperty)
                               , out rootOrder))
             {
                 rootOrder = -1;
             }
         }
         if (rootOrder == -1)
         {
             var rootOrderAsString = transform.GetUnityObjectPropertyValue(UnityYamlConstants.RootOrderProperty).AsString();
             if (!int.TryParse(rootOrderAsString, out rootOrder))
             {
                 rootOrder = -1;
             }
         }
         RootIndices.Add(rootOrder);
     }
 }
 public static IBlockMappingNode GetPrefabModification(IYamlDocument yamlDocument)
 {
     // Prefab instance has a map of modifications, that stores delta of instance and prefab
     return(yamlDocument.GetUnityObjectPropertyValue(UnityYamlConstants.ModificationProperty) as IBlockMappingNode);
 }
        public static string GetAttachedGameObjectName(UnitySceneDataLocalCache cache, IYamlDocument document)
        {
            var consumer = new UnityPathCachedSceneConsumer();

            cache.ProcessSceneHierarchyFromComponentToRoot(document, consumer);

            var parts = consumer.NameParts;

            if (parts.Count == 0)
            {
                return("...");
            }
            return(string.Join("/", consumer.NameParts));
        }
 public static INode GetUnityObjectPropertyValue([CanBeNull] this IYamlDocument document, [NotNull] string key)
 {
     return(FindRootBlockMapEntries(document).FindMapEntryBySimpleKey(key)?.Content.Value);
 }
Esempio n. 18
0
        public static string GetUnityObjectTag(IYamlDocument document)
        {
            var tag = (document.Body.BlockNode as IChameleonBlockMappingNode)?.Properties.TagProperty.GetText();

            return(tag);
        }
        public static string GetFileId(this IYamlDocument yamlDocument)
        {
            var properties = GetDocumentBlockNodeProperties(yamlDocument.Body.BlockNode);

            return(properties?.AnchorProperty?.Text?.GetText());
        }
Esempio n. 20
0
 private static bool IsStripped(IYamlDocument element)
 {
     return(((element.Body.BlockNode as IChameleonBlockMappingNode)?.Properties?.LastChild as YamlTokenType.GenericTokenElement)?
            .GetText().Equals("stripped") == true);
 }
Esempio n. 21
0
        public static string GetGameObjectPathFromComponent([NotNull] UnitySceneProcessor sceneProcessor, [NotNull] IYamlDocument componentDocument)
        {
            var consumer = new UnityPathSceneConsumer();

            sceneProcessor.ProcessSceneHierarchyFromComponentToRoot(componentDocument, consumer);

            var parts = consumer.NameParts;

            if (parts.Count == 0)
            {
                return("Unknown");
            }

            if (parts.Count == 1)
            {
                return(parts[0]);
            }

            var sb = new StringBuilder();

            for (var i = parts.Count - 1; i >= 0; i--)
            {
                sb.Append(parts[i]);
                sb.Append("\\");
            }

            return(sb.ToString());
        }
Esempio n. 22
0
        // Invariant : startGameObject is Transform Component if it is not stripped
        // This method traverse scene hierarchy via visiting transform components and push corresponding to transform GameObject into consumer
        private void ProcessSceneHierarchyFromComponentToRootInner(IYamlDocument startUnityObject, IUnitySceneProcessorConsumer consumer, IBlockMappingNode modifications)
        {
            var currentUnityObject = startUnityObject;

            while (currentUnityObject != null)
            {
                // Unity object could be stripped, it means, that corresponding real object belongs to another yaml file
                // Also, it has reference to prefab instance in current file, which stores all prefab modification
                if (IsStripped(currentUnityObject))
                {
                    var file             = (IYamlFile)currentUnityObject.GetContainingFile();
                    var correspondingId  = currentUnityObject.GetUnityObjectPropertyValue(GetCorrespondingSourceObjectProperty())?.AsFileID();
                    var prefabInstanceId = currentUnityObject.GetUnityObjectPropertyValue(GetPrefabInstanceProperty())?.AsFileID();

                    // assert not null
                    if (correspondingId == null || prefabInstanceId == null)
                    {
                        return;
                    }

                    var prefabInstance   = file.FindDocumentByAnchor(prefabInstanceId.fileID);
                    var prefabSourceFile = myMetaFileGuidCache.GetAssetFilePathsFromGuid(correspondingId.guid);
                    if (prefabSourceFile.Count > 1 || prefabSourceFile.Count == 0)
                    {
                        return;
                    }

                    myFactory.PsiModule.NotNull("externalFilesModuleFactory.PsiModule != null")
                    .TryGetFileByPath(prefabSourceFile.First(), out var sourceFile);

                    if (sourceFile == null)
                    {
                        return;
                    }

                    // [TODO] Is prefab file committed???
                    var prefabFile = (IYamlFile)sourceFile.GetDominantPsiFile <YamlLanguage>();

                    var prefabStartGameObject = prefabFile.FindDocumentByAnchor(correspondingId.fileID);
                    if (!IsStripped(prefabStartGameObject))
                    {
                        // !u!4 is transform. If tag is different, let's extract transform, there are two cases:
                        // 1) prefabStartGameObject is GameObject(!u!1), take its transform
                        // 2) prefabStartGameObject is Component, so get attached gameobject and from this gameobject take transform component
                        if (!GetUnityObjectTag(prefabStartGameObject).Equals("!u!4"))
                        {
                            var attachedGameObject = prefabStartGameObject;
                            if (!GetUnityObjectTag(prefabStartGameObject).Equals("!u!1"))
                            {
                                attachedGameObject =
                                    attachedGameObject.GetUnityObjectDocumentFromFileIDProperty(UnityYamlConstants
                                                                                                .GameObjectProperty);
                            }
                            prefabStartGameObject = UnityObjectPsiUtil.FindTransformComponentForGameObject(attachedGameObject);
                        }
                    }
                    var localModifications = UnityObjectPsiUtil.GetPrefabModification(prefabInstance);
                    ProcessSceneHierarchyFromComponentToRootInner(prefabStartGameObject, consumer, localModifications);
                    currentUnityObject = UnityObjectPsiUtil.GetTransformFromPrefabInstance(prefabInstance);
                }
                else
                {
                    // assert that startGameObject is GameObject
                    var father     = currentUnityObject.GetUnityObjectDocumentFromFileIDProperty(UnityYamlConstants.FatherProperty);
                    var gameObject = currentUnityObject.GetUnityObjectDocumentFromFileIDProperty(UnityYamlConstants.GameObjectProperty);
                    consumer.ConsumeGameObject(gameObject, modifications);
                    currentUnityObject = father;
                }
            }
        }
Esempio n. 23
0
        public static bool CanContainReference([NotNull] IYamlDocument document)
        {
            var buffer = document.GetTextAsBuffer();

            return(CanContainReference(buffer));
        }