Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
tsubaki committed Jul 26, 2015
1 parent f9b44e0 commit 8ca57a5
Show file tree
Hide file tree
Showing 24 changed files with 629 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Assets/Cleaner.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Assets/Cleaner/Editor.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

152 changes: 152 additions & 0 deletions Assets/Cleaner/Editor/AssetCollector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/**
asset cleaner
Copyright (c) 2015 Tatsuhiko Yamamura
This software is released under the MIT License.
http://opensource.org/licenses/mit-license.php
*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using System.IO;
using System.Text.RegularExpressions;

namespace AssetClean
{
public class AssetCollector
{
public List<string> deleteFileList = new List<string> ();
ClassReferenceCollection classCollection = new ClassReferenceCollection ();
ShaderReferenceCollection shaderCollection = new ShaderReferenceCollection ();

public bool useCodeStrip = true;
public bool saveEditorExtensions = true;

public void Collection ()
{
try {
deleteFileList.Clear ();

if( useCodeStrip ){
classCollection.Collection ();
}
shaderCollection.Collection ();

// Find assets
var files = Directory.GetFiles ("Assets", "*.*", SearchOption.AllDirectories)
.Where (item => Path.GetExtension (item) != ".meta")
.Where (item => Path.GetExtension (item) != ".js")
.Where (item => Path.GetExtension (item) != ".dll")
.Where (item => Regex.IsMatch (item, "[\\/\\\\]Gizmos[\\/\\\\]") == false)
.Where (item => Regex.IsMatch (item, "[\\/\\\\]Plugins[\\/\\\\]Android[\\/\\\\]") == false)
.Where (item => Regex.IsMatch (item, "[\\/\\\\]Plugins[\\/\\\\]iOS[\\/\\\\]") == false)
.Where (item => Regex.IsMatch (item, "[\\/\\\\]Resources[\\/\\\\]") == false);

if( useCodeStrip == false ){
files = files.Where( item => Path.GetExtension(item) != ".cs");
}

foreach (var path in files) {
var guid = AssetDatabase.AssetPathToGUID (path);
deleteFileList.Add (guid);
}
EditorUtility.DisplayProgressBar ("checking", "collection all files", 0.2f);
UnregistReferenceFromResources();

EditorUtility.DisplayProgressBar ("checking", "check reference from resources", 0.4f);
UnregistReferenceFromScenes();

EditorUtility.DisplayProgressBar ("checking", "check reference from scenes", 0.6f);
if( saveEditorExtensions ){
UnregistEditorCodes();
}
} finally {
EditorUtility.ClearProgressBar ();
}
}
void UnregistReferenceFromResources()
{
var resourcesFiles = Directory.GetFiles ("Assets", "*.*", SearchOption.AllDirectories)
.Where (item => Regex.IsMatch (item, "[\\/\\\\]Resources[\\/\\\\]") == true)
.Where (item => Path.GetExtension (item) != ".meta")
.ToArray ();
foreach (var path in AssetDatabase.GetDependencies (resourcesFiles)) {
UnregistFromDelteList (AssetDatabase.AssetPathToGUID(path));
}
}

void UnregistReferenceFromScenes()
{
// Exclude objects that reference from scenes.
var scenes = EditorBuildSettings.scenes
.Where (item => item.enabled == true)
.Select (item => item.path)
.ToArray ();
foreach (var path in AssetDatabase.GetDependencies (scenes)) {
if( saveEditorExtensions == false ){
Debug.Log(path);
}
UnregistFromDelteList (AssetDatabase.AssetPathToGUID(path));
}
}

void UnregistEditorCodes()
{
// Exclude objects that reference from Editor API
var editorcodes = Directory.GetFiles ("Assets", "*.cs", SearchOption.AllDirectories)
.Where (item => Regex.IsMatch (item, "[\\/\\\\]Editor[\\/\\\\]") == true)
.ToArray ();

var undeleteClassList = classCollection.codeFileList
.Where (codefile => codefile.Value.Any( guid => deleteFileList.Contains(guid)) == false)
.Select( item => item.Key );

EditorUtility.DisplayProgressBar ("checking", "check reference from editor codes", 0.8f);

foreach (var path in editorcodes) {
var code = File.ReadAllText (path);
code = Regex.Replace(code, "//.*[\\n\\r]", "");
code = Regex.Replace(code, "/\\*.*[\\n\\r]\\*/", "");
if (Regex.IsMatch (code, "(\\[MenuItem|AssetPostprocessor|EditorWindow)")) {
UnregistFromDelteList ( AssetDatabase.AssetPathToGUID(path));
continue;
}

