Skip to content

Commit 4f2c179

Browse files
committed
Initial commit.
0 parents  commit 4f2c179

File tree

9 files changed

+531
-0
lines changed

9 files changed

+531
-0
lines changed

.gitignore

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
bin
2+
obj
3+
TestResults
4+
test-results
5+
.metadata
6+
*.class
7+
*.settings
8+
local.properties
9+
*.userprefs
10+
.DS_Store
11+
*.user
12+
*.suo

Proguard.Build.Tasks/JniIndexer.cs

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using System;
2+
using System.Linq;
3+
using Mono.Cecil;
4+
using System.Collections.Generic;
5+
6+
namespace BitterFudge.Proguard.Build
7+
{
8+
class JniIndexer
9+
{
10+
readonly Dictionary<string, JniType> typeMap = new Dictionary<string, JniType> ();
11+
12+
public List<JniType> Crawl (IEnumerable<TypeDefinition> types)
13+
{
14+
try {
15+
foreach (var t in types) {
16+
var jniType = GetJniType (t);
17+
if (jniType == null)
18+
continue;
19+
20+
// Get all class registration attributes
21+
var regAttrs = t.Events.Cast<IMemberDefinition> ()
22+
.Union (t.Fields.Cast<IMemberDefinition> ())
23+
.Union (t.Properties.Cast<IMemberDefinition> ())
24+
.Union (t.Methods.Cast<IMemberDefinition> ())
25+
.SelectMany (m => m.CustomAttributes)
26+
.Where (a => a.AttributeType.FullName == "Android.Runtime.RegisterAttribute");
27+
28+
foreach (var attr in regAttrs) {
29+
String jniName = null;
30+
String jniSig = null;
31+
if (attr.ConstructorArguments.Count > 0) {
32+
jniName = (string)attr.ConstructorArguments [0].Value;
33+
}
34+
if (attr.ConstructorArguments.Count > 1) {
35+
jniSig = (string)attr.ConstructorArguments [1].Value;
36+
}
37+
if (jniName == null)
38+
continue;
39+
40+
jniType.Members.Add (new JniMember (jniName, jniSig));
41+
}
42+
}
43+
44+
return typeMap.Values.ToList ();
45+
} finally {
46+
typeMap.Clear ();
47+
}
48+
}
49+
50+
JniType GetJniType (TypeDefinition typeDef)
51+
{
52+
var attr = typeDef.CustomAttributes
53+
.SingleOrDefault (a => a.AttributeType.FullName == "Android.Runtime.RegisterAttribute");
54+
55+
var name = attr != null ? (string)attr.ConstructorArguments [0].Value : null;
56+
if (name == null)
57+
return null;
58+
59+
JniType jniType;
60+
if (!typeMap.TryGetValue (name, out jniType)) {
61+
jniType = new JniType (name);
62+
typeMap [name] = jniType;
63+
}
64+
return jniType;
65+
}
66+
}
67+
}

Proguard.Build.Tasks/JniMember.cs

