forked from Unity-Technologies/UnityCsReference
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProjectStateRestHandler.cs
More file actions
171 lines (143 loc) · 6.48 KB
/
Copy pathProjectStateRestHandler.cs
File metadata and controls
171 lines (143 loc) · 6.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor.Scripting;
using UnityEditor.Scripting.ScriptCompilation;
using UnityEditorInternal;
using UnityEditor.Utils;
using UnityEngine;
namespace UnityEditor.RestService
{
internal class ProjectStateRestHandler : JSONHandler
{
protected override JSONValue HandleGet(Request request, JSONValue payload)
{
AssetDatabase.Refresh();
return JsonForProject();
}
public class Island
{
public MonoIsland MonoIsland { get; set; }
public String Name { get; set; }
public List<String> References { get; set; }
}
private static JSONValue JsonForProject()
{
var islands = EditorCompilationInterface.GetAllMonoIslands().Select(i => new Island
{
MonoIsland = i,
Name = Path.GetFileNameWithoutExtension(i._output),
References = i._references.ToList()
}).ToList();
// Mono islands have references to each others output location. For MD we want to have the reference
// be to the actual project, so we are going to update the references here
foreach (Island island in islands)
{
var toAdd = new List<string>();
var toRemove = new List<string>();
foreach (var reference in island.References)
{
var refName = Path.GetFileNameWithoutExtension(reference);
if (reference.StartsWith("Library/") && islands.Any(i => i.Name == refName))
{
toAdd.Add(refName);
toRemove.Add(reference);
}
if (reference.EndsWith("/UnityEditor.dll") || reference.EndsWith("/UnityEngine.dll")
|| reference.EndsWith("\\UnityEditor.dll") || reference.EndsWith("\\UnityEngine.dll"))
toRemove.Add(reference);
}
island.References.Add(InternalEditorUtility.GetEditorAssemblyPath());
island.References.Add(InternalEditorUtility.GetEngineAssemblyPath());
foreach (var a in toAdd)
island.References.Add(a);
foreach (var r in toRemove)
island.References.Remove(r);
}
var files = islands.SelectMany(i => i.MonoIsland._files).Concat(GetAllSupportedFiles()).Distinct().ToArray();
var emptyDirectories = RelativeToProjectPath(FindEmptyDirectories(AssetsPath, files));
var result = new JSONValue();
result["islands"] = new JSONValue(islands.Select(i => JsonForIsland(i)).Where(i2 => !i2.IsNull()).ToList());
result["basedirectory"] = ProjectPath;
var assetDatabase = new JSONValue();
assetDatabase["files"] = ToJSON(files);
assetDatabase["emptydirectories"] = ToJSON(emptyDirectories);
result["assetdatabase"] = assetDatabase;
return result;
}
static bool IsSupportedExtension(string extension)
{
if (extension.StartsWith("."))
extension = extension.Substring(1);
var all = EditorSettings.projectGenerationBuiltinExtensions.Concat(EditorSettings.projectGenerationUserExtensions);
return all.Any(s => string.Equals(s, extension, StringComparison.InvariantCultureIgnoreCase));
}
private static IEnumerable<string> GetAllSupportedFiles()
{
var projectPath = ProjectPath.EndsWith("/") ? ProjectPath : ProjectPath + "/";
return AssetDatabase.GetAllAssetPaths().Where(asset => {
var absolutePath = Path.GetFullPath(asset).ConvertSeparatorsToUnity();
if (!absolutePath.StartsWith(projectPath))
return false;
return IsSupportedExtension(Path.GetExtension(asset));
});
}
private static JSONValue JsonForIsland(Island island)
{
if (island.Name == "UnityEngine" || island.Name == "UnityEditor")
return null;
var result = new JSONValue();
result["name"] = island.Name;
result["language"] = island.Name.Contains("Boo") ? "Boo" : island.Name.Contains("UnityScript") ? "UnityScript" : "C#";
result["files"] = ToJSON(island.MonoIsland._files);
result["defines"] = ToJSON(island.MonoIsland._defines);
result["references"] = ToJSON(island.MonoIsland._references);
result["basedirectory"] = ProjectPath;
return result;
}
private static void FindPotentialEmptyDirectories(string path, ICollection<string> result)
{
var directories = Directory.GetDirectories(path);
if (directories.Length == 0)
{
result.Add(path.Replace('\\', '/'));
return;
}
foreach (var directory in directories)
FindPotentialEmptyDirectories(directory, result);
}
private static IEnumerable<string> FindPotentialEmptyDirectories(string path)
{
var result = new List<string>();
FindPotentialEmptyDirectories(path, result);
return result;
}
private static string[] FindEmptyDirectories(string path, string[] files)
{
var potentialEmptyDirectories = FindPotentialEmptyDirectories(path);
return potentialEmptyDirectories.Where(d => !files.Any(f => f.StartsWith(d))).ToArray();
}
private static string[] RelativeToProjectPath(string[] paths)
{
var projectPath = ProjectPath.EndsWith("/") ? ProjectPath : ProjectPath + "/";
return paths.Select(d => d.StartsWith(projectPath) ? d.Substring(projectPath.Length) : d).ToArray();
}
static string ProjectPath
{
get { return Path.GetDirectoryName(Application.dataPath); }
}
static string AssetsPath
{
get { return ProjectPath + "/Assets"; }
}
internal static void Register()
{
Router.RegisterHandler("/unity/projectstate", new ProjectStateRestHandler());
}
}
}