foreach (var undeleteClass in undeleteClassList) {
if (Regex.IsMatch (code, string.Format ("\\[CustomEditor.*\\(\\s*{0}\\s*\\).*\\]", undeleteClass.Name))) {
UnregistFromDelteList (path);
continue;
}
}
}
}

void UnregistFromDelteList (string guid)
{
if (deleteFileList.Contains (guid) == false) {
return;
}
deleteFileList.Remove (guid);

if (classCollection.references.ContainsKey (guid) == true) {

foreach (var type in classCollection.references[guid]) {
var codePaths = classCollection.codeFileList [type];
foreach( var codePath in codePaths){
UnregistFromDelteList (codePath);
}
}
}

if (shaderCollection.shaderFileList.ContainsValue (guid)) {
var shader = shaderCollection.shaderFileList.First (item => item.Value == guid);
var shaderAssets = shaderCollection.shaderReferenceList [shader.Key];
foreach (var shaderPath in shaderAssets) {
UnregistFromDelteList (shaderPath);
}
}
}
}
}
12 changes: 12 additions & 0 deletions Assets/Cleaner/Editor/AssetCollector.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

175 changes: 175 additions & 0 deletions Assets/Cleaner/Editor/ClassReferenceCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/**
asset cleaner
Copyright (c) 2015 Tatsuhiko Yamamura
This software is released under the MIT License.
http://opensource.org/licenses/mit-license.php
*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEditor;
using System.IO;
using System.Reflection;
using System.Linq;

namespace AssetClean
{
public class ClassReferenceCollection
{
// type : guid
public Dictionary<System.Type, List<string>> codeFileList = new Dictionary<System.Type, List<string>> ();
// guid : types
public Dictionary<string, List<System.Type>> references = new Dictionary<string, List<System.Type>> ();

public void Collection ()
{
references.Clear ();
EditorUtility.DisplayProgressBar ("checking", "collection all type", 0);

// Connect the files and class.
var codes = Directory.GetFiles ("Assets", "*.cs", SearchOption.AllDirectories);
// connect each classes.
var firstPassList = new List<string>();
if( Directory.Exists ("Assets/Plugins") )
firstPassList.AddRange( Directory.GetFiles ("Assets/Plugins", "*.cs", SearchOption.AllDirectories));
if( Directory.Exists ("Assets/Standard Assets") )
firstPassList.AddRange( Directory.GetFiles ("Assets/Standard Assets", "*.cs", SearchOption.AllDirectories));

var allFirstpassTypes = collectionAllFastspassClasses ();
CollectionCodeFileDictionary (allFirstpassTypes, firstPassList.ToArray());


var alltypes = CollectionAllClasses ();
CollectionCodeFileDictionary (alltypes, codes.ToArray());
alltypes.AddRange (allFirstpassTypes);

int count = 0;
foreach (var codepath in firstPassList) {
CollectionReferenceClasses (AssetDatabase.AssetPathToGUID (codepath), allFirstpassTypes);
EditorUtility.DisplayProgressBar ("checking", "analytics codes", ((float)++count / codes.Length) * 0.5f + 0.5f);
}
count = 0;
foreach (var codepath in codes) {
CollectionReferenceClasses (AssetDatabase.AssetPathToGUID (codepath), alltypes);
EditorUtility.DisplayProgressBar ("checking", "analytics codes", ((float)++count / codes.Length) * 0.5f);
}
}

void CollectionCodeFileDictionary (List<System.Type> alltypes, string[] codes)
{
float count = 1;
foreach (var codePath in codes) {
EditorUtility.DisplayProgressBar ("checking", "search files", count++ / codes.Length);

// connect file and classes.
var code = System.IO.File.ReadAllText (codePath);
code = Regex.Replace(code, "//.*[\\n\\r]", "");
code = Regex.Replace(code, "/\\*.*[\\n\\r]\\*/", "");