+185
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
using System;
2+
using System.Text;
3+
using System.Collections.Generic;
4+
5+
namespace BitterFudge.Proguard.Build
6+
{
7+
class JniMember
8+
{
9+
readonly string name;
10+
readonly string signature;
11+
12+
public JniMember (string name, string signature)
13+
{
14+
this.name = name;
15+
this.signature = signature;
16+
}
17+
18+
public string Name {
19+
get { return name; }
20+
}
21+
22+
public string Signature {
23+
get { return signature; }
24+
}
25+
26+
public override string ToString ()
27+
{
28+
var name = Name;
29+
if (name == ".ctor")
30+
name = "<init>";
31+
32+
var e = Signature.GetEnumerator ();
33+
if (!e.MoveNext ())
34+
throw new FormatException ("Invalid signature");
35+
36+
var str = Parse (e, name);
37+
38+
if (e.MoveNext ())
39+
throw new FormatException ("Invalid signature");
40+
41+
return str;
42+
}
43+
44+
string Parse (CharEnumerator e, string name = null)
45+
{
46+
return ParseMethod (e, name) ?? ParsePrimitive (e, name) ?? ParseArray (e, name) ?? ParseClass (e, name);
47+
}
48+
49+
string ParseMethod (CharEnumerator e, string name = null)
50+
{
51+
if (e.Current != '(')
52+
return null;
53+
54+
List<string> args = new List<string> ();
55+
if (!e.MoveNext ())
56+
throw new FormatException ();
57+
while (e.Current != ')') {
58+
args.Add (Parse (e));
59+
if (!e.MoveNext ())
60+
throw new FormatException ();
61+
}
62+
63+
if (!e.MoveNext ())
64+
throw new FormatException ();
65+
var returnType = Parse (e);
66+
67+
var sb = new StringBuilder ();
68+
if (returnType != "void" || name != "<init>") {
69+
sb.Append (returnType);
70+
sb.Append (' ');
71+
}
72+
if (name != null) {
73+
sb.Append (name);
74+
}
75+
sb.Append ("(");
76+
sb.Append (String.Join (", ", args));
77+
sb.Append (")");
78+
return sb.ToString ();
79+
}
80+
81+
string ParsePrimitive (CharEnumerator e, string name = null)
82+
{
83+
string type;
84+
switch (e.Current) {
85+
case 'V':
86+
type = "void";
87+
break;
88+
case 'Z':
89+
type = "boolean";
90+
break;
91+
case 'B':
92+
type = "byte";
93+
break;
94+
case 'C':
95+
type = "char";
96+
break;
97+
case 'S':
98+
type = "short";
99+
break;
100+
case 'I':
101+
type = "int";
102+
break;
103+
case 'J':
104+
type = "long";
105+
break;
106+
case 'F':
107+
type = "float";
108+
break;
109+
case 'D':
110+
type = "double";
111+
break;
112+
default:
113+
return null;
114+
}
115+
116+
if (name == null)
117+
return type;
118+
return String.Concat (type, " ", name);
119+
}
120+
121+
string ParseArray (CharEnumerator e, string name = null)
122+
{
123+
if (e.Current != '[')
124+
return null;
125+
126+
if (!e.MoveNext ())
127+
throw new FormatException ();
128+
129+
var type = Parse (e);
130+
if (name == null)
131+
return type;
132+
return String.Concat (type, " ", name);
133+
}
134+
135+
string ParseClass (CharEnumerator e, string name = null)
136+
{
137+
if (e.Current != 'L')
138+
return null;
139+
140+
var sb = new StringBuilder ();
141+
if (!e.MoveNext ())
142+
throw new FormatException ();
143+
while (e.Current != ';') {
144+
sb.Append (e.Current == '/' ? '.' : e.Current);
145+
if (!e.MoveNext ())
146+
throw new FormatException ();
147+
}
148+
149+
if (name != null) {
150+
sb.Append (' ');
151+
sb.Append (name);
152+
}
153+
return sb.ToString ();
154+
}
155+
156+
public override bool Equals (object obj)
157+
{
158+
if (obj == null)
159+
return false;
160+
161+
var rec = obj as JniMember;
162+
if (rec == null)
163+
return false;
164+
165+
return this.Name == rec.Name && this.Signature == rec.Signature;
166+
}
167+
168+
public override int GetHashCode ()
169+
{
170+
var hash = name != null ? name.GetHashCode () : 0;
171+
hash ^= signature != null ? signature.GetHashCode () : 0;
172+
return hash;
173+
}
174+
175+
public static bool operator == (JniMember a, JniMember b)
176+
{
177+
return ReferenceEquals (a, b) || (!ReferenceEquals (a, null) && a.Equals (b));
178+
}
179+
180+
public static bool operator != (JniMember a, JniMember b)
181+
{
182+
return !(a == b);
183+
}
184+
}
185+
}