foreach (var type in alltypes) {

if( codeFileList.ContainsKey(type ) == false ){
codeFileList.Add(type, new List<string>());
}
var list = codeFileList[type];

if (string.IsNullOrEmpty (type.Namespace) == false) {
var namespacepattern = string.Format ("namespace[\\s.]{0}[{{\\s\\n]", type.Namespace);
if (Regex.IsMatch (code, namespacepattern) == false) {
continue;
}
}

string typeName = type.IsGenericTypeDefinition ? type.GetGenericTypeDefinition ().Name.Split ('`') [0] : type.Name;
if (Regex.IsMatch (code, string.Format ("class\\s*{0}?[\\s:<{{]", typeName))) {
list.Add( AssetDatabase.AssetPathToGUID(codePath) );
continue;
}

if (Regex.IsMatch (code, string.Format ("struct\\s*{0}[\\s:<{{]", typeName))) {
list.Add( AssetDatabase.AssetPathToGUID(codePath) );
continue;
}

if (Regex.IsMatch (code, string.Format ("enum\\s*{0}[\\s{{]", type.Name))) {
list.Add( AssetDatabase.AssetPathToGUID(codePath) );
continue;
}

if (Regex.IsMatch (code, string.Format ("delegate\\s*{0}\\s\\(", type.Name))) {
list.Add( AssetDatabase.AssetPathToGUID(codePath) );
continue;
}
}
}
}

List<System.Type> CollectionAllClasses ()
{
List<System.Type> alltypes = new List<System.Type> ();

if (File.Exists ("Library/ScriptAssemblies/Assembly-CSharp.dll"))
alltypes.AddRange (Assembly.LoadFile ("Library/ScriptAssemblies/Assembly-CSharp.dll").GetTypes ());
if (File.Exists ("Library/ScriptAssemblies/Assembly-CSharp-Editor.dll"))
alltypes.AddRange (Assembly.LoadFile ("Library/ScriptAssemblies/Assembly-CSharp-Editor.dll").GetTypes ());

return alltypes .ToList ();
}

List<System.Type> collectionAllFastspassClasses()
{
List<System.Type> alltypes = new List<System.Type> ();
if (File.Exists ("Library/ScriptAssemblies/Assembly-CSharp-firstpass.dll"))
alltypes.AddRange (Assembly.LoadFile ("Library/ScriptAssemblies/Assembly-CSharp-firstpass.dll").GetTypes ());
if (File.Exists ("Library/ScriptAssemblies/Assembly-CSharp-Editor-firstpass.dll"))
alltypes.AddRange (Assembly.LoadFile ("Library/ScriptAssemblies/Assembly-CSharp-Editor-firstpass.dll").GetTypes ());
return alltypes;
}

void CollectionReferenceClasses (string guid, List<System.Type> types)
{
var codePath = AssetDatabase.GUIDToAssetPath(guid);
if (string.IsNullOrEmpty (codePath) || references.ContainsKey (guid) || File.Exists(codePath)==false) {
return;
}

var code = System.IO.File.ReadAllText (codePath);
code = Regex.Replace(code, "//.*[\\n\\r]", "");
code = Regex.Replace(code, "/\\*.*[\\n\\r]\\*/", "");

var list = new List<System.Type> ();
references [guid] = list;

foreach (var type in types) {

if (string.IsNullOrEmpty (type.Namespace) == false) {
var namespacepattern = string.Format ("[namespace|using][\\s\\.]{0}[{{\\s\\r\\n\\r;]", type.Namespace);
if (Regex.IsMatch (code, namespacepattern) == false) {
continue;
}
}

if (codeFileList.ContainsKey (type) == false) {
continue;
}

string match = string.Empty;
if (type.IsGenericTypeDefinition) {
string typeName = type.GetGenericTypeDefinition ().Name.Split ('`') [0];
match = string.Format ("[\\]\\[\\.\\s<(]{0}[\\.\\s\\n\\r>,<(){{]", typeName);
} else {
match = string.Format ("[\\]\\[\\.\\s<(]{0}[\\.\\s\\n\\r>,<(){{\\]]", type.Name.Replace("Attribute", ""));
}
if (Regex.IsMatch (code, match)) {
list.Add (type);
var typeGuid = codeFileList[type];
foreach( var referenceGuid in typeGuid){
CollectionReferenceClasses (referenceGuid, types);
}
}
}
}
}
}
12 changes: 12 additions & 0 deletions Assets/Cleaner/Editor/ClassReferenceCollection.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8ca57a5

Please sign in to comment.