Proguard.Build.Tasks/JniType.cs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace BitterFudge.Proguard.Build
5+
{
6+
class JniType
7+
{
8+
readonly string name;
9+
readonly HashSet<JniMember> members = new HashSet<JniMember> ();
10+
11+
public JniType (string name)
12+
{
13+
this.name = name;
14+
}
15+
16+
public string Name {
17+
get { return name; }
18+
}
19+
20+
public ISet<JniMember> Members {
21+
get { return members; }
22+
}
23+
24+
public override string ToString ()
25+
{
26+
return Name.Replace ('/', '.');
27+
}
28+
}
29+
}
30+

Proguard.Build.Tasks/OS.cs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.IO;
3+
4+
namespace BitterFudge.Proguard.Build
5+
{
6+
public static class OS
7+
{
8+
public static bool IsWindows { get; private set; }
9+
10+
static OS ()
11+
{
12+
IsWindows = Path.PathSeparator == '\\';
13+
}
14+
}
15+
}
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6+
<ProductVersion>12.0.0</ProductVersion>
7+
<SchemaVersion>2.0</SchemaVersion>
8+
<ProjectGuid>{509B3785-1D8A-4524-BDAD-179700B12FEB}</ProjectGuid>
9+
<OutputType>Library</OutputType>
10+
<RootNamespace>BitterFudge.Proguard.Build</RootNamespace>
11+
<AssemblyName>Proguard.Build.Tasks</AssemblyName>
12+
</PropertyGroup>
13+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
14+
<DebugSymbols>true</DebugSymbols>
15+
<DebugType>full</DebugType>
16+
<Optimize>false</Optimize>
17+
<OutputPath>bin\Debug</OutputPath>
18+
<DefineConstants>DEBUG;</DefineConstants>
19+
<ErrorReport>prompt</ErrorReport>
20+
<WarningLevel>4</WarningLevel>
21+
<ConsolePause>false</ConsolePause>
22+
</PropertyGroup>
23+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
24+
<DebugType>full</DebugType>
25+
<Optimize>true</Optimize>
26+
<OutputPath>bin\Release</OutputPath>
27+
<ErrorReport>prompt</ErrorReport>
28+
<WarningLevel>4</WarningLevel>
29+
<ConsolePause>false</ConsolePause>
30+
</PropertyGroup>
31+
<ItemGroup>
32+
<Reference Include="System" />
33+
<Reference Include="Microsoft.Build.Utilities.v4.0" />
34+
<Reference Include="Microsoft.Build.Framework" />
35+
<Reference Include="Mono.Cecil, Version=0.9.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
36+
<Private>True</Private>
37+
</Reference>
38+
</ItemGroup>
39+
<ItemGroup>
40+
<Compile Include="Properties\AssemblyInfo.cs" />
41+
<Compile Include="OS.cs" />
42+
<Compile Include="JniType.cs" />
43+
<Compile Include="JniMember.cs" />
44+
<Compile Include="JniIndexer.cs" />
45+
<Compile Include="Tasks\Proguard.cs">
46+
<DependentUpon>..\ReferenceCollector.cs</DependentUpon>
47+
</Compile>
48+
</ItemGroup>
49+
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
50+
<ItemGroup>
51+
<Folder Include="Tasks\" />
52+
</ItemGroup>
53+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
4+
// Information about this assembly is defined by the following attributes.
5+
// Change them to the values specific to your project.
6+
[assembly: AssemblyTitle ("Proguard.Build.Tasks")]
7+
[assembly: AssemblyDescription ("")]
8+
[assembly: AssemblyConfiguration ("")]
9+
[assembly: AssemblyCompany ("BitterFudge OÜ")]
10+
[assembly: AssemblyProduct ("")]
11+
[assembly: AssemblyCopyright ("BitterFudge OÜ")]
12+
[assembly: AssemblyTrademark ("")]
13+
[assembly: AssemblyCulture ("")]
14+
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
15+
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
16+
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
17+
[assembly: AssemblyVersion ("1.0.*")]
18+
// The following attributes are used to specify the signing key for the assembly,
19+
// if desired. See the Mono documentation for more information about signing.
20+
//[assembly: AssemblyDelaySign(false)]
21+
//[assembly: AssemblyKeyFile("")]
22+

0 commit comments

Comments
 (